From: Peter Bergner Date: Mon, 31 May 2021 03:45:55 +0000 (-0500) Subject: rs6000: MMA test case ICEs using -O3 [PR99842] X-Git-Tag: releases/gcc-11.2.0~194 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aaa8419bcf2ec491c0fd41a526f5817da0cf3ed4;p=thirdparty%2Fgcc.git rs6000: MMA test case ICEs using -O3 [PR99842] The mma_assemble_input_operand predicate does not accept reg+reg indexed addresses which can lead to ICEs. The lxv and lxvp instructions have indexed forms (lxvx and lxvpx), so the simple solution is to just allow indexed addresses in the predicate. 2021-05-30 Peter Bergner gcc/ PR target/99842 * config/rs6000/predicates.md(mma_assemble_input_operand): Allow indexed form addresses. gcc/testsuite/ PR target/99842 * g++.target/powerpc/pr99842.C: New. (cherry picked from commit df4e0359dad239854af0ea9eacb8e7e3719557d0) --- diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index e21bc745f72c..121cbf14810e 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -1172,7 +1172,8 @@ (match_test "(mode == V16QImode && (vsx_register_operand (op, mode) || (MEM_P (op) - && quad_address_p (XEXP (op, 0), mode, false))))")) + && (indexed_or_indirect_address (XEXP (op, 0), mode) + || quad_address_p (XEXP (op, 0), mode, false)))))")) ;; Return 1 if this operand is valid for an MMA disassemble insn. (define_predicate "mma_disassemble_output_operand" diff --git a/gcc/testsuite/g++.target/powerpc/pr99842.C b/gcc/testsuite/g++.target/powerpc/pr99842.C new file mode 100644 index 000000000000..922450e2c214 --- /dev/null +++ b/gcc/testsuite/g++.target/powerpc/pr99842.C @@ -0,0 +1,188 @@ +/* PR target/99842 */ +/* { dg-require-effective-target power10_ok } */ +/* { dg-options "-O3 -mdejagnu-cpu=power10 -Wno-return-type" } */ + +/* Verify we do not ICE on the following noisy creduced test case. */ + +enum { a, b, c, d }; +template struct e; +template struct e { + typedef h f; +}; +template struct ac; +template struct ac : ac {}; +template struct l; +template class n; +template class o; +template class ag; +template class af; +template struct ad; +template struct an { + typedef n::ai, ac::aj> f; +}; +template struct am { typedef o f; }; +template ::ao, + typename = typename ac::av> +struct ak; +template struct ak { + typedef typename am::f f; +}; +template struct aq; +template struct aq { typedef ar at; }; +template ap bf(const typename ad::f *); +template ap aw(typename ad::f *ax) { return bf(ax); } +typedef __attribute__((altivec(vector__))) double au; +template <> struct ad { typedef double f; }; +template <> au bf(const double *ax) { return __builtin_vec_vsx_ld(0, ax); } +template struct az {}; +template class o : public l { +public: + typedef typename ac::ah ah; + template al &operator+=(const o &); +}; +template struct l {}; +template struct ac> { + typedef typename ba::ah ah; + enum { ai, aj }; +}; +template +class af + : public ak< + af, const n>, + n, bd>, + int, int>::f {}; +template struct be; +template void bi(bj, bg bm, g) { + typename an::f bk(bm); +} +template void bl(bj, bg bm, g bp) { + be::bn(a, bm, bp); +} +template struct bo; +class bs { +public: + bs(double *, int); + double &operator()(int, int) { return bq[br]; } + template bw bt(int i, int j) { + double &bu = operator()(i, j); + return aw(&bu); + } + double *bq; + int br; +}; +class ca : public bs { +public: + ca(double *by, int bz) : bs(by, bz) {} +}; +template class ce : public am::f { +protected: + template void cb(l) { + af, const n>, + n> + cc; + bl(0, cc, az()); + } + template void ch(long); + template void ch(l cf) { cb(cf); } +}; +template +struct ac> { + typedef cg ah; + typedef int av; +}; +template +class n : public ce> { +public: + template n(ab p) { n::template ch(p); } +}; +template struct ac> { + typedef ba ao; + typedef typename e::f ah; + typedef typename aq::av, typename ac::av, bc>::at av; +}; +template class cm; +template +class ag + : public cm::av, typename ac::av, int>::at> { +}; +template +class cm : public ak, n>>::f {}; +template +template +al &o::operator+=(const o &) { + af, const n>, + n> + co; + bi(0, co, int()); +} +enum { cp }; +template struct cq; +template struct cr { + enum { q }; + enum { ae = cq::at }; +}; +template <> struct cq { + enum { at = d }; +}; +struct t { + template static void bn(ba, bb, s) { + typedef typename bb::ah x; + x u; + bo::bn(0, 0, ca(0, 0), ca(&u, 1), 0, 0, 0); + } +}; +template ::ae> struct cu; +template +struct be, az> { + static void bn(cd, af bm, az) { + ag, const n> da; + cu::cv(c, da, bm); + } +}; +template struct cw { + template + static void + cv(bj, ag, const n>, + n bx) { + double alpha; + ag, const n> bh; + al::cx(c, bh, bx, alpha); + } +}; +template struct cu : cw> { + template static void cx(s, ba, bb bx, typename af::ah) { + ba cz; + t::bn(cz, bx, c); + } +}; +template +void db(__vector_quad *, __vector_pair &, dj); +template +void dc(ca alhs) { + typedef au dj; + typedef au dd; + ca bh(alhs); + enum { de }; + __vector_quad df, dg; + int j; + dd v; + __vector_pair dh; + __builtin_mma_assemble_pair( + &dh, (__attribute__((altivec(vector__))) char)bh.bt(0, j), + (__attribute__((altivec(vector__))) char)bh.bt(0, j)); + db(&df, dh, v); + __vector_pair di; + __builtin_mma_assemble_pair( + &di, (__attribute__((altivec(vector__))) char)bh.bt(0, j), + (__attribute__((altivec(vector__))) char)bh.bt(0, j)); + db(&dg, di, v); +} +template struct bo { + static void bn(bv, bv, w bh, cy, double, bv, double) { + dc(bh); + } +}; +void dm() { + n dk(1), y(0); + y += dk; +}