aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/rs6000/rs6000.c2
-rw-r--r--gcc/lra.c67
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr88845.c24
5 files changed, 78 insertions, 29 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3408e67..8a10820 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2019-03-06 Peter Bergner <bergner@linux.ibm.com>
+
+ PR rtl-optimization/88845
+ * config/rs6000/rs6000.c (rs6000_emit_move_si_sf_subreg): Enable during
+ LRA.
+ * lra.c (remove_scratches_1): New function.
+ (remove_scratches): Use it.
+ (lra_emit_move): Likewise.
+
2019-03-06 Claudiu Zissulescu <claziss@synopsys.com>
* config/arc/arc-c.def (__ARC_UNALIGNED__): Set it on
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index b489bef..d72a51a 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -9890,7 +9890,7 @@ valid_sf_si_move (rtx dest, rtx src, machine_mode mode)
static bool
rs6000_emit_move_si_sf_subreg (rtx dest, rtx source, machine_mode mode)
{
- if (TARGET_DIRECT_MOVE_64BIT && !lra_in_progress && !reload_completed
+ if (TARGET_DIRECT_MOVE_64BIT && !reload_completed
&& (!SUBREG_P (dest) || !sf_subreg_operand (dest, mode))
&& SUBREG_P (source) && sf_subreg_operand (source, mode))
{
diff --git a/gcc/lra.c b/gcc/lra.c
index f130065..bef2f67 100644
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -159,6 +159,7 @@ static void invalidate_insn_recog_data (int);
static int get_insn_freq (rtx_insn *);
static void invalidate_insn_data_regno_info (lra_insn_recog_data_t,
rtx_insn *, int);
+static void remove_scratches_1 (rtx_insn *);
/* Expand all regno related info needed for LRA. */
static void
@@ -494,7 +495,11 @@ lra_emit_move (rtx x, rtx y)
if (rtx_equal_p (x, y))
return;
old = max_reg_num ();
- emit_move_insn (x, y);
+ rtx_insn *insn = emit_move_insn (x, y);
+ /* The move pattern may require scratch registers, so convert them
+ into real registers now. */
+ if (insn != NULL_RTX)
+ remove_scratches_1 (insn);
if (REG_P (x))
lra_reg_info[ORIGINAL_REGNO (x)].last_reload = ++lra_curr_reload_num;
/* Function emit_move can create pseudos -- so expand the pseudo
@@ -2077,47 +2082,53 @@ lra_register_new_scratch_op (rtx_insn *insn, int nop, int icode)
add_reg_note (insn, REG_UNUSED, op);
}
-/* Change scratches onto pseudos and save their location. */
+/* Change INSN's scratches into pseudos and save their location. */
static void
-remove_scratches (void)
+remove_scratches_1 (rtx_insn *insn)
{
int i;
bool insn_changed_p;
- basic_block bb;
- rtx_insn *insn;
rtx reg;
lra_insn_recog_data_t id;
struct lra_static_insn_data *static_id;
+ id = lra_get_insn_recog_data (insn);
+ static_id = id->insn_static_data;
+ insn_changed_p = false;
+ for (i = 0; i < static_id->n_operands; i++)
+ if (GET_CODE (*id->operand_loc[i]) == SCRATCH
+ && GET_MODE (*id->operand_loc[i]) != VOIDmode)
+ {
+ insn_changed_p = true;
+ *id->operand_loc[i] = reg
+ = lra_create_new_reg (static_id->operand[i].mode,
+ *id->operand_loc[i], ALL_REGS, NULL);
+ lra_register_new_scratch_op (insn, i, id->icode);
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file,
+ "Removing SCRATCH in insn #%u (nop %d)\n",
+ INSN_UID (insn), i);
+ }
+ if (insn_changed_p)
+ /* Because we might use DF right after caller-saves sub-pass
+ we need to keep DF info up to date. */
+ df_insn_rescan (insn);
+}
+
+/* Change scratches into pseudos and save their location. */
+static void
+remove_scratches (void)
+{
+ basic_block bb;
+ rtx_insn *insn;
+
scratches.create (get_max_uid ());
bitmap_initialize (&scratch_bitmap, &reg_obstack);
bitmap_initialize (&scratch_operand_bitmap, &reg_obstack);
FOR_EACH_BB_FN (bb, cfun)
FOR_BB_INSNS (bb, insn)
if (INSN_P (insn))
- {
- id = lra_get_insn_recog_data (insn);
- static_id = id->insn_static_data;
- insn_changed_p = false;
- for (i = 0; i < static_id->n_operands; i++)
- if (GET_CODE (*id->operand_loc[i]) == SCRATCH
- && GET_MODE (*id->operand_loc[i]) != VOIDmode)
- {
- insn_changed_p = true;
- *id->operand_loc[i] = reg
- = lra_create_new_reg (static_id->operand[i].mode,
- *id->operand_loc[i], ALL_REGS, NULL);
- lra_register_new_scratch_op (insn, i, id->icode);
- if (lra_dump_file != NULL)
- fprintf (lra_dump_file,
- "Removing SCRATCH in insn #%u (nop %d)\n",
- INSN_UID (insn), i);
- }
- if (insn_changed_p)
- /* Because we might use DF right after caller-saves sub-pass
- we need to keep DF info up to date. */
- df_insn_rescan (insn);
- }
+ remove_scratches_1 (insn);
}
/* Changes pseudos created by function remove_scratches onto scratches. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9b2951f..9a65e3a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-03-06 Peter Bergner <bergner@linux.ibm.com>
+
+ PR rtl-optimization/88845
+ * gcc.target/powerpc/pr88845.c: New test.
+
2019-03-06 Marek Polacek <polacek@redhat.com>
PR c++/87378 - bogus -Wredundant-move warning.
diff --git a/gcc/testsuite/gcc.target/powerpc/pr88845.c b/gcc/testsuite/gcc.target/powerpc/pr88845.c
new file mode 100644
index 0000000..a939fa9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr88845.c
@@ -0,0 +1,24 @@
+/* { dg-do compile { target powerpc*-*-linux* } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power8 -O2" } */
+/* { dg-final { scan-assembler {\mmtvsrd\M} { target { lp64 } } } } */
+/* { dg-final { scan-assembler {\mxscvspdpn\M} { target { lp64 } } } } */
+
+/* Verify that we do not ICE and that we generate a direct move
+ for float types when compiling for 64-bit. */
+
+struct a {
+ unsigned ui;
+ float f;
+};
+
+void
+foo (void)
+{
+ float e;
+ struct a s;
+ e = s.f;
+ __asm__("" : : "d" (e));
+}