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