This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, rs6000] Fix PR65914


Hi,

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65914 demonstrates that we
fail to match vector predicates with pseudos that are in the virtual
stack register range.  The reduced test case provided with the bug
report, when compiled for the C++14 standard, demonstrates that we need
to be able to do this.  This patch loosens the restriction for the
vector predicates so that all pseudos are accepted.  Thanks to Uli
Weigand for his insights on this bug.

As a side benefit, applying this patch fixes a number of libgomp tests
that have been failing recently.

Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no
regressions.  Is this ok for trunk?  After it burns in, I would propose
to backport it to GCC 5.1 and GCC 4.9 (when the tree is open).

Thanks,
Bill


[gcc]

2015-05-19  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

	* config/rs6000/predicates.md (altivec_register_operand): Permit
	virtual stack registers.
	(vsx_register_operand): Likewise.
	(vfloat_operand): Likewise.
	(vint_operand): Likewise.
	(vlogical_operand): Likewise.

[gcc/testsuite]

2015-05-19  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

	* g++.dg/torture/pr65419.C:  New.


Index: gcc/config/rs6000/predicates.md
===================================================================
--- gcc/config/rs6000/predicates.md	(revision 224671)
+++ gcc/config/rs6000/predicates.md	(working copy)
@@ -41,7 +41,7 @@
   if (!REG_P (op))
     return 0;
 
-  if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+  if (REGNO (op) >= FIRST_PSEUDO_REGISTER)
     return 1;
 
   return ALTIVEC_REGNO_P (REGNO (op));
@@ -57,7 +57,7 @@
   if (!REG_P (op))
     return 0;
 
-  if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+  if (REGNO (op) >= FIRST_PSEUDO_REGISTER)
     return 1;
 
   return VSX_REGNO_P (REGNO (op));
@@ -74,7 +74,7 @@
   if (!REG_P (op))
     return 0;
 
-  if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+  if (REGNO (op) >= FIRST_PSEUDO_REGISTER)
     return 1;
 
   return VFLOAT_REGNO_P (REGNO (op));
@@ -91,7 +91,7 @@
   if (!REG_P (op))
     return 0;
 
-  if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+  if (REGNO (op) >= FIRST_PSEUDO_REGISTER)
     return 1;
 
   return VINT_REGNO_P (REGNO (op));
@@ -108,7 +108,7 @@
   if (!REG_P (op))
     return 0;
 
-  if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+  if (REGNO (op) >= FIRST_PSEUDO_REGISTER)
     return 1;
 
   return VLOGICAL_REGNO_P (REGNO (op));
Index: gcc/testsuite/g++.dg/torture/pr65419.C
===================================================================
--- gcc/testsuite/g++.dg/torture/pr65419.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/pr65419.C	(working copy)
@@ -0,0 +1,70 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c++14" } */
+
+enum expression_template_option { et_on };
+template <class, expression_template_option = et_on> class A;
+template <class, class, class, class = void, class = void> struct expression;
+template <class T> struct B { typedef const T &type; };
+template <class tag, class A1, class A2, class A3, class A4>
+struct B<expression<tag, A1, A2, A3, A4>> {
+  typedef expression<tag, A1, A2> type;
+};
+template <class tag, class Arg1, class Arg2>
+struct expression<tag, Arg1, Arg2> {
+  expression(Arg1 p1, const Arg2 &p2) : arg1(p1), arg2(p2) {}
+  typename B<Arg1>::type arg1;
+  typename B<Arg2>::type arg2;
+};
+template <class Backend> expression<int, int, A<Backend>> sin(A<Backend>) {
+  return expression<int, int, A<Backend>>(0, 0);
+}
+template <class tag, class A1, class A2, class A3, class A4>
+expression<int, int, expression<tag, A1, A2>>
+  asin(expression<tag, A1, A2, A3, A4> p1) {
+  return expression<int, int, expression<tag, A1, A2>>(0, p1);
+}
+template <class B, expression_template_option ET, class tag, class Arg1,
+	  class Arg2, class Arg3, class Arg4>
+expression<int, A<B>, expression<tag, Arg1, Arg2>>
+  operator+(A<B, ET>, expression<tag, Arg1, Arg2, Arg3, Arg4> p2) {
+  return expression<int, A<B>, expression<tag, Arg1, Arg2>>(0, p2);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2,
+	  class Arg1b, class Arg2b, class Arg3b, class Arg4b>
+expression<int, expression<tag, Arg1, Arg2>, expression<tag2, Arg1b, Arg2b>>
+  operator*(expression<tag, Arg1, Arg2, Arg3, Arg4> p1,
+	    expression<tag2, Arg1b, Arg2b, Arg3b, Arg4b> p2) {
+  return expression<int, expression<tag, Arg1, Arg2>,
+		    expression<tag2, Arg1b, Arg2b>>(p1, p2);
+}
+template <class B> expression<int, A<B>, A<B>> operator/(A<B>, A<B>) {
+  return expression<int, A<B>, A<B>>(0, 0);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
+void operator/(expression<tag, Arg1, Arg2, Arg3, Arg4>, V);
+template <class, expression_template_option> class A {
+public:
+  A() {}
+  template <class V> A(V) {}
+};
+template <class T, class Policy> void jacobi_recurse(T, T, Policy) {
+  T a, b, c;
+  (a+asin(b/c) * sin(a)) / 0.1;
+}
+template <class T, class Policy> void jacobi_imp(T p1, Policy) {
+  T x;
+  jacobi_recurse(x, p1, 0);
+}
+template <class T, class U, class V, class Policy>
+void jacobi_elliptic(T, U, V, Policy) {
+  jacobi_imp(static_cast<T>(0), 0);
+}
+template <class U, class T, class Policy> void jacobi_sn(U, T, Policy) {
+  jacobi_elliptic(static_cast<T>(0), 0, 0, 0);
+}
+template <class U, class T> void jacobi_sn(U, T p2) { jacobi_sn(0, p2, 0); }
+template <class T> void test_extra(T) {
+  T d;
+  jacobi_sn(0, d);
+}
+void foo() { test_extra(A<int>()); }



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]