[ARM] Make getInstSizeInBytes() use instruction size from InstrInfo.td

Currently, ARMBaseInstrInfo::getInstSizeInBytes() uses hard-coded
instruction size for some pseudo-instructions, while this
information should ideally be found in ARMInstrInfo.td,
ARMInstrThumb(2).td files (which can be accessed via MCInstrDesc). Hence,
the .td files should be updated and no hard-coded instruction sizes
should be used by getInstSizeInBytes() anymore.

Differential Revision: https://reviews.llvm.org/D118009
This commit is contained in:
tyb0807
2022-01-23 22:29:33 +00:00
parent dd88f40c80
commit 762f0b5463
7 changed files with 286 additions and 44 deletions

View File

@@ -752,23 +752,17 @@ unsigned ARMBaseInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo();
const MCInstrDesc &MCID = MI.getDesc();
if (MCID.getSize())
return MCID.getSize();
switch (MI.getOpcode()) {
default:
// pseudo-instruction sizes are zero.
return 0;
// Return the size specified in .td file. If there's none, return 0, as we
// can't define a default size (Thumb1 instructions are 2 bytes, Thumb2
// instructions are 2-4 bytes, and ARM instructions are 4 bytes), in
// contrast to AArch64 instructions which have a default size of 4 bytes for
// example.
return MCID.getSize();
case TargetOpcode::BUNDLE:
return getInstBundleLength(MI);
case ARM::MOVi16_ga_pcrel:
case ARM::MOVTi16_ga_pcrel:
case ARM::t2MOVi16_ga_pcrel:
case ARM::t2MOVTi16_ga_pcrel:
return 4;
case ARM::MOVi32imm:
case ARM::t2MOVi32imm:
return 8;
case ARM::CONSTPOOL_ENTRY:
case ARM::JUMPTABLE_INSTS:
case ARM::JUMPTABLE_ADDRS:
@@ -777,19 +771,6 @@ unsigned ARMBaseInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
// If this machine instr is a constant pool entry, its size is recorded as
// operand #2.
return MI.getOperand(2).getImm();
case ARM::Int_eh_sjlj_longjmp:
return 16;
case ARM::tInt_eh_sjlj_longjmp:
return 10;
case ARM::tInt_WIN_eh_sjlj_longjmp:
return 12;
case ARM::Int_eh_sjlj_setjmp:
case ARM::Int_eh_sjlj_setjmp_nofp:
return 20;
case ARM::tInt_eh_sjlj_setjmp:
case ARM::t2Int_eh_sjlj_setjmp:
case ARM::t2Int_eh_sjlj_setjmp_nofp:
return 12;
case ARM::SPACE:
return MI.getOperand(1).getImm();
case ARM::INLINEASM:
@@ -800,14 +781,6 @@ unsigned ARMBaseInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
Size = alignTo(Size, 4);
return Size;
}
case ARM::SpeculationBarrierISBDSBEndBB:
case ARM::t2SpeculationBarrierISBDSBEndBB:
// This gets lowered to 2 4-byte instructions.
return 8;
case ARM::SpeculationBarrierSBEndBB:
case ARM::t2SpeculationBarrierSBEndBB:
// This gets lowered to 1 4-byte instructions.
return 4;
}
}

View File

