Skip to content

Commit

Permalink
[flang][lowering] Add support for lowering the dot_product intrinsic
Browse files Browse the repository at this point in the history
This patch adds support for lowering the `dot_product` intrinsic from
Fortran to the FIR dialect of MLIR.

This is part of the upstreaming effort from the `fir-dev` branch in [1].

[1] https://github.com/flang-compiler/f18-llvm-project

Differential Revision: https://reviews.llvm.org/D121684

Co-authored-by: Jean Perier <jperier@nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
Co-authored-by: Valentin Clement <clementval@gmail.com>
Co-authored-by: Mark Leair <leairmark@gmail.com>
  • Loading branch information
5 people committed Mar 15, 2022
1 parent 3a42296 commit 6714da0
Show file tree
Hide file tree
Showing 2 changed files with 288 additions and 0 deletions.
41 changes: 41 additions & 0 deletions flang/lib/Lower/IntrinsicCall.cpp
Expand Up @@ -197,6 +197,33 @@ genProdOrSum(FN func, FD funcDim, mlir::Type resultType,
args[1], mask, rank);
}

/// Process calls to DotProduct
template <typename FN>
static fir::ExtendedValue
genDotProd(FN func, mlir::Type resultType, fir::FirOpBuilder &builder,
mlir::Location loc, Fortran::lower::StatementContext *stmtCtx,
llvm::ArrayRef<fir::ExtendedValue> args) {

assert(args.size() == 2);

// Handle required vector arguments
mlir::Value vectorA = fir::getBase(args[0]);
mlir::Value vectorB = fir::getBase(args[1]);

mlir::Type eleTy = fir::dyn_cast_ptrOrBoxEleTy(vectorA.getType())
.cast<fir::SequenceType>()
.getEleTy();
if (fir::isa_complex(eleTy)) {
mlir::Value result = builder.createTemporary(loc, eleTy);
func(builder, loc, vectorA, vectorB, result);
return builder.create<fir::LoadOp>(loc, result);
}

auto resultBox = builder.create<fir::AbsentOp>(
loc, fir::BoxType::get(builder.getI1Type()));
return func(builder, loc, vectorA, vectorB, resultBox);
}

