[llvm] [DAG][ARM] canCreateUndefOrPoisonForTargetNode - ARMISD VORRIMM\VBICIMM nodes can't create poison/undef (PR #156831)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 4 01:53:39 PDT 2025


https://github.com/woruyu created https://github.com/llvm/llvm-project/pull/156831

### Summary
This PR resolves https://github.com/llvm/llvm-project/issues/156640

>From 40645586bf479a428eb72025e5625f16eb4c96d8 Mon Sep 17 00:00:00 2001
From: woruyu <1214539920 at qq.com>
Date: Thu, 4 Sep 2025 16:44:03 +0800
Subject: [PATCH] [DAG][ARM] canCreateUndefOrPoisonForTargetNode - ARMISD
 VORRIMM\VBICIMM nodes can't create poison/undef

---
 llvm/lib/Target/ARM/ARMISelLowering.cpp        | 13 +++++++++++++
 llvm/lib/Target/ARM/ARMISelLowering.h          |  4 ++++
 .../Target/ARM/ARMSelectionDAGTest.cpp         | 18 ++++++++++++++++++
 3 files changed, 35 insertions(+)

diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 601806dacf092..219e039f6c2c3 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -21363,6 +21363,19 @@ bool ARMTargetLowering::canCombineStoreAndExtract(Type *VectorTy, Value *Idx,
   return false;
 }
 
+bool ARMTargetLowering::canCreateUndefOrPoisonForTargetNode(
+    SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
+    bool PoisonOnly, bool ConsiderFlags, unsigned Depth) const {
+  unsigned Opcode = Op.getOpcode();
+  switch (Opcode) {
+  case ARMISD::VORRIMM:
+  case ARMISD::VBICIMM:
+    return false;
+  }
+  return TargetLowering::canCreateUndefOrPoisonForTargetNode(
+      Op, DemandedElts, DAG, PoisonOnly, ConsiderFlags, Depth);
+}
+
 bool ARMTargetLowering::isCheapToSpeculateCttz(Type *Ty) const {
   return Subtarget->hasV5TOps() && !Subtarget->isThumb1Only();
 }
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h
index 955e47bf033fc..ccf6d509313b9 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.h
+++ b/llvm/lib/Target/ARM/ARMISelLowering.h
@@ -707,6 +707,10 @@ class VectorType;
     bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx,
                                    unsigned &Cost) const override;
 
+    bool canCreateUndefOrPoisonForTargetNode(
+        SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
+        bool PoisonOnly, bool ConsiderFlags, unsigned Depth) const override;
+
     bool canMergeStoresTo(unsigned AddressSpace, EVT MemVT,
                           const MachineFunction &MF) const override {
       // Do not merge to larger than i32.
diff --git a/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
index 7a47807679120..988fa28323c71 100644
--- a/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
+++ b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
@@ -106,6 +106,19 @@ TEST_F(ARMSelectionDAGTest, computeKnownBits_VORRIMM) {
   KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
   EXPECT_EQ(Known.One, APInt(32, 0xAA));
   EXPECT_EQ(Known.Zero, APInt(32, 0x0));
+
+  // LHS(per-lane)     = 00000000 00000000 00000000 00000000  (0x00000000)
+  // Encoded(per-lane) = 00000000 00000000 00000000 10101010  (0x000000AA)
+  //  =>
+  // Known.One  = 00000000 00000000 00000000 10101010  (0x000000AA)
+  // Known.Zero = 11111111 11111111 11111111 01010101  (0x00000000)
+  SDValue Zero = DAG->getConstant(0, DL, MVT::i32);
+  SDValue ZeroVec = DAG->getSplatBuildVector(VT, DL, Zero);
+  Op = DAG->getNode(ARMISD::VORRIMM, DL, VT, ZeroVec, EncSD);
+  auto FrVORRIMM = DAG->getFreeze(Op);
+  Known = DAG->computeKnownBits(FrVORRIMM);
+  EXPECT_EQ(Known.One, APInt(32, 0xAA));
+  EXPECT_EQ(Known.Zero, APInt(32, 0xFFFFFF55));
 }
 
 /// VBIC (immediate): x & ~imm with 32-bit elements.
@@ -129,6 +142,11 @@ TEST_F(ARMSelectionDAGTest, computeKnownBits_VBICIMM) {
   KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
   EXPECT_EQ(Known.One, APInt(32, 0xFFFFFF55));
   EXPECT_EQ(Known.Zero, APInt(32, 0x000000AA));
+
+  auto FrVBICIMM = DAG->getFreeze(Op);
+  Known = DAG->computeKnownBits(FrVBICIMM);
+  EXPECT_EQ(Known.One, APInt(32, 0xFFFFFF55));
+  EXPECT_EQ(Known.Zero, APInt(32, 0x000000AA));
 }
 
 /// VORR (immediate): per-lane OR with 32-bit elements.



More information about the llvm-commits mailing list