diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index fdfe5cbd498..4e713fb1218 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -6793,15 +6793,6 @@ bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, ICmpInst *ICI = dyn_cast(FoundCondValue); if (!ICI) return false; - // Bail if the ICmp's operands' types are wider than the needed type - // before attempting to call getSCEV on them. This avoids infinite - // recursion, since the analysis of widening casts can require loop - // exit condition information for overflow checking, which would - // lead back here. - if (getTypeSizeInBits(LHS->getType()) < - getTypeSizeInBits(ICI->getOperand(0)->getType())) - return false; - // Now that we found a conditional branch that dominates the loop or controls // the loop latch. Check to see if it is the comparison we are looking for. ICmpInst::Predicate FoundPred; @@ -6813,9 +6804,17 @@ bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, const SCEV *FoundLHS = getSCEV(ICI->getOperand(0)); const SCEV *FoundRHS = getSCEV(ICI->getOperand(1)); - // Balance the types. The case where FoundLHS' type is wider than - // LHS' type is checked for above. - if (getTypeSizeInBits(LHS->getType()) > + // Balance the types. + if (getTypeSizeInBits(LHS->getType()) < + getTypeSizeInBits(FoundLHS->getType())) { + if (CmpInst::isSigned(Pred)) { + LHS = getSignExtendExpr(LHS, FoundLHS->getType()); + RHS = getSignExtendExpr(RHS, FoundLHS->getType()); + } else { + LHS = getZeroExtendExpr(LHS, FoundLHS->getType()); + RHS = getZeroExtendExpr(RHS, FoundLHS->getType()); + } + } else if (getTypeSizeInBits(LHS->getType()) > getTypeSizeInBits(FoundLHS->getType())) { if (CmpInst::isSigned(FoundPred)) { FoundLHS = getSignExtendExpr(FoundLHS, LHS->getType()); diff --git a/test/Analysis/ScalarEvolution/ext-antecedent.ll b/test/Analysis/ScalarEvolution/ext-antecedent.ll new file mode 100644 index 00000000000..e8d38133ad3 --- /dev/null +++ b/test/Analysis/ScalarEvolution/ext-antecedent.ll @@ -0,0 +1,45 @@ +; RUN: opt -S -indvars < %s | FileCheck %s + +declare void @use(i1) + +define void @sext_condition(i8 %t) { +; CHECK-LABEL: sext_condition + entry: + %st = sext i8 %t to i16 + %ecmp = icmp slt i16 %st, 42 + br i1 %ecmp, label %loop, label %exit + + loop: +; CHECK-LABEL: loop + %idx = phi i8 [ %t, %entry ], [ %idx.inc, %loop ] + %idx.inc = add i8 %idx, 1 + %c = icmp slt i8 %idx, 42 +; CHECK: call void @use(i1 true) + call void @use(i1 %c) + %be = icmp slt i8 %idx.inc, 42 + br i1 %be, label %loop, label %exit + + exit: + ret void +} + +define void @zext_condition(i8 %t) { +; CHECK-LABEL: zext_condition + entry: + %st = zext i8 %t to i16 + %ecmp = icmp ult i16 %st, 42 + br i1 %ecmp, label %loop, label %exit + + loop: +; CHECK-LABEL: loop + %idx = phi i8 [ %t, %entry ], [ %idx.inc, %loop ] + %idx.inc = add i8 %idx, 1 + %c = icmp ult i8 %idx, 42 +; CHECK: call void @use(i1 true) + call void @use(i1 %c) + %be = icmp ult i8 %idx.inc, 42 + br i1 %be, label %loop, label %exit + + exit: + ret void +}