[llvm] 7e81526 - [RISCV] Optimize immediate materialisation with BSETI/BCLRI

Ben Shi via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 13 21:57:12 PDT 2021


Author: Ben Shi
Date: 2021-10-14T04:56:47Z
New Revision: 7e815261267727b1a7138e7135225c482541c677

URL: https://github.com/llvm/llvm-project/commit/7e815261267727b1a7138e7135225c482541c677
DIFF: https://github.com/llvm/llvm-project/commit/7e815261267727b1a7138e7135225c482541c677.diff

LOG: [RISCV] Optimize immediate materialisation with BSETI/BCLRI

Opitimize immediate materialisation in the following way if profitable:
1. Use BCLRI for upper 32 bits if the lower 32 bits are negative int32.
2. Use BSETI for upper 32 bits if the lower 32 bits are positive int32.

Reviewed By: craig.topper

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

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
    llvm/test/CodeGen/RISCV/imm.ll
    llvm/test/MC/RISCV/rv64zbs-aliases-valid.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
index 31c4f67c90b82..a040df34d9ec1 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
@@ -195,16 +195,17 @@ InstSeq generateInstSeq(int64_t Val, const FeatureBitset &ActiveFeatures) {
     }
   }
 
-  // Perform the following optimization with the Zbs extension.
-  // 1. For values in range 0xffffffff 7fffffff ~ 0xffffffff 00000000,
-  //    call generateInstSeqImpl with Val|0x80000000 (which is expected be
-  //    an int32), then emit (BCLRI r, 31).
-  // 2. For values in range 0x80000000 ~ 0xffffffff, call generateInstSeqImpl
-  //    with Val&~0x80000000 (which is expected to be an int32), then
-  //    emit (BSETI r, 31).
+  // Perform optimization with BCLRI/BSETI in the Zbs extension.
   if (Res.size() > 2 && ActiveFeatures[RISCV::FeatureStdExtZbs]) {
     assert(ActiveFeatures[RISCV::Feature64Bit] &&
            "Expected RV32 to only need 2 instructions");
+
+    // 1. For values in range 0xffffffff 7fffffff ~ 0xffffffff 00000000,
+    //    call generateInstSeqImpl with Val|0x80000000 (which is expected be
+    //    an int32), then emit (BCLRI r, 31).
+    // 2. For values in range 0x80000000 ~ 0xffffffff, call generateInstSeqImpl
+    //    with Val&~0x80000000 (which is expected to be an int32), then
+    //    emit (BSETI r, 31).
     int64_t NewVal;
     unsigned Opc;
     if (Val < 0) {
@@ -221,6 +222,32 @@ InstSeq generateInstSeq(int64_t Val, const FeatureBitset &ActiveFeatures) {
       if (TmpSeq.size() < Res.size())
         Res = TmpSeq;
     }
+
+    // Try to use BCLRI for upper 32 bits if the original lower 32 bits are
+    // negative int32, or use BSETI for upper 32 bits if the original lower
+    // 32 bits are positive int32.
+    int32_t Lo = Val;
+    uint32_t Hi = Val >> 32;
+    Opc = 0;
+    RISCVMatInt::InstSeq TmpSeq;
+    generateInstSeqImpl(Lo, ActiveFeatures, TmpSeq);
+    // Check if it is profitable to use BCLRI/BSETI.
+    if (Lo > 0 && TmpSeq.size() + countPopulation(Hi) < Res.size()) {
+      Opc = RISCV::BSETI;
+    } else if (Lo < 0 && TmpSeq.size() + countPopulation(~Hi) < Res.size()) {
+      Opc = RISCV::BCLRI;
+      Hi = ~Hi;
+    }
+    // Search for each bit and build corresponding BCLRI/BSETI.
+    if (Opc > 0) {
+      while (Hi != 0) {
+        unsigned Bit = countTrailingZeros(Hi);
+        TmpSeq.push_back(RISCVMatInt::Inst(Opc, Bit + 32));
+        Hi &= ~(1 << Bit);
+      }
+      if (TmpSeq.size() < Res.size())
+        Res = TmpSeq;
+    }
   }
 
   return Res;

diff  --git a/llvm/test/CodeGen/RISCV/imm.ll b/llvm/test/CodeGen/RISCV/imm.ll
index fa55e8b561a8f..b2cfe6c6dea55 100644
--- a/llvm/test/CodeGen/RISCV/imm.ll
+++ b/llvm/test/CodeGen/RISCV/imm.ll
@@ -841,13 +841,12 @@ define i64 @imm_2reg_1() nounwind {
 ;
 ; RV64IZBS-LABEL: imm_2reg_1:
 ; RV64IZBS:       # %bb.0:
-; RV64IZBS-NEXT:    addi a0, zero, -1
-; RV64IZBS-NEXT:    slli a0, a0, 35
-; RV64IZBS-NEXT:    addi a0, a0, 9
-; RV64IZBS-NEXT:    slli a0, a0, 13
-; RV64IZBS-NEXT:    addi a0, a0, 837
-; RV64IZBS-NEXT:    slli a0, a0, 12
-; RV64IZBS-NEXT:    addi a0, a0, 1656
+; RV64IZBS-NEXT:    lui a0, 74565
+; RV64IZBS-NEXT:    addiw a0, a0, 1656
+; RV64IZBS-NEXT:    bseti a0, a0, 60
+; RV64IZBS-NEXT:    bseti a0, a0, 61
+; RV64IZBS-NEXT:    bseti a0, a0, 62
+; RV64IZBS-NEXT:    bseti a0, a0, 63
 ; RV64IZBS-NEXT:    ret
   ret i64 -1152921504301427080 ; 0xF000_0000_1234_5678
 }
@@ -935,10 +934,9 @@ define i64 @imm_5372288229() {
 ;
 ; RV64IZBS-LABEL: imm_5372288229:
 ; RV64IZBS:       # %bb.0:
-; RV64IZBS-NEXT:    lui a0, 160
-; RV64IZBS-NEXT:    addiw a0, a0, 437
-; RV64IZBS-NEXT:    slli a0, a0, 13
-; RV64IZBS-NEXT:    addi a0, a0, -795
+; RV64IZBS-NEXT:    lui a0, 263018
+; RV64IZBS-NEXT:    addiw a0, a0, -795
+; RV64IZBS-NEXT:    bseti a0, a0, 32
 ; RV64IZBS-NEXT:    ret
   ret i64 5372288229
 }
@@ -969,10 +967,9 @@ define i64 @imm_neg_5372288229() {
 ;
 ; RV64IZBS-LABEL: imm_neg_5372288229:
 ; RV64IZBS:       # %bb.0:
-; RV64IZBS-NEXT:    lui a0, 1048416
-; RV64IZBS-NEXT:    addiw a0, a0, -437
-; RV64IZBS-NEXT:    slli a0, a0, 13
-; RV64IZBS-NEXT:    addi a0, a0, 795
+; RV64IZBS-NEXT:    lui a0, 785558
+; RV64IZBS-NEXT:    addiw a0, a0, 795
+; RV64IZBS-NEXT:    bclri a0, a0, 32
 ; RV64IZBS-NEXT:    ret
   ret i64 -5372288229
 }
@@ -1003,10 +1000,9 @@ define i64 @imm_8953813715() {
 ;
 ; RV64IZBS-LABEL: imm_8953813715:
 ; RV64IZBS:       # %bb.0:
-; RV64IZBS-NEXT:    lui a0, 267
-; RV64IZBS-NEXT:    addiw a0, a0, -637
-; RV64IZBS-NEXT:    slli a0, a0, 13
-; RV64IZBS-NEXT:    addi a0, a0, -1325
+; RV64IZBS-NEXT:    lui a0, 88838
+; RV64IZBS-NEXT:    addiw a0, a0, -1325
+; RV64IZBS-NEXT:    bseti a0, a0, 33
 ; RV64IZBS-NEXT:    ret
   ret i64 8953813715
 }
@@ -1037,10 +1033,9 @@ define i64 @imm_neg_8953813715() {
 ;
 ; RV64IZBS-LABEL: imm_neg_8953813715:
 ; RV64IZBS:       # %bb.0:
-; RV64IZBS-NEXT:    lui a0, 1048309
-; RV64IZBS-NEXT:    addiw a0, a0, 637
-; RV64IZBS-NEXT:    slli a0, a0, 13
-; RV64IZBS-NEXT:    addi a0, a0, 1325
+; RV64IZBS-NEXT:    lui a0, 959738
+; RV64IZBS-NEXT:    addiw a0, a0, 1325
+; RV64IZBS-NEXT:    bclri a0, a0, 33
 ; RV64IZBS-NEXT:    ret
   ret i64 -8953813715
 }
@@ -1174,12 +1169,9 @@ define i64 @imm_70370820078523() {
 ;
 ; RV64IZBS-LABEL: imm_70370820078523:
 ; RV64IZBS:       # %bb.0:
-; RV64IZBS-NEXT:    lui a0, 256
-; RV64IZBS-NEXT:    addiw a0, a0, 31
-; RV64IZBS-NEXT:    slli a0, a0, 12
-; RV64IZBS-NEXT:    addi a0, a0, -273
-; RV64IZBS-NEXT:    slli a0, a0, 14
-; RV64IZBS-NEXT:    addi a0, a0, -1093
+; RV64IZBS-NEXT:    lui a0, 506812
+; RV64IZBS-NEXT:    addiw a0, a0, -1093
+; RV64IZBS-NEXT:    bseti a0, a0, 46
 ; RV64IZBS-NEXT:    ret
   ret i64 70370820078523 ; 0x40007bbbbbbb
 }
@@ -1216,13 +1208,9 @@ define i64 @imm_neg_9223372034778874949() {
 ;
 ; RV64IZBS-LABEL: imm_neg_9223372034778874949:
 ; RV64IZBS:       # %bb.0:
-; RV64IZBS-NEXT:    addi a0, zero, -1
-; RV64IZBS-NEXT:    slli a0, a0, 37
-; RV64IZBS-NEXT:    addi a0, a0, 31
-; RV64IZBS-NEXT:    slli a0, a0, 12
-; RV64IZBS-NEXT:    addi a0, a0, -273
-; RV64IZBS-NEXT:    slli a0, a0, 14
-; RV64IZBS-NEXT:    addi a0, a0, -1093
+; RV64IZBS-NEXT:    lui a0, 506812
+; RV64IZBS-NEXT:    addiw a0, a0, -1093
+; RV64IZBS-NEXT:    bseti a0, a0, 63
 ; RV64IZBS-NEXT:    ret
   ret i64 -9223372034778874949 ; 0x800000007bbbbbbb
 }
@@ -1259,13 +1247,10 @@ define i64 @imm_neg_9223301666034697285() {
 ;
 ; RV64IZBS-LABEL: imm_neg_9223301666034697285:
 ; RV64IZBS:       # %bb.0:
-; RV64IZBS-NEXT:    lui a0, 917505
-; RV64IZBS-NEXT:    slli a0, a0, 8
-; RV64IZBS-NEXT:    addi a0, a0, 31
-; RV64IZBS-NEXT:    slli a0, a0, 12
-; RV64IZBS-NEXT:    addi a0, a0, -273
-; RV64IZBS-NEXT:    slli a0, a0, 14
-; RV64IZBS-NEXT:    addi a0, a0, -1093
+; RV64IZBS-NEXT:    lui a0, 506812
+; RV64IZBS-NEXT:    addiw a0, a0, -1093
+; RV64IZBS-NEXT:    bseti a0, a0, 46
+; RV64IZBS-NEXT:    bseti a0, a0, 63
 ; RV64IZBS-NEXT:    ret
   ret i64 -9223301666034697285 ; 0x800040007bbbbbbb
 }
@@ -1328,10 +1313,9 @@ define i64 @imm_neg_8798043653189() {
 ;
 ; RV64IZBS-LABEL: imm_neg_8798043653189:
 ; RV64IZBS:       # %bb.0:
-; RV64IZBS-NEXT:    lui a0, 917475
-; RV64IZBS-NEXT:    addiw a0, a0, -273
-; RV64IZBS-NEXT:    slli a0, a0, 14
-; RV64IZBS-NEXT:    addi a0, a0, -1093
+; RV64IZBS-NEXT:    lui a0, 572348
+; RV64IZBS-NEXT:    addiw a0, a0, -1093
+; RV64IZBS-NEXT:    bclri a0, a0, 43
 ; RV64IZBS-NEXT:    ret
   ret i64 -8798043653189 ; 0xfffff7ff8bbbbbbb
 }
@@ -1365,11 +1349,9 @@ define i64 @imm_9223372034904144827() {
 ;
 ; RV64IZBS-LABEL: imm_9223372034904144827:
 ; RV64IZBS:       # %bb.0:
-; RV64IZBS-NEXT:    lui a0, 1048343
-; RV64IZBS-NEXT:    addiw a0, a0, 1911
-; RV64IZBS-NEXT:    slli a0, a0, 12
-; RV64IZBS-NEXT:    addi a0, a0, 1911
-; RV64IZBS-NEXT:    srli a0, a0, 1
+; RV64IZBS-NEXT:    lui a0, 572348
+; RV64IZBS-NEXT:    addiw a0, a0, -1093
+; RV64IZBS-NEXT:    bclri a0, a0, 63
 ; RV64IZBS-NEXT:    ret
   ret i64 9223372034904144827 ; 0x7fffffff8bbbbbbb
 }
@@ -1407,13 +1389,10 @@ define i64 @imm_neg_9223354442718100411() {
 ;
 ; RV64IZBS-LABEL: imm_neg_9223354442718100411:
 ; RV64IZBS:       # %bb.0:
-; RV64IZBS-NEXT:    lui a0, 524287
-; RV64IZBS-NEXT:    slli a0, a0, 6
-; RV64IZBS-NEXT:    addi a0, a0, -29
-; RV64IZBS-NEXT:    slli a0, a0, 12
-; RV64IZBS-NEXT:    addi a0, a0, -273
-; RV64IZBS-NEXT:    slli a0, a0, 14
-; RV64IZBS-NEXT:    addi a0, a0, -1093
+; RV64IZBS-NEXT:    lui a0, 572348
+; RV64IZBS-NEXT:    addiw a0, a0, -1093
+; RV64IZBS-NEXT:    bclri a0, a0, 44
+; RV64IZBS-NEXT:    bclri a0, a0, 63
 ; RV64IZBS-NEXT:    ret
   ret i64 9223354442718100411 ; 0x7fffefff8bbbbbbb
 }

diff  --git a/llvm/test/MC/RISCV/rv64zbs-aliases-valid.s b/llvm/test/MC/RISCV/rv64zbs-aliases-valid.s
index efa3a143c7052..c170416e882e2 100644
--- a/llvm/test/MC/RISCV/rv64zbs-aliases-valid.s
+++ b/llvm/test/MC/RISCV/rv64zbs-aliases-valid.s
@@ -58,3 +58,23 @@ li x5, 2147485013
 # CHECK-S-OBJ: addi t0, zero, -1365
 # CHECK-S-OBJ-NEXT: bclri t0, t0, 31
 li x5, -2147485013
+
+# CHECK-S-OBJ-NOALIAS: lui t1, 572348
+# CHECK-S-OBJ-NOALIAS-NEXT: addiw t1, t1, -1093
+# CHECK-S-OBJ-NOALIAS-NEXT: bclri t1, t1, 44
+# CHECK-S-OBJ-NOALIAS-NEXT: bclri t1, t1, 63
+# CHECK-S-OBJ: lui t1, 572348
+# CHECK-S-OBJ-NEXT: addiw t1, t1, -1093
+# CHECK-S-OBJ-NEXT: bclri t1, t1, 44
+# CHECK-S-OBJ-NEXT: bclri t1, t1, 63
+li x6, 9223354442718100411
+
+# CHECK-S-OBJ-NOALIAS: lui t1, 506812
+# CHECK-S-OBJ-NOALIAS-NEXT: addiw t1, t1, -1093
+# CHECK-S-OBJ-NOALIAS-NEXT: bseti t1, t1, 46
+# CHECK-S-OBJ-NOALIAS-NEXT: bseti t1, t1, 63
+# CHECK-S-OBJ: lui t1, 506812
+# CHECK-S-OBJ-NEXT: addiw t1, t1, -1093
+# CHECK-S-OBJ-NEXT: bseti t1, t1, 46
+# CHECK-S-OBJ-NEXT: bseti t1, t1, 63
+li x6, -9223301666034697285


        


More information about the llvm-commits mailing list