[llvm] 4f7ce10 - [RISCV] Don't combine (sext_inreg (fmv_x_anyexth X), i16) with Zhinx.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 14 15:20:53 PDT 2024
Author: Craig Topper
Date: 2024-08-14T15:18:10-07:00
New Revision: 4f7ce107de0c3ae0fb5748f98bc696b6eec7aad9
URL: https://github.com/llvm/llvm-project/commit/4f7ce107de0c3ae0fb5748f98bc696b6eec7aad9
DIFF: https://github.com/llvm/llvm-project/commit/4f7ce107de0c3ae0fb5748f98bc696b6eec7aad9.diff
LOG: [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.
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
llvm/test/CodeGen/RISCV/rv64zfh-half-convert.ll
llvm/test/CodeGen/RISCV/rv64zfhmin-half-convert.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 2b14deb479bf6f..02f48d41b56b3c 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -13843,8 +13843,10 @@ performSIGN_EXTEND_INREGCombine(SDNode *N, SelectionDAG &DAG,
EVT VT = N->getValueType(0);
// 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))
+ cast<VTSDNode>(N->getOperand(1))->getVT().bitsGE(MVT::i16) &&
+ Subtarget.hasStdExtZfhmin())
return DAG.getNode(RISCVISD::FMV_X_SIGNEXTH, SDLoc(N), VT,
Src.getOperand(0));
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
index 85715ca9145c35..abdd366741eb04 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
@@ -458,7 +458,6 @@ def : Pat<(any_fpextend FPR16INX:$rs1), (FCVT_S_H_INX FPR16INX:$rs1, FRM_RNE)>;
// Moves (no conversion)
def : Pat<(f16 (riscv_fmv_h_x GPR:$src)), (COPY_TO_REGCLASS GPR:$src, GPR)>;
def : Pat<(riscv_fmv_x_anyexth FPR16INX:$src), (COPY_TO_REGCLASS FPR16INX:$src, GPR)>;
-def : Pat<(riscv_fmv_x_signexth FPR16INX:$src), (COPY_TO_REGCLASS FPR16INX:$src, GPR)>;
def : Pat<(fcopysign FPR32INX:$rs1, FPR16INX:$rs2), (FSGNJ_S_INX $rs1, (FCVT_S_H_INX $rs2, FRM_RNE))>;
} // Predicates = [HasStdExtZhinxmin]
diff --git a/llvm/test/CodeGen/RISCV/rv64zfh-half-convert.ll b/llvm/test/CodeGen/RISCV/rv64zfh-half-convert.ll
index 08dcefa0464030..9aec4dea63b9d2 100644
--- a/llvm/test/CodeGen/RISCV/rv64zfh-half-convert.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zfh-half-convert.ll
@@ -123,6 +123,8 @@ define signext i16 @bcvt_f16_to_sext_i16(half %a, half %b) nounwind {
; RV64IZHINX-LABEL: bcvt_f16_to_sext_i16:
; RV64IZHINX: # %bb.0:
; RV64IZHINX-NEXT: fadd.h a0, a0, a1
+; RV64IZHINX-NEXT: slli a0, a0, 48
+; RV64IZHINX-NEXT: srai a0, a0, 48
; RV64IZHINX-NEXT: ret
%1 = fadd half %a, %b
%2 = bitcast half %1 to i16
diff --git a/llvm/test/CodeGen/RISCV/rv64zfhmin-half-convert.ll b/llvm/test/CodeGen/RISCV/rv64zfhmin-half-convert.ll
index f867fe46f0ec33..aac1a65e6c4fec 100644
--- a/llvm/test/CodeGen/RISCV/rv64zfhmin-half-convert.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zfhmin-half-convert.ll
@@ -144,6 +144,8 @@ define signext i16 @bcvt_f16_to_sext_i16(half %a, half %b) nounwind {
; RV64IZHINXMIN-NEXT: fcvt.s.h a0, a0
; RV64IZHINXMIN-NEXT: fadd.s a0, a0, a1
; RV64IZHINXMIN-NEXT: fcvt.h.s a0, a0
+; RV64IZHINXMIN-NEXT: slli a0, a0, 48
+; RV64IZHINXMIN-NEXT: srai a0, a0, 48
; RV64IZHINXMIN-NEXT: ret
%1 = fadd half %a, %b
%2 = bitcast half %1 to i16
More information about the llvm-commits
mailing list