public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Segher Boessenkool <segher@kernel.crashing.org>
To: Alan Modra <amodra@gmail.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [RS6000] PR88614, output_operand: invalid %z value
Date: Fri, 18 Jan 2019 22:02:00 -0000	[thread overview]
Message-ID: <20190118220213.GT14180@gate.crashing.org> (raw)
In-Reply-To: <20190106225918.GG3170@bubble.grove.modra.org>

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?)

> +;; 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?

> +     (plus (if_then_else (match_test "TARGET_CMODEL != CMODEL_SMALL")
> +			 (const_int 8)
> +			 (const_int 4))
> +	   (plus (if_then_else (match_test "GET_CODE (operands[1]) != SYMBOL_REF")
> +			       (plus (if_then_else (match_test "!rs6000_speculate_indirect_jumps")
> +						   (const_int 4)
> +						   (const_int 0))
> +				     (if_then_else (match_test "DEFAULT_ABI == ABI_AIX")
> +						   (const_int 4)
> +						   (const_int 0)))
> +			       (const_int 0))
> +		 (if_then_else (match_test "DEFAULT_ABI != ABI_V4")
> +			       (const_int 8)
> +			       (const_int 4)))))])

This part is way too wide.  Maybe it is would be readable if not :-(


Segher

  reply	other threads:[~2019-01-18 22:02 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 [this message]
2019-01-20 13:38   ` Alan Modra
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=20190118220213.GT14180@gate.crashing.org \
    --to=segher@kernel.crashing.org \
    --cc=amodra@gmail.com \
    --cc=gcc-patches@gcc.gnu.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).