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
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.
--- 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 (0xfff0, __builtin_ffs (n), [5]);
+ t = __builtin_ffs (g[7]);
+ e *= __builtin_sub_overflow (o, t, );
+ 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;
+}
Jakub