llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Sirui Mu (Lancern) <details> <summary>Changes</summary> This PR adds LLVMIR lowering support for the `cir.call` operation. --- Full diff: https://github.com/llvm/llvm-project/pull/138873.diff 4 Files Affected: - (modified) clang/include/clang/CIR/MissingFeatures.h (+2) - (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+45) - (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h (+9) - (modified) clang/test/CIR/CodeGen/call.cpp (+24-12) ``````````diff diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index eb75a073d1817..d49098768ad09 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -104,6 +104,8 @@ struct MissingFeatures { static bool opCallExtParameterInfo() { return false; } static bool opCallCIRGenFuncInfoParamInfo() { return false; } static bool opCallCIRGenFuncInfoExtParamInfo() { return false; } + static bool opCallLandingPad() { return false; } + static bool opCallContinueBlock() { return false; } // ScopeOp handling static bool opScopeCleanupRegion() { return false; } diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 6137adb1e9936..8ba079a55f1c5 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -651,6 +651,50 @@ mlir::LogicalResult CIRToLLVMReturnOpLowering::matchAndRewrite( return mlir::LogicalResult::success(); } +static mlir::LogicalResult +rewriteCallOrInvoke(mlir::Operation *op, mlir::ValueRange callOperands, + mlir::ConversionPatternRewriter &rewriter, + const mlir::TypeConverter *converter, + mlir::FlatSymbolRefAttr calleeAttr) { + llvm::SmallVector<mlir::Type, 8> llvmResults; + auto cirResults = op->getResultTypes(); + + if (converter->convertTypes(cirResults, llvmResults).failed()) + return mlir::failure(); + + assert(!cir::MissingFeatures::opCallCallConv()); + assert(!cir::MissingFeatures::opCallSideEffect()); + + mlir::LLVM::LLVMFunctionType llvmFnTy; + if (calleeAttr) { // direct call + auto fn = + mlir::SymbolTable::lookupNearestSymbolFrom<mlir::FunctionOpInterface>( + op, calleeAttr); + assert(fn && "Did not find function for call"); + llvmFnTy = cast<mlir::LLVM::LLVMFunctionType>( + converter->convertType(fn.getFunctionType())); + } else { // indirect call + assert(!cir::MissingFeatures::opCallIndirect()); + return op->emitError("Indirect calls are NYI"); + } + + assert(!cir::MissingFeatures::opCallLandingPad()); + assert(!cir::MissingFeatures::opCallContinueBlock()); + assert(!cir::MissingFeatures::opCallCallConv()); + assert(!cir::MissingFeatures::opCallSideEffect()); + + rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>(op, llvmFnTy, calleeAttr, + callOperands); + return mlir::success(); +} + +mlir::LogicalResult CIRToLLVMCallOpLowering::matchAndRewrite( + cir::CallOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + return rewriteCallOrInvoke(op.getOperation(), adaptor.getOperands(), rewriter, + getTypeConverter(), op.getCalleeAttr()); +} + mlir::LogicalResult CIRToLLVMLoadOpLowering::matchAndRewrite( cir::LoadOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { @@ -1589,6 +1633,7 @@ void ConvertCIRToLLVMPass::runOnOperation() { CIRToLLVMBinOpLowering, CIRToLLVMBrCondOpLowering, CIRToLLVMBrOpLowering, + CIRToLLVMCallOpLowering, CIRToLLVMCmpOpLowering, CIRToLLVMConstantOpLowering, CIRToLLVMFuncOpLowering, diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h index f248ea31e7844..0da4f9ba2c791 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h @@ -64,6 +64,15 @@ class CIRToLLVMReturnOpLowering mlir::ConversionPatternRewriter &) const override; }; +class CIRToLLVMCallOpLowering : public mlir::OpConversionPattern<cir::CallOp> { +public: + using mlir::OpConversionPattern<cir::CallOp>::OpConversionPattern; + + mlir::LogicalResult + matchAndRewrite(cir::CallOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const override; +}; + class CIRToLLVMAllocaOpLowering : public mlir::OpConversionPattern<cir::AllocaOp> { mlir::DataLayout const &dataLayout; diff --git a/clang/test/CIR/CodeGen/call.cpp b/clang/test/CIR/CodeGen/call.cpp index f6dc5e15933ed..3b1ab8b5fc498 100644 --- a/clang/test/CIR/CodeGen/call.cpp +++ b/clang/test/CIR/CodeGen/call.cpp @@ -1,13 +1,19 @@ -// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - 2>&1 | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM void f1() {} void f2() { f1(); } -// CHECK-LABEL: cir.func @_Z2f1v -// CHECK-LABEL: cir.func @_Z2f2v -// CHECK: cir.call @_Z2f1v() : () -> () +// CIR-LABEL: cir.func @_Z2f1v +// CIR-LABEL: cir.func @_Z2f2v +// CIR: cir.call @_Z2f1v() : () -> () + +// LLVM-LABEL: define void @_Z2f2v() { +// LLVM: call void @_Z2f1v() int f3() { return 2; } int f4() { @@ -15,9 +21,12 @@ int f4() { return x; } -// CHECK-LABEL: cir.func @_Z2f3v() -> !s32i -// CHECK-LABEL: cir.func @_Z2f4v() -> !s32i -// CHECK: cir.call @_Z2f3v() : () -> !s32i +// CIR-LABEL: cir.func @_Z2f3v() -> !s32i +// CIR-LABEL: cir.func @_Z2f4v() -> !s32i +// CIR: cir.call @_Z2f3v() : () -> !s32i + +// LLVM-LABEL: define i32 @_Z2f4v() { +// LLVM: %{{.+}} = call i32 @_Z2f3v() int f5(int a, int *b, bool c); int f6() { @@ -25,8 +34,11 @@ int f6() { return f5(2, &b, false); } -// CHECK-LABEL: cir.func @_Z2f6v() -> !s32i -// CHECK: %[[#b:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init] -// CHECK: %[[#a:]] = cir.const #cir.int<2> : !s32i -// CHECK-NEXT: %[[#c:]] = cir.const #false -// CHECK-NEXT: %{{.+}} = cir.call @_Z2f5iPib(%[[#a]], %[[#b:]], %[[#c]]) : (!s32i, !cir.ptr<!s32i>, !cir.bool) -> !s32i +// CIR-LABEL: cir.func @_Z2f6v() -> !s32i +// CIR: %[[#b:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init] +// CIR: %[[#a:]] = cir.const #cir.int<2> : !s32i +// CIR-NEXT: %[[#c:]] = cir.const #false +// CIR-NEXT: %{{.+}} = cir.call @_Z2f5iPib(%[[#a]], %[[#b:]], %[[#c]]) : (!s32i, !cir.ptr<!s32i>, !cir.bool) -> !s32i + +// LLVM-LABEL: define i32 @_Z2f6v() { +// LLVM: %{{.+}} = call i32 @_Z2f5iPib(i32 2, ptr %{{.+}}, i1 false) `````````` </details> https://github.com/llvm/llvm-project/pull/138873 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits