diff --git a/llvm/lib/Target/ARM/ARMInstrFormats.td b/llvm/lib/Target/ARM/ARMInstrFormats.td --- a/llvm/lib/Target/ARM/ARMInstrFormats.td +++ b/llvm/lib/Target/ARM/ARMInstrFormats.td @@ -410,6 +410,7 @@ bit validForTailPredication = 0; bit retainsPreviousHalfElement = 0; bit horizontalReduction = 0; + bit doubleWidthResult = 0; // If this is a pseudo instruction, mark it isCodeGenOnly. let isCodeGenOnly = !eq(!cast(f), "Pseudo"); @@ -425,6 +426,7 @@ let TSFlags{20} = validForTailPredication; let TSFlags{21} = retainsPreviousHalfElement; let TSFlags{22} = horizontalReduction; + let TSFlags{23} = doubleWidthResult; let Constraints = cstr; let Itinerary = itin; diff --git a/llvm/lib/Target/ARM/ARMInstrMVE.td b/llvm/lib/Target/ARM/ARMInstrMVE.td --- a/llvm/lib/Target/ARM/ARMInstrMVE.td +++ b/llvm/lib/Target/ARM/ARMInstrMVE.td @@ -2513,6 +2513,7 @@ let Inst{11-6} = 0b111101; let Inst{4} = 0b0; let Inst{0} = 0b0; + let doubleWidthResult = 1; } multiclass MVE_VMOVL_m sz, bit U, @@ -4357,6 +4361,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(MachineInstructionHorizontalReduction, IsCorrect) { using namespace ARM; @@ -159,7 +256,6 @@ uint64_t Flags = Desc.TSFlags; if ((Flags & ARMII::DomainMask) != ARMII::DomainMVE) continue; - bool Valid = (Flags & ARMII::HorizontalReduction) != 0; ASSERT_EQ(HorizontalReduction(i), Valid) << MII->getName(i)