llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Kunal Dubey (xakep8)
<details>
<summary>Changes</summary>
This allows CIR to emit global initializers where a constant address is cast to
an integer.
This fixes compound literals like `unsigned long addr = (unsigned
long)(int[]){1, 2, 3}` and also handles global variable, array element and
function addresses cast to integers.
Fixes #<!-- -->216618
---
Full diff: https://github.com/llvm/llvm-project/pull/220643.diff
4 Files Affected:
- (modified) clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp (+14-9)
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+5-8)
- (modified) clang/test/CIR/CodeGen/compound_literal.c (+6)
- (added) clang/test/CIR/CodeGen/global-address-to-int.c (+22)
``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index 385568c7f6f0f..dcdd9ba3c0d62 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -809,7 +809,9 @@ mlir::Attribute ConstantLValueEmitter::tryEmit() {
// non-zero null pointer and addrspace casts that aren't trivially
// represented in LLVM IR.
mlir::Type destTy = cgm.getTypes().convertTypeForMem(destType);
- assert(mlir::isa<cir::PointerType>(destTy));
+ assert((mlir::isa<cir::PointerType>(destTy) ||
+ mlir::isa<cir::IntType>(destTy)) &&
+ "constant lvalue destination must be pointer or integer");
// If there's no base at all, this is a null or absolute pointer,
// possibly cast back to an integer type.
@@ -830,14 +832,15 @@ mlir::Attribute ConstantLValueEmitter::tryEmit() {
// Convert to the appropriate type; this could be an lvalue for
// an integer. FIXME: performAddrSpaceCast
- if (mlir::isa<cir::PointerType>(destTy)) {
- if (auto attr = mlir::dyn_cast<mlir::Attribute>(value))
+ if (auto attr = mlir::dyn_cast<mlir::Attribute>(value)) {
+ if (auto gv = mlir::dyn_cast<cir::GlobalViewAttr>(attr))
+ return cir::GlobalViewAttr::get(destTy, gv.getSymbol(), gv.getIndices());
+
+ if (mlir::isa<cir::PointerType>(destTy))
return attr;
- cgm.errorNYI("ConstantLValueEmitter: non-attribute pointer");
- return {};
}
- cgm.errorNYI("ConstantLValueEmitter: other?");
+ cgm.errorNYI("ConstantLValueEmitter: non-attribute pointer or integer");
return {};
}
@@ -872,9 +875,11 @@ ConstantLValueEmitter::tryEmitBase(const
APValue::LValueBase &base) {
// fop.getFunctionType(), so initializers stay valid when a no-prototype
// FuncOp is later replaced by a prototyped definition with the same
// symbol. CIR allows the view type to differ from the symbol's type.
- mlir::Type ptrTy = cgm.getTypes().convertTypeForMem(destType);
- assert(mlir::isa<cir::PointerType>(ptrTy) &&
- "function address in constant must be a pointer");
+ mlir::Type destTy = cgm.getTypes().convertTypeForMem(destType);
+ cir::PointerType ptrTy =
+ mlir::isa<cir::PointerType>(destTy)
+ ? mlir::cast<cir::PointerType>(destTy)
+ : cir::PointerType::get(fop.getFunctionType());
return cir::GlobalViewAttr::get(
ptrTy,
mlir::FlatSymbolRefAttr::get(mlirContext, fop.getSymNameAttr()));
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 233e6aaa15adb..857d9af482c69 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -2434,14 +2434,11 @@ mlir::LogicalResult
CIRToLLVMConstantOpLowering::matchAndRewrite(
value);
} else if (mlir::isa<cir::IntType>(op.getType())) {
// Lower GlobalViewAttr to llvm.mlir.addressof + llvm.mlir.ptrtoint
- if (auto ga = mlir::dyn_cast<cir::GlobalViewAttr>(op.getValue())) {
- // We can have a global view with an integer type in the case of method
- // pointers, but the lowering of those doesn't go through this path.
- // They are handled in the visitCirAttr. This is left as an error until
- // we have a test case that reaches it.
- assert(!cir::MissingFeatures::globalViewIntLowering());
- op.emitError() << "global view with integer type";
- return mlir::failure();
+ if (auto gv = mlir::dyn_cast<cir::GlobalViewAttr>(op.getValue())) {
+ auto newOp = lowerCirAttrAsValue(op, gv, rewriter, symbolTables,
+ getTypeConverter());
+ rewriter.replaceOp(op, newOp);
+ return mlir::success();
}
attr = rewriter.getIntegerAttr(
diff --git a/clang/test/CIR/CodeGen/compound_literal.c
b/clang/test/CIR/CodeGen/compound_literal.c
index d3d45f5af8e27..7d38e5b2cd6d0 100644
--- a/clang/test/CIR/CodeGen/compound_literal.c
+++ b/clang/test/CIR/CodeGen/compound_literal.c
@@ -65,3 +65,9 @@ int **p9 = (int*[]){&x, &x};
// LLVM: @x = global i32 0, align 4
// LLVM: @.compoundliteral.9 = internal global [2 x ptr] [ptr @x, ptr @x],
align 8
// LLVM: @p9 = global ptr @.compoundliteral.9, align 8
+
+unsigned long addr = (unsigned long)(int[]){1, 2, 3};
+// CIR: cir.global "private" internal @".compoundliteral.10" =
#cir.const_array<[#cir.int<1> : !s32i, #cir.int<2> : !s32i, #cir.int<3> :
!s32i]> : !cir.array<!s32i x 3> {alignment = 4 : i64}
+// CIR: cir.global external @addr = #cir.global_view<@".compoundliteral.10"> :
!u64i {alignment = 8 : i64}
+// LLVM: @.compoundliteral.10 = internal global [3 x i32] [i32 1, i32 2, i32
3], align 4
+// LLVM: @addr = global i64 ptrtoint (ptr @.compoundliteral.10 to i64), align 8
diff --git a/clang/test/CIR/CodeGen/global-address-to-int.c
b/clang/test/CIR/CodeGen/global-address-to-int.c
new file mode 100644
index 0000000000000..3b24941d4c9c4
--- /dev/null
+++ b/clang/test/CIR/CodeGen/global-address-to-int.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o
%t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o
%t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
+
+int x;
+int arr[4];
+int f(void);
+
+unsigned long gx = (unsigned long)&x;
+// CIR: cir.global external @gx = #cir.global_view<@x> : !u64i
+// LLVM: @gx = global i64 ptrtoint (ptr @x to i64), align 8
+
+unsigned long garr2 = (unsigned long)&arr[2];
+// CIR: cir.global external @garr2 = #cir.global_view<@arr, [2 : i32]> : !u64i
+// LLVM: @garr2 = global i64 ptrtoint (ptr getelementptr {{.*}}(i8, ptr @arr,
i64 8) to i64), align 8
+
+unsigned long gf = (unsigned long)&f;
+// CIR: cir.global external @gf = #cir.global_view<@f> : !u64i
+// LLVM: @gf = global i64 ptrtoint (ptr @f to i64), align 8
``````````
</details>
https://github.com/llvm/llvm-project/pull/220643
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits