From ba60c92e63fce06f858626f5052ad8ee0efdbbcc Mon Sep 17 00:00:00 2001 From: Sirui Mu Date: Mon, 30 Dec 2024 21:47:52 +0800 Subject: [PATCH] [CIR] Add integer result type for `#cir.global_view` --- .../include/clang/CIR/Dialect/IR/CIRAttrs.td | 5 +++ .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 34 ++++++++++++++----- clang/test/CIR/Lowering/globals.cir | 20 +++++++++++ 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index e54b52b96c91..3e12a9307807 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -607,11 +607,16 @@ def GlobalViewAttr : CIR_Attr<"GlobalView", "global_view", [TypedAttrInterface]> for `!cir.ptr`, an offset is applied. The first index is relative to the original symbol type, not the produced one. + The result type of this attribute may be an integer type. In such a case, + the pointer to the referenced global is casted to an integer and this + attribute represents the casted result. + Example: ``` cir.global external @s = @".str2": !cir.ptr cir.global external @x = #cir.global_view<@s> : !cir.ptr + cir.global external @s_addr = #cir.global_view<@s> : !s64i cir.global external @rgb = #cir.const_array<[0 : i8, -23 : i8, 33 : i8] : !cir.array> cir.global external @elt_ptr = #cir.global_view<@rgb, [1]> : !cir.ptr diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 236cb602f735..d023db0efebe 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -698,17 +698,25 @@ lowerCirAttrAsValue(mlir::Operation *parentOp, cir::GlobalViewAttr globalAttr, indices, true); } - auto ptrTy = mlir::dyn_cast(globalAttr.getType()); - assert(ptrTy && "Expecting pointer type in GlobalViewAttr"); - auto llvmEltTy = - convertTypeForMemory(*converter, dataLayout, ptrTy.getPointee()); + if (auto intTy = mlir::dyn_cast(globalAttr.getType())) { + auto llvmDstTy = converter->convertType(globalAttr.getType()); + return rewriter.create(parentOp->getLoc(), + llvmDstTy, addrOp); + } + + if (auto ptrTy = mlir::dyn_cast(globalAttr.getType())) { + auto llvmEltTy = + convertTypeForMemory(*converter, dataLayout, ptrTy.getPointee()); - if (llvmEltTy == sourceType) - return addrOp; + if (llvmEltTy == sourceType) + return addrOp; - auto llvmDstTy = converter->convertType(globalAttr.getType()); - return rewriter.create(parentOp->getLoc(), llvmDstTy, - addrOp); + auto llvmDstTy = converter->convertType(globalAttr.getType()); + return rewriter.create(parentOp->getLoc(), llvmDstTy, + addrOp); + } + + llvm_unreachable("Expecting pointer or integer type for GlobalViewAttr"); } /// Switches on the type of attribute and calls the appropriate conversion. @@ -1681,6 +1689,14 @@ mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite( attr = rewriter.getIntegerAttr(typeConverter->convertType(op.getType()), value); } else if (mlir::isa(op.getType())) { + // Lower GlobalAddrAttr to llvm.mlir.addressof + llvm.mlir.ptrtoint + if (auto ga = mlir::dyn_cast(op.getValue())) { + auto newOp = + lowerCirAttrAsValue(op, ga, rewriter, getTypeConverter(), dataLayout); + rewriter.replaceOp(op, newOp); + return mlir::success(); + } + attr = rewriter.getIntegerAttr( typeConverter->convertType(op.getType()), mlir::cast(op.getValue()).getValue()); diff --git a/clang/test/CIR/Lowering/globals.cir b/clang/test/CIR/Lowering/globals.cir index 765544e8c125..0108b56b8a7b 100644 --- a/clang/test/CIR/Lowering/globals.cir +++ b/clang/test/CIR/Lowering/globals.cir @@ -27,6 +27,7 @@ module { cir.global external @alpha = #cir.const_array<[#cir.int<97> : !s8i, #cir.int<98> : !s8i, #cir.int<99> : !s8i, #cir.int<0> : !s8i]> : !cir.array cir.global "private" constant internal @".str" = #cir.const_array<"example\00" : !cir.array> : !cir.array {alignment = 1 : i64} cir.global external @s = #cir.global_view<@".str"> : !cir.ptr + cir.global external @s_addr = #cir.global_view<@".str"> : !u64i // MLIR: llvm.mlir.global internal constant @".str"("example\00") // MLIR-SAME: {addr_space = 0 : i32, alignment = 1 : i64} // MLIR: llvm.mlir.global external @s() {addr_space = 0 : i32} : !llvm.ptr { @@ -34,8 +35,14 @@ module { // MLIR: %1 = llvm.bitcast %0 : !llvm.ptr to !llvm.ptr // MLIR: llvm.return %1 : !llvm.ptr // MLIR: } + // MLIR: llvm.mlir.global external @s_addr() {addr_space = 0 : i32} : i64 { + // MLIR: %0 = llvm.mlir.addressof @".str" : !llvm.ptr + // MLIR: %1 = llvm.ptrtoint %0 : !llvm.ptr to i64 + // MLIR: llvm.return %1 : i64 + // MLIR: } // LLVM: @.str = internal constant [8 x i8] c"example\00" // LLVM: @s = global ptr @.str + // LLVM: @s_addr = global i64 ptrtoint (ptr @.str to i64) cir.global external @aPtr = #cir.global_view<@a> : !cir.ptr // MLIR: llvm.mlir.global external @aPtr() {addr_space = 0 : i32} : !llvm.ptr { // MLIR: %0 = llvm.mlir.addressof @a : !llvm.ptr @@ -198,4 +205,17 @@ module { } // MLIR: %0 = llvm.mlir.addressof @zero_array + cir.func @global_view_as_integer() -> !u64i { + %0 = cir.const #cir.global_view<@".str"> : !u64i + cir.return %0 : !u64i + } + // MLIR-LABEL: @global_view_as_integer + // MLIR-NEXT: %0 = llvm.mlir.addressof @".str" : !llvm.ptr + // MLIR-NEXT: %1 = llvm.ptrtoint %0 : !llvm.ptr to i64 + // MLIR-NEXT: llvm.return %1 : i64 + // MLIR-NEXT: } + // LLVM-LABEL: @global_view_as_integer + // LLVM-NEXT: ret i64 ptrtoint (ptr @.str to i64) + // LLVM-NEXT: } + }