forked from OSchip/llvm-project
[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:
parent
d2be9ae0da
commit
bb2fc19c63
|
@ -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)));
|
||||
|
|
|
@ -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}
|
||||
|
|
Loading…
Reference in New Issue