Skip to content

Commit 4f7ce10

Browse files
committed
[RISCV] Don't combine (sext_inreg (fmv_x_anyexth X), i16) with Zhinx.
With Zfh and Zfhmin this combine creates a fmv_x_signexth node so we can remember that the result is sign extended. This become a fmv.x.h instruction which sign extends its result. With Zhinx, fmv_x_signexth becomes a COPY_TO_REGCLASS. In order for this to guarantee the result is properly sign extended we need all producers of a GPRF16 register class to guarantee the rest of the GPR is sign extended. I don't think we've done that. bitcasts from i16 to f16 definitely don't do it. The safest thing to do is to not do this combine so the sign_extend_inreg will emit a shift pair. This is also consistent with the code generated for Zfinx on RV64, we don't assume the upper 32 bits are sign extended.
1 parent 48809fa commit 4f7ce10

File tree

4 files changed

+7
-2
lines changed

4 files changed

+7
-2
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13843,8 +13843,10 @@ performSIGN_EXTEND_INREGCombine(SDNode *N, SelectionDAG &DAG,
1384313843
EVT VT = N->getValueType(0);
1384413844

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

llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,6 @@ def : Pat<(any_fpextend FPR16INX:$rs1), (FCVT_S_H_INX FPR16INX:$rs1, FRM_RNE)>;
458458
// Moves (no conversion)
459459
def : Pat<(f16 (riscv_fmv_h_x GPR:$src)), (COPY_TO_REGCLASS GPR:$src, GPR)>;
460460
def : Pat<(riscv_fmv_x_anyexth FPR16INX:$src), (COPY_TO_REGCLASS FPR16INX:$src, GPR)>;
461-
def : Pat<(riscv_fmv_x_signexth FPR16INX:$src), (COPY_TO_REGCLASS FPR16INX:$src, GPR)>;
462461

463462
def : Pat<(fcopysign FPR32INX:$rs1, FPR16INX:$rs2), (FSGNJ_S_INX $rs1, (FCVT_S_H_INX $rs2, FRM_RNE))>;
464463
} // Predicates = [HasStdExtZhinxmin]

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ define signext i16 @bcvt_f16_to_sext_i16(half %a, half %b) nounwind {
123123
; RV64IZHINX-LABEL: bcvt_f16_to_sext_i16:
124124
; RV64IZHINX: # %bb.0:
125125
; RV64IZHINX-NEXT: fadd.h a0, a0, a1
126+
; RV64IZHINX-NEXT: slli a0, a0, 48
127+
; RV64IZHINX-NEXT: srai a0, a0, 48
126128
; RV64IZHINX-NEXT: ret
127129
%1 = fadd half %a, %b
128130
%2 = bitcast half %1 to i16

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ define signext i16 @bcvt_f16_to_sext_i16(half %a, half %b) nounwind {
144144
; RV64IZHINXMIN-NEXT: fcvt.s.h a0, a0
145145
; RV64IZHINXMIN-NEXT: fadd.s a0, a0, a1
146146
; RV64IZHINXMIN-NEXT: fcvt.h.s a0, a0
147+
; RV64IZHINXMIN-NEXT: slli a0, a0, 48
148+
; RV64IZHINXMIN-NEXT: srai a0, a0, 48
147149
; RV64IZHINXMIN-NEXT: ret
148150
%1 = fadd half %a, %b
149151
%2 = bitcast half %1 to i16

0 commit comments

Comments
 (0)