aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2023-09-12 12:23:13 +0200
committerJakub Jelinek <jakub@redhat.com>2023-09-12 12:23:13 +0200
commit6067dbdcf77df995129214248f062d9ce18b48d8 (patch)
tree8d214016fea91a7c344333701c2fa373ecce35e9
parent89b5866742a17c38cc98edd9e434cff8e3a3c7ea (diff)
downloadgcc-6067dbdcf77df995129214248f062d9ce18b48d8.zip
gcc-6067dbdcf77df995129214248f062d9ce18b48d8.tar.gz
gcc-6067dbdcf77df995129214248f062d9ce18b48d8.tar.bz2
sccvn: Avoid ICEs on _BitInt load BIT_AND_EXPR mask [PR111338]
The following testcase ICEs, because vn_walk_cb_data::push_partial_def uses a fixed size buffer (64 target bytes) for its construction/deconstruction of partial stores and fails if larger precision than that is needed, and the PR93582 changes assert push_partial_def succeeds (and check the various other conditions much earlier when seeing the BIT_AND_EXPR statement, like CHAR_BIT == 8, BITS_PER_UNIT == 8, BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN, etc.). So, just removing the assert and allowing it fail there doesn't really work and ICEs later on. The following patch moves the bufsize out of the method and tests it together with the other checks. BTW, perhaps we could increase the bufsize as well or in addition to increasing it make the buffer allocated using XALLOCAVEC, but still I think it is useful to have some upper bound and so I think this patch is useful even in that case. 2023-09-12 Jakub Jelinek <jakub@redhat.com> PR middle-end/111338 * tree-ssa-sccvn.cc (struct vn_walk_cb_data): Add bufsize non-static data member. (vn_walk_cb_data::push_partial_def): Remove bufsize variable. (visit_nary_op): Avoid the BIT_AND_EXPR with constant rhs2 optimization if type's precision is too large for vn_walk_cb_data::bufsize. * gcc.dg/bitint-37.c: New test.
-rw-r--r--gcc/testsuite/gcc.dg/bitint-37.c11
-rw-r--r--gcc/tree-ssa-sccvn.cc3
2 files changed, 13 insertions, 1 deletions
diff --git a/gcc/testsuite/gcc.dg/bitint-37.c b/gcc/testsuite/gcc.dg/bitint-37.c
new file mode 100644
index 0000000..23a8f2d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-37.c
@@ -0,0 +1,11 @@
+/* PR middle-end/111338 */
+/* { dg-do compile { target bitint575 } } */
+/* { dg-options "-O1" } */
+
+_BitInt(575) e;
+
+_BitInt(575)
+foo (void)
+{
+ return e & 1;
+}
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index b41bc66..d9487be 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -1903,6 +1903,7 @@ struct vn_walk_cb_data
alias_set_type first_base_set;
splay_tree known_ranges;
obstack ranges_obstack;
+ static constexpr HOST_WIDE_INT bufsize = 64;
};
vn_walk_cb_data::~vn_walk_cb_data ()
@@ -1973,7 +1974,6 @@ vn_walk_cb_data::push_partial_def (pd_data pd,
HOST_WIDE_INT offseti,
HOST_WIDE_INT maxsizei)
{
- const HOST_WIDE_INT bufsize = 64;
/* We're using a fixed buffer for encoding so fail early if the object
we want to interpret is bigger. */
if (maxsizei > bufsize * BITS_PER_UNIT
@@ -5414,6 +5414,7 @@ visit_nary_op (tree lhs, gassign *stmt)
&& CHAR_BIT == 8
&& BITS_PER_UNIT == 8
&& BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
+ && TYPE_PRECISION (type) <= vn_walk_cb_data::bufsize * BITS_PER_UNIT
&& !integer_all_onesp (gimple_assign_rhs2 (stmt))
&& !integer_zerop (gimple_assign_rhs2 (stmt)))
{