[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