From patchwork Thu Feb 11 20:22:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Bergner X-Patchwork-Id: 1439664 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=itXmh0T6; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Dc7N53Zyfz9sB4 for ; Fri, 12 Feb 2021 07:22:27 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id CECAF3836C2F; Thu, 11 Feb 2021 20:22:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CECAF3836C2F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1613074944; bh=Pcg9vi/4vz03jq0G180/bTWHO8xA5cW4R5jqf+2TuNk=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=itXmh0T6UXkgds5aXaPb5layNFaSrmXFMtMtk2+pehXOK7M3tJxZTUGxibpg8s8wz 9NHxhlEyWsG7MqjRhFZDV5do1jGRnlL7X7KucSoU4DlbdPqVyCD+ztscZK+qtmTj+p IaRFVR2XgJ41/d6s2BDDUBGHkKp6LQGvy6OFKDjs= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id 2E9283836C2D for ; Thu, 11 Feb 2021 20:22:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 2E9283836C2D Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 11BK9Dmd154392; Thu, 11 Feb 2021 15:22:21 -0500 Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 36nb05rsyq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 11 Feb 2021 15:22:21 -0500 Received: from m0098394.ppops.net (m0098394.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 11BKAL8N160999; Thu, 11 Feb 2021 15:22:20 -0500 Received: from ppma05wdc.us.ibm.com (1b.90.2fa9.ip4.static.sl-reverse.com [169.47.144.27]) by mx0a-001b2d01.pphosted.com with ESMTP id 36nb05rsya-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 11 Feb 2021 15:22:20 -0500 Received: from pps.filterd (ppma05wdc.us.ibm.com [127.0.0.1]) by ppma05wdc.us.ibm.com (8.16.0.42/8.16.0.42) with SMTP id 11BKHaG0004750; Thu, 11 Feb 2021 20:22:19 GMT Received: from b01cxnp22034.gho.pok.ibm.com (b01cxnp22034.gho.pok.ibm.com [9.57.198.24]) by ppma05wdc.us.ibm.com with ESMTP id 36hjr9r7td-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 11 Feb 2021 20:22:19 +0000 Received: from b01ledav004.gho.pok.ibm.com (b01ledav004.gho.pok.ibm.com [9.57.199.109]) by b01cxnp22034.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 11BKMJYO25297342 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 11 Feb 2021 20:22:19 GMT Received: from b01ledav004.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 10DAB112064; Thu, 11 Feb 2021 20:22:19 +0000 (GMT) Received: from b01ledav004.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 81147112061; Thu, 11 Feb 2021 20:22:18 +0000 (GMT) Received: from [9.160.72.247] (unknown [9.160.72.247]) by b01ledav004.gho.pok.ibm.com (Postfix) with ESMTP; Thu, 11 Feb 2021 20:22:18 +0000 (GMT) To: GCC Patches Subject: [PATCH, pushed] rs6000: Fix invalid address used in MMA built-in function Message-ID: <62a18266-e8ab-20e1-9c24-78307f246b4c@linux.ibm.com> Date: Thu, 11 Feb 2021 14:22:18 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:78.0) Gecko/20100101 Thunderbird/78.7.0 MIME-Version: 1.0 Content-Language: en-US X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.369, 18.0.737 definitions=2021-02-11_07:2021-02-11, 2021-02-11 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 phishscore=0 spamscore=0 impostorscore=0 adultscore=0 lowpriorityscore=0 priorityscore=1501 clxscore=1015 suspectscore=0 mlxscore=0 bulkscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2009150000 definitions=main-2102110157 X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Peter Bergner via Gcc-patches From: Peter Bergner Reply-To: Peter Bergner Cc: Jakub Jelinek , Segher Boessenkool Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" The mma_assemble_input_operand predicate is too lenient on the memory operands it will accept, leading to an ICE when illegitimate addresses are passed in. The solution is to only accept memory operands with addresses that are valid for quad word memory accesses. The test case is a minimized test case from the Eigen library. The creduced test case is very noisy with respect to warnings, so the test case has added -w to silence them. Thanks to Jakub for diagnosing the bug! This passed bootstrap and regtesting with no regressions on powerpc64le-linux. Approved offline by Segher. Committed and pushed. Peter gcc/ PR target/99041 * config/rs6000/predicates.md (mma_assemble_input_operand): Restrict memory addresses that are legal for quad word accesses. gcc/testsuite/ PR target/99041 * g++.target/powerpc/pr99041.C: New test. diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 76328ecff3d..bd26c62b3a4 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -1156,7 +1156,9 @@ ;; Return 1 if this operand is valid for a MMA assemble accumulator insn. (define_special_predicate "mma_assemble_input_operand" (match_test "(mode == V16QImode - && (vsx_register_operand (op, mode) || MEM_P (op)))")) + && (vsx_register_operand (op, mode) + || (MEM_P (op) + && 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/pr99041.C b/gcc/testsuite/g++.target/powerpc/pr99041.C new file mode 100644 index 00000000000..c83f9806570 --- /dev/null +++ b/gcc/testsuite/g++.target/powerpc/pr99041.C @@ -0,0 +1,84 @@ +/* PR target/99041 */ +/* { dg-require-effective-target power10_ok } */ +/* { dg-options "-O2 -mdejagnu-cpu=power10 -w" } */ + +/* Verify we do not ICE on the following source. */ + +long a, b, c, d, e; + enum { f }; + enum { g, aa }; + enum { h }; + template < typename > struct ai; + template < typename > struct ad; + template < typename, int, int ah, int = 0, int = f, int = ah > class ab; + template < typename > class ar; + template < typename > class ak; + template < typename, int, int = 1, bool = false > class aj; + template < typename > class an; + template < typename, typename > class al; + template < typename, typename, int = h > class am; + template < typename, unsigned > class ao; + template < typename > struct ap; + template < typename aq > struct av { typedef ar< aq > ac; }; + template < typename > struct as { typedef av< am< al< int, an< aj< ab< double, 5, 2 >, false > > >, int > >::ac ac; }; + template < typename at > at au(const typename ap< at >::ac *); + template < typename at, int > at cc(typename ap< at >::ac *aw) { return au< at >(aw); } + typedef __attribute__((altivec(vector__))) double ax; + template <> struct ap< ax > { typedef double ac; }; + template <> ax au(const double *aw) { return __builtin_vec_vsx_ld(0, aw); } + template < typename > struct ay {}; + template < typename aq > class ae : public ad< aq > { public: typedef typename ai< aq >::ba ba; }; + template < typename aq > class ar : public ae< aq > { public: ak< aq > bk(); }; + template < typename > struct ad {}; + template < int > class bc; + template < typename bd, typename bf, int bg > struct ai< am< bd, bf, bg > > { typedef typename bd::ba ba; }; + template < typename bh, typename bj, int bg > class am : public bc< bg > { public: bh bu(); bj k(); }; + template < int bg > class bc : public as< am< int, int, bg > >::ac {}; + template < typename, typename, typename > struct l; + template < typename m, typename bl, typename ag > void n(m bm, bl bn, ag bo) { l< m, bl, ag >::bz(bm, bn, bo); } + template < typename, typename, typename, typename > struct bp; + class o { public: o(double *, long); double &operator()(long i, long j) { return p[aa ? j + i * w : w]; } template < typename q, int t > q br(long i, long j) { double &cl = operator()(i, j); return cc< q, t >(&cl); } double *p; long w; }; + class bt : public o { public: bt(double *cf, long bv) : o(cf, bv) {} }; + struct bw { enum { bx }; }; + template < typename bq > class ak { public: template < typename by > void operator=(by) { am< al< const an< const aj< aj< ab< double, 5, 5, 2 >, -1, -1 >, -1 > >, const an< const aj< aj< ab< double, 5, 5, 2 >, -1, -1 >, -1 > > >, ao< aj< ab< double, 5, 0 >, 1 >, 0 > > ck; n(ca, ck, ay< typename by::ba >()); } bq ca; }; + template < typename aq > class dn : public av< aq >::ac {}; + template < typename cd, int af, int ah, int ce, int co, int cg > struct ai< ab< cd, af, ah, ce, co, cg > > { typedef cd ba; enum { bs }; }; + template < typename, int, int, int, int co, int cg > class ab : public dn< ab< int, co, cg > > { public: template < typename by > ab(by); }; + template < typename, typename ch > class al : public ch {}; + template < typename aq > class az { public: typedef typename ai< aq >::ba ba; typedef const ba *ci; ba &cj(long); }; + template < typename ct > class bb : public az< ct > { public: bb(typename bb::ci, long); }; + template < typename cx, int cm, int cn, bool da > struct ai< aj< cx, cm, cn, da > > : ai< cx > {}; + template < typename > class cp; + template < typename cx, int, int, bool > class aj : public cp< cx > { public: aj(cx, long, long, long, long); }; + template < typename cx > class cp : public av< aj< cx, 1 > >::ac {}; + template < typename cq > class an : public cq {}; + template < typename cq, unsigned cr > struct ai< ao< cq, cr > > { typedef cq cs; }; + template < typename, unsigned > class ao { public: typedef aj< ab< double, 5, 0 >, 1 > cq; typename ai< ao >::cs cu(); }; + template < typename, typename > struct cv; + template < typename cw, typename bd, typename bf, int dh, typename ba > struct l< cw, am< bd, bf, dh >, ay< ba > > { static void bz(cw bm, am< bd, bf > bn, ay< ba >) { cv< bd, bf >::cy(bm, bn.bu(), bn.k()); } }; + template < typename bf, typename aq > struct cz { template < typename m > static void cy(m bm, al< const an< const aj< aj< ab< double, 5, 5, 2 >, -1, -1 >, -1 > >, const an< const aj< aj< ab< double, 5, 5, 2 >, -1, -1 >, -1 > > > bu, bf) { dl(bm, bu); } template < typename m > static void dl(m bm, al< const an< const aj< aj< ab< double, 5, 5, 2 >, -1, -1 >, -1 > >, const an< const aj< aj< ab< double, 5, 5, 2 >, -1, -1 >, -1 > > > bu) { typename alpha; bf k; aq::dl(bm, bu, k, alpha); } }; + template < typename, typename, bool > struct u; + template < typename bd, typename bf > struct cv : cz< bf, cv< bd, bf > > { template < typename v > static void dl(v bm, bd bu, bf k, typename am< bd, bf >::ba alpha) { u< bd, typename bf::cq, false >::bz(bm, bu, k.cu(), alpha); } }; + template < typename, int, typename, bool, typename, bool, int, int = g > struct db; + template < typename cb, int x, typename z, bool dc, typename dd, bool de, int df > struct db< cb, x, z, dc, dd, de, aa, df > { typedef z dg; static void bz(cb, cb, const z *, cb, const dd *, cb, dg *, cb, const dg &); }; + template < typename cb, int x, typename z, bool dc, typename dd, bool de, int df > void db< cb, x, z, dc, dd, de, aa, df >::bz(cb, cb, const z *_lhs, cb di, const dd *dj, cb dk, dg *_res, cb dm, const dg &alpha) { cb cols; bb< ab< z, 1, aa > > bu(_lhs, cols), res(_res, dm); bb< ab< dd, 1, 1 > > k(dj, cols); for (cb pi;;) { cb actualPanelWidth, s, r; bp< cb, bt, dd, bt >::bz(actualPanelWidth, r, bt(&bu.cj(s), di), bt(&k.cj(s), dk), &res.cj(pi), dm, alpha); } } + template < int, int > struct trmv_selector; + template < typename bd, typename bf > struct u< bd, bf, false > { template < typename v > static void bz(v bm, bd bu, bf k, typename v::ba alpha) { v dstT(bm); trmv_selector< 0, ai< bf >::bs ?: aa >::bz(k, bu, dstT, alpha); } }; + template < int x > struct trmv_selector< x, aa > { template < typename bd, typename bf, typename v > static void bz(bd, bf, v, typename v::ba) { typedef typename bf::ba dd; typedef bw LhsBlasTraits; typedef bw RhsBlasTraits; typename actualAlpha; dd actualRhsPtr; db< long, x, typename bd::ba, LhsBlasTraits::bx, dd, RhsBlasTraits::bx, aa >::bz(0, 0, 0, 0, &actualRhsPtr, 1, 0, 0, actualAlpha); } }; + template < typename LhsPacket, typename, bool > void pger_vec(__vector_quad *, __vector_pair &, LhsPacket); + template < typename, typename, typename, typename, typename, typename > void gemv_row(bt alhs) { typedef ax LhsPacket; typedef ax RhsPacket; bt bu(alhs); enum { LhsAlignment, LhsPacketSize }; long i, j; __vector_quad c0; for (;; j += LhsPacketSize) { RhsPacket b0; __vector_pair b00; __builtin_mma_assemble_pair(&b00, (__attribute__((altivec(vector__))) char) bu.br< LhsPacket, LhsAlignment >(1, j), (__attribute__((altivec(vector__))) char) bu.br< LhsPacket, LhsAlignment >(i, j)); pger_vec< LhsPacket, RhsPacket, true >(&c0, b00, b0); } } + template < typename cb, typename LhsMapper, typename RhsMapper > struct bp< cb, LhsMapper, double, RhsMapper > { static void bz(cb, cb, LhsMapper bu, RhsMapper, double *, cb, double) { gemv_row< cb, double, LhsMapper, double, RhsMapper, double >(bu); } }; + class be { public: template < typename v, typename Workspace > void cy(v, Workspace workspace) { applyThisOnTheLeft(workspace, true); } template < typename v, typename Workspace > void applyThisOnTheLeft(v bm, Workspace) { aj< ab< double, 5, 0 >, 1 > sub_vecs1(m_vectors, c, a, c, b); aj< v, 1 > sub_dst(bm, d, 0, e, 0); apply_block_householder_on_the_left(sub_dst, sub_vecs1, b); } ab< double, 5, 5 > m_vectors; }; + template < typename TriangularFactorType, typename VectorsType, typename CoeffsType > void make_block_householder_triangular_factor(TriangularFactorType triFactor, VectorsType vectors, CoeffsType) { triFactor.bk() = vectors; } + template < typename cq, typename VectorsType, typename CoeffsType > void apply_block_householder_on_the_left(cq, VectorsType vectors, CoeffsType hCoeffs) { enum { TFactorSize }; ab< typename cq::ba, TFactorSize, aa > y(0); make_block_householder_triangular_factor(y, vectors, hCoeffs); } + class HessenbergDecomposition { public: be matrixQ(); }; + template < typename > class RealSchur { public: enum { MaxColsAtCompileTime }; template < typename InputType > RealSchur &compute(const ad< InputType > &, bool); ab< double, 5, 5 > m_matU; ab< double, MaxColsAtCompileTime, 1 > m_workspaceVector; HessenbergDecomposition m_hess; }; + template < typename cq > template < typename InputType > RealSchur< cq > &RealSchur< cq >::compute(const ad< InputType > &, bool) { m_hess.matrixQ().cy(m_matU, m_workspaceVector); } + template < typename > class EigenSolver { public: EigenSolver(); template < typename InputType > EigenSolver &compute(const ad< InputType > &, bool = true); RealSchur< int > m_realSchur; }; + template < typename cq > template < typename InputType > EigenSolver< cq > &EigenSolver< cq >::compute(const ad< InputType > &matrix, bool computeEigenvectors) { m_realSchur.compute(matrix, computeEigenvectors); } + class PolynomialSolver { public: PolynomialSolver(ab< double, 0, 1 >) { ab< int, 0, 0 > __trans_tmp_1 = m_eigenSolver.compute(__trans_tmp_1); } EigenSolver< double > m_eigenSolver; }; + struct increment_if_fixed_size { enum { bi }; }; + template < int, typename, typename > void aux_evalSolver(ab< double, 0, 1 > pols) { PolynomialSolver solve_constr(pols); } + template < int Deg, typename > void evalSolver(ab< double, 0, 1 > pols) { aux_evalSolver< Deg, ab< double, 0, 1 >, PolynomialSolver >(pols); } + template < typename, int _Deg > void polynomialsolver(int) { ab< double, increment_if_fixed_size::bi, 1 > pols = 1; evalSolver< _Deg, ab< double, increment_if_fixed_size::bi, 1 > >(pols); } + void test_polynomialsolver() { polynomialsolver< double, 5 >(5); }