1229 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 42; RUN: opt < %s -passes=loop-vectorize,dce,instcombine -force-vector-interleave=1 -force-vector-width=4 -prefer-inloop-reductions -S | FileCheck %s3 4define float @cond_fadd(ptr noalias nocapture readonly %a, ptr noalias nocapture readonly %cond, i64 %N){5; CHECK-LABEL: define float @cond_fadd(6; CHECK-SAME: ptr noalias readonly captures(none) [[A:%.*]], ptr noalias readonly captures(none) [[COND:%.*]], i64 [[N:%.*]]) {7; CHECK-NEXT: entry:8; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 49; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]10; CHECK: vector.ph:11; CHECK-NEXT: [[N_VEC:%.*]] = and i64 [[N]], -412; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]13; CHECK: vector.body:14; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ]15; CHECK-NEXT: [[VEC_PHI:%.*]] = phi float [ 1.000000e+00, [[VECTOR_PH]] ], [ [[TMP26:%.*]], [[PRED_LOAD_CONTINUE6]] ]16; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds float, ptr [[COND]], i64 [[INDEX]]17; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x float>, ptr [[TMP0]], align 418; CHECK-NEXT: [[TMP1:%.*]] = fcmp une <4 x float> [[WIDE_LOAD]], splat (float 5.000000e+00)19; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x i1> [[TMP1]], i64 020; CHECK-NEXT: br i1 [[TMP2]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]21; CHECK: pred.load.if:22; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[INDEX]]23; CHECK-NEXT: [[TMP4:%.*]] = load float, ptr [[TMP3]], align 424; CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x float> poison, float [[TMP4]], i64 025; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE]]26; CHECK: pred.load.continue:27; CHECK-NEXT: [[TMP6:%.*]] = phi <4 x float> [ poison, [[VECTOR_BODY]] ], [ [[TMP5]], [[PRED_LOAD_IF]] ]28; CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x i1> [[TMP1]], i64 129; CHECK-NEXT: br i1 [[TMP7]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]30; CHECK: pred.load.if1:31; CHECK-NEXT: [[TMP8:%.*]] = getelementptr float, ptr [[A]], i64 [[INDEX]]32; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP8]], i64 433; CHECK-NEXT: [[TMP10:%.*]] = load float, ptr [[TMP9]], align 434; CHECK-NEXT: [[TMP11:%.*]] = insertelement <4 x float> [[TMP6]], float [[TMP10]], i64 135; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE2]]36; CHECK: pred.load.continue2:37; CHECK-NEXT: [[TMP12:%.*]] = phi <4 x float> [ [[TMP6]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP11]], [[PRED_LOAD_IF1]] ]38; CHECK-NEXT: [[TMP13:%.*]] = extractelement <4 x i1> [[TMP1]], i64 239; CHECK-NEXT: br i1 [[TMP13]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]40; CHECK: pred.load.if3:41; CHECK-NEXT: [[TMP14:%.*]] = getelementptr float, ptr [[A]], i64 [[INDEX]]42; CHECK-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP14]], i64 843; CHECK-NEXT: [[TMP16:%.*]] = load float, ptr [[TMP15]], align 444; CHECK-NEXT: [[TMP17:%.*]] = insertelement <4 x float> [[TMP12]], float [[TMP16]], i64 245; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE4]]46; CHECK: pred.load.continue4:47; CHECK-NEXT: [[TMP18:%.*]] = phi <4 x float> [ [[TMP12]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP17]], [[PRED_LOAD_IF3]] ]48; CHECK-NEXT: [[TMP19:%.*]] = extractelement <4 x i1> [[TMP1]], i64 349; CHECK-NEXT: br i1 [[TMP19]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6]]50; CHECK: pred.load.if5:51; CHECK-NEXT: [[TMP20:%.*]] = getelementptr float, ptr [[A]], i64 [[INDEX]]52; CHECK-NEXT: [[TMP21:%.*]] = getelementptr i8, ptr [[TMP20]], i64 1253; CHECK-NEXT: [[TMP22:%.*]] = load float, ptr [[TMP21]], align 454; CHECK-NEXT: [[TMP23:%.*]] = insertelement <4 x float> [[TMP18]], float [[TMP22]], i64 355; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE6]]56; CHECK: pred.load.continue6:57; CHECK-NEXT: [[TMP24:%.*]] = phi <4 x float> [ [[TMP18]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ]58; CHECK-NEXT: [[TMP25:%.*]] = select fast <4 x i1> [[TMP1]], <4 x float> [[TMP24]], <4 x float> zeroinitializer59; CHECK-NEXT: [[TMP26]] = call fast float @llvm.vector.reduce.fadd.v4f32(float [[VEC_PHI]], <4 x float> [[TMP25]])60; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 461; CHECK-NEXT: [[TMP27:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]62; CHECK-NEXT: br i1 [[TMP27]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]63; CHECK: middle.block:64; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]65; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]66; CHECK: scalar.ph:67; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]68; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi float [ [[TMP26]], [[MIDDLE_BLOCK]] ], [ 1.000000e+00, [[ENTRY]] ]69; CHECK-NEXT: br label [[FOR_BODY:%.*]]70; CHECK: for.body:71; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ]72; CHECK-NEXT: [[RDX:%.*]] = phi float [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[RES:%.*]], [[FOR_INC]] ]73; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[COND]], i64 [[IV]]74; CHECK-NEXT: [[TMP28:%.*]] = load float, ptr [[ARRAYIDX]], align 475; CHECK-NEXT: [[TOBOOL:%.*]] = fcmp une float [[TMP28]], 5.000000e+0076; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_INC]]77; CHECK: if.then:78; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[IV]]79; CHECK-NEXT: [[TMP29:%.*]] = load float, ptr [[ARRAYIDX2]], align 480; CHECK-NEXT: [[FADD:%.*]] = fadd fast float [[RDX]], [[TMP29]]81; CHECK-NEXT: br label [[FOR_INC]]82; CHECK: for.inc:83; CHECK-NEXT: [[RES]] = phi float [ [[RDX]], [[FOR_BODY]] ], [ [[FADD]], [[IF_THEN]] ]84; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 185; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]86; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]87; CHECK: for.end:88; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi float [ [[RES]], [[FOR_INC]] ], [ [[TMP26]], [[MIDDLE_BLOCK]] ]89; CHECK-NEXT: ret float [[RES_LCSSA]]90;91entry:92 br label %for.body93 94for.body:95 %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]96 %rdx = phi float [ 1.000000e+00, %entry ], [ %res, %for.inc ]97 %arrayidx = getelementptr inbounds float, ptr %cond, i64 %iv98 %0 = load float, ptr %arrayidx99 %tobool = fcmp une float %0, 5.000000e+00100 br i1 %tobool, label %if.then, label %for.inc101 102if.then:103 %arrayidx2 = getelementptr inbounds float, ptr %a, i64 %iv104 %1 = load float, ptr %arrayidx2105 %fadd = fadd fast float %rdx, %1106 br label %for.inc107 108for.inc:109 %res = phi float [ %rdx, %for.body ], [ %fadd, %if.then ]110 %iv.next = add i64 %iv, 1111 %exitcond.not = icmp eq i64 %iv.next, %N112 br i1 %exitcond.not, label %for.end, label %for.body113 114for.end:115 ret float %res116}117 118define float @cond_cmp_sel(ptr noalias %a, ptr noalias %cond, i64 %N) {119; CHECK-LABEL: define float @cond_cmp_sel(120; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[COND:%.*]], i64 [[N:%.*]]) {121; CHECK-NEXT: entry:122; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4123; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]124; CHECK: vector.ph:125; CHECK-NEXT: [[N_VEC:%.*]] = and i64 [[N]], -4126; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]127; CHECK: vector.body:128; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ]129; CHECK-NEXT: [[VEC_PHI:%.*]] = phi float [ 1.000000e+00, [[VECTOR_PH]] ], [ [[RDX_MINMAX_SELECT:%.*]], [[PRED_LOAD_CONTINUE6]] ]130; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds float, ptr [[COND]], i64 [[INDEX]]131; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x float>, ptr [[TMP0]], align 4132; CHECK-NEXT: [[TMP1:%.*]] = fcmp une <4 x float> [[WIDE_LOAD]], splat (float 3.000000e+00)133; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x i1> [[TMP1]], i64 0134; CHECK-NEXT: br i1 [[TMP2]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]135; CHECK: pred.load.if:136; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[INDEX]]137; CHECK-NEXT: [[TMP4:%.*]] = load float, ptr [[TMP3]], align 4138; CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x float> poison, float [[TMP4]], i64 0139; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE]]140; CHECK: pred.load.continue:141; CHECK-NEXT: [[TMP6:%.*]] = phi <4 x float> [ poison, [[VECTOR_BODY]] ], [ [[TMP5]], [[PRED_LOAD_IF]] ]142; CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x i1> [[TMP1]], i64 1143; CHECK-NEXT: br i1 [[TMP7]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]144; CHECK: pred.load.if1:145; CHECK-NEXT: [[TMP8:%.*]] = getelementptr float, ptr [[A]], i64 [[INDEX]]146; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP8]], i64 4147; CHECK-NEXT: [[TMP10:%.*]] = load float, ptr [[TMP9]], align 4148; CHECK-NEXT: [[TMP11:%.*]] = insertelement <4 x float> [[TMP6]], float [[TMP10]], i64 1149; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE2]]150; CHECK: pred.load.continue2:151; CHECK-NEXT: [[TMP12:%.*]] = phi <4 x float> [ [[TMP6]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP11]], [[PRED_LOAD_IF1]] ]152; CHECK-NEXT: [[TMP13:%.*]] = extractelement <4 x i1> [[TMP1]], i64 2153; CHECK-NEXT: br i1 [[TMP13]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]154; CHECK: pred.load.if3:155; CHECK-NEXT: [[TMP14:%.*]] = getelementptr float, ptr [[A]], i64 [[INDEX]]156; CHECK-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP14]], i64 8157; CHECK-NEXT: [[TMP16:%.*]] = load float, ptr [[TMP15]], align 4158; CHECK-NEXT: [[TMP17:%.*]] = insertelement <4 x float> [[TMP12]], float [[TMP16]], i64 2159; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE4]]160; CHECK: pred.load.continue4:161; CHECK-NEXT: [[TMP18:%.*]] = phi <4 x float> [ [[TMP12]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP17]], [[PRED_LOAD_IF3]] ]162; CHECK-NEXT: [[TMP19:%.*]] = extractelement <4 x i1> [[TMP1]], i64 3163; CHECK-NEXT: br i1 [[TMP19]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6]]164; CHECK: pred.load.if5:165; CHECK-NEXT: [[TMP20:%.*]] = getelementptr float, ptr [[A]], i64 [[INDEX]]166; CHECK-NEXT: [[TMP21:%.*]] = getelementptr i8, ptr [[TMP20]], i64 12167; CHECK-NEXT: [[TMP22:%.*]] = load float, ptr [[TMP21]], align 4168; CHECK-NEXT: [[TMP23:%.*]] = insertelement <4 x float> [[TMP18]], float [[TMP22]], i64 3169; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE6]]170; CHECK: pred.load.continue6:171; CHECK-NEXT: [[TMP24:%.*]] = phi <4 x float> [ [[TMP18]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ]172; CHECK-NEXT: [[TMP25:%.*]] = select fast <4 x i1> [[TMP1]], <4 x float> [[TMP24]], <4 x float> splat (float 0x47EFFFFFE0000000)173; CHECK-NEXT: [[TMP26:%.*]] = call fast float @llvm.vector.reduce.fmin.v4f32(<4 x float> [[TMP25]])174; CHECK-NEXT: [[RDX_MINMAX_SELECT]] = call fast float @llvm.minnum.f32(float [[TMP26]], float [[VEC_PHI]])175; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4176; CHECK-NEXT: [[TMP27:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]177; CHECK-NEXT: br i1 [[TMP27]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]178; CHECK: middle.block:179; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]180; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]181; CHECK: scalar.ph:182; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]183; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi float [ [[RDX_MINMAX_SELECT]], [[MIDDLE_BLOCK]] ], [ 1.000000e+00, [[ENTRY]] ]184; CHECK-NEXT: br label [[FOR_BODY:%.*]]185; CHECK: for.body:186; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ]187; CHECK-NEXT: [[RDX:%.*]] = phi float [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[RES:%.*]], [[FOR_INC]] ]188; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[COND]], i64 [[IV]]189; CHECK-NEXT: [[TMP28:%.*]] = load float, ptr [[ARRAYIDX]], align 4190; CHECK-NEXT: [[TOBOOL:%.*]] = fcmp une float [[TMP28]], 3.000000e+00191; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_INC]]192; CHECK: if.then:193; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[IV]]194; CHECK-NEXT: [[TMP29:%.*]] = load float, ptr [[ARRAYIDX2]], align 4195; CHECK-NEXT: [[FSEL:%.*]] = call fast float @llvm.minnum.f32(float [[RDX]], float [[TMP29]])196; CHECK-NEXT: br label [[FOR_INC]]197; CHECK: for.inc:198; CHECK-NEXT: [[RES]] = phi float [ [[RDX]], [[FOR_BODY]] ], [ [[FSEL]], [[IF_THEN]] ]199; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1200; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]201; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]202; CHECK: for.end:203; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi float [ [[RES]], [[FOR_INC]] ], [ [[RDX_MINMAX_SELECT]], [[MIDDLE_BLOCK]] ]204; CHECK-NEXT: ret float [[RES_LCSSA]]205;206entry:207 br label %for.body208 209for.body:210 %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]211 %rdx = phi float [ 1.000000e+00, %entry ], [ %res, %for.inc ]212 %arrayidx = getelementptr inbounds float, ptr %cond, i64 %iv213 %0 = load float, ptr %arrayidx214 %tobool = fcmp une float %0, 3.000000e+00215 br i1 %tobool, label %if.then, label %for.inc216 217if.then:218 %arrayidx2 = getelementptr inbounds float, ptr %a, i64 %iv219 %1 = load float, ptr %arrayidx2220 %fcmp = fcmp fast olt float %rdx, %1221 %fsel = select fast i1 %fcmp, float %rdx, float %1222 br label %for.inc223 224for.inc:225 %res = phi float [ %rdx, %for.body ], [ %fsel, %if.then ]226 %iv.next = add i64 %iv, 1227 %exitcond.not = icmp eq i64 %iv.next, %N228 br i1 %exitcond.not, label %for.end, label %for.body229 230for.end:231 ret float %res232}233 234define i32 @conditional_and(ptr noalias %A, ptr noalias %B, i32 %cond, i64 noundef %N) #0 {235; CHECK-LABEL: define i32 @conditional_and(236; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i32 [[COND:%.*]], i64 noundef [[N:%.*]]) {237; CHECK-NEXT: entry:238; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4239; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]240; CHECK: vector.ph:241; CHECK-NEXT: [[N_VEC:%.*]] = and i64 [[N]], -4242; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i32> poison, i32 [[COND]], i64 0243; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i32> [[BROADCAST_SPLATINSERT]], <4 x i32> poison, <4 x i32> zeroinitializer244; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]245; CHECK: vector.body:246; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ]247; CHECK-NEXT: [[VEC_PHI:%.*]] = phi i32 [ 7, [[VECTOR_PH]] ], [ [[TMP27:%.*]], [[PRED_LOAD_CONTINUE6]] ]248; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDEX]]249; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4250; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[WIDE_LOAD]], [[BROADCAST_SPLAT]]251; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x i1> [[TMP1]], i64 0252; CHECK-NEXT: br i1 [[TMP2]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]253; CHECK: pred.load.if:254; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[INDEX]]255; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4256; CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x i32> poison, i32 [[TMP4]], i64 0257; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE]]258; CHECK: pred.load.continue:259; CHECK-NEXT: [[TMP6:%.*]] = phi <4 x i32> [ poison, [[VECTOR_BODY]] ], [ [[TMP5]], [[PRED_LOAD_IF]] ]260; CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x i1> [[TMP1]], i64 1261; CHECK-NEXT: br i1 [[TMP7]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]262; CHECK: pred.load.if1:263; CHECK-NEXT: [[TMP8:%.*]] = getelementptr i32, ptr [[B]], i64 [[INDEX]]264; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP8]], i64 4265; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 4266; CHECK-NEXT: [[TMP11:%.*]] = insertelement <4 x i32> [[TMP6]], i32 [[TMP10]], i64 1267; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE2]]268; CHECK: pred.load.continue2:269; CHECK-NEXT: [[TMP12:%.*]] = phi <4 x i32> [ [[TMP6]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP11]], [[PRED_LOAD_IF1]] ]270; CHECK-NEXT: [[TMP13:%.*]] = extractelement <4 x i1> [[TMP1]], i64 2271; CHECK-NEXT: br i1 [[TMP13]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]272; CHECK: pred.load.if3:273; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i32, ptr [[B]], i64 [[INDEX]]274; CHECK-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP14]], i64 8275; CHECK-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4276; CHECK-NEXT: [[TMP17:%.*]] = insertelement <4 x i32> [[TMP12]], i32 [[TMP16]], i64 2277; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE4]]278; CHECK: pred.load.continue4:279; CHECK-NEXT: [[TMP18:%.*]] = phi <4 x i32> [ [[TMP12]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP17]], [[PRED_LOAD_IF3]] ]280; CHECK-NEXT: [[TMP19:%.*]] = extractelement <4 x i1> [[TMP1]], i64 3281; CHECK-NEXT: br i1 [[TMP19]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6]]282; CHECK: pred.load.if5:283; CHECK-NEXT: [[TMP20:%.*]] = getelementptr i32, ptr [[B]], i64 [[INDEX]]284; CHECK-NEXT: [[TMP21:%.*]] = getelementptr i8, ptr [[TMP20]], i64 12285; CHECK-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4286; CHECK-NEXT: [[TMP23:%.*]] = insertelement <4 x i32> [[TMP18]], i32 [[TMP22]], i64 3287; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE6]]288; CHECK: pred.load.continue6:289; CHECK-NEXT: [[TMP24:%.*]] = phi <4 x i32> [ [[TMP18]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ]290; CHECK-NEXT: [[TMP25:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[TMP24]], <4 x i32> splat (i32 -1)291; CHECK-NEXT: [[TMP26:%.*]] = call i32 @llvm.vector.reduce.and.v4i32(<4 x i32> [[TMP25]])292; CHECK-NEXT: [[TMP27]] = and i32 [[VEC_PHI]], [[TMP26]]293; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4294; CHECK-NEXT: [[TMP28:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]295; CHECK-NEXT: br i1 [[TMP28]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]296; CHECK: middle.block:297; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]298; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]299; CHECK: scalar.ph:300; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]301; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP27]], [[MIDDLE_BLOCK]] ], [ 7, [[ENTRY]] ]302; CHECK-NEXT: br label [[FOR_BODY:%.*]]303; CHECK: for.body:304; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ]305; CHECK-NEXT: [[RDX:%.*]] = phi i32 [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[RES:%.*]], [[FOR_INC]] ]306; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IV]]307; CHECK-NEXT: [[TMP29:%.*]] = load i32, ptr [[ARRAYIDX]], align 4308; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP29]], [[COND]]309; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_INC]]310; CHECK: if.then:311; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]312; CHECK-NEXT: [[TMP30:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4313; CHECK-NEXT: [[AND:%.*]] = and i32 [[TMP30]], [[RDX]]314; CHECK-NEXT: br label [[FOR_INC]]315; CHECK: for.inc:316; CHECK-NEXT: [[RES]] = phi i32 [ [[AND]], [[IF_THEN]] ], [ [[RDX]], [[FOR_BODY]] ]317; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1318; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]319; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP7:![0-9]+]]320; CHECK: for.end:321; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_INC]] ], [ [[TMP27]], [[MIDDLE_BLOCK]] ]322; CHECK-NEXT: ret i32 [[RES_LCSSA]]323;324entry:325 br label %for.body326 327for.body:328 %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]329 %rdx = phi i32 [ 7, %entry ], [ %res, %for.inc ]330 %arrayidx = getelementptr inbounds i32, ptr %A, i64 %iv331 %0 = load i32, ptr %arrayidx332 %tobool = icmp eq i32 %0, %cond333 br i1 %tobool, label %if.then, label %for.inc334 335if.then:336 %arrayidx2 = getelementptr inbounds i32, ptr %B, i64 %iv337 %1 = load i32, ptr %arrayidx2338 %and = and i32 %1, %rdx339 br label %for.inc340 341for.inc:342 %res = phi i32 [ %and, %if.then ], [ %rdx, %for.body ]343 %iv.next = add nuw nsw i64 %iv, 1344 %exitcond.not = icmp eq i64 %iv.next, %N345 br i1 %exitcond.not, label %for.end, label %for.body346 347for.end:348 ret i32 %res349}350 351define i32 @simple_chained_rdx(ptr noalias %a, ptr noalias %b, ptr noalias %cond, i64 noundef %N) {352; CHECK-LABEL: define i32 @simple_chained_rdx(353; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[COND:%.*]], i64 noundef [[N:%.*]]) {354; CHECK-NEXT: entry:355; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4356; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]357; CHECK: vector.ph:358; CHECK-NEXT: [[N_VEC:%.*]] = and i64 [[N]], -4359; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]360; CHECK: vector.body:361; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ]362; CHECK-NEXT: [[VEC_PHI:%.*]] = phi i32 [ 5, [[VECTOR_PH]] ], [ [[TMP46:%.*]], [[PRED_LOAD_CONTINUE6]] ]363; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[INDEX]]364; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4365; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[WIDE_LOAD]], zeroinitializer366; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x i1> [[TMP1]], i64 0367; CHECK-NEXT: br i1 [[TMP2]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]368; CHECK: pred.load.if:369; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDEX]]370; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4371; CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x i32> poison, i32 [[TMP4]], i64 0372; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[INDEX]]373; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[TMP6]], align 4374; CHECK-NEXT: [[TMP8:%.*]] = insertelement <4 x i32> poison, i32 [[TMP7]], i64 0375; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE]]376; CHECK: pred.load.continue:377; CHECK-NEXT: [[TMP9:%.*]] = phi <4 x i32> [ poison, [[VECTOR_BODY]] ], [ [[TMP5]], [[PRED_LOAD_IF]] ]378; CHECK-NEXT: [[TMP10:%.*]] = phi <4 x i32> [ poison, [[VECTOR_BODY]] ], [ [[TMP8]], [[PRED_LOAD_IF]] ]379; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i1> [[TMP1]], i64 1380; CHECK-NEXT: br i1 [[TMP11]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]381; CHECK: pred.load.if1:382; CHECK-NEXT: [[TMP12:%.*]] = or disjoint i64 [[INDEX]], 1383; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[TMP12]]384; CHECK-NEXT: [[TMP14:%.*]] = load i32, ptr [[TMP13]], align 4385; CHECK-NEXT: [[TMP15:%.*]] = insertelement <4 x i32> [[TMP9]], i32 [[TMP14]], i64 1386; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP12]]387; CHECK-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 4388; CHECK-NEXT: [[TMP18:%.*]] = insertelement <4 x i32> [[TMP10]], i32 [[TMP17]], i64 1389; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE2]]390; CHECK: pred.load.continue2:391; CHECK-NEXT: [[TMP19:%.*]] = phi <4 x i32> [ [[TMP9]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP15]], [[PRED_LOAD_IF1]] ]392; CHECK-NEXT: [[TMP20:%.*]] = phi <4 x i32> [ [[TMP10]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP18]], [[PRED_LOAD_IF1]] ]393; CHECK-NEXT: [[TMP21:%.*]] = extractelement <4 x i1> [[TMP1]], i64 2394; CHECK-NEXT: br i1 [[TMP21]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]395; CHECK: pred.load.if3:396; CHECK-NEXT: [[TMP22:%.*]] = or disjoint i64 [[INDEX]], 2397; CHECK-NEXT: [[TMP23:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[TMP22]]398; CHECK-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4399; CHECK-NEXT: [[TMP25:%.*]] = insertelement <4 x i32> [[TMP19]], i32 [[TMP24]], i64 2400; CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP22]]401; CHECK-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4402; CHECK-NEXT: [[TMP28:%.*]] = insertelement <4 x i32> [[TMP20]], i32 [[TMP27]], i64 2403; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE4]]404; CHECK: pred.load.continue4:405; CHECK-NEXT: [[TMP29:%.*]] = phi <4 x i32> [ [[TMP19]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP25]], [[PRED_LOAD_IF3]] ]406; CHECK-NEXT: [[TMP30:%.*]] = phi <4 x i32> [ [[TMP20]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP28]], [[PRED_LOAD_IF3]] ]407; CHECK-NEXT: [[TMP31:%.*]] = extractelement <4 x i1> [[TMP1]], i64 3408; CHECK-NEXT: br i1 [[TMP31]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6]]409; CHECK: pred.load.if5:410; CHECK-NEXT: [[TMP32:%.*]] = or disjoint i64 [[INDEX]], 3411; CHECK-NEXT: [[TMP33:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[TMP32]]412; CHECK-NEXT: [[TMP34:%.*]] = load i32, ptr [[TMP33]], align 4413; CHECK-NEXT: [[TMP35:%.*]] = insertelement <4 x i32> [[TMP29]], i32 [[TMP34]], i64 3414; CHECK-NEXT: [[TMP36:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP32]]415; CHECK-NEXT: [[TMP37:%.*]] = load i32, ptr [[TMP36]], align 4416; CHECK-NEXT: [[TMP38:%.*]] = insertelement <4 x i32> [[TMP30]], i32 [[TMP37]], i64 3417; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE6]]418; CHECK: pred.load.continue6:419; CHECK-NEXT: [[TMP39:%.*]] = phi <4 x i32> [ [[TMP29]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP35]], [[PRED_LOAD_IF5]] ]420; CHECK-NEXT: [[TMP40:%.*]] = phi <4 x i32> [ [[TMP30]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP38]], [[PRED_LOAD_IF5]] ]421; CHECK-NEXT: [[TMP41:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[TMP39]], <4 x i32> zeroinitializer422; CHECK-NEXT: [[TMP42:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP41]])423; CHECK-NEXT: [[TMP43:%.*]] = add i32 [[VEC_PHI]], [[TMP42]]424; CHECK-NEXT: [[TMP44:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[TMP40]], <4 x i32> zeroinitializer425; CHECK-NEXT: [[TMP45:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP44]])426; CHECK-NEXT: [[TMP46]] = add i32 [[TMP43]], [[TMP45]]427; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4428; CHECK-NEXT: [[TMP47:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]429; CHECK-NEXT: br i1 [[TMP47]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]430; CHECK: middle.block:431; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]432; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]433; CHECK: scalar.ph:434; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]435; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP46]], [[MIDDLE_BLOCK]] ], [ 5, [[ENTRY]] ]436; CHECK-NEXT: br label [[FOR_BODY:%.*]]437; CHECK: for.body:438; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]439; CHECK-NEXT: [[RDX:%.*]] = phi i32 [ [[RES:%.*]], [[FOR_INC]] ], [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ]440; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[IV]]441; CHECK-NEXT: [[TMP48:%.*]] = load i32, ptr [[ARRAYIDX]], align 4442; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP48]], 0443; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[FOR_INC]], label [[IF_THEN:%.*]]444; CHECK: if.then:445; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IV]]446; CHECK-NEXT: [[TMP49:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4447; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP49]], [[RDX]]448; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]449; CHECK-NEXT: [[TMP50:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4450; CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[ADD]], [[TMP50]]451; CHECK-NEXT: br label [[FOR_INC]]452; CHECK: for.inc:453; CHECK-NEXT: [[RES]] = phi i32 [ [[ADD3]], [[IF_THEN]] ], [ [[RDX]], [[FOR_BODY]] ]454; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1455; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]456; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP9:![0-9]+]]457; CHECK: for.end:458; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_INC]] ], [ [[TMP46]], [[MIDDLE_BLOCK]] ]459; CHECK-NEXT: ret i32 [[RES_LCSSA]]460;461entry:462 br label %for.body463 464for.body:465 %iv = phi i64 [ %iv.next, %for.inc ], [ 0, %entry ]466 %rdx = phi i32 [ %res, %for.inc ], [ 5, %entry ]467 %arrayidx = getelementptr inbounds i32, ptr %cond, i64 %iv468 %0 = load i32, ptr %arrayidx469 %tobool.not = icmp eq i32 %0, 0470 br i1 %tobool.not, label %for.inc, label %if.then471 472if.then:473 %arrayidx1 = getelementptr inbounds i32, ptr %a, i64 %iv474 %1 = load i32, ptr %arrayidx1475 %add = add nsw i32 %1, %rdx476 %arrayidx2 = getelementptr inbounds i32, ptr %b, i64 %iv477 %2 = load i32, ptr %arrayidx2478 %add3 = add nsw i32 %add, %2479 br label %for.inc480 481for.inc:482 %res = phi i32 [ %add3, %if.then ], [ %rdx, %for.body ]483 %iv.next = add nuw nsw i64 %iv, 1484 %exitcond.not = icmp eq i64 %iv.next, %N485 br i1 %exitcond.not, label %for.end, label %for.body486 487for.end:488 ret i32 %res489}490 491;492; Negative Tests493;494 495;496; Reduction not performed in loop as the phi has more than two incoming values497;498define i64 @nested_cond_and(ptr noalias nocapture readonly %a, ptr noalias nocapture readonly %b, ptr noalias nocapture readonly %cond, i64 %N){499; CHECK-LABEL: define i64 @nested_cond_and(500; CHECK-SAME: ptr noalias readonly captures(none) [[A:%.*]], ptr noalias readonly captures(none) [[B:%.*]], ptr noalias readonly captures(none) [[COND:%.*]], i64 [[N:%.*]]) {501; CHECK-NEXT: entry:502; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4503; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]504; CHECK: vector.ph:505; CHECK-NEXT: [[N_VEC:%.*]] = and i64 [[N]], -4506; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]507; CHECK: vector.body:508; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE14:%.*]] ]509; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <4 x i64> [ <i64 5, i64 -1, i64 -1, i64 -1>, [[VECTOR_PH]] ], [ [[PREDPHI15:%.*]], [[PRED_LOAD_CONTINUE14]] ]510; CHECK-NEXT: [[TMP0:%.*]] = or disjoint i64 [[INDEX]], 1511; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i64 [[INDEX]], 2512; CHECK-NEXT: [[TMP2:%.*]] = or disjoint i64 [[INDEX]], 3513; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[COND]], i64 [[INDEX]]514; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP3]], align 4515; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <4 x i64> [[WIDE_LOAD]], zeroinitializer516; CHECK-NEXT: [[TMP5:%.*]] = extractelement <4 x i1> [[TMP4]], i64 0517; CHECK-NEXT: br i1 [[TMP5]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]518; CHECK: pred.load.if:519; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[INDEX]]520; CHECK-NEXT: [[TMP7:%.*]] = load i64, ptr [[TMP6]], align 4521; CHECK-NEXT: [[TMP8:%.*]] = insertelement <4 x i64> poison, i64 [[TMP7]], i64 0522; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE]]523; CHECK: pred.load.continue:524; CHECK-NEXT: [[TMP9:%.*]] = phi <4 x i64> [ poison, [[VECTOR_BODY]] ], [ [[TMP8]], [[PRED_LOAD_IF]] ]525; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i1> [[TMP4]], i64 1526; CHECK-NEXT: br i1 [[TMP10]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]527; CHECK: pred.load.if1:528; CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP0]]529; CHECK-NEXT: [[TMP12:%.*]] = load i64, ptr [[TMP11]], align 4530; CHECK-NEXT: [[TMP13:%.*]] = insertelement <4 x i64> [[TMP9]], i64 [[TMP12]], i64 1531; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE2]]532; CHECK: pred.load.continue2:533; CHECK-NEXT: [[TMP14:%.*]] = phi <4 x i64> [ [[TMP9]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP13]], [[PRED_LOAD_IF1]] ]534; CHECK-NEXT: [[TMP15:%.*]] = extractelement <4 x i1> [[TMP4]], i64 2535; CHECK-NEXT: br i1 [[TMP15]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]536; CHECK: pred.load.if3:537; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP1]]538; CHECK-NEXT: [[TMP17:%.*]] = load i64, ptr [[TMP16]], align 4539; CHECK-NEXT: [[TMP18:%.*]] = insertelement <4 x i64> [[TMP14]], i64 [[TMP17]], i64 2540; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE4]]541; CHECK: pred.load.continue4:542; CHECK-NEXT: [[TMP19:%.*]] = phi <4 x i64> [ [[TMP14]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP18]], [[PRED_LOAD_IF3]] ]543; CHECK-NEXT: [[TMP20:%.*]] = extractelement <4 x i1> [[TMP4]], i64 3544; CHECK-NEXT: br i1 [[TMP20]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6:%.*]]545; CHECK: pred.load.if5:546; CHECK-NEXT: [[TMP21:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP2]]547; CHECK-NEXT: [[TMP22:%.*]] = load i64, ptr [[TMP21]], align 4548; CHECK-NEXT: [[TMP23:%.*]] = insertelement <4 x i64> [[TMP19]], i64 [[TMP22]], i64 3549; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE6]]550; CHECK: pred.load.continue6:551; CHECK-NEXT: [[TMP24:%.*]] = phi <4 x i64> [ [[TMP19]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ]552; CHECK-NEXT: [[TMP25:%.*]] = icmp eq <4 x i64> [[TMP24]], splat (i64 3)553; CHECK-NEXT: [[TMP26:%.*]] = select <4 x i1> [[TMP4]], <4 x i1> [[TMP25]], <4 x i1> zeroinitializer554; CHECK-NEXT: [[TMP27:%.*]] = extractelement <4 x i1> [[TMP26]], i64 0555; CHECK-NEXT: br i1 [[TMP27]], label [[PRED_LOAD_IF7:%.*]], label [[PRED_LOAD_CONTINUE8:%.*]]556; CHECK: pred.load.if7:557; CHECK-NEXT: [[TMP28:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[INDEX]]558; CHECK-NEXT: [[TMP29:%.*]] = load i64, ptr [[TMP28]], align 4559; CHECK-NEXT: [[TMP30:%.*]] = insertelement <4 x i64> poison, i64 [[TMP29]], i64 0560; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE8]]561; CHECK: pred.load.continue8:562; CHECK-NEXT: [[TMP31:%.*]] = phi <4 x i64> [ poison, [[PRED_LOAD_CONTINUE6]] ], [ [[TMP30]], [[PRED_LOAD_IF7]] ]563; CHECK-NEXT: [[TMP32:%.*]] = extractelement <4 x i1> [[TMP26]], i64 1564; CHECK-NEXT: br i1 [[TMP32]], label [[PRED_LOAD_IF9:%.*]], label [[PRED_LOAD_CONTINUE10:%.*]]565; CHECK: pred.load.if9:566; CHECK-NEXT: [[TMP33:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP0]]567; CHECK-NEXT: [[TMP34:%.*]] = load i64, ptr [[TMP33]], align 4568; CHECK-NEXT: [[TMP35:%.*]] = insertelement <4 x i64> [[TMP31]], i64 [[TMP34]], i64 1569; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE10]]570; CHECK: pred.load.continue10:571; CHECK-NEXT: [[TMP36:%.*]] = phi <4 x i64> [ [[TMP31]], [[PRED_LOAD_CONTINUE8]] ], [ [[TMP35]], [[PRED_LOAD_IF9]] ]572; CHECK-NEXT: [[TMP37:%.*]] = extractelement <4 x i1> [[TMP26]], i64 2573; CHECK-NEXT: br i1 [[TMP37]], label [[PRED_LOAD_IF11:%.*]], label [[PRED_LOAD_CONTINUE12:%.*]]574; CHECK: pred.load.if11:575; CHECK-NEXT: [[TMP38:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP1]]576; CHECK-NEXT: [[TMP39:%.*]] = load i64, ptr [[TMP38]], align 4577; CHECK-NEXT: [[TMP40:%.*]] = insertelement <4 x i64> [[TMP36]], i64 [[TMP39]], i64 2578; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE12]]579; CHECK: pred.load.continue12:580; CHECK-NEXT: [[TMP41:%.*]] = phi <4 x i64> [ [[TMP36]], [[PRED_LOAD_CONTINUE10]] ], [ [[TMP40]], [[PRED_LOAD_IF11]] ]581; CHECK-NEXT: [[TMP42:%.*]] = extractelement <4 x i1> [[TMP26]], i64 3582; CHECK-NEXT: br i1 [[TMP42]], label [[PRED_LOAD_IF13:%.*]], label [[PRED_LOAD_CONTINUE14]]583; CHECK: pred.load.if13:584; CHECK-NEXT: [[TMP43:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP2]]585; CHECK-NEXT: [[TMP44:%.*]] = load i64, ptr [[TMP43]], align 4586; CHECK-NEXT: [[TMP45:%.*]] = insertelement <4 x i64> [[TMP41]], i64 [[TMP44]], i64 3587; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE14]]588; CHECK: pred.load.continue14:589; CHECK-NEXT: [[TMP46:%.*]] = phi <4 x i64> [ [[TMP41]], [[PRED_LOAD_CONTINUE12]] ], [ [[TMP45]], [[PRED_LOAD_IF13]] ]590; CHECK-NEXT: [[PREDPHI_V:%.*]] = select <4 x i1> [[TMP26]], <4 x i64> [[TMP46]], <4 x i64> [[TMP24]]591; CHECK-NEXT: [[PREDPHI:%.*]] = select <4 x i1> [[TMP4]], <4 x i64> [[PREDPHI_V]], <4 x i64> splat (i64 -1)592; CHECK-NEXT: [[PREDPHI15]] = and <4 x i64> [[VEC_PHI]], [[PREDPHI]]593; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4594; CHECK-NEXT: [[TMP49:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]595; CHECK-NEXT: br i1 [[TMP49]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]596; CHECK: middle.block:597; CHECK-NEXT: [[TMP50:%.*]] = call i64 @llvm.vector.reduce.and.v4i64(<4 x i64> [[PREDPHI15]])598; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]599; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]600; CHECK: scalar.ph:601; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]602; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi i64 [ [[TMP50]], [[MIDDLE_BLOCK]] ], [ 5, [[ENTRY]] ]603; CHECK-NEXT: br label [[FOR_BODY:%.*]]604; CHECK: for.body:605; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_INC:%.*]] ]606; CHECK-NEXT: [[RDX:%.*]] = phi i64 [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[RES:%.*]], [[FOR_INC]] ]607; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[COND]], i64 [[IV]]608; CHECK-NEXT: [[TMP51:%.*]] = load i64, ptr [[ARRAYIDX]], align 4609; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[TMP51]], 0610; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[FOR_INC]]611; CHECK: if.then:612; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]613; CHECK-NEXT: [[TMP52:%.*]] = load i64, ptr [[ARRAYIDX2]], align 4614; CHECK-NEXT: [[AND1:%.*]] = and i64 [[RDX]], [[TMP52]]615; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp eq i64 [[TMP52]], 3616; CHECK-NEXT: br i1 [[TOBOOL2]], label [[IF_THEN_2:%.*]], label [[FOR_INC]]617; CHECK: if.then.2:618; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]619; CHECK-NEXT: [[TMP53:%.*]] = load i64, ptr [[ARRAYIDX3]], align 4620; CHECK-NEXT: [[AND2:%.*]] = and i64 [[RDX]], [[TMP53]]621; CHECK-NEXT: br label [[FOR_INC]]622; CHECK: for.inc:623; CHECK-NEXT: [[RES]] = phi i64 [ [[AND2]], [[IF_THEN_2]] ], [ [[AND1]], [[IF_THEN]] ], [ [[RDX]], [[FOR_BODY]] ]624; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1625; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]626; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP11:![0-9]+]]627; CHECK: for.end:628; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i64 [ [[RES]], [[FOR_INC]] ], [ [[TMP50]], [[MIDDLE_BLOCK]] ]629; CHECK-NEXT: ret i64 [[RES_LCSSA]]630;631entry:632 br label %for.body633 634for.body:635 %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]636 %rdx = phi i64 [ 5, %entry ], [ %res, %for.inc ]637 %arrayidx = getelementptr inbounds i64, ptr %cond, i64 %iv638 %0 = load i64, ptr %arrayidx639 %tobool = icmp eq i64 %0, 0640 br i1 %tobool, label %if.then, label %for.inc641 642if.then:643 %arrayidx2 = getelementptr inbounds i64, ptr %a, i64 %iv644 %1 = load i64, ptr %arrayidx2645 %and1 = and i64 %rdx, %1646 %tobool2 = icmp eq i64 %1, 3647 br i1 %tobool2, label %if.then.2, label %for.inc648 649if.then.2:650 %arrayidx3 = getelementptr inbounds i64, ptr %b, i64 %iv651 %2 = load i64, ptr %arrayidx3652 %and2 = and i64 %rdx, %2653 br label %for.inc654 655for.inc:656 %res = phi i64 [ %and2, %if.then.2 ], [ %and1, %if.then ], [ %rdx, %for.body ]657 %iv.next = add nuw nsw i64 %iv, 1658 %exitcond.not = icmp eq i64 %iv.next, %N659 br i1 %exitcond.not, label %for.end, label %for.body660 661for.end:662 ret i64 %res663}664 665; Chain of conditional & unconditional reductions. We currently only support conditional reductions666; if they are the last in the chain, i.e. the loop exit instruction is a Phi node. Therefore we reject667; the Phi (%rdx1) as it has more than one use.668;669define i32 @cond-uncond(ptr noalias %src1, ptr noalias %src2, ptr noalias %cond, i64 noundef %n) #0 {670; CHECK-LABEL: define i32 @cond-uncond(671; CHECK-SAME: ptr noalias [[SRC1:%.*]], ptr noalias [[SRC2:%.*]], ptr noalias [[COND:%.*]], i64 noundef [[N:%.*]]) {672; CHECK-NEXT: entry:673; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4674; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]675; CHECK: vector.ph:676; CHECK-NEXT: [[N_VEC:%.*]] = and i64 [[N]], -4677; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]678; CHECK: vector.body:679; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ]680; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP27:%.*]], [[PRED_LOAD_CONTINUE6]] ]681; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[INDEX]]682; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4683; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[WIDE_LOAD]], zeroinitializer684; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x i1> [[TMP1]], i64 0685; CHECK-NEXT: br i1 [[TMP2]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]686; CHECK: pred.load.if:687; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[INDEX]]688; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4689; CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x i32> poison, i32 [[TMP4]], i64 0690; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE]]691; CHECK: pred.load.continue:692; CHECK-NEXT: [[TMP6:%.*]] = phi <4 x i32> [ poison, [[VECTOR_BODY]] ], [ [[TMP5]], [[PRED_LOAD_IF]] ]693; CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x i1> [[TMP1]], i64 1694; CHECK-NEXT: br i1 [[TMP7]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]695; CHECK: pred.load.if1:696; CHECK-NEXT: [[TMP8:%.*]] = getelementptr i32, ptr [[SRC2]], i64 [[INDEX]]697; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP8]], i64 4698; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 4699; CHECK-NEXT: [[TMP11:%.*]] = insertelement <4 x i32> [[TMP6]], i32 [[TMP10]], i64 1700; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE2]]701; CHECK: pred.load.continue2:702; CHECK-NEXT: [[TMP12:%.*]] = phi <4 x i32> [ [[TMP6]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP11]], [[PRED_LOAD_IF1]] ]703; CHECK-NEXT: [[TMP13:%.*]] = extractelement <4 x i1> [[TMP1]], i64 2704; CHECK-NEXT: br i1 [[TMP13]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]705; CHECK: pred.load.if3:706; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i32, ptr [[SRC2]], i64 [[INDEX]]707; CHECK-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP14]], i64 8708; CHECK-NEXT: [[TMP16:%.*]] = load i32, ptr [[TMP15]], align 4709; CHECK-NEXT: [[TMP17:%.*]] = insertelement <4 x i32> [[TMP12]], i32 [[TMP16]], i64 2710; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE4]]711; CHECK: pred.load.continue4:712; CHECK-NEXT: [[TMP18:%.*]] = phi <4 x i32> [ [[TMP12]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP17]], [[PRED_LOAD_IF3]] ]713; CHECK-NEXT: [[TMP19:%.*]] = extractelement <4 x i1> [[TMP1]], i64 3714; CHECK-NEXT: br i1 [[TMP19]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6]]715; CHECK: pred.load.if5:716; CHECK-NEXT: [[TMP20:%.*]] = getelementptr i32, ptr [[SRC2]], i64 [[INDEX]]717; CHECK-NEXT: [[TMP21:%.*]] = getelementptr i8, ptr [[TMP20]], i64 12718; CHECK-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4719; CHECK-NEXT: [[TMP23:%.*]] = insertelement <4 x i32> [[TMP18]], i32 [[TMP22]], i64 3720; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE6]]721; CHECK: pred.load.continue6:722; CHECK-NEXT: [[TMP24:%.*]] = phi <4 x i32> [ [[TMP18]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ]723; CHECK-NEXT: [[TMP25:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[TMP24]], <4 x i32> zeroinitializer724; CHECK-NEXT: [[PREDPHI:%.*]] = add <4 x i32> [[VEC_PHI]], [[TMP25]]725; CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds i32, ptr [[SRC1]], i64 [[INDEX]]726; CHECK-NEXT: [[WIDE_LOAD7:%.*]] = load <4 x i32>, ptr [[TMP26]], align 4727; CHECK-NEXT: [[TMP27]] = add <4 x i32> [[WIDE_LOAD7]], [[PREDPHI]]728; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4729; CHECK-NEXT: [[TMP28:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]730; CHECK-NEXT: br i1 [[TMP28]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]]731; CHECK: middle.block:732; CHECK-NEXT: [[TMP29:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP27]])733; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]734; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]735; CHECK: scalar.ph:736; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP29]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]737; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ]738; CHECK-NEXT: br label [[FOR_BODY:%.*]]739; CHECK: for.body:740; CHECK-NEXT: [[RDX1:%.*]] = phi i32 [ [[ADD2:%.*]], [[IF_END:%.*]] ], [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ]741; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[IF_END]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]742; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[IV]]743; CHECK-NEXT: [[TMP30:%.*]] = load i32, ptr [[ARRAYIDX]], align 4744; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP30]], 0745; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END]], label [[IF_THEN:%.*]]746; CHECK: if.then:747; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[IV]]748; CHECK-NEXT: [[TMP31:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4749; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP31]], [[RDX1]]750; CHECK-NEXT: br label [[IF_END]]751; CHECK: if.end:752; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ [[RDX1]], [[FOR_BODY]] ]753; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[SRC1]], i64 [[IV]]754; CHECK-NEXT: [[TMP32:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4755; CHECK-NEXT: [[ADD2]] = add nsw i32 [[TMP32]], [[RES]]756; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1757; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]758; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP13:![0-9]+]]759; CHECK: for.end:760; CHECK-NEXT: [[ADD2_LCSSA:%.*]] = phi i32 [ [[ADD2]], [[IF_END]] ], [ [[TMP29]], [[MIDDLE_BLOCK]] ]761; CHECK-NEXT: ret i32 [[ADD2_LCSSA]]762;763entry:764 br label %for.body765 766for.body:767 %rdx1 = phi i32 [ %add2, %if.end ], [ 0, %entry ]768 %iv = phi i64 [ %iv.next, %if.end ], [ 0, %entry]769 %arrayidx = getelementptr inbounds i32, ptr %cond, i64 %iv770 %0 = load i32, ptr %arrayidx771 %tobool.not = icmp eq i32 %0, 0772 br i1 %tobool.not, label %if.end, label %if.then773 774if.then:775 %arrayidx1 = getelementptr inbounds i32, ptr %src2, i64 %iv776 %1 = load i32, ptr %arrayidx1777 %add = add nsw i32 %1, %rdx1778 br label %if.end779 780if.end:781 %res = phi i32 [ %add, %if.then ], [ %rdx1, %for.body ]782 %arrayidx2 = getelementptr inbounds i32, ptr %src1, i64 %iv783 %2 = load i32, ptr %arrayidx2784 %add2 = add nsw i32 %2, %res785 %iv.next = add nuw nsw i64 %iv, 1786 %exitcond.not = icmp eq i64 %iv.next, %n787 br i1 %exitcond.not, label %for.end, label %for.body788 789for.end:790 ret i32 %add2791}792 793;794; Chain of two conditional reductions. We do not vectorise this with in-loop reductions as neither795; of the incoming values of the LoopExitInstruction (%res) is the reduction Phi (%rdx1).796;797define float @cond_cond(ptr noalias %src1, ptr noalias %src2, ptr noalias %cond, i64 %n) #0 {798; CHECK-LABEL: define float @cond_cond(799; CHECK-SAME: ptr noalias [[SRC1:%.*]], ptr noalias [[SRC2:%.*]], ptr noalias [[COND:%.*]], i64 [[N:%.*]]) {800; CHECK-NEXT: entry:801; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4802; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]803; CHECK: vector.ph:804; CHECK-NEXT: [[N_VEC:%.*]] = and i64 [[N]], -4805; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]806; CHECK: vector.body:807; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE14:%.*]] ]808; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <4 x float> [ <float 2.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00>, [[VECTOR_PH]] ], [ [[PREDPHI15:%.*]], [[PRED_LOAD_CONTINUE14]] ]809; CHECK-NEXT: [[TMP0:%.*]] = or disjoint i64 [[INDEX]], 1810; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i64 [[INDEX]], 2811; CHECK-NEXT: [[TMP2:%.*]] = or disjoint i64 [[INDEX]], 3812; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds float, ptr [[COND]], i64 [[INDEX]]813; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x float>, ptr [[TMP3]], align 4814; CHECK-NEXT: [[TMP4:%.*]] = fcmp fast oeq <4 x float> [[WIDE_LOAD]], splat (float 3.000000e+00)815; CHECK-NEXT: [[TMP5:%.*]] = extractelement <4 x i1> [[TMP4]], i64 0816; CHECK-NEXT: br i1 [[TMP5]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]817; CHECK: pred.load.if:818; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds float, ptr [[SRC1]], i64 [[INDEX]]819; CHECK-NEXT: [[TMP7:%.*]] = load float, ptr [[TMP6]], align 4820; CHECK-NEXT: [[TMP8:%.*]] = insertelement <4 x float> poison, float [[TMP7]], i64 0821; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE]]822; CHECK: pred.load.continue:823; CHECK-NEXT: [[TMP9:%.*]] = phi <4 x float> [ poison, [[VECTOR_BODY]] ], [ [[TMP8]], [[PRED_LOAD_IF]] ]824; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i1> [[TMP4]], i64 1825; CHECK-NEXT: br i1 [[TMP10]], label [[PRED_LOAD_IF1:%.*]], label [[PRED_LOAD_CONTINUE2:%.*]]826; CHECK: pred.load.if1:827; CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds float, ptr [[SRC1]], i64 [[TMP0]]828; CHECK-NEXT: [[TMP12:%.*]] = load float, ptr [[TMP11]], align 4829; CHECK-NEXT: [[TMP13:%.*]] = insertelement <4 x float> [[TMP9]], float [[TMP12]], i64 1830; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE2]]831; CHECK: pred.load.continue2:832; CHECK-NEXT: [[TMP14:%.*]] = phi <4 x float> [ [[TMP9]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP13]], [[PRED_LOAD_IF1]] ]833; CHECK-NEXT: [[TMP15:%.*]] = extractelement <4 x i1> [[TMP4]], i64 2834; CHECK-NEXT: br i1 [[TMP15]], label [[PRED_LOAD_IF3:%.*]], label [[PRED_LOAD_CONTINUE4:%.*]]835; CHECK: pred.load.if3:836; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds float, ptr [[SRC1]], i64 [[TMP1]]837; CHECK-NEXT: [[TMP17:%.*]] = load float, ptr [[TMP16]], align 4838; CHECK-NEXT: [[TMP18:%.*]] = insertelement <4 x float> [[TMP14]], float [[TMP17]], i64 2839; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE4]]840; CHECK: pred.load.continue4:841; CHECK-NEXT: [[TMP19:%.*]] = phi <4 x float> [ [[TMP14]], [[PRED_LOAD_CONTINUE2]] ], [ [[TMP18]], [[PRED_LOAD_IF3]] ]842; CHECK-NEXT: [[TMP20:%.*]] = extractelement <4 x i1> [[TMP4]], i64 3843; CHECK-NEXT: br i1 [[TMP20]], label [[PRED_LOAD_IF5:%.*]], label [[PRED_LOAD_CONTINUE6:%.*]]844; CHECK: pred.load.if5:845; CHECK-NEXT: [[TMP21:%.*]] = getelementptr inbounds float, ptr [[SRC1]], i64 [[TMP2]]846; CHECK-NEXT: [[TMP22:%.*]] = load float, ptr [[TMP21]], align 4847; CHECK-NEXT: [[TMP23:%.*]] = insertelement <4 x float> [[TMP19]], float [[TMP22]], i64 3848; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE6]]849; CHECK: pred.load.continue6:850; CHECK-NEXT: [[TMP24:%.*]] = phi <4 x float> [ [[TMP19]], [[PRED_LOAD_CONTINUE4]] ], [ [[TMP23]], [[PRED_LOAD_IF5]] ]851; CHECK-NEXT: [[TMP25:%.*]] = fadd fast <4 x float> [[TMP24]], [[VEC_PHI]]852; CHECK-NEXT: [[PREDPHI:%.*]] = select <4 x i1> [[TMP4]], <4 x float> [[TMP25]], <4 x float> [[VEC_PHI]]853; CHECK-NEXT: [[TMP26:%.*]] = fcmp fast oeq <4 x float> [[WIDE_LOAD]], splat (float 7.000000e+00)854; CHECK-NEXT: [[TMP27:%.*]] = extractelement <4 x i1> [[TMP26]], i64 0855; CHECK-NEXT: br i1 [[TMP27]], label [[PRED_LOAD_IF7:%.*]], label [[PRED_LOAD_CONTINUE8:%.*]]856; CHECK: pred.load.if7:857; CHECK-NEXT: [[TMP28:%.*]] = getelementptr inbounds float, ptr [[SRC2]], i64 [[INDEX]]858; CHECK-NEXT: [[TMP29:%.*]] = load float, ptr [[TMP28]], align 4859; CHECK-NEXT: [[TMP30:%.*]] = insertelement <4 x float> poison, float [[TMP29]], i64 0860; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE8]]861; CHECK: pred.load.continue8:862; CHECK-NEXT: [[TMP31:%.*]] = phi <4 x float> [ poison, [[PRED_LOAD_CONTINUE6]] ], [ [[TMP30]], [[PRED_LOAD_IF7]] ]863; CHECK-NEXT: [[TMP32:%.*]] = extractelement <4 x i1> [[TMP26]], i64 1864; CHECK-NEXT: br i1 [[TMP32]], label [[PRED_LOAD_IF9:%.*]], label [[PRED_LOAD_CONTINUE10:%.*]]865; CHECK: pred.load.if9:866; CHECK-NEXT: [[TMP33:%.*]] = getelementptr inbounds float, ptr [[SRC2]], i64 [[TMP0]]867; CHECK-NEXT: [[TMP34:%.*]] = load float, ptr [[TMP33]], align 4868; CHECK-NEXT: [[TMP35:%.*]] = insertelement <4 x float> [[TMP31]], float [[TMP34]], i64 1869; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE10]]870; CHECK: pred.load.continue10:871; CHECK-NEXT: [[TMP36:%.*]] = phi <4 x float> [ [[TMP31]], [[PRED_LOAD_CONTINUE8]] ], [ [[TMP35]], [[PRED_LOAD_IF9]] ]872; CHECK-NEXT: [[TMP37:%.*]] = extractelement <4 x i1> [[TMP26]], i64 2873; CHECK-NEXT: br i1 [[TMP37]], label [[PRED_LOAD_IF11:%.*]], label [[PRED_LOAD_CONTINUE12:%.*]]874; CHECK: pred.load.if11:875; CHECK-NEXT: [[TMP38:%.*]] = getelementptr inbounds float, ptr [[SRC2]], i64 [[TMP1]]876; CHECK-NEXT: [[TMP39:%.*]] = load float, ptr [[TMP38]], align 4877; CHECK-NEXT: [[TMP40:%.*]] = insertelement <4 x float> [[TMP36]], float [[TMP39]], i64 2878; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE12]]879; CHECK: pred.load.continue12:880; CHECK-NEXT: [[TMP41:%.*]] = phi <4 x float> [ [[TMP36]], [[PRED_LOAD_CONTINUE10]] ], [ [[TMP40]], [[PRED_LOAD_IF11]] ]881; CHECK-NEXT: [[TMP42:%.*]] = extractelement <4 x i1> [[TMP26]], i64 3882; CHECK-NEXT: br i1 [[TMP42]], label [[PRED_LOAD_IF13:%.*]], label [[PRED_LOAD_CONTINUE14]]883; CHECK: pred.load.if13:884; CHECK-NEXT: [[TMP43:%.*]] = getelementptr inbounds float, ptr [[SRC2]], i64 [[TMP2]]885; CHECK-NEXT: [[TMP44:%.*]] = load float, ptr [[TMP43]], align 4886; CHECK-NEXT: [[TMP45:%.*]] = insertelement <4 x float> [[TMP41]], float [[TMP44]], i64 3887; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE14]]888; CHECK: pred.load.continue14:889; CHECK-NEXT: [[TMP46:%.*]] = phi <4 x float> [ [[TMP41]], [[PRED_LOAD_CONTINUE12]] ], [ [[TMP45]], [[PRED_LOAD_IF13]] ]890; CHECK-NEXT: [[TMP47:%.*]] = fadd fast <4 x float> [[TMP46]], [[PREDPHI]]891; CHECK-NEXT: [[PREDPHI15]] = select <4 x i1> [[TMP26]], <4 x float> [[TMP47]], <4 x float> [[PREDPHI]]892; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4893; CHECK-NEXT: [[TMP48:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]894; CHECK-NEXT: br i1 [[TMP48]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]]895; CHECK: middle.block:896; CHECK-NEXT: [[TMP49:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float 0.000000e+00, <4 x float> [[PREDPHI15]])897; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]898; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]899; CHECK: scalar.ph:900; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi float [ [[TMP49]], [[MIDDLE_BLOCK]] ], [ 2.000000e+00, [[ENTRY:%.*]] ]901; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ]902; CHECK-NEXT: br label [[FOR_BODY:%.*]]903; CHECK: for.body:904; CHECK-NEXT: [[RDX1:%.*]] = phi float [ [[RES:%.*]], [[FOR_INC:%.*]] ], [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ]905; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[FOR_INC]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]906; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[COND]], i64 [[IV]]907; CHECK-NEXT: [[TMP50:%.*]] = load float, ptr [[ARRAYIDX]], align 4908; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast oeq float [[TMP50]], 3.000000e+00909; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]910; CHECK: if.then:911; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr [[SRC1]], i64 [[IV]]912; CHECK-NEXT: [[TMP51:%.*]] = load float, ptr [[ARRAYIDX2]], align 4913; CHECK-NEXT: [[ADD:%.*]] = fadd fast float [[TMP51]], [[RDX1]]914; CHECK-NEXT: br label [[IF_END]]915; CHECK: if.end:916; CHECK-NEXT: [[RDX2:%.*]] = phi float [ [[ADD]], [[IF_THEN]] ], [ [[RDX1]], [[FOR_BODY]] ]917; CHECK-NEXT: [[CMP5:%.*]] = fcmp fast oeq float [[TMP50]], 7.000000e+00918; CHECK-NEXT: br i1 [[CMP5]], label [[IF_THEN6:%.*]], label [[FOR_INC]]919; CHECK: if.then6:920; CHECK-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, ptr [[SRC2]], i64 [[IV]]921; CHECK-NEXT: [[TMP52:%.*]] = load float, ptr [[ARRAYIDX7]], align 4922; CHECK-NEXT: [[ADD2:%.*]] = fadd fast float [[TMP52]], [[RDX2]]923; CHECK-NEXT: br label [[FOR_INC]]924; CHECK: for.inc:925; CHECK-NEXT: [[RES]] = phi float [ [[ADD2]], [[IF_THEN6]] ], [ [[RDX2]], [[IF_END]] ]926; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1927; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]928; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP15:![0-9]+]]929; CHECK: for.end:930; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi float [ [[RES]], [[FOR_INC]] ], [ [[TMP49]], [[MIDDLE_BLOCK]] ]931; CHECK-NEXT: ret float [[RES_LCSSA]]932;933entry:934 br label %for.body935 936for.body:937 %rdx1 = phi float [ %res, %for.inc ], [ 2.000000e+00, %entry ]938 %iv = phi i64 [ %iv.next, %for.inc ], [ 0, %entry ]939 %arrayidx = getelementptr inbounds float, ptr %cond, i64 %iv940 %0 = load float, ptr %arrayidx941 %cmp1 = fcmp fast oeq float %0, 3.000000e+00942 br i1 %cmp1, label %if.then, label %if.end943 944if.then:945 %arrayidx2 = getelementptr inbounds float, ptr %src1, i64 %iv946 %1 = load float, ptr %arrayidx2947 %add = fadd fast float %1, %rdx1948 br label %if.end949 950if.end:951 %rdx2 = phi float [ %add, %if.then ], [ %rdx1, %for.body ]952 %cmp5 = fcmp fast oeq float %0, 7.000000e+00953 br i1 %cmp5, label %if.then6, label %for.inc954 955if.then6:956 %arrayidx7 = getelementptr inbounds float, ptr %src2, i64 %iv957 %2 = load float, ptr %arrayidx7958 %add2 = fadd fast float %2, %rdx2959 br label %for.inc960 961for.inc:962 %res = phi float [ %add2, %if.then6 ], [ %rdx2, %if.end ]963 %iv.next = add nuw nsw i64 %iv, 1964 %exitcond.not = icmp eq i64 %iv.next, %n965 br i1 %exitcond.not, label %for.end, label %for.body966 967for.end:968 ret float %res969}970 971;972; Chain of an unconditional & a conditional reduction. We do not vectorise this in-loop as neither of the973; incoming values of the LoopExitInstruction (%res) is the reduction Phi (%rdx).974;975define i32 @uncond_cond(ptr noalias %src1, ptr noalias %src2, ptr noalias %cond, i64 %N) #0 {976; CHECK-LABEL: define i32 @uncond_cond(977; CHECK-SAME: ptr noalias [[SRC1:%.*]], ptr noalias [[SRC2:%.*]], ptr noalias [[COND:%.*]], i64 [[N:%.*]]) {978; CHECK-NEXT: entry:979; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 4980; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]981; CHECK: vector.ph:982; CHECK-NEXT: [[N_VEC:%.*]] = and i64 [[N]], -4983; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]984; CHECK: vector.body:985; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE7:%.*]] ]986; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[PREDPHI:%.*]], [[PRED_LOAD_CONTINUE7]] ]987; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[SRC1]], i64 [[INDEX]]988; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4989; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[WIDE_LOAD]], [[VEC_PHI]]990; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[INDEX]]991; CHECK-NEXT: [[WIDE_LOAD1:%.*]] = load <4 x i32>, ptr [[TMP2]], align 4992; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <4 x i32> [[WIDE_LOAD1]], zeroinitializer993; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x i1> [[TMP3]], i64 0994; CHECK-NEXT: br i1 [[TMP4]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]995; CHECK: pred.load.if:996; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[INDEX]]997; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 4998; CHECK-NEXT: [[TMP7:%.*]] = insertelement <4 x i32> poison, i32 [[TMP6]], i64 0999; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE]]1000; CHECK: pred.load.continue:1001; CHECK-NEXT: [[TMP8:%.*]] = phi <4 x i32> [ poison, [[VECTOR_BODY]] ], [ [[TMP7]], [[PRED_LOAD_IF]] ]1002; CHECK-NEXT: [[TMP9:%.*]] = extractelement <4 x i1> [[TMP3]], i64 11003; CHECK-NEXT: br i1 [[TMP9]], label [[PRED_LOAD_IF2:%.*]], label [[PRED_LOAD_CONTINUE3:%.*]]1004; CHECK: pred.load.if2:1005; CHECK-NEXT: [[TMP10:%.*]] = getelementptr i32, ptr [[SRC2]], i64 [[INDEX]]1006; CHECK-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP10]], i64 41007; CHECK-NEXT: [[TMP12:%.*]] = load i32, ptr [[TMP11]], align 41008; CHECK-NEXT: [[TMP13:%.*]] = insertelement <4 x i32> [[TMP8]], i32 [[TMP12]], i64 11009; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE3]]1010; CHECK: pred.load.continue3:1011; CHECK-NEXT: [[TMP14:%.*]] = phi <4 x i32> [ [[TMP8]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP13]], [[PRED_LOAD_IF2]] ]1012; CHECK-NEXT: [[TMP15:%.*]] = extractelement <4 x i1> [[TMP3]], i64 21013; CHECK-NEXT: br i1 [[TMP15]], label [[PRED_LOAD_IF4:%.*]], label [[PRED_LOAD_CONTINUE5:%.*]]1014; CHECK: pred.load.if4:1015; CHECK-NEXT: [[TMP16:%.*]] = getelementptr i32, ptr [[SRC2]], i64 [[INDEX]]1016; CHECK-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP16]], i64 81017; CHECK-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 41018; CHECK-NEXT: [[TMP19:%.*]] = insertelement <4 x i32> [[TMP14]], i32 [[TMP18]], i64 21019; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE5]]1020; CHECK: pred.load.continue5:1021; CHECK-NEXT: [[TMP20:%.*]] = phi <4 x i32> [ [[TMP14]], [[PRED_LOAD_CONTINUE3]] ], [ [[TMP19]], [[PRED_LOAD_IF4]] ]1022; CHECK-NEXT: [[TMP21:%.*]] = extractelement <4 x i1> [[TMP3]], i64 31023; CHECK-NEXT: br i1 [[TMP21]], label [[PRED_LOAD_IF6:%.*]], label [[PRED_LOAD_CONTINUE7]]1024; CHECK: pred.load.if6:1025; CHECK-NEXT: [[TMP22:%.*]] = getelementptr i32, ptr [[SRC2]], i64 [[INDEX]]1026; CHECK-NEXT: [[TMP23:%.*]] = getelementptr i8, ptr [[TMP22]], i64 121027; CHECK-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 41028; CHECK-NEXT: [[TMP25:%.*]] = insertelement <4 x i32> [[TMP20]], i32 [[TMP24]], i64 31029; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE7]]1030; CHECK: pred.load.continue7:1031; CHECK-NEXT: [[TMP26:%.*]] = phi <4 x i32> [ [[TMP20]], [[PRED_LOAD_CONTINUE5]] ], [ [[TMP25]], [[PRED_LOAD_IF6]] ]1032; CHECK-NEXT: [[TMP27:%.*]] = select <4 x i1> [[TMP3]], <4 x i32> [[TMP26]], <4 x i32> zeroinitializer1033; CHECK-NEXT: [[PREDPHI]] = add <4 x i32> [[TMP1]], [[TMP27]]1034; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 41035; CHECK-NEXT: [[TMP28:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]1036; CHECK-NEXT: br i1 [[TMP28]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]]1037; CHECK: middle.block:1038; CHECK-NEXT: [[TMP29:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[PREDPHI]])1039; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]1040; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]1041; CHECK: scalar.ph:1042; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP29]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]1043; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ]1044; CHECK-NEXT: br label [[FOR_BODY:%.*]]1045; CHECK: for.body:1046; CHECK-NEXT: [[RDX:%.*]] = phi i32 [ [[RES:%.*]], [[FOR_INC:%.*]] ], [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ]1047; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[FOR_INC]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]1048; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[SRC1]], i64 [[IV]]1049; CHECK-NEXT: [[TMP30:%.*]] = load i32, ptr [[ARRAYIDX]], align 41050; CHECK-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP30]], [[RDX]]1051; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[IV]]1052; CHECK-NEXT: [[TMP31:%.*]] = load i32, ptr [[ARRAYIDX1]], align 41053; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP31]], 01054; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[FOR_INC]], label [[IF_THEN:%.*]]1055; CHECK: if.then:1056; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[IV]]1057; CHECK-NEXT: [[TMP32:%.*]] = load i32, ptr [[ARRAYIDX2]], align 41058; CHECK-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP32]], [[ADD1]]1059; CHECK-NEXT: br label [[FOR_INC]]1060; CHECK: for.inc:1061; CHECK-NEXT: [[RES]] = phi i32 [ [[ADD2]], [[IF_THEN]] ], [ [[ADD1]], [[FOR_BODY]] ]1062; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 11063; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]1064; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP17:![0-9]+]]1065; CHECK: for.end:1066; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i32 [ [[RES]], [[FOR_INC]] ], [ [[TMP29]], [[MIDDLE_BLOCK]] ]1067; CHECK-NEXT: ret i32 [[RES_LCSSA]]1068;1069entry:1070 br label %for.body1071 1072for.body:1073 %rdx = phi i32 [ %res, %for.inc ], [ 0, %entry ]1074 %iv = phi i64 [ %iv.next, %for.inc ], [ 0, %entry ]1075 %arrayidx = getelementptr inbounds i32, ptr %src1, i64 %iv1076 %0 = load i32, ptr %arrayidx1077 %add1 = add nsw i32 %0, %rdx1078 %arrayidx1 = getelementptr inbounds i32, ptr %cond, i64 %iv1079 %1 = load i32, ptr %arrayidx11080 %tobool.not = icmp eq i32 %1, 01081 br i1 %tobool.not, label %for.inc, label %if.then1082 1083if.then:1084 %arrayidx2 = getelementptr inbounds i32, ptr %src2, i64 %iv1085 %2 = load i32, ptr %arrayidx21086 %add2 = add nsw i32 %2, %add11087 br label %for.inc1088 1089for.inc:1090 %res = phi i32 [ %add2, %if.then ], [ %add1, %for.body ]1091 %iv.next = add nuw nsw i64 %iv, 11092 %exitcond.not = icmp eq i64 %iv.next, %N1093 br i1 %exitcond.not, label %for.end, label %for.body1094 1095for.end:1096 ret i32 %res1097}1098 1099;1100; Chain of multiple unconditional & conditional reductions. Does not vectorise in-loop as when we look back1101; through the chain and check the number of uses of %add1, we find more than the expected one use.1102;1103define i32 @uncond_cond_uncond(ptr noalias %src1, ptr noalias %src2, ptr noalias %cond, i64 noundef %N) {1104; CHECK-LABEL: define i32 @uncond_cond_uncond(1105; CHECK-SAME: ptr noalias [[SRC1:%.*]], ptr noalias [[SRC2:%.*]], ptr noalias [[COND:%.*]], i64 noundef [[N:%.*]]) {1106; CHECK-NEXT: entry:1107; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 41108; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]1109; CHECK: vector.ph:1110; CHECK-NEXT: [[N_VEC:%.*]] = and i64 [[N]], -41111; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]1112; CHECK: vector.body:1113; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE7:%.*]] ]1114; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP28:%.*]], [[PRED_LOAD_CONTINUE7]] ]1115; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[SRC1]], i64 [[INDEX]]1116; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP0]], align 41117; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[WIDE_LOAD]], [[VEC_PHI]]1118; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[INDEX]]1119; CHECK-NEXT: [[WIDE_LOAD1:%.*]] = load <4 x i32>, ptr [[TMP2]], align 41120; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <4 x i32> [[WIDE_LOAD1]], zeroinitializer1121; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x i1> [[TMP3]], i64 01122; CHECK-NEXT: br i1 [[TMP4]], label [[PRED_LOAD_IF:%.*]], label [[PRED_LOAD_CONTINUE:%.*]]1123; CHECK: pred.load.if:1124; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[INDEX]]1125; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 41126; CHECK-NEXT: [[TMP7:%.*]] = insertelement <4 x i32> poison, i32 [[TMP6]], i64 01127; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE]]1128; CHECK: pred.load.continue:1129; CHECK-NEXT: [[TMP8:%.*]] = phi <4 x i32> [ poison, [[VECTOR_BODY]] ], [ [[TMP7]], [[PRED_LOAD_IF]] ]1130; CHECK-NEXT: [[TMP9:%.*]] = extractelement <4 x i1> [[TMP3]], i64 11131; CHECK-NEXT: br i1 [[TMP9]], label [[PRED_LOAD_IF2:%.*]], label [[PRED_LOAD_CONTINUE3:%.*]]1132; CHECK: pred.load.if2:1133; CHECK-NEXT: [[TMP10:%.*]] = getelementptr i32, ptr [[SRC2]], i64 [[INDEX]]1134; CHECK-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP10]], i64 41135; CHECK-NEXT: [[TMP12:%.*]] = load i32, ptr [[TMP11]], align 41136; CHECK-NEXT: [[TMP13:%.*]] = insertelement <4 x i32> [[TMP8]], i32 [[TMP12]], i64 11137; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE3]]1138; CHECK: pred.load.continue3:1139; CHECK-NEXT: [[TMP14:%.*]] = phi <4 x i32> [ [[TMP8]], [[PRED_LOAD_CONTINUE]] ], [ [[TMP13]], [[PRED_LOAD_IF2]] ]1140; CHECK-NEXT: [[TMP15:%.*]] = extractelement <4 x i1> [[TMP3]], i64 21141; CHECK-NEXT: br i1 [[TMP15]], label [[PRED_LOAD_IF4:%.*]], label [[PRED_LOAD_CONTINUE5:%.*]]1142; CHECK: pred.load.if4:1143; CHECK-NEXT: [[TMP16:%.*]] = getelementptr i32, ptr [[SRC2]], i64 [[INDEX]]1144; CHECK-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP16]], i64 81145; CHECK-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 41146; CHECK-NEXT: [[TMP19:%.*]] = insertelement <4 x i32> [[TMP14]], i32 [[TMP18]], i64 21147; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE5]]1148; CHECK: pred.load.continue5:1149; CHECK-NEXT: [[TMP20:%.*]] = phi <4 x i32> [ [[TMP14]], [[PRED_LOAD_CONTINUE3]] ], [ [[TMP19]], [[PRED_LOAD_IF4]] ]1150; CHECK-NEXT: [[TMP21:%.*]] = extractelement <4 x i1> [[TMP3]], i64 31151; CHECK-NEXT: br i1 [[TMP21]], label [[PRED_LOAD_IF6:%.*]], label [[PRED_LOAD_CONTINUE7]]1152; CHECK: pred.load.if6:1153; CHECK-NEXT: [[TMP22:%.*]] = getelementptr i32, ptr [[SRC2]], i64 [[INDEX]]1154; CHECK-NEXT: [[TMP23:%.*]] = getelementptr i8, ptr [[TMP22]], i64 121155; CHECK-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 41156; CHECK-NEXT: [[TMP25:%.*]] = insertelement <4 x i32> [[TMP20]], i32 [[TMP24]], i64 31157; CHECK-NEXT: br label [[PRED_LOAD_CONTINUE7]]1158; CHECK: pred.load.continue7:1159; CHECK-NEXT: [[TMP26:%.*]] = phi <4 x i32> [ [[TMP20]], [[PRED_LOAD_CONTINUE5]] ], [ [[TMP25]], [[PRED_LOAD_IF6]] ]1160; CHECK-NEXT: [[TMP27:%.*]] = select <4 x i1> [[TMP3]], <4 x i32> [[TMP26]], <4 x i32> zeroinitializer1161; CHECK-NEXT: [[PREDPHI:%.*]] = add <4 x i32> [[TMP1]], [[TMP27]]1162; CHECK-NEXT: [[TMP28]] = add <4 x i32> [[PREDPHI]], [[WIDE_LOAD]]1163; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 41164; CHECK-NEXT: [[TMP29:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]1165; CHECK-NEXT: br i1 [[TMP29]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP18:![0-9]+]]1166; CHECK: middle.block:1167; CHECK-NEXT: [[TMP30:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP28]])1168; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]1169; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]1170; CHECK: scalar.ph:1171; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP30]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]1172; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ]1173; CHECK-NEXT: br label [[FOR_BODY:%.*]]1174; CHECK: for.body:1175; CHECK-NEXT: [[RDX:%.*]] = phi i32 [ [[ADD3:%.*]], [[IF_END:%.*]] ], [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ]1176; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[IF_END]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]1177; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[SRC1]], i64 [[IV]]1178; CHECK-NEXT: [[TMP31:%.*]] = load i32, ptr [[ARRAYIDX]], align 41179; CHECK-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP31]], [[RDX]]1180; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[COND]], i64 [[IV]]1181; CHECK-NEXT: [[TMP32:%.*]] = load i32, ptr [[ARRAYIDX1]], align 41182; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP32]], 01183; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END]], label [[IF_THEN:%.*]]1184; CHECK: if.then:1185; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[SRC2]], i64 [[IV]]1186; CHECK-NEXT: [[TMP33:%.*]] = load i32, ptr [[ARRAYIDX2]], align 41187; CHECK-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP33]], [[ADD1]]1188; CHECK-NEXT: br label [[IF_END]]1189; CHECK: if.end:1190; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[ADD2]], [[IF_THEN]] ], [ [[ADD1]], [[FOR_BODY]] ]1191; CHECK-NEXT: [[ADD3]] = add nsw i32 [[RES]], [[TMP31]]1192; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 11193; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]1194; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP19:![0-9]+]]1195; CHECK: for.end:1196; CHECK-NEXT: [[ADD3_LCSSA:%.*]] = phi i32 [ [[ADD3]], [[IF_END]] ], [ [[TMP30]], [[MIDDLE_BLOCK]] ]1197; CHECK-NEXT: ret i32 [[ADD3_LCSSA]]1198;1199entry:1200 br label %for.body1201 1202for.body:1203 %rdx = phi i32 [ %add3, %if.end ], [ 0, %entry ]1204 %iv = phi i64 [ %iv.next, %if.end ], [ 0, %entry ]1205 %arrayidx = getelementptr inbounds i32, ptr %src1, i64 %iv1206 %0 = load i32, ptr %arrayidx1207 %add1 = add nsw i32 %0, %rdx1208 %arrayidx1 = getelementptr inbounds i32, ptr %cond, i64 %iv1209 %1 = load i32, ptr %arrayidx11210 %tobool.not = icmp eq i32 %1, 01211 br i1 %tobool.not, label %if.end, label %if.then1212 1213if.then:1214 %arrayidx2 = getelementptr inbounds i32, ptr %src2, i64 %iv1215 %2 = load i32, ptr %arrayidx21216 %add2 = add nsw i32 %2, %add11217 br label %if.end1218 1219if.end:1220 %res = phi i32 [ %add2, %if.then ], [ %add1, %for.body ]1221 %add3 = add nsw i32 %res, %01222 %iv.next = add nuw nsw i64 %iv, 11223 %exitcond.not = icmp eq i64 %iv.next, %N1224 br i1 %exitcond.not, label %for.end, label %for.body1225 1226for.end:1227 ret i32 %add31228}1229