diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index bc97a065f74c..6b9f6b6aa4e2 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -2231,7 +2231,8 @@ def GetGlobalOp : CIR_Op<"get_global", The `cir.get_global` operation retrieves the address pointing to a named global variable. If the global variable is marked constant, writing to the resulting address (such as through a `cir.store` operation) is - undefined. Resulting type must always be a `!cir.ptr<...>` type. + undefined. Resulting type must always be a `!cir.ptr<...>` type with the + same address space as the global variable. Addresses of thread local globals can only be retrieved if this operation is marked `thread_local`, which indicates the address isn't constant. @@ -2241,6 +2242,9 @@ def GetGlobalOp : CIR_Op<"get_global", %x = cir.get_global @foo : !cir.ptr ... %y = cir.get_global thread_local @batata : !cir.ptr + ... + cir.global external addrspace(offload_global) @gv = #cir.int<0> : !s32i + %z = cir.get_global @gv : !cir.ptr ``` }]; diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 686e71f66de7..1b35d62b281f 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -2044,8 +2044,10 @@ GetGlobalOp::verifySymbolUses(SymbolTableCollection &symbolTable) { << "' does not reference a valid cir.global or cir.func"; mlir::Type symTy; + mlir::cir::AddressSpaceAttr symAddrSpace{}; if (auto g = dyn_cast(op)) { symTy = g.getSymType(); + symAddrSpace = g.getAddrSpaceAttr(); // Verify that for thread local global access, the global needs to // be marked with tls bits. if (getTls() && !g.getTlsModel()) @@ -2060,6 +2062,14 @@ GetGlobalOp::verifySymbolUses(SymbolTableCollection &symbolTable) { return emitOpError("result type pointee type '") << resultType.getPointee() << "' does not match type " << symTy << " of the global @" << getName(); + + if (symAddrSpace != resultType.getAddrSpace()) { + return emitOpError() + << "result type address space does not match the address " + "space of the global @" + << getName(); + } + return success(); } diff --git a/clang/test/CIR/IR/invalid.cir b/clang/test/CIR/IR/invalid.cir index fbbe3a0b7d87..182845fa2b6f 100644 --- a/clang/test/CIR/IR/invalid.cir +++ b/clang/test/CIR/IR/invalid.cir @@ -1272,3 +1272,16 @@ module { } } +// ----- + +!s32i = !cir.int + +module { + cir.global external addrspace(offload_global) @gv = #cir.int<0> : !s32i + + cir.func @test_get_global() { + // expected-error@+1 {{'cir.get_global' op result type address space does not match the address space of the global @gv}} + %addr = cir.get_global @gv : !cir.ptr + cir.return + } +}