// RUN: llvm-tblgen -gen-subtarget -I %p/../../include %s -o - | FileCheck %s include "llvm/Target/Target.td" def TestTargetInstrInfo : InstrInfo; def TestTarget : Target { let InstructionSet = TestTargetInstrInfo; } def FeatureFoo : SubtargetFeature<"foo", "HasFoo", "true", "enable foo">; def FeatureBar : SubtargetFeature<"bar", "HasBar", "true", "enable bar">; def ResX0 : ProcResource<1>; let OutOperandList = (outs), InOperandList = (ins) in def Inst_A : Instruction; def SchedModel_A: SchedMachineModel { let CompleteModel = false; } let SchedModel = SchedModel_A in { def SchedWriteResA : SchedWriteRes<[ResX0]> { let Latency = 2; } def SchedWriteResB : SchedWriteRes<[ResX0]> { let Latency = 4; } def SchedWriteResC : SchedWriteRes<[ResX0]> { let Latency = 8; } def SchedWriteResD : SchedWriteRes<[ResX0]> { let Latency = 16; } def SchedWriteResE : SchedWriteRes<[ResX0]> { let Latency = 32; } // Check SchedPredicate with subtarget feature. def FeatureFooPred : FeatureSchedPredicate; def FeatureBarPred : FeatureSchedPredicate; // Check SchedPredicate combiners. // First, check MC-only combiners. def CombinedAllOfPred: AllOfSchedPreds<[FeatureFooPred, MCSchedPredicate>]>; // Then, check nested combiner that can be used with MCInst and MachineInstr. def CombinedAnyOfPred: AnyOfSchedPreds<[CombinedAllOfPred, NoneOfSchedPreds<[FeatureBarPred, SchedPredicate<[{/*hello=*/false}]>]>]>; // Check if the inverse predicate correctly wraps (or not wrap) its sub-predicates. def CombinedNotPred : NotSchedPred>, NotSchedPred]>>; def Variant : SchedWriteVariant<[ SchedVar, SchedVar, SchedVar, SchedVar, SchedVar, ]>; def : InstRW<[Variant], (instrs Inst_A)>; } def ProcessorA: ProcessorModel<"ProcessorA", SchedModel_A, []>; // CHECK: unsigned resolveVariantSchedClassImpl(unsigned SchedClass, // CHECK-NEXT: const MCInst *MI, const MCInstrInfo *MCII, const MCSubtargetInfo &STI, unsigned CPUID) // CHECK: case {{.*}}: // Inst_A // CHECK-NEXT: if (CPUID == {{.*}}) { // SchedModel_A // CHECK-NEXT: if (STI.hasFeature(TestTarget::FeatureFoo)) // CHECK-NEXT: return {{.*}}; // SchedWriteResA // CHECK-NEXT: if (STI.hasFeature(TestTarget::FeatureFoo) && MI->getOperand(1).getImm() == 0) // CHECK-NEXT: return {{.*}}; // SchedWriteResC // CHECK-NEXT: if (!(MI->getOperand(3).getImm() == 0 && !STI.hasFeature(TestTarget::FeatureFoo))) // CHECK-NEXT: return {{.*}}; // SchedWriteResE // CHECK-NEXT: return {{.*}}; // SchedWriteResB // CHECK: unsigned resolveVariantSchedClass(unsigned SchedClass, // CHECK-NEXT: const MCInst *MI, const MCInstrInfo *MCII, // CHECK-NEXT: unsigned CPUID) const final { // CHECK-NEXT: return TestTarget_MC::resolveVariantSchedClassImpl(SchedClass, MI, MCII, *this, CPUID); // CHECK-NEXT: } // CHECK: unsigned TestTargetGenSubtargetInfo // CHECK-NEXT: ::resolveSchedClass(unsigned SchedClass, const MachineInstr *MI, const TargetSchedModel *SchedModel) const { // CHECK-NEXT: switch (SchedClass) { // CHECK-NEXT: case {{.*}}: // Inst_A // CHECK-NEXT: if (SchedModel->getProcessorID() == {{.*}}) { // SchedModel_A // CHECK-NEXT: if (this->hasFeature(TestTarget::FeatureFoo)) // CHECK-NEXT: return {{.*}}; // SchedWriteResA // CHECK-NEXT: if (this->hasFeature(TestTarget::FeatureFoo) && MI->getOperand(1).getImm() == 0) // CHECK-NEXT: return {{.*}}; // SchedWriteResC // CHECK-NEXT: if ((this->hasFeature(TestTarget::FeatureFoo) && MI->getOperand(1).getImm() == 0) || !(this->hasFeature(TestTarget::FeatureBar) || (/*hello=*/false))) // CHECK-NEXT: return {{.*}}; // SchedWriteResD // CHECK-NEXT: if (!(MI->getOperand(3).getImm() == 0 && !this->hasFeature(TestTarget::FeatureFoo))) // CHECK-NEXT: return {{.*}}; // SchedWriteResE // CHECK-NEXT: return {{.*}}; // SchedWriteResB