[llvm] [InstCombine]: Handle known negative variables with KnownBits (PR #89682)

via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 22 15:14:04 PDT 2024


https://github.com/AtariDreams created https://github.com/llvm/llvm-project/pull/89682

None

>From 4abc53adbff54d371c1751242480ba28a8bfe3d8 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Mon, 22 Apr 2024 18:11:12 -0400
Subject: [PATCH 1/2] Pre-commit test (NFC)

---
 llvm/test/Transforms/InstCombine/udiv-simplify.ll | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/udiv-simplify.ll b/llvm/test/Transforms/InstCombine/udiv-simplify.ll
index bd6e5efc05f187..d454e705889612 100644
--- a/llvm/test/Transforms/InstCombine/udiv-simplify.ll
+++ b/llvm/test/Transforms/InstCombine/udiv-simplify.ll
@@ -98,6 +98,17 @@ define i8 @udiv_demanded_low_bits_set(i8 %a) {
   ret i8 %u
 }
 
+define i8 @udiv_large_value(i8 %a) {
+; CHECK-LABEL: @udiv_large_value(
+; CHECK-NEXT:    [[O:%.*]] = or i8 [[A:%.*]], -76
+; CHECK-NEXT:    [[U:%.*]] = udiv i8 [[A]], [[O]]
+; CHECK-NEXT:    ret i8 [[U]]
+;
+  %o = or i8 %a, 180
+  %u = udiv i8 %a, %o
+  ret i8 %u
+}
+
 ; This can't divide evenly, so it is poison.
 
 define i8 @udiv_exact_demanded_low_bits_set(i8 %a) {

>From d1977c04c8b0b96c4f2f2049f0355e46e2ef3235 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Mon, 22 Apr 2024 18:09:33 -0400
Subject: [PATCH 2/2] [InstCombine]: Handle known negative variables with
 KnownBits

---
 llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 8 +++++++-
 llvm/test/Transforms/InstCombine/udiv-simplify.ll        | 5 +++--
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 4ed4c36e21e016..f03c31e613d601 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -1491,12 +1491,18 @@ Instruction *InstCombinerImpl::visitUDiv(BinaryOperator &I) {
   }
 
   // Op0 / C where C is large (negative) --> zext (Op0 >= C)
-  // TODO: Could use isKnownNegative() to handle non-constant values.
   Type *Ty = I.getType();
   if (match(Op1, m_Negative())) {
     Value *Cmp = Builder.CreateICmpUGE(Op0, Op1);
     return CastInst::CreateZExtOrBitCast(Cmp, Ty);
   }
+
+  KnownBits Known = computeKnownBits(Op1, 0, &I);
+  if (Known.isNegative()) {
+    Value *Cmp = Builder.CreateICmpUGE(Op0, Op1);
+    return CastInst::CreateZExtOrBitCast(Cmp, Ty);
+  }
+
   // Op0 / (sext i1 X) --> zext (Op0 == -1) (if X is 0, the div is undefined)
   if (match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) {
     Value *Cmp = Builder.CreateICmpEQ(Op0, ConstantInt::getAllOnesValue(Ty));
diff --git a/llvm/test/Transforms/InstCombine/udiv-simplify.ll b/llvm/test/Transforms/InstCombine/udiv-simplify.ll
index d454e705889612..82532e3e6ff8c9 100644
--- a/llvm/test/Transforms/InstCombine/udiv-simplify.ll
+++ b/llvm/test/Transforms/InstCombine/udiv-simplify.ll
@@ -100,8 +100,9 @@ define i8 @udiv_demanded_low_bits_set(i8 %a) {
 
 define i8 @udiv_large_value(i8 %a) {
 ; CHECK-LABEL: @udiv_large_value(
-; CHECK-NEXT:    [[O:%.*]] = or i8 [[A:%.*]], -76
-; CHECK-NEXT:    [[U:%.*]] = udiv i8 [[A]], [[O]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[A:%.*]], -76
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[TMP1]], -76
+; CHECK-NEXT:    [[U:%.*]] = zext i1 [[TMP2]] to i8
 ; CHECK-NEXT:    ret i8 [[U]]
 ;
   %o = or i8 %a, 180



More information about the llvm-commits mailing list