[llvm] [X86] Split FLDEXP when AVX512 is not available (PR #208292)

Evgenii Kudriashov via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 8 11:53:45 PDT 2026


https://github.com/e-kud created https://github.com/llvm/llvm-project/pull/208292

Mark the 512-bit types Custom only under useAVX512Regs(); otherwise generic type legalization splits FLDEXP into the legal narrower halves that LowerFLDEXP handles.

Add a LIT test for the v8f64 -> two 256-bit vscalefpd split.

>From 94f5f6ea6631c713db11db2be4588b51040892f7 Mon Sep 17 00:00:00 2001
From: Yanliang Mu <yanliang.mu at intel.com>
Date: Wed, 8 Jul 2026 09:53:33 -0700
Subject: [PATCH] [X86] Split FLDEXP when AVX512 is not available

Mark the 512-bit types Custom only under useAVX512Regs(); otherwise
generic type legalization splits FLDEXP into the legal narrower halves
that LowerFLDEXP handles.

Add a LIT test for the v8f64 -> two 256-bit vscalefpd split.
---
 llvm/lib/Target/X86/X86ISelLowering.cpp |  5 ++--
 llvm/test/CodeGen/X86/ldexp-avx512.ll   | 31 +++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index cc3aba9d431d6..f0af991cfaf6c 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -1899,6 +1899,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
       setOperationAction(ISD::STRICT_FMA, VT, Legal);
       setOperationAction(ISD::FCOPYSIGN, VT, Custom);
       setOperationAction(ISD::FCANONICALIZE, VT, Expand);
+      setOperationAction(ISD::FLDEXP, VT, Custom);
     }
     setOperationAction(ISD::LRINT, MVT::v16f32,
                        Subtarget.hasDQI() ? Legal : Custom);
@@ -2196,6 +2197,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
     setOperationAction(ISD::FNEG, MVT::v32f16, Custom);
     setOperationAction(ISD::FABS, MVT::v32f16, Custom);
     setOperationAction(ISD::FCOPYSIGN, MVT::v32f16, Custom);
+    setOperationAction(ISD::FLDEXP, MVT::v32f16, Custom);
 
     if (Subtarget.hasGFNI()) {
       setOperationAction(ISD::CTLZ, MVT::v64i8, Custom);
@@ -2221,8 +2223,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
   // narrower widths.
   if (!Subtarget.useSoftFloat() && Subtarget.hasAVX512()) {
     for (MVT VT : {MVT::f16, MVT::f32, MVT::f64, MVT::v8f16, MVT::v4f32,
-                   MVT::v2f64, MVT::v16f16, MVT::v8f32, MVT::v4f64, MVT::v32f16,
-                   MVT::v16f32, MVT::v8f64})
+                   MVT::v2f64, MVT::v16f16, MVT::v8f32, MVT::v4f64})
       setOperationAction(ISD::FLDEXP, VT, Custom);
 
     // These operations are handled on non-VLX by artificially widening in
diff --git a/llvm/test/CodeGen/X86/ldexp-avx512.ll b/llvm/test/CodeGen/X86/ldexp-avx512.ll
index 9ed867060a9c7..874596ed3e41d 100644
--- a/llvm/test/CodeGen/X86/ldexp-avx512.ll
+++ b/llvm/test/CodeGen/X86/ldexp-avx512.ll
@@ -321,5 +321,36 @@ define <8 x double> @test_ldexp_8xdouble(<8 x double> %x, <8 x i32> %exp) nounwi
 }
 declare <8 x double> @llvm.ldexp.v8f64.v8i32(<8 x double>, <8 x i32>)
 
+; When 512-bit vectors are disabled (prefer-vector-width=256) the v8f64 FLDEXP
+; result type is illegal and must be split by generic type legalization into
+; two legal 256-bit halves, rather than being diverted into ReplaceNodeResults.
+define <8 x double> @test_ldexp_8xdouble_prefer256(<8 x double> %x, <8 x i32> %exp) nounwind "min-legal-vector-width"="256" "prefer-vector-width"="256" {
+; AVX512-LABEL: test_ldexp_8xdouble_prefer256:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vcvtdq2pd %ymm1, %zmm1
+; AVX512-NEXT:    vscalefpd %zmm1, %zmm0, %zmm0
+; AVX512-NEXT:    retq
+;
+; AVX512VL-LABEL: test_ldexp_8xdouble_prefer256:
+; AVX512VL:       # %bb.0:
+; AVX512VL-NEXT:    vextractf128 $1, %ymm2, %xmm3
+; AVX512VL-NEXT:    vcvtdq2pd %xmm2, %ymm2
+; AVX512VL-NEXT:    vscalefpd %ymm2, %ymm0, %ymm0
+; AVX512VL-NEXT:    vcvtdq2pd %xmm3, %ymm2
+; AVX512VL-NEXT:    vscalefpd %ymm2, %ymm1, %ymm1
+; AVX512VL-NEXT:    retq
+;
+; AVX512VLFP16-LABEL: test_ldexp_8xdouble_prefer256:
+; AVX512VLFP16:       # %bb.0:
+; AVX512VLFP16-NEXT:    vextractf128 $1, %ymm2, %xmm3
+; AVX512VLFP16-NEXT:    vcvtdq2pd %xmm2, %ymm2
+; AVX512VLFP16-NEXT:    vscalefpd %ymm2, %ymm0, %ymm0
+; AVX512VLFP16-NEXT:    vcvtdq2pd %xmm3, %ymm2
+; AVX512VLFP16-NEXT:    vscalefpd %ymm2, %ymm1, %ymm1
+; AVX512VLFP16-NEXT:    retq
+  %r = call <8 x double> @llvm.ldexp.v8f64.v8i32(<8 x double> %x, <8 x i32> %exp)
+  ret <8 x double> %r
+}
+
 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
 ; AVX512VLF: {{.*}}



More information about the llvm-commits mailing list