Blame SOURCES/gcc9-fixes.patch

02b0fd
2019-11-22  Jonathan Wakely  <jwakely@redhat.com>
02b0fd
02b0fd
	Backport from mainline
02b0fd
	2019-10-29  Jonathan Wakely  <jwakely@redhat.com>
02b0fd
02b0fd
	PR libstdc++/92267
02b0fd
	* include/bits/stl_deque.h (_Deque_iterator(const _Deque_iterator&)):
02b0fd
	Do not define as defaulted.
02b0fd
	* testsuite/23_containers/deque/types/92267.cc: New test.
02b0fd
02b0fd
2019-11-21  Jakub Jelinek  <jakub@redhat.com>
02b0fd
02b0fd
	PR tree-optimization/91355
02b0fd
	* tree-ssa-sink.c (select_best_block): Use >= rather than >
02b0fd
	for early_bb scaled count with best_bb count comparison.
02b0fd
02b0fd
2019-11-21  Richard Biener  <rguenther@suse.de>
02b0fd
02b0fd
	Revert
02b0fd
	2019-09-17  Richard Biener  <rguenther@suse.de>
02b0fd
02b0fd
	PR tree-optimization/91790
02b0fd
	* tree-vect-stmts.c (vectorizable_load): For BB vectorization
02b0fd
	use the correct DR for setting up realignment.
02b0fd
02b0fd
2019-11-20  Peter Bergner <bergner@linux.ibm.com>
02b0fd
02b0fd
	Backport from mainline
02b0fd
	2019-11-07  Peter Bergner <bergner@linux.ibm.com>
02b0fd
02b0fd
	PR other/92090
02b0fd
	* config/rs6000/predicates.md (input_operand): Allow MODE_PARTIAL_INT
02b0fd
	modes for integer constants.
02b0fd
02b0fd
2019-11-20  Michael Matz  <matz@suse.de>
02b0fd
02b0fd
	Backport from mainline
02b0fd
	PR middle-end/90796
02b0fd
	* gimple-loop-jam.c (any_access_function_variant_p): New function.
02b0fd
	(adjust_unroll_factor): Use it to constrain safety, new parameter.
02b0fd
	(tree_loop_unroll_and_jam): Adjust call and profitable unroll factor.
02b0fd
02b0fd
2019-11-20  Joseph Myers  <joseph@codesourcery.com>
02b0fd
02b0fd
	* doc/invoke.texi (-Wc11-c2x-compat): Document.
02b0fd
02b0fd
--- libstdc++-v3/include/bits/stl_deque.h	(revision 278492)
02b0fd
+++ libstdc++-v3/include/bits/stl_deque.h	(revision 278614)
02b0fd
@@ -158,13 +158,16 @@
02b0fd
 #else
02b0fd
       // Conversion from iterator to const_iterator.
02b0fd
       template
02b0fd
-              typename = _Require<is_same<_Self, const_iterator>,
02b0fd
-                                  is_same<_Iter, iterator>>>
02b0fd
+	       typename = _Require<is_same<_Self, const_iterator>,
02b0fd
+				   is_same<_Iter, iterator>>>
02b0fd
        _Deque_iterator(const _Iter& __x) noexcept
02b0fd
        : _M_cur(__x._M_cur), _M_first(__x._M_first),
02b0fd
-         _M_last(__x._M_last), _M_node(__x._M_node) { }
02b0fd
+	 _M_last(__x._M_last), _M_node(__x._M_node) { }
02b0fd
 
02b0fd
-      _Deque_iterator(const _Deque_iterator&) = default;
02b0fd
+      _Deque_iterator(const _Deque_iterator& __x) noexcept
02b0fd
+       : _M_cur(__x._M_cur), _M_first(__x._M_first),
02b0fd
+	 _M_last(__x._M_last), _M_node(__x._M_node) { }
02b0fd
+
02b0fd
       _Deque_iterator& operator=(const _Deque_iterator&) = default;
02b0fd
 #endif
02b0fd
 
