Skip to content

Commit d1ecfaa

Browse files
committed
[SDAG] try to fold one-demanded-bit-of-multiply
This is a translation of the transform added to InstCombine with: D118539
1 parent 6a92949 commit d1ecfaa

File tree

2 files changed

+18
-13
lines changed

2 files changed

+18
-13
lines changed

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,6 +2265,19 @@ bool TargetLowering::SimplifyDemandedBits(
22652265
break;
22662266
}
22672267
case ISD::MUL:
2268+
if (DemandedBits.isPowerOf2()) {
2269+
// The LSB of X*Y is set only if (X & 1) == 1 and (Y & 1) == 1.
2270+
// If we demand exactly one bit N and we have "X * (C' << N)" where C' is
2271+
// odd (has LSB set), then the left-shifted low bit of X is the answer.
2272+
unsigned CTZ = DemandedBits.countTrailingZeros();
2273+
ConstantSDNode *C = isConstOrConstSplat(Op.getOperand(1), DemandedElts);
2274+
if (C && C->getAPIntValue().countTrailingZeros() == CTZ) {
2275+
EVT ShiftAmtTy = getShiftAmountTy(VT, TLO.DAG.getDataLayout());
2276+
SDValue AmtC = TLO.DAG.getConstant(CTZ, dl, ShiftAmtTy);
2277+
SDValue Shl = TLO.DAG.getNode(ISD::SHL, dl, VT, Op.getOperand(0), AmtC);
2278+
return TLO.CombineTo(Op, Shl);
2279+
}
2280+
}
22682281
// For a squared value "X * X", the bottom 2 bits are 0 and X[0] because:
22692282
// X * X is odd iff X is odd.
22702283
// 'Quadratic Reciprocity': X * X -> 0 for bit[1]

llvm/test/CodeGen/AArch64/combine-mul.ll

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ define <4 x i32> @combine_mul_self_demandedbits_vector(<4 x i32> %x) {
6666
define i8 @one_demanded_bit(i8 %x) {
6767
; CHECK-LABEL: one_demanded_bit:
6868
; CHECK: // %bb.0:
69-
; CHECK-NEXT: neg w8, w0, lsl #6
69+
; CHECK-NEXT: lsl w8, w0, #6
7070
; CHECK-NEXT: orr w0, w8, #0xffffffbf
7171
; CHECK-NEXT: ret
7272
%m = mul i8 %x, 192 ; 0b1100_0000
@@ -77,16 +77,9 @@ define i8 @one_demanded_bit(i8 %x) {
7777
define <2 x i64> @one_demanded_bit_splat(<2 x i64> %x) {
7878
; CHECK-LABEL: one_demanded_bit_splat:
7979
; CHECK: // %bb.0:
80-
; CHECK-NEXT: fmov x8, d0
81-
; CHECK-NEXT: mov x9, v0.d[1]
82-
; CHECK-NEXT: add x8, x8, x8, lsl #2
83-
; CHECK-NEXT: lsl x8, x8, #5
84-
; CHECK-NEXT: add x9, x9, x9, lsl #2
85-
; CHECK-NEXT: fmov d0, x8
86-
; CHECK-NEXT: lsl x8, x9, #5
87-
; CHECK-NEXT: mov w9, #32
88-
; CHECK-NEXT: mov v0.d[1], x8
89-
; CHECK-NEXT: dup v1.2d, x9
80+
; CHECK-NEXT: mov w8, #32
81+
; CHECK-NEXT: shl v0.2d, v0.2d, #5
82+
; CHECK-NEXT: dup v1.2d, x8
9083
; CHECK-NEXT: and v0.16b, v0.16b, v1.16b
9184
; CHECK-NEXT: ret
9285
%m = mul <2 x i64> %x, <i64 160, i64 160> ; 0b1010_0000
@@ -97,8 +90,7 @@ define <2 x i64> @one_demanded_bit_splat(<2 x i64> %x) {
9790
define i32 @one_demanded_low_bit(i32 %x) {
9891
; CHECK-LABEL: one_demanded_low_bit:
9992
; CHECK: // %bb.0:
100-
; CHECK-NEXT: neg w8, w0
101-
; CHECK-NEXT: and w0, w8, #0x1
93+
; CHECK-NEXT: and w0, w0, #0x1
10294
; CHECK-NEXT: ret
10395
%m = mul i32 %x, -63 ; any odd number will do
10496
%r = and i32 %m, 1

0 commit comments

Comments
 (0)