[llvm-branch-commits] [llvm] release/23.x: [SelectionDAG] Do not flag undef bitcast lanes as known zero (PR #229742)

Aochang Liu via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Oct 7 05:28:58 PDT 2026


https://github.com/HelloWorldU created https://github.com/llvm/llvm-project/pull/229742

Backport of the TargetLowering part of 975b04bb9ed3 (#213326), which fixes the "Elements flagged as undef AND zero" assertion in SimplifyDemandedVectorElts. The computeKnownBits change in that commit is an optimization and is not needed for the fix. Adds the reproducer from the issue as a PowerPC test.

Fixes #229620

Assisted-by: Claude Opus 5.5

>From 147836ea22c87605a5fa06d609939744dacfe485 Mon Sep 17 00:00:00 2001
From: HelloWorldU <asd001liu at gmail.com>
Date: Wed, 7 Oct 2026 12:19:19 +0000
Subject: [PATCH] [SelectionDAG] Do not flag undef bitcast lanes as known zero

Backport of the TargetLowering part of 975b04bb9ed3 (#213326), which fixes
the "Elements flagged as undef AND zero" assertion in
SimplifyDemandedVectorElts. The computeKnownBits change in that commit is an
optimization and is not needed for the fix. Adds the reproducer from the issue
as a PowerPC test.

Fixes #229620

Assisted-by: Claude Opus 5.5
---
 .../CodeGen/SelectionDAG/TargetLowering.cpp   |  5 +++-
 llvm/test/CodeGen/PowerPC/pr229620.ll         | 24 +++++++++++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/PowerPC/pr229620.ll

diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 2ac0f71a96e81..8e3d51509e475 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -3403,7 +3403,9 @@ bool TargetLowering::SimplifyDemandedVectorElts(
             continue;
           for (unsigned SrcElt = 0; SrcElt != NumSrcElts; ++SrcElt) {
             unsigned Elt = Scale * SrcElt + SubElt;
-            if (DemandedElts[Elt])
+            // A wholly-undef source lane is reported as undef below; don't also
+            // flag it as zero, keeping the undef and zero sets disjoint.
+            if (DemandedElts[Elt] && !SrcUndef[SrcElt])
               KnownZero.setBit(Elt);
           }
         }
@@ -3970,6 +3972,7 @@ bool TargetLowering::SimplifyDemandedVectorElts(
     break;
   }
   }
+
   assert((KnownUndef & KnownZero) == 0 && "Elements flagged as undef AND zero");
 
   // Constant fold all undef cases.
diff --git a/llvm/test/CodeGen/PowerPC/pr229620.ll b/llvm/test/CodeGen/PowerPC/pr229620.ll
new file mode 100644
index 0000000000000..2dc96234915e4
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/pr229620.ll
@@ -0,0 +1,24 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr10 < %s | FileCheck %s
+
+;; SimplifyDemandedVectorElts must not report a bitcast lane as both undef and
+;; zero when its whole source lane is undef.
+
+define <8 x i32> @bitcast_undef_lane(<6 x i32> %x) {
+; CHECK-LABEL: bitcast_undef_lane:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    mtfprwz 0, 7
+; CHECK-NEXT:    mtfprwz 1, 8
+; CHECK-NEXT:    xxspltiw 35, 8384513
+; CHECK-NEXT:    xxmrghw 34, 1, 0
+; CHECK-NEXT:    vsubuwm 2, 3, 2
+; CHECK-NEXT:    vpkudum 3, 2, 2
+; CHECK-NEXT:    xxmrglw 34, 34, 34
+; CHECK-NEXT:    xxlor 35, 35, 34
+; CHECK-NEXT:    blr
+  %sub = sub nuw <6 x i32> splat (i32 8384513), %x
+  %s0 = shufflevector <6 x i32> %sub, <6 x i32> zeroinitializer, <8 x i32> <i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 4, i32 poison>
+  %s1 = shufflevector <6 x i32> %sub, <6 x i32> zeroinitializer, <8 x i32> <i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 5, i32 poison>
+  %or = or <8 x i32> %s0, %s1
+  ret <8 x i32> %or
+}



More information about the llvm-branch-commits mailing list