[flang-commits] [flang] 6714da0 - [flang][lowering] Add support for lowering the `dot_product` intrinsic

Andrzej Warzynski via flang-commits flang-commits at lists.llvm.org
Tue Mar 15 09:02:47 PDT 2022


Author: Andrzej Warzynski
Date: 2022-03-15T15:59:27Z
New Revision: 6714da0d14f130a799cf044ca6c5dd953a9c59ea

URL: https://github.com/llvm/llvm-project/commit/6714da0d14f130a799cf044ca6c5dd953a9c59ea
DIFF: https://github.com/llvm/llvm-project/commit/6714da0d14f130a799cf044ca6c5dd953a9c59ea.diff

LOG: [flang][lowering] Add support for lowering the `dot_product` intrinsic

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 at nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz at nvidia.com>
Co-authored-by: Valentin Clement <clementval at gmail.com>
Co-authored-by: Mark Leair <leairmark at gmail.com>

Added: 
    flang/test/Lower/Intrinsics/dot_product.f90

Modified: 
    flang/lib/Lower/IntrinsicCall.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp
index 04d1f58d10ec2..9eec8534006d0 100644
--- a/flang/lib/Lower/IntrinsicCall.cpp
+++ b/flang/lib/Lower/IntrinsicCall.cpp
@@ -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 {
 
@@ -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
@@ -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",
@@ -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) {

diff  --git a/flang/test/Lower/Intrinsics/dot_product.f90 b/flang/test/Lower/Intrinsics/dot_product.f90
new file mode 100644
index 0000000000000..3b4c77a853b58
--- /dev/null
+++ b/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


        


More information about the flang-commits mailing list