From 2c32aeb868bf7de3ddfeacf4f822158e7a5e1791 Mon Sep 17 00:00:00 2001 From: Vladislav Dzhidzhoev Date: Wed, 24 Jun 2026 03:42:52 +0200 Subject: [PATCH 1/4] [mlir][dxsa] Add topology instructions Example: dxsa.cut dxsa.emit dxsa.emit_then_cut dxsa.emit_stream 1 dxsa.cut_stream 3 dxsa.emit_then_cut_stream 2 --- .../mlir/Dialect/DXSA/IR/DXSAOpBase.td | 12 ++ mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td | 6 +- .../mlir/Dialect/DXSA/IR/DXSATopologyOps.td | 154 ++++++++++++++++++ mlir/lib/Target/DXSA/BinaryParser.cpp | 71 ++++++-- mlir/test/Target/DXSA/topology.test | 51 ++++++ .../Target/DXSA/topology_stream_invalid.mlir | 29 ++++ 6 files changed, 306 insertions(+), 17 deletions(-) create mode 100644 mlir/include/mlir/Dialect/DXSA/IR/DXSATopologyOps.td create mode 100644 mlir/test/Target/DXSA/topology.test create mode 100644 mlir/test/Target/DXSA/topology_stream_invalid.mlir diff --git a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOpBase.td b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOpBase.td index 6f67ca4c3329..4a4de2dd5acf 100644 --- a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOpBase.td +++ b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOpBase.td @@ -28,6 +28,12 @@ class DXSA_Op traits = []> : // DXSA shared bases for ops with inline operands //===----------------------------------------------------------------------===// +class DXSA_NullaryOp : DXSA_Op { + let arguments = (ins); + let results = (outs); + let assemblyFormat = "attr-dict"; +} + class DXSA_UnaryOp : DXSA_Op { let arguments = (ins DXSA_DstOperandAttr:$dst, @@ -61,4 +67,10 @@ class DXSA_TernaryOp : DXSA_Op { "(`precise` $precise^)? $dst `,` $src0 `,` $src1 `,` $src2 attr-dict"; } +class DXSA_GsStreamIndexOp : DXSA_Op { + let arguments = (ins ConfinedAttr]>:$index); + let assemblyFormat = [{ $index attr-dict }]; +} + #endif // MLIR_DIALECT_DXSA_IR_DXSAOPBASE diff --git a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td index 255ba7a5dd2e..4726b0243f87 100644 --- a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td +++ b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td @@ -14,6 +14,7 @@ include "mlir/Dialect/DXSA/IR/DXSATypes.td" include "mlir/Dialect/DXSA/IR/DXSAFPArithOps.td" include "mlir/Dialect/DXSA/IR/DXSAConditionOps.td" include "mlir/Dialect/DXSA/IR/DXSABitwiseOps.td" +include "mlir/Dialect/DXSA/IR/DXSATopologyOps.td" include "mlir/Dialect/DXSA/IR/DXSATypeConversionOps.td" include "mlir/IR/AttrTypeBase.td" include "mlir/IR/BuiltinAttributeInterfaces.td" @@ -1095,7 +1096,7 @@ def DXSA_DclSampler : DXSA_Op<"dcl_sampler"> { let hasVerifier = 1; } -def DXSA_DclStream : DXSA_Op<"dcl_stream"> { +def DXSA_DclStream : DXSA_GsStreamIndexOp<"dcl_stream"> { let summary = "declares a geometry shader (GS) output stream"; let description = [{ The `dxsa.dcl_stream` operation declares a geometry shader (GS) output stream. @@ -1108,9 +1109,6 @@ def DXSA_DclStream : DXSA_Op<"dcl_stream"> { dxsa.dcl_stream 0 ``` }]; - let arguments = (ins ConfinedAttr]>:$index); - let assemblyFormat = [{ $index attr-dict }]; } def DXSA_DclResource : DXSA_Op<"dcl_resource"> { diff --git a/mlir/include/mlir/Dialect/DXSA/IR/DXSATopologyOps.td b/mlir/include/mlir/Dialect/DXSA/IR/DXSATopologyOps.td new file mode 100644 index 000000000000..24529a68fa34 --- /dev/null +++ b/mlir/include/mlir/Dialect/DXSA/IR/DXSATopologyOps.td @@ -0,0 +1,154 @@ +//===- DXSTopologyOps.td - DXSA topology ops ---------------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Topology instructions of the DXSA dialect. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_DIALECT_DXSA_IR_DXSATOPOLOGYOPS +#define MLIR_DIALECT_DXSA_IR_DXSATOPOLOGYOPS + +include "mlir/Dialect/DXSA/IR/DXSAOpBase.td" + +//===----------------------------------------------------------------------===// +// dxsa.emit +//===----------------------------------------------------------------------===// + +def DXSA_Emit : DXSA_NullaryOp<"emit"> { + let summary = "outputs a geometry-shader vertex from declared output registers"; + let description = [{ + The `dxsa.emit` operation reads every declared `o#` output register and + outputs a vertex from the geometry shader. Each `dxsa.emit` produces one + vertex; successive emits assemble primitives according to the output + topology declared by `dxsa.dcl_output_topology`. + + A geometry shader may issue `dxsa.emit` any number of times, including + inside flow control. If output streams have been declared with + `dxsa.dcl_stream`, `dxsa.emit_stream` must be used instead. + + Example: + + ```mlir + dxsa.emit + ``` + }]; +} + +//===----------------------------------------------------------------------===// +// dxsa.cut +//===----------------------------------------------------------------------===// + +def DXSA_Cut : DXSA_NullaryOp<"cut"> { + let summary = "ends the current geometry-shader output strip"; + let description = [{ + The `dxsa.cut` operation ends the current output strip at the last emitted + vertex, so the next `dxsa.emit` begins a new strip. This only affects + linestrip and trianglestrip output topologies; for pointlist output, + `dxsa.cut` has no effect. + + A geometry shader may issue `dxsa.cut` any number of times, including + inside flow control. If output streams have been declared with + `dxsa.dcl_stream`, `dxsa.cut_stream` must be used instead. + + Example: + + ```mlir + dxsa.cut + ``` + }]; +} + +//===----------------------------------------------------------------------===// +// dxsa.emit_then_cut +//===----------------------------------------------------------------------===// + +def DXSA_EmitThenCut : DXSA_NullaryOp<"emit_then_cut"> { + let summary = "outputs a geometry-shader vertex and ends the current strip"; + let description = [{ + The `dxsa.emit_then_cut` operation has the same effect as `dxsa.emit`, + immediately followed by `dxsa.cut`. + + A geometry shader may issue `dxsa.emit_then_cut` any number of times, + including inside flow control. If output streams have been declared with + `dxsa.dcl_stream`, `dxsa.emit_then_cut_stream` must be used instead. + + Example: + + ```mlir + dxsa.emit_then_cut + ``` + }]; +} + +//===----------------------------------------------------------------------===// +// dxsa.emit_stream +//===----------------------------------------------------------------------===// + +def DXSA_EmitStream : DXSA_GsStreamIndexOp<"emit_stream"> { + let summary = "outputs a geometry-shader vertex on an output stream"; + let description = [{ + The `dxsa.emit_stream` operation reads every declared `o#` output register + for stream `$index` and outputs a vertex on that geometry-shader output + stream. Each `dxsa.emit_stream` produces one vertex; successive emits on + the same stream assemble primitives according to the output topology + declared for that stream. + + The `$index` must be in the range [0, 3]. + + Example: + + ```mlir + dxsa.emit_stream 0 + ``` + }]; +} + +//===----------------------------------------------------------------------===// +// dxsa.cut_stream +//===----------------------------------------------------------------------===// + +def DXSA_CutStream : DXSA_GsStreamIndexOp<"cut_stream"> { + let summary = "ends the current strip on a geometry-shader output stream"; + let description = [{ + The `dxsa.cut_stream` operation ends the current output strip at the last + emitted vertex on stream `$index`, so the next emit on that stream begins a + new strip. This has the same semantics as `dxsa.cut`, scoped to the given + output stream. + + The `$index` must be in the range [0, 3]. + + Example: + + ```mlir + dxsa.cut_stream 0 + ``` + }]; +} + +//===----------------------------------------------------------------------===// +// dxsa.emit_then_cut_stream +//===----------------------------------------------------------------------===// + +def DXSA_EmitThenCutStream : DXSA_GsStreamIndexOp<"emit_then_cut_stream"> { + let summary = "outputs a vertex on a stream and ends the current strip"; + let description = [{ + The `dxsa.emit_then_cut_stream` operation has the same effect as + `dxsa.emit_stream`, immediately followed by `dxsa.cut_stream`, on stream + `$index`. + + The `$index` must be in the range [0, 3]. + + Example: + + ```mlir + dxsa.emit_then_cut_stream 0 + ``` + }]; +} + +#endif // MLIR_DIALECT_DXSA_IR_DXSATOPOLOGYOPS diff --git a/mlir/lib/Target/DXSA/BinaryParser.cpp b/mlir/lib/Target/DXSA/BinaryParser.cpp index e005ae531398..2699500833c2 100644 --- a/mlir/lib/Target/DXSA/BinaryParser.cpp +++ b/mlir/lib/Target/DXSA/BinaryParser.cpp @@ -626,9 +626,9 @@ class DXBuilder { return dxsa::DclMaxOutputVertexCount::create(builder, loc, count); } - Instruction buildDclStream(uint32_t index, Location loc) { - return dxsa::DclStream::create(builder, loc, - builder.getI32IntegerAttr(index)); + template + Instruction buildGsStreamIndexOp(uint32_t index, Location loc) { + return OpT::create(builder, loc, builder.getI32IntegerAttr(index)); } Instruction buildDclInputPs(dxsa::InterpolationMode interpolationMode, @@ -800,6 +800,14 @@ class DXBuilder { dsts); } + template + Instruction + buildOpWithPreciseMask(uint32_t /*preciseMask*/, Location loc, + const std::array &, + const std::array &) { + return OpT::create(builder, loc); + } + Instruction buildDclInput(dxsa::DstOperandAttr operand, Location loc) { return dxsa::DclInput::create(builder, loc, operand); } @@ -1440,21 +1448,29 @@ class Parser { return builder.buildDclMaxOutputVertexCount(count, loc); } - FailureOr parseDclStream(Location loc) { - auto operand = parseDstOperand(); - FAILURE_IF_FAILED(operand); - if (operand->getType() != dxsa::OperandType::m) + template + FailureOr parseGsStreamIndex(SrcOrDstOperand operand, + Location loc) { + if (operand.getType() != dxsa::OperandType::m) return emitError(loc, "unexpected operand type: ") - << dxsa::stringifyOperandType(operand->getType()); - if (operand->getComponents().getValue() != dxsa::OperandComponents::none) + << dxsa::stringifyOperandType(operand.getType()); + if (operand.getComponents().getValue() != dxsa::OperandComponents::none) return emitError(loc, "unexpected operand components: ") << dxsa::stringifyOperandComponents( - operand->getComponents().getValue()); - auto indices = getRequiredImmIndices(*operand, loc); + operand.getComponents().getValue()); + auto indices = getRequiredImmIndices(operand, loc); FAILURE_IF_FAILED(indices); if (indices->size() != 1) return emitError(loc, "unsupported index dimension: ") << indices->size(); - return builder.buildDclStream((*indices)[0], loc); + return (*indices)[0]; + } + + FailureOr parseDclStream(Location loc) { + auto operand = parseDstOperand(); + FAILURE_IF_FAILED(operand); + auto index = parseGsStreamIndex(*operand, loc); + FAILURE_IF_FAILED(index); + return builder.buildGsStreamIndexOp(*index, loc); } FailureOr @@ -1642,8 +1658,9 @@ class Parser { } // Get plain immediates with no relative indices. + template FailureOr> - getRequiredImmIndices(dxsa::DstOperandAttr operand, Location loc) { + getRequiredImmIndices(SrcOrDstOperand operand, Location loc) { SmallVector indices; if (auto index = operand.getIndex()) for (dxsa::IndexAttr entry : index) { @@ -1693,6 +1710,18 @@ class Parser { preciseMask, loc); } + template + FailureOr decodeStreamIndexOp(size_t beginOffset, + uint32_t length, Location loc) { + auto operand = parseSrcOperand(); + FAILURE_IF_FAILED(operand); + auto index = parseGsStreamIndex(*operand, loc); + FAILURE_IF_FAILED(index); + if (failed(verifyInstructionLength(beginOffset, length))) + return failure(); + return builder.buildGsStreamIndexOp(*index, loc); + } + FailureOr parseDclInput(Location loc) { auto operand = parseDstOperand(); FAILURE_IF_FAILED(operand); @@ -2301,6 +2330,9 @@ class Parser { decodeOp( \ beginOffset, instructionLengthInTokens, modifier.preciseMask, \ getLocation()) +#define STREAM_INDEX_OP(OP) \ + decodeStreamIndexOp(beginOffset, instructionLengthInTokens, \ + getLocation()) switch (opcode) { case D3D10_SB_OPCODE_ADD: @@ -2403,9 +2435,22 @@ class Parser { return PLAIN_OP(UShr, 1, 2); case D3D10_SB_OPCODE_XOR: return PLAIN_OP(Xor, 1, 2); + case D3D10_SB_OPCODE_EMIT: + return PLAIN_OP(Emit, 0, 0); + case D3D10_SB_OPCODE_EMITTHENCUT: + return PLAIN_OP(EmitThenCut, 0, 0); + case D3D10_SB_OPCODE_CUT: + return PLAIN_OP(Cut, 0, 0); + case D3D11_SB_OPCODE_EMIT_STREAM: + return STREAM_INDEX_OP(EmitStream); + case D3D11_SB_OPCODE_CUT_STREAM: + return STREAM_INDEX_OP(CutStream); + case D3D11_SB_OPCODE_EMITTHENCUT_STREAM: + return STREAM_INDEX_OP(EmitThenCutStream); } #undef SATURABLE_OP #undef PLAIN_OP +#undef STREAM_INDEX_OP SmallVector operands; for (unsigned i = 0; i < numOperands; ++i) { diff --git a/mlir/test/Target/DXSA/topology.test b/mlir/test/Target/DXSA/topology.test new file mode 100644 index 000000000000..b3a7861299be --- /dev/null +++ b/mlir/test/Target/DXSA/topology.test @@ -0,0 +1,51 @@ +// RUN: mlir-translate --import-dxsa-hex %s | FileCheck %s +// RUN: mlir-translate --import-dxsa-hex %s | mlir-opt --verify-roundtrip + +// CHECK: dxsa.module { + +// CHECK-NEXT: dxsa.cut +0x01000009 + +// CHECK-NEXT: dxsa.emit +0x01000013 + +// CHECK-NEXT: dxsa.emit_then_cut +0x01000014 + +// CHECK-NEXT: dxsa.emit_stream 0 +0x03000075, 0x00110000, 0x00000000 + +// CHECK-NEXT: dxsa.emit_stream 1 +0x03000075, 0x00110000, 0x00000001 + +// CHECK-NEXT: dxsa.emit_stream 2 +0x03000075, 0x00110000, 0x00000002 + +// CHECK-NEXT: dxsa.emit_stream 3 +0x03000075, 0x00110000, 0x00000003 + +// CHECK-NEXT: dxsa.cut_stream 0 +0x03000076, 0x00110000, 0x00000000 + +// CHECK-NEXT: dxsa.cut_stream 1 +0x03000076, 0x00110000, 0x00000001 + +// CHECK-NEXT: dxsa.cut_stream 2 +0x03000076, 0x00110000, 0x00000002 + +// CHECK-NEXT: dxsa.cut_stream 3 +0x03000076, 0x00110000, 0x00000003 + +// CHECK-NEXT: dxsa.emit_then_cut_stream 0 +0x03000077, 0x00110000, 0x00000000 + +// CHECK-NEXT: dxsa.emit_then_cut_stream 1 +0x03000077, 0x00110000, 0x00000001 + +// CHECK-NEXT: dxsa.emit_then_cut_stream 2 +0x03000077, 0x00110000, 0x00000002 + +// CHECK-NEXT: dxsa.emit_then_cut_stream 3 +0x03000077, 0x00110000, 0x00000003 + +// CHECK-NEXT: } diff --git a/mlir/test/Target/DXSA/topology_stream_invalid.mlir b/mlir/test/Target/DXSA/topology_stream_invalid.mlir new file mode 100644 index 000000000000..d6cff05ec373 --- /dev/null +++ b/mlir/test/Target/DXSA/topology_stream_invalid.mlir @@ -0,0 +1,29 @@ +// RUN: mlir-opt %s -split-input-file -verify-diagnostics + +// expected-error@+1 {{attribute 'index' failed to satisfy constraint: 32-bit signless integer attribute whose value is non-negative whose maximum value is 3}} +dxsa.emit_stream -1 + +// ----- + +// expected-error@+1 {{attribute 'index' failed to satisfy constraint: 32-bit signless integer attribute whose value is non-negative whose maximum value is 3}} +dxsa.emit_stream 4 + +// ----- + +// expected-error@+1 {{attribute 'index' failed to satisfy constraint: 32-bit signless integer attribute whose value is non-negative whose maximum value is 3}} +dxsa.cut_stream -1 + +// ----- + +// expected-error@+1 {{attribute 'index' failed to satisfy constraint: 32-bit signless integer attribute whose value is non-negative whose maximum value is 3}} +dxsa.cut_stream 4 + +// ----- + +// expected-error@+1 {{attribute 'index' failed to satisfy constraint: 32-bit signless integer attribute whose value is non-negative whose maximum value is 3}} +dxsa.emit_then_cut_stream -1 + +// ----- + +// expected-error@+1 {{attribute 'index' failed to satisfy constraint: 32-bit signless integer attribute whose value is non-negative whose maximum value is 3}} +dxsa.emit_then_cut_stream 4 From 84d75cbe46d84171066b180272ed6f0edb8d3312 Mon Sep 17 00:00:00 2001 From: Vladislav Dzhidzhoev Date: Thu, 25 Jun 2026 11:47:07 +0200 Subject: [PATCH 2/4] Address review comments --- .../mlir/Dialect/DXSA/IR/DXSATopologyOps.td | 2 +- mlir/test/Target/DXSA/topology.test | 18 ------------------ 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/mlir/include/mlir/Dialect/DXSA/IR/DXSATopologyOps.td b/mlir/include/mlir/Dialect/DXSA/IR/DXSATopologyOps.td index 24529a68fa34..d93d267adf0d 100644 --- a/mlir/include/mlir/Dialect/DXSA/IR/DXSATopologyOps.td +++ b/mlir/include/mlir/Dialect/DXSA/IR/DXSATopologyOps.td @@ -1,4 +1,4 @@ -//===- DXSTopologyOps.td - DXSA topology ops ---------------*- tablegen -*-===// +//===- DXSATopologyOps.td - DXSA topology ops --------------*- tablegen -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/mlir/test/Target/DXSA/topology.test b/mlir/test/Target/DXSA/topology.test index b3a7861299be..c52d9116bd66 100644 --- a/mlir/test/Target/DXSA/topology.test +++ b/mlir/test/Target/DXSA/topology.test @@ -15,36 +15,18 @@ // CHECK-NEXT: dxsa.emit_stream 0 0x03000075, 0x00110000, 0x00000000 -// CHECK-NEXT: dxsa.emit_stream 1 -0x03000075, 0x00110000, 0x00000001 - -// CHECK-NEXT: dxsa.emit_stream 2 -0x03000075, 0x00110000, 0x00000002 - // CHECK-NEXT: dxsa.emit_stream 3 0x03000075, 0x00110000, 0x00000003 // CHECK-NEXT: dxsa.cut_stream 0 0x03000076, 0x00110000, 0x00000000 -// CHECK-NEXT: dxsa.cut_stream 1 -0x03000076, 0x00110000, 0x00000001 - -// CHECK-NEXT: dxsa.cut_stream 2 -0x03000076, 0x00110000, 0x00000002 - // CHECK-NEXT: dxsa.cut_stream 3 0x03000076, 0x00110000, 0x00000003 // CHECK-NEXT: dxsa.emit_then_cut_stream 0 0x03000077, 0x00110000, 0x00000000 -// CHECK-NEXT: dxsa.emit_then_cut_stream 1 -0x03000077, 0x00110000, 0x00000001 - -// CHECK-NEXT: dxsa.emit_then_cut_stream 2 -0x03000077, 0x00110000, 0x00000002 - // CHECK-NEXT: dxsa.emit_then_cut_stream 3 0x03000077, 0x00110000, 0x00000003 From f68f5e5e4efca2f5fdcf0c63133af0b6bc130375 Mon Sep 17 00:00:00 2001 From: Vladislav Dzhidzhoev Date: Thu, 25 Jun 2026 12:09:12 +0200 Subject: [PATCH 3/4] Removed function which is now dead code --- mlir/lib/Target/DXSA/BinaryParser.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/mlir/lib/Target/DXSA/BinaryParser.cpp b/mlir/lib/Target/DXSA/BinaryParser.cpp index 7075a3e02c9f..9c8ea1e5b75e 100644 --- a/mlir/lib/Target/DXSA/BinaryParser.cpp +++ b/mlir/lib/Target/DXSA/BinaryParser.cpp @@ -808,14 +808,6 @@ class DXBuilder { dsts); } - template - Instruction - buildOpWithPreciseMask(uint32_t /*preciseMask*/, Location loc, - const std::array &, - const std::array &) { - return OpT::create(builder, loc); - } - Instruction buildDclInput(dxsa::DstOperandAttr operand, Location loc) { return dxsa::DclInput::create(builder, loc, operand); } From b8c4550ca7c60e78896df4e18b9f63112f9261ea Mon Sep 17 00:00:00 2001 From: Vladislav Dzhidzhoev Date: Sat, 27 Jun 2026 23:00:53 +0200 Subject: [PATCH 4/4] Use split-input-file in tests --- mlir/test/Target/DXSA/topology.test | 42 ++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/mlir/test/Target/DXSA/topology.test b/mlir/test/Target/DXSA/topology.test index c52d9116bd66..738780827d8f 100644 --- a/mlir/test/Target/DXSA/topology.test +++ b/mlir/test/Target/DXSA/topology.test @@ -1,33 +1,63 @@ -// RUN: mlir-translate --import-dxsa-hex %s | FileCheck %s -// RUN: mlir-translate --import-dxsa-hex %s | mlir-opt --verify-roundtrip - -// CHECK: dxsa.module { +// RUN: mlir-translate --split-input-file --import-dxsa-hex %s | FileCheck %s +// RUN: mlir-translate --split-input-file --import-dxsa-hex %s | mlir-opt --split-input-file --verify-roundtrip +// CHECK-LABEL: dxsa.module { // CHECK-NEXT: dxsa.cut +// CHECK-NEXT: } 0x01000009 +// ----- + +// CHECK-LABEL: dxsa.module { // CHECK-NEXT: dxsa.emit +// CHECK-NEXT: } 0x01000013 +// ----- + +// CHECK-LABEL: dxsa.module { // CHECK-NEXT: dxsa.emit_then_cut +// CHECK-NEXT: } 0x01000014 +// ----- + +// CHECK-LABEL: dxsa.module { // CHECK-NEXT: dxsa.emit_stream 0 +// CHECK-NEXT: } 0x03000075, 0x00110000, 0x00000000 +// ----- + +// CHECK-LABEL: dxsa.module { // CHECK-NEXT: dxsa.emit_stream 3 +// CHECK-NEXT: } 0x03000075, 0x00110000, 0x00000003 +// ----- + +// CHECK-LABEL: dxsa.module { // CHECK-NEXT: dxsa.cut_stream 0 +// CHECK-NEXT: } 0x03000076, 0x00110000, 0x00000000 +// ----- + +// CHECK-LABEL: dxsa.module { // CHECK-NEXT: dxsa.cut_stream 3 +// CHECK-NEXT: } 0x03000076, 0x00110000, 0x00000003 +// ----- + +// CHECK-LABEL: dxsa.module { // CHECK-NEXT: dxsa.emit_then_cut_stream 0 +// CHECK-NEXT: } 0x03000077, 0x00110000, 0x00000000 -// CHECK-NEXT: dxsa.emit_then_cut_stream 3 -0x03000077, 0x00110000, 0x00000003 +// ----- +// CHECK-LABEL: dxsa.module { +// CHECK-NEXT: dxsa.emit_then_cut_stream 3 // CHECK-NEXT: } +0x03000077, 0x00110000, 0x00000003