[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