aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2017-11-17 15:46:04 +0100
committerSegher Boessenkool <segher@gcc.gnu.org>2017-11-17 15:46:04 +0100
commit58b46683bd70c20c2543d60ca28af4dec4ec0443 (patch)
tree790f4a75755e3d6b1e7d35f1096306ceaa0a535c /gcc
parent107d4a0f07c87e7351c35dd4ced25adf63e7fa0b (diff)
downloadgcc-58b46683bd70c20c2543d60ca28af4dec4ec0443.zip
gcc-58b46683bd70c20c2543d60ca28af4dec4ec0443.tar.gz
gcc-58b46683bd70c20c2543d60ca28af4dec4ec0443.tar.bz2
combine: Don't split insns if half is unused (PR82621)
If we have a PARALLEL of two SETs, and one half is unused, we currently happily split that into two instructions (although the unused one is useless). Worse, as PR82621 shows, combine will happily merge this insn into I3 even if some intervening insn sets the same register again, which is wrong. This fixes it by not splitting PARALLELs with REG_UNUSED notes. It all is handled fine by combine in that case: just the "single set that is unused" case isn't handled properly. This also results in better code: combine will now actually throw away the unused SET. (It still won't do that in an I3). PR rtl-optimization/82621 * combine.c (try_combine): Do not split PARALLELs of two SETs if the dest of one of those SETs is unused. From-SVN: r254874
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/combine.c3
2 files changed, 8 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 993ac9b..c0249e8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2017-11-17 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR rtl-optimization/82621
+ * combine.c (try_combine): Do not split PARALLELs of two SETs if the
+ dest of one of those SETs is unused.
+
2017-11-17 Richard Biener <rguenther@suse.de>
PR fortran/83017
diff --git a/gcc/combine.c b/gcc/combine.c
index eab10c5..404cf33 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -3010,7 +3010,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
&& is_parallel_of_n_reg_sets (PATTERN (i2), 2)
&& can_split_parallel_of_n_reg_sets (i2, 2)
&& !reg_used_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 0)), i2, i3)
- && !reg_used_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 1)), i2, i3))
+ && !reg_used_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 1)), i2, i3)
+ && !find_reg_note (i2, REG_UNUSED, 0))
{
/* If there is no I1, there is no I0 either. */
i0 = i1;