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

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 14 08:21:04 PST 2021


Author: Sanjay Patel
Date: 2021-12-14T11:18:36-05:00
New Revision: bb2fc19c6355d990a4cfb94be20528fbe37950a8

URL: https://github.com/llvm/llvm-project/commit/bb2fc19c6355d990a4cfb94be20528fbe37950a8
DIFF: https://github.com/llvm/llvm-project/commit/bb2fc19c6355d990a4cfb94be20528fbe37950a8.diff

LOG: [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

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
    llvm/test/Transforms/InstCombine/reuse-constant-from-select-in-icmp.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 518d3952dce5..a6d6b5199105 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -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)));

diff  --git a/llvm/test/Transforms/InstCombine/reuse-constant-from-select-in-icmp.ll b/llvm/test/Transforms/InstCombine/reuse-constant-from-select-in-icmp.ll
index 6eb21466e603..1c768f9d0818 100644
--- a/llvm/test/Transforms/InstCombine/reuse-constant-from-select-in-icmp.ll
+++ b/llvm/test/Transforms/InstCombine/reuse-constant-from-select-in-icmp.ll
@@ -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}


        


More information about the llvm-commits mailing list