[llvm] [InstCombine] Fold `icmp samesign u{gt/ge/lt/le} (X +nsw C2), C` -> `icmp s{gt/ge/lt/le} X, (C - C2)` (PR #169960)

Tirthankar Mazumder via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 30 10:21:22 PST 2025


================
@@ -3167,20 +3167,21 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
 
   // If the add does not wrap, we can always adjust the compare by subtracting
   // the constants. Equality comparisons are handled elsewhere. SGE/SLE/UGE/ULE
-  // are canonicalized to SGT/SLT/UGT/ULT.
-  if ((Add->hasNoSignedWrap() &&
-       (Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLT)) ||
-      (Add->hasNoUnsignedWrap() &&
-       (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_ULT))) {
+  // has been canonicalized to SGT/SLT/UGT/ULT.
+  CmpInst::Predicate ChosenPred = Pred.getPreferredSignedPredicate();
+  if ((Add->hasNoSignedWrap() && (ChosenPred == ICmpInst::ICMP_SGT ||
+                                  ChosenPred == ICmpInst::ICMP_SLT)) ||
+      (Add->hasNoUnsignedWrap() && (ChosenPred == ICmpInst::ICMP_UGT ||
+                                    ChosenPred == ICmpInst::ICMP_ULT))) {
     bool Overflow;
-    APInt NewC =
-        Cmp.isSigned() ? C.ssub_ov(*C2, Overflow) : C.usub_ov(*C2, Overflow);
+    APInt NewC = ICmpInst::isSigned(ChosenPred) ? C.ssub_ov(*C2, Overflow)
+                                                : C.usub_ov(*C2, Overflow);
     // If there is overflow, the result must be true or false.
     // TODO: Can we assert there is no overflow because InstSimplify always
     // handles those cases?
----------------
wermos wrote:

Can this comment be removed? If I understood this comment correctly, then it is obvious that there _are_ cases where an overflow can happen so this defensive code is needed. Specifically, the `@icmp_samesign_with_nsw_add_neg` test causes an overflow to happen.

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


More information about the llvm-commits mailing list