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 <[email protected]> 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 <[email protected]> --- .../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 <[email protected]> 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); } _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
