[llvm] 8f62a80 - [RISCV] Optimize (and (shl GPR:, uimm5:), 0xffffffff) to use 2 shifts instead of 3.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 25 23:32:23 PDT 2021


Author: Craig Topper
Date: 2021-03-25T23:31:01-07:00
New Revision: 8f62a80328e34aee34246af4d7e3981ebe9ef37f

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

LOG: [RISCV] Optimize (and (shl GPR:, uimm5:), 0xffffffff) to use 2 shifts instead of 3.

The and would normally become SLLI+SRLI, giving us 2 SLLI+SRLI. We
can detect this and combine the 2 SLLIs into 1.

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVInstrInfo.td
    llvm/test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index b07204c00ac9..ba483469a5a9 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -320,6 +320,12 @@ def ImmSub32 : SDNodeXForm<imm, [{
                                    N->getValueType(0));
 }]>;
 
+// Return an immediate value plus 32.
+def ImmPlus32 : SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant(N->getSExtValue() + 32, SDLoc(N),
+                                   N->getValueType(0));
+}]>;
+
 // Return an immediate subtracted from XLen.
 def ImmSubFromXLen : SDNodeXForm<imm, [{
   uint64_t XLen = Subtarget->getXLen();
@@ -1141,6 +1147,11 @@ def : Pat<(i64 (shl (and GPR:$rs1, 0xffffffff), uimm5:$shamt)),
 // shl/and can appear in the other order too.
 def : Pat<(i64 (SLLIUWPat GPR:$rs1, uimm5:$shamt)),
           (SRLI (SLLI GPR:$rs1, 32), (ImmSubFrom32 uimm5:$shamt))>;
+
+// If we're shifting a value left by 0-31 bits, and then masking to 32-bits,
+// use 2 shifts instead of 3.
+def : Pat<(i64 (and (shl GPR:$rs1, uimm5:$shamt), 0xffffffff)),
+          (SRLI (SLLI GPR:$rs1, (ImmPlus32 uimm5:$shamt)), 32)>;
 }
 
 let Predicates = [IsRV64] in {

diff  --git a/llvm/test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll b/llvm/test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll
index b14ed50315d7..8c6c5d79de81 100644
--- a/llvm/test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll
+++ b/llvm/test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll
@@ -1478,8 +1478,7 @@ define signext i32 @sext_slliw_zext(i32 zeroext %a) nounwind {
 define zeroext i32 @zext_slliw_aext(i32 %a) nounwind {
 ; RV64I-LABEL: zext_slliw_aext:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    slli a0, a0, 7
-; RV64I-NEXT:    slli a0, a0, 32
+; RV64I-NEXT:    slli a0, a0, 39
 ; RV64I-NEXT:    srli a0, a0, 32
 ; RV64I-NEXT:    ret
   %1 = shl i32 %a, 7
@@ -1489,8 +1488,7 @@ define zeroext i32 @zext_slliw_aext(i32 %a) nounwind {
 define zeroext i32 @zext_slliw_sext(i32 signext %a) nounwind {
 ; RV64I-LABEL: zext_slliw_sext:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    slli a0, a0, 8
-; RV64I-NEXT:    slli a0, a0, 32
+; RV64I-NEXT:    slli a0, a0, 40
 ; RV64I-NEXT:    srli a0, a0, 32
 ; RV64I-NEXT:    ret
   %1 = shl i32 %a, 8
@@ -1500,8 +1498,7 @@ define zeroext i32 @zext_slliw_sext(i32 signext %a) nounwind {
 define zeroext i32 @zext_slliw_zext(i32 zeroext %a) nounwind {
 ; RV64I-LABEL: zext_slliw_zext:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    slli a0, a0, 9
-; RV64I-NEXT:    slli a0, a0, 32
+; RV64I-NEXT:    slli a0, a0, 41
 ; RV64I-NEXT:    srli a0, a0, 32
 ; RV64I-NEXT:    ret
   %1 = shl i32 %a, 9


        


More information about the llvm-commits mailing list