Index: llvm/lib/Target/ARM/ARMInstrFormats.td =================================================================== --- llvm/lib/Target/ARM/ARMInstrFormats.td +++ llvm/lib/Target/ARM/ARMInstrFormats.td @@ -409,6 +409,7 @@ bit validForTailPredication = 0; bit retainsPreviousHalfElement = 0; + bit doubleWidthResult = 0; // If this is a pseudo instruction, mark it isCodeGenOnly. let isCodeGenOnly = !eq(!cast(f), "Pseudo"); @@ -423,6 +424,7 @@ let TSFlags{19} = thumbArithFlagSetting; let TSFlags{20} = validForTailPredication; let TSFlags{21} = retainsPreviousHalfElement; + let TSFlags{22} = doubleWidthResult; let Constraints = cstr; let Itinerary = itin; Index: llvm/lib/Target/ARM/ARMInstrMVE.td =================================================================== --- llvm/lib/Target/ARM/ARMInstrMVE.td +++ llvm/lib/Target/ARM/ARMInstrMVE.td @@ -2506,6 +2506,7 @@ let Inst{11-6} = 0b111101; let Inst{4} = 0b0; let Inst{0} = 0b0; + let doubleWidthResult = 1; } multiclass MVE_VMOVL_m sz, bit U, @@ -4350,6 +4354,7 @@ let Inst{7} = Qn{3}; let Inst{0} = 0b0; let validForTailPredication = 1; + let doubleWidthResult = 1; } multiclass MVE_VMULL_m( + static_cast( + T->createTargetMachine(TT, "generic", "", Options, None, None, + CodeGenOpt::Default))); + ARMSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()), + std::string(TM->getTargetFeatureString()), + *static_cast(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(MachineInstructionRetainsPreviousHalfElement, IsCorrect) { using namespace ARM;