[InstCombine] prevent infinite looping from opposing cmp and select transforms (PR52684)

As noted in the code comment, we might want to simply give up on this select
transform completely (given how many exceptions there are already and the
risk of future conflicts), but for now, carve out one more bailout to
avoid an infinite loop.

Fixes #52684:
https://github.com/llvm/llvm-project/issues/52684
This commit is contained in:
Sanjay Patel 2021-12-14 10:46:25 -05:00
parent d2be9ae0da
commit bb2fc19c63
2 changed files with 34 additions and 2 deletions

View File

@ -1482,7 +1482,12 @@ tryToReuseConstantFromSelectInComparison(SelectInst &Sel, ICmpInst &Cmp,
if (C0->getType() != Sel.getType())
return nullptr;
// FIXME: are there any magic icmp predicate+constant pairs we must not touch?
// ULT with 'add' of a constant is canonical. See foldICmpAddConstant().
// FIXME: Are there more magic icmp predicate+constant pairs we must avoid?
// Or should we just abandon this transform entirely?
if (Pred == CmpInst::ICMP_ULT && match(X, m_Add(m_Value(), m_Constant())))
return nullptr;
Value *SelVal0, *SelVal1; // We do not care which one is from where.
match(&Sel, m_Select(m_Value(), m_Value(SelVal0), m_Value(SelVal1)));

View File

@ -19,7 +19,7 @@
define i32 @p0_ult_65536(i32 %x, i32 %y) {
; CHECK-LABEL: @p0_ult_65536(
; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt i32 [[X:%.*]], 65535
; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 65535, i32 [[Y:%.*]], !prof !0
; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 65535, i32 [[Y:%.*]], !prof [[PROF0:![0-9]+]]
; CHECK-NEXT: ret i32 [[R]]
;
%t = icmp ult i32 %x, 65536
@ -331,6 +331,33 @@ define i32 @n26_all_good1(i32 %x, i32 %y) {
ret i32 %r
}
; https://llvm.org/PR52684
; Do not infinite loop by opposing 'ult' canonicalization.
define i32 @ult_inf_loop(i32 %x) {
; CHECK-LABEL: @ult_inf_loop(
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], -1
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 2
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 1, i32 -3
; CHECK-NEXT: ret i32 [[SEL]]
;
%add = add i32 %x, -1
%cmp = icmp ult i32 %add, 2
%sel = select i1 %cmp, i32 1, i32 -3
ret i32 %sel
}
define <2 x i32> @ult_inf_loop_vec(<2 x i32> %x) {
; CHECK-LABEL: @ult_inf_loop_vec(
; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 38, i32 38>
; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[TMP1]], <i32 -4, i32 -4>
; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i32> <i32 -5, i32 -5>, <2 x i32> <i32 3, i32 3>
; CHECK-NEXT: ret <2 x i32> [[SEL]]
;
%add = add <2 x i32> %x, <i32 42, i32 42>
%cmp = icmp ugt <2 x i32> %add, <i32 3, i32 3>
%sel = select <2 x i1> %cmp, <2 x i32> <i32 -5, i32 -5>, <2 x i32> <i32 3, i32 3>
ret <2 x i32> %sel
}
; CHECK: !0 = !{!"branch_weights", i32 1, i32 2000}