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