re PR middle-end/56015 (expand expands p[9] = COMPLEX_EXPR <-IMAGPART_EXPR <p[9]...
authorJakub Jelinek <jakub@redhat.com>
Fri, 18 Jan 2013 17:15:07 +0000 (18:15 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 18 Jan 2013 17:15:07 +0000 (18:15 +0100)
PR middle-end/56015
* expr.c (expand_expr_real_2) <case COMPLEX_EXPR>: Handle
the case where writing real complex part of target modifies
op1.

* gfortran.dg/pr56015.f90: New test.

From-SVN: r195301

gcc/ChangeLog
gcc/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/pr56015.f90 [new file with mode: 0644]

index 8174a4b346b2acfebb19544ef185bd74b4e68a4a..6ba1e8643e8c213a584204ce691cc688934aea9a 100644 (file)
@@ -1,3 +1,10 @@
+2013-01-18  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/56015
+       * expr.c (expand_expr_real_2) <case COMPLEX_EXPR>: Handle
+       the case where writing real complex part of target modifies
+       op1.
+
 2013-01-18  James Greenhalgh  <james.greenhalgh@arm.com>
 
        * config/aarch64/aarch64-simd.md
@@ -69,7 +76,6 @@
        * regrename.c (build_def_use): Ignore REG_DEAD notes if there is a
        REG_UNUSED for the same register.
 
-
 2013-01-17  Richard Biener  <rguenther@suse.de>
            Marek Polacek  <polacek@redhat.com>
 
index 12029d6915a6df837f0ed10554df8ae30b27c760..08c5c9d0c589c61c9d4d11126c438da62e165c8a 100644 (file)
@@ -8860,6 +8860,54 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
 
       if (!target)
        target = gen_reg_rtx (TYPE_MODE (type));
+      else
+       /* If target overlaps with op1, then either we need to force
+          op1 into a pseudo (if target also overlaps with op0),
+          or write the complex parts in reverse order.  */
+       switch (GET_CODE (target))
+         {
+         case CONCAT:
+           if (reg_overlap_mentioned_p (XEXP (target, 0), op1))
+             {
+               if (reg_overlap_mentioned_p (XEXP (target, 1), op0))
+                 {
+                 complex_expr_force_op1:
+                   temp = gen_reg_rtx (GET_MODE_INNER (GET_MODE (target)));
+                   emit_move_insn (temp, op1);
+                   op1 = temp;
+                   break;
+                 }
+             complex_expr_swap_order:
+               /* Move the imaginary (op1) and real (op0) parts to their
+                  location.  */
+               write_complex_part (target, op1, true);
+               write_complex_part (target, op0, false);
+
+               return target;
+             }
+           break;
+         case MEM:
+           temp = adjust_address_nv (target,
+                                     GET_MODE_INNER (GET_MODE (target)), 0);
+           if (reg_overlap_mentioned_p (temp, op1))
+             {
+               enum machine_mode imode = GET_MODE_INNER (GET_MODE (target));
+               temp = adjust_address_nv (target, imode,
+                                         GET_MODE_SIZE (imode));
+               if (reg_overlap_mentioned_p (temp, op0))
+                 goto complex_expr_force_op1;
+               goto complex_expr_swap_order;
+             }
+           break;
+         default:
+           if (reg_overlap_mentioned_p (target, op1))
+             {
+               if (reg_overlap_mentioned_p (target, op0))
+                 goto complex_expr_force_op1;
+               goto complex_expr_swap_order;
+             }
+           break;
+         }
 
       /* Move the real (op0) and imaginary (op1) parts to their location.  */
       write_complex_part (target, op0, false);
index 910abf1eb35eeac291da07522afc7ab70bffc11f..13eb611e3b576d3b30387933adfac963bffd9a9e 100644 (file)
@@ -1,3 +1,8 @@
+2013-01-18  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/56015
+       * gfortran.dg/pr56015.f90: New test.
+
 2013-01-18  Janis Johnson  <janisjo@codesourcery.com>
 
        * gcc.dg/vect/vect-multitypes-12.c: Refactor dg-final directive.
diff --git a/gcc/testsuite/gfortran.dg/pr56015.f90 b/gcc/testsuite/gfortran.dg/pr56015.f90
new file mode 100644 (file)
index 0000000..21d9d64
--- /dev/null
@@ -0,0 +1,16 @@
+! PR middle-end/56015
+! { dg-do run }
+! { dg-options "-Ofast -fno-inline" }
+
+program pr56015
+  implicit none
+  complex*16 p(10)
+  p(:) = (0.1d0, 0.2d0)
+  p(:) = (0.0d0, 1.0d0) * p(:)
+  call foo (p)
+contains
+  subroutine foo (p)
+    complex*16 p(10)
+    if (any (p .ne. (-0.2d0, 0.1d0))) call abort
+  end subroutine
+end program pr56015