[llvm] [X86] Move Non-VLX handling for VPMADD52 instructions entirely into tablegen (PR #200800)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 1 06:32:37 PDT 2026


https://github.com/RKSimon updated https://github.com/llvm/llvm-project/pull/200800

>From 9a756bdd5cdb5d104631b9672bea40e7d3d0b77f Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Mon, 1 Jun 2026 13:36:44 +0100
Subject: [PATCH] [X86] Move Non-VLX handling for VPMADD52 instructions
 entirely into tablegen

Just widen v2i64/v4i64 cases to v8i64

Removes more VLX/NoVLX testing from DAG
---
 llvm/lib/Target/X86/X86ISelLowering.cpp       | 10 ++-----
 llvm/lib/Target/X86/X86InstrAVX512.td         | 29 +++++++++++++++++++
 .../test/CodeGen/X86/ifma-combine-vpmadd52.ll | 11 ++++---
 llvm/test/CodeGen/X86/slow-pmullq.ll          |  6 ++--
 4 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 7656b0442c853..66846654cbbdd 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -50755,9 +50755,8 @@ static SDValue combineMulToPMADD52(SDNode *N, const SDLoc &DL,
   // 128/256-bit vectors (v2i64/v4i64) require either AVX512-IFMA + VLX, or
   // AVX-IFMA.
   bool Supported512 = (VT == MVT::v8i64) && Subtarget.hasIFMA();
-  bool SupportedSmall =
-      (VT == MVT::v2i64 || VT == MVT::v4i64) &&
-      ((Subtarget.hasIFMA() && Subtarget.hasVLX()) || Subtarget.hasAVXIFMA());
+  bool SupportedSmall = (VT == MVT::v2i64 || VT == MVT::v4i64) &&
+                        (Subtarget.hasIFMA() || Subtarget.hasAVXIFMA());
 
   if (!Supported512 && !SupportedSmall)
     return SDValue();
@@ -59718,11 +59717,6 @@ static SDValue matchVPMADD52(SDNode *N, SelectionDAG &DAG, const SDLoc &DL,
       (!Subtarget.hasAVXIFMA() && !Subtarget.hasIFMA()))
     return SDValue();
 
-  // Need AVX-512VL vector length extensions if operating on XMM/YMM registers
-  if (!Subtarget.hasAVXIFMA() && !Subtarget.hasVLX() &&
-      VT.getSizeInBits() < 512)
-    return SDValue();
-
   const auto TotalSize = VT.getSizeInBits();
   if (TotalSize < 128 || !isPowerOf2_64(TotalSize))
     return SDValue();
diff --git a/llvm/lib/Target/X86/X86InstrAVX512.td b/llvm/lib/Target/X86/X86InstrAVX512.td
index 95c75165ed4eb..1122258e5bcf9 100644
--- a/llvm/lib/Target/X86/X86InstrAVX512.td
+++ b/llvm/lib/Target/X86/X86InstrAVX512.td
@@ -7229,6 +7229,35 @@ defm VPMADD52HUQ : avx512_pmadd52_common<0xb5, "vpmadd52huq", x86vpmadd52h,
                                          SchedWriteVecIMul, avx512vl_i64_info>,
                                          REX_W;
 
+// Use 512bit VPMADD52LUQ/VPMADD52HUQ version to implement 128/256 bit in case NoVLX.
+let Predicates = [HasIFMA, NoVLX] in {
+  def : Pat<(v2i64 (x86vpmadd52l VR128X:$x, VR128X:$y, VR128X:$z)),
+            (EXTRACT_SUBREG
+             (VPMADD52LUQZr
+              (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR128X:$x, sub_xmm),
+              (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR128X:$y, sub_xmm),
+              (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR128X:$z, sub_xmm)), sub_xmm)>;
+  def : Pat<(v2i64 (x86vpmadd52l VR128X:$x, VR128X:$y, VR128X:$z)),
+            (EXTRACT_SUBREG
+             (VPMADD52HUQZr
+              (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR128X:$x, sub_xmm),
+              (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR128X:$y, sub_xmm),
+              (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR128X:$z, sub_xmm)), sub_xmm)>;
+
+  def : Pat<(v4i64 (x86vpmadd52l VR256X:$x, VR256X:$y, VR256X:$z)),
+            (EXTRACT_SUBREG
+             (VPMADD52LUQZr
+              (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$x, sub_ymm),
+              (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$y, sub_ymm),
+              (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$z, sub_ymm)), sub_ymm)>;
+  def : Pat<(v4i64 (x86vpmadd52l VR256X:$x, VR256X:$y, VR256X:$z)),
+            (EXTRACT_SUBREG
+             (VPMADD52HUQZr
+              (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$x, sub_ymm),
+              (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$y, sub_ymm),
+              (INSERT_SUBREG (v8i64 (IMPLICIT_DEF)), VR256X:$z, sub_ymm)), sub_ymm)>;
+}
+
 //===----------------------------------------------------------------------===//
 // AVX-512  Scalar convert from sign integer to float/double
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/CodeGen/X86/ifma-combine-vpmadd52.ll b/llvm/test/CodeGen/X86/ifma-combine-vpmadd52.ll
index 019496c504887..3287cdcf6d672 100644
--- a/llvm/test/CodeGen/X86/ifma-combine-vpmadd52.ll
+++ b/llvm/test/CodeGen/X86/ifma-combine-vpmadd52.ll
@@ -222,11 +222,12 @@ define <4 x i64> @test_256_combine(<4 x i64> %x, <4 x i64> %y, <4 x i64> %z) {
 ;
 ; AVX512-NOVL-LABEL: test_256_combine:
 ; AVX512-NOVL:       # %bb.0:
+; AVX512-NOVL-NEXT:    # kill: def $ymm2 killed $ymm2 def $zmm2
 ; AVX512-NOVL-NEXT:    vpbroadcastq {{.*#+}} ymm3 = [67108863,67108863,67108863,67108863]
 ; AVX512-NOVL-NEXT:    vpand %ymm3, %ymm0, %ymm0
 ; AVX512-NOVL-NEXT:    vpand %ymm3, %ymm1, %ymm1
-; AVX512-NOVL-NEXT:    vpmuldq %ymm1, %ymm0, %ymm0
-; AVX512-NOVL-NEXT:    vpaddq %ymm0, %ymm2, %ymm0
+; AVX512-NOVL-NEXT:    vpmadd52luq %zmm2, %zmm1, %zmm0
+; AVX512-NOVL-NEXT:    # kill: def $ymm0 killed $ymm0 killed $zmm0
 ; AVX512-NOVL-NEXT:    retq
 ;
 ; AVX512VL-LABEL: test_256_combine:
@@ -274,11 +275,13 @@ define <2 x i64> @test_128_combine(<2 x i64> %x, <2 x i64> %y, <2 x i64> %z) {
 ;
 ; AVX512-NOVL-LABEL: test_128_combine:
 ; AVX512-NOVL:       # %bb.0:
+; AVX512-NOVL-NEXT:    # kill: def $xmm2 killed $xmm2 def $zmm2
 ; AVX512-NOVL-NEXT:    vpbroadcastq {{.*#+}} xmm3 = [67108863,67108863]
 ; AVX512-NOVL-NEXT:    vpand %xmm3, %xmm0, %xmm0
 ; AVX512-NOVL-NEXT:    vpand %xmm3, %xmm1, %xmm1
-; AVX512-NOVL-NEXT:    vpmuldq %xmm1, %xmm0, %xmm0
-; AVX512-NOVL-NEXT:    vpaddq %xmm0, %xmm2, %xmm0
+; AVX512-NOVL-NEXT:    vpmadd52luq %zmm2, %zmm1, %zmm0
+; AVX512-NOVL-NEXT:    # kill: def $xmm0 killed $xmm0 killed $zmm0
+; AVX512-NOVL-NEXT:    vzeroupper
 ; AVX512-NOVL-NEXT:    retq
 ;
 ; AVX512VL-LABEL: test_128_combine:
diff --git a/llvm/test/CodeGen/X86/slow-pmullq.ll b/llvm/test/CodeGen/X86/slow-pmullq.ll
index 501bdf1761366..e3bb600cb7042 100644
--- a/llvm/test/CodeGen/X86/slow-pmullq.ll
+++ b/llvm/test/CodeGen/X86/slow-pmullq.ll
@@ -169,7 +169,8 @@ define <4 x i64> @test_mul_52bit_ymm(<4 x i64> %a, <4 x i64> %b) {
 ; NOVLX-NEXT:    vpand %ymm2, %ymm0, %ymm0
 ; NOVLX-NEXT:    vpbroadcastq {{.*#+}} ymm2 = [524287,524287,524287,524287]
 ; NOVLX-NEXT:    vpand %ymm2, %ymm1, %ymm1
-; NOVLX-NEXT:    vpmullq %zmm1, %zmm0, %zmm0
+; NOVLX-NEXT:    vpxor %xmm2, %xmm2, %xmm2
+; NOVLX-NEXT:    vpmadd52luq %zmm2, %zmm1, %zmm0
 ; NOVLX-NEXT:    # kill: def $ymm0 killed $ymm0 killed $zmm0
 ; NOVLX-NEXT:    retq
 ;
@@ -187,7 +188,8 @@ define <4 x i64> @test_mul_52bit_ymm(<4 x i64> %a, <4 x i64> %b) {
 ; GENERIC-NOVLX-NEXT:    vpand %ymm2, %ymm0, %ymm0
 ; GENERIC-NOVLX-NEXT:    vpbroadcastq {{.*#+}} ymm2 = [524287,524287,524287,524287]
 ; GENERIC-NOVLX-NEXT:    vpand %ymm2, %ymm1, %ymm1
-; GENERIC-NOVLX-NEXT:    vpmullq %zmm1, %zmm0, %zmm0
+; GENERIC-NOVLX-NEXT:    vpxor %xmm2, %xmm2, %xmm2
+; GENERIC-NOVLX-NEXT:    vpmadd52luq %zmm2, %zmm1, %zmm0
 ; GENERIC-NOVLX-NEXT:    # kill: def $ymm0 killed $ymm0 killed $zmm0
 ; GENERIC-NOVLX-NEXT:    retq
 



More information about the llvm-commits mailing list