Skip to content

Commit cb3c32c

Browse files
committed
[RISCV][test] Add tests for RISCVInstrInfo::describeLoadedValue
Tests are in preparation for adding handling of the load of a constant value as Mips does (noted in <llvm#72356 (comment)>). I've opted to implement these tests as a C++ unit test as on balance I _think_ it's easier to follow and maintain than .mir tests trying to indirectly test this function. That said, you see the limitations with the test of describeLoadedValue on a memory operation where we'd rather pass `MachinePointerInfo::getFixedStack` but can't because we'd need to then ensure the necessary stack metadata for the function is present.
1 parent 18e1179 commit cb3c32c

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

llvm/unittests/Target/RISCV/RISCVInstrInfoTest.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "RISCVSubtarget.h"
1111
#include "RISCVTargetMachine.h"
1212
#include "llvm/CodeGen/MachineModuleInfo.h"
13+
#include "llvm/IR/DebugInfoMetadata.h"
1314
#include "llvm/MC/TargetRegistry.h"
1415
#include "llvm/Support/TargetSelect.h"
1516
#include "llvm/Target/TargetLoweringObjectFile.h"
@@ -174,6 +175,83 @@ TEST_P(RISCVInstrInfoTest, GetMemOperandsWithOffsetWidth) {
174175
EXPECT_EQ(Width, 4u);
175176
}
176177

178+
static void expectDIEPrintResult(const DIExpression *Expr, StringRef Expected) {
179+
std::string Output;
180+
raw_string_ostream OS(Output);
181+
Expr->print(OS);
182+
OS.flush();
183+
EXPECT_EQ(OS.str(), Expected);
184+
}
185+
186+
TEST_P(RISCVInstrInfoTest, DescribeLoadedValue) {
187+
const RISCVInstrInfo *TII = ST->getInstrInfo();
188+
DebugLoc DL;
189+
190+
MachineBasicBlock *MBB = MF->CreateMachineBasicBlock();
191+
MF->getProperties().set(MachineFunctionProperties::Property::NoVRegs);
192+
193+
// Register move.
194+
auto *MI1 = BuildMI(*MBB, MBB->begin(), DL, TII->get(RISCV::ADDI), RISCV::X1)
195+
.addReg(RISCV::X2)
196+
.addImm(0)
197+
.getInstr();
198+
EXPECT_FALSE(TII->describeLoadedValue(*MI1, RISCV::X2).has_value());
199+
std::optional<ParamLoadedValue> MI1Res =
200+
TII->describeLoadedValue(*MI1, RISCV::X1);
201+
ASSERT_TRUE(MI1Res.has_value());
202+
ASSERT_TRUE(MI1Res->first.isReg());
203+
EXPECT_EQ(MI1Res->first.getReg(), RISCV::X2);
204+
expectDIEPrintResult(MI1Res->second, "!DIExpression()");
205+
206+
// Load immediate.
207+
auto *MI2 = BuildMI(*MBB, MBB->begin(), DL, TII->get(RISCV::ADDI), RISCV::X3)
208+
.addReg(RISCV::X0)
209+
.addImm(111)
210+
.getInstr();
211+
std::optional<ParamLoadedValue> MI2Res =
212+
TII->describeLoadedValue(*MI2, RISCV::X3);
213+
ASSERT_TRUE(MI2Res.has_value());
214+
ASSERT_TRUE(MI2Res->first.isReg());
215+
EXPECT_EQ(MI2Res->first.getReg(), RISCV::X0);
216+
// TODO: Could be a DW_OP_constu if this is recognised as a immediate load
217+
// rather than just an addi.
218+
expectDIEPrintResult(MI2Res->second, "!DIExpression(DW_OP_plus_uconst, 111)");
219+
220+
// Add immediate.
221+
auto *MI3 = BuildMI(*MBB, MBB->begin(), DL, TII->get(RISCV::ADDI), RISCV::X2)
222+
.addReg(RISCV::X3)
223+
.addImm(222)
224+
.getInstr();
225+
std::optional<ParamLoadedValue> MI3Res =
226+
TII->describeLoadedValue(*MI3, RISCV::X2);
227+
ASSERT_TRUE(MI3Res.has_value());
228+
ASSERT_TRUE(MI3Res->first.isReg());
229+
EXPECT_EQ(MI3Res->first.getReg(), RISCV::X3);
230+
expectDIEPrintResult(MI3Res->second, "!DIExpression(DW_OP_plus_uconst, 222)");
231+
232+
// Load value from memory.
233+
// It would be better (more reflective of real-world describeLoadedValue
234+
// usage) to test using MachinePointerInfo::getFixedStack, but
235+
// unfortunately it would be overly fiddly to make this work.
236+
auto MMO = MF->getMachineMemOperand(MachinePointerInfo::getConstantPool(*MF),
237+
MachineMemOperand::MOLoad, 1, Align(1));
238+
auto *MI4 = BuildMI(*MBB, MBB->begin(), DL, TII->get(RISCV::LB), RISCV::X1)
239+
.addReg(RISCV::X2)
240+
.addImm(-128)
241+
.addMemOperand(MMO)
242+
.getInstr();
243+
std::optional<ParamLoadedValue> MI4Res =
244+
TII->describeLoadedValue(*MI4, RISCV::X1);
245+
ASSERT_TRUE(MI4Res.has_value());
246+
ASSERT_TRUE(MI4Res->first.isReg());
247+
EXPECT_EQ(MI4Res->first.getReg(), RISCV::X2);
248+
expectDIEPrintResult(
249+
MI4Res->second,
250+
"!DIExpression(DW_OP_constu, 128, DW_OP_minus, DW_OP_deref_size, 1)");
251+
252+
MF->deleteMachineBasicBlock(MBB);
253+
}
254+
177255
} // namespace
178256

179257
INSTANTIATE_TEST_SUITE_P(RV32And64, RISCVInstrInfoTest,

0 commit comments

Comments
 (0)