[llvm] [InstCombine]: Handle known negative variables with KnownBits (PR #89682)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 22 15:14:37 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: AtariDreams (AtariDreams)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/89682.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (+7-1)
- (modified) llvm/test/Transforms/InstCombine/udiv-simplify.ll (+12)
``````````diff
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 bd6e5efc05f187..82532e3e6ff8c9 100644
--- a/llvm/test/Transforms/InstCombine/udiv-simplify.ll
+++ b/llvm/test/Transforms/InstCombine/udiv-simplify.ll
@@ -98,6 +98,18 @@ 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: [[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
+ %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) {
``````````
</details>
https://github.com/llvm/llvm-project/pull/89682
More information about the llvm-commits
mailing list