Find a file
Jakub Jelinek b57d7ef4bd bitintlower: Fix up handling of nested casts in m_upward_2limbs cases [PR119707]
The following testcase is miscompiled I believe starting with
PR112941 r14-6742.  That commit fixed the bitint-55.c testcase.
The m_first initialization for such conversion initializes 2 SSA_NAMEs,
one is PHI result on the loop (m_data[save_data_cnt]) and the other
(m_data[save_data_cnt+1]) is the argument of that PHI from the latch
edge initialized somewhere in the loop.  Both of these are used to
propagate sign extension (i.e. either 0 or all ones limb) from the
iteration with the sign bit of a narrower type to following iterations.
The bitint-55.c testcase was ICEing with invalid SSA forms as it was
using unconditionally the PHI argument SSA_NAME even in places which
weren't dominated by that.  And the code which was touched is about
handling constant idx, so if e.g. there are nested casts and the
outer one does conditional code based on index comparison with
a particular constant index.
In the following testcase there are 2 nested casts, one from signed
_BitInt(129) to unsigned _BitInt(255) and the outer from unsigned
_BitInt(255) to unsigned _BitInt(256).  The m_upward_2limbs case which
is used for handling mergeable arithmetics (like +-|&^ and casts etc.)
one loop iteration handles 2 limbs, the first half the even ones, the
second half the odd ones.
And for these 2 conversions, the special one for the inner conversion
on x86_64 is with index 2 where the sign bit of _BitInt(129) is present,
while for the outer one index 3 where we need to mask off the most
significant bit.
The r15-6742 change started using m_data[save_data_cnt] for all constant
indexes if it is still inside of the loop (and it is sign extension).
But that doesn't work correctly for the case where the inner conversion
produces the sign extension limb in the loop for an even index and
the outer conversion needs to special case the immediately next conversion,
because in that case using the PHI result will see still 0 there rather
than the updated value from the handling of previous limb.
So the following patch special cases this and uses the other SSA_NAME.

Commented IL, trying to lower
  _1 = (unsigned _BitInt(255)) y_4(D);
  _2 = (unsigned _BitInt(256)) _1;
  _3 = _2 + x_5(D);
  <retval> = _3;
we were emitting
  <bb 3> [local count: 1073741824]:
  # _8 = PHI <0(2), _9(12)>     // This is the limb index
  # _10 = PHI <0(2), _11(12)>   // Sign extension limb from inner cast (0 or ~0UL)
  # _22 = PHI <0(2), _23(12)>   // Overflow bit from addition of previous limb
  if (_8 <= 2)
    goto <bb 4>; [80.00%]
  else
    goto <bb 7>; [20.00%]

  <bb 4> [local count: 1073741824]:
  if (_8 == 2)
    goto <bb 6>; [20.00%]
  else
    goto <bb 5>; [80.00%]

  <bb 5> [local count: 1073741824]:
  _12 = VIEW_CONVERT_EXPR<unsigned long[3]>(y)[_8];     // Full limbs in y
  goto <bb 7>; [100.00%]

  <bb 6> [local count: 214748360]:
  _13 = MEM <unsigned long> [(_BitInt(129) *)&y + 16B]; // y[2] which
  _14 = (<unnamed-signed:1>) _13;                       // needs to be
  _15 = (unsigned long) _14;                            // sign extended
  _16 = (signed long) _15;                              // to full
  _17 = _16 >> 63;                                      // limb
  _18 = (unsigned long) _17;

  <bb 7> [local count: 1073741824]:
  # _19 = PHI <_12(5), _10(3), _15(6)>  // Limb to add for result of casts
  # _20 = PHI <0(5), _10(3), _18(6)>    // Sign extension limb from previous limb
  _11 = _20;                            // PHI _10 argument above
  _21 = VIEW_CONVERT_EXPR<unsigned long[4]>(x)[_8];
  _24 = .UADDC (_19, _21, _22);
  _25 = IMAGPART_EXPR <_24>;
  _26 = REALPART_EXPR <_24>;
  VIEW_CONVERT_EXPR<unsigned long[4]>(<retval>)[_8] = _26;
  _27 = _8 + 1;
  if (_27 == 3)                 // For the outer cast limb 3 is special
    goto <bb 11>; [20.00%]
  else
    goto <bb 8>; [80.00%]

  <bb 8> [local count: 1073741824]:
  if (_27 < 2)
    goto <bb 9>; [80.00%]
  else
    goto <bb 10>; [20.00%]

  <bb 9> [local count: 1073741824]:
  _28 = VIEW_CONVERT_EXPR<unsigned long[3]>(y)[_27];    // These are used in full

  <bb 10> [local count: 1073741824]:
  # _29 = PHI <_28(9), _11(8)>
  goto <bb 12>; [100.00%]

  <bb 11> [local count: 214748360]:
