diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/lra-constraints.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr70689.c | 27 |
4 files changed, 51 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 60b327b..458f2cd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-04-18 Vladimir Makarov <vmakarov@redhat.com> + + PR middle-end/70689 + * lra-constraints.c (equiv_substition_p): New. + (process_alt_operands): Use it. + (swap_operands): Swap it. + (curr_insn_transform): Update it. + 2016-04-18 Michael Matz <matz@suse.de> * tree.h (TYPE_ALIGN, DECL_ALIGN): Return shifted amount. diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index c00afe7..14d5f1d 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -1258,6 +1258,10 @@ static bool goal_alt_swapped; /* The chosen insn alternative. */ static int goal_alt_number; +/* True if the corresponding operand is the result of an equivalence + substitution. */ +static bool equiv_substition_p[MAX_RECOG_OPERANDS]; + /* The following five variables are used to choose the best insn alternative. They reflect final characteristics of the best alternative. */ @@ -2064,7 +2068,10 @@ process_alt_operands (int only_alternative) memory, or make other memory by reloading the address like for 'o'. */ if (CONST_POOL_OK_P (mode, op) - || MEM_P (op) || REG_P (op)) + || MEM_P (op) || REG_P (op) + /* We can restore the equiv insn by a + reload. */ + || equiv_substition_p[nop]) badop = false; constmemok = true; offmemok = true; @@ -3371,6 +3378,7 @@ swap_operands (int nop) std::swap (curr_operand_mode[nop], curr_operand_mode[nop + 1]); std::swap (original_subreg_reg_mode[nop], original_subreg_reg_mode[nop + 1]); std::swap (*curr_id->operand_loc[nop], *curr_id->operand_loc[nop + 1]); + std::swap (equiv_substition_p[nop], equiv_substition_p[nop + 1]); /* Swap the duplicates too. */ lra_update_dup (curr_id, nop); lra_update_dup (curr_id, nop + 1); @@ -3473,8 +3481,10 @@ curr_insn_transform (bool check_only_p) old = SUBREG_REG (old); subst = get_equiv_with_elimination (old, curr_insn); original_subreg_reg_mode[i] = VOIDmode; + equiv_substition_p[i] = false; if (subst != old) { + equiv_substition_p[i] = true; subst = copy_rtx (subst); lra_assert (REG_P (old)); if (GET_CODE (op) != SUBREG) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6d9912a..e6bd406 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-04-18 Vladimir Makarov <vmakarov@redhat.com> + + PR middle-end/70689 + * testsuite/gcc.target/i386/pr70689.c: New. + 2016-04-18 H.J. Lu <hongjiu.lu@intel.com> PR target/70708 diff --git a/gcc/testsuite/gcc.target/i386/pr70689.c b/gcc/testsuite/gcc.target/i386/pr70689.c new file mode 100644 index 0000000..0529a00 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr70689.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target ia32 } */ +/* { dg-options "-O1" } */ + +struct S +{ + int f; +}; + +double a; +int c; + +static +void fn1 (struct S *p1) +{ + for (; c; ) + if (p1->f++) + a = (int) p1; +} + +int +main () +{ + struct S b = { 0 }; + fn1 (&b); + return 0; +} |