Skip to content

Commit 387291f

Browse files
mikeurbachMorten Borup Petersen
and
Morten Borup Petersen
authored
Bump LLVM to b0b546d44777eb1fa25995384876bd14a006a929. (#7976)
This is not a totally routine bump. Python support is changing in preparation for a switch to nanobind: https://discourse.llvm.org/t/psa-python-binding-dependencies-changing/83376 There were also some more DialectConversion changes: llvm/llvm-project#116470 `InstanceOpConversion`'s 1:1 in FlattenIO generalizes to the 1:N pattern, so we can drop the 1:1 pattern. Secondly, it seems like the biggest violating thing here is the fact that we were missing a materialization for exploding struct outputs of `hw.module.extern`... This was actually a pretty glaring mistake in the existing IR, which had a check for invalid IR - woops! Combined with folders, this also seems to have removed some (not all!) of the redundant struct_create/struct_explode patterns in the output. With the 1:N operand adaptor, we no longer have to manually filter i0 operands inside a conversion pattern. Instead, this information is already implicitly available via the adaptor (i.e. that an operand was removed via. materialization). This also implies that 1:N patterns need to handle the case where the `OneToNOpAdaptor` is empty. In general, it feels like one would _very_ rarely have to use both the `OneToNOpAdaptor` and `OpAdaptor` overloads at the same time - this should be reserved for when there is truly a difference between 1:1 and 1:N patterns. However, in practice - as this little fixing excercise has demonstrated - most patterns where `OneToNOpAdaptor` is relevant, are generalized 1:N patterns, and doesn't need a specific `1:1` overload. --------- Co-authored-by: Morten Borup Petersen <[email protected]>
1 parent 0276e17 commit 387291f

File tree

8 files changed

+117
-54
lines changed

8 files changed

+117
-54
lines changed

.github/workflows/nightlyIntegrationTests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
# John and re-run the job.
2020
runs-on: ["self-hosted", "1ES.Pool=1ES-CIRCT-builds", "linux"]
2121
container:
22-
image: ghcr.io/circt/images/circt-integration-test:v18.0
22+
image: ghcr.io/circt/images/circt-integration-test:v18.1
2323
volumes:
2424
- /mnt:/__w/circt
2525
strategy:

.github/workflows/shortIntegrationTests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
# John and re-run the job.
3030
runs-on: ["self-hosted", "1ES.Pool=1ES-CIRCT-builds", "linux"]
3131
container:
32-
image: ghcr.io/circt/images/circt-integration-test:v18.0
32+
image: ghcr.io/circt/images/circt-integration-test:v18.1
3333
volumes:
3434
- /mnt:/__w/circt
3535
strategy:

CMakeLists.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -513,8 +513,12 @@ option(CIRCT_BINDINGS_PYTHON_ENABLED "Enables CIRCT Python bindings." OFF)
513513

514514
if(CIRCT_BINDINGS_PYTHON_ENABLED)
515515
message(STATUS "CIRCT Python bindings are enabled.")
516-
include(MLIRDetectPythonEnv)
517-
mlir_configure_python_dev_packages()
516+
set(MLIR_DISABLE_CONFIGURE_PYTHON_DEV_PACKAGES 0)
517+
mlir_detect_pybind11_install()
518+
# Prime the search like mlir_configure_python_dev_modules
519+
find_package(Python3 3.8 COMPONENTS Interpreter Development)
520+
find_package(Python3 3.8 COMPONENTS Interpreter Development.Module)
521+
find_package(pybind11 2.10 CONFIG REQUIRED)
518522
else()
519523
message(STATUS "CIRCT Python bindings are disabled.")
520524
# Lookup python either way as some integration tests use python without the

lib/Conversion/ExportVerilog/PruneZeroValuedLogic.cpp

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ static bool noI0TypedValue(ValueRange values) {
3333
return noI0Type(values.getTypes());
3434
}
3535

36+
/// Flatten the given value ranges into a single vector of values.
37+
static SmallVector<Value> flattenValues(ArrayRef<ValueRange> values) {
38+
SmallVector<Value> result;
39+
for (const auto &vals : values)
40+
llvm::append_range(result, vals);
41+
return result;
42+
}
43+
3644
namespace {
3745

3846
class PruneTypeConverter : public mlir::TypeConverter {
@@ -51,11 +59,17 @@ struct NoI0OperandsConversionPattern : public OpConversionPattern<TOp> {
5159
public:
5260
using OpConversionPattern<TOp>::OpConversionPattern;
5361
using OpAdaptor = typename OpConversionPattern<TOp>::OpAdaptor;
62+
using OneToNOpAdaptor = typename OpConversionPattern<TOp>::OneToNOpAdaptor;
5463

5564
LogicalResult
56-
matchAndRewrite(TOp op, OpAdaptor adaptor,
65+
matchAndRewrite(TOp op, OneToNOpAdaptor adaptor,
5766
ConversionPatternRewriter &rewriter) const override {
58-
if (noI0TypedValue(adaptor.getOperands()))
67+
ValueRange flattenedOperands = flattenValues(adaptor.getOperands());
68+
69+
// flattenedOperands may be empty (in case all operands are i0 typed and
70+
// have already been pruned. Then the 1:N adaptor will reflect this as no
71+
// operands).
72+
if (!flattenedOperands.empty() && noI0TypedValue(flattenedOperands))
5973
return failure();
6074

6175
// Part of i0-typed logic - prune it!
@@ -76,6 +90,8 @@ struct NoI0OperandsConversionPattern<comb::ICmpOp>
7690
public:
7791
using OpConversionPattern<comb::ICmpOp>::OpConversionPattern;
7892
using OpAdaptor = typename OpConversionPattern<comb::ICmpOp>::OpAdaptor;
93+
using OneToNOpAdaptor =
94+
typename OpConversionPattern<comb::ICmpOp>::OneToNOpAdaptor;
7995

8096
// Returns the result of applying the predicate when the LHS and RHS are the
8197
// exact same value.
@@ -103,9 +119,9 @@ struct NoI0OperandsConversionPattern<comb::ICmpOp>
103119
}
104120

105121
LogicalResult
106-
matchAndRewrite(comb::ICmpOp op, OpAdaptor adaptor,
122+
matchAndRewrite(comb::ICmpOp op, OneToNOpAdaptor adaptor,
107123
ConversionPatternRewriter &rewriter) const override {
108-
if (noI0TypedValue(adaptor.getOperands()))
124+
if (noI0TypedValue(flattenValues(adaptor.getOperands())))
109125
return failure();
110126

111127
// Caluculate the result of i0 value comparison.
@@ -123,11 +139,14 @@ struct NoI0OperandsConversionPattern<comb::ParityOp>
123139
public:
124140
using OpConversionPattern<comb::ParityOp>::OpConversionPattern;
125141
using OpAdaptor = typename OpConversionPattern<comb::ParityOp>::OpAdaptor;
142+
using OneToNOpAdaptor =
143+
typename OpConversionPattern<comb::ParityOp>::OneToNOpAdaptor;
126144

127145
LogicalResult
128-
matchAndRewrite(comb::ParityOp op, OpAdaptor adaptor,
146+
matchAndRewrite(comb::ParityOp op, OneToNOpAdaptor adaptor,
129147
ConversionPatternRewriter &rewriter) const override {
130-
if (noI0TypedValue(adaptor.getOperands()))
148+
ValueRange flattenedOperands = flattenValues(adaptor.getOperands());
149+
if (!flattenedOperands.empty() && noI0TypedValue(flattenedOperands))
131150
return failure();
132151

133152
// The value of "comb.parity i0" is 0.
@@ -143,9 +162,11 @@ struct NoI0OperandsConversionPattern<comb::ConcatOp>
143162
public:
144163
using OpConversionPattern<comb::ConcatOp>::OpConversionPattern;
145164
using OpAdaptor = typename OpConversionPattern<comb::ConcatOp>::OpAdaptor;
165+
using OneToNOpAdaptor =
166+
typename OpConversionPattern<comb::ConcatOp>::OneToNOpAdaptor;
146167

147168
LogicalResult
148-
matchAndRewrite(comb::ConcatOp op, OpAdaptor adaptor,
169+
matchAndRewrite(comb::ConcatOp op, OneToNOpAdaptor adaptor,
149170
ConversionPatternRewriter &rewriter) const override {
150171
// Replace an i0 value with i0 constant.
151172
if (op.getType().isInteger(0)) {
@@ -154,14 +175,18 @@ struct NoI0OperandsConversionPattern<comb::ConcatOp>
154175
return success();
155176
}
156177

157-
if (noI0TypedValue(adaptor.getOperands()))
178+
SmallVector<Value> materializedOperands =
179+
flattenValues(adaptor.getOperands());
180+
181+
// If the materializedOperands are the same as the original operands, then
182+
// there were no i0 operands. If not, then that means that this op used to
183+
// have an i0 operand but materialization removed that operand, as reflect
184+
// in the 1:N operand adaptor.
185+
if (materializedOperands.size() == adaptor.getOperands().size())
158186
return failure();
159187

160-
// Filter i0 operands and create a new concat op.
161-
SmallVector<Value> newOperands;
162-
llvm::copy_if(op.getOperands(), std::back_inserter(newOperands),
163-
[](auto op) { return !op.getType().isInteger(0); });
164-
rewriter.replaceOpWithNewOp<comb::ConcatOp>(op, newOperands);
188+
// Create a new concat op with the materialized operands.
189+
rewriter.replaceOpWithNewOp<comb::ConcatOp>(op, materializedOperands);
165190
return success();
166191
}
167192
};
@@ -184,10 +209,10 @@ template <typename TOp>
184209
struct NoI0ResultsConversionPattern : public OpConversionPattern<TOp> {
185210
public:
186211
using OpConversionPattern<TOp>::OpConversionPattern;
187-
using OpAdaptor = typename OpConversionPattern<TOp>::OpAdaptor;
212+
using OneToNOpAdaptor = typename OpConversionPattern<TOp>::OneToNOpAdaptor;
188213

189214
LogicalResult
190-
matchAndRewrite(TOp op, OpAdaptor adaptor,
215+
matchAndRewrite(TOp op, OneToNOpAdaptor adaptor,
191216
ConversionPatternRewriter &rewriter) const override {
192217
if (noI0TypedValue(op->getResults()))
193218
return failure();

lib/Dialect/HW/Transforms/FlattenIO.cpp

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ static llvm::SmallVector<Type> getInnerTypes(hw::StructType t) {
4646

4747
namespace {
4848

49+
/// Flatten the given value ranges into a single vector of values.
50+
static SmallVector<Value> flattenValues(ArrayRef<ValueRange> values) {
51+
SmallVector<Value> result;
52+
for (const auto &vals : values)
53+
llvm::append_range(result, vals);
54+
return result;
55+
}
56+
4957
// Replaces an output op with a new output with flattened (exploded) structs.
5058
struct OutputOpConversion : public OpConversionPattern<hw::OutputOp> {
5159
OutputOpConversion(TypeConverter &typeConverter, MLIRContext *context,
@@ -74,6 +82,29 @@ struct OutputOpConversion : public OpConversionPattern<hw::OutputOp> {
7482
rewriter.replaceOpWithNewOp<hw::OutputOp>(op, convOperands);
7583
return success();
7684
}
85+
86+
LogicalResult
87+
matchAndRewrite(hw::OutputOp op, OneToNOpAdaptor adaptor,
88+
ConversionPatternRewriter &rewriter) const override {
89+
llvm::SmallVector<Value> convOperands;
90+
91+
// Flatten the operands.
92+
for (auto operand : flattenValues(adaptor.getOperands())) {
93+
if (auto structType = getStructType(operand.getType())) {
94+
auto explodedStruct = rewriter.create<hw::StructExplodeOp>(
95+
op.getLoc(), getInnerTypes(structType), operand);
96+
llvm::copy(explodedStruct.getResults(),
97+
std::back_inserter(convOperands));
98+
} else {
99+
convOperands.push_back(operand);
100+
}
101+
}
102+
103+
// And replace.
104+
opVisited->insert(op->getParentOp());
105+
rewriter.replaceOpWithNewOp<hw::OutputOp>(op, convOperands);
106+
return success();
107+
}
77108
DenseSet<Operation *> *opVisited;
78109
};
79110

@@ -85,7 +116,7 @@ struct InstanceOpConversion : public OpConversionPattern<hw::InstanceOp> {
85116
externModules(externModules) {}
86117

87118
LogicalResult
88-
matchAndRewrite(hw::InstanceOp op, OpAdaptor adaptor,
119+
matchAndRewrite(hw::InstanceOp op, OneToNOpAdaptor adaptor,
89120
ConversionPatternRewriter &rewriter) const override {
90121
auto referencedMod = op.getReferencedModuleNameAttr();
91122
// If externModules is populated and this is an extern module instance,
@@ -96,7 +127,7 @@ struct InstanceOpConversion : public OpConversionPattern<hw::InstanceOp> {
96127
auto loc = op.getLoc();
97128
// Flatten the operands.
98129
llvm::SmallVector<Value> convOperands;
99-
for (auto operand : adaptor.getOperands()) {
130+
for (auto operand : flattenValues(adaptor.getOperands())) {
100131
if (auto structType = getStructType(operand.getType())) {
101132
auto explodedStruct = rewriter.create<hw::StructExplodeOp>(
102133
loc, getInnerTypes(structType), operand);
@@ -176,6 +207,16 @@ class FlattenIOTypeConverter : public TypeConverter {
176207
return success();
177208
});
178209

210+
// Materialize !hw.struct<a,b,...> to a, b, ... via. hw.explode. This
211+
// situation may occur in case of hw.extern_module's with struct outputs.
212+
addTargetMaterialization([](OpBuilder &builder, TypeRange resultTypes,
213+
ValueRange inputs, Location loc) {
214+
if (inputs.size() != 1 && !isStructType(inputs[0].getType()))
215+
return ValueRange();
216+
217+
auto explodeOp = builder.create<hw::StructExplodeOp>(loc, inputs[0]);
218+
return ValueRange(explodeOp.getResults());
219+
});
179220
addTargetMaterialization([](OpBuilder &builder, hw::StructType type,
180221
ValueRange inputs, Location loc) {
181222
auto result = builder.create<hw::StructCreateOp>(loc, type, inputs);
@@ -397,9 +438,12 @@ static LogicalResult flattenOpsOfType(ModuleOp module, bool recursive,
397438
target.addDynamicallyLegalOp<hw::InstanceOp>([&](hw::InstanceOp op) {
398439
auto refName = op.getReferencedModuleName();
399440
return externModules.contains(refName) ||
400-
llvm::none_of(op->getOperands(), [](auto operand) {
401-
return isStructType(operand.getType());
402-
});
441+
(llvm::none_of(op->getOperands(),
442+
[](auto operand) {
443+
return isStructType(operand.getType());
444+
}) &&
445+
llvm::none_of(op->getResultTypes(),
446+
[](auto result) { return isStructType(result); }));
403447
});
404448

405449
DenseMap<Operation *, ArrayAttr> oldArgNames, oldResNames;
@@ -498,7 +542,7 @@ class FlattenIOPass : public circt::hw::impl::FlattenIOBase<FlattenIOPass> {
498542
void runOnOperation() override {
499543
ModuleOp module = getOperation();
500544
if (!flattenExtern) {
501-
// Record the extern modules, donot flatten them.
545+
// Record the extern modules, do not flatten them.
502546
for (auto m : module.getOps<hw::HWModuleExternOp>())
503547
externModules.insert(m.getModuleName());
504548
if (flattenIO<hw::HWModuleOp, hw::HWModuleGeneratedOp>(

llvm

Submodule llvm updated 11507 files

test/Dialect/HW/flatten-io.mlir

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,18 @@ hw.module @level0(in %arg0 : i32, out out0 : i32) {
1111
}
1212

1313
// BASIC-LABEL: hw.module @level1(in %arg0 : i32, in %in.a : i1, in %in.b : i2, in %arg1 : i32, out out0 : i32, out out.a : i1, out out.b : i2, out out1 : i32) {
14-
// BASIC-NEXT: %0 = hw.struct_create (%in.a, %in.b) : !hw.struct<a: i1, b: i2>
15-
// BASIC-NEXT: %a, %b = hw.struct_explode %0 : !hw.struct<a: i1, b: i2>
16-
// BASIC-NEXT: hw.output %arg0, %a, %b, %arg1 : i32, i1, i2, i32
14+
// BASIC-NEXT: hw.output %arg0, %in.a, %in.b, %arg1 : i32, i1, i2, i32
1715
// BASIC-NEXT: }
1816
!Struct1 = !hw.struct<a: i1, b: i2>
1917
hw.module @level1(in %arg0 : i32, in %in : !Struct1, in %arg1: i32, out out0 : i32, out out: !Struct1, out out1: i32) {
2018
hw.output %arg0, %in, %arg1 : i32, !Struct1, i32
2119
}
2220

2321
// BASIC-LABEL: hw.module @level2(in %in.aa.a : i1, in %in.aa.b : i2, in %in.bb.a : i1, in %in.bb.b : i2, out out.aa.a : i1, out out.aa.b : i2, out out.bb.a : i1, out out.bb.b : i2) {
24-
// BASIC-NEXT: %[[v1:.+]] = hw.struct_create (%in.bb.a, %in.bb.b) : !hw.struct<a: i1, b: i2>
25-
// BASIC-NEXT: %[[v0:.+]] = hw.struct_create (%in.aa.a, %in.aa.b) : !hw.struct<a: i1, b: i2>
26-
// BASIC-NEXT: %[[v2:.+]] = hw.struct_create (%[[v0]], %[[v1]]) : !hw.struct<aa: !hw.struct<a: i1, b: i2>, bb: !hw.struct<a: i1, b: i2>>
27-
// BASIC-NEXT: %aa, %bb = hw.struct_explode %[[v2]] : !hw.struct<aa: !hw.struct<a: i1, b: i2>, bb: !hw.struct<a: i1, b: i2>>
28-
// BASIC-NEXT: %a, %b = hw.struct_explode %aa : !hw.struct<a: i1, b: i2>
29-
// BASIC-NEXT: %a_0, %b_1 = hw.struct_explode %bb : !hw.struct<a: i1, b: i2>
22+
// BASIC-NEXT: %0 = hw.struct_create (%in.bb.a, %in.bb.b) : !hw.struct<a: i1, b: i2>
23+
// BASIC-NEXT: %1 = hw.struct_create (%in.aa.a, %in.aa.b) : !hw.struct<a: i1, b: i2>
24+
// BASIC-NEXT: %a, %b = hw.struct_explode %1 : !hw.struct<a: i1, b: i2>
25+
// BASIC-NEXT: %a_0, %b_1 = hw.struct_explode %0 : !hw.struct<a: i1, b: i2>
3026
// BASIC-NEXT: hw.output %a, %b, %a_0, %b_1 : i1, i2, i1, i2
3127
// BASIC-NEXT: }
3228
!Struct2 = !hw.struct<aa: !Struct1, bb: !Struct1>
@@ -40,30 +36,26 @@ hw.type_scope @foo {
4036
!ScopedStruct = !hw.typealias<@foo::@bar, !Struct1>
4137

4238
// BASIC-LABEL: hw.module @scoped(in %arg0 : i32, in %in.a : i1, in %in.b : i2, in %arg1 : i32, out out0 : i32, out out.a : i1, out out.b : i2, out out1 : i32) {
43-
// BASIC-NEXT: %0 = hw.struct_create (%in.a, %in.b) : !hw.typealias<@foo::@bar, !hw.struct<a: i1, b: i2>>
44-
// BASIC-NEXT: %a, %b = hw.struct_explode %0 : !hw.typealias<@foo::@bar, !hw.struct<a: i1, b: i2>>
45-
// BASIC-NEXT: hw.output %arg0, %a, %b, %arg1 : i32, i1, i2, i32
39+
// BASIC-NEXT: hw.output %arg0, %in.a, %in.b, %arg1 : i32, i1, i2, i32
4640
// BASIC-NEXT: }
4741
hw.module @scoped(in %arg0 : i32, in %in : !ScopedStruct, in %arg1: i32, out out0 : i32, out out: !ScopedStruct, out out1: i32) {
4842
hw.output %arg0, %in, %arg1 : i32, !ScopedStruct, i32
4943
}
5044

5145
// BASIC-LABEL: hw.module @instance(in %arg0 : i32, in %arg1.a : i1, in %arg1.b : i2, out out.a : i1, out out.b : i2) {
52-
// BASIC-NEXT: %0 = hw.struct_create (%arg1.a, %arg1.b) : !hw.struct<a: i1, b: i2>
53-
// BASIC-NEXT: %a, %b = hw.struct_explode %0 : !hw.struct<a: i1, b: i2>
54-
// BASIC-NEXT: %l1.out0, %l1.out.a, %l1.out.b, %l1.out1 = hw.instance "l1" @level1(arg0: %arg0: i32, in.a: %a: i1, in.b: %b: i2, arg1: %arg0: i32) -> (out0: i32, out.a: i1, out.b: i2, out1: i32)
55-
// BASIC-NEXT: %1 = hw.struct_create (%l1.out.a, %l1.out.b) : !hw.struct<a: i1, b: i2>
56-
// BASIC-NEXT: %a_0, %b_1 = hw.struct_explode %1 : !hw.struct<a: i1, b: i2>
57-
// BASIC-NEXT: hw.output %a_0, %b_1 : i1, i2
46+
// BASIC-NEXT: %l1.out0, %l1.out.a, %l1.out.b, %l1.out1 = hw.instance "l1" @level1(arg0: %arg0: i32, in.a: %arg1.a: i1, in.b: %arg1.b: i2, arg1: %arg0: i32) -> (out0: i32, out.a: i1, out.b: i2, out1: i32)
47+
// BASIC-NEXT: %0 = hw.struct_create (%l1.out.a, %l1.out.b) : !hw.struct<a: i1, b: i2>
48+
// BASIC-NEXT: %a, %b = hw.struct_explode %0 : !hw.struct<a: i1, b: i2>
49+
// BASIC-NEXT: hw.output %a, %b : i1, i2
5850
// BASIC-NEXT: }
5951
hw.module @instance(in %arg0 : i32, in %arg1 : !Struct1, out out : !Struct1) {
6052
%0:3 = hw.instance "l1" @level1(arg0: %arg0 : i32, in: %arg1 : !Struct1, arg1: %arg0 : i32) -> (out0: i32, out: !Struct1, out1: i32)
6153
hw.output %0#1 : !Struct1
6254
}
6355

64-
hw.module.extern @level1_extern2(out out1: i32, in %arg0 : i32, out out: !Struct1, in %in : !Struct1, in %arg1: i32, out out0 : i32 )
6556
// EXTERN-LABEL: hw.module.extern @level1_extern2
6657
// EXTERN-SAME: out out1 : i32, in %arg0 : i32, out out_a : i1, out out_b : i2, in %in_a : i1, in %in_b : i2, in %arg1 : i32, out out0 : i32
58+
hw.module.extern @level1_extern2(out out1: i32, in %arg0 : i32, out out: !Struct1, in %in : !Struct1, in %arg1: i32, out out0 : i32 )
6759

6860
hw.module @instance_extern2(in %arg0 : i32, in %arg1 : !Struct1, out out : !Struct1) {
6961
%0:3 = hw.instance "l1" @level1_extern(arg0: %arg0 : i32, in: %arg1 : !Struct1, arg1: %arg0 : i32) -> (out0: i32, out: !Struct1, out1: i32)
@@ -76,14 +68,12 @@ hw.module @instance_extern2(in %arg0 : i32, in %arg1 : !Struct1, out out : !Stru
7668
hw.module.extern @level1_extern(in %arg0 : i32, in %in : !Struct1, in %arg1: i32, out out0 : i32, out out: !Struct1, out out1: i32)
7769

7870

79-
// EXTERN-LABEL: hw.module @instance_extern(in %arg0 : i32, in %arg1_a : i1, in %arg1_b : i2, out out_a : i1, out out_b : i2) {
80-
// EXTERN-NEXT: %0 = hw.struct_create (%arg1_a, %arg1_b) : !hw.struct<a: i1, b: i2>
81-
// EXTERN-NEXT: %a, %b = hw.struct_explode %0 : !hw.struct<a: i1, b: i2>
82-
// EXTERN-NEXT: %l1.out0, %l1.out_a, %l1.out_b, %l1.out1 = hw.instance "l1" @level1_extern(arg0: %arg0: i32, in_a: %a: i1, in_b: %b: i2, arg1: %arg0: i32) -> (out0: i32, out_a: i1, out_b: i2, out1: i32)
83-
// EXTERN-NEXT: %1 = hw.struct_create (%l1.out_a, %l1.out_b) : !hw.struct<a: i1, b: i2>
84-
// EXTERN-NEXT: %a_0, %b_1 = hw.struct_explode %1 : !hw.struct<a: i1, b: i2>
85-
// EXTERN-NEXT: hw.output %a_0, %b_1 : i1, i2
86-
71+
// EXTERN-LABEL: hw.module @instance_extern(in %arg0 : i32, in %arg1_a : i1, in %arg1_b : i2, out out_a : i1, out out_b : i2) {
72+
// EXTERN-NEXT: %l1.out0, %l1.out_a, %l1.out_b, %l1.out1 = hw.instance "l1" @level1_extern(arg0: %arg0: i32, in_a: %arg1_a: i1, in_b: %arg1_b: i2, arg1: %arg0: i32) -> (out0: i32, out_a: i1, out_b: i2, out1: i32)
73+
// EXTERN-NEXT: %0 = hw.struct_create (%l1.out_a, %l1.out_b) : !hw.struct<a: i1, b: i2>
74+
// EXTERN-NEXT: %a, %b = hw.struct_explode %0 : !hw.struct<a: i1, b: i2>
75+
// EXTERN-NEXT: hw.output %a, %b : i1, i2
76+
// EXTERN-NEXT: }
8777
hw.module @instance_extern(in %arg0 : i32, in %arg1 : !Struct1, out out : !Struct1) {
8878
%0:3 = hw.instance "l1" @level1_extern(arg0: %arg0 : i32, in: %arg1 : !Struct1, arg1: %arg0 : i32) -> (out0: i32, out: !Struct1, out1: i32)
8979
hw.output %0#1 : !Struct1

test/Dialect/SMT/core-errors.mlir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ func.func @func_range_no_smt_type(%arg0: !smt.func<(!smt.bool) !smt.func<(!smt.b
460460
// -----
461461

462462
func.func @func_range_no_smt_type(%arg0: !smt.func<(!smt.bool) !smt.bool>) {
463-
// expected-error @below {{0 operands present, but expected 1}}
463+
// expected-error @below {{got 0 operands and 1 types}}
464464
smt.apply_func %arg0() : !smt.func<(!smt.bool) !smt.bool>
465465
return
466466
}

0 commit comments

Comments
 (0)