diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td @@ -92,7 +92,7 @@ // Type constraint accepting any LLVM pointer type. def LLVM_AnyPointer : Type()">, - "LLVM pointer type">; + "LLVM pointer type", "::mlir::LLVM::LLVMPointerType">; // Type constraint accepting LLVM pointer type with an additional constraint // on the element type. @@ -103,7 +103,7 @@ "$_self", "$_self.cast<::mlir::LLVM::LLVMPointerType>().getElementType()", pointee.predicate>]>]>, - "LLVM pointer to " # pointee.summary>; + "LLVM pointer to " # pointee.summary, "::mlir::LLVM::LLVMPointerType">; // Type constraints accepting LLVM pointer type to integer of a specific width. class LLVM_IntPtrBase : Type< diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -827,7 +827,7 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof", [NoSideEffect]> { let arguments = (ins FlatSymbolRefAttr:$global_name); - let results = (outs LLVM_Type:$res); + let results = (outs LLVM_AnyPointer:$res); let summary = "Creates a pointer pointing to a global or a function"; diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -1654,14 +1654,19 @@ return emitOpError( "must reference a global defined by 'llvm.mlir.global' or 'llvm.func'"); - if (global && - LLVM::LLVMPointerType::get(global.getType(), global.getAddrSpace()) != - getResult().getType()) + LLVMPointerType type = getType(); + if (global && global.getAddrSpace() != type.getAddressSpace()) + return emitOpError("pointer address space must match address space of the " + "referenced global"); + + if (type.isOpaque()) + return success(); + + if (global && type.getElementType() != global.getType()) return emitOpError( "the type must be a pointer to the type of the referenced global"); - if (function && LLVM::LLVMPointerType::get(function.getFunctionType()) != - getResult().getType()) + if (function && type.getElementType() != function.getFunctionType()) return emitOpError( "the type must be a pointer to the type of the referenced function"); diff --git a/mlir/test/Dialect/LLVMIR/global.mlir b/mlir/test/Dialect/LLVMIR/global.mlir --- a/mlir/test/Dialect/LLVMIR/global.mlir +++ b/mlir/test/Dialect/LLVMIR/global.mlir @@ -61,6 +61,8 @@ llvm.mlir.global external @has_thr_local(42 : i64) {thr_local} : i64 // CHECK: llvm.mlir.global external @has_dso_local(42 : i64) {dso_local} : i64 llvm.mlir.global external @has_dso_local(42 : i64) {dso_local} : i64 +// CHECK: llvm.mlir.global external @has_addr_space(32 : i64) {addr_space = 3 : i32} : i64 +llvm.mlir.global external @has_addr_space(32 : i64) {addr_space = 3: i32} : i64 // CHECK-LABEL: references func.func @references() { @@ -70,6 +72,12 @@ // CHECK: llvm.mlir.addressof @".string" : !llvm.ptr> %1 = llvm.mlir.addressof @".string" : !llvm.ptr> + // CHECK: llvm.mlir.addressof @global : !llvm.ptr + %2 = llvm.mlir.addressof @global : !llvm.ptr + + // CHECK: llvm.mlir.addressof @has_addr_space : !llvm.ptr<3> + %3 = llvm.mlir.addressof @has_addr_space : !llvm.ptr<3> + llvm.return } @@ -201,7 +209,7 @@ llvm.mlir.global internal @g(32 : i64) {addr_space = 3: i32} : i64 func.func @mismatch_addr_space_implicit_global() { - // expected-error @+1 {{op the type must be a pointer to the type of the referenced global}} + // expected-error @+1 {{pointer address space must match address space of the referenced global}} llvm.mlir.addressof @g : !llvm.ptr } @@ -209,9 +217,17 @@ llvm.mlir.global internal @g(32 : i64) {addr_space = 3: i32} : i64 func.func @mismatch_addr_space() { - // expected-error @+1 {{op the type must be a pointer to the type of the referenced global}} + // expected-error @+1 {{pointer address space must match address space of the referenced global}} llvm.mlir.addressof @g : !llvm.ptr } +// ----- + +llvm.mlir.global internal @g(32 : i64) {addr_space = 3: i32} : i64 + +func.func @mismatch_addr_space_opaque() { + // expected-error @+1 {{pointer address space must match address space of the referenced global}} + llvm.mlir.addressof @g : !llvm.ptr<4> +} // ----- diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir --- a/mlir/test/Dialect/LLVMIR/invalid.mlir +++ b/mlir/test/Dialect/LLVMIR/invalid.mlir @@ -508,7 +508,7 @@ // ----- func.func @null_non_llvm_type() { - // expected-error@+1 {{must be LLVM pointer type, but got 'i32'}} + // expected-error@+1 {{custom op 'llvm.mlir.null' invalid kind of type specified}} llvm.mlir.null : i32 }