diff options
author | Jakub Jelinek <jakub@redhat.com> | 2021-08-31 10:29:23 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2021-08-31 10:29:23 +0200 |
commit | 06ac981ffb3c0d6997f2e1c01ffaf6253b6a244f (patch) | |
tree | f591a07ea017fb479fc5641299b480a1920062bb /gcc/fortran/trans-openmp.c | |
parent | dd817ccd26fc9b4a961332da68ca62f050d7624d (diff) | |
download | gcc-06ac981ffb3c0d6997f2e1c01ffaf6253b6a244f.zip gcc-06ac981ffb3c0d6997f2e1c01ffaf6253b6a244f.tar.gz gcc-06ac981ffb3c0d6997f2e1c01ffaf6253b6a244f.tar.bz2 |
tree-ssa-ccp: Fix up bit_value_binop on RSHIFT_EXPR [PR102134]
As mentioned in the PR, this hunk is guarded with !wi::neg_p (r1val | r1mask, sgn)
which means if sgn is UNSIGNED, it is always true, but r1val | r1mask in
widest_int is still sign-extended. That means wi::clz (arg) returns 0,
wi::get_precision (arg) returns some very large number
(WIDE_INT_MAX_PRECISION, on x86_64 576 bits) and width is 64, so we end up
with lzcount of -512 where the code afterwards expects a non-negative
lzcount. For arg without the sign bit set the code works right, those
numbers are zero extended and so wi::clz must return wi::get_precision (arg) - width
plus number of leading zero bits within the width precision.
The patch fixes it by handling the sign-extension specially, either it could
be done through wi::neg_p (arg) check, but lzcount == 0 works identically.
2021-08-31 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/102134
* tree-ssa-ccp.c (bit_value_binop) <case RSHIFT_EXPR>: If sgn is
UNSIGNED and r1val | r1mask has MSB set, ensure lzcount doesn't
become negative.
* gcc.c-torture/execute/pr102134.c: New test.
Diffstat (limited to 'gcc/fortran/trans-openmp.c')
0 files changed, 0 insertions, 0 deletions