From 77c42bd4fb63e73366c6532e30a9e8131debdde5 Mon Sep 17 00:00:00 2001 From: uros Date: Tue, 27 Mar 2012 15:36:34 +0000 Subject: [PATCH] PR target/52698 * config/i386/i386-protos.h (ix86_legitimize_reload_address): New prototype. * config/i386/i386.h (LEGITIMIZE_RELOAD_ADDRESS): New define. * config/i386/i386.c: Include reload.h. (ix86_legitimize_reload_address): New function. testsuite/ChangeLog: PR target/52698 * gcc.target/i386/pr52698.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@185883 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 12 +++++-- gcc/config/i386/i386-protos.h | 3 +- gcc/config/i386/i386.c | 59 +++++++++++++++++++++++++++++++++ gcc/config/i386/i386.h | 11 ++++++ gcc/testsuite/ChangeLog | 6 ++++ gcc/testsuite/gcc.target/i386/pr52698.c | 18 ++++++++++ 6 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr52698.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b7736fb..6cc1653 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,9 +1,17 @@ +2012-03-27 Uros Bizjak + + PR target/52698 + * config/i386/i386-protos.h (ix86_legitimize_reload_address): + New prototype. + * config/i386/i386.h (LEGITIMIZE_RELOAD_ADDRESS): New define. + * config/i386/i386.c: Include reload.h. + (ix86_legitimize_reload_address): New function. + 2012-03-27 H.J. Lu * opth-gen.awk: Allocated a bit for Mask and InverseMask if it hasn't been allocated. Define a target macro for Mask and - InverseMask if it hasn't been defined. Remove MaskExists - handling. + InverseMask if it hasn't been defined. Remove MaskExists handling. * doc/options.texi: Remove MaskNeeded. diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 630112f..f300a56 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -65,7 +65,8 @@ extern bool ix86_expand_strlen (rtx, rtx, rtx, rtx); extern bool constant_address_p (rtx); extern bool legitimate_pic_operand_p (rtx); extern bool legitimate_pic_address_disp_p (rtx); - +extern bool ix86_legitimize_reload_address (rtx, enum machine_mode, + int, int, int); extern void print_reg (rtx, int, FILE*); extern void ix86_print_operand (FILE *, rtx, int); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index a21f2da..18172a1 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see #include "target-def.h" #include "common/common-target.h" #include "langhooks.h" +#include "reload.h" #include "cgraph.h" #include "gimple.h" #include "dwarf2.h" @@ -12010,6 +12011,64 @@ legitimate_pic_address_disp_p (rtx disp) return false; } +/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to + replace the input X, or the original X if no replacement is called for. + The output parameter *WIN is 1 if the calling macro should goto WIN, + 0 if it should not. */ + +bool +ix86_legitimize_reload_address (rtx x, + enum machine_mode mode ATTRIBUTE_UNUSED, + int opnum, int type, + int ind_levels ATTRIBUTE_UNUSED) +{ + /* Reload can generate: + + (plus:DI (plus:DI (unspec:DI [(const_int 0 [0])] UNSPEC_TP) + (reg:DI 97)) + (reg:DI 2 cx)) + + This RTX is rejected from ix86_legitimate_address_p due to + non-strictness of base register 97. Following this rejection, + reload pushes all three components into separate registers, + creating invalid memory address RTX. + + Following code reloads only the invalid part of the + memory address RTX. */ + + if (GET_CODE (x) == PLUS + && REG_P (XEXP (x, 1)) + && GET_CODE (XEXP (x, 0)) == PLUS + && REG_P (XEXP (XEXP (x, 0), 1))) + { + rtx base, index; + bool something_reloaded = false; + + base = XEXP (XEXP (x, 0), 1); + if (!REG_OK_FOR_BASE_STRICT_P (base)) + { + push_reload (base, NULL_RTX, &XEXP (XEXP (x, 0), 1), NULL, + BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0, + opnum, (enum reload_type) type); + something_reloaded = true; + } + + index = XEXP (x, 1); + if (!REG_OK_FOR_INDEX_STRICT_P (index)) + { + push_reload (index, NULL_RTX, &XEXP (x, 1), NULL, + INDEX_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0, + opnum, (enum reload_type) type); + something_reloaded = true; + } + + gcc_assert (something_reloaded); + return true; + } + + return false; +} + /* Recognizes RTL expressions that are valid memory addresses for an instruction. The MODE argument is the machine mode for the MEM expression that wants to use this address. diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 3fcd209..a53c70a 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1630,6 +1630,17 @@ typedef struct ix86_args { #define CONSTANT_ADDRESS_P(X) constant_address_p (X) +/* Try a machine-dependent way of reloading an illegitimate address + operand. If we find one, push the reload and jump to WIN. This + macro is used in only one place: `find_reloads_address' in reload.c. */ + +#define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, INDL, WIN) \ +do { \ + if (ix86_legitimize_reload_address ((X), (MODE), (OPNUM), \ + (int)(TYPE), (INDL))) \ + goto WIN; \ +} while (0) + /* If defined, a C expression to determine the base term of address X. This macro is used in only one place: `find_base_term' in alias.c. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 408184a..a9f0bc8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-03-27 Uros Bizjak + H.J. Lu + + PR target/52698 + * gcc.target/i386/pr52698.c: New test. + 2012-03-27 Richard Guenther PR middle-end/52720 diff --git a/gcc/testsuite/gcc.target/i386/pr52698.c b/gcc/testsuite/gcc.target/i386/pr52698.c new file mode 100644 index 0000000..d84685c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr52698.c @@ -0,0 +1,18 @@ +/* { dg-do compile { target { ! { ia32 } } } } */ +/* { dg-options "-O2 -mx32 -maddress-mode=long" } */ + +extern void abort (void); +static __thread unsigned char foo [32] +__attribute__ ((tls_model ("initial-exec"), aligned (sizeof (void *)))); + +void +test2 (void) +{ + unsigned int s; + for (s = 0; s < sizeof (foo); ++s) + { + if (foo [s] != s) + abort (); + foo [s] = sizeof (foo) - s; + } +} -- 2.7.4