@@ -1460,7 +1460,7 @@ mlir::Type lowerArrayType(cir::ArrayType type, bool hasValueSemantics,
14601460 shape.push_back (arrayType.getSize ());
14611461 curType = arrayType.getEltType ();
14621462 }
1463- auto elementType = converter. convertType ( curType);
1463+ auto elementType = convertTypeForMemory (converter, curType);
14641464 // FIXME: The element type might not be converted
14651465 if (!elementType)
14661466 return nullptr ;
@@ -1475,13 +1475,17 @@ mlir::Type lowerArrayType(cir::ArrayType type, bool hasValueSemantics,
14751475mlir::TypeConverter prepareTypeConverter (mlir::DataLayout &dataLayout) {
14761476 mlir::TypeConverter converter;
14771477 converter.addConversion ([&](cir::PointerType type) -> mlir::Type {
1478- auto ty = convertTypeForMemory (converter, type.getPointee ());
1478+ auto pointeeType = type.getPointee ();
1479+ if (mlir::isa<cir::ArrayType>(pointeeType))
1480+ // A pointer to an array gives the array a reference semantics, lower to a
1481+ // memref.
1482+ return lowerArrayType (mlir::cast<cir::ArrayType>(pointeeType),
1483+ /* hasValueSemantics */ false , converter);
1484+ auto ty = convertTypeForMemory (converter, pointeeType);
14791485 // FIXME: The pointee type might not be converted (e.g. struct)
14801486 if (!ty)
14811487 return nullptr ;
1482- if (isa<cir::ArrayType>(type.getPointee ()))
1483- // An array is already lowered as a memref with reference semantics
1484- return ty;
1488+ // Each level of pointer becomes a level of memref
14851489 return mlir::MemRefType::get ({}, ty);
14861490 });
14871491 converter.addConversion (
@@ -1520,23 +1524,15 @@ mlir::TypeConverter prepareTypeConverter(mlir::DataLayout &dataLayout) {
15201524 return mlir::BFloat16Type::get (type.getContext ());
15211525 });
15221526 converter.addConversion ([&](cir::ArrayType type) -> mlir::Type {
1523- // Arrays in C/C++ have a reference semantics when not in a
1524- // class/struct/union, so use a memref .
1525- return lowerArrayType (type, /* hasValueSemantics */ false , converter);
1527+ // Assume we are in a class/struct/union context with value semantics, so
1528+ // lower as a tensor .
1529+ return lowerArrayType (type, /* hasValueSemantics */ true , converter);
15261530 });
15271531 converter.addConversion ([&](cir::VectorType type) -> mlir::Type {
15281532 auto ty = converter.convertType (type.getEltType ());
15291533 return mlir::VectorType::get (type.getSize (), ty);
15301534 });
15311535 converter.addConversion ([&](cir::StructType type) -> mlir::Type {
1532- auto convertWithValueSemanticsArray = [&](mlir::Type t) {
1533- if (mlir::isa<cir::ArrayType>(t))
1534- // Inside a class/struct/union, an array has value semantics and is
1535- // lowered as a tensor.
1536- return lowerArrayType (mlir::cast<cir::ArrayType>(t),
1537- /* hasValueSemantics */ true , converter);
1538- return converter.convertType (t);
1539- };
15401536 // FIXME(cir): create separate unions, struct, and classes types.
15411537 // Convert struct members.
15421538 llvm::SmallVector<mlir::Type> mlirMembers;
@@ -1545,13 +1541,13 @@ mlir::TypeConverter prepareTypeConverter(mlir::DataLayout &dataLayout) {
15451541 // TODO(cir): This should be properly validated.
15461542 case cir::StructType::Struct:
15471543 for (auto ty : type.getMembers ())
1548- mlirMembers.push_back (convertWithValueSemanticsArray (ty));
1544+ mlirMembers.push_back (converter. convertType (ty));
15491545 break ;
15501546 // Unions are lowered as only the largest member.
15511547 case cir::StructType::Union: {
15521548 auto largestMember = type.getLargestMember (dataLayout);
15531549 if (largestMember)
1554- mlirMembers.push_back (convertWithValueSemanticsArray (largestMember));
1550+ mlirMembers.push_back (converter. convertType (largestMember));
15551551 break ;
15561552 }
15571553 }
0 commit comments