1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
2; RUN: opt -openmp-opt-cgscc -S < %s | FileCheck %s
3; RUN: opt -passes=openmp-opt-cgscc -S < %s | FileCheck %s
4target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
5
6%struct.ident_t = type { i32, i32, i32, i32, i8* }
7
8@0 = private unnamed_addr constant %struct.ident_t { i32 0, i32 34, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str0, i32 0, i32 0) }, align 8
9@1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str1, i32 0, i32 0) }, align 8
10@2 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str2, i32 0, i32 0) }, align 8
11@.str0 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1
12@.str1 = private unnamed_addr constant [23 x i8] c";file001;loc0001;0;0;;\00", align 1
13@.str2 = private unnamed_addr constant [23 x i8] c";file002;loc0002;0;0;;\00", align 1
14
15; UTC_ARGS: --disable
16; CHECK-DAG: @0 = private unnamed_addr constant %struct.ident_t { i32 0, i32 34, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str0, i32 0, i32 0) }, align 8
17; CHECK-DAG: @1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str1, i32 0, i32 0) }, align 8
18; CHECK-DAG: @2 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str2, i32 0, i32 0) }, align 8
19; CHECK-DAG: @.str0 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1
20; CHECK-DAG: @.str1 = private unnamed_addr constant [23 x i8] c";file001;loc0001;0;0;;\00", align 1
21; CHECK-DAG: @.str2 = private unnamed_addr constant [23 x i8] c";file002;loc0002;0;0;;\00", align 1
22; CHECK-DAG: @3 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str0, i32 0, i32 0) }, align 8
23; UTC_ARGS: --enable
24
25
26declare i32 @__kmpc_global_thread_num(%struct.ident_t*)
27declare void @useI32(i32)
28
29define void @external(i1 %c) {
30; CHECK-LABEL: define {{[^@]+}}@external
31; CHECK-SAME: (i1 [[C:%.*]])
32; CHECK-NEXT:  entry:
33; CHECK-NEXT:    [[C2:%.*]] = tail call i32 @__kmpc_global_thread_num(%struct.ident_t* nonnull @0)
34; CHECK-NEXT:    br i1 [[C]], label [[T:%.*]], label [[E:%.*]]
35; CHECK:       t:
36; CHECK-NEXT:    call void @internal(i32 [[C2]], i32 [[C2]])
37; CHECK-NEXT:    call void @useI32(i32 [[C2]])
38; CHECK-NEXT:    br label [[M:%.*]]
39; CHECK:       e:
40; CHECK-NEXT:    call void @internal(i32 [[C2]], i32 [[C2]])
41; CHECK-NEXT:    call void @useI32(i32 [[C2]])
42; CHECK-NEXT:    br label [[M]]
43; CHECK:       m:
44; CHECK-NEXT:    call void @internal(i32 0, i32 [[C2]])
45; CHECK-NEXT:    call void @useI32(i32 [[C2]])
46; CHECK-NEXT:    ret void
47;
48entry:
49  br i1 %c, label %t, label %e
50t:
51  %c0 = tail call i32 @__kmpc_global_thread_num(%struct.ident_t* nonnull @0)
52  call void @internal(i32 %c0, i32 %c0)
53  call void @useI32(i32 %c0)
54  br label %m
55e:
56  %c1 = tail call i32 @__kmpc_global_thread_num(%struct.ident_t* nonnull @0)
57  call void @internal(i32 %c1, i32 %c1)
58  call void @useI32(i32 %c1)
59  br label %m
60m:
61  %c2 = tail call i32 @__kmpc_global_thread_num(%struct.ident_t* nonnull @0)
62  call void @internal(i32 0, i32 %c2)
63  call void @useI32(i32 %c2)
64  ret void
65}
66
67define internal void @internal(i32 %not_gtid, i32 %gtid) {
68; CHECK-LABEL: define {{[^@]+}}@internal
69; CHECK-SAME: (i32 [[NOT_GTID:%.*]], i32 [[GTID:%.*]])
70; CHECK-NEXT:  entry:
71; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[GTID]], [[GTID]]
72; CHECK-NEXT:    br i1 [[C]], label [[T:%.*]], label [[E:%.*]]
73; CHECK:       t:
74; CHECK-NEXT:    call void @useI32(i32 [[GTID]])
75; CHECK-NEXT:    call void @external(i1 [[C]])
76; CHECK-NEXT:    br label [[M:%.*]]
77; CHECK:       e:
78; CHECK-NEXT:    call void @useI32(i32 [[GTID]])
79; CHECK-NEXT:    br label [[M]]
80; CHECK:       m:
81; CHECK-NEXT:    call void @useI32(i32 [[GTID]])
82; CHECK-NEXT:    ret void
83;
84entry:
85  %cc = tail call i32 @__kmpc_global_thread_num(%struct.ident_t* nonnull @0)
86  %c = icmp eq i32 %cc, %gtid
87  br i1 %c, label %t, label %e
88t:
89  %c0 = tail call i32 @__kmpc_global_thread_num(%struct.ident_t* nonnull @0)
90  call void @useI32(i32 %c0)
91  call void @external(i1 %c)
92  br label %m
93e:
94  %c1 = tail call i32 @__kmpc_global_thread_num(%struct.ident_t* nonnull @0)
95  call void @useI32(i32 %c1)
96  br label %m
97m:
98  %c2 = tail call i32 @__kmpc_global_thread_num(%struct.ident_t* nonnull @0)
99  call void @useI32(i32 %c2)
100  ret void
101}
102
103
104define void @local_and_global_gtid_calls() {
105; CHECK-LABEL: define {{[^@]+}}@local_and_global_gtid_calls()
106; CHECK-NEXT:  entry:
107; CHECK-NEXT:    [[TID5:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @3)
108; CHECK-NEXT:    [[DOTKMPC_LOC_ADDR:%.*]] = alloca [[STRUCT_IDENT_T:%.*]], align 8
109; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
110; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
111; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
112; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
113; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
114; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
115; CHECK-NEXT:    ret void
116;
117entry:
118  %.kmpc_loc.addr = alloca %struct.ident_t, align 8
119  %tid0 = call i32 @__kmpc_global_thread_num(%struct.ident_t* %.kmpc_loc.addr)
120  %tid1 = call i32 @__kmpc_global_thread_num(%struct.ident_t* @1)
121  %tid2 = call i32 @__kmpc_global_thread_num(%struct.ident_t* %.kmpc_loc.addr)
122  call void @useI32(i32 %tid0)
123  call void @useI32(i32 %tid1)
124  call void @useI32(i32 %tid2)
125  %tid3 = call i32 @__kmpc_global_thread_num(%struct.ident_t* %.kmpc_loc.addr)
126  %tid4 = call i32 @__kmpc_global_thread_num(%struct.ident_t* @2)
127  %tid5 = call i32 @__kmpc_global_thread_num(%struct.ident_t* %.kmpc_loc.addr)
128  call void @useI32(i32 %tid3)
129  call void @useI32(i32 %tid4)
130  call void @useI32(i32 %tid5)
131  ret void
132}
133
134define void @local_gtid_calls_only() {
135; CHECK-LABEL: define {{[^@]+}}@local_gtid_calls_only()
136; CHECK-NEXT:  entry:
137; CHECK-NEXT:    [[TID5:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @3)
138; CHECK-NEXT:    [[DOTKMPC_LOC_ADDR1:%.*]] = alloca [[STRUCT_IDENT_T:%.*]], align 8
139; CHECK-NEXT:    [[DOTKMPC_LOC_ADDR2:%.*]] = alloca [[STRUCT_IDENT_T]], align 8
140; CHECK-NEXT:    [[DOTKMPC_LOC_ADDR3:%.*]] = alloca [[STRUCT_IDENT_T]], align 8
141; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
142; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
143; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
144; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
145; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
146; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
147; CHECK-NEXT:    ret void
148;
149entry:
150  %.kmpc_loc.addr1 = alloca %struct.ident_t, align 8
151  %.kmpc_loc.addr2 = alloca %struct.ident_t, align 8
152  %.kmpc_loc.addr3 = alloca %struct.ident_t, align 8
153  %tid0 = call i32 @__kmpc_global_thread_num(%struct.ident_t* %.kmpc_loc.addr1)
154  %tid1 = call i32 @__kmpc_global_thread_num(%struct.ident_t* %.kmpc_loc.addr2)
155  %tid2 = call i32 @__kmpc_global_thread_num(%struct.ident_t* %.kmpc_loc.addr3)
156  call void @useI32(i32 %tid0)
157  call void @useI32(i32 %tid1)
158  call void @useI32(i32 %tid2)
159  %tid3 = call i32 @__kmpc_global_thread_num(%struct.ident_t* %.kmpc_loc.addr1)
160  %tid4 = call i32 @__kmpc_global_thread_num(%struct.ident_t* %.kmpc_loc.addr2)
161  %tid5 = call i32 @__kmpc_global_thread_num(%struct.ident_t* %.kmpc_loc.addr3)
162  call void @useI32(i32 %tid3)
163  call void @useI32(i32 %tid4)
164  call void @useI32(i32 %tid5)
165  ret void
166}
167
168declare i32 @omp_get_level()
169define void @local_and_global_glvl_calls() {
170; CHECK-LABEL: define {{[^@]+}}@local_and_global_glvl_calls()
171; CHECK-NEXT:  entry:
172; CHECK-NEXT:    [[TID5:%.*]] = call i32 @omp_get_level()
173; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
174; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
175; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
176; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
177; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
178; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
179; CHECK-NEXT:    ret void
180;
181entry:
182  %tid0 = call i32 @omp_get_level()
183  %tid1 = call i32 @omp_get_level()
184  %tid2 = call i32 @omp_get_level()
185  call void @useI32(i32 %tid0)
186  call void @useI32(i32 %tid1)
187  call void @useI32(i32 %tid2)
188  %tid3 = call i32 @omp_get_level()
189  %tid4 = call i32 @omp_get_level()
190  %tid5 = call i32 @omp_get_level()
191  call void @useI32(i32 %tid3)
192  call void @useI32(i32 %tid4)
193  call void @useI32(i32 %tid5)
194  ret void
195}
196
197define void @local_glvl_calls_only() {
198; CHECK-LABEL: define {{[^@]+}}@local_glvl_calls_only()
199; CHECK-NEXT:  entry:
200; CHECK-NEXT:    [[TID5:%.*]] = call i32 @omp_get_level()
201; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
202; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
203; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
204; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
205; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
206; CHECK-NEXT:    call void @useI32(i32 [[TID5]])
207; CHECK-NEXT:    ret void
208;
209entry:
210  %tid0 = call i32 @omp_get_level()
211  %tid1 = call i32 @omp_get_level()
212  %tid2 = call i32 @omp_get_level()
213  call void @useI32(i32 %tid0)
214  call void @useI32(i32 %tid1)
215  call void @useI32(i32 %tid2)
216  %tid3 = call i32 @omp_get_level()
217  %tid4 = call i32 @omp_get_level()
218  %tid5 = call i32 @omp_get_level()
219  call void @useI32(i32 %tid3)
220  call void @useI32(i32 %tid4)
221  call void @useI32(i32 %tid5)
222  ret void
223}
224