Skip to content

Commit 772e493

Browse files
committed
[ARM,MVE] Revise immediate VBIC/VORR to look more like NEON.
Summary: In NEON, the immediate forms of VBIC and VORR are each represented as a single MC instruction, which takes its immediate operand already encoded in a NEON-friendly format: 8 data bits, plus some control bits indicating how to expand them into a full vector. In MVE, we represented immediate VBIC and VORR as four separate MC instructions each, for an 8-bit immediate shifted left by 0, 8, 16 or 24 bits. For each one, the value of the immediate operand is in the 'natural' form, i.e. the numerical value that would actually be BICed or ORRed into each vector lane (and also the same value shown in assembly). For example, MVE_VBICIZ16v4i32 takes an operand such as 0xab0000, which NEON would represent as 0xab | (control bits << 8). The MVE approach is superficially nice (it makes assembly input and output easy, and it's also nice if you're manually constructing immediate VBICs). But it turns out that it's better for isel if we make the NEON and MVE instructions work the same, because the ARMISD::VBICIMM and VORRIMM node types already encode their immediate into the NEON format, so it's easier if we can just use it. Also, this commit reduces the total amount of code rather than increasing it, which is surely an indication that it really is simpler to do it this way! Reviewers: dmgreen, ostannard, miyuki, MarkMurrayARM Reviewed By: dmgreen Subscribers: kristof.beyls, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D73205
1 parent e8fc850 commit 772e493

File tree

7 files changed

+28
-172
lines changed

7 files changed

+28
-172
lines changed

llvm/lib/Target/ARM/ARMInstrMVE.td

