[llvm] [DAG][ARM] computeKnownBitsForTargetNode - add handling for ARMISD VORRIMM\VBICIMM nodes (PR #149494)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 3 03:04:46 PDT 2025
https://github.com/woruyu updated https://github.com/llvm/llvm-project/pull/149494
>From a65beb481dc5d5777da27d90e8b2aad9a1e79c04 Mon Sep 17 00:00:00 2001
From: woruyu <1214539920 at qq.com>
Date: Fri, 18 Jul 2025 18:55:21 +0800
Subject: [PATCH 1/9] [DAG][ARM] computeKnownBitsForTargetNode - add handling
for ARMISD VORRIMM\VBICIMM nodes
---
llvm/lib/Target/ARM/ARMISelLowering.cpp | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 22ba30b734a16..63d41eada2455 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -20065,6 +20065,31 @@ void ARMTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
Known = KnownOp0.intersectWith(KnownOp1);
break;
}
+ case ARMISD::VORRIMM: {
+ KnownBits KnownLHS = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
+
+ unsigned Encoded = Op.getConstantOperandVal(1);
+ unsigned ElemSize = Op.getValueType().getScalarSizeInBits();
+ uint64_t DecodedVal = ARM_AM::decodeVMOVModImm(Encoded, ElemSize);
+ APInt Imm(Known.getBitWidth(), DecodedVal);
+
+ Known.One = KnownLHS.One | Imm;
+ Known.Zero = KnownLHS.Zero & ~Imm;
+ return;
+ }
+ case ARMISD::VBICIMM: {
+ KnownBits KnownLHS = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
+
+ unsigned Encoded = Op.getConstantOperandVal(1);
+ unsigned ElemSize = Op.getValueType().getScalarSizeInBits();
+ uint64_t DecodedVal = ARM_AM::decodeVMOVModImm(Encoded, ElemSize);
+ APInt Imm(Known.getBitWidth(), DecodedVal);
+
+ APInt NotImm = ~Imm;
+ Known.One = KnownLHS.One & NotImm;
+ Known.Zero = KnownLHS.Zero | Imm;
+ return;
+ }
}
}
>From 81e056c15a8b50a6d41cfbfddf4e7c0ca533f183 Mon Sep 17 00:00:00 2001
From: woruyu <1214539920 at qq.com>
Date: Mon, 21 Jul 2025 10:43:20 +0800
Subject: [PATCH 2/9] fix: review
---
llvm/lib/Target/ARM/ARMISelLowering.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 63d41eada2455..4f4bc53dce4bf 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -20069,9 +20069,9 @@ void ARMTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
KnownBits KnownLHS = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
unsigned Encoded = Op.getConstantOperandVal(1);
- unsigned ElemSize = Op.getValueType().getScalarSizeInBits();
+ unsigned ElemSize = Op.getScalarValueSizeInBits();
uint64_t DecodedVal = ARM_AM::decodeVMOVModImm(Encoded, ElemSize);
- APInt Imm(Known.getBitWidth(), DecodedVal);
+ APInt Imm(ElemSize, DecodedVal);
Known.One = KnownLHS.One | Imm;
Known.Zero = KnownLHS.Zero & ~Imm;
@@ -20081,9 +20081,9 @@ void ARMTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
KnownBits KnownLHS = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
unsigned Encoded = Op.getConstantOperandVal(1);
- unsigned ElemSize = Op.getValueType().getScalarSizeInBits();
+ unsigned ElemSize = Op.getScalarValueSizeInBits();
uint64_t DecodedVal = ARM_AM::decodeVMOVModImm(Encoded, ElemSize);
- APInt Imm(Known.getBitWidth(), DecodedVal);
+ APInt Imm(ElemSize, DecodedVal);
APInt NotImm = ~Imm;
Known.One = KnownLHS.One & NotImm;
>From cb386cfeda4d61fc5527b1a825383dac50ad4529 Mon Sep 17 00:00:00 2001
From: woruyu <1214539920 at qq.com>
Date: Fri, 15 Aug 2025 15:35:42 +0800
Subject: [PATCH 3/9] test: add ARMSelectionDAGTest
---
.../Target/ARM/ARMSelectionDAGTest.cpp | 128 ++++++++++++++++++
llvm/unittests/Target/ARM/CMakeLists.txt | 1 +
2 files changed, 129 insertions(+)
create mode 100644 llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
diff --git a/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
new file mode 100644
index 0000000000000..aa1d8730b8c3c
--- /dev/null
+++ b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
@@ -0,0 +1,128 @@
+#include "ARMISelLowering.h"
+#include "MCTargetDesc/ARMAddressingModes.h"
+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/IR/MDBuilder.h"
+#include "llvm/IR/Module.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/KnownBits.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+
+class ARMSelectionDAGTest : public testing::Test {
+protected:
+ static void SetUpTestCase() {
+ LLVMInitializeARMTargetInfo();
+ LLVMInitializeARMTarget();
+ LLVMInitializeARMTargetMC();
+ }
+
+ void SetUp() override {
+ StringRef Assembly = "define void @f() { ret void }";
+
+ Triple TargetTriple("armv7-unknown-none-eabi");
+
+ std::string Error;
+ const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
+
+ TargetOptions Options;
+ TM = std::unique_ptr<TargetMachine>(
+ T->createTargetMachine(TargetTriple,
+ /*CPU*/ "cortex-a9",
+ /*Features*/ "+neon", Options, std::nullopt,
+ std::nullopt, CodeGenOptLevel::Aggressive));
+
+ SMDiagnostic SMError;
+ M = parseAssemblyString(Assembly, SMError, Context);
+ if (!M)
+ report_fatal_error(SMError.getMessage());
+ M->setDataLayout(TM->createDataLayout());
+
+ F = M->getFunction("f");
+ if (!F)
+ report_fatal_error("Function 'f' not found");
+
+ MachineModuleInfo MMI(TM.get());
+
+ MF = std::make_unique<MachineFunction>(*F, *TM, *TM->getSubtargetImpl(*F),
+ MMI.getContext(), /*FunctionNum*/ 0);
+
+ DAG = std::make_unique<SelectionDAG>(*TM, CodeGenOptLevel::None);
+ if (!DAG)
+ report_fatal_error("SelectionDAG allocation failed");
+
+ OptimizationRemarkEmitter ORE(F);
+ DAG->init(*MF, ORE, /*LibInfo*/ nullptr, /*AA*/ nullptr,
+ /*AC*/ nullptr, /*MDT*/ nullptr, /*MSDT*/ nullptr, MMI, nullptr);
+ }
+
+ TargetLoweringBase::LegalizeTypeAction getTypeAction(EVT VT) {
+ return DAG->getTargetLoweringInfo().getTypeAction(Context, VT);
+ }
+
+ EVT getTypeToTransformTo(EVT VT) {
+ return DAG->getTargetLoweringInfo().getTypeToTransformTo(Context, VT);
+ }
+
+ LLVMContext Context;
+ std::unique_ptr<TargetMachine> TM;
+ std::unique_ptr<Module> M;
+ Function *F = nullptr;
+ std::unique_ptr<MachineFunction> MF;
+ std::unique_ptr<SelectionDAG> DAG;
+};
+
+TEST_F(ARMSelectionDAGTest, computeKnownBits_VORRIMM) {
+ SDLoc DL;
+ EVT VT = EVT::getVectorVT(Context, EVT::getIntegerVT(Context, 32), 2);
+
+ SDValue LHS = DAG->getConstant(0, DL, VT);
+
+ unsigned Encoded = 0xF0;
+ SDValue EncSD = DAG->getTargetConstant(Encoded, DL, MVT::i32);
+ SDValue Op = DAG->getNode(ARMISD::VORRIMM, DL, VT, LHS, EncSD);
+
+ APInt DemandedElts(/*numBits=*/2, /*val=*/3);
+
+ KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
+
+ unsigned ElemBits = 32;
+ uint64_t Decoded = ARM_AM::decodeVMOVModImm(Encoded, ElemBits);
+ APInt Imm(32, Decoded);
+
+ EXPECT_EQ(Known.One, Imm);
+ EXPECT_EQ(Known.Zero, ~Imm);
+}
+
+TEST_F(ARMSelectionDAGTest, computeKnownBits_VBICIMM) {
+ SDLoc DL;
+ EVT VT = EVT::getVectorVT(Context, EVT::getIntegerVT(Context, 32), 2);
+
+ APInt AllOnes(32, 0);
+ AllOnes.setAllBits();
+ SDValue LHS = DAG->getConstant(AllOnes, DL, VT);
+
+ unsigned Encoded = 0xF0;
+ SDValue EncSD = DAG->getTargetConstant(Encoded, DL, MVT::i32);
+ SDValue Op = DAG->getNode(ARMISD::VBICIMM, DL, VT, LHS, EncSD);
+
+ APInt DemandedElts(2, 3);
+
+ KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
+
+ unsigned ElemBits = 32;
+ uint64_t Decoded = ARM_AM::decodeVMOVModImm(Encoded, ElemBits);
+ APInt Imm(32, Decoded);
+
+ EXPECT_EQ(Known.One, ~Imm);
+ EXPECT_EQ(Known.Zero, Imm);
+}
+
+} // end namespace llvm
diff --git a/llvm/unittests/Target/ARM/CMakeLists.txt b/llvm/unittests/Target/ARM/CMakeLists.txt
index 5da249708abf9..1bd2eda4e23c9 100644
--- a/llvm/unittests/Target/ARM/CMakeLists.txt
+++ b/llvm/unittests/Target/ARM/CMakeLists.txt
@@ -22,4 +22,5 @@ set(LLVM_LINK_COMPONENTS
add_llvm_target_unittest(ARMTests
MachineInstrTest.cpp
InstSizes.cpp
+ ARMSelectionDAGTest.cpp
)
>From a186123b5586a55b9c992cd9e72184a159a1abe0 Mon Sep 17 00:00:00 2001
From: woruyu <1214539920 at qq.com>
Date: Fri, 15 Aug 2025 16:33:09 +0800
Subject: [PATCH 4/9] fix: review
---
llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
index aa1d8730b8c3c..ac302684ea678 100644
--- a/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
+++ b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
@@ -1,3 +1,10 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
#include "ARMISelLowering.h"
#include "MCTargetDesc/ARMAddressingModes.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
@@ -89,7 +96,7 @@ TEST_F(ARMSelectionDAGTest, computeKnownBits_VORRIMM) {
SDValue EncSD = DAG->getTargetConstant(Encoded, DL, MVT::i32);
SDValue Op = DAG->getNode(ARMISD::VORRIMM, DL, VT, LHS, EncSD);
- APInt DemandedElts(/*numBits=*/2, /*val=*/3);
+ APInt DemandedElts = APInt::getAllOnes(2);
KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
@@ -105,15 +112,14 @@ TEST_F(ARMSelectionDAGTest, computeKnownBits_VBICIMM) {
SDLoc DL;
EVT VT = EVT::getVectorVT(Context, EVT::getIntegerVT(Context, 32), 2);
- APInt AllOnes(32, 0);
- AllOnes.setAllBits();
+ APInt AllOnes = APInt::getAllOnes(32);
SDValue LHS = DAG->getConstant(AllOnes, DL, VT);
unsigned Encoded = 0xF0;
SDValue EncSD = DAG->getTargetConstant(Encoded, DL, MVT::i32);
SDValue Op = DAG->getNode(ARMISD::VBICIMM, DL, VT, LHS, EncSD);
- APInt DemandedElts(2, 3);
+ APInt DemandedElts = APInt::getAllOnes(2);
KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
>From f7e34de39fe5ccf2eea5445dd15e4a5db28f6307 Mon Sep 17 00:00:00 2001
From: woruyu <1214539920 at qq.com>
Date: Mon, 18 Aug 2025 19:02:32 +0800
Subject: [PATCH 5/9] fix: review
---
.../Target/ARM/ARMSelectionDAGTest.cpp | 50 +++++++++----------
1 file changed, 24 insertions(+), 26 deletions(-)
diff --git a/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
index ac302684ea678..266b7fbcd606d 100644
--- a/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
+++ b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
@@ -88,47 +88,45 @@ class ARMSelectionDAGTest : public testing::Test {
TEST_F(ARMSelectionDAGTest, computeKnownBits_VORRIMM) {
SDLoc DL;
- EVT VT = EVT::getVectorVT(Context, EVT::getIntegerVT(Context, 32), 2);
+ EVT VT = EVT::getVectorVT(Context, EVT::getIntegerVT(Context, 8), 2);
+ SDValue LHS = DAG->getRegister(0, VT);
- SDValue LHS = DAG->getConstant(0, DL, VT);
-
- unsigned Encoded = 0xF0;
- SDValue EncSD = DAG->getTargetConstant(Encoded, DL, MVT::i32);
+ unsigned Encoded = 0xAA;
+ SDValue EncSD = DAG->getTargetConstant(ARM_AM::createVMOVModImm(0xe, Encoded),
+ DL, MVT::i32);
SDValue Op = DAG->getNode(ARMISD::VORRIMM, DL, VT, LHS, EncSD);
+ // LHS = ????????
+ // Encoded = 10101010
+ // =>
+ // Known.One = 10101010 (0xAA)
+ // Known.Zero = 00000000 (0x0)
APInt DemandedElts = APInt::getAllOnes(2);
-
KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
-
- unsigned ElemBits = 32;
- uint64_t Decoded = ARM_AM::decodeVMOVModImm(Encoded, ElemBits);
- APInt Imm(32, Decoded);
-
- EXPECT_EQ(Known.One, Imm);
- EXPECT_EQ(Known.Zero, ~Imm);
+ EXPECT_EQ(Known.One, APInt(8, 0xAA));
+ EXPECT_EQ(Known.Zero, APInt(8, 0x0));
}
TEST_F(ARMSelectionDAGTest, computeKnownBits_VBICIMM) {
SDLoc DL;
- EVT VT = EVT::getVectorVT(Context, EVT::getIntegerVT(Context, 32), 2);
+ EVT VT = EVT::getVectorVT(Context, EVT::getIntegerVT(Context, 8), 2);
- APInt AllOnes = APInt::getAllOnes(32);
- SDValue LHS = DAG->getConstant(AllOnes, DL, VT);
+ SDValue LHS = DAG->getConstant(APInt(8, 0xCC), DL, VT);
- unsigned Encoded = 0xF0;
- SDValue EncSD = DAG->getTargetConstant(Encoded, DL, MVT::i32);
+ unsigned Encoded = 0xAA;
+ SDValue EncSD = DAG->getTargetConstant(ARM_AM::createVMOVModImm(0xe, Encoded),
+ DL, MVT::i32);
SDValue Op = DAG->getNode(ARMISD::VBICIMM, DL, VT, LHS, EncSD);
+ // LHS = 11001100
+ // Encoded = 10101010
+ // =>
+ // Known.One = 01000100 (0x44)
+ // Known.Zero = 10111011 (0xBB)
APInt DemandedElts = APInt::getAllOnes(2);
-
KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
-
- unsigned ElemBits = 32;
- uint64_t Decoded = ARM_AM::decodeVMOVModImm(Encoded, ElemBits);
- APInt Imm(32, Decoded);
-
- EXPECT_EQ(Known.One, ~Imm);
- EXPECT_EQ(Known.Zero, Imm);
+ EXPECT_EQ(Known.One, APInt(8, 0x44));
+ EXPECT_EQ(Known.Zero, APInt(8, 0xBB));
}
} // end namespace llvm
>From 2a6ba966977b0ca3d698456f97c8d736ee385630 Mon Sep 17 00:00:00 2001
From: woruyu <1214539920 at qq.com>
Date: Fri, 22 Aug 2025 17:49:36 +0800
Subject: [PATCH 6/9] fix: review
---
llvm/lib/Target/ARM/ARMISelLowering.cpp | 32 +++++---------
.../Target/ARM/ARMSelectionDAGTest.cpp | 44 ++++++++++---------
2 files changed, 35 insertions(+), 41 deletions(-)
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 4f4bc53dce4bf..ffbb7413b91fe 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -20065,29 +20065,21 @@ void ARMTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
Known = KnownOp0.intersectWith(KnownOp1);
break;
}
- case ARMISD::VORRIMM: {
- KnownBits KnownLHS = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
-
- unsigned Encoded = Op.getConstantOperandVal(1);
- unsigned ElemSize = Op.getScalarValueSizeInBits();
- uint64_t DecodedVal = ARM_AM::decodeVMOVModImm(Encoded, ElemSize);
- APInt Imm(ElemSize, DecodedVal);
-
- Known.One = KnownLHS.One | Imm;
- Known.Zero = KnownLHS.Zero & ~Imm;
- return;
- }
+ case ARMISD::VORRIMM:
case ARMISD::VBICIMM: {
KnownBits KnownLHS = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
-
unsigned Encoded = Op.getConstantOperandVal(1);
- unsigned ElemSize = Op.getScalarValueSizeInBits();
- uint64_t DecodedVal = ARM_AM::decodeVMOVModImm(Encoded, ElemSize);
- APInt Imm(ElemSize, DecodedVal);
-
- APInt NotImm = ~Imm;
- Known.One = KnownLHS.One & NotImm;
- Known.Zero = KnownLHS.Zero | Imm;
+ unsigned DecEltBits = 0;
+ uint64_t DecodedVal = ARM_AM::decodeVMOVModImm(Encoded, DecEltBits);
+
+ if (Op.getScalarValueSizeInBits() == DecEltBits) {
+ bool IsVORR = Op.getOpcode() == ARMISD::VORRIMM;
+ APInt Imm(DecEltBits, DecodedVal);
+ Known.One = IsVORR ? (KnownLHS.One | Imm) : (KnownLHS.One & ~Imm);
+ Known.Zero = IsVORR ? (KnownLHS.Zero & ~Imm) : (KnownLHS.Zero | Imm);
+ } else {
+ Known = KnownLHS;
+ }
return;
}
}
diff --git a/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
index 266b7fbcd606d..60ddb6520a060 100644
--- a/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
+++ b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
@@ -86,47 +86,49 @@ class ARMSelectionDAGTest : public testing::Test {
std::unique_ptr<SelectionDAG> DAG;
};
+/// VORR (immediate): per-lane OR with 32-bit elements.
+/// cmode=0x0 puts imm8 in byte0 => per-lane constant = 0x000000AA.
TEST_F(ARMSelectionDAGTest, computeKnownBits_VORRIMM) {
SDLoc DL;
- EVT VT = EVT::getVectorVT(Context, EVT::getIntegerVT(Context, 8), 2);
+ EVT VT = EVT::getVectorVT(Context, EVT::getIntegerVT(Context, 32), 4);
SDValue LHS = DAG->getRegister(0, VT);
- unsigned Encoded = 0xAA;
- SDValue EncSD = DAG->getTargetConstant(ARM_AM::createVMOVModImm(0xe, Encoded),
+ SDValue EncSD = DAG->getTargetConstant(ARM_AM::createVMOVModImm(0x0, 0xAA),
DL, MVT::i32);
SDValue Op = DAG->getNode(ARMISD::VORRIMM, DL, VT, LHS, EncSD);
- // LHS = ????????
- // Encoded = 10101010
+ // LHS(per-lane) = ???????? ???????? ???????? ????????
+ // Encoded(per-lane) = 00000000 00000000 00000000 10101010 (0x000000AA)
// =>
- // Known.One = 10101010 (0xAA)
- // Known.Zero = 00000000 (0x0)
- APInt DemandedElts = APInt::getAllOnes(2);
+ // Known.One = 00000000 00000000 00000000 10101010 (0x000000AA)
+ // Known.Zero = 00000000 00000000 00000000 00000000 (0x00000000)
+ APInt DemandedElts = APInt::getAllOnes(4);
KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
- EXPECT_EQ(Known.One, APInt(8, 0xAA));
- EXPECT_EQ(Known.Zero, APInt(8, 0x0));
+ EXPECT_EQ(Known.One, APInt(32, 0xAA));
+ EXPECT_EQ(Known.Zero, APInt(32, 0x0));
}
+/// VBIC (immediate): x & ~imm with 32-bit elements.
+/// LHS(per-lane)=0xFFFFFFFF; imm per-lane = 0x000000AA => result = 0xFFFFFF55
TEST_F(ARMSelectionDAGTest, computeKnownBits_VBICIMM) {
SDLoc DL;
- EVT VT = EVT::getVectorVT(Context, EVT::getIntegerVT(Context, 8), 2);
+ EVT VT = EVT::getVectorVT(Context, EVT::getIntegerVT(Context, 32), 4);
- SDValue LHS = DAG->getConstant(APInt(8, 0xCC), DL, VT);
+ SDValue LHS = DAG->getConstant(APInt(32, 0xFFFFFFFF), DL, VT);
- unsigned Encoded = 0xAA;
- SDValue EncSD = DAG->getTargetConstant(ARM_AM::createVMOVModImm(0xe, Encoded),
+ SDValue EncSD = DAG->getTargetConstant(ARM_AM::createVMOVModImm(0x0, 0xAA),
DL, MVT::i32);
SDValue Op = DAG->getNode(ARMISD::VBICIMM, DL, VT, LHS, EncSD);
- // LHS = 11001100
- // Encoded = 10101010
+ // LHS(per-lane) = 11111111 11111111 11111111 11111111 (0xFFFFFFFF)
+ // Encoded(per-lane) = 00000000 00000000 00000000 10101010 (0x000000AA)
// =>
- // Known.One = 01000100 (0x44)
- // Known.Zero = 10111011 (0xBB)
- APInt DemandedElts = APInt::getAllOnes(2);
+ // Known.One = 11111111 11111111 11111111 01010101 (0xFFFFFF55)
+ // Known.Zero = 00000000 00000000 00000000 10101010 (0x000000AA)
+ APInt DemandedElts = APInt::getAllOnes(4);
KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
- EXPECT_EQ(Known.One, APInt(8, 0x44));
- EXPECT_EQ(Known.Zero, APInt(8, 0xBB));
+ EXPECT_EQ(Known.One, APInt(32, 0xFFFFFF55));
+ EXPECT_EQ(Known.Zero, APInt(32, 0x000000AA));
}
} // end namespace llvm
>From 01faad1b3c0e0d188b03876fa5a1adbc3ded0d4f Mon Sep 17 00:00:00 2001
From: woruyu <1214539920 at qq.com>
Date: Fri, 22 Aug 2025 18:02:27 +0800
Subject: [PATCH 7/9] fix: format
---
llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
index 60ddb6520a060..c9ae0d27a521b 100644
--- a/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
+++ b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
@@ -93,8 +93,8 @@ TEST_F(ARMSelectionDAGTest, computeKnownBits_VORRIMM) {
EVT VT = EVT::getVectorVT(Context, EVT::getIntegerVT(Context, 32), 4);
SDValue LHS = DAG->getRegister(0, VT);
- SDValue EncSD = DAG->getTargetConstant(ARM_AM::createVMOVModImm(0x0, 0xAA),
- DL, MVT::i32);
+ SDValue EncSD =
+ DAG->getTargetConstant(ARM_AM::createVMOVModImm(0x0, 0xAA), DL, MVT::i32);
SDValue Op = DAG->getNode(ARMISD::VORRIMM, DL, VT, LHS, EncSD);
// LHS(per-lane) = ???????? ???????? ???????? ????????
@@ -116,8 +116,8 @@ TEST_F(ARMSelectionDAGTest, computeKnownBits_VBICIMM) {
SDValue LHS = DAG->getConstant(APInt(32, 0xFFFFFFFF), DL, VT);
- SDValue EncSD = DAG->getTargetConstant(ARM_AM::createVMOVModImm(0x0, 0xAA),
- DL, MVT::i32);
+ SDValue EncSD =
+ DAG->getTargetConstant(ARM_AM::createVMOVModImm(0x0, 0xAA), DL, MVT::i32);
SDValue Op = DAG->getNode(ARMISD::VBICIMM, DL, VT, LHS, EncSD);
// LHS(per-lane) = 11111111 11111111 11111111 11111111 (0xFFFFFFFF)
>From 6aca4c28dd7e9a1000bd04c53d27f567afc2e379 Mon Sep 17 00:00:00 2001
From: woruyu <1214539920 at qq.com>
Date: Fri, 29 Aug 2025 10:56:11 +0800
Subject: [PATCH 8/9] fix: review and add a test
---
llvm/lib/Target/ARM/ARMISelLowering.cpp | 9 ++--
.../Target/ARM/ARMSelectionDAGTest.cpp | 49 ++++++++++++++++++-
2 files changed, 53 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index ffbb7413b91fe..d0e0134a68b34 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -20071,16 +20071,19 @@ void ARMTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
unsigned Encoded = Op.getConstantOperandVal(1);
unsigned DecEltBits = 0;
uint64_t DecodedVal = ARM_AM::decodeVMOVModImm(Encoded, DecEltBits);
+ bool IsVORR = Op.getOpcode() == ARMISD::VORRIMM;
if (Op.getScalarValueSizeInBits() == DecEltBits) {
- bool IsVORR = Op.getOpcode() == ARMISD::VORRIMM;
APInt Imm(DecEltBits, DecodedVal);
Known.One = IsVORR ? (KnownLHS.One | Imm) : (KnownLHS.One & ~Imm);
Known.Zero = IsVORR ? (KnownLHS.Zero & ~Imm) : (KnownLHS.Zero | Imm);
} else {
- Known = KnownLHS;
+ if (IsVORR)
+ Known.One = KnownLHS.One;
+ else
+ Known.Zero = KnownLHS.Zero;
}
- return;
+ break;
}
}
}
diff --git a/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
index c9ae0d27a521b..7a47807679120 100644
--- a/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
+++ b/llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp
@@ -90,7 +90,7 @@ class ARMSelectionDAGTest : public testing::Test {
/// cmode=0x0 puts imm8 in byte0 => per-lane constant = 0x000000AA.
TEST_F(ARMSelectionDAGTest, computeKnownBits_VORRIMM) {
SDLoc DL;
- EVT VT = EVT::getVectorVT(Context, EVT::getIntegerVT(Context, 32), 4);
+ EVT VT = MVT::v4i32;
SDValue LHS = DAG->getRegister(0, VT);
SDValue EncSD =
@@ -112,7 +112,7 @@ TEST_F(ARMSelectionDAGTest, computeKnownBits_VORRIMM) {
/// LHS(per-lane)=0xFFFFFFFF; imm per-lane = 0x000000AA => result = 0xFFFFFF55
TEST_F(ARMSelectionDAGTest, computeKnownBits_VBICIMM) {
SDLoc DL;
- EVT VT = EVT::getVectorVT(Context, EVT::getIntegerVT(Context, 32), 4);
+ EVT VT = MVT::v4i32;
SDValue LHS = DAG->getConstant(APInt(32, 0xFFFFFFFF), DL, VT);
@@ -131,4 +131,49 @@ TEST_F(ARMSelectionDAGTest, computeKnownBits_VBICIMM) {
EXPECT_EQ(Known.Zero, APInt(32, 0x000000AA));
}
+/// VORR (immediate): per-lane OR with 32-bit elements.
+/// Encoded = 0x2AA (cmode=0x2, imm8=0xAA) => per-lane constant = 0x0000AA00.
+TEST_F(ARMSelectionDAGTest, computeKnownBits_VORRIMM_cmode2) {
+ SDLoc DL;
+ EVT VT = MVT::v4i32;
+ SDValue LHS = DAG->getRegister(0, VT);
+
+ // Use the exact encoded immediate the reviewer asked for.
+ SDValue EncSD =
+ DAG->getTargetConstant(ARM_AM::createVMOVModImm(0x2, 0xAA), DL, MVT::i32);
+ SDValue Op = DAG->getNode(ARMISD::VORRIMM, DL, VT, LHS, EncSD);
+
+ // LHS (per-lane) = ???????? ???????? ???????? ????????
+ // Encoded (per-lane) = 00000000 00000000 10101010 00000000 (0x0000AA00)
+ // =>
+ // Known.One = 00000000 00000000 10101010 00000000 (0x0000AA00)
+ // Known.Zero = 00000000 00000000 00000000 00000000 (0x00000000)
+ APInt DemandedElts = APInt::getAllOnes(4);
+ KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
+ EXPECT_EQ(Known.One, APInt(32, 0x0000AA00));
+ EXPECT_EQ(Known.Zero, APInt(32, 0x00000000));
+}
+
+/// VBIC (immediate) with constant-all-ones LHS:
+/// Encoded = 0x2AA => per-lane constant = 0x0000AA00; VBIC = A & ~Imm.
+TEST_F(ARMSelectionDAGTest, computeKnownBits_VBICIMM_cmode2_lhs_ones) {
+ SDLoc DL;
+ EVT VT = MVT::v4i32;
+
+ SDValue LHS = DAG->getConstant(APInt(32, 0xFFFFFFFF), DL, VT);
+ SDValue EncSD =
+ DAG->getTargetConstant(ARM_AM::createVMOVModImm(0x2, 0xAA), DL, MVT::i32);
+ SDValue Op = DAG->getNode(ARMISD::VBICIMM, DL, VT, LHS, EncSD);
+
+ // LHS (per-lane) = 11111111 11111111 11111111 11111111
+ // Encoded (per-lane) = 00000000 00000000 10101010 00000000 (0x0000AA00)
+ // =>
+ // Known.One = 11111111 11111111 01010101 11111111 (0xFFFF55FF)
+ // Known.Zero = 00000000 00000000 10101010 00000000 (0x0000AA00)
+ APInt DemandedElts = APInt::getAllOnes(4);
+ KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
+ EXPECT_EQ(Known.One, APInt(32, 0xFFFF55FF));
+ EXPECT_EQ(Known.Zero, APInt(32, 0x0000AA00));
+}
+
} // end namespace llvm
>From a7fbc849515517a1ad18d7ff954826e77c3025ea Mon Sep 17 00:00:00 2001
From: woruyu <1214539920 at qq.com>
Date: Wed, 3 Sep 2025 18:03:55 +0800
Subject: [PATCH 9/9] fix: conservative for EltBits == DecEltBits
---
llvm/lib/Target/ARM/ARMISelLowering.cpp | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index d0e0134a68b34..93fce395a9a7f 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -20067,22 +20067,25 @@ void ARMTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
}
case ARMISD::VORRIMM:
case ARMISD::VBICIMM: {
- KnownBits KnownLHS = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
unsigned Encoded = Op.getConstantOperandVal(1);
unsigned DecEltBits = 0;
uint64_t DecodedVal = ARM_AM::decodeVMOVModImm(Encoded, DecEltBits);
- bool IsVORR = Op.getOpcode() == ARMISD::VORRIMM;
- if (Op.getScalarValueSizeInBits() == DecEltBits) {
- APInt Imm(DecEltBits, DecodedVal);
- Known.One = IsVORR ? (KnownLHS.One | Imm) : (KnownLHS.One & ~Imm);
- Known.Zero = IsVORR ? (KnownLHS.Zero & ~Imm) : (KnownLHS.Zero | Imm);
- } else {
- if (IsVORR)
- Known.One = KnownLHS.One;
- else
- Known.Zero = KnownLHS.Zero;
+ unsigned EltBits = Op.getScalarValueSizeInBits();
+ if (EltBits != DecEltBits) {
+ // Be conservative: only update Known when EltBits == DecEltBits.
+ // This is believed to always be true for VORRIMM/VBICIMM today, but if
+ // that changes in the future, doing nothing here is safer than risking
+ // subtle bugs.
+ break;
}
+
+ KnownBits KnownLHS = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
+ bool IsVORR = Op.getOpcode() == ARMISD::VORRIMM;
+ APInt Imm(DecEltBits, DecodedVal);
+
+ Known.One = IsVORR ? (KnownLHS.One | Imm) : (KnownLHS.One & ~Imm);
+ Known.Zero = IsVORR ? (KnownLHS.Zero & ~Imm) : (KnownLHS.Zero | Imm);
break;
}
}
More information about the llvm-commits
mailing list