xref: /llvm-project/llvm/unittests/Target/ARM/MachineInstrTest.cpp (revision 26a475afe5cf9acf8dfe3e6cf8ebf1343ec3b72c)
1 #include "ARMBaseInstrInfo.h"
2 #include "ARMSubtarget.h"
3 #include "ARMTargetMachine.h"
4 #include "llvm/Support/TargetRegistry.h"
5 #include "llvm/Support/TargetSelect.h"
6 #include "llvm/Target/TargetMachine.h"
7 #include "llvm/Target/TargetOptions.h"
8 
9 #include "gtest/gtest.h"
10 
11 using namespace llvm;
12 
13 // Test for instructions that aren't immediately obviously valid within a
14 // tail-predicated loop. This should be marked up in their tablegen
15 // descriptions. Currently the horizontal vector operations are tagged.
16 // TODO Add instructions that perform:
17 // - truncation,
18 // - extensions,
19 // - byte swapping,
20 // - others?
21 TEST(MachineInstrInvalidTailPredication, IsCorrect) {
22   LLVMInitializeARMTargetInfo();
23   LLVMInitializeARMTarget();
24   LLVMInitializeARMTargetMC();
25 
26   auto TT(Triple::normalize("thumbv8.1m.main-arm-none-eabi"));
27   std::string Error;
28   const Target *T = TargetRegistry::lookupTarget(TT, Error);
29   if (!T) {
30     dbgs() << Error;
31     return;
32   }
33 
34   TargetOptions Options;
35   auto TM = std::unique_ptr<LLVMTargetMachine>(
36     static_cast<LLVMTargetMachine*>(
37       T->createTargetMachine(TT, "generic", "", Options, None, None,
38                              CodeGenOpt::Default)));
39   auto MII = TM->getMCInstrInfo();
40 
41   using namespace ARM;
42 
43   auto IsInvalidTPOpcode = [](unsigned Opcode) {
44     switch (Opcode) {
45     case MVE_VABAVs8:
46     case MVE_VABAVs16:
47     case MVE_VABAVs32:
48     case MVE_VABAVu8:
49     case MVE_VABAVu16:
50     case MVE_VABAVu32:
51     case MVE_VADDVs8acc:
52     case MVE_VADDVs16acc:
53     case MVE_VADDVs32acc:
54     case MVE_VADDVu8acc:
55     case MVE_VADDVu16acc:
56     case MVE_VADDVu32acc:
57     case MVE_VADDVs8no_acc:
58     case MVE_VADDVs16no_acc:
59     case MVE_VADDVs32no_acc:
60     case MVE_VADDVu8no_acc:
61     case MVE_VADDVu16no_acc:
62     case MVE_VADDVu32no_acc:
63     case MVE_VADDLVs32no_acc:
64     case MVE_VADDLVu32no_acc:
65     case MVE_VADDLVs32acc:
66     case MVE_VADDLVu32acc:
67     case MVE_VMLADAVas16:
68     case MVE_VMLADAVas32:
69     case MVE_VMLADAVas8:
70     case MVE_VMLADAVau16:
71     case MVE_VMLADAVau32:
72     case MVE_VMLADAVau8:
73     case MVE_VMLADAVaxs16:
74     case MVE_VMLADAVaxs32:
75     case MVE_VMLADAVaxs8:
76     case MVE_VMLADAVs16:
77     case MVE_VMLADAVs32:
78     case MVE_VMLADAVs8:
79     case MVE_VMLADAVu16:
80     case MVE_VMLADAVu32:
81     case MVE_VMLADAVu8:
82     case MVE_VMLADAVxs16:
83     case MVE_VMLADAVxs32:
84     case MVE_VMLADAVxs8:
85     case MVE_VMLALDAVas16:
86     case MVE_VMLALDAVas32:
87     case MVE_VMLALDAVau16:
88     case MVE_VMLALDAVau32:
89     case MVE_VMLALDAVaxs16:
90     case MVE_VMLALDAVaxs32:
91     case MVE_VMLALDAVs16:
92     case MVE_VMLALDAVs32:
93     case MVE_VMLALDAVu16:
94     case MVE_VMLALDAVu32:
95     case MVE_VMLALDAVxs16:
96     case MVE_VMLALDAVxs32:
97     case MVE_VMLSDAVas16:
98     case MVE_VMLSDAVas32:
99     case MVE_VMLSDAVas8:
100     case MVE_VMLSDAVaxs16:
101     case MVE_VMLSDAVaxs32:
102     case MVE_VMLSDAVaxs8:
103     case MVE_VMLSDAVs16:
104     case MVE_VMLSDAVs32:
105     case MVE_VMLSDAVs8:
106     case MVE_VMLSDAVxs16:
107     case MVE_VMLSDAVxs32:
108     case MVE_VMLSDAVxs8:
109     case MVE_VMLSLDAVas16:
110     case MVE_VMLSLDAVas32:
111     case MVE_VMLSLDAVaxs16:
112     case MVE_VMLSLDAVaxs32:
113     case MVE_VMLSLDAVs16:
114     case MVE_VMLSLDAVs32:
115     case MVE_VMLSLDAVxs16:
116     case MVE_VMLSLDAVxs32:
117     case MVE_VRMLALDAVHas32:
118     case MVE_VRMLALDAVHau32:
119     case MVE_VRMLALDAVHaxs32:
120     case MVE_VRMLALDAVHs32:
121     case MVE_VRMLALDAVHu32:
122     case MVE_VRMLALDAVHxs32:
123     case MVE_VRMLSLDAVHas32:
124     case MVE_VRMLSLDAVHaxs32:
125     case MVE_VRMLSLDAVHs32:
126     case MVE_VRMLSLDAVHxs32:
127     case MVE_VMAXNMVf16:
128     case MVE_VMINNMVf16:
129     case MVE_VMAXNMVf32:
130     case MVE_VMINNMVf32:
131     case MVE_VMAXNMAVf16:
132     case MVE_VMINNMAVf16:
133     case MVE_VMAXNMAVf32:
134     case MVE_VMINNMAVf32:
135     case MVE_VMAXVs8:
136     case MVE_VMAXVs16:
137     case MVE_VMAXVs32:
138     case MVE_VMAXVu8:
139     case MVE_VMAXVu16:
140     case MVE_VMAXVu32:
141     case MVE_VMINVs8:
142     case MVE_VMINVs16:
143     case MVE_VMINVs32:
144     case MVE_VMINVu8:
145     case MVE_VMINVu16:
146     case MVE_VMINVu32:
147     case MVE_VMAXAVs8:
148     case MVE_VMAXAVs16:
149     case MVE_VMAXAVs32:
150     case MVE_VMINAVs8:
151     case MVE_VMINAVs16:
152     case MVE_VMINAVs32:
153       return true;
154     default:
155       return false;
156     }
157   };
158 
159   for (unsigned i = 0; i < ARM::INSTRUCTION_LIST_END; ++i) {
160     uint64_t Flags = MII->get(i).TSFlags;
161     bool Invalid = (Flags & ARMII::InvalidForTailPredication) != 0;
162     ASSERT_EQ(IsInvalidTPOpcode(i), Invalid)
163         << MII->getName(i)
164         << ": mismatched expectation for tail-predicated safety\n";
165   }
166 }
167