[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:54:10 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-arm
Author: woruyu (woruyu)
<details>
<summary>Changes</summary>
### Summary
This PR resolves https://github.com/llvm/llvm-project/issues/156640
---
Full diff: https://github.com/llvm/llvm-project/pull/156831.diff
3 Files Affected:
- (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+13)
- (modified) llvm/lib/Target/ARM/ARMISelLowering.h (+4)
- (modified) llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp (+18)
``````````diff
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.
``````````
</details>
https://github.com/llvm/llvm-project/pull/156831
More information about the llvm-commits
mailing list