]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/gcc-tumbl.git/commitdiff
Backported from mainline
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 1 Feb 2013 14:10:48 +0000 (14:10 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 1 Feb 2013 14:10:48 +0000 (14:10 +0000)
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.

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

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@195657 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 70e229053e556332121e94934acefc3b323e2180..dd6f030315defd7df0690e9d62b39d46c4900b13 100644 (file)
@@ -1,6 +1,13 @@
 2013-02-01  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       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-15  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/55940
index 1dcb9f59c2581f5b78b8144795e42f9eadbd25d9..4c248e061550b83a33983f4bb684568ca7619804 100644 (file)
@@ -8696,6 +8696,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 c97ee105e26dd176053b309f154a2cd01eed18d4..37fbb5346d5283b5295f32f5091cc84a923c46f9 100644 (file)
@@ -1,6 +1,11 @@
 2013-02-01  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2013-01-18  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/56015
+       * gfortran.dg/pr56015.f90: New test.
+
        2013-01-15  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/55940
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