diff options
author | Sam Parker <sam.parker@arm.com> | 2019-09-17 07:43:04 +0000 |
---|---|---|
committer | Sam Parker <sam.parker@arm.com> | 2019-09-17 07:43:04 +0000 |
commit | 26a475afe5cf9acf8dfe3e6cf8ebf1343ec3b72c (patch) | |
tree | d8f2fae86fa0461c8b15d67ae7ad40560d95f6c2 /llvm/unittests/Target/ARM/MachineInstrTest.cpp | |
parent | 30d86f1858dbeaaeb5d5a2a6ba8631f7f839e094 (diff) | |
download | bcm5719-llvm-26a475afe5cf9acf8dfe3e6cf8ebf1343ec3b72c.tar.gz bcm5719-llvm-26a475afe5cf9acf8dfe3e6cf8ebf1343ec3b72c.zip |
[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
llvm-svn: 372076
Diffstat (limited to 'llvm/unittests/Target/ARM/MachineInstrTest.cpp')
-rw-r--r-- | llvm/unittests/Target/ARM/MachineInstrTest.cpp | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/llvm/unittests/Target/ARM/MachineInstrTest.cpp b/llvm/unittests/Target/ARM/MachineInstrTest.cpp new file mode 100644 index 00000000000..77bba08dcbc --- /dev/null +++ b/llvm/unittests/Target/ARM/MachineInstrTest.cpp @@ -0,0 +1,166 @@ +#include "ARMBaseInstrInfo.h" +#include "ARMSubtarget.h" +#include "ARMTargetMachine.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" + +#include "gtest/gtest.h" + +using namespace llvm; + +// Test for instructions that aren't immediately obviously valid within a +// tail-predicated loop. This should be marked up in their tablegen +// descriptions. Currently the horizontal vector operations are tagged. +// TODO Add instructions that perform: +// - truncation, +// - extensions, +// - byte swapping, +// - others? +TEST(MachineInstrInvalidTailPredication, IsCorrect) { + 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))); + auto MII = TM->getMCInstrInfo(); + + using namespace ARM; + + auto IsInvalidTPOpcode = [](unsigned Opcode) { + switch (Opcode) { + case MVE_VABAVs8: + case MVE_VABAVs16: + case MVE_VABAVs32: + case MVE_VABAVu8: + case MVE_VABAVu16: + case MVE_VABAVu32: + case MVE_VADDVs8acc: + case MVE_VADDVs16acc: + case MVE_VADDVs32acc: + case MVE_VADDVu8acc: + case MVE_VADDVu16acc: + case MVE_VADDVu32acc: + case MVE_VADDVs8no_acc: + case MVE_VADDVs16no_acc: + case MVE_VADDVs32no_acc: + case MVE_VADDVu8no_acc: + case MVE_VADDVu16no_acc: + case MVE_VADDVu32no_acc: + case MVE_VADDLVs32no_acc: + case MVE_VADDLVu32no_acc: + case MVE_VADDLVs32acc: + case MVE_VADDLVu32acc: + case MVE_VMLADAVas16: + case MVE_VMLADAVas32: + case MVE_VMLADAVas8: + case MVE_VMLADAVau16: + case MVE_VMLADAVau32: + case MVE_VMLADAVau8: + case MVE_VMLADAVaxs16: + case MVE_VMLADAVaxs32: + case MVE_VMLADAVaxs8: + case MVE_VMLADAVs16: + case MVE_VMLADAVs32: + case MVE_VMLADAVs8: + case MVE_VMLADAVu16: + case MVE_VMLADAVu32: + case MVE_VMLADAVu8: + case MVE_VMLADAVxs16: + case MVE_VMLADAVxs32: + case MVE_VMLADAVxs8: + case MVE_VMLALDAVas16: + case MVE_VMLALDAVas32: + case MVE_VMLALDAVau16: + case MVE_VMLALDAVau32: + case MVE_VMLALDAVaxs16: + case MVE_VMLALDAVaxs32: + case MVE_VMLALDAVs16: + case MVE_VMLALDAVs32: + case MVE_VMLALDAVu16: + case MVE_VMLALDAVu32: + case MVE_VMLALDAVxs16: + case MVE_VMLALDAVxs32: + case MVE_VMLSDAVas16: + case MVE_VMLSDAVas32: + case MVE_VMLSDAVas8: + case MVE_VMLSDAVaxs16: + case MVE_VMLSDAVaxs32: + case MVE_VMLSDAVaxs8: + case MVE_VMLSDAVs16: + case MVE_VMLSDAVs32: + case MVE_VMLSDAVs8: + case MVE_VMLSDAVxs16: + case MVE_VMLSDAVxs32: + case MVE_VMLSDAVxs8: + case MVE_VMLSLDAVas16: + case MVE_VMLSLDAVas32: + case MVE_VMLSLDAVaxs16: + case MVE_VMLSLDAVaxs32: + case MVE_VMLSLDAVs16: + case MVE_VMLSLDAVs32: + case MVE_VMLSLDAVxs16: + case MVE_VMLSLDAVxs32: + case MVE_VRMLALDAVHas32: + case MVE_VRMLALDAVHau32: + case MVE_VRMLALDAVHaxs32: + case MVE_VRMLALDAVHs32: + case MVE_VRMLALDAVHu32: + case MVE_VRMLALDAVHxs32: + case MVE_VRMLSLDAVHas32: + case MVE_VRMLSLDAVHaxs32: + case MVE_VRMLSLDAVHs32: + case MVE_VRMLSLDAVHxs32: + case MVE_VMAXNMVf16: + case MVE_VMINNMVf16: + case MVE_VMAXNMVf32: + case MVE_VMINNMVf32: + case MVE_VMAXNMAVf16: + case MVE_VMINNMAVf16: + case MVE_VMAXNMAVf32: + case MVE_VMINNMAVf32: + case MVE_VMAXVs8: + case MVE_VMAXVs16: + case MVE_VMAXVs32: + case MVE_VMAXVu8: + case MVE_VMAXVu16: + case MVE_VMAXVu32: + case MVE_VMINVs8: + case MVE_VMINVs16: + case MVE_VMINVs32: + case MVE_VMINVu8: + case MVE_VMINVu16: + case MVE_VMINVu32: + case MVE_VMAXAVs8: + case MVE_VMAXAVs16: + case MVE_VMAXAVs32: + case MVE_VMINAVs8: + case MVE_VMINAVs16: + case MVE_VMINAVs32: + return true; + default: + return false; + } + }; + + for (unsigned i = 0; i < ARM::INSTRUCTION_LIST_END; ++i) { + uint64_t Flags = MII->get(i).TSFlags; + bool Invalid = (Flags & ARMII::InvalidForTailPredication) != 0; + ASSERT_EQ(IsInvalidTPOpcode(i), Invalid) + << MII->getName(i) + << ": mismatched expectation for tail-predicated safety\n"; + } +} |