02b0fd
--- libstdc++-v3/testsuite/23_containers/deque/types/92267.cc	(nonexistent)
02b0fd
+++ libstdc++-v3/testsuite/23_containers/deque/types/92267.cc	(revision 278614)
02b0fd
@@ -0,0 +1,27 @@
02b0fd
+// Copyright (C) 2019 Free Software Foundation, Inc.
02b0fd
+//
02b0fd
+// This file is part of the GNU ISO C++ Library.  This library is free
02b0fd
+// software; you can redistribute it and/or modify it under the
02b0fd
+// terms of the GNU General Public License as published by the
02b0fd
+// Free Software Foundation; either version 3, or (at your option)
02b0fd
+// any later version.
02b0fd
+
02b0fd
+// This library is distributed in the hope that it will be useful,
02b0fd
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
02b0fd
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
02b0fd
+// GNU General Public License for more details.
02b0fd
+
02b0fd
+// You should have received a copy of the GNU General Public License along
02b0fd
+// with this library; see the file COPYING3.  If not see
02b0fd
+// <http://www.gnu.org/licenses/>.
02b0fd
+
02b0fd
+// { dg-do compile { target c++11 } }
02b0fd
+
02b0fd
+#include <deque>
02b0fd
+
02b0fd
+using std::deque;
02b0fd
+using std::is_trivially_copy_constructible;
02b0fd
+
02b0fd
+// PR libstdc++/92267
02b0fd
+static_assert(!is_trivially_copy_constructible<deque<int>::iterator>::value);
02b0fd
+static_assert(!is_trivially_copy_constructible<deque<int>::const_iterator>::value);
02b0fd
--- gcc/doc/invoke.texi	(revision 278492)
02b0fd
+++ gcc/doc/invoke.texi	(revision 278614)
02b0fd
@@ -292,6 +292,7 @@
02b0fd
 -Wbool-compare  -Wbool-operation @gol
02b0fd
 -Wno-builtin-declaration-mismatch @gol
02b0fd
 -Wno-builtin-macro-redefined  -Wc90-c99-compat  -Wc99-c11-compat @gol
02b0fd
+-Wc11-c2x-compat @gol
02b0fd
 -Wc++-compat  -Wc++11-compat  -Wc++14-compat  -Wc++17-compat  @gol
02b0fd
 -Wcast-align  -Wcast-align=strict  -Wcast-function-type  -Wcast-qual  @gol
02b0fd
 -Wchar-subscripts  -Wcatch-value  -Wcatch-value=@var{n} @gol
02b0fd
@@ -6698,6 +6699,14 @@
02b0fd
 and so on.  This option is independent of the standards mode.  Warnings are
02b0fd
 disabled in the expression that follows @code{__extension__}.
02b0fd
 
02b0fd
+@item -Wc11-c2x-compat @r{(C and Objective-C only)}
02b0fd
+@opindex Wc11-c2x-compat
02b0fd
+@opindex Wno-c11-c2x-compat
02b0fd
+Warn about features not present in ISO C11, but present in ISO C2X.
02b0fd
+For instance, warn about omitting the string in @code{_Static_assert}.
02b0fd
+This option is independent of the standards mode.  Warnings are
02b0fd
+disabled in the expression that follows @code{__extension__}.
02b0fd
+
02b0fd
 @item -Wc++-compat @r{(C and Objective-C only)}
02b0fd
 @opindex Wc++-compat
02b0fd
 @opindex Wno-c++-compat
