[clang] [CIR] Upstream handling for delete array (PR #165225)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 27 03:03:27 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Shawn K (kimsh02)
<details>
<summary>Changes</summary>
Upstream `DeleteArrayOp` and `clang/test/CIR/CodeGen/delete-array.cpp`
---
Full diff: https://github.com/llvm/llvm-project/pull/165225.diff
4 Files Affected:
- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+18)
- (modified) clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp (+2-2)
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+37)
- (added) clang/test/CIR/CodeGen/delete-array.cpp (+16)
``````````diff
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/165225
More information about the cfe-commits
mailing list