[llvm] 6f86e6b - [ARM][MVE] Add target flag for narrowing insts
Sam Parker via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 24 01:37:04 PDT 2020
Author: Sam Parker
Date: 2020-03-24T08:36:44Z
New Revision: 6f86e6bf4043b0fc75d285bac06ebc7c3f5828b0
URL: https://github.com/llvm/llvm-project/commit/6f86e6bf4043b0fc75d285bac06ebc7c3f5828b0
DIFF: https://github.com/llvm/llvm-project/commit/6f86e6bf4043b0fc75d285bac06ebc7c3f5828b0.diff
LOG: [ARM][MVE] Add target flag for narrowing insts
Add a flag, 'RetainsPreviousHalfElement', for operations that operate
on top/bottom halves of their input and only write to half of their
destination, leaving the other half to retain its previous value.
Differential Revision: https://reviews.llvm.org/D76608
Added:
Modified:
llvm/lib/Target/ARM/ARMInstrFormats.td
llvm/lib/Target/ARM/ARMInstrMVE.td
llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
llvm/unittests/Target/ARM/MachineInstrTest.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/ARM/ARMInstrFormats.td b/llvm/lib/Target/ARM/ARMInstrFormats.td
index 6e4a8ebab14c..535784bc3ce3 100644
--- a/llvm/lib/Target/ARM/ARMInstrFormats.td
+++ b/llvm/lib/Target/ARM/ARMInstrFormats.td
@@ -408,6 +408,7 @@ class InstTemplate<AddrMode am, int sz, IndexMode im,
bit thumbArithFlagSetting = 0;
bit validForTailPredication = 0;
+ bit retainsPreviousHalfElement = 0;
// If this is a pseudo instruction, mark it isCodeGenOnly.
let isCodeGenOnly = !eq(!cast<string>(f), "Pseudo");
@@ -421,6 +422,7 @@ class InstTemplate<AddrMode am, int sz, IndexMode im,
let TSFlags{18-15} = D.Value;
let TSFlags{19} = thumbArithFlagSetting;
let TSFlags{20} = validForTailPredication;
+ let TSFlags{21} = retainsPreviousHalfElement;
let Constraints = cstr;
let Itinerary = itin;
diff --git a/llvm/lib/Target/ARM/ARMInstrMVE.td b/llvm/lib/Target/ARM/ARMInstrMVE.td
index b94d071ca03d..e9e037df66f4 100644
--- a/llvm/lib/Target/ARM/ARMInstrMVE.td
+++ b/llvm/lib/Target/ARM/ARMInstrMVE.td
@@ -2688,6 +2688,7 @@ class MVE_VxSHRN<string iname, string suffix, bit bit_12, bit bit_28,
let Inst{4} = 0b0;
let Inst{0} = 0b1;
let validForTailPredication = 1;
+ let retainsPreviousHalfElement = 1;
}
def MVE_VRSHRNi16bh : MVE_VxSHRN<"vrshrnb", "i16", 0b0, 0b1, shr_imm8> {
@@ -2730,6 +2731,7 @@ class MVE_VxQRSHRUN<string iname, string suffix, bit bit_28, bit bit_12,
let Inst{4} = 0b0;
let Inst{0} = 0b0;
let validForTailPredication = 1;
+ let retainsPreviousHalfElement = 1;
}
def MVE_VQRSHRUNs16bh : MVE_VxQRSHRUN<
@@ -2779,6 +2781,7 @@ class MVE_VxQRSHRN<string iname, string suffix, bit bit_0, bit bit_12,
let Inst{4} = 0b0;
let Inst{0} = bit_0;
let validForTailPredication = 1;
+ let retainsPreviousHalfElement = 1;
}
multiclass MVE_VxQRSHRN_types<string iname, bit bit_0, bit bit_12> {
@@ -4492,6 +4495,7 @@ class MVE_VxMOVxN<string iname, string suffix, bit bit_28, bit bit_17,
let Inst{7} = !if(!eq(bit_17, 0), 1, 0);
let Inst{0} = 0b1;
let validForTailPredication = 1;
+ let retainsPreviousHalfElement = 1;
}
multiclass MVE_VxMOVxN_halves<string iname, string suffix,
@@ -4589,6 +4593,7 @@ class MVE_VCVT_ff<string iname, string suffix, bit op, bit T,
let Inst{0} = 0b1;
let Predicates = [HasMVEFloat];
+ let retainsPreviousHalfElement = 1;
}
multiclass MVE_VCVT_f2h_m<string iname, int half> {
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
index 6293a2462306..0c9925cf1d9e 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
@@ -396,6 +396,10 @@ namespace ARMII {
// Whether an instruction can be included in an MVE tail-predicated loop.
ValidForTailPredication = 1 << 20,
+ // Whether an instruction writes to the top/bottom half of a vector element
+ // and leaves the other half untouched.
+ RetainsPreviousHalfElement = 1 << 21,
+
//===------------------------------------------------------------------===//
// Code domain.
DomainShift = 15,
diff --git a/llvm/unittests/Target/ARM/MachineInstrTest.cpp b/llvm/unittests/Target/ARM/MachineInstrTest.cpp
index 94939603845d..609785818900 100644
--- a/llvm/unittests/Target/ARM/MachineInstrTest.cpp
+++ b/llvm/unittests/Target/ARM/MachineInstrTest.cpp
@@ -10,11 +10,110 @@
using namespace llvm;
+TEST(MachineInstructionRetainsPreviousHalfElement, IsCorrect) {
+ using namespace ARM;
+
+ auto RetainsPreviousHalfElement = [](unsigned Opcode) {
+ switch (Opcode) {
+ default:
+ break;
+ case MVE_VMOVNi16bh:
+ case MVE_VMOVNi16th:
+ case MVE_VMOVNi32bh:
+ case MVE_VMOVNi32th:
+ case MVE_VQMOVNs16bh:
+ case MVE_VQMOVNs16th:
+ case MVE_VQMOVNs32bh:
+ case MVE_VQMOVNs32th:
+ case MVE_VQMOVNu16bh:
+ case MVE_VQMOVNu16th:
+ case MVE_VQMOVNu32bh:
+ case MVE_VQMOVNu32th:
+ case MVE_VQMOVUNs16bh:
+ case MVE_VQMOVUNs16th:
+ case MVE_VQMOVUNs32bh:
+ case MVE_VQMOVUNs32th:
+ case MVE_VQRSHRNbhs16:
+ case MVE_VQRSHRNbhs32:
+ case MVE_VQRSHRNbhu16:
+ case MVE_VQRSHRNbhu32:
+ case MVE_VQRSHRNths16:
+ case MVE_VQRSHRNths32:
+ case MVE_VQRSHRNthu16:
+ case MVE_VQRSHRNthu32:
+ case MVE_VQRSHRUNs16bh:
+ case MVE_VQRSHRUNs16th:
+ case MVE_VQRSHRUNs32bh:
+ case MVE_VQRSHRUNs32th:
+ case MVE_VQSHRNbhs16:
+ case MVE_VQSHRNbhs32:
+ case MVE_VQSHRNbhu16:
+ case MVE_VQSHRNbhu32:
+ case MVE_VQSHRNths16:
+ case MVE_VQSHRNths32:
+ case MVE_VQSHRNthu16:
+ case MVE_VQSHRNthu32:
+ case MVE_VQSHRUNs16bh:
+ case MVE_VQSHRUNs16th:
+ case MVE_VQSHRUNs32bh:
+ case MVE_VQSHRUNs32th:
+ case MVE_VRSHRNi16bh:
+ case MVE_VRSHRNi16th:
+ case MVE_VRSHRNi32bh:
+ case MVE_VRSHRNi32th:
+ case MVE_VSHRNi16bh:
+ case MVE_VSHRNi16th:
+ case MVE_VSHRNi32bh:
+ case MVE_VSHRNi32th:
+ case MVE_VCVTf16f32bh:
+ case MVE_VCVTf16f32th:
+ case MVE_VCVTf32f16bh:
+ case MVE_VCVTf32f16th:
+ 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::RetainsPreviousHalfElement) != 0;
+ ASSERT_EQ(RetainsPreviousHalfElement(i), Valid)
+ << MII->getName(i)
+ << ": mismatched expectation for tail-predicated safety\n";
+ }
+}
// Test for instructions that aren't immediately obviously valid within a
// tail-predicated loop. This should be marked up in their tablegen
// descriptions. Currently we, conservatively, disallow:
// - cross beat carries.
-// - narrowing of results.
// - complex operations.
// - horizontal operations.
// - byte swapping.
More information about the llvm-commits
mailing list