diff mbox

[PR,63551] Use proper type in evaluate_conditions_for_known_args

Message ID 20141121200750.GD7784@virgil.suse
State New
Headers show

Commit Message

Martin Jambor Nov. 21, 2014, 8:07 p.m. UTC
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?

Thanks,

Martin


2014-11-21  Martin Jambor  <mjambor@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.

Comments

Richard Biener Nov. 21, 2014, 8:18 p.m. UTC | #1
On November 21, 2014 9:07:50 PM CET, Martin Jambor <mjambor@suse.cz> 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 think you want to use fold_unary (VIEW_CONVERT,...) Here if you consider the case with
Int and float.  And "fail" if that returns NULL or not a constant.

Thanks,
Richard.

>Thanks,
>
>Martin
>
>
>2014-11-21  Martin Jambor  <mjambor@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;
>+}
Martin Jambor Nov. 21, 2014, 8:18 p.m. UTC | #2
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  <mjambor@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;
> +}
diff mbox

Patch

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;
+}