Patchwork [Fortran] PR57785 - Fix folding of dot_product for complex vars

login
register
mail settings
Submitter Tobias Burnus
Date July 3, 2013, 12:05 p.m.
Message ID <51D4137B.4000405@net-b.de>
Download mbox | patch
Permalink /patch/256605/
State New
Headers show

Comments

Tobias Burnus - July 3, 2013, 12:05 p.m.
Pending patches:http://gcc.gnu.org/ml/fortran/2013-07/msg00002.html


Thanks goes to Dominique for debugging the issue!

Build and regtested on x86-64-gnu-linux.
OK for the trunk? I think one should also backport it to 4.7/4.8. 
(Folding - and hence the bug - exist since GCC 4.5.)

Tobias
Tobias Burnus - July 8, 2013, 1:53 p.m.
Am 03.07.2013 14:05, schrieb Tobias Burnus:
> Thanks goes to Dominique for debugging the issue!
>
> Build and regtested on x86-64-gnu-linux.
> OK for the trunk? I think one should also backport it to 4.7/4.8. 
> (Folding - and hence the bug - exist since GCC 4.5.)

For the trunk, committed as Rev. 200786 - using the attached test case 
as replacement for the original one.


Dominique Dhumieres wrote:
> (2) I don't like the scan-tree-dump: they are fragile and have a limited
> coverage. I'ld prefer a test such as the following
> ! { dg-do run }

And I really dislike "dg-do run" tests for compile-time simplifications. 
I think the attached test case should combine the best of the two worlds.

In general, I think one needs both: Many things aren't reliably testable 
with run-time tests. Thus, dumps help a lot: They have a *better* 
coverage of certain things and are usually quite robust. Having 
compile-only tests is also a tad faster. On the other hand, run tests 
are good to ensure that the interplay of different features works well.

Tobias

Patch

2013-07-03  Tobias Burnus  <burnus@net-b.de>

	PR fortran/57785
	* simplify.c (compute_dot_product): Complex conjugate for
	dot_product.
	(gfc_simplify_dot_product, gfc_simplify_matmul): Update call.

2013-07-03  Tobias Burnus  <burnus@net-b.de>

	PR fortran/57785
	* gfortran.dg/dot_product_2.f90: New.

diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index 41e1dfb..32b8332 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -333,13 +333,15 @@  init_result_expr (gfc_expr *e, int init, gfc_expr *array)
 }
 
 
-/* Helper function for gfc_simplify_dot_product() and gfc_simplify_matmul.  */
+/* Helper function for gfc_simplify_dot_product() and gfc_simplify_matmul;
+   if conj_a is true, the matrix_a is complex conjugated.  */
 
 static gfc_expr *
 compute_dot_product (gfc_expr *matrix_a, int stride_a, int offset_a,
-		     gfc_expr *matrix_b, int stride_b, int offset_b)
+		     gfc_expr *matrix_b, int stride_b, int offset_b,
+		     bool conj_a)
 {
-  gfc_expr *result, *a, *b;
+  gfc_expr *result, *a, *b, *c;
 
   result = gfc_get_constant_expr (matrix_a->ts.type, matrix_a->ts.kind,
 				  &matrix_a->where);
@@ -362,9 +364,11 @@  compute_dot_product (gfc_expr *matrix_a, int stride_a, int offset_a,
 	  case BT_INTEGER:
 	  case BT_REAL:
 	  case BT_COMPLEX:
-	    result = gfc_add (result,
-			      gfc_multiply (gfc_copy_expr (a),
-					    gfc_copy_expr (b)));
+	    if (conj_a && a->ts.type == BT_COMPLEX)
+	      c = gfc_simplify_conjg (a);
+	    else
+	      c = gfc_copy_expr (a);
+	    result = gfc_add (result, gfc_multiply (c, gfc_copy_expr (b)));
 	    break;
 
 	  default:
@@ -1882,7 +1886,7 @@  gfc_simplify_dot_product (gfc_expr *vector_a, gfc_expr *vector_b)
   gcc_assert (vector_b->rank == 1);
   gcc_assert (gfc_compare_types (&vector_a->ts, &vector_b->ts));
 
-  return compute_dot_product (vector_a, 1, 0, vector_b, 1, 0);
+  return compute_dot_product (vector_a, 1, 0, vector_b, 1, 0, true);
 }
 
 
@@ -3910,7 +3914,7 @@  gfc_simplify_matmul (gfc_expr *matrix_a, gfc_expr *matrix_b)
       for (row = 0; row < result_rows; ++row)
 	{
 	  gfc_expr *e = compute_dot_product (matrix_a, stride_a, offset_a,
-					     matrix_b, 1, offset_b);
+					     matrix_b, 1, offset_b, false);
 	  gfc_constructor_append_expr (&result->value.constructor,
 				       e, NULL);
 
--- /dev/null	2013-07-03 08:52:40.042058079 +0200
+++ gcc/gcc/testsuite/gfortran.dg/dot_product_2.f90	2013-07-03 12:36:37.466598257 +0200
@@ -0,0 +1,15 @@ 
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+!
+! PR fortran/57785
+!
+! Contributed by Kontantinos Anagnostopoulos
+!
+! The implicit complex conjugate was missing
+
+complex :: z
+z = DOT_PRODUCT ((/ (1.0, 2.0), (2.0, 3.0) /), (/ (1.0, 1.0), (1.0, 4.0) /))
+end
+
+! { dg-final { scan-tree-dump "z = __complex__ \\(1.7e\\\+1, 4.0e\\\+0\\);" "original" } }
+! { dg-final { cleanup-tree-dump "original" } }