[llvm] 9502061 - [InstCombine] avoid infinite loop in demanded bits for select

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 28 07:25:10 PST 2021


Author: Sanjay Patel
Date: 2021-02-28T10:17:53-05:00
New Revision: 9502061bcc86982641772f45b7e7a0eb7437f054

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

LOG: [InstCombine] avoid infinite loop in demanded bits for select

https://llvm.org/PR49205

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
    llvm/test/Transforms/InstCombine/select-imm-canon.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index c265516213aa..16efe863779a 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -345,10 +345,14 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
         return false;
 
       // Get the constant out of the ICmp, if there is one.
+      // Only try this when exactly 1 operand is a constant (if both operands
+      // are constant, the icmp should eventually simplify). Otherwise, we may
+      // invert the transform that reduces set bits and infinite-loop.
+      Value *X;
       const APInt *CmpC;
       ICmpInst::Predicate Pred;
-      if (!match(I->getOperand(0), m_c_ICmp(Pred, m_APInt(CmpC), m_Value())) ||
-          CmpC->getBitWidth() != SelC->getBitWidth())
+      if (!match(I->getOperand(0), m_ICmp(Pred, m_Value(X), m_APInt(CmpC))) ||
+          isa<Constant>(X) || CmpC->getBitWidth() != SelC->getBitWidth())
         return ShrinkDemandedConstant(I, OpNo, DemandedMask);
 
       // If the constant is already the same as the ICmp, leave it as-is.

diff  --git a/llvm/test/Transforms/InstCombine/select-imm-canon.ll b/llvm/test/Transforms/InstCombine/select-imm-canon.ll
index e230b3b92777..fec6d693954a 100644
--- a/llvm/test/Transforms/InstCombine/select-imm-canon.ll
+++ b/llvm/test/Transforms/InstCombine/select-imm-canon.ll
@@ -87,3 +87,41 @@ define i8 @original_logical(i32 %A, i32 %B) {
   %conv7 = trunc i32 %spec.select.i to i8
   ret i8 %conv7
 }
+
+; This would infinite loop because we have potentially opposing
+; constant transforms on degenerate (unsimplified) cmps.
+
+define i32 @PR49205(i32 %t0, i1 %b) {
+; CHECK-LABEL: @PR49205(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[FOR_COND:%.*]]
+; CHECK:       for.cond:
+; CHECK-NEXT:    br i1 [[B:%.*]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    br label [[FOR_COND]]
+; CHECK:       for.end:
+; CHECK-NEXT:    ret i32 1
+;
+entry:
+  br label %for.cond
+
+for.cond:
+  %s = phi i32 [ 7, %entry ], [ %add, %for.body ]
+  br i1 %b, label %for.body, label %for.end
+
+for.body:
+  %div = add i32 %t0, undef
+  %add = add nsw i32 %div, 1
+  br label %for.cond
+
+for.end:
+  %cmp6 = icmp ne i32 %s, 4
+  %conv = zext i1 %cmp6 to i32
+  %and7 = and i32 %s, %conv
+  %sub = sub i32 %s, %and7
+  %cmp9 = icmp ne i32 %sub, 4
+  %conv10 = zext i1 %cmp9 to i32
+  %sub11 = sub i32 %conv10, %sub
+  %and = and i32 %sub11, 1
+  ret i32 %and
+}


        


More information about the llvm-commits mailing list