[llvm] 958f9ff - [SLP][NFC]Add a test for mixed fma/fmuladd scalars, NFC

via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 22 07:53:28 PDT 2026


Author: Alexey Bataev
Date: 2026-07-22T10:53:24-04:00
New Revision: 958f9ff83ea9aa071df1c84c6a467b17d6b8dadf

URL: https://github.com/llvm/llvm-project/commit/958f9ff83ea9aa071df1c84c6a467b17d6b8dadf
DIFF: https://github.com/llvm/llvm-project/commit/958f9ff83ea9aa071df1c84c6a467b17d6b8dadf.diff

LOG: [SLP][NFC]Add a test for mixed fma/fmuladd scalars, NFC



Reviewers: 

Pull Request: https://github.com/llvm/llvm-project/pull/211280

Added: 
    llvm/test/Transforms/SLPVectorizer/X86/fma-fmuladd-mix.ll

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/SLPVectorizer/X86/fma-fmuladd-mix.ll b/llvm/test/Transforms/SLPVectorizer/X86/fma-fmuladd-mix.ll
new file mode 100644
index 0000000000000..3179f53823941
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/fma-fmuladd-mix.ll
@@ -0,0 +1,126 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -mtriple=x86_64-unknown -passes=slp-vectorizer -S | FileCheck %s --check-prefix=NO-FMA
+; RUN: opt < %s -mtriple=x86_64-unknown -mcpu=core-avx2 -passes=slp-vectorizer -S | FileCheck %s --check-prefix=FMA
+
+ at srcA64 = common global [8 x double] zeroinitializer, align 64
+ at srcB64 = common global [8 x double] zeroinitializer, align 64
+ at srcC64 = common global [8 x double] zeroinitializer, align 64
+ at dst64 = common global [8 x double] zeroinitializer, align 64
+
+declare double @llvm.fma.f64(double, double, double)
+declare double @llvm.fmuladd.f64(double, double, double)
+
+; A bundle mixing fma and fmuladd widens to a single vector fma on an FMA
+; target; the fmuladd lane is fused, which is one of its permitted lowerings.
+define void @fma_fmuladd_2f64() {
+; NO-FMA-LABEL: @fma_fmuladd_2f64(
+; NO-FMA-NEXT:    [[A0:%.*]] = load double, ptr @srcA64, align 8
+; NO-FMA-NEXT:    [[A1:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @srcA64, i32 0, i64 1), align 8
+; NO-FMA-NEXT:    [[B0:%.*]] = load double, ptr @srcB64, align 8
+; NO-FMA-NEXT:    [[B1:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @srcB64, i32 0, i64 1), align 8
+; NO-FMA-NEXT:    [[C0:%.*]] = load double, ptr @srcC64, align 8
+; NO-FMA-NEXT:    [[C1:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @srcC64, i32 0, i64 1), align 8
+; NO-FMA-NEXT:    [[FMA0:%.*]] = call double @llvm.fma.f64(double [[A0]], double [[B0]], double [[C0]])
+; NO-FMA-NEXT:    [[FMA1:%.*]] = call double @llvm.fmuladd.f64(double [[A1]], double [[B1]], double [[C1]])
+; NO-FMA-NEXT:    store double [[FMA0]], ptr @dst64, align 8
+; NO-FMA-NEXT:    store double [[FMA1]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 1), align 8
+; NO-FMA-NEXT:    ret void
+;
+; FMA-LABEL: @fma_fmuladd_2f64(
+; FMA-NEXT:    [[A0:%.*]] = load double, ptr @srcA64, align 8
+; FMA-NEXT:    [[A1:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @srcA64, i32 0, i64 1), align 8
+; FMA-NEXT:    [[B0:%.*]] = load double, ptr @srcB64, align 8
+; FMA-NEXT:    [[B1:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @srcB64, i32 0, i64 1), align 8
+; FMA-NEXT:    [[C0:%.*]] = load double, ptr @srcC64, align 8
+; FMA-NEXT:    [[C1:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @srcC64, i32 0, i64 1), align 8
+; FMA-NEXT:    [[FMA0:%.*]] = call double @llvm.fma.f64(double [[A0]], double [[B0]], double [[C0]])
+; FMA-NEXT:    [[FMA1:%.*]] = call double @llvm.fmuladd.f64(double [[A1]], double [[B1]], double [[C1]])
+; FMA-NEXT:    store double [[FMA0]], ptr @dst64, align 8
+; FMA-NEXT:    store double [[FMA1]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 1), align 8
+; FMA-NEXT:    ret void
+;
+  %a0 = load double, ptr @srcA64, align 8
+  %a1 = load double, ptr getelementptr inbounds ([8 x double], ptr @srcA64, i32 0, i64 1), align 8
+  %b0 = load double, ptr @srcB64, align 8
+  %b1 = load double, ptr getelementptr inbounds ([8 x double], ptr @srcB64, i32 0, i64 1), align 8
+  %c0 = load double, ptr @srcC64, align 8
+  %c1 = load double, ptr getelementptr inbounds ([8 x double], ptr @srcC64, i32 0, i64 1), align 8
+  %fma0 = call double @llvm.fma.f64(double %a0, double %b0, double %c0)
+  %fma1 = call double @llvm.fmuladd.f64(double %a1, double %b1, double %c1)
+  store double %fma0, ptr @dst64, align 8
+  store double %fma1, ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 1), align 8
+  ret void
+}
+
+; Reversed lane order: the fmuladd appears first, so the representative must be
+; switched to the fma to emit the always-fused vector form.
+define void @fmuladd_fma_2f64() {
+; NO-FMA-LABEL: @fmuladd_fma_2f64(
+; NO-FMA-NEXT:    [[A0:%.*]] = load double, ptr @srcA64, align 8
+; NO-FMA-NEXT:    [[A1:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @srcA64, i32 0, i64 1), align 8
+; NO-FMA-NEXT:    [[B0:%.*]] = load double, ptr @srcB64, align 8
+; NO-FMA-NEXT:    [[B1:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @srcB64, i32 0, i64 1), align 8
+; NO-FMA-NEXT:    [[C0:%.*]] = load double, ptr @srcC64, align 8
+; NO-FMA-NEXT:    [[C1:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @srcC64, i32 0, i64 1), align 8
+; NO-FMA-NEXT:    [[FMA0:%.*]] = call double @llvm.fmuladd.f64(double [[A0]], double [[B0]], double [[C0]])
+; NO-FMA-NEXT:    [[FMA1:%.*]] = call double @llvm.fma.f64(double [[A1]], double [[B1]], double [[C1]])
+; NO-FMA-NEXT:    store double [[FMA0]], ptr @dst64, align 8
+; NO-FMA-NEXT:    store double [[FMA1]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 1), align 8
+; NO-FMA-NEXT:    ret void
+;
+; FMA-LABEL: @fmuladd_fma_2f64(
+; FMA-NEXT:    [[A0:%.*]] = load double, ptr @srcA64, align 8
+; FMA-NEXT:    [[A1:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @srcA64, i32 0, i64 1), align 8
+; FMA-NEXT:    [[B0:%.*]] = load double, ptr @srcB64, align 8
+; FMA-NEXT:    [[B1:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @srcB64, i32 0, i64 1), align 8
+; FMA-NEXT:    [[C0:%.*]] = load double, ptr @srcC64, align 8
+; FMA-NEXT:    [[C1:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @srcC64, i32 0, i64 1), align 8
+; FMA-NEXT:    [[FMA0:%.*]] = call double @llvm.fmuladd.f64(double [[A0]], double [[B0]], double [[C0]])
+; FMA-NEXT:    [[FMA1:%.*]] = call double @llvm.fma.f64(double [[A1]], double [[B1]], double [[C1]])
+; FMA-NEXT:    store double [[FMA0]], ptr @dst64, align 8
+; FMA-NEXT:    store double [[FMA1]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 1), align 8
+; FMA-NEXT:    ret void
+;
+  %a0 = load double, ptr @srcA64, align 8
+  %a1 = load double, ptr getelementptr inbounds ([8 x double], ptr @srcA64, i32 0, i64 1), align 8
+  %b0 = load double, ptr @srcB64, align 8
+  %b1 = load double, ptr getelementptr inbounds ([8 x double], ptr @srcB64, i32 0, i64 1), align 8
+  %c0 = load double, ptr @srcC64, align 8
+  %c1 = load double, ptr getelementptr inbounds ([8 x double], ptr @srcC64, i32 0, i64 1), align 8
+  %fma0 = call double @llvm.fmuladd.f64(double %a0, double %b0, double %c0)
+  %fma1 = call double @llvm.fma.f64(double %a1, double %b1, double %c1)
+  store double %fma0, ptr @dst64, align 8
+  store double %fma1, ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 1), align 8
+  ret void
+}
+
+; Control: a pure fmuladd bundle stays fmuladd, keeping the freedom to split.
+define void @fmuladd_2f64() {
+; NO-FMA-LABEL: @fmuladd_2f64(
+; NO-FMA-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr @srcA64, align 8
+; NO-FMA-NEXT:    [[TMP2:%.*]] = load <2 x double>, ptr @srcB64, align 8
+; NO-FMA-NEXT:    [[TMP3:%.*]] = load <2 x double>, ptr @srcC64, align 8
+; NO-FMA-NEXT:    [[TMP4:%.*]] = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> [[TMP1]], <2 x double> [[TMP2]], <2 x double> [[TMP3]])
+; NO-FMA-NEXT:    store <2 x double> [[TMP4]], ptr @dst64, align 8
+; NO-FMA-NEXT:    ret void
+;
+; FMA-LABEL: @fmuladd_2f64(
+; FMA-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr @srcA64, align 8
+; FMA-NEXT:    [[TMP2:%.*]] = load <2 x double>, ptr @srcB64, align 8
+; FMA-NEXT:    [[TMP3:%.*]] = load <2 x double>, ptr @srcC64, align 8
+; FMA-NEXT:    [[TMP4:%.*]] = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> [[TMP1]], <2 x double> [[TMP2]], <2 x double> [[TMP3]])
+; FMA-NEXT:    store <2 x double> [[TMP4]], ptr @dst64, align 8
+; FMA-NEXT:    ret void
+;
+  %a0 = load double, ptr @srcA64, align 8
+  %a1 = load double, ptr getelementptr inbounds ([8 x double], ptr @srcA64, i32 0, i64 1), align 8
+  %b0 = load double, ptr @srcB64, align 8
+  %b1 = load double, ptr getelementptr inbounds ([8 x double], ptr @srcB64, i32 0, i64 1), align 8
+  %c0 = load double, ptr @srcC64, align 8
+  %c1 = load double, ptr getelementptr inbounds ([8 x double], ptr @srcC64, i32 0, i64 1), align 8
+  %fma0 = call double @llvm.fmuladd.f64(double %a0, double %b0, double %c0)
+  %fma1 = call double @llvm.fmuladd.f64(double %a1, double %b1, double %c1)
+  store double %fma0, ptr @dst64, align 8
+  store double %fma1, ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 1), align 8
+  ret void
+}


        


More information about the llvm-commits mailing list