[llvm] [InstCombine] Fold the bound check idiom into sign bit test (PR #76439)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 7 04:02:15 PST 2024


================
@@ -2636,6 +2636,26 @@ Instruction *InstCombinerImpl::foldICmpDivConstant(ICmpInst &Cmp,
   if (!match(Y, m_APInt(C2)))
     return nullptr;
 
+  // Fold the bound check idiom:
+  //  T *end, *start;
+  //  (size_t)(end - start) > (size_t)(PTRDIFF_MAX / sizeof(T))
+  // into:
+  //  (ptrdiff_t)(end - start) < 0
+  // i.e.:
+  //   icmp ugt (sdiv exact X, C2), (sdiv signed_max, C2) --> icmp slt X, 0
+  //   icmp ult (sdiv exact X, C2), (sdiv signed_max, C2) + 1 --> icmp sgt X, -1
+  // where C2 is positive.
+  if (DivIsSigned && Div->hasOneUse() && Div->isExact() &&
+      (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_ULT) &&
+      C2->isStrictlyPositive() &&
+      APInt::getSignedMaxValue(C2->getBitWidth()).sdiv(*C2) +
+              APInt(C2->getBitWidth(), Pred == ICmpInst::ICMP_UGT ? 0 : 1) ==
+          C)
----------------
dtcxzyw wrote:

> The ugt would become slt 0 for the right boundary.

We will fold `icmp ugt i64 (sdiv exact i64 %x, 24), 384307168202282325` into `icmp ugt i64 %x, 9223372036854775800`. The latter form cannot be simplified into `icmp slt i64 %x, 0`.
Alive2: https://alive2.llvm.org/ce/z/WEPmRN


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


More information about the llvm-commits mailing list