[llvm] [ARM] computeKnownBitsForTargetNode for VMOVIMM/VMVNIMM Fixes #149276 (PR #171434)
Medha Tiwari via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 9 06:12:58 PST 2025
https://github.com/medhatiwari updated https://github.com/llvm/llvm-project/pull/171434
>From b95076a7ae107b464e9371a312cf45827991f1dd Mon Sep 17 00:00:00 2001
From: Medha Tiwari <medhatiwari at ibm.com>
Date: Tue, 9 Dec 2025 19:42:44 +0530
Subject: [PATCH] [ARM] computeKnownBitsForTargetNode for VMOVIMM/VMVNIMM Fixes
#149276
---
llvm/lib/Target/ARM/ARMISelLowering.cpp | 24 ++++++++++++++
llvm/lib/Target/ARM/ARMISelLowering.h | 2 ++
.../Target/ARM/ARMSelectionDAGTest.cpp | 32 +++++++++++++++++++
3 files changed, 58 insertions(+)
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 2d26c67a8077a..1f85765167138 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -19863,7 +19863,31 @@ void ARMTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
Known.Zero = IsVORR ? (KnownLHS.Zero & ~Imm) : (KnownLHS.Zero | Imm);
break;
}
+ case ARMISD::VMOVIMM:
+ case ARMISD::VMVNIMM: {
+ unsigned Encoded = Op.getConstantOperandVal(0);
+ unsigned DecEltBits = 0;
+ uint64_t DecodedVal = ARM_AM::decodeVMOVModImm(Encoded, DecEltBits);
+
+ unsigned EltBits = Op.getScalarValueSizeInBits();
+ if (EltBits != DecEltBits)
+ break;
+
+ APInt Imm(DecEltBits, DecodedVal);
+
+ if (Op.getOpcode() == ARMISD::VMVNIMM)
+ Imm.flipAllBits();
+
+ Known = KnownBits::makeConstant(Imm);
+ break;
}
+ }
+}
+
+bool ARMTargetLowering::isTargetCanonicalConstantNode(SDValue Op) const {
+ return Op.getOpcode() == ARMISD::VMOVIMM ||
+ Op.getOpcode() == ARMISD::VMVNIMM ||
+ TargetLowering::isTargetCanonicalConstantNode(Op);
}
bool ARMTargetLowering::targetShrinkDemandedConstant(
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h
index d0fb58c764edd..4c1fc6fdfac90 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.h
+++ b/llvm/lib/Target/ARM/ARMISelLowering.h
@@ -221,6 +221,8 @@ class VectorType;
const SelectionDAG &DAG,
unsigned Depth) const override;
+ bool isTargetCanonicalConstantNode(SDValue Op) const override;
+
bool targetShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits,
const APInt &DemandedElts,
TargetLoweringOpt &TLO) const override;
diff --git a/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
index c763da95fa455..852e07d5c24f1 100644
--- a/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
+++ b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
@@ -194,4 +194,36 @@ TEST_F(ARMSelectionDAGTest, computeKnownBits_VBICIMM_cmode2_lhs_ones) {
EXPECT_EQ(Known.Zero, APInt(32, 0x0000AA00));
}
+/// VMOVIMM: Move immediate to vector register.
+/// cmode=0x0 puts imm8 in byte0 => per-lane constant = 0x000000AA.
+TEST_F(ARMSelectionDAGTest, computeKnownBits_VMOVIMM) {
+ SDLoc DL;
+ EVT VT = MVT::v4i32;
+
+ SDValue EncSD =
+ DAG->getTargetConstant(ARM_AM::createVMOVModImm(0x0, 0xAA), DL, MVT::i32);
+ SDValue Op = DAG->getNode(ARMISD::VMOVIMM, DL, VT, EncSD);
+
+ APInt DemandedElts = APInt::getAllOnes(4);
+ KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
+ EXPECT_EQ(Known.One, APInt(32, 0x000000AA));
+ EXPECT_EQ(Known.Zero, APInt(32, 0xFFFFFF55));
+}
+
+/// VMVNIMM: Move NOT immediate to vector register.
+/// cmode=0x0 puts imm8 in byte0 => decoded = 0x000000AA, result = ~0x000000AA.
+TEST_F(ARMSelectionDAGTest, computeKnownBits_VMVNIMM) {
+ SDLoc DL;
+ EVT VT = MVT::v4i32;
+
+ SDValue EncSD =
+ DAG->getTargetConstant(ARM_AM::createVMOVModImm(0x0, 0xAA), DL, MVT::i32);
+ SDValue Op = DAG->getNode(ARMISD::VMVNIMM, DL, VT, EncSD);
+
+ APInt DemandedElts = APInt::getAllOnes(4);
+ KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
+ EXPECT_EQ(Known.One, APInt(32, 0xFFFFFF55));
+ EXPECT_EQ(Known.Zero, APInt(32, 0x000000AA));
+}
+
} // end namespace llvm
More information about the llvm-commits
mailing list