1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature 2; RUN: opt -S -attributor -openmp-opt-cgscc < %s | FileCheck %s 3; RUN: opt -S -passes='attributor,cgscc(openmp-opt-cgscc)' < %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* noundef nonnull align 8 dereferenceable(24) @[[GLOB0:[0-9]+]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined.willreturn to void (i32*, i32*, ...)*)) 31; CHECK-NEXT: ret void 32; 33; CHECK1-LABEL: define {{[^@]+}}@delete_parallel_0() { 34; CHECK1-NEXT: entry: 35; CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0:[0-9]+]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined.willreturn to void (i32*, i32*, ...)*)) 36; CHECK1-NEXT: ret void 37; CHECK2-LABEL: define {{[^@]+}}@delete_parallel_0() { 38; CHECK2-NEXT: entry: 39; CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0:[0-9]+]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined.willreturn to void (i32*, i32*, ...)*)) 40; CHECK2-NEXT: ret void 41entry: 42 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*, ...)*)) 43 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*, ...)*)) 44 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*, ...)*)) 45 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*, ...)*)) 46 ret void 47} 48 49define internal void @.omp_outlined.willreturn(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { 50; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn 51; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0:[0-9]+]] { 52; CHECK-NEXT: entry: 53; CHECK-NEXT: call void @unknown() #[[ATTR0]] 54; CHECK-NEXT: ret void 55; 56; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.willreturn 57; CHECK1-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0:[0-9]+]] { 58; CHECK1-NEXT: entry: 59; CHECK1-NEXT: call void @unknown() #[[ATTR0]] 60; CHECK1-NEXT: ret void 61; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined.willreturn 62; CHECK2-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0:[0-9]+]] { 63; CHECK2-NEXT: entry: 64; CHECK2-NEXT: call void @unknown() #[[ATTR0]] 65; CHECK2-NEXT: ret void 66entry: 67 call void @unknown() willreturn 68 ret void 69} 70 71define internal void @.omp_outlined.willreturn.0(i32* noalias %.global_tid., i32* noalias %.bound_tid.) willreturn { 72; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.0 73; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR1:[0-9]+]] { 74; CHECK-NEXT: entry: 75; CHECK-NEXT: call void @readonly() #[[ATTR4:[0-9]+]] 76; CHECK-NEXT: ret void 77; 78; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.0 79; CHECK1-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR1:[0-9]+]] { 80; CHECK1-NEXT: entry: 81; CHECK1-NEXT: call void @readonly() #[[ATTR4:[0-9]+]] 82; CHECK1-NEXT: ret void 83; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.0 84; CHECK2-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR1:[0-9]+]] { 85; CHECK2-NEXT: entry: 86; CHECK2-NEXT: call void @readonly() #[[ATTR4:[0-9]+]] 87; CHECK2-NEXT: ret void 88entry: 89 call void @readonly() 90 ret void 91} 92 93define internal void @.omp_outlined.willreturn.1(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { 94; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.1 95; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR2:[0-9]+]] { 96; CHECK-NEXT: entry: 97; CHECK-NEXT: call void @readnone() #[[ATTR0]] 98; CHECK-NEXT: ret void 99; 100; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.1 101; CHECK1-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR2:[0-9]+]] { 102; CHECK1-NEXT: entry: 103; CHECK1-NEXT: call void @readnone() #[[ATTR0]] 104; CHECK1-NEXT: ret void 105; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.1 106; CHECK2-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR2:[0-9]+]] { 107; CHECK2-NEXT: entry: 108; CHECK2-NEXT: call void @readnone() #[[ATTR0]] 109; CHECK2-NEXT: ret void 110entry: 111 call void @readnone() willreturn 112 ret void 113} 114 115define internal void @.omp_outlined.willreturn.2(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { 116; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.2 117; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3:[0-9]+]] { 118; CHECK-NEXT: entry: 119; CHECK-NEXT: ret void 120; 121; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.2 122; CHECK1-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3:[0-9]+]] { 123; CHECK1-NEXT: entry: 124; CHECK1-NEXT: ret void 125; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.2 126; CHECK2-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3:[0-9]+]] { 127; CHECK2-NEXT: entry: 128; CHECK2-NEXT: ret void 129entry: 130 ret void 131} 132 133; void delete_parallel_1(void) { 134; #pragma omp parallel 135; { unknown(); } 136; #pragma omp parallel 137; { readonly(); } 138; #pragma omp parallel 139; { readnone(); } 140; #pragma omp parallel 141; {} 142; } 143; 144; We delete only the last parallel regions in this test because the others might not return. 145define void @delete_parallel_1() { 146; CHECK-LABEL: define {{[^@]+}}@delete_parallel_1() { 147; CHECK-NEXT: entry: 148; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*)) 149; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined..0 to void (i32*, i32*, ...)*)) 150; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*)) 151; CHECK-NEXT: ret void 152; 153; CHECK1-LABEL: define {{[^@]+}}@delete_parallel_1() { 154; CHECK1-NEXT: entry: 155; CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*)) 156; CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined..0 to void (i32*, i32*, ...)*)) 157; CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*)) 158; CHECK1-NEXT: ret void 159; CHECK2-LABEL: define {{[^@]+}}@delete_parallel_1() { 160; CHECK2-NEXT: entry: 161; CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*)) 162; CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined..0 to void (i32*, i32*, ...)*)) 163; CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*)) 164; CHECK2-NEXT: ret void 165entry: 166 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*, ...)*)) 167 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*, ...)*)) 168 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*, ...)*)) 169 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*, ...)*)) 170 ret void 171} 172 173define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { 174; CHECK-LABEL: define {{[^@]+}}@.omp_outlined. 175; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) { 176; CHECK-NEXT: entry: 177; CHECK-NEXT: call void @unknown() 178; CHECK-NEXT: ret void 179; 180; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined. 181; CHECK1-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) { 182; CHECK1-NEXT: entry: 183; CHECK1-NEXT: call void @unknown() 184; CHECK1-NEXT: ret void 185; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined. 186; CHECK2-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) { 187; CHECK2-NEXT: entry: 188; CHECK2-NEXT: call void @unknown() 189; CHECK2-NEXT: ret void 190entry: 191 call void @unknown() 192 ret void 193} 194 195define internal void @.omp_outlined..0(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { 196; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..0 197; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR4]] { 198; CHECK-NEXT: entry: 199; CHECK-NEXT: call void @readonly() #[[ATTR4]] 200; CHECK-NEXT: ret void 201; 202; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..0 203; CHECK1-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR4]] { 204; CHECK1-NEXT: entry: 205; CHECK1-NEXT: call void @readonly() #[[ATTR4]] 206; CHECK1-NEXT: ret void 207; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..0 208; CHECK2-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR4]] { 209; CHECK2-NEXT: entry: 210; CHECK2-NEXT: call void @readonly() #[[ATTR4]] 211; CHECK2-NEXT: ret void 212entry: 213 call void @readonly() 214 ret void 215} 216 217define internal void @.omp_outlined..1(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { 218; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..1 219; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR5:[0-9]+]] { 220; CHECK-NEXT: entry: 221; CHECK-NEXT: call void @readnone() 222; CHECK-NEXT: ret void 223; 224; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..1 225; CHECK1-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR5:[0-9]+]] { 226; CHECK1-NEXT: entry: 227; CHECK1-NEXT: call void @readnone() 228; CHECK1-NEXT: ret void 229; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..1 230; CHECK2-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR5:[0-9]+]] { 231; CHECK2-NEXT: entry: 232; CHECK2-NEXT: call void @readnone() 233; CHECK2-NEXT: ret void 234entry: 235 call void @readnone() 236 ret void 237} 238 239define internal void @.omp_outlined..2(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { 240; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..2 241; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3]] { 242; CHECK-NEXT: entry: 243; CHECK-NEXT: ret void 244; 245; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..2 246; CHECK1-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3]] { 247; CHECK1-NEXT: entry: 248; CHECK1-NEXT: ret void 249; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..2 250; CHECK2-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3]] { 251; CHECK2-NEXT: entry: 252; CHECK2-NEXT: ret void 253entry: 254 ret void 255} 256 257; void delete_parallel_2(void) { 258; int a = 0; 259; #pragma omp parallel 260; { 261; if (omp_get_thread_num() == 0) 262; ++a; 263; } 264; #pragma omp parallel 265; { 266; #pragma omp master 267; ++a; 268; } 269; #pragma omp parallel 270; { 271; #pragma omp single 272; ++a; 273; } 274; #pragma omp parallel reduction(+: a) 275; { 276; ++a; 277; } 278; } 279; 280; FIXME: We do not realize that `a` is dead and all accesses to it can be removed 281; making the parallel regions readonly and deletable. 282define void @delete_parallel_2() { 283; CHECK-LABEL: define {{[^@]+}}@delete_parallel_2() { 284; CHECK-NEXT: entry: 285; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 286; CHECK-NEXT: [[TMP:%.*]] = bitcast i32* [[A]] to i8* 287; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull align 4 dereferenceable(4) [[TMP]]) #[[ATTR0]] 288; CHECK-NEXT: store i32 0, i32* [[A]], align 4 289; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..3 to void (i32*, i32*, ...)*), i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]]) 290; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..4 to void (i32*, i32*, ...)*), i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]]) 291; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..5 to void (i32*, i32*, ...)*), i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]]) 292; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..6 to void (i32*, i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]]) 293; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8* 294; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull [[TMP1]]) 295; CHECK-NEXT: ret void 296; 297; CHECK1-LABEL: define {{[^@]+}}@delete_parallel_2() { 298; CHECK1-NEXT: entry: 299; CHECK1-NEXT: [[A:%.*]] = alloca i32, align 4 300; CHECK1-NEXT: [[TMP:%.*]] = bitcast i32* [[A]] to i8* 301; CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull align 4 dereferenceable(4) [[TMP]]) #[[ATTR0]] 302; CHECK1-NEXT: store i32 0, i32* [[A]], align 4 303; CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..3 to void (i32*, i32*, ...)*), i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]]) 304; CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..4 to void (i32*, i32*, ...)*), i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]]) 305; CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..5 to void (i32*, i32*, ...)*), i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]]) 306; CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..6 to void (i32*, i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]]) 307; CHECK1-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8* 308; CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull [[TMP1]]) 309; CHECK1-NEXT: ret void 310; CHECK2-LABEL: define {{[^@]+}}@delete_parallel_2() { 311; CHECK2-NEXT: entry: 312; CHECK2-NEXT: [[A:%.*]] = alloca i32, align 4 313; CHECK2-NEXT: [[TMP:%.*]] = bitcast i32* [[A]] to i8* 314; CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull align 4 dereferenceable(4) [[TMP]]) #[[ATTR0]] 315; CHECK2-NEXT: store i32 0, i32* [[A]], align 4 316; CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..3 to void (i32*, i32*, ...)*), i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]]) 317; CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..4 to void (i32*, i32*, ...)*), i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]]) 318; CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..5 to void (i32*, i32*, ...)*), i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]]) 319; CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..6 to void (i32*, i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]]) 320; CHECK2-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8* 321; CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull [[TMP1]]) 322; CHECK2-NEXT: ret void 323entry: 324 %a = alloca i32, align 4 325 %tmp = bitcast i32* %a to i8* 326 call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %tmp) 327 store i32 0, i32* %a, align 4 328 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) 329 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) 330 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) 331 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) 332 %tmp1 = bitcast i32* %a to i8* 333 call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %tmp1) 334 ret void 335} 336 337define internal void @.omp_outlined..3(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) { 338; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..3 339; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] { 340; CHECK-NEXT: entry: 341; CHECK-NEXT: [[CALL:%.*]] = call i32 @omp_get_thread_num() #[[ATTR14:[0-9]+]] 342; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 343; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 344; CHECK: if.then: 345; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[A]], align 4 346; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP]], 1 347; CHECK-NEXT: store i32 [[INC]], i32* [[A]], align 4 348; CHECK-NEXT: br label [[IF_END]] 349; CHECK: if.end: 350; CHECK-NEXT: ret void 351; 352; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..3 353; CHECK1-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] { 354; CHECK1-NEXT: entry: 355; CHECK1-NEXT: [[CALL:%.*]] = call i32 @omp_get_thread_num() #[[ATTR14:[0-9]+]] 356; CHECK1-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 357; CHECK1-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 358; CHECK1: if.then: 359; CHECK1-NEXT: [[TMP:%.*]] = load i32, i32* [[A]], align 4 360; CHECK1-NEXT: [[INC:%.*]] = add nsw i32 [[TMP]], 1 361; CHECK1-NEXT: store i32 [[INC]], i32* [[A]], align 4 362; CHECK1-NEXT: br label [[IF_END]] 363; CHECK1: if.end: 364; CHECK1-NEXT: ret void 365; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..3 366; CHECK2-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] { 367; CHECK2-NEXT: entry: 368; CHECK2-NEXT: [[CALL:%.*]] = call i32 @omp_get_thread_num() #[[ATTR14:[0-9]+]] 369; CHECK2-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 370; CHECK2-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 371; CHECK2: if.then: 372; CHECK2-NEXT: [[TMP:%.*]] = load i32, i32* [[A]], align 4 373; CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP]], 1 374; CHECK2-NEXT: store i32 [[INC]], i32* [[A]], align 4 375; CHECK2-NEXT: br label [[IF_END]] 376; CHECK2: if.end: 377; CHECK2-NEXT: ret void 378entry: 379 %call = call i32 @omp_get_thread_num() 380 %cmp = icmp eq i32 %call, 0 381 br i1 %cmp, label %if.then, label %if.end 382 383if.then: ; preds = %entry 384 %tmp = load i32, i32* %a, align 4 385 %inc = add nsw i32 %tmp, 1 386 store i32 %inc, i32* %a, align 4 387 br label %if.end 388 389if.end: ; preds = %if.then, %entry 390 ret void 391} 392 393define internal void @.omp_outlined..4(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) { 394; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..4 395; CHECK-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) { 396; CHECK-NEXT: entry: 397; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 398; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(%struct.ident_t* noundef nonnull @[[GLOB0]], i32 [[TMP]]) 399; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 400; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]] 401; CHECK: omp_if.then: 402; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[A]], align 4 403; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1 404; CHECK-NEXT: store i32 [[INC]], i32* [[A]], align 4 405; CHECK-NEXT: call void @__kmpc_end_master(%struct.ident_t* noundef nonnull @[[GLOB0]], i32 [[TMP]]) 406; CHECK-NEXT: br label [[OMP_IF_END]] 407; CHECK: omp_if.end: 408; CHECK-NEXT: ret void 409; 410; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..4 411; CHECK1-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) { 412; CHECK1-NEXT: entry: 413; CHECK1-NEXT: [[TMP:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 414; CHECK1-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(%struct.ident_t* noundef nonnull @[[GLOB0]], i32 [[TMP]]) 415; CHECK1-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 416; CHECK1-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]] 417; CHECK1: omp_if.then: 418; CHECK1-NEXT: [[TMP3:%.*]] = load i32, i32* [[A]], align 4 419; CHECK1-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1 420; CHECK1-NEXT: store i32 [[INC]], i32* [[A]], align 4 421; CHECK1-NEXT: call void @__kmpc_end_master(%struct.ident_t* noundef nonnull @[[GLOB0]], i32 [[TMP]]) 422; CHECK1-NEXT: br label [[OMP_IF_END]] 423; CHECK1: omp_if.end: 424; CHECK1-NEXT: ret void 425; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..4 426; CHECK2-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) { 427; CHECK2-NEXT: entry: 428; CHECK2-NEXT: [[TMP:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 429; CHECK2-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(%struct.ident_t* noundef nonnull @[[GLOB0]], i32 [[TMP]]) 430; CHECK2-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 431; CHECK2-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]] 432; CHECK2: omp_if.then: 433; CHECK2-NEXT: [[TMP3:%.*]] = load i32, i32* [[A]], align 4 434; CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1 435; CHECK2-NEXT: store i32 [[INC]], i32* [[A]], align 4 436; CHECK2-NEXT: call void @__kmpc_end_master(%struct.ident_t* noundef nonnull @[[GLOB0]], i32 [[TMP]]) 437; CHECK2-NEXT: br label [[OMP_IF_END]] 438; CHECK2: omp_if.end: 439; CHECK2-NEXT: ret void 440entry: 441 %tmp = load i32, i32* %.global_tid., align 4 442 %tmp1 = call i32 @__kmpc_master(%struct.ident_t* nonnull @0, i32 %tmp) 443 %tmp2 = icmp eq i32 %tmp1, 0 444 br i1 %tmp2, label %omp_if.end, label %omp_if.then 445 446omp_if.then: ; preds = %entry 447 %tmp3 = load i32, i32* %a, align 4 448 %inc = add nsw i32 %tmp3, 1 449 store i32 %inc, i32* %a, align 4 450 call void @__kmpc_end_master(%struct.ident_t* nonnull @0, i32 %tmp) 451 br label %omp_if.end 452 453omp_if.end: ; preds = %entry, %omp_if.then 454 ret void 455} 456 457declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) 458 459declare i32 @omp_get_thread_num() inaccessiblememonly nofree nosync nounwind readonly 460 461declare i32 @__kmpc_master(%struct.ident_t*, i32) 462 463declare void @__kmpc_end_master(%struct.ident_t*, i32) 464 465define internal void @.omp_outlined..5(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) { 466; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..5 467; CHECK-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) { 468; CHECK-NEXT: entry: 469; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull @[[GLOB0]]) #[[ATTR14]] 470; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 471; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_single(%struct.ident_t* noundef nonnull @[[GLOB0]], i32 [[TMP]]) 472; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 473; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]] 474; CHECK: omp_if.then: 475; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[A]], align 4 476; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1 477; CHECK-NEXT: store i32 [[INC]], i32* [[A]], align 4 478; CHECK-NEXT: call void @__kmpc_end_single(%struct.ident_t* noundef nonnull @[[GLOB0]], i32 [[TMP]]) 479; CHECK-NEXT: br label [[OMP_IF_END]] 480; CHECK: omp_if.end: 481; CHECK-NEXT: call void @__kmpc_barrier(%struct.ident_t* noundef nonnull @[[GLOB1:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM]]) 482; CHECK-NEXT: ret void 483; 484; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..5 485; CHECK1-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) { 486; CHECK1-NEXT: entry: 487; CHECK1-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull @[[GLOB0]]) #[[ATTR14]] 488; CHECK1-NEXT: [[TMP:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 489; CHECK1-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_single(%struct.ident_t* noundef nonnull @[[GLOB0]], i32 [[TMP]]) 490; CHECK1-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 491; CHECK1-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]] 492; CHECK1: omp_if.then: 493; CHECK1-NEXT: [[TMP3:%.*]] = load i32, i32* [[A]], align 4 494; CHECK1-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1 495; CHECK1-NEXT: store i32 [[INC]], i32* [[A]], align 4 496; CHECK1-NEXT: call void @__kmpc_end_single(%struct.ident_t* noundef nonnull @[[GLOB0]], i32 [[TMP]]) 497; CHECK1-NEXT: br label [[OMP_IF_END]] 498; CHECK1: omp_if.end: 499; CHECK1-NEXT: call void @__kmpc_barrier(%struct.ident_t* noundef nonnull @[[GLOB1:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM]]) 500; CHECK1-NEXT: ret void 501; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..5 502; CHECK2-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) { 503; CHECK2-NEXT: entry: 504; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull @[[GLOB0]]) #[[ATTR14]] 505; CHECK2-NEXT: [[TMP:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 506; CHECK2-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_single(%struct.ident_t* noundef nonnull @[[GLOB0]], i32 [[TMP]]) 507; CHECK2-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 508; CHECK2-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]] 509; CHECK2: omp_if.then: 510; CHECK2-NEXT: [[TMP3:%.*]] = load i32, i32* [[A]], align 4 511; CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1 512; CHECK2-NEXT: store i32 [[INC]], i32* [[A]], align 4 513; CHECK2-NEXT: call void @__kmpc_end_single(%struct.ident_t* noundef nonnull @[[GLOB0]], i32 [[TMP]]) 514; CHECK2-NEXT: br label [[OMP_IF_END]] 515; CHECK2: omp_if.end: 516; CHECK2-NEXT: call void @__kmpc_barrier(%struct.ident_t* noundef nonnull @[[GLOB1:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM]]) 517; CHECK2-NEXT: ret void 518entry: 519 %omp_global_thread_num = call i32 @__kmpc_global_thread_num(%struct.ident_t* nonnull @0) 520 %tmp = load i32, i32* %.global_tid., align 4 521 %tmp1 = call i32 @__kmpc_single(%struct.ident_t* nonnull @0, i32 %tmp) 522 %tmp2 = icmp eq i32 %tmp1, 0 523 br i1 %tmp2, label %omp_if.end, label %omp_if.then 524 525omp_if.then: ; preds = %entry 526 %tmp3 = load i32, i32* %a, align 4 527 %inc = add nsw i32 %tmp3, 1 528 store i32 %inc, i32* %a, align 4 529 call void @__kmpc_end_single(%struct.ident_t* nonnull @0, i32 %tmp) 530 br label %omp_if.end 531 532omp_if.end: ; preds = %entry, %omp_if.then 533 call void @__kmpc_barrier(%struct.ident_t* nonnull @1, i32 %omp_global_thread_num) #6 534 ret void 535} 536 537define internal void @.omp_outlined..6(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) { 538; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..6 539; CHECK-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) { 540; CHECK-NEXT: entry: 541; CHECK-NEXT: [[A1:%.*]] = alloca i32, align 4 542; CHECK-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8 543; CHECK-NEXT: [[TMP:%.*]] = bitcast i32* [[A1]] to i8* 544; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull align 4 [[TMP]]) #[[ATTR0]] 545; CHECK-NEXT: store i32 1, i32* [[A1]], align 4 546; CHECK-NEXT: [[TMP1:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i32** 547; CHECK-NEXT: store i32* [[A1]], i32** [[TMP1]], align 8 548; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 549; CHECK-NEXT: [[TMP3:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8* 550; CHECK-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* noundef nonnull @[[GLOB2:[0-9]+]], i32 [[TMP2]], i32 noundef 1, i64 noundef 8, i8* noundef nonnull align 8 [[TMP3]], void (i8*, i8*)* noundef nonnull @.omp.reduction.reduction_func, [8 x i32]* noundef nonnull @.gomp_critical_user_.reduction.var) 551; CHECK-NEXT: switch i32 [[TMP4]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [ 552; CHECK-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] 553; CHECK-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] 554; CHECK-NEXT: ] 555; CHECK: .omp.reduction.case1: 556; CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* [[A]], align 4 557; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[A1]], align 4 558; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]] 559; CHECK-NEXT: store i32 [[ADD]], i32* [[A]], align 4 560; CHECK-NEXT: call void @__kmpc_end_reduce_nowait(%struct.ident_t* noundef nonnull @[[GLOB2]], i32 [[TMP2]], [8 x i32]* noundef nonnull @.gomp_critical_user_.reduction.var) 561; CHECK-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]] 562; CHECK: .omp.reduction.case2: 563; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[A1]], align 4 564; CHECK-NEXT: [[TMP8:%.*]] = atomicrmw add i32* [[A]], i32 [[TMP7]] monotonic, align 4 565; CHECK-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]] 566; CHECK: .omp.reduction.default: 567; CHECK-NEXT: [[TMP9:%.*]] = bitcast i32* [[A1]] to i8* 568; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull [[TMP9]]) 569; CHECK-NEXT: ret void 570; 571; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..6 572; CHECK1-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) { 573; CHECK1-NEXT: entry: 574; CHECK1-NEXT: [[A1:%.*]] = alloca i32, align 4 575; CHECK1-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8 576; CHECK1-NEXT: [[TMP:%.*]] = bitcast i32* [[A1]] to i8* 577; CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull align 4 [[TMP]]) #[[ATTR0]] 578; CHECK1-NEXT: store i32 1, i32* [[A1]], align 4 579; CHECK1-NEXT: [[TMP1:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i32** 580; CHECK1-NEXT: store i32* [[A1]], i32** [[TMP1]], align 8 581; CHECK1-NEXT: [[TMP2:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 582; CHECK1-NEXT: [[TMP3:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8* 583; CHECK1-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* noundef nonnull @[[GLOB2:[0-9]+]], i32 [[TMP2]], i32 noundef 1, i64 noundef 8, i8* noundef nonnull align 8 [[TMP3]], void (i8*, i8*)* noundef nonnull @.omp.reduction.reduction_func, [8 x i32]* noundef nonnull @.gomp_critical_user_.reduction.var) 584; CHECK1-NEXT: switch i32 [[TMP4]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [ 585; CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] 586; CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] 587; CHECK1-NEXT: ] 588; CHECK1: .omp.reduction.case1: 589; CHECK1-NEXT: [[TMP5:%.*]] = load i32, i32* [[A]], align 4 590; CHECK1-NEXT: [[TMP6:%.*]] = load i32, i32* [[A1]], align 4 591; CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]] 592; CHECK1-NEXT: store i32 [[ADD]], i32* [[A]], align 4 593; CHECK1-NEXT: call void @__kmpc_end_reduce_nowait(%struct.ident_t* noundef nonnull @[[GLOB2]], i32 [[TMP2]], [8 x i32]* noundef nonnull @.gomp_critical_user_.reduction.var) 594; CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]] 595; CHECK1: .omp.reduction.case2: 596; CHECK1-NEXT: [[TMP7:%.*]] = load i32, i32* [[A1]], align 4 597; CHECK1-NEXT: [[TMP8:%.*]] = atomicrmw add i32* [[A]], i32 [[TMP7]] monotonic, align 4 598; CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]] 599; CHECK1: .omp.reduction.default: 600; CHECK1-NEXT: [[TMP9:%.*]] = bitcast i32* [[A1]] to i8* 601; CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull [[TMP9]]) 602; CHECK1-NEXT: ret void 603; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..6 604; CHECK2-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) { 605; CHECK2-NEXT: entry: 606; CHECK2-NEXT: [[A1:%.*]] = alloca i32, align 4 607; CHECK2-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8 608; CHECK2-NEXT: [[TMP:%.*]] = bitcast i32* [[A1]] to i8* 609; CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull align 4 [[TMP]]) #[[ATTR0]] 610; CHECK2-NEXT: store i32 1, i32* [[A1]], align 4 611; CHECK2-NEXT: [[TMP1:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i32** 612; CHECK2-NEXT: store i32* [[A1]], i32** [[TMP1]], align 8 613; CHECK2-NEXT: [[TMP2:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 614; CHECK2-NEXT: [[TMP3:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8* 615; CHECK2-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* noundef nonnull @[[GLOB2:[0-9]+]], i32 [[TMP2]], i32 noundef 1, i64 noundef 8, i8* noundef nonnull align 8 [[TMP3]], void (i8*, i8*)* noundef nonnull @.omp.reduction.reduction_func, [8 x i32]* noundef nonnull @.gomp_critical_user_.reduction.var) 616; CHECK2-NEXT: switch i32 [[TMP4]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [ 617; CHECK2-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] 618; CHECK2-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] 619; CHECK2-NEXT: ] 620; CHECK2: .omp.reduction.case1: 621; CHECK2-NEXT: [[TMP5:%.*]] = load i32, i32* [[A]], align 4 622; CHECK2-NEXT: [[TMP6:%.*]] = load i32, i32* [[A1]], align 4 623; CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]] 624; CHECK2-NEXT: store i32 [[ADD]], i32* [[A]], align 4 625; CHECK2-NEXT: call void @__kmpc_end_reduce_nowait(%struct.ident_t* noundef nonnull @[[GLOB2]], i32 [[TMP2]], [8 x i32]* noundef nonnull @.gomp_critical_user_.reduction.var) 626; CHECK2-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]] 627; CHECK2: .omp.reduction.case2: 628; CHECK2-NEXT: [[TMP7:%.*]] = load i32, i32* [[A1]], align 4 629; CHECK2-NEXT: [[TMP8:%.*]] = atomicrmw add i32* [[A]], i32 [[TMP7]] monotonic, align 4 630; CHECK2-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]] 631; CHECK2: .omp.reduction.default: 632; CHECK2-NEXT: [[TMP9:%.*]] = bitcast i32* [[A1]] to i8* 633; CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull [[TMP9]]) 634; CHECK2-NEXT: ret void 635entry: 636 %a1 = alloca i32, align 4 637 %.omp.reduction.red_list = alloca [1 x i8*], align 8 638 %tmp = bitcast i32* %a1 to i8* 639 call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %tmp) 640 store i32 1, i32* %a1, align 4 641 %tmp1 = bitcast [1 x i8*]* %.omp.reduction.red_list to i32** 642 store i32* %a1, i32** %tmp1, align 8 643 %tmp2 = load i32, i32* %.global_tid., align 4 644 %tmp3 = bitcast [1 x i8*]* %.omp.reduction.red_list to i8* 645 %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) 646 switch i32 %tmp4, label %.omp.reduction.default [ 647 i32 1, label %.omp.reduction.case1 648 i32 2, label %.omp.reduction.case2 649 ] 650 651.omp.reduction.case1: ; preds = %entry 652 %tmp5 = load i32, i32* %a, align 4 653 %tmp6 = load i32, i32* %a1, align 4 654 %add = add nsw i32 %tmp5, %tmp6 655 store i32 %add, i32* %a, align 4 656 call void @__kmpc_end_reduce_nowait(%struct.ident_t* nonnull @2, i32 %tmp2, [8 x i32]* nonnull @.gomp_critical_user_.reduction.var) 657 br label %.omp.reduction.default 658 659.omp.reduction.case2: ; preds = %entry 660 %tmp7 = load i32, i32* %a1, align 4 661 %tmp8 = atomicrmw add i32* %a, i32 %tmp7 monotonic 662 br label %.omp.reduction.default 663 664.omp.reduction.default: ; preds = %.omp.reduction.case2, %.omp.reduction.case1, %entry 665 %tmp9 = bitcast i32* %a1 to i8* 666 call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %tmp9) 667 ret void 668} 669 670define internal void @.omp.reduction.reduction_func(i8* %arg, i8* %arg1) { 671; CHECK-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func 672; CHECK-SAME: (i8* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG:%.*]], i8* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG1:%.*]]) #[[ATTR10:[0-9]+]] { 673; CHECK-NEXT: entry: 674; CHECK-NEXT: [[TMP:%.*]] = bitcast i8* [[ARG1]] to i32** 675; CHECK-NEXT: [[TMP2:%.*]] = load i32*, i32** [[TMP]], align 8 676; CHECK-NEXT: [[TMP3:%.*]] = bitcast i8* [[ARG]] to i32** 677; CHECK-NEXT: [[TMP4:%.*]] = load i32*, i32** [[TMP3]], align 8 678; CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP4]], align 4 679; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[TMP2]], align 4 680; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]] 681; CHECK-NEXT: store i32 [[ADD]], i32* [[TMP4]], align 4 682; CHECK-NEXT: ret void 683; 684; CHECK1-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func 685; CHECK1-SAME: (i8* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG:%.*]], i8* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG1:%.*]]) #[[ATTR10:[0-9]+]] { 686; CHECK1-NEXT: entry: 687; CHECK1-NEXT: [[TMP:%.*]] = bitcast i8* [[ARG1]] to i32** 688; CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[TMP]], align 8 689; CHECK1-NEXT: [[TMP3:%.*]] = bitcast i8* [[ARG]] to i32** 690; CHECK1-NEXT: [[TMP4:%.*]] = load i32*, i32** [[TMP3]], align 8 691; CHECK1-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP4]], align 4 692; CHECK1-NEXT: [[TMP6:%.*]] = load i32, i32* [[TMP2]], align 4 693; CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]] 694; CHECK1-NEXT: store i32 [[ADD]], i32* [[TMP4]], align 4 695; CHECK1-NEXT: ret void 696; CHECK2-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func 697; CHECK2-SAME: (i8* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG:%.*]], i8* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG1:%.*]]) #[[ATTR10:[0-9]+]] { 698; CHECK2-NEXT: entry: 699; CHECK2-NEXT: [[TMP:%.*]] = bitcast i8* [[ARG1]] to i32** 700; CHECK2-NEXT: [[TMP2:%.*]] = load i32*, i32** [[TMP]], align 8 701; CHECK2-NEXT: [[TMP3:%.*]] = bitcast i8* [[ARG]] to i32** 702; CHECK2-NEXT: [[TMP4:%.*]] = load i32*, i32** [[TMP3]], align 8 703; CHECK2-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP4]], align 4 704; CHECK2-NEXT: [[TMP6:%.*]] = load i32, i32* [[TMP2]], align 4 705; CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]] 706; CHECK2-NEXT: store i32 [[ADD]], i32* [[TMP4]], align 4 707; CHECK2-NEXT: ret void 708entry: 709 %tmp = bitcast i8* %arg1 to i32** 710 %tmp2 = load i32*, i32** %tmp, align 8 711 %tmp3 = bitcast i8* %arg to i32** 712 %tmp4 = load i32*, i32** %tmp3, align 8 713 %tmp5 = load i32, i32* %tmp4, align 4 714 %tmp6 = load i32, i32* %tmp2, align 4 715 %add = add nsw i32 %tmp5, %tmp6 716 store i32 %add, i32* %tmp4, align 4 717 ret void 718} 719 720declare i32 @__kmpc_single(%struct.ident_t*, i32) 721 722declare void @__kmpc_end_single(%struct.ident_t*, i32) 723 724declare void @__kmpc_barrier(%struct.ident_t*, i32) 725 726declare i32 @__kmpc_global_thread_num(%struct.ident_t*) nofree nosync nounwind readonly 727 728declare i32 @__kmpc_reduce_nowait(%struct.ident_t*, i32, i32, i64, i8*, void (i8*, i8*)*, [8 x i32]*) 729 730declare void @__kmpc_end_reduce_nowait(%struct.ident_t*, i32, [8 x i32]*) 731 732declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) 733 734declare !callback !2 void @__kmpc_fork_call(%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) 735 736declare void @unknown() 737 738declare void @readonly() readonly 739 740declare void @readnone() readnone 741 742!llvm.module.flags = !{!8} 743 744!0 = !{i32 1, !"wchar_size", i32 4} 745!1 = !{!"clang"} 746!2 = !{!3} 747!3 = !{i64 2, i64 -1, i64 -1, i1 true} 748!4 = !{!5, !5, i64 0} 749!5 = !{!"int", !6, i64 0} 750!6 = !{!"omnipotent char", !7, i64 0} 751!7 = !{!"Simple C/C++ TBAA"} 752!8 = !{i32 7, !"openmp", i32 50} 753