[Bug tree-optimization/113370] wrong code with shift and _BitInt() at -O0

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

Jakub Jelinek  changed:

   What|Removed |Added

 Status|ASSIGNED|RESOLVED
   Target Milestone|--- |14.0
 Resolution|--- |FIXED

--- Comment #4 from Jakub Jelinek  ---
Fixed, thanks for the report.

[Bug tree-optimization/113370] wrong code with shift and _BitInt() at -O0

2024-01-15 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113370

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

https://gcc.gnu.org/g:8a1927856a10c5ff1b86504c345c8be449b53c30

commit r14-7239-g8a1927856a10c5ff1b86504c345c8be449b53c30
Author: Jakub Jelinek 
Date:   Mon Jan 15 09:58:37 2024 +0100

lower-bitint: Fix up handling of INTEGER_CSTs in handle_operand in right
shifts or comparisons [PR113370]

The INTEGER_CST code uses the remainder bits in computations whether to use
whole constant or just part of it and extend it at runtime, and furthermore
uses it to avoid using all bits even when using the (almost) whole
constant.
The problem is that the prec % (2 * limb_prec) computation it uses is
appropriate only for the normal lowering of mergeable operations (where
we process 2 limbs at a time in a loop starting with least significant
limbs and process the remaining 0-2 limbs after the loop (there with
constant indexes).  For that case it is ok not to emit the upper
prec % (2 * limb_prec) bits into the constant, because those bits will be
extracted using INTEGER_CST idx and so will be used directly in the
statements as INTEGER_CSTs.
For other cases, where we either process just a single limb in a loop,
process it downwards (e.g. non-equality comparisons) or with some runtime
addends (some shifts), there is either just at most one limb lowered with
INTEGER_CST idx after the loop (e.g. for right shift) or before the loop
(e.g. non-equality comparisons), or all limbs are processed with
non-INTEGER_CST indexes (e.g. for left shift, when m_var_msb is set).
Now, the m_var_msb case is already handled through
  if (m_var_msb)
type = TREE_TYPE (op);
  else
/* If we have a guarantee the most significant partial limb
   (if any) will be only accessed through handle_operand
   with INTEGER_CST idx, we don't need to include the
partial
   limb in .rodata.  */
type = build_bitint_type (prec - rem, 1);
but for the right shifts or comparisons the prec - rem when rem was
prec % (2 * limb_prec) was incorrect, so the following patch fixes it
to use remainder for 2 limbs only if m_upwards_2limb and remainder for
1 limb otherwise.

2024-01-15  Jakub Jelinek  

PR tree-optimization/113370
* gimple-lower-bitint.cc (bitint_large_huge::handle_operand): Only
set rem to prec % (2 * limb_prec) if m_upwards_2limb, otherwise
set it to just prec % limb_prec.

* gcc.dg/torture/bitint-48.c: New test.

[Bug tree-optimization/113370] wrong code with shift and _BitInt() at -O0

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

Jakub Jelinek  changed:

   What|Removed |Added

   Assignee|unassigned at gcc dot gnu.org  |jakub at gcc dot gnu.org
 Status|NEW |ASSIGNED

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

Untested fix.

[Bug tree-optimization/113370] wrong code with shift and _BitInt() at -O0

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

Andrew Pinski  changed:

   What|Removed |Added

 Ever confirmed|0   |1
   Last reconfirmed||2024-01-13
 Status|UNCONFIRMED |NEW

--- Comment #1 from Andrew Pinski  ---
Confirmed.

Testcase which shows what something is wrong with the original value:
```
typedef _BitInt(255) B;

[[gnu::noipa]]
B
foo(int s)
{
  B a = 0;
  a = (-(B)3) >> s;
  return a;
}

int
main(void)
{
  B x = foo(51);
  unsigned long *a = (unsigned long *)
  __builtin_printf("%lx\n", a[0]);
  __builtin_printf("%lx\n", a[1]);
  __builtin_printf("%lx\n", a[2]);
  __builtin_printf("%lx\n", a[3]);
  //if (x != -1)
  //  __builtin_abort();
  return 0;
}
```