diff options
author | Jakub Jelinek <jakub@redhat.com> | 2024-09-02 09:44:09 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2024-09-02 09:44:09 +0200 |
commit | 25d51fb7d098a9ac8880ccb2121d889815680177 (patch) | |
tree | efd9e9c0a7b409e1fbcdc200a2fe0ec7b4282ce4 /gcc | |
parent | 9aaedfc4146c5e4b8412913a6ca4092a2731c35c (diff) | |
download | gcc-25d51fb7d098a9ac8880ccb2121d889815680177.zip gcc-25d51fb7d098a9ac8880ccb2121d889815680177.tar.gz gcc-25d51fb7d098a9ac8880ccb2121d889815680177.tar.bz2 |
ranger: Fix up range computation for CLZ [PR116486]
The initial CLZ gimple-range-op.cc implementation handled just the
case where second argument to .CLZ is equal to prec, but in
r15-1014 I've added also handling of the -1 case. As the following
testcase shows, incorrectly though for the case where the first argument
has [0,0] range. If the second argument is prec, then the result should
be [prec,prec] and that was handled correctly, but when the second argument
is -1, the result should be [-1,-1] but instead it was incorrectly computed
as [prec-1,prec-1] (when second argument is prec, mini is 0 and maxi is
prec, while when second argument is -1, mini is -1 and maxi is prec-1).
Fixed thusly (the actual handling is then similar to the CTZ [0,0] case).
2024-09-02 Jakub Jelinek <jakub@redhat.com>
PR middle-end/116486
* gimple-range-op.cc (cfn_clz::fold_range): If lh is [0,0]
and mini is -1, return [-1,-1] range rather than [prec-1,prec-1].
* gcc.dg/bitint-109.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/gimple-range-op.cc | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/bitint-109.c | 25 |
2 files changed, 29 insertions, 2 deletions
diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc index d1c5271..68a7df8 100644 --- a/gcc/gimple-range-op.cc +++ b/gcc/gimple-range-op.cc @@ -972,8 +972,10 @@ cfn_clz::fold_range (irange &r, tree type, const irange &lh, { // If CLZ_DEFINED_VALUE_AT_ZERO is 2 with VALUE of prec, // return [prec, prec] or [-1, -1], otherwise ignore the range. - if (maxi == prec || mini == -1) - mini = maxi; + if (maxi == prec) + mini = prec; + else if (mini == -1) + maxi = -1; } else if (mini >= 0) mini = newmini; diff --git a/gcc/testsuite/gcc.dg/bitint-109.c b/gcc/testsuite/gcc.dg/bitint-109.c new file mode 100644 index 0000000..84c4314 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-109.c @@ -0,0 +1,25 @@ +/* PR middle-end/116486 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-O2 -fno-tree-ccp" } */ + +unsigned u; + +#if __BITINT_MAXWIDTH__ >= 129 +#define N 0x100000000000000000000000000000000uwb +#else +#define N 0xffffffffffffffffuwb +#endif + +int +foo (void) +{ + return __builtin_stdc_first_leading_one (u / N); +} + +int +main () +{ + int x = foo (); + if (x) + __builtin_abort (); +} |