1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -S %s | FileCheck %s 3 4target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 5 6define void @test() { 7; CHECK-LABEL: @test( 8; CHECK-NEXT: br label [[FOR_BODY_LR_PH_I_I_I:%.*]] 9; CHECK: for.body.lr.ph.i.i.i: 10; CHECK-NEXT: br i1 true, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] 11; CHECK: vector.ph: 12; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 13; CHECK: vector.body: 14; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 15; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4 16; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[INDEX_NEXT]], 0 17; CHECK-NEXT: br i1 [[TMP1]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] 18; CHECK: middle.block: 19; CHECK-NEXT: br i1 false, label [[FOR_END_I_I_I:%.*]], label [[SCALAR_PH]] 20; CHECK: scalar.ph: 21; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 0, [[MIDDLE_BLOCK]] ], [ 0, [[FOR_BODY_LR_PH_I_I_I]] ] 22; CHECK-NEXT: br label [[FOR_BODY_I_I_I:%.*]] 23; CHECK: for.body.i.i.i: 24; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC_I_I_I:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] 25; CHECK-NEXT: br label [[FOR_INC_I_I_I]] 26; CHECK: for.inc.i.i.i: 27; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1 28; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 29; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], undef 30; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY_I_I_I]], label [[FOR_END_I_I_I]], !llvm.loop [[LOOP3:![0-9]+]] 31; CHECK: for.end.i.i.i: 32; CHECK-NEXT: [[LCSSA:%.*]] = phi ptr [ undef, [[FOR_INC_I_I_I]] ], [ undef, [[MIDDLE_BLOCK]] ] 33; CHECK-NEXT: unreachable 34; 35 br label %for.body.lr.ph.i.i.i 36 37for.body.lr.ph.i.i.i: 38 br label %for.body.i.i.i 39 40for.body.i.i.i: 41 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc.i.i.i ], [ 0, %for.body.lr.ph.i.i.i ] 42 br label %for.inc.i.i.i 43 44for.inc.i.i.i: 45 %indvars.iv.next = add i64 %indvars.iv, 1 46 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 47 %exitcond = icmp ne i32 %lftr.wideiv, undef 48 br i1 %exitcond, label %for.body.i.i.i, label %for.end.i.i.i 49 50for.end.i.i.i: 51 %lcssa = phi ptr [ undef, %for.inc.i.i.i ] 52 unreachable 53} 54 55; PR16139 56define void @test2(ptr %x) { 57; CHECK-LABEL: @test2( 58; CHECK-NEXT: entry: 59; CHECK-NEXT: indirectbr ptr [[X:%.*]], [label [[L0:%.*]], label %L1] 60; CHECK: L0: 61; CHECK-NEXT: br label [[L0]] 62; CHECK: L1: 63; CHECK-NEXT: ret void 64; 65entry: 66 indirectbr ptr %x, [ label %L0, label %L1 ] 67 68L0: 69 br label %L0 70 71L1: 72 ret void 73} 74 75; This loop has different uniform instructions before and after LCSSA. 76define void @test3() { 77; CHECK-LABEL: @test3( 78; CHECK-NEXT: entry: 79; CHECK-NEXT: [[ADD41:%.*]] = add i32 undef, undef 80; CHECK-NEXT: [[IDXPROM4736:%.*]] = zext i32 [[ADD41]] to i64 81; CHECK-NEXT: br label [[WHILE_BODY:%.*]] 82; CHECK: while.body: 83; CHECK-NEXT: [[IDXPROM4738:%.*]] = phi i64 [ [[IDXPROM47:%.*]], [[WHILE_BODY]] ], [ [[IDXPROM4736]], [[ENTRY:%.*]] ] 84; CHECK-NEXT: [[POS_337:%.*]] = phi i32 [ [[INC46:%.*]], [[WHILE_BODY]] ], [ [[ADD41]], [[ENTRY]] ] 85; CHECK-NEXT: [[INC46]] = add i32 [[POS_337]], 1 86; CHECK-NEXT: [[ARRAYIDX48:%.*]] = getelementptr inbounds [1024 x i8], ptr undef, i64 0, i64 [[IDXPROM4738]] 87; CHECK-NEXT: store i8 0, ptr [[ARRAYIDX48]], align 1 88; CHECK-NEXT: [[AND43:%.*]] = and i32 [[INC46]], 3 89; CHECK-NEXT: [[CMP44:%.*]] = icmp eq i32 [[AND43]], 0 90; CHECK-NEXT: [[IDXPROM47]] = zext i32 [[INC46]] to i64 91; CHECK-NEXT: br i1 [[CMP44]], label [[WHILE_END:%.*]], label [[WHILE_BODY]] 92; CHECK: while.end: 93; CHECK-NEXT: [[INC46_LCSSA:%.*]] = phi i32 [ [[INC46]], [[WHILE_BODY]] ] 94; CHECK-NEXT: [[ADD58:%.*]] = add i32 [[INC46_LCSSA]], 4 95; CHECK-NEXT: ret void 96; 97entry: 98 %add41 = add i32 undef, undef 99 %idxprom4736 = zext i32 %add41 to i64 100 br label %while.body 101 102while.body: 103 %idxprom4738 = phi i64 [ %idxprom47, %while.body ], [ %idxprom4736, %entry ] 104 %pos.337 = phi i32 [ %inc46, %while.body ], [ %add41, %entry ] 105 %inc46 = add i32 %pos.337, 1 106 %arrayidx48 = getelementptr inbounds [1024 x i8], ptr undef, i64 0, i64 %idxprom4738 107 store i8 0, ptr %arrayidx48, align 1 108 %and43 = and i32 %inc46, 3 109 %cmp44 = icmp eq i32 %and43, 0 110 %idxprom47 = zext i32 %inc46 to i64 111 br i1 %cmp44, label %while.end, label %while.body 112 113while.end: 114 %add58 = add i32 %inc46, 4 115 ret void 116} 117 118; Make sure LV doesn't crash on IR where some LCSSA uses are unreachable. 119define i32 @pr57508(ptr %src) { 120; CHECK-LABEL: @pr57508( 121; CHECK-NEXT: entry: 122; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] 123; CHECK: vector.ph: 124; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 125; CHECK: vector.body: 126; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 127; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4 128; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i64 [[INDEX_NEXT]], 2000 129; CHECK-NEXT: br i1 [[TMP0]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]] 130; CHECK: middle.block: 131; CHECK-NEXT: br i1 false, label [[LOOP_EXIT:%.*]], label [[SCALAR_PH]] 132; CHECK: scalar.ph: 133; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 2000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] 134; CHECK-NEXT: [[BC_RESUME_VAL1:%.*]] = phi i32 [ 2000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY]] ] 135; CHECK-NEXT: br label [[LOOP:%.*]] 136; CHECK: loop: 137; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] 138; CHECK-NEXT: [[LOCAL:%.*]] = phi i32 [ [[LOCAL_NEXT:%.*]], [[LOOP]] ], [ [[BC_RESUME_VAL1]], [[SCALAR_PH]] ] 139; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 140; CHECK-NEXT: [[LOCAL_NEXT]] = add i32 [[LOCAL]], 1 141; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], 2000 142; CHECK-NEXT: br i1 [[EC]], label [[LOOP_EXIT]], label [[LOOP]], !llvm.loop [[LOOP5:![0-9]+]] 143; CHECK: loop.exit: 144; CHECK-NEXT: unreachable 145; CHECK: bb: 146; CHECK-NEXT: [[LOCAL_USE:%.*]] = add i32 poison, 1 147; CHECK-NEXT: ret i32 [[LOCAL_USE]] 148; 149entry: 150 br label %loop 151 152loop: 153 %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ] 154 %local = phi i32 [ %local.next, %loop ], [ 0, %entry ] 155 %iv.next = add nuw nsw i64 %iv, 1 156 %local.next = add i32 %local, 1 157 %ec = icmp eq i64 %iv, 2000 158 br i1 %ec, label %loop.exit, label %loop 159 160loop.exit: 161 unreachable 162 163bb: 164 %local.use = add i32 %local, 1 165 ret i32 %local.use 166} 167