[clang] fa0638e - [CIR] Cast alloca for function parameter to the right address space (#220836)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 8 03:48:02 PDT 2026
Author: Mariya Podchishchaeva
Date: 2026-09-08T12:47:58+02:00
New Revision: fa0638edc6628ce2c386519ffdcbdcf35513e67e
URL: https://github.com/llvm/llvm-project/commit/fa0638edc6628ce2c386519ffdcbdcf35513e67e
DIFF: https://github.com/llvm/llvm-project/commit/fa0638edc6628ce2c386519ffdcbdcf35513e67e.diff
LOG: [CIR] Cast alloca for function parameter to the right address space (#220836)
Function parameters are stored into temporary allocas and for
address-space aware targets allocas may yield pointers to address spaces
that are different from default address space or the address space of
the parameter type. Do a cast to avoid mismatch. The address space
mismatch was reproduced using cir.ternary op returning a function
parameter and a local variable. For local variables and return
temporaries we already cast alloca address space to temporary address
space but not for function parameter allocas.
Added:
clang/test/CIR/CodeGenHIP/ternary-struct-addrspace.hip
Modified:
clang/lib/CIR/CodeGen/CIRGenFunction.cpp
clang/lib/CIR/CodeGen/CIRGenFunction.h
clang/test/CIR/CodeGenOpenMP/target-map.c
Removed:
################################################################################
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 25ae08364713b..6da9e8ac88e16 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -488,10 +488,17 @@ void CIRGenFunction::emitFunctionProlog(const FunctionArgList &args,
convertType(paramVar->getType()), paramLoc, alignment,
/*insertIntoFnEntryBlock=*/true);
- declare(addrVal, paramVar, paramVar->getType(), paramLoc, alignment,
+ mlir::ptr::MemorySpaceAttrInterface destAddrSpace =
+ cir::toCIRAddressSpaceAttr(getMLIRContext(),
+ paramVar->getType().getAddressSpace());
+ Address addr = Address(addrVal, alignment);
+ addr = maybeCastStackAddressSpace(addr, destAddrSpace);
+
+ declare(addr.getPointer(), paramVar, paramVar->getType(), paramLoc,
+ alignment,
/*isParam=*/true);
- setAddrOfLocalVar(paramVar, Address(addrVal, alignment));
+ setAddrOfLocalVar(paramVar, addr);
bool isPromoted = isa<ParmVarDecl>(paramVar) &&
cast<ParmVarDecl>(paramVar)->isKNRPromoted();
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index fe5ff90c25bef..8547a77e86faf 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -2548,7 +2548,7 @@ class CIRGenFunction : public CIRGenTypeCache {
Address
maybeCastStackAddressSpace(Address alloca,
mlir::ptr::MemorySpaceAttrInterface destAddrSpace,
- mlir::Value arraySize);
+ mlir::Value arraySize = nullptr);
Address createDefaultAlignTempAlloca(mlir::Type ty, mlir::Location loc,
const Twine &name);
diff --git a/clang/test/CIR/CodeGenHIP/ternary-struct-addrspace.hip b/clang/test/CIR/CodeGenHIP/ternary-struct-addrspace.hip
new file mode 100644
index 0000000000000..8dfbe163fa090
--- /dev/null
+++ b/clang/test/CIR/CodeGenHIP/ternary-struct-addrspace.hip
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -x hip -fclangir -fcuda-is-device -emit-cir %s -o - | FileCheck %s
+
+// Verify that a ternary expression returning a struct parameter from a
+// __device__ function produces a well-typed cir.ternary: both branch yields
+// and the result must all carry the same pointer type (no address-space
+// mismatch between the private-address-space alloca and the cast result).
+
+struct S { int a; };
+
+__attribute__((device)) bool cmp(S, S);
+
+__attribute__((device)) S choose(const S x) {
+ S y = x;
+ return cmp(x, y) ? x : y;
+}
+
+
+// CHECK: %[[X:.*]] = cir.alloca "x" {{.*}} : !cir.ptr<!rec_S, target_address_space(5)>
+// CHECK: %[[Y:.*]] = cir.alloca "y" {{.*}} : !cir.ptr<!rec_S, target_address_space(5)> loc(#loc18)
+
+// CHECK: %[[Y_CAST:.*]] = cir.cast address_space %[[Y]] : !cir.ptr<!rec_S, target_address_space(5)> -> !cir.ptr<!rec_S>
+// CHECK: %[[X_CAST:.*]] = cir.cast address_space %[[X]] : !cir.ptr<!rec_S, target_address_space(5)> -> !cir.ptr<!rec_S>
+
+// CHECK: %[[TERNARY:.*]] = cir.ternary({{.*}}, true {
+// CHECK: cir.yield %[[X_CAST]] : !cir.ptr<!rec_S>
+// CHECK: }, false {
+// CHECK: cir.yield %[[Y_CAST]] : !cir.ptr<!rec_S>
+// CHECK: }) : (!cir.bool) -> !cir.ptr<!rec_S>
diff --git a/clang/test/CIR/CodeGenOpenMP/target-map.c b/clang/test/CIR/CodeGenOpenMP/target-map.c
index a4218a8c4a97d..11a00e3fd094d 100644
--- a/clang/test/CIR/CodeGenOpenMP/target-map.c
+++ b/clang/test/CIR/CodeGenOpenMP/target-map.c
@@ -89,9 +89,9 @@ void target_map_multiple(int a, int b) {
// CIR-DEVICE: cir.func{{.*}}@target_map_multiple
// CIR-DEVICE-DAG: %[[A_ALLOCA:.*]] = cir.alloca "a" align(4) init : !cir.ptr<!s32i, target_address_space(5)>
// CIR-DEVICE-DAG: %[[B_ALLOCA:.*]] = cir.alloca "b" align(4) init : !cir.ptr<!s32i, target_address_space(5)>
+ // CIR-DEVICE: %[[CAST_B:.*]] = cir.cast address_space %[[B_ALLOCA]] : !cir.ptr<!s32i, target_address_space(5)> -> !cir.ptr<!s32i>
// CIR-DEVICE: %[[CAST_A:.*]] = cir.cast address_space %[[A_ALLOCA]] : !cir.ptr<!s32i, target_address_space(5)> -> !cir.ptr<!s32i>
// CIR-DEVICE: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[CAST_A]] : !cir.ptr<!s32i>, !s32i) map_clauses(to) capture(ByRef) name("a") -> !cir.ptr<!s32i>
- // CIR-DEVICE: %[[CAST_B:.*]] = cir.cast address_space %[[B_ALLOCA]] : !cir.ptr<!s32i, target_address_space(5)> -> !cir.ptr<!s32i>
// CIR-DEVICE: %[[MAP_B:.*]] = omp.map.info var_ptr(%[[CAST_B]] : !cir.ptr<!s32i>, !s32i) map_clauses(from) capture(ByRef) name("b") -> !cir.ptr<!s32i>
// CIR-DEVICE: omp.target kernel_type(generic) map_entries(%[[MAP_A]] -> %[[ARG_A:.*]], %[[MAP_B]] -> %[[ARG_B:.*]] : !cir.ptr<!s32i>, !cir.ptr<!s32i>) {
// CIR-DEVICE: omp.terminator
More information about the cfe-commits
mailing list