1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -globalopt -S | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; RUN: opt -emulated-tls < %s -globalopt -S | FileCheck %s 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Workerdeclare void @wait() 5*9880d681SAndroid Build Coastguard Workerdeclare void @signal() 6*9880d681SAndroid Build Coastguard Workerdeclare void @start_thread(void ()*) 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Worker@x = internal thread_local global [100 x i32] zeroinitializer, align 16 9*9880d681SAndroid Build Coastguard Worker@ip = internal global i32* null, align 8 10*9880d681SAndroid Build Coastguard Worker 11*9880d681SAndroid Build Coastguard Worker; PR14309: GlobalOpt would think that the value of @ip is always the address of 12*9880d681SAndroid Build Coastguard Worker; x[1]. However, that address is different for different threads so @ip cannot 13*9880d681SAndroid Build Coastguard Worker; be replaced with a constant. 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Workerdefine i32 @f() { 16*9880d681SAndroid Build Coastguard Workerentry: 17*9880d681SAndroid Build Coastguard Worker ; Set @ip to point to x[1] for thread 1. 18*9880d681SAndroid Build Coastguard Worker store i32* getelementptr inbounds ([100 x i32], [100 x i32]* @x, i64 0, i64 1), i32** @ip, align 8 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker ; Run g on a new thread. 21*9880d681SAndroid Build Coastguard Worker tail call void @start_thread(void ()* @g) nounwind 22*9880d681SAndroid Build Coastguard Worker tail call void @wait() nounwind 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Worker ; Reset x[1] for thread 1. 25*9880d681SAndroid Build Coastguard Worker store i32 0, i32* getelementptr inbounds ([100 x i32], [100 x i32]* @x, i64 0, i64 1), align 4 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Worker ; Read the value of @ip, which now points at x[1] for thread 2. 28*9880d681SAndroid Build Coastguard Worker %0 = load i32*, i32** @ip, align 8 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Worker %1 = load i32, i32* %0, align 4 31*9880d681SAndroid Build Coastguard Worker ret i32 %1 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f( 34*9880d681SAndroid Build Coastguard Worker; Make sure that the load from @ip hasn't been removed. 35*9880d681SAndroid Build Coastguard Worker; CHECK: load i32*, i32** @ip 36*9880d681SAndroid Build Coastguard Worker; CHECK: ret 37*9880d681SAndroid Build Coastguard Worker} 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Workerdefine internal void @g() nounwind uwtable { 40*9880d681SAndroid Build Coastguard Workerentry: 41*9880d681SAndroid Build Coastguard Worker ; Set @ip to point to x[1] for thread 2. 42*9880d681SAndroid Build Coastguard Worker store i32* getelementptr inbounds ([100 x i32], [100 x i32]* @x, i64 0, i64 1), i32** @ip, align 8 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Worker ; Store 50 in x[1] for thread 2. 45*9880d681SAndroid Build Coastguard Worker store i32 50, i32* getelementptr inbounds ([100 x i32], [100 x i32]* @x, i64 0, i64 1), align 4 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Worker tail call void @signal() nounwind 48*9880d681SAndroid Build Coastguard Worker ret void 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @g( 51*9880d681SAndroid Build Coastguard Worker; Make sure that the store to @ip hasn't been removed. 52*9880d681SAndroid Build Coastguard Worker; CHECK: store {{.*}} @ip 53*9880d681SAndroid Build Coastguard Worker; CHECK: ret 54*9880d681SAndroid Build Coastguard Worker} 55