https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87535

            Bug ID: 87535
           Summary: multiple attribute assume_aligned interpreted
                    inconsistently
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

The example below shows that attribute assume_aligned is interpreted
inconsistently between apparently equivalent declarations of the same function.
 When two such attributes are specified on the same declaration the one
specified last wins.  When the same pair are specified on distinct declarations
of the same function, the first one wins.

Clang treats both forms consistently, but honors the attribute that was
specified last.  I think it's debatable whether that's preferable to honoring
the most restrictive one as specified for _Alignas by C11.  I'm leaning toward
going with the C11 approach to minimize surprises due to an inconsistency.

$ cat c.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout c.c
__attribute ((assume_aligned (8),     // ignored
              assume_aligned (32)))   // overrdides prior attribute
char* f (void);

void f1 (void)
{
  char *p = f ();
  if ((__INTPTR_TYPE__)p & 31)   // folded to false
    __builtin_abort ();
}

__attribute ((assume_aligned (8)))   // overrides subsequent attribute
void* g (void);

__attribute ((assume_aligned (32)))   // attribute ignored
void* g (void);

void g1 (void)
{
  void *p = g ();
  if ((__INTPTR_TYPE__)p & 31)   // not folded
    __builtin_abort ();
}


;; Function f1 (f1, funcdef_no=0, decl_uid=1908, cgraph_uid=1, symbol_order=0)

f1 ()
{
  <bb 2> [local count: 1073741824]:
  f (); [tail call]
  return;

}



;; Function g1 (g1, funcdef_no=1, decl_uid=1916, cgraph_uid=2, symbol_order=1)

g1 ()
{
  void * p;
  long int p.1_1;
  long int _2;

  <bb 2> [local count: 1073741824]:
  p_5 = g ();
  p.1_1 = (long int) p_5;
  _2 = p.1_1 & 31;
  if (_2 != 0)
    goto <bb 3>; [0.00%]
  else
    goto <bb 4>; [99.96%]

  <bb 3> [count: 0]:
  __builtin_abort ();

  <bb 4> [local count: 1073312328]:
  return;

}

Reply via email to