ConstantInt::get(ExitCountValue->getType(), VF * UF),
"min.iters.check", VectorPH->getTerminator());
- // The loop index does not have to start at Zero. Find the original start
- // value from the induction PHI node. If we don't have an induction variable
- // then we know that it starts at zero.
Builder.SetInsertPoint(VectorPH->getTerminator());
- Value *StartIdx = ExtendedIdx =
- OldInduction
- ? Builder.CreateZExt(OldInduction->getIncomingValueForBlock(VectorPH),
- IdxTy)
- : ConstantInt::get(IdxTy, 0);
+ Value *StartIdx = ExtendedIdx = ConstantInt::get(IdxTy, 0);
// Count holds the overall loop count (N).
Value *Count = Exp.expandCodeFor(ExitCount, ExitCount->getType(),
} else {
// Handle other induction variables that are now based on the
// canonical one.
- Value *NormalizedIdx = Builder.CreateSub(Induction, ExtendedIdx,
- "normalized.idx");
- NormalizedIdx = Builder.CreateSExtOrTrunc(NormalizedIdx, PhiTy);
- Broadcasted = II.transform(Builder, NormalizedIdx);
+ auto *V = Builder.CreateSExtOrTrunc(Induction, PhiTy);
+ Broadcasted = II.transform(Builder, V);
Broadcasted->setName("offset.idx");
}
Broadcasted = getBroadcastInstrs(Broadcasted);
// Int inductions are special because we only allow one IV.
if (ID.getKind() == InductionDescriptor::IK_IntInduction &&
- ID.getStepValue()->isOne()) {
+ ID.getStepValue()->isOne() &&
+ isa<Constant>(ID.getStartValue()) &&
+ cast<Constant>(ID.getStartValue())->isNullValue()) {
// Use the phi node with the widest type as induction. Use the last
// one if there are multiple (no good reason for doing this other
- // than it is expedient).
+ // than it is expedient). We've checked that it begins at zero and
+ // steps by one, so this is a canonical induction variable.
if (!Induction || PhiTy == WidestIndTy)
Induction = Phi;
}
; CHECK-LABEL: @multi_int_induction(
; CHECK: vector.body:
; CHECK: %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]
-; CHECK: %normalized.idx = sub i64 %index, 0
-; CHECK: %[[VAR:.*]] = trunc i64 %normalized.idx to i32
+; CHECK: %[[VAR:.*]] = trunc i64 %index to i32
; CHECK: %offset.idx = add i32 190, %[[VAR]]
define void @multi_int_induction(i32* %A, i32 %N) {
for.body.lr.ph:
; CHECK-LABEL: testoverflowcheck
; CHECK: entry
; CHECK: %[[LOAD:.*]] = load i8
-; CHECK: %[[VAL:.*]] = zext i8 %[[LOAD]] to i32
; CHECK: br
; CHECK: scalar.ph
-; CHECK: phi i32 [ %{{.*}}, %middle.block ], [ %[[VAL]], %entry ]
+; CHECK: phi i8 [ %{{.*}}, %middle.block ], [ %[[LOAD]], %entry ]
@e = global i8 1, align 1
@d = common global i32 0, align 4
; CHECK-LABEL: @reverse_forward_induction_i64_i8(
; CHECK: vector.body
; CHECK: %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]
-; CHECK: %normalized.idx = sub i64 %index, 0
-; CHECK: %offset.idx = sub i64 1023, %normalized.idx
+; CHECK: %offset.idx = sub i64 1023, %index
; CHECK: trunc i64 %index to i8
define void @reverse_forward_induction_i64_i8() {
; CHECK-LABEL: @reverse_forward_induction_i64_i8_signed(
; CHECK: vector.body:
-; CHECK: %index = phi i64 [ 129, %vector.ph ], [ %index.next, %vector.body ]
-; CHECK: %normalized.idx = sub i64 %index, 129
-; CHECK: %offset.idx = sub i64 1023, %normalized.idx
-; CHECK: trunc i64 %index to i8
+; CHECK: %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]
+; CHECK: %offset.idx = sub i64 1023, %index
define void @reverse_forward_induction_i64_i8_signed() {
entry: