[llvm] [RISCV] Strength reduce mul by 2^N - 2^M (PR #88983)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 16 13:45:13 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Philip Reames (preames)
<details>
<summary>Changes</summary>
This is a three instruction expansion, and does not depend on zba, so most of the test changes are in base RV32/64I configurations.
With zba, this gets immediates such as 14, 28, 30, 56, 60, 62.. which aren't covered by our other expansions.
---
Patch is 42.06 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/88983.diff
14 Files Affected:
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+39-24)
- (modified) llvm/test/CodeGen/RISCV/mul.ll (+80-84)
- (modified) llvm/test/CodeGen/RISCV/rv32xtheadba.ll (+12-8)
- (modified) llvm/test/CodeGen/RISCV/rv32zba.ll (+12-8)
- (modified) llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zba.ll (+18-16)
- (modified) llvm/test/CodeGen/RISCV/rv64xtheadba.ll (+12-8)
- (modified) llvm/test/CodeGen/RISCV/rv64zba.ll (+27-23)
- (modified) llvm/test/CodeGen/RISCV/rvv/calling-conv-fastcc.ll (+48-50)
- (modified) llvm/test/CodeGen/RISCV/rvv/extract-subvector.ll (+6-6)
- (modified) llvm/test/CodeGen/RISCV/rvv/mscatter-combine.ll (+5-3)
- (modified) llvm/test/CodeGen/RISCV/rvv/setcc-fp-vp.ll (+9-9)
- (modified) llvm/test/CodeGen/RISCV/rvv/stepvector.ll (+7-6)
- (modified) llvm/test/CodeGen/RISCV/srem-seteq-illegal-types.ll (+42-37)
- (modified) llvm/test/CodeGen/RISCV/urem-vector-lkk.ll (+24-22)
``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7b4bec2f65b741..6a2ca5699c8a42 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -13408,8 +13408,8 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
if (VT != Subtarget.getXLenVT())
return SDValue();
- if (!Subtarget.hasStdExtZba() && !Subtarget.hasVendorXTHeadBa())
- return SDValue();
+ const bool HasShlAdd =
+ Subtarget.hasStdExtZba() || Subtarget.hasVendorXTHeadBa();
ConstantSDNode *CNode = dyn_cast<ConstantSDNode>(N->getOperand(1));
if (!CNode)
@@ -13418,14 +13418,15 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
// 3/5/9 * 2^N -> shXadd (sll X, C), (sll X, C)
// Matched in tablegen, avoid perturbing patterns.
- for (uint64_t Divisor : {3, 5, 9})
- if (MulAmt % Divisor == 0 && isPowerOf2_64(MulAmt / Divisor))
- return SDValue();
+ if (HasShlAdd)
+ for (uint64_t Divisor : {3, 5, 9})
+ if (MulAmt % Divisor == 0 && isPowerOf2_64(MulAmt / Divisor))
+ return SDValue();
// If this is a power 2 + 2/4/8, we can use a shift followed by a single
// shXadd. First check if this a sum of two power of 2s because that's
// easy. Then count how many zeros are up to the first bit.
- if (isPowerOf2_64(MulAmt & (MulAmt - 1))) {
+ if (HasShlAdd && isPowerOf2_64(MulAmt & (MulAmt - 1))) {
unsigned ScaleShift = llvm::countr_zero(MulAmt);
if (ScaleShift >= 1 && ScaleShift < 4) {
unsigned ShiftAmt = Log2_64((MulAmt & (MulAmt - 1)));
@@ -13440,26 +13441,27 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
// 2^(1,2,3) * 3,5,9 + 1 -> (shXadd (shYadd x, x), x)
// Matched in tablegen, avoid perturbing patterns.
- switch (MulAmt) {
- case 11:
- case 13:
- case 19:
- case 21:
- case 25:
- case 27:
- case 29:
- case 37:
- case 41:
- case 45:
- case 73:
- case 91:
- return SDValue();
- default:
- break;
- }
+ if (HasShlAdd)
+ switch (MulAmt) {
+ case 11:
+ case 13:
+ case 19:
+ case 21:
+ case 25:
+ case 27:
+ case 29:
+ case 37:
+ case 41:
+ case 45:
+ case 73:
+ case 91:
+ return SDValue();
+ default:
+ break;
+ }
// 2^n + 2/4/8 + 1 -> (add (shl X, C1), (shXadd X, X))
- if (MulAmt > 2 && isPowerOf2_64((MulAmt - 1) & (MulAmt - 2))) {
+ if (HasShlAdd && MulAmt > 2 && isPowerOf2_64((MulAmt - 1) & (MulAmt - 2))) {
unsigned ScaleShift = llvm::countr_zero(MulAmt - 1);
if (ScaleShift >= 1 && ScaleShift < 4) {
unsigned ShiftAmt = Log2_64(((MulAmt - 1) & (MulAmt - 2)));
@@ -13474,6 +13476,19 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
}
}
+ // 2^N - 2^M -> (sub (shl X, C1), (shl X, C2))
+ uint64_t MulAmtLowBit = MulAmt & (-MulAmt);
+ if (isPowerOf2_64(MulAmt + MulAmtLowBit)) {
+ uint64_t ShiftAmt1 = MulAmt + MulAmtLowBit;
+ SDLoc DL(N);
+ SDValue Shift1 = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
+ DAG.getConstant(Log2_64(ShiftAmt1), DL, VT));
+ SDValue Shift2 =
+ DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
+ DAG.getConstant(Log2_64(MulAmtLowBit), DL, VT));
+ return DAG.getNode(ISD::SUB, DL, VT, Shift1, Shift2);
+ }
+
return SDValue();
}
diff --git a/llvm/test/CodeGen/RISCV/mul.ll b/llvm/test/CodeGen/RISCV/mul.ll
index 364e8c7b38dacc..395d6024e92030 100644
--- a/llvm/test/CodeGen/RISCV/mul.ll
+++ b/llvm/test/CodeGen/RISCV/mul.ll
@@ -473,24 +473,23 @@ define i32 @muli32_p14(i32 %a) nounwind {
;
; RV32IM-LABEL: muli32_p14:
; RV32IM: # %bb.0:
-; RV32IM-NEXT: li a1, 14
-; RV32IM-NEXT: mul a0, a0, a1
+; RV32IM-NEXT: slli a1, a0, 1
+; RV32IM-NEXT: slli a0, a0, 4
+; RV32IM-NEXT: sub a0, a0, a1
; RV32IM-NEXT: ret
;
; RV64I-LABEL: muli32_p14:
; RV64I: # %bb.0:
-; RV64I-NEXT: addi sp, sp, -16
-; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: li a1, 14
-; RV64I-NEXT: call __muldi3
-; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
-; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: slli a1, a0, 1
+; RV64I-NEXT: slli a0, a0, 4
+; RV64I-NEXT: sub a0, a0, a1
; RV64I-NEXT: ret
;
; RV64IM-LABEL: muli32_p14:
; RV64IM: # %bb.0:
-; RV64IM-NEXT: li a1, 14
-; RV64IM-NEXT: mulw a0, a0, a1
+; RV64IM-NEXT: slli a1, a0, 1
+; RV64IM-NEXT: slli a0, a0, 4
+; RV64IM-NEXT: subw a0, a0, a1
; RV64IM-NEXT: ret
%1 = mul i32 %a, 14
ret i32 %1
@@ -504,24 +503,23 @@ define i32 @muli32_p28(i32 %a) nounwind {
;
; RV32IM-LABEL: muli32_p28:
; RV32IM: # %bb.0:
-; RV32IM-NEXT: li a1, 28
-; RV32IM-NEXT: mul a0, a0, a1
+; RV32IM-NEXT: slli a1, a0, 2
+; RV32IM-NEXT: slli a0, a0, 5
+; RV32IM-NEXT: sub a0, a0, a1
; RV32IM-NEXT: ret
;
; RV64I-LABEL: muli32_p28:
; RV64I: # %bb.0:
-; RV64I-NEXT: addi sp, sp, -16
-; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: li a1, 28
-; RV64I-NEXT: call __muldi3
-; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
-; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: slli a1, a0, 2
+; RV64I-NEXT: slli a0, a0, 5
+; RV64I-NEXT: sub a0, a0, a1
; RV64I-NEXT: ret
;
; RV64IM-LABEL: muli32_p28:
; RV64IM: # %bb.0:
-; RV64IM-NEXT: li a1, 28
-; RV64IM-NEXT: mulw a0, a0, a1
+; RV64IM-NEXT: slli a1, a0, 2
+; RV64IM-NEXT: slli a0, a0, 5
+; RV64IM-NEXT: subw a0, a0, a1
; RV64IM-NEXT: ret
%1 = mul i32 %a, 28
ret i32 %1
@@ -535,24 +533,23 @@ define i32 @muli32_p30(i32 %a) nounwind {
;
; RV32IM-LABEL: muli32_p30:
; RV32IM: # %bb.0:
-; RV32IM-NEXT: li a1, 30
-; RV32IM-NEXT: mul a0, a0, a1
+; RV32IM-NEXT: slli a1, a0, 1
+; RV32IM-NEXT: slli a0, a0, 5
+; RV32IM-NEXT: sub a0, a0, a1
; RV32IM-NEXT: ret
;
; RV64I-LABEL: muli32_p30:
; RV64I: # %bb.0:
-; RV64I-NEXT: addi sp, sp, -16
-; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: li a1, 30
-; RV64I-NEXT: call __muldi3
-; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
-; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: slli a1, a0, 1
+; RV64I-NEXT: slli a0, a0, 5
+; RV64I-NEXT: sub a0, a0, a1
; RV64I-NEXT: ret
;
; RV64IM-LABEL: muli32_p30:
; RV64IM: # %bb.0:
-; RV64IM-NEXT: li a1, 30
-; RV64IM-NEXT: mulw a0, a0, a1
+; RV64IM-NEXT: slli a1, a0, 1
+; RV64IM-NEXT: slli a0, a0, 5
+; RV64IM-NEXT: subw a0, a0, a1
; RV64IM-NEXT: ret
%1 = mul i32 %a, 30
ret i32 %1
@@ -566,24 +563,23 @@ define i32 @muli32_p56(i32 %a) nounwind {
;
; RV32IM-LABEL: muli32_p56:
; RV32IM: # %bb.0:
-; RV32IM-NEXT: li a1, 56
-; RV32IM-NEXT: mul a0, a0, a1
+; RV32IM-NEXT: slli a1, a0, 3
+; RV32IM-NEXT: slli a0, a0, 6
+; RV32IM-NEXT: sub a0, a0, a1
; RV32IM-NEXT: ret
;
; RV64I-LABEL: muli32_p56:
; RV64I: # %bb.0:
-; RV64I-NEXT: addi sp, sp, -16
-; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: li a1, 56
-; RV64I-NEXT: call __muldi3
-; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
-; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: slli a1, a0, 3
+; RV64I-NEXT: slli a0, a0, 6
+; RV64I-NEXT: sub a0, a0, a1
; RV64I-NEXT: ret
;
; RV64IM-LABEL: muli32_p56:
; RV64IM: # %bb.0:
-; RV64IM-NEXT: li a1, 56
-; RV64IM-NEXT: mulw a0, a0, a1
+; RV64IM-NEXT: slli a1, a0, 3
+; RV64IM-NEXT: slli a0, a0, 6
+; RV64IM-NEXT: subw a0, a0, a1
; RV64IM-NEXT: ret
%1 = mul i32 %a, 56
ret i32 %1
@@ -597,24 +593,23 @@ define i32 @muli32_p60(i32 %a) nounwind {
;
; RV32IM-LABEL: muli32_p60:
; RV32IM: # %bb.0:
-; RV32IM-NEXT: li a1, 60
-; RV32IM-NEXT: mul a0, a0, a1
+; RV32IM-NEXT: slli a1, a0, 2
+; RV32IM-NEXT: slli a0, a0, 6
+; RV32IM-NEXT: sub a0, a0, a1
; RV32IM-NEXT: ret
;
; RV64I-LABEL: muli32_p60:
; RV64I: # %bb.0:
-; RV64I-NEXT: addi sp, sp, -16
-; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: li a1, 60
-; RV64I-NEXT: call __muldi3
-; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
-; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: slli a1, a0, 2
+; RV64I-NEXT: slli a0, a0, 6
+; RV64I-NEXT: sub a0, a0, a1
; RV64I-NEXT: ret
;
; RV64IM-LABEL: muli32_p60:
; RV64IM: # %bb.0:
-; RV64IM-NEXT: li a1, 60
-; RV64IM-NEXT: mulw a0, a0, a1
+; RV64IM-NEXT: slli a1, a0, 2
+; RV64IM-NEXT: slli a0, a0, 6
+; RV64IM-NEXT: subw a0, a0, a1
; RV64IM-NEXT: ret
%1 = mul i32 %a, 60
ret i32 %1
@@ -628,24 +623,23 @@ define i32 @muli32_p62(i32 %a) nounwind {
;
; RV32IM-LABEL: muli32_p62:
; RV32IM: # %bb.0:
-; RV32IM-NEXT: li a1, 62
-; RV32IM-NEXT: mul a0, a0, a1
+; RV32IM-NEXT: slli a1, a0, 1
+; RV32IM-NEXT: slli a0, a0, 6
+; RV32IM-NEXT: sub a0, a0, a1
; RV32IM-NEXT: ret
;
; RV64I-LABEL: muli32_p62:
; RV64I: # %bb.0:
-; RV64I-NEXT: addi sp, sp, -16
-; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: li a1, 62
-; RV64I-NEXT: call __muldi3
-; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
-; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: slli a1, a0, 1
+; RV64I-NEXT: slli a0, a0, 6
+; RV64I-NEXT: sub a0, a0, a1
; RV64I-NEXT: ret
;
; RV64IM-LABEL: muli32_p62:
; RV64IM: # %bb.0:
-; RV64IM-NEXT: li a1, 62
-; RV64IM-NEXT: mulw a0, a0, a1
+; RV64IM-NEXT: slli a1, a0, 1
+; RV64IM-NEXT: slli a0, a0, 6
+; RV64IM-NEXT: subw a0, a0, a1
; RV64IM-NEXT: ret
%1 = mul i32 %a, 62
ret i32 %1
@@ -943,24 +937,23 @@ define i32 @muli32_p384(i32 %a) nounwind {
;
; RV32IM-LABEL: muli32_p384:
; RV32IM: # %bb.0:
-; RV32IM-NEXT: li a1, 384
-; RV32IM-NEXT: mul a0, a0, a1
+; RV32IM-NEXT: slli a1, a0, 7
+; RV32IM-NEXT: slli a0, a0, 9
+; RV32IM-NEXT: sub a0, a0, a1
; RV32IM-NEXT: ret
;
; RV64I-LABEL: muli32_p384:
; RV64I: # %bb.0:
-; RV64I-NEXT: addi sp, sp, -16
-; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: li a1, 384
-; RV64I-NEXT: call __muldi3
-; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
-; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: slli a1, a0, 7
+; RV64I-NEXT: slli a0, a0, 9
+; RV64I-NEXT: sub a0, a0, a1
; RV64I-NEXT: ret
;
; RV64IM-LABEL: muli32_p384:
; RV64IM: # %bb.0:
-; RV64IM-NEXT: li a1, 384
-; RV64IM-NEXT: mulw a0, a0, a1
+; RV64IM-NEXT: slli a1, a0, 7
+; RV64IM-NEXT: slli a0, a0, 9
+; RV64IM-NEXT: subw a0, a0, a1
; RV64IM-NEXT: ret
%1 = mul i32 %a, 384
ret i32 %1
@@ -974,24 +967,23 @@ define i32 @muli32_p12288(i32 %a) nounwind {
;
; RV32IM-LABEL: muli32_p12288:
; RV32IM: # %bb.0:
-; RV32IM-NEXT: lui a1, 3
-; RV32IM-NEXT: mul a0, a0, a1
+; RV32IM-NEXT: slli a1, a0, 12
+; RV32IM-NEXT: slli a0, a0, 14
+; RV32IM-NEXT: sub a0, a0, a1
; RV32IM-NEXT: ret
;
; RV64I-LABEL: muli32_p12288:
; RV64I: # %bb.0:
-; RV64I-NEXT: addi sp, sp, -16
-; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT: lui a1, 3
-; RV64I-NEXT: call __muldi3
-; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
-; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: slli a1, a0, 12
+; RV64I-NEXT: slli a0, a0, 14
+; RV64I-NEXT: sub a0, a0, a1
; RV64I-NEXT: ret
;
; RV64IM-LABEL: muli32_p12288:
; RV64IM: # %bb.0:
-; RV64IM-NEXT: lui a1, 3
-; RV64IM-NEXT: mulw a0, a0, a1
+; RV64IM-NEXT: slli a1, a0, 12
+; RV64IM-NEXT: slli a0, a0, 14
+; RV64IM-NEXT: subw a0, a0, a1
; RV64IM-NEXT: ret
%1 = mul i32 %a, 12288
ret i32 %1
@@ -1191,12 +1183,16 @@ define i64 @muli64_p3840(i64 %a) nounwind {
;
; RV32IM-LABEL: muli64_p3840:
; RV32IM: # %bb.0:
+; RV32IM-NEXT: slli a2, a1, 8
+; RV32IM-NEXT: slli a1, a1, 12
+; RV32IM-NEXT: sub a1, a1, a2
; RV32IM-NEXT: li a2, 15
; RV32IM-NEXT: slli a2, a2, 8
-; RV32IM-NEXT: mul a1, a1, a2
-; RV32IM-NEXT: mulhu a3, a0, a2
-; RV32IM-NEXT: add a1, a3, a1
-; RV32IM-NEXT: mul a0, a0, a2
+; RV32IM-NEXT: mulhu a2, a0, a2
+; RV32IM-NEXT: add a1, a2, a1
+; RV32IM-NEXT: slli a2, a0, 8
+; RV32IM-NEXT: slli a0, a0, 12
+; RV32IM-NEXT: sub a0, a0, a2
; RV32IM-NEXT: ret
;
; RV64I-LABEL: muli64_p3840:
diff --git a/llvm/test/CodeGen/RISCV/rv32xtheadba.ll b/llvm/test/CodeGen/RISCV/rv32xtheadba.ll
index 3bf7704dd18360..332e49771bedf9 100644
--- a/llvm/test/CodeGen/RISCV/rv32xtheadba.ll
+++ b/llvm/test/CodeGen/RISCV/rv32xtheadba.ll
@@ -97,8 +97,9 @@ define i64 @th_addsl_2_extra_sext(i32 %x, i32 %y, i32 %z) {
define i32 @addmul6(i32 %a, i32 %b) {
; RV32I-LABEL: addmul6:
; RV32I: # %bb.0:
-; RV32I-NEXT: li a2, 6
-; RV32I-NEXT: mul a0, a0, a2
+; RV32I-NEXT: slli a2, a0, 1
+; RV32I-NEXT: slli a0, a0, 3
+; RV32I-NEXT: sub a0, a0, a2
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
@@ -133,8 +134,9 @@ define i32 @addmul10(i32 %a, i32 %b) {
define i32 @addmul12(i32 %a, i32 %b) {
; RV32I-LABEL: addmul12:
; RV32I: # %bb.0:
-; RV32I-NEXT: li a2, 12
-; RV32I-NEXT: mul a0, a0, a2
+; RV32I-NEXT: slli a2, a0, 2
+; RV32I-NEXT: slli a0, a0, 4
+; RV32I-NEXT: sub a0, a0, a2
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
@@ -187,8 +189,9 @@ define i32 @addmul20(i32 %a, i32 %b) {
define i32 @addmul24(i32 %a, i32 %b) {
; RV32I-LABEL: addmul24:
; RV32I: # %bb.0:
-; RV32I-NEXT: li a2, 24
-; RV32I-NEXT: mul a0, a0, a2
+; RV32I-NEXT: slli a2, a0, 3
+; RV32I-NEXT: slli a0, a0, 5
+; RV32I-NEXT: sub a0, a0, a2
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
@@ -259,8 +262,9 @@ define i32 @addmul72(i32 %a, i32 %b) {
define i32 @mul96(i32 %a) {
; RV32I-LABEL: mul96:
; RV32I: # %bb.0:
-; RV32I-NEXT: li a1, 96
-; RV32I-NEXT: mul a0, a0, a1
+; RV32I-NEXT: slli a1, a0, 5
+; RV32I-NEXT: slli a0, a0, 7
+; RV32I-NEXT: sub a0, a0, a1
; RV32I-NEXT: ret
;
; RV32XTHEADBA-LABEL: mul96:
diff --git a/llvm/test/CodeGen/RISCV/rv32zba.ll b/llvm/test/CodeGen/RISCV/rv32zba.ll
index cc632a09c8054b..9c720223dc06e1 100644
--- a/llvm/test/CodeGen/RISCV/rv32zba.ll
+++ b/llvm/test/CodeGen/RISCV/rv32zba.ll
@@ -63,8 +63,9 @@ define i64 @sh3add(i64 %0, ptr %1) {
define i32 @addmul6(i32 %a, i32 %b) {
; RV32I-LABEL: addmul6:
; RV32I: # %bb.0:
-; RV32I-NEXT: li a2, 6
-; RV32I-NEXT: mul a0, a0, a2
+; RV32I-NEXT: slli a2, a0, 1
+; RV32I-NEXT: slli a0, a0, 3
+; RV32I-NEXT: sub a0, a0, a2
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
@@ -99,8 +100,9 @@ define i32 @addmul10(i32 %a, i32 %b) {
define i32 @addmul12(i32 %a, i32 %b) {
; RV32I-LABEL: addmul12:
; RV32I: # %bb.0:
-; RV32I-NEXT: li a2, 12
-; RV32I-NEXT: mul a0, a0, a2
+; RV32I-NEXT: slli a2, a0, 2
+; RV32I-NEXT: slli a0, a0, 4
+; RV32I-NEXT: sub a0, a0, a2
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
@@ -153,8 +155,9 @@ define i32 @addmul20(i32 %a, i32 %b) {
define i32 @addmul24(i32 %a, i32 %b) {
; RV32I-LABEL: addmul24:
; RV32I: # %bb.0:
-; RV32I-NEXT: li a2, 24
-; RV32I-NEXT: mul a0, a0, a2
+; RV32I-NEXT: slli a2, a0, 3
+; RV32I-NEXT: slli a0, a0, 5
+; RV32I-NEXT: sub a0, a0, a2
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: ret
;
@@ -225,8 +228,9 @@ define i32 @addmul72(i32 %a, i32 %b) {
define i32 @mul96(i32 %a) {
; RV32I-LABEL: mul96:
; RV32I: # %bb.0:
-; RV32I-NEXT: li a1, 96
-; RV32I-NEXT: mul a0, a0, a1
+; RV32I-NEXT: slli a1, a0, 5
+; RV32I-NEXT: slli a0, a0, 7
+; RV32I-NEXT: sub a0, a0, a1
; RV32I-NEXT: ret
;
; RV32ZBA-LABEL: mul96:
diff --git a/llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zba.ll b/llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zba.ll
index ee9b73ca82f213..5c1001a0632434 100644
--- a/llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zba.ll
+++ b/llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zba.ll
@@ -369,8 +369,9 @@ define i64 @sh2add_extra_sext(i32 %x, i32 %y, i32 %z) {
define i64 @addmul6(i64 %a, i64 %b) {
; RV64I-LABEL: addmul6:
; RV64I: # %bb.0:
-; RV64I-NEXT: li a2, 6
-; RV64I-NEXT: mul a0, a0, a2
+; RV64I-NEXT: slli a2, a0, 1
+; RV64I-NEXT: slli a0, a0, 3
+; RV64I-NEXT: sub a0, a0, a2
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
@@ -405,8 +406,9 @@ define i64 @addmul10(i64 %a, i64 %b) {
define i64 @addmul12(i64 %a, i64 %b) {
; RV64I-LABEL: addmul12:
; RV64I: # %bb.0:
-; RV64I-NEXT: li a2, 12
-; RV64I-NEXT: mul a0, a0, a2
+; RV64I-NEXT: slli a2, a0, 2
+; RV64I-NEXT: slli a0, a0, 4
+; RV64I-NEXT: sub a0, a0, a2
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
@@ -459,8 +461,9 @@ define i64 @addmul20(i64 %a, i64 %b) {
define i64 @addmul24(i64 %a, i64 %b) {
; RV64I-LABEL: addmul24:
; RV64I: # %bb.0:
-; RV64I-NEXT: li a2, 24
-; RV64I-NEXT: mul a0, a0, a2
+; RV64I-NEXT: slli a2, a0, 3
+; RV64I-NEXT: slli a0, a0, 5
+; RV64I-NEXT: sub a0, a0, a2
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
@@ -531,8 +534,9 @@ define i64 @addmul72(i64 %a, i64 %b) {
define i64 @mul96(i64 %a) {
; RV64I-LABEL: mul96:
; RV64I: # %bb.0:
-; RV64I-NEXT: li a1, 96
-; RV64I-NEXT: mul a0, a0, a1
+; RV64I-NEXT: slli a1, a0, 5
+; RV64I-NEXT: slli a0, a0, 7
+; RV64I-NEXT: sub a0, a0, a1
; RV64I-NEXT: ret
;
; RV64ZBA-LABEL: mul96:
@@ -579,10 +583,10 @@ define i64 @mul288(i64 %a) {
define i64 @zext_mul96(i32 signext %a) {
; RV64I-LABEL: zext_mul96:
; RV64I: # %bb.0:
-; RV64I-NEXT: li a1, 3
-; RV64I-NEXT: slli a1, a1, 37
; RV64I-NEXT: slli a0, a0, 32
-; RV64I-NEXT: mulhu a0, a0, a1
+; RV64I-NEXT: srli a1, a0, 27
+; RV64I-NEXT: srli a0, a0, 25
+; RV64I-NEXT: sub a0, a0, a1
; RV64I-NEXT: ret
;
; RV64ZBA-LABEL: zext_mul96:
@@ -638,11 +642,9 @@ define i64 @zext_mul288(i32 signext %a) {
define i64 @zext_mul12884901888(i32 signext %a) {
; RV64I-LABEL: zext_mul12884901888:
; RV64I: # %bb.0:
-; RV64I-NEXT: slli a0, a0, 32
-; RV64I-NEXT: srli a0, a0, 32
-; RV64I-NEXT: li a1, 3
-; RV64I-NEXT: slli a1, a1, 32
-; RV64I-NEXT: mul a0, a0, a1
+; RV64I-NEXT: slli a1, a0, 32
+; RV64I-NEXT: slli a0, a0, 34
+; RV64I-NEXT: sub a0, a0, a1
; RV64I-NEXT: ret
;
; RV64ZBA-LABEL: zext_mul12884901888:
diff --git a/llvm/test/CodeGen/RISCV/rv64xtheadba.ll b/llvm/test/CodeGen/RISCV/rv64xtheadba.ll
index 1450c86c76d05f..939211573cac72 100644
--- a/llvm/test/CodeGen/RISCV/rv64xtheadba.ll
+++ b/llvm/test/CodeGen/RISCV/rv64xtheadba.ll
@@ -93,8 +93,9 @@ define i64 @th_addsl_2_extra_sext(i32 %x, i32 %y, i32 %z) {
define i64 @addmul6(i64 %a, i64 %b) {
; RV64I-LABEL: addmul6:
; RV64I: # %bb.0:
-; RV64I-NEXT: li a2, 6
-; RV64I-NEXT: mul a0, a0, a2
+; RV64I-NEXT: slli a2, a0, 1
+; RV64I-NEXT: slli a0, a0, 3
+; RV64I-NEXT: sub a0, a0, a2
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
@@ -129,8 +130,9 @@ define i64 @addmul10(i64 %a, i64 %b) {
define i64 @addmul12(i64 %a, i64 %b) {
; RV64I-LABEL: addmul12:
; RV64I: # %bb.0:
-; RV64I-NEXT: li a2, 12
-; RV64I-NEXT: mul a0, a0, a2
+; RV64I-NEXT: slli a2, a0, 2
+; RV64I-NEXT: slli a0, a0, 4
+; RV64I-NEXT: sub a0, a0, a2
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
@@ -183,8 +185,9 @@ define i64 @addmul20(i64 %a, i64 %b) {
define i64 @addmul24(i64 %a, i64 %b) {
; RV64I-LABEL: addmul24:
; RV64I: # %bb.0:
-; RV64I-NEXT: li a2, 24
-; RV64I-NEXT: mul a0, a0, a2
+; RV64I-NEXT: slli a2, a0, 3
+; RV64I-NEXT: slli a0, a0, 5
+; RV64I-NEXT: sub a0, a0, a2
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: ret
;
@@ -255,8 +258,9 @@ define i64 @addmul72(i64 %a, i64 %b) {
define i64 @mul96(i64 %a) {
; RV64I-LABEL: mul96:
; RV64I: # %bb.0:
-; RV64I-NEXT: li a1, 96
-; RV64I-NEXT: mul a0, a0, a1
+; RV64I-NEXT: slli a1, a0, 5
+; RV64I-NEXT: slli a0, a0, 7
+; RV64I-NEXT: sub a0, a0, a1
; RV64I-NEXT: ret
;
; RV64XTHEADBA-LABEL: mul96:
diff --git a/llvm/test/CodeGen/RISCV/rv64zba.ll b/llvm/test/CodeGen/RISCV/rv64zba.ll
index b4c80b60e0bad5..ba0380755cdab3 100644
--- a/llvm/test/CodeGen/RISCV/rv64zba.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zba.ll
@@ -374,8 +374,9 @@ define i64 @sh2add_extra_sext(i32 %x, i32 %y, i32 %z) {
define i64 @addmul6(i64 %a, i64 %b) {
; RV64I-LABEL: addmul6:
; RV64I: # %bb.0:
-; RV64I-NEXT: li a2, 6
-; RV64I-NEXT: mul a0, a0, a2
+...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/88983
More information about the llvm-commits
mailing list