Skip to content

Commit

Permalink
[ARM][MVE] Add DoubleWidthResult flag
Browse files Browse the repository at this point in the history
Add a flag for those instructions which read from the top/bottom
halves of their inputs and produce a vector of results with double
width elements.

Differential Revision: https://reviews.llvm.org/D76762
  • Loading branch information
sparker-arm committed Mar 27, 2020
1 parent bda3dd0 commit 0e6aa08
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 1 deletion.
2 changes: 2 additions & 0 deletions llvm/lib/Target/ARM/ARMInstrFormats.td
Expand Up @@ -410,6 +410,7 @@ class InstTemplate<AddrMode am, int sz, IndexMode im,
bit validForTailPredication = 0;
bit retainsPreviousHalfElement = 0;
bit horizontalReduction = 0;
bit doubleWidthResult = 0;

// If this is a pseudo instruction, mark it isCodeGenOnly.
let isCodeGenOnly = !eq(!cast<string>(f), "Pseudo");
Expand All @@ -425,6 +426,7 @@ class InstTemplate<AddrMode am, int sz, IndexMode im,
let TSFlags{20} = validForTailPredication;
let TSFlags{21} = retainsPreviousHalfElement;
let TSFlags{22} = horizontalReduction;
let TSFlags{23} = doubleWidthResult;

let Constraints = cstr;
let Itinerary = itin;
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/ARM/ARMInstrMVE.td
Expand Up @@ -2513,6 +2513,7 @@ class MVE_VMOVL<string iname, string suffix, bits<2> sz, bit U, bit top,
let Inst{11-6} = 0b111101;
let Inst{4} = 0b0;
let Inst{0} = 0b0;
let doubleWidthResult = 1;
}

multiclass MVE_VMOVL_m<bit top, string chr, MVEVectorVTInfo OutVTI,
Expand Down Expand Up @@ -2580,6 +2581,8 @@ class MVE_VSHLL_imm<string iname, string suffix, bit U, bit th,

// For the MVE_VSHLL_patterns multiclass to refer to
Operand immediateType = immtype;

let doubleWidthResult = 1;
}

// The immediate VSHLL instructions accept shift counts from 1 up to
Expand Down Expand Up @@ -2623,6 +2626,7 @@ class MVE_VSHLL_by_lane_width<string iname, string suffix, bits<2> size,
let Inst{11-6} = 0b111000;
let Inst{4} = 0b0;
let Inst{0} = 0b1;
let doubleWidthResult = 1;
}

multiclass MVE_VSHLL_lw<string iname, string suffix, bits<2> sz, bit U,
Expand Down Expand Up @@ -4357,6 +4361,7 @@ class MVE_VMULL<string iname, string suffix, bit bit_28, bits<2> bits_21_20,
let Inst{7} = Qn{3};
let Inst{0} = 0b0;
let validForTailPredication = 1;
let doubleWidthResult = 1;
}

multiclass MVE_VMULL_m<MVEVectorVTInfo VTI,
Expand Down Expand Up @@ -4731,6 +4736,7 @@ class MVE_VQDMULL<string iname, string suffix, bit size, bit T,
let Inst{7} = Qn{3};
let Inst{0} = 0b1;
let validForTailPredication = 1;
let doubleWidthResult = 1;
}

multiclass MVE_VQDMULL_m<string iname, MVEVectorVTInfo VTI, bit size, bit T,
Expand Down Expand Up @@ -4937,6 +4943,7 @@ class MVE_VQDMULL_qr<string iname, string suffix, bit size,
let Inst{8} = 0b1;
let Inst{5} = 0b1;
let validForTailPredication = 1;
let doubleWidthResult = 1;
}

