llvm.org GIT mirror llvm / 126de93
Add AArch64 unit tests Add unit tests for checking a few tricky instruction sizes. Also remove the old tests for the instruction sizes, which were clunky and brittle. Since this is the first set of target-specific unit tests, we need to add some CMake plumbing. In the future, adding unit tests for a given target will be as simple as creating a directory with the same name as the target under unittests/Target. The tests are only run if the target is enabled in LLVM_TARGETS_TO_BUILD. Differential Revision: https://reviews.llvm.org/D24548 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283990 91177308-0d34-0410-b5e6-96231b3b80d8 Diana Picus 4 years ago
7 changed file(s) with 151 addition(s) and 208 deletion(s). Raw diff Collapse all Expand all
+0
-65
test/CodeGen/MIR/AArch64/inst-size-patchpoint.mir less more
None # RUN: llc -mtriple=aarch64-unknown -run-pass branch-relaxation -aarch64-tbz-offset-bits=4 %s -o - | FileCheck %s
1 --- |
2 ; ModuleID = '/tmp/test.ll'
3 source_filename = "test.ll"
4 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
5 target triple = "aarch64-unknown"
6
7 define void @test_patchpoint_length(i32 %in) {
8 %val = and i32 %in, 1
9 %tst = icmp eq i32 %val, 0
10 br i1 %tst, label %true, label %false
11
12 true: ; preds = %0
13 tail call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 0, i32 32, i8* null, i32 0)
14 ret void
15
16 false: ; preds = %0
17 ret void
18 }
19
20 declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)
21 ...
22 ---
23 # CHECK-LABEL: name:{{.*}}test_patchpoint_length
24 # If the size of the patchpoint is computed correctly, that will push
25 # the bb.2.false block too far away from the TBNZW, so the branch will
26 # have to be relaxed (note that we're using -aarch64-tbz-offset-bits to
27 # constrain the range that can be reached with the TBNZW to something smaller
28 # than what the patchpoint is lowered to).
29 # CHECK: TBZW killed %w0, 0, %bb.1.true
30 # CHECK: B %bb.2.false
31 name: test_patchpoint_length
32 tracksRegLiveness: false
33 liveins:
34 - { reg: '%w0' }
35 frameInfo:
36 hasPatchPoint: true
37 stackSize: 16
38 offsetAdjustment: 0
39 maxAlignment: 8
40 adjustsStack: true
41 hasCalls: true
42 maxCallFrameSize: 0
43 stack:
44 - { id: 0, type: spill-slot, offset: -8, size: 8, alignment: 8, callee-saved-register: '%lr' }
45 - { id: 1, type: spill-slot, offset: -16, size: 8, alignment: 8, callee-saved-register: '%fp' }
46 body: |
47 bb.0 (%ir-block.0):
48 successors: %bb.1.true, %bb.2.false
49 liveins: %w0, %lr, %fp
50
51 TBNZW killed %w0, 0, %bb.2.false
52
53 bb.1.true:
54 successors: %bb.2.false
55 liveins: %lr, %fp
56
57 PATCHPOINT 0, 32, 0, 0, 0, csr_aarch64_aapcs, implicit-def dead early-clobber %x16, implicit-def dead early-clobber %x17, implicit-def dead early-clobber %lr, implicit-def %sp
58
59 bb.2.false:
60 liveins: %lr, %fp
61
62 RET killed %lr
63
64 ...
+0
-63
test/CodeGen/MIR/AArch64/inst-size-stackmap.mir less more
None # RUN: llc -mtriple=aarch64-unknown -run-pass branch-relaxation -aarch64-tbz-offset-bits=4 %s -o - | FileCheck %s
1 --- |
2 ; ModuleID = 'test.ll'
3 source_filename = "test.ll"
4 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
5 target triple = "aarch64-unknown"
6
7 define void @test_stackmap_length(i32 %in) {
8 %val = and i32 %in, 1
9 %tst = icmp eq i32 %val, 0
10 br i1 %tst, label %true, label %false
11
12 true: ; preds = %0
13 tail call void (i64, i32, ...) @llvm.experimental.stackmap(i64 0, i32 32)
14 ret void
15
16 false: ; preds = %0
17 ret void
18 }
19
20 declare void @llvm.experimental.stackmap(i64, i32, ...)
21 ...
22 ---
23 # CHECK-LABEL: name:{{.*}}test_stackmap_length
24 # If the size of the stackmap is computed correctly, that will push
25 # the bb.2.false block too far away from the TBNZW, so the branch will
26 # have to be relaxed (note that we're using -aarch64-tbz-offset-bits to
27 # constrain the range that can be reached with the TBNZW to something smaller
28 # than what the stackmap is lowered to).
29 # CHECK: TBZW killed %w0, 0, %bb.1.true
30 # CHECK: B %bb.2.false
31 name: test_stackmap_length
32 tracksRegLiveness: false
33 liveins:
34 - { reg: '%w0' }
35 frameInfo:
36 hasStackMap: true
37 stackSize: 16
38 offsetAdjustment: 0
39 maxAlignment: 8
40 adjustsStack: true
41 hasCalls: true
42 stack:
43 - { id: 0, type: spill-slot, offset: -8, size: 8, alignment: 8, callee-saved-register: '%lr' }
44 - { id: 1, type: spill-slot, offset: -16, size: 8, alignment: 8, callee-saved-register: '%fp' }
45 body: |
46 bb.0 (%ir-block.0):
47 successors: %bb.1.true, %bb.2.false
48 liveins: %w0, %lr, %fp
49
50 TBNZW killed %w0, 0, %bb.2.false
51
52 bb.1.true:
53 successors: %bb.2.false
54 liveins: %lr, %fp
55
56 STACKMAP 0, 32, implicit-def dead early-clobber %x16, implicit-def dead early-clobber %x17, implicit-def dead early-clobber %lr
57
58 bb.2.false:
59 liveins: %lr, %fp
60
61 RET killed %lr
62
+0
-80
test/CodeGen/MIR/AArch64/inst-size-tlsdesc-callseq.mir less more
None # RUN: llc -mtriple=aarch64-unknown -run-pass branch-relaxation -aarch64-tbz-offset-bits=4 %s -o - | FileCheck %s
1 --- |
2 ; ModuleID = 'test.ll'
3 source_filename = "test.ll"
4 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
5 target triple = "aarch64-unknown"
6
7 @ThreadLocalGlobal = external thread_local local_unnamed_addr global i32, align 8
8
9 define i32 @test_tlsdesc_callseq_length(i32 %in) {
10 %val = and i32 %in, 1
11 %tst = icmp eq i32 %val, 0
12 br i1 %tst, label %true, label %false
13
14 true: ; preds = %0
15 %1 = load i32, i32* @ThreadLocalGlobal, align 8
16 ret i32 %1
17
18 false: ; preds = %0
19 ret i32 0
20 }
21
22 ...
23 ---
24 # CHECK-LABEL: name:{{.*}}test_tlsdesc_callseq_length
25 # If the size of TLSDESC_CALLSEQ is computed correctly, that will push
26 # the bb.2.false block too far away from the TBNZW, so the branch will
27 # have to be relaxed (note that we're using -aarch64-tbz-offset-bits to
28 # constrain the range that can be reached with the TBNZW to something smaller
29 # than what TLSDESC_CALLSEQ is lowered to).
30 # CHECK: TBZW killed %w0, 0, %bb.1.true
31 # CHECK: B %bb.2.false
32 name: test_tlsdesc_callseq_length
33 alignment: 2
34 exposesReturnsTwice: false
35 tracksRegLiveness: false
36 liveins:
37 - { reg: '%w0' }
38 frameInfo:
39 isFrameAddressTaken: false
40 isReturnAddressTaken: false
41 hasStackMap: false
42 hasPatchPoint: false
43 stackSize: 16
44 offsetAdjustment: 0
45 maxAlignment: 16
46 adjustsStack: false
47 hasCalls: true
48 maxCallFrameSize: 0
49 hasOpaqueSPAdjustment: false
50 hasVAStart: false
51 hasMustTailInVarArgFunc: false
52 stack:
53 - { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16, callee-saved-register: '%lr' }
54 body: |
55 bb.0 (%ir-block.0):
56 successors: %bb.1.true, %bb.2.false
57 liveins: %w0, %lr
58
59 TBNZW killed %w0, 0, %bb.2.false
60
61 bb.1.true:
62 liveins: %lr
63
64 early-clobber %sp = frame-setup STRXpre killed %lr, %sp, -16 :: (store 8 into %stack.0)
65 frame-setup CFI_INSTRUCTION def_cfa_offset 16
66 frame-setup CFI_INSTRUCTION offset %w30, -16
67 TLSDESC_CALLSEQ target-flags(aarch64-tls) @ThreadLocalGlobal, implicit-def dead %lr, implicit-def %x0, implicit-def dead %x1
68 %x8 = MRS 56962
69 %w0 = LDRWroX killed %x8, killed %x0, 0, 0 :: (load 4 from @ThreadLocalGlobal, align 8)
70 early-clobber %sp, %lr = LDRXpost %sp, 16 :: (load 8 from %stack.0)
71 RET killed %lr, implicit killed %w0
72
73 bb.2.false:
74 liveins: %lr
75
76 %w0 = ORRWrs %wzr, %wzr, 0
77 RET killed %lr, implicit killed %w0
78
79 ...
2424 add_subdirectory(Option)
2525 add_subdirectory(ProfileData)
2626 add_subdirectory(Support)
27 add_subdirectory(Target)
2728 add_subdirectory(Transforms)
0 include_directories(
1 ${CMAKE_SOURCE_DIR}/lib/Target/AArch64
2 ${CMAKE_BINARY_DIR}/lib/Target/AArch64
3 )
4
5 # FIXME: We're really requiring way too many components here, and a lot of it is
6 # because of the TargetOptions
7 set(LLVM_LINK_COMPONENTS
8 AArch64CodeGen
9 AArch64Desc
10 AArch64Info
11 CodeGen
12 Core
13 MC
14 MIRParser
15 SelectionDAG
16 Support
17 Target
18 )
19
20 add_llvm_unittest(AArch64Tests
21 InstSizes.cpp
22 )
0 #include "AArch64Subtarget.h"
1 #include "AArch64TargetMachine.h"
2 #include "llvm/CodeGen/MIRParser/MIRParser.h"
3 #include "llvm/CodeGen/MachineModuleInfo.h"
4 #include "llvm/Support/TargetRegistry.h"
5 #include "llvm/Support/TargetSelect.h"
6
7 #include "gtest/gtest.h"
8
9 using namespace llvm;
10
11 namespace {
12 std::unique_ptr createTargetMachine() {
13 auto TT(Triple::normalize("aarch64--"));
14 std::string CPU("generic");
15 std::string FS("");
16
17 LLVMInitializeAArch64TargetInfo();
18 LLVMInitializeAArch64Target();
19 LLVMInitializeAArch64TargetMC();
20
21 std::string Error;
22 const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);
23 assert(TheTarget && "Target not registered");
24
25 return std::unique_ptr(
26 TheTarget->createTargetMachine(TT, CPU, FS, TargetOptions(), None,
27 CodeModel::Default, CodeGenOpt::Default));
28 }
29
30 std::unique_ptr createInstrInfo(TargetMachine *TM) {
31 AArch64Subtarget ST(TM->getTargetTriple(), TM->getTargetCPU(),
32 TM->getTargetFeatureString(), *TM, /* isLittle */ false);
33 return llvm::make_unique(ST);
34 }
35
36 /// The \p InputIRSnippet is only needed for things that can't be expressed in
37 /// the \p InputMIRSnippet (global variables etc)
38 /// TODO: Some of this might be useful for other architectures as well - extract
39 /// the platform-independent parts somewhere they can be reused.
40 void runChecks(
41 TargetMachine *TM, AArch64InstrInfo *II, const StringRef InputIRSnippet,
42 const StringRef InputMIRSnippet,
43 std::function Checks) {
44 LLVMContext Context;
45
46 auto MIRString =
47 "--- |\n"
48 " declare void @sizes()\n"
49 + InputIRSnippet.str() +
50 "...\n"
51 "---\n"
52 "name: sizes\n"
53 "body: |\n"
54 " bb.0:\n"
55 + InputMIRSnippet.str();
56
57 std::unique_ptr MBuffer = MemoryBuffer::getMemBuffer(MIRString);
58 std::unique_ptr MParser =
59 createMIRParser(std::move(MBuffer), Context);
60 assert(MParser && "Couldn't create MIR parser");
61
62 std::unique_ptr M = MParser->parseLLVMModule();
63 assert(M && "Couldn't parse module");
64
65 M->setTargetTriple(TM->getTargetTriple().getTriple());
66 M->setDataLayout(TM->createDataLayout());
67
68 auto F = M->getFunction("sizes");
69 assert(F && "Couldn't find intended function");
70
71 MachineModuleInfo MMI(TM);
72 MMI.setMachineFunctionInitializer(MParser.get());
73 auto &MF = MMI.getMachineFunction(*F);
74
75 Checks(*II, MF);
76 }
77
78 } // anonymous namespace
79
80 TEST(InstSizes, STACKMAP) {
81 std::unique_ptr TM = createTargetMachine();
82 std::unique_ptr II = createInstrInfo(TM.get());
83
84 runChecks(TM.get(), II.get(), "", " STACKMAP 0, 16\n"
85 " STACKMAP 1, 32\n",
86 [](AArch64InstrInfo &II, MachineFunction &MF) {
87 auto I = MF.begin()->begin();
88 EXPECT_EQ(16u, II.getInstSizeInBytes(*I));
89 ++I;
90 EXPECT_EQ(32u, II.getInstSizeInBytes(*I));
91 });
92 }
93
94 TEST(InstSizes, PATCHPOINT) {
95 std::unique_ptr TM = createTargetMachine();
96 std::unique_ptr II = createInstrInfo(TM.get());
97
98 runChecks(TM.get(), II.get(), "",
99 " PATCHPOINT 0, 16, 0, 0, 0, csr_aarch64_aapcs\n"
100 " PATCHPOINT 1, 32, 0, 0, 0, csr_aarch64_aapcs\n",
101 [](AArch64InstrInfo &II, MachineFunction &MF) {
102 auto I = MF.begin()->begin();
103 EXPECT_EQ(16u, II.getInstSizeInBytes(*I));
104 ++I;
105 EXPECT_EQ(32u, II.getInstSizeInBytes(*I));
106 });
107 }
108
109 TEST(InstSizes, TLSDESC_CALLSEQ) {
110 std::unique_ptr TM = createTargetMachine();
111 std::unique_ptr II = createInstrInfo(TM.get());
112
113 runChecks(
114 TM.get(), II.get(),
115 " @ThreadLocalGlobal = external thread_local global i32, align 8\n",
116 " TLSDESC_CALLSEQ target-flags(aarch64-tls) @ThreadLocalGlobal\n",
117 [](AArch64InstrInfo &II, MachineFunction &MF) {
118 auto I = MF.begin()->begin();
119 EXPECT_EQ(16u, II.getInstSizeInBytes(*I));
120 });
121 }
0 foreach(t ${LLVM_TARGETS_TO_BUILD})
1 if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${t})
2 add_subdirectory(${t})
3 endif()
4 endforeach()