Skip to content

Commit b030705

Browse files
committed
[BOLT] Do not return Def-ed registers from MCPlusBuilder::getUsedRegs
Update the implementation of MCPlusBuilder::getUsedRegs to match its description in the header file, add unit tests.
1 parent 111af76 commit b030705

File tree

2 files changed

+113
-3
lines changed

2 files changed

+113
-3
lines changed

bolt/lib/Core/MCPlusBuilder.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -442,10 +442,10 @@ void MCPlusBuilder::getUsedRegs(const MCInst &Inst, BitVector &Regs) const {
442442
for (MCPhysReg ImplicitUse : InstInfo.implicit_uses())
443443
Regs |= getAliases(ImplicitUse, /*OnlySmaller=*/true);
444444

445-
for (unsigned I = 0, E = Inst.getNumOperands(); I != E; ++I) {
446-
if (!Inst.getOperand(I).isReg())
445+
for (const MCOperand &Operand : useOperands(Inst)) {
446+
if (!Operand.isReg())
447447
continue;
448-
Regs |= getAliases(Inst.getOperand(I).getReg(), /*OnlySmaller=*/true);
448+
Regs |= getAliases(Operand.getReg(), /*OnlySmaller=*/true);
449449
}
450450
}
451451

bolt/unittests/Core/MCPlusBuilder.cpp

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#ifdef AARCH64_AVAILABLE
1010
#include "AArch64Subtarget.h"
11+
#include "MCTargetDesc/AArch64MCTargetDesc.h"
1112
#endif // AARCH64_AVAILABLE
1213

1314
#ifdef X86_AVAILABLE
@@ -19,6 +20,7 @@
1920
#include "bolt/Rewrite/RewriteInstance.h"
2021
#include "llvm/BinaryFormat/ELF.h"
2122
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
23+
#include "llvm/MC/MCInstBuilder.h"
2224
#include "llvm/Support/TargetSelect.h"
2325
#include "gtest/gtest.h"
2426

@@ -70,6 +72,20 @@ struct MCPlusBuilderTester : public testing::TestWithParam<Triple::ArchType> {
7072
BC->MRI.get(), BC->STI.get())));
7173
}
7274

