[llvm] r327849 - TableGen: Check the dynamic type of !cast<Rec>(string)
Nicolai Haehnle via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 19 07:14:20 PDT 2018
Author: nha
Date: Mon Mar 19 07:14:20 2018
New Revision: 327849
URL: http://llvm.org/viewvc/llvm-project?rev=327849&view=rev
Log:
TableGen: Check the dynamic type of !cast<Rec>(string)
Summary:
The docs already claim that this happens, but so far it hasn't. As a
consequence, existing TableGen files get this wrong a lot, but luckily
the fixes are all reasonably straightforward.
To make this work with all the existing forms of self-references (since
the true type of a record is only built up over time), the lookup of
self-references in !cast is delayed until the final resolving step.
Change-Id: If5923a72a252ba2fbc81a889d59775df0ef31164
Reviewers: arsenm, craig.topper, tra, MartinO
Subscribers: wdng, javed.absar, llvm-commits
Differential Revision: https://reviews.llvm.org/D44475
Modified:
llvm/trunk/include/llvm/TableGen/Record.h
llvm/trunk/include/llvm/Target/TargetSelectionDAG.td
llvm/trunk/lib/TableGen/Record.cpp
llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td
llvm/trunk/lib/Target/AMDGPU/SMInstructions.td
llvm/trunk/lib/Target/SystemZ/SystemZOperands.td
llvm/trunk/test/TableGen/cast-typeerror.td
llvm/trunk/test/TableGen/self-reference.td
Modified: llvm/trunk/include/llvm/TableGen/Record.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/TableGen/Record.h?rev=327849&r1=327848&r2=327849&view=diff
==============================================================================
--- llvm/trunk/include/llvm/TableGen/Record.h (original)
+++ llvm/trunk/include/llvm/TableGen/Record.h Mon Mar 19 07:14:20 2018
@@ -788,7 +788,7 @@ public:
// Fold - If possible, fold this to a simpler init. Return this if not
// possible to fold.
- Init *Fold(Record *CurRec) const;
+ Init *Fold(Record *CurRec, bool IsFinal = false) const;
Init *resolveReferences(Resolver &R) const override;
@@ -1497,6 +1497,9 @@ public:
/// If there are any field references that refer to fields
/// that have been filled in, we can propagate the values now.
+ ///
+ /// This is a final resolve: any error messages, e.g. due to undefined
+ /// !cast references, are generated now.
void resolveReferences();
/// Apply the resolver to the name of the record as well as to the
@@ -1786,6 +1789,7 @@ Init *QualifyName(Record &CurRec, MultiC
/// Init::resolveReferences.
class Resolver {
Record *CurRec;
+ bool IsFinal = false;
public:
explicit Resolver(Record *CurRec) : CurRec(CurRec) {}
@@ -1801,6 +1805,13 @@ public:
// result in a ? (UnsetInit). This behavior is used to represent instruction
// encodings by keeping references to unset variables within a record.
virtual bool keepUnsetBits() const { return false; }
+
+ // Whether this is the final resolve step before adding a record to the
+ // RecordKeeper. Error reporting during resolve and related constant folding
+ // should only happen when this is true.
+ bool isFinal() const { return IsFinal; }
+
+ void setFinal(bool Final) { IsFinal = Final; }
};
/// Resolve arbitrary mappings.
@@ -1861,7 +1872,10 @@ class ShadowResolver final : public Reso
DenseSet<Init *> Shadowed;
public:
- explicit ShadowResolver(Resolver &R) : Resolver(R.getCurrentRecord()), R(R) {}
+ explicit ShadowResolver(Resolver &R)
+ : Resolver(R.getCurrentRecord()), R(R) {
+ setFinal(R.isFinal());
+ }
void addShadow(Init *Key) { Shadowed.insert(Key); }
Modified: llvm/trunk/include/llvm/Target/TargetSelectionDAG.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSelectionDAG.td?rev=327849&r1=327848&r2=327849&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetSelectionDAG.td (original)
+++ llvm/trunk/include/llvm/Target/TargetSelectionDAG.td Mon Mar 19 07:14:20 2018
@@ -1132,27 +1132,27 @@ def setne : PatFrag<(ops node:$lhs, nod
multiclass binary_atomic_op_ord<SDNode atomic_op> {
def #NAME#_monotonic : PatFrag<(ops node:$ptr, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$val)> {
+ (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingMonotonic = 1;
}
def #NAME#_acquire : PatFrag<(ops node:$ptr, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$val)> {
+ (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingAcquire = 1;
}
def #NAME#_release : PatFrag<(ops node:$ptr, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$val)> {
+ (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingRelease = 1;
}
def #NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$val)> {
+ (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingAcquireRelease = 1;
}
def #NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$val)> {
+ (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingSequentiallyConsistent = 1;
}
@@ -1160,27 +1160,27 @@ multiclass binary_atomic_op_ord<SDNode a
multiclass ternary_atomic_op_ord<SDNode atomic_op> {
def #NAME#_monotonic : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$cmp, node:$val)> {
+ (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingMonotonic = 1;
}
def #NAME#_acquire : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$cmp, node:$val)> {
+ (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingAcquire = 1;
}
def #NAME#_release : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$cmp, node:$val)> {
+ (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingRelease = 1;
}
def #NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$cmp, node:$val)> {
+ (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingAcquireRelease = 1;
}
def #NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (!cast<SDNode>(#NAME) node:$ptr, node:$cmp, node:$val)> {
+ (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingSequentiallyConsistent = 1;
}
Modified: llvm/trunk/lib/TableGen/Record.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/Record.cpp?rev=327849&r1=327848&r2=327849&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/Record.cpp (original)
+++ llvm/trunk/lib/TableGen/Record.cpp Mon Mar 19 07:14:20 2018
@@ -194,7 +194,7 @@ void RecordRecTy::Profile(FoldingSetNode
std::string RecordRecTy::getAsString() const {
if (NumClasses == 1)
- return getClasses()[0]->getName();
+ return getClasses()[0]->getNameInitAsString();
std::string Str = "{";
bool First = true;
@@ -202,7 +202,7 @@ std::string RecordRecTy::getAsString() c
if (!First)
Str += ", ";
First = false;
- Str += R->getName();
+ Str += R->getNameInitAsString();
}
Str += "}";
return Str;
@@ -700,7 +700,7 @@ void UnOpInit::Profile(FoldingSetNodeID
ProfileUnOpInit(ID, getOpcode(), getOperand(), getType());
}
-Init *UnOpInit::Fold(Record *CurRec) const {
+Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
switch (getOpcode()) {
case CAST:
if (isa<StringRecTy>(getType())) {
@@ -715,12 +715,34 @@ Init *UnOpInit::Fold(Record *CurRec) con
} else if (isa<RecordRecTy>(getType())) {
if (StringInit *Name = dyn_cast<StringInit>(LHS)) {
assert(CurRec && "NULL pointer");
- if (Record *D = (CurRec->getRecords()).getDef(Name->getValue()))
- return DefInit::get(D);
+ Record *D;
- PrintFatalError(CurRec->getLoc(),
- Twine("Undefined reference to record: '") +
- Name->getValue() + "'\n");
+ // Self-references are allowed, but their resolution is delayed until
+ // the final resolve to ensure that we get the correct type for them.
+ if (Name == CurRec->getNameInit()) {
+ if (!IsFinal)
+ break;
+ D = CurRec;
+ } else {
+ D = CurRec->getRecords().getDef(Name->getValue());
+ if (!D) {
+ if (IsFinal)
+ PrintFatalError(CurRec->getLoc(),
+ Twine("Undefined reference to record: '") +
+ Name->getValue() + "'\n");
+ break;
+ }
+ }
+
+ DefInit *DI = DefInit::get(D);
+ if (!DI->getType()->typeIsA(getType())) {
+ PrintFatalError(CurRec->getLoc(),
+ Twine("Expected type '") +
+ getType()->getAsString() + "', got '" +
+ DI->getType()->getAsString() + "' in: " +
+ getAsString() + "\n");
+ }
+ return DI;
}
}
@@ -762,9 +784,9 @@ Init *UnOpInit::Fold(Record *CurRec) con
Init *UnOpInit::resolveReferences(Resolver &R) const {
Init *lhs = LHS->resolveReferences(R);
- if (LHS != lhs)
+ if (LHS != lhs || (R.isFinal() && getOpcode() == CAST))
return (UnOpInit::get(getOpcode(), lhs, getType()))
- ->Fold(R.getCurrentRecord());
+ ->Fold(R.getCurrentRecord(), R.isFinal());
return const_cast<UnOpInit *>(this);
}
@@ -1904,6 +1926,7 @@ void Record::resolveReferences(Resolver
void Record::resolveReferences() {
RecordResolver R(*this);
+ R.setFinal(true);
resolveReferences(R);
}
Modified: llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td?rev=327849&r1=327848&r2=327849&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td Mon Mar 19 07:14:20 2018
@@ -5931,10 +5931,10 @@ multiclass SIMDThreeScalarHS<bit U, bits
multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
SDPatternOperator OpNode = null_frag> {
def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
- (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
+ (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
asm, []>;
def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
- (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
+ (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
asm, []>;
}
@@ -8789,7 +8789,7 @@ class BaseSIMDLdStSingleTied<bit L, bit
let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
- Operand listtype>
+ DAGOperand listtype>
: BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
(outs listtype:$Vt), (ins GPR64sp:$Rn),
[]> {
@@ -8801,7 +8801,7 @@ class BaseSIMDLdR<bit Q, bit R, bits<3>
}
let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
- string asm, Operand listtype, Operand GPR64pi>
+ string asm, DAGOperand listtype, DAGOperand GPR64pi>
: BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
"$Rn = $wback",
(outs GPR64sp:$wback, listtype:$Vt),
@@ -8859,46 +8859,46 @@ multiclass SIMDLdrAliases<string asm, st
multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
int Offset1, int Offset2, int Offset4, int Offset8> {
def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
- !cast<Operand>("VecList" # Count # "8b")>;
+ !cast<DAGOperand>("VecList" # Count # "8b")>;
def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
- !cast<Operand>("VecList" # Count #"16b")>;
+ !cast<DAGOperand>("VecList" # Count #"16b")>;
def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
- !cast<Operand>("VecList" # Count #"4h")>;
+ !cast<DAGOperand>("VecList" # Count #"4h")>;
def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
- !cast<Operand>("VecList" # Count #"8h")>;
+ !cast<DAGOperand>("VecList" # Count #"8h")>;
def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
- !cast<Operand>("VecList" # Count #"2s")>;
+ !cast<DAGOperand>("VecList" # Count #"2s")>;
def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
- !cast<Operand>("VecList" # Count #"4s")>;
+ !cast<DAGOperand>("VecList" # Count #"4s")>;
def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
- !cast<Operand>("VecList" # Count #"1d")>;
+ !cast<DAGOperand>("VecList" # Count #"1d")>;
def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
- !cast<Operand>("VecList" # Count #"2d")>;
+ !cast<DAGOperand>("VecList" # Count #"2d")>;
def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
- !cast<Operand>("VecList" # Count # "8b"),
- !cast<Operand>("GPR64pi" # Offset1)>;
+ !cast<DAGOperand>("VecList" # Count # "8b"),
+ !cast<DAGOperand>("GPR64pi" # Offset1)>;
def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
- !cast<Operand>("VecList" # Count # "16b"),
- !cast<Operand>("GPR64pi" # Offset1)>;
+ !cast<DAGOperand>("VecList" # Count # "16b"),
+ !cast<DAGOperand>("GPR64pi" # Offset1)>;
def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
- !cast<Operand>("VecList" # Count # "4h"),
- !cast<Operand>("GPR64pi" # Offset2)>;
+ !cast<DAGOperand>("VecList" # Count # "4h"),
+ !cast<DAGOperand>("GPR64pi" # Offset2)>;
def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
- !cast<Operand>("VecList" # Count # "8h"),
- !cast<Operand>("GPR64pi" # Offset2)>;
+ !cast<DAGOperand>("VecList" # Count # "8h"),
+ !cast<DAGOperand>("GPR64pi" # Offset2)>;
def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
- !cast<Operand>("VecList" # Count # "2s"),
- !cast<Operand>("GPR64pi" # Offset4)>;
+ !cast<DAGOperand>("VecList" # Count # "2s"),
+ !cast<DAGOperand>("GPR64pi" # Offset4)>;
def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
- !cast<Operand>("VecList" # Count # "4s"),
- !cast<Operand>("GPR64pi" # Offset4)>;
+ !cast<DAGOperand>("VecList" # Count # "4s"),
+ !cast<DAGOperand>("GPR64pi" # Offset4)>;
def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
- !cast<Operand>("VecList" # Count # "1d"),
- !cast<Operand>("GPR64pi" # Offset8)>;
+ !cast<DAGOperand>("VecList" # Count # "1d"),
+ !cast<DAGOperand>("GPR64pi" # Offset8)>;
def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
- !cast<Operand>("VecList" # Count # "2d"),
- !cast<Operand>("GPR64pi" # Offset8)>;
+ !cast<DAGOperand>("VecList" # Count # "2d"),
+ !cast<DAGOperand>("GPR64pi" # Offset8)>;
defm : SIMDLdrAliases<asm, "8b", Count, Offset1, 64>;
defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>;
@@ -9300,9 +9300,9 @@ multiclass SIMDLdSt4SingleAliases<string
let Predicates = [HasNEON, HasRDM] in {
class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
- RegisterOperand regtype, string asm,
+ RegisterOperand regtype, string asm,
string kind, list<dag> pattern>
- : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind,
+ : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind,
pattern> {
}
multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
@@ -9311,7 +9311,7 @@ multiclass SIMDThreeSameVectorSQRDMLxHTi
[(set (v4i16 V64:$dst),
(Accum (v4i16 V64:$Rd),
(v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
- (v4i16 V64:$Rm)))))]>;
+ (v4i16 V64:$Rm)))))]>;
def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
[(set (v8i16 V128:$dst),
(Accum (v8i16 V128:$Rd),
@@ -9375,28 +9375,28 @@ multiclass SIMDIndexedSQRDMLxHSDTied<bit
let Inst{21} = idx{0};
}
- // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
+ // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
// an intermediate EXTRACT_SUBREG would be untyped.
- // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we
+ // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we
// got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
- (i32 (vector_extract
+ (i32 (vector_extract
(v4i32 (insert_subvector
- (undef),
- (v2i32 (int_aarch64_neon_sqrdmulh
+ (undef),
+ (v2i32 (int_aarch64_neon_sqrdmulh
(v2i32 V64:$Rn),
- (v2i32 (AArch64duplane32
+ (v2i32 (AArch64duplane32
(v4i32 V128:$Rm),
VectorIndexS:$idx)))),
(i32 0))),
(i64 0))))),
(EXTRACT_SUBREG
(v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
- (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
- FPR32Op:$Rd,
- ssub)),
+ (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
+ FPR32Op:$Rd,
+ ssub)),
V64:$Rn,
- V128:$Rm,
+ V128:$Rm,
VectorIndexS:$idx)),
ssub)>;
@@ -9417,26 +9417,26 @@ multiclass SIMDIndexedSQRDMLxHSDTied<bit
// FIXME: it would be nice to use the scalar (v1i32) instruction here, but
// an intermediate EXTRACT_SUBREG would be untyped.
def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
- (i32 (vector_extract
- (v4i32 (int_aarch64_neon_sqrdmulh
+ (i32 (vector_extract
+ (v4i32 (int_aarch64_neon_sqrdmulh
(v4i32 V128:$Rn),
- (v4i32 (AArch64duplane32
+ (v4i32 (AArch64duplane32
(v4i32 V128:$Rm),
VectorIndexS:$idx)))),
(i64 0))))),
(EXTRACT_SUBREG
(v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
- (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
- FPR32Op:$Rd,
- ssub)),
+ (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
+ FPR32Op:$Rd,
+ ssub)),
V128:$Rn,
- V128:$Rm,
+ V128:$Rm,
VectorIndexS:$idx)),
ssub)>;
def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
FPR16Op, FPR16Op, V128_lo,
- VectorIndexH, asm, ".h", "", "", ".h",
+ VectorIndexH, asm, ".h", "", "", ".h",
[]> {
bits<3> idx;
let Inst{11} = idx{2};
@@ -9930,7 +9930,7 @@ class BaseLDOPregister<string op, string
let Predicates = [HasLSE];
}
-multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
+multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
string order> {
let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
def B : BaseLDOPregister<op, order, "b", GPR32>;
@@ -9947,15 +9947,15 @@ multiclass LDOPregister<bits<3> opc, str
let Predicates = [HasLSE] in
multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op,
string size, dag SrcRHS, dag DstRHS> {
- def : Pat<(!cast<SDNode>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS),
+ def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS),
(!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>;
- def : Pat<(!cast<SDNode>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS),
+ def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS),
(!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>;
- def : Pat<(!cast<SDNode>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS),
+ def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS),
(!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>;
- def : Pat<(!cast<SDNode>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS),
+ def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS),
(!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
- def : Pat<(!cast<SDNode>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS),
+ def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS),
(!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
}
@@ -9994,15 +9994,15 @@ multiclass LDOPregister_patterns_mod<str
let Predicates = [HasLSE] in
multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op,
string size, dag OLD, dag NEW> {
- def : Pat<(!cast<SDNode>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW),
+ def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW),
(!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>;
- def : Pat<(!cast<SDNode>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW),
+ def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW),
(!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>;
- def : Pat<(!cast<SDNode>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW),
+ def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW),
(!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>;
- def : Pat<(!cast<SDNode>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW),
+ def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW),
(!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
- def : Pat<(!cast<SDNode>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW),
+ def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW),
(!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
}
Modified: llvm/trunk/lib/Target/AMDGPU/SMInstructions.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/SMInstructions.td?rev=327849&r1=327848&r2=327849&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/SMInstructions.td (original)
+++ llvm/trunk/lib/Target/AMDGPU/SMInstructions.td Mon Mar 19 07:14:20 2018
@@ -500,7 +500,7 @@ let AddedComplexity = SM_LOAD_PATTERN.Ad
class SMRD_Pattern_ci <string Instr, ValueType vt> : GCNPat <
(smrd_load (SMRDImm32 i64:$sbase, i32:$offset)),
- (vt (!cast<SM_Pseudo>(Instr#"_IMM_ci") $sbase, $offset, 0))> {
+ (vt (!cast<InstSI>(Instr#"_IMM_ci") $sbase, $offset, 0))> {
let OtherPredicates = [isCIOnly];
}
Modified: llvm/trunk/lib/Target/SystemZ/SystemZOperands.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZOperands.td?rev=327849&r1=327848&r2=327849&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZOperands.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZOperands.td Mon Mar 19 07:14:20 2018
@@ -115,13 +115,13 @@ class AddressingMode<string seltype, str
class BDMode<string type, string bitsize, string dispsize, string suffix>
: AddressingMode<type, bitsize, dispsize, suffix, "", 2, "BDAddr",
(ops !cast<RegisterOperand>("ADDR"##bitsize),
- !cast<Immediate>("disp"##dispsize##"imm"##bitsize))>;
+ !cast<Operand>("disp"##dispsize##"imm"##bitsize))>;
// An addressing mode with a base, displacement and index.
class BDXMode<string type, string bitsize, string dispsize, string suffix>
: AddressingMode<type, bitsize, dispsize, suffix, "", 3, "BDXAddr",
(ops !cast<RegisterOperand>("ADDR"##bitsize),
- !cast<Immediate>("disp"##dispsize##"imm"##bitsize),
+ !cast<Operand>("disp"##dispsize##"imm"##bitsize),
!cast<RegisterOperand>("ADDR"##bitsize))>;
// A BDMode paired with an immediate length operand of LENSIZE bits.
@@ -130,21 +130,21 @@ class BDLMode<string type, string bitsiz
: AddressingMode<type, bitsize, dispsize, suffix, "Len"##lensize, 3,
"BDLAddr",
(ops !cast<RegisterOperand>("ADDR"##bitsize),
- !cast<Immediate>("disp"##dispsize##"imm"##bitsize),
- !cast<Immediate>("imm"##bitsize))>;
+ !cast<Operand>("disp"##dispsize##"imm"##bitsize),
+ !cast<Operand>("imm"##bitsize))>;
// A BDMode paired with a register length operand.
class BDRMode<string type, string bitsize, string dispsize, string suffix>
: AddressingMode<type, bitsize, dispsize, suffix, "", 3, "BDRAddr",
(ops !cast<RegisterOperand>("ADDR"##bitsize),
- !cast<Immediate>("disp"##dispsize##"imm"##bitsize),
+ !cast<Operand>("disp"##dispsize##"imm"##bitsize),
!cast<RegisterOperand>("GR"##bitsize))>;
// An addressing mode with a base, displacement and a vector index.
class BDVMode<string bitsize, string dispsize>
: AddressOperand<bitsize, dispsize, "", "BDVAddr",
(ops !cast<RegisterOperand>("ADDR"##bitsize),
- !cast<Immediate>("disp"##dispsize##"imm"##bitsize),
+ !cast<Operand>("disp"##dispsize##"imm"##bitsize),
!cast<RegisterOperand>("VR128"))>;
//===----------------------------------------------------------------------===//
Modified: llvm/trunk/test/TableGen/cast-typeerror.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/cast-typeerror.td?rev=327849&r1=327848&r2=327849&view=diff
==============================================================================
--- llvm/trunk/test/TableGen/cast-typeerror.td (original)
+++ llvm/trunk/test/TableGen/cast-typeerror.td Mon Mar 19 07:14:20 2018
@@ -10,5 +10,5 @@ class C<string name> {
B b = !cast<B>(name);
}
-// CHECK: error: Invalid value of type 'A' is found when setting 'b' of type 'B'
+// CHECK: error: Expected type 'B', got 'A' in: !cast<B>("A0")
def Test : C<"A0">;
Modified: llvm/trunk/test/TableGen/self-reference.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/self-reference.td?rev=327849&r1=327848&r2=327849&view=diff
==============================================================================
--- llvm/trunk/test/TableGen/self-reference.td (original)
+++ llvm/trunk/test/TableGen/self-reference.td Mon Mar 19 07:14:20 2018
@@ -16,6 +16,14 @@
// CHECK: dag q = (ops C0);
// CHECK: }
+// CHECK: def D0 {
+// CHECK: D d = D0;
+// CHECK: }
+
+// CHECK: def E0 {
+// CHECK: E e = E0;
+// CHECK: }
+
def ops;
class A<dag d> {
@@ -42,3 +50,26 @@ class C<string self> {
}
def C0 : C<"C0">;
+
+// Explore some unused corner cases.
+//
+// A self-reference within a class may seem icky, but it unavoidably falls out
+// orthogonally of having forward class declarations and late resolve of self
+// references.
+class D<string self> {
+ D d = !cast<D>(self);
+}
+
+def D0 : D<"D0">;
+
+class E<E x> {
+ E e = x;
+}
+
+// Putting the !cast directly in the def should work as well: we shouldn't
+// depend on implementation details of when exactly the record is looked up.
+//
+// Note the difference between !cast<E>("E0") and plain E0: the latter wouldn't
+// work here because E0 does not yet have E as a superclass while the template
+// arguments are being parsed.
+def E0 : E<!cast<E>("E0")>;
More information about the llvm-commits
mailing list