From 3c22703a4b865a421b8748240c854cd2f247e716 Mon Sep 17 00:00:00 2001 From: uros Date: Mon, 1 Aug 2011 17:13:30 +0000 Subject: [PATCH] PR target/49927 * config/i386/i386.c (ix86_address_subreg_operand): New. (ix86_decompose_address): Use ix86_address_subreg_operand. (ix86_legitimate_address_p): Do not assert that subregs satisfy register_no_elim_operand in DImode. testsuite/ChangeLog: PR target/49927 * gcc.target/i386/pr49927.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@177064 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 20 ++++++++++----- gcc/config/i386/i386.c | 43 ++++++++++++++++++++++----------- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.target/i386/pr49927.c | 11 +++++++++ 4 files changed, 59 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr49927.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1b5e6de..c3d1b3a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2011-08-01 Uros Bizjak + + PR target/49927 + * config/i386/i386.c (ix86_address_subreg_operand): New. + (ix86_decompose_address): Use ix86_address_subreg_operand. + (ix86_legitimate_address_p): Do not assert that subregs satisfy + register_no_elim_operand in DImode. + 2011-08-01 Ira Rosen PR tree-optimization/49926 @@ -5,7 +13,7 @@ in a chain doesn't have uses both inside and outside the loop. 2011-08-01 Georg-Johann Lay - + * config/avr/avr.h (mcu_type_s): Add errata_skip field. * config/avr/avr-devices.c (avr_mcu_types): Use it. * config/avr/avr-mcus.def (AVR_MCU): Use it. @@ -17,7 +25,8 @@ 2011-08-02 Alan Modra - * config/rs6000/rs6000-protos.h (rs6000_save_toc_in_prologue_p): Delete. + * config/rs6000/rs6000-protos.h (rs6000_save_toc_in_prologue_p): + Delete. * config/rs6000/rs6000.c (rs6000_save_toc_in_prologue_p): Make static. (rs6000_emit_prologue): Don't prematurely return when TARGET_SINGLE_PIC_BASE. Don't emit eh_frame info in @@ -40,13 +49,12 @@ 2011-08-01 Kirill Yukhin PR target/49547 - * config.gcc (i[34567]86-*-*): Replace abmintrin.h with - lzcntintrin.h. + * config.gcc (i[34567]86-*-*): Replace abmintrin.h with lzcntintrin.h. (x86_64-*-*): Likewise. * config/i386/i386.opt (mlzcnt): New. * config/i386/abmintrin.h: File removed. (__lzcnt_u16, __lzcnt, __lzcnt_u64): Moved to ... - * config/i386/lzcntintrin.h: ... here. New file. + * config/i386/lzcntintrin.h: ... here. New file. (__lzcnt): Rename to ... (__lzcnt32): ... this. * config/i386/bmiintrin.h (head): Update copyright year. @@ -183,10 +191,10 @@ (*rep_stosdi_rex64): Disable when %eax, %ecx or %edi are fixed. (*rep_stossi): Ditto. (*rep_stosqi): Ditto. + (*strlenqi_1): Ditto. (cmpstrnsi): Also fail when %ecx is fixed. (*cmpstrnqi_nz_1): Disable when %ecx, %esi or %edi are fixed. (*cmpstrnqi_1): Ditto. - (*strlenqi_1): Ditto. (*strmovdi_rex_1): Disable when %esi or %edi are fixed. (*strmovsi_1): Ditto. (*strmovhi_1): Ditto. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index c8ea48f..0e4f3f4 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -11096,6 +11096,30 @@ ix86_live_on_entry (bitmap regs) } } +/* Determine if op is suitable SUBREG RTX for address. */ + +static bool +ix86_address_subreg_operand (rtx op) +{ + enum machine_mode mode; + + if (!REG_P (op)) + return false; + + mode = GET_MODE (op); + + if (GET_MODE_CLASS (mode) != MODE_INT) + return false; + + /* Don't allow SUBREGs that span more than a word. It can lead to spill + failures when the register is one word out of a two word structure. */ + if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) + return false; + + /* Allow only SUBREGs of non-eliminable hard registers. */ + return register_no_elim_operand (op, mode); +} + /* Extract the parts of an RTL expression that is a valid memory address for an instruction. Return 0 if the structure of the address is grossly off. Return -1 if the address contains ASHIFT, so it is not @@ -11116,8 +11140,7 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) base = addr; else if (GET_CODE (addr) == SUBREG) { - /* Allow only subregs of DImode hard regs. */ - if (register_no_elim_operand (SUBREG_REG (addr), DImode)) + if (ix86_address_subreg_operand (SUBREG_REG (addr))) base = addr; else return 0; @@ -11175,8 +11198,7 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) break; case SUBREG: - /* Allow only subregs of DImode hard regs in PLUS chains. */ - if (!register_no_elim_operand (SUBREG_REG (op), DImode)) + if (!ix86_address_subreg_operand (SUBREG_REG (op))) return 0; /* FALLTHRU */ @@ -11228,9 +11250,8 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) { if (REG_P (index)) ; - /* Allow only subregs of DImode hard regs. */ else if (GET_CODE (index) == SUBREG - && register_no_elim_operand (SUBREG_REG (index), DImode)) + && ix86_address_subreg_operand (SUBREG_REG (index))) ; else return 0; @@ -11677,10 +11698,7 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, if (REG_P (base)) reg = base; else if (GET_CODE (base) == SUBREG && REG_P (SUBREG_REG (base))) - { - reg = SUBREG_REG (base); - gcc_assert (register_no_elim_operand (reg, DImode)); - } + reg = SUBREG_REG (base); else /* Base is not a register. */ return false; @@ -11702,10 +11720,7 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, if (REG_P (index)) reg = index; else if (GET_CODE (index) == SUBREG && REG_P (SUBREG_REG (index))) - { - reg = SUBREG_REG (index); - gcc_assert (register_no_elim_operand (reg, DImode)); - } + reg = SUBREG_REG (index); else /* Index is not a register. */ return false; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b1a3122..7a5d30f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-08-01 Uros Bizjak + + PR target/49927 + * gcc.target/i386/pr49927.c: New test. + 2011-08-01 Ira Rosen PR tree-optimization/49926 diff --git a/gcc/testsuite/gcc.target/i386/pr49927.c b/gcc/testsuite/gcc.target/i386/pr49927.c new file mode 100644 index 0000000..5850597 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr49927.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +char a[1][1]; +long long b; + +void +foo (void) +{ + --a[b][b]; +} -- 2.7.4