diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -1534,6 +1534,7 @@ bool RISCVDAGToDAGISel::hasAllNBitUsers(SDNode *Node, unsigned Bits) const { assert((Node->getOpcode() == ISD::ADD || Node->getOpcode() == ISD::SUB || Node->getOpcode() == ISD::MUL || Node->getOpcode() == ISD::SHL || + Node->getOpcode() == ISD::SIGN_EXTEND_INREG || isa(Node)) && "Unexpected opcode"); diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -1262,10 +1262,18 @@ return hasAllWUsers(Node); }]>; +def sexti32_allwusers : PatFrag<(ops node:$src), + (sext_inreg node:$src, i32), [{ + return hasAllWUsers(Node); +}]>; + let Predicates = [IsRV64] in { /// sext and zext +// Sign extend is not needed if all users are W instructions. +def : Pat<(sexti32_allwusers GPR:$rs1), (XLenVT GPR:$rs1)>; + def : Pat<(sext_inreg GPR:$rs1, i32), (ADDIW GPR:$rs1, 0)>; /// ALU operations diff --git a/llvm/test/CodeGen/RISCV/rv64zba.ll b/llvm/test/CodeGen/RISCV/rv64zba.ll --- a/llvm/test/CodeGen/RISCV/rv64zba.ll +++ b/llvm/test/CodeGen/RISCV/rv64zba.ll @@ -375,8 +375,7 @@ ; selected as sh2add which does not sign extend. SimplifyDemandedBits is unable ; to remove the sext_inreg because it has multiple uses. The ashr will use the ; sext_inreg to become sraiw. The shl usage is unnecessary if it is selected -; as a sllw. -; FIXME: We should not emit a sext.w. +; as a sllw. Make sure we don't emit a sext.w. define i64 @sh2add_extra_sext(i32 %x, i32 %y, i32 %z) { ; RV64I-LABEL: sh2add_extra_sext: ; RV64I: # %bb.0: @@ -390,8 +389,7 @@ ; RV64B-LABEL: sh2add_extra_sext: ; RV64B: # %bb.0: ; RV64B-NEXT: sh2add a0, a0, a1 -; RV64B-NEXT: sext.w a1, a0 -; RV64B-NEXT: sllw a1, a2, a1 +; RV64B-NEXT: sllw a1, a2, a0 ; RV64B-NEXT: sraiw a0, a0, 2 ; RV64B-NEXT: mul a0, a1, a0 ; RV64B-NEXT: ret @@ -399,8 +397,7 @@ ; RV64ZBA-LABEL: sh2add_extra_sext: ; RV64ZBA: # %bb.0: ; RV64ZBA-NEXT: sh2add a0, a0, a1 -; RV64ZBA-NEXT: sext.w a1, a0 -; RV64ZBA-NEXT: sllw a1, a2, a1 +; RV64ZBA-NEXT: sllw a1, a2, a0 ; RV64ZBA-NEXT: sraiw a0, a0, 2 ; RV64ZBA-NEXT: mul a0, a1, a0 ; RV64ZBA-NEXT: ret