[Bug middle-end/105533] UBSAN: gcc/expmed.cc:3272:26: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long int'

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

Jakub Jelinek  changed:

   What|Removed |Added

 Resolution|--- |FIXED
   Assignee|unassigned at gcc dot gnu.org  |jakub at gcc dot gnu.org
 Status|UNCONFIRMED |RESOLVED

--- Comment #14 from Jakub Jelinek  ---
.

[Bug middle-end/105533] UBSAN: gcc/expmed.cc:3272:26: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long int'

2024-03-08 Thread dcb314 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105533

--- Comment #13 from David Binderman  ---
Seems fixed to me. 

I built a bootstrap with ASAN and UBSAN
for languages C, C++ and Fortran and changed the usual
-O2 for -O3 -march=znver3 and the bootstrap passed.

I hadn't realised a bootstrap was such a good test of the compiler.

[Bug middle-end/105533] UBSAN: gcc/expmed.cc:3272:26: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long int'

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

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

https://gcc.gnu.org/g:e1bd0f293d8407d4e8149fbafd470612323dc938

commit r14-9353-ge1bd0f293d8407d4e8149fbafd470612323dc938
Author: Jakub Jelinek 
Date:   Thu Mar 7 10:01:08 2024 +0100

sccvn: Avoid UB in ao_ref_init_from_vn_reference [PR105533]

When compiling libgcc or on e.g.
int a[64];
int p;

void
foo (void)
{
  int s = 1;
  while (p)
{
  s -= 11;
  a[s] != 0;
}
}
sccvn invokes UB in the compiler as detected by ubsan:
../../gcc/poly-int.h:1089:5: runtime error: left shift of negative value
-40
The problem is that we still use C++11..C++17 as the implementation
language
and in those C++ versions shifting negative values left is UB (well defined
since C++20) and above in
   offset += op->off << LOG2_BITS_PER_UNIT;
op->off is poly_int64 with -40 value (in libgcc with -8).
I understand the offset_int << LOG2_BITS_PER_UNIT shifts but it is then
well
defined during underlying implementation which is done on the uhwi limbs,
but for poly_int64 we use
offset += pop->off * BITS_PER_UNIT;
a few lines earlier and I think that is both more readable in what it
actually does and triggers UB only if there would be signed multiply
overflow.  In the end, the compiler will treat them the same at least at
the
RTL level (at least, if not and they aren't the same cost, it should).

2024-03-07  Jakub Jelinek  

PR middle-end/105533
* tree-ssa-sccvn.cc (ao_ref_init_from_vn_reference) :
Multiple op->off by BITS_PER_UNIT instead of shifting it left by
LOG2_BITS_PER_UNIT.

[Bug middle-end/105533] UBSAN: gcc/expmed.cc:3272:26: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long int'

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

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

https://gcc.gnu.org/g:c655c8d8d845b36c59babb2413ce7aa3584dbeda

commit r14-9354-gc655c8d8d845b36c59babb2413ce7aa3584dbeda
Author: Jakub Jelinek 
Date:   Thu Mar 7 10:02:00 2024 +0100

expand: Fix UB in choose_mult_variant [PR105533]

As documented in the function comment, choose_mult_variant attempts to
compute costs of 3 different cases, val, -val and val - 1.
The -val case is actually only done if val fits into host int, so there
should be no overflow, but the val - 1 case is done unconditionally.
val is shwi (but inside of synth_mult already uhwi), so when val is
HOST_WIDE_INT_MIN, val - 1 invokes UB.  The following patch fixes that
by using val - HOST_WIDE_INT_1U, but I'm not really convinced it would
DTRT for > 64-bit modes, so I've guarded it as well.  Though, arch
would need to have really strange costs that something that could be
expressed as x << 63 would be better expressed as (x * 0x7fff)
+ 1
In the long term, I think we should just rewrite
choose_mult_variant/synth_mult etc. to work on wide_int.

2024-03-07  Jakub Jelinek  

PR middle-end/105533
* expmed.cc (choose_mult_variant): Only try the val - 1 variant
if val is not HOST_WIDE_INT_MIN or if mode has exactly
HOST_BITS_PER_WIDE_INT precision.  Avoid triggering UB while
computing
val - 1.

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

[Bug middle-end/105533] UBSAN: gcc/expmed.cc:3272:26: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long int'

2024-03-06 Thread rguenther at suse dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105533

--- Comment #10 from rguenther at suse dot de  ---
On Wed, 6 Mar 2024, jakub at gcc dot gnu.org wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105533
> 
> Jakub Jelinek  changed:
> 
>What|Removed |Added
> 
>  CC||rguenth at gcc dot gnu.org
> 
> --- Comment #7 from Jakub Jelinek  ---
> The second UB is on
> #2  ao_ref_init_from_vn_reference (ref=, set=1, base_set=1,
> type=, ops=...) at ../../gcc/tree-ssa-sccvn.cc:1224
> 1224offset += op->off << LOG2_BITS_PER_UNIT;
> where op->off is negative.
> Isn't this just an unnecessary optimization?  I mean can't we just do
> offset += op->off * BITS_PER_UNIT;
> BITS_PER_UNIT is a constant 8 on all targets we support...

