[llvm] 2e43eea - [RISCV] Optimize multiplication with immediates

Ben Shi via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 15 02:29:20 PDT 2023


Author: Ben Shi
Date: 2023-04-15T17:29:06+08:00
New Revision: 2e43eea2da4ec9d2e8f9ce2fd8fae0c034d2465a

URL: https://github.com/llvm/llvm-project/commit/2e43eea2da4ec9d2e8f9ce2fd8fae0c034d2465a
DIFF: https://github.com/llvm/llvm-project/commit/2e43eea2da4ec9d2e8f9ce2fd8fae0c034d2465a.diff

LOG: [RISCV] Optimize multiplication with immediates

The optimization of (mul x, c) to (ADD (SLLI x, i0), (SLLI x, i1))
is only enabled for i32 multiplication on rv64, because of
the regression in i64 multiplication on rv32.

However we can change the condition to that the immediate 'c'
should only be used once, then the above regression can also be
avoided, and ohter chances of optimization can be enabled.

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D147410

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVISelLowering.cpp
    llvm/test/CodeGen/RISCV/mul.ll
    llvm/test/CodeGen/RISCV/rv32zba.ll
    llvm/test/CodeGen/RISCV/rv64zba.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 94c422263940c..7641c0f2805c3 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -15253,13 +15253,10 @@ bool RISCVTargetLowering::decomposeMulByConstant(LLVMContext &Context, EVT VT,
           ((Imm - 2).isPowerOf2() || (Imm - 4).isPowerOf2() ||
            (Imm - 8).isPowerOf2()))
         return true;
-      // Omit the following optimization if the sub target has the M extension
-      // and the data size >= XLen.
-      if (HasExtMOrZmmul && VT.getSizeInBits() >= Subtarget.getXLen())
-        return false;
       // Break the MUL to two SLLI instructions and an ADD/SUB, if Imm needs
       // a pair of LUI/ADDI.