multiclass MVE_VQDMULL_qr_m<string iname, MVEVectorVTInfo VTI, bit size,
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
Expand Up @@ -403,6 +403,10 @@ namespace ARMII {
// Whether the instruction produces a scalar result from vector operands.
HorizontalReduction = 1 << 22,

// Whether this instruction produces a vector result that is larger than
// its input, typically reading from the top/bottom halves of the input(s).
DoubleWidthResult = 1 << 23,

//===------------------------------------------------------------------===//
// Code domain.
DomainShift = 15,
Expand Down
98 changes: 97 additions & 1 deletion llvm/unittests/Target/ARM/MachineInstrTest.cpp
Expand Up @@ -10,6 +10,103 @@

using namespace llvm;

TEST(MachineInstructionDoubleWidthResult, IsCorrect) {
using namespace ARM;

auto DoubleWidthResult = [](unsigned Opcode) {
switch (Opcode) {
default:
break;
case MVE_VMULLBp16:
case MVE_VMULLBp8:
case MVE_VMULLBs16:
case MVE_VMULLBs32:
case MVE_VMULLBs8:
case MVE_VMULLBu16:
case MVE_VMULLBu32:
case MVE_VMULLBu8:
case MVE_VMULLTp16:
case MVE_VMULLTp8:
case MVE_VMULLTs16:
case MVE_VMULLTs32:
case MVE_VMULLTs8:
case MVE_VMULLTu16:
case MVE_VMULLTu32:
case MVE_VMULLTu8:
case MVE_VQDMULL_qr_s16bh:
case MVE_VQDMULL_qr_s16th:
case MVE_VQDMULL_qr_s32bh:
case MVE_VQDMULL_qr_s32th:
case MVE_VQDMULLs16bh:
case MVE_VQDMULLs16th:
case MVE_VQDMULLs32bh:
case MVE_VQDMULLs32th:
case MVE_VMOVLs16bh:
case MVE_VMOVLs16th:
case MVE_VMOVLs8bh:
case MVE_VMOVLs8th:
case MVE_VMOVLu16bh:
case MVE_VMOVLu16th:
case MVE_VMOVLu8bh:
case MVE_VMOVLu8th:
case MVE_VSHLL_imms16bh:
case MVE_VSHLL_imms16th:
case MVE_VSHLL_imms8bh:
case MVE_VSHLL_imms8th:
case MVE_VSHLL_immu16bh:
case MVE_VSHLL_immu16th:
case MVE_VSHLL_immu8bh:
case MVE_VSHLL_immu8th:
case MVE_VSHLL_lws16bh:
case MVE_VSHLL_lws16th:
case MVE_VSHLL_lws8bh:
case MVE_VSHLL_lws8th:
case MVE_VSHLL_lwu16bh:
case MVE_VSHLL_lwu16th:
case MVE_VSHLL_lwu8bh:
case MVE_VSHLL_lwu8th:
return true;
}
return false;
};

LLVMInitializeARMTargetInfo();
LLVMInitializeARMTarget();
LLVMInitializeARMTargetMC();

auto TT(Triple::normalize("thumbv8.1m.main-arm-none-eabi"));
std::string Error;
const Target *T = TargetRegistry::lookupTarget(TT, Error);
if (!T) {
dbgs() << Error;
return;
}

TargetOptions Options;
auto TM = std::unique_ptr<LLVMTargetMachine>(
static_cast<LLVMTargetMachine*>(
T->createTargetMachine(TT, "generic", "", Options, None, None,
CodeGenOpt::Default)));
ARMSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()),
std::string(TM->getTargetFeatureString()),
*static_cast<const ARMBaseTargetMachine *>(TM.get()), false);
const ARMBaseInstrInfo *TII = ST.getInstrInfo();
auto MII = TM->getMCInstrInfo();

for (unsigned i = 0; i < ARM::INSTRUCTION_LIST_END; ++i) {
const MCInstrDesc &Desc = TII->get(i);

uint64_t Flags = Desc.TSFlags;
if ((Flags & ARMII::DomainMask) != ARMII::DomainMVE)
continue;

bool Valid = (Flags & ARMII::DoubleWidthResult) != 0;
ASSERT_EQ(DoubleWidthResult(i), Valid)
<< MII->getName(i)
<< ": mismatched expectation for tail-predicated safety\n";
}
}

TEST(MachineInstructionHorizontalReduction, IsCorrect) {
using namespace ARM;

Expand Down Expand Up @@ -159,7 +256,6 @@ TEST(MachineInstructionHorizontalReduction, IsCorrect) {
uint64_t Flags = Desc.TSFlags;
if ((Flags & ARMII::DomainMask) != ARMII::DomainMVE)
continue;

bool Valid = (Flags & ARMII::HorizontalReduction) != 0;
ASSERT_EQ(HorizontalReduction(i), Valid)
<< MII->getName(i)
Expand Down

0 comments on commit 0e6aa08

Please sign in to comment.