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 horizontalReduction = 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} = horizontalReduction; 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 @@ -556,6 +556,7 @@ let Inst{5} = Qm{3}; let Inst{3-1} = Qm{2-0}; let Inst{0} = 0b1; + let horizontalReduction = 1; } multiclass MVE_VABAV_m { @@ -605,6 +606,7 @@ let Inst{5} = A; let Inst{3-1} = Qm{2-0}; let Inst{0} = 0b0; + let horizontalReduction = 1; } def ARMVADDVs : SDNode<"ARMISD::VADDVs", SDTVecReduce>; @@ -678,6 +680,7 @@ let Inst{5} = A; let Inst{3-1} = Qm{2-0}; let Inst{0} = 0b0; + let horizontalReduction = 1; } def SDTVecReduceL : SDTypeProfile<2, 1, [ // VADDLV @@ -749,6 +752,7 @@ let Inst{6-5} = 0b00; let Inst{3-1} = Qm{2-0}; let Inst{0} = 0b0; + let horizontalReduction = 1; let Predicates = [HasMVEFloat]; } @@ -808,6 +812,7 @@ let Inst{6-5} = 0b00; let Inst{3-1} = Qm{2-0}; let Inst{0} = 0b0; + let horizontalReduction = 1; } multiclass MVE_VMINMAXV_p( + 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::HorizontalReduction) != 0; + ASSERT_EQ(HorizontalReduction(i), Valid) + << MII->getName(i) + << ": mismatched expectation for tail-predicated safety\n"; + } +} + TEST(MachineInstructionRetainsPreviousHalfElement, IsCorrect) { using namespace ARM;