diff mbox series

Fix up match.pd ICE on kernel build (PR middle-end/91725)

Message ID 20190911075230.GE2120@tucnak
State New
Headers show
Series Fix up match.pd ICE on kernel build (PR middle-end/91725) | expand

Commit Message

Jakub Jelinek Sept. 11, 2019, 7:52 a.m. UTC
Hi!

My recent change broke Linux kernel build, where we ICE in get_nonzero_bits
which apparently assumes it must be called only on INTEGER_CSTs or
SSA_NAMEs, while during generic folding it can be called say with PLUS_EXPR
etc.

tree_nonzero_bits apparently can be called on any tree code, as it has the
return -1 fallback, but it doesn't really handle vector types, because it
uses TYPE_PRECISION instead of element_precision.
get_nonzero_bits also doesn't do anything useful for vector types,
INTEGER_CSTs aren't vectors and vector type SSA_NAMEs won't really have
range info (though, uses element_precision).  In theory for VECTOR_CSTs we
could or in get_nonzero_bits from all elements together or something
similar, but still for SSA_NAMEs as we don't track anything it won't be
useful, so this patch just punts on vector types if there is a widening
conversion from signed.  After all, a widening conversion for vectors
wouldn't be really a conversion, but VEC_UNPACK_{LO,HI}_EXPR.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-09-11  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/91725
	* match.pd ((A / (1 << B)) -> (A >> B)): Call tree_nonzero_bits instead
	of get_nonzero_bits, only call it for integral types.

	* gcc.c-torture/compile/pr91725.c: New test.


	Jakub

Comments

Richard Biener Sept. 11, 2019, 8:17 a.m. UTC | #1
On Wed, 11 Sep 2019, Jakub Jelinek wrote:

> Hi!
> 
> My recent change broke Linux kernel build, where we ICE in get_nonzero_bits
> which apparently assumes it must be called only on INTEGER_CSTs or
> SSA_NAMEs, while during generic folding it can be called say with PLUS_EXPR
> etc.
> 
> tree_nonzero_bits apparently can be called on any tree code, as it has the
> return -1 fallback, but it doesn't really handle vector types, because it
> uses TYPE_PRECISION instead of element_precision.
> get_nonzero_bits also doesn't do anything useful for vector types,
> INTEGER_CSTs aren't vectors and vector type SSA_NAMEs won't really have
> range info (though, uses element_precision).  In theory for VECTOR_CSTs we
> could or in get_nonzero_bits from all elements together or something
> similar, but still for SSA_NAMEs as we don't track anything it won't be
> useful, so this patch just punts on vector types if there is a widening
> conversion from signed.  After all, a widening conversion for vectors
> wouldn't be really a conversion, but VEC_UNPACK_{LO,HI}_EXPR.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

> 2019-09-11  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR middle-end/91725
> 	* match.pd ((A / (1 << B)) -> (A >> B)): Call tree_nonzero_bits instead
> 	of get_nonzero_bits, only call it for integral types.
> 
> 	* gcc.c-torture/compile/pr91725.c: New test.
> 
> --- gcc/match.pd.jj	2019-09-10 10:13:29.723000308 +0200
> +++ gcc/match.pd	2019-09-10 20:14:06.164054126 +0200
> @@ -325,9 +325,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>  	      && (TYPE_UNSIGNED (TREE_TYPE (@1))
>  		  || (element_precision (type)
>  		      == element_precision (TREE_TYPE (@1)))
> -		  || (get_nonzero_bits (@0)
> -		      & wi::mask (element_precision (TREE_TYPE (@1)) - 1, true,
> -				  element_precision (type))) == 0))))
> +		  || (INTEGRAL_TYPE_P (type)
> +		      && (tree_nonzero_bits (@0)
> +			  & wi::mask (element_precision (TREE_TYPE (@1)) - 1,
> +				      true,
> +				      element_precision (type))) == 0)))))
>    (rshift @0 @2)))
>  
>  /* Preserve explicit divisions by 0: the C++ front-end wants to detect
> --- gcc/testsuite/gcc.c-torture/compile/pr91725.c.jj	2019-09-10 20:09:39.499987576 +0200
> +++ gcc/testsuite/gcc.c-torture/compile/pr91725.c	2019-09-10 20:08:21.302141038 +0200
> @@ -0,0 +1,7 @@
> +/* PR middle-end/91725 */
> +
> +unsigned long long
> +foo (unsigned long long x, unsigned long long y, int z)
> +{
> +  return (x + y) / (1 << z);
> +}
> 
> 	Jakub
>
diff mbox series

Patch

--- gcc/match.pd.jj	2019-09-10 10:13:29.723000308 +0200
+++ gcc/match.pd	2019-09-10 20:14:06.164054126 +0200
@@ -325,9 +325,11 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 	      && (TYPE_UNSIGNED (TREE_TYPE (@1))
 		  || (element_precision (type)
 		      == element_precision (TREE_TYPE (@1)))
-		  || (get_nonzero_bits (@0)
-		      & wi::mask (element_precision (TREE_TYPE (@1)) - 1, true,
-				  element_precision (type))) == 0))))
+		  || (INTEGRAL_TYPE_P (type)
+		      && (tree_nonzero_bits (@0)
+			  & wi::mask (element_precision (TREE_TYPE (@1)) - 1,
+				      true,
+				      element_precision (type))) == 0)))))
   (rshift @0 @2)))
 
 /* Preserve explicit divisions by 0: the C++ front-end wants to detect
--- gcc/testsuite/gcc.c-torture/compile/pr91725.c.jj	2019-09-10 20:09:39.499987576 +0200
+++ gcc/testsuite/gcc.c-torture/compile/pr91725.c	2019-09-10 20:08:21.302141038 +0200
@@ -0,0 +1,7 @@ 
+/* PR middle-end/91725 */
+
+unsigned long long
+foo (unsigned long long x, unsigned long long y, int z)
+{
+  return (x + y) / (1 << z);
+}