diff options
author | Jakub Jelinek <jakub@redhat.com> | 2023-11-29 12:26:50 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2023-11-29 12:26:50 +0100 |
commit | 5c95bf945c632925efba86dd5dceccdb9da8884c (patch) | |
tree | 26f49cc0ce608962c2e20b784eb962d08e679dbc | |
parent | d65eb8a6bbeae7533dd41cb307b427f3f8585d9b (diff) | |
download | gcc-5c95bf945c632925efba86dd5dceccdb9da8884c.zip gcc-5c95bf945c632925efba86dd5dceccdb9da8884c.tar.gz gcc-5c95bf945c632925efba86dd5dceccdb9da8884c.tar.bz2 |
fold-const: Fix up multiple_of_p [PR112733]
We ICE on the following testcase when wi::multiple_of_p is called on
widest_int 1 and -128 with UNSIGNED. I still need to work on the
actual wide-int.cc issue, the latest patch attached to the PR regressed
bitint-{38,39}.c, so will need to debug that, but there is a clear bug
on the fold-const.cc side as well - widest_int is a signed representation
by definition, using UNSIGNED with it certainly doesn't match what was
intended, because -128 as the second operand effectively means unsigned
131072 bit 0xfffff............ffff80 integer, not the signed char -128
that appeared in the source.
In the INTEGER_CST case a few lines above this we already use
case INTEGER_CST:
if (TREE_CODE (bottom) != INTEGER_CST || integer_zerop (bottom))
return false;
return wi::multiple_of_p (wi::to_widest (top), wi::to_widest (bottom),
SIGNED);
so I think using SIGNED with widest_int is best there (compared to the
other choices in the PR).
2023-11-29 Jakub Jelinek <jakub@redhat.com>
PR middle-end/112733
* fold-const.cc (multiple_of_p): Pass SIGNED rather than
UNSIGNED for wi::multiple_of_p on widest_int arguments.
* gcc.dg/pr112733.c: New test.
-rw-r--r-- | gcc/fold-const.cc | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr112733.c | 16 |
2 files changed, 17 insertions, 1 deletions
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index dff09b8..2692b98 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -14563,7 +14563,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom, bool nowrap) && TREE_CODE (op2) == INTEGER_CST && integer_pow2p (bottom) && wi::multiple_of_p (wi::to_widest (op2), - wi::to_widest (bottom), UNSIGNED)) + wi::to_widest (bottom), SIGNED)) return true; op1 = gimple_assign_rhs1 (stmt); diff --git a/gcc/testsuite/gcc.dg/pr112733.c b/gcc/testsuite/gcc.dg/pr112733.c new file mode 100644 index 0000000..d6f99f7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr112733.c @@ -0,0 +1,16 @@ +/* PR middle-end/112733 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +signed char a, c; +short b; + +void +foo (void) +{ + signed char *e = &a; + c = foo != 0; + *e &= c; + for (; b; --b) + *e &= -128; +} |