forked from OSchip/llvm-project
[flang][CodeGen] Transform `fir.call` to `llvm.call`
This patch extends the `FIRToLLVMLowering` pass in Flang by adding a hook to transform `fir.call` to `llvm.call`. This is part of the upstreaming effort from the `fir-dev` branch in [1]. [1] https://github.com/flang-compiler/f18-llvm-project Patch originally written by: Co-authored-by: Eric Schweitz <eschweitz@nvidia.com> Co-authored-by: V Donaldson <vdonaldson@nvidia.com> Differential Revision: https://reviews.llvm.org/D113278
This commit is contained in:
parent
c2b91eef27
commit
ddd11b9a4b
|
@ -79,6 +79,22 @@ struct AddrOfOpConversion : public FIROpConversion<fir::AddrOfOp> {
|
|||
}
|
||||
};
|
||||
|
||||
// `fir.call` -> `llvm.call`
|
||||
struct CallOpConversion : public FIROpConversion<fir::CallOp> {
|
||||
using FIROpConversion::FIROpConversion;
|
||||
|
||||
mlir::LogicalResult
|
||||
matchAndRewrite(fir::CallOp call, OpAdaptor adaptor,
|
||||
mlir::ConversionPatternRewriter &rewriter) const override {
|
||||
SmallVector<mlir::Type> resultTys;
|
||||
for (auto r : call.getResults())
|
||||
resultTys.push_back(convertType(r.getType()));
|
||||
rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>(
|
||||
call, resultTys, adaptor.getOperands(), call->getAttrs());
|
||||
return success();
|
||||
}
|
||||
};
|
||||
|
||||
/// Lower `fir.has_value` operation to `llvm.return` operation.
|
||||
struct HasValueOpConversion : public FIROpConversion<fir::HasValueOp> {
|
||||
using FIROpConversion::FIROpConversion;
|
||||
|
@ -489,10 +505,11 @@ public:
|
|||
fir::LLVMTypeConverter typeConverter{getModule()};
|
||||
mlir::OwningRewritePatternList pattern(context);
|
||||
pattern.insert<
|
||||
AddrOfOpConversion, ExtractValueOpConversion, HasValueOpConversion,
|
||||
GlobalOpConversion, InsertOnRangeOpConversion, InsertValueOpConversion,
|
||||
SelectOpConversion, SelectRankOpConversion, UndefOpConversion,
|
||||
UnreachableOpConversion, ZeroOpConversion>(typeConverter);
|
||||
AddrOfOpConversion, CallOpConversion, ExtractValueOpConversion,
|
||||
HasValueOpConversion, GlobalOpConversion, InsertOnRangeOpConversion,
|
||||
InsertValueOpConversion, SelectOpConversion, SelectRankOpConversion,
|
||||
UndefOpConversion, UnreachableOpConversion, ZeroOpConversion>(
|
||||
typeConverter);
|
||||
mlir::populateStdToLLVMConversionPatterns(typeConverter, pattern);
|
||||
mlir::arith::populateArithmeticToLLVMConversionPatterns(typeConverter,
|
||||
pattern);
|
||||
|
|
|
@ -323,3 +323,56 @@ func @insert_tuple(%a : tuple<i32, f32>) {
|
|||
// CHECK-SAME: %[[TUPLE:.*]]: !llvm.struct<(i32, f32)>
|
||||
// CHECK: %{{.*}} = llvm.insertvalue %{{.*}}, %[[TUPLE]][1 : index] : !llvm.struct<(i32, f32)>
|
||||
// CHECK: llvm.return
|
||||
|
||||
// -----
|
||||
// Test `fir.call` -> `llvm.call` conversion for functions that take no arguments
|
||||
// and return nothing
|
||||
|
||||
func @dummy_basic() {
|
||||
return
|
||||
}
|
||||
|
||||
func @test_call_basic() {
|
||||
fir.call @dummy_basic() : () -> ()
|
||||
return
|
||||
}
|
||||
|
||||
// CHECK-LABEL: func @test_call_basic() {
|
||||
// CHECK-NEXT: llvm.call @dummy_basic() : () -> ()
|
||||
// CHECK-NEXT: return
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// Test `fir.call` -> `llvm.call` conversion for functions that take one
|
||||
// argument and return nothing
|
||||
|
||||
func @dummy_with_arg(%arg0 : i32) {
|
||||
return
|
||||
}
|
||||
|
||||
func @test_call_with_arg(%arg0 : i32) {
|
||||
fir.call @dummy_with_arg(%arg0) : (i32) -> ()
|
||||
return
|
||||
}
|
||||
|
||||
// CHECK-LABEL: llvm.func @test_call_with_arg(%arg0: i32) {
|
||||
// CHECK-NEXT: llvm.call @dummy_with_arg(%arg0) : (i32) -> ()
|
||||
// CHECK-NEXT: llvm.return
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// Test `fir.call` -> `llvm.call` conversion for functions that take no
|
||||
// arguments, but return a value
|
||||
|
||||
func @dummy_return_val() -> i32 {
|
||||
%1 = arith.constant 123 : i32
|
||||
return %1 : i32
|
||||
}
|
||||
|
||||
func @test_call_return_val() -> i32 {
|
||||
%1 = fir.call @dummy_return_val() : () -> (i32)
|
||||
return %1 : i32
|
||||
}
|
||||
|
||||
// CHECK-LABEL: llvm.func @test_call_return_val() -> i32 {
|
||||
// CHECK-NEXT: %0 = llvm.call @dummy_return_val() : () -> i32
|
||||
// CHECK-NEXT: llvm.return %0 : i32
|
||||
// CHECK-NEXT: }
|
||||
|
|
Loading…
Reference in New Issue