Skip to content

Commit 9cdcb6f

Browse files
committed
add AddPromotedToType(ISD::FMA, MVT::f16, MVT::f64);
1 parent 6581c75 commit 9cdcb6f

17 files changed

+538
-471
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3518,7 +3518,8 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FMAD(SDNode *N) {
35183518

35193519
SDValue Res;
35203520
if (OVT == MVT::f16) {
3521-
// An f16 fma must go via f64 to prevent double rounding issues.
3521+
// If f16 fma is not natively supported, the value must be promoted to an
3522+
// f64 (and not to f32!) to prevent double rounding issues.
35223523
SDValue A64 = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Op0, Flags);
35233524
SDValue B64 = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Op1, Flags);
35243525
SDValue C64 = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Op2, Flags);

llvm/lib/CodeGen/TargetLoweringBase.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,11 @@ void TargetLoweringBase::initActions() {
842842
}
843843
}
844844

845+
// If f16 fma is not natively supported, the value must be promoted to an f64
846+
// (and not to f32!) to prevent double rounding issues.
847+
AddPromotedToType(ISD::FMA, MVT::f16, MVT::f64);
848+
AddPromotedToType(ISD::STRICT_FMA, MVT::f16, MVT::f64);
849+
845850
// Set default actions for various operations.
846851
for (MVT VT : MVT::all_valuetypes()) {
847852
// Default all indexed load / store to expand.

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,15 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
572572
setOperationAction({ISD::SINT_TO_FP, ISD::UINT_TO_FP}, XLenVT, Custom);
573573
}
574574

575+
if (!Subtarget.hasStdExtD()) {
576+
// FIXME: handle f16 fma when f64 is not legal. Using an f32 fma
577+
// instruction runs into double rounding issues, so this is wrong.
578+
// Normally we'd use an f64 fma, but without the D extension the f64 type
579+
// is not legal. This should probably be a libcall.
580+
AddPromotedToType(ISD::FMA, MVT::f16, MVT::f32);
581+
AddPromotedToType(ISD::STRICT_FMA, MVT::f16, MVT::f32);
582+
}
583+
575584
setOperationAction(ISD::BITCAST, MVT::i16, Custom);
576585

577586
setOperationAction(ISD::STRICT_FP_ROUND, MVT::f16, Legal);

llvm/test/CodeGen/AArch64/f16-instructions.ll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,11 +1378,11 @@ define half @test_log2(half %a) #0 {
13781378
define half @test_fma(half %a, half %b, half %c) #0 {
13791379
; CHECK-CVT-SD-LABEL: test_fma:
13801380
; CHECK-CVT-SD: // %bb.0:
1381-
; CHECK-CVT-SD-NEXT: fcvt s2, h2
1382-
; CHECK-CVT-SD-NEXT: fcvt s1, h1
1383-
; CHECK-CVT-SD-NEXT: fcvt s0, h0
1384-
; CHECK-CVT-SD-NEXT: fmadd s0, s0, s1, s2
1385-
; CHECK-CVT-SD-NEXT: fcvt h0, s0
1381+
; CHECK-CVT-SD-NEXT: fcvt d2, h2
1382+
; CHECK-CVT-SD-NEXT: fcvt d1, h1
1383+
; CHECK-CVT-SD-NEXT: fcvt d0, h0
1384+
; CHECK-CVT-SD-NEXT: fmadd d0, d0, d1, d2
1385+
; CHECK-CVT-SD-NEXT: fcvt h0, d0
13861386
; CHECK-CVT-SD-NEXT: ret
13871387
;
13881388
; CHECK-FP16-LABEL: test_fma:

0 commit comments

Comments
 (0)