llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-aarch64 Author: Matt Arsenault (arsenm) <details> <summary>Changes</summary> Co-authored-by: Claude (Claude-Opus-4.8) <noreply@<!-- -->anthropic.com> --- Full diff: https://github.com/llvm/llvm-project/pull/221439.diff 3 Files Affected: - (modified) llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (+3-3) - (modified) llvm/test/CodeGen/ARM/cortex-a57-misched-vfma.ll (+203-31) - (modified) llvm/test/CodeGen/Hexagon/sffms.ll (+3-3) ``````````diff diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 82d4921ae405b..733d0eb9baa40 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -18910,7 +18910,6 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) { EVT VT = N->getValueType(0); SDLoc SL(N); - const TargetOptions &Options = DAG.getTarget().Options; // Floating-point multiply-add with intermediate rounding. bool HasFMAD = (LegalOperations && TLI.isFMADLegal(DAG, N)); @@ -18924,8 +18923,9 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) { return SDValue(); const SDNodeFlags Flags = N->getFlags(); - bool AllowFusionGlobally = - (Options.AllowFPOpFusion == FPOpFusion::Fast || HasFMAD); + // FMAD (with intermediate rounding) is always safe to form; FMA requires the + // contract fast-math flag. + bool AllowFusionGlobally = HasFMAD; // If the subtraction is not contractable, do not combine. if (!AllowFusionGlobally && !N->getFlags().hasAllowContract()) diff --git a/llvm/test/CodeGen/ARM/cortex-a57-misched-vfma.ll b/llvm/test/CodeGen/ARM/cortex-a57-misched-vfma.ll index 557102c24bd7c..1d5eb8f73aac2 100644 --- a/llvm/test/CodeGen/ARM/cortex-a57-misched-vfma.ll +++ b/llvm/test/CodeGen/ARM/cortex-a57-misched-vfma.ll @@ -1,6 +1,5 @@ ; REQUIRES: asserts -; RUN: llc < %s -mtriple=armv8r-eabi -mcpu=cortex-a57 -enable-misched -verify-misched -debug-only=machine-scheduler -o - 2>&1 > /dev/null | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DEFAULT -; RUN: llc < %s -mtriple=armv8r-eabi -mcpu=cortex-a57 -enable-misched -verify-misched -debug-only=machine-scheduler -o - 2>&1 > /dev/null -fp-contract=fast | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-FAST +; RUN: llc < %s -mtriple=armv8r-eabi -mcpu=cortex-a57 -enable-misched -verify-misched -debug-only=machine-scheduler -o - 2>&1 > /dev/null | FileCheck %s --check-prefix=CHECK ; Check latencies of vmul/vfma accumulate chains. define arm_aapcs_vfpcc float @Test1(float %f1, float %f2, float %f3, float %f4, float %f5, float %f6) { @@ -15,8 +14,7 @@ define arm_aapcs_vfpcc float @Test1(float %f1, float %f2, float %f3, float %f4, ; > VMULS read-advanced latency to VMLAS = 0 ; CHECK-SAME: Latency=0 -; CHECK-DEFAULT: VMLAS -; CHECK-FAST: VFMAS +; CHECK: VMLAS ; > VMLAS common latency = 9 ; CHECK: Latency : 9 ; CHECK: Successors: @@ -24,8 +22,7 @@ define arm_aapcs_vfpcc float @Test1(float %f1, float %f2, float %f3, float %f4, ; > VMLAS read-advanced latency to the next VMLAS = 4 ; CHECK-SAME: Latency=4 -; CHECK-DEFAULT: VMLAS -; CHECK-FAST: VFMAS +; CHECK: VMLAS ; CHECK: Latency : 9 ; CHECK: Successors: ; CHECK: Data @@ -41,6 +38,42 @@ define arm_aapcs_vfpcc float @Test1(float %f1, float %f2, float %f3, float %f4, ret float %add2 } +define arm_aapcs_vfpcc float @Test1_contract(float %f1, float %f2, float %f3, float %f4, float %f5, float %f6) { +; CHECK: Current Schedule Region +; CHECK: Test1_contract:%bb.0 + +; CHECK: VMULS +; > VMULS common latency = 5 +; CHECK: Latency : 5 +; CHECK: Successors: +; CHECK: Data +; > VMULS read-advanced latency to VFMAS = 0 +; CHECK-SAME: Latency=0 + +; CHECK: VFMAS +; > VFMAS common latency = 9 +; CHECK: Latency : 9 +; CHECK: Successors: +; CHECK: Data +; > VFMAS read-advanced latency to the next VFMAS = 4 +; CHECK-SAME: Latency=4 + +; CHECK: VFMAS +; CHECK: Latency : 9 +; CHECK: Successors: +; CHECK: Data +; > VFMAS not-optimized latency to VMOVRS = 9 +; CHECK-SAME: Latency=9 + +; f1 * f2 + f3 * f4 + f5 * f6 ==> VMULS, VFMAS, VFMAS + %mul1 = fmul contract float %f1, %f2 + %mul2 = fmul contract float %f3, %f4 + %mul3 = fmul contract float %f5, %f6 + %add1 = fadd contract float %mul1, %mul2 + %add2 = fadd contract float %add1, %mul3 + ret float %add2 +} + ; ASIMD form define arm_aapcs_vfpcc <2 x float> @Test2(<2 x float> %f1, <2 x float> %f2, <2 x float> %f3, <2 x float> %f4, <2 x float> %f5, <2 x float> %f6) { ; CHECK: Current Schedule Region @@ -54,8 +87,7 @@ define arm_aapcs_vfpcc <2 x float> @Test2(<2 x float> %f1, <2 x float> %f2, <2 x ; VMULfd read-advanced latency to VMLAfd = 0 ; CHECK-SAME: Latency=0 -; CHECK-DEFAULT: VMLAfd -; CHECK-FAST: VFMAfd +; CHECK: VMLAfd ; > VMLAfd common latency = 9 ; CHECK: Latency : 9 ; CHECK: Successors: @@ -63,15 +95,14 @@ define arm_aapcs_vfpcc <2 x float> @Test2(<2 x float> %f1, <2 x float> %f2, <2 x ; > VMLAfd read-advanced latency to the next VMLAfd = 4 ; CHECK-SAME: Latency=4 -; CHECK-DEFAULT: VMLAfd -; CHECK-FAST: VFMAfd +; CHECK: VMLAfd ; CHECK: Latency : 9 ; CHECK: Successors: ; CHECK: Data ; > VMLAfd not-optimized latency to VMOVRRD = 9 ; CHECK-SAME: Latency=9 -; f1 * f2 + f3 * f4 + f5 * f6 ==> VMULS, VMLAS, VMLAS +; f1 * f2 + f3 * f4 + f5 * f6 ==> VMULfd, VMLAfd, VMLAfd %mul1 = fmul <2 x float> %f1, %f2 %mul2 = fmul <2 x float> %f3, %f4 %mul3 = fmul <2 x float> %f5, %f6 @@ -80,6 +111,44 @@ define arm_aapcs_vfpcc <2 x float> @Test2(<2 x float> %f1, <2 x float> %f2, <2 x ret <2 x float> %add2 } +; ASIMD form. The 'contract' flag does not fuse NEON <2 x float> macs, so this +; still selects the unfused VMLAfd form. +define arm_aapcs_vfpcc <2 x float> @Test2_contract(<2 x float> %f1, <2 x float> %f2, <2 x float> %f3, <2 x float> %f4, <2 x float> %f5, <2 x float> %f6) { +; CHECK: Current Schedule Region +; CHECK: Test2_contract:%bb.0 + +; CHECK: VMULfd +; > VMULfd common latency = 5 +; CHECK: Latency : 5 +; CHECK: Successors: +; CHECK: Data +; VMULfd read-advanced latency to VMLAfd = 0 +; CHECK-SAME: Latency=0 + +; CHECK: VMLAfd +; > VMLAfd common latency = 9 +; CHECK: Latency : 9 +; CHECK: Successors: +; CHECK: Data +; > VMLAfd read-advanced latency to the next VMLAfd = 4 +; CHECK-SAME: Latency=4 + +; CHECK: VMLAfd +; CHECK: Latency : 9 +; CHECK: Successors: +; CHECK: Data +; > VMLAfd not-optimized latency to VMOVRRD = 9 +; CHECK-SAME: Latency=9 + +; f1 * f2 + f3 * f4 + f5 * f6 ==> VMULfd, VMLAfd, VMLAfd + %mul1 = fmul contract <2 x float> %f1, %f2 + %mul2 = fmul contract <2 x float> %f3, %f4 + %mul3 = fmul contract <2 x float> %f5, %f6 + %add1 = fadd contract <2 x float> %mul1, %mul2 + %add2 = fadd contract <2 x float> %add1, %mul3 + ret <2 x float> %add2 +} + define arm_aapcs_vfpcc float @Test3(float %f1, float %f2, float %f3, float %f4, float %f5, float %f6) { ; CHECK: Current Schedule Region ; CHECK: Test3:%bb.0 @@ -92,24 +161,22 @@ define arm_aapcs_vfpcc float @Test3(float %f1, float %f2, float %f3, float %f4, ; > VMULS read-advanced latency to VMLSS = 0 ; CHECK-SAME: Latency=0 -; CHECK-DEFAULT: VMLSS -; CHECK-FAST: VFNMSS -; > VFNMSS common latency = 9 +; CHECK: VMLSS +; > VMLSS common latency = 9 ; CHECK: Latency : 9 ; CHECK: Successors: ; CHECK: Data -; > VFNMSS read-advanced latency to the next VMLSS = 4 +; > VMLSS read-advanced latency to the next VMLSS = 4 ; CHECK-SAME: Latency=4 -; CHECK-DEFAULT: VMLSS -; CHECK-FAST: VFMSS +; CHECK: VMLSS ; CHECK: Latency : 9 ; CHECK: Successors: ; CHECK: Data ; > VMLSS not-optimized latency to VMOVRS = 9 ; CHECK-SAME: Latency=9 -; f1 * f2 + f3 * f4 + f5 * f6 ==> VMULS, VMLSS, VMLSS +; f1 * f2 - f3 * f4 - f5 * f6 ==> VMULS, VMLSS, VMLSS %mul1 = fmul float %f1, %f2 %mul2 = fmul float %f3, %f4 %mul3 = fmul float %f5, %f6 @@ -118,6 +185,42 @@ define arm_aapcs_vfpcc float @Test3(float %f1, float %f2, float %f3, float %f4, ret float %sub2 } +define arm_aapcs_vfpcc float @Test3_contract(float %f1, float %f2, float %f3, float %f4, float %f5, float %f6) { +; CHECK: Current Schedule Region +; CHECK: Test3_contract:%bb.0 + +; CHECK: VMULS +; > VMULS common latency = 5 +; CHECK: Latency : 5 +; CHECK: Successors: +; CHECK: Data +; > VMULS read-advanced latency to VFNMSS = 0 +; CHECK-SAME: Latency=0 + +; CHECK: VFNMSS +; > VFNMSS common latency = 9 +; CHECK: Latency : 9 +; CHECK: Successors: +; CHECK: Data +; > VFNMSS read-advanced latency to the next VFMSS = 4 +; CHECK-SAME: Latency=4 + +; CHECK: VFMSS +; CHECK: Latency : 9 +; CHECK: Successors: +; CHECK: Data +; > VFMSS not-optimized latency to VMOVRS = 9 +; CHECK-SAME: Latency=9 + +; f1 * f2 - f3 * f4 - f5 * f6 ==> VMULS, VFNMSS, VFMSS + %mul1 = fmul contract float %f1, %f2 + %mul2 = fmul contract float %f3, %f4 + %mul3 = fmul contract float %f5, %f6 + %sub1 = fsub contract float %mul1, %mul2 + %sub2 = fsub contract float %sub1, %mul3 + ret float %sub2 +} + ; ASIMD form define arm_aapcs_vfpcc <2 x float> @Test4(<2 x float> %f1, <2 x float> %f2, <2 x float> %f3, <2 x float> %f4, <2 x float> %f5, <2 x float> %f6) { ; CHECK: Current Schedule Region @@ -131,8 +234,7 @@ define arm_aapcs_vfpcc <2 x float> @Test4(<2 x float> %f1, <2 x float> %f2, <2 x ; VMULfd read-advanced latency to VMLSfd = 0 ; CHECK-SAME: Latency=0 -; CHECK-DEFAULT: VMLSfd -; CHECK-FAST: VFMSfd +; CHECK: VMLSfd ; > VMLSfd common latency = 9 ; CHECK: Latency : 9 ; CHECK: Successors: @@ -140,15 +242,14 @@ define arm_aapcs_vfpcc <2 x float> @Test4(<2 x float> %f1, <2 x float> %f2, <2 x ; > VMLSfd read-advanced latency to the next VMLSfd = 4 ; CHECK-SAME: Latency=4 -; CHECK-DEFAULT: VMLSfd -; CHECK-FAST: VFMSfd +; CHECK: VMLSfd ; CHECK: Latency : 9 ; CHECK: Successors: ; CHECK: Data ; > VMLSfd not-optimized latency to VMOVRRD = 9 ; CHECK-SAME: Latency=9 -; f1 * f2 + f3 * f4 + f5 * f6 ==> VMULS, VMLSS, VMLSS +; f1 * f2 - f3 * f4 - f5 * f6 ==> VMULfd, VMLSfd, VMLSfd %mul1 = fmul <2 x float> %f1, %f2 %mul2 = fmul <2 x float> %f3, %f4 %mul3 = fmul <2 x float> %f5, %f6 @@ -157,40 +258,111 @@ define arm_aapcs_vfpcc <2 x float> @Test4(<2 x float> %f1, <2 x float> %f2, <2 x ret <2 x float> %sub2 } +; ASIMD form. The 'contract' flag does not fuse NEON <2 x float> macs, so this +; still selects the unfused VMLSfd form. +define arm_aapcs_vfpcc <2 x float> @Test4_contract(<2 x float> %f1, <2 x float> %f2, <2 x float> %f3, <2 x float> %f4, <2 x float> %f5, <2 x float> %f6) { +; CHECK: Current Schedule Region +; CHECK: Test4_contract:%bb.0 + +; CHECK: VMULfd +; > VMULfd common latency = 5 +; CHECK: Latency : 5 +; CHECK: Successors: +; CHECK: Data +; VMULfd read-advanced latency to VMLSfd = 0 +; CHECK-SAME: Latency=0 + +; CHECK: VMLSfd +; > VMLSfd common latency = 9 +; CHECK: Latency : 9 +; CHECK: Successors: +; CHECK: Data +; > VMLSfd read-advanced latency to the next VMLSfd = 4 +; CHECK-SAME: Latency=4 + +; CHECK: VMLSfd +; CHECK: Latency : 9 +; CHECK: Successors: +; CHECK: Data +; > VMLSfd not-optimized latency to VMOVRRD = 9 +; CHECK-SAME: Latency=9 + +; f1 * f2 - f3 * f4 - f5 * f6 ==> VMULfd, VMLSfd, VMLSfd + %mul1 = fmul contract <2 x float> %f1, %f2 + %mul2 = fmul contract <2 x float> %f3, %f4 + %mul3 = fmul contract <2 x float> %f5, %f6 + %sub1 = fsub contract <2 x float> %mul1, %mul2 + %sub2 = fsub contract <2 x float> %sub1, %mul3 + ret <2 x float> %sub2 +} + define arm_aapcs_vfpcc float @Test5(float %f1, float %f2, float %f3) { ; CHECK: Current Schedule Region ; CHECK: Test5:%bb.0 -; CHECK-DEFAULT: VNMLS -; CHECK-FAST: VFNMS +; CHECK: VNMLSS ; CHECK: Latency : 9 ; CHECK: Successors: ; CHECK: Data -; > VMLAS not-optimized latency to VMOVRS = 9 +; > VNMLSS not-optimized latency to VMOVRS = 9 ; CHECK-SAME: Latency=9 -; f1 * f2 - f3 ==> VNMLS/VFNMS +; f1 * f2 - f3 ==> VNMLSS %mul = fmul float %f1, %f2 %sub = fsub float %mul, %f3 ret float %sub } +define arm_aapcs_vfpcc float @Test5_contract(float %f1, float %f2, float %f3) { +; CHECK: Current Schedule Region +; CHECK: Test5_contract:%bb.0 + +; CHECK: VFNMSS +; CHECK: Latency : 9 +; CHECK: Successors: +; CHECK: Data +; > VFNMSS not-optimized latency to VMOVRS = 9 +; CHECK-SAME: Latency=9 + +; f1 * f2 - f3 ==> VFNMSS + %mul = fmul contract float %f1, %f2 + %sub = fsub contract float %mul, %f3 + ret float %sub +} + define arm_aapcs_vfpcc float @Test6(float %f1, float %f2, float %f3) { ; CHECK: Current Schedule Region ; CHECK: Test6:%bb.0 -; CHECK-DEFAULT: VNMLA -; CHECK-FAST: VFNMA +; CHECK: VNMLAS ; CHECK: Latency : 9 ; CHECK: Successors: ; CHECK: Data -; > VMLAS not-optimized latency to VMOVRS = 9 +; > VNMLAS not-optimized latency to VMOVRS = 9 ; CHECK-SAME: Latency=9 -; f1 * f2 - f3 ==> VNMLA/VFNMA +; -(f1 * f2) - f2 ==> VNMLAS %mul = fmul float %f1, %f2 %sub1 = fsub float -0.0, %mul %sub2 = fsub float %sub1, %f2 ret float %sub2 } + +define arm_aapcs_vfpcc float @Test6_contract(float %f1, float %f2, float %f3) { +; CHECK: Current Schedule Region +; CHECK: Test6_contract:%bb.0 + +; CHECK: VFNMAS +; CHECK: Latency : 9 +; CHECK: Successors: +; CHECK: Data +; > VFNMAS not-optimized latency to VMOVRS = 9 +; CHECK-SAME: Latency=9 + +; -(f1 * f2) - f2 ==> VFNMAS + %mul = fmul contract float %f1, %f2 + %sub1 = fsub contract float -0.0, %mul + %sub2 = fsub contract float %sub1, %f2 + ret float %sub2 +} diff --git a/llvm/test/CodeGen/Hexagon/sffms.ll b/llvm/test/CodeGen/Hexagon/sffms.ll index 577cad8aa9d31..a65a6f59507fc 100644 --- a/llvm/test/CodeGen/Hexagon/sffms.ll +++ b/llvm/test/CodeGen/Hexagon/sffms.ll @@ -1,4 +1,4 @@ -; RUN: llc -mtriple=hexagon -fp-contract=fast < %s | FileCheck %s +; RUN: llc -mtriple=hexagon < %s | FileCheck %s ; Check that "Rx-=sfmpy(Rs,Rt)" is being generated for "fsub(fmul(..))" @@ -16,8 +16,8 @@ entry: %arrayidx3 = getelementptr inbounds ptr, ptr %0, i32 %col1 %3 = load ptr, ptr %arrayidx3, align 4 %4 = load float, ptr %3, align 4 - %mul = fmul float %2, %4 - %sub = fsub float %2, %mul + %mul = fmul contract float %2, %4 + %sub = fsub contract float %2, %mul %arrayidx10 = getelementptr inbounds float, ptr %3, i32 %col1 store float %sub, ptr %arrayidx10, align 4 ret void `````````` </details> https://github.com/llvm/llvm-project/pull/221439 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
