-
Notifications
You must be signed in to change notification settings - Fork 11.4k
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
[flang] Fix for atand(Y,X), and implment atan2d(Y,X), atanpi(X), atanpi(Y,X), atan2pi(Y,X) #79002
Conversation
@llvm/pr-subscribers-flang-semantics @llvm/pr-subscribers-flang-fir-hlfir Author: Yi Wu (yi-wu-arm) ChangesBoth call the Full diff: https://github.com/llvm/llvm-project/pull/79002.diff 6 Files Affected:
diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
index 80f79d42fc2b75c..e85ad402fb2c33c 100644
--- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
+++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
@@ -174,6 +174,7 @@ struct IntrinsicLibrary {
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>);
+ mlir::Value genAtan2d(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue
genCommandArgumentCount(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genAssociated(mlir::Type,
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index da6d5970089884c..c059fa3502c35e2 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -333,11 +333,15 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
common::Intent::In, {ArgFlag::canBeNull}}},
DefaultLogical, Rank::elemental, IntrinsicClass::inquiryFunction},
{"atan", {{"x", SameFloating}}, SameFloating},
- {"atand", {{"x", SameFloating}}, SameFloating},
{"atan", {{"y", OperandReal}, {"x", OperandReal}}, OperandReal},
- {"atand", {{"y", OperandReal}, {"x", OperandReal}}, OperandReal},
+ {"atand",
+ {{"y", SameReal, Rank::scalar, Optionality::required,
+ common::Intent::In},
+ {"x", SameReal, Rank::scalar, Optionality::optional,
+ common::Intent::In}},
+ SameReal, Rank::scalar, IntrinsicClass::inquiryFunction},
{"atan2", {{"y", OperandReal}, {"x", OperandReal}}, OperandReal},
- {"atan2d", {{"y", OperandReal}, {"x", OperandReal}}, OperandReal},
+ {"atan2d", {{"y", SameReal}, {"x", SameReal}}, SameReal},
{"atanh", {{"x", SameFloating}}, SameFloating},
{"bessel_j0", {{"x", SameReal}}, SameReal},
{"bessel_j1", {{"x", SameReal}}, SameReal},
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index ac7d4fbe23e6738..b685878ad8c60f6 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -138,6 +138,7 @@ static constexpr IntrinsicHandler handlers[]{
&I::genAssociated,
{{{"pointer", asInquired}, {"target", asInquired}}},
/*isElemental=*/false},
+ {"atan2d", &I::genAtan2d},
{"atand", &I::genAtand},
{"bessel_jn",
&I::genBesselJn,
@@ -2128,13 +2129,53 @@ IntrinsicLibrary::genAny(mlir::Type resultType,
return readAndAddCleanUp(resultMutableBox, resultType, "ANY");
}
+// ATAN2D
+mlir::Value IntrinsicLibrary::genAtan2d(mlir::Type resultType,
+ llvm::ArrayRef<mlir::Value> args) {
+ assert(args.size() == 2);
+
+ mlir::Value y = fir::getBase(args[0]);
+ mlir::Value x = fir::getBase(args[1]);
+
+ // When Y == 0 X must not be 0
+ mlir::Value zero = builder.createRealZeroConstant(loc, y.getType());
+ mlir::Value cmpYEq0 = builder.create<mlir::arith::CmpFOp>(
+ loc, mlir::arith::CmpFPredicate::UEQ, y, zero);
+ mlir::Value cmpXEq0 = builder.create<mlir::arith::CmpFOp>(
+ loc, mlir::arith::CmpFPredicate::UEQ, x, zero);
+ mlir::Value terminationCheck =
+ builder.create<mlir::arith::AndIOp>(loc, cmpYEq0, cmpXEq0);
+ builder.genIfThenElse(loc, terminationCheck)
+ .genThen([&]() {
+ fir::runtime::genReportFatalUserError(builder, loc,
+ "When Y == 0 X must not be 0");
+ })
+ .end();
+
+ // atand(y,x) atan2d(y,x) == atan2(y,x) * 180/pi
+ mlir::Value atan = builder.create<mlir::math::Atan2Op>(loc, y, x);
+ mlir::MLIRContext *context = builder.getContext();
+ llvm::APFloat pi = llvm::APFloat(llvm::numbers::pi);
+ mlir::Value dfactor = builder.createRealConstant(
+ loc, mlir::FloatType::getF64(context), llvm::APFloat(180.0) / pi);
+ mlir::Value factor = builder.createConvert(loc, resultType, dfactor);
+ return builder.create<mlir::arith::MulFOp>(loc, atan, factor);
+}
+
+// ATAND
mlir::Value IntrinsicLibrary::genAtand(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args) {
- assert(args.size() == 1);
+ assert(args.size() == 2);
+
+ mlir::Value atan;
+
+ // atand(y,x) atan2d(y,x) == atan2(y,x) * 180/pi
+ if (isStaticallyPresent(args[1])) {
+ atan = builder.create<mlir::math::Atan2Op>(loc, args[0], args[1]);
+ } else {
+ atan = builder.create<mlir::math::AtanOp>(loc, args[0]);
+ }
mlir::MLIRContext *context = builder.getContext();
- mlir::FunctionType ftype =
- mlir::FunctionType::get(context, {resultType}, {args[0].getType()});
- mlir::Value atan = getRuntimeCallGenerator("atan", ftype)(builder, loc, args);
llvm::APFloat pi = llvm::APFloat(llvm::numbers::pi);
mlir::Value dfactor = builder.createRealConstant(
loc, mlir::FloatType::getF64(context), llvm::APFloat(180.0) / pi);
diff --git a/flang/test/Lower/Intrinsics/atan2d.f90 b/flang/test/Lower/Intrinsics/atan2d.f90
new file mode 100644
index 000000000000000..f94c2d79c0d4b79
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/atan2d.f90
@@ -0,0 +1,28 @@
+! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-FAST"
+! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-FAST"
+
+
+function test_real4_all_args(y,x)
+ real(4) :: x, y, test_real4
+ test_real4 = atan2d(y,x)
+end function
+
+! CHECK-LABEL: @_QPtest_real4_all_args
+! CHECK: %[[terminationCheck:.*]] = arith.andi %[[YEq0:.*]], %[[XEq0:.*]] : i1
+! CHECK: fir.if %[[terminationCheck]]
+! CHECK-FAST: %[[atan2:.*]] = math.atan2 %{{.*}}, %{{.*}}: f32
+! CHECK: %[[dfactor:.*]] = arith.constant 57.295779513082323 : f64
+! CHECK: %[[factor:.*]] = fir.convert %[[dfactor]] : (f64) -> f32
+! CHECK: %{{.*}} = arith.mulf %[[atan2]], %[[factor]] fastmath<contract> : f32
+
+function test_real8_all_args(y,x)
+ real(8) :: x, y, test_real8
+ test_real8 = atan2d(y,x)
+end function
+
+! CHECK-LABEL: @_QPtest_real8_all_args
+! CHECK: %[[terminationCheck:.*]] = arith.andi %[[YEq0:.*]], %[[XEq0:.*]] : i1
+! CHECK: fir.if %[[terminationCheck]]
+! CHECK-FAST: %[[atan2:.*]] = math.atan2 %{{.*}}, %{{.*}}: f64
+! CHECK: %[[factor:.*]] = arith.constant 57.295779513082323 : f64
+! CHECK: %{{.*}} = arith.mulf %[[atan2]], %[[factor]] fastmath<contract> : f64
diff --git a/flang/test/Lower/Intrinsics/atand-optional.f90 b/flang/test/Lower/Intrinsics/atand-optional.f90
new file mode 100644
index 000000000000000..b3b98144ead42ee
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/atand-optional.f90
@@ -0,0 +1,14 @@
+! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-FAST"
+! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-FAST"
+
+function test_real4_all_args_optional(y,x)
+ real(4), optional :: x, y
+ real(4) :: test_real4
+ test_real4 = atand(y,x)
+end function
+
+! CHECK-LABEL: @_QPtest_real4_all_args_optional
+! CHECK-FAST: %[[atan2:.*]] = math.atan2 %{{.*}}, %{{.*}}: f32
+! CHECK: %[[dfactor:.*]] = arith.constant 57.295779513082323 : f64
+! CHECK: %[[factor:.*]] = fir.convert %[[dfactor]] : (f64) -> f32
+! CHECK: %{{.*}} = arith.mulf %[[atan2]], %[[factor]] fastmath<contract> : f32
diff --git a/flang/test/Lower/Intrinsics/atand.f90 b/flang/test/Lower/Intrinsics/atand.f90
index 2483bef46e60f6f..25d882b693ed81c 100644
--- a/flang/test/Lower/Intrinsics/atand.f90
+++ b/flang/test/Lower/Intrinsics/atand.f90
@@ -1,5 +1,4 @@
! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-FAST"
-! RUN: bbc --math-runtime=precise -emit-fir -hlfir=false %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-PRECISE"
! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-FAST"
function test_real4(x)
@@ -8,7 +7,6 @@ function test_real4(x)
end function
! CHECK-LABEL: @_QPtest_real4
-! CHECK-PRECISE: %[[atan:.*]] = fir.call @atanf({{%[A-Za-z0-9._]+}}) fastmath<contract> : (f32) -> f32
! CHECK-FAST: %[[atan:.*]] = math.atan %{{.*}} : f32
! CHECK: %[[dfactor:.*]] = arith.constant 57.295779513082323 : f64
! CHECK: %[[factor:.*]] = fir.convert %[[dfactor]] : (f64) -> f32
@@ -20,7 +18,27 @@ function test_real8(x)
end function
! CHECK-LABEL: @_QPtest_real8
-! CHECK-PRECISE: %[[atan:.*]] = fir.call @atan({{%[A-Za-z0-9._]+}}) fastmath<contract> : (f64) -> f64
! CHECK-FAST: %[[atan:.*]] = math.atan %{{.*}} : f64
! CHECK: %[[factor:.*]] = arith.constant 57.295779513082323 : f64
! CHECK: %{{.*}} = arith.mulf %[[atan]], %[[factor]] fastmath<contract> : f64
+
+function test_real4_all_args(y,x)
+ real(4) :: x, y, test_real4
+ test_real4 = atand(y,x)
+end function
+
+! CHECK-LABEL: @_QPtest_real4_all_args
+! CHECK-FAST: %[[atan2:.*]] = math.atan2 %{{.*}}, %{{.*}}: f32
+! CHECK: %[[dfactor:.*]] = arith.constant 57.295779513082323 : f64
+! CHECK: %[[factor:.*]] = fir.convert %[[dfactor]] : (f64) -> f32
+! CHECK: %{{.*}} = arith.mulf %[[atan2]], %[[factor]] fastmath<contract> : f32
+
+function test_real8_all_args(y,x)
+ real(8) :: x, y, test_real8
+ test_real8 = atand(y,x)
+end function
+
+! CHECK-LABEL: @_QPtest_real8_all_args
+! CHECK-FAST: %[[atan2:.*]] = math.atan2 %{{.*}}, %{{.*}}: f64
+! CHECK: %[[factor:.*]] = arith.constant 57.295779513082323 : f64
+! CHECK: %{{.*}} = arith.mulf %[[atan2]], %[[factor]] fastmath<contract> : f64
|
Standard for
Standard for
|
I didn't add the result check on both |
I should have pointed it out early. The same issue occurs in |
Both |
9d91cf0
to
3805534
Compare
d201481
to
3a1f93d
Compare
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.
Few new comments, LGTM otherwise.
build and pass all tests on Windows MSVC |
…runtime as before
Co-authored-by: jeanPerier <jean.perier.polytechnique@gmail.com>
Co-authored-by: jeanPerier <jean.perier.polytechnique@gmail.com>
Co-authored-by: jeanPerier <jean.perier.polytechnique@gmail.com>
c37a45d
to
5335907
Compare
|
Hi, @jeanPerier sorry for throwing a ping, do you mind have a quick look at the updated code? I've changed |
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 addressing my comments.
…pi(Y,X), atan2pi(Y,X) (llvm#79002) Fix: llvm#78568 --------- Co-authored-by: jeanPerier <jean.perier.polytechnique@gmail.com>
Both call the
mlir::math::Atan2op
, with the non zero check of: if Y is zeroX must not be 0.Fix: #78568