blob: 833224074ac34651b128c7181250af0cccb79c6a [file] [log] [blame] [edit]
// RUN: rm -rf %t && split-file %s %t
// RUN: not llvm-tblgen --gen-asm-matcher -I %p/../../include -I %t -I %S \
// RUN: %t/inst-alias-bad-reg.td -o /dev/null 2>&1 | FileCheck %t/inst-alias-bad-reg.td --implicit-check-not="error:"
// RUN: not llvm-tblgen --gen-asm-matcher -I %p/../../include -I %t -I %S \
// RUN: %t/inst-alias-static-predicates.td -o /dev/null 2>&1 | FileCheck %t/inst-alias-static-predicates.td --implicit-check-not="error:"
// RUN: not llvm-tblgen --gen-compress-inst-emitter -I %p/../../include -I %t -I %S \
// RUN: %t/compress-regclass-by-hwmode.td -o /dev/null 2>&1 | FileCheck %t/compress-regclass-by-hwmode.td --implicit-check-not="error:"
// RUN: not llvm-tblgen --gen-compress-inst-emitter -I %p/../../include -I %t -I %S \
// RUN: %t/compress-regclass-by-hwmode-2.td -o /dev/null 2>&1 | FileCheck %t/compress-regclass-by-hwmode-2.td --implicit-check-not="error:"
// RUN: not llvm-tblgen --gen-dag-isel -I %p/../../include -I %t -I %S \
// RUN: %t/vt-by-hwmode-missing.td -o /dev/null 2>&1 | FileCheck %t/vt-by-hwmode-missing.td --implicit-check-not="error:"
// RUN: not llvm-tblgen --gen-dag-isel -I %p/../../include -I %t -I %S \
// RUN: %t/multiple-entries-for-same-mode.td -o /dev/null 2>&1 | FileCheck %t/multiple-entries-for-same-mode.td --implicit-check-not="error:"
//--- Common.td
include "Common/RegClassByHwModeCommon.td"
def IsPtr64 : Predicate<"Subtarget->isPtr64()">;
def IsPtr32 : Predicate<"!Subtarget->isPtr64()">;
defvar Ptr32 = DefaultMode;
def Ptr64 : HwMode<[IsPtr64]>;
def PtrRC : RegClassByHwMode<[Ptr32, Ptr64], [XRegs, YRegs]>;
def PTR_MOV : TestInstruction {
let OutOperandList = (outs PtrRC:$dst);
let InOperandList = (ins PtrRC:$src);
let AsmString = "ptr_mov $dst, $src";
let opcode = 0;
}
//--- inst-alias-bad-reg.td
include "Common.td"
/// This should fail since X0 is not necessarily part of PtrRC.
def BAD_REG : InstAlias<"ptr_zero $rd", (PTR_MOV PtrRC:$dst, X0)>;
// CHECK: [[#@LINE-1]]:5: error: cannot resolve HwMode for PtrRC
// CHECK: Common.td:7:5: note: PtrRC defined here
def MyTargetISA : InstrInfo;
def MyTarget : Target { let InstructionSet = MyTargetISA; }
//--- inst-alias-static-predicates.td
include "Common.td"
/// In theory we could allow the following code since the predicates statically
/// resolve to the correct register class, but since this is non-trivial, check
// that we get a sensible-ish error instead.
let Predicates = [IsPtr32] in
def MOV_X0 : InstAlias<"mov_x0 $dst", (PTR_MOV PtrRC:$dst, X0)>;
// CHECK: [[#@LINE-1]]:5: error: cannot resolve HwMode for PtrRC
// CHECK: Common.td:7:5: note: PtrRC defined here
let Predicates = [IsPtr64] in
def MOV_Y0 : InstAlias<"mov_y0 $dst", (PTR_MOV PtrRC:$dst, Y0)>;
def MyTargetISA : InstrInfo;
def MyTarget : Target { let InstructionSet = MyTargetISA; }
//--- compress-regclass-by-hwmode.td
include "Common.td"
def PTR_ZERO_SMALL : TestInstruction {
let OutOperandList = (outs PtrRC:$dst);
let InOperandList = (ins);
let AsmString = "ptr_zero $dst";
let opcode = 1;
let Size = 1;
}
/// This should fail since X0 is not necessarily part of PtrRC.
def : CompressPat<(PTR_MOV PtrRC:$dst, X0),
(PTR_ZERO_SMALL PtrRC:$dst)>;
// CHECK: [[#@LINE-2]]:1: error: Error in Dag '(PTR_MOV PtrRC:$dst, X0)': Register 'X0' is not in register class 'PtrRC'
def MyTargetISA : InstrInfo;
def MyTarget : Target { let InstructionSet = MyTargetISA; }
//--- compress-regclass-by-hwmode-2.td
include "Common.td"
def X_MOV_BIG : TestInstruction {
let OutOperandList = (outs XRegs:$dst);
let InOperandList = (ins XRegs:$src);
let AsmString = "x_mov $dst, $src";
let opcode = 1;
let Size = 4;
}
/// This should fail since PtrRC is not necessarily part of XRegs.
/// In theory, this could be resolved depending on the Predicates but
/// for not we should just always emit an error.
let Predicates = [IsPtr32] in
def : CompressPat<(X_MOV_BIG XRegs:$dst, XRegs:$src),
(PTR_MOV PtrRC:$dst, PtrRC:$src)>;
// CHECK: [[#@LINE-2]]:1: error: Type mismatch between Input and Output Dag operand 'dst'
def MyTargetISA : InstrInfo;
def MyTarget : Target { let InstructionSet = MyTargetISA; }
//--- vt-by-hwmode-missing.td
include "Common.td"
/// This should fail since we are missing a DefaultMode entry for the
/// ValueTypeByHwMode and can't resolve it for the Ptr32 (default) case.
def BadVT : ValueTypeByHwMode<[Ptr64], [i64]>;
def BadVTRegClass : RegisterClass<"MyTarget", [i64, BadVT], 64, (add Y0, Y1)>;
/// NOTE: this error only occurs for RegClassByHwMode, normal RegisterClass
/// logic for VT resolution takes a different code path and does not error.
def TEST_OK : TestInstruction {
let OutOperandList = (outs BadVTRegClass:$dst);
let InOperandList = (ins BadVTRegClass:$src1, BadVTRegClass:$src2);
let AsmString = "test $dst, $src1, $src2";
let Pattern = [(set BadVTRegClass:$dst, (add BadVTRegClass:$src1, BadVTRegClass:$src2))];
}
/// Once we use RegClassByHwMode, we get an error about missing modes:
def BadPtrRC : RegClassByHwMode<[Ptr32, Ptr64], [BadVTRegClass, YRegs]>;
// CHECK: vt-by-hwmode-missing.td:[[#@LINE-1]]:5: error: Could not resolve VT for Mode DefaultMode
// CHECK: vt-by-hwmode-missing.td:4:5: note: ValueTypeByHwMode BadVT defined here
// CHECK: vt-by-hwmode-missing.td:[[#@LINE+1]]:5: note: pattern instantiated here
def TEST : TestInstruction {
let OutOperandList = (outs BadPtrRC:$dst);
let InOperandList = (ins BadPtrRC:$src1, BadPtrRC:$src2);
let AsmString = "test $dst, $src1, $src2";
let opcode = 0;
let Pattern = [(set BadPtrRC:$dst, (add BadPtrRC:$src1, BadPtrRC:$src2))];
}
def MyTargetISA : InstrInfo;
def MyTarget : Target { let InstructionSet = MyTargetISA; }
//--- multiple-entries-for-same-mode.td
include "Common.td"
/// We should get an error if the same mode is listed more than once
defvar Ptr64Alias = Ptr64;
def BadRegClass : RegClassByHwMode<[Ptr32, Ptr64, Ptr64Alias], [XRegs, YRegs, YRegs]>;
// CHECK: [[#@LINE-1]]:5: error: duplicate RegisterClass entry for HwMode Ptr64: YRegs
// Need at least one CompressPat use of the bad reg class to trigger the error:
def USE_BAD_REG_CLASS : TestInstruction {
let OutOperandList = (outs BadRegClass:$dst);
let InOperandList = (ins BadRegClass:$src1, BadRegClass:$src2);
let AsmString = "bad $dst";
let Pattern = [(set BadRegClass:$dst, (add BadRegClass:$src1, BadRegClass:$src2))];
}
def MyTargetISA : InstrInfo;
def MyTarget : Target {
let InstructionSet = MyTargetISA;
}