On Fri, 11 Jan 2013, Richard Biener wrote:

> On Thu, 10 Jan 2013, Eric Botcazou wrote:
> 
> > > The problem with this intermediate inconsistency is that ...
> > > 
> > > > That's why only the final result should matter and need be correct.
> > > 
> > > ... this can't be ensured anymore.  In some cases the inconsistency
> > > between the mem attributes and what XEXP(MEM, 0) represents can't be
> > > repaired by the later bitpos adjustments, or better it can be only be
> > > repaired by falling back to the conservative side for e.g. the alignment,
> > > because we don't store enough information in the mem attributes to recover
> > > what was lost.
> > 
> > Indeed, looking at the history of the code shows that the alignment 
> > handling 
> > via MEM_REF and get_object_alignment is an afterthought.  Originally, it 
> > was 
> > set only in a few specific cases:
> > 
> >   /* We can set the alignment from the type if we are making an object,
> >      this is an INDIRECT_REF, or if TYPE_ALIGN_OK.  */
> > 
> > and also for DECL_P and CONSTANT_CLASS_P.  That was it, so this was 
> > actually 
> > the alignment of the base and disregarding BITPOS was fine.
> 
> Yes, in these cases bitpos is zero.  It's wrong in the !align_computed
> path and possibly in the ARRAY_REF -> DECL_P path (only not as
> optimistic as it could be).
> 
> > > When briefly discussing this yesterday I suggested (without having the
> > > code in front of me) that it be best to simply set the mem attributes only
> > > at the very end, after having computed to final MEM address including all
> > > adjustments, instead of generating wrong mem attributes initially and
> > > hoping for the adjustments to make it come out right at the end.
> > 
> > Maybe, but for 4.7 (and probably 4.8) I think we should be conservative and 
> > only fix the problems recently introduced.
> > 
> > So, in the end, I think that we should go either for Richard's initial 
> > patch 
> > in this thread, possibly with a ??? comment along the lines of:
> > 
> >     /* ??? If we haven't computed the alignment yet, compute it now.  Note
> >         that, if already computed above, the alignment is that of the base
> >         object of T so it is OK to have disregarded BITPOS above.  However,
> >         here we are using get_object_alignment_1 which returns the precise
> >         alignment of T so we need to account for the BITPOS adjustment.  */
> >     if (!align_computed)
> > 
> > or for Richard's initial patch + the removal of the MEM_REF block (which is 
> > midway between Richard's initial patch and Richard's last patch).
> 
> Thus I'm preparing a patch that applies to both 4.7 and 4.8 at this
> point, leaving some holes I see open (which are not to be closed in
> the same way due to differences in behavior of get_object_alignment
> on the 4.7 branch vs. trunk).
> 
> Bootstrap and regtest on x86_64-unknown-linux-gnu running, Eric,
> can you give this a strict-align target testing on the 4.7 branch?
> Martin, can you re-test this on sparc (it's slightly different again)?
> 
> I'm going to remove the MEM_REF block as a followup (we can't backport
> that due to pessimizations this will cause due to different
> get_object_alignment behavior - yet, unless we backport that change
> as well), it's a source of wrong alignment as well, due to the
> usage of MAX () - the get_object_alignment result will never shrink
> alignment this way (and thus implicitely relies on attrs.align
> being BITS_PER_UNIT when !align_computed).
> 
> The get_object_alignment behavior change is
> 
> 2012-07-18  Richard Guenther  <rguent...@suse.de>
> 
>         * tree.h (get_object_or_type_alignment): Remove.
>         * builtins.c (get_object_alignment_2): New function copied from
>         get_object_alignment_1.  Take extra argument to indicate whether
>         we take the address of EXP.  Rework to use type alignment 
> information
>         if not, and return whether the result is an approximation or not.
>         (get_object_alignment_1): Wrap around get_object_alignment_2.
>         (get_pointer_alignment_1): Call get_object_alignment_2 indicating
>         we take the address.
>         (get_object_or_type_alignment): Remove.
>         * expr.c (expand_assignment): Call get_object_alignment.
>         (expand_expr_real_1): Likewise.
> 
> and followups.

I have applied the minimal fix to trunk now.  We retain the clearly
incorrect fact that the !align_computed path only ever increases
alignment (it's only ever set previously to either BITS_PER_UNIT
or via the MEM_REF block).  I will momentarily test a followup
removing that block for trunk.

Thanks,
Richard.