75+
void assertRegMask(const BitVector &RegMask,
76+
std::initializer_list<MCPhysReg> ExpectedRegs) {
77+
ASSERT_EQ(RegMask.count(), ExpectedRegs.size());
78+
for (MCPhysReg Reg : ExpectedRegs)
79+
ASSERT_TRUE(RegMask[Reg]) << "Expected " << BC->MRI->getName(Reg) << ".";
80+
}
81+
82+
void assertRegMask(std::function<void(BitVector &)> FillRegMask,
83+
std::initializer_list<MCPhysReg> ExpectedRegs) {
84+
BitVector RegMask(BC->MRI->getNumRegs());
85+
FillRegMask(RegMask);
86+
assertRegMask(RegMask, ExpectedRegs);
87+
}
88+
7389
void testRegAliases(Triple::ArchType Arch, uint64_t Register,
7490
uint64_t *Aliases, size_t Count,
7591
bool OnlySmaller = false) {
@@ -155,6 +171,100 @@ TEST_P(MCPlusBuilderTester, AArch64_CmpJNE) {
155171
ASSERT_EQ(Label, BB->getLabel());
156172
}
157173

174+
TEST_P(MCPlusBuilderTester, testAccessedRegsImplicitDef) {
175+
if (GetParam() != Triple::aarch64)
176+
GTEST_SKIP();
177+
178+
// adds x0, x5, #42
179+
MCInst Inst = MCInstBuilder(AArch64::ADDSXri)
180+
.addReg(AArch64::X0)
181+
.addReg(AArch64::X5)
182+
.addImm(42)
183+
.addImm(0);
184+
185+
assertRegMask([&](BitVector &BV) { BC->MIB->getClobberedRegs(Inst, BV); },
186+
{AArch64::NZCV, AArch64::W0, AArch64::X0, AArch64::W0_HI,
187+
AArch64::X0_X1_X2_X3_X4_X5_X6_X7, AArch64::W0_W1,
188+
AArch64::X0_X1});
189+
190+
assertRegMask(
191+
[&](BitVector &BV) { BC->MIB->getTouchedRegs(Inst, BV); },
192+
{AArch64::NZCV, AArch64::W0, AArch64::W5, AArch64::X0, AArch64::X5,
193+
AArch64::W0_HI, AArch64::W5_HI, AArch64::X0_X1_X2_X3_X4_X5_X6_X7,
194+
AArch64::X2_X3_X4_X5_X6_X7_X8_X9, AArch64::X4_X5_X6_X7_X8_X9_X10_X11,
195+
AArch64::W0_W1, AArch64::W4_W5, AArch64::X0_X1, AArch64::X4_X5});
196+
197+
assertRegMask([&](BitVector &BV) { BC->MIB->getWrittenRegs(Inst, BV); },
198+
{AArch64::NZCV, AArch64::W0, AArch64::X0, AArch64::W0_HI});
199+
200+
assertRegMask([&](BitVector &BV) { BC->MIB->getUsedRegs(Inst, BV); },
201+
{AArch64::W5, AArch64::X5, AArch64::W5_HI});
202+
203+
assertRegMask([&](BitVector &BV) { BC->MIB->getSrcRegs(Inst, BV); },
204+
{AArch64::W5, AArch64::X5, AArch64::W5_HI});
205+
}
206+
207+
TEST_P(MCPlusBuilderTester, testAccessedRegsImplicitUse) {
208+
if (GetParam() != Triple::aarch64)
209+
GTEST_SKIP();
210+
211+
// b.eq <label>
212+
MCInst Inst =
213+
MCInstBuilder(AArch64::Bcc)
214+
.addImm(AArch64CC::EQ)
215+
.addImm(0); // <label> - should be Expr, but immediate 0 works too.
216+
217+
assertRegMask([&](BitVector &BV) { BC->MIB->getClobberedRegs(Inst, BV); },
218+
{});
219+
220+
assertRegMask([&](BitVector &BV) { BC->MIB->getTouchedRegs(Inst, BV); },
221+
{AArch64::NZCV});
222+
223+
assertRegMask([&](BitVector &BV) { BC->MIB->getWrittenRegs(Inst, BV); }, {});
224+
225+
assertRegMask([&](BitVector &BV) { BC->MIB->getUsedRegs(Inst, BV); },
226+
{AArch64::NZCV});
227+
228+
assertRegMask([&](BitVector &BV) { BC->MIB->getSrcRegs(Inst, BV); },
229+
{AArch64::NZCV});
230+
}
231+
232+
TEST_P(MCPlusBuilderTester, testAccessedRegsMultipleDefs) {
233+
if (GetParam() != Triple::aarch64)
234+
GTEST_SKIP();
235+
236+
// ldr x0, [x5], #16
237+
MCInst Inst = MCInstBuilder(AArch64::LDRXpost)
238+
.addReg(AArch64::X5)
239+
.addReg(AArch64::X0)
240+
.addReg(AArch64::X5)
241+
.addImm(16);
242+
243+
assertRegMask(
244+
[&](BitVector &BV) { BC->MIB->getClobberedRegs(Inst, BV); },
245+
{AArch64::W0, AArch64::W5, AArch64::X0, AArch64::X5, AArch64::W0_HI,
246+
AArch64::W5_HI, AArch64::X0_X1_X2_X3_X4_X5_X6_X7,
247+
AArch64::X2_X3_X4_X5_X6_X7_X8_X9, AArch64::X4_X5_X6_X7_X8_X9_X10_X11,
248+
AArch64::W0_W1, AArch64::W4_W5, AArch64::X0_X1, AArch64::X4_X5});
249+
250+
assertRegMask(
251+
[&](BitVector &BV) { BC->MIB->getTouchedRegs(Inst, BV); },
252+
{AArch64::W0, AArch64::W5, AArch64::X0, AArch64::X5, AArch64::W0_HI,
253+
AArch64::W5_HI, AArch64::X0_X1_X2_X3_X4_X5_X6_X7,
254+
AArch64::X2_X3_X4_X5_X6_X7_X8_X9, AArch64::X4_X5_X6_X7_X8_X9_X10_X11,
255+
AArch64::W0_W1, AArch64::W4_W5, AArch64::X0_X1, AArch64::X4_X5});
256+
257+
assertRegMask([&](BitVector &BV) { BC->MIB->getWrittenRegs(Inst, BV); },
258+
{AArch64::W0, AArch64::X0, AArch64::W0_HI, AArch64::W5,
259+
AArch64::X5, AArch64::W5_HI});
260+
261+
assertRegMask([&](BitVector &BV) { BC->MIB->getUsedRegs(Inst, BV); },
262+
{AArch64::W5, AArch64::X5, AArch64::W5_HI});
263+
264+
assertRegMask([&](BitVector &BV) { BC->MIB->getSrcRegs(Inst, BV); },
265+
{AArch64::W5, AArch64::X5, AArch64::W5_HI});
266+
}
267+
158268
#endif // AARCH64_AVAILABLE
159269

160270
#ifdef X86_AVAILABLE

0 commit comments

Comments
 (0)