1 #include "ARMBaseInstrInfo.h" 2 #include "ARMSubtarget.h" 3 #include "ARMTargetMachine.h" 4 #include "llvm/Support/TargetRegistry.h" 5 #include "llvm/Support/TargetSelect.h" 6 #include "llvm/Target/TargetMachine.h" 7 #include "llvm/Target/TargetOptions.h" 8 9 #include "gtest/gtest.h" 10 11 using namespace llvm; 12 13 // Test for instructions that aren't immediately obviously valid within a 14 // tail-predicated loop. This should be marked up in their tablegen 15 // descriptions. Currently the horizontal vector operations are tagged. 16 // TODO Add instructions that perform: 17 // - truncation, 18 // - extensions, 19 // - byte swapping, 20 // - others? 21 TEST(MachineInstrInvalidTailPredication, IsCorrect) { 22 LLVMInitializeARMTargetInfo(); 23 LLVMInitializeARMTarget(); 24 LLVMInitializeARMTargetMC(); 25 26 auto TT(Triple::normalize("thumbv8.1m.main-arm-none-eabi")); 27 std::string Error; 28 const Target *T = TargetRegistry::lookupTarget(TT, Error); 29 if (!T) { 30 dbgs() << Error; 31 return; 32 } 33 34 TargetOptions Options; 35 auto TM = std::unique_ptr<LLVMTargetMachine>( 36 static_cast<LLVMTargetMachine*>( 37 T->createTargetMachine(TT, "generic", "", Options, None, None, 38 CodeGenOpt::Default))); 39 auto MII = TM->getMCInstrInfo(); 40 41 using namespace ARM; 42 43 auto IsInvalidTPOpcode = [](unsigned Opcode) { 44 switch (Opcode) { 45 case MVE_VABAVs8: 46 case MVE_VABAVs16: 47 case MVE_VABAVs32: 48 case MVE_VABAVu8: 49 case MVE_VABAVu16: 50 case MVE_VABAVu32: 51 case MVE_VADDVs8acc: 52 case MVE_VADDVs16acc: 53 case MVE_VADDVs32acc: 54 case MVE_VADDVu8acc: 55 case MVE_VADDVu16acc: 56 case MVE_VADDVu32acc: 57 case MVE_VADDVs8no_acc: 58 case MVE_VADDVs16no_acc: 59 case MVE_VADDVs32no_acc: 60 case MVE_VADDVu8no_acc: 61 case MVE_VADDVu16no_acc: 62 case MVE_VADDVu32no_acc: 63 case MVE_VADDLVs32no_acc: 64 case MVE_VADDLVu32no_acc: 65 case MVE_VADDLVs32acc: 66 case MVE_VADDLVu32acc: 67 case MVE_VMLADAVas16: 68 case MVE_VMLADAVas32: 69 case MVE_VMLADAVas8: 70 case MVE_VMLADAVau16: 71 case MVE_VMLADAVau32: 72 case MVE_VMLADAVau8: 73 case MVE_VMLADAVaxs16: 74 case MVE_VMLADAVaxs32: 75 case MVE_VMLADAVaxs8: 76 case MVE_VMLADAVs16: 77 case MVE_VMLADAVs32: 78 case MVE_VMLADAVs8: 79 case MVE_VMLADAVu16: 80 case MVE_VMLADAVu32: 81 case MVE_VMLADAVu8: 82 case MVE_VMLADAVxs16: 83 case MVE_VMLADAVxs32: 84 case MVE_VMLADAVxs8: 85 case MVE_VMLALDAVas16: 86 case MVE_VMLALDAVas32: 87 case MVE_VMLALDAVau16: 88 case MVE_VMLALDAVau32: 89 case MVE_VMLALDAVaxs16: 90 case MVE_VMLALDAVaxs32: 91 case MVE_VMLALDAVs16: 92 case MVE_VMLALDAVs32: 93 case MVE_VMLALDAVu16: 94 case MVE_VMLALDAVu32: 95 case MVE_VMLALDAVxs16: 96 case MVE_VMLALDAVxs32: 97 case MVE_VMLSDAVas16: 98 case MVE_VMLSDAVas32: 99 case MVE_VMLSDAVas8: 100 case MVE_VMLSDAVaxs16: 101 case MVE_VMLSDAVaxs32: 102 case MVE_VMLSDAVaxs8: 103 case MVE_VMLSDAVs16: 104 case MVE_VMLSDAVs32: 105 case MVE_VMLSDAVs8: 106 case MVE_VMLSDAVxs16: 107 case MVE_VMLSDAVxs32: 108 case MVE_VMLSDAVxs8: 109 case MVE_VMLSLDAVas16: 110 case MVE_VMLSLDAVas32: 111 case MVE_VMLSLDAVaxs16: 112 case MVE_VMLSLDAVaxs32: 113 case MVE_VMLSLDAVs16: 114 case MVE_VMLSLDAVs32: 115 case MVE_VMLSLDAVxs16: 116 case MVE_VMLSLDAVxs32: 117 case MVE_VRMLALDAVHas32: 118 case MVE_VRMLALDAVHau32: 119 case MVE_VRMLALDAVHaxs32: 120 case MVE_VRMLALDAVHs32: 121 case MVE_VRMLALDAVHu32: 122 case MVE_VRMLALDAVHxs32: 123 case MVE_VRMLSLDAVHas32: 124 case MVE_VRMLSLDAVHaxs32: 125 case MVE_VRMLSLDAVHs32: 126 case MVE_VRMLSLDAVHxs32: 127 case MVE_VMAXNMVf16: 128 case MVE_VMINNMVf16: 129 case MVE_VMAXNMVf32: 130 case MVE_VMINNMVf32: 131 case MVE_VMAXNMAVf16: 132 case MVE_VMINNMAVf16: 133 case MVE_VMAXNMAVf32: 134 case MVE_VMINNMAVf32: 135 case MVE_VMAXVs8: 136 case MVE_VMAXVs16: 137 case MVE_VMAXVs32: 138 case MVE_VMAXVu8: 139 case MVE_VMAXVu16: 140 case MVE_VMAXVu32: 141 case MVE_VMINVs8: 142 case MVE_VMINVs16: 143 case MVE_VMINVs32: 144 case MVE_VMINVu8: 145 case MVE_VMINVu16: 146 case MVE_VMINVu32: 147 case MVE_VMAXAVs8: 148 case MVE_VMAXAVs16: 149 case MVE_VMAXAVs32: 150 case MVE_VMINAVs8: 151 case MVE_VMINAVs16: 152 case MVE_VMINAVs32: 153 return true; 154 default: 155 return false; 156 } 157 }; 158 159 for (unsigned i = 0; i < ARM::INSTRUCTION_LIST_END; ++i) { 160 uint64_t Flags = MII->get(i).TSFlags; 161 bool Invalid = (Flags & ARMII::InvalidForTailPredication) != 0; 162 ASSERT_EQ(IsInvalidTPOpcode(i), Invalid) 163 << MII->getName(i) 164 << ": mismatched expectation for tail-predicated safety\n"; 165 } 166 } 167