[MooreToCore] Fix variable op lowering of aggregate types (#7481)

This commit is contained in:
Martin Erhart 2024-08-09 08:46:31 +01:00 committed by GitHub
parent fa95071921
commit 84d73b94aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 11 deletions

View File

@ -158,6 +158,7 @@ struct VariableOpConversion : public OpConversionPattern<VariableOp> {
LogicalResult
matchAndRewrite(VariableOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override {
Location loc = op.getLoc();
Type resultType = typeConverter->convertType(op.getResult().getType());
Value init = adaptor.getInitial();
// TODO: Unsupport x/z, so the initial value is 0.
@ -165,10 +166,18 @@ struct VariableOpConversion : public OpConversionPattern<VariableOp> {
Domain::FourValued)
return failure();
if (!init)
init = rewriter.create<hw::ConstantOp>(op->getLoc(), resultType, 0);
rewriter.replaceOpWithNewOp<llhd::SigOp>(op, hw::InOutType::get(resultType),
op.getNameAttr(), init);
if (!init) {
Type elementType = cast<hw::InOutType>(resultType).getElementType();
int64_t width = hw::getBitWidth(elementType);
if (width == -1)
return failure();
Value constZero = rewriter.create<hw::ConstantOp>(loc, APInt(width, 0));
init = rewriter.createOrFold<hw::BitcastOp>(loc, elementType, constZero);
}
rewriter.replaceOpWithNewOp<llhd::SigOp>(op, resultType, op.getNameAttr(),
init);
return success();
}
};
@ -715,10 +724,7 @@ static void populateTypeConversion(TypeConverter &typeConverter) {
});
typeConverter.addConversion([&](RefType type) -> std::optional<Type> {
if (isa<IntType, ArrayType, UnpackedArrayType>(type.getNestedType()))
return mlir::IntegerType::get(type.getContext(),
type.getBitSize().value());
return std::nullopt;
return hw::InOutType::get(typeConverter.convertType(type.getNestedType()));
});
// Valid target types.

View File

@ -312,9 +312,20 @@ moore.module @Variable() {
moore.output
}
// CHECK-LABEL: func @Struct
func.func @Struct(%arg0: !moore.struct<{exp_bits: i32, man_bits: i32}>) -> !moore.i32 {
// CHECK-LABEL: hw.module @Struct
moore.module @Struct(in %arg0 : !moore.struct<{exp_bits: i32, man_bits: i32}>, out a : !moore.i32, out b : !moore.struct<{exp_bits: i32, man_bits: i32}>, out c : !moore.struct<{exp_bits: i32, man_bits: i32}>) {
// CHECK: hw.struct_extract %arg0["exp_bits"] : !hw.struct<exp_bits: i32, man_bits: i32>
%0 = moore.struct_extract %arg0, "exp_bits" : !moore.struct<{exp_bits: i32, man_bits: i32}> -> i32
return %0 : !moore.i32
// CHECK: [[C0:%.+]] = hw.constant 0 : i64
// CHECK: [[INIT:%.+]] = hw.bitcast [[C0]] : (i64) -> !hw.struct<exp_bits: i32, man_bits: i32>
// CHECK: llhd.sig "" [[INIT]] : !hw.struct<exp_bits: i32, man_bits: i32>
// CHECK: llhd.sig "" %arg0 : !hw.struct<exp_bits: i32, man_bits: i32>
%1 = moore.variable : <struct<{exp_bits: i32, man_bits: i32}>>
%2 = moore.variable %arg0 : <struct<{exp_bits: i32, man_bits: i32}>>
%3 = moore.read %1 : <struct<{exp_bits: i32, man_bits: i32}>>
%4 = moore.read %2 : <struct<{exp_bits: i32, man_bits: i32}>>
moore.output %0, %3, %4 : !moore.i32, !moore.struct<{exp_bits: i32, man_bits: i32}>, !moore.struct<{exp_bits: i32, man_bits: i32}>
}