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

Ben Shi via llvm-commits llvm-commits at lists.llvm.org
Mon May 24 23:14:17 PDT 2021


Author: Ben Shi
Date: 2021-05-25T14:14:09+08:00
New Revision: bf77317049a880af541e31ba7ea43cb229ee4c0f

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

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

Reviewed By: craig.topper

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

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 6134e8e8ad3e4..9d332e4e08700 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
@@ -90,13 +90,13 @@ def BSETINVMask : ImmLeaf<XLenVT, [{
 // 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;
+  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, [{
@@ -111,6 +111,23 @@ def BSETINVTwoBitsMaskHigh : SDNodeXForm<imm, [{
                                    N->getValueType(0));
 }]>;
 
+// Check if (or r, imm) can be optimized to (BSETI (ORI r, i0), i1),
+// in which imm = i0 | (1 << i1).
+def BSETINVORIMask : PatLeaf<(imm), [{
+  if (!N->hasOneUse())
+    return false;
+  // The immediate should not be a simm12.
+  if (isInt<12>(N->getSExtValue()))
+    return false;
+  // There should be only one set bit from bit 11 to the top.
+  return isPowerOf2_64(N->getZExtValue() & ~0x7ff);
+}]>;
+
+def BSETINVORIMaskLow : SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant(N->getZExtValue() & 0x7ff,
+                                   SDLoc(N), N->getValueType(0));
+}]>;
+
 //===----------------------------------------------------------------------===//
 // Instruction class templates
 //===----------------------------------------------------------------------===//
@@ -754,6 +771,12 @@ def : Pat<(or GPR:$r, BSETINVTwoBitsMask:$i),
 def : Pat<(xor GPR:$r, BSETINVTwoBitsMask:$i),
           (BINVI (BINVI GPR:$r, (BSETINVTwoBitsMaskLow BSETINVTwoBitsMask:$i)),
                  (BSETINVTwoBitsMaskHigh BSETINVTwoBitsMask:$i))>;
+def : Pat<(or GPR:$r, BSETINVORIMask:$i),
+          (BSETI (ORI GPR:$r, (BSETINVORIMaskLow BSETINVORIMask:$i)),
+                 (BSETINVTwoBitsMaskHigh BSETINVORIMask:$i))>;
+def : Pat<(xor GPR:$r, BSETINVORIMask:$i),
+          (BINVI (XORI GPR:$r, (BSETINVORIMaskLow BSETINVORIMask:$i)),
+                 (BSETINVTwoBitsMaskHigh BSETINVORIMask:$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 bb48c92276884..8e87a57179c06 100644
--- a/llvm/test/CodeGen/RISCV/rv32zbs.ll
+++ b/llvm/test/CodeGen/RISCV/rv32zbs.ll
@@ -743,16 +743,14 @@ define i32 @xor_i32_4099(i32 %a) nounwind {
 ;
 ; RV32IB-LABEL: xor_i32_4099:
 ; RV32IB:       # %bb.0:
-; RV32IB-NEXT:    lui a1, 1
-; RV32IB-NEXT:    addi a1, a1, 3
-; RV32IB-NEXT:    xor a0, a0, a1
+; RV32IB-NEXT:    xori a0, a0, 3
+; RV32IB-NEXT:    binvi a0, a0, 12
 ; RV32IB-NEXT:    ret
 ;
 ; RV32IBS-LABEL: xor_i32_4099:
 ; RV32IBS:       # %bb.0:
-; RV32IBS-NEXT:    lui a1, 1
-; RV32IBS-NEXT:    addi a1, a1, 3
-; RV32IBS-NEXT:    xor a0, a0, a1
+; RV32IBS-NEXT:    xori a0, a0, 3
+; RV32IBS-NEXT:    binvi a0, a0, 12
 ; RV32IBS-NEXT:    ret
   %xor = xor i32 %a, 4099
   ret i32 %xor
@@ -787,16 +785,14 @@ define i32 @xor_i32_66901(i32 %a) nounwind {
 ;
 ; RV32IB-LABEL: xor_i32_66901:
 ; RV32IB:       # %bb.0:
-; RV32IB-NEXT:    lui a1, 16
-; RV32IB-NEXT:    addi a1, a1, 1365
-; RV32IB-NEXT:    xor a0, a0, a1
+; RV32IB-NEXT:    xori a0, a0, 1365
+; RV32IB-NEXT:    binvi a0, a0, 16
 ; RV32IB-NEXT:    ret
 ;
 ; RV32IBS-LABEL: xor_i32_66901:
 ; RV32IBS:       # %bb.0:
-; RV32IBS-NEXT:    lui a1, 16
-; RV32IBS-NEXT:    addi a1, a1, 1365
-; RV32IBS-NEXT:    xor a0, a0, a1
+; RV32IBS-NEXT:    xori a0, a0, 1365
+; RV32IBS-NEXT:    binvi a0, a0, 16
 ; RV32IBS-NEXT:    ret
   %xor = xor i32 %a, 66901
   ret i32 %xor
@@ -835,16 +831,14 @@ define i32 @or_i32_4099(i32 %a) nounwind {
 ;
 ; RV32IB-LABEL: or_i32_4099:
 ; RV32IB:       # %bb.0:
-; RV32IB-NEXT:    lui a1, 1
-; RV32IB-NEXT:    addi a1, a1, 3
-; RV32IB-NEXT:    or a0, a0, a1
+; RV32IB-NEXT:    ori a0, a0, 3
+; RV32IB-NEXT:    bseti a0, a0, 12
 ; RV32IB-NEXT:    ret
 ;
 ; RV32IBS-LABEL: or_i32_4099:
 ; RV32IBS:       # %bb.0:
-; RV32IBS-NEXT:    lui a1, 1
-; RV32IBS-NEXT:    addi a1, a1, 3
-; RV32IBS-NEXT:    or a0, a0, a1
+; RV32IBS-NEXT:    ori a0, a0, 3
+; RV32IBS-NEXT:    bseti a0, a0, 12
 ; RV32IBS-NEXT:    ret
   %or = or i32 %a, 4099
   ret i32 %or
@@ -879,16 +873,14 @@ define i32 @or_i32_66901(i32 %a) nounwind {
 ;
 ; RV32IB-LABEL: or_i32_66901:
 ; RV32IB:       # %bb.0:
-; RV32IB-NEXT:    lui a1, 16
-; RV32IB-NEXT:    addi a1, a1, 1365
-; RV32IB-NEXT:    or a0, a0, a1
+; RV32IB-NEXT:    ori a0, a0, 1365
+; RV32IB-NEXT:    bseti a0, a0, 16
 ; RV32IB-NEXT:    ret
 ;
 ; RV32IBS-LABEL: or_i32_66901:
 ; RV32IBS:       # %bb.0:
-; RV32IBS-NEXT:    lui a1, 16
-; RV32IBS-NEXT:    addi a1, a1, 1365
-; RV32IBS-NEXT:    or a0, a0, a1
+; RV32IBS-NEXT:    ori a0, a0, 1365
+; RV32IBS-NEXT:    bseti a0, a0, 16
 ; RV32IBS-NEXT:    ret
   %or = or i32 %a, 66901
   ret i32 %or

diff  --git a/llvm/test/CodeGen/RISCV/rv64zbs.ll b/llvm/test/CodeGen/RISCV/rv64zbs.ll
index 4803fe0fbd112..6abe82ebe26b6 100644
--- a/llvm/test/CodeGen/RISCV/rv64zbs.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zbs.ll
@@ -1244,16 +1244,14 @@ define i64 @xor_i64_4099(i64 %a) nounwind {
 ;
 ; RV64IB-LABEL: xor_i64_4099:
 ; RV64IB:       # %bb.0:
-; RV64IB-NEXT:    lui a1, 1
-; RV64IB-NEXT:    addiw a1, a1, 3
-; RV64IB-NEXT:    xor a0, a0, a1
+; RV64IB-NEXT:    xori a0, a0, 3
+; RV64IB-NEXT:    binvi a0, a0, 12
 ; RV64IB-NEXT:    ret
 ;
 ; RV64IBS-LABEL: xor_i64_4099:
 ; RV64IBS:       # %bb.0:
-; RV64IBS-NEXT:    lui a1, 1
-; RV64IBS-NEXT:    addiw a1, a1, 3
-; RV64IBS-NEXT:    xor a0, a0, a1
+; RV64IBS-NEXT:    xori a0, a0, 3
+; RV64IBS-NEXT:    binvi a0, a0, 12
 ; RV64IBS-NEXT:    ret
   %xor = xor i64 %a, 4099
   ret i64 %xor
@@ -1312,16 +1310,14 @@ define i64 @xor_i64_66901(i64 %a) nounwind {
 ;
 ; RV64IB-LABEL: xor_i64_66901:
 ; RV64IB:       # %bb.0:
-; RV64IB-NEXT:    lui a1, 16
-; RV64IB-NEXT:    addiw a1, a1, 1365
-; RV64IB-NEXT:    xor a0, a0, a1
+; RV64IB-NEXT:    xori a0, a0, 1365
+; RV64IB-NEXT:    binvi a0, a0, 16
 ; RV64IB-NEXT:    ret
 ;
 ; RV64IBS-LABEL: xor_i64_66901:
 ; RV64IBS:       # %bb.0:
-; RV64IBS-NEXT:    lui a1, 16
-; RV64IBS-NEXT:    addiw a1, a1, 1365
-; RV64IBS-NEXT:    xor a0, a0, a1
+; RV64IBS-NEXT:    xori a0, a0, 1365
+; RV64IBS-NEXT:    binvi a0, a0, 16
 ; RV64IBS-NEXT:    ret
   %xor = xor i64 %a, 66901
   ret i64 %xor
@@ -1337,16 +1333,14 @@ define i64 @or_i64_4099(i64 %a) nounwind {
 ;
 ; RV64IB-LABEL: or_i64_4099:
 ; RV64IB:       # %bb.0:
-; RV64IB-NEXT:    lui a1, 1
-; RV64IB-NEXT:    addiw a1, a1, 3
-; RV64IB-NEXT:    or a0, a0, a1
+; RV64IB-NEXT:    ori a0, a0, 3
+; RV64IB-NEXT:    bseti a0, a0, 12
 ; RV64IB-NEXT:    ret
 ;
 ; RV64IBS-LABEL: or_i64_4099:
 ; RV64IBS:       # %bb.0:
-; RV64IBS-NEXT:    lui a1, 1
-; RV64IBS-NEXT:    addiw a1, a1, 3
-; RV64IBS-NEXT:    or a0, a0, a1
+; RV64IBS-NEXT:    ori a0, a0, 3
+; RV64IBS-NEXT:    bseti a0, a0, 12
 ; RV64IBS-NEXT:    ret
   %or = or i64 %a, 4099
   ret i64 %or
@@ -1381,16 +1375,14 @@ define i64 @or_i64_66901(i64 %a) nounwind {
 ;
 ; RV64IB-LABEL: or_i64_66901:
 ; RV64IB:       # %bb.0:
-; RV64IB-NEXT:    lui a1, 16
-; RV64IB-NEXT:    addiw a1, a1, 1365
-; RV64IB-NEXT:    or a0, a0, a1
+; RV64IB-NEXT:    ori a0, a0, 1365
+; RV64IB-NEXT:    bseti a0, a0, 16
 ; RV64IB-NEXT:    ret
 ;
 ; RV64IBS-LABEL: or_i64_66901:
 ; RV64IBS:       # %bb.0:
-; RV64IBS-NEXT:    lui a1, 16
-; RV64IBS-NEXT:    addiw a1, a1, 1365
-; RV64IBS-NEXT:    or a0, a0, a1
+; RV64IBS-NEXT:    ori a0, a0, 1365
+; RV64IBS-NEXT:    bseti a0, a0, 16
 ; RV64IBS-NEXT:    ret
   %or = or i64 %a, 66901
   ret i64 %or


        


More information about the llvm-commits mailing list