[GlobalISel][KnownBits] Implement G_CTPOP

Implementation copied almost verbatim from ValueTracking.

Differential revision: https://reviews.llvm.org/D107606
This commit is contained in:
Jon Roelofs 2021-08-05 14:57:44 -07:00
parent a8a38ef3d9
commit ce6eb4f15a
2 changed files with 70 additions and 1 deletions

View File

@ -9,7 +9,7 @@
/// Provides analysis for querying information about KnownBits during GISel
/// passes.
//
//===------------------
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/GlobalISel/Utils.h"
@ -510,6 +510,18 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known,
Known = Known.reverseBits();
break;
}
case TargetOpcode::G_CTPOP: {
computeKnownBitsImpl(MI.getOperand(1).getReg(), Known2, DemandedElts,
Depth + 1);
// We can bound the space the count needs. Also, bits known to be zero can't
// contribute to the population.
unsigned BitsPossiblySet = Known2.countMaxPopulation();
unsigned LowBits = Log2_32(BitsPossiblySet)+1;
Known.Zero.setBitsFrom(LowBits);
// TODO: we could bound Known.One using the lower bound on the number of
// bits which might be set provided by popcnt KnownOne2.
break;
}
case TargetOpcode::G_UBFX: {
KnownBits SrcOpKnown, OffsetKnown, WidthKnown;
computeKnownBitsImpl(MI.getOperand(1).getReg(), SrcOpKnown, DemandedElts,

View File

@ -1672,6 +1672,63 @@ TEST_F(AArch64GISelMITest, TestKnownBitsAssertZext) {
EXPECT_EQ(0xFFFFFFFFFFFFFFF8u, Res.Zero.getZExtValue());
}
TEST_F(AArch64GISelMITest, TestKnownBitsCTPOP) {
StringRef MIRString = R"(
%src:_(s32) = COPY $w0
%unknown:_(s32) = G_CTPOP %src
%constant_4294967295:_(s32) = G_CONSTANT i32 4294967295
%thirtytwo:_(s32) = G_CTPOP %constant_4294967295
%thirtytwo_copy:_(s32) = COPY %thirtytwo
%constant_15:_(s32) = G_CONSTANT i32 15
%four:_(s32) = G_CTPOP %constant_15
%four_copy:_(s32) = COPY %four
%constant_1:_(s32) = G_CONSTANT i32 1
%one:_(s32) = G_CTPOP %constant_1
%one_copy:_(s32) = COPY %one
)";
setUp(MIRString);
if (!TM)
return;
Register UnknownCopy = Copies[Copies.size() - 4];
Register ThirtytwoCopy = Copies[Copies.size() - 3];
Register FourCopy = Copies[Copies.size() - 2];
Register OneCopy = Copies[Copies.size() - 1];
GISelKnownBits Info(*MF);
MachineInstr *Copy;
Register SrcReg;
KnownBits Res;
Copy = MRI->getVRegDef(UnknownCopy);
SrcReg = Copy->getOperand(1).getReg();
Res = Info.getKnownBits(SrcReg);
EXPECT_EQ(1u, Res.getBitWidth());
EXPECT_EQ(0u, Res.One.getZExtValue());
EXPECT_EQ(0u, Res.Zero.getZExtValue());
Copy = MRI->getVRegDef(ThirtytwoCopy);
SrcReg = Copy->getOperand(1).getReg();
Res = Info.getKnownBits(SrcReg);
EXPECT_EQ(32u, Res.getBitWidth());
EXPECT_EQ(0u, Res.One.getZExtValue());
EXPECT_EQ(0xFFFFFFC0u, Res.Zero.getZExtValue());
Copy = MRI->getVRegDef(FourCopy);
SrcReg = Copy->getOperand(1).getReg();
Res = Info.getKnownBits(SrcReg);
EXPECT_EQ(32u, Res.getBitWidth());
EXPECT_EQ(0u, Res.One.getZExtValue());
EXPECT_EQ(0xFFFFFFF8u, Res.Zero.getZExtValue());
Copy = MRI->getVRegDef(OneCopy);
SrcReg = Copy->getOperand(1).getReg();
Res = Info.getKnownBits(SrcReg);
EXPECT_EQ(32u, Res.getBitWidth());
EXPECT_EQ(0u, Res.One.getZExtValue());
EXPECT_EQ(0xFFFFFFFEu, Res.Zero.getZExtValue());
}
TEST_F(AMDGPUGISelMITest, TestKnownBitsUBFX) {
StringRef MIRString = " %3:_(s32) = G_IMPLICIT_DEF\n"
" %4:_(s32) = G_CONSTANT i32 12\n"