-
Notifications
You must be signed in to change notification settings - Fork 11.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[LLVM][TableGen] Support type casts of nodes with multiple results
Currently, type casts can only be used to pattern match for intrinsics with a single overloaded return value. For instance: ``` def int_foo : Intrinsic<[llvm_anyint_ty], []>; def : Pat<(i32 (int_foo)), ...>; ``` This patch extends type casts to support matching intrinsics with multiple overloaded return values. As an example, the following defines a pattern that matches only if the overloaded intrinsic call returns an `i16` for the first result and an `i32` for the second result: ``` def int_bar : Intrinsic<[llvm_anyint_ty, llvm_anyint_ty], []>; def : Pat<([i16, i32] (int_bar)), ...>; ```
- Loading branch information
1 parent
9830156
commit d6cc3d9
Showing
4 changed files
with
116 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// RUN: not llvm-tblgen -gen-dag-isel -I %p/../../include -I %p/Common -DERROR1 %s 2>&1 | FileCheck --check-prefix=ERROR1 %s | ||
// RUN: not llvm-tblgen -gen-dag-isel -I %p/../../include -I %p/Common -DERROR2 %s 2>&1 | FileCheck --check-prefix=ERROR2 %s | ||
// RUN: not llvm-tblgen -gen-dag-isel -I %p/../../include -I %p/Common -DERROR3 %s 2>&1 | FileCheck --check-prefix=ERROR3 %s | ||
// RUN: not llvm-tblgen -gen-dag-isel -I %p/../../include -I %p/Common -DERROR4 %s 2>&1 | FileCheck --check-prefix=ERROR4 %s | ||
|
||
include "llvm/Target/Target.td" | ||
include "GlobalISelEmitterCommon.td" | ||
|
||
def int_foo : Intrinsic<[llvm_anyint_ty, llvm_anyint_ty], [llvm_i32_ty]>; | ||
def int_bar : Intrinsic<[], []>; | ||
|
||
def INSTR_FOO : Instruction { | ||
let OutOperandList = (outs GPR32:$a, GPR32:$b); | ||
let InOperandList = (ins GPR32:$c); | ||
} | ||
def INSTR_BAR : Instruction { | ||
let OutOperandList = (outs); | ||
let InOperandList = (ins); | ||
} | ||
|
||
#ifdef ERROR1 | ||
// ERROR1: [[@LINE+1]]:1: error: {{.*}} Invalid number of type casts! | ||
def : Pat<([i32, i32, i32] (int_foo (i32 GPR32:$a))), ([i32, i32, i32] (INSTR_FOO $a))>; | ||
#endif | ||
|
||
#ifdef ERROR2 | ||
// ERROR2: [[@LINE+1]]:1: error: {{.*}} Invalid number of type casts! | ||
def : Pat<([]<ValueType> (int_bar)), ([]<ValueType> (INSTR_BAR))>; | ||
#endif | ||
|
||
#ifdef ERROR3 | ||
// ERROR3: [[@LINE+1]]:1: error: {{.*}} Type cast only takes one operand! | ||
def : Pat<([i32, i32] (int_foo), (int_foo)), ([i32, i32] (INSTR_FOO))>; | ||
#endif | ||
|
||
#ifdef ERROR4 | ||
// ERROR4: [[@LINE+1]]:1: error: {{.*}} Type cast should not have a name! | ||
def : Pat<([i32, i32] ([i32, i32] (int_foo)):$name), ([i32, i32] (INSTR_FOO))>; | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// RUN: llvm-tblgen -gen-dag-isel -I %p/../../include -I %p/Common %s | FileCheck -check-prefix=SDAG %s | ||
// RUN: llvm-tblgen -gen-global-isel -optimize-match-table=false -warn-on-skipped-patterns -I %p/../../include -I %p/Common %s -o - < %s | FileCheck -check-prefix=GISEL %s | ||
|
||
include "llvm/Target/Target.td" | ||
include "GlobalISelEmitterCommon.td" | ||
|
||
def REG : Register<"REG">; | ||
def GPR : RegisterClass<"MyTarget", [i16, i32], 32, (add REG)>; | ||
|
||
def int_foo : Intrinsic<[llvm_anyint_ty, llvm_anyint_ty], []>; | ||
|
||
def INSTR_FOO_I16_I32 : Instruction { | ||
let OutOperandList = (outs GPR:$a, GPR:$b); | ||
let InOperandList = (ins); | ||
} | ||
def INSTR_FOO_I32_I16 : Instruction { | ||
let OutOperandList = (outs GPR:$a, GPR:$b); | ||
let InOperandList = (ins); | ||
} | ||
|
||
// SDAG: 7*/ OPC_SwitchType {{.*}}, 10, /*MVT::i16*/6 | ||
// SDAG: OPC_CheckTypeRes, 1, /*MVT::i32*/7 | ||
// SDAG: OPC_MorphNodeTo2Chain, TARGET_VAL(::INSTR_FOO_I16_I32) | ||
|
||
// GISEL: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s16 | ||
// GISEL: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s32 | ||
// GISEL: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(::INSTR_FOO_I16_I32) | ||
def : Pat<([i16, i32] (int_foo)), ([i16, i32] (INSTR_FOO_I16_I32))>; | ||
|
||
// SDAG: 20*/ /*SwitchType*/ {{.*}} /*MVT::i32*/7 | ||
// SDAG: OPC_CheckTypeRes, 1, /*MVT::i16*/6 | ||
// SDAG: OPC_MorphNodeTo2Chain, TARGET_VAL(::INSTR_FOO_I32_I16) | ||
|
||
// GISEL: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32 | ||
// GISEL: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s16 | ||
// GISEL: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(::INSTR_FOO_I32_I16) | ||
def : Pat<([i32, i16] (int_foo)), ([i32, i16] (INSTR_FOO_I32_I16))>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters