[PATCH] D115459: [InstSimplify] Fold compare of no-wrap subtract

Hasyimi Bahrudin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 9 11:45:46 PST 2021


hasyimibhar created this revision.
Herald added a subscriber: hiraditya.
hasyimibhar requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Simplify (icmp nsw|nuw (sub X, C2), C) to true|false.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D115459

Files:
  llvm/lib/Analysis/InstructionSimplify.cpp
  llvm/test/Transforms/InstSimplify/icmp.ll


Index: llvm/test/Transforms/InstSimplify/icmp.ll
===================================================================
--- llvm/test/Transforms/InstSimplify/icmp.ll
+++ llvm/test/Transforms/InstSimplify/icmp.ll
@@ -211,3 +211,18 @@
   %sub2 = sub i32 42, %p2
   br label %loop
 }
+
+define i1 @test_negative_combined_sub_signed_overflow(i8 %x) {
+; CHECK-LABEL: @test_negative_combined_sub_signed_overflow(
+; CHECK-NEXT:    ret i1 false
+;
+  %y = sub nsw i8 127, %x
+  %z = icmp slt i8 %y, -1
+  ret i1 %z
+}
+
+define i1 @test_negative_combined_sub_unsigned_overflow(i64 %x) {
+  %y = sub nuw i64 10, %x
+  %z = icmp ult i64 %y, 11
+  ret i1 %z
+}
Index: llvm/lib/Analysis/InstructionSimplify.cpp
===================================================================
--- llvm/lib/Analysis/InstructionSimplify.cpp
+++ llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2832,6 +2832,54 @@
   return nullptr;
 }
 
+// Simplify (icmp (sub nuw/nsw C2, Y), C) to true/false.
+static Value *simplifyICmpWithNoWrapSub(CmpInst::Predicate Pred,
+                                        BinaryOperator *Sub, Value *RHS,
+                                        const InstrInfoQuery &IIQ) {
+  const APInt *C, *C2;
+
+  if (Sub->getOpcode() != Instruction::Sub)
+    return nullptr;
+  if (!match(RHS, m_APInt(C)))
+    return nullptr;
+  if (!match(Sub->getOperand(0), m_APInt(C2)))
+    return nullptr;
+
+  bool isNSW = IIQ.hasNoSignedWrap(Sub);
+  bool isNUW = IIQ.hasNoUnsignedWrap(Sub);
+
+  if (!(CmpInst::isUnsigned(Pred) && isNUW) &&
+      !(CmpInst::isSigned(Pred) && isNSW))
+    return nullptr;
+
+  Type *ITy = GetCompareTy(RHS); // The return type.
+
+  ConstantRange RHS_CR = ConstantRange::makeExactICmpRegion(Pred, *C);
+
+  if (RHS_CR.isEmptySet())
+    return ConstantInt::getFalse(ITy);
+  if (RHS_CR.isFullSet())
+    return ConstantInt::getTrue(ITy);
+
+  unsigned noWrapKind;
+  if (isNSW)
+    noWrapKind = OverflowingBinaryOperator::NoSignedWrap;
+  else
+    noWrapKind = OverflowingBinaryOperator::NoUnsignedWrap;
+
+  ConstantRange LHS_CR = ConstantRange(*C2).subWithNoWrap(
+      ConstantRange::getFull(C2->getBitWidth()), noWrapKind);
+
+  if (!LHS_CR.isFullSet()) {
+    if (RHS_CR.contains(LHS_CR))
+      return ConstantInt::getTrue(ITy);
+    if (RHS_CR.inverse().contains(LHS_CR))
+      return ConstantInt::getFalse(ITy);
+  }
+
+  return nullptr;
+}
+
 static Value *simplifyICmpWithConstant(CmpInst::Predicate Pred, Value *LHS,
                                        Value *RHS, const InstrInfoQuery &IIQ) {
   Type *ITy = GetCompareTy(RHS); // The return type.
@@ -3015,6 +3063,9 @@
       return getTrue(ITy);
   }
 
+  if (Value *V = simplifyICmpWithNoWrapSub(Pred, LBO, RHS, Q.IIQ))
+    return V;
+
   return nullptr;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D115459.393240.patch
Type: text/x-patch
Size: 2751 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211209/0f8d975a/attachment.bin>


More information about the llvm-commits mailing list