[llvm] 78a31bb - [RISCV] Change how we isel (add X, [-4096, -2049]) or (add X, [2048,4095]).

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 24 08:32:08 PDT 2022


Author: Craig Topper
Date: 2022-06-24T08:31:52-07:00
New Revision: 78a31bb96961b30222f96d45b589bad7bc957cb4

URL: https://github.com/llvm/llvm-project/commit/78a31bb96961b30222f96d45b589bad7bc957cb4
DIFF: https://github.com/llvm/llvm-project/commit/78a31bb96961b30222f96d45b589bad7bc957cb4.diff

LOG: [RISCV] Change how we isel (add X, [-4096, -2049]) or (add X, [2048,4095]).

We currently split the immediate almost equally between two addis.
If the immediate is odd, it won't be split exactly equal.

This patch instead gives one addi an immediate of 2047 or -2048 and the
other getsthe remainder. If the original immediate is near -2049 or 2048,
this might allow the use of c.addi for the addi that receives the
smaller immediate.

Reviewed By: asb, luismarques

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

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVInstrInfo.td
    llvm/test/CodeGen/RISCV/add-imm.ll
    llvm/test/CodeGen/RISCV/addimm-mulimm.ll
    llvm/test/CodeGen/RISCV/xaluo.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 2c494f74cd16b..7e907a6f91a2d 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -419,7 +419,9 @@ def ImmSubFrom32 : SDNodeXForm<imm, [{
 }]>;
 
 // Check if (add r, imm) can be optimized to (ADDI (ADDI r, imm0), imm1),