-      if (!Imm.isSignedIntN(12) && Imm.countr_zero() < 12) {
+      if (!Imm.isSignedIntN(12) && Imm.countr_zero() < 12 &&
+          ConstNode->hasOneUse()) {
         APInt ImmS = Imm.ashr(Imm.countr_zero());
         if ((ImmS + 1).isPowerOf2() || (ImmS - 1).isPowerOf2() ||
             (1 - ImmS).isPowerOf2())

diff  --git a/llvm/test/CodeGen/RISCV/mul.ll b/llvm/test/CodeGen/RISCV/mul.ll
index 31843f5f3029f..49c8d16db6b0d 100644
--- a/llvm/test/CodeGen/RISCV/mul.ll
+++ b/llvm/test/CodeGen/RISCV/mul.ll
@@ -819,9 +819,9 @@ define i32 @muli32_p4352(i32 %a) nounwind {
 ;
 ; RV32IM-LABEL: muli32_p4352:
 ; RV32IM:       # %bb.0:
-; RV32IM-NEXT:    li a1, 17
-; RV32IM-NEXT:    slli a1, a1, 8
-; RV32IM-NEXT:    mul a0, a0, a1
+; RV32IM-NEXT:    slli a1, a0, 8
+; RV32IM-NEXT:    slli a0, a0, 12
+; RV32IM-NEXT:    add a0, a0, a1
 ; RV32IM-NEXT:    ret
 ;
 ; RV64I-LABEL: muli32_p4352:
@@ -851,9 +851,9 @@ define i32 @muli32_p3840(i32 %a) nounwind {
 ;
 ; RV32IM-LABEL: muli32_p3840:
 ; RV32IM:       # %bb.0:
-; RV32IM-NEXT:    li a1, 15
-; RV32IM-NEXT:    slli a1, a1, 8
-; RV32IM-NEXT:    mul a0, a0, a1
+; RV32IM-NEXT:    slli a1, a0, 8
+; RV32IM-NEXT:    slli a0, a0, 12
+; RV32IM-NEXT:    sub a0, a0, a1
 ; RV32IM-NEXT:    ret
 ;
 ; RV64I-LABEL: muli32_p3840:
@@ -883,9 +883,9 @@ define i32 @muli32_m3840(i32 %a) nounwind {
 ;
 ; RV32IM-LABEL: muli32_m3840:
 ; RV32IM:       # %bb.0:
-; RV32IM-NEXT:    li a1, -15
-; RV32IM-NEXT:    slli a1, a1, 8
-; RV32IM-NEXT:    mul a0, a0, a1
+; RV32IM-NEXT:    slli a1, a0, 12
+; RV32IM-NEXT:    slli a0, a0, 8
+; RV32IM-NEXT:    sub a0, a0, a1
 ; RV32IM-NEXT:    ret
 ;
 ; RV64I-LABEL: muli32_m3840:
@@ -976,9 +976,9 @@ define i64 @muli64_p4352(i64 %a) nounwind {
 ;
 ; RV64IM-LABEL: muli64_p4352:
 ; RV64IM:       # %bb.0:
-; RV64IM-NEXT:    li a1, 17
-; RV64IM-NEXT:    slli a1, a1, 8
-; RV64IM-NEXT:    mul a0, a0, a1
+; RV64IM-NEXT:    slli a1, a0, 8
+; RV64IM-NEXT:    slli a0, a0, 12
+; RV64IM-NEXT:    add a0, a0, a1
 ; RV64IM-NEXT:    ret
   %1 = mul i64 %a, 4352
   ret i64 %1
@@ -1020,9 +1020,9 @@ define i64 @muli64_p3840(i64 %a) nounwind {
 ;
 ; RV64IM-LABEL: muli64_p3840:
 ; RV64IM:       # %bb.0:
-; RV64IM-NEXT:    li a1, 15
-; RV64IM-NEXT:    slli a1, a1, 8
-; RV64IM-NEXT:    mul a0, a0, a1
+; RV64IM-NEXT:    slli a1, a0, 8
+; RV64IM-NEXT:    slli a0, a0, 12
+; RV64IM-NEXT:    sub a0, a0, a1
 ; RV64IM-NEXT:    ret
   %1 = mul i64 %a, 3840
   ret i64 %1
@@ -1105,9 +1105,9 @@ define i64 @muli64_m3840(i64 %a) nounwind {
 ;
 ; RV64IM-LABEL: muli64_m3840:
 ; RV64IM:       # %bb.0:
-; RV64IM-NEXT:    li a1, -15
-; RV64IM-NEXT:    slli a1, a1, 8
-; RV64IM-NEXT:    mul a0, a0, a1
+; RV64IM-NEXT:    slli a1, a0, 12
+; RV64IM-NEXT:    slli a0, a0, 8
+; RV64IM-NEXT:    sub a0, a0, a1
 ; RV64IM-NEXT:    ret
   %1 = mul i64 %a, -3840
   ret i64 %1

diff  --git a/llvm/test/CodeGen/RISCV/rv32zba.ll b/llvm/test/CodeGen/RISCV/rv32zba.ll
index b29ef39febc9b..0908a393338c5 100644
--- a/llvm/test/CodeGen/RISCV/rv32zba.ll
+++ b/llvm/test/CodeGen/RISCV/rv32zba.ll
@@ -479,9 +479,9 @@ define i32 @mul81(i32 %a) {
 define i32 @mul4098(i32 %a) {
 ; RV32I-LABEL: mul4098:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    lui a1, 1
-; RV32I-NEXT:    addi a1, a1, 2
-; RV32I-NEXT:    mul a0, a0, a1
+; RV32I-NEXT:    slli a1, a0, 1
+; RV32I-NEXT:    slli a0, a0, 12
+; RV32I-NEXT:    add a0, a0, a1
 ; RV32I-NEXT:    ret
 ;
 ; RV32ZBA-LABEL: mul4098:
@@ -496,9 +496,9 @@ define i32 @mul4098(i32 %a) {
 define i32 @mul4100(i32 %a) {
 ; RV32I-LABEL: mul4100:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    lui a1, 1
-; RV32I-NEXT:    addi a1, a1, 4
-; RV32I-NEXT:    mul a0, a0, a1
+; RV32I-NEXT:    slli a1, a0, 2
+; RV32I-NEXT:    slli a0, a0, 12
+; RV32I-NEXT:    add a0, a0, a1
 ; RV32I-NEXT:    ret
 ;
 ; RV32ZBA-LABEL: mul4100:
@@ -513,9 +513,9 @@ define i32 @mul4100(i32 %a) {
 define i32 @mul4104(i32 %a) {
 ; RV32I-LABEL: mul4104:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    lui a1, 1
-; RV32I-NEXT:    addi a1, a1, 8
-; RV32I-NEXT:    mul a0, a0, a1
+; RV32I-NEXT:    slli a1, a0, 3
+; RV32I-NEXT:    slli a0, a0, 12
+; RV32I-NEXT:    add a0, a0, a1
 ; RV32I-NEXT:    ret
 ;
 ; RV32ZBA-LABEL: mul4104:

diff  --git a/llvm/test/CodeGen/RISCV/rv64zba.ll b/llvm/test/CodeGen/RISCV/rv64zba.ll
index d89d5885f2535..2f82d56eb9c05 100644
--- a/llvm/test/CodeGen/RISCV/rv64zba.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zba.ll
@@ -986,9 +986,9 @@ define i64 @mul81(i64 %a) {
 define i64 @mul4098(i64 %a) {
 ; RV64I-LABEL: mul4098:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    lui a1, 1
-; RV64I-NEXT:    addiw a1, a1, 2
-; RV64I-NEXT:    mul a0, a0, a1
+; RV64I-NEXT:    slli a1, a0, 1
+; RV64I-NEXT:    slli a0, a0, 12
+; RV64I-NEXT:    add a0, a0, a1
 ; RV64I-NEXT:    ret
 ;
 ; RV64ZBA-LABEL: mul4098:
@@ -1003,9 +1003,9 @@ define i64 @mul4098(i64 %a) {
 define i64 @mul4100(i64 %a) {
 ; RV64I-LABEL: mul4100:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    lui a1, 1
-; RV64I-NEXT:    addiw a1, a1, 4
-; RV64I-NEXT:    mul a0, a0, a1
+; RV64I-NEXT:    slli a1, a0, 2
+; RV64I-NEXT:    slli a0, a0, 12
+; RV64I-NEXT:    add a0, a0, a1
 ; RV64I-NEXT:    ret
 ;
 ; RV64ZBA-LABEL: mul4100:
@@ -1020,9 +1020,9 @@ define i64 @mul4100(i64 %a) {
 define i64 @mul4104(i64 %a) {
 ; RV64I-LABEL: mul4104:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    lui a1, 1
-; RV64I-NEXT:    addiw a1, a1, 8
-; RV64I-NEXT:    mul a0, a0, a1
+; RV64I-NEXT:    slli a1, a0, 3
+; RV64I-NEXT:    slli a0, a0, 12
+; RV64I-NEXT:    add a0, a0, a1
 ; RV64I-NEXT:    ret
 ;
 ; RV64ZBA-LABEL: mul4104:


        


More information about the llvm-commits mailing list