llvm.org GIT mirror llvm / 9cbd8cb
[ARM][MVE] Add invalidForTailPredication to TSFlags Set this bit for the MVE reduction instructions to prevent a loop from becoming tail predicated in their presence. Differential Revision: https://reviews.llvm.org/D67444 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@372076 91177308-0d34-0410-b5e6-96231b3b80d8 Sam Parker 1 year, 7 days ago
5 changed file(s) with 197 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
407407 // mnemonic (when not in an IT block) or preclude it (when in an IT block).
408408 bit thumbArithFlagSetting = 0;
409409
410 bit invalidForTailPredication = 0;
411
410412 // If this is a pseudo instruction, mark it isCodeGenOnly.
411413 let isCodeGenOnly = !eq(!cast(f), "Pseudo");
412414
418420 let TSFlags{14} = canXformTo16Bit;
419421 let TSFlags{18-15} = D.Value;
420422 let TSFlags{19} = thumbArithFlagSetting;
423 let TSFlags{20} = invalidForTailPredication;
421424
422425 let Constraints = cstr;
423426 let Itinerary = itin;
505505 let Inst{5} = Qm{3};
506506 let Inst{3-1} = Qm{2-0};
507507 let Inst{0} = 0b1;
508 let invalidForTailPredication = 1;
508509 }
509510
510511 def MVE_VABAVs8 : MVE_VABAV<"s8", 0b0, 0b00>;
531532 let Inst{5} = A;
532533 let Inst{3-1} = Qm{2-0};
533534 let Inst{0} = 0b0;
535 let invalidForTailPredication = 1;
534536 }
535537
536538 multiclass MVE_VADDV_A size,
581583 let Inst{5} = A;
582584 let Inst{3-1} = Qm{2-0};
583585 let Inst{0} = 0b0;
586 let invalidForTailPredication = 1;
584587 }
585588
586589 multiclass MVE_VADDLV_A pattern=[]> {
618621 let Inst{0} = 0b0;
619622
620623 let Predicates = [HasMVEFloat];
624 let invalidForTailPredication = 1;
621625 }
622626
623627 multiclass MVE_VMINMAXNMV_fty pattern=[]> {
654658 let Inst{6-5} = 0b00;
655659 let Inst{3-1} = Qm{2-0};
656660 let Inst{0} = 0b0;
661 let invalidForTailPredication = 1;
657662 }
658663
659664 multiclass MVE_VMINMAXV_ty pattern=[]> {
726731 let Inst{5} = A;
727732 let Inst{3-1} = Qm{2-0};
728733 let Inst{0} = bit_0;
734 let invalidForTailPredication = 1;
729735 }
730736
731737 multiclass MVE_VMLAMLSDAV_A
801807 let Inst{5} = A;
802808 let Inst{3-1} = Qm{2-0};
803809 let Inst{0} = bit_0;
810 let invalidForTailPredication = 1;
804811 }
805812
806813 multiclass MVE_VMLALDAVBase_A
392392 // in an IT block).
393393 ThumbArithFlagSetting = 1 << 19,
394394
395 // Whether an instruction should be excluded from an MVE tail-predicated
396 // loop.
397 InvalidForTailPredication = 1 << 20,
398
395399 //===------------------------------------------------------------------===//
396400 // Code domain.
397401 DomainShift = 15,
0 include_directories(
1 ${CMAKE_SOURCE_DIR}/lib/Target/ARM
2 ${CMAKE_BINARY_DIR}/lib/Target/ARM
3 )
4
5 set(LLVM_LINK_COMPONENTS
6 ARMCodeGen
7 ARMDesc
8 ARMInfo
9 MC
10 Support
11 Target
12 )
13
14 add_llvm_unittest(ARMTests
15 MachineInstrTest.cpp
16 )
0 #include "ARMBaseInstrInfo.h"
1 #include "ARMSubtarget.h"
2 #include "ARMTargetMachine.h"
3 #include "llvm/Support/TargetRegistry.h"
4 #include "llvm/Support/TargetSelect.h"
5 #include "llvm/Target/TargetMachine.h"
6 #include "llvm/Target/TargetOptions.h"
7
8 #include "gtest/gtest.h"
9
10 using namespace llvm;
11
12 // Test for instructions that aren't immediately obviously valid within a
13 // tail-predicated loop. This should be marked up in their tablegen
14 // descriptions. Currently the horizontal vector operations are tagged.
15 // TODO Add instructions that perform:
16 // - truncation,
17 // - extensions,
18 // - byte swapping,
19 // - others?
20 TEST(MachineInstrInvalidTailPredication, IsCorrect) {
21 LLVMInitializeARMTargetInfo();
22 LLVMInitializeARMTarget();
23 LLVMInitializeARMTargetMC();
24
25 auto TT(Triple::normalize("thumbv8.1m.main-arm-none-eabi"));
26 std::string Error;
27 const Target *T = TargetRegistry::lookupTarget(TT, Error);
28 if (!T) {
29 dbgs() << Error;
30 return;
31 }
32
33 TargetOptions Options;
34 auto TM = std::unique_ptr(
35 static_cast(
36 T->createTargetMachine(TT, "generic", "", Options, None, None,
37 CodeGenOpt::Default)));
38 auto MII = TM->getMCInstrInfo();
39
40 using namespace ARM;
41
42 auto IsInvalidTPOpcode = [](unsigned Opcode) {
43 switch (Opcode) {
44 case MVE_VABAVs8:
45 case MVE_VABAVs16:
46 case MVE_VABAVs32:
47 case MVE_VABAVu8:
48 case MVE_VABAVu16:
49 case MVE_VABAVu32:
50 case MVE_VADDVs8acc:
51 case MVE_VADDVs16acc:
52 case MVE_VADDVs32acc:
53 case MVE_VADDVu8acc:
54 case MVE_VADDVu16acc:
55 case MVE_VADDVu32acc:
56 case MVE_VADDVs8no_acc:
57 case MVE_VADDVs16no_acc:
58 case MVE_VADDVs32no_acc:
59 case MVE_VADDVu8no_acc:
60 case MVE_VADDVu16no_acc:
61 case MVE_VADDVu32no_acc:
62 case MVE_VADDLVs32no_acc:
63 case MVE_VADDLVu32no_acc:
64 case MVE_VADDLVs32acc:
65 case MVE_VADDLVu32acc:
66 case MVE_VMLADAVas16:
67 case MVE_VMLADAVas32:
68 case MVE_VMLADAVas8:
69 case MVE_VMLADAVau16:
70 case MVE_VMLADAVau32:
71 case MVE_VMLADAVau8:
72 case MVE_VMLADAVaxs16:
73 case MVE_VMLADAVaxs32:
74 case MVE_VMLADAVaxs8:
75 case MVE_VMLADAVs16:
76 case MVE_VMLADAVs32:
77 case MVE_VMLADAVs8:
78 case MVE_VMLADAVu16:
79 case MVE_VMLADAVu32:
80 case MVE_VMLADAVu8:
81 case MVE_VMLADAVxs16:
82 case MVE_VMLADAVxs32:
83 case MVE_VMLADAVxs8:
84 case MVE_VMLALDAVas16:
85 case MVE_VMLALDAVas32:
86 case MVE_VMLALDAVau16:
87 case MVE_VMLALDAVau32:
88 case MVE_VMLALDAVaxs16:
89 case MVE_VMLALDAVaxs32:
90 case MVE_VMLALDAVs16:
91 case MVE_VMLALDAVs32:
92 case MVE_VMLALDAVu16:
93 case MVE_VMLALDAVu32:
94 case MVE_VMLALDAVxs16:
95 case MVE_VMLALDAVxs32:
96 case MVE_VMLSDAVas16:
97 case MVE_VMLSDAVas32:
98 case MVE_VMLSDAVas8:
99 case MVE_VMLSDAVaxs16:
100 case MVE_VMLSDAVaxs32:
101 case MVE_VMLSDAVaxs8:
102 case MVE_VMLSDAVs16:
103 case MVE_VMLSDAVs32:
104 case MVE_VMLSDAVs8:
105 case MVE_VMLSDAVxs16:
106 case MVE_VMLSDAVxs32:
107 case MVE_VMLSDAVxs8:
108 case MVE_VMLSLDAVas16:
109 case MVE_VMLSLDAVas32:
110 case MVE_VMLSLDAVaxs16:
111 case MVE_VMLSLDAVaxs32:
112 case MVE_VMLSLDAVs16:
113 case MVE_VMLSLDAVs32:
114 case MVE_VMLSLDAVxs16:
115 case MVE_VMLSLDAVxs32:
116 case MVE_VRMLALDAVHas32:
117 case MVE_VRMLALDAVHau32:
118 case MVE_VRMLALDAVHaxs32:
119 case MVE_VRMLALDAVHs32:
120 case MVE_VRMLALDAVHu32:
121 case MVE_VRMLALDAVHxs32:
122 case MVE_VRMLSLDAVHas32:
123 case MVE_VRMLSLDAVHaxs32:
124 case MVE_VRMLSLDAVHs32:
125 case MVE_VRMLSLDAVHxs32:
126 case MVE_VMAXNMVf16:
127 case MVE_VMINNMVf16:
128 case MVE_VMAXNMVf32:
129 case MVE_VMINNMVf32:
130 case MVE_VMAXNMAVf16:
131 case MVE_VMINNMAVf16:
132 case MVE_VMAXNMAVf32:
133 case MVE_VMINNMAVf32:
134 case MVE_VMAXVs8:
135 case MVE_VMAXVs16:
136 case MVE_VMAXVs32:
137 case MVE_VMAXVu8:
138 case MVE_VMAXVu16:
139 case MVE_VMAXVu32:
140 case MVE_VMINVs8:
141 case MVE_VMINVs16:
142 case MVE_VMINVs32:
143 case MVE_VMINVu8:
144 case MVE_VMINVu16:
145 case MVE_VMINVu32:
146 case MVE_VMAXAVs8:
147 case MVE_VMAXAVs16:
148 case MVE_VMAXAVs32:
149 case MVE_VMINAVs8:
150 case MVE_VMINAVs16:
151 case MVE_VMINAVs32:
152 return true;
153 default:
154 return false;
155 }
156 };
157
158 for (unsigned i = 0; i < ARM::INSTRUCTION_LIST_END; ++i) {
159 uint64_t Flags = MII->get(i).TSFlags;
160 bool Invalid = (Flags & ARMII::InvalidForTailPredication) != 0;
161 ASSERT_EQ(IsInvalidTPOpcode(i), Invalid)
162 << MII->getName(i)
163 << ": mismatched expectation for tail-predicated safety\n";
164 }
165 }