mirror of
https://forge.sourceware.org/marek/gcc.git
synced 2026-02-22 12:00:11 -05:00
63cd56d487bdea70bf30fb0db8cd4f755338d54b
Shifts are the only special case I'm aware of where the most
significant limb (if it is has padding bits) is accessed inside of a loop or
with access outside of a loop but with variable idx. Everything else should
access the most significant limb using INTEGER_CST idx and thus can (and
should) deal with the needed extension on that access directly.
And RSHIFT_EXPR shouldn't really violate the content of the padding bits.
For LSHIFT_EXPR we should IMHO do the following (which fixes the testcase
on s390x-linux).
The LSHIFT_EXPR is
/* Lower
dst = src << n;
as
unsigned n1 = n % limb_prec;
size_t n2 = n / limb_prec;
size_t n3 = n1 != 0;
unsigned n4 = (limb_prec - n1) % limb_prec;
size_t idx;
size_t p = prec / limb_prec - (prec % limb_prec == 0);
for (idx = p; (ssize_t) idx >= (ssize_t) (n2 + n3); --idx)
dst[idx] = (src[idx - n2] << n1) | (src[idx - n2 - n3] >> n4);
if (n1)
{
dst[idx] = src[idx - n2] << n1;
--idx;
}
for (; (ssize_t) idx >= 0; --idx)
dst[idx] = 0; */
as described in the comment (note, the comments are for the little-endian
lowering only, didn't want to complicate it with endianity).
As can be seen, the most significant limb can be modifier either inside
of the loop or in the if (n1) body if the loop had 0 iterations.
In your patch you've modified I believe just the loop and not the if body,
and made it conditional on every iteration (furthermore through
gimplification of COND_EXPR which is not the way this is done elsewhere in
gimple-lower-bitint.cc, there is if_then helper and it builds
gimple_build_cond etc.). I think that is way too expensive. In theory we
could peel off the first iteration manually and do the info->extended
handling in there and do it again inside of the if (n1) case if idx ==
(bitint_big_endian ? size_zero_node : p) in that case, but I think just
doing the extension after the loops is easier.
Note, we don't need to worry about volatile here, the shift is done into
an addressable variable memory only if it is non-volatile, otherwise it
is computed into a temporary and then copied over into the volatile var.
2025-05-22 Jakub Jelinek <jakub@redhat.com>
* gimple-lower-bitint.cc (bitint_extended): New variable.
(bitint_large_huge::lower_shift_stmt): For LSHIFT_EXPR with
bitint_extended if lhs has most significant partial limb extend
it afterwards.
* gcc.dg/bitintext.h: New file.
* gcc.dg/torture/bitint-82.c: New test.
…
…
…
…
…
…
…
…
…
…
…
…
…
…
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.
Description
Languages
C++
30.7%
C
30%
Ada
14.5%
D
6.1%
Go
5.7%
Other
12.5%