@@ -3657,6 +3657,8 @@ def : InstAlias<"mov${p} $Rd, $imm",
(MOVi16 GPR:$Rd, imm0_65535_expr:$imm, pred:$p), 0>,
Requires<[IsARM, HasV6T2]>;
// This gets lowered to a single 4-byte instructions
let Size = 4 in
def MOVi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
(ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>,
Sched<[WriteALU]>;
@@ -3680,6 +3682,8 @@ def MOVTi16 : AI1<0b1010, (outs GPRnopc:$Rd),
let DecoderMethod = "DecodeArmMOVTWInstruction";
}
// This gets lowered to a single 4-byte instructions
let Size = 4 in
def MOVTi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
(ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>,
Sched<[WriteALU]>;
@@ -5895,27 +5899,30 @@ def : ARMPat<(ARMthread_pointer), (MRC 15, 0, 13, 0, 3)>,
//
// These are pseudo-instructions and are lowered to individual MC-insts, so
// no encoding information is necessary.
// This gets lowered to an instruction sequence of 20 bytes
let Defs =
[ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15 ],
hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in {
hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1, Size = 20 in {
def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
NoItinerary,
[(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
Requires<[IsARM, HasVFP2]>;
}
// This gets lowered to an instruction sequence of 20 bytes
let Defs =
[ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR ],
hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in {
hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1, Size = 20 in {
def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
NoItinerary,
[(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
Requires<[IsARM, NoVFP]>;
}
// This gets lowered to an instruction sequence of 16 bytes
// FIXME: Non-IOS version(s)
let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, Size = 16,
Defs = [ R7, LR, SP ] in {
def Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch),
NoItinerary,
@@ -5958,7 +5965,7 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in
// This is a single pseudo instruction, the benefit is that it can be remat'd
// as a single unit instead of having to handle reg inputs.
// FIXME: Remove this when we can do generalized remat.
let isReMaterializable = 1, isMoveImm = 1 in
let isReMaterializable = 1, isMoveImm = 1, Size = 8 in
def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
[(set GPR:$dst, (arm_i32imm:$src))]>,
Requires<[IsARM]>;
@@ -6419,8 +6426,12 @@ def SPACE : PseudoInst<(outs GPR:$Rd), (ins i32imm:$size, GPR:$Rn),
// SpeculationBarrierEndBB must only be used after an unconditional control
// flow, i.e. after a terminator for which isBarrier is True.
let hasSideEffects = 1, isCodeGenOnly = 1, isTerminator = 1, isBarrier = 1 in {
// This gets lowered to a pair of 4-byte instructions
let Size = 8 in
def SpeculationBarrierISBDSBEndBB
: PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
// This gets lowered to a single 4-byte instructions
let Size = 4 in
def SpeculationBarrierSBEndBB
: PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
}

View File

@@ -1537,25 +1537,28 @@ def tTPsoft : tPseudoInst<(outs), (ins), 4, IIC_Br,
// Defs. By doing so, we also cause the prologue/epilogue code to actively
// preserve all of the callee-saved registers, which is exactly what we want.
// $val is a scratch register for our use.
// This gets lowered to an instruction sequence of 12 bytes
let Defs = [ R0, R1, R2, R3, R4, R5, R6, R7, R12, CPSR ],
hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1,
hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1, Size = 12,
usesCustomInserter = 1 in
def tInt_eh_sjlj_setjmp : ThumbXI<(outs),(ins tGPR:$src, tGPR:$val),
AddrModeNone, 0, NoItinerary, "","",
[(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>;
// This gets lowered to an instruction sequence of 10 bytes
// FIXME: Non-IOS version(s)
let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, isCodeGenOnly = 1,
Defs = [ R7, LR, SP ] in
Size = 10, Defs = [ R7, LR, SP ] in
def tInt_eh_sjlj_longjmp : XI<(outs), (ins tGPR:$src, tGPR:$scratch),
AddrModeNone, 0, IndexModeNone,
Pseudo, NoItinerary, "", "",
[(ARMeh_sjlj_longjmp tGPR:$src, tGPR:$scratch)]>,
Requires<[IsThumb,IsNotWindows]>;
// This gets lowered to an instruction sequence of 12 bytes
// (Windows is Thumb2-only)
let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, isCodeGenOnly = 1,
Defs = [ R11, LR, SP ] in
Size = 12, Defs = [ R11, LR, SP ] in
def tInt_WIN_eh_sjlj_longjmp
: XI<(outs), (ins GPR:$src, GPR:$scratch), AddrModeNone, 0, IndexModeNone,
Pseudo, NoItinerary, "", "", [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,

View File

@@ -2194,6 +2194,8 @@ def : InstAlias<"mov${p} $Rd, $imm",
(t2MOVi16 rGPR:$Rd, imm256_65535_expr:$imm, pred:$p), 0>,
Requires<[IsThumb, HasV8MBaseline]>, Sched<[WriteALU]>;
// This gets lowered to a single 4-byte instructions
let Size = 4 in
def t2MOVi16_ga_pcrel : PseudoInst<(outs rGPR:$Rd),
(ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>,
Sched<[WriteALU]>;
@@ -2223,6 +2225,8 @@ def t2MOVTi16 : T2I<(outs rGPR:$Rd),
let DecoderMethod = "DecodeT2MOVTWInstruction";
}
// This gets lowered to a single 4-byte instructions
let Size = 4 in
def t2MOVTi16_ga_pcrel : PseudoInst<(outs rGPR:$Rd),
(ins rGPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>,
Sched<[WriteALU]>, Requires<[IsThumb, HasV8MBaseline]>;
@@ -3814,10 +3818,11 @@ def : T2Pat<(stlex_2 (and GPR:$Rt, 0xffff), addr_offset_none:$addr),
// doing so, we also cause the prologue/epilogue code to actively preserve
// all of the callee-saved registers, which is exactly what we want.
// $val is a scratch register for our use.
// This gets lowered to an instruction sequence of 12 bytes
let Defs =
[ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR,
Q0, Q1, Q2, Q3, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15],
hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1,
hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1, Size = 12,
usesCustomInserter = 1 in {
def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
AddrModeNone, 0, NoItinerary, "", "",
@@ -3825,9 +3830,10 @@ let Defs =
Requires<[IsThumb2, HasVFP2]>;
}
// This gets lowered to an instruction sequence of 12 bytes
let Defs =
[ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR ],
hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1,
hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1, Size = 12,
usesCustomInserter = 1 in {
def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
AddrModeNone, 0, NoItinerary, "", "",
@@ -4224,7 +4230,7 @@ def : t2InstAlias<"hvc\t$imm16", (t2HVC imm0_65535:$imm16)>;
// 32-bit immediate using movw + movt.
// This is a single pseudo instruction to make it re-materializable.
// FIXME: Remove this when we can do generalized remat.
let isReMaterializable = 1, isMoveImm = 1 in
let isReMaterializable = 1, isMoveImm = 1, Size = 8 in
def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
[(set rGPR:$dst, (i32 imm:$src))]>,
Requires<[IsThumb, UseMovt]>;
@@ -5006,8 +5012,12 @@ def : InstAlias<"dfb${p}", (t2DSB 0xc, pred:$p), 1>, Requires<[HasDFB]>;
// SpeculationBarrierEndBB must only be used after an unconditional control
// flow, i.e. after a terminator for which isBarrier is True.
let hasSideEffects = 1, isCodeGenOnly = 1, isTerminator = 1, isBarrier = 1 in {
// This gets lowered to a pair of 4-byte instructions
let Size = 8 in
def t2SpeculationBarrierISBDSBEndBB
: PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
// This gets lowered to a single 4-byte instructions
let Size = 4 in
def t2SpeculationBarrierSBEndBB
: PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
}

View File

@@ -10,6 +10,7 @@ set(LLVM_LINK_COMPONENTS
CodeGen
GlobalISel
MC
MIRParser
SelectionDAG
Support
Target
@@ -17,4 +18,5 @@ set(LLVM_LINK_COMPONENTS
add_llvm_target_unittest(ARMTests
MachineInstrTest.cpp
InstSizes.cpp
)

View File

@@ -0,0 +1,242 @@
#include "ARMInstrInfo.h"
#include "ARMSubtarget.h"
#include "ARMTargetMachine.h"
#include "llvm/CodeGen/MIRParser/MIRParser.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "gtest/gtest.h"
using namespace llvm;
namespace {
/// The \p InputIRSnippet is only needed for things that can't be expressed in
/// the \p InputMIRSnippet (global variables etc)
/// TODO: Some of this might be useful for other architectures as well - extract
/// the platform-independent parts somewhere they can be reused.
void runChecks(
LLVMTargetMachine *TM, const ARMBaseInstrInfo *II,
const StringRef InputIRSnippet, const StringRef InputMIRSnippet,
unsigned Expected,
std::function<void(const ARMBaseInstrInfo &, MachineFunction &, unsigned &)>
Checks) {
LLVMContext Context;
auto MIRString = "--- |\n"
" declare void @sizes()\n" +
InputIRSnippet.str() +
"...\n"
"---\n"
"name: sizes\n"
"constants:\n"
" - id: 0\n"
" value: i32 12345678\n"
" alignment: 4\n"
"jumpTable:\n"
" kind: inline\n"
" entries:\n"
" - id: 0\n"
" blocks: [ '%bb.0' ]\n"
"body: |\n"
" bb.0:\n" +
InputMIRSnippet.str();
std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRString);
std::unique_ptr<MIRParser> MParser =
createMIRParser(std::move(MBuffer), Context);
ASSERT_TRUE(MParser);
std::unique_ptr<Module> M = MParser->parseIRModule();
ASSERT_TRUE(M);
M->setTargetTriple(TM->getTargetTriple().getTriple());
M->setDataLayout(TM->createDataLayout());
MachineModuleInfo MMI(TM);
bool Res = MParser->parseMachineFunctions(*M, MMI);
ASSERT_FALSE(Res);
auto F = M->getFunction("sizes");
ASSERT_TRUE(F != nullptr);
auto &MF = MMI.getOrCreateMachineFunction(*F);
Checks(*II, MF, Expected);
}
} // anonymous namespace
TEST(InstSizes, PseudoInst) {
LLVMInitializeARMTargetInfo();
LLVMInitializeARMTarget();
LLVMInitializeARMTargetMC();
auto TT(Triple::normalize("thumbv8.1m.main-none-none-eabi"));
std::string Error;
const Target *T = TargetRegistry::lookupTarget(TT, Error);
if (!T) {
dbgs() << Error;
return;
}
TargetOptions Options;
auto TM = std::unique_ptr<LLVMTargetMachine>(
static_cast<LLVMTargetMachine *>(T->createTargetMachine(
TT, "generic", "", Options, None, None, CodeGenOpt::Default)));
ARMSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()),
std::string(TM->getTargetFeatureString()),
*static_cast<const ARMBaseTargetMachine *>(TM.get()), false);
const ARMBaseInstrInfo *II = ST.getInstrInfo();
auto cmpInstSize = [](const ARMBaseInstrInfo &II, MachineFunction &MF,
unsigned &Expected) {
auto I = MF.begin()->begin();
EXPECT_EQ(Expected, II.getInstSizeInBytes(*I));
};
runChecks(TM.get(), II, "",
" $r0 = MOVi16_ga_pcrel"
" target-flags(arm-lo16, arm-nonlazy) @sizes, 0\n",
4u, cmpInstSize);
runChecks(TM.get(), II, "",
" $r0 = MOVTi16_ga_pcrel $r0,"
" target-flags(arm-hi16, arm-nonlazy) @sizes, 0\n",
4u, cmpInstSize);
runChecks(TM.get(), II, "",
" $r0 = t2MOVi16_ga_pcrel"
" target-flags(arm-lo16, arm-nonlazy) @sizes, 0\n",
4u, cmpInstSize);
runChecks(TM.get(), II, "",
" $r0 = t2MOVTi16_ga_pcrel $r0,"
" target-flags(arm-hi16, arm-nonlazy) @sizes, 0\n",
4u, cmpInstSize);
runChecks(TM.get(), II, "", " $r0 = MOVi32imm 2\n", 8u, cmpInstSize);
runChecks(TM.get(), II, "", " $r0 = t2MOVi32imm 2\n", 8u, cmpInstSize);
runChecks(TM.get(), II, "",
" SpeculationBarrierISBDSBEndBB\n"
" tBX_RET 14, $noreg, implicit $r0\n",
8u, cmpInstSize);
runChecks(TM.get(), II, "",
" t2SpeculationBarrierISBDSBEndBB\n"
" tBX_RET 14, $noreg, implicit $r0\n",
8u, cmpInstSize);
runChecks(TM.get(), II, "",
" SpeculationBarrierSBEndBB\n"
" tBX_RET 14, $noreg, implicit $r0\n",
4u, cmpInstSize);
runChecks(TM.get(), II, "",
" t2SpeculationBarrierSBEndBB\n"
" tBX_RET 14, $noreg, implicit $r0\n",
4u, cmpInstSize);
runChecks(TM.get(), II, "",
" Int_eh_sjlj_longjmp $r0, $r1, implicit-def $r7,"
" implicit-def $lr, implicit-def $sp\n",
16u, cmpInstSize);
runChecks(TM.get(), II, "",
" tInt_eh_sjlj_longjmp $r0, $r1, implicit-def $r7,"
" implicit-def $lr, implicit-def $sp\n",
10u, cmpInstSize);
runChecks(TM.get(), II, "",
" tInt_WIN_eh_sjlj_longjmp $r0, $r1, implicit-def $r11,"
" implicit-def $lr, implicit-def $sp\n",
12u, cmpInstSize);
runChecks(TM.get(), II, "",
" Int_eh_sjlj_setjmp $r0, $r1, implicit-def $r0,"
" implicit-def $r1, implicit-def $r2, implicit-def $r3,"
" implicit-def $r4, implicit-def $r5, implicit-def $r6,"
" implicit-def $r7, implicit-def $r8, implicit-def $r9,"
" implicit-def $r10, implicit-def $r11, implicit-def $r12,"
" implicit-def $lr, implicit-def $cpsr, implicit-def $q0,"
" implicit-def $q1, implicit-def $q2, implicit-def $q3,"
" implicit-def $q4, implicit-def $q5, implicit-def $q6,"
" implicit-def $q7, implicit-def $q8, implicit-def $q9,"
" implicit-def $q10, implicit-def $q11, implicit-def $q12,"
" implicit-def $q13, implicit-def $q14, implicit-def $q15\n"
" tBX_RET 14, $noreg, implicit $r0\n",
20u, cmpInstSize);
runChecks(TM.get(), II, "",
" Int_eh_sjlj_setjmp_nofp $r0, $r1, implicit-def $r0,"
" implicit-def $r1, implicit-def $r2, implicit-def $r3,"
" implicit-def $r4, implicit-def $r5, implicit-def $r6,"
" implicit-def $r7, implicit-def $r8, implicit-def $r9,"
" implicit-def $r10, implicit-def $r11, implicit-def $r12,"
" implicit-def $lr, implicit-def $cpsr\n"
" tBX_RET 14, $noreg, implicit $r0\n",
20u, cmpInstSize);
runChecks(TM.get(), II, "",
" tInt_eh_sjlj_setjmp $r0, $r1, implicit-def $r0,"
" implicit-def $r1, implicit-def $r2, implicit-def $r3,"
" implicit-def $r4, implicit-def $r5, implicit-def $r6,"
" implicit-def $r7, implicit-def $r12, implicit-def $cpsr\n"
" tBX_RET 14, $noreg, implicit $r0\n",
12u, cmpInstSize);
runChecks(TM.get(), II, "",
" t2Int_eh_sjlj_setjmp $r0, $r1, implicit-def $r0,"
" implicit-def $r1, implicit-def $r2, implicit-def $r3,"
" implicit-def $r4, implicit-def $r5, implicit-def $r6,"
" implicit-def $r7, implicit-def $r8, implicit-def $r9,"
" implicit-def $r10, implicit-def $r11, implicit-def $r12,"
" implicit-def $lr, implicit-def $cpsr, implicit-def $q0,"
" implicit-def $q1, implicit-def $q2, implicit-def $q3,"
" implicit-def $q8, implicit-def $q9, implicit-def $q10,"
" implicit-def $q11, implicit-def $q12, implicit-def $q13,"
" implicit-def $q14, implicit-def $q15\n"
" tBX_RET 14, $noreg, implicit $r0\n",
12u, cmpInstSize);
runChecks(TM.get(), II, "",
" t2Int_eh_sjlj_setjmp_nofp $r0, $r1, implicit-def $r0,"
" implicit-def $r1, implicit-def $r2, implicit-def $r3,"
" implicit-def $r4, implicit-def $r5, implicit-def $r6,"
" implicit-def $r7, implicit-def $r8, implicit-def $r9,"
" implicit-def $r10, implicit-def $r11, implicit-def $r12,"
" implicit-def $lr, implicit-def $cpsr\n"
" tBX_RET 14, $noreg, implicit $r0\n",
12u, cmpInstSize);
runChecks(TM.get(), II, "", " CONSTPOOL_ENTRY 3, %const.0, 8\n", 8u,
cmpInstSize);
runChecks(TM.get(), II, "", " JUMPTABLE_ADDRS 0, %jump-table.0, 123\n", 123u,
cmpInstSize);
runChecks(TM.get(), II, "", " JUMPTABLE_INSTS 0, %jump-table.0, 456\n", 456u,
cmpInstSize);
runChecks(TM.get(), II, "", " JUMPTABLE_TBB 0, %jump-table.0, 789\n", 789u,
cmpInstSize);
runChecks(TM.get(), II, "", " JUMPTABLE_TBH 0, %jump-table.0, 188\n", 188u,
cmpInstSize);
runChecks(TM.get(), II, "", " $r0 = SPACE 40, undef $r0\n", 40u,
cmpInstSize);
runChecks(TM.get(), II, "", " INLINEASM &\"movs r0, #42\", 1\n", 6u,
cmpInstSize);
runChecks(TM.get(), II,
" define void @foo() {\n"
" entry:\n"
" ret void\n"
" }\n",
" INLINEASM_BR &\"b ${0:l}\", 1, 13, blockaddress(@foo, "
"%ir-block.entry)\n",
6u, cmpInstSize);
}

View File

@@ -2,6 +2,7 @@ import("//llvm/utils/unittest/unittest.gni")
unittest("ARMTests") {
deps = [
"//llvm/lib/CodeGen/MIRParser",
"//llvm/lib/MC",
"//llvm/lib/Support",
"//llvm/lib/Target",
@@ -11,5 +12,5 @@ unittest("ARMTests") {
"//llvm/lib/Target/ARM/Utils",
]
include_dirs = [ "//llvm/lib/Target/ARM" ]
sources = [ "MachineInstrTest.cpp" ]
sources = [ "MachineInstrTest.cpp", "InstSizes.cpp" ]
}