> Thanks,
> Richard.
> 
> 2013-01-11  Richard Biener  <rguent...@suse.de>
> 
>       PR middle-end/55882
>       * emit-rtl.c (set_mem_attributes_minus_bitpos): Correctly
>       account for bitpos when computing alignment.
> 
>       * gcc.dg/torture/pr55882.c: New testcase.
> 
> Index: gcc/emit-rtl.c
> ===================================================================
> *** gcc/emit-rtl.c    (revision 195102)
> --- gcc/emit-rtl.c    (working copy)
> *************** set_mem_attributes_minus_bitpos (rtx ref
> *** 1839,1845 ****
>   
>         if (!align_computed)
>       {
> !       unsigned int obj_align = get_object_alignment (t);
>         attrs.align = MAX (attrs.align, obj_align);
>       }
>       }
> --- 1839,1850 ----
>   
>         if (!align_computed)
>       {
> !       unsigned int obj_align;
> !       unsigned HOST_WIDE_INT obj_bitpos;
> !       get_object_alignment_1 (t, &obj_align, &obj_bitpos);
> !       obj_bitpos = (obj_bitpos - bitpos) & (obj_align - 1);
> !       if (obj_bitpos != 0)
> !         obj_align = (obj_bitpos & -obj_bitpos);
>         attrs.align = MAX (attrs.align, obj_align);
>       }
>       }
> Index: gcc/testsuite/gcc.dg/torture/pr55882.c
> ===================================================================
> *** gcc/testsuite/gcc.dg/torture/pr55882.c    (revision 0)
> --- gcc/testsuite/gcc.dg/torture/pr55882.c    (working copy)
> ***************
> *** 0 ****
> --- 1,94 ----
> + /* { dg-do run } */
> + 
> + typedef enum
> + {
> +   PVT_A = 0,
> +   PVT_B = 1,
> +   PVT_CONFIG = 2,
> +   PVT_RESERVED3 = 3,
> + } T_CR_SELECT;
> + 
> + typedef enum
> + {
> +   STD_ULOGIC_0 = 0,
> +   STD_ULOGIC_1 = 1,
> + } STD_ULOGIC;
> + 
> + typedef struct
> + {
> +   unsigned char rtp : 3;
> +   unsigned char rtn : 3;
> + } C;
> + 
> + typedef struct
> + {
> +   unsigned char nd;
> +   unsigned char pd;
> +   unsigned char rtn;
> +   unsigned char rtp;
> + } A;
> + 
> + typedef struct
> + {
> +   unsigned short reserved : 14;
> +   unsigned char Z_rx_enable : 2;
> +   A pvt;
> + } B;
> + 
> + typedef struct
> + {
> +   B cr_dsclk_q3;
> +   B cr_data_q3;
> +   B cr_addr_q3;
> +   B cr_cmd_q3;
> +   B cr_pres_q3;
> +   C cr_vref_q3[6];
> +   unsigned char pres_disable;
> +   unsigned char pres_drive_high;
> +   unsigned char c_enab_120;
> +   STD_ULOGIC clk_tximp;
> +   STD_ULOGIC dqs_tximp;
> +   STD_ULOGIC cmd_tximp;
> +   STD_ULOGIC data_tximp;
> +   STD_ULOGIC dqs_rxterm;
> +   STD_ULOGIC data_rxterm;
> +   T_CR_SELECT cr_clk_sel;
> +   unsigned char cr_clk : 5;
> +   T_CR_SELECT cr_dsclk_odd_sel;
> +   unsigned char cr_dsclk_odd : 5;
> +   T_CR_SELECT cr_dsclk_even_sel;
> +   unsigned char cr_dsclk_even : 5;
> +   T_CR_SELECT cr_data_sel;
> +   unsigned char cr_data : 5;
> +   T_CR_SELECT cr_vref_sel;
> +   unsigned char cr_vref : 5;
> +   T_CR_SELECT cr_others_sel;
> +   unsigned char cr_others : 5;
> + } CONFIG;
> + 
> + typedef struct
> + {
> +   unsigned char enable_monitor;
> +   unsigned short step_out_pointer : 12;
> +   unsigned short hold_out_pointer : 12;
> +   unsigned short enable_wr_dqs : 12;
> +   unsigned short use_alt_rd_dqs : 12;
> +   CONFIG io_buf;
> + } mystruct;
> + 
> + unsigned short __attribute__((noinline,noclone))
> + testfunction(unsigned i)
> + {
> +   mystruct dmfe[8];
> +   dmfe[0].use_alt_rd_dqs = 1;
> +   dmfe[i].use_alt_rd_dqs = 0;
> +   return dmfe[0].use_alt_rd_dqs;
> + }
> + 
> + extern void abort (void);
> + int main ()
> + {
> +   if (testfunction(0) != 0) 
> +     abort ();
> +   return 0;
> + }
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend

Reply via email to