aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2024-01-27 13:06:17 +0100
committerJakub Jelinek <jakub@redhat.com>2024-01-27 13:06:17 +0100
commit3f5ac4696351c352980f8cd1b063df89894549c2 (patch)
tree1dab95aa6e86bb569396c9475113a6ac2e43be33 /gcc
parent675e522903825d41230fcbcafaf7d640205179f4 (diff)
downloadgcc-3f5ac4696351c352980f8cd1b063df89894549c2.zip
gcc-3f5ac4696351c352980f8cd1b063df89894549c2.tar.gz
gcc-3f5ac4696351c352980f8cd1b063df89894549c2.tar.bz2
lower-bitint: Fix up VIEW_CONVERT_EXPR handling in lower_mergeable_stmt [PR113568]
We generally allow merging mergeable stmts with some final cast (but not further casts or mergeable operations after the cast). As some casts are handled conditionally, if (idx < cst) handle_operand (idx); else if idx == cst) handle_operand (cst); else ..., we must sure that e.g. the mergeable PLUS_EXPR/MINUS_EXPR/NEGATE_EXPR never appear in handle_operand called from such casts, because it ICEs on invalid SSA_NAME form (that part could be fixable by adding further PHIs) but also because we'd need to correctly propagate the overflow flags from the if to else if. So, instead lower_mergeable_stmt handles an outermost widening cast (or widening cast feeding outermost store) specially. The problem was similar to PR113408, that VIEW_CONVERT_EXPR tree is present in the gimple_assign_rhs1 while it is not for NOP_EXPR/CONVERT_EXPR, so the checks whether the outermost cast should be handled didn't handle the VCE case and so handle_plus_minus was called from the conditional handle_cast. 2024-01-27 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/113568 * gimple-lower-bitint.cc (bitint_large_huge::lower_mergeable_stmt): For VIEW_CONVERT_EXPR use first operand of rhs1 instead of rhs1 in the widening extension checks. * gcc.dg/bitint-78.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gimple-lower-bitint.cc2
-rw-r--r--gcc/testsuite/gcc.dg/bitint-78.c21
2 files changed, 23 insertions, 0 deletions
diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc
index 79e3b55..6a7ce0c 100644
--- a/gcc/gimple-lower-bitint.cc
+++ b/gcc/gimple-lower-bitint.cc
@@ -2401,6 +2401,8 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code,
rhs1 = gimple_assign_rhs1 (store_operand
? SSA_NAME_DEF_STMT (store_operand)
: stmt);
+ if (TREE_CODE (rhs1) == VIEW_CONVERT_EXPR)
+ rhs1 = TREE_OPERAND (rhs1, 0);
/* Optimize mergeable ops ending with widening cast to _BitInt
(or followed by store). We can lower just the limbs of the
cast operand and widen afterwards. */
diff --git a/gcc/testsuite/gcc.dg/bitint-78.c b/gcc/testsuite/gcc.dg/bitint-78.c
new file mode 100644
index 0000000..6c08757
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-78.c
@@ -0,0 +1,21 @@
+/* PR tree-optimization/113568 */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-O2 -std=c23" } */
+
+signed char c;
+#if __BITINT_MAXWIDTH__ >= 464
+_BitInt(464) g;
+
+void
+foo (void)
+{
+ _BitInt(464) a[2] = {};
+ _BitInt(464) b;
+ while (c)
+ {
+ b = g + 1;
+ g = a[0];
+ a[0] = b;
+ }
+}
+#endif