On Thu, Jan 10, 2019 at 11:20 PM Jakub Jelinek <ja...@redhat.com> wrote: > > Hi! > > The following testcase ICEs in dwarf2out.c, because a few sse.md patterns > contain invalid RTL, in particular > (const_vector:V2SF [(const_int 0) (const_int 0)]) > Elements of a V2SF const_vector should be (const_double:SF 0), not > (const_int 0). Unfortunately, we can't add explicitly const_double 0 > constants the way one can write (const_int 0), so this patch uses > separate define_expand to add those CONST0_RTX args and match_operand > with "const0_rtx" "C" to match that. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2019-01-10 Jakub Jelinek <ja...@redhat.com> > > PR target/88785 > * config/i386/sse.md (float<floatunssuffix>v2div2sf2): Turn into > define_expand. > (*float<floatunssuffix>v2div2sf2): New define_insn. > (float<floatunssuffix>v2div2sf2_mask): Turn into define_expand. > (*float<floatunssuffix>v2div2sf2_mask): New define_insn. > (*float<floatunssuffix>v2div2sf2_mask_1): Replace > subrtxes (const_vector:V2SF [(const_int 0) (const_int 0)]) with > match_operands with "const0_operand" "C". > > * g++.target/i386/pr88785.C: New test.
OK. Thanks, Uros. > --- gcc/config/i386/sse.md.jj 2019-01-10 11:43:17.520326228 +0100 > +++ gcc/config/i386/sse.md 2019-01-10 12:57:52.946797987 +0100 > @@ -5222,11 +5222,19 @@ (define_insn "float<floatunssuffix><ssel > (set_attr "prefix" "evex") > (set_attr "mode" "<MODE>")]) > > -(define_insn "float<floatunssuffix>v2div2sf2" > +(define_expand "float<floatunssuffix>v2div2sf2" > [(set (match_operand:V4SF 0 "register_operand" "=v") > (vec_concat:V4SF > (any_float:V2SF (match_operand:V2DI 1 "nonimmediate_operand" > "vm")) > - (const_vector:V2SF [(const_int 0) (const_int 0)])))] > + (match_dup 2)))] > + "TARGET_AVX512DQ && TARGET_AVX512VL" > + "operands[2] = CONST0_RTX (V2SFmode);") > + > +(define_insn "*float<floatunssuffix>v2div2sf2" > + [(set (match_operand:V4SF 0 "register_operand" "=v") > + (vec_concat:V4SF > + (any_float:V2SF (match_operand:V2DI 1 "nonimmediate_operand" > "vm")) > + (match_operand:V2SF 2 "const0_operand" "C")))] > "TARGET_AVX512DQ && TARGET_AVX512VL" > "vcvt<floatsuffix>qq2ps{x}\t{%1, %0|%0, %1}" > [(set_attr "type" "ssecvt") > @@ -5260,16 +5268,29 @@ (define_expand "vec_pack<floatprefix>_fl > DONE; > }) > > -(define_insn "float<floatunssuffix>v2div2sf2_mask" > +(define_expand "float<floatunssuffix>v2div2sf2_mask" > + [(set (match_operand:V4SF 0 "register_operand" "=v") > + (vec_concat:V4SF > + (vec_merge:V2SF > + (any_float:V2SF (match_operand:V2DI 1 "nonimmediate_operand" > "vm")) > + (vec_select:V2SF > + (match_operand:V4SF 2 "nonimm_or_0_operand" "0C") > + (parallel [(const_int 0) (const_int 1)])) > + (match_operand:QI 3 "register_operand" "Yk")) > + (match_dup 4)))] > + "TARGET_AVX512DQ && TARGET_AVX512VL" > + "operands[4] = CONST0_RTX (V2SFmode);") > + > +(define_insn "*float<floatunssuffix>v2div2sf2_mask" > [(set (match_operand:V4SF 0 "register_operand" "=v") > (vec_concat:V4SF > (vec_merge:V2SF > - (any_float:V2SF (match_operand:V2DI 1 "nonimmediate_operand" > "vm")) > + (any_float:V2SF (match_operand:V2DI 1 "nonimmediate_operand" > "vm")) > (vec_select:V2SF > (match_operand:V4SF 2 "nonimm_or_0_operand" "0C") > (parallel [(const_int 0) (const_int 1)])) > (match_operand:QI 3 "register_operand" "Yk")) > - (const_vector:V2SF [(const_int 0) (const_int 0)])))] > + (match_operand:V2SF 4 "const0_operand" "C")))] > "TARGET_AVX512DQ && TARGET_AVX512VL" > "vcvt<floatsuffix>qq2ps{x}\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}" > [(set_attr "type" "ssecvt") > @@ -5282,9 +5303,9 @@ (define_insn "*float<floatunssuffix>v2di > (vec_merge:V2SF > (any_float:V2SF (match_operand:V2DI 1 > "nonimmediate_operand" "vm")) > - (const_vector:V2SF [(const_int 0) (const_int 0)]) > + (match_operand:V2SF 3 "const0_operand" "C") > (match_operand:QI 2 "register_operand" "Yk")) > - (const_vector:V2SF [(const_int 0) (const_int 0)])))] > + (match_operand:V2SF 4 "const0_operand" "C")))] > "TARGET_AVX512DQ && TARGET_AVX512VL" > "vcvt<floatsuffix>qq2ps{x}\t{%1, %0%{%2%}%{z%}|%0%{%2%}%{z%}, %1}" > [(set_attr "type" "ssecvt") > --- gcc/testsuite/g++.target/i386/pr88785.C.jj 2019-01-10 13:08:22.987439456 > +0100 > +++ gcc/testsuite/g++.target/i386/pr88785.C 2019-01-10 13:08:17.396531359 > +0100 > @@ -0,0 +1,197 @@ > +// PR target/88785 > +// { dg-do compile } > +// { dg-options "-O2 -g -std=c++17 -mavx512vl -mavx512dq" } > + > +namespace a { > +template <class> class b; > +template <class> class d; > +} > +template <int f> struct g { static constexpr int e = f; }; > +template <typename> struct aa; > +template <typename...> struct o; > +template <typename h, typename ab> struct o<h, ab> : aa<h>::ac {}; > +template <typename...> struct j; > +template <typename h, typename ab> struct j<h, ab> : aa<ab>::ac {}; > +template <typename... k> constexpr bool l = o<k...>::e; > +template <typename, typename> struct r : g<false> {}; > +template <typename m> struct r<m, m> : g<true> {}; > +template <typename ad> struct aa { typedef ad ac; }; > +template <bool, typename ad, typename> using ae = ad; > +template <typename...> using af = void; > +typedef float ag __attribute__((__vector_size__(16))); > +ag ah; > +ag ai(__attribute__((__vector_size__(2 * sizeof(long long)))) long long z) { > + ah = ag{}; > + __attribute__((__vector_size__(4 * sizeof(float)))) float aj = ah; > + return __builtin_ia32_cvtqq2ps128_mask(z, aj, 1); > +} > +namespace a { > +int ak; > +int al; > +template <long> int am; > +template <class> struct an; > +template <class> struct ao; > +template <class m> using ap = typename ao<m>::ac; > +template <class, unsigned long, class = af<>> struct aq; > +template <class m> using ar = aq<m, sizeof(m)>; > +template <class as, class at> as au(at); > +template <class> struct av; > +template <class m> using aw = typename av<m>::ac; > +template <class m, int ax> struct ay { > + static constexpr long az = ax * sizeof(int); > + using ac [[gnu::__vector_size__(az)]] = m; > +}; > +template <class m, long ba> using bb = typename ay<m, ba>::ac; > +template <class m> struct p { > + using bc = decltype(m()[0]); > + static constexpr int bd = sizeof(bc); > +}; > +template <class as, class m, class = p<m>> as be(m); > +template <class as, class... at> as bf(at... z) { return be<as>(z...); } > +template <class m, unsigned long ax, class bg = aw<m>> bg bh(aq<m, ax>) { > + return bg(); > +} > +template <> struct av<float> { > + using ac [[gnu::__vector_size__(16)]] = float; > +}; > +template <class> struct av { > + using ac [[gnu::__vector_size__(16)]] = long long; > +}; > +template <unsigned long bi> struct aq<bool, bi> {}; > +template <class m, unsigned long bi, class bj = bb<m, bi>, > + bool = l<r<bb<m, bi>, aw<m>>, r<bj, m>>> > +struct bk; > +template <class m, unsigned long bi, class bj> struct bk<m, bi, bj, true> { > + bj bl; > + bk(bb<m, bi> z) : bl(z) {} > +}; > +template <class m, unsigned long bi, class bj> struct bk<m, bi, bj, false> > {}; > +template <class m, unsigned long bi> struct aq<m, bi> : bk<m, bi> { > + using bm = bb<m, bi>; > + static constexpr long bd = bi; > + aq(); > + template <class bn> aq(bn z) : bk<m, bi>(z) {} > + m operator[](long); > +}; > +template <class> constexpr long bo = g<0>::e; > +template <class m> struct ao { using ac = typename an<m>::br; }; > +template <class bp, class m> class bq { > + using bu = m; > + bp bs; > + m bt; > + > +public: > + template <class bn, class bv> void q(bn z, bv bw) { > + auto s = bx(bt), by = bx(bs); > + ap<bu>::bz(s, z, bw, by); > + } > +}; > +class ca { > +public: > + template <class bn, class bv> void cb(bn, bv); > +}; > +template <class m> ca cc(typename b<m>::cd, m &); > +template <class m> bq<d<m>, b<m>> cc(typename b<m>::cd, const m &); > +struct ce; > +template <class t, int ax> struct cf { > + using br = typename t::br; > + using cg = aq<long, ax>; > + using ch = aq<long, ax>; > +}; > +struct ci { > + template <class m> static constexpr long cj = sizeof(m); > + struct ck : j<int, g<sizeof(int)>> {}; > + template <class> static constexpr bool cl = ck::e; > + using br = ce; > + template <class m> using cn = ae<cl<m>, cf<ci, cj<m>>, int>; > +}; > +template <class> struct an : ci::cn<long> {}; > +template <class> class d : an<int> { > + using cm = ch; > + > +public: > + cm bl; > +}; > +template <class m> auto bx(m z) { return z.bl; } > +template <class> class b : an<int> { > + using cm = cg; > + > +public: > + using cd = d<long>; > + static long cu(); > + b(); > + template <class bn, class bv> b(bn, bv) {} > + cm bl; > +}; > +template <class m> auto bx(b<m> z) { return z.bl; } > +template <class m, class co> void cq(ar<m>, co, aq<bool, ar<m>::bd>); > +template <class as, class bu, class cp> as be(bu z) { > + using cs = typename cp::bc; > + constexpr long ax = cp::bd; > + auto cr = bh(z); > + aq<cs, ax> f; > + using bn = typename p<as>::bc; > + constexpr bool cy = sizeof(f), ct = sizeof(bn); > + if (ct) > + if (cy) { > + ag cw = ai(cr); > + return cw; > + } > +} > +template <class as, class at> auto cv(at z) { return bf<as>(z); } > +struct G { > + template <class m> using ch = typename ci::cn<m>::ch; > + template <class m, unsigned long ax, class bn, class co> > + static void bz(aq<m, ax> z, bn *, co, ch<m> cx) { > + using da = aq<bn, sizeof(bn)>; > + using bu = typename da::bm; > + using bp = aq<ae<1, bool, bn>, da::bd>; > + auto cz = cv<bu>(z); > + cq(da(cz), ae<0, int, co>(), au<bp>(cx)); > + } > +}; > +struct ce : G {}; > +} > +class D { > +public: > + D(...); > + template <typename db> void operator<<(db); > +}; > +template <class dc> dc dd; > +struct de { > + long cu(); > +}; > +template <typename dc> void dg() { > + using db = long; > + auto df = dd<a::b<long>>; > + using a::ak; > + using a::al; > + constexpr long di = 1, alignment = a::bo<a::b<long>>; > + using dh = ae<di, decltype(al), int>; > + dh dk, am = a::am<alignment>; > + const a::b<long> dj; > + de u; > + auto dm = 0 ? u.cu() : 0; > + float dl[dm]; > + db reference; > + a::b<long> x; > + auto compare = [&](long) { > + int n; > + a::b<long>(reference, ak); > + for (auto i = 0; 0; ++i) > + [] { > + auto v = 0, w = 0; > + return D(w, v); > + }() << n; > + }; > + compare(0); > + using c = a::b<long>::cd; > + c dn; > + a::b y = df; > + auto v(y); > + cc(dn, x).cb(dl, am); > + long i; > + cc(dn, dj).q(&dl[dc::cu()], dk); > + ++i; > +} > +void test() { dg<a::b<long>>(); } > > Jakub