TableGen: Explicitly test some cases of self-references and !cast errors

Summary:
These are cases of self-references that exist today in practice. Let's
add tests for them to avoid regressions.

The self-references in PPCInstrInfo.td can be expressed in a simpler
way. Allowing this type of self-reference while at the same time
consistently doing late-resolve even for self-references is problematic
because there are references to fields that aren't in any class. Since
there's no need for this type of self-reference anyway, let's just
remove it.

Change-Id: I914e0b3e1ae7adae33855fac409b536879bc3f62

Reviewers: arsenm, craig.topper, tra, MartinO

Subscribers: nemanjai, wdng, kbarton, llvm-commits

Differential Revision: https://reviews.llvm.org/D44474

llvm-svn: 327848
This commit is contained in:
Nicolai Haehnle 2018-03-19 14:14:10 +00:00
parent 335c70f55e
commit 18f1998a00
5 changed files with 78 additions and 7 deletions

View File

@ -1887,7 +1887,7 @@ void Record::resolveReferences(Resolver &R, const RecordVal *SkipVal) {
PrintFatalError(getLoc(), Twine("Invalid value ") + Type +
"is found when setting '" +
Value.getNameInitAsString() +
" of type '" +
"' of type '" +
Value.getType()->getAsString() +
"' after resolving references: " +
VR->getAsUnquotedString() + "\n");

View File

@ -4695,10 +4695,10 @@ def DWMaskValues {
def DWSwapInByte {
dag Swap1 = (OR8 (AND8 (RLDICL $A, 63, 1), DWMaskValues.Lo1),
(AND8 (RLDICR $A, 1, 62), DWMaskValues.Hi1));
dag Swap2 = (OR8 (AND8 (RLDICL DWSwapInByte.Swap1, 62, 2), DWMaskValues.Lo2),
(AND8 (RLDICR DWSwapInByte.Swap1, 2, 61), DWMaskValues.Hi2));
dag Swap4 = (OR8 (AND8 (RLDICL DWSwapInByte.Swap2, 60, 4), DWMaskValues.Lo4),
(AND8 (RLDICR DWSwapInByte.Swap2, 4, 59), DWMaskValues.Hi4));
dag Swap2 = (OR8 (AND8 (RLDICL Swap1, 62, 2), DWMaskValues.Lo2),
(AND8 (RLDICR Swap1, 2, 61), DWMaskValues.Hi2));
dag Swap4 = (OR8 (AND8 (RLDICL Swap2, 60, 4), DWMaskValues.Lo4),
(AND8 (RLDICR Swap2, 4, 59), DWMaskValues.Hi4));
}
// Intra-byte swap is done, now start inter-byte swap.
@ -4718,7 +4718,7 @@ def DWBytes7656 {
def DWBytes7654 {
dag Word = (RLWIMI DWBytes7656.Word, DWBytes4567.Word, 8, 24, 31);
dag DWord =
(i64 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), DWBytes7654.Word, sub_32));
(i64 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), Word, sub_32));
}
def DWBytes0123 {
@ -4737,7 +4737,7 @@ def DWBytes3212 {
def DWBytes3210 {
dag Word = (RLWIMI DWBytes3212.Word, DWBytes0123.Word, 8, 24, 31);
dag DWord =
(i64 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), DWBytes3210.Word, sub_32));
(i64 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), Word, sub_32));
}
// Now both high word and low word are reversed, next

View File

@ -0,0 +1,14 @@
// RUN: not llvm-tblgen %s 2>&1 | FileCheck %s
// XFAIL: vg_leak
class A;
class B;
def A0 : A;
class C<string name> {
B b = !cast<B>(name);
}
// CHECK: error: Invalid value of type 'A' is found when setting 'b' of type 'B'
def Test : C<"A0">;

View File

@ -0,0 +1,13 @@
// RUN: not llvm-tblgen %s 2>&1 | FileCheck %s
// XFAIL: vg_leak
class A<A x> {
A a = x;
}
// At the time A0 is referenced, A has not yet been established as a superclass.
// This kind of self-reference is discourage, but if you *really* want it, you
// can force it with !cast.
//
// CHECK: Value 'A:x' of type 'A' is incompatible with initializer
def A0 : A<A0>;

View File

@ -0,0 +1,44 @@
// RUN: llvm-tblgen %s | FileCheck %s
// XFAIL: vg_leak
// CHECK: --- Defs ---
// CHECK: def A0 {
// CHECK: dag a = (ops A0);
// CHECK: }
// CHECK: def B0 {
// CHECK: dag a = (ops);
// CHECK: A b = B0;
// CHECK: }
// CHECK: def C0 {
// CHECK: dag q = (ops C0);
// CHECK: }
def ops;
class A<dag d> {
dag a = d;
}
// This type of self-reference is used in various places defining register
// classes.
def A0 : A<(ops A0)>;
class B<string self> {
A b = !cast<A>(self);
}
// A stronger form of this type of self-reference is used at least in the
// SystemZ backend to define a record which is a ComplexPattern and an Operand
// at the same time.
def B0 : A<(ops)>, B<"B0">;
// Casting C0 to C by name here is tricky, because it happens while (or rather:
// before) adding C as a superclass. However, SystemZ uses this pattern.
class C<string self> {
dag q = (ops !cast<C>(self));
}
def C0 : C<"C0">;