[flang-commits] [flang] 0b55a8d - [flang] Fix intrinsic interface for DIMAG/DCONJG
via flang-commits
flang-commits at lists.llvm.org
Thu Apr 14 06:35:48 PDT 2022
Author: PeixinQiao
Date: 2022-04-14T21:34:00+08:00
New Revision: 0b55a8dc6fe81a9b3f8c67ec0b5192baa4bc80b8
URL: https://github.com/llvm/llvm-project/commit/0b55a8dc6fe81a9b3f8c67ec0b5192baa4bc80b8
DIFF: https://github.com/llvm/llvm-project/commit/0b55a8dc6fe81a9b3f8c67ec0b5192baa4bc80b8.diff
LOG: [flang] Fix intrinsic interface for DIMAG/DCONJG
The intrinsics DREAL, DIMAG, and DCONJG are from Fortran 77 extensions.
For DREAL, the type of argument is extended to any complex. For DIMAG
and DCONJG, the type of argument for them should be complex(8). For DIMAG,
the result type should be real(8). For DCONJG, the result type should be
complex(8). Fix the intrinsic interface for them and add test cases for
the semantic checks and the lowering.
Reviewed By: Jean Perier
Differential Revision: https://reviews.llvm.org/D123459
Added:
flang/test/Lower/Intrinsics/dconjg.f90
flang/test/Lower/Intrinsics/dimag.f90
flang/test/Lower/Intrinsics/dreal.f90
flang/test/Semantics/intrinsics01.f90
Modified:
flang/lib/Evaluate/intrinsics.cpp
flang/unittests/Evaluate/intrinsics.cpp
Removed:
################################################################################
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index c20ccc69ea32e..41731acf63cda 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -955,7 +955,8 @@ static const SpecificIntrinsicInterface specificIntrinsicFunction[]{
{"y", AnyIntOrReal, Rank::elementalOrBOZ, Optionality::optional}},
DoublePrecisionComplex},
"cmplx", true},
- {{"dconjg", {{"z", AnyComplex}}, DoublePrecisionComplex}, "conjg"},
+ {{"dconjg", {{"z", DoublePrecisionComplex}}, DoublePrecisionComplex},
+ "conjg"},
{{"dcos", {{"x", DoublePrecision}}, DoublePrecision}, "cos"},
{{"dcosh", {{"x", DoublePrecision}}, DoublePrecision}, "cosh"},
{{"ddim", {{"x", DoublePrecision}, {"y", DoublePrecision}},
@@ -964,7 +965,7 @@ static const SpecificIntrinsicInterface specificIntrinsicFunction[]{
{{"dexp", {{"x", DoublePrecision}}, DoublePrecision}, "exp"},
{{"dfloat", {{"a", AnyInt}}, DoublePrecision}, "real", true},
{{"dim", {{"x", DefaultReal}, {"y", DefaultReal}}, DefaultReal}},
- {{"dimag", {{"z", AnyComplex}}, DoublePrecision}, "aimag"},
+ {{"dimag", {{"z", DoublePrecisionComplex}}, DoublePrecision}, "aimag"},
{{"dint", {{"a", DoublePrecision}}, DoublePrecision}, "aint"},
{{"dlog", {{"x", DoublePrecision}}, DoublePrecision}, "log"},
{{"dlog10", {{"x", DoublePrecision}}, DoublePrecision}, "log10"},
diff --git a/flang/test/Lower/Intrinsics/dconjg.f90 b/flang/test/Lower/Intrinsics/dconjg.f90
new file mode 100644
index 0000000000000..b5590e4d6bec0
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/dconjg.f90
@@ -0,0 +1,19 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+subroutine test_dconjg(r, c)
+ complex(8), intent(out) :: r
+ complex(8), intent(in) :: c
+
+! CHECK-LABEL: func @_QPtest_dconjg(
+! CHECK-SAME: %[[ARG_0:.*]]: !fir.ref<!fir.complex<8>> {fir.bindc_name = "r"},
+! CHECK-SAME: %[[ARG_1:.*]]: !fir.ref<!fir.complex<8>> {fir.bindc_name = "c"}) {
+! CHECK: %[[VAL_0:.*]] = fir.load %[[ARG_1]] : !fir.ref<!fir.complex<8>>
+! CHECK: %[[VAL_1:.*]] = fir.extract_value %[[VAL_0]], [1 : index] : (!fir.complex<8>) -> f64
+! CHECK: %[[VAL_2:.*]] = arith.negf %[[VAL_1]] : f64
+! CHECK: %[[VAL_3:.*]] = fir.insert_value %[[VAL_0]], %[[VAL_2]], [1 : index] : (!fir.complex<8>, f64) -> !fir.complex<8>
+! CHECK: fir.store %[[VAL_3]] to %[[ARG_0]] : !fir.ref<!fir.complex<8>>
+! CHECK: return
+! CHECK: }
+
+ r = dconjg(c)
+end
diff --git a/flang/test/Lower/Intrinsics/dimag.f90 b/flang/test/Lower/Intrinsics/dimag.f90
new file mode 100644
index 0000000000000..535ca5f060ca2
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/dimag.f90
@@ -0,0 +1,17 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+subroutine test_dimag(r, c)
+ real(8), intent(out) :: r
+ complex(8), intent(in) :: c
+
+! CHECK-LABEL: func @_QPtest_dimag(
+! CHECK-SAME: %[[ARG_0:.*]]: !fir.ref<f64> {fir.bindc_name = "r"},
+! CHECK-SAME: %[[ARG_1:.*]]: !fir.ref<!fir.complex<8>> {fir.bindc_name = "c"}) {
+! CHECK: %[[VAL_0:.*]] = fir.load %[[ARG_1]] : !fir.ref<!fir.complex<8>>
+! CHECK: %[[VAL_1:.*]] = fir.extract_value %[[VAL_0]], [1 : index] : (!fir.complex<8>) -> f64
+! CHECK: fir.store %[[VAL_1]] to %[[ARG_0]] : !fir.ref<f64>
+! CHECK: return
+! CHECK: }
+
+ r = dimag(c)
+end
diff --git a/flang/test/Lower/Intrinsics/dreal.f90 b/flang/test/Lower/Intrinsics/dreal.f90
new file mode 100644
index 0000000000000..65d05c900e51a
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/dreal.f90
@@ -0,0 +1,17 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+subroutine test_dreal(r, c)
+ real(8), intent(out) :: r
+ complex(8), intent(in) :: c
+
+! CHECK-LABEL: func @_QPtest_dreal(
+! CHECK-SAME: %[[ARG_0:.*]]: !fir.ref<f64> {fir.bindc_name = "r"},
+! CHECK-SAME: %[[ARG_1:.*]]: !fir.ref<!fir.complex<8>> {fir.bindc_name = "c"}) {
+! CHECK: %[[VAL_0:.*]] = fir.load %[[ARG_1]] : !fir.ref<!fir.complex<8>>
+! CHECK: %[[VAL_1:.*]] = fir.extract_value %[[VAL_0]], [0 : index] : (!fir.complex<8>) -> f64
+! CHECK: fir.store %[[VAL_1]] to %[[ARG_0]] : !fir.ref<f64>
+! CHECK: return
+! CHECK: }
+
+ r = dreal(c)
+end
diff --git a/flang/test/Semantics/intrinsics01.f90 b/flang/test/Semantics/intrinsics01.f90
new file mode 100644
index 0000000000000..28808f8e766ba
--- /dev/null
+++ b/flang/test/Semantics/intrinsics01.f90
@@ -0,0 +1,41 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+! Check for semantic errors for DREAL, DIMAG, DCONJG intrinsics
+
+subroutine s()
+ real :: a
+ complex(4) :: c4 ! test scalar
+ complex(8) :: c8
+ complex(16) :: c16(2) ! test array
+
+ !ERROR: Actual argument for 'a=' has bad type 'REAL(4)'
+ print *, dreal(a)
+
+ print *, dreal(c4)
+
+ print *, dreal(c8)
+
+ print *, dreal(c16)
+
+ !ERROR: Actual argument for 'z=' has bad type 'REAL(4)'
+ print *, dimag(a)
+
+ !ERROR: Actual argument for 'z=' has bad type or kind 'COMPLEX(4)'
+ print *, dimag(c4)
+
+ print *, dimag(c8)
+
+ !ERROR: Actual argument for 'z=' has bad type or kind 'COMPLEX(16)'
+ print *, dimag(c16)
+
+ !ERROR: Actual argument for 'z=' has bad type 'REAL(4)'
+ print *, dconjg(a)
+
+ !ERROR: Actual argument for 'z=' has bad type or kind 'COMPLEX(4)'
+ print *, dconjg(c4)
+
+ print *, dconjg(c8)
+
+ !ERROR: Actual argument for 'z=' has bad type or kind 'COMPLEX(16)'
+ print *, dconjg(c16)
+
+end subroutine
diff --git a/flang/unittests/Evaluate/intrinsics.cpp b/flang/unittests/Evaluate/intrinsics.cpp
index 678f0da6894e5..363171636dfc2 100644
--- a/flang/unittests/Evaluate/intrinsics.cpp
+++ b/flang/unittests/Evaluate/intrinsics.cpp
@@ -237,9 +237,6 @@ void TestIntrinsics() {
TestCall{defaults, table, "conjg"}
.Push(Const(Scalar<Complex8>{}))
.DoCall(Complex8::GetType());
- TestCall{defaults, table, "dconjg"}
- .Push(Const(Scalar<Complex4>{}))
- .DoCall(Complex8::GetType());
TestCall{defaults, table, "dconjg"}
.Push(Const(Scalar<Complex8>{}))
.DoCall(Complex8::GetType());
More information about the flang-commits
mailing list