diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -752,23 +752,17 @@ 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 @@ // 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 @@ 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; } } diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -3657,6 +3657,8 @@ (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 @@ 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 @@ // // 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 @@ // 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 @@ // 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<[]>; } diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td --- a/llvm/lib/Target/ARM/ARMInstrThumb.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb.td @@ -1537,25 +1537,28 @@ // 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)]>, diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -2194,6 +2194,8 @@ (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 @@ 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 @@ // 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 @@ 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 @@ // 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 @@ // 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<[]>; } diff --git a/llvm/unittests/Target/ARM/CMakeLists.txt b/llvm/unittests/Target/ARM/CMakeLists.txt --- a/llvm/unittests/Target/ARM/CMakeLists.txt +++ b/llvm/unittests/Target/ARM/CMakeLists.txt @@ -10,6 +10,7 @@ CodeGen GlobalISel MC + MIRParser SelectionDAG Support Target @@ -17,4 +18,5 @@ add_llvm_target_unittest(ARMTests MachineInstrTest.cpp + InstSizes.cpp ) diff --git a/llvm/unittests/Target/ARM/InstSizes.cpp b/llvm/unittests/Target/ARM/InstSizes.cpp new file mode 100644 --- /dev/null +++ b/llvm/unittests/Target/ARM/InstSizes.cpp @@ -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 + 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 MBuffer = MemoryBuffer::getMemBuffer(MIRString); + std::unique_ptr MParser = + createMIRParser(std::move(MBuffer), Context); + ASSERT_TRUE(MParser); + + std::unique_ptr 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( + static_cast(T->createTargetMachine( + TT, "generic", "", Options, None, None, CodeGenOpt::Default))); + ARMSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()), + std::string(TM->getTargetFeatureString()), + *static_cast(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); +} diff --git a/llvm/utils/gn/secondary/llvm/unittests/Target/ARM/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/Target/ARM/BUILD.gn --- a/llvm/utils/gn/secondary/llvm/unittests/Target/ARM/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/unittests/Target/ARM/BUILD.gn @@ -2,6 +2,7 @@ unittest("ARMTests") { deps = [ + "//llvm/lib/CodeGen/MIRParser", "//llvm/lib/MC", "//llvm/lib/Support", "//llvm/lib/Target", @@ -11,5 +12,5 @@ "//llvm/lib/Target/ARM/Utils", ] include_dirs = [ "//llvm/lib/Target/ARM" ] - sources = [ "MachineInstrTest.cpp" ] + sources = [ "MachineInstrTest.cpp", "InstSizes.cpp" ] }