[llvm] d8b2686 - [InstCombine] prevent infinite looping in or-icmp fold (PR46712)
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 15 11:12:32 PDT 2020
Author: Sanjay Patel
Date: 2020-07-15T14:12:12-04:00
New Revision: d8b268680d0858aaf30cb1a278b64b11361bc780
URL: https://github.com/llvm/llvm-project/commit/d8b268680d0858aaf30cb1a278b64b11361bc780
DIFF: https://github.com/llvm/llvm-project/commit/d8b268680d0858aaf30cb1a278b64b11361bc780.diff
LOG: [InstCombine] prevent infinite looping in or-icmp fold (PR46712)
I'm not sure if the test is truly minimal, but we need to
induce a situation where a value becomes a constant but is
not immediately folded before getting to the 'or' transform.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/or.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index d3c718a919c0..1304d46fdef4 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1148,11 +1148,12 @@ static Value *foldAndOrOfICmpsWithConstEq(ICmpInst *Cmp0, ICmpInst *Cmp1,
assert((IsAnd || Logic.getOpcode() == Instruction::Or) && "Wrong logic op");
// Match an equality compare with a non-poison constant as Cmp0.
+ // Also, give up if the compare can be constant-folded to avoid looping.
ICmpInst::Predicate Pred0;
Value *X;
Constant *C;
if (!match(Cmp0, m_ICmp(Pred0, m_Value(X), m_Constant(C))) ||
- !isGuaranteedNotToBeUndefOrPoison(C))
+ !isGuaranteedNotToBeUndefOrPoison(C) || isa<Constant>(X))
return nullptr;
if ((IsAnd && Pred0 != ICmpInst::ICMP_EQ) ||
(!IsAnd && Pred0 != ICmpInst::ICMP_NE))
diff --git a/llvm/test/Transforms/InstCombine/or.ll b/llvm/test/Transforms/InstCombine/or.ll
index b747c5d97810..48496948c190 100644
--- a/llvm/test/Transforms/InstCombine/or.ll
+++ b/llvm/test/Transforms/InstCombine/or.ll
@@ -841,3 +841,38 @@ define <16 x i1> @test51(<16 x i1> %arg, <16 x i1> %arg1) {
%tmp3 = or <16 x i1> %tmp, %tmp2
ret <16 x i1> %tmp3
}
+
+; This would infinite loop because it reaches a transform
+; that was not expecting a constant-foldable value.
+
+define i32 @PR46712(i1 %x, i1 %y, i1 %b, i64 %z) {
+; CHECK-LABEL: @PR46712(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
+; CHECK: true:
+; CHECK-NEXT: [[BOOL5:%.*]] = icmp eq i64 [[Z:%.*]], 0
+; CHECK-NEXT: [[SEL:%.*]] = zext i1 [[BOOL5]] to i32
+; CHECK-NEXT: br label [[END]]
+; CHECK: end:
+; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SEL]], [[TRUE]] ]
+; CHECK-NEXT: ret i32 [[T5]]
+;
+entry:
+ %t2 = or i1 %x, %y
+ %conv = sext i1 %t2 to i32
+ %cmp = icmp sge i32 %conv, 1
+ %conv2 = zext i1 %cmp to i64
+ br i1 %b, label %true, label %end
+
+true:
+ %bool4 = icmp eq i64 %conv2, 0
+ %bool5 = icmp ne i64 %z, 0
+ %and = and i1 %bool4, %bool5
+ %sel = select i1 %and, i1 false, i1 true
+ br label %end
+
+end:
+ %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
+ %conv8 = zext i1 %t5 to i32
+ ret i32 %conv8
+}
More information about the llvm-commits
mailing list