diff --git a/gcc/testsuite/gcc.c-torture/execute/pr102134.c b/gcc/testsuite/gcc.c-torture/execute/pr102134.c new file mode 100644 index 00000000000..55cf4eb70a3 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr102134.c @@ -0,0 +1,23 @@ +/* PR tree-optimization/102134 */ + +typedef unsigned long long u64; + +u64 g; + +void +foo (u64 a, u64 b, u64 c, u64 *r) +{ + b *= b; + u64 x = a && ((b >> (c & 63)) | ((b << (c & 63)) & g)); + *r = x + a; +} + +int +main () +{ + u64 x; + foo (1, 3000, 0, &x); + if (x != 2) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index f4a99aca4b4..70ce6a4d5b8 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -1695,7 +1695,8 @@ bit_value_binop (enum tree_code code, signop sgn, int width, /* Logical right shift, or zero sign bit. */ widest_int arg = r1val | r1mask; int lzcount = wi::clz (arg); - lzcount -= wi::get_precision (arg) - width; + if (lzcount) + lzcount -= wi::get_precision (arg) - width; widest_int tmp = wi::mask (width, false); tmp = wi::lrshift (tmp, lzcount); tmp = wi::lrshift (tmp, wi::bit_and_not (r2val, r2mask));