[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