Skip to content

Commit

Permalink
[RISCV][DAGCombine] Combine sext_inreg (shl X, Y), i32 into `sllw X…
Browse files Browse the repository at this point in the history
  • Loading branch information
dtcxzyw authored Oct 4, 2024
1 parent 1753de2 commit 9cf8c09
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 4 deletions.
16 changes: 12 additions & 4 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1489,6 +1489,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
ISD::INTRINSIC_WO_CHAIN, ISD::ADD, ISD::SUB, ISD::MUL,
ISD::AND, ISD::OR, ISD::XOR, ISD::SETCC, ISD::SELECT});
setTargetDAGCombine(ISD::SRA);
setTargetDAGCombine(ISD::SIGN_EXTEND_INREG);

if (Subtarget.hasStdExtFOrZfinx())
setTargetDAGCombine({ISD::FADD, ISD::FMAXNUM, ISD::FMINNUM, ISD::FMUL});
Expand All @@ -1502,8 +1503,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,

if (Subtarget.hasStdExtZbkb())
setTargetDAGCombine(ISD::BITREVERSE);
if (Subtarget.hasStdExtZfhminOrZhinxmin())
setTargetDAGCombine(ISD::SIGN_EXTEND_INREG);

if (Subtarget.hasStdExtFOrZfinx())
setTargetDAGCombine({ISD::ZERO_EXTEND, ISD::FP_TO_SINT, ISD::FP_TO_UINT,
ISD::FP_TO_SINT_SAT, ISD::FP_TO_UINT_SAT});
Expand Down Expand Up @@ -14456,15 +14456,23 @@ performSIGN_EXTEND_INREGCombine(SDNode *N, SelectionDAG &DAG,
const RISCVSubtarget &Subtarget) {
SDValue Src = N->getOperand(0);
EVT VT = N->getValueType(0);
EVT SrcVT = cast<VTSDNode>(N->getOperand(1))->getVT();
unsigned Opc = Src.getOpcode();

// Fold (sext_inreg (fmv_x_anyexth X), i16) -> (fmv_x_signexth X)
// Don't do this with Zhinx. We need to explicitly sign extend the GPR.
if (Src.getOpcode() == RISCVISD::FMV_X_ANYEXTH &&
cast<VTSDNode>(N->getOperand(1))->getVT().bitsGE(MVT::i16) &&
if (Opc == RISCVISD::FMV_X_ANYEXTH && SrcVT.bitsGE(MVT::i16) &&
Subtarget.hasStdExtZfhmin())
return DAG.getNode(RISCVISD::FMV_X_SIGNEXTH, SDLoc(N), VT,
Src.getOperand(0));

// Fold (sext_inreg (shl X, Y), i32) -> (sllw X, Y) iff Y u< 32
if (Opc == ISD::SHL && Subtarget.is64Bit() && SrcVT == MVT::i32 &&
VT == MVT::i64 && !isa<ConstantSDNode>(Src.getOperand(1)) &&
DAG.computeKnownBits(Src.getOperand(1)).countMaxActiveBits() <= 5)
return DAG.getNode(RISCVISD::SLLW, SDLoc(N), VT, Src.getOperand(0),
Src.getOperand(1));

return SDValue();
}

Expand Down
33 changes: 33 additions & 0 deletions llvm/test/CodeGen/RISCV/rv64zbs.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1210,3 +1210,36 @@ define i1 @icmp_eq_nonpow2(i32 signext %x) nounwind {
%cmp = icmp eq i32 %x, 32767
ret i1 %cmp
}

define signext i32 @fold_sextinreg_shl_to_sllw(i64 %x) nounwind {
; CHECK-LABEL: fold_sextinreg_shl_to_sllw:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: li a1, 1
; CHECK-NEXT: sllw a0, a1, a0
; CHECK-NEXT: ret
entry:
%mask = and i64 %x, 31
%shl = shl i64 1, %mask
%trunc = trunc i64 %shl to i32
ret i32 %trunc
}

define signext i32 @fold_sextinreg_shl_to_sllw_large_shamt(i64 %x) nounwind {
; RV64I-LABEL: fold_sextinreg_shl_to_sllw_large_shamt:
; RV64I: # %bb.0: # %entry
; RV64I-NEXT: li a1, 1
; RV64I-NEXT: sll a0, a1, a0
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: ret
;
; RV64ZBS-LABEL: fold_sextinreg_shl_to_sllw_large_shamt:
; RV64ZBS: # %bb.0: # %entry
; RV64ZBS-NEXT: bset a0, zero, a0
; RV64ZBS-NEXT: sext.w a0, a0
; RV64ZBS-NEXT: ret
entry:
%mask = and i64 %x, 63
%shl = shl i64 1, %mask
%trunc = trunc i64 %shl to i32
ret i32 %trunc
}

0 comments on commit 9cf8c09

Please sign in to comment.