re PR target/80125 (r246297 causes segfault in reg_used_between_p())
authorJakub Jelinek <jakub@redhat.com>
Tue, 21 Mar 2017 14:49:51 +0000 (15:49 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 21 Mar 2017 14:49:51 +0000 (15:49 +0100)
PR target/80125
* combine.c (can_combine_p): Revert the 2017-03-20 change, only
check reg_used_between_p between insn and one of succ or succ2
depending on if succ is artificial insn not inserted into insn
stream.

* gcc.target/powerpc/pr80125.c: New test.

Co-Authored-By: Segher Boessenkool <segher@kernel.crashing.org>
From-SVN: r246323

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/pr80125.c [new file with mode: 0644]

index a7a13f1049a62fc8fcb7ff79fb28b6433ff637b9..03b2a419331e261ffd608ca3b5941d07046b9c3d 100644 (file)
@@ -1,3 +1,12 @@
+2017-03-21  Jakub Jelinek  <jakub@redhat.com>
+           Segher Boessenkool  <segher@kernel.crashing.org>
+
+       PR target/80125
+       * combine.c (can_combine_p): Revert the 2017-03-20 change, only
+       check reg_used_between_p between insn and one of succ or succ2
+       depending on if succ is artificial insn not inserted into insn
+       stream.
+
 2017-03-21  Martin Liska  <mliska@suse.cz>
 
        PR gcov-profile/80081
index 17258f0e0c5ac27916cd59617dffa31df42dd6b7..c118aa25806be21dcdd4144f86115c8de853386d 100644 (file)
@@ -1954,15 +1954,20 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED,
       /* Don't substitute into a non-local goto, this confuses CFG.  */
       || (JUMP_P (i3) && find_reg_note (i3, REG_NON_LOCAL_GOTO, NULL_RTX))
       /* Make sure that DEST is not used after INSN but before SUCC, or
-        between SUCC and SUCC2.  */
-      || (succ && reg_used_between_p (dest, insn, succ))
-      || (succ2 && reg_used_between_p (dest, succ, succ2))
-      /* Make sure that DEST is not used after SUCC but before I3.  */
+        after SUCC and before SUCC2, or after SUCC2 but before I3.  */
       || (!all_adjacent
          && ((succ2
               && (reg_used_between_p (dest, succ2, i3)
                   || reg_used_between_p (dest, succ, succ2)))
-             || (!succ2 && succ && reg_used_between_p (dest, succ, i3))))
+             || (!succ2 && succ && reg_used_between_p (dest, succ, i3))
+             || (succ
+                 /* SUCC and SUCC2 can be split halves from a PARALLEL; in
+                    that case SUCC is not in the insn stream, so use SUCC2
+                    instead for this test.  */
+                 && reg_used_between_p (dest, insn,
+                                        succ2
+                                        && INSN_UID (succ) == INSN_UID (succ2)
+                                        ? succ2 : succ))))
       /* Make sure that the value that is to be substituted for the register
         does not use any registers whose values alter in between.  However,
         If the insns are adjacent, a use can't cross a set even though we
index c2be77a3b21bbd3017403be8fd73ef0f1ed81ee9..6a87efc180d53405184cdff7a45af7c85ba10d42 100644 (file)
@@ -1,3 +1,8 @@
+2017-03-21  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/80125
+       * gcc.target/powerpc/pr80125.c: New test.
+
 2017-03-21  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
             Richard Biener  <rguenther@suse.de>
 
diff --git a/gcc/testsuite/gcc.target/powerpc/pr80125.c b/gcc/testsuite/gcc.target/powerpc/pr80125.c
new file mode 100644 (file)
index 0000000..494a6e6
--- /dev/null
@@ -0,0 +1,23 @@
+/* PR target/80125 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -maltivec" } */
+
+#include <altivec.h>
+
+int a[1];
+
+void
+foo ()
+{
+  vector int b, e, f, g, h, j, n;
+  vector unsigned c, d;
+  f = vec_sums (h, b);
+  vector int i = vec_mergel (f, g);
+  vector int k = vec_mergel (i, j);
+  vector int l = vec_sl (k, c);
+  vector int m = vec_sl (l, d);
+  vector char o;
+  vector int p = vec_perm (m, n, o);
+  e = vec_sra (p, c);
+  vec_st (e, 0, a);
+}