// TODO error handling -> return a code or directly emit messages ?
struct IntrinsicLibrary {

Expand Down Expand Up @@ -240,6 +267,8 @@ struct IntrinsicLibrary {
fir::ExtendedValue genAssociated(mlir::Type,
llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genChar(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genDotProduct(mlir::Type,
llvm::ArrayRef<fir::ExtendedValue>);
template <Extremum, ExtremumBehavior>
mlir::Value genExtremum(mlir::Type, llvm::ArrayRef<mlir::Value>);
/// Lowering for the IAND intrinsic. The IAND intrinsic expects two arguments
Expand Down Expand Up @@ -351,6 +380,10 @@ static constexpr IntrinsicHandler handlers[]{
{{{"pointer", asInquired}, {"target", asInquired}}},
/*isElemental=*/false},
{"char", &I::genChar},
{"dot_product",
&I::genDotProduct,
{{{"vector_a", asBox}, {"vector_b", asBox}}},
/*isElemental=*/false},
{"iand", &I::genIand},
{"min", &I::genExtremum<Extremum::Min, ExtremumBehavior::MinMaxss>},
{"sum",
Expand Down Expand Up @@ -1226,6 +1259,14 @@ IntrinsicLibrary::genChar(mlir::Type type,
return fir::CharBoxValue{cast, len};
}

// DOT_PRODUCT
fir::ExtendedValue
IntrinsicLibrary::genDotProduct(mlir::Type resultType,
llvm::ArrayRef<fir::ExtendedValue> args) {
return genDotProd(fir::runtime::genDotProduct, resultType, builder, loc,
stmtCtx, args);
}

// IAND
mlir::Value IntrinsicLibrary::genIand(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args) {
Expand Down
247 changes: 247 additions & 0 deletions flang/test/Lower/Intrinsics/dot_product.f90
@@ -0,0 +1,247 @@
! RUN: bbc -emit-fir %s -o - | FileCheck %s
! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s

! DOT_PROD
! CHECK-LABEL: dot_prod_int_default
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?xi32>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?xi32>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?xi32>>
subroutine dot_prod_int_default (x, y, z)
integer, dimension(1:) :: x,y
integer, dimension(1:) :: z
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<none>
! CHECK-DAG: %[[res:.*]] = fir.call @_FortranADotProductInteger4(%[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i32
z = dot_product(x,y)
end subroutine

! CHECK-LABEL: dot_prod_int_kind_1
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?xi8>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?xi8>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?xi8>>
subroutine dot_prod_int_kind_1 (x, y, z)
integer(kind=1), dimension(1:) :: x,y
integer(kind=1), dimension(1:) :: z
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xi8>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?xi8>>) -> !fir.box<none>
! CHECK-DAG: %[[res:.*]] = fir.call @_FortranADotProductInteger1(%[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i8
z = dot_product(x,y)
end subroutine

! CHECK-LABEL: dot_prod_int_kind_2
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?xi16>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?xi16>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?xi16>>
subroutine dot_prod_int_kind_2 (x, y, z)
integer(kind=2), dimension(1:) :: x,y
integer(kind=2), dimension(1:) :: z
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xi16>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?xi16>>) -> !fir.box<none>
! CHECK-DAG: %[[res:.*]] = fir.call @_FortranADotProductInteger2(%[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i16
z = dot_product(x,y)
end subroutine

! CHECK-LABEL: dot_prod_int_kind_4
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?xi32>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?xi32>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?xi32>>
subroutine dot_prod_int_kind_4 (x, y, z)
integer(kind=4), dimension(1:) :: x,y
integer(kind=4), dimension(1:) :: z
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<none>
! CHECK-DAG: %[[res:.*]] = fir.call @_FortranADotProductInteger4(%[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i32
z = dot_product(x,y)
end subroutine

! CHECK-LABEL: dot_prod_int_kind_8
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?xi64>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?xi64>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?xi64>>
subroutine dot_prod_int_kind_8 (x, y, z)
integer(kind=8), dimension(1:) :: x,y
integer(kind=8), dimension(1:) :: z
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xi64>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?xi64>>) -> !fir.box<none>
! CHECK-DAG: %[[res:.*]] = fir.call @_FortranADotProductInteger8(%[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i64
z = dot_product(x,y)
end subroutine

! CHECK-LABEL: dot_prod_int_kind_16
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?xi128>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?xi128>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?xi128>>
subroutine dot_prod_int_kind_16 (x, y, z)
integer(kind=16), dimension(1:) :: x,y
integer(kind=16), dimension(1:) :: z
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xi128>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?xi128>>) -> !fir.box<none>
! CHECK-DAG: %[[res:.*]] = fir.call @_FortranADotProductInteger16(%[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i128
z = dot_product(x,y)
end subroutine

! CHECK-LABEL: dot_prod_real_kind_default
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?xf32>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?xf32>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?xf32>>
subroutine dot_prod_real_kind_default (x, y, z)
real, dimension(1:) :: x,y
real, dimension(1:) :: z
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
! CHECK-DAG: %[[res:.*]] = fir.call @_FortranADotProductReal4(%[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> f32
z = dot_product(x,y)
end subroutine

! CHECK-LABEL: dot_prod_real_kind_4
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?xf32>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?xf32>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?xf32>>
subroutine dot_prod_real_kind_4 (x, y, z)
real(kind=4), dimension(1:) :: x,y
real(kind=4), dimension(1:) :: z
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
! CHECK-DAG: %[[res:.*]] = fir.call @_FortranADotProductReal4(%[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> f32
z = dot_product(x,y)
end subroutine

! CHECK-LABEL: dot_prod_real_kind_8
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?xf64>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?xf64>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?xf64>>
subroutine dot_prod_real_kind_8 (x, y, z)
real(kind=8), dimension(1:) :: x,y
real(kind=8), dimension(1:) :: z
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xf64>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?xf64>>) -> !fir.box<none>
! CHECK-DAG: %[[res:.*]] = fir.call @_FortranADotProductReal8(%[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> f64
z = dot_product(x,y)
end subroutine

! CHECK-LABEL: dot_prod_real_kind_10
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?xf80>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?xf80>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?xf80>>
subroutine dot_prod_real_kind_10 (x, y, z)
real(kind=10), dimension(1:) :: x,y
real(kind=10), dimension(1:) :: z
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xf80>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?xf80>>) -> !fir.box<none>
! CHECK-DAG: %[[res:.*]] = fir.call @_FortranADotProductReal10(%[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> f80
z = dot_product(x,y)
end subroutine

! CHECK-LABEL: dot_prod_real_kind_16
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?xf128>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?xf128>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?xf128>>
subroutine dot_prod_real_kind_16 (x, y, z)
real(kind=16), dimension(1:) :: x,y
real(kind=16), dimension(1:) :: z
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xf128>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?xf128>>) -> !fir.box<none>
! CHECK-DAG: %[[res:.*]] = fir.call @_FortranADotProductReal16(%[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> f128
z = dot_product(x,y)
end subroutine

! CHECK-LABEL: dot_prod_double_default
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?xf64>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?xf64>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?xf64>>
subroutine dot_prod_double_default (x, y, z)
double precision, dimension(1:) :: x,y
double precision, dimension(1:) :: z
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xf64>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?xf64>>) -> !fir.box<none>
! CHECK-DAG: %[[res:.*]] = fir.call @_FortranADotProductReal8(%[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> f64
z = dot_product(x,y)
end subroutine

! CHECK-LABEL: dot_prod_complex_default
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?x!fir.complex<4>>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?x!fir.complex<4>>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?x!fir.complex<4>>>
subroutine dot_prod_complex_default (x, y, z)
complex, dimension(1:) :: x,y
complex, dimension(1:) :: z
! CHECK-DAG: %0 = fir.alloca !fir.complex<4>
! CHECK-DAG: %[[res_conv:[0-9]+]] = fir.convert %0 : (!fir.ref<!fir.complex<4>>) -> !fir.ref<complex<f32>>
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?x!fir.complex<4>>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?x!fir.complex<4>>>) -> !fir.box<none>
! CHECK-DAG: fir.call @_FortranACppDotProductComplex4(%[[res_conv]], %[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.ref<complex<f32>>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> none
z = dot_product(x,y)
end subroutine

! CHECK-LABEL: dot_prod_complex_kind_4
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?x!fir.complex<4>>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?x!fir.complex<4>>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?x!fir.complex<4>>>
subroutine dot_prod_complex_kind_4 (x, y, z)
complex(kind=4), dimension(1:) :: x,y
complex(kind=4), dimension(1:) :: z
! CHECK-DAG: %0 = fir.alloca !fir.complex<4>
! CHECK-DAG: %[[res_conv:[0-9]+]] = fir.convert %0 : (!fir.ref<!fir.complex<4>>) -> !fir.ref<complex<f32>>
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?x!fir.complex<4>>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?x!fir.complex<4>>>) -> !fir.box<none>
! CHECK-DAG: fir.call @_FortranACppDotProductComplex4(%[[res_conv]], %[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.ref<complex<f32>>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> none
z = dot_product(x,y)
end subroutine

! CHECK-LABEL: dot_prod_complex_kind_8
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?x!fir.complex<8>>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?x!fir.complex<8>>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?x!fir.complex<8>>>
subroutine dot_prod_complex_kind_8 (x, y, z)
complex(kind=8), dimension(1:) :: x,y
complex(kind=8), dimension(1:) :: z
! CHECK-DAG: %0 = fir.alloca !fir.complex<8>
! CHECK-DAG: %[[res_conv:[0-9]+]] = fir.convert %0 : (!fir.ref<!fir.complex<8>>) -> !fir.ref<complex<f64>>
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?x!fir.complex<8>>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?x!fir.complex<8>>>) -> !fir.box<none>
! CHECK-DAG: fir.call @_FortranACppDotProductComplex8(%[[res_conv]], %[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.ref<complex<f64>>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> none
z = dot_product(x,y)
end subroutine

! CHECK-LABEL: dot_prod_complex_kind_10
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?x!fir.complex<10>>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?x!fir.complex<10>>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?x!fir.complex<10>>>
subroutine dot_prod_complex_kind_10 (x, y, z)
complex(kind=10), dimension(1:) :: x,y
complex(kind=10), dimension(1:) :: z
! CHECK-DAG: %0 = fir.alloca !fir.complex<10>
! CHECK-DAG: %[[res_conv:[0-9]+]] = fir.convert %0 : (!fir.ref<!fir.complex<10>>) -> !fir.ref<complex<f80>>
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?x!fir.complex<10>>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?x!fir.complex<10>>>) -> !fir.box<none>
! CHECK-DAG: fir.call @_FortranACppDotProductComplex10(%[[res_conv]], %[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.ref<complex<f80>>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
z = dot_product(x,y)
end subroutine

! CHECK-LABEL: dot_prod_complex_kind_16
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?x!fir.complex<16>>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?x!fir.complex<16>>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?x!fir.complex<16>>>
subroutine dot_prod_complex_kind_16 (x, y, z)
complex(kind=16), dimension(1:) :: x,y
complex(kind=16), dimension(1:) :: z
! CHECK-DAG: %0 = fir.alloca !fir.complex<16>
! CHECK-DAG: %[[res_conv:[0-9]+]] = fir.convert %0 : (!fir.ref<!fir.complex<16>>) -> !fir.ref<complex<f128>>
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?x!fir.complex<16>>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?x!fir.complex<16>>>) -> !fir.box<none>
! CHECK-DAG: fir.call @_FortranACppDotProductComplex16(%[[res_conv]], %[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.ref<complex<f128>>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
z = dot_product(x,y)
end subroutine

! CHECK-LABEL: dot_prod_logical
! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?x!fir.logical<4>>>
! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?x!fir.logical<4>>>
! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?x!fir.logical<4>>>
subroutine dot_prod_logical (x, y, z)
logical, dimension(1:) :: x,y
logical, dimension(1:) :: z
! CHECK-DAG: %[[x_conv:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?x!fir.logical<4>>>) -> !fir.box<none>
! CHECK-DAG: %[[y_conv:.*]] = fir.convert %[[y]] : (!fir.box<!fir.array<?x!fir.logical<4>>>) -> !fir.box<none>
! CHECK-DAG: %[[res:.*]] = fir.call @_FortranADotProductLogical(%[[x_conv]], %[[y_conv]], %{{[0-9]+}}, %{{.*}}) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> i1
z = dot_product(x,y)
end subroutine

0 comments on commit 6714da0

Please sign in to comment.