[llvm] 0fdcca0 - [InstCombine] Fold X sdiv (-1 << C) -> -(X u>> Y) iff X is non-negative
Roman Lebedev via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 17 12:50:24 PDT 2020
Author: Roman Lebedev
Date: 2020-07-17T22:50:09+03:00
New Revision: 0fdcca07ad2c0bdc2cdd40ba638109926f4f513b
URL: https://github.com/llvm/llvm-project/commit/0fdcca07ad2c0bdc2cdd40ba638109926f4f513b
DIFF: https://github.com/llvm/llvm-project/commit/0fdcca07ad2c0bdc2cdd40ba638109926f4f513b.diff
LOG: [InstCombine] Fold X sdiv (-1 << C) -> -(X u>> Y) iff X is non-negative
This is the one i'm seeing as missed optimization,
although there are likely other possibilities, as usual.
There are 4 variants of a general sdiv->udiv fold:
https://rise4fun.com/Alive/VS6
Name: v0
Pre: C0 >= 0 && C1 >= 0
%r = sdiv i8 C0, C1
=>
%r = udiv i8 C0, C1
Name: v1
Pre: C0 <= 0 && C1 >= 0
%r = sdiv i8 C0, C1
=>
%t0 = udiv i8 -C0, C1
%r = sub i8 0, %t0
Name: v2
Pre: C0 >= 0 && C1 <= 0
%r = sdiv i8 C0, C1
=>
%t0 = udiv i8 C0, -C1
%r = sub i8 0, %t0
Name: v3
Pre: C0 <= 0 && C1 <= 0
%r = sdiv i8 C0, C1
=>
%r = udiv i8 -C0, -C1
If we really don't like sdiv (more than udiv that is),
and are okay with increasing instruction count (2 new negations),
and we ensure that we don't undo the fold,
then we could just implement these..
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
llvm/test/Transforms/InstCombine/sdiv-of-non-negative-by-negative-power-of-two.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index c6233a68847d..f039989c004c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -1182,6 +1182,13 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) {
return BO;
}
+ if (match(Op1, m_NegatedPower2())) {
+ // X sdiv (-(1 << C)) -> -(X sdiv (1 << C)) ->
+ // -> -(X udiv (1 << C)) -> -(X u>> C)
+ return BinaryOperator::CreateNeg(Builder.Insert(foldUDivPow2Cst(
+ Op0, ConstantExpr::getNeg(cast<Constant>(Op1)), I, *this)));
+ }
+
if (isKnownToBeAPowerOfTwo(Op1, /*OrZero*/ true, 0, &I)) {
// X sdiv (1 << Y) -> X udiv (1 << Y) ( -> X u>> Y)
// Safe because the only negative value (1 << Y) can take on is
diff --git a/llvm/test/Transforms/InstCombine/sdiv-of-non-negative-by-negative-power-of-two.ll b/llvm/test/Transforms/InstCombine/sdiv-of-non-negative-by-negative-power-of-two.ll
index c10a98a41acb..f9dd32bfc612 100644
--- a/llvm/test/Transforms/InstCombine/sdiv-of-non-negative-by-negative-power-of-two.ll
+++ b/llvm/test/Transforms/InstCombine/sdiv-of-non-negative-by-negative-power-of-two.ll
@@ -13,7 +13,8 @@ define i8 @t0(i8 %x, i8 %y) {
; CHECK-LABEL: @t0(
; CHECK-NEXT: [[X_IS_NONNEGATIVE:%.*]] = icmp sgt i8 [[X:%.*]], -1
; CHECK-NEXT: call void @llvm.assume(i1 [[X_IS_NONNEGATIVE]])
-; CHECK-NEXT: [[DIV:%.*]] = sdiv i8 [[X]], -32
+; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[X]], 5
+; CHECK-NEXT: [[DIV:%.*]] = sub nsw i8 0, [[TMP1]]
; CHECK-NEXT: ret i8 [[DIV]]
;
%x_is_nonnegative = icmp sge i8 %x, 0
More information about the llvm-commits
mailing list