public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Georg-Johann Lay <avr@gjlay.de>
To: Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>,
	 gcc-patches@gcc.gnu.org
Cc: chertykov@gmail.com
Subject: Re: [patch,avr] Fix PR 65657 - read from __memx address space tramples arguments to function call
Date: Thu, 16 Apr 2015 09:02:00 -0000	[thread overview]
Message-ID: <552F7A8D.1080709@gjlay.de> (raw)
In-Reply-To: <20150416064347.GA31491@atmel.com>

Am 04/16/2015 um 08:43 AM schrieb Senthil Kumar Selvaraj:
> This patch fixes PR 65657.

The following artifact appears to be PR63633.

> When cfgexpand.c expands a function call, it first figures out the
> registers in which the arguments will go, followed by expansion of the
> arguments themselves (right to left). It later emits mov insns to set
> the precomputed registers with the expanded RTXes.
>
> If one of the arguments is a __memx char pointer dereference, the mov
> eventually expands to gen_xload<mode>_A (for certain cases), which
> clobbers R22, R21 and Z.  This causes problems if one of those
> clobbered registers was precomputed to hold another argument.
>
> In general, call expansion does not appear to take clobbers into account -
> when it checks for argument overlap, the RTX (args[i].value) is only a MEM
> in QImode for the memx deref - the clobber shows up when it eventually
> calls emit_move_insn, at which point, it is too late.
>
> This does not happen for a int pointer dereference - turns out that
> precompute_register_parameters does a copy_to_mode_reg if the
> cost of args[i].value is more than COSTS_N_INSNS(1) i.e., it creates a
> pseudo and later assigns the pseudo to the arg register. This is done
> before any moves to arg registers is done, so other arguments are not
> overwritten.
>
> Doing the same thing - providing a better cost estimate for a MEM rtx in
> the non-default address space, makes this problem go away, and that is
> what this patch does. Regression testing does not show any new failures.
>
> The fix does seem tangential to the core problem - not sure if there is
> a better way to fix this?
>
> If not, could someone commit this please? I don't have commit access.
>
> Regards
> Senthil
>
> gcc/ChangeLog
>
> 2015-04-16  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
>
> 	* config/avr/avr.c (avr_rtx_costs_1): Increase cost for
> 	MEM rtx in non-default address space.
>
> gcc/testsuite/ChangeLog
>
> 2015-04-16  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
>
> 	* gcc.target/avr/pr65657.c: New.
>
> diff --git gcc/config/avr/avr.c gcc/config/avr/avr.c
> index 68d5ddc..c9b8678 100644
> --- gcc/config/avr/avr.c
> +++ gcc/config/avr/avr.c
> @@ -9959,7 +9959,11 @@ avr_rtx_costs_1 (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED,
>         return true;
>
>       case MEM:
> -      *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
> +      /* MEM rtx with non-default address space is more
> +         expensive. Not expressing that results in reg
> +         clobber during expand (PR 65657). */
> +      *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
> +                  + (MEM_ADDR_SPACE(x) == ADDR_SPACE_RAM ? 0 : 5));
>         return true;

IMO costs should not be used to fix wrong code or ICEs.  Presumably the fix is 
similar to the one used by PR63633.

Johann

>       case NEG:
> diff --git gcc/testsuite/gcc.target/avr/pr65657.c gcc/testsuite/gcc.target/avr/pr65657.c
> new file mode 100644
> index 0000000..d908fe3
> --- /dev/null
> +++ gcc/testsuite/gcc.target/avr/pr65657.c
> @@ -0,0 +1,39 @@
> +/* { dg-do run } */
> +/* { dg-options "-Os" } */
> +
> +/* When cfgexpand expands the call to foo, it
> +   assigns registers R22:R23 to 0xABCD and R24
> +   to *x. Because x is a __memx address space
> +   pointer, the dereference results in an RTL
> +   insn that clobbers R22 among other
> +   registers (xload<mode>_A).
> +
> +   Call expansion does not take this into account
> +   and ends up clobbering R22 set previously to
> +   hold part of the second argument.
> +*/
> +
> +#include <stdlib.h>
> +
> +void __attribute__((noinline))
> +    __attribute__((noclone))
> +foo (char c, volatile unsigned int d)
> +{
> +    if (d != 0xABCD)
> +      abort();
> +    if (c != 'A')
> +        abort();
> +}
> +
> +void __attribute__((noinline))
> +    __attribute__((noclone))
> +readx(const char __memx *x)
> +{
> +    foo (*x, 0xABCD);
> +}
> +
> +const char __memx arr[] = { 'A' };
> +int main()
> +{
> +   readx (arr);
> +}
>

  reply	other threads:[~2015-04-16  9:02 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-16  6:42 Senthil Kumar Selvaraj
2015-04-16  9:02 ` Georg-Johann Lay [this message]
2015-04-16  9:26   ` Senthil Kumar Selvaraj
2015-04-16 16:47     ` Georg-Johann Lay
2015-04-16 16:49       ` Georg-Johann Lay
2015-04-16 16:55       ` Denis Chertykov
2015-04-17  7:45       ` Senthil Kumar Selvaraj
2015-04-17 11:34         ` Denis Chertykov
2015-04-23  7:02         ` Senthil Kumar Selvaraj

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=552F7A8D.1080709@gjlay.de \
    --to=avr@gjlay.de \
    --cc=chertykov@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=senthil_kumar.selvaraj@atmel.com \
    /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).