Fix CSE CLZ/CTZ handling (PR rtl-optimization/85376, variant)

Message ID 20180413170642.GE8577@tucnak
State New
Headers show
Series
  • Fix CSE CLZ/CTZ handling (PR rtl-optimization/85376, variant)
Related show

Commit Message

Jakub Jelinek April 13, 2018, 5:06 p.m.
On Fri, Apr 13, 2018 at 12:33:02AM +0200, Jakub Jelinek wrote:
> The following patch let us punt in these cases.  Bootstrapped/regtested on
> x86_64-linux and i686-linux, ok for trunk?
> 
> Another option would be to tweak simplify-rtx.c and instead of doing
>           else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
>             int_value = GET_MODE_PRECISION (imode);
> do
>           else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
> 	    return NULL_RTX;
> and similarly for CLZ, haven't tested what would break if anything;
> we've been doing something like that since r62453 when the
> C?Z_DEFINED_VALUE_AT_ZERO macros have been introduced, and before that
> actually the same, just unconditionally assumed the value is undefined at 0.

And here is the variant patch, also bootstrapped/regtested on x86_64-linux
and i686-linux.  Is this one ok for trunk, or the other one (or something
else)?

2018-04-13  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/85376
	* simplify-rtx.c (simplify_const_unary_operation): For CLZ and CTZ and
	zero op0, if C?Z_DEFINED_VALUE_AT_ZERO is false, return NULL_RTX
	instead of a specific value.

	* gcc.dg/pr85376.c: New test.



	Jakub

Patch

--- gcc/simplify-rtx.c.jj	2018-03-21 11:13:00.322234030 +0100
+++ gcc/simplify-rtx.c	2018-04-13 11:47:05.689621937 +0200
@@ -1877,7 +1877,7 @@  simplify_const_unary_operation (enum rtx
 	  if (wi::ne_p (op0, 0))
 	    int_value = wi::clz (op0);
 	  else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
-	    int_value = GET_MODE_PRECISION (imode);
+	    return NULL_RTX;
 	  result = wi::shwi (int_value, result_mode);
 	  break;
 
@@ -1889,7 +1889,7 @@  simplify_const_unary_operation (enum rtx
 	  if (wi::ne_p (op0, 0))
 	    int_value = wi::ctz (op0);
 	  else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
-	    int_value = GET_MODE_PRECISION (imode);
+	    return NULL_RTX;
 	  result = wi::shwi (int_value, result_mode);
 	  break;
 
--- gcc/testsuite/gcc.dg/pr85376.c.jj	2018-04-12 17:44:41.506370642 +0200
+++ gcc/testsuite/gcc.dg/pr85376.c	2018-04-12 17:45:11.669401115 +0200
@@ -0,0 +1,32 @@ 
+/* PR rtl-optimization/85376 */
+/* { dg-do run { target int128 } } */
+/* { dg-options "-Og -fno-dce -fgcse -fno-tree-ccp -fno-tree-copy-prop -Wno-psabi" } */
+
+typedef unsigned int U __attribute__ ((vector_size (64)));
+typedef unsigned __int128 V __attribute__ ((vector_size (64)));
+unsigned int e, i, l;
+unsigned char f;
+U g, h, k, j;
+
+static inline V
+foo (unsigned char n, unsigned short o, unsigned int p, U q, U r, U s)
+{
+  unsigned int t;
+  o <<= 5;
+  q[7] >>= __builtin_add_overflow (0xfffffff0, __builtin_ffs (n), &s[5]);
+  t = __builtin_ffs (g[7]);
+  e *= __builtin_sub_overflow (o, t, &f);
+  return f + (V) g + (V) h + (V) q + i + (V) j + (V) s + (V) k + l;
+}
+
+int
+main ()
+{
+  if (__SIZEOF_INT128__ != 16 || __SIZEOF_INT__ != 4 || __CHAR_BIT__ != 8)
+    return 0;
+  V x = foo (0, 1, 5, (U) { }, (U) { }, (U) { });
+  for (unsigned i = 0; i < 4; i++)
+    if ((unsigned int) x[i] != 0x20)
+      __builtin_abort ();
+  return 0;
+}