[clang] [CIR] Upstream handling of integral-to-pointer casts (PR #161653)

Shawn K via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 2 10:12:36 PDT 2025


https://github.com/kimsh02 updated https://github.com/llvm/llvm-project/pull/161653

>From eec6869a048bb92fd58efbe811412196a8d9d783 Mon Sep 17 00:00:00 2001
From: kimsh02 <kimshawn02 at icloud.com>
Date: Thu, 2 Oct 2025 04:37:05 -0700
Subject: [PATCH 1/7] [CIR] Upstream handling of integral-to-pointer casts

---
 .../clang/CIR/Dialect/IR/CIRDataLayout.h      | 18 +++++++++++++++
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp    | 19 ++++++++++++++++
 clang/test/CIR/CodeGen/cast.cpp               | 22 +++++++++++++++++++
 3 files changed, 59 insertions(+)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h b/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h
index 417a226e44cbf..c7450d8770714 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h
+++ b/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h
@@ -14,6 +14,11 @@
 
 #include "mlir/Dialect/DLTI/DLTI.h"
 #include "mlir/IR/BuiltinOps.h"
+#include "clang/CIR/Dialect/IR/CIRAttrs.h"
+#include "clang/CIR/Dialect/IR/CIRTypes.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/Support/Alignment.h"
+#include "llvm/Support/TypeSize.h"
 
 namespace cir {
 
@@ -81,6 +86,19 @@ class CIRDataLayout {
   }
 
   llvm::TypeSize getTypeSizeInBits(mlir::Type ty) const;
+
+    llvm::TypeSize getPointerTypeSizeInBits(mlir::Type Ty) const {
+    assert(mlir::isa<cir::PointerType>(Ty) &&
+           "This should only be called with a pointer type");
+    return layout.getTypeSizeInBits(Ty);
+  }
+
+  mlir::Type getIntPtrType(mlir::Type Ty) const {
+    assert(mlir::isa<cir::PointerType>(Ty) && "Expected pointer type");
+    auto IntTy =
+        cir::IntType::get(Ty.getContext(), getPointerTypeSizeInBits(Ty), false);
+    return IntTy;
+  }
 };
 
 } // namespace cir
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 500007f6f241b..c64c5f7d7a9c8 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1889,6 +1889,25 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
     }
     return v;
   }
+  case CK_IntegralToPointer: {
+    auto DestCIRTy = cgf.convertType(destTy);
+    mlir::Value Src = Visit(const_cast<Expr *>(subExpr));
+
+    // Properly resize by casting to an int of the same size as the pointer.
+    // Clang's IntegralToPointer includes 'bool' as the source, but in CIR
+    // 'bool' is not an integral type.  So check the source type to get the
+    // correct CIR conversion.
+    auto MiddleTy = cgf.cgm.getDataLayout().getIntPtrType(DestCIRTy);
+    auto MiddleVal = builder.createCast(subExpr->getType()->isBooleanType()
+                                            ? cir::CastKind::bool_to_int
+                                            : cir::CastKind::integral,
+                                        Src, MiddleTy);
+
+    if (cgf.cgm.getCodeGenOpts().StrictVTablePointers)
+      llvm_unreachable("NYI");
+
+    return builder.createIntToPtr(MiddleVal, DestCIRTy);
+  }  
 
   case CK_ArrayToPointerDecay:
     return cgf.emitArrayToPointerDecay(subExpr).getPointer();
