Skip to content

Commit 692808e

Browse files
rotaterighttstellar
authored andcommitted
[InstCombine] avoid infinite loop in demanded bits for select
https://llvm.org/PR49205 (cherry picked from commit 9502061)
1 parent c637d4d commit 692808e

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,10 +345,14 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
345345
return false;
346346

347347
// Get the constant out of the ICmp, if there is one.
348+
// Only try this when exactly 1 operand is a constant (if both operands
349+
// are constant, the icmp should eventually simplify). Otherwise, we may
350+
// invert the transform that reduces set bits and infinite-loop.
351+
Value *X;
348352
const APInt *CmpC;
349353
ICmpInst::Predicate Pred;
350-
if (!match(I->getOperand(0), m_c_ICmp(Pred, m_APInt(CmpC), m_Value())) ||
351-
CmpC->getBitWidth() != SelC->getBitWidth())
354+
if (!match(I->getOperand(0), m_ICmp(Pred, m_Value(X), m_APInt(CmpC))) ||
355+
isa<Constant>(X) || CmpC->getBitWidth() != SelC->getBitWidth())
352356
return ShrinkDemandedConstant(I, OpNo, DemandedMask);
353357

354358
// If the constant is already the same as the ICmp, leave it as-is.

llvm/test/Transforms/InstCombine/select-imm-canon.ll

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,41 @@ define i8 @original_logical(i32 %A, i32 %B) {
8787
%conv7 = trunc i32 %spec.select.i to i8
8888
ret i8 %conv7
8989
}
90+
91+
; This would infinite loop because we have potentially opposing
92+
; constant transforms on degenerate (unsimplified) cmps.
93+
94+
define i32 @PR49205(i32 %t0, i1 %b) {
95+
; CHECK-LABEL: @PR49205(
96+
; CHECK-NEXT: entry:
97+
; CHECK-NEXT: br label [[FOR_COND:%.*]]
98+
; CHECK: for.cond:
99+
; CHECK-NEXT: br i1 [[B:%.*]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
100+
; CHECK: for.body:
101+
; CHECK-NEXT: br label [[FOR_COND]]
102+
; CHECK: for.end:
103+
; CHECK-NEXT: ret i32 1
104+
;
105+
entry:
106+
br label %for.cond
107+
108+
for.cond:
109+
%s = phi i32 [ 7, %entry ], [ %add, %for.body ]
110+
br i1 %b, label %for.body, label %for.end
111+
112+
for.body:
113+
%div = add i32 %t0, undef
114+
%add = add nsw i32 %div, 1
115+
br label %for.cond
116+
117+
for.end:
118+
%cmp6 = icmp ne i32 %s, 4
119+
%conv = zext i1 %cmp6 to i32
120+
%and7 = and i32 %s, %conv
121+
%sub = sub i32 %s, %and7
122+
%cmp9 = icmp ne i32 %sub, 4
123+
%conv10 = zext i1 %cmp9 to i32
124+
%sub11 = sub i32 %conv10, %sub
125+
%and = and i32 %sub11, 1
126+
ret i32 %and
127+
}

0 commit comments

Comments
 (0)