[llvm] r372076 - [ARM][MVE] Add invalidForTailPredication to TSFlags

Sam Parker via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 17 00:43:04 PDT 2019


Author: sam_parker
Date: Tue Sep 17 00:43:04 2019
New Revision: 372076

URL: http://llvm.org/viewvc/llvm-project?rev=372076&view=rev
Log:
[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

Added:
    llvm/trunk/unittests/Target/ARM/
    llvm/trunk/unittests/Target/ARM/CMakeLists.txt
    llvm/trunk/unittests/Target/ARM/MachineInstrTest.cpp
Modified:
    llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
    llvm/trunk/lib/Target/ARM/ARMInstrMVE.td
    llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h

Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=372076&r1=372075&r2=372076&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Tue Sep 17 00:43:04 2019
@@ -408,6 +408,8 @@ class InstTemplate<AddrMode am, int sz,
   // mnemonic (when not in an IT block) or preclude it (when in an IT block).
   bit thumbArithFlagSetting = 0;
 
+  bit invalidForTailPredication = 0;
+
   // If this is a pseudo instruction, mark it isCodeGenOnly.
   let isCodeGenOnly = !eq(!cast<string>(f), "Pseudo");
 
@@ -419,6 +421,7 @@ class InstTemplate<AddrMode am, int sz,
   let TSFlags{14}    = canXformTo16Bit;
   let TSFlags{18-15} = D.Value;
   let TSFlags{19}    = thumbArithFlagSetting;
+  let TSFlags{20}    = invalidForTailPredication;
 
   let Constraints = cstr;
   let Itinerary = itin;

Modified: llvm/trunk/lib/Target/ARM/ARMInstrMVE.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrMVE.td?rev=372076&r1=372075&r2=372076&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrMVE.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrMVE.td Tue Sep 17 00:43:04 2019
@@ -506,6 +506,7 @@ class MVE_VABAV<string suffix, bit U, bi
   let Inst{5} = Qm{3};
   let Inst{3-1} = Qm{2-0};
   let Inst{0} = 0b1;
+  let invalidForTailPredication = 1;
 }
 
 def MVE_VABAVs8  : MVE_VABAV<"s8", 0b0, 0b00>;
@@ -532,6 +533,7 @@ class MVE_VADDV<string iname, string suf
   let Inst{5} = A;
   let Inst{3-1} = Qm{2-0};
   let Inst{0} = 0b0;
+  let invalidForTailPredication = 1;
 }
 
 multiclass MVE_VADDV_A<string suffix, bit U, bits<2> size,
@@ -582,6 +584,7 @@ class MVE_VADDLV<string iname, string su
   let Inst{5} = A;
   let Inst{3-1} = Qm{2-0};
   let Inst{0} = 0b0;
+  let invalidForTailPredication = 1;
 }
 
 multiclass MVE_VADDLV_A<string suffix, bit U, list<dag> pattern=[]> {
@@ -619,6 +622,7 @@ class MVE_VMINMAXNMV<string iname, strin
   let Inst{0} = 0b0;
 
   let Predicates = [HasMVEFloat];
+  let invalidForTailPredication = 1;
 }
 
 multiclass MVE_VMINMAXNMV_fty<string iname, bit bit_7, list<dag> pattern=[]> {
@@ -655,6 +659,7 @@ class MVE_VMINMAXV<string iname, string
   let Inst{6-5} = 0b00;
   let Inst{3-1} = Qm{2-0};
   let Inst{0} = 0b0;
+  let invalidForTailPredication = 1;
 }
 
 multiclass MVE_VMINMAXV_ty<string iname, bit bit_7, list<dag> pattern=[]> {
@@ -727,6 +732,7 @@ class MVE_VMLAMLSDAV<string iname, strin
   let Inst{5} = A;
   let Inst{3-1} = Qm{2-0};
   let Inst{0} = bit_0;
+  let invalidForTailPredication = 1;
 }
 
 multiclass MVE_VMLAMLSDAV_A<string iname, string x, string suffix,
@@ -802,6 +808,7 @@ class MVE_VMLALDAVBase<string iname, str
   let Inst{5} = A;
   let Inst{3-1} = Qm{2-0};
   let Inst{0} = bit_0;
+  let invalidForTailPredication = 1;
 }
 
 multiclass MVE_VMLALDAVBase_A<string iname, string x, string suffix,

Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h?rev=372076&r1=372075&r2=372076&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h Tue Sep 17 00:43:04 2019
@@ -393,6 +393,10 @@ namespace ARMII {
     // in an IT block).
     ThumbArithFlagSetting = 1 << 19,
 
+    // Whether an instruction should be excluded from an MVE tail-predicated
+    // loop.
+    InvalidForTailPredication = 1 << 20,
+
     //===------------------------------------------------------------------===//
     // Code domain.
     DomainShift   = 15,

Added: llvm/trunk/unittests/Target/ARM/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Target/ARM/CMakeLists.txt?rev=372076&view=auto
==============================================================================
--- llvm/trunk/unittests/Target/ARM/CMakeLists.txt (added)
+++ llvm/trunk/unittests/Target/ARM/CMakeLists.txt Tue Sep 17 00:43:04 2019
@@ -0,0 +1,17 @@
+include_directories(
+  ${CMAKE_SOURCE_DIR}/lib/Target/ARM
+  ${CMAKE_BINARY_DIR}/lib/Target/ARM
+  )
+
+set(LLVM_LINK_COMPONENTS
+  ARMCodeGen
+  ARMDesc
+  ARMInfo
+  MC
+  Support
+  Target
+)
+
+add_llvm_unittest(ARMTests
+  MachineInstrTest.cpp
+  )

Added: llvm/trunk/unittests/Target/ARM/MachineInstrTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Target/ARM/MachineInstrTest.cpp?rev=372076&view=auto
==============================================================================
--- llvm/trunk/unittests/Target/ARM/MachineInstrTest.cpp (added)
+++ llvm/trunk/unittests/Target/ARM/MachineInstrTest.cpp Tue Sep 17 00:43:04 2019
@@ -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";
+  }
+}




More information about the llvm-commits mailing list