fold-const: Fix division folding with vector operands [PR94412]

Message ID 20200331081543.GE2212@tucnak
State New
Headers show
Series
  • fold-const: Fix division folding with vector operands [PR94412]
Related show

Commit Message

Iain Buclaw via Gcc-patches March 31, 2020, 8:15 a.m.
Hi!

The following testcase is miscompiled since 4.9, we treat unsigned
vector types as if they were signed and "optimize" negations across it.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2020-03-31  Marc Glisse  <marc.glisse@inria.fr>
	    Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/94412
	* fold-const.c (fold_binary_loc) <case TRUNC_DIV_EXPR>: Use
	ANY_INTEGRAL_TYPE_P instead of INTEGRAL_TYPE_P.

	* gcc.c-torture/execute/pr94412.c: New test.


	Jakub

Comments

Richard Biener March 31, 2020, 8:53 a.m. | #1
On Tue, 31 Mar 2020, Jakub Jelinek wrote:

> Hi!

> 

> The following testcase is miscompiled since 4.9, we treat unsigned

> vector types as if they were signed and "optimize" negations across it.

> 

> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for

> trunk?


OK.

Richard.

> 2020-03-31  Marc Glisse  <marc.glisse@inria.fr>

> 	    Jakub Jelinek  <jakub@redhat.com>

> 

> 	PR middle-end/94412

> 	* fold-const.c (fold_binary_loc) <case TRUNC_DIV_EXPR>: Use

> 	ANY_INTEGRAL_TYPE_P instead of INTEGRAL_TYPE_P.

> 

> 	* gcc.c-torture/execute/pr94412.c: New test.

> 

> --- gcc/fold-const.c.jj	2020-03-19 10:23:34.106114042 +0100

> +++ gcc/fold-const.c	2020-03-30 23:00:32.273551465 +0200

> @@ -11148,11 +11148,11 @@ fold_binary_loc (location_t loc, enum tr

>  

>        /* Convert -A / -B to A / B when the type is signed and overflow is

>  	 undefined.  */

> -      if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))

> +      if ((!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))

>  	  && TREE_CODE (op0) == NEGATE_EXPR

>  	  && negate_expr_p (op1))

>  	{

> -	  if (INTEGRAL_TYPE_P (type))

> +	  if (ANY_INTEGRAL_TYPE_P (type))

>  	    fold_overflow_warning (("assuming signed overflow does not occur "

>  				    "when distributing negation across "

>  				    "division"),

> @@ -11162,11 +11162,11 @@ fold_binary_loc (location_t loc, enum tr

>  						    TREE_OPERAND (arg0, 0)),

>  				  negate_expr (op1));

>  	}

> -      if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))

> +      if ((!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))

>  	  && TREE_CODE (arg1) == NEGATE_EXPR

>  	  && negate_expr_p (op0))

>  	{

> -	  if (INTEGRAL_TYPE_P (type))

> +	  if (ANY_INTEGRAL_TYPE_P (type))

>  	    fold_overflow_warning (("assuming signed overflow does not occur "

>  				    "when distributing negation across "

>  				    "division"),

> --- gcc/testsuite/gcc.c-torture/execute/pr94412.c.jj	2020-03-30 23:12:17.499118691 +0200

> +++ gcc/testsuite/gcc.c-torture/execute/pr94412.c	2020-03-30 23:12:00.701367149 +0200

> @@ -0,0 +1,28 @@

> +/* PR middle-end/94412 */

> +

> +typedef unsigned V __attribute__ ((__vector_size__ (sizeof (unsigned) * 2)));

> +

> +void

> +foo (V *v, V *w)

> +{

> +  *w = -*v / 11;

> +}

> +

> +void

> +bar (V *v, V *w)

> +{

> +  *w = -18 / -*v;

> +}

> +

> +int

> +main ()

> +{

> +  V a = (V) { 1, 0 };

> +  V b = (V) { 3, __INT_MAX__ };

> +  V c, d;

> +  foo (&a, &c);

> +  bar (&b, &d);

> +  if (c[0] != -1U / 11 || c[1] != 0 || d[0] != 0 || d[1] != -18U / -__INT_MAX__)

> +    __builtin_abort ();

> +  return 0;

> +}

> 

> 	Jakub

> 

> 


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

Patch

--- gcc/fold-const.c.jj	2020-03-19 10:23:34.106114042 +0100
+++ gcc/fold-const.c	2020-03-30 23:00:32.273551465 +0200
@@ -11148,11 +11148,11 @@  fold_binary_loc (location_t loc, enum tr
 
       /* Convert -A / -B to A / B when the type is signed and overflow is
 	 undefined.  */
-      if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
+      if ((!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
 	  && TREE_CODE (op0) == NEGATE_EXPR
 	  && negate_expr_p (op1))
 	{
-	  if (INTEGRAL_TYPE_P (type))
+	  if (ANY_INTEGRAL_TYPE_P (type))
 	    fold_overflow_warning (("assuming signed overflow does not occur "
 				    "when distributing negation across "
 				    "division"),
@@ -11162,11 +11162,11 @@  fold_binary_loc (location_t loc, enum tr
 						    TREE_OPERAND (arg0, 0)),
 				  negate_expr (op1));
 	}
-      if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
+      if ((!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
 	  && TREE_CODE (arg1) == NEGATE_EXPR
 	  && negate_expr_p (op0))
 	{
-	  if (INTEGRAL_TYPE_P (type))
+	  if (ANY_INTEGRAL_TYPE_P (type))
 	    fold_overflow_warning (("assuming signed overflow does not occur "
 				    "when distributing negation across "
 				    "division"),
--- gcc/testsuite/gcc.c-torture/execute/pr94412.c.jj	2020-03-30 23:12:17.499118691 +0200
+++ gcc/testsuite/gcc.c-torture/execute/pr94412.c	2020-03-30 23:12:00.701367149 +0200
@@ -0,0 +1,28 @@ 
+/* PR middle-end/94412 */
+
+typedef unsigned V __attribute__ ((__vector_size__ (sizeof (unsigned) * 2)));
+
+void
+foo (V *v, V *w)
+{
+  *w = -*v / 11;
+}
+
+void
+bar (V *v, V *w)
+{
+  *w = -18 / -*v;
+}
+
+int
+main ()
+{
+  V a = (V) { 1, 0 };
+  V b = (V) { 3, __INT_MAX__ };
+  V c, d;
+  foo (&a, &c);
+  bar (&b, &d);
+  if (c[0] != -1U / 11 || c[1] != 0 || d[0] != 0 || d[1] != -18U / -__INT_MAX__)
+    __builtin_abort ();
+  return 0;
+}