Index: llvm/trunk/include/llvm/Target/TargetSchedule.td =================================================================== --- llvm/trunk/include/llvm/Target/TargetSchedule.td +++ llvm/trunk/include/llvm/Target/TargetSchedule.td @@ -373,6 +373,10 @@ SchedMachineModel SchedModel = ?; code Predicate = pred; } + +// Define a predicate to be typically used as the default case in a +// SchedVariant. It the SchedVariant does not use any other predicate based on +// MCSchedPredicate, this is the default scheduling case used by llvm-mca. def NoSchedPred : MCSchedPredicate; // Associate a predicate with a list of SchedReadWrites. By default, Index: llvm/trunk/test/tools/llvm-mca/AArch64/CortexA57/shifted-register.s =================================================================== --- llvm/trunk/test/tools/llvm-mca/AArch64/CortexA57/shifted-register.s +++ llvm/trunk/test/tools/llvm-mca/AArch64/CortexA57/shifted-register.s @@ -1,7 +1,25 @@ -# RUN: not llvm-mca -march=aarch64 -mcpu=cortex-a57 -resource-pressure=false < %s 2> %t -# RUN: FileCheck --input-file %t %s +# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py +# RUN: llvm-mca -march=aarch64 -mcpu=cortex-a57 -resource-pressure=false < %s | FileCheck %s add x0, x1, x2, lsl #3 -# CHECK: error -# CHECK-SAME: unable to resolve scheduling class for write variant. +# CHECK: Iterations: 100 +# CHECK-NEXT: Instructions: 100 +# CHECK-NEXT: Total Cycles: 53 +# CHECK-NEXT: Total uOps: 100 + +# CHECK: Dispatch Width: 3 +# CHECK-NEXT: uOps Per Cycle: 1.89 +# CHECK-NEXT: IPC: 1.89 +# CHECK-NEXT: Block RThroughput: 0.5 + +# CHECK: Instruction Info: +# CHECK-NEXT: [1]: #uOps +# CHECK-NEXT: [2]: Latency +# CHECK-NEXT: [3]: RThroughput +# CHECK-NEXT: [4]: MayLoad +# CHECK-NEXT: [5]: MayStore +# CHECK-NEXT: [6]: HasSideEffects (U) + +# CHECK: [1] [2] [3] [4] [5] [6] Instructions: +# CHECK-NEXT: 1 1 0.50 add x0, x1, x2, lsl #3 Index: llvm/trunk/test/tools/llvm-mca/AArch64/Cyclone/register-offset.s =================================================================== --- llvm/trunk/test/tools/llvm-mca/AArch64/Cyclone/register-offset.s +++ llvm/trunk/test/tools/llvm-mca/AArch64/Cyclone/register-offset.s @@ -1,9 +1,29 @@ -# RUN: not llvm-mca -march=aarch64 -mcpu=cyclone -resource-pressure=false < %s 2> %t -# RUN: FileCheck --input-file %t %s +# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py +# RUN: llvm-mca -march=aarch64 -mcpu=cyclone -resource-pressure=false < %s | FileCheck %s ldr x7, [x1, #8] ldr x6, [x1, x2] ldr x4, [x1, x2, sxtx] -# CHECK: error -# CHECK-SAME: unable to resolve scheduling class for write variant. +# CHECK: Iterations: 100 +# CHECK-NEXT: Instructions: 300 +# CHECK-NEXT: Total Cycles: 156 +# CHECK-NEXT: Total uOps: 300 + +# CHECK: Dispatch Width: 6 +# CHECK-NEXT: uOps Per Cycle: 1.92 +# CHECK-NEXT: IPC: 1.92 +# CHECK-NEXT: Block RThroughput: 1.5 + +# CHECK: Instruction Info: +# CHECK-NEXT: [1]: #uOps +# CHECK-NEXT: [2]: Latency +# CHECK-NEXT: [3]: RThroughput +# CHECK-NEXT: [4]: MayLoad +# CHECK-NEXT: [5]: MayStore +# CHECK-NEXT: [6]: HasSideEffects (U) + +# CHECK: [1] [2] [3] [4] [5] [6] Instructions: +# CHECK-NEXT: 1 4 0.50 * ldr x7, [x1, #8] +# CHECK-NEXT: 1 4 0.50 * ldr x6, [x1, x2] +# CHECK-NEXT: 1 4 0.50 * ldr x4, [x1, x2, sxtx] Index: llvm/trunk/test/tools/llvm-mca/ARM/unsupported-write-variant.s =================================================================== --- llvm/trunk/test/tools/llvm-mca/ARM/unsupported-write-variant.s +++ llvm/trunk/test/tools/llvm-mca/ARM/unsupported-write-variant.s @@ -1,4 +1,6 @@ # RUN: not llvm-mca -march=arm -mcpu=swift -all-views=false 2>&1 < %s | FileCheck %s +# D54648 results in this test to become valid. +# XFAIL: * add r3, r1, r12, lsl #2 Index: llvm/trunk/utils/TableGen/SubtargetEmitter.cpp =================================================================== --- llvm/trunk/utils/TableGen/SubtargetEmitter.cpp +++ llvm/trunk/utils/TableGen/SubtargetEmitter.cpp @@ -1504,9 +1504,9 @@ continue; if (OnlyExpandMCInstPredicates) { - // Ignore this variant scheduling class if transitions don't uses any + // Ignore this variant scheduling class no transitions use any meaningful // MCSchedPredicate definitions. - if (!all_of(SC.Transitions, [](const CodeGenSchedTransition &T) { + if (!any_of(SC.Transitions, [](const CodeGenSchedTransition &T) { return hasMCSchedPredicates(T); })) continue; @@ -1560,6 +1560,7 @@ PE.setExpandForMC(OnlyExpandMCInstPredicates); for (unsigned PI : ProcIndices) { OS << " "; + // Emit a guard on the processor ID. if (PI != 0) { OS << (OnlyExpandMCInstPredicates @@ -1573,11 +1574,23 @@ for (const CodeGenSchedTransition &T : SC.Transitions) { if (PI != 0 && !count(T.ProcIndices, PI)) continue; + + // Emit only transitions based on MCSchedPredicate, if it's the case. + // At least the transition specified by NoSchedPred is emitted, + // which becomes the default transition for those variants otherwise + // not based on MCSchedPredicate. + // FIXME: preferably, llvm-mca should instead assume a reasonable + // default when a variant transition is not based on MCSchedPredicate + // for a given processor. + if (OnlyExpandMCInstPredicates && !hasMCSchedPredicates(T)) + continue; + PE.setIndentLevel(3); emitPredicates(T, SchedModels.getSchedClass(T.ToClassIdx), PE, OS); } OS << " }\n"; + if (PI == 0) break; }