Skip to content

Commit b95076a

Browse files
committed
[ARM] computeKnownBitsForTargetNode for VMOVIMM/VMVNIMM Fixes #149276
1 parent 4e94198 commit b95076a

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19863,7 +19863,31 @@ void ARMTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
1986319863
Known.Zero = IsVORR ? (KnownLHS.Zero & ~Imm) : (KnownLHS.Zero | Imm);
1986419864
break;
1986519865
}
19866+
case ARMISD::VMOVIMM:
19867+
case ARMISD::VMVNIMM: {
19868+
unsigned Encoded = Op.getConstantOperandVal(0);
19869+
unsigned DecEltBits = 0;
19870+
uint64_t DecodedVal = ARM_AM::decodeVMOVModImm(Encoded, DecEltBits);
19871+
19872+
unsigned EltBits = Op.getScalarValueSizeInBits();
19873+
if (EltBits != DecEltBits)
19874+
break;
19875+
19876+
APInt Imm(DecEltBits, DecodedVal);
19877+
19878+
if (Op.getOpcode() == ARMISD::VMVNIMM)
19879+
Imm.flipAllBits();
19880+
19881+
Known = KnownBits::makeConstant(Imm);
19882+
break;
1986619883
}
19884+
}
19885+
}
19886+
19887+
bool ARMTargetLowering::isTargetCanonicalConstantNode(SDValue Op) const {
19888+
return Op.getOpcode() == ARMISD::VMOVIMM ||
19889+
Op.getOpcode() == ARMISD::VMVNIMM ||
19890+
TargetLowering::isTargetCanonicalConstantNode(Op);
1986719891
}
1986819892

1986919893
bool ARMTargetLowering::targetShrinkDemandedConstant(

llvm/lib/Target/ARM/ARMISelLowering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ class VectorType;
221221
const SelectionDAG &DAG,
222222
unsigned Depth) const override;
223223

224+
bool isTargetCanonicalConstantNode(SDValue Op) const override;
225+
224226
bool targetShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits,
225227
const APInt &DemandedElts,
226228
TargetLoweringOpt &TLO) const override;

llvm/unittests/Target/ARM/ARMSelectionDAGTest.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,4 +194,36 @@ TEST_F(ARMSelectionDAGTest, computeKnownBits_VBICIMM_cmode2_lhs_ones) {
194194
EXPECT_EQ(Known.Zero, APInt(32, 0x0000AA00));
195195
}
196196

197+
/// VMOVIMM: Move immediate to vector register.
198+
/// cmode=0x0 puts imm8 in byte0 => per-lane constant = 0x000000AA.
199+
TEST_F(ARMSelectionDAGTest, computeKnownBits_VMOVIMM) {
200+
SDLoc DL;
201+
EVT VT = MVT::v4i32;
202+
203+
SDValue EncSD =
204+
DAG->getTargetConstant(ARM_AM::createVMOVModImm(0x0, 0xAA), DL, MVT::i32);
205+
SDValue Op = DAG->getNode(ARMISD::VMOVIMM, DL, VT, EncSD);
206+
207+
APInt DemandedElts = APInt::getAllOnes(4);
208+
KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
209+
EXPECT_EQ(Known.One, APInt(32, 0x000000AA));
210+
EXPECT_EQ(Known.Zero, APInt(32, 0xFFFFFF55));
211+
}
212+
213+
/// VMVNIMM: Move NOT immediate to vector register.
214+
/// cmode=0x0 puts imm8 in byte0 => decoded = 0x000000AA, result = ~0x000000AA.
215+
TEST_F(ARMSelectionDAGTest, computeKnownBits_VMVNIMM) {
216+
SDLoc DL;
217+
EVT VT = MVT::v4i32;
218+
219+
SDValue EncSD =
220+
DAG->getTargetConstant(ARM_AM::createVMOVModImm(0x0, 0xAA), DL, MVT::i32);
221+
SDValue Op = DAG->getNode(ARMISD::VMVNIMM, DL, VT, EncSD);
222+
223+
APInt DemandedElts = APInt::getAllOnes(4);
224+
KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
225+
EXPECT_EQ(Known.One, APInt(32, 0xFFFFFF55));
226+
EXPECT_EQ(Known.Zero, APInt(32, 0x000000AA));
227+
}
228+
197229
} // end namespace llvm

0 commit comments

Comments
 (0)