On Fri, 7 Feb 2014, Jakub Jelinek wrote:

> On Fri, Feb 07, 2014 at 10:02:29AM +0100, Richard Biener wrote:
> > > +  if (TREE_CODE (position) != INTEGER_CST
> > > +      || TREE_INT_CST_HIGH (position)
> > > +      || TREE_INT_CST_LOW (position) < 1
> > > +      || TREE_INT_CST_LOW (position) > arg_count)
> > 
> > You make it easier for wide-int folks if you use tree_fits_uhwi_p
> > and tree_to_uhwi ...
> 
> That was just a copy of the code from alloc_size, changed that too.
> 
> > > +static prop_value_t
> > > +bit_value_alloc_assume_aligned_attribute (gimple stmt, tree attr,
> > > +                                   prop_value_t ptrval,
> > > +                                   bool alloc_aligned)
> > > +{
> > 
> > This function is very similar to the existing bit_value_assume_aligned
> > which asks for some factoring?  Like share the tails once you've
> > figured out align and misalign values?
> 
> I've added support for the two attributes and original
> __builtin_assume_aligned in just one function, will test it momentarily.
> 
> > I wonder if we want to backport support for these attributes
> > to 4.8 (and 4.7?).
> 
> I think it doesn't help much.  At least glibc will need to conditionalize
> the attributes on gcc version anyway, so they will be used only for GCC >=
> 4.9 anyway (unless we'd do it for >= 4.8.4 or something, can't be 4.8.3,
> because, while it hasn't been released, current 4.8 branch snapshot mark
> themselves as 4.8.3 in the patchlevel).

Ah, indeed.  Didn't think about the snapshots...

> > Will you be working on a glibc patch?
> 
> I'll tell our glibc folks.

Thanks.  Updated patch looks ok.

Richard.

> 2014-02-07  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR middle-end/60092
>       * tree-ssa-ccp.c (surely_varying_stmt_p): Don't return true
>       if TYPE_ATTRIBUTES (gimple_call_fntype ()) contain
>       assume_aligned or alloc_align attributes.
>       (bit_value_assume_aligned): Add ATTR, PTRVAL and ALLOC_ALIGN
>       arguments.  Handle also assume_aligned and alloc_align attributes.
>       (evaluate_stmt): Adjust bit_value_assume_aligned caller.
>       Handle calls to functions with assume_aligned or alloc_align
>       attributes.
>       * doc/extend.texi: Document assume_aligned and alloc_align
>       attributes.
> c-family/
>       * c-common.c (handle_alloc_size_attribute): Use tree_fits_uhwi_p
>       and tree_to_uhwi.
>       (handle_alloc_align_attribute, handle_assume_aligned_attribute): New
>       functions.
>       (c_common_attribute_table): Add alloc_align and assume_aligned
>       attributes.
> testsuite/
>       * gcc.dg/attr-alloc_align-1.c: New test.
>       * gcc.dg/attr-alloc_align-2.c: New test.
>       * gcc.dg/attr-alloc_align-3.c: New test.
>       * gcc.dg/attr-assume_aligned-1.c: New test.
>       * gcc.dg/attr-assume_aligned-2.c: New test.
>       * gcc.dg/attr-assume_aligned-3.c: New test.
> 
> --- gcc/c-family/c-common.c.jj        2014-02-07 11:44:07.114924852 +0100
> +++ gcc/c-family/c-common.c   2014-02-07 11:58:23.996841044 +0100
> @@ -366,6 +366,8 @@ static tree handle_warn_unused_result_at
>  static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
>  static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
>  static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
> +static tree handle_alloc_align_attribute (tree *, tree, tree, int, bool *);
> +static tree handle_assume_aligned_attribute (tree *, tree, tree, int, bool 
> *);
>  static tree handle_target_attribute (tree *, tree, tree, int, bool *);
>  static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
>  static tree ignore_attribute (tree *, tree, tree, int, bool *);
> @@ -766,6 +768,10 @@ const struct attribute_spec c_common_att
>                             handle_omp_declare_simd_attribute, false },
>    { "omp declare target",     0, 0, true, false, false,
>                             handle_omp_declare_target_attribute, false },
> +  { "alloc_align",         1, 1, false, true, true,
> +                           handle_alloc_align_attribute, false },
> +  { "assume_aligned",              1, 2, false, true, true,
> +                           handle_assume_aligned_attribute, false },
>    { NULL,                     0, 0, false, false, false, NULL, false }
>  };
>  
> @@ -8043,16 +8049,62 @@ handle_alloc_size_attribute (tree *node,
>         && TREE_CODE (position) != FUNCTION_DECL)
>       position = default_conversion (position);
>  
> -      if (TREE_CODE (position) != INTEGER_CST
> -       || TREE_INT_CST_HIGH (position)
> -       || TREE_INT_CST_LOW (position) < 1
> -       || TREE_INT_CST_LOW (position) > arg_count )
> +      if (tree_fits_uhwi_p (position)
> +       || !IN_RANGE (tree_to_uhwi (position), 1, arg_count))
>       {
>         warning (OPT_Wattributes,
>                  "alloc_size parameter outside range");
>         *no_add_attrs = true;
>         return NULL_TREE;
>       }
> +    }
> +  return NULL_TREE;
> +}
> +
> +/* Handle a "alloc_align" attribute; arguments as in
> +   struct attribute_spec.handler.  */
> +
> +static tree
> +handle_alloc_align_attribute (tree *node, tree, tree args, int,
> +                           bool *no_add_attrs)
> +{
> +  unsigned arg_count = type_num_arguments (*node);
> +  tree position = TREE_VALUE (args);
> +  if (position && TREE_CODE (position) != IDENTIFIER_NODE)
> +    position = default_conversion (position);
> +
> +  if (tree_fits_uhwi_p (position)
> +      || !IN_RANGE (tree_to_uhwi (position), 1, arg_count))
> +    {
> +      warning (OPT_Wattributes,
> +            "alloc_align parameter outside range");
> +      *no_add_attrs = true;
> +      return NULL_TREE;
> +    }
> +  return NULL_TREE;
> +}
> +
> +/* Handle a "assume_aligned" attribute; arguments as in
> +   struct attribute_spec.handler.  */
> +
> +static tree
> +handle_assume_aligned_attribute (tree *, tree, tree args, int,
> +                              bool *no_add_attrs)
> +{
> +  for (; args; args = TREE_CHAIN (args))
> +    {
> +      tree position = TREE_VALUE (args);
> +      if (position && TREE_CODE (position) != IDENTIFIER_NODE
> +       && TREE_CODE (position) != FUNCTION_DECL)
> +     position = default_conversion (position);
> +
> +      if (TREE_CODE (position) != INTEGER_CST)
> +     {
> +       warning (OPT_Wattributes,
> +                "assume_aligned parameter not integer constant");
> +       *no_add_attrs = true;
> +       return NULL_TREE;
> +     }
>      }
>    return NULL_TREE;
>  }
> --- gcc/tree-ssa-ccp.c.jj     2014-02-07 11:46:16.296610648 +0100
> +++ gcc/tree-ssa-ccp.c        2014-02-07 12:09:57.705818787 +0100
> @@ -738,13 +738,18 @@ surely_varying_stmt_p (gimple stmt)
>      return true;
>  
>    /* If it is a call and does not return a value or is not a
> -     builtin and not an indirect call, it is varying.  */
> +     builtin and not an indirect call or a call to function with
> +     assume_aligned/alloc_align attribute, it is varying.  */
>    if (is_gimple_call (stmt))
>      {
> -      tree fndecl;
> +      tree fndecl, fntype = gimple_call_fntype (stmt);
>        if (!gimple_call_lhs (stmt)
>         || ((fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
> -           && !DECL_BUILT_IN (fndecl)))
> +           && !DECL_BUILT_IN (fndecl)
> +           && !lookup_attribute ("assume_aligned",
> +                                 TYPE_ATTRIBUTES (fntype))
> +           && !lookup_attribute ("alloc_align",
> +                                 TYPE_ATTRIBUTES (fntype))))
>       return true;
>      }
>  
> @@ -1476,40 +1481,86 @@ bit_value_binop (enum tree_code code, tr
>    return val;
>  }
>  
> -/* Return the propagation value when applying __builtin_assume_aligned to
> -   its arguments.  */
> +/* Return the propagation value for __builtin_assume_aligned
> +   and functions with assume_aligned or alloc_aligned attribute.
> +   For __builtin_assume_aligned, ATTR is NULL_TREE,
> +   for assume_aligned attribute ATTR is non-NULL and ALLOC_ALIGNED
> +   is false, for alloc_aligned attribute ATTR is non-NULL and
> +   ALLOC_ALIGNED is true.  */
>  
>  static prop_value_t
> -bit_value_assume_aligned (gimple stmt)
> +bit_value_assume_aligned (gimple stmt, tree attr, prop_value_t ptrval,
> +                       bool alloc_aligned)
>  {
> -  tree ptr = gimple_call_arg (stmt, 0), align, misalign = NULL_TREE;
> -  tree type = TREE_TYPE (ptr);
> +  tree align, misalign = NULL_TREE, type;
>    unsigned HOST_WIDE_INT aligni, misaligni = 0;
> -  prop_value_t ptrval = get_value_for_expr (ptr, true);
>    prop_value_t alignval;
>    double_int value, mask;
>    prop_value_t val;
> +
> +  if (attr == NULL_TREE)
> +    {
> +      tree ptr = gimple_call_arg (stmt, 0);
> +      type = TREE_TYPE (ptr);
> +      ptrval = get_value_for_expr (ptr, true);
> +    }
> +  else
> +    {
> +      tree lhs = gimple_call_lhs (stmt);
> +      type = TREE_TYPE (lhs);
> +    }
> +
>    if (ptrval.lattice_val == UNDEFINED)
>      return ptrval;
>    gcc_assert ((ptrval.lattice_val == CONSTANT
>              && TREE_CODE (ptrval.value) == INTEGER_CST)
>             || ptrval.mask.is_minus_one ());
> -  align = gimple_call_arg (stmt, 1);
> -  if (!tree_fits_uhwi_p (align))
> -    return ptrval;
> -  aligni = tree_to_uhwi (align);
> -  if (aligni <= 1
> -      || (aligni & (aligni - 1)) != 0)
> -    return ptrval;
> -  if (gimple_call_num_args (stmt) > 2)
> +  if (attr == NULL_TREE)
>      {
> -      misalign = gimple_call_arg (stmt, 2);
> -      if (!tree_fits_uhwi_p (misalign))
> +      /* Get aligni and misaligni from __builtin_assume_aligned.  */
> +      align = gimple_call_arg (stmt, 1);
> +      if (!tree_fits_uhwi_p (align))
>       return ptrval;
> -      misaligni = tree_to_uhwi (misalign);
> -      if (misaligni >= aligni)
> +      aligni = tree_to_uhwi (align);
> +      if (gimple_call_num_args (stmt) > 2)
> +     {
> +       misalign = gimple_call_arg (stmt, 2);
> +       if (!tree_fits_uhwi_p (misalign))
> +         return ptrval;
> +       misaligni = tree_to_uhwi (misalign);
> +     }
> +    }
> +  else
> +    {
> +      /* Get aligni and misaligni from assume_aligned or
> +      alloc_align attributes.  */
> +      if (TREE_VALUE (attr) == NULL_TREE)
> +     return ptrval;
> +      attr = TREE_VALUE (attr);
> +      align = TREE_VALUE (attr);
> +      if (!tree_fits_uhwi_p (align))
>       return ptrval;
> +      aligni = tree_to_uhwi (align);
> +      if (alloc_aligned)
> +     {
> +       if (aligni == 0 || aligni > gimple_call_num_args (stmt))
> +         return ptrval;
> +       align = gimple_call_arg (stmt, aligni - 1);
> +       if (!tree_fits_uhwi_p (align))
> +         return ptrval;
> +       aligni = tree_to_uhwi (align);
> +     }
> +      else if (TREE_CHAIN (attr) && TREE_VALUE (TREE_CHAIN (attr)))
> +     {
> +       misalign = TREE_VALUE (TREE_CHAIN (attr));
> +       if (!tree_fits_uhwi_p (misalign))
> +         return ptrval;
> +       misaligni = tree_to_uhwi (misalign);
> +     }
>      }
> +  if (aligni <= 1 || (aligni & (aligni - 1)) != 0 || misaligni >= aligni)
> +    return ptrval;
> +
>    align = build_int_cst_type (type, -aligni);
>    alignval = get_value_for_expr (align, true);
>    bit_value_binop_1 (BIT_AND_EXPR, type, &value, &mask,
> @@ -1708,12 +1759,27 @@ evaluate_stmt (gimple stmt)
>             break;
>  
>           case BUILT_IN_ASSUME_ALIGNED:
> -           val = bit_value_assume_aligned (stmt);
> +           val = bit_value_assume_aligned (stmt, NULL_TREE, val, false);
>             break;
>  
>           default:;
>           }
>       }
> +      if (is_gimple_call (stmt) && gimple_call_lhs (stmt))
> +     {
> +       tree fntype = gimple_call_fntype (stmt);
> +       if (fntype)
> +         {
> +           tree attrs = lookup_attribute ("assume_aligned",
> +                                          TYPE_ATTRIBUTES (fntype));
> +           if (attrs)
> +             val = bit_value_assume_aligned (stmt, attrs, val, false);
> +           attrs = lookup_attribute ("alloc_align",
> +                                     TYPE_ATTRIBUTES (fntype));
> +           if (attrs)
> +             val = bit_value_assume_aligned (stmt, attrs, val, true);
> +         }
> +     }
>        is_constant = (val.lattice_val == CONSTANT);
>      }
>  
> --- gcc/doc/extend.texi.jj    2014-02-07 11:44:05.843926848 +0100
> +++ gcc/doc/extend.texi       2014-02-07 11:53:54.472485819 +0100
> @@ -2154,8 +2154,8 @@ The keyword @code{__attribute__} allows
>  attributes when making a declaration.  This keyword is followed by an
>  attribute specification inside double parentheses.  The following
>  attributes are currently defined for functions on all targets:
> -@code{aligned}, @code{alloc_size}, @code{noreturn},
> -@code{returns_twice}, @code{noinline}, @code{noclone},
> +@code{aligned}, @code{alloc_size}, @code{alloc_align}, @code{assume_aligned},
> +@code{noreturn}, @code{returns_twice}, @code{noinline}, @code{noclone},
>  @code{always_inline}, @code{flatten}, @code{pure}, @code{const},
>  @code{nothrow}, @code{sentinel}, @code{format}, @code{format_arg},
>  @code{no_instrument_function}, @code{no_split_stack},
> @@ -2249,6 +2249,46 @@ declares that @code{my_calloc} returns m
>  the product of parameter 1 and 2 and that @code{my_realloc} returns memory
>  of the size given by parameter 2.
>  
> +@item alloc_align
> +@cindex @code{alloc_align} attribute
> +The @code{alloc_align} attribute is used to tell the compiler that the
> +function return value points to memory, where the returned pointer minimum
> +alignment is given by one of the functions parameters.  GCC uses this
> +information to improve pointer alignment analysis.
> +
> +The function parameter denoting the allocated alignment is specified by
> +one integer argument, whose number is the argument of the attribute.
> +Argument numbering starts at one.
> +
> +For instance,
> +
> +@smallexample
> +void* my_memalign(size_t, size_t) __attribute__((alloc_align(1)))
> +@end smallexample
> +
> +@noindent
> +declares that @code{my_memalign} returns memory with minimum alignment
> +given by parameter 1.
> +
> +@item assume_aligned
> +@cindex @code{assume_aligned} attribute
> +The @code{assume_aligned} attribute is used to tell the compiler that the
> +function return value points to memory, where the returned pointer minimum
> +alignment is given by the first argument.
> +If the attribute has two arguments, the second argument is misalignment 
> offset.
> +
> +For instance
> +
> +@smallexample
> +void* my_alloc1(size_t) __attribute__((assume_aligned(16)))
> +void* my_alloc2(size_t) __attribute__((assume_aligned(32, 8)))
> +@end smallexample
> +
> +@noindent
> +declares that @code{my_alloc1} returns 16-byte aligned pointer and
> +that @code{my_alloc2} returns a pointer whose value modulo 32 is equal
> +to 8.
> +
>  @item always_inline
>  @cindex @code{always_inline} function attribute
>  Generally, functions are not inlined unless optimization is specified.
> --- gcc/testsuite/gcc.dg/attr-alloc_align-1.c.jj      2014-02-07 
> 11:53:54.473485822 +0100
> +++ gcc/testsuite/gcc.dg/attr-alloc_align-1.c 2014-02-07 11:53:54.473485822 
> +0100
> @@ -0,0 +1,39 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O3" } */
> +
> +double *my_alloc1 (int len, int align) __attribute__((__alloc_align__ (2)));
> +double *my_alloc2 (int align, int len) __attribute__((alloc_align (1)));
> +
> +void
> +test1 (int len, int align)
> +{
> +  int i;
> +  double *__restrict o1 = my_alloc1 (len, 32);
> +  double *__restrict o2 = my_alloc1 (len, 32);
> +  double *__restrict o3 = my_alloc1 (len, 32);
> +  double *__restrict i1 = my_alloc1 (len, 32);
> +  double *__restrict i2 = my_alloc1 (len, align);
> +  for (i = 0; i < len; ++i)
> +    {
> +      o1[i] = i1[i] * i2[i];
> +      o2[i] = i1[i] + i2[i];
> +      o3[i] = i1[i] - i2[i];
> +    }
> +}
> +
> +void
> +test2 (int len, int align)
> +{
> +  int i;
> +  double *__restrict o1 = my_alloc2 (32, len);
> +  double *__restrict o2 = my_alloc2 (32, len);
> +  double *__restrict o3 = my_alloc2 (32, len);
> +  double *__restrict i1 = my_alloc2 (32, len);
> +  double *__restrict i2 = my_alloc2 (align, len);
> +  for (i = 0; i < len; ++i)
> +    {
> +      o1[i] = i1[i] * i2[i];
> +      o2[i] = i1[i] + i2[i];
> +      o3[i] = i1[i] - i2[i];
> +    }
> +}
> --- gcc/testsuite/gcc.dg/attr-alloc_align-2.c.jj      2014-02-07 
> 11:53:54.473485822 +0100
> +++ gcc/testsuite/gcc.dg/attr-alloc_align-2.c 2014-02-07 11:53:54.473485822 
> +0100
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +
> +int i;
> +void *f1 (int) __attribute__((alloc_align (1)));
> +void *f2 (int, int, int) __attribute__((alloc_align (3)));
> +void *f3 (void) __attribute__((alloc_align)); /* { dg-error "wrong number of 
> arguments specified" } */
> +void *f4 (int, int) __attribute__((alloc_align (1, 2))); /* { dg-error 
> "wrong number of arguments specified" } */
> +void *f5 (void) __attribute__((alloc_align (i))); /* { dg-warning "outside 
> range" } */
> +void *f6 (int) __attribute__((alloc_align (0))); /* { dg-warning "outside 
> range" } */
> +void *f7 (int) __attribute__((alloc_align (2))); /* { dg-warning "outside 
> range" } */
> --- gcc/testsuite/gcc.dg/attr-alloc_align-3.c.jj      2014-02-07 
> 11:53:54.474485825 +0100
> +++ gcc/testsuite/gcc.dg/attr-alloc_align-3.c 2014-02-07 11:53:54.474485825 
> +0100
> @@ -0,0 +1,56 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +char *my_alloc1 (int len, int align) __attribute__((__alloc_align__ (2)));
> +char *my_alloc2 (int align, int len) __attribute__((alloc_align (1)));
> +
> +int
> +test1 (int len)
> +{
> +  int i;
> +  char *p = my_alloc1 (len, 32);
> +  return ((__INTPTR_TYPE__) p) & 31;
> +}
> +
> +int
> +test2 (int len)
> +{
> +  int i;
> +  char *p = my_alloc2 (32, len);
> +  return ((__INTPTR_TYPE__) p) & 31;
> +}
> +
> +int
> +test3 (int len)
> +{
> +  int i;
> +  char *p = my_alloc1 (len, 16);
> +  return ((__INTPTR_TYPE__) p) & 15;
> +}
> +
> +int
> +test4 (int len)
> +{
> +  int i;
> +  char *p = my_alloc2 (16, len);
> +  return ((__INTPTR_TYPE__) p) & 15;
> +}
> +
> +int
> +test5 (int len, int align)
> +{
> +  int i;
> +  char *p = my_alloc1 (len, align);
> +  return ((__INTPTR_TYPE__) p) & 15;
> +}
> +
> +int
> +test6 (int len, int align)
> +{
> +  int i;
> +  char *p = my_alloc2 (align, len);
> +  return ((__INTPTR_TYPE__) p) & 15;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "return 0" 4 "optimized" } } */
> +/* { dg-final { cleanup-tree-dump "optimized" } } */
> --- gcc/testsuite/gcc.dg/attr-assume_aligned-1.c.jj   2014-02-07 
> 11:53:54.474485825 +0100
> +++ gcc/testsuite/gcc.dg/attr-assume_aligned-1.c      2014-02-07 
> 11:53:54.474485825 +0100
> @@ -0,0 +1,39 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O3" } */
> +
> +double *my_alloc1 (int len) __attribute__((__assume_aligned__ (16)));
> +double *my_alloc2 (int len) __attribute__((__assume_aligned__ (32, 16)));
> +
> +void
> +test1 (int len)
> +{
> +  int i;
> +  double *__restrict o1 = my_alloc1 (len);
> +  double *__restrict o2 = my_alloc1 (len);
> +  double *__restrict o3 = my_alloc1 (len);
> +  double *__restrict i1 = my_alloc1 (len);
> +  double *__restrict i2 = my_alloc1 (len);
> +  for (i = 0; i < len; ++i)
> +    {
> +      o1[i] = i1[i] * i2[i];
> +      o2[i] = i1[i] + i2[i];
> +      o3[i] = i1[i] - i2[i];
> +    }
> +}
> +
> +void
> +test2 (int len)
> +{
> +  int i;
> +  double *__restrict o1 = my_alloc2 (len);
> +  double *__restrict o2 = my_alloc2 (len);
> +  double *__restrict o3 = my_alloc2 (len);
> +  double *__restrict i1 = my_alloc2 (len);
> +  double *__restrict i2 = my_alloc2 (len);
> +  for (i = 0; i < len; ++i)
> +    {
> +      o1[i] = i1[i] * i2[i];
> +      o2[i] = i1[i] + i2[i];
> +      o3[i] = i1[i] - i2[i];
> +    }
> +}
> --- gcc/testsuite/gcc.dg/attr-assume_aligned-2.c.jj   2014-02-07 
> 11:53:54.474485825 +0100
> +++ gcc/testsuite/gcc.dg/attr-assume_aligned-2.c      2014-02-07 
> 11:53:54.474485825 +0100
> @@ -0,0 +1,8 @@
> +/* { dg-do compile } */
> +
> +int i;
> +void *f1 (void) __attribute__((assume_aligned (32)));
> +void *f2 (void) __attribute__((assume_aligned (16, 4)));
> +void *f3 (void) __attribute__((assume_aligned)); /* { dg-error "wrong number 
> of arguments specified" } */
> +void *f4 (void) __attribute__((assume_aligned (32, 16, 8))); /* { dg-error 
> "wrong number of arguments specified" } */
> +void *f5 (void) __attribute__((assume_aligned (i))); /* { dg-warning 
> "integer constant" } */
> --- gcc/testsuite/gcc.dg/attr-assume_aligned-3.c.jj   2014-02-07 
> 11:53:54.474485825 +0100
> +++ gcc/testsuite/gcc.dg/attr-assume_aligned-3.c      2014-02-07 
> 11:53:54.474485825 +0100
> @@ -0,0 +1,24 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +char *my_alloc1 (int len) __attribute__((__assume_aligned__ (32)));
> +char *my_alloc2 (int len) __attribute__((assume_aligned (32, 4)));
> +
> +int
> +test1 (int len)
> +{
> +  int i;
> +  char *p = my_alloc1 (len);
> +  return ((__INTPTR_TYPE__) p) & 31;
> +}
> +
> +int
> +test2 (int len)
> +{
> +  int i;
> +  char *p = my_alloc2 (len);
> +  return (((__INTPTR_TYPE__) p) & 31) != 4;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "return 0" 2 "optimized" } } */
> +/* { dg-final { cleanup-tree-dump "optimized" } } */
> 
> 
>       Jakub
> 
> 

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

Reply via email to