[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