Skip to content

Commit 4dd722a

Browse files
authored
[CIR][LLVMLowering] Lower cir.objectsize (#545)
Lowers `cir.objectsize` to `llvm.objectsize`
1 parent 216b6d8 commit 4dd722a

File tree

10 files changed

+82
-82
lines changed

10 files changed

+82
-82
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

+10-17
Original file line numberDiff line numberDiff line change
@@ -1775,31 +1775,24 @@ def GetGlobalOp : CIR_Op<"get_global",
17751775
[Pure, DeclareOpInterfaceMethods<SymbolUserOpInterface>]> {
17761776
let summary = "Get the address of a global variable";
17771777
let description = [{
1778-
The `cir.get_global` operation retrieves the address pointing to a
1779-
named global variable. If the global variable is marked constant, writing
1780-
to the resulting address (such as through a `cir.store` operation) is
1781-
undefined. Resulting type must always be a `!cir.ptr<...>` type.
1778+
The `cir.get_global` operation retrieves the address pointing to a
1779+
named global variable. If the global variable is marked constant, writing
1780+
to the resulting address (such as through a `cir.store` operation) is
1781+
undefined. Resulting type must always be a `!cir.ptr<...>` type.
17821782

1783-
Addresses of thread local globals can only be retrieved if this operation
1784-
is marked `thread_local`, which indicates the address isn't constant.
1783+
Example:
17851784

1786-
Example:
1787-
```mlir
1788-
%x = cir.get_global @foo : !cir.ptr<i32>
1789-
...
1790-
%y = cir.get_global thread_local @batata : !cir.ptr<i32>
1791-
```
1785+
```mlir
1786+
%x = cir.get_global @foo : !cir.ptr<i32>
1787+
```
17921788
}];
17931789

1794-
let arguments = (ins FlatSymbolRefAttr:$name, UnitAttr:$tls);
1790+
let arguments = (ins FlatSymbolRefAttr:$name);
17951791
let results = (outs Res<CIR_PointerType, "", []>:$addr);
17961792

17971793
// FIXME: we should not be printing `cir.ptr` below, that should come
17981794
// from the pointer type directly.
1799-
let assemblyFormat = [{
1800-
(`thread_local` $tls^)?
1801-
$name `:` `cir.ptr` type($addr) attr-dict
1802-
}];
1795+
let assemblyFormat = "$name `:` `cir.ptr` type($addr) attr-dict";
18031796

18041797
// `GetGlobalOp` is fully verified by its traits.
18051798
let hasVerifier = 0;

clang/lib/CIR/CodeGen/CIRGenBuilder.h

+3-5
Original file line numberDiff line numberDiff line change
@@ -697,11 +697,9 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy {
697697
return create<mlir::cir::GlobalOp>(loc, uniqueName, type, isConst, linkage);
698698
}
699699

700-
mlir::Value createGetGlobal(mlir::cir::GlobalOp global,
701-
bool threadLocal = false) {
702-
return create<mlir::cir::GetGlobalOp>(global.getLoc(),
703-
getPointerTo(global.getSymType()),
704-
global.getName(), threadLocal);
700+
mlir::Value createGetGlobal(mlir::cir::GlobalOp global) {
701+
return create<mlir::cir::GetGlobalOp>(
702+
global.getLoc(), getPointerTo(global.getSymType()), global.getName());
705703
}
706704

707705
mlir::Value createGetBitfield(mlir::Location loc, mlir::Type resultType,

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -719,10 +719,11 @@ static LValue buildGlobalVarDeclLValue(CIRGenFunction &CGF, const Expr *E,
719719
if (CGF.getLangOpts().OpenMP)
720720
llvm_unreachable("not implemented");
721721

722-
// Traditional LLVM codegen handles thread local separately, CIR handles
723-
// as part of getAddrOfGlobalVar.
724722
auto V = CGF.CGM.getAddrOfGlobalVar(VD);
725723

724+
if (VD->getTLSKind() != VarDecl::TLS_None)
725+
llvm_unreachable("NYI");
726+
726727
auto RealVarTy = CGF.getTypes().convertTypeForMem(VD->getType());
727728
auto realPtrTy = CGF.getBuilder().getPointerTo(RealVarTy);
728729
if (realPtrTy != V.getType())

clang/lib/CIR/CodeGen/CIRGenModule.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -836,12 +836,11 @@ mlir::Value CIRGenModule::getAddrOfGlobalVar(const VarDecl *D, mlir::Type Ty,
836836
if (!Ty)
837837
Ty = getTypes().convertTypeForMem(ASTTy);
838838

839-
bool tlsAccess = D->getTLSKind() != VarDecl::TLS_None;
840839
auto g = buildGlobal(D, Ty, IsForDefinition);
841840
auto ptrTy =
842841
mlir::cir::PointerType::get(builder.getContext(), g.getSymType());
843-
return builder.create<mlir::cir::GetGlobalOp>(
844-
getLoc(D->getSourceRange()), ptrTy, g.getSymName(), tlsAccess);
842+
return builder.create<mlir::cir::GetGlobalOp>(getLoc(D->getSourceRange()),
843+
ptrTy, g.getSymName());
845844
}
846845

847846
mlir::cir::GlobalViewAttr

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

+2-6
Original file line numberDiff line numberDiff line change
@@ -1634,13 +1634,9 @@ GetGlobalOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
16341634
<< "' does not reference a valid cir.global or cir.func";
16351635

16361636
mlir::Type symTy;
1637-
if (auto g = dyn_cast<GlobalOp>(op)) {
1637+
if (auto g = dyn_cast<GlobalOp>(op))
16381638
symTy = g.getSymType();
1639-
// Verify that for thread local global access, the global needs to
1640-
// be marked with tls bits.
1641-
if (getTls() && !g.getTlsModel())
1642-
return emitOpError("access to global not marked thread local");
1643-
} else if (auto f = dyn_cast<FuncOp>(op))
1639+
else if (auto f = dyn_cast<FuncOp>(op))
16441640
symTy = f.getFunctionType();
16451641
else
16461642
llvm_unreachable("shall not get here");

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

+33-12
Original file line numberDiff line numberDiff line change
@@ -1613,16 +1613,7 @@ class CIRGetGlobalOpLowering
16131613

16141614
auto type = getTypeConverter()->convertType(op.getType());
16151615
auto symbol = op.getName();
1616-
mlir::Operation *newop =
1617-
rewriter.create<mlir::LLVM::AddressOfOp>(op.getLoc(), type, symbol);
1618-
1619-
if (op.getTls()) {
1620-
// Handle access to TLS via intrinsic.
1621-
newop = rewriter.create<mlir::LLVM::ThreadlocalAddressOp>(
1622-
op.getLoc(), type, newop->getResult(0));
1623-
}
1624-
1625-
rewriter.replaceOp(op, newop);
1616+
rewriter.replaceOpWithNewOp<mlir::LLVM::AddressOfOp>(op, type, symbol);
16261617
return mlir::success();
16271618
}
16281619
};
@@ -2287,6 +2278,36 @@ class CIRBitClrsbOpLowering
22872278
}
22882279
};
22892280

2281+
class CIRObjSizeOpLowering
2282+
: public mlir::OpConversionPattern<mlir::cir::ObjSizeOp> {
2283+
public:
2284+
using OpConversionPattern<mlir::cir::ObjSizeOp>::OpConversionPattern;
2285+
2286+
mlir::LogicalResult
2287+
matchAndRewrite(mlir::cir::ObjSizeOp op, OpAdaptor adaptor,
2288+
mlir::ConversionPatternRewriter &rewriter) const override {
2289+
auto llvmResTy = getTypeConverter()->convertType(op.getType());
2290+
auto loc = op->getLoc();
2291+
2292+
auto llvmIntrinNameAttr =
2293+
mlir::StringAttr::get(rewriter.getContext(), "llvm.objectsize");
2294+
mlir::cir::SizeInfoType kindInfo = op.getKind();
2295+
auto falseValue = rewriter.create<mlir::LLVM::ConstantOp>(
2296+
loc, rewriter.getI1Type(), false);
2297+
auto trueValue = rewriter.create<mlir::LLVM::ConstantOp>(
2298+
loc, rewriter.getI1Type(), true);
2299+
2300+
rewriter.replaceOpWithNewOp<mlir::LLVM::CallIntrinsicOp>(
2301+
op, llvmResTy, llvmIntrinNameAttr,
2302+
mlir::ValueRange{adaptor.getPtr(),
2303+
kindInfo == mlir::cir::SizeInfoType::max ? falseValue
2304+
: trueValue,
2305+
trueValue, op.getDynamic() ? trueValue : falseValue});
2306+
2307+
return mlir::LogicalResult::success();
2308+
}
2309+
};
2310+
22902311
class CIRBitClzOpLowering
22912312
: public mlir::OpConversionPattern<mlir::cir::BitClzOp> {
22922313
public:
@@ -3033,8 +3054,8 @@ void populateCIRToLLVMConversionPatterns(mlir::RewritePatternSet &patterns,
30333054
CIRVectorShuffleVecLowering, CIRStackSaveLowering,
30343055
CIRStackRestoreLowering, CIRUnreachableLowering, CIRTrapLowering,
30353056
CIRInlineAsmOpLowering, CIRSetBitfieldLowering, CIRGetBitfieldLowering,
3036-
CIRPrefetchLowering, CIRIsConstantOpLowering>(converter,
3037-
patterns.getContext());
3057+
CIRPrefetchLowering, CIRObjSizeOpLowering, CIRIsConstantOpLowering>(
3058+
converter, patterns.getContext());
30383059
}
30393060

30403061
namespace {
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir-enable -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir-enable -emit-llvm %s -o %t.ll
4+
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
5+
void b(void *__attribute__((pass_object_size(0))));
6+
void e(void *__attribute__((pass_object_size(2))));
7+
void c() {
8+
int a;
9+
int d[a];
10+
b(d);
11+
e(d);
12+
}
13+
14+
// CIR: cir.func no_proto @c()
15+
// CIR: [[TMP0:%.*]] = cir.alloca !s32i, cir.ptr <!s32i>, %{{[0-9]+}} : !u64i, ["vla"] {alignment = 16 : i64}
16+
// CIR: [[TMP1:%.*]] = cir.cast(bitcast, [[TMP0]] : !cir.ptr<!s32i>), !cir.ptr<!void>
17+
// CIR-NEXT: [[TMP2:%.*]] = cir.objsize([[TMP1]] : <!void>, max) -> !u64i
18+
// CIR-NEXT: cir.call @b([[TMP1]], [[TMP2]]) : (!cir.ptr<!void>, !u64i) -> ()
19+
// CIR: [[TMP3:%.*]] = cir.cast(bitcast, [[TMP0]] : !cir.ptr<!s32i>), !cir.ptr<!void>
20+
// CIR: [[TMP4:%.*]] = cir.objsize([[TMP3]] : <!void>, min) -> !u64i
21+
// CIR-NEXT: cir.call @e([[TMP3]], [[TMP4]]) : (!cir.ptr<!void>, !u64i) -> ()
22+
23+
// LLVM: define void @c()
24+
// LLVM: [[TMP0:%.*]] = alloca i32, i64 %{{[0-9]+}},
25+
// LLVM: [[TMP1:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 false, i1 true, i1 false),
26+
// LLVM-NEXT: call void @b(ptr [[TMP0]], i64 [[TMP1]])
27+
// LLVM: [[TMP2:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[TMP0]], i1 true, i1 true, i1 false),
28+
// LLVM-NEXT: call void @e(ptr [[TMP0]], i64 [[TMP2]])

clang/test/CIR/CodeGen/tls.c

-11
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,6 @@
33
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir-enable -emit-llvm %s -o %t.ll
44
// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
55

6-
extern __thread int b;
7-
int c(void) { return *&b; }
8-
// CIR: cir.global "private" external tls_dyn @b : !s32i
9-
// CIR: cir.func @c() -> !s32i
10-
// CIR: %[[TLS_ADDR:.*]] = cir.get_global thread_local @b : cir.ptr <!s32i>
11-
126
__thread int a;
137
// CIR: cir.global external tls_dyn @a = #cir.int<0> : !s32i
14-
15-
// LLVM: @b = external thread_local global i32
168
// LLVM: @a = thread_local global i32 0
17-
18-
// LLVM-LABEL: @c
19-
// LLVM: = call ptr @llvm.threadlocal.address.p0(ptr @b)

clang/test/CIR/IR/global.cir

+1-13
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,6 @@ module {
6363
cir.global external tls_local_dyn @model1 = #cir.int<0> : !s32i
6464
cir.global external tls_init_exec @model2 = #cir.int<0> : !s32i
6565
cir.global external tls_local_exec @model3 = #cir.int<0> : !s32i
66-
67-
cir.global "private" external tls_dyn @batata : !s32i
68-
cir.func @f35() {
69-
%0 = cir.get_global thread_local @batata : cir.ptr <!s32i>
70-
cir.return
71-
}
7266
}
7367

7468
// CHECK: cir.global external @a = #cir.int<3> : !s32i
@@ -97,10 +91,4 @@ module {
9791
// CHECK: cir.global external tls_dyn @model0 = #cir.int<0> : !s32i
9892
// CHECK: cir.global external tls_local_dyn @model1 = #cir.int<0> : !s32i
9993
// CHECK: cir.global external tls_init_exec @model2 = #cir.int<0> : !s32i
100-
// CHECK: cir.global external tls_local_exec @model3 = #cir.int<0> : !s32i
101-
102-
// CHECK: cir.global "private" external tls_dyn @batata : !s32i
103-
// CHECK: cir.func @f35() {
104-
// CHECK: %0 = cir.get_global thread_local @batata : cir.ptr <!s32i>
105-
// CHECK: cir.return
106-
// CHECK: }
94+
// CHECK: cir.global external tls_local_exec @model3 = #cir.int<0> : !s32i

clang/test/CIR/IR/invalid.cir

-13
Original file line numberDiff line numberDiff line change
@@ -1033,16 +1033,3 @@ cir.func @bad_fetch(%x: !cir.ptr<!cir.float>, %y: !cir.float) -> () {
10331033
%12 = cir.atomic.fetch(xor, %x : !cir.ptr<!cir.float>, %y : !cir.float, seq_cst) : !cir.float
10341034
cir.return
10351035
}
1036-
1037-
// -----
1038-
1039-
!s32i = !cir.int<s, 32>
1040-
1041-
module {
1042-
cir.global "private" external @batata : !s32i
1043-
cir.func @f35() {
1044-
// expected-error@+1 {{access to global not marked thread local}}
1045-
%0 = cir.get_global thread_local @batata : cir.ptr <!s32i>
1046-
cir.return
1047-
}
1048-
}

0 commit comments

Comments
 (0)