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

Richard Sandiford <rsandifo at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |rsandifo at gcc dot gnu.org

--- Comment #9 from Richard Sandiford <rsandifo at gcc dot gnu.org> ---
(In reply to Jan Hubicka from comment #7)
> Hash needs to be stable for LTO streaming which affects types.  But at least
> we ought to compare types when we are comparing bodies in
> func_checker::compare_gimple_call.  I guess for non-varadic calls this
> happens since both calls must have same signature. 
> 
> This untested patch may fix it
> diff --git a/gcc/ipa-icf-gimple.cc b/gcc/ipa-icf-gimple.cc
> index 31f6cdbda06..ef9e3ea3164 100644
> --- a/gcc/ipa-icf-gimple.cc
> +++ b/gcc/ipa-icf-gimple.cc
> @@ -746,6 +746,8 @@ func_checker::compare_gimple_call (gcall *s1, gcall *s2)
>  
>        if (!compare_operand (t1, t2, get_operand_access_type (&map, t1)))
>         return return_false_with_msg ("GIMPLE call operands are different");
> +      if (!types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2))
> +       return return_false_with_msg ("GIMPLE call operand types are
> different");
>      }
>  
>    /* Return value checking.  */
> 
> I wonder if it won't cause us to give up too often, perhaps we could do that
> only for variadic calls and calls with no prototype or so.
What about Alexander's asm example in comment 6?  I just hit what looks like
another instance of this when trying to write a testcase for a different bug:

void
f1 ()
{
  struct { unsigned short a, b; } x;
  unsigned int y;                                                               
  asm ("" : "=r" (x), "=r" (y));
  x.a = y;
  asm volatile ("" :: "r" (x));
}

void
f2 ()                                                                          
{
  struct { unsigned short a, b; } x;
  unsigned char y;
  asm ("" : "=r" (x), "=r" (y));
  x.a = y;
  asm volatile ("" :: "r" (x));
}                                                                               

icf treats f2 as a dup of f1, even though f2 includes a zero extension from
unsigned char to unsigned short.  Thus on aarch64 we get:

f1:
        bfi     w0, w1, 0, 16
        ret

f2:
        bfi     w0, w1, 0, 16
        ret

Reply via email to