Lines changed: 24 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -10,44 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
class ExpandImmAsmOp<string shift> : AsmOperandClass {
14-
let Name = !strconcat("ExpandImm", shift);
15-
let PredicateMethod = !strconcat("isExpImm<", shift, ">");
16-
let RenderMethod = "addImmOperands";
17-
}
18-
class InvertedExpandImmAsmOp<string shift, string size> : AsmOperandClass {
19-
let Name = !strconcat("InvertedExpandImm", shift, "_", size);
20-
let PredicateMethod = !strconcat("isInvertedExpImm<", shift, ",", size, ">");
21-
let RenderMethod = "addImmOperands";
22-
}
23-
24-
class ExpandImm<string shift> : Operand<i32> {
25-
let ParserMatchClass = ExpandImmAsmOp<shift>;
26-
let EncoderMethod = !strconcat("getExpandedImmOpValue<",shift,",false>");
27-
let DecoderMethod = !strconcat("DecodeExpandedImmOperand<",shift,">");
28-
let PrintMethod = "printExpandedImmOperand";
29-
}
30-
class InvertedExpandImm<string shift, string size> : Operand<i32> {
31-
let ParserMatchClass = InvertedExpandImmAsmOp<shift, size>;
32-
let EncoderMethod = !strconcat("getExpandedImmOpValue<",shift,",true>");
33-
let PrintMethod = "printExpandedImmOperand";
34-
// No decoder method needed, because this operand type is only used
35-
// by aliases (VAND and VORN)
36-
}
37-
38-
def expzero00 : ExpandImm<"0">;
39-
def expzero08 : ExpandImm<"8">;
40-
def expzero16 : ExpandImm<"16">;
41-
def expzero24 : ExpandImm<"24">;
42-
43-
def expzero00inv16 : InvertedExpandImm<"0", "16">;
44-
def expzero08inv16 : InvertedExpandImm<"8", "16">;
45-
46-
def expzero00inv32 : InvertedExpandImm<"0", "32">;
47-
def expzero08inv32 : InvertedExpandImm<"8", "32">;
48-
def expzero16inv32 : InvertedExpandImm<"16", "32">;
49-
def expzero24inv32 : InvertedExpandImm<"24", "32">;
50-
5113
// VPT condition mask
5214
def vpt_mask : Operand<i32> {
5315
let PrintMethod = "printVPTMask";
@@ -1383,10 +1345,10 @@ defm : MVE_bit_op_with_inv<MVE_v8i16, or, int_arm_mve_orn_predicated, MVE_VORN>;
13831345
defm : MVE_bit_op_with_inv<MVE_v4i32, or, int_arm_mve_orn_predicated, MVE_VORN>;
13841346
defm : MVE_bit_op_with_inv<MVE_v2i64, or, int_arm_mve_orn_predicated, MVE_VORN>;
13851347

1386-
class MVE_bit_cmode<string iname, string suffix, bits<4> cmode, dag inOps>
1348+
class MVE_bit_cmode<string iname, string suffix, bit halfword, dag inOps>
13871349
: MVE_p<(outs MQPR:$Qd), inOps, NoItinerary,
13881350
iname, suffix, "$Qd, $imm", vpred_n, "$Qd = $Qd_src"> {
1389-
bits<8> imm;
1351+
bits<12> imm;
13901352
bits<4> Qd;
13911353

13921354
let Inst{28} = imm{7};
@@ -1396,66 +1358,45 @@ class MVE_bit_cmode<string iname, string suffix, bits<4> cmode, dag inOps>
13961358
let Inst{18-16} = imm{6-4};
13971359
let Inst{15-13} = Qd{2-0};
13981360
let Inst{12} = 0b0;
1399-
let Inst{11-8} = cmode;
1361+
let Inst{11} = halfword;
1362+
let Inst{10} = !if(halfword, 0, imm{10});
1363+
let Inst{9} = imm{9};
1364+
let Inst{8} = 0b1;
14001365
let Inst{7-6} = 0b01;
14011366
let Inst{4} = 0b1;
14021367
let Inst{3-0} = imm{3-0};
14031368
}
14041369

1405-
class MVE_VORR<string suffix, bits<4> cmode, ExpandImm imm_type>
1406-
: MVE_bit_cmode<"vorr", suffix, cmode, (ins MQPR:$Qd_src, imm_type:$imm)> {
1370+
class MVE_VORR<string suffix, bit hw, Operand imm_type>
1371+
: MVE_bit_cmode<"vorr", suffix, hw, (ins MQPR:$Qd_src, imm_type:$imm)> {
14071372
let Inst{5} = 0b0;
14081373
let validForTailPredication = 1;
14091374
}
14101375

1411-
def MVE_VORRIZ0v4i32 : MVE_VORR<"i32", 0b0001, expzero00>;
1412-
def MVE_VORRIZ0v8i16 : MVE_VORR<"i16", 0b1001, expzero00>;
1413-
def MVE_VORRIZ8v4i32 : MVE_VORR<"i32", 0b0011, expzero08>;
1414-
def MVE_VORRIZ8v8i16 : MVE_VORR<"i16", 0b1011, expzero08>;
1415-
def MVE_VORRIZ16v4i32 : MVE_VORR<"i32", 0b0101, expzero16>;
1416-
def MVE_VORRIZ24v4i32 : MVE_VORR<"i32", 0b0111, expzero24>;
1417-
1418-
def MVE_VORNIZ0v4i32 : MVEAsmPseudo<"vorn${vp}.i32\t$Qd, $imm",
1419-
(ins MQPR:$Qd_src, expzero00inv32:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
1420-
def MVE_VORNIZ0v8i16 : MVEAsmPseudo<"vorn${vp}.i16\t$Qd, $imm",
1421-
(ins MQPR:$Qd_src, expzero00inv16:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
1422-
def MVE_VORNIZ8v4i32 : MVEAsmPseudo<"vorn${vp}.i32\t$Qd, $imm",
1423-
(ins MQPR:$Qd_src, expzero08inv32:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
1424-
def MVE_VORNIZ8v8i16 : MVEAsmPseudo<"vorn${vp}.i16\t$Qd, $imm",
1425-
(ins MQPR:$Qd_src, expzero08inv16:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
1426-
def MVE_VORNIZ16v4i32 : MVEAsmPseudo<"vorn${vp}.i32\t$Qd, $imm",
1427-
(ins MQPR:$Qd_src, expzero16inv32:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
1428-
def MVE_VORNIZ24v4i32 : MVEAsmPseudo<"vorn${vp}.i32\t$Qd, $imm",
1429-
(ins MQPR:$Qd_src, expzero24inv32:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
1376+
def MVE_VORRimmi16 : MVE_VORR<"i16", 1, nImmSplatI16>;
1377+
def MVE_VORRimmi32 : MVE_VORR<"i32", 0, nImmSplatI32>;
1378+
1379+
def MVE_VORNimmi16 : MVEInstAlias<"vorn${vp}.i16\t$Qd, $imm",
1380+
(MVE_VORRimmi16 MQPR:$Qd, nImmSplatNotI16:$imm, vpred_n:$vp), 0>;
1381+
def MVE_VORNimmi32 : MVEInstAlias<"vorn${vp}.i32\t$Qd, $imm",
1382+
(MVE_VORRimmi32 MQPR:$Qd, nImmSplatNotI32:$imm, vpred_n:$vp), 0>;
14301383

14311384
def MVE_VMOV : MVEInstAlias<"vmov${vp}\t$Qd, $Qm",
14321385
(MVE_VORR MQPR:$Qd, MQPR:$Qm, MQPR:$Qm, vpred_r:$vp)>;
14331386

1434-
class MVE_VBIC<string suffix, bits<4> cmode, ExpandImm imm_type>
1435-
: MVE_bit_cmode<"vbic", suffix, cmode, (ins MQPR:$Qd_src, imm_type:$imm)> {
1387+
class MVE_VBIC<string suffix, bit hw, Operand imm_type>
1388+
: MVE_bit_cmode<"vbic", suffix, hw, (ins MQPR:$Qd_src, imm_type:$imm)> {
14361389
let Inst{5} = 0b1;
14371390
let validForTailPredication = 1;
14381391
}
14391392

1440-
def MVE_VBICIZ0v4i32 : MVE_VBIC<"i32", 0b0001, expzero00>;
1441-
def MVE_VBICIZ0v8i16 : MVE_VBIC<"i16", 0b1001, expzero00>;
1442-
def MVE_VBICIZ8v4i32 : MVE_VBIC<"i32", 0b0011, expzero08>;
1443-
def MVE_VBICIZ8v8i16 : MVE_VBIC<"i16", 0b1011, expzero08>;
1444-
def MVE_VBICIZ16v4i32 : MVE_VBIC<"i32", 0b0101, expzero16>;
1445-
def MVE_VBICIZ24v4i32 : MVE_VBIC<"i32", 0b0111, expzero24>;
1446-
1447-
def MVE_VANDIZ0v4i32 : MVEAsmPseudo<"vand${vp}.i32\t$Qda, $imm",
1448-
(ins MQPR:$Qda_src, expzero00inv32:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
1449-
def MVE_VANDIZ0v8i16 : MVEAsmPseudo<"vand${vp}.i16\t$Qda, $imm",
1450-
(ins MQPR:$Qda_src, expzero00inv16:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
1451-
def MVE_VANDIZ8v4i32 : MVEAsmPseudo<"vand${vp}.i32\t$Qda, $imm",
1452-
(ins MQPR:$Qda_src, expzero08inv32:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
1453-
def MVE_VANDIZ8v8i16 : MVEAsmPseudo<"vand${vp}.i16\t$Qda, $imm",
1454-
(ins MQPR:$Qda_src, expzero08inv16:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
1455-
def MVE_VANDIZ16v4i32 : MVEAsmPseudo<"vand${vp}.i32\t$Qda, $imm",
1456-
(ins MQPR:$Qda_src, expzero16inv32:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
1457-
def MVE_VANDIZ24v4i32 : MVEAsmPseudo<"vand${vp}.i32\t$Qda, $imm",
1458-
(ins MQPR:$Qda_src, expzero24inv32:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
1393+
def MVE_VBICimmi16 : MVE_VBIC<"i16", 1, nImmSplatI16>;
1394+
def MVE_VBICimmi32 : MVE_VBIC<"i32", 0, nImmSplatI32>;
1395+
1396+
def MVE_VANDimmi16 : MVEInstAlias<"vand${vp}.i16\t$Qd, $imm",
1397+
(MVE_VBICimmi16 MQPR:$Qd, nImmSplatNotI16:$imm, vpred_n:$vp), 0>;
1398+
def MVE_VANDimmi32 : MVEInstAlias<"vand${vp}.i32\t$Qd, $imm",
1399+
(MVE_VBICimmi32 MQPR:$Qd, nImmSplatNotI32:$imm, vpred_n:$vp), 0>;
14591400

14601401
class MVE_VMOV_lane_direction {
14611402
bit bit_20;

llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8223,50 +8223,6 @@ bool ARMAsmParser::processInstruction(MCInst &Inst,
82238223
}
82248224

82258225
switch (Inst.getOpcode()) {
8226-
case ARM::MVE_VORNIZ0v4i32:
8227-
case ARM::MVE_VORNIZ0v8i16:
8228-
case ARM::MVE_VORNIZ8v4i32:
8229-
case ARM::MVE_VORNIZ8v8i16:
8230-
case ARM::MVE_VORNIZ16v4i32:
8231-
case ARM::MVE_VORNIZ24v4i32:
8232-
case ARM::MVE_VANDIZ0v4i32:
8233-
case ARM::MVE_VANDIZ0v8i16:
8234-
case ARM::MVE_VANDIZ8v4i32:
8235-
case ARM::MVE_VANDIZ8v8i16:
8236-
case ARM::MVE_VANDIZ16v4i32:
8237-
case ARM::MVE_VANDIZ24v4i32: {
8238-
unsigned Opcode;
8239-
bool imm16 = false;
8240-
switch(Inst.getOpcode()) {
8241-
case ARM::MVE_VORNIZ0v4i32: Opcode = ARM::MVE_VORRIZ0v4i32; break;
8242-
case ARM::MVE_VORNIZ0v8i16: Opcode = ARM::MVE_VORRIZ0v8i16; imm16 = true; break;
8243-
case ARM::MVE_VORNIZ8v4i32: Opcode = ARM::MVE_VORRIZ8v4i32; break;
8244-
case ARM::MVE_VORNIZ8v8i16: Opcode = ARM::MVE_VORRIZ8v8i16; imm16 = true; break;
8245-
case ARM::MVE_VORNIZ16v4i32: Opcode = ARM::MVE_VORRIZ16v4i32; break;
8246-
case ARM::MVE_VORNIZ24v4i32: Opcode = ARM::MVE_VORRIZ24v4i32; break;
8247-
case ARM::MVE_VANDIZ0v4i32: Opcode = ARM::MVE_VBICIZ0v4i32; break;
8248-
case ARM::MVE_VANDIZ0v8i16: Opcode = ARM::MVE_VBICIZ0v8i16; imm16 = true; break;
8249-
case ARM::MVE_VANDIZ8v4i32: Opcode = ARM::MVE_VBICIZ8v4i32; break;
8250-
case ARM::MVE_VANDIZ8v8i16: Opcode = ARM::MVE_VBICIZ8v8i16; imm16 = true; break;
8251-
case ARM::MVE_VANDIZ16v4i32: Opcode = ARM::MVE_VBICIZ16v4i32; break;
8252-
case ARM::MVE_VANDIZ24v4i32: Opcode = ARM::MVE_VBICIZ24v4i32; break;
8253-
default: llvm_unreachable("unexpected opcode");
8254-
}
8255-
8256-
MCInst TmpInst;
8257-
TmpInst.setOpcode(Opcode);
8258-
TmpInst.addOperand(Inst.getOperand(0));
8259-
TmpInst.addOperand(Inst.getOperand(1));
8260-
8261-
// invert immediate
8262-
unsigned imm = ~Inst.getOperand(2).getImm() & (imm16 ? 0xffff : 0xffffffff);
8263-
TmpInst.addOperand(MCOperand::createImm(imm));
8264-
8265-
TmpInst.addOperand(Inst.getOperand(3));
8266-
TmpInst.addOperand(Inst.getOperand(4));
8267-
Inst = TmpInst;
8268-
return true;
8269-
}
82708226
// Alias for alternate form of 'ldr{,b}t Rt, [Rn], #imm' instruction.
82718227
case ARM::LDRT_POST:
82728228
case ARM::LDRBT_POST: {

llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -538,10 +538,6 @@ template<unsigned MinLog, unsigned MaxLog>
538538
static DecodeStatus DecodePowerTwoOperand(MCInst &Inst, unsigned Val,
539539
uint64_t Address,
540540
const void *Decoder);
541-
template <int shift>
542-
static DecodeStatus DecodeExpandedImmOperand(MCInst &Inst, unsigned Val,
543-
uint64_t Address,
544-
const void *Decoder);
545541
template<unsigned start>
546542
static DecodeStatus DecodeMVEPairVectorIndexOperand(MCInst &Inst, unsigned Val,
547543
uint64_t Address,
@@ -6395,16 +6391,6 @@ static DecodeStatus DecodePowerTwoOperand(MCInst &Inst, unsigned Val,
63956391
return S;
63966392
}
63976393

6398-
template <int shift>
6399-
static DecodeStatus DecodeExpandedImmOperand(MCInst &Inst, unsigned Val,
6400-
uint64_t Address,
6401-
const void *Decoder) {
6402-
Val <<= shift;
6403-
6404-
Inst.addOperand(MCOperand::createImm(Val));
6405-
return MCDisassembler::Success;
6406-
}
6407-
64086394
template<unsigned start>
64096395
static DecodeStatus DecodeMVEPairVectorIndexOperand(MCInst &Inst, unsigned Val,
64106396
uint64_t Address,

llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,15 +1669,6 @@ void ARMInstPrinter::printVPTMask(const MCInst *MI, unsigned OpNum,
16691669
}
16701670
}
16711671

1672-
void ARMInstPrinter::printExpandedImmOperand(const MCInst *MI, unsigned OpNum,
1673-
const MCSubtargetInfo &STI,
1674-
raw_ostream &O) {
1675-
uint32_t Val = MI->getOperand(OpNum).getImm();
1676-
O << markup("<imm:") << "#0x";
1677-
O.write_hex(Val);
1678-
O << markup(">");
1679-
}
1680-
16811672
void ARMInstPrinter::printMveSaturateOp(const MCInst *MI, unsigned OpNum,
16821673
const MCSubtargetInfo &STI,
16831674
raw_ostream &O) {

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,6 @@ class ARMInstPrinter : public MCInstPrinter {
260260
const MCSubtargetInfo &STI, raw_ostream &O);
261261
void printMveAddrModeQOperand(const MCInst *MI, unsigned OpNum,
262262
const MCSubtargetInfo &STI, raw_ostream &O);
263-
void printExpandedImmOperand(const MCInst *MI, unsigned OpNum,
264-
const MCSubtargetInfo &STI, raw_ostream &O);
265263
void printMveSaturateOp(const MCInst *MI, unsigned OpNum,
266264
const MCSubtargetInfo &STI, raw_ostream &O);
267265
private:

llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -413,14 +413,6 @@ class ARMMCCodeEmitter : public MCCodeEmitter {
413413
unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op,
414414
SmallVectorImpl<MCFixup> &Fixups,
415415
const MCSubtargetInfo &STI) const;
416-
template <uint8_t shift, bool invert>
417-
unsigned getExpandedImmOpValue(const MCInst &MI, unsigned Op,
418-
SmallVectorImpl<MCFixup> &Fixups,
419-
const MCSubtargetInfo &STI) const {
420-
static_assert(shift <= 32, "Shift count must be less than or equal to 32.");
421-
const MCOperand MO = MI.getOperand(Op);
422-
return (invert ? (MO.getImm() ^ 0xff) : MO.getImm()) >> shift;
423-
}
424416

425417
unsigned NEONThumb2DataIPostEncoder(const MCInst &MI,
426418
unsigned EncodedValue,

llvm/unittests/Target/ARM/MachineInstrTest.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,8 @@ TEST(MachineInstrValidTailPredication, IsCorrect) {
6262
case MVE_VADDi8:
6363
case MVE_VAND:
6464
case MVE_VBIC:
65-
case MVE_VBICIZ0v4i32:
66-
case MVE_VBICIZ0v8i16:
67-
case MVE_VBICIZ16v4i32:
68-
case MVE_VBICIZ24v4i32:
69-
case MVE_VBICIZ8v4i32:
70-
case MVE_VBICIZ8v8i16:
65+
case MVE_VBICimmi16:
66+
case MVE_VBICimmi32:
7167
case MVE_VBRSR16:
7268
case MVE_VBRSR32:
7369
case MVE_VBRSR8:
@@ -296,12 +292,8 @@ TEST(MachineInstrValidTailPredication, IsCorrect) {
296292
case MVE_VNEGs8:
297293
case MVE_VORN:
298294
case MVE_VORR:
299-
case MVE_VORRIZ0v4i32:
300-
case MVE_VORRIZ0v8i16:
301-
case MVE_VORRIZ16v4i32:
302-
case MVE_VORRIZ24v4i32:
303-
case MVE_VORRIZ8v4i32:
304-
case MVE_VORRIZ8v8i16:
295+
case MVE_VORRimmi16:
296+
case MVE_VORRimmi32:
305297
case MVE_VPST:
306298
case MVE_VQABSs16:
307299
case MVE_VQABSs32:

0 commit comments

Comments
 (0)