Skip to content

Commit e872502

Browse files
committed
[ARM][MVE] Add HorizontalReduction flag
Add a target flag for instructions that reduce into one, or more, scalar reg(s), including variants of: - VADDV - VABAV - VMINV/VMAXV - VMLADAV Differential Revision: https://reviews.llvm.org/D76683
1 parent 856bdd0 commit e872502

File tree

4 files changed

+169
-0
lines changed

4 files changed

+169
-0
lines changed

llvm/lib/Target/ARM/ARMInstrFormats.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ class InstTemplate<AddrMode am, int sz, IndexMode im,
409409

410410
bit validForTailPredication = 0;
411411
bit retainsPreviousHalfElement = 0;
412+
bit horizontalReduction = 0;
412413

413414
// If this is a pseudo instruction, mark it isCodeGenOnly.
414415
let isCodeGenOnly = !eq(!cast<string>(f), "Pseudo");
@@ -423,6 +424,7 @@ class InstTemplate<AddrMode am, int sz, IndexMode im,
423424
let TSFlags{19} = thumbArithFlagSetting;
424425
let TSFlags{20} = validForTailPredication;
425426
let TSFlags{21} = retainsPreviousHalfElement;
427+
let TSFlags{22} = horizontalReduction;
426428

427429
let Constraints = cstr;
428430
let Itinerary = itin;

llvm/lib/Target/ARM/ARMInstrMVE.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,7 @@ class MVE_VABAV<string suffix, bit U, bits<2> size>
556556
let Inst{5} = Qm{3};
557557
let Inst{3-1} = Qm{2-0};
558558
let Inst{0} = 0b1;
559+
let horizontalReduction = 1;
559560
}
560561

561562
multiclass MVE_VABAV_m<MVEVectorVTInfo VTI> {
@@ -605,6 +606,7 @@ class MVE_VADDV<string iname, string suffix, dag iops, string cstr,
605606
let Inst{5} = A;
606607
let Inst{3-1} = Qm{2-0};
607608
let Inst{0} = 0b0;
609+
let horizontalReduction = 1;
608610
}
609611

610612
def ARMVADDVs : SDNode<"ARMISD::VADDVs", SDTVecReduce>;
@@ -678,6 +680,7 @@ class MVE_VADDLV<string iname, string suffix, dag iops, string cstr,
678680
let Inst{5} = A;
679681
let Inst{3-1} = Qm{2-0};
680682
let Inst{0} = 0b0;
683+
let horizontalReduction = 1;
681684
}
682685

683686
def SDTVecReduceL : SDTypeProfile<2, 1, [ // VADDLV
@@ -749,6 +752,7 @@ class MVE_VMINMAXNMV<string iname, string suffix, bit sz,
749752
let Inst{6-5} = 0b00;
750753
let Inst{3-1} = Qm{2-0};
751754
let Inst{0} = 0b0;
755+
let horizontalReduction = 1;
752756

753757
let Predicates = [HasMVEFloat];
754758
}
@@ -808,6 +812,7 @@ class MVE_VMINMAXV<string iname, string suffix, bit U, bits<2> size,
808812
let Inst{6-5} = 0b00;
809813
let Inst{3-1} = Qm{2-0};
810814
let Inst{0} = 0b0;
815+
let horizontalReduction = 1;
811816
}
812817

813818
multiclass MVE_VMINMAXV_p<string iname, bit notAbs, bit isMin,
@@ -899,6 +904,7 @@ class MVE_VMLAMLSDAV<string iname, string suffix, dag iops, string cstr,
899904
let Inst{5} = A;
900905
let Inst{3-1} = Qm{2-0};
901906
let Inst{0} = bit_0;
907+
let horizontalReduction = 1;
902908
}
903909

904910
multiclass MVE_VMLAMLSDAV_A<string iname, string x, MVEVectorVTInfo VTI,
@@ -1057,6 +1063,7 @@ class MVE_VMLALDAVBase<string iname, string suffix, dag iops, string cstr,
10571063
let Inst{5} = A;
10581064
let Inst{3-1} = Qm{2-0};
10591065
let Inst{0} = bit_0;
1066+
let horizontalReduction = 1;
10601067
}
10611068

