On Thu, 11 Mar 2021, Jakub Jelinek wrote:

> Hi!
> 
> The following testcase is miscompiled, because IPA-ICF considers the two
> functions identical.  They aren't, the types of the .VEC_CONVERT call
> lhs is different.  But for calls to internal functions, there is no
> fntype nor callee with a function type to compare, so all we compare
> is just the ifn, arguments and some call flags.
> 
> The following patch fixes it by checking the internal fn calls like e.g. 
> gimple
> assignments where the type of the lhs is checked too.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2021-03-11  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR ipa/99517
>       * ipa-icf-gimple.c (func_checker::compare_gimple_call): For internal
>       function calls with lhs fail if the lhs don't have compatible types.
> 
>       * gcc.target/i386/avx2-pr99517-1.c: New test.
>       * gcc.target/i386/avx2-pr99517-2.c: New test.
> 
> --- gcc/ipa-icf-gimple.c.jj   2021-01-04 10:25:38.752234741 +0100
> +++ gcc/ipa-icf-gimple.c      2021-03-10 15:02:06.287502784 +0100
> @@ -667,7 +667,7 @@ func_checker::compare_gimple_call (gcall
>    tree fntype1 = gimple_call_fntype (s1);
>    tree fntype2 = gimple_call_fntype (s2);
>  
> -  /* For direct calls we verify that types are comopatible so if we matced
> +  /* For direct calls we verify that types are compatible so if we matched
>       callees, callers must match, too.  For indirect calls however verify
>       function type.  */
>    if (!gimple_call_fndecl (s1))
> @@ -703,6 +703,14 @@ func_checker::compare_gimple_call (gcall
>    t1 = gimple_get_lhs (s1);
>    t2 = gimple_get_lhs (s2);
>  
> +  /* For internal calls, lhs types need to be verified, as neither fntype nor
> +     callee comparisons can catch that.  */
> +  if (gimple_call_internal_p (s1)
> +      && t1
> +      && t2
> +      && !compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2)))
> +    return return_false_with_msg ("GIMPLE internal call LHS type mismatch");
> +
>    return compare_operand (t1, t2, get_operand_access_type (&map, t1));
>  }
>  
> --- gcc/testsuite/gcc.target/i386/avx2-pr99517-1.c.jj 2021-03-10 
> 15:28:33.175959797 +0100
> +++ gcc/testsuite/gcc.target/i386/avx2-pr99517-1.c    2021-03-10 
> 15:28:57.117695186 +0100
> @@ -0,0 +1,25 @@
> +/* PR ipa/99517 */
> +/* { dg-do run { target avx2 } } */
> +/* { dg-additional-sources "avx2-pr99517-2.c" } */
> +/* { dg-options "-O2 -mavx2" } */
> +
> +#include "avx2-check.h"
> +
> +typedef signed char v32qi __attribute__((vector_size(32)));
> +typedef int v4si __attribute__((vector_size(16)));
> +typedef long long int v4di __attribute__((vector_size(32)));
> +typedef double v4df __attribute__((vector_size(32)));
> +extern v32qi foo (v4si);
> +extern v32qi bar (v4si);
> +
> +static void
> +avx2_test (void)
> +{
> +  v4si a = { 1, -2, 3, -4 };
> +  __asm ("" : "+x" (a));
> +  v4di b = (v4di) bar (a);
> +  v4df c = (v4df) foo (a);
> +  if (b[0] != 1 || c[0] != 1.0 || b[1] != -2 || c[1] != -2.0
> +      || b[2] != 3 || c[2] != 3.0 || b[3] != -4 || c[3] != -4.0)
> +    __builtin_abort ();
> +}
> --- gcc/testsuite/gcc.target/i386/avx2-pr99517-2.c.jj 2021-03-10 
> 15:30:33.974624677 +0100
> +++ gcc/testsuite/gcc.target/i386/avx2-pr99517-2.c    2021-03-10 
> 15:30:28.529684856 +0100
> @@ -0,0 +1,20 @@
> +/* PR ipa/99517 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mavx2" } */
> +
> +typedef signed char v32qi __attribute__((vector_size(32)));
> +typedef int v4si __attribute__((vector_size(16)));
> +typedef long long int v4di __attribute__((vector_size(32)));
> +typedef double v4df __attribute__((vector_size(32)));
> +
> +v32qi
> +foo (v4si x)
> +{
> +  return (v32qi) __builtin_convertvector (x, v4df);
> +}
> +
> +v32qi
> +bar (v4si x)
> +{
> +  return (v32qi) __builtin_convertvector (x, v4di);
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Reply via email to