[DAG] isKnownToBeAPowerOfTwo - add DemandedElts + OrZero handling to ISD::SELECT/VSELECT cases (#181753)
Pass DemandedElts and OrZero arguments through SELECT/VSELECT nodes when checking if values are power-of-two. Add unit tests for scalar SELECT (OrZero) and vector VSELECT (DemandedElts + OrZero). Resolves #181645
This commit is contained in:
parent
47a969ef88
commit
900778e40d
@ -4747,9 +4747,9 @@ bool SelectionDAG::isKnownToBeAPowerOfTwo(SDValue Val,
|
||||
|
||||
case ISD::SELECT:
|
||||
case ISD::VSELECT:
|
||||
return isKnownToBeAPowerOfTwo(Val.getOperand(2), /*OrZero=*/false,
|
||||
return isKnownToBeAPowerOfTwo(Val.getOperand(2), DemandedElts, OrZero,
|
||||
Depth + 1) &&
|
||||
isKnownToBeAPowerOfTwo(Val.getOperand(1), /*OrZero=*/false,
|
||||
isKnownToBeAPowerOfTwo(Val.getOperand(1), DemandedElts, OrZero,
|
||||
Depth + 1);
|
||||
|
||||
case ISD::ZERO_EXTEND:
|
||||
|
||||
@ -914,6 +914,63 @@ TEST_F(AArch64SelectionDAGTest, KnownToBeAPowerOfTwo_Constants) {
|
||||
EXPECT_TRUE(DAG->isKnownToBeAPowerOfTwo(SplatBig, /*OrZero=*/true));
|
||||
}
|
||||
|
||||
TEST_F(AArch64SelectionDAGTest, KnownToBeAPowerOfTwo_Select) {
|
||||
SDLoc Loc;
|
||||
auto Cst0 = DAG->getConstant(0, Loc, MVT::i32);
|
||||
auto Cst3 = DAG->getConstant(3, Loc, MVT::i32);
|
||||
auto Cst4 = DAG->getConstant(4, Loc, MVT::i32);
|
||||
auto CstBig = DAG->getConstant(2 << 17, Loc, MVT::i32);
|
||||
|
||||
auto Cond = DAG->getCopyFromReg(DAG->getEntryNode(), Loc, 1, MVT::i1);
|
||||
auto Select40 = DAG->getNode(ISD::SELECT, Loc, MVT::i32, Cond, Cst4, Cst0);
|
||||
auto Select43 = DAG->getNode(ISD::SELECT, Loc, MVT::i32, Cond, Cst4, Cst3);
|
||||
auto Select4Big =
|
||||
DAG->getNode(ISD::SELECT, Loc, MVT::i32, Cond, Cst4, CstBig);
|
||||
|
||||
EXPECT_FALSE(DAG->isKnownToBeAPowerOfTwo(Select40));
|
||||
EXPECT_TRUE(DAG->isKnownToBeAPowerOfTwo(Select40, /*OrZero=*/true));
|
||||
EXPECT_FALSE(DAG->isKnownToBeAPowerOfTwo(Select43));
|
||||
EXPECT_TRUE(DAG->isKnownToBeAPowerOfTwo(Select4Big));
|
||||
|
||||
auto VecVT = MVT::v2i16;
|
||||
auto Vec04 = DAG->getBuildVector(VecVT, Loc, {Cst0, Cst4});
|
||||
auto Vec44 = DAG->getBuildVector(VecVT, Loc, {Cst4, Cst4});
|
||||
auto Vec4Big = DAG->getBuildVector(VecVT, Loc, {Cst4, CstBig});
|
||||
auto Vec0Big = DAG->getBuildVector(VecVT, Loc, {Cst0, CstBig});
|
||||
|
||||
auto VecCond = DAG->getCopyFromReg(DAG->getEntryNode(), Loc, 2, MVT::v2i1);
|
||||
auto VSelect0444 =
|
||||
DAG->getNode(ISD::VSELECT, Loc, VecVT, VecCond, Vec04, Vec44);
|
||||
auto VSelect4444 =
|
||||
DAG->getNode(ISD::VSELECT, Loc, VecVT, VecCond, Vec44, Vec44);
|
||||
auto VSelect040Big =
|
||||
DAG->getNode(ISD::VSELECT, Loc, VecVT, VecCond, Vec04, Vec0Big);
|
||||
auto VSelect444Big =
|
||||
DAG->getNode(ISD::VSELECT, Loc, VecVT, VecCond, Vec44, Vec4Big);
|
||||
|
||||
APInt DemandLo(2, 1);
|
||||
EXPECT_FALSE(DAG->isKnownToBeAPowerOfTwo(VSelect0444, DemandLo));
|
||||
EXPECT_TRUE(
|
||||
DAG->isKnownToBeAPowerOfTwo(VSelect0444, DemandLo, /*OrZero=*/true));
|
||||
EXPECT_TRUE(DAG->isKnownToBeAPowerOfTwo(VSelect444Big, DemandLo));
|
||||
|
||||
APInt DemandHi(2, 2);
|
||||
EXPECT_FALSE(DAG->isKnownToBeAPowerOfTwo(VSelect444Big, DemandHi));
|
||||
EXPECT_TRUE(
|
||||
DAG->isKnownToBeAPowerOfTwo(VSelect444Big, DemandHi, /*OrZero=*/true));
|
||||
EXPECT_TRUE(DAG->isKnownToBeAPowerOfTwo(VSelect0444, DemandHi));
|
||||
|
||||
APInt DemandAll(2, 3);
|
||||
EXPECT_FALSE(DAG->isKnownToBeAPowerOfTwo(VSelect0444, DemandAll));
|
||||
EXPECT_FALSE(DAG->isKnownToBeAPowerOfTwo(VSelect040Big, DemandAll));
|
||||
EXPECT_FALSE(DAG->isKnownToBeAPowerOfTwo(VSelect444Big, DemandAll));
|
||||
EXPECT_TRUE(DAG->isKnownToBeAPowerOfTwo(VSelect4444, DemandAll));
|
||||
EXPECT_TRUE(
|
||||
DAG->isKnownToBeAPowerOfTwo(VSelect040Big, DemandAll, /*OrZero=*/true));
|
||||
EXPECT_TRUE(
|
||||
DAG->isKnownToBeAPowerOfTwo(VSelect444Big, DemandAll, /*OrZero=*/true));
|
||||
}
|
||||
|
||||
TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) {
|
||||
TargetLowering TL(*TM, *STI);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user