1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -loop-vectorize -force-vector-width=2 -S %s | FileCheck %s 3 4%s1 = type { [32000 x double], [32000 x double], [32000 x double] } 5 6define i32 @load_with_pointer_phi_no_runtime_checks(%s1* %data) { 7; CHECK-LABEL: @load_with_pointer_phi_no_runtime_checks( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] 10; CHECK: vector.ph: 11; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 12; CHECK: vector.body: 13; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 14; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] 15; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 16; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <2 x i64> [[VEC_IND]], <i64 15999, i64 15999> 17; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[S1:%.*]], %s1* [[DATA:%.*]], i64 0, i32 0, i64 [[TMP0]] 18; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[S1]], %s1* [[DATA]], i64 0, i32 2, <2 x i64> [[VEC_IND]] 19; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[S1]], %s1* [[DATA]], i64 0, i32 1, <2 x i64> [[VEC_IND]] 20; CHECK-NEXT: [[TMP5:%.*]] = xor <2 x i1> [[TMP1]], <i1 true, i1 true> 21; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP1]], <2 x double*> [[TMP4]], <2 x double*> [[TMP3]] 22; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x double*> [[PREDPHI]], i32 0 23; CHECK-NEXT: [[TMP7:%.*]] = load double, double* [[TMP6]], align 8 24; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x double*> [[PREDPHI]], i32 1 25; CHECK-NEXT: [[TMP9:%.*]] = load double, double* [[TMP8]], align 8 26; CHECK-NEXT: [[TMP10:%.*]] = insertelement <2 x double> poison, double [[TMP7]], i32 0 27; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x double> [[TMP10]], double [[TMP9]], i32 1 28; CHECK-NEXT: [[TMP12:%.*]] = fmul <2 x double> <double 3.000000e+00, double 3.000000e+00>, [[TMP11]] 29; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds double, double* [[TMP2]], i32 0 30; CHECK-NEXT: [[TMP14:%.*]] = bitcast double* [[TMP13]] to <2 x double>* 31; CHECK-NEXT: store <2 x double> [[TMP12]], <2 x double>* [[TMP14]], align 8 32; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 33; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], <i64 2, i64 2> 34; CHECK-NEXT: [[TMP15:%.*]] = icmp eq i64 [[INDEX_NEXT]], 32000 35; CHECK-NEXT: br i1 [[TMP15]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] 36; CHECK: middle.block: 37; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 32000, 32000 38; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]] 39; CHECK: scalar.ph: 40; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 32000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] 41; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 42; CHECK: loop.header: 43; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 44; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 45; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i64 [[IV]], 15999 46; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[S1]], %s1* [[DATA]], i64 0, i32 0, i64 [[IV]] 47; CHECK-NEXT: br i1 [[CMP5]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 48; CHECK: if.then: 49; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds [[S1]], %s1* [[DATA]], i64 0, i32 1, i64 [[IV]] 50; CHECK-NEXT: br label [[LOOP_LATCH]] 51; CHECK: if.else: 52; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds [[S1]], %s1* [[DATA]], i64 0, i32 2, i64 [[IV]] 53; CHECK-NEXT: br label [[LOOP_LATCH]] 54; CHECK: loop.latch: 55; CHECK-NEXT: [[GEP_2_SINK:%.*]] = phi double* [ [[GEP_2]], [[IF_ELSE]] ], [ [[GEP_1]], [[IF_THEN]] ] 56; CHECK-NEXT: [[V8:%.*]] = load double, double* [[GEP_2_SINK]], align 8 57; CHECK-NEXT: [[MUL16:%.*]] = fmul double 3.000000e+00, [[V8]] 58; CHECK-NEXT: store double [[MUL16]], double* [[ARRAYIDX]], align 8 59; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 32000 60; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT]], label [[LOOP_HEADER]], !llvm.loop [[LOOP2:![0-9]+]] 61; CHECK: exit: 62; CHECK-NEXT: ret i32 10 63; 64entry: 65 br label %loop.header 66 67loop.header: ; preds = %loop.latch, %entry 68 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 69 %iv.next = add nuw nsw i64 %iv, 1 70 %cmp5 = icmp ult i64 %iv, 15999 71 %arrayidx = getelementptr inbounds %s1, %s1 * %data, i64 0, i32 0, i64 %iv 72 br i1 %cmp5, label %if.then, label %if.else 73 74if.then: ; preds = %loop.header 75 %gep.1 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 1, i64 %iv 76 br label %loop.latch 77 78if.else: ; preds = %loop.header 79 %gep.2 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 2, i64 %iv 80 br label %loop.latch 81 82loop.latch: ; preds = %if.else, %if.then 83 %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ] 84 %v8 = load double, double* %gep.2.sink, align 8 85 %mul16 = fmul double 3.0, %v8 86 store double %mul16, double* %arrayidx, align 8 87 %exitcond.not = icmp eq i64 %iv.next, 32000 88 br i1 %exitcond.not, label %exit, label %loop.header 89 90exit: ; preds = %loop.latch 91 ret i32 10 92} 93 94define i32 @store_with_pointer_phi_no_runtime_checks(%s1* %data) { 95; CHECK-LABEL: @store_with_pointer_phi_no_runtime_checks( 96; CHECK-NEXT: entry: 97; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] 98; CHECK: vector.ph: 99; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 100; CHECK: vector.body: 101; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 102; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] 103; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 104; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <2 x i64> [[VEC_IND]], <i64 15999, i64 15999> 105; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[S1:%.*]], %s1* [[DATA:%.*]], i64 0, i32 0, i64 [[TMP0]] 106; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[S1]], %s1* [[DATA]], i64 0, i32 2, <2 x i64> [[VEC_IND]] 107; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[S1]], %s1* [[DATA]], i64 0, i32 1, <2 x i64> [[VEC_IND]] 108; CHECK-NEXT: [[TMP5:%.*]] = xor <2 x i1> [[TMP1]], <i1 true, i1 true> 109; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP1]], <2 x double*> [[TMP4]], <2 x double*> [[TMP3]] 110; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds double, double* [[TMP2]], i32 0 111; CHECK-NEXT: [[TMP7:%.*]] = bitcast double* [[TMP6]] to <2 x double>* 112; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x double>, <2 x double>* [[TMP7]], align 8 113; CHECK-NEXT: [[TMP8:%.*]] = fmul <2 x double> <double 3.000000e+00, double 3.000000e+00>, [[WIDE_LOAD]] 114; CHECK-NEXT: [[TMP9:%.*]] = extractelement <2 x double> [[TMP8]], i32 0 115; CHECK-NEXT: [[TMP10:%.*]] = extractelement <2 x double*> [[PREDPHI]], i32 0 116; CHECK-NEXT: store double [[TMP9]], double* [[TMP10]], align 8 117; CHECK-NEXT: [[TMP11:%.*]] = extractelement <2 x double> [[TMP8]], i32 1 118; CHECK-NEXT: [[TMP12:%.*]] = extractelement <2 x double*> [[PREDPHI]], i32 1 119; CHECK-NEXT: store double [[TMP11]], double* [[TMP12]], align 8 120; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 121; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], <i64 2, i64 2> 122; CHECK-NEXT: [[TMP13:%.*]] = icmp eq i64 [[INDEX_NEXT]], 32000 123; CHECK-NEXT: br i1 [[TMP13]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]] 124; CHECK: middle.block: 125; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 32000, 32000 126; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]] 127; CHECK: scalar.ph: 128; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 32000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] 129; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 130; CHECK: loop.header: 131; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 132; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 133; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i64 [[IV]], 15999 134; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[S1]], %s1* [[DATA]], i64 0, i32 0, i64 [[IV]] 135; CHECK-NEXT: br i1 [[CMP5]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 136; CHECK: if.then: 137; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds [[S1]], %s1* [[DATA]], i64 0, i32 1, i64 [[IV]] 138; CHECK-NEXT: br label [[LOOP_LATCH]] 139; CHECK: if.else: 140; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds [[S1]], %s1* [[DATA]], i64 0, i32 2, i64 [[IV]] 141; CHECK-NEXT: br label [[LOOP_LATCH]] 142; CHECK: loop.latch: 143; CHECK-NEXT: [[GEP_2_SINK:%.*]] = phi double* [ [[GEP_2]], [[IF_ELSE]] ], [ [[GEP_1]], [[IF_THEN]] ] 144; CHECK-NEXT: [[V8:%.*]] = load double, double* [[ARRAYIDX]], align 8 145; CHECK-NEXT: [[MUL16:%.*]] = fmul double 3.000000e+00, [[V8]] 146; CHECK-NEXT: store double [[MUL16]], double* [[GEP_2_SINK]], align 8 147; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 32000 148; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT]], label [[LOOP_HEADER]], !llvm.loop [[LOOP5:![0-9]+]] 149; CHECK: exit: 150; CHECK-NEXT: ret i32 10 151; 152entry: 153 br label %loop.header 154 155loop.header: ; preds = %loop.latch, %entry 156 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 157 %iv.next = add nuw nsw i64 %iv, 1 158 %cmp5 = icmp ult i64 %iv, 15999 159 %arrayidx = getelementptr inbounds %s1, %s1 * %data, i64 0, i32 0, i64 %iv 160 br i1 %cmp5, label %if.then, label %if.else 161 162if.then: ; preds = %loop.header 163 %gep.1 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 1, i64 %iv 164 br label %loop.latch 165 166if.else: ; preds = %loop.header 167 %gep.2 = getelementptr inbounds %s1, %s1* %data, i64 0, i32 2, i64 %iv 168 br label %loop.latch 169 170loop.latch: ; preds = %if.else, %if.then 171 %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ] 172 %v8 = load double, double* %arrayidx, align 8 173 %mul16 = fmul double 3.0, %v8 174 store double %mul16, double* %gep.2.sink, align 8 175 %exitcond.not = icmp eq i64 %iv.next, 32000 176 br i1 %exitcond.not, label %exit, label %loop.header 177 178exit: ; preds = %loop.latch 179 ret i32 10 180} 181 182define i32 @store_with_pointer_phi_runtime_checks(double* %A, double* %B, double* %C) { 183; CHECK-LABEL: @store_with_pointer_phi_runtime_checks( 184; CHECK-NEXT: entry: 185; CHECK-NEXT: [[B1:%.*]] = bitcast double* [[B:%.*]] to i8* 186; CHECK-NEXT: [[C3:%.*]] = bitcast double* [[C:%.*]] to i8* 187; CHECK-NEXT: [[A6:%.*]] = bitcast double* [[A:%.*]] to i8* 188; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]] 189; CHECK: vector.memcheck: 190; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr double, double* [[B]], i64 32000 191; CHECK-NEXT: [[SCEVGEP2:%.*]] = bitcast double* [[SCEVGEP]] to i8* 192; CHECK-NEXT: [[SCEVGEP4:%.*]] = getelementptr double, double* [[C]], i64 32000 193; CHECK-NEXT: [[SCEVGEP45:%.*]] = bitcast double* [[SCEVGEP4]] to i8* 194; CHECK-NEXT: [[SCEVGEP7:%.*]] = getelementptr double, double* [[A]], i64 32000 195; CHECK-NEXT: [[SCEVGEP78:%.*]] = bitcast double* [[SCEVGEP7]] to i8* 196; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult i8* [[B1]], [[SCEVGEP45]] 197; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* [[C3]], [[SCEVGEP2]] 198; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]] 199; CHECK-NEXT: [[BOUND09:%.*]] = icmp ult i8* [[B1]], [[SCEVGEP78]] 200; CHECK-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[A6]], [[SCEVGEP2]] 201; CHECK-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]] 202; CHECK-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]] 203; CHECK-NEXT: [[BOUND012:%.*]] = icmp ult i8* [[C3]], [[SCEVGEP78]] 204; CHECK-NEXT: [[BOUND113:%.*]] = icmp ult i8* [[A6]], [[SCEVGEP45]] 205; CHECK-NEXT: [[FOUND_CONFLICT14:%.*]] = and i1 [[BOUND012]], [[BOUND113]] 206; CHECK-NEXT: [[CONFLICT_RDX15:%.*]] = or i1 [[CONFLICT_RDX]], [[FOUND_CONFLICT14]] 207; CHECK-NEXT: br i1 [[CONFLICT_RDX15]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] 208; CHECK: vector.ph: 209; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 210; CHECK: vector.body: 211; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 212; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] 213; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 214; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <2 x i64> [[VEC_IND]], <i64 15999, i64 15999> 215; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds double, double* [[A]], i64 [[TMP0]] 216; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds double, double* [[C]], <2 x i64> [[VEC_IND]] 217; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds double, double* [[B]], <2 x i64> [[VEC_IND]] 218; CHECK-NEXT: [[TMP5:%.*]] = xor <2 x i1> [[TMP1]], <i1 true, i1 true> 219; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP1]], <2 x double*> [[TMP4]], <2 x double*> [[TMP3]] 220; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds double, double* [[TMP2]], i32 0 221; CHECK-NEXT: [[TMP7:%.*]] = bitcast double* [[TMP6]] to <2 x double>* 222; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x double>, <2 x double>* [[TMP7]], align 8, !alias.scope !6 223; CHECK-NEXT: [[TMP8:%.*]] = fmul <2 x double> <double 3.000000e+00, double 3.000000e+00>, [[WIDE_LOAD]] 224; CHECK-NEXT: [[TMP9:%.*]] = extractelement <2 x double> [[TMP8]], i32 0 225; CHECK-NEXT: [[TMP10:%.*]] = extractelement <2 x double*> [[PREDPHI]], i32 0 226; CHECK-NEXT: store double [[TMP9]], double* [[TMP10]], align 8 227; CHECK-NEXT: [[TMP11:%.*]] = extractelement <2 x double> [[TMP8]], i32 1 228; CHECK-NEXT: [[TMP12:%.*]] = extractelement <2 x double*> [[PREDPHI]], i32 1 229; CHECK-NEXT: store double [[TMP11]], double* [[TMP12]], align 8 230; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 231; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], <i64 2, i64 2> 232; CHECK-NEXT: [[TMP13:%.*]] = icmp eq i64 [[INDEX_NEXT]], 32000 233; CHECK-NEXT: br i1 [[TMP13]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP9:![0-9]+]] 234; CHECK: middle.block: 235; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 32000, 32000 236; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]] 237; CHECK: scalar.ph: 238; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 32000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ], [ 0, [[VECTOR_MEMCHECK]] ] 239; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 240; CHECK: loop.header: 241; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 242; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 243; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i64 [[IV]], 15999 244; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds double, double* [[A]], i64 [[IV]] 245; CHECK-NEXT: br i1 [[CMP5]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 246; CHECK: if.then: 247; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds double, double* [[B]], i64 [[IV]] 248; CHECK-NEXT: br label [[LOOP_LATCH]] 249; CHECK: if.else: 250; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds double, double* [[C]], i64 [[IV]] 251; CHECK-NEXT: br label [[LOOP_LATCH]] 252; CHECK: loop.latch: 253; CHECK-NEXT: [[GEP_2_SINK:%.*]] = phi double* [ [[GEP_2]], [[IF_ELSE]] ], [ [[GEP_1]], [[IF_THEN]] ] 254; CHECK-NEXT: [[V8:%.*]] = load double, double* [[ARRAYIDX]], align 8 255; CHECK-NEXT: [[MUL16:%.*]] = fmul double 3.000000e+00, [[V8]] 256; CHECK-NEXT: store double [[MUL16]], double* [[GEP_2_SINK]], align 8 257; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 32000 258; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT]], label [[LOOP_HEADER]], !llvm.loop [[LOOP10:![0-9]+]] 259; CHECK: exit: 260; CHECK-NEXT: ret i32 10 261; 262entry: 263 br label %loop.header 264 265loop.header: ; preds = %loop.latch, %entry 266 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] 267 %iv.next = add nuw nsw i64 %iv, 1 268 %cmp5 = icmp ult i64 %iv, 15999 269 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 270 br i1 %cmp5, label %if.then, label %if.else 271 272if.then: ; preds = %loop.header 273 %gep.1 = getelementptr inbounds double, double* %B, i64 %iv 274 br label %loop.latch 275 276if.else: ; preds = %loop.header 277 %gep.2 = getelementptr inbounds double, double* %C, i64 %iv 278 br label %loop.latch 279 280loop.latch: ; preds = %if.else, %if.then 281 %gep.2.sink = phi double* [ %gep.2, %if.else ], [ %gep.1, %if.then ] 282 %v8 = load double, double* %arrayidx, align 8 283 %mul16 = fmul double 3.0, %v8 284 store double %mul16, double* %gep.2.sink, align 8 285 %exitcond.not = icmp eq i64 %iv.next, 32000 286 br i1 %exitcond.not, label %exit, label %loop.header 287 288exit: ; preds = %loop.latch 289 ret i32 10 290} 291 292define i32 @load_with_pointer_phi_outside_loop(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) { 293; CHECK-LABEL: @load_with_pointer_phi_outside_loop( 294; CHECK-NEXT: entry: 295; CHECK-NEXT: br i1 [[C_0:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 296; CHECK: if.then: 297; CHECK-NEXT: br label [[LOOP_PH:%.*]] 298; CHECK: if.else: 299; CHECK-NEXT: [[PTR_SELECT:%.*]] = select i1 [[C_1:%.*]], double* [[C:%.*]], double* [[B:%.*]] 300; CHECK-NEXT: br label [[LOOP_PH]] 301; CHECK: loop.ph: 302; CHECK-NEXT: [[PTR:%.*]] = phi double* [ [[A:%.*]], [[IF_THEN]] ], [ [[PTR_SELECT]], [[IF_ELSE]] ] 303; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 304; CHECK: loop.header: 305; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[LOOP_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_HEADER]] ] 306; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 307; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds double, double* [[A]], i64 [[IV]] 308; CHECK-NEXT: [[V8:%.*]] = load double, double* [[PTR]], align 8 309; CHECK-NEXT: [[MUL16:%.*]] = fmul double 3.000000e+00, [[V8]] 310; CHECK-NEXT: store double [[MUL16]], double* [[ARRAYIDX]], align 8 311; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 32000 312; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP_HEADER]] 313; CHECK: exit: 314; CHECK-NEXT: ret i32 10 315; 316entry: 317 br i1 %c.0, label %if.then, label %if.else 318 319if.then: 320 br label %loop.ph 321 322if.else: 323 %ptr.select = select i1 %c.1, double* %C, double* %B 324 br label %loop.ph 325 326loop.ph: 327 %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ] 328 br label %loop.header 329 330loop.header: ; preds = %loop.latch, %entry 331 %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ] 332 %iv.next = add nuw nsw i64 %iv, 1 333 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 334 %v8 = load double, double* %ptr, align 8 335 %mul16 = fmul double 3.0, %v8 336 store double %mul16, double* %arrayidx, align 8 337 %exitcond.not = icmp eq i64 %iv.next, 32000 338 br i1 %exitcond.not, label %exit, label %loop.header 339 340exit: ; preds = %loop.latch 341 ret i32 10 342} 343 344define i32 @store_with_pointer_phi_outside_loop(double* %A, double* %B, double* %C, i1 %c.0, i1 %c.1) { 345; CHECK-LABEL: @store_with_pointer_phi_outside_loop( 346; CHECK-NEXT: entry: 347; CHECK-NEXT: br i1 [[C_0:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 348; CHECK: if.then: 349; CHECK-NEXT: br label [[LOOP_PH:%.*]] 350; CHECK: if.else: 351; CHECK-NEXT: [[PTR_SELECT:%.*]] = select i1 [[C_1:%.*]], double* [[C:%.*]], double* [[B:%.*]] 352; CHECK-NEXT: br label [[LOOP_PH]] 353; CHECK: loop.ph: 354; CHECK-NEXT: [[PTR:%.*]] = phi double* [ [[A:%.*]], [[IF_THEN]] ], [ [[PTR_SELECT]], [[IF_ELSE]] ] 355; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 356; CHECK: loop.header: 357; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[LOOP_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_HEADER]] ] 358; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 359; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds double, double* [[A]], i64 [[IV]] 360; CHECK-NEXT: [[V8:%.*]] = load double, double* [[ARRAYIDX]], align 8 361; CHECK-NEXT: [[MUL16:%.*]] = fmul double 3.000000e+00, [[V8]] 362; CHECK-NEXT: store double [[MUL16]], double* [[PTR]], align 8 363; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 32000 364; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[EXIT:%.*]], label [[LOOP_HEADER]] 365; CHECK: exit: 366; CHECK-NEXT: ret i32 10 367; 368entry: 369 br i1 %c.0, label %if.then, label %if.else 370 371if.then: 372 br label %loop.ph 373 374if.else: 375 %ptr.select = select i1 %c.1, double* %C, double* %B 376 br label %loop.ph 377 378loop.ph: 379 %ptr = phi double* [ %A, %if.then ], [ %ptr.select, %if.else ] 380 br label %loop.header 381 382loop.header: ; preds = %loop.latch, %entry 383 %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop.header ] 384 %iv.next = add nuw nsw i64 %iv, 1 385 %arrayidx = getelementptr inbounds double, double* %A, i64 %iv 386 %v8 = load double, double* %arrayidx, align 8 387 %mul16 = fmul double 3.0, %v8 388 store double %mul16, double* %ptr, align 8 389 %exitcond.not = icmp eq i64 %iv.next, 32000 390 br i1 %exitcond.not, label %exit, label %loop.header 391 392exit: ; preds = %loop.latch 393 ret i32 10 394} 395