Skip to content

Commit 673d68c

Browse files
committed
[RISCV] Fold (sext_inreg (fmv_x_anyexth X), i16) -> (fmv_x_signexth X).
Add a new ISD opcode to represent the sign extending behavior of vmv.x.h. Keep the previous anyext opcode to allow the existing (fmv_x_anyexth (fmv_h_x X)) combine to keep working without needing to generate a sign extend. For fmv.x.w we are able to match the sext_inreg in an isel pattern, but a 16-bit sext_inreg is lowered to a shift pair before isel. This seemed like a larger match than we should do in isel. Differential Revision: https://reviews.llvm.org/D118974
1 parent 7c67592 commit 673d68c

File tree

4 files changed

+24
-4
lines changed

4 files changed

+24
-4
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
10691069
setTargetDAGCombine(ISD::OR);
10701070
setTargetDAGCombine(ISD::XOR);
10711071
setTargetDAGCombine(ISD::ANY_EXTEND);
1072+
if (Subtarget.hasStdExtZfh())
1073+
setTargetDAGCombine(ISD::SIGN_EXTEND_INREG);
10721074
if (Subtarget.hasStdExtF()) {
10731075
setTargetDAGCombine(ISD::ZERO_EXTEND);
10741076
setTargetDAGCombine(ISD::FP_TO_SINT);
@@ -7355,6 +7357,18 @@ static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG) {
73557357
return combineSelectAndUseCommutative(N, DAG, /*AllOnes*/ false);
73567358
}
73577359

7360+
static SDValue performSIGN_EXTEND_INREG(SDNode *N, SelectionDAG &DAG) {
7361+
SDValue Src = N->getOperand(0);
7362+
7363+
// Fold (sext_inreg (fmv_x_anyexth X), i16) -> (fmv_x_signexth X)
7364+
if (Src.getOpcode() == RISCVISD::FMV_X_ANYEXTH &&
7365+
cast<VTSDNode>(N->getOperand(1))->getVT().bitsGE(MVT::i16))
7366+
return DAG.getNode(RISCVISD::FMV_X_SIGNEXTH, SDLoc(N), N->getValueType(0),
7367+
Src.getOperand(0));
7368+
7369+
return SDValue();
7370+
}
7371+
73587372
// Attempt to turn ANY_EXTEND into SIGN_EXTEND if the input to the ANY_EXTEND
73597373
// has users that require SIGN_EXTEND and the SIGN_EXTEND can be done for free
73607374
// by an instruction like ADDW/SUBW/MULW. Without this the ANY_EXTEND would be
@@ -7941,6 +7955,8 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
79417955
return performORCombine(N, DAG, Subtarget);
79427956
case ISD::XOR:
79437957
return performXORCombine(N, DAG);
7958+
case ISD::SIGN_EXTEND_INREG:
7959+
return performSIGN_EXTEND_INREG(N, DAG);
79447960
case ISD::ANY_EXTEND:
79457961
return performANY_EXTENDCombine(N, DCI, Subtarget);
79467962
case ISD::ZERO_EXTEND:
@@ -10336,6 +10352,7 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
1033610352
NODE_NAME_CASE(FSR)
1033710353
NODE_NAME_CASE(FMV_H_X)
1033810354
NODE_NAME_CASE(FMV_X_ANYEXTH)
10355+
NODE_NAME_CASE(FMV_X_SIGNEXTH)
1033910356
NODE_NAME_CASE(FMV_W_X_RV64)
1034010357
NODE_NAME_CASE(FMV_X_ANYEXTW_RV64)
1034110358
NODE_NAME_CASE(FCVT_X)

llvm/lib/Target/RISCV/RISCVISelLowering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,15 @@ enum NodeType : unsigned {
7575
//
7676
// FMV_H_X matches the semantics of the FMV.H.X.
7777
// FMV_X_ANYEXTH is similar to FMV.X.H but has an any-extended result.
78+
// FMV_X_SIGNEXTH is similar to FMV.X.H and has a sign-extended result.
7879
// FMV_W_X_RV64 matches the semantics of the FMV.W.X.
7980
// FMV_X_ANYEXTW_RV64 is similar to FMV.X.W but has an any-extended result.
8081
//
8182
// This is a more convenient semantic for producing dagcombines that remove
8283
// unnecessary GPR->FPR->GPR moves.
8384
FMV_H_X,
8485
FMV_X_ANYEXTH,
86+
FMV_X_SIGNEXTH,
8587
FMV_W_X_RV64,
8688
FMV_X_ANYEXTW_RV64,
8789
// FP to XLen int conversions. Corresponds to fcvt.l(u).s/d/h on RV64 and

llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717

1818
def SDT_RISCVFMV_H_X
1919
: SDTypeProfile<1, 1, [SDTCisVT<0, f16>, SDTCisVT<1, XLenVT>]>;
20-
def SDT_RISCVFMV_X_ANYEXTH
20+
def SDT_RISCVFMV_X_EXTH
2121
: SDTypeProfile<1, 1, [SDTCisVT<0, XLenVT>, SDTCisVT<1, f16>]>;
2222

2323
def riscv_fmv_h_x
2424
: SDNode<"RISCVISD::FMV_H_X", SDT_RISCVFMV_H_X>;
2525
def riscv_fmv_x_anyexth
26-
: SDNode<"RISCVISD::FMV_X_ANYEXTH", SDT_RISCVFMV_X_ANYEXTH>;
26+
: SDNode<"RISCVISD::FMV_X_ANYEXTH", SDT_RISCVFMV_X_EXTH>;
27+
def riscv_fmv_x_signexth
28+
: SDNode<"RISCVISD::FMV_X_SIGNEXTH", SDT_RISCVFMV_X_EXTH>;
2729

2830
//===----------------------------------------------------------------------===//
2931
// Instructions
@@ -299,6 +301,7 @@ def : Pat<(any_fpextend FPR16:$rs1), (FCVT_S_H FPR16:$rs1)>;
299301
// Moves (no conversion)
300302
def : Pat<(riscv_fmv_h_x GPR:$src), (FMV_H_X GPR:$src)>;
301303
def : Pat<(riscv_fmv_x_anyexth FPR16:$src), (FMV_X_H FPR16:$src)>;
304+
def : Pat<(riscv_fmv_x_signexth FPR16:$src), (FMV_X_H FPR16:$src)>;
302305
} // Predicates = [HasStdExtZfhOrZfhmin]
303306

304307
let Predicates = [HasStdExtZfh, IsRV32] in {

llvm/test/CodeGen/RISCV/rv64zfh-half-convert.ll

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@ define signext i16 @bcvt_f16_to_sext_i16(half %a, half %b) nounwind {
7979
; RV64IZFH: # %bb.0:
8080
; RV64IZFH-NEXT: fadd.h ft0, fa0, fa1
8181
; RV64IZFH-NEXT: fmv.x.h a0, ft0
82-
; RV64IZFH-NEXT: slli a0, a0, 48
83-
; RV64IZFH-NEXT: srai a0, a0, 48
8482
; RV64IZFH-NEXT: ret
8583
%1 = fadd half %a, %b
8684
%2 = bitcast half %1 to i16

0 commit comments

Comments
 (0)