[llvm] CodeGen: Drop AllowFPOpFusion check from fmuladd lowering (PR #221667)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 7 00:40:09 PDT 2026
https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/221667
llvm.fmuladd is inherently contractible and intended for the target's
choice. Previously -fp-contract=off would disable the contraction lowering
of the intrinsic. Remove this check so the global option can be deleted.
Co-authored-by: Claude (Claude Opus 4.8)
>From 9f281ab92792609cb9cfcc98795f3b9416e68bdb Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Sun, 6 Sep 2026 20:23:31 +0200
Subject: [PATCH] CodeGen: Drop AllowFPOpFusion check from fmuladd lowering
llvm.fmuladd is inherently contractible and intended for the target's
choice. Previously -fp-contract=off would disable the contraction lowering
of the intrinsic. Remove this check so the global option can be deleted.
Co-authored-by: Claude (Claude Opus 4.8)
---
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 4 +--
.../SelectionDAG/SelectionDAGBuilder.cpp | 6 ++--
.../GlobalISel/arm64-irtranslator-fmuladd.ll | 35 ++++++-------------
3 files changed, 14 insertions(+), 31 deletions(-)
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index ee4bcf773433d..75f3023e479c5 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -3163,13 +3163,11 @@ bool IRTranslatorImpl::translateKnownIntrinsic(const CallInst &CI,
case Intrinsic::udiv_fix_sat:
return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIXSAT, CI, MIRBuilder);
case Intrinsic::fmuladd: {
- const TargetMachine &TM = MF->getTarget();
Register Dst = getOrCreateVReg(CI);
Register Op0 = getOrCreateVReg(*CI.getArgOperand(0));
Register Op1 = getOrCreateVReg(*CI.getArgOperand(1));
Register Op2 = getOrCreateVReg(*CI.getArgOperand(2));
- if (TM.Options.AllowFPOpFusion != FPOpFusion::Strict &&
- TLI->isFMAFasterThanFMulAndFAdd(*MF,
+ if (TLI->isFMAFasterThanFMulAndFAdd(*MF,
TLI->getValueType(*DL, CI.getType()))) {
// TODO: Revisit this to see if we should move this part of the
// lowering to the combiner.
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 710a1eda00cc1..f34f1c7e9c969 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -7229,8 +7229,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
}
case Intrinsic::fmuladd: {
EVT VT = TLI.getValueType(DAG.getDataLayout(), I.getType());
- if (TM.Options.AllowFPOpFusion != FPOpFusion::Strict &&
- TLI.isFMAFasterThanFMulAndFAdd(DAG.getMachineFunction(), VT)) {
+ if (TLI.isFMAFasterThanFMulAndFAdd(DAG.getMachineFunction(), VT)) {
setValue(&I, DAG.getNode(ISD::FMA, sdl,
getValue(I.getArgOperand(0)).getValueType(),
getValue(I.getArgOperand(0)),
@@ -8724,8 +8723,7 @@ void SelectionDAGBuilder::visitConstrainedFPIntrinsic(
case Intrinsic::experimental_constrained_fmuladd: {
Opcode = ISD::STRICT_FMA;
// Break fmuladd into fmul and fadd.
- if (TM.Options.AllowFPOpFusion == FPOpFusion::Strict ||
- !TLI.isFMAFasterThanFMulAndFAdd(DAG.getMachineFunction(), VT)) {
+ if (!TLI.isFMAFasterThanFMulAndFAdd(DAG.getMachineFunction(), VT)) {
Opers.pop_back();
SDValue Mul = DAG.getNode(ISD::STRICT_FMUL, sdl, VTs, Opers, Flags);
pushFPOpOutChain(Mul, EB);
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator-fmuladd.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator-fmuladd.ll
index b742689a3ca45..291d89cdde99a 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator-fmuladd.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator-fmuladd.ll
@@ -1,32 +1,19 @@
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-; RUN: llc -o - -verify-machineinstrs -global-isel -stop-after=irtranslator -fp-contract=fast %s | FileCheck %s --check-prefix=FPFAST
-; RUN: llc -o - -verify-machineinstrs -global-isel -stop-after=irtranslator -fp-contract=off %s | FileCheck %s --check-prefix=FPOFF
+; RUN: llc -o - -verify-machineinstrs -global-isel -stop-after=irtranslator %s | FileCheck %s
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
target triple = "aarch64--"
define float @test_fmuladd(float %x, float %y, float %z) {
- ; FPFAST-LABEL: name: test_fmuladd
- ; FPFAST: bb.1 (%ir-block.0):
- ; FPFAST-NEXT: liveins: $s0, $s1, $s2
- ; FPFAST-NEXT: {{ $}}
- ; FPFAST-NEXT: [[COPY:%[0-9]+]]:_(f32) = COPY $s0
- ; FPFAST-NEXT: [[COPY1:%[0-9]+]]:_(f32) = COPY $s1
- ; FPFAST-NEXT: [[COPY2:%[0-9]+]]:_(f32) = COPY $s2
- ; FPFAST-NEXT: [[FMA:%[0-9]+]]:_(f32) = G_FMA [[COPY]], [[COPY1]], [[COPY2]]
- ; FPFAST-NEXT: $s0 = COPY [[FMA]](f32)
- ; FPFAST-NEXT: RET_ReallyLR implicit $s0
- ;
- ; FPOFF-LABEL: name: test_fmuladd
- ; FPOFF: bb.1 (%ir-block.0):
- ; FPOFF-NEXT: liveins: $s0, $s1, $s2
- ; FPOFF-NEXT: {{ $}}
- ; FPOFF-NEXT: [[COPY:%[0-9]+]]:_(f32) = COPY $s0
- ; FPOFF-NEXT: [[COPY1:%[0-9]+]]:_(f32) = COPY $s1
- ; FPOFF-NEXT: [[COPY2:%[0-9]+]]:_(f32) = COPY $s2
- ; FPOFF-NEXT: [[FMUL:%[0-9]+]]:_(f32) = G_FMUL [[COPY]], [[COPY1]]
- ; FPOFF-NEXT: [[FADD:%[0-9]+]]:_(f32) = G_FADD [[FMUL]], [[COPY2]]
- ; FPOFF-NEXT: $s0 = COPY [[FADD]](f32)
- ; FPOFF-NEXT: RET_ReallyLR implicit $s0
+ ; CHECK-LABEL: name: test_fmuladd
+ ; CHECK: bb.1 (%ir-block.0):
+ ; CHECK-NEXT: liveins: $s0, $s1, $s2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(f32) = COPY $s0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(f32) = COPY $s1
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(f32) = COPY $s2
+ ; CHECK-NEXT: [[FMA:%[0-9]+]]:_(f32) = G_FMA [[COPY]], [[COPY1]], [[COPY2]]
+ ; CHECK-NEXT: $s0 = COPY [[FMA]](f32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $s0
%res = call float @llvm.fmuladd.f32(float %x, float %y, float %z)
ret float %res
}
More information about the llvm-commits
mailing list