[llvm] [InstCombine] `A == MIN_INT ? B != MIN_INT : A < B` to `A < B` (PR #120177)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 17 21:10:15 PST 2024


================
@@ -1781,6 +1781,51 @@ static Value *foldSelectInstWithICmpConst(SelectInst &SI, ICmpInst *ICI,
   return nullptr;
 }
 
+/// `A == MIN_INT ? B != MIN_INT : A < B` --> `A < B`
+/// `A == MAX_INT ? B != MAX_INT : A > B` --> `A > B`
+static Value *foldSelectWithExtremeEqCond(Value *CmpLHS, Value *CmpRHS,
+                                          Value *TrueVal, Value *FalseVal,
+                                          IRBuilderBase &Builder) {
+  CmpPredicate Pred;
+  Value *A, *B;
+
+  if (!match(FalseVal, m_ICmp(Pred, m_Value(A), m_Value(B))))
+    return nullptr;
+
+  Type *Ty = A->getType();
+
+  if (Ty->isPointerTy())
+    return nullptr;
+
+  // make sure `CmpLHS` is on the LHS of `FalseVal`.
+  if (CmpLHS == B) {
+    std::swap(A, B);
+    Pred = CmpInst::getSwappedPredicate(Pred);
+  }
+
+  APInt C;
+  unsigned BitWidth = Ty->getScalarSizeInBits();
+
+  if (ICmpInst::isLT(Pred)) {
+    C = CmpInst::isSigned(Pred) ? APInt::getSignedMinValue(BitWidth)
+                                : APInt::getMinValue(BitWidth);
+  } else if (ICmpInst::isGT(Pred)) {
+    C = CmpInst::isSigned(Pred) ? APInt::getSignedMaxValue(BitWidth)
+                                : APInt::getMaxValue(BitWidth);
+  } else {
+    return nullptr;
+  }
+
+  if (!match(CmpLHS, m_Specific(A)) || !match(CmpRHS, m_SpecificInt(C)))
----------------
dtcxzyw wrote:

```suggestion
  if (CmpLHS != A || !match(CmpRHS, m_SpecificInt(C)))
```
May be better to move the `CmpLHS != A` check before the construction of C?

https://github.com/llvm/llvm-project/pull/120177


More information about the llvm-commits mailing list