[Bug middle-end/105533] UBSAN: gcc/expmed.cc:3272:26: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long int'
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'
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'
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'
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'
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'
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'
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'
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'
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'
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'
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'
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'
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'
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))); }