diff options
| -rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 23 | ||||
| -rw-r--r-- | llvm/test/Analysis/ScalarEvolution/ext-antecedent.ll | 45 | 
2 files changed, 56 insertions, 12 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index fdfe5cbd498..4e713fb1218 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -6793,15 +6793,6 @@ bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred,    ICmpInst *ICI = dyn_cast<ICmpInst>(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/llvm/test/Analysis/ScalarEvolution/ext-antecedent.ll b/llvm/test/Analysis/ScalarEvolution/ext-antecedent.ll new file mode 100644 index 00000000000..e8d38133ad3 --- /dev/null +++ b/llvm/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 +}  | 

