[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.
This commit is contained in:
Sanjay Patel 2020-07-15 14:09:46 -04:00
parent efc30e591b
commit d8b268680d
2 changed files with 37 additions and 1 deletions

View File

@ -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))

View File

@ -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
}