Skip to content

Commit a6f709a

Browse files
committed
Refactor address space handling based on TargetSpaceAttr and update performAddrSpaceCast
1 parent 765cb3f commit a6f709a

File tree

7 files changed

+56
-117
lines changed

7 files changed

+56
-117
lines changed

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -198,16 +198,20 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
198198
// default (e.g. in C / C++ auto vars are in the generic address space). At
199199
// the AST level this is handled within CreateTempAlloca et al., but for the
200200
// builtin / dynamic alloca we have to handle it here.
201-
cir::AddressSpace aas = getCIRAllocaAddressSpace();
202-
cir::AddressSpace eas = cir::toCIRAddressSpace(
203-
e->getType()->getPointeeType().getAddressSpace());
204-
if (eas != aas) {
201+
202+
LangAS allocaAddrSpace = clang::LangAS::Default;
203+
if (getCIRAllocaAddressSpace()) {
204+
allocaAddrSpace = clang::getLangASFromTargetAS(
205+
getCIRAllocaAddressSpace().getValue().getUInt());
206+
}
207+
LangAS exprAddrSpace = e->getType()->getPointeeType().getAddressSpace();
208+
if (exprAddrSpace != allocaAddrSpace) {
205209
cgm.errorNYI(e->getSourceRange(), "Non-default address space for alloca");
206210
}
207211

208212
// Bitcast the alloca to the expected type.
209-
return RValue::get(
210-
builder.createBitcast(allocaAddr, builder.getVoidPtrTy(aas)));
213+
return RValue::get(builder.createBitcast(
214+
allocaAddr, builder.getVoidPtrTy(allocaAddrSpace)));
211215
}
212216

