[llvm] f82cf61 - [indvars] Fix pr52276 (missing one use check)

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 25 09:27:13 PDT 2021


Author: Philip Reames
Date: 2021-10-25T09:26:55-07:00
New Revision: f82cf6187fbe9584ba0a8d9bf4d703498df249e6

URL: https://github.com/llvm/llvm-project/commit/f82cf6187fbe9584ba0a8d9bf4d703498df249e6
DIFF: https://github.com/llvm/llvm-project/commit/f82cf6187fbe9584ba0a8d9bf4d703498df249e6.diff

LOG: [indvars] Fix pr52276 (missing one use check)

The recently added logic to canonicalize exit conditions to unsigned relies on facts which hold about the use (i.e. exit test).  Applying this blindly to the icmp is not legal, as there may be another use which never reaches the exit.  Restrict ourselves to case where we have a single use.

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
    llvm/test/Transforms/IndVarSimplify/finite-exit-comparisons.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
index 4f18f6199b1b..678d341ddcbd 100644
--- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -1430,7 +1430,7 @@ bool IndVarSimplify::canonicalizeExitCondition(Loop *L) {
     assert(BI->isConditional() && "exit branch must be conditional");
 
     auto *ICmp = dyn_cast<ICmpInst>(BI->getCondition());
-    if (!ICmp)
+    if (!ICmp || !ICmp->hasOneUse())
       continue;
 
     auto *LHS = ICmp->getOperand(0);

diff  --git a/llvm/test/Transforms/IndVarSimplify/finite-exit-comparisons.ll b/llvm/test/Transforms/IndVarSimplify/finite-exit-comparisons.ll
index ad7126647fb5..0859c057ed2a 100644
--- a/llvm/test/Transforms/IndVarSimplify/finite-exit-comparisons.ll
+++ b/llvm/test/Transforms/IndVarSimplify/finite-exit-comparisons.ll
@@ -154,6 +154,63 @@ for.end:                                          ; preds = %for.body, %entry
   ret void
 }
 
+; Fact holds for exiting branch, but not for earlier use
+; We could recognize the unreachable loop here, but don't currently.  Its
+; also not terribly interesting, because EarlyCSE will fold condition.
+define void @slt_neg_multiple_use(i8 %start) mustprogress {
+; CHECK-LABEL: @slt_neg_multiple_use(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[START:%.*]] to i16
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[ZEXT]], 254
+; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]
+; CHECK:       for.body.preheader:
+; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]
+; CHECK:       for.end.loopexit:
+; CHECK-NEXT:    br label [[FOR_END]]
+; CHECK:       for.end:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %zext = zext i8 %start to i16
+  %cmp = icmp slt i16 %zext, 254
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %entry, %for.body
+  br i1 %cmp, label %for.body, label %for.end
+
+for.end:                                          ; preds = %for.body, %entry
+  ret void
+}
+
+define void @slt_neg_multiple_use2(i8 %start, i16 %n) mustprogress {
+; CHECK-LABEL: @slt_neg_multiple_use2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[START:%.*]] to i16
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[ZEXT]], [[N:%.*]]
+; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]
+; CHECK:       for.body.preheader:
+; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]
+; CHECK:       for.end.loopexit:
+; CHECK-NEXT:    br label [[FOR_END]]
+; CHECK:       for.end:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %zext = zext i8 %start to i16
+  %cmp = icmp slt i16 %zext, %n
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %entry, %for.body
+  br i1 %cmp, label %for.body, label %for.end
+
+for.end:                                          ; preds = %for.body, %entry
+  ret void
+}
+
 @G = external global i8
 
 ; Negative case where the loop could be infinite and make progress


        


More information about the llvm-commits mailing list