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 <[email protected]> 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> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
