https://github.com/kimsh02 created https://github.com/llvm/llvm-project/pull/165225
Upstream `DeleteArrayOp` and `clang/test/CIR/CodeGen/delete-array.cpp` >From c42f2e6f43219a49dc6f4d1780286234904192ed Mon Sep 17 00:00:00 2001 From: kimsh02 <[email protected]> Date: Mon, 27 Oct 2025 02:58:25 -0700 Subject: [PATCH] [CIR] Upstream handling for delete array --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 18 +++++++++ clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp | 4 +- .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 37 +++++++++++++++++++ clang/test/CIR/CodeGen/delete-array.cpp | 16 ++++++++ 4 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 clang/test/CIR/CodeGen/delete-array.cpp diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 2b361ed0982c6..b7bdfe7d9f5b6 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -4089,6 +4089,24 @@ def CIR_PrefetchOp : CIR_Op<"prefetch"> { }]; } +//===----------------------------------------------------------------------===// +// DeleteArrayOp +//===----------------------------------------------------------------------===// + +def CIR_DeleteArrayOp : CIR_Op<"delete.array"> { + let summary = "Delete address representing an array"; + let description = [{ + `cir.delete.array` operation deletes an array. For example, `delete[] ptr;` + will be translated to `cir.delete.array %ptr`. + }]; + + let arguments = (ins CIR_PointerType:$address); + + let assemblyFormat = [{ + $address `:` type($address) attr-dict + }]; +} + //===----------------------------------------------------------------------===// // PtrDiffOp //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp index 7a35382e79a93..42d066e88225c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp @@ -626,8 +626,8 @@ void CIRGenFunction::emitCXXDeleteExpr(const CXXDeleteExpr *e) { ptr = ptr.withElementType(builder, convertTypeForMem(deleteTy)); if (e->isArrayForm()) { - assert(!cir::MissingFeatures::deleteArray()); - cgm.errorNYI(e->getSourceRange(), "emitCXXDeleteExpr: array delete"); + cir::DeleteArrayOp::create(builder, ptr.getPointer().getLoc(), + ptr.getPointer()); return; } else { emitObjectDelete(*this, e, ptr, deleteTy); diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 5a6193fa8d840..aba182e2c9952 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -1704,6 +1704,43 @@ mlir::LogicalResult CIRToLLVMPrefetchOpLowering::matchAndRewrite( return mlir::success(); } +// Make sure the LLVM function we are about to create a call for actually +// exists, if not create one. Returns a function +static void getOrCreateLLVMFuncOp(mlir::ConversionPatternRewriter &rewriter, + mlir::Operation *srcOp, + llvm::StringRef fnName, mlir::Type fnTy) { + auto modOp = srcOp->getParentOfType<mlir::ModuleOp>(); + auto enclosingFnOp = srcOp->getParentOfType<mlir::LLVM::LLVMFuncOp>(); + mlir::Operation *sourceSymbol = + mlir::SymbolTable::lookupSymbolIn(modOp, fnName); + if (!sourceSymbol) { + mlir::OpBuilder::InsertionGuard guard(rewriter); + rewriter.setInsertionPoint(enclosingFnOp); + mlir::LLVM::LLVMFuncOp::create(rewriter, srcOp->getLoc(), fnName, fnTy); + } +} + +mlir::LogicalResult CIRToLLVMDeleteArrayOpLowering::matchAndRewrite( + cir::DeleteArrayOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + StringRef fnName = "_ZdaPv"; + + auto voidTy = rewriter.getType<mlir::LLVM::LLVMVoidType>(); + mlir::Type llvmPtrTy = + mlir::LLVM::LLVMPointerType::get(rewriter.getContext()); + + mlir::Type fnTy = mlir::LLVM::LLVMFunctionType::get(voidTy, {llvmPtrTy}, + /*isVarArg=*/false); + + getOrCreateLLVMFuncOp(rewriter, op, fnName, fnTy); + + // Replace the operation with a call to _ZdaPv with the pointer argument + rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>( + op, mlir::TypeRange{}, fnName, mlir::ValueRange{adaptor.getAddress()}); + + return mlir::success(); +} + mlir::LogicalResult CIRToLLVMPtrDiffOpLowering::matchAndRewrite( cir::PtrDiffOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { diff --git a/clang/test/CIR/CodeGen/delete-array.cpp b/clang/test/CIR/CodeGen/delete-array.cpp new file mode 100644 index 0000000000000..0ff08be61ef45 --- /dev/null +++ b/clang/test/CIR/CodeGen/delete-array.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -emit-llvm %s -o %t.ll +// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s + +void test_delete_array(int *ptr) { + delete[] ptr; +} + +// CIR: cir.delete.array + +// LLVM: call void @_ZdaPv{{(m)?}}(ptr + +// OGCG: call void @_ZdaPv{{(m)?}}(ptr _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
