Skip to content

Commit 806b491

Browse files
authored
[CIR] LLVMIR lowering for cir.call (llvm#138873)
1 parent a68f35a commit 806b491

File tree

4 files changed

+80
-12
lines changed

4 files changed

+80
-12
lines changed

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ struct MissingFeatures {
104104
static bool opCallExtParameterInfo() { return false; }
105105
static bool opCallCIRGenFuncInfoParamInfo() { return false; }
106106
static bool opCallCIRGenFuncInfoExtParamInfo() { return false; }
107+
static bool opCallLandingPad() { return false; }
108+
static bool opCallContinueBlock() { return false; }
107109

108110
// ScopeOp handling
109111
static bool opScopeCleanupRegion() { return false; }

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,50 @@ mlir::LogicalResult CIRToLLVMReturnOpLowering::matchAndRewrite(
651651
return mlir::LogicalResult::success();
652652
}
653653

654+
static mlir::LogicalResult
655+
rewriteCallOrInvoke(mlir::Operation *op, mlir::ValueRange callOperands,
656+
mlir::ConversionPatternRewriter &rewriter,
657+
const mlir::TypeConverter *converter,
658+
mlir::FlatSymbolRefAttr calleeAttr) {
659+
llvm::SmallVector<mlir::Type, 8> llvmResults;
660+
mlir::ValueTypeRange<mlir::ResultRange> cirResults = op->getResultTypes();
661+
662+
if (converter->convertTypes(cirResults, llvmResults).failed())
663+
return mlir::failure();
664+
665+
assert(!cir::MissingFeatures::opCallCallConv());
666+
assert(!cir::MissingFeatures::opCallSideEffect());
667+
668+
mlir::LLVM::LLVMFunctionType llvmFnTy;
669+
if (calleeAttr) { // direct call
670+
mlir::FunctionOpInterface fn =
671+
mlir::SymbolTable::lookupNearestSymbolFrom<mlir::FunctionOpInterface>(
672+
op, calleeAttr);
673+
assert(fn && "Did not find function for call");
674+
llvmFnTy = cast<mlir::LLVM::LLVMFunctionType>(
675+
converter->convertType(fn.getFunctionType()));
676+
} else { // indirect call
677+
assert(!cir::MissingFeatures::opCallIndirect());
678+
return op->emitError("Indirect calls are NYI");
679+
}
680+
681+
assert(!cir::MissingFeatures::opCallLandingPad());
682+
assert(!cir::MissingFeatures::opCallContinueBlock());
683+
assert(!cir::MissingFeatures::opCallCallConv());
684+
assert(!cir::MissingFeatures::opCallSideEffect());
685+
686+
rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>(op, llvmFnTy, calleeAttr,
687+
callOperands);
688+
return mlir::success();
689+
}
690+
691+
mlir::LogicalResult CIRToLLVMCallOpLowering::matchAndRewrite(
692+
cir::CallOp op, OpAdaptor adaptor,
693+
mlir::ConversionPatternRewriter &rewriter) const {
694+
return rewriteCallOrInvoke(op.getOperation(), adaptor.getOperands(), rewriter,
695+
getTypeConverter(), op.getCalleeAttr());
696+
}
697+
654698
mlir::LogicalResult CIRToLLVMLoadOpLowering::matchAndRewrite(
655699
cir::LoadOp op, OpAdaptor adaptor,
656700
mlir::ConversionPatternRewriter &rewriter) const {
@@ -1589,6 +1633,7 @@ void ConvertCIRToLLVMPass::runOnOperation() {
15891633
CIRToLLVMBinOpLowering,
15901634
CIRToLLVMBrCondOpLowering,
15911635
CIRToLLVMBrOpLowering,
1636+
CIRToLLVMCallOpLowering,
15921637
CIRToLLVMCmpOpLowering,
15931638
CIRToLLVMConstantOpLowering,
15941639
CIRToLLVMFuncOpLowering,

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,15 @@ class CIRToLLVMReturnOpLowering
6464
mlir::ConversionPatternRewriter &) const override;
6565
};
6666

67+
class CIRToLLVMCallOpLowering : public mlir::OpConversionPattern<cir::CallOp> {
68+
public:
69+
using mlir::OpConversionPattern<cir::CallOp>::OpConversionPattern;
70+
71+
mlir::LogicalResult
72+
matchAndRewrite(cir::CallOp op, OpAdaptor adaptor,
73+
mlir::ConversionPatternRewriter &rewriter) const override;
74+
};
75+
6776
class CIRToLLVMAllocaOpLowering
6877
: public mlir::OpConversionPattern<cir::AllocaOp> {
6978
mlir::DataLayout const &dataLayout;

clang/test/CIR/CodeGen/call.cpp

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,44 @@
1-
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - 2>&1 | FileCheck %s
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
4+
// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
25

36
void f1() {}
47
void f2() {
58
f1();
69
}
710

8-
// CHECK-LABEL: cir.func @_Z2f1v
9-
// CHECK-LABEL: cir.func @_Z2f2v
10-
// CHECK: cir.call @_Z2f1v() : () -> ()
11+
// CIR-LABEL: cir.func @_Z2f1v
12+
// CIR-LABEL: cir.func @_Z2f2v
13+
// CIR: cir.call @_Z2f1v() : () -> ()
14+
15+
// LLVM-LABEL: define void @_Z2f2v() {
16+
// LLVM: call void @_Z2f1v()
1117

1218
int f3() { return 2; }
1319
int f4() {
1420
int x = f3();
1521
return x;
1622
}
1723

18-
// CHECK-LABEL: cir.func @_Z2f3v() -> !s32i
19-
// CHECK-LABEL: cir.func @_Z2f4v() -> !s32i
20-
// CHECK: cir.call @_Z2f3v() : () -> !s32i
24+
// CIR-LABEL: cir.func @_Z2f3v() -> !s32i
25+
// CIR-LABEL: cir.func @_Z2f4v() -> !s32i
26+
// CIR: cir.call @_Z2f3v() : () -> !s32i
27+
28+
// LLVM-LABEL: define i32 @_Z2f4v() {
29+
// LLVM: %{{.+}} = call i32 @_Z2f3v()
2130

2231
int f5(int a, int *b, bool c);
2332
int f6() {
2433
int b = 1;
2534
return f5(2, &b, false);
2635
}
2736

28-
// CHECK-LABEL: cir.func @_Z2f6v() -> !s32i
29-
// CHECK: %[[#b:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init]
30-
// CHECK: %[[#a:]] = cir.const #cir.int<2> : !s32i
31-
// CHECK-NEXT: %[[#c:]] = cir.const #false
32-
// CHECK-NEXT: %{{.+}} = cir.call @_Z2f5iPib(%[[#a]], %[[#b:]], %[[#c]]) : (!s32i, !cir.ptr<!s32i>, !cir.bool) -> !s32i
37+
// CIR-LABEL: cir.func @_Z2f6v() -> !s32i
38+
// CIR: %[[#b:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init]
39+
// CIR: %[[#a:]] = cir.const #cir.int<2> : !s32i
40+
// CIR-NEXT: %[[#c:]] = cir.const #false
41+
// CIR-NEXT: %{{.+}} = cir.call @_Z2f5iPib(%[[#a]], %[[#b:]], %[[#c]]) : (!s32i, !cir.ptr<!s32i>, !cir.bool) -> !s32i
42+
43+
// LLVM-LABEL: define i32 @_Z2f6v() {
44+
// LLVM: %{{.+}} = call i32 @_Z2f5iPib(i32 2, ptr %{{.+}}, i1 false)

0 commit comments

Comments
 (0)