Skip to content

Commit 0fdcca0

Browse files
committed
[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..
1 parent 66b6698 commit 0fdcca0

File tree

2 files changed

+9
-1
lines changed

2 files changed

+9
-1
lines changed

llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,13 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) {
11821182
return BO;
11831183
}
11841184

1185+
if (match(Op1, m_NegatedPower2())) {
1186+
// X sdiv (-(1 << C)) -> -(X sdiv (1 << C)) ->
1187+
// -> -(X udiv (1 << C)) -> -(X u>> C)
1188+
return BinaryOperator::CreateNeg(Builder.Insert(foldUDivPow2Cst(
1189+
Op0, ConstantExpr::getNeg(cast<Constant>(Op1)), I, *this)));
1190+
}
1191+
11851192
if (isKnownToBeAPowerOfTwo(Op1, /*OrZero*/ true, 0, &I)) {
11861193
// X sdiv (1 << Y) -> X udiv (1 << Y) ( -> X u>> Y)
11871194
// Safe because the only negative value (1 << Y) can take on is

llvm/test/Transforms/InstCombine/sdiv-of-non-negative-by-negative-power-of-two.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ define i8 @t0(i8 %x, i8 %y) {
1313
; CHECK-LABEL: @t0(
1414
; CHECK-NEXT: [[X_IS_NONNEGATIVE:%.*]] = icmp sgt i8 [[X:%.*]], -1
1515
; CHECK-NEXT: call void @llvm.assume(i1 [[X_IS_NONNEGATIVE]])
16-
; CHECK-NEXT: [[DIV:%.*]] = sdiv i8 [[X]], -32
16+
; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[X]], 5
17+
; CHECK-NEXT: [[DIV:%.*]] = sub nsw i8 0, [[TMP1]]
1718
; CHECK-NEXT: ret i8 [[DIV]]
1819
;
1920
%x_is_nonnegative = icmp sge i8 %x, 0

0 commit comments

Comments
 (0)