// And HERE is the actual bug.  Using _10 for idx 3 will mean it is always
// zero there and doesn't contain the _18 value propagated to it.
// It should be
// _30 = (<unnamed-unsigned:63>) _11;
// Now if the outer conversion had special iteration say 5, we could
// have used _10 fine here, by that time it already propagates through
// the PHI.
  _30 = (<unnamed-unsigned:63>) _10;
  _31 = (unsigned long) _30;

  <bb 12> [local count: 1073741824]:
  # _32 = PHI <_29(10), _31(11)>
  _33 = VIEW_CONVERT_EXPR<unsigned long[4]>(x)[_27];
  _34 = .UADDC (_32, _33, _25);
  _23 = IMAGPART_EXPR <_34>;
  _35 = REALPART_EXPR <_34>;
  VIEW_CONVERT_EXPR<unsigned long[4]>(<retval>)[_27] = _35;
  _9 = _8 + 2;
  if (_9 != 4)
    goto <bb 3>; [0.05%]
  else
    goto <bb 13>; [99.95%]

2025-04-11  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/119707
	* gimple-lower-bitint.cc (bitint_large_huge::handle_cast): Only use
	m_data[save_data_cnt] instead of m_data[save_data_cnt + 1] if
	idx is odd and equal to low + 1.  Remember tree_to_uhwi (idx) in
	a temporary instead of calling the function multiple times.

	* gcc.dg/torture/bitint-76.c: New test.
