Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@ def LLVMStructType : LLVMType<"LLVMStruct", "struct", [
ArrayRef<Type> elements,
bool isPacked = false);

static LLVMStructType getUniquedIdentified(MLIRContext *context, StringRef name,
ArrayRef<Type> elements,
bool isPacked = false);

/// Gets or creates a literal struct with the given body in the provided
/// context.
static LLVMStructType getLiteral(MLIRContext *context, ArrayRef<Type> types,
Expand Down
17 changes: 11 additions & 6 deletions mlir/lib/Dialect/LLVMIR/IR/LLVMTypeSyntax.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,8 @@ Type LLVMStructType::parse(AsmParser &parser) {
if (!isIdentified)
return LLVMStructType::getLiteralChecked([loc] { return emitError(loc); },
loc.getContext(), {}, isPacked);
auto type = LLVMStructType::getIdentifiedChecked(
[loc] { return emitError(loc); }, loc.getContext(), name);
return trySetStructBody(type, {}, isPacked, parser, kwLoc);
auto type = LLVMStructType::getUniquedIdentified(loc.getContext(), name, {}, isPacked);
return type;
}

// Parse subtypes. For identified structs, put the identifier of the struct on
Expand All @@ -272,9 +271,15 @@ Type LLVMStructType::parse(AsmParser &parser) {
if (!isIdentified)
return LLVMStructType::getLiteralChecked(
[loc] { return emitError(loc); }, loc.getContext(), subtypes, isPacked);
auto type = LLVMStructType::getIdentifiedChecked(
[loc] { return emitError(loc); }, loc.getContext(), name);
return trySetStructBody(type, subtypes, isPacked, parser, subtypesLoc);
for (Type t : subtypes) {
if (!LLVMStructType::isValidElementType(t)) {
parser.emitError(subtypesLoc)
<< "invalid LLVM structure element type: " << t;
return LLVMStructType();
}
}
auto type = LLVMStructType::getUniquedIdentified(loc.getContext(), name, subtypes, isPacked);
return type;
}

/// Parses a type appearing inside another LLVM dialect-compatible type. This
Expand Down
16 changes: 16 additions & 0 deletions mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,22 @@ LLVMStructType LLVMStructType::getIdentifiedChecked(
return Base::getChecked(emitError, context, name, /*opaque=*/false);
}

LLVMStructType LLVMStructType::getUniquedIdentified(MLIRContext *context,
StringRef name,
ArrayRef<Type> elements,
bool isPacked) {
std::string stringName = name.str();
unsigned counter = 1;
do {
auto type = LLVMStructType::getIdentified(context, stringName);
if (failed(type.setBody(elements, isPacked))) {
stringName = (Twine(name) + "." + Twine(counter++)).str();
continue;
}
return type;
} while (true);
}

LLVMStructType LLVMStructType::getNewIdentified(MLIRContext *context,
StringRef name,
ArrayRef<Type> elements,
Expand Down
29 changes: 29 additions & 0 deletions mlir/test/Dialect/LLVMIR/struct_type_conflict.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// RUN: mlir-opt %s -o - | FileCheck %s

module {
llvm.func @foo(%arg0: i32) -> i32 attributes {dso_local} {
%0 = llvm.mlir.constant(1 : i32) : i32
%1 = llvm.mlir.constant(0 : i32) : i32
// CHECK: !llvm.struct<"struct.S", (i32)>
%2 = llvm.alloca %0 x !llvm.struct<"struct.S", (i32)> {alignment = 4 : i64} : (i32) -> !llvm.ptr
%3 = llvm.getelementptr inbounds %2[%1, 0] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<"struct.S", (i32)>
llvm.store %arg0, %3 {alignment = 4 : i64} : i32, !llvm.ptr
%4 = llvm.getelementptr inbounds %2[%1, 0] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<"struct.S", (i32)>
%5 = llvm.load %4 {alignment = 4 : i64} : !llvm.ptr -> i32
llvm.return %5 : i32
}
}

module {
llvm.func @getX(%arg0: !llvm.struct<"struct.S", (i32, i1, i32)>) -> i32 attributes {dso_local} {
%0 = llvm.mlir.constant(1 : i32) : i32
%1 = llvm.mlir.constant(0 : i32) : i32
// CHECK: !llvm.struct<"struct.S.1", (i32, i1, i32)>
%2 = llvm.alloca %0 x !llvm.struct<"struct.S", (i32, i1, i32)> {alignment = 4 : i64} : (i32) -> !llvm.ptr
%3 = llvm.getelementptr inbounds %2[%1, 0] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<"struct.S", (i32, i1, i32)>
llvm.store %arg0, %3 {alignment = 4 : i64} : !llvm.struct<"struct.S", (i32, i1, i32)>, !llvm.ptr
%4 = llvm.getelementptr inbounds %2[%1, 0] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<"struct.S", (i32, i1, i32)>
%5 = llvm.load %4 {alignment = 4 : i64} : !llvm.ptr -> i32
llvm.return %5 : i32
}
}
1 change: 1 addition & 0 deletions mlir/test/Dialect/LLVMIR/types-invalid.mlir
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: mlir-opt --allow-unregistered-dialect -split-input-file -verify-diagnostics %s
// REQUIRES: modified-named-struct-type-parser

func.func @array_of_void() {
// expected-error @+1 {{invalid array element type}}
Expand Down