[llvm] fe97f95 - [InstCombine] propagate "exact" through folds of div
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 12 06:26:45 PDT 2022
Author: Sanjay Patel
Date: 2022-10-12T09:25:05-04:00
New Revision: fe97f95036674692dd85939c867c4312b73df88f
URL: https://github.com/llvm/llvm-project/commit/fe97f95036674692dd85939c867c4312b73df88f
DIFF: https://github.com/llvm/llvm-project/commit/fe97f95036674692dd85939c867c4312b73df88f.diff
LOG: [InstCombine] propagate "exact" through folds of div
These folds were added recently with:
6b869be8100d
8da2fa856f1b
...but they didn't account for the "exact" attribute,
and that can be safely propagated:
https://alive2.llvm.org/ce/z/F_WhnR
https://alive2.llvm.org/ce/z/ft9Cgr
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
llvm/test/Transforms/InstCombine/div-shift.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index c7a7be1886d9..b861406246ec 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -827,28 +827,34 @@ static Instruction *foldIDivShl(BinaryOperator &I,
Type *Ty = I.getType();
// With appropriate no-wrap constraints, remove a common factor in the
- // dividend and divisor that is disguised as a left-shift.
+ // dividend and divisor that is disguised as a left-shifted value.
Value *X, *Y, *Z;
- if (match(Op1, m_Shl(m_Value(X), m_Value(Z))) &&
- match(Op0, m_c_Mul(m_Specific(X), m_Value(Y)))) {
- // Both operands must have the matching no-wrap for this kind of division.
- auto *Mul = cast<OverflowingBinaryOperator>(Op0);
- auto *Shl = cast<OverflowingBinaryOperator>(Op1);
- bool HasNUW = Mul->hasNoUnsignedWrap() && Shl->hasNoUnsignedWrap();
- bool HasNSW = Mul->hasNoSignedWrap() && Shl->hasNoSignedWrap();
-
- // (X * Y) u/ (X << Z) --> Y u>> Z
- if (!IsSigned && HasNUW)
- return BinaryOperator::CreateLShr(Y, Z);
-
- // (X * Y) s/ (X << Z) --> Y s/ (1 << Z)
- if (IsSigned && HasNSW && (Op0->hasOneUse() || Op1->hasOneUse())) {
- Value *Shl = Builder.CreateShl(ConstantInt::get(Ty, 1), Z);
- return BinaryOperator::CreateSDiv(Y, Shl);
- }
+ if (!match(Op1, m_Shl(m_Value(X), m_Value(Z))) ||
+ !match(Op0, m_c_Mul(m_Specific(X), m_Value(Y))))
+ return nullptr;
+
+ // Both operands must have the matching no-wrap for this kind of division.
+ Instruction *Ret = nullptr;
+ auto *Mul = cast<OverflowingBinaryOperator>(Op0);
+ auto *Shl = cast<OverflowingBinaryOperator>(Op1);
+ bool HasNUW = Mul->hasNoUnsignedWrap() && Shl->hasNoUnsignedWrap();
+ bool HasNSW = Mul->hasNoSignedWrap() && Shl->hasNoSignedWrap();
+
+ // (X * Y) u/ (X << Z) --> Y u>> Z
+ if (!IsSigned && HasNUW)
+ Ret = BinaryOperator::CreateLShr(Y, Z);
+
+ // (X * Y) s/ (X << Z) --> Y s/ (1 << Z)
+ if (IsSigned && HasNSW && (Op0->hasOneUse() || Op1->hasOneUse())) {
+ Value *Shl = Builder.CreateShl(ConstantInt::get(Ty, 1), Z);
+ Ret = BinaryOperator::CreateSDiv(Y, Shl);
}
- return nullptr;
+ if (!Ret)
+ return nullptr;
+
+ Ret->setIsExact(I.isExact());
+ return Ret;
}
/// This function implements the transforms common to both integer division
diff --git a/llvm/test/Transforms/InstCombine/div-shift.ll b/llvm/test/Transforms/InstCombine/div-shift.ll
index d357ec742894..bac752a750db 100644
--- a/llvm/test/Transforms/InstCombine/div-shift.ll
+++ b/llvm/test/Transforms/InstCombine/div-shift.ll
@@ -314,7 +314,7 @@ define i5 @sdiv_mul_shl_nsw(i5 %x, i5 %y, i5 %z) {
define i5 @sdiv_mul_shl_nsw_exact_commute1(i5 %x, i5 %y, i5 %z) {
; CHECK-LABEL: @sdiv_mul_shl_nsw_exact_commute1(
; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i5 1, [[Z:%.*]]
-; CHECK-NEXT: [[D:%.*]] = sdiv i5 [[Y:%.*]], [[TMP1]]
+; CHECK-NEXT: [[D:%.*]] = sdiv exact i5 [[Y:%.*]], [[TMP1]]
; CHECK-NEXT: ret i5 [[D]]
;
%m1 = mul nsw i5 %y, %x
@@ -453,7 +453,7 @@ define i5 @udiv_mul_shl_nuw(i5 %x, i5 %y, i5 %z) {
define i5 @udiv_mul_shl_nuw_exact_commute1(i5 %x, i5 %y, i5 %z) {
; CHECK-LABEL: @udiv_mul_shl_nuw_exact_commute1(
-; CHECK-NEXT: [[D:%.*]] = lshr i5 [[Y:%.*]], [[Z:%.*]]
+; CHECK-NEXT: [[D:%.*]] = lshr exact i5 [[Y:%.*]], [[Z:%.*]]
; CHECK-NEXT: ret i5 [[D]]
;
%m1 = mul nuw i5 %y, %x
More information about the llvm-commits
mailing list