mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
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:
parent
663e769575
commit
74a4d54f41
@ -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");
|
||||
|
@ -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
|
||||
|
14
test/TableGen/cast-typeerror.td
Normal file
14
test/TableGen/cast-typeerror.td
Normal 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">;
|
13
test/TableGen/self-reference-typeerror.td
Normal file
13
test/TableGen/self-reference-typeerror.td
Normal 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>;
|
44
test/TableGen/self-reference.td
Normal file
44
test/TableGen/self-reference.td
Normal 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">;
|
Loading…
x
Reference in New Issue
Block a user