Skip to content

Commit dfff57e

Browse files
authored
[RISCV] Add isel special case for (and (shl X, c2), c1) -> (slli_uw (srli x, c3-c2), c3). (#91638)
Where c1 is a shifted mask with 32 set bits and c3 trailing zeros.
1 parent 5a0e0b6 commit dfff57e

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,19 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
14161416
ReplaceNode(Node, SLLI);
14171417
return;
14181418
}
1419+
1420+
// If we have 32 bits in the mask, we can use SLLI_UW instead of SLLI.
1421+
if (C2 < Trailing && Leading + Trailing == 32 && OneUseOrZExtW &&
1422+
Subtarget->hasStdExtZba()) {
1423+
SDNode *SRLI = CurDAG->getMachineNode(
1424+
RISCV::SRLI, DL, VT, X,
1425+
CurDAG->getTargetConstant(Trailing - C2, DL, VT));
1426+
SDNode *SLLI_UW = CurDAG->getMachineNode(
1427+
RISCV::SLLI_UW, DL, VT, SDValue(SRLI, 0),
1428+
CurDAG->getTargetConstant(Trailing, DL, VT));
1429+
ReplaceNode(Node, SLLI_UW);
1430+
return;
1431+
}
14191432
}
14201433
}
14211434

llvm/test/CodeGen/RISCV/rv64zba.ll

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2866,8 +2866,7 @@ define ptr @gep_lshr_i32(ptr %0, i64 %1) {
28662866
;
28672867
; RV64ZBA-LABEL: gep_lshr_i32:
28682868
; RV64ZBA: # %bb.0: # %entry
2869-
; RV64ZBA-NEXT: slli a1, a1, 2
2870-
; RV64ZBA-NEXT: srli a1, a1, 4
2869+
; RV64ZBA-NEXT: srli a1, a1, 2
28712870
; RV64ZBA-NEXT: slli.uw a1, a1, 4
28722871
; RV64ZBA-NEXT: sh2add a1, a1, a1
28732872
; RV64ZBA-NEXT: add a0, a0, a1
@@ -2891,8 +2890,7 @@ define i64 @srli_slliw(i64 %1) {
28912890
;
28922891
; RV64ZBA-LABEL: srli_slliw:
28932892
; RV64ZBA: # %bb.0: # %entry
2894-
; RV64ZBA-NEXT: slli a0, a0, 2
2895-
; RV64ZBA-NEXT: srli a0, a0, 4
2893+
; RV64ZBA-NEXT: srli a0, a0, 2
28962894
; RV64ZBA-NEXT: slli.uw a0, a0, 4
28972895
; RV64ZBA-NEXT: ret
28982896
entry:
@@ -2902,6 +2900,40 @@ entry:
29022900
ret i64 %4
29032901
}
29042902

2903+
define i64 @srli_slliw_canonical(i64 %0) {
2904+
; RV64I-LABEL: srli_slliw_canonical:
2905+
; RV64I: # %bb.0: # %entry
2906+
; RV64I-NEXT: slli a0, a0, 2
2907+
; RV64I-NEXT: li a1, 1
2908+
; RV64I-NEXT: slli a1, a1, 36
2909+
; RV64I-NEXT: addi a1, a1, -16
2910+
; RV64I-NEXT: and a0, a0, a1
2911+
; RV64I-NEXT: ret
2912+
;
2913+
; RV64ZBA-LABEL: srli_slliw_canonical:
2914+
; RV64ZBA: # %bb.0: # %entry
2915+
; RV64ZBA-NEXT: srli a0, a0, 2
2916+
; RV64ZBA-NEXT: slli.uw a0, a0, 4
2917+
; RV64ZBA-NEXT: ret
2918+
entry:
2919+
%1 = shl i64 %0, 2
2920+
%2 = and i64 %1, 68719476720
2921+
ret i64 %2
2922+
}
2923+
2924+
; Make sure we don't accidentally use slli.uw with a shift of 32.
2925+
define i64 @srli_slliuw_negative_test(i64 %0) {
2926+
; CHECK-LABEL: srli_slliuw_negative_test:
2927+
; CHECK: # %bb.0: # %entry
2928+
; CHECK-NEXT: srli a0, a0, 6
2929+
; CHECK-NEXT: slli a0, a0, 32
2930+
; CHECK-NEXT: ret
2931+
entry:
2932+
%1 = lshr i64 %0, 6
2933+
%2 = shl i64 %1, 32
2934+
ret i64 %2
2935+
}
2936+
29052937
define i64 @srli_slli_i16(i64 %1) {
29062938
; CHECK-LABEL: srli_slli_i16:
29072939
; CHECK: # %bb.0: # %entry

0 commit comments

Comments
 (0)