summaryrefslogtreecommitdiff
path: root/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Optimizer/Builder/IntrinsicCall.cpp')
-rw-r--r--flang/lib/Optimizer/Builder/IntrinsicCall.cpp69
1 files changed, 69 insertions, 0 deletions
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index d877be0cbc0a..dee08c7d85f8 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -1184,6 +1184,54 @@ static mlir::Value genLibCall(fir::FirOpBuilder &builder, mlir::Location loc,
return libCall.getResult(0);
}
+static mlir::Value genLibSplitComplexArgsCall(
+ fir::FirOpBuilder &builder, mlir::Location loc, llvm::StringRef libFuncName,
+ mlir::FunctionType libFuncType, llvm::ArrayRef<mlir::Value> args) {
+ assert(args.size() == 2 && "Incorrect #args to genLibSplitComplexArgsCall");
+
+ auto getSplitComplexArgsType = [&builder, &args]() -> mlir::FunctionType {
+ mlir::Type ctype = args[0].getType();
+ auto fKind = ctype.cast<fir::ComplexType>().getFKind();
+ mlir::Type ftype;
+
+ if (fKind == 2)
+ ftype = builder.getF16Type();
+ else if (fKind == 3)
+ ftype = builder.getBF16Type();
+ else if (fKind == 4)
+ ftype = builder.getF32Type();
+ else if (fKind == 8)
+ ftype = builder.getF64Type();
+ else if (fKind == 10)
+ ftype = builder.getF80Type();
+ else if (fKind == 16)
+ ftype = builder.getF128Type();
+ else
+ assert(0 && "Unsupported Complex Type");
+
+ return builder.getFunctionType({ftype, ftype, ftype, ftype}, {ctype});
+ };
+
+ llvm::SmallVector<mlir::Value, 4> splitArgs;
+ mlir::Value cplx1 = args[0];
+ auto real1 = fir::factory::Complex{builder, loc}.extractComplexPart(
+ cplx1, /*isImagPart=*/false);
+ splitArgs.push_back(real1);
+ auto imag1 = fir::factory::Complex{builder, loc}.extractComplexPart(
+ cplx1, /*isImagPart=*/true);
+ splitArgs.push_back(imag1);
+ mlir::Value cplx2 = args[1];
+ auto real2 = fir::factory::Complex{builder, loc}.extractComplexPart(
+ cplx2, /*isImagPart=*/false);
+ splitArgs.push_back(real2);
+ auto imag2 = fir::factory::Complex{builder, loc}.extractComplexPart(
+ cplx2, /*isImagPart=*/true);
+ splitArgs.push_back(imag2);
+
+ return genLibCall(builder, loc, libFuncName, getSplitComplexArgsType(),
+ splitArgs);
+}
+
template <typename T>
static mlir::Value genMathOp(fir::FirOpBuilder &builder, mlir::Location loc,
llvm::StringRef mathLibFuncName,
@@ -1345,6 +1393,22 @@ static constexpr MathOperation mathOperations[] = {
{"cosh", "cosh", genF64F64FuncType, genLibCall},
{"cosh", "ccoshf", genComplexComplexFuncType<4>, genLibCall},
{"cosh", "ccosh", genComplexComplexFuncType<8>, genLibCall},
+ {"divc",
+ {},
+ genComplexComplexComplexFuncType<2>,
+ genComplexMathOp<mlir::complex::DivOp>},
+ {"divc",
+ {},
+ genComplexComplexComplexFuncType<3>,
+ genComplexMathOp<mlir::complex::DivOp>},
+ {"divc", "__divsc3", genComplexComplexComplexFuncType<4>,
+ genLibSplitComplexArgsCall},
+ {"divc", "__divdc3", genComplexComplexComplexFuncType<8>,
+ genLibSplitComplexArgsCall},
+ {"divc", "__divxc3", genComplexComplexComplexFuncType<10>,
+ genLibSplitComplexArgsCall},
+ {"divc", "__divtc3", genComplexComplexComplexFuncType<16>,
+ genLibSplitComplexArgsCall},
{"erf", "erff", genF32F32FuncType, genMathOp<mlir::math::ErfOp>},
{"erf", "erf", genF64F64FuncType, genMathOp<mlir::math::ErfOp>},
{"erfc", "erfcf", genF32F32FuncType, genLibCall},
@@ -5661,6 +5725,11 @@ mlir::Value fir::genMin(fir::FirOpBuilder &builder, mlir::Location loc,
args);
}
+mlir::Value fir::genDivC(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Type type, mlir::Value x, mlir::Value y) {
+ return IntrinsicLibrary{builder, loc}.genRuntimeCall("divc", type, {x, y});
+}
+
mlir::Value fir::genPow(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Type type, mlir::Value x, mlir::Value y) {
// TODO: since there is no libm version of pow with integer exponent,