[PATCH] D134706: [AArch64] Lower multiplication by a constant int to shl+sub+shl
Allen zhong via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 27 00:26:27 PDT 2022
Allen created this revision.
Allen added reviewers: dmgreen, efriedma.
Herald added subscribers: hiraditya, kristof.beyls.
Herald added a project: All.
Allen requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
Decompose the const 14 can be separated from D132322 <https://reviews.llvm.org/D132322>
Change the costmodel to lower a = b * C where C = 2^n - 2^m to
lsl w8, w0, n
sub w0, w8, w0, lsl m
https://reviews.llvm.org/D134706
Files:
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
llvm/test/CodeGen/AArch64/mul_pow2.ll
Index: llvm/test/CodeGen/AArch64/mul_pow2.ll
===================================================================
--- llvm/test/CodeGen/AArch64/mul_pow2.ll
+++ llvm/test/CodeGen/AArch64/mul_pow2.ll
@@ -408,8 +408,8 @@
define i32 @test14(i32 %x) {
; CHECK-LABEL: test14:
; CHECK: // %bb.0:
-; CHECK-NEXT: mov w8, #14
-; CHECK-NEXT: mul w0, w0, w8
+; CHECK-NEXT: lsl w8, w0, #4
+; CHECK-NEXT: sub w0, w8, w0, lsl #1
; CHECK-NEXT: ret
;
; GISEL-LABEL: test14:
Index: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -14799,7 +14799,7 @@
// More aggressively, some multiplications N0 * C can be lowered to
// shift+add+shift if the constant C = A * B where A = 2^N + 1 and B = 2^M,
// e.g. 6=3*2=(2+1)*2.
- // TODO: consider lowering more cases, e.g. C = 14, -6, -14 or even 45
+ // TODO: consider lowering more cases, e.g. C = -6, -14 or even 45
// which equals to (1+2)*16-(1+2).
// TrailingZeroes is used to test if the mul can be lowered to
@@ -14826,12 +14826,16 @@
bool ShiftValUseIsN0 = true;
// Do we need to negate the result?
bool NegateResult = false;
+ // Is the sub has 2 shifted value operands?
+ bool Sub2Shift = false;
if (ConstValue.isNonNegative()) {
// (mul x, 2^N + 1) => (add (shl x, N), x)
// (mul x, 2^N - 1) => (sub (shl x, N), x)
// (mul x, (2^N + 1) * 2^M) => (shl (add (shl x, N), x), M)
+ // (mul x, (2^(N-M) - 1) * 2^M) => (sub (shl x, N), (shl x, M))
APInt SCVMinus1 = ShiftedConstValue - 1;
+ APInt SCVPlus1 = ShiftedConstValue + 1;
APInt CVPlus1 = ConstValue + 1;
if (SCVMinus1.isPowerOf2()) {
ShiftAmt = SCVMinus1.logBase2();
@@ -14839,6 +14843,10 @@
} else if (CVPlus1.isPowerOf2()) {
ShiftAmt = CVPlus1.logBase2();
AddSubOpc = ISD::SUB;
+ } else if (SCVPlus1.isPowerOf2()) {
+ ShiftAmt = SCVPlus1.logBase2() + TrailingZeroes;
+ AddSubOpc = ISD::SUB;
+ Sub2Shift = true;
} else
return SDValue();
} else {
@@ -14858,11 +14866,15 @@
return SDValue();
}
- SDValue ShiftedVal = DAG.getNode(ISD::SHL, DL, VT, N0,
- DAG.getConstant(ShiftAmt, DL, MVT::i64));
-
- SDValue AddSubN0 = ShiftValUseIsN0 ? ShiftedVal : N0;
- SDValue AddSubN1 = ShiftValUseIsN0 ? N0 : ShiftedVal;
+ SDValue ShiftedVal0 = DAG.getNode(ISD::SHL, DL, VT, N0,
+ DAG.getConstant(ShiftAmt, DL, MVT::i64));
+ if (Sub2Shift) {
+ SDValue ShiftedVal1 = DAG.getNode(
+ ISD::SHL, DL, VT, N0, DAG.getConstant(TrailingZeroes, DL, MVT::i64));
+ return DAG.getNode(ISD::SUB, DL, VT, ShiftedVal0, ShiftedVal1);
+ }
+ SDValue AddSubN0 = ShiftValUseIsN0 ? ShiftedVal0 : N0;
+ SDValue AddSubN1 = ShiftValUseIsN0 ? N0 : ShiftedVal0;
SDValue Res = DAG.getNode(AddSubOpc, DL, VT, AddSubN0, AddSubN1);
assert(!(NegateResult && TrailingZeroes) &&
"NegateResult and TrailingZeroes cannot both be true for now.");
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D134706.463116.patch
Type: text/x-patch
Size: 3133 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220927/5d1eb0dd/attachment-0001.bin>
More information about the llvm-commits
mailing list