[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 04:40:29 PDT 2025
https://github.com/kimsh02 created https://github.com/llvm/llvm-project/pull/161653
Fix #153658
Handle integral to pointer casts and port the relevant `cast.cpp` test cases from incubator.
>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] [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>
More information about the cfe-commits
mailing list