-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang] Implement ACOSD and ASIND #80448
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-flang-fir-hlfir Author: Michael Klemm (mjklemm) ChangesThis PR implements two missing intrinsics from F2023: ACOSD and ASIND. The implementation breaks them down to the existing ACOS and ASIN implementation. Full diff: https://github.com/llvm/llvm-project/pull/80448.diff 4 Files Affected:
diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
index 8149cdd383ae6..59a67c49fd610 100644
--- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
+++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
@@ -162,6 +162,7 @@ struct IntrinsicLibrary {
/// if the argument is an integer, into llvm intrinsics if the argument is
/// real and to the `hypot` math routine if the argument is of complex type.
mlir::Value genAbs(mlir::Type, llvm::ArrayRef<mlir::Value>);
+ mlir::Value genAcosd(mlir::Type, llvm::ArrayRef<mlir::Value>);
template <void (*CallRuntime)(fir::FirOpBuilder &, mlir::Location loc,
mlir::Value, mlir::Value)>
fir::ExtendedValue genAdjustRtCall(mlir::Type,
@@ -173,11 +174,12 @@ struct IntrinsicLibrary {
llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genAnint(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genAny(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
- mlir::Value genAtand(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue
genCommandArgumentCount(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
+ mlir::Value genAsind(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genAssociated(mlir::Type,
llvm::ArrayRef<fir::ExtendedValue>);
+ mlir::Value genAtand(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genBesselJn(mlir::Type,
llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genBesselYn(mlir::Type,
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 438ee4071b385..4e874d9fb1dcf 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -111,6 +111,7 @@ static constexpr IntrinsicHandler handlers[]{
{"abort", &I::genAbort},
{"abs", &I::genAbs},
{"achar", &I::genChar},
+ {"acosd", &I::genAcosd},
{"adjustl",
&I::genAdjustRtCall<fir::runtime::genAdjustL>,
{{{"string", asAddr}}},
@@ -134,6 +135,7 @@ static constexpr IntrinsicHandler handlers[]{
&I::genAny,
{{{"mask", asAddr}, {"dim", asValue}}},
/*isElemental=*/false},
+ {"asind", &I::genAsind},
{"associated",
&I::genAssociated,
{{{"pointer", asInquired}, {"target", asInquired}}},
@@ -2003,6 +2005,21 @@ mlir::Value IntrinsicLibrary::genAbs(mlir::Type resultType,
llvm_unreachable("unexpected type in ABS argument");
}
+// ACOSD
+mlir::Value IntrinsicLibrary::genAcosd(mlir::Type resultType,
+ llvm::ArrayRef<mlir::Value> args) {
+ assert(args.size() == 1);
+ mlir::MLIRContext *context = builder.getContext();
+ mlir::FunctionType ftype =
+ mlir::FunctionType::get(context, {resultType}, {args[0].getType()});
+ llvm::APFloat pi = llvm::APFloat(llvm::numbers::pi);
+ mlir::Value dfactor = builder.createRealConstant(
+ loc, mlir::FloatType::getF64(context), pi / llvm::APFloat(180.0));
+ mlir::Value factor = builder.createConvert(loc, args[0].getType(), dfactor);
+ mlir::Value arg = builder.create<mlir::arith::MulFOp>(loc, args[0], factor);
+ return getRuntimeCallGenerator("acos", ftype)(builder, loc, {arg});
+}
+
// ADJUSTL & ADJUSTR
template <void (*CallRuntime)(fir::FirOpBuilder &, mlir::Location loc,
mlir::Value, mlir::Value)>
@@ -2139,6 +2156,22 @@ IntrinsicLibrary::genAny(mlir::Type resultType,
return readAndAddCleanUp(resultMutableBox, resultType, "ANY");
}
+// ASIND
+mlir::Value IntrinsicLibrary::genAsind(mlir::Type resultType,
+ llvm::ArrayRef<mlir::Value> args) {
+ assert(args.size() == 1);
+ mlir::MLIRContext *context = builder.getContext();
+ mlir::FunctionType ftype =
+ mlir::FunctionType::get(context, {resultType}, {args[0].getType()});
+ llvm::APFloat pi = llvm::APFloat(llvm::numbers::pi);
+ mlir::Value dfactor = builder.createRealConstant(
+ loc, mlir::FloatType::getF64(context), pi / llvm::APFloat(180.0));
+ mlir::Value factor = builder.createConvert(loc, args[0].getType(), dfactor);
+ mlir::Value arg = builder.create<mlir::arith::MulFOp>(loc, args[0], factor);
+ return getRuntimeCallGenerator("asin", ftype)(builder, loc, {arg});
+}
+
+// ATAND
mlir::Value IntrinsicLibrary::genAtand(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args) {
assert(args.size() == 1);
diff --git a/flang/test/Lower/Intrinsics/acosd.f90 b/flang/test/Lower/Intrinsics/acosd.f90
new file mode 100644
index 0000000000000..3f558d66c35a1
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/acosd.f90
@@ -0,0 +1,24 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK"
+! RUN: bbc --math-runtime=precise -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-PRECISE"
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK"
+
+function test_real4(x)
+ real :: x, test_real4
+ test_real4 = acosd(x)
+end function
+
+! CHECK-LABEL: @_QPtest_real4
+! CHECK: %[[dfactor:.*]] = arith.constant 0.017453292519943295 : f64
+! CHECK: %[[factor:.*]] = fir.convert %[[dfactor]] : (f64) -> f32
+! CHECK: %[[arg:.*]] = arith.mulf %{{[A-Za-z0-9._]+}}, %[[factor]] fastmath<contract> : f32
+! CHECK-PRECISE: %{{.*}} = fir.call @acosf(%[[arg]]) fastmath<contract> : (f32) -> f32
+
+function test_real8(x)
+ real(8) :: x, test_real8
+ test_real8 = acosd(x)
+end function
+
+! CHECK-LABEL: @_QPtest_real8
+! CHECK: %[[factor:.*]] = arith.constant 0.017453292519943295 : f64
+! CHECK: %[[arg:.*]] = arith.mulf %{{[A-Za-z0-9._]+}}, %[[factor]] fastmath<contract> : f64
+! CHECK-PRECISE: %{{.*}} = fir.call @acos(%[[arg]]) fastmath<contract> : (f64) -> f64
diff --git a/flang/test/Lower/Intrinsics/asind.f90 b/flang/test/Lower/Intrinsics/asind.f90
new file mode 100644
index 0000000000000..e03f2e5598555
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/asind.f90
@@ -0,0 +1,24 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK"
+! RUN: bbc --math-runtime=precise -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-PRECISE"
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK"
+
+function test_real4(x)
+ real :: x, test_real4
+ test_real4 = asind(x)
+end function
+
+! CHECK-LABEL: @_QPtest_real4
+! CHECK: %[[dfactor:.*]] = arith.constant 0.017453292519943295 : f64
+! CHECK: %[[factor:.*]] = fir.convert %[[dfactor]] : (f64) -> f32
+! CHECK: %[[arg:.*]] = arith.mulf %{{[A-Za-z0-9._]+}}, %[[factor]] fastmath<contract> : f32
+! CHECK-PRECISE: %{{.*}} = fir.call @asinf(%[[arg]]) fastmath<contract> : (f32) -> f32
+
+function test_real8(x)
+ real(8) :: x, test_real8
+ test_real8 = asind(x)
+end function
+
+! CHECK-LABEL: @_QPtest_real8
+! CHECK: %[[factor:.*]] = arith.constant 0.017453292519943295 : f64
+! CHECK: %[[arg:.*]] = arith.mulf %{{[A-Za-z0-9._]+}}, %[[factor]] fastmath<contract> : f64
+! CHECK-PRECISE: %{{.*}} = fir.call @asin(%[[arg]]) fastmath<contract> : (f64) -> f64
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks for providing the missing trigonometry functions!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks for this!
This PR implements two missing intrinsics from F2023: ACOSD and ASIND. The implementation breaks them down to the existing ACOS and ASIN implementation.
This PR implements two missing intrinsics from F2023: ACOSD and ASIND. The implementation breaks them down to the existing ACOS and ASIN implementation.