[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