2025-04-11 08:27:55 +02:00
.forgejo top-level: Add pull request template for Forgejo 2024-10-23 19:45:09 +01:00
.github
c++tools Update copyright years. 2025-01-02 11:59:57 +01:00
config Daily bump. 2024-11-26 00:19:26 +00:00
contrib Daily bump. 2025-03-28 00:19:00 +00:00
fixincludes Daily bump. 2024-07-12 00:17:52 +00:00
gcc bitintlower: Fix up handling of nested casts in m_upward_2limbs cases [PR119707] 2025-04-11 08:27:55 +02:00
gnattools Daily bump. 2025-04-02 00:18:25 +00:00
gotools Daily bump. 2024-04-16 00:18:06 +00:00
include Daily bump. 2025-03-30 00:16:46 +00:00
INSTALL
libada Update copyright years. 2025-01-02 11:59:57 +01:00
libatomic Daily bump. 2025-01-11 00:19:49 +00:00
libbacktrace Daily bump. 2025-04-11 00:17:32 +00:00
libcc1 Update copyright years. 2025-01-02 11:59:57 +01:00
libcody Update Copyright year in ChangeLog files 2025-01-02 11:13:18 +01:00
libcpp Daily bump. 2025-04-10 00:18:06 +00:00
libdecnumber Update copyright years. 2025-01-02 11:59:57 +01:00
libffi Daily bump. 2024-10-26 00:19:39 +00:00
libgcc Daily bump. 2025-04-09 00:18:02 +00:00
libgcobol Daily bump. 2025-04-11 00:17:32 +00:00
libgfortran Daily bump. 2025-04-10 00:18:06 +00:00
libgm2 Daily bump. 2025-03-29 00:17:59 +00:00
libgo libgo: bump libgo version for GCC 15 release 2025-03-04 11:43:22 -08:00
libgomp Daily bump. 2025-04-11 00:17:32 +00:00
libgrust Daily bump. 2025-04-01 00:19:09 +00:00
libiberty Daily bump. 2025-03-30 00:16:46 +00:00
libitm Daily bump. 2025-01-03 00:17:15 +00:00
libobjc Update copyright years. 2025-01-02 11:59:57 +01:00
libphobos Daily bump. 2025-04-09 00:18:02 +00:00
libquadmath Daily bump. 2025-04-10 00:18:06 +00:00
libsanitizer Daily bump. 2025-01-07 00:18:08 +00:00
libssp Update copyright years. 2025-01-02 11:59:57 +01:00
libstdc++-v3 Daily bump. 2025-04-11 00:17:32 +00:00
libvtv Update copyright years. 2025-01-02 11:59:57 +01:00
lto-plugin Daily bump. 2025-03-07 00:17:19 +00:00
maintainer-scripts Daily bump. 2025-04-08 00:17:33 +00:00
zlib
.b4-config Add config file so b4 uses inbox.sourceware.org automatically 2024-07-28 11:13:16 +01:00
.dir-locals.el dir-locals: apply our C settings in C++ also 2024-07-31 20:38:27 +02:00
.gitattributes
.gitignore gccrs: git: Ignore libgrust build folders 2025-03-17 16:35:21 +01:00
ABOUT-NLS
ar-lib
ChangeLog Daily bump. 2025-04-03 00:18:15 +00:00
ChangeLog.jit
ChangeLog.tree-ssa
compile
config-ml.in Remove extra argument from subst macro 2025-03-13 07:26:04 +01:00
config.guess
config.rpath
config.sub
configure config, toplevel, Darwin: Pass -B instead of -L to C++ commands. 2025-04-02 15:04:37 +01:00
configure.ac config, toplevel, Darwin: Pass -B instead of -L to C++ commands. 2025-04-02 15:04:37 +01:00
COPYING
COPYING.LIB
COPYING.RUNTIME
COPYING3
COPYING3.LIB
depcomp
install-sh
libtool-ldflags
libtool.m4
ltgcc.m4
ltmain.sh ltmain.sh: allow more flags at link-time 2024-09-25 19:05:24 +01:00
ltoptions.m4
ltsugar.m4
ltversion.m4
lt~obsolete.m4
MAINTAINERS MAINTAINERS: Update my name 2025-03-31 23:35:29 +01:00
Makefile.def toplevel, libcobol: Add dependency on libquadmath build [PR119244]. 2025-03-25 19:31:10 +00:00
Makefile.in toplevel, libcobol: Add dependency on libquadmath build [PR119244]. 2025-03-25 19:31:10 +00:00
Makefile.tpl toplevel, Makefile: Add missing CXX_FOR_TARGET export [PR88319]. 2025-03-23 20:44:33 +00:00
missing
mkdep
mkinstalldirs
move-if-change
multilib.am
README
SECURITY.txt Remove Debian from SECURITY.txt 2024-11-19 12:27:33 +01:00
symlink-tree
test-driver
ylwrap

This directory contains the GNU Compiler Collection (GCC).

The GNU Compiler Collection is free software.  See the files whose
names start with COPYING for copying permission.  The manuals, and
some of the runtime libraries, are under different terms; see the
individual source files for details.

The directory INSTALL contains copies of the installation information
as HTML and plain text.  The source of this information is
gcc/doc/install.texi.  The installation information includes details
of what is included in the GCC sources and what files GCC installs.

See the file gcc/doc/gcc.texi (together with other files that it
includes) for usage and porting information.  An online readable
version of the manual is in the files gcc/doc/gcc.info*.

See http://gcc.gnu.org/bugs/ for how to report bugs usefully.

Copyright years on GCC source files may be listed using range
notation, e.g., 1987-2012, indicating that every year in the range,
inclusive, is a copyrightable year that could otherwise be listed
individually.