------- Comment #1 from jakub at gcc dot gnu dot org  2007-10-02 13:38 -------
Simplified testcase which also fails on x86_64-linux:

/* PR tree-optimization/33619 */
/* { dg-do run } */
/* { dg-options "-O2" } */

#ifdef __powerpc__
# define REG1 "3"
# define REG2 "4"
#elif defined __x86_64__
# define REG1 "rdi"
# define REG2 "rsi"
#endif

static inline void
bar (unsigned long x, int y)
{
  register unsigned long p1 __asm__ (REG1) = x;
  register unsigned long p2 __asm__ (REG2) = y;
  __asm__ volatile ("" : "=r" (p1), "=r" (p2) : "0" (p1), "1" (p2) : "memory");
  if (p1 != 0xdeadUL || p2 != 0xbefUL)
    __builtin_abort ();
}

__attribute__((const, noinline)) int
baz (int x)
{
  return x;
}

__attribute__((noinline)) void
foo (unsigned long *x, int y)
{
  unsigned long a = *x;
  bar (a, baz (y));
}

int
main (void)
{
  unsigned long a = 0xdeadUL;
  foo (&a, 0xbefUL);
  return 0;
}

In the presence of DECL_HARD_REGISTER vars making any kind of calls, even when
they are const or pure, replaceable is IMHO wrong.  Does it buy us anything to
make any calls replaceable (i.e. what would we lose by simply
if (get_call_expr_in (stmt))
  return false;
in is_replaceable_p)?  If yes, we either need to disallow them if the current
BB ever sets or uses any DECL_HARD_REGISTER vars, or need to do analysis
if the replacement in rewrite_trees crosses any such sets or uses.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33619

Reply via email to