Skip to content

Commit 8f62a80

Browse files
committed
[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.
1 parent 5a18c57 commit 8f62a80

File tree

2 files changed

+14
-6
lines changed

2 files changed

+14
-6
lines changed

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,12 @@ def ImmSub32 : SDNodeXForm<imm, [{
320320
N->getValueType(0));
321321
}]>;
322322

323+
// Return an immediate value plus 32.
324+
def ImmPlus32 : SDNodeXForm<imm, [{
325+
return CurDAG->getTargetConstant(N->getSExtValue() + 32, SDLoc(N),
326+
N->getValueType(0));
327+
}]>;
328+
323329
// Return an immediate subtracted from XLen.
324330
def ImmSubFromXLen : SDNodeXForm<imm, [{
325331
uint64_t XLen = Subtarget->getXLen();
@@ -1141,6 +1147,11 @@ def : Pat<(i64 (shl (and GPR:$rs1, 0xffffffff), uimm5:$shamt)),
11411147
// shl/and can appear in the other order too.
11421148
def : Pat<(i64 (SLLIUWPat GPR:$rs1, uimm5:$shamt)),
11431149
(SRLI (SLLI GPR:$rs1, 32), (ImmSubFrom32 uimm5:$shamt))>;
1150+
1151+
// If we're shifting a value left by 0-31 bits, and then masking to 32-bits,
1152+
// use 2 shifts instead of 3.
1153+
def : Pat<(i64 (and (shl GPR:$rs1, uimm5:$shamt), 0xffffffff)),
1154+
(SRLI (SLLI GPR:$rs1, (ImmPlus32 uimm5:$shamt)), 32)>;
11441155
}
11451156

11461157
let Predicates = [IsRV64] in {

llvm/test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,8 +1478,7 @@ define signext i32 @sext_slliw_zext(i32 zeroext %a) nounwind {
14781478
define zeroext i32 @zext_slliw_aext(i32 %a) nounwind {
14791479
; RV64I-LABEL: zext_slliw_aext:
14801480
; RV64I: # %bb.0:
1481-
; RV64I-NEXT: slli a0, a0, 7
1482-
; RV64I-NEXT: slli a0, a0, 32
1481+
; RV64I-NEXT: slli a0, a0, 39
14831482
; RV64I-NEXT: srli a0, a0, 32
14841483
; RV64I-NEXT: ret
14851484
%1 = shl i32 %a, 7
@@ -1489,8 +1488,7 @@ define zeroext i32 @zext_slliw_aext(i32 %a) nounwind {
14891488
define zeroext i32 @zext_slliw_sext(i32 signext %a) nounwind {
14901489
; RV64I-LABEL: zext_slliw_sext:
14911490
; RV64I: # %bb.0:
1492-
; RV64I-NEXT: slli a0, a0, 8
1493-
; RV64I-NEXT: slli a0, a0, 32
1491+
; RV64I-NEXT: slli a0, a0, 40
14941492
; RV64I-NEXT: srli a0, a0, 32
14951493
; RV64I-NEXT: ret
14961494
%1 = shl i32 %a, 8
@@ -1500,8 +1498,7 @@ define zeroext i32 @zext_slliw_sext(i32 signext %a) nounwind {
15001498
define zeroext i32 @zext_slliw_zext(i32 zeroext %a) nounwind {
15011499
; RV64I-LABEL: zext_slliw_zext:
15021500
; RV64I: # %bb.0:
1503-
; RV64I-NEXT: slli a0, a0, 9
1504-
; RV64I-NEXT: slli a0, a0, 32
1501+
; RV64I-NEXT: slli a0, a0, 41
15051502
; RV64I-NEXT: srli a0, a0, 32
15061503
; RV64I-NEXT: ret
15071504
%1 = shl i32 %a, 9

0 commit comments

Comments
 (0)