diff --git a/clang/test/CIR/CodeGen/cast.cpp b/clang/test/CIR/CodeGen/cast.cpp
index 7afa955cf3bcf..a1fd92612fe37 100644
--- a/clang/test/CIR/CodeGen/cast.cpp
+++ b/clang/test/CIR/CodeGen/cast.cpp
@@ -131,3 +131,25 @@ void bitcast() {
 
 // LLVM: %[[D_VEC:.*]] = load <2 x double>, ptr {{.*}}, align 16
 // LLVM: %[[I_VEC:.*]] = bitcast <2 x double> %[[D_VEC]] to <4 x i32>
+
+void f(long int start) {
+  void *p = (void*)start;
+}
+// CIR: %[[L:.*]] = cir.load {{.*}} : !cir.ptr<!s64i>, !s64i
+// CIR: %[[MID:.*]] = cir.cast integral %[[L]] : !s64i -> !u64i
+// CIR:          cir.cast int_to_ptr %[[MID]] : !u64i -> !cir.ptr<!void>
+
+struct A { int x; };
+
+void int_cast(long ptr) {
+  ((A *)ptr)->x = 0;
+}
+// CIR: cir.cast int_to_ptr {{.*}} : !u64i -> !cir.ptr<!rec_A>
+// LLVM: inttoptr {{.*}} to ptr
+
+void null_cast(long) {
+  *(int *)0 = 0;
+  ((A *)0)->x = 0;
+}
+// CIR: #cir.ptr<null> : !cir.ptr<!s32i>
+// CIR: #cir.ptr<null> : !cir.ptr<!rec_A>

>From 54e154c347a9085ac18314908d79ff1e1e5101b2 Mon Sep 17 00:00:00 2001
From: kimsh02 <kimshawn02 at icloud.com>
Date: Thu, 2 Oct 2025 04:45:22 -0700
Subject: [PATCH 2/7] Clang-format

---
 clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h | 2 +-
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp         | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h b/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h
index c7450d8770714..5bcdbd9a0c8ca 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h
+++ b/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h
@@ -87,7 +87,7 @@ class CIRDataLayout {
 
   llvm::TypeSize getTypeSizeInBits(mlir::Type ty) const;
 
-    llvm::TypeSize getPointerTypeSizeInBits(mlir::Type Ty) const {
+  llvm::TypeSize getPointerTypeSizeInBits(mlir::Type Ty) const {
     assert(mlir::isa<cir::PointerType>(Ty) &&
            "This should only be called with a pointer type");
     return layout.getTypeSizeInBits(Ty);
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index c64c5f7d7a9c8..6938be2fa6729 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1907,7 +1907,7 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
       llvm_unreachable("NYI");
 
     return builder.createIntToPtr(MiddleVal, DestCIRTy);
-  }  
+  }
 
   case CK_ArrayToPointerDecay:
     return cgf.emitArrayToPointerDecay(subExpr).getPointer();

>From 280738848c9232fdc31a9b88a96049bbd26ebb98 Mon Sep 17 00:00:00 2001
From: Shawn K <kimshawn02 at icloud.com>
Date: Thu, 2 Oct 2025 10:10:12 -0700
Subject: [PATCH 3/7] Update clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Co-authored-by: Andy Kaylor <akaylor at nvidia.com>
---
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 6938be2fa6729..6c67c0f82a427 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1898,7 +1898,7 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
     // 'bool' is not an integral type.  So check the source type to get the
     // correct CIR conversion.
     auto MiddleTy = cgf.cgm.getDataLayout().getIntPtrType(DestCIRTy);
-    auto MiddleVal = builder.createCast(subExpr->getType()->isBooleanType()
+    cir::CastOp middleVal = builder.createCast(subExpr->getType()->isBooleanType()
                                             ? cir::CastKind::bool_to_int
                                             : cir::CastKind::integral,
                                         Src, MiddleTy);

>From d328d2775ea584ffba46dd408d7f3032edb981cd Mon Sep 17 00:00:00 2001
From: Shawn K <kimshawn02 at icloud.com>
Date: Thu, 2 Oct 2025 10:11:27 -0700
Subject: [PATCH 4/7] Update clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Co-authored-by: Andy Kaylor <akaylor at nvidia.com>
---
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 6c67c0f82a427..82d8563af7608 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1890,7 +1890,7 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
     return v;
   }
   case CK_IntegralToPointer: {
-    auto DestCIRTy = cgf.convertType(destTy);
+    mlir:Type destCIRTy = cgf.convertType(destTy);
     mlir::Value Src = Visit(const_cast<Expr *>(subExpr));
 
     // Properly resize by casting to an int of the same size as the pointer.

>From ec1ca90540e34760be30882437b4a959c0c18f8e Mon Sep 17 00:00:00 2001
From: Shawn K <kimshawn02 at icloud.com>
Date: Thu, 2 Oct 2025 10:11:49 -0700
Subject: [PATCH 5/7] Update clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Co-authored-by: Andy Kaylor <akaylor at nvidia.com>
---
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 82d8563af7608..6bb1e5dd8ed2a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1891,7 +1891,7 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
   }
   case CK_IntegralToPointer: {
     mlir:Type destCIRTy = cgf.convertType(destTy);
-    mlir::Value Src = Visit(const_cast<Expr *>(subExpr));
+    mlir::Value src = Visit(const_cast<Expr *>(subExpr));
 
     // Properly resize by casting to an int of the same size as the pointer.
     // Clang's IntegralToPointer includes 'bool' as the source, but in CIR

>From 2b3d7cb783a50817eccb40c6c3ce21c5b9429921 Mon Sep 17 00:00:00 2001
From: Shawn K <kimshawn02 at icloud.com>
Date: Thu, 2 Oct 2025 10:12:00 -0700
Subject: [PATCH 6/7] Update clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Co-authored-by: Andy Kaylor <akaylor at nvidia.com>
---
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 6bb1e5dd8ed2a..244973a12e3f5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1897,7 +1897,7 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
     // Clang's IntegralToPointer includes 'bool' as the source, but in CIR
     // 'bool' is not an integral type.  So check the source type to get the
     // correct CIR conversion.
-    auto MiddleTy = cgf.cgm.getDataLayout().getIntPtrType(DestCIRTy);
+    mlirType middleTy = cgf.cgm.getDataLayout().getIntPtrType(destCIRTy);
     cir::CastOp middleVal = builder.createCast(subExpr->getType()->isBooleanType()
                                             ? cir::CastKind::bool_to_int
                                             : cir::CastKind::integral,

>From 9a9e05d4f9d6a00e4a37eaa84d26b0405199ca30 Mon Sep 17 00:00:00 2001
From: Shawn K <kimshawn02 at icloud.com>
Date: Thu, 2 Oct 2025 10:12:25 -0700
Subject: [PATCH 7/7] Update clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Co-authored-by: Andy Kaylor <akaylor at nvidia.com>
---
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 244973a12e3f5..c8a4f42566b17 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1904,7 +1904,7 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
                                         Src, MiddleTy);
 
     if (cgf.cgm.getCodeGenOpts().StrictVTablePointers)
-      llvm_unreachable("NYI");
+      cgf.cgm.errorNYI(subExpr->getSourceRange(), "IntegralToPointer: strict vtable pointers");
 
     return builder.createIntToPtr(MiddleVal, DestCIRTy);
   }



More information about the cfe-commits mailing list