1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature 2; RUN: opt -S -attributor -openmpopt < %s | FileCheck %s 3; RUN: opt -S -passes='attributor,cgscc(openmpopt)' < %s | FileCheck %s 4; 5target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 6 7%struct.ident_t = type { i32, i32, i32, i32, i8* } 8 9@.str = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1 10@0 = private unnamed_addr global %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 0) }, align 8 11@1 = private unnamed_addr global %struct.ident_t { i32 0, i32 322, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 0) }, align 8 12@.gomp_critical_user_.reduction.var = common global [8 x i32] zeroinitializer 13@2 = private unnamed_addr global %struct.ident_t { i32 0, i32 18, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 0) }, align 8 14 15; void delete_parallel_0(void) { 16; #pragma omp parallel 17; { unknown_willreturn(); } 18; #pragma omp parallel 19; { readonly_willreturn(); } 20; #pragma omp parallel 21; { readnone_willreturn(); } 22; #pragma omp parallel 23; {} 24; } 25; 26; We delete all but the first of the parallel regions in this test. 27define void @delete_parallel_0() { 28; CHECK-LABEL: define {{[^@]+}}@delete_parallel_0() 29; CHECK-NEXT: entry: 30; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 0, void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*)* @.omp_outlined.willreturn to void (i32*, i32*, ...)*)) 31; CHECK-NEXT: ret void 32; 33entry: 34 call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined.willreturn to void (i32*, i32*, ...)*)) 35 call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined.willreturn.0 to void (i32*, i32*, ...)*)) 36 call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined.willreturn.1 to void (i32*, i32*, ...)*)) 37 call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined.willreturn.2 to void (i32*, i32*, ...)*)) 38 ret void 39} 40 41define internal void @.omp_outlined.willreturn(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { 42entry: 43 call void @unknown() willreturn 44 ret void 45} 46 47define internal void @.omp_outlined.willreturn.0(i32* noalias %.global_tid., i32* noalias %.bound_tid.) willreturn { 48entry: 49 call void @readonly() 50 ret void 51} 52 53define internal void @.omp_outlined.willreturn.1(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { 54entry: 55 call void @readnone() willreturn 56 ret void 57} 58 59define internal void @.omp_outlined.willreturn.2(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { 60entry: 61 ret void 62} 63 64; void delete_parallel_1(void) { 65; #pragma omp parallel 66; { unknown(); } 67; #pragma omp parallel 68; { readonly(); } 69; #pragma omp parallel 70; { readnone(); } 71; #pragma omp parallel 72; {} 73; } 74; 75; We delete only the last parallel regions in this test because the others might not return. 76define void @delete_parallel_1() { 77; CHECK-LABEL: define {{[^@]+}}@delete_parallel_1() 78; CHECK-NEXT: entry: 79; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 0, void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*)) 80; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 0, void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*)* @.omp_outlined..0 to void (i32*, i32*, ...)*)) 81; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 0, void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*)) 82; CHECK-NEXT: ret void 83; 84entry: 85 call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*)) 86 call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..0 to void (i32*, i32*, ...)*)) 87 call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*)) 88 call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..2 to void (i32*, i32*, ...)*)) 89 ret void 90} 91 92define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { 93entry: 94 call void @unknown() 95 ret void 96} 97 98define internal void @.omp_outlined..0(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { 99entry: 100 call void @readonly() 101 ret void 102} 103 104define internal void @.omp_outlined..1(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { 105entry: 106 call void @readnone() 107 ret void 108} 109 110define internal void @.omp_outlined..2(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { 111entry: 112 ret void 113} 114 115; void delete_parallel_2(void) { 116; int a = 0; 117; #pragma omp parallel 118; { 119; if (omp_get_thread_num() == 0) 120; ++a; 121; } 122; #pragma omp parallel 123; { 124; #pragma omp master 125; ++a; 126; } 127; #pragma omp parallel 128; { 129; #pragma omp single 130; ++a; 131; } 132; #pragma omp parallel reduction(+: a) 133; { 134; ++a; 135; } 136; } 137; 138; FIXME: We do not realize that `a` is dead and all accesses to it can be removed 139; making the parallel regions readonly and deletable. 140define void @delete_parallel_2() { 141; CHECK-LABEL: define {{[^@]+}}@delete_parallel_2() 142; CHECK-NEXT: entry: 143; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 144; CHECK-NEXT: [[TMP:%.*]] = bitcast i32* [[A]] to i8* 145; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull align 4 dereferenceable(4) [[TMP]]) #0 146; CHECK-NEXT: store i32 0, i32* [[A]], align 4 147; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 1, void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*)* @.omp_outlined..3 to void (i32*, i32*, ...)*), i32* nocapture nofree nonnull align 4 dereferenceable(4) [[A]]) 148; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 1, void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*)* @.omp_outlined..4 to void (i32*, i32*, ...)*), i32* nocapture nonnull align 4 dereferenceable(4) [[A]]) 149; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 1, void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*)* @.omp_outlined..5 to void (i32*, i32*, ...)*), i32* nocapture nonnull align 4 dereferenceable(4) [[A]]) 150; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8 dereferenceable(24) @0, i32 1, void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*)* @.omp_outlined..6 to void (i32*, i32*, ...)*), i32* nocapture nonnull align 4 dereferenceable(4) [[A]]) 151; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8* 152; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull [[TMP1]]) 153; CHECK-NEXT: ret void 154; 155entry: 156 %a = alloca i32, align 4 157 %tmp = bitcast i32* %a to i8* 158 call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %tmp) 159 store i32 0, i32* %a, align 4 160 call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* @.omp_outlined..3 to void (i32*, i32*, ...)*), i32* nonnull %a) 161 call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* @.omp_outlined..4 to void (i32*, i32*, ...)*), i32* nonnull %a) 162 call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* @.omp_outlined..5 to void (i32*, i32*, ...)*), i32* nonnull %a) 163 call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @0, i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* @.omp_outlined..6 to void (i32*, i32*, ...)*), i32* nonnull %a) 164 %tmp1 = bitcast i32* %a to i8* 165 call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %tmp1) 166 ret void 167} 168 169define internal void @.omp_outlined..3(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) { 170entry: 171 %call = call i32 @omp_get_thread_num() 172 %cmp = icmp eq i32 %call, 0 173 br i1 %cmp, label %if.then, label %if.end 174 175if.then: ; preds = %entry 176 %tmp = load i32, i32* %a, align 4 177 %inc = add nsw i32 %tmp, 1 178 store i32 %inc, i32* %a, align 4 179 br label %if.end 180 181if.end: ; preds = %if.then, %entry 182 ret void 183} 184 185define internal void @.omp_outlined..4(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) { 186entry: 187 %tmp = load i32, i32* %.global_tid., align 4 188 %tmp1 = call i32 @__kmpc_master(%struct.ident_t* nonnull @0, i32 %tmp) 189 %tmp2 = icmp eq i32 %tmp1, 0 190 br i1 %tmp2, label %omp_if.end, label %omp_if.then 191 192omp_if.then: ; preds = %entry 193 %tmp3 = load i32, i32* %a, align 4 194 %inc = add nsw i32 %tmp3, 1 195 store i32 %inc, i32* %a, align 4 196 call void @__kmpc_end_master(%struct.ident_t* nonnull @0, i32 %tmp) 197 br label %omp_if.end 198 199omp_if.end: ; preds = %entry, %omp_if.then 200 ret void 201} 202 203declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) 204 205declare i32 @omp_get_thread_num() inaccessiblememonly nofree nosync nounwind readonly 206 207declare i32 @__kmpc_master(%struct.ident_t*, i32) 208 209declare void @__kmpc_end_master(%struct.ident_t*, i32) 210 211define internal void @.omp_outlined..5(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) { 212entry: 213 %omp_global_thread_num = call i32 @__kmpc_global_thread_num(%struct.ident_t* nonnull @0) 214 %tmp = load i32, i32* %.global_tid., align 4 215 %tmp1 = call i32 @__kmpc_single(%struct.ident_t* nonnull @0, i32 %tmp) 216 %tmp2 = icmp eq i32 %tmp1, 0 217 br i1 %tmp2, label %omp_if.end, label %omp_if.then 218 219omp_if.then: ; preds = %entry 220 %tmp3 = load i32, i32* %a, align 4 221 %inc = add nsw i32 %tmp3, 1 222 store i32 %inc, i32* %a, align 4 223 call void @__kmpc_end_single(%struct.ident_t* nonnull @0, i32 %tmp) 224 br label %omp_if.end 225 226omp_if.end: ; preds = %entry, %omp_if.then 227 call void @__kmpc_barrier(%struct.ident_t* nonnull @1, i32 %omp_global_thread_num) #6 228 ret void 229} 230 231define internal void @.omp_outlined..6(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) { 232entry: 233 %a1 = alloca i32, align 4 234 %.omp.reduction.red_list = alloca [1 x i8*], align 8 235 %tmp = bitcast i32* %a1 to i8* 236 call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %tmp) 237 store i32 1, i32* %a1, align 4 238 %tmp1 = bitcast [1 x i8*]* %.omp.reduction.red_list to i32** 239 store i32* %a1, i32** %tmp1, align 8 240 %tmp2 = load i32, i32* %.global_tid., align 4 241 %tmp3 = bitcast [1 x i8*]* %.omp.reduction.red_list to i8* 242 %tmp4 = call i32 @__kmpc_reduce_nowait(%struct.ident_t* nonnull @2, i32 %tmp2, i32 1, i64 8, i8* nonnull %tmp3, void (i8*, i8*)* nonnull @.omp.reduction.reduction_func, [8 x i32]* nonnull @.gomp_critical_user_.reduction.var) 243 switch i32 %tmp4, label %.omp.reduction.default [ 244 i32 1, label %.omp.reduction.case1 245 i32 2, label %.omp.reduction.case2 246 ] 247 248.omp.reduction.case1: ; preds = %entry 249 %tmp5 = load i32, i32* %a, align 4 250 %tmp6 = load i32, i32* %a1, align 4 251 %add = add nsw i32 %tmp5, %tmp6 252 store i32 %add, i32* %a, align 4 253 call void @__kmpc_end_reduce_nowait(%struct.ident_t* nonnull @2, i32 %tmp2, [8 x i32]* nonnull @.gomp_critical_user_.reduction.var) 254 br label %.omp.reduction.default 255 256.omp.reduction.case2: ; preds = %entry 257 %tmp7 = load i32, i32* %a1, align 4 258 %tmp8 = atomicrmw add i32* %a, i32 %tmp7 monotonic 259 br label %.omp.reduction.default 260 261.omp.reduction.default: ; preds = %.omp.reduction.case2, %.omp.reduction.case1, %entry 262 %tmp9 = bitcast i32* %a1 to i8* 263 call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %tmp9) 264 ret void 265} 266 267define internal void @.omp.reduction.reduction_func(i8* %arg, i8* %arg1) { 268entry: 269 %tmp = bitcast i8* %arg1 to i32** 270 %tmp2 = load i32*, i32** %tmp, align 8 271 %tmp3 = bitcast i8* %arg to i32** 272 %tmp4 = load i32*, i32** %tmp3, align 8 273 %tmp5 = load i32, i32* %tmp4, align 4 274 %tmp6 = load i32, i32* %tmp2, align 4 275 %add = add nsw i32 %tmp5, %tmp6 276 store i32 %add, i32* %tmp4, align 4 277 ret void 278} 279 280declare i32 @__kmpc_single(%struct.ident_t*, i32) 281 282declare void @__kmpc_end_single(%struct.ident_t*, i32) 283 284declare void @__kmpc_barrier(%struct.ident_t*, i32) 285 286declare i32 @__kmpc_global_thread_num(%struct.ident_t*) nofree nosync nounwind readonly 287 288declare i32 @__kmpc_reduce_nowait(%struct.ident_t*, i32, i32, i64, i8*, void (i8*, i8*)*, [8 x i32]*) 289 290declare void @__kmpc_end_reduce_nowait(%struct.ident_t*, i32, [8 x i32]*) 291 292declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) 293 294declare !callback !2 void @__kmpc_fork_call(%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) 295 296declare void @unknown() 297 298declare void @readonly() readonly 299 300declare void @readnone() readnone 301 302!0 = !{i32 1, !"wchar_size", i32 4} 303!1 = !{!"clang"} 304!2 = !{!3} 305!3 = !{i64 2, i64 -1, i64 -1, i1 true} 306!4 = !{!5, !5, i64 0} 307!5 = !{!"int", !6, i64 0} 308!6 = !{!"omnipotent char", !7, i64 0} 309!7 = !{!"Simple C/C++ TBAA"} 310