[llvm] [X86] Fix assertion when lowering FP_ROUND (PR #185562)

Aiden Grossman via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 10 13:51:37 PDT 2026


https://github.com/boomanaiden154 updated https://github.com/llvm/llvm-project/pull/185562

>From 3dc591bdb8f15c5b31bf646b439ffff6a2edbaaa Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Tue, 10 Mar 2026 03:01:03 +0000
Subject: [PATCH 1/4] [X86] Fix assertion when lowering FP_ROUND

443ce5569ee9854cfef1139cf6b9cf05165e0902 caused us to start hitting
assertions with non-standard vector widths (<3 x float>) in this case
now that node types are actually enforced. There was a place in
X86ISelLowering.cpp where we just passed along a 64-bit integer whereas
other places constructing a CVTPS2PH node specifically construct a new
integer.
---
 llvm/lib/Target/X86/X86ISelLowering.cpp       | 10 ++++--
 .../CodeGen/X86/vector-half-conversions.ll    | 34 +++++++++++++++++++
 2 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 4ce343922a02e..48f4e71f3c514 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -35390,10 +35390,14 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
         return;
 
       if (IsStrict)
-        V = DAG.getNode(X86ISD::STRICT_CVTPS2PH, dl, {MVT::v8i16, MVT::Other},
-                        {Chain, Src, Rnd});
+        V = DAG.getNode(
+            X86ISD::STRICT_CVTPS2PH, dl, {MVT::v8i16, MVT::Other},
+            {Chain, Src,
+             DAG.getTargetConstant(Rnd->getAsZExtVal(), dl, MVT::i32)});
       else
-        V = DAG.getNode(X86ISD::CVTPS2PH, dl, MVT::v8i16, Src, Rnd);
+        V = DAG.getNode(
+            X86ISD::CVTPS2PH, dl, MVT::v8i16, Src,
+            DAG.getTargetConstant(Rnd->getAsZExtVal(), dl, MVT::i32));
 
       Results.push_back(DAG.getBitcast(MVT::v8f16, V));
       if (IsStrict)
diff --git a/llvm/test/CodeGen/X86/vector-half-conversions.ll b/llvm/test/CodeGen/X86/vector-half-conversions.ll
index 2fd0a96a6e4b0..3121856e7e07b 100644
--- a/llvm/test/CodeGen/X86/vector-half-conversions.ll
+++ b/llvm/test/CodeGen/X86/vector-half-conversions.ll
@@ -2178,6 +2178,40 @@ define <4 x i16> @cvt_4f32_to_4i16(<4 x float> %a0) nounwind {
   ret <4 x i16> %2
 }
 
+define <3 x half> @cvt_3f32_to_3f16(<3 x float> %a0) nounwind {
+; AVX-LABEL: cvt_3f32_to_3f16:
+; AVX:       # %bb.0:
+; AVX-NEXT:    subq $56, %rsp
+; AVX-NEXT:    vmovapd %xmm0, (%rsp) # 16-byte Spill
+; AVX-NEXT:    vshufpd {{.*#+}} xmm0 = xmm0[1,0]
+; AVX-NEXT:    callq __truncsfhf2 at PLT
+; AVX-NEXT:    vmovapd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; AVX-NEXT:    vmovshdup (%rsp), %xmm0 # 16-byte Folded Reload
+; AVX-NEXT:    # xmm0 = mem[1,1,3,3]
+; AVX-NEXT:    callq __truncsfhf2 at PLT
+; AVX-NEXT:    vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; AVX-NEXT:    vmovdqa (%rsp), %xmm0 # 16-byte Reload
+; AVX-NEXT:    callq __truncsfhf2 at PLT
+; AVX-NEXT:    vpunpcklwd {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload
+; AVX-NEXT:    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1],xmm0[2],mem[2],xmm0[3],mem[3]
+; AVX-NEXT:    vinsertps $28, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload
+; AVX-NEXT:    # xmm0 = xmm0[0],mem[0],zero,zero
+; AVX-NEXT:    addq $56, %rsp
+; AVX-NEXT:    retq
+;
+; F16C-LABEL: cvt_3f32_to_3f16:
+; F16C:       # %bb.0:
+; F16C-NEXT:    vcvtps2ph $0, %xmm0, %xmm0
+; F16C-NEXT:    retq
+;
+; AVX512-LABEL: cvt_3f32_to_3f16:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vcvtps2ph $0, %xmm0, %xmm0
+; AVX512-NEXT:    retq
+  %1 = fptrunc <3 x float> %a0 to <3 x half>
+  ret <3 x half> %1
+}
+
 define <8 x i16> @cvt_4f32_to_8i16_undef(<4 x float> %a0) nounwind {
 ; AVX-LABEL: cvt_4f32_to_8i16_undef:
 ; AVX:       # %bb.0:

>From 756ee92731877e0d5f7d51a33ae210556bcd48ef Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Tue, 10 Mar 2026 13:07:11 +0000
Subject: [PATCH 2/4] feedback

---
 llvm/lib/Target/X86/X86ISelLowering.cpp          | 10 +++++-----
 llvm/test/CodeGen/X86/vector-half-conversions.ll |  4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 48f4e71f3c514..fc58a984631c6 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -35375,7 +35375,6 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
     bool IsStrict = N->isStrictFPOpcode();
     SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
     SDValue Src = N->getOperand(IsStrict ? 1 : 0);
-    SDValue Rnd = N->getOperand(IsStrict ? 2 : 1);
     EVT SrcVT = Src.getValueType();
     EVT VT = N->getValueType(0);
     SDValue V;
@@ -35393,11 +35392,12 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
         V = DAG.getNode(
             X86ISD::STRICT_CVTPS2PH, dl, {MVT::v8i16, MVT::Other},
             {Chain, Src,
-             DAG.getTargetConstant(Rnd->getAsZExtVal(), dl, MVT::i32)});
+             DAG.getTargetConstant(X86::STATIC_ROUNDING::CUR_DIRECTION, dl,
+                                   MVT::i32)});
       else
-        V = DAG.getNode(
-            X86ISD::CVTPS2PH, dl, MVT::v8i16, Src,
-            DAG.getTargetConstant(Rnd->getAsZExtVal(), dl, MVT::i32));
+        V = DAG.getNode(X86ISD::CVTPS2PH, dl, MVT::v8i16, Src,
+                        DAG.getTargetConstant(
+                            X86::STATIC_ROUNDING::CUR_DIRECTION, dl, MVT::i32));
 
       Results.push_back(DAG.getBitcast(MVT::v8f16, V));
       if (IsStrict)
diff --git a/llvm/test/CodeGen/X86/vector-half-conversions.ll b/llvm/test/CodeGen/X86/vector-half-conversions.ll
index 3121856e7e07b..8048985ccb1ff 100644
--- a/llvm/test/CodeGen/X86/vector-half-conversions.ll
+++ b/llvm/test/CodeGen/X86/vector-half-conversions.ll
@@ -2201,12 +2201,12 @@ define <3 x half> @cvt_3f32_to_3f16(<3 x float> %a0) nounwind {
 ;
 ; F16C-LABEL: cvt_3f32_to_3f16:
 ; F16C:       # %bb.0:
-; F16C-NEXT:    vcvtps2ph $0, %xmm0, %xmm0
+; F16C-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
 ; F16C-NEXT:    retq
 ;
 ; AVX512-LABEL: cvt_3f32_to_3f16:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vcvtps2ph $0, %xmm0, %xmm0
+; AVX512-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
 ; AVX512-NEXT:    retq
   %1 = fptrunc <3 x float> %a0 to <3 x half>
   ret <3 x half> %1

>From 5c984639e1cb22e7ea4f841630d176a7f0ba1c5f Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Tue, 10 Mar 2026 20:41:25 +0000
Subject: [PATCH 3/4] remove stopgap

---
 llvm/lib/Target/X86/X86SelectionDAGInfo.cpp | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/llvm/lib/Target/X86/X86SelectionDAGInfo.cpp b/llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
index f6b00f6a924c6..1e55e329c44e7 100644
--- a/llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
+++ b/llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
@@ -88,9 +88,6 @@ void X86SelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
     // result #0 must have type v2i64, but has type v16i8/v8i16
   case X86ISD::CMPCCXADD:
     // operand #4 must have type i8, but has type i32
-  case X86ISD::CVTPS2PH:
-    // invalid node: operand #1 must have type i32, but has type i64
-    return;
   }
 
   SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);

>From 28a617897f006a2b15f8aa0baa3392613c056425 Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Tue, 10 Mar 2026 20:51:23 +0000
Subject: [PATCH 4/4] fix

---
 llvm/lib/Target/X86/X86SelectionDAGInfo.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/lib/Target/X86/X86SelectionDAGInfo.cpp b/llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
index 1e55e329c44e7..77f8a3f266e10 100644
--- a/llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
+++ b/llvm/lib/Target/X86/X86SelectionDAGInfo.cpp
@@ -88,6 +88,7 @@ void X86SelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
     // result #0 must have type v2i64, but has type v16i8/v8i16
   case X86ISD::CMPCCXADD:
     // operand #4 must have type i8, but has type i32
+    return;
   }
 
   SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);



More information about the llvm-commits mailing list