-// in which imm = imm0 + imm1 and both imm0 and imm1 are simm12.
+// in which imm = imm0 + imm1 and both imm0 and imm1 are simm12. We make imm0
+// as large as possible and imm1 as small as possible so that we might be able
+// to use c.addi for the small immediate.
 def AddiPair : PatLeaf<(imm), [{
   if (!N->hasOneUse())
     return false;
@@ -428,16 +430,19 @@ def AddiPair : PatLeaf<(imm), [{
   return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094);
 }]>;
 
-// Return imm/2.
-def AddiPairImmA : SDNodeXForm<imm, [{
-  return CurDAG->getTargetConstant(N->getSExtValue() / 2, SDLoc(N),
+// Return imm - (imm < 0 ? -2048 : 2047).
+def AddiPairImmSmall : SDNodeXForm<imm, [{
+  int64_t Imm = N->getSExtValue();
+  int64_t Adj = N->getSExtValue() < 0 ? -2048 : 2047;
+  return CurDAG->getTargetConstant(Imm - Adj, SDLoc(N),
                                    N->getValueType(0));
 }]>;
 
-// Return imm - imm/2.
-def AddiPairImmB : SDNodeXForm<imm, [{
-  int64_t Imm = N->getSExtValue();
-  return CurDAG->getTargetConstant(Imm - Imm / 2, SDLoc(N),
+// Return -2048 if immediate is negative or 2047 if positive. These are the
+// largest simm12 values.
+def AddiPairImmLarge : SDNodeXForm<imm, [{
+  int64_t Imm = N->getSExtValue() < 0 ? -2048 : 2047;
+  return CurDAG->getTargetConstant(Imm, SDLoc(N),
                                    N->getValueType(0));
 }]>;
 
@@ -1651,14 +1656,14 @@ def : Pat<(debugtrap), (EBREAK)>;
 
 /// Simple optimization
 def : Pat<(add GPR:$rs1, (AddiPair:$rs2)),
-          (ADDI (ADDI GPR:$rs1, (AddiPairImmB AddiPair:$rs2)),
-                (AddiPairImmA GPR:$rs2))>;
+          (ADDI (ADDI GPR:$rs1, (AddiPairImmLarge AddiPair:$rs2)),
+                (AddiPairImmSmall GPR:$rs2))>;
 
 let Predicates = [IsRV64] in {
 // Select W instructions if only the lower 32-bits of the result are used.
 def : Pat<(binop_allwusers<add> GPR:$rs1, (AddiPair:$rs2)),
-          (ADDIW (ADDIW GPR:$rs1, (AddiPairImmB AddiPair:$rs2)),
-                 (AddiPairImmA AddiPair:$rs2))>;
+          (ADDIW (ADDIW GPR:$rs1, (AddiPairImmLarge AddiPair:$rs2)),
+                 (AddiPairImmSmall AddiPair:$rs2))>;
 }
 
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/test/CodeGen/RISCV/add-imm.ll b/llvm/test/CodeGen/RISCV/add-imm.ll
index 82178da984b8f..d24deeea45cb9 100644
--- a/llvm/test/CodeGen/RISCV/add-imm.ll
+++ b/llvm/test/CodeGen/RISCV/add-imm.ll
@@ -23,14 +23,14 @@ define i32 @add_positive_low_bound_reject(i32 %a) nounwind {
 define i32 @add_positive_low_bound_accept(i32 %a) nounwind {
 ; RV32I-LABEL: add_positive_low_bound_accept:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    addi a0, a0, 1024
-; RV32I-NEXT:    addi a0, a0, 1024
+; RV32I-NEXT:    addi a0, a0, 2047
+; RV32I-NEXT:    addi a0, a0, 1
 ; RV32I-NEXT:    ret
 ;
 ; RV64I-LABEL: add_positive_low_bound_accept:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    addiw a0, a0, 1024
-; RV64I-NEXT:    addiw a0, a0, 1024
+; RV64I-NEXT:    addiw a0, a0, 2047
+; RV64I-NEXT:    addiw a0, a0, 1
 ; RV64I-NEXT:    ret
   %1 = add i32 %a, 2048
   ret i32 %1
@@ -87,14 +87,14 @@ define i32 @add_negative_high_bound_reject(i32 %a) nounwind {
 define i32 @add_negative_high_bound_accept(i32 %a) nounwind {
 ; RV32I-LABEL: add_negative_high_bound_accept:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    addi a0, a0, -1025
-; RV32I-NEXT:    addi a0, a0, -1024
+; RV32I-NEXT:    addi a0, a0, -2048
+; RV32I-NEXT:    addi a0, a0, -1
 ; RV32I-NEXT:    ret
 ;
 ; RV64I-LABEL: add_negative_high_bound_accept:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    addiw a0, a0, -1025
-; RV64I-NEXT:    addiw a0, a0, -1024
+; RV64I-NEXT:    addiw a0, a0, -2048
+; RV64I-NEXT:    addiw a0, a0, -1
 ; RV64I-NEXT:    ret
   %1 = add i32 %a, -2049
   ret i32 %1
@@ -137,14 +137,14 @@ define i32 @add_negative_low_bound_reject(i32 %a) nounwind {
 define i32 @add32_accept(i32 %a) nounwind {
 ; RV32I-LABEL: add32_accept:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    addi a0, a0, 1500
-; RV32I-NEXT:    addi a0, a0, 1499
+; RV32I-NEXT:    addi a0, a0, 2047
+; RV32I-NEXT:    addi a0, a0, 952
 ; RV32I-NEXT:    ret
 ;
 ; RV64I-LABEL: add32_accept:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    addiw a0, a0, 1500
-; RV64I-NEXT:    addiw a0, a0, 1499
+; RV64I-NEXT:    addiw a0, a0, 2047
+; RV64I-NEXT:    addiw a0, a0, 952
 ; RV64I-NEXT:    ret
   %1 = add i32 %a, 2999
   ret i32 %1
@@ -153,14 +153,14 @@ define i32 @add32_accept(i32 %a) nounwind {
 define signext i32 @add32_sext_accept(i32 signext %a) nounwind {
 ; RV32I-LABEL: add32_sext_accept:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    addi a0, a0, 1500
-; RV32I-NEXT:    addi a0, a0, 1499
+; RV32I-NEXT:    addi a0, a0, 2047
+; RV32I-NEXT:    addi a0, a0, 952
 ; RV32I-NEXT:    ret
 ;
 ; RV64I-LABEL: add32_sext_accept:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    addiw a0, a0, 1500
-; RV64I-NEXT:    addiw a0, a0, 1499
+; RV64I-NEXT:    addiw a0, a0, 2047
+; RV64I-NEXT:    addiw a0, a0, 952
 ; RV64I-NEXT:    ret
   %1 = add i32 %a, 2999
   ret i32 %1
@@ -170,16 +170,16 @@ define signext i32 @add32_sext_accept(i32 signext %a) nounwind {
 define signext i32 @add32_sext_reject_on_rv64(i32 signext %a) nounwind {
 ; RV32I-LABEL: add32_sext_reject_on_rv64:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    addi a0, a0, 1500
-; RV32I-NEXT:    addi a0, a0, 1500
+; RV32I-NEXT:    addi a0, a0, 2047
+; RV32I-NEXT:    addi a0, a0, 953
 ; RV32I-NEXT:    lui a1, %hi(gv0)
 ; RV32I-NEXT:    sw a0, %lo(gv0)(a1)
 ; RV32I-NEXT:    ret
 ;
 ; RV64I-LABEL: add32_sext_reject_on_rv64:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    addiw a0, a0, 1500
-; RV64I-NEXT:    addiw a0, a0, 1500
+; RV64I-NEXT:    addiw a0, a0, 2047
+; RV64I-NEXT:    addiw a0, a0, 953
 ; RV64I-NEXT:    lui a1, %hi(gv0)
 ; RV64I-NEXT:    sw a0, %lo(gv0)(a1)
 ; RV64I-NEXT:    ret
@@ -191,8 +191,8 @@ define signext i32 @add32_sext_reject_on_rv64(i32 signext %a) nounwind {
 define i64 @add64_accept(i64 %a) nounwind {
 ; RV32I-LABEL: add64_accept:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    addi a2, a0, 1500
-; RV32I-NEXT:    addi a2, a2, 1499
+; RV32I-NEXT:    addi a2, a0, 2047
+; RV32I-NEXT:    addi a2, a2, 952
 ; RV32I-NEXT:    sltu a0, a2, a0
 ; RV32I-NEXT:    add a1, a1, a0
 ; RV32I-NEXT:    mv a0, a2
@@ -200,8 +200,8 @@ define i64 @add64_accept(i64 %a) nounwind {
 ;
 ; RV64I-LABEL: add64_accept:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    addi a0, a0, 1500
-; RV64I-NEXT:    addi a0, a0, 1499
+; RV64I-NEXT:    addi a0, a0, 2047
+; RV64I-NEXT:    addi a0, a0, 952
 ; RV64I-NEXT:    ret
   %1 = add i64 %a, 2999
   ret i64 %1

diff  --git a/llvm/test/CodeGen/RISCV/addimm-mulimm.ll b/llvm/test/CodeGen/RISCV/addimm-mulimm.ll
index 86b1a5ff0a3d4..3437305402f01 100644
--- a/llvm/test/CodeGen/RISCV/addimm-mulimm.ll
+++ b/llvm/test/CodeGen/RISCV/addimm-mulimm.ll
@@ -551,8 +551,8 @@ define i64 @add_mul_combine_infinite_loop(i64 %x) {
 ; RV32IMB-NEXT:    sh3add a1, a1, a2
 ; RV32IMB-NEXT:    sh1add a0, a0, a0
 ; RV32IMB-NEXT:    slli a2, a0, 3
-; RV32IMB-NEXT:    addi a0, a2, 1024
-; RV32IMB-NEXT:    addi a0, a0, 1024
+; RV32IMB-NEXT:    addi a0, a2, 2047
+; RV32IMB-NEXT:    addi a0, a0, 1
 ; RV32IMB-NEXT:    sltu a2, a0, a2
 ; RV32IMB-NEXT:    add a1, a1, a2
 ; RV32IMB-NEXT:    ret

diff  --git a/llvm/test/CodeGen/RISCV/xaluo.ll b/llvm/test/CodeGen/RISCV/xaluo.ll
index e86cedce4aa17..05301a1362684 100644
--- a/llvm/test/CodeGen/RISCV/xaluo.ll
+++ b/llvm/test/CodeGen/RISCV/xaluo.ll
@@ -4094,8 +4094,8 @@ define zeroext i1 @uaddo.i64.constant_2048(i64 %v1, i64* %res) {
 ; RV32-LABEL: uaddo.i64.constant_2048:
 ; RV32:       # %bb.0: # %entry
 ; RV32-NEXT:    mv a3, a0
-; RV32-NEXT:    addi a0, a0, 1024
-; RV32-NEXT:    addi a4, a0, 1024
+; RV32-NEXT:    addi a0, a0, 2047
+; RV32-NEXT:    addi a4, a0, 1
 ; RV32-NEXT:    sltu a0, a4, a3
 ; RV32-NEXT:    add a5, a1, a0
 ; RV32-NEXT:    bgeu a4, a3, .LBB67_2
@@ -4108,8 +4108,8 @@ define zeroext i1 @uaddo.i64.constant_2048(i64 %v1, i64* %res) {
 ;
 ; RV64-LABEL: uaddo.i64.constant_2048:
 ; RV64:       # %bb.0: # %entry
-; RV64-NEXT:    addi a2, a0, 1024
-; RV64-NEXT:    addi a2, a2, 1024
+; RV64-NEXT:    addi a2, a0, 2047
+; RV64-NEXT:    addi a2, a2, 1
 ; RV64-NEXT:    sltu a0, a2, a0
 ; RV64-NEXT:    sd a2, 0(a1)
 ; RV64-NEXT:    ret
@@ -4117,8 +4117,8 @@ define zeroext i1 @uaddo.i64.constant_2048(i64 %v1, i64* %res) {
 ; RV32ZBA-LABEL: uaddo.i64.constant_2048:
 ; RV32ZBA:       # %bb.0: # %entry
 ; RV32ZBA-NEXT:    mv a3, a0
-; RV32ZBA-NEXT:    addi a0, a0, 1024
-; RV32ZBA-NEXT:    addi a4, a0, 1024
+; RV32ZBA-NEXT:    addi a0, a0, 2047
+; RV32ZBA-NEXT:    addi a4, a0, 1
 ; RV32ZBA-NEXT:    sltu a0, a4, a3
 ; RV32ZBA-NEXT:    add a5, a1, a0
 ; RV32ZBA-NEXT:    bgeu a4, a3, .LBB67_2
@@ -4131,8 +4131,8 @@ define zeroext i1 @uaddo.i64.constant_2048(i64 %v1, i64* %res) {
 ;
 ; RV64ZBA-LABEL: uaddo.i64.constant_2048:
 ; RV64ZBA:       # %bb.0: # %entry
-; RV64ZBA-NEXT:    addi a2, a0, 1024
-; RV64ZBA-NEXT:    addi a2, a2, 1024
+; RV64ZBA-NEXT:    addi a2, a0, 2047
+; RV64ZBA-NEXT:    addi a2, a2, 1
 ; RV64ZBA-NEXT:    sltu a0, a2, a0
 ; RV64ZBA-NEXT:    sd a2, 0(a1)
 ; RV64ZBA-NEXT:    ret
@@ -4148,8 +4148,8 @@ define zeroext i1 @uaddo.i64.constant_2049(i64 %v1, i64* %res) {
 ; RV32-LABEL: uaddo.i64.constant_2049:
 ; RV32:       # %bb.0: # %entry
 ; RV32-NEXT:    mv a3, a0
-; RV32-NEXT:    addi a0, a0, 1025
-; RV32-NEXT:    addi a4, a0, 1024
+; RV32-NEXT:    addi a0, a0, 2047
+; RV32-NEXT:    addi a4, a0, 2
 ; RV32-NEXT:    sltu a0, a4, a3
 ; RV32-NEXT:    add a5, a1, a0
 ; RV32-NEXT:    bgeu a4, a3, .LBB68_2
@@ -4162,8 +4162,8 @@ define zeroext i1 @uaddo.i64.constant_2049(i64 %v1, i64* %res) {
 ;
 ; RV64-LABEL: uaddo.i64.constant_2049:
 ; RV64:       # %bb.0: # %entry
-; RV64-NEXT:    addi a2, a0, 1025
-; RV64-NEXT:    addi a2, a2, 1024
+; RV64-NEXT:    addi a2, a0, 2047
+; RV64-NEXT:    addi a2, a2, 2
 ; RV64-NEXT:    sltu a0, a2, a0
 ; RV64-NEXT:    sd a2, 0(a1)
 ; RV64-NEXT:    ret
@@ -4171,8 +4171,8 @@ define zeroext i1 @uaddo.i64.constant_2049(i64 %v1, i64* %res) {
 ; RV32ZBA-LABEL: uaddo.i64.constant_2049:
 ; RV32ZBA:       # %bb.0: # %entry
 ; RV32ZBA-NEXT:    mv a3, a0
-; RV32ZBA-NEXT:    addi a0, a0, 1025
-; RV32ZBA-NEXT:    addi a4, a0, 1024
+; RV32ZBA-NEXT:    addi a0, a0, 2047
+; RV32ZBA-NEXT:    addi a4, a0, 2
 ; RV32ZBA-NEXT:    sltu a0, a4, a3
 ; RV32ZBA-NEXT:    add a5, a1, a0
 ; RV32ZBA-NEXT:    bgeu a4, a3, .LBB68_2
@@ -4185,8 +4185,8 @@ define zeroext i1 @uaddo.i64.constant_2049(i64 %v1, i64* %res) {
 ;
 ; RV64ZBA-LABEL: uaddo.i64.constant_2049:
 ; RV64ZBA:       # %bb.0: # %entry
-; RV64ZBA-NEXT:    addi a2, a0, 1025
-; RV64ZBA-NEXT:    addi a2, a2, 1024
+; RV64ZBA-NEXT:    addi a2, a0, 2047
+; RV64ZBA-NEXT:    addi a2, a2, 2
 ; RV64ZBA-NEXT:    sltu a0, a2, a0
 ; RV64ZBA-NEXT:    sd a2, 0(a1)
 ; RV64ZBA-NEXT:    ret


        


More information about the llvm-commits mailing list