diff --git a/llvm/test/TableGen/bare-minimum-psets.td b/llvm/test/TableGen/bare-minimum-psets.td new file mode 100644 --- /dev/null +++ b/llvm/test/TableGen/bare-minimum-psets.td @@ -0,0 +1,67 @@ +// RUN: llvm-tblgen -gen-register-info -I %p/../../include -I %p/Common %s | FileCheck %s + +// Test to check the bare minimum pressure sets. +// At least one register pressure set is required for the target. +// Allowed the pset only for D_32 regclass and ignored it for all +// other classes including the tuples. +include "llvm/Target/Target.td" + +class MyClass types, dag registers> + : RegisterClass<"MyTarget", types, size, registers> { + let Size = size; +} + +def sub0 : SubRegIndex<32>; +def sub1 : SubRegIndex<32, 32>; + +let Namespace = "MyTarget" in { + def D : Register<"d">; + foreach Index = 0-7 in { + def S#Index : Register <"s"#Index>; + } +} + +// Should generate psets for D_32 +def D_32 : MyClass<32, [i32], (add D)>; + +let GeneratePressureSet = 0 in { + def S_32 : MyClass<32, [i32], (sequence "S%u", 0, 7)>; + def SD_32 : MyClass<32, [i32], (add S_32, D_32)>; +} + +def S_64 : RegisterTuples<[sub0, sub1], + [(decimate (shl S_32, 0), 1), + (decimate (shl S_32, 1), 1) + ]>; + +def SReg_64 : MyClass<64, [i64], (add S_64)> { + let GeneratePressureSet = 0; +} + +def MyTarget : Target; + +// CHECK-LABEL: // Register pressure sets enum. +// CHECK-NEXT: namespace MyTarget { +// CHECK-NEXT: enum RegisterPressureSets { +// CHECK-NEXT: D_32 = 0, +// CHECK-NEXT: }; +// NAMESPACE-NEXT: } // end namespace TestNamespace + +// CHECK-LABEL: getRegPressureSetName(unsigned Idx) const { +// CHECK-NEXT: static const char *const PressureNameTable[] = { +// CHECK-NEXT: "D_32", +// CHECK-NEXT: }; +// CHECK-NEXT: return PressureNameTable[Idx]; +// CHECK-NEXT: } + +// CHECK: unsigned MyTargetGenRegisterInfo:: +// CHECK-NEXT: getRegPressureSetLimit(const MachineFunction &MF, unsigned Idx) const { +// CHECK-NEXT: static const uint8_t PressureLimitTable[] = { +// CHECK-NEXT: {{[0-9]+}}, // 0: D_32 +// CHECK-NEXT: }; +// CHECK-NEXT: return PressureLimitTable[Idx]; +// CHECK-NEXT:} + +// CHECK: static const int RCSetsTable[] = { +// CHECK-NEXT: /* 0 */ 0, -1, +// CHECK-NEXT: }; diff --git a/llvm/test/TableGen/empty-psets.td b/llvm/test/TableGen/empty-psets.td new file mode 100644 --- /dev/null +++ b/llvm/test/TableGen/empty-psets.td @@ -0,0 +1,15 @@ +// RUN: not llvm-tblgen -gen-register-info -I %p/../../include -I %p/Common %s 2>&1 | FileCheck %s + +// Negative test to check empty Psets for a target. + +include "llvm/Target/Target.td" + +def R : Register<"r">; + +def R_32 : RegisterClass<"MyTarget", [i32], 0, (add R)> { + let GeneratePressureSet = 0; +} + +def MyTarget : Target; + +// CHECK: error: RegUnitSets cannot be empty! diff --git a/llvm/utils/TableGen/CodeGenRegisters.cpp b/llvm/utils/TableGen/CodeGenRegisters.cpp --- a/llvm/utils/TableGen/CodeGenRegisters.cpp +++ b/llvm/utils/TableGen/CodeGenRegisters.cpp @@ -1915,6 +1915,9 @@ RegUnitSets.pop_back(); } + if (RegUnitSets.empty()) + PrintFatalError("RegUnitSets cannot be empty!"); + LLVM_DEBUG(dbgs() << "\nBefore pruning:\n"; for (unsigned USIdx = 0, USEnd = RegUnitSets.size(); USIdx < USEnd; ++USIdx) { @@ -2025,7 +2028,8 @@ } } LLVM_DEBUG(dbgs() << "\n"); - assert(!RegClassUnitSets[RCIdx].empty() && "missing unit set for regclass"); + assert((!RegClassUnitSets[RCIdx].empty() || !RC.GeneratePressureSet) && + "missing unit set for regclass"); } // For each register unit, ensure that we have the list of UnitSets that