[llvm-branch-commits] [llvm] [DAG] isGuaranteedNotToBeUndefOrPoison - add ISD::BITCAST demanded elements handling (PR #200933)
Krzysztof Drewniak via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Jun 4 12:54:33 PDT 2026
https://github.com/krzysz00 updated https://github.com/llvm/llvm-project/pull/200933
>From daed4961bafc10c596b945b7eb4086ddb042dd57 Mon Sep 17 00:00:00 2001
From: Krzysztof Drewniak <Krzysztof.Drewniak at amd.com>
Date: Fri, 29 May 2026 22:30:39 +0000
Subject: [PATCH 1/2] [SelectionDAG] Track bitcast demanded elements in noundef
tests
Bitcasts preserve undef/poison status, but vector bitcasts can change
which source lanes cover a demanded result lane. Map the demanded
element mask through fixed-length vector bitcasts before checking the
source where possible.
AI note: an LLM generated the code and the test, I've read them
Co-Authored-By: OpenAI Codex <codex at openai.com>
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 41 ++++++++++++++++
llvm/test/CodeGen/X86/freeze-vector.ll | 48 +++++--------------
2 files changed, 53 insertions(+), 36 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 87fa8414279b5..191cc856f0063 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5654,6 +5654,47 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
case ISD::UNDEF:
return !includesUndef(Kind);
+ case ISD::BITCAST: {
+ if (!DemandedElts)
+ return true;
+
+ SDValue Src = Op.getOperand(0);
+ EVT SrcVT = Src.getValueType();
+ EVT DstVT = Op.getValueType();
+
+ if (!SrcVT.isFixedLengthVector() || !DstVT.isFixedLengthVector())
+ return isGuaranteedNotToBeUndefOrPoison(Src, Kind, Depth + 1);
+
+ unsigned SrcEltBits = SrcVT.getScalarSizeInBits();
+ unsigned DstEltBits = DstVT.getScalarSizeInBits();
+ unsigned NumSrcElts = SrcVT.getVectorNumElements();
+ unsigned NumDstElts = DstVT.getVectorNumElements();
+
+ if (SrcEltBits == DstEltBits)
+ return isGuaranteedNotToBeUndefOrPoison(Src, DemandedElts, Kind,
+ Depth + 1);
+
+ if (SrcEltBits < DstEltBits) {
+ if (DstEltBits % SrcEltBits != 0)
+ return isGuaranteedNotToBeUndefOrPoison(Src, Kind, Depth + 1);
+
+ assert(NumSrcElts == NumDstElts * (DstEltBits / SrcEltBits) &&
+ "Unexpected fixed-width vector bitcast");
+ APInt DemandedSrcElts = APIntOps::ScaleBitMask(DemandedElts, NumSrcElts);
+ return isGuaranteedNotToBeUndefOrPoison(Src, DemandedSrcElts, Kind,
+ Depth + 1);
+ }
+
+ if (SrcEltBits % DstEltBits != 0)
+ return isGuaranteedNotToBeUndefOrPoison(Src, Kind, Depth + 1);
+
+ assert(NumDstElts == NumSrcElts * (SrcEltBits / DstEltBits) &&
+ "Unexpected fixed-width vector bitcast");
+ APInt DemandedSrcElts = APIntOps::ScaleBitMask(DemandedElts, NumSrcElts);
+ return isGuaranteedNotToBeUndefOrPoison(Src, DemandedSrcElts, Kind,
+ Depth + 1);
+ }
+
case ISD::BUILD_VECTOR:
// NOTE: BUILD_VECTOR has implicit truncation of wider scalar elements -
// this shouldn't affect the result.
diff --git a/llvm/test/CodeGen/X86/freeze-vector.ll b/llvm/test/CodeGen/X86/freeze-vector.ll
index b7bce108860cd..5f19a3d295bcc 100644
--- a/llvm/test/CodeGen/X86/freeze-vector.ll
+++ b/llvm/test/CodeGen/X86/freeze-vector.ll
@@ -166,18 +166,10 @@ define void @freeze_bitcast_to_wider_elt_escape(ptr %origin, ptr %escape, ptr %d
}
define <4 x i32> @freeze_extract_bitcast_high_demanded(<2 x i64> %a, <2 x i64> %b) {
-; X86-LABEL: freeze_extract_bitcast_high_demanded:
-; X86: # %bb.0:
-; X86-NEXT: vpsrld $1, %xmm1, %xmm0
-; X86-NEXT: retl
-;
-; X64-LABEL: freeze_extract_bitcast_high_demanded:
-; X64: # %bb.0:
-; X64-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0
-; X64-NEXT: vpsrld $1, %ymm0, %ymm0
-; X64-NEXT: vextracti128 $1, %ymm0, %xmm0
-; X64-NEXT: vzeroupper
-; X64-NEXT: retq
+; CHECK-LABEL: freeze_extract_bitcast_high_demanded:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vpsrld $1, %xmm1, %xmm0
+; CHECK-NEXT: ret{{[l|q]}}
%poisonable = add nsw <2 x i64> %a, <i64 9223372036854775807, i64 9223372036854775807>
%wide = shufflevector <2 x i64> %poisonable, <2 x i64> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
%bc = bitcast <4 x i64> %wide to <8 x i32>
@@ -188,18 +180,10 @@ define <4 x i32> @freeze_extract_bitcast_high_demanded(<2 x i64> %a, <2 x i64> %
}
define <2 x i64> @freeze_extract_bitcast_low_width_high_demanded(<4 x i32> %a, <4 x i32> %b) {
-; X86-LABEL: freeze_extract_bitcast_low_width_high_demanded:
-; X86: # %bb.0:
-; X86-NEXT: vpsrlq $1, %xmm1, %xmm0
-; X86-NEXT: retl
-;
-; X64-LABEL: freeze_extract_bitcast_low_width_high_demanded:
-; X64: # %bb.0:
-; X64-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0
-; X64-NEXT: vpsrlq $1, %ymm0, %ymm0
-; X64-NEXT: vextracti128 $1, %ymm0, %xmm0
-; X64-NEXT: vzeroupper
-; X64-NEXT: retq
+; CHECK-LABEL: freeze_extract_bitcast_low_width_high_demanded:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vpsrlq $1, %xmm1, %xmm0
+; CHECK-NEXT: ret{{[l|q]}}
%poisonable = add nsw <4 x i32> %a, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647>
%wide = shufflevector <4 x i32> %poisonable, <4 x i32> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
%bc = bitcast <8 x i32> %wide to <4 x i64>
@@ -210,18 +194,10 @@ define <2 x i64> @freeze_extract_bitcast_low_width_high_demanded(<4 x i32> %a, <
}
define <4 x i32> @freeze_extract_bitcast_equal_width_high_demanded(<4 x float> %a, <4 x float> %b) {
-; X86-LABEL: freeze_extract_bitcast_equal_width_high_demanded:
-; X86: # %bb.0:
-; X86-NEXT: vpsrld $1, %xmm1, %xmm0
-; X86-NEXT: retl
-;
-; X64-LABEL: freeze_extract_bitcast_equal_width_high_demanded:
-; X64: # %bb.0:
-; X64-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0
-; X64-NEXT: vpsrld $1, %ymm0, %ymm0
-; X64-NEXT: vextracti128 $1, %ymm0, %xmm0
-; X64-NEXT: vzeroupper
-; X64-NEXT: retq
+; CHECK-LABEL: freeze_extract_bitcast_equal_width_high_demanded:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vpsrld $1, %xmm1, %xmm0
+; CHECK-NEXT: ret{{[l|q]}}
%poisonable = fadd nnan <4 x float> %a, zeroinitializer
%wide = shufflevector <4 x float> %poisonable, <4 x float> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
%bc = bitcast <8 x float> %wide to <8 x i32>
>From 9c9f0a54e8ce33d9951951a2838a6dc8ca8e8af3 Mon Sep 17 00:00:00 2001
From: Krzysztof Drewniak <Krzysztof.Drewniak at amd.com>
Date: Wed, 3 Jun 2026 18:29:37 +0000
Subject: [PATCH 2/2] Review style etc.
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 191cc856f0063..5d0ada4a1790a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5655,20 +5655,17 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
return !includesUndef(Kind);
case ISD::BITCAST: {
- if (!DemandedElts)
- return true;
-
SDValue Src = Op.getOperand(0);
EVT SrcVT = Src.getValueType();
EVT DstVT = Op.getValueType();
- if (!SrcVT.isFixedLengthVector() || !DstVT.isFixedLengthVector())
+ if (!SrcVT.isVector() || !DstVT.isVector())
return isGuaranteedNotToBeUndefOrPoison(Src, Kind, Depth + 1);
unsigned SrcEltBits = SrcVT.getScalarSizeInBits();
unsigned DstEltBits = DstVT.getScalarSizeInBits();
- unsigned NumSrcElts = SrcVT.getVectorNumElements();
- unsigned NumDstElts = DstVT.getVectorNumElements();
+ ElementCount NumSrcElts = SrcVT.getVectorElementCount();
+ ElementCount NumDstElts = DstVT.getVectorElementCount();
if (SrcEltBits == DstEltBits)
return isGuaranteedNotToBeUndefOrPoison(Src, DemandedElts, Kind,
@@ -5679,8 +5676,9 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
return isGuaranteedNotToBeUndefOrPoison(Src, Kind, Depth + 1);
assert(NumSrcElts == NumDstElts * (DstEltBits / SrcEltBits) &&
- "Unexpected fixed-width vector bitcast");
- APInt DemandedSrcElts = APIntOps::ScaleBitMask(DemandedElts, NumSrcElts);
+ "Unexpected vector bitcast");
+ APInt DemandedSrcElts =
+ APIntOps::ScaleBitMask(DemandedElts, NumSrcElts.getKnownMinValue());
return isGuaranteedNotToBeUndefOrPoison(Src, DemandedSrcElts, Kind,
Depth + 1);
}
@@ -5689,8 +5687,9 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
return isGuaranteedNotToBeUndefOrPoison(Src, Kind, Depth + 1);
assert(NumDstElts == NumSrcElts * (SrcEltBits / DstEltBits) &&
- "Unexpected fixed-width vector bitcast");
- APInt DemandedSrcElts = APIntOps::ScaleBitMask(DemandedElts, NumSrcElts);
+ "Unexpected vector bitcast");
+ APInt DemandedSrcElts =
+ APIntOps::ScaleBitMask(DemandedElts, NumSrcElts.getKnownMinValue());
return isGuaranteedNotToBeUndefOrPoison(Src, DemandedSrcElts, Kind,
Depth + 1);
}
More information about the llvm-branch-commits
mailing list