aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPeter Bergner <bergner@linux.ibm.com>2018-11-14 02:17:35 +0000
committerPeter Bergner <bergner@gcc.gnu.org>2018-11-13 20:17:35 -0600
commit38e601118ca88adf0a472750b0da83f0ef1798a7 (patch)
tree0fae6ff41c29662d2e5d7dc1d94845b3bc9a4456 /gcc
parent72931dea2b1c27ef70f8b5dce3b12a0db7f44fa4 (diff)
downloadgcc-38e601118ca88adf0a472750b0da83f0ef1798a7.zip
gcc-38e601118ca88adf0a472750b0da83f0ef1798a7.tar.gz
gcc-38e601118ca88adf0a472750b0da83f0ef1798a7.tar.bz2
re PR rtl-optimization/87507 (IRA unnecessarily uses non-volatile registers during register assignment)
gcc/ PR rtl-optimization/87507 * lower-subreg.c (operand_for_swap_move_operator): New function. (simple_move): Strip simple operators. (find_pseudo_copy): Likewise. (resolve_operand_for_swap_move_operator): New function. (resolve_simple_move): Strip simple operators and swap operands. gcc/testsuite/ PR rtl-optimization/87507 * gcc.target/powerpc/pr87507.c: New test. * gcc.target/powerpc/pr68805.c: Update expected results. From-SVN: r266097
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/lower-subreg.c61
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr68805.c4
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr87507.c22
5 files changed, 98 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fa13fdd..62f6383 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2018-11-13 Peter Bergner <bergner@linux.ibm.com>
+
+ PR rtl-optimization/87507
+ * lower-subreg.c (operand_for_swap_move_operator): New function.
+ (simple_move): Strip simple operators.
+ (find_pseudo_copy): Likewise.
+ (resolve_operand_for_swap_move_operator): New function.
+ (resolve_simple_move): Strip simple operators and swap operands.
+
2018-11-13 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/87898
diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
index 72818b8..25cb155 100644
--- a/gcc/lower-subreg.c
+++ b/gcc/lower-subreg.c
@@ -320,6 +320,24 @@ simple_move_operand (rtx x)
return true;
}
+/* If X is an operator that can be treated as a simple move that we
+ can split, then return the operand that is operated on. */
+
+static rtx
+operand_for_swap_move_operator (rtx x)
+{
+ /* A word sized rotate of a register pair is equivalent to swapping
+ the registers in the register pair. */
+ if (GET_CODE (x) == ROTATE
+ && GET_MODE (x) == twice_word_mode
+ && simple_move_operand (XEXP (x, 0))
+ && CONST_INT_P (XEXP (x, 1))
+ && INTVAL (XEXP (x, 1)) == BITS_PER_WORD)
+ return XEXP (x, 0);
+
+ return NULL_RTX;
+}
+
/* If INSN is a single set between two objects that we want to split,
return the single set. SPEED_P says whether we are optimizing
INSN for speed or size.
@@ -330,7 +348,7 @@ simple_move_operand (rtx x)
static rtx
simple_move (rtx_insn *insn, bool speed_p)
{
- rtx x;
+ rtx x, op;
rtx set;
machine_mode mode;
@@ -348,6 +366,9 @@ simple_move (rtx_insn *insn, bool speed_p)
return NULL_RTX;
x = SET_SRC (set);
+ if ((op = operand_for_swap_move_operator (x)) != NULL_RTX)
+ x = op;
+
if (x != recog_data.operand[0] && x != recog_data.operand[1])
return NULL_RTX;
/* For the src we can handle ASM_OPERANDS, and it is beneficial for
@@ -386,9 +407,13 @@ find_pseudo_copy (rtx set)
{
rtx dest = SET_DEST (set);
rtx src = SET_SRC (set);
+ rtx op;
unsigned int rd, rs;
bitmap b;
+ if ((op = operand_for_swap_move_operator (src)) != NULL_RTX)
+ src = op;
+
if (!REG_P (dest) || !REG_P (src))
return false;
@@ -846,6 +871,21 @@ can_decompose_p (rtx x)
return true;
}
+/* OPND is a concatn operand this is used with a simple move operator.
+ Return a new rtx with the concatn's operands swapped. */
+
+static rtx
+resolve_operand_for_swap_move_operator (rtx opnd)
+{
+ gcc_assert (GET_CODE (opnd) == CONCATN);
+ rtx concatn = copy_rtx (opnd);
+ rtx op0 = XVECEXP (concatn, 0, 0);
+ rtx op1 = XVECEXP (concatn, 0, 1);
+ XVECEXP (concatn, 0, 0) = op1;
+ XVECEXP (concatn, 0, 1) = op0;
+ return concatn;
+}
+
/* Decompose the registers used in a simple move SET within INSN. If
we don't change anything, return INSN, otherwise return the start
of the sequence of moves. */
@@ -853,7 +893,7 @@ can_decompose_p (rtx x)
static rtx_insn *
resolve_simple_move (rtx set, rtx_insn *insn)
{
- rtx src, dest, real_dest;
+ rtx src, dest, real_dest, src_op;
rtx_insn *insns;
machine_mode orig_mode, dest_mode;
unsigned int orig_size, words;
@@ -876,6 +916,23 @@ resolve_simple_move (rtx set, rtx_insn *insn)
real_dest = NULL_RTX;
+ if ((src_op = operand_for_swap_move_operator (src)) != NULL_RTX)
+ {
+ if (resolve_reg_p (dest))
+ {
+ /* DEST is a CONCATN, so swap its operands and strip
+ SRC's operator. */
+ dest = resolve_operand_for_swap_move_operator (dest);
+ src = src_op;
+ }
+ else if (resolve_reg_p (src_op))
+ {
+ /* SRC is an operation on a CONCATN, so strip the operator and
+ swap the CONCATN's operands. */
+ src = resolve_operand_for_swap_move_operator (src_op);
+ }
+ }
+
if (GET_CODE (src) == SUBREG
&& resolve_reg_p (SUBREG_REG (src))
&& (maybe_ne (SUBREG_BYTE (src), 0)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index be7cf28..c1c92b1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2018-11-13 Peter Bergner <bergner@linux.ibm.com>
+
+ PR rtl-optimization/87507
+ * gcc.target/powerpc/pr87507.c: New test.
+ * gcc.target/powerpc/pr68805.c: Update expected results.
+
2018-11-13 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/87898
diff --git a/gcc/testsuite/gcc.target/powerpc/pr68805.c b/gcc/testsuite/gcc.target/powerpc/pr68805.c
index 626e227..9f76e2b 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr68805.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr68805.c
@@ -9,7 +9,7 @@ typedef struct bar {
void foo (TYPE *p, TYPE *q) { *p = *q; }
-/* { dg-final { scan-assembler "lxvd2x" } } */
-/* { dg-final { scan-assembler "stxvd2x" } } */
+/* { dg-final { scan-assembler-times {\mld\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mstd\M} 2 } } */
/* { dg-final { scan-assembler-not "xxpermdi" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr87507.c b/gcc/testsuite/gcc.target/powerpc/pr87507.c
new file mode 100644
index 0000000..d30a744
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr87507.c
@@ -0,0 +1,22 @@
+/* { dg-do compile { target powerpc64le-*-* } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-options "-O2 -mcpu=power8" } */
+
+typedef struct
+{
+ __int128_t x;
+ __int128_t y;
+} foo_t;
+
+void
+foo (long cond, foo_t *dst, __int128_t src)
+{
+ if (cond)
+ {
+ dst->x = src;
+ dst->y = src;
+ }
+}
+
+/* { dg-final { scan-assembler-times {\mstd\M} 4 } } */
+/* { dg-final { scan-assembler-not {\mld\M} } } */