diff options
author | Jakub Jelinek <jakub@redhat.com> | 2024-01-27 13:06:55 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2024-01-27 13:06:55 +0100 |
commit | a12b0e9360e88fceb0414bfb34c8c1ad87c5ac90 (patch) | |
tree | 0595a7cebd40bf1d755ac82e6a128129dad47c21 /gcc/tree.cc | |
parent | 3f5ac4696351c352980f8cd1b063df89894549c2 (diff) | |
download | gcc-a12b0e9360e88fceb0414bfb34c8c1ad87c5ac90.zip gcc-a12b0e9360e88fceb0414bfb34c8c1ad87c5ac90.tar.gz gcc-a12b0e9360e88fceb0414bfb34c8c1ad87c5ac90.tar.bz2 |
lower-bitint: Avoid sign-extending cast to unsigned types feeding div/mod/float [PR113614]
The following testcase is miscompiled, because some narrower value
is sign-extended to wider unsigned _BitInt used as division operand.
handle_operand_addr for that case returns the narrower value and
precision -prec_of_narrower_value. That works fine for multiplication
(at least, normal multiplication, but we don't merge casts with
.MUL_OVERFLOW or the ubsan multiplication right now), because the
result is the same whether we treat the arguments as signed or unsigned.
But is completely wrong for division/modulo or conversions to
floating-point, if we pass negative prec for an input operand of a libgcc
handler, those treat it like a negative number, not an unsigned one
sign-extended from something smaller (and it doesn't know to what precision
it has been extended).
So, the following patch fixes it by making sure we don't merge such
sign-extensions to unsigned _BitInt type with division, modulo or
conversions to floating point.
2024-01-27 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/113614
* gimple-lower-bitint.cc (gimple_lower_bitint): Don't merge
widening casts from signed to unsigned types with TRUNC_DIV_EXPR,
TRUNC_MOD_EXPR or FLOAT_EXPR uses.
* gcc.dg/torture/bitint-54.c: New test.
Diffstat (limited to 'gcc/tree.cc')
0 files changed, 0 insertions, 0 deletions