Skip to content

Commit eb19183

Browse files
authored
[AArch64] canCreateUndefOrPoisonForTargetNode - AArch64ISD::MOVI opcodes can't create undef/poison (#149323)
Possible fix for failed fold in #148191
1 parent f0332eb commit eb19183

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30959,6 +30959,24 @@ bool AArch64TargetLowering::SimplifyDemandedBitsForTargetNode(
3095930959
Op, OriginalDemandedBits, OriginalDemandedElts, Known, TLO, Depth);
3096030960
}
3096130961

30962+
bool AArch64TargetLowering::canCreateUndefOrPoisonForTargetNode(
30963+
SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
30964+
bool PoisonOnly, bool ConsiderFlags, unsigned Depth) const {
30965+
30966+
// TODO: Add more target nodes.
30967+
switch (Op.getOpcode()) {
30968+
case AArch64ISD::MOVI:
30969+
case AArch64ISD::MOVIedit:
30970+
case AArch64ISD::MOVImsl:
30971+
case AArch64ISD::MOVIshift:
30972+
case AArch64ISD::MVNImsl:
30973+
case AArch64ISD::MVNIshift:
30974+
return false;
30975+
}
30976+
return TargetLowering::canCreateUndefOrPoisonForTargetNode(
30977+
Op, DemandedElts, DAG, PoisonOnly, ConsiderFlags, Depth);
30978+
}
30979+
3096230980
bool AArch64TargetLowering::isTargetCanonicalConstantNode(SDValue Op) const {
3096330981
return Op.getOpcode() == AArch64ISD::DUP ||
3096430982
Op.getOpcode() == AArch64ISD::MOVI ||

llvm/lib/Target/AArch64/AArch64ISelLowering.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,12 @@ class AArch64TargetLowering : public TargetLowering {
869869
TargetLoweringOpt &TLO,
870870
unsigned Depth) const override;
871871

872+
bool canCreateUndefOrPoisonForTargetNode(SDValue Op,
873+
const APInt &DemandedElts,
874+
const SelectionDAG &DAG,
875+
bool PoisonOnly, bool ConsiderFlags,
876+
unsigned Depth) const override;
877+
872878
bool isTargetCanonicalConstantNode(SDValue Op) const override;
873879

874880
// With the exception of data-predicate transitions, no instructions are

llvm/unittests/Target/AArch64/AArch64SelectionDAGTest.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_UADDO_CARRY) {
319319
}
320320

