From: Bill Schmidt Date: Mon, 25 Apr 2016 22:29:49 +0000 (+0000) Subject: backport: re PR target/70098 (PowerPC64: eigen hits ICE following invalid register... X-Git-Tag: releases/gcc-4.9.4~207 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ec7267bffde5b8974720ff27aafd51a4cbd14ca3;p=thirdparty%2Fgcc.git backport: re PR target/70098 (PowerPC64: eigen hits ICE following invalid register assignment) [gcc] 2016-04-25 Bill Schmidt Backport from mainline 2016-03-14 Segher Boessenkool PR target/70098 * config/rs6000/rs6000.md (*ctr_internal1, *ctr_internal2, *ctr_internal5, *ctr_internal6): Also allow "d" as output. (define_split for the GPR case): Use int_reg_operand instead of gpc_reg_operand for the output. [gcc/testsuite] 2016-04-25 Bill Schmidt Backport from mainline 2016-03-14 Segher Boessenkool PR target/70098 * lib/target-supports.exp (check_effective_target_powerpc64_no_dm): New function. * g++.dg/pr70098.C: New testcase. From-SVN: r235424 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d6d083faddde..b2498c790058 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2016-04-25 Bill Schmidt + + Backport from mainline + 2016-03-14 Segher Boessenkool + + PR target/70098 + * config/rs6000/rs6000.md (*ctr_internal1, *ctr_internal2, + *ctr_internal5, *ctr_internal6): Also allow "d" as output. + (define_split for the GPR case): Use int_reg_operand instead of + gpc_reg_operand for the output. + 2016-04-21 Andreas Krebbel Backport from mainline diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index bd43b1bd08a0..a3efbbc0022a 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -14909,7 +14909,7 @@ (const_int 1)) (label_ref (match_operand 0 "" "")) (pc))) - (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l") + (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l") (plus:P (match_dup 1) (const_int -1))) (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) @@ -14933,7 +14933,7 @@ (const_int 1)) (pc) (label_ref (match_operand 0 "" "")))) - (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l") + (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l") (plus:P (match_dup 1) (const_int -1))) (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) @@ -14959,7 +14959,7 @@ (const_int 1)) (label_ref (match_operand 0 "" "")) (pc))) - (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l") + (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l") (plus:P (match_dup 1) (const_int -1))) (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) @@ -14983,7 +14983,7 @@ (const_int 1)) (pc) (label_ref (match_operand 0 "" "")))) - (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l") + (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*c*l") (plus:P (match_dup 1) (const_int -1))) (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) @@ -15010,7 +15010,7 @@ (const_int 1)]) (match_operand 5 "" "") (match_operand 6 "" ""))) - (set (match_operand:P 0 "gpc_reg_operand" "") + (set (match_operand:P 0 "int_reg_operand" "") (plus:P (match_dup 1) (const_int -1))) (clobber (match_scratch:CC 3 "")) (clobber (match_scratch:P 4 ""))] diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 868b415670f7..e0e8039b436b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2016-04-25 Bill Schmidt + + Backport from mainline + 2016-03-14 Segher Boessenkool + + PR target/70098 + * lib/target-supports.exp (check_effective_target_powerpc64_no_dm): + New function. + * g++.dg/pr70098.C: New testcase. + 2016-04-21 Andreas Krebbel Backport from mainline diff --git a/gcc/testsuite/g++.dg/pr70098.C b/gcc/testsuite/g++.dg/pr70098.C new file mode 100644 index 000000000000..f5eb48f96e25 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr70098.C @@ -0,0 +1,91 @@ +// PR target/70098 +// { dg-do compile } +// { dg-options -O2 } +// { dg-require-effective-target c++11 } +// { dg-xfail-if "PR70098" { lp64 && powerpc64_no_dm } } +// { dg-prune-output ".*internal compiler error.*" } + +template < typename > struct traits; +template < typename, int _Rows, int _Cols, int = 0, int = _Rows, + int = _Cols > class Matrix; +template < typename > class G; +template < typename Derived > struct A { + typedef G < Derived > type; +}; + +template < typename Derived > class C { +public: + enum { RowsAtCompileTime = + traits < Derived >::RowsAtCompileTime } static Zero; +}; + +template < typename Derived > class G:public C < Derived > { +}; + +template < int _Rows > class D { +public: + long rows() { + return _Rows; + } +}; + +template < typename Derived > class PlainObjectBase:public A < Derived >::type { + typedef typename A < Derived >::type Base; + D < Base::RowsAtCompileTime > m_storage; + +public: + long rows() { + return m_storage.rows(); + } +}; + +int fn1(); + +struct B { + static long run(long x, long) { + int offset(fn1()); + return x + offset; +}}; + +long fn2(int x) +{ + return B::run(x, 0); +} + +template < typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, + int _MaxCols > + struct traits > { + enum { RowsAtCompileTime = _Rows }; +}; + +template < typename, int, int, int, int _MaxRows, int _MaxCols > + class Matrix:public PlainObjectBase < Matrix < double, _MaxRows, + _MaxCols >> { +public: + template < typename OtherDerived > Matrix(OtherDerived); +}; + +struct F { + static Matrix < double, 2, 2 > run(long size) { + Matrix < double, 2, 2 > diag = Matrix < double, 2, 2 >::Zero; + long i = 0; + while (i < size) { + long randomInt = fn2(-1); + if (randomInt == 0) + ++i; + else { + double alpha(randomInt); + diag = alpha; + i = 2; + } + } + + return diag; + } +}; + +void fn3(Matrix < double, 2, 2 > m) +{ + long size = m.rows(); + F::run(size); +} diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 29489ff800ee..19c512f4eb90 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -1393,6 +1393,19 @@ proc check_effective_target_avx_runtime { } { return 0 } +# Return 1 if we are compiling for 64-bit PowerPC but we do not use direct +# move instructions for moves from GPR to FPR. + +proc check_effective_target_powerpc64_no_dm { } { + # The "mulld" checks if we are generating PowerPC64 code. The "lfd" + # checks if we do not use direct moves, but use the old-fashioned + # slower move-via-the-stack. + return [check_no_messages_and_pattern powerpc64_no_dm \ + {\mmulld\M.*\mlfd} assembly { + double f(long long x) { return x*x; } + } {-O2}] +} + # Return 1 if the target supports executing power8 vector instructions, 0 # otherwise. Cache the result.