[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