10621069
multiclass MVE_VMLALDAVBase_A<string iname, string x, string suffix,

llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,9 @@ namespace ARMII {
400400
// and leaves the other half untouched.
401401
RetainsPreviousHalfElement = 1 << 21,
402402

403+
// Whether the instruction produces a scalar result from vector operands.
404+
HorizontalReduction = 1 << 22,
405+
403406
//===------------------------------------------------------------------===//
404407
// Code domain.
405408
DomainShift = 15,

llvm/unittests/Target/ARM/MachineInstrTest.cpp

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,163 @@
1010

1111
using namespace llvm;
1212

13+
TEST(MachineInstructionHorizontalReduction, IsCorrect) {
14+
using namespace ARM;
15+
16+
auto HorizontalReduction = [](unsigned Opcode) {
17+
switch (Opcode) {
18+
default:
19+
break;
20+
case MVE_VABAVs16:
21+
case MVE_VABAVs32:
22+
case MVE_VABAVs8:
23+
case MVE_VABAVu16:
24+
case MVE_VABAVu32:
25+
case MVE_VABAVu8:
26+
case MVE_VADDLVs32acc:
27+
case MVE_VADDLVs32no_acc:
28+
case MVE_VADDLVu32acc:
29+
case MVE_VADDLVu32no_acc:
30+
case MVE_VADDVs16acc:
31+
case MVE_VADDVs16no_acc:
32+
case MVE_VADDVs32acc:
33+
case MVE_VADDVs32no_acc:
34+
case MVE_VADDVs8acc:
35+
case MVE_VADDVs8no_acc:
36+
case MVE_VADDVu16acc:
37+
case MVE_VADDVu16no_acc:
38+
case MVE_VADDVu32acc:
39+
case MVE_VADDVu32no_acc:
40+
case MVE_VADDVu8acc:
41+
case MVE_VADDVu8no_acc:
42+
case MVE_VMAXAVs16:
43+
case MVE_VMAXAVs32:
44+
case MVE_VMAXAVs8:
45+
case MVE_VMAXNMAVf16:
46+
case MVE_VMAXNMAVf32:
47+
case MVE_VMAXNMVf16:
48+
case MVE_VMAXNMVf32:
49+
case MVE_VMAXVs16:
50+
case MVE_VMAXVs32:
51+
case MVE_VMAXVs8:
52+
case MVE_VMAXVu16:
53+
case MVE_VMAXVu32:
54+
case MVE_VMAXVu8:
55+
case MVE_VMINAVs16:
56+
case MVE_VMINAVs32:
57+
case MVE_VMINAVs8:
58+
case MVE_VMINNMAVf16:
59+
case MVE_VMINNMAVf32:
60+
case MVE_VMINNMVf16:
61+
case MVE_VMINNMVf32:
62+
case MVE_VMINVs16:
63+
case MVE_VMINVs32:
64+
case MVE_VMINVs8:
65+
case MVE_VMINVu16:
66+
case MVE_VMINVu32:
67+
case MVE_VMINVu8:
68+
case MVE_VMLADAVas16:
69+
case MVE_VMLADAVas32:
70+
case MVE_VMLADAVas8:
71+
case MVE_VMLADAVau16:
72+
case MVE_VMLADAVau32:
73+
case MVE_VMLADAVau8:
74+
case MVE_VMLADAVaxs16:
75+
case MVE_VMLADAVaxs32:
76+
case MVE_VMLADAVaxs8:
77+
case MVE_VMLADAVs16:
78+
case MVE_VMLADAVs32:
79+
case MVE_VMLADAVs8:
80+
case MVE_VMLADAVu16:
81+
case MVE_VMLADAVu32:
82+
case MVE_VMLADAVu8:
83+
case MVE_VMLADAVxs16:
84+
case MVE_VMLADAVxs32:
85+
case MVE_VMLADAVxs8:
86+
case MVE_VMLALDAVas16:
87+
case MVE_VMLALDAVas32:
88+
case MVE_VMLALDAVau16:
89+
case MVE_VMLALDAVau32:
90+
case MVE_VMLALDAVaxs16:
91+
case MVE_VMLALDAVaxs32:
92+
case MVE_VMLALDAVs16:
93+
case MVE_VMLALDAVs32:
94+
case MVE_VMLALDAVu16:
95+
case MVE_VMLALDAVu32:
96+
case MVE_VMLALDAVxs16:
97+
case MVE_VMLALDAVxs32:
98+
case MVE_VMLSDAVas16:
99+
case MVE_VMLSDAVas32:
100+
case MVE_VMLSDAVas8:
101+
case MVE_VMLSDAVaxs16:
102+
case MVE_VMLSDAVaxs32:
103+
case MVE_VMLSDAVaxs8:
104+
case MVE_VMLSDAVs16:
105+
case MVE_VMLSDAVs32:
106+
case MVE_VMLSDAVs8:
107+
case MVE_VMLSDAVxs16:
108+
case MVE_VMLSDAVxs32:
109+
case MVE_VMLSDAVxs8:
110+
case MVE_VMLSLDAVas16:
111+
case MVE_VMLSLDAVas32:
112+
case MVE_VMLSLDAVaxs16:
113+
case MVE_VMLSLDAVaxs32:
114+
case MVE_VMLSLDAVs16:
115+
case MVE_VMLSLDAVs32:
116+
case MVE_VMLSLDAVxs16:
117+
case MVE_VMLSLDAVxs32:
118+
case MVE_VRMLALDAVHas32:
119+
case MVE_VRMLALDAVHau32:
120+
case MVE_VRMLALDAVHaxs32:
121+
case MVE_VRMLALDAVHs32:
122+
case MVE_VRMLALDAVHu32:
123+
case MVE_VRMLALDAVHxs32:
124+
case MVE_VRMLSLDAVHas32:
125+
case MVE_VRMLSLDAVHaxs32:
126+
case MVE_VRMLSLDAVHs32:
127+
case MVE_VRMLSLDAVHxs32:
128+
return true;
129+
}
130+
return false;
131+
};
132+
133+
LLVMInitializeARMTargetInfo();
134+
LLVMInitializeARMTarget();
135+
LLVMInitializeARMTargetMC();
136+
137+
auto TT(Triple::normalize("thumbv8.1m.main-arm-none-eabi"));
138+
std::string Error;
139+
const Target *T = TargetRegistry::lookupTarget(TT, Error);
140+
if (!T) {
141+
dbgs() << Error;
142+
return;
143+
}
144+
145+
TargetOptions Options;
146+
auto TM = std::unique_ptr<LLVMTargetMachine>(
147+
static_cast<LLVMTargetMachine*>(
148+
T->createTargetMachine(TT, "generic", "", Options, None, None,
149+
CodeGenOpt::Default)));
150+
ARMSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()),
151+
std::string(TM->getTargetFeatureString()),
152+
*static_cast<const ARMBaseTargetMachine *>(TM.get()), false);
153+
const ARMBaseInstrInfo *TII = ST.getInstrInfo();
154+
auto MII = TM->getMCInstrInfo();
155+
156+
for (unsigned i = 0; i < ARM::INSTRUCTION_LIST_END; ++i) {
157+
const MCInstrDesc &Desc = TII->get(i);
158+
159+
uint64_t Flags = Desc.TSFlags;
160+
if ((Flags & ARMII::DomainMask) != ARMII::DomainMVE)
161+
continue;
162+
163+
bool Valid = (Flags & ARMII::HorizontalReduction) != 0;
164+
ASSERT_EQ(HorizontalReduction(i), Valid)
165+
<< MII->getName(i)
166+
<< ": mismatched expectation for tail-predicated safety\n";
167+
}
168+
}
169+
13170
TEST(MachineInstructionRetainsPreviousHalfElement, IsCorrect) {
14171
using namespace ARM;
15172

0 commit comments

Comments
 (0)