On Thu, 3 Jan 2013, Martin Jambor wrote:

> Hi,
> 
> the patch below fixes PR 55755 which was in the compiler for years.
> The problem is that a replacement of a bit-field can have a larger
> TYPE_SIZE than the type of the field and so creating a V_C_E from it
> to the field type may result in invalid gimple.  We do that when we
> scalarize only one side of an assignment and get incompatible types on
> both sides and the other (non-scalar) side has a child access in the
> access tree (regardless if it is to be scalarize or not).
> 
> When looking at the issue I realized that the last condition is
> completely unnecessary (at least now, the first concepts of the "new"
> SRA were a bit different) because the subsequent handling of
> sub-replacements will do the right thing (load/store them to the
> original aggregate) and removing it is indeed the correct thing to
> deal with this bug - if both sides are scalarized, size of both will
> grow to mode size, if only one, we can avoid the V_C_E.  I am a little
> worried about the contains_bitfld_comp_ref_p and
> contains_vce_or_bfcref_p gurads which are there because of Ada PR
> 46349 (which involves aggregate bit-fields) and which might in theory
> lead to the same problem but I'm weary of touching it, at least not in
> one commit (I'm testing what happens if I remove them right now), and
> this patch does not make the current situation any worse.
> 
> In order to make sure we do not mess up when the non-scalar side has
> sub-replacements in it, I have added a new testcase.
> 
> The patch has passed bootstrap and testing on x86_64-linux on trunk
> and the 4.7 and 4.6 branches.  I'd like to commit it to all of them,
> perhaps after having it on trunk only for a while.

Ok for trunk and branches after a while.

Thanks,
Richard.

> Thanks,
> 
> Martin
> 
> 
> 2013-01-02  Martin Jambor  <mjam...@suse.cz>
> 
>       PR tree-optimization/55755
>       * tree-sra.c (sra_modify_assign): Do not check that an access has no
>       children when trying to avoid producing a VIEW_CONVERT_EXPR.
> 
> testsuite/
>       * gcc.dg/torture/pr55755.c: New test.
>       * gcc.dg/tree-ssa/sra-13.c: Likewise.
>       * gcc.dg/tree-ssa/pr45144.c: Update.
> 
> Index: src/gcc/testsuite/gcc.dg/torture/pr55755.c
> ===================================================================
> --- /dev/null
> +++ src/gcc/testsuite/gcc.dg/torture/pr55755.c
> @@ -0,0 +1,43 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target int32plus } */
> +
> +struct S4
> +{
> +  unsigned f0:24;
> +} __attribute__((__packed__));
> +
> +struct S4 g_10 = {
> +  6210831
> +};
> +
> +struct S5
> +{
> +  int i;
> +  struct S4 l_8[2];
> +}  __attribute__((__packed__));
> +
> +int a, b;
> +
> +struct S4 func_2 (int x)
> +{
> +  struct S5 l = {
> +    0,
> +    {{0}, {0}}
> +  };
> +  l.i = a;
> +  g_10 = l.l_8[1];
> +  for (; x<2; x++) {
> +    struct S4 tmp = {
> +      11936567
> +    };
> +    l.l_8[x] = tmp;
> +  }
> +  b = l.i;
> +  return g_10;
> +}
> +
> +int main (void)
> +{
> +  func_2 (0);
> +  return 0;
> +}
> Index: src/gcc/testsuite/gcc.dg/tree-ssa/sra-13.c
> ===================================================================
> --- /dev/null
> +++ src/gcc/testsuite/gcc.dg/tree-ssa/sra-13.c
> @@ -0,0 +1,114 @@
> +/* Test that SRA replacement can deal with assignments that have
> +   sub-replacements on one side and a single scalar replacement on another.  
> */
> +/* { dg-do run } */
> +/* { dg-options "-O1" } */
> +
> +struct A
> +{
> +  int i1, i2;
> +};
> +
> +struct B
> +{
> +  long long int l;
> +};
> +
> +union U
> +{
> +  struct A a;
> +  struct B b;
> +};
> +
> +int b, gi;
> +long gl;
> +union U gu1, gu2;
> +
> +int __attribute__ ((noinline, noclone))
> +foo (void)
> +{
> +  union U x, y;
> +  int r;
> +
> +  y = gu1;
> +  if (b)
> +    y.b.l = gl;
> +
> +  x = y;
> +
> +  if (!b)
> +    r = x.a.i1;
> +  else
> +    r = 0;
> +
> +  gu2 = x;
> +  return r;
> +}
> +
> +long long int __attribute__ ((noinline, noclone))
> +bar (void)
> +{
> +  union U x, y;
> +  int r;
> +
> +  y = gu1;
> +  if (b)
> +    y.a.i1 = gi;
> +
> +  x = y;
> +
> +  if (!b)
> +    r = x.b.l;
> +  else
> +    r = 0;
> +
> +  gu2 = x;
> +  return r;
> +}
> +
> +
> +int
> +main (void)
> +{
> +  int r;
> +  long long int s;
> +
> +  b = 0;
> +  gu1.a.i1 = 123;
> +  gu1.a.i2 = 234;
> +  r = foo ();
> +  if (r != 123)
> +    __builtin_abort ();
> +  if (gu2.a.i1 != 123)
> +    __builtin_abort ();
> +  if (gu2.a.i2 != 234)
> +    __builtin_abort ();
> +
> +  b = 1;
> +  gl = 10000001;
> +  gu1.b.l = 10000000;
> +  r = foo ();
> +  if (r != 0)
> +    __builtin_abort ();
> +  if (gu2.b.l != 10000001)
> +    __builtin_abort ();
> +
> +  b = 0;
> +  gu1.b.l = 20000000;
> +  s = bar ();
> +  if (s != 20000000)
> +    __builtin_abort ();
> +  if (gu2.b.l != 20000000)
> +    __builtin_abort ();
> +
> +  b = 1;
> +  gi = 456;
> +  gu1.a.i1 = 123;
> +  gu1.a.i2 = 234;
> +  s = bar ();
> +  if (s != 0)
> +    __builtin_abort ();
> +  if (gu2.a.i1 != 456)
> +    __builtin_abort ();
> +
> +  return 0;
> +}
> Index: src/gcc/tree-sra.c
> ===================================================================
> --- src.orig/gcc/tree-sra.c
> +++ src/gcc/tree-sra.c
> @@ -3087,15 +3087,13 @@ sra_modify_assign (gimple *stmt, gimple_
>            ???  This should move to fold_stmt which we simply should
>            call after building a VIEW_CONVERT_EXPR here.  */
>         if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
> -           && !contains_bitfld_comp_ref_p (lhs)
> -           && !access_has_children_p (lacc))
> +           && !contains_bitfld_comp_ref_p (lhs))
>           {
>             lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
>             gimple_assign_set_lhs (*stmt, lhs);
>           }
>         else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
> -                && !contains_vce_or_bfcref_p (rhs)
> -                && !access_has_children_p (racc))
> +                && !contains_vce_or_bfcref_p (rhs))
>           rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
>  
>         if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
> Index: src/gcc/testsuite/gcc.dg/tree-ssa/pr45144.c
> ===================================================================
> --- src.orig/gcc/testsuite/gcc.dg/tree-ssa/pr45144.c
> +++ src/gcc/testsuite/gcc.dg/tree-ssa/pr45144.c
> @@ -43,5 +43,5 @@ bar (unsigned orig, unsigned *new)
>    *new = foo (&a);
>  }
>  
> -/* { dg-final { scan-tree-dump " = VIEW_CONVERT_EXPR<unsigned int>\\(a\\);" 
> "optimized"} } */
> +/* { dg-final { scan-tree-dump-not "unnamed-unsigned:19" "optimized"} } */
>  /* { dg-final { cleanup-tree-dump "optimized" } } */
> 
> 

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