02b0fd
--- gcc/testsuite/gcc.target/powerpc/pr92090-2.c	(nonexistent)
02b0fd
+++ gcc/testsuite/gcc.target/powerpc/pr92090-2.c	(revision 278614)
02b0fd
@@ -0,0 +1,45 @@
02b0fd
+/* { dg-do compile } */
02b0fd
+/* { dg-options "-mdejagnu-cpu=power8 -Os -w" } */
02b0fd
+/* { dg-additional-options "-mbig" { target powerpc64le-*-* } } */
02b0fd
+
02b0fd
+/* Verify that we don't ICE.  */
02b0fd
+
02b0fd
+int a;
02b0fd
+static _Atomic long double b, c, d, m;
02b0fd
+double n;
02b0fd
+extern int foo (void);
02b0fd
+extern void bar (int, int, int, int);
02b0fd
+
02b0fd
+void
02b0fd
+bug (void)
02b0fd
+{
02b0fd
+  b = 1.79769313486231580793728971405301199e308L;
02b0fd
+  for (int i = 0; i < 10000; i++)
02b0fd
+    if (__builtin_isinf (n))
02b0fd
+      b;
02b0fd
+  c = 1;
02b0fd
+  int e, f, g, h;
02b0fd
+  while (a)
02b0fd
+    ;
02b0fd
+  for (int i; i; i++)
02b0fd
+    {
02b0fd
+      double j = c /= foo ();
02b0fd
+      if (__builtin_isinf (j))
02b0fd
+	{
02b0fd
+	  if (foo == 1 << 31)
02b0fd
+	    e++;
02b0fd
+	  f++;
02b0fd
+	  c = 0;
02b0fd
+	}
02b0fd
+      else
02b0fd
+	{
02b0fd
+	  if (foo == 1 << 30)
02b0fd
+	    g++;
02b0fd
+	  h++;
02b0fd
+	  c = 1;
02b0fd
+	}
02b0fd
+    }
02b0fd
+  bar (e, f, g, h);
02b0fd
+  d = 1.79769313486231580793728971405301199e308L;
02b0fd
+  m = 1;
02b0fd
+}
02b0fd
--- gcc/testsuite/gcc.target/powerpc/pr92090.c	(nonexistent)
02b0fd
+++ gcc/testsuite/gcc.target/powerpc/pr92090.c	(revision 278614)
02b0fd
@@ -0,0 +1,43 @@
02b0fd
+/* { dg-do compile } */
02b0fd
+/* { dg-options "-mdejagnu-cpu=power8 -Os" } */
02b0fd
+/* { dg-additional-options "-mbig" { target powerpc64le-*-* } } */
02b0fd
+
02b0fd
+/* Verify that we don't ICE.  */
02b0fd
+
02b0fd
+_Atomic int a;
02b0fd
+_Atomic long double b, c;
02b0fd
+int j;
02b0fd
+void foo (void);
02b0fd
+void bar (int, int, int, int);
02b0fd
+
02b0fd
+void
02b0fd
+bug (void)
02b0fd
+{
02b0fd
+  b = 1;
02b0fd
+  int d, e, f, g;
02b0fd
+  while (a)
02b0fd
+    ;
02b0fd
+  for (int h = 0; h < 10000; h++)
02b0fd
+    {
02b0fd
+      double i = b /= 3;
02b0fd
+      foo ();
02b0fd
+      if (i)
02b0fd
+	{
02b0fd
+	  if (i == 1)
02b0fd
+	    d++;
02b0fd
+	  e++;
02b0fd
+	  b = 0;
02b0fd
+	}
02b0fd
+      else
02b0fd
+	{
02b0fd
+	  if (i == 2)
02b0fd
+	    f++;
02b0fd
+	  g++;
02b0fd
+	  b = 1;
02b0fd
+	}
02b0fd
+    }
02b0fd
+  bar (d, e, f, g);
02b0fd
+  c = 1;
02b0fd
+  for (int h; h; h++)
02b0fd
+    j = 0;
02b0fd
+}
02b0fd
--- gcc/testsuite/gcc.dg/unroll-and-jam.c	(revision 278492)
02b0fd
+++ gcc/testsuite/gcc.dg/unroll-and-jam.c	(revision 278614)
02b0fd
@@ -1,5 +1,5 @@
02b0fd
 /* { dg-do run } */
