aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2013-01-18 18:15:07 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2013-01-18 18:15:07 +0100
commit3f0fee7b4d54d49364a47021c7d2dd9bd4c84c73 (patch)
treec961c9a38a96cfcad2a5854770ba3b274de81430 /gcc
parentb69a7864fbaf0a80b6e39b9680b821fba6eb8d0c (diff)
downloadgcc-3f0fee7b4d54d49364a47021c7d2dd9bd4c84c73.zip
gcc-3f0fee7b4d54d49364a47021c7d2dd9bd4c84c73.tar.gz
gcc-3f0fee7b4d54d49364a47021c7d2dd9bd4c84c73.tar.bz2
re PR middle-end/56015 (expand expands p[9] = COMPLEX_EXPR <-IMAGPART_EXPR <p[9]>, REALPART_EXPR <p[9]>>; incorrectly.)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/expr.c48
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/pr56015.f9016
4 files changed, 76 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8174a4b..6ba1e86 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
diff --git a/gcc/expr.c b/gcc/expr.c
index 12029d6..08c5c9d 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 910abf1..13eb611 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..21d9d64
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr56015.f90
@@ -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