// Handle required vector arguments
mlir::Value vectorA = fir::getBase(args[0]);
mlir::Value vectorB = fir::getBase(args[1]);
+ // Result type is used for picking appropriate runtime function.
+ mlir::Type eleTy = resultType;
- 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()));
+ // This operation is only used to pass the result type
+ // information to the DotProduct generator.
+ auto resultBox = builder.create<fir::AbsentOp>(loc, fir::BoxType::get(eleTy));
return func(builder, loc, vectorA, vectorB, resultBox);
}
! 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
+
+! CHECK-LABEL: dot_product_mixed_int_real
+! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?xi32>>
+! CHECK-SAME: %[[y:arg1]]: !fir.box<!fir.array<?xf32>>
+! CHECK-SAME: %[[z:arg2]]: !fir.box<!fir.array<?xf32>>
+subroutine dot_product_mixed_int_real(x, y, z)
+ integer, dimension(1:) :: x
+ real, dimension(1:) :: y, 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<?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_product_mixed_int_complex
+! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?xi32>>
+! 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_product_mixed_int_complex(x, y, z)
+ integer, dimension(1:) :: x
+ complex, dimension(1:) :: y, z
+ ! CHECK-DAG: %[[res:.*]] = fir.alloca !fir.complex<4>
+ ! CHECK-DAG: %[[res_conv:.*]] = fir.convert %[[res]] : (!fir.ref<!fir.complex<4>>) -> !fir.ref<complex<f32>>
+ ! 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<?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_product_mixed_real_complex
+! CHECK-SAME: %[[x:arg0]]: !fir.box<!fir.array<?xf32>>
+! 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_product_mixed_real_complex(x, y, z)
+ real, dimension(1:) :: x
+ complex, dimension(1:) :: y, z
+ ! CHECK-DAG: %[[res:.*]] = fir.alloca !fir.complex<4>
+ ! CHECK-DAG: %[[res_conv:.*]] = fir.convert %[[res]] : (!fir.ref<!fir.complex<4>>) -> !fir.ref<complex<f32>>
+ ! 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<?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
mlir::Type refSeqTy = fir::ReferenceType::get(seqTy);
mlir::Value a = builder.create<fir::UndefOp>(loc, refSeqTy);
mlir::Value b = builder.create<fir::UndefOp>(loc, refSeqTy);
- mlir::Value result = builder.create<fir::UndefOp>(loc, seqTy);
+ mlir::Value result =
+ builder.create<fir::UndefOp>(loc, fir::ReferenceType::get(eleTy));
mlir::Value prod = fir::runtime::genDotProduct(builder, loc, a, b, result);
if (fir::isa_complex(eleTy))
checkCallOpFromResultBox(result, fctName, 3);