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 <ja...@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. --- 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; +} Jakub