Skip to content

Commit b5fd6b4

Browse files
committed
[RISCV] Teach instruction selection to elide sext.w in some cases.
If a sext_inreg is up for isel, and all its users are W instructions, we can skip emitting the sext_inreg. This helpful if the producing instruction can't become a W instruction. Reviewed By: asb Differential Revision: https://reviews.llvm.org/D108966
1 parent 5ebdb07 commit b5fd6b4

File tree

3 files changed

+11
-5
lines changed

3 files changed

+11
-5
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,6 +1536,7 @@ bool RISCVDAGToDAGISel::selectZExti32(SDValue N, SDValue &Val) {
15361536
bool RISCVDAGToDAGISel::hasAllNBitUsers(SDNode *Node, unsigned Bits) const {
15371537
assert((Node->getOpcode() == ISD::ADD || Node->getOpcode() == ISD::SUB ||
15381538
Node->getOpcode() == ISD::MUL || Node->getOpcode() == ISD::SHL ||
1539+
Node->getOpcode() == ISD::SIGN_EXTEND_INREG ||
15391540
isa<ConstantSDNode>(Node)) &&
15401541
"Unexpected opcode");
15411542

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,10 +1262,18 @@ class overflowingbinopw<SDPatternOperator operator>
12621262
return hasAllWUsers(Node);
12631263
}]>;
12641264

1265+
def sexti32_allwusers : PatFrag<(ops node:$src),
1266+
(sext_inreg node:$src, i32), [{
1267+
return hasAllWUsers(Node);
1268+
}]>;
1269+
12651270
let Predicates = [IsRV64] in {
12661271

12671272
/// sext and zext
12681273

1274+
// Sign extend is not needed if all users are W instructions.
1275+
def : Pat<(sexti32_allwusers GPR:$rs1), (XLenVT GPR:$rs1)>;
1276+
12691277
def : Pat<(sext_inreg GPR:$rs1, i32), (ADDIW GPR:$rs1, 0)>;
12701278

12711279
/// ALU operations

llvm/test/CodeGen/RISCV/rv64zba.ll

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,6 @@ define i64 @sh3adduw_2(i64 %0, i64 %1) {
376376
; to remove the sext_inreg because it has multiple uses. The ashr will use the
377377
; sext_inreg to become sraiw. This leaves the sext_inreg only used by the shl.
378378
; If the shl is selected as sllw, we don't need the sext_inreg.
379-
; FIXME: We should not emit a sext.w.
380379
define i64 @sh2add_extra_sext(i32 %x, i32 %y, i32 %z) {
381380
; RV64I-LABEL: sh2add_extra_sext:
382381
; RV64I: # %bb.0:
@@ -390,17 +389,15 @@ define i64 @sh2add_extra_sext(i32 %x, i32 %y, i32 %z) {
390389
; RV64B-LABEL: sh2add_extra_sext:
391390
; RV64B: # %bb.0:
392391
; RV64B-NEXT: sh2add a0, a0, a1
393-
; RV64B-NEXT: sext.w a1, a0
394-
; RV64B-NEXT: sllw a1, a2, a1
392+
; RV64B-NEXT: sllw a1, a2, a0
395393
; RV64B-NEXT: sraiw a0, a0, 2
396394
; RV64B-NEXT: mul a0, a1, a0
397395
; RV64B-NEXT: ret
398396
;
399397
; RV64ZBA-LABEL: sh2add_extra_sext:
400398
; RV64ZBA: # %bb.0:
401399
; RV64ZBA-NEXT: sh2add a0, a0, a1
402-
; RV64ZBA-NEXT: sext.w a1, a0
403-
; RV64ZBA-NEXT: sllw a1, a2, a1
400+
; RV64ZBA-NEXT: sllw a1, a2, a0
404401
; RV64ZBA-NEXT: sraiw a0, a0, 2
405402
; RV64ZBA-NEXT: mul a0, a1, a0
406403
; RV64ZBA-NEXT: ret

0 commit comments

Comments
 (0)