Skip to content

Commit 47f4a07

Browse files
authored
[GlobalISel] Add Knownbits for G_LOAD/ZEXTLOAD/SEXTLOAD with range metadata (#86431)
Similar to #80829 for GlobalISel.
1 parent 54ca1e2 commit 47f4a07

File tree

3 files changed

+93
-22
lines changed

3 files changed

+93
-22
lines changed

llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -405,18 +405,23 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known,
405405
}
406406
case TargetOpcode::G_LOAD: {
407407
const MachineMemOperand *MMO = *MI.memoperands_begin();
408-
if (const MDNode *Ranges = MMO->getRanges()) {
409-
computeKnownBitsFromRangeMetadata(*Ranges, Known);
410-
}
411-
408+
KnownBits KnownRange(MMO->getMemoryType().getScalarSizeInBits());
409+
if (const MDNode *Ranges = MMO->getRanges())
410+
computeKnownBitsFromRangeMetadata(*Ranges, KnownRange);
411+
Known = KnownRange.anyext(Known.getBitWidth());
412412
break;
413413
}
414+
case TargetOpcode::G_SEXTLOAD:
414415
case TargetOpcode::G_ZEXTLOAD: {
415416
if (DstTy.isVector())
416417
break;
417-
// Everything above the retrieved bits is zero
418-
Known.Zero.setBitsFrom(
419-
(*MI.memoperands_begin())->getSizeInBits().getValue());
418+
const MachineMemOperand *MMO = *MI.memoperands_begin();
419+
KnownBits KnownRange(MMO->getMemoryType().getScalarSizeInBits());
420+
if (const MDNode *Ranges = MMO->getRanges())
421+
computeKnownBitsFromRangeMetadata(*Ranges, KnownRange);
422+
Known = Opcode == TargetOpcode::G_SEXTLOAD
423+
? KnownRange.sext(Known.getBitWidth())
424+
: KnownRange.zext(Known.getBitWidth());
420425
break;
421426
}
422427
case TargetOpcode::G_ASHR: {

llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp

Lines changed: 80 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,25 @@ TEST_F(AMDGPUGISelMITest, TestIsKnownToBeAPowerOfTwo) {
11001100
EXPECT_TRUE(isKnownToBeAPowerOfTwo(CopyOrPow2, *MRI, &KB));
11011101
}
11021102

1103+
static void AddRangeMetadata(LLVMContext &Context, MachineInstr *Load) {
1104+
IntegerType *Int8Ty = Type::getInt8Ty(Context);
1105+
1106+
// Value must be in [0, 2)
1107+
Metadata *LowAndHigh[] = {
1108+
ConstantAsMetadata::get(ConstantInt::get(Int8Ty, 0)),
1109+
ConstantAsMetadata::get(ConstantInt::get(Int8Ty, 2))};
1110+
auto NewMDNode = MDNode::get(Context, LowAndHigh);
1111+
const MachineMemOperand *OldMMO = *Load->memoperands_begin();
1112+
MachineMemOperand *NewMMO =
1113+
Load->getParent()->getParent()->getMachineMemOperand(
1114+
OldMMO->getPointerInfo(), OldMMO->getFlags(), OldMMO->getMemoryType(),
1115+
OldMMO->getAlign(), OldMMO->getAAInfo(), NewMDNode);
1116+
MachineIRBuilder MIB(*Load);
1117+
MIB.buildLoadInstr(Load->getOpcode(), Load->getOperand(0),
1118+
Load->getOperand(1), *NewMMO);
1119+
Load->eraseFromParent();
1120+
}
1121+
11031122
TEST_F(AArch64GISelMITest, TestMetadata) {
11041123
StringRef MIRString = " %imp:_(p0) = G_IMPLICIT_DEF\n"
11051124
" %load:_(s8) = G_LOAD %imp(p0) :: (load (s8))\n"
@@ -1120,20 +1139,7 @@ TEST_F(AArch64GISelMITest, TestMetadata) {
11201139
MachineInstr *And = MRI->getVRegDef(SrcReg);
11211140
MachineInstr *Ext = MRI->getVRegDef(And->getOperand(1).getReg());
11221141
MachineInstr *Load = MRI->getVRegDef(Ext->getOperand(1).getReg());
1123-
IntegerType *Int8Ty = Type::getInt8Ty(Context);
1124-
1125-
// Value must be in [0, 2)
1126-
Metadata *LowAndHigh[] = {
1127-
ConstantAsMetadata::get(ConstantInt::get(Int8Ty, 0)),
1128-
ConstantAsMetadata::get(ConstantInt::get(Int8Ty, 2))};
1129-
auto NewMDNode = MDNode::get(Context, LowAndHigh);
1130-
const MachineMemOperand *OldMMO = *Load->memoperands_begin();
1131-
MachineMemOperand NewMMO(OldMMO->getPointerInfo(), OldMMO->getFlags(),
1132-
OldMMO->getSizeInBits(), OldMMO->getAlign(),
1133-
OldMMO->getAAInfo(), NewMDNode);
1134-
MachineIRBuilder MIB(*Load);
1135-
MIB.buildLoad(Load->getOperand(0), Load->getOperand(1), NewMMO);
1136-
Load->eraseFromParent();
1142+
AddRangeMetadata(Context, Load);
11371143

11381144
GISelKnownBits Info(*MF);
11391145
KnownBits Res = Info.getKnownBits(And->getOperand(1).getReg());
@@ -1148,6 +1154,66 @@ TEST_F(AArch64GISelMITest, TestMetadata) {
11481154
EXPECT_EQ(Mask.getZExtValue(), Res.Zero.getZExtValue());
11491155
}
11501156

1157+
TEST_F(AArch64GISelMITest, TestMetadataExt) {
1158+
StringRef MIRString = " %imp:_(p0) = G_IMPLICIT_DEF\n"
1159+
" %load:_(s32) = G_LOAD %imp(p0) :: (load (s8))\n"
1160+
" %copy:_(s32) = COPY %load(s32)\n";
1161+
setUp(MIRString);
1162+
if (!TM)
1163+
GTEST_SKIP();
1164+
1165+
Register CopyReg = Copies[Copies.size() - 1];
1166+
MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg);
1167+
Register SrcReg = FinalCopy->getOperand(1).getReg();
1168+
MachineInstr *Load = MRI->getVRegDef(SrcReg);
1169+
AddRangeMetadata(Context, Load);
1170+
1171+
GISelKnownBits Info(*MF);
1172+
KnownBits Res = Info.getKnownBits(SrcReg);
1173+
EXPECT_TRUE(Res.One.isZero());
1174+
EXPECT_EQ(Res.Zero.getZExtValue(), 0xfeu);
1175+
}
1176+
1177+
TEST_F(AArch64GISelMITest, TestMetadataZExt) {
1178+
StringRef MIRString = " %imp:_(p0) = G_IMPLICIT_DEF\n"
1179+
" %load:_(s32) = G_ZEXTLOAD %imp(p0) :: (load (s8))\n"
1180+
" %copy:_(s32) = COPY %load(s32)\n";
1181+
setUp(MIRString);
1182+
if (!TM)
1183+
GTEST_SKIP();
1184+
1185+
Register CopyReg = Copies[Copies.size() - 1];
1186+
MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg);
1187+
Register SrcReg = FinalCopy->getOperand(1).getReg();
1188+
MachineInstr *Load = MRI->getVRegDef(SrcReg);
1189+
AddRangeMetadata(Context, Load);
1190+
1191+
GISelKnownBits Info(*MF);
1192+
KnownBits Res = Info.getKnownBits(SrcReg);
1193+
EXPECT_TRUE(Res.One.isZero());
1194+
EXPECT_EQ(Res.Zero.getZExtValue(), 0xfffffffe);
1195+
}
1196+
1197+
TEST_F(AArch64GISelMITest, TestMetadataSExt) {
1198+
StringRef MIRString = " %imp:_(p0) = G_IMPLICIT_DEF\n"
1199+
" %load:_(s32) = G_SEXTLOAD %imp(p0) :: (load (s8))\n"
1200+
" %copy:_(s32) = COPY %load(s32)\n";
1201+
setUp(MIRString);
1202+
if (!TM)
1203+
GTEST_SKIP();
1204+
1205+
Register CopyReg = Copies[Copies.size() - 1];
1206+
MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg);
1207+
Register SrcReg = FinalCopy->getOperand(1).getReg();
1208+
MachineInstr *Load = MRI->getVRegDef(SrcReg);
1209+
AddRangeMetadata(Context, Load);
1210+
1211+
GISelKnownBits Info(*MF);
1212+
KnownBits Res = Info.getKnownBits(SrcReg);
1213+
EXPECT_TRUE(Res.One.isZero());
1214+
EXPECT_EQ(Res.Zero.getZExtValue(), 0xfffffffe);
1215+
}
1216+
11511217
TEST_F(AArch64GISelMITest, TestKnownBitsExt) {
11521218
StringRef MIRString = " %c1:_(s16) = G_CONSTANT i16 1\n"
11531219
" %x:_(s16) = G_IMPLICIT_DEF\n"

llvm/unittests/CodeGen/GlobalISel/KnownBitsVectorTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1008,7 +1008,7 @@ TEST_F(AArch64GISelMITest, TestVectorMetadata) {
10081008
auto *NewMDNode = MDNode::get(Context, LowAndHigh);
10091009
const MachineMemOperand *OldMMO = *Load->memoperands_begin();
10101010
MachineMemOperand NewMMO(OldMMO->getPointerInfo(), OldMMO->getFlags(),
1011-
OldMMO->getSizeInBits(), OldMMO->getAlign(),
1011+
OldMMO->getMemoryType(), OldMMO->getAlign(),
10121012
OldMMO->getAAInfo(), NewMDNode);
10131013
MachineIRBuilder MIB(*Load);
10141014
MIB.buildLoad(Load->getOperand(0), Load->getOperand(1), NewMMO);

0 commit comments

Comments
 (0)