321321
// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
322+
// Attempt to FREEZE the MOV/MVN nodes to show that they can still be analysed.
322323
TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_MOVI) {
323324
SDLoc Loc;
324325
auto IntSca32VT = MVT::i32;
@@ -344,6 +345,11 @@ TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_MOVI) {
344345
EXPECT_EQ(Known.Zero, APInt(64, 0x00FF00FFFF00FF00));
345346
EXPECT_EQ(Known.One, APInt(64, 0xFF00FF0000FF00FF));
346347

348+
auto FrMOVIedit128 = DAG->getFreeze(OpMOVIedit128);
349+
Known = DAG->computeKnownBits(FrMOVIedit128);
350+
EXPECT_EQ(Known.Zero, APInt(64, 0x00FF00FFFF00FF00));
351+
EXPECT_EQ(Known.One, APInt(64, 0xFF00FF0000FF00FF));
352+
347353
auto N264 = DAG->getConstant(264, Loc, IntSca32VT);
348354
auto OpMOVImsl64 =
349355
DAG->getNode(AArch64ISD::MOVImsl, Loc, Int2Vec32VT, N165, N264);
@@ -358,6 +364,11 @@ TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_MOVI) {
358364
EXPECT_EQ(Known.Zero, APInt(32, 0xFF5A0000));
359365
EXPECT_EQ(Known.One, APInt(32, 0x00A5FFFF));
360366

367+
auto FrMOVImsl128 = DAG->getFreeze(OpMOVImsl128);
368+
Known = DAG->computeKnownBits(FrMOVImsl128);
369+
EXPECT_EQ(Known.Zero, APInt(32, 0xFF5A0000));
370+
EXPECT_EQ(Known.One, APInt(32, 0x00A5FFFF));
371+
361372
auto OpMVNImsl64 =
362373
DAG->getNode(AArch64ISD::MVNImsl, Loc, Int2Vec32VT, N165, N272);
363374
Known = DAG->computeKnownBits(OpMVNImsl64);
@@ -370,6 +381,11 @@ TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_MOVI) {
370381
EXPECT_EQ(Known.Zero, APInt(32, 0x0000A5FF));
371382
EXPECT_EQ(Known.One, APInt(32, 0xFFFF5A00));
372383

384+
auto FrMVNImsl128 = DAG->getFreeze(OpMVNImsl128);
385+
Known = DAG->computeKnownBits(FrMVNImsl128);
386+
EXPECT_EQ(Known.Zero, APInt(32, 0x0000A5FF));
387+
EXPECT_EQ(Known.One, APInt(32, 0xFFFF5A00));
388+
373389
auto N0 = DAG->getConstant(0, Loc, IntSca32VT);
374390
auto OpMOVIshift2Vec32 =
375391
DAG->getNode(AArch64ISD::MOVIshift, Loc, Int2Vec32VT, N165, N0);
@@ -384,6 +400,11 @@ TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_MOVI) {
384400
EXPECT_EQ(Known.Zero, APInt(32, 0x5AFFFFFF));
385401
EXPECT_EQ(Known.One, APInt(32, 0xA5000000));
386402

403+
auto FrMOVIshift4Vec32 = DAG->getFreeze(OpMOVIshift4Vec32);
404+
Known = DAG->computeKnownBits(FrMOVIshift4Vec32);
405+
EXPECT_EQ(Known.Zero, APInt(32, 0x5AFFFFFF));
406+
EXPECT_EQ(Known.One, APInt(32, 0xA5000000));
407+
387408
auto OpMVNIshift2Vec32 =
388409
DAG->getNode(AArch64ISD::MVNIshift, Loc, Int2Vec32VT, N165, N24);
389410
Known = DAG->computeKnownBits(OpMVNIshift2Vec32);
@@ -396,6 +417,11 @@ TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_MOVI) {
396417
EXPECT_EQ(Known.Zero, APInt(32, 0x000000A5));
397418
EXPECT_EQ(Known.One, APInt(32, 0xFFFFFF5A));
398419

420+
auto FrMVNIshift4Vec32 = DAG->getFreeze(OpMVNIshift4Vec32);
421+
Known = DAG->computeKnownBits(FrMVNIshift4Vec32);
422+
EXPECT_EQ(Known.Zero, APInt(32, 0x000000A5));
423+
EXPECT_EQ(Known.One, APInt(32, 0xFFFFFF5A));
424+
399425
auto N8 = DAG->getConstant(8, Loc, IntSca32VT);
400426
auto OpMOVIshift4Vec16 =
401427
DAG->getNode(AArch64ISD::MOVIshift, Loc, Int4Vec16VT, N165, N0);
@@ -409,6 +435,11 @@ TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_MOVI) {
409435
EXPECT_EQ(Known.Zero, APInt(16, 0x5AFF));
410436
EXPECT_EQ(Known.One, APInt(16, 0xA500));
411437

438+
auto FrMOVIshift8Vec16 = DAG->getFreeze(OpMOVIshift8Vec16);
439+
Known = DAG->computeKnownBits(FrMOVIshift8Vec16);
440+
EXPECT_EQ(Known.Zero, APInt(16, 0x5AFF));
441+
EXPECT_EQ(Known.One, APInt(16, 0xA500));
442+
412443
auto OpMVNIshift4Vec16 =
413444
DAG->getNode(AArch64ISD::MVNIshift, Loc, Int4Vec16VT, N165, N8);
414445
Known = DAG->computeKnownBits(OpMVNIshift4Vec16);
@@ -421,6 +452,11 @@ TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_MOVI) {
421452
EXPECT_EQ(Known.Zero, APInt(16, 0x00A5));
422453
EXPECT_EQ(Known.One, APInt(16, 0xFF5A));
423454

455+
auto FrMVNIshift8Vec16 = DAG->getFreeze(OpMVNIshift8Vec16);
456+
Known = DAG->computeKnownBits(FrMVNIshift8Vec16);
457+
EXPECT_EQ(Known.Zero, APInt(16, 0x00A5));
458+
EXPECT_EQ(Known.One, APInt(16, 0xFF5A));
459+
424460
auto OpMOVI8Vec8 = DAG->getNode(AArch64ISD::MOVI, Loc, Int8Vec8VT, N165);
425461
Known = DAG->computeKnownBits(OpMOVI8Vec8);
426462
EXPECT_EQ(Known.Zero, APInt(8, 0x5A));
@@ -430,6 +466,11 @@ TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_MOVI) {
430466
Known = DAG->computeKnownBits(OpMOVI16Vec8);
431467
EXPECT_EQ(Known.Zero, APInt(8, 0x5A));
432468
EXPECT_EQ(Known.One, APInt(8, 0xA5));
469+
470+
auto FrMOVI16Vec8 = DAG->getFreeze(OpMOVI16Vec8);
471+
Known = DAG->computeKnownBits(FrMOVI16Vec8);
472+
EXPECT_EQ(Known.Zero, APInt(8, 0x5A));
473+
EXPECT_EQ(Known.One, APInt(8, 0xA5));
433474
}
434475

435476
// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.

0 commit comments

Comments
 (0)