https://github.com/xakep8 updated 
https://github.com/llvm/llvm-project/pull/220643

>From 4d14dd537ccbaa88021da802529244abe0328cc2 Mon Sep 17 00:00:00 2001
From: Kunal Dubey <[email protected]>
Date: Wed, 2 Sep 2026 21:42:30 +0530
Subject: [PATCH] [CIR] Support pointer-to-int global initializers

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.
---
 clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp  | 23 +++++++++++--------
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 13 ++++-------
 clang/test/CIR/CodeGen/compound_literal.c     |  6 +++++
 .../test/CIR/CodeGen/global-address-to-int.c  | 22 ++++++++++++++++++
 4 files changed, 47 insertions(+), 17 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/global-address-to-int.c

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index 4bebe053f5768..4a9e412d06816 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -818,7 +818,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.
@@ -839,14 +841,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 {};
 }
 
@@ -881,9 +884,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 6f7509c363fd3..3904e16c18578 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -2478,14 +2478,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

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to