It's a habit from dealing with offset_int (but this is poly_int64)
where the multiply is possibly a lot more costly than a shift.

So yeah, a multiply is fine I guess.

[Bug middle-end/105533] UBSAN: gcc/expmed.cc:3272:26: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long int'

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

--- Comment #9 from Jakub Jelinek  ---
Created attachment 57632
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=57632&action=edit
gcc14-pr105533.patch

Untested fix for the other issue.

[Bug middle-end/105533] UBSAN: gcc/expmed.cc:3272:26: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long int'

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

--- Comment #8 from Jakub Jelinek  ---
The same function already does
offset += pop->off * BITS_PER_UNIT;
a few lines earlier, so I think doing it here is fine as well.
Or yet another option is to cast pop->off or op->off to offset_int first and do
the
left shift in offset_int type where it is well defined.
2024-03-06  Jakub Jelinek  

PR middle-end/105533
* tree-ssa-sccvn.cc (ao_ref_init_from_vn_reference) :
Multiple op->off by BITS_PER_UNIT instead of shifting it left by
LOG2_BITS_PER_UNIT.

--- gcc/tree-ssa-sccvn.cc.jj2024-02-28 22:57:18.318658827 +0100
+++ gcc/tree-ssa-sccvn.cc   2024-03-06 14:52:16.819229719 +0100
@@ -1221,7 +1221,7 @@ ao_ref_init_from_vn_reference (ao_ref *r
  if (maybe_eq (op->off, -1))
max_size = -1;
  else
-   offset += op->off << LOG2_BITS_PER_UNIT;
+   offset += op->off * BITS_PER_UNIT;
  break;

case REALPART_EXPR:

[Bug middle-end/105533] UBSAN: gcc/expmed.cc:3272:26: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long int'

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

Jakub Jelinek  changed:

   What|Removed |Added

 CC||rguenth at gcc dot gnu.org

--- Comment #7 from Jakub Jelinek  ---
The second UB is on
#2  ao_ref_init_from_vn_reference (ref=, set=1, base_set=1,
type=, ops=...) at ../../gcc/tree-ssa-sccvn.cc:1224
1224offset += op->off << LOG2_BITS_PER_UNIT;
where op->off is negative.
Isn't this just an unnecessary optimization?  I mean can't we just do
offset += op->off * BITS_PER_UNIT;
BITS_PER_UNIT is a constant 8 on all targets we support...

[Bug middle-end/105533] UBSAN: gcc/expmed.cc:3272:26: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long int'

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

--- Comment #6 from Jakub Jelinek  ---
Testcase for the first compile time UB (-O3):
long long a, b, c;

void
foo (long long e)
{
  long long d = a & 9223372036854775808ULL;
  c = b;
  if (d && e)
c = c | d;
}
Testcase for the second compile time UB (-O2):
int a[64];
int p;

void
foo (void)
{
  int stack_elt = 1;
  while (p)
{
  stack_elt -= 11;
  a[stack_elt] != 0;
}
}

[Bug middle-end/105533] UBSAN: gcc/expmed.cc:3272:26: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long int'

2024-03-06 Thread dcb314 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105533

--- Comment #5 from David Binderman  ---
The problem with expmed.c happens with -O2 -march=znver3,
so it's more prevalent than I thought.

The problem with poly-int.h seems to require -O3.

So they look like two separate problems.

[Bug middle-end/105533] UBSAN: gcc/expmed.cc:3272:26: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long int'

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

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org

--- Comment #4 from Jakub Jelinek  ---
I see both
/usr/src/gcc/obj5/./gcc/xgcc -B/usr/src/gcc/obj5/./gcc/
-B/usr/local/x86_64-pc-linux-gnu/bin/ -B/usr/local/x86_64-pc-linux-gnu/lib/
-isystem /usr/local/x86_64-pc-linux-gnu/include -isystem
/usr/local/x86_64-pc-linux-gnu/sys-include   -fno-checking -g -O3 -O2  -g -O3
-DIN_GCC   -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual
-Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition  -isystem
./include  -fpic -mlong-double-80 -DUSE_ELF_SYMVER -fcf-protection -mshstk -g
-DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector  -fpic -mlong-double-80
-DUSE_ELF_SYMVER -fcf-protection -mshstk -I. -I. -I../.././gcc
-I../../../libgcc -I../../../libgcc/. -I../../../libgcc/../gcc
-I../../../libgcc/../include -I../../../libgcc/config/libbid
-DENABLE_DECIMAL_BID_FORMAT -DHAVE_CC_TLS  -DUSE_TLS  -o bid128_add.o -MT
bid128_add.o -MD -MP -MF bid128_add.dep -c
../../../libgcc/config/libbid/bid128_add.c
../../gcc/expmed.cc:3288:26: runtime error: signed integer overflow:
-9223372036854775808 - 1 cannot be represented in type 'long int'
/usr/src/gcc/obj5/./gcc/xgcc -B/usr/src/gcc/obj5/./gcc/
-B/usr/local/x86_64-pc-linux-gnu/bin/ -B/usr/local/x86_64-pc-linux-gnu/lib/
-isystem /usr/local/x86_64-pc-linux-gnu/include -isystem
/usr/local/x86_64-pc-linux-gnu/sys-include   -fno-checking -g -O3 -O2  -g -O3
-DIN_GCC   -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual
-Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition  -isystem
./include  -fpic -mlong-double-80 -DUSE_ELF_SYMVER -fcf-protection -mshstk -g
-DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector  -fpic -mlong-double-80
-DUSE_ELF_SYMVER -fcf-protection -mshstk -I. -I. -I../.././gcc
-I../../../libgcc -I../../../libgcc/. -I../../../libgcc/../gcc
-I../../../libgcc/../include -I../../../libgcc/config/libbid
-DENABLE_DECIMAL_BID_FORMAT -DHAVE_CC_TLS  -DUSE_TLS  -o unwind-dw2.o -MT
unwind-dw2.o -MD -MP -MF unwind-dw2.dep -fexceptions -c
../../../libgcc/unwind-dw2.c -fvisibility=hidden -DHIDE_EXPORTS
../../gcc/poly-int.h:1089:5: runtime error: left shift of negative value -8
so will have a look at those.

[Bug middle-end/105533] UBSAN: gcc/expmed.cc:3272:26: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long int'

2024-03-06 Thread dcb314 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105533

--- Comment #3 from David Binderman  ---
Asan, most of the checking flags, fortran and the -march setting not required.

Current configure script is:

../trunk.20210101/configure \
--disable-multilib \
--disable-werror \
--with-pkgversion=$HASH \
--with-build-config=bootstrap-ubsan \
--enable-checking=yes \
--enable-languages=c,c++

sed 's;-O2;-O3;' < Makefile > Makefile.tmp
diff Makefile Makefile.tmp
mv Makefile.tmp Makefile

>From the output of the bootstrap:

Configuring stage 2 in x86_64-pc-linux-gnu/libgcc
../../trunk.20210101/gcc/poly-int.h:1089:5: runtime error: left shift of
negative value -8
../../trunk.20210101/gcc/poly-int.h:1089:5: runtime error: left shift of
negative value -8
../../trunk.20210101/gcc/expmed.cc:3288:26: runtime error: signed integer
overflow: -9223372036854775808 - 1 cannot be represented in type 'long int'
Configuring stage 2 in x86_64-pc-linux-gnu/libgomp

[Bug middle-end/105533] UBSAN: gcc/expmed.cc:3272:26: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long int'

2024-03-05 Thread dcb314 at hotmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105533

David Binderman  changed:

   What|Removed |Added

 CC||dcb314 at hotmail dot com

--- Comment #2 from David Binderman  ---
I see something similar when attempting a bootstrap with asan & ubsan on
current gcc trunk:

gcc/expmed.cc:3288:26: runtime error: signed integer overflow:
-9223372036854775808 - 1 cannot be represented in type 'long int'

Configure is:

../trunk/configure \
--disable-multilib \
--disable-werror \
--with-build-config=bootstrap-asan \
--with-build-config=bootstrap-ubsan \
--enable-checking=df,extra,fold,rtl,yes \
--enable-languages=c,c++,fortran

And there are extra flags added to the top level Makefile:

sed 's;-O2;-O3 -march=native;' < Makefile > Makefile.tmp
diff Makefile Makefile.tmp
mv Makefile.tmp Makefile

I wonder if this is a regression for gcc-14.

[Bug middle-end/105533] UBSAN: gcc/expmed.cc:3272:26: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long int'

2022-10-30 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105533

Andrew Pinski  changed:

   What|Removed |Added

  Component|tree-optimization   |middle-end
 Target||x86_64-pc-linux-gnu
   Host|x86_64-pc-linux-gnu |

--- Comment #1 from Andrew Pinski  ---
choose_mult_variant (machine_mode mode, HOST_WIDE_INT val,

...
  synth_mult (&alg2, val - 1, &limit, mode);


But slsr should not be processing any of these IR I don't think.

  _7 = _4 *  Inf;
  c$imag_8 = (long intD.8) _7;
  # VUSE <.MEM_16>
  i.1_9 = iD.1980;
  # RANGE [-2147483648, 2147483647]
  _10 = (long intD.8) i.1_9;
  c$real_23 = c$real_6 * _10;
  c$imag_24 = c$imag_8 * _10;

Huh? This does not make sense at all.
  float _4;
  float _7;

  if (tree_fits_shwi_p (rhs2))
return mult_by_coeff_cost (tree_to_shwi (rhs2), lhs_mode, speed);

But I don't see that even call that.
bool
tree_fits_shwi_p (const_tree t)
{
  return (t != NULL_TREE
  && TREE_CODE (t) == INTEGER_CST
  && wi::fits_shwi_p (wi::to_widest (t)));
}