From: Alan Modra <amodra@gmail.com>
To: Segher Boessenkool <segher@kernel.crashing.org>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [RS6000] PR88614, output_operand: invalid %z value
Date: Sun, 20 Jan 2019 13:38:00 -0000 [thread overview]
Message-ID: <20190120133833.GF29797@bubble.grove.modra.org> (raw)
In-Reply-To: <20190118220213.GT14180@gate.crashing.org>
On Fri, Jan 18, 2019 at 04:02:14PM -0600, Segher Boessenkool wrote:
> Hi Alan,
>
> On Mon, Jan 07, 2019 at 09:29:18AM +1030, Alan Modra wrote:
> > The direct cause of this PR is the fact that tls_gdld_nomark didn't
> > handle indirect calls. Adding the missing support revealed that most
> > indirect calls were being optimised back to direct calls anyway, due
> > to tls_gdld_nomark not checking any of the parallel elements except
> > the first (plus the extra element that distinguishes this call from
> > normal calls). Just checking the number of elements is enough to
> > separate the indirect calls from direct for ABI_ELFv2 and ABI_AIX,
> > while checking for the LONG_CALL bit in the cookie works for ABI_V4.
> > Direct calls being substituted for indirect calls is not the only
> > unwanted substitution. See the tls_nomark_call comment. I also saw a
> > _GLOBAL_OFFSET_TABLE_ symbol_ref being substituted for the GOT reg,
> > hence the unspec_tls change.
>
> > Bootstrap and regression testing on powerpc64le-linux and
> > powerpc64-linux in progress. Note that the patch requires
> > https://gcc.gnu.org/ml/gcc-patches/2019-01/msg00252.html or the
> > earlier version for the attribute support.
>
> (Did you commit that yet?)
Yes, the prerequisite patches have been committed.
> > +;; Verify that elements of the tls_gdld_nomark call insn parallel past the
> > +;; second element (added to distinguish this call from normal calls) match
> > +;; the normal contours of a call insn. This is necessary to prevent
> > +;; substitutions we don't want, for example, an indirect call being
> > +;; optimised to a direct call, or (set (reg:r2) (unspec [] UNSPEC_TOCSLOT))
> > +;; being cleverly optimised to (set (reg:r2) (reg:r2)) because gcc
> > +;; "knows" that r2 hasn't changed from a previous call.
> > +(define_predicate "tls_nomark_call"
> > + (match_code "parallel")
> > +{
> > + int n = XVECLEN (op, 0);
> > + rtvec v = XVEC (op, 0);
> > + rtx set = RTVEC_ELT (v, 0);
> > + if (GET_CODE (set) != SET)
> > + return 0;
> > + rtx call = XEXP (set, 1);
> > + if (GET_CODE (call) != CALL)
> > + return 0;
> > + rtx mem = XEXP (call, 0);
> > + if (GET_CODE (mem) != MEM)
> > + return 0;
> > + rtx addr = XEXP (mem, 0);
> > + if (GET_CODE (addr) == SYMBOL_REF)
> > + {
> > + if (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_AIX)
> > + return (n == 3 && GET_CODE (RTVEC_ELT (v, 2)) == CLOBBER
> > + && REG_P (XEXP (RTVEC_ELT (v, 2), 0))
> > + && REGNO (XEXP (RTVEC_ELT (v, 2), 0)) == LR_REGNO);
> > + else if (DEFAULT_ABI == ABI_V4)
> > + return (n >= 4 && n <= 5 && GET_CODE (RTVEC_ELT (v, 2)) == USE
> > + && CONST_INT_P (XEXP (RTVEC_ELT (v, 2), 0))
> > + && (INTVAL (XEXP (RTVEC_ELT (v, 2), 0)) & CALL_LONG) == 0
> > + && (n == 4
> > + || (GET_CODE (RTVEC_ELT (v, 3)) == USE
> > + && REG_P (XEXP (RTVEC_ELT (v, 3), 0))))
> > + && GET_CODE (RTVEC_ELT (v, n - 1)) == CLOBBER
> > + && REG_P (XEXP (RTVEC_ELT (v, n - 1), 0))
> > + && REGNO (XEXP (RTVEC_ELT (v, n - 1), 0)) == LR_REGNO);
> > + else
> > + gcc_unreachable ();
> > + }
> > + else if (indirect_call_operand (addr, mode))
> > + {
> > + if (DEFAULT_ABI == ABI_ELFv2)
> > + return (n == 4 && GET_CODE (RTVEC_ELT (v, 2)) == SET
> > + && REG_P (XEXP (RTVEC_ELT (v, 2), 0))
> > + && REGNO (XEXP (RTVEC_ELT (v, 2), 0)) == TOC_REGNUM
> > + && GET_CODE (XEXP (RTVEC_ELT (v, 2), 1)) == UNSPEC
> > + && XINT (XEXP (RTVEC_ELT (v, 2), 1), 1) == UNSPEC_TOCSLOT
> > + && XVECLEN (XEXP (RTVEC_ELT (v, 2), 1), 0) == 1
> > + && CONST_INT_P (XVECEXP (XEXP (RTVEC_ELT (v, 2), 1), 0, 0))
> > + && GET_CODE (RTVEC_ELT (v, 3)) == CLOBBER
> > + && REG_P (XEXP (RTVEC_ELT (v, 3), 0))
> > + && REGNO (XEXP (RTVEC_ELT (v, 3), 0)) == LR_REGNO);
> > + else if (DEFAULT_ABI == ABI_AIX)
> > + return (n == 5 && GET_CODE (RTVEC_ELT (v, 2)) == USE
> > + && GET_CODE (XEXP (RTVEC_ELT (v, 2), 0)) == MEM
> > + && GET_CODE (RTVEC_ELT (v, 3)) == SET
> > + && REG_P (XEXP (RTVEC_ELT (v, 3), 0))
> > + && REGNO (XEXP (RTVEC_ELT (v, 3), 0)) == TOC_REGNUM
> > + && GET_CODE (XEXP (RTVEC_ELT (v, 3), 1)) == UNSPEC
> > + && XINT (XEXP (RTVEC_ELT (v, 3), 1), 1) == UNSPEC_TOCSLOT
> > + && XVECLEN (XEXP (RTVEC_ELT (v, 3), 1), 0) == 1
> > + && CONST_INT_P (XVECEXP (XEXP (RTVEC_ELT (v, 3), 1), 0, 0))
> > + && GET_CODE (RTVEC_ELT (v, 4)) == CLOBBER
> > + && REG_P (XEXP (RTVEC_ELT (v, 4), 0))
> > + && REGNO (XEXP (RTVEC_ELT (v, 4), 0)) == LR_REGNO);
> > + else if (DEFAULT_ABI == ABI_V4)
> > + return (n == 4 && GET_CODE (RTVEC_ELT (v, 2)) == USE
> > + && CONST_INT_P (XEXP (RTVEC_ELT (v, 2), 0))
> > + && GET_CODE (RTVEC_ELT (v, 3)) == CLOBBER
> > + && REG_P (XEXP (RTVEC_ELT (v, 3), 0))
> > + && REGNO (XEXP (RTVEC_ELT (v, 3), 0)) == LR_REGNO);
> > + else
> > + gcc_unreachable ();
> > + }
> > + else
> > + return 0;
> > +})
>
> I find things like this almost impossible to read (and to verify for
> correctness). Maybe you can factor it a bit more? Does it need to be a
> predicate at all, or can you handle it by having various patterns?
Hmm, if I invent a couple of new unspecs, UNSPEC_TLSGD_NOMARK and
UNSPEC_TLSLD_NOMARK, using them in place of UNSPEC_TLSGD and
UNSPEC_TLSLD when !TARGET_TLS_MARKERS then that should be enough to
tell when we have a -mno-tls-markers __tls_get_addr call. So I guess
I could kill off edit_tls_call_insn and tls_gdld_nomark. The
call_value_local and call_value_indirect insns would then need to
detect the special call and emit the arg setup insns.
--
Alan Modra
Australia Development Lab, IBM
next prev parent reply other threads:[~2019-01-20 13:38 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-06 22:59 Alan Modra
2019-01-18 22:02 ` Segher Boessenkool
2019-01-20 13:38 ` Alan Modra [this message]
2019-01-21 12:19 ` Alan Modra
2019-01-21 14:23 ` Segher Boessenkool
2019-01-22 0:30 ` Alan Modra
2019-01-22 0:35 ` Segher Boessenkool
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190120133833.GF29797@bubble.grove.modra.org \
--to=amodra@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=segher@kernel.crashing.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).