1*2e14900dSBjorn Pettersson; RUN: opt < %s -passes=loop-vectorize -force-vector-interleave=2 -force-vector-width=4 -S | FileCheck %s 2cee313d2SEric Christopher 3cee313d2SEric Christophertarget 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" 4cee313d2SEric Christopher 5cee313d2SEric Christopher; Make sure consecutive vector generates correct negative indices. 6cee313d2SEric Christopher; PR15882 7cee313d2SEric Christopher 8cee313d2SEric Christopher; CHECK: %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] 9446e7c64SFlorian Hahn; CHECK: [[OFFSET_IDX:%.+]] = sub i64 %startval, %index 10446e7c64SFlorian Hahn; CHECK: %[[a0:.+]] = add i64 [[OFFSET_IDX]], 0 11446e7c64SFlorian Hahn; CHECK: %[[a4:.+]] = add i64 [[OFFSET_IDX]], -4 12cee313d2SEric Christopher 13cee313d2SEric Christopherdefine i32 @reverse_induction_i64(i64 %startval, i32 * %ptr) { 14cee313d2SEric Christopherentry: 15cee313d2SEric Christopher br label %for.body 16cee313d2SEric Christopher 17cee313d2SEric Christopherfor.body: 18cee313d2SEric Christopher %add.i7 = phi i64 [ %startval, %entry ], [ %add.i, %for.body ] 19cee313d2SEric Christopher %i.06 = phi i32 [ 0, %entry ], [ %inc4, %for.body ] 20cee313d2SEric Christopher %redux5 = phi i32 [ 0, %entry ], [ %inc.redux, %for.body ] 21cee313d2SEric Christopher %add.i = add i64 %add.i7, -1 22cee313d2SEric Christopher %kind_.i = getelementptr inbounds i32, i32* %ptr, i64 %add.i 23cee313d2SEric Christopher %tmp.i1 = load i32, i32* %kind_.i, align 4 24cee313d2SEric Christopher %inc.redux = add i32 %tmp.i1, %redux5 25cee313d2SEric Christopher %inc4 = add i32 %i.06, 1 26cee313d2SEric Christopher %exitcond = icmp ne i32 %inc4, 1024 27cee313d2SEric Christopher br i1 %exitcond, label %for.body, label %loopend 28cee313d2SEric Christopher 29cee313d2SEric Christopherloopend: 30cee313d2SEric Christopher ret i32 %inc.redux 31cee313d2SEric Christopher} 32cee313d2SEric Christopher 33cee313d2SEric Christopher; CHECK-LABEL: @reverse_induction_i128( 34cee313d2SEric Christopher; CHECK: %index = phi i128 [ 0, %vector.ph ], [ %index.next, %vector.body ] 35b3e8ace1SFlorian Hahn; CHECK: [[OFFSET_IDX:%.+]] = sub i128 %startval, %index 36b3e8ace1SFlorian Hahn; CHECK: %[[a0:.+]] = add i128 [[OFFSET_IDX]], 0 37b3e8ace1SFlorian Hahn; CHECK: %[[a4:.+]] = add i128 [[OFFSET_IDX]], -4 38cee313d2SEric Christopher 39cee313d2SEric Christopherdefine i32 @reverse_induction_i128(i128 %startval, i32 * %ptr) { 40cee313d2SEric Christopherentry: 41cee313d2SEric Christopher br label %for.body 42cee313d2SEric Christopher 43cee313d2SEric Christopherfor.body: 44cee313d2SEric Christopher %add.i7 = phi i128 [ %startval, %entry ], [ %add.i, %for.body ] 45cee313d2SEric Christopher %i.06 = phi i32 [ 0, %entry ], [ %inc4, %for.body ] 46cee313d2SEric Christopher %redux5 = phi i32 [ 0, %entry ], [ %inc.redux, %for.body ] 47cee313d2SEric Christopher %add.i = add i128 %add.i7, -1 48cee313d2SEric Christopher %kind_.i = getelementptr inbounds i32, i32* %ptr, i128 %add.i 49cee313d2SEric Christopher %tmp.i1 = load i32, i32* %kind_.i, align 4 50cee313d2SEric Christopher %inc.redux = add i32 %tmp.i1, %redux5 51cee313d2SEric Christopher %inc4 = add i32 %i.06, 1 52cee313d2SEric Christopher %exitcond = icmp ne i32 %inc4, 1024 53cee313d2SEric Christopher br i1 %exitcond, label %for.body, label %loopend 54cee313d2SEric Christopher 55cee313d2SEric Christopherloopend: 56cee313d2SEric Christopher ret i32 %inc.redux 57cee313d2SEric Christopher} 58cee313d2SEric Christopher 59cee313d2SEric Christopher; CHECK-LABEL: @reverse_induction_i16( 60cee313d2SEric Christopher; CHECK: %index = phi i32 [ 0, %vector.ph ], [ %index.next, %vector.body ] 61446e7c64SFlorian Hahn; CHECK: [[OFFSET_IDX:%.+]] = sub i16 %startval, {{.*}} 62446e7c64SFlorian Hahn; CHECK: %[[a0:.+]] = add i16 [[OFFSET_IDX]], 0 63446e7c64SFlorian Hahn; CHECK: %[[a4:.+]] = add i16 [[OFFSET_IDX]], -4 64cee313d2SEric Christopher 65cee313d2SEric Christopherdefine i32 @reverse_induction_i16(i16 %startval, i32 * %ptr) { 66cee313d2SEric Christopherentry: 67cee313d2SEric Christopher br label %for.body 68cee313d2SEric Christopher 69cee313d2SEric Christopherfor.body: 70cee313d2SEric Christopher %add.i7 = phi i16 [ %startval, %entry ], [ %add.i, %for.body ] 71cee313d2SEric Christopher %i.06 = phi i32 [ 0, %entry ], [ %inc4, %for.body ] 72cee313d2SEric Christopher %redux5 = phi i32 [ 0, %entry ], [ %inc.redux, %for.body ] 73cee313d2SEric Christopher %add.i = add i16 %add.i7, -1 74cee313d2SEric Christopher %kind_.i = getelementptr inbounds i32, i32* %ptr, i16 %add.i 75cee313d2SEric Christopher %tmp.i1 = load i32, i32* %kind_.i, align 4 76cee313d2SEric Christopher %inc.redux = add i32 %tmp.i1, %redux5 77cee313d2SEric Christopher %inc4 = add i32 %i.06, 1 78cee313d2SEric Christopher %exitcond = icmp ne i32 %inc4, 1024 79cee313d2SEric Christopher br i1 %exitcond, label %for.body, label %loopend 80cee313d2SEric Christopher 81cee313d2SEric Christopherloopend: 82cee313d2SEric Christopher ret i32 %inc.redux 83cee313d2SEric Christopher} 84cee313d2SEric Christopher 85cee313d2SEric Christopher 86cee313d2SEric Christopher@a = common global [1024 x i32] zeroinitializer, align 16 87cee313d2SEric Christopher 88cee313d2SEric Christopher; We incorrectly transformed this loop into an empty one because we left the 89cee313d2SEric Christopher; induction variable in i8 type and truncated the exit value 1024 to 0. 90cee313d2SEric Christopher; int a[1024]; 91cee313d2SEric Christopher; 92cee313d2SEric Christopher; void fail() { 93cee313d2SEric Christopher; int reverse_induction = 1023; 94cee313d2SEric Christopher; unsigned char forward_induction = 0; 95cee313d2SEric Christopher; while ((reverse_induction) >= 0) { 96cee313d2SEric Christopher; forward_induction++; 97cee313d2SEric Christopher; a[reverse_induction] = forward_induction; 98cee313d2SEric Christopher; --reverse_induction; 99cee313d2SEric Christopher; } 100cee313d2SEric Christopher; } 101cee313d2SEric Christopher 102cee313d2SEric Christopher; CHECK-LABEL: @reverse_forward_induction_i64_i8( 103cee313d2SEric Christopher; CHECK: %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] 104446e7c64SFlorian Hahn; CHECK: [[OFFSET_IDX:%.+]] = sub i64 1023, %index 105446e7c64SFlorian Hahn; CHECK: %[[a0:.+]] = add i64 [[OFFSET_IDX]], 0 106446e7c64SFlorian Hahn; CHECK: %[[a4:.+]] = add i64 [[OFFSET_IDX]], -4 107cee313d2SEric Christopher 108cee313d2SEric Christopherdefine void @reverse_forward_induction_i64_i8() { 109cee313d2SEric Christopherentry: 110cee313d2SEric Christopher br label %while.body 111cee313d2SEric Christopher 112cee313d2SEric Christopherwhile.body: 113cee313d2SEric Christopher %indvars.iv = phi i64 [ 1023, %entry ], [ %indvars.iv.next, %while.body ] 114cee313d2SEric Christopher %forward_induction.05 = phi i8 [ 0, %entry ], [ %inc, %while.body ] 115cee313d2SEric Christopher %inc = add i8 %forward_induction.05, 1 116cee313d2SEric Christopher %conv = zext i8 %inc to i32 117cee313d2SEric Christopher %arrayidx = getelementptr inbounds [1024 x i32], [1024 x i32]* @a, i64 0, i64 %indvars.iv 118cee313d2SEric Christopher store i32 %conv, i32* %arrayidx, align 4 119cee313d2SEric Christopher %indvars.iv.next = add i64 %indvars.iv, -1 120cee313d2SEric Christopher %0 = trunc i64 %indvars.iv to i32 121cee313d2SEric Christopher %cmp = icmp sgt i32 %0, 0 122cee313d2SEric Christopher br i1 %cmp, label %while.body, label %while.end 123cee313d2SEric Christopher 124cee313d2SEric Christopherwhile.end: 125cee313d2SEric Christopher ret void 126cee313d2SEric Christopher} 127cee313d2SEric Christopher 128cee313d2SEric Christopher; CHECK-LABEL: @reverse_forward_induction_i64_i8_signed( 129cee313d2SEric Christopher; CHECK: %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] 130446e7c64SFlorian Hahn; CHECK: [[OFFSET_IDX:%.+]] = sub i64 1023, %index 131446e7c64SFlorian Hahn; CHECK: %[[a0:.+]] = add i64 [[OFFSET_IDX]], 0 132446e7c64SFlorian Hahn; CHECK: %[[a4:.+]] = add i64 [[OFFSET_IDX]], -4 133cee313d2SEric Christopher 134cee313d2SEric Christopherdefine void @reverse_forward_induction_i64_i8_signed() { 135cee313d2SEric Christopherentry: 136cee313d2SEric Christopher br label %while.body 137cee313d2SEric Christopher 138cee313d2SEric Christopherwhile.body: 139cee313d2SEric Christopher %indvars.iv = phi i64 [ 1023, %entry ], [ %indvars.iv.next, %while.body ] 140cee313d2SEric Christopher %forward_induction.05 = phi i8 [ -127, %entry ], [ %inc, %while.body ] 141cee313d2SEric Christopher %inc = add i8 %forward_induction.05, 1 142cee313d2SEric Christopher %conv = sext i8 %inc to i32 143cee313d2SEric Christopher %arrayidx = getelementptr inbounds [1024 x i32], [1024 x i32]* @a, i64 0, i64 %indvars.iv 144cee313d2SEric Christopher store i32 %conv, i32* %arrayidx, align 4 145cee313d2SEric Christopher %indvars.iv.next = add i64 %indvars.iv, -1 146cee313d2SEric Christopher %0 = trunc i64 %indvars.iv to i32 147cee313d2SEric Christopher %cmp = icmp sgt i32 %0, 0 148cee313d2SEric Christopher br i1 %cmp, label %while.body, label %while.end 149cee313d2SEric Christopher 150cee313d2SEric Christopherwhile.end: 151cee313d2SEric Christopher ret void 152cee313d2SEric Christopher} 153