213217
case Builtin::BIcos:

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include "clang/AST/Decl.h"
2323
#include "clang/AST/Expr.h"
2424
#include "clang/AST/ExprCXX.h"
25+
#include "clang/Basic/AddressSpaces.h"
26+
#include "clang/Basic/TargetInfo.h"
2527
#include "clang/CIR/Dialect/IR/CIRDialect.h"
2628
#include "clang/CIR/MissingFeatures.h"
2729
#include <optional>
@@ -1194,13 +1196,10 @@ LValue CIRGenFunction::emitCastLValue(const CastExpr *e) {
11941196
case CK_AddressSpaceConversion: {
11951197
LValue lv = emitLValue(e->getSubExpr());
11961198
QualType destTy = getContext().getPointerType(e->getType());
1197-
cir::AddressSpace srcAS =
1198-
cir::toCIRAddressSpace(e->getSubExpr()->getType().getAddressSpace());
1199-
cir::AddressSpace destAS =
1200-
cir::toCIRAddressSpace(e->getType().getAddressSpace());
1201-
mlir::Value V = getTargetHooks().performAddrSpaceCast(
1202-
*this, lv.getPointer(), srcAS, destAS, convertType(destTy));
1203-
return makeAddrLValue(Address(V, convertTypeForMem(e->getType()),
1199+
mlir::Value v = getTargetHooks().performAddrSpaceCast(
1200+
*this, lv.getPointer(), convertType(destTy));
1201+
1202+
return makeAddrLValue(Address(v, convertTypeForMem(e->getType()),
12041203
lv.getAddress().getAlignment()),
12051204
e->getType(), lv.getBaseInfo());
12061205
}
@@ -2297,9 +2296,17 @@ Address CIRGenFunction::createTempAlloca(mlir::Type ty, CharUnits align,
22972296
// be different from the type defined by the language. For example,
22982297
// in C++ the auto variables are in the default address space. Therefore
22992298
// cast alloca to the default address space when necessary.
2300-
if (auto astAS = cir::toCIRAddressSpace(cgm.getLangTempAllocaAddressSpace());
2301-
getCIRAllocaAddressSpace() != astAS) {
2302-
llvm_unreachable("Requires address space cast which is NYI");
2299+
2300+
LangAS allocaAS = cgm.getLangTempAllocaAddressSpace();
2301+
LangAS dstTyAS = clang::LangAS::Default;
2302+
if (getCIRAllocaAddressSpace()) {
2303+
dstTyAS = clang::getLangASFromTargetAS(
2304+
getCIRAllocaAddressSpace().getValue().getUInt());
2305+
}
2306+
2307+
if (dstTyAS != allocaAS) {
2308+
getTargetHooks().performAddrSpaceCast(*this, v,
2309+
builder.getPointerTo(ty, dstTyAS));
23032310
}
23042311
return Address(v, ty, align);
23052312
}

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,12 +1886,8 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
18861886
}
18871887
// Since target may map different address spaces in AST to the same address
18881888
// space, an address space conversion may end up as a bitcast.
1889-
cir::AddressSpace srcAS = cir::toCIRAddressSpace(
1890-
subExpr->getType()->getPointeeType().getAddressSpace());
1891-
cir::AddressSpace destAS =
1892-
cir::toCIRAddressSpace(destTy->getPointeeType().getAddressSpace());
18931889
return cgf.cgm.getTargetCIRGenInfo().performAddrSpaceCast(
1894-
cgf, Visit(subExpr), srcAS, destAS, convertType(destTy));
1890+
cgf, Visit(subExpr), convertType(destTy));
18951891
}
18961892

18971893
case CK_AtomicToNonAtomic: {

clang/lib/CIR/CodeGen/TargetInfo.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,14 @@ bool TargetCIRGenInfo::isNoProtoCallVariadic(
7171
return false;
7272
}
7373

74-
mlir::Value TargetCIRGenInfo::performAddrSpaceCast(
75-
CIRGenFunction &cgf, mlir::Value src, cir::AddressSpace srcAS,
76-
cir::AddressSpace destAS, mlir::Type destTy, bool isNonNull) const {
74+
mlir::Value TargetCIRGenInfo::performAddrSpaceCast(CIRGenFunction &cgf,
75+
mlir::Value v,
76+
mlir::Type destTy,
77+
bool isNonNull) const {
7778
// Since target may map different address spaces in AST to the same address
7879
// space, an address space conversion may end up as a bitcast.
79-
if (cir::GlobalOp globalOp = src.getDefiningOp<cir::GlobalOp>())
80+
if (cir::GlobalOp globalOp = v.getDefiningOp<cir::GlobalOp>())
8081
cgf.cgm.errorNYI("Global op addrspace cast");
8182
// Try to preserve the source's name to make IR more readable.
82-
return cgf.getBuilder().createAddrSpaceCast(src, destTy);
83+
return cgf.getBuilder().createAddrSpaceCast(v, destTy);
8384
}

clang/lib/CIR/CodeGen/TargetInfo.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,9 @@ class TargetCIRGenInfo {
5252
}
5353
/// Perform address space cast of an expression of pointer type.
5454
/// \param V is the value to be casted to another address space.
55-
/// \param SrcAddr is the CIR address space of \p V.
56-
/// \param DestAddr is the targeted CIR address space.
5755
/// \param DestTy is the destination pointer type.
5856
/// \param IsNonNull is the flag indicating \p V is known to be non null.
5957
virtual mlir::Value performAddrSpaceCast(CIRGenFunction &cgf, mlir::Value v,
60-
cir::AddressSpace srcAS,
61-
cir::AddressSpace destAS,
6258
mlir::Type destTy,
6359
bool isNonNull = false) const;
6460

clang/test/CIR/CodeGen/address-space-conversion.cpp

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ using ri2_t = int __attribute__((address_space(2))) &;
1717
void test_ptr() {
1818
pi1_t ptr1;
1919
pi2_t ptr2 = (pi2_t)ptr1;
20-
// CIR: %[[#PTR1:]] = cir.load{{.*}} %{{[0-9]+}} : !cir.ptr<!cir.ptr<!s32
21-
// CIR-NEXT: %[[#CAST:]] = cir.cast(address_space, %[[#PTR1]] : !cir.ptr<!s32i, addrspace(target<1>)>), !cir.ptr<!s32i, addrspace(target<2>)>
22-
// CIR-NEXT: cir.store{{.*}} %[[#CAST]], %{{[0-9]+}} : !cir.ptr<!s32i, addrspace(target<2>)>, !cir.ptr<!cir.ptr<!s32i, addrspace(target<2>)>>
20+
// CIR: %[[#PTR1:]] = cir.load align(8) %{{[0-9]+}} : !cir.ptr<!cir.ptr<!s32i, target_address_space(1)>>, !cir.ptr<!s32i, target_address_space(1)>
21+
// CIR-NEXT: %[[#CAST:]] = cir.cast address_space %[[#PTR1]] : !cir.ptr<!s32i, target_address_space(1)> -> !cir.ptr<!s32i, target_address_space(2)>
22+
// CIR-NEXT: cir.store align(8) %[[#CAST]], %{{[0-9]+}} : !cir.ptr<!s32i, target_address_space(2)>, !cir.ptr<!cir.ptr<!s32i, target_address_space(2)>>
2323

2424
// LLVM: %[[#PTR1:]] = load ptr addrspace(1), ptr %{{[0-9]+}}, align 8
2525
// LLVM-NEXT: %[[#CAST:]] = addrspacecast ptr addrspace(1) %[[#PTR1]] to ptr addrspace(2)
@@ -37,15 +37,15 @@ void test_ref() {
3737
pi1_t ptr;
3838
ri1_t ref1 = *ptr;
3939
ri2_t ref2 = (ri2_t)ref1;
40-
// CIR: %[[#DEREF:]] = cir.load deref{{.*}} %{{[0-9]+}} : !cir.ptr<!cir.ptr<!s32i, addrspace(target<1>)>>, !cir.ptr<!s32i, addrspace(target<1>)>
41-
// CIR-NEXT: cir.store{{.*}} %[[#DEREF]], %[[#ALLOCAREF1:]] : !cir.ptr<!s32i, addrspace(target<1>)>, !cir.ptr<!cir.ptr<!s32i, addrspace(target<1>)>>
42-
// CIR-NEXT: %[[#REF1:]] = cir.load{{.*}} %[[#ALLOCAREF1]] : !cir.ptr<!cir.ptr<!s32i, addrspace(target<1>)>>, !cir.ptr<!s32i, addrspace(target<1>)>
43-
// CIR-NEXT: %[[#CAST:]] = cir.cast(address_space, %[[#REF1]] : !cir.ptr<!s32i, addrspace(target<1>)>), !cir.ptr<!s32i, addrspace(target<2>)>
44-
// CIR-NEXT: cir.store{{.*}} %[[#CAST]], %{{[0-9]+}} : !cir.ptr<!s32i, addrspace(target<2>)>, !cir.ptr<!cir.ptr<!s32i, addrspace(target<2>)>>
40+
// CIR: %[[#DEREF:]] = cir.load deref align(8) %{{[0-9]+}} : !cir.ptr<!cir.ptr<!s32i, target_address_space(1)>>, !cir.ptr<!s32i, target_address_space(1)>
41+
// CIR-NEXT: cir.store align(8) %[[#DEREF]], %{{[0-9]+}} : !cir.ptr<!s32i, target_address_space(1)>, !cir.ptr<!cir.ptr<!s32i, target_address_space(1)>>
42+
// CIR-NEXT: %[[#REF1:]] = cir.load %{{[0-9]+}} : !cir.ptr<!cir.ptr<!s32i, target_address_space(1)>>, !cir.ptr<!s32i, target_address_space(1)>
43+
// CIR-NEXT: %[[#CAST:]] = cir.cast address_space %[[#REF1]] : !cir.ptr<!s32i, target_address_space(1)> -> !cir.ptr<!s32i, target_address_space(2)>
44+
// CIR-NEXT: cir.store align(8) %[[#CAST]], %{{[0-9]+}} : !cir.ptr<!s32i, target_address_space(2)>, !cir.ptr<!cir.ptr<!s32i, target_address_space(2)>>
4545

4646
// LLVM: %[[#DEREF:]] = load ptr addrspace(1), ptr %{{[0-9]+}}, align 8
47-
// LLVM-NEXT: store ptr addrspace(1) %[[#DEREF]], ptr %[[#ALLOCAREF1:]], align 8
48-
// LLVM-NEXT: %[[#REF1:]] = load ptr addrspace(1), ptr %[[#ALLOCAREF1]], align 8
47+
// LLVM-NEXT: store ptr addrspace(1) %[[#DEREF]], ptr %{{[0-9]+}}, align 8
48+
// LLVM-NEXT: %[[#REF1:]] = load ptr addrspace(1), ptr %{{[0-9]+}}, align 8
4949
// LLVM-NEXT: %[[#CAST:]] = addrspacecast ptr addrspace(1) %[[#REF1]] to ptr addrspace(2)
5050
// LLVM-NEXT: store ptr addrspace(2) %[[#CAST]], ptr %{{[0-9]+}}, align 8
5151

@@ -62,10 +62,10 @@ void test_ref() {
6262
void test_nullptr() {
6363
constexpr pi1_t null1 = nullptr;
6464
pi2_t ptr = (pi2_t)null1;
65-
// CIR: %[[#NULL1:]] = cir.const #cir.ptr<null> : !cir.ptr<!s32i, addrspace(target<1>)>
66-
// CIR-NEXT: cir.store{{.*}} %[[#NULL1]], %{{[0-9]+}} : !cir.ptr<!s32i, addrspace(target<1>)>, !cir.ptr<!cir.ptr<!s32i, addrspace(target<1>)>>
67-
// CIR-NEXT: %[[#NULL2:]] = cir.const #cir.ptr<null> : !cir.ptr<!s32i, addrspace(target<2>)>
68-
// CIR-NEXT: cir.store{{.*}} %[[#NULL2]], %{{[0-9]+}} : !cir.ptr<!s32i, addrspace(target<2>)>, !cir.ptr<!cir.ptr<!s32i, addrspace(target<2>)>>
65+
// CIR: %[[#NULL1:]] = cir.const #cir.ptr<null> : !cir.ptr<!s32i, target_address_space(1)>
66+
// CIR-NEXT: cir.store align(8) %[[#NULL1]], %{{[0-9]+}} : !cir.ptr<!s32i, target_address_space(1)>, !cir.ptr<!cir.ptr<!s32i, target_address_space(1)>>
67+
// CIR-NEXT: %[[#NULL2:]] = cir.const #cir.ptr<null> : !cir.ptr<!s32i, target_address_space(2)>
68+
// CIR-NEXT: cir.store align(8) %[[#NULL2]], %{{[0-9]+}} : !cir.ptr<!s32i, target_address_space(2)>, !cir.ptr<!cir.ptr<!s32i, target_address_space(2)>>
6969

7070
// LLVM: store ptr addrspace(1) null, ptr %{{[0-9]+}}, align 8
7171
// LLVM-NEXT: store ptr addrspace(2) null, ptr %{{[0-9]+}}, align 8
@@ -74,16 +74,19 @@ void test_nullptr() {
7474
// OGCG-NEXT: store ptr addrspace(2) null, ptr %{{.*}}, align 8
7575
}
7676

77+
// CIR: cir.func dso_local @{{.*test_side_effect.*}}
78+
// LLVM: define dso_local void @{{.*test_side_effect.*}}
79+
// OGCG: define dso_local void @{{.*test_side_effect.*}}
7780
void test_side_effect(pi1_t b) {
7881
pi2_t p = (pi2_t)(*b++, (int*)0);
79-
// CIR: %{{[0-9]+}} = cir.ptr_stride(%{{[0-9]+}} : !cir.ptr<!s32i, addrspace(target<1>)>, %{{[0-9]+}} : !s32i), !cir.ptr<!s32i, addrspace(target<1>)>
80-
// CIR: %[[#CAST:]] = cir.const #cir.ptr<null> : !cir.ptr<!s32i, addrspace(target<2>)>
81-
// CIR-NEXT: cir.store{{.*}} %[[#CAST]], %{{[0-9]+}} : !cir.ptr<!s32i, addrspace(target<2>)>, !cir.ptr<!cir.ptr<!s32i, addrspace(target<2>)>>
82+
// CIR: %[[#DEREF:]] = cir.load deref align(8) %{{[0-9]+}} : !cir.ptr<!cir.ptr<!s32i, target_address_space(1)>>, !cir.ptr<!s32i, target_address_space(1)>
83+
// CIR: %[[#STRIDE:]] = cir.ptr_stride(%[[#DEREF]] : !cir.ptr<!s32i, target_address_space(1)>, %{{[0-9]+}} : !s32i), !cir.ptr<!s32i, target_address_space(1)>
84+
// CIR: %[[#NULL:]] = cir.const #cir.ptr<null> : !cir.ptr<!s32i, target_address_space(2)>
85+
// CIR-NEXT: cir.store align(8) %[[#NULL]], %{{[0-9]+}} : !cir.ptr<!s32i, target_address_space(2)>, !cir.ptr<!cir.ptr<!s32i, target_address_space(2)>>
8286

83-
// LLVM: %{{[0-9]+}} = getelementptr i32, ptr addrspace(1) %{{[0-9]+}}, i64 1
87+
// LLVM: %{{[0-9]+}} = getelementptr {{.*}}i32, ptr addrspace(1) %{{[0-9]+}}, i{{32|64}} 1
8488
// LLVM: store ptr addrspace(2) null, ptr %{{[0-9]+}}, align 8
8589

8690
// OGCG: %{{.*}} = getelementptr{{.*}} i32, ptr addrspace(1) %{{.*}}, i32 1
8791
// OGCG: store ptr addrspace(2) null, ptr %{{.*}}, align 8
88-
8992
}

clang/test/CIR/address-space-conversion.cpp

Lines changed: 0 additions & 68 deletions
This file was deleted.

0 commit comments

Comments
 (0)