[llvm] [InstCombine] Fold -X / -Y -> X / Y (PR #88422)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 12 08:30:58 PDT 2024
https://github.com/AtariDreams updated https://github.com/llvm/llvm-project/pull/88422
>From 882b69ad496abe6de3a2fedcfb1a75716dd9d0b0 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Thu, 11 Apr 2024 13:56:36 -0400
Subject: [PATCH 1/2] [InstCombine] Pre-commit tests (NFC)
---
llvm/test/Transforms/InstCombine/div.ll | 48 +++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/div.ll b/llvm/test/Transforms/InstCombine/div.ll
index e8a25ff44d0296..03db721b770bb8 100644
--- a/llvm/test/Transforms/InstCombine/div.ll
+++ b/llvm/test/Transforms/InstCombine/div.ll
@@ -1648,6 +1648,54 @@ define i32 @sdiv_mul_nsw_sub_nsw(i32 %x, i32 %y) {
ret i32 %d
}
+define i32 @sdiv_neg_divisor_known_non_min(i32 %x, i32 %z) {
+; CHECK-LABEL: @sdiv_neg_divisor_known_non_min(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[OR:%.*]] = or i32 [[Z:%.*]], 1
+; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[Z1:%.*]]
+; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[OR]], [[SUB]]
+; CHECK-NEXT: ret i32 [[DIV]]
+;
+entry:
+ %or = or i32 %x, 1
+ %sub = sub nsw i32 0, %z
+ %div = sdiv i32 %or, %sub
+ ret i32 %div
+}
+
+define i32 @double_negative_division_known_non_int_min(i32 %x, i32 %z) {
+; CHECK-LABEL: @double_negative_division_known_non_int_min(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[Z:%.*]] = or i32 [[Z1:%.*]], 1
+; CHECK-NEXT: [[SUB1:%.*]] = sub nsw i32 0, [[Z2:%.*]]
+; CHECK-NEXT: [[DIV21:%.*]] = sdiv i32 [[Z]], [[SUB1]]
+; CHECK-NEXT: [[DIV2:%.*]] = sub nsw i32 0, [[DIV21]]
+; CHECK-NEXT: ret i32 [[DIV2]]
+;
+entry:
+ %notMin = or i32 %x, 1
+ %sub2 = sub nsw i32 0, %notMin
+ %sub1 = sub nsw i32 0, %z
+ %div2 = sdiv i32 %sub2, %sub1
+ ret i32 %div2
+}
+
+; Negative test
+
+define i32 @negative_divisior_only(i32 %x, i32 %z) {
+; CHECK-LABEL: @negative_divisior_only(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[SUB1:%.*]] = sub nsw i32 0, [[Z:%.*]]
+; CHECK-NEXT: [[DIV2:%.*]] = sdiv i32 [[X:%.*]], [[SUB1]]
+; CHECK-NEXT: ret i32 [[DIV2]]
+;
+entry:
+ %sub1 = sub nsw i32 0, %z
+ %div2 = sdiv i32 %x, %sub1
+ ret i32 %div2
+}
+
+
; exact propagates
define i8 @sdiv_sdiv_mul_nsw_exact_exact(i8 %x, i8 %y, i8 %z) {
>From 392bfa536620f538c229d024248f878933300e52 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Thu, 11 Apr 2024 13:58:15 -0400
Subject: [PATCH 2/2] [InstCombine] Fold -X / -Y -> X / Y, and X / -Y -> -(X /
Y) if X is known to not be INT_MIN
Alive Proofs:
https://alive2.llvm.org/ce/z/zLMokH
https://alive2.llvm.org/ce/z/xviNg3
https://alive2.llvm.org/ce/z/4rdGvf
https://alive2.llvm.org/ce/z/LDqsa_
---
.../InstCombine/InstCombineMulDivRem.cpp | 21 +++++++++++++++----
llvm/test/Transforms/InstCombine/div.ll | 14 ++++++-------
2 files changed, 23 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 4dc1319f1c437f..b94a34b475f59d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -1581,10 +1581,24 @@ Instruction *InstCombinerImpl::visitSDiv(BinaryOperator &I) {
}
// -X / Y --> -(X / Y)
- Value *Y;
- if (match(&I, m_SDiv(m_OneUse(m_NSWNeg(m_Value(X))), m_Value(Y))))
+ if (match(Op0, m_OneUse(m_NSWNeg(m_Value(X)))))
return BinaryOperator::CreateNSWNeg(
- Builder.CreateSDiv(X, Y, I.getName(), I.isExact()));
+ Builder.CreateSDiv(X, Op1, I.getName(), I.isExact()));
+
+ // X / -Y --> -(X / Y), if X is known to not be INT_MIN,
+ // or -Y is known to not be -1.
+ Value *Y;
+ KnownBits KnownDividend = computeKnownBits(Op0, 0, &I);
+ if (match(Op1, m_OneUse(m_NSWNeg(m_Value(Y))))) {
+ KnownBits KnownDivisor = computeKnownBits(Op1, 0, &I);
+ if (!KnownDividend.getSignedMinValue().isMinSignedValue() ||
+ // FIXME: Hack for checking if is -1, which is just all ones
+ !KnownDivisor.getMaxValue().isMaxValue()) {
+
+ return BinaryOperator::CreateNSWNeg(
+ Builder.CreateSDiv(Op0, Y, I.getName(), I.isExact()));
+ }
+ }
// abs(X) / X --> X > -1 ? 1 : -1
// X / abs(X) --> X > -1 ? 1 : -1
@@ -1596,7 +1610,6 @@ Instruction *InstCombinerImpl::visitSDiv(BinaryOperator &I) {
ConstantInt::getAllOnesValue(Ty));
}
- KnownBits KnownDividend = computeKnownBits(Op0, 0, &I);
if (!I.isExact() &&
(match(Op1, m_Power2(Op1C)) || match(Op1, m_NegatedPower2(Op1C))) &&
KnownDividend.countMinTrailingZeros() >= Op1C->countr_zero()) {
diff --git a/llvm/test/Transforms/InstCombine/div.ll b/llvm/test/Transforms/InstCombine/div.ll
index 03db721b770bb8..93cc566c52ea6c 100644
--- a/llvm/test/Transforms/InstCombine/div.ll
+++ b/llvm/test/Transforms/InstCombine/div.ll
@@ -1651,10 +1651,10 @@ define i32 @sdiv_mul_nsw_sub_nsw(i32 %x, i32 %y) {
define i32 @sdiv_neg_divisor_known_non_min(i32 %x, i32 %z) {
; CHECK-LABEL: @sdiv_neg_divisor_known_non_min(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[OR:%.*]] = or i32 [[Z:%.*]], 1
-; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[Z1:%.*]]
-; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[OR]], [[SUB]]
-; CHECK-NEXT: ret i32 [[DIV]]
+; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], 1
+; CHECK-NEXT: [[DIV2:%.*]] = sdiv i32 [[OR]], [[DIV:%.*]]
+; CHECK-NEXT: [[DIV1:%.*]] = sub nsw i32 0, [[DIV2]]
+; CHECK-NEXT: ret i32 [[DIV1]]
;
entry:
%or = or i32 %x, 1
@@ -1667,10 +1667,8 @@ define i32 @double_negative_division_known_non_int_min(i32 %x, i32 %z) {
; CHECK-LABEL: @double_negative_division_known_non_int_min(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[Z:%.*]] = or i32 [[Z1:%.*]], 1
-; CHECK-NEXT: [[SUB1:%.*]] = sub nsw i32 0, [[Z2:%.*]]
-; CHECK-NEXT: [[DIV21:%.*]] = sdiv i32 [[Z]], [[SUB1]]
-; CHECK-NEXT: [[DIV2:%.*]] = sub nsw i32 0, [[DIV21]]
-; CHECK-NEXT: ret i32 [[DIV2]]
+; CHECK-NEXT: [[DIV21:%.*]] = sdiv i32 [[Z]], [[SUB1:%.*]]
+; CHECK-NEXT: ret i32 [[DIV21]]
;
entry:
%notMin = or i32 %x, 1
More information about the llvm-commits
mailing list