Skip to content

Commit 839c821

Browse files
authored
[LegalizeTypes][RISCV][X86] Legalize FP_ROUND to libcall in SoftPromoteHalfRes_FP_ROUND if the input type is softened. (#119481)
Previously we created an FP_TO_FP16 and legalized it in SoftenFloatOp_FP_ROUND. This caused i16 to be sent to call lowering instead of f16. This results in the ABI not being followed if f16 is supposed to be passed in a different register than i16. Looking at the libgcc binary for the library function it appears the value is returned in xmm0 so the X86 test was being miscompiled before. Fixes #107607.
1 parent 5797ed6 commit 839c821

File tree

4 files changed

+1295
-2
lines changed

4 files changed

+1295
-2
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3415,6 +3415,23 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND(SDNode *N) {
34153415
SDValue Op = N->getOperand(IsStrict ? 1 : 0);
34163416
EVT SVT = Op.getValueType();
34173417

3418+
// If the input type needs to be softened, do that now so that call lowering
3419+
// will see the f16 type.
3420+
if (getTypeAction(SVT) == TargetLowering::TypeSoftenFloat) {
3421+
RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, RVT);
3422+
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall");
3423+
3424+
SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
3425+
Op = GetSoftenedFloat(Op);
3426+
TargetLowering::MakeLibCallOptions CallOptions;
3427+
CallOptions.setTypeListBeforeSoften(SVT, RVT, true);
3428+
std::pair<SDValue, SDValue> Tmp =
3429+
TLI.makeLibCall(DAG, LC, RVT, Op, CallOptions, SDLoc(N), Chain);
3430+
if (IsStrict)
3431+
ReplaceValueWith(SDValue(N, 1), Tmp.second);
3432+
return DAG.getNode(ISD::BITCAST, SDLoc(N), MVT::i16, Tmp.first);
3433+
}
3434+
34183435
if (IsStrict) {
34193436
SDValue Res = DAG.getNode(GetPromotionOpcodeStrict(SVT, RVT), SDLoc(N),
34203437
{MVT::i16, MVT::Other}, {N->getOperand(0), Op});

0 commit comments

Comments
 (0)