[Bug middle-end/113722] [14 Regression] Constant folding of __builtin_bswap128 is broken since r14-1455

2024-02-03 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113722

Jakub Jelinek  changed:

   What|Removed |Added

 Status|ASSIGNED|RESOLVED
 Resolution|--- |FIXED

--- Comment #6 from Jakub Jelinek  ---
Fixed.

[Bug middle-end/113722] [14 Regression] Constant folding of __builtin_bswap128 is broken since r14-1455

2024-02-03 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113722

--- Comment #5 from GCC Commits  ---
The master branch has been updated by Jakub Jelinek :

https://gcc.gnu.org/g:09df058a09f888daad26fa80634068b38b4ad04d

commit r14-8776-g09df058a09f888daad26fa80634068b38b4ad04d
Author: Jakub Jelinek 
Date:   Sat Feb 3 14:38:27 2024 +0100

wide-int: Fix up wi::bswap_large [PR113722]

Since bswap has been converted from a method to a function we miscompile
the following testcase.  The problem is the assumption that the passed in
len argument (number of limbs in the xval array) is the upper bound for the
bswap result, which is true only if precision is <= 64.  If precision is
larger than that, e.g. 128 as in the testcase, if the argument has only
one limb (i.e. 0 to ~(unsigned HOST_WIDE_INT) 0), the result can still
need 2 limbs for that precision, or generally BLOCKS_NEEDED (precision)
limbs, it all depends on how many least significant limbs of the operand
are zero.  bswap_large as implemented only cleared len limbs of result,
then swapped the bytes (invoking UB when oring something in all the limbs
above it) and finally passed len to canonize, saying that more limbs
aren't needed.

The following patch fixes it by renaming len to xlen (so that it is clear
it is X's length), using it solely for safe_uhwi argument when we attempt
to read from X, and using new len = BLOCKS_NEEDED (precision) instead in
the other two spots (i.e. when clearing the val array, turned it also
into memset, and in canonize argument).  wi::bswap asserts it isn't invoked
on widest_int, so we are always invoked on wide_int or similar and those
have preallocated result sized for the corresponding precision (i.e.
BLOCKS_NEEDED (precision)).

2024-02-03  Jakub Jelinek  

PR middle-end/113722
* wide-int.cc (wi::bswap_large): Rename third argument from
len to xlen and adjust use in safe_uhwi.  Add len variable, set
it to BLOCKS_NEEDED (precision) and use it for clearing of val
and as canonize argument.  Clear val using memset instead of
a loop.

* gcc.dg/pr113722.c: New test.

[Bug middle-end/113722] [14 Regression] Constant folding of __builtin_bswap128 is broken since r14-1455

2024-02-02 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113722

--- Comment #4 from Jakub Jelinek  ---
Created attachment 57296
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=57296=edit
gcc14-pr113722.patch

Untested fix.

[Bug middle-end/113722] [14 Regression] Constant folding of __builtin_bswap128 is broken since r14-1455

2024-02-02 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113722

Jakub Jelinek  changed:

   What|Removed |Added

Summary|[14 Regression] Constant|[14 Regression] Constant
   |folding of  |folding of
   |__builtin_bswap128 is   |__builtin_bswap128 is
   |broken  |broken since r14-1455
 Status|NEW |ASSIGNED
   Assignee|unassigned at gcc dot gnu.org  |jakub at gcc dot gnu.org
   Priority|P3  |P1

--- Comment #3 from Jakub Jelinek  ---
Anyway, at -O0
int
main ()
{
  unsigned __int128 a = __builtin_bswap128 ((unsigned __int128) 2);
  unsigned __int128 b = 2;
  unsigned __int128 c = __builtin_bswap128 (b);
  if (a != c)
__builtin_abort ();
}
regressed with r14-1455-g0ede6b5ad77c4791a513ab312b9e278dafc2bff9
I'll have a look.

[Bug middle-end/113722] [14 Regression] Constant folding of __builtin_bswap128 is broken

2024-02-02 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113722

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org

--- Comment #2 from Jakub Jelinek  ---
The #c0 testcase is broken, res >> 64 has still __uint128_t type, so you
shouldn't pass it to %ld format specifier.

[Bug middle-end/113722] [14 Regression] Constant folding of __builtin_bswap128 is broken

2024-02-02 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113722

Andrew Pinski  changed:

   What|Removed |Added

  Component|regression  |middle-end
 Ever confirmed|0   |1
   Last reconfirmed||2024-02-02
Summary|Folding of  |[14 Regression] Constant
   |__builtin_bswap128 doesn't  |folding of
   |work anymore|__builtin_bswap128 is
   ||broken
   Keywords||wrong-code
 Status|UNCONFIRMED |NEW
   Target Milestone|--- |14.0

--- Comment #1 from Andrew Pinski  ---
Simplified testcase:
```
#define constant 2
int main() {
__uint128_t res = __builtin_bswap128 ((__uint128_t)constant);
__uint128_t t = constant;
__uint128_t res1 = __builtin_bswap128 (t);
if (res != res1)
  __builtin_abort();
}
```