02b0fd
-/* { dg-options "-O3 -floop-unroll-and-jam --param unroll-jam-min-percent=0 -fdump-tree-unrolljam-details" } */
02b0fd
+/* { dg-options "-O3 -floop-unroll-and-jam -fno-tree-loop-im --param unroll-jam-min-percent=0 -fdump-tree-unrolljam-details" } */
02b0fd
 /* { dg-require-effective-target int32plus } */
02b0fd
 
02b0fd
 #include <stdio.h>
02b0fd
@@ -34,7 +34,7 @@
02b0fd
 #define TEST(name, body, test) \
02b0fd
 static void __attribute__((noinline,noclone)) name (unsigned long n, unsigned long m) \
02b0fd
 { \
02b0fd
-  unsigned long i, j; \
02b0fd
+  unsigned i, j; \
02b0fd
   for (i = 1; i < m; i++) { \
02b0fd
       for (j = 1; j < n; j++) { \
02b0fd
 	  body; \
02b0fd
@@ -58,9 +58,14 @@
02b0fd
 TEST(foo4, aa[i][j] = aa[i-1][j+1] * aa[i-1][j+1] / 2, checkaa()) //notok, -1,1
02b0fd
 TEST(foo5, aa[i][j] = aa[i+1][j+1] * aa[i+1][j+1] / 2, checkaa()) //ok, 1,1
02b0fd
 TEST(foo6, aa[i][j] = aa[i+1][j] * aa[i+1][j] / 2, checkaa()) //ok, -1,0
02b0fd
+TEST(foo61, aa[i][0] = aa[i+1][0] * aa[i+1][0] / 2, checkaa()) //notok, -1,0
02b0fd
+TEST(foo62, aa[i][j/2] = aa[i+1][j/2] * aa[i+1][j/2] / 2, checkaa()) //notok, not affine
02b0fd
+TEST(foo63, aa[i][j%2] = aa[i+1][j%2] * aa[i+1][j%2] / 2, checkaa()) //notok, not affine
02b0fd
 TEST(foo7, aa[i+1][j] = aa[i][j] * aa[i][j] / 2, checkaa()) //ok, 1,0
02b0fd
 TEST(foo9, b[j] = 3*b[j+1] + 1, checkb()) //notok, 0,-1
02b0fd
 TEST(foo10, b[j] = 3*b[j] + 1, checkb()) //ok, 0,0
02b0fd
+extern int f;
02b0fd
+TEST(foo11, f = b[i-1] = 1 + 3* b[i+1], checkb()) //ok, 2,0 but must reduce unroll factor to 2, (it would be incorrect with unroll-by-3, which the profitability would suggest)
02b0fd
 
02b0fd
 /* foo8 should work as well, but currently doesn't because the distance
02b0fd
    vectors we compute are too pessimistic.  We compute
02b0fd
@@ -68,6 +73,7 @@
02b0fd
    and the last one causes us to lose.  */
02b0fd
 TEST(foo8, b[j+1] = 3*b[j] + 1, checkb()) //ok, 0,1
02b0fd
 
02b0fd
+int f;
02b0fd
 unsigned int a[1024];
02b0fd
 unsigned int b[1024];
02b0fd
 unsigned int aa[16][1024];
02b0fd
@@ -88,10 +94,12 @@
02b0fd
     printf(" %s\n", #name); \
02b0fd
     init();for(i=0;i<4;i++)name##noopt(32,8); checka = checksum; \
02b0fd
     init();for(i=0;i<4;i++)name(32,8); \
02b0fd
+    if (checka != checksum) fail = 1; \
02b0fd
     printf("%sok %s\n", checka != checksum ? "NOT " : "", #name);
02b0fd
 
02b0fd
 int main()
02b0fd
 {
02b0fd
+  int fail = 0;
02b0fd
   int i;
02b0fd
   unsigned checka;
02b0fd
   RUN(foo1);
02b0fd
@@ -100,12 +108,18 @@
02b0fd
   RUN(foo4);
02b0fd
   RUN(foo5);
02b0fd
   RUN(foo6);
02b0fd
+  RUN(foo61);
02b0fd
+  RUN(foo62);
02b0fd
+  RUN(foo63);
02b0fd
   RUN(foo7);
02b0fd
   RUN(foo8);
02b0fd
   RUN(foo9);
02b0fd
   RUN(foo10);
02b0fd
-  return 0;
02b0fd
+  RUN(foo11);
02b0fd
+  if (fail)
02b0fd
+    __builtin_abort();
02b0fd
+  return fail;
02b0fd
 }
02b0fd
 
02b0fd
-/* Five loops should be unroll-jammed (actually six, but see above).  */
02b0fd
-/* { dg-final { scan-tree-dump-times "applying unroll and jam" 5 "unrolljam" } } */
02b0fd
+/* Six loops should be unroll-jammed (actually seven, but see above).  */
02b0fd
+/* { dg-final { scan-tree-dump-times "applying unroll and jam" 6 "unrolljam" } } */
02b0fd
--- gcc/testsuite/g++.dg/torture/pr91355.C	(nonexistent)
02b0fd
+++ gcc/testsuite/g++.dg/torture/pr91355.C	(revision 278614)
02b0fd
@@ -0,0 +1,28 @@
02b0fd
+// PR tree-optimization/91355
02b0fd
+// { dg-do run }
02b0fd
+// { dg-options "-std=c++14" }
02b0fd
+
02b0fd
+unsigned int d = 0;
02b0fd
+
02b0fd
+struct S {
02b0fd
+  S () { d++; }
02b0fd
+  S (const S &) { d++; }
02b0fd
+  ~S () { d--; }
02b0fd
+};
02b0fd
+
02b0fd
+void
02b0fd
+foo (int i) throw (int) // { dg-warning "dynamic exception specifications are deprecated" }
02b0fd
+{
02b0fd
+  if (i == 0)
02b0fd
+    throw 3;
02b0fd
+  S d;
02b0fd
+  throw 3;
02b0fd
+}
02b0fd
+
02b0fd
+int
02b0fd
+main ()
02b0fd
+{
02b0fd
+  try { foo (1); } catch (...) {}
02b0fd
+  if (d)
02b0fd
+    __builtin_abort ();
02b0fd
+}
02b0fd
--- gcc/tree-ssa-sink.c	(revision 278492)
02b0fd
+++ gcc/tree-ssa-sink.c	(revision 278614)
02b0fd
@@ -229,7 +229,7 @@
02b0fd
       /* If result of comparsion is unknown, preffer EARLY_BB.
02b0fd
 	 Thus use !(...>=..) rather than (...<...)  */
02b0fd
       && !(best_bb->count.apply_scale (100, 1)
02b0fd
-	   > (early_bb->count.apply_scale (threshold, 1))))
02b0fd
+	   >= early_bb->count.apply_scale (threshold, 1)))
02b0fd
     return best_bb;
02b0fd
 
02b0fd
   /* No better block found, so return EARLY_BB, which happens to be the
02b0fd
--- gcc/tree-vect-stmts.c	(revision 278492)
02b0fd
+++ gcc/tree-vect-stmts.c	(revision 278614)
02b0fd
@@ -8276,9 +8276,7 @@
02b0fd
        || alignment_support_scheme == dr_explicit_realign)
02b0fd
       && !compute_in_loop)
02b0fd
     {
02b0fd
-      msq = vect_setup_realignment (first_stmt_info_for_drptr
02b0fd
-				    ? first_stmt_info_for_drptr
02b0fd
-				    : first_stmt_info, gsi, &realignment_token,
02b0fd
+      msq = vect_setup_realignment (first_stmt_info, gsi, &realignment_token,
02b0fd
 				    alignment_support_scheme, NULL_TREE,
02b0fd
 				    &at_loop);
02b0fd
       if (alignment_support_scheme == dr_explicit_realign_optimized)
02b0fd
--- gcc/gimple-loop-jam.c	(revision 278492)
02b0fd
+++ gcc/gimple-loop-jam.c	(revision 278614)
02b0fd
@@ -360,9 +360,26 @@
02b0fd
   rewrite_into_loop_closed_ssa_1 (NULL, 0, SSA_OP_USE, loop);
02b0fd
 }
02b0fd
 
02b0fd
+/* Return true if any of the access functions for dataref A
02b0fd
+   isn't invariant with respect to loop LOOP_NEST.  */
02b0fd
+static bool
02b0fd
+any_access_function_variant_p (const struct data_reference *a,
02b0fd
+			       const class loop *loop_nest)
02b0fd
+{
02b0fd
+  unsigned int i;
02b0fd
+  vec<tree> fns = DR_ACCESS_FNS (a);
02b0fd
+  tree t;
02b0fd
+
02b0fd
+  FOR_EACH_VEC_ELT (fns, i, t)
02b0fd
+    if (!evolution_function_is_invariant_p (t, loop_nest->num))
02b0fd
+      return true;
02b0fd
+
02b0fd
+  return false;
02b0fd
+}
02b0fd
+
02b0fd
 /* Returns true if the distance in DDR can be determined and adjusts
02b0fd
    the unroll factor in *UNROLL to make unrolling valid for that distance.
02b0fd
-   Otherwise return false.
02b0fd
+   Otherwise return false.  DDR is with respect to the outer loop of INNER.
02b0fd
 
02b0fd
    If this data dep can lead to a removed memory reference, increment
02b0fd
    *REMOVED and adjust *PROFIT_UNROLL to be the necessary unroll factor
02b0fd
@@ -369,7 +386,7 @@
02b0fd
    for this to happen.  */
02b0fd
 
02b0fd
 static bool
02b0fd
-adjust_unroll_factor (struct data_dependence_relation *ddr,
02b0fd
+adjust_unroll_factor (class loop *inner, struct data_dependence_relation *ddr,
02b0fd
 		      unsigned *unroll, unsigned *profit_unroll,
02b0fd
 		      unsigned *removed)
02b0fd
 {
02b0fd
@@ -392,9 +409,59 @@
02b0fd
 	    gcc_unreachable ();
02b0fd
 	  else if ((unsigned)dist >= *unroll)
02b0fd
 	    ;
02b0fd
-	  else if (lambda_vector_lexico_pos (dist_v + 1, DDR_NB_LOOPS (ddr) - 1)
02b0fd
-		   || (lambda_vector_zerop (dist_v + 1, DDR_NB_LOOPS (ddr) - 1)
02b0fd
-		       && dist > 0))
02b0fd
+	  else if (lambda_vector_zerop (dist_v + 1, DDR_NB_LOOPS (ddr) - 1))
02b0fd
+	    {
02b0fd
+	      /* We have (a,0) with a < N, so this will be transformed into
02b0fd
+	         (0,0) after unrolling by N.  This might potentially be a
02b0fd
+		 problem, if it's not a read-read dependency.  */
02b0fd
+	      if (DR_IS_READ (DDR_A (ddr)) && DR_IS_READ (DDR_B (ddr)))
02b0fd
+		;
02b0fd
+	      else
02b0fd
+		{
02b0fd
+		  /* So, at least one is a write, and we might reduce the
02b0fd
+		     distance vector to (0,0).  This is still no problem
02b0fd
+		     if both data-refs are affine with respect to the inner
02b0fd
+		     loops.  But if one of them is invariant with respect
02b0fd
+		     to an inner loop our reordering implicit in loop fusion
02b0fd
+		     corrupts the program, as our data dependences don't
02b0fd
+		     capture this.  E.g. for:
02b0fd
+		       for (0 <= i < n)
02b0fd
+		         for (0 <= j < m)
02b0fd
+		           a[i][0] = a[i+1][0] + 2;    // (1)
02b0fd
+		           b[i][j] = b[i+1][j] + 2;    // (2)
02b0fd
+		     the distance vector for both statements is (-1,0),
02b0fd
+		     but exchanging the order for (2) is okay, while
02b0fd
+		     for (1) it is not.  To see this, write out the original
02b0fd
+		     accesses (assume m is 2):
02b0fd
+		       a i j original
02b0fd
+		       0 0 0 r a[1][0] b[1][0]
02b0fd
+		       1 0 0 w a[0][0] b[0][0]
02b0fd
+		       2 0 1 r a[1][0] b[1][1]
02b0fd
+		       3 0 1 w a[0][0] b[0][1]
02b0fd
+		       4 1 0 r a[2][0] b[2][0]
02b0fd
+		       5 1 0 w a[1][0] b[1][0]
02b0fd
+		     after unroll-by-2 and fusion the accesses are done in
02b0fd
+		     this order (from column a): 0,1, 4,5, 2,3, i.e. this:
02b0fd
+		       a i j transformed
02b0fd
+		       0 0 0 r a[1][0] b[1][0]
02b0fd
+		       1 0 0 w a[0][0] b[0][0]
02b0fd
+		       4 1 0 r a[2][0] b[2][0]
02b0fd
+		       5 1 0 w a[1][0] b[1][0]
02b0fd
+		       2 0 1 r a[1][0] b[1][1]  
02b0fd
+		       3 0 1 w a[0][0] b[0][1]
02b0fd
+		     Note how access 2 accesses the same element as access 5
02b0fd
+		     for array 'a' but not for array 'b'.  */
02b0fd
+		  if (any_access_function_variant_p (DDR_A (ddr), inner)
02b0fd
+		      && any_access_function_variant_p (DDR_B (ddr), inner))
02b0fd
+		    ;
02b0fd
+		  else
02b0fd
+		    /* And if any dataref of this pair is invariant with
02b0fd
+		       respect to the inner loop, we have no chance than
02b0fd
+		       to reduce the unroll factor.  */
02b0fd
+		    *unroll = dist;
02b0fd
+		}
02b0fd
+	    }
02b0fd
+	  else if (lambda_vector_lexico_pos (dist_v + 1, DDR_NB_LOOPS (ddr) - 1))
02b0fd
 	    ;
02b0fd
 	  else
02b0fd
 	    *unroll = dist;
02b0fd
@@ -486,7 +553,7 @@
02b0fd
 	  /* Now check the distance vector, for determining a sensible
02b0fd
 	     outer unroll factor, and for validity of merging the inner
02b0fd
 	     loop copies.  */
02b0fd
-	  if (!adjust_unroll_factor (ddr, &unroll_factor, &profit_unroll,
02b0fd
+	  if (!adjust_unroll_factor (loop, ddr, &unroll_factor, &profit_unroll,
02b0fd
 				     &removed))
02b0fd
 	    {
02b0fd
 	      /* Couldn't get the distance vector.  For two reads that's
02b0fd
@@ -506,7 +573,7 @@
02b0fd
 	 to ignore all profitability concerns and apply the transformation
02b0fd
 	 always.  */
02b0fd
       if (!PARAM_VALUE (PARAM_UNROLL_JAM_MIN_PERCENT))
02b0fd
-	profit_unroll = 2;
02b0fd
+	profit_unroll = MAX(2, profit_unroll);
02b0fd
       else if (removed * 100 / datarefs.length ()
02b0fd
 	  < (unsigned)PARAM_VALUE (PARAM_UNROLL_JAM_MIN_PERCENT))
02b0fd
 	profit_unroll = 1;
02b0fd
--- gcc/config/rs6000/predicates.md	(revision 278492)
02b0fd
+++ gcc/config/rs6000/predicates.md	(revision 278614)
02b0fd
@@ -1053,8 +1053,7 @@
02b0fd
     return 1;
02b0fd
 
02b0fd
   /* Allow any integer constant.  */
02b0fd
-  if (GET_MODE_CLASS (mode) == MODE_INT
02b0fd
-      && CONST_SCALAR_INT_P (op))
02b0fd
+  if (SCALAR_INT_MODE_P (mode) && CONST_SCALAR_INT_P (op))
02b0fd
     return 1;
02b0fd
 
02b0fd
   /* Allow easy vector constants.  */