-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[TableGen] Support for optional chain in Selection DAG nodes #163079
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,6 +26,7 @@ enum SDNP { | |
| SDNPOptInGlue, | ||
| SDNPMemOperand, | ||
| SDNPVariadic, | ||
| SDNPMayHaveChain | ||
| }; | ||
|
|
||
| enum SDTC : uint8_t { | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -29,3 +29,4 @@ def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'. | |||||
| def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'. | ||||||
| def SDNPMemOperand : SDNodeProperty; // Touches memory, has assoc MemOperand | ||||||
| def SDNPVariadic : SDNodeProperty; // Node has variable arguments. | ||||||
| def SDNPMayHaveChain: SDNodeProperty; // Optionally has chain operand/result. | ||||||
|
||||||
| def SDNPMayHaveChain: SDNodeProperty; // Optionally has chain operand/result. | |
| def SDNPOptChain : SDNodeProperty; // Optionally has chain operand/result. |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -717,13 +717,31 @@ END_TWO_BYTE_PACK() | |||||
| case ISD::STRICT_FP_TO_FP16: | ||||||
| case ISD::STRICT_BF16_TO_FP: | ||||||
| case ISD::STRICT_FP_TO_BF16: | ||||||
| #define FP_OPERATION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) | ||||||
| #define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \ | ||||||
| case ISD::STRICT_##DAGN: | ||||||
| #include "llvm/IR/ConstrainedOps.def" | ||||||
| return true; | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| /// Test if this node is a floating-point operation which can exist in two | ||||||
| /// forms, - with chain or without it. | ||||||
| bool isFPOperation() const { | ||||||
|
||||||
| switch (NodeType) { | ||||||
| default: | ||||||
| return false; | ||||||
| #define FP_OPERATION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) case ISD::DAGN: | ||||||
| #include "llvm/IR/ConstrainedOps.def" | ||||||
| return true; | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| /// Test if this node has an input chain. | ||||||
|
||||||
| /// Test if this node has an input chain. | |
| /// Test if this node has a chain. |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are other operands that have MVT::Other type. In particular, setcc predicates. Some targets may use this type for other custom operands.
I wish we had a dedicated MVT::Chain type, like we have MVT::Glue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should be checking for a chain result? I don't think that's ambiguous. Unfortunately, there might be a Glue result after the chain result so it requires checking the last and possibly second to last result.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -47,6 +47,16 @@ void SDNodeInfo::verifyNode(const SelectionDAG &DAG, const SDNode *N) const { | |
| bool HasInGlue = Desc.hasProperty(SDNPInGlue); | ||
| bool HasOptInGlue = Desc.hasProperty(SDNPOptInGlue); | ||
| bool IsVariadic = Desc.hasProperty(SDNPVariadic); | ||
| bool MayHaveChain = Desc.hasProperty(SDNPMayHaveChain); | ||
|
|
||
| if (HasChain && MayHaveChain) | ||
| reportNodeError( | ||
| DAG, N, "Flags 'HasChain' and 'MayHaveChain' cannot be both specified"); | ||
|
||
|
|
||
| if (MayHaveChain && N->getNumOperands() > 0 && | ||
| N->getOperand(0).getValueType() == MVT::Other) { | ||
| HasChain = true; | ||
| } | ||
|
|
||
| unsigned ActualNumResults = N->getNumValues(); | ||
| unsigned ExpectedNumResults = Desc.NumResults + HasChain + HasOutGlue; | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -46,15 +46,22 @@ def my_node_3 : SDNode< | |||||
| SDNPOutGlue, SDNPInGlue, SDNPOptInGlue] | ||||||
| >; | ||||||
|
|
||||||
| def my_node_4 : SDNode< | ||||||
| "MyTargetISD::NODE_4", | ||||||
| SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisVT<1, f32>]>, | ||||||
| [SDNPMayHaveChain] | ||||||
| >; | ||||||
|
|
||||||
| // CHECK: namespace llvm::MyTargetISD { | ||||||
| // CHECK-EMPTY: | ||||||
| // CHECK-NEXT: enum GenNodeType : unsigned { | ||||||
| // CHECK-NEXT: NODE_1 = ISD::BUILTIN_OP_END, | ||||||
| // CHECK-NEXT: NODE_2, | ||||||
| // CHECK-NEXT: NODE_3, | ||||||
| // CHECK-NEXT: NODE_4 | ||||||
|
||||||
| // CHECK-NEXT: NODE_4 | |
| // CHECK-NEXT: NODE_4, |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| // RUN: llvm-tblgen -gen-dag-isel -I %p/../../include %s 2>&1 | FileCheck %s | ||
|
|
||
| include "llvm/Target/Target.td" | ||
|
|
||
| def TestTargetInstrInfo : InstrInfo; | ||
|
|
||
|
|
||
| def TestTarget : Target { | ||
| let InstructionSet = TestTargetInstrInfo; | ||
| } | ||
|
|
||
| def R0 : Register<"r0"> { let Namespace = "MyTarget"; } | ||
| def GPR : RegisterClass<"MyTarget", [i32, f32], 32, (add R0)>; | ||
|
|
||
| def a_nearbyint : SDNode< | ||
| "MyTargetISD::A_NEARBYINT", | ||
| SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>, | ||
| [SDNPMayHaveChain] | ||
| >; | ||
|
|
||
| def I_NEARBYINT : Instruction { | ||
| let OutOperandList = (outs GPR:$out); | ||
| let InOperandList = (ins GPR:$x); | ||
| } | ||
|
|
||
| def : Pat<(a_nearbyint GPR:$x), (I_NEARBYINT GPR:$x)>; | ||
| def : Pat<(a_nearbyint (a_nearbyint GPR:$x)), (I_NEARBYINT GPR:$x)>; | ||
|
|
||
| // CHECK-LABEL: OPC_CheckOpcode, TARGET_VAL(MyTargetISD::A_NEARBYINT), | ||
| // CHECK-NEXT: OPC_RecordOptionalChain, | ||
| // CHECK-NEXT: OPC_Scope, 17 | ||
| // CHECK-NEXT: OPC_MoveChild0, | ||
| // CHECK-NEXT: OPC_CheckOpcode, TARGET_VAL(MyTargetISD::A_NEARBYINT), | ||
| // CHECK-NEXT: OPC_RecordOptionalChain, | ||
| // CHECK-NEXT: OPC_CheckFoldableChainNode, | ||
| // CHECK-NEXT: OPC_RecordChild0, | ||
| // CHECK-NEXT: OPC_MoveParent, | ||
| // CHECK-NEXT: OPC_EmitMergeInputChains, 0, | ||
| // CHECK-NEXT: OPC_MorphNodeTo1, TARGET_VAL(::I_NEARBYINT), 0, | ||
| // CHECK-NEXT: /*MVT::f32*/12, 1/*#Ops*/, 2, | ||
|
|
||
| // CHECK: /*Scope*/ 10, | ||
| // CHECK-NEXT: OPC_RecordChild0, | ||
| // CHECK-NEXT: OPC_EmitMergeInputChains, 0, | ||
| // CHECK-NEXT: OPC_MorphNodeTo1, TARGET_VAL(::I_NEARBYINT), 0, | ||
| // CHECK-NEXT: /*MVT::f32*/12, 1/*#Ops*/, 1, |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -28,6 +28,7 @@ enum SDNP { | |||||
| SDNPSideEffect, | ||||||
| SDNPMemOperand, | ||||||
| SDNPVariadic, | ||||||
| SDNPMayHaveChain | ||||||
|
||||||
| SDNPMayHaveChain | |
| SDNPMayHaveChain, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.