[llvm] 7746e81 - [RISCV] Optimize or/xor with immediate in the zbs extension

Ben Shi via llvm-commits llvm-commits at lists.llvm.org
Sun May 16 20:00:01 PDT 2021


Author: Ben Shi
Date: 2021-05-17T10:59:52+08:00
New Revision: 7746e818a5492a7d023556a0515e9b3bb7e7d811

URL: https://github.com/llvm/llvm-project/commit/7746e818a5492a7d023556a0515e9b3bb7e7d811
DIFF: https://github.com/llvm/llvm-project/commit/7746e818a5492a7d023556a0515e9b3bb7e7d811.diff

LOG: [RISCV] Optimize or/xor with immediate in the zbs extension

Reviewed By: craig.topper

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

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVInstrInfoB.td
    llvm/test/CodeGen/RISCV/rv32zbs.ll
    llvm/test/CodeGen/RISCV/rv64zbs.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
index f0de488b7885f..6134e8e8ad3e4 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
@@ -87,6 +87,30 @@ def BSETINVMask : ImmLeaf<XLenVT, [{
   return !isInt<12>(Imm) && isPowerOf2_32(Imm);
 }], BSETINVXForm>;
 
+// Check if (or r, i) can be optimized to (BSETI (BSETI r, i0), i1),
+// in which i = (1 << i0) | (1 << i1).
+def BSETINVTwoBitsMask : PatLeaf<(imm), [{
+   if (!N->hasOneUse())
+     return false;
+   // The immediate should not be a simm12.
+   if (isInt<12>(N->getSExtValue()))
+     return false;
+   // The immediate must have exactly two bits set.
+   return countPopulation(N->getZExtValue()) == 2;
+}]>;
+
+def BSETINVTwoBitsMaskLow : SDNodeXForm<imm, [{
+  uint64_t I = N->getZExtValue();
+  return CurDAG->getTargetConstant(countTrailingZeros(I), SDLoc(N),
+                                   N->getValueType(0));
+}]>;
+
+def BSETINVTwoBitsMaskHigh : SDNodeXForm<imm, [{
+  uint64_t I = N->getZExtValue();
+  return CurDAG->getTargetConstant(63 - countLeadingZeros(I), SDLoc(N),
+                                   N->getValueType(0));
+}]>;
+
 //===----------------------------------------------------------------------===//
 // Instruction class templates
 //===----------------------------------------------------------------------===//
@@ -723,6 +747,13 @@ def : Pat<(xor GPR:$rs1, BSETINVMask:$mask),
 
 def : Pat<(and (srl GPR:$rs1, uimmlog2xlen:$shamt), (XLenVT 1)),
           (BEXTI GPR:$rs1, uimmlog2xlen:$shamt)>;
+
+def : Pat<(or GPR:$r, BSETINVTwoBitsMask:$i),
+          (BSETI (BSETI GPR:$r, (BSETINVTwoBitsMaskLow BSETINVTwoBitsMask:$i)),
+                 (BSETINVTwoBitsMaskHigh BSETINVTwoBitsMask:$i))>;
+def : Pat<(xor GPR:$r, BSETINVTwoBitsMask:$i),
+          (BINVI (BINVI GPR:$r, (BSETINVTwoBitsMaskLow BSETINVTwoBitsMask:$i)),
+                 (BSETINVTwoBitsMaskHigh BSETINVTwoBitsMask:$i))>;
 }
 
 // There's no encoding for roli in the the 'B' extension as it can be

diff  --git a/llvm/test/CodeGen/RISCV/rv32zbs.ll b/llvm/test/CodeGen/RISCV/rv32zbs.ll
index 7f0a6d8a4f9bc..c55bc01b3276f 100644
--- a/llvm/test/CodeGen/RISCV/rv32zbs.ll
+++ b/llvm/test/CodeGen/RISCV/rv32zbs.ll
@@ -720,16 +720,14 @@ define i32 @xor_i32_4098(i32 %a) nounwind {
 ;
 ; RV32IB-LABEL: xor_i32_4098:
 ; RV32IB:       # %bb.0:
-; RV32IB-NEXT:    lui a1, 1
-; RV32IB-NEXT:    addi a1, a1, 2
-; RV32IB-NEXT:    xor a0, a0, a1
+; RV32IB-NEXT:    binvi a0, a0, 1
+; RV32IB-NEXT:    binvi a0, a0, 12
 ; RV32IB-NEXT:    ret
 ;
 ; RV32IBS-LABEL: xor_i32_4098:
 ; RV32IBS:       # %bb.0:
-; RV32IBS-NEXT:    lui a1, 1
-; RV32IBS-NEXT:    addi a1, a1, 2
-; RV32IBS-NEXT:    xor a0, a0, a1
+; RV32IBS-NEXT:    binvi a0, a0, 1
+; RV32IBS-NEXT:    binvi a0, a0, 12
 ; RV32IBS-NEXT:    ret
   %xor = xor i32 %a, 4098
   ret i32 %xor
@@ -789,16 +787,14 @@ define i32 @or_i32_4098(i32 %a) nounwind {
 ;
 ; RV32IB-LABEL: or_i32_4098:
 ; RV32IB:       # %bb.0:
-; RV32IB-NEXT:    lui a1, 1
-; RV32IB-NEXT:    addi a1, a1, 2
-; RV32IB-NEXT:    or a0, a0, a1
+; RV32IB-NEXT:    bseti a0, a0, 1
+; RV32IB-NEXT:    bseti a0, a0, 12
 ; RV32IB-NEXT:    ret
 ;
 ; RV32IBS-LABEL: or_i32_4098:
 ; RV32IBS:       # %bb.0:
-; RV32IBS-NEXT:    lui a1, 1
-; RV32IBS-NEXT:    addi a1, a1, 2
-; RV32IBS-NEXT:    or a0, a0, a1
+; RV32IBS-NEXT:    bseti a0, a0, 1
+; RV32IBS-NEXT:    bseti a0, a0, 12
 ; RV32IBS-NEXT:    ret
   %or = or i32 %a, 4098
   ret i32 %or

diff  --git a/llvm/test/CodeGen/RISCV/rv64zbs.ll b/llvm/test/CodeGen/RISCV/rv64zbs.ll
index b980983eda765..199dcab0deb0a 100644
--- a/llvm/test/CodeGen/RISCV/rv64zbs.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zbs.ll
@@ -1221,18 +1221,14 @@ define i64 @xor_i64_large(i64 %a) nounwind {
 ;
 ; RV64IB-LABEL: xor_i64_large:
 ; RV64IB:       # %bb.0:
-; RV64IB-NEXT:    addi a1, zero, 1
-; RV64IB-NEXT:    slli a1, a1, 32
-; RV64IB-NEXT:    addi a1, a1, 1
-; RV64IB-NEXT:    xor a0, a0, a1
+; RV64IB-NEXT:    binvi a0, a0, 0
+; RV64IB-NEXT:    binvi a0, a0, 32
 ; RV64IB-NEXT:    ret
 ;
 ; RV64IBS-LABEL: xor_i64_large:
 ; RV64IBS:       # %bb.0:
-; RV64IBS-NEXT:    addi a1, zero, 1
-; RV64IBS-NEXT:    slli a1, a1, 32
-; RV64IBS-NEXT:    addi a1, a1, 1
-; RV64IBS-NEXT:    xor a0, a0, a1
+; RV64IBS-NEXT:    binvi a0, a0, 0
+; RV64IBS-NEXT:    binvi a0, a0, 32
 ; RV64IBS-NEXT:    ret
   %xor = xor i64 %a, 4294967297
   ret i64 %xor
@@ -1293,18 +1289,14 @@ define i64 @or_i64_large(i64 %a) nounwind {
 ;
 ; RV64IB-LABEL: or_i64_large:
 ; RV64IB:       # %bb.0:
-; RV64IB-NEXT:    addi a1, zero, 1
-; RV64IB-NEXT:    slli a1, a1, 32
-; RV64IB-NEXT:    addi a1, a1, 1
-; RV64IB-NEXT:    or a0, a0, a1
+; RV64IB-NEXT:    bseti a0, a0, 0
+; RV64IB-NEXT:    bseti a0, a0, 32
 ; RV64IB-NEXT:    ret
 ;
 ; RV64IBS-LABEL: or_i64_large:
 ; RV64IBS:       # %bb.0:
-; RV64IBS-NEXT:    addi a1, zero, 1
-; RV64IBS-NEXT:    slli a1, a1, 32
-; RV64IBS-NEXT:    addi a1, a1, 1
-; RV64IBS-NEXT:    or a0, a0, a1
+; RV64IBS-NEXT:    bseti a0, a0, 0
+; RV64IBS-NEXT:    bseti a0, a0, 32
 ; RV64IBS-NEXT:    ret
   %or = or i64 %a, 4294967297
   ret i64 %or


        


More information about the llvm-commits mailing list