On Fri, Nov 21, 2014 at 09:07:50PM +0100, Martin Jambor wrote:
> Hi,
> 
> the testcase of PR 63551 passes a union between a signed and an
> unsigned integer between two functions as a parameter.  The caller
> initializes to an unsigned integer with the highest order bit set, the
> callee loads the data through the signed field and compares with zero.
> evaluate_conditions_for_known_args then wrongly evaluated the
> condition in these circumstances, which later on lead to insertion of
> builtin_unreachable and miscompilation.
> 
> Fixed by fold_converting the known value first.  I use the type of the
> value in the condition which should do exactly the right thing because
> the value is taken from the corresponding gimple_cond statement in
> which types must match.
> 
> Bootstrapped and tested on x86_64-linux.  OK for trunk?

I forgot, this is also a 4.9 bug and I have bootstrapped and tested it
on top of the 4.9 branch as well.  So OK for trunk and the 4.9 branch?

Thanks,

Martin

> 
> 2014-11-21  Martin Jambor  <mjam...@suse.cz>
> 
>       PR ipa/63551
>       * ipa-inline-analysis.c (evaluate_conditions_for_known_args): Convert
>       value of the argument to the type of the value in the condition.
> 
> testsuite/
>       * gcc.dg/ipa/pr63551.c: New test.
> 
> 
> Index: src/gcc/ipa-inline-analysis.c
> ===================================================================
> --- src.orig/gcc/ipa-inline-analysis.c
> +++ src/gcc/ipa-inline-analysis.c
> @@ -880,6 +880,7 @@ evaluate_conditions_for_known_args (stru
>       }
>        if (c->code == IS_NOT_CONSTANT || c->code == CHANGED)
>       continue;
> +      val = fold_convert (TREE_TYPE (c->val), val);
>        res = fold_binary_to_constant (c->code, boolean_type_node, val, 
> c->val);
>        if (res && integer_zerop (res))
>       continue;
> Index: src/gcc/testsuite/gcc.dg/ipa/pr63551.c
> ===================================================================
> --- /dev/null
> +++ src/gcc/testsuite/gcc.dg/ipa/pr63551.c
> @@ -0,0 +1,33 @@
> +/* { dg-do run } */
> +/* { dg-options "-Os" } */
> +
> +union U
> +{
> +  unsigned int f0;
> +  int f1;
> +};
> +
> +int a, d;
> +
> +void
> +fn1 (union U p)
> +{
> +  if (p.f1 <= 0)
> +    if (a)
> +      d = 0;
> +}
> +
> +void
> +fn2 ()
> +{
> +  d = 0;
> +  union U b = { 4294967286 };
> +  fn1 (b);
> +}
> +
> +int
> +main ()
> +{
> +  fn2 ();
> +  return 0;
> +}

Reply via email to