Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -4089,6 +4089,24 @@ def CIR_PrefetchOp : CIR_Op<"prefetch"> {
}];
}

//===----------------------------------------------------------------------===//
// DeleteArrayOp
//===----------------------------------------------------------------------===//

def CIR_DeleteArrayOp : CIR_Op<"delete.array"> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def CIR_DeleteArrayOp : CIR_Op<"delete.array"> {
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;`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`cir.delete.array` operation deletes an array. For example, `delete[] ptr;`
`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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$address `:` type($address) attr-dict
$address `:` qualified(type($address)) attr-dict

}];
}

//===----------------------------------------------------------------------===//
// PtrDiffOp
//===----------------------------------------------------------------------===//
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
37 changes: 37 additions & 0 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
16 changes: 16 additions & 0 deletions clang/test/CIR/CodeGen/delete-array.cpp
Original file line number Diff line number Diff line change
@@ -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
Comment on lines +12 to +16
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make more explicit checks