lower-bitint: Fix up handling of uninitialized large/huge _BitInt call arguments [PR113316]
Checks
Commit Message
Hi!
The code to assign large/huge _BitInt SSA_NAMEs to partitions intentionally
ignores uninitialized SSA_NAMEs:
/* Also ignore uninitialized uses. */
if (SSA_NAME_IS_DEFAULT_DEF (s)
&& (!SSA_NAME_VAR (s) || VAR_P (SSA_NAME_VAR (s))))
continue;
because there is no need to store them into memory, all we need is when
trying to extract some limb from them use uninitialized SSA_NAME for the
limb.
The following testcase shows this is a problem for call arguments though,
for those we need to create replacement SSA_NAMEs which are loaded from
the underlying variable. For uninitialized SSA_NAMEs because we didn't
create underlying variable for them var_to_partition doesn't work, the
following patch handles it by just creating an uninitialized replacement
SSA_NAME.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2024-01-12 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/113316
* gimple-lower-bitint.cc (bitint_large_huge::lower_call): Handle
uninitialized large/huge _BitInt arguments to calls.
* gcc.dg/bitint-67.c: New test.
Jakub
Comments
On Fri, 12 Jan 2024, Jakub Jelinek wrote:
> Hi!
>
> The code to assign large/huge _BitInt SSA_NAMEs to partitions intentionally
> ignores uninitialized SSA_NAMEs:
> /* Also ignore uninitialized uses. */
> if (SSA_NAME_IS_DEFAULT_DEF (s)
> && (!SSA_NAME_VAR (s) || VAR_P (SSA_NAME_VAR (s))))
> continue;
> because there is no need to store them into memory, all we need is when
> trying to extract some limb from them use uninitialized SSA_NAME for the
> limb.
>
> The following testcase shows this is a problem for call arguments though,
> for those we need to create replacement SSA_NAMEs which are loaded from
> the underlying variable. For uninitialized SSA_NAMEs because we didn't
> create underlying variable for them var_to_partition doesn't work, the
> following patch handles it by just creating an uninitialized replacement
> SSA_NAME.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK
> 2024-01-12 Jakub Jelinek <jakub@redhat.com>
>
> PR tree-optimization/113316
> * gimple-lower-bitint.cc (bitint_large_huge::lower_call): Handle
> uninitialized large/huge _BitInt arguments to calls.
>
> * gcc.dg/bitint-67.c: New test.
>
> --- gcc/gimple-lower-bitint.cc.jj 2024-01-11 11:46:49.147779946 +0100
> +++ gcc/gimple-lower-bitint.cc 2024-01-11 13:52:46.106182653 +0100
> @@ -5118,14 +5118,23 @@ bitint_large_huge::lower_call (tree obj,
> || TREE_CODE (TREE_TYPE (arg)) != BITINT_TYPE
> || bitint_precision_kind (TREE_TYPE (arg)) <= bitint_prec_middle)
> continue;
> - int p = var_to_partition (m_map, arg);
> - tree v = m_vars[p];
> - gcc_assert (v != NULL_TREE);
> - if (!types_compatible_p (TREE_TYPE (arg), TREE_TYPE (v)))
> - v = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (arg), v);
> - arg = make_ssa_name (TREE_TYPE (arg));
> - gimple *g = gimple_build_assign (arg, v);
> - gsi_insert_before (&gsi, g, GSI_SAME_STMT);
> + if (SSA_NAME_IS_DEFAULT_DEF (arg)
> + && (!SSA_NAME_VAR (arg) || VAR_P (SSA_NAME_VAR (arg))))
> + {
> + tree var = create_tmp_reg (TREE_TYPE (arg));
> + arg = get_or_create_ssa_default_def (cfun, var);
> + }
> + else
> + {
> + int p = var_to_partition (m_map, arg);
> + tree v = m_vars[p];
> + gcc_assert (v != NULL_TREE);
> + if (!types_compatible_p (TREE_TYPE (arg), TREE_TYPE (v)))
> + v = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (arg), v);
> + arg = make_ssa_name (TREE_TYPE (arg));
> + gimple *g = gimple_build_assign (arg, v);
> + gsi_insert_before (&gsi, g, GSI_SAME_STMT);
> + }
> gimple_call_set_arg (stmt, i, arg);
> if (m_preserved == NULL)
> m_preserved = BITMAP_ALLOC (NULL);
> --- gcc/testsuite/gcc.dg/bitint-67.c.jj 2024-01-11 13:54:14.561936065 +0100
> +++ gcc/testsuite/gcc.dg/bitint-67.c 2024-01-11 13:55:09.474162196 +0100
> @@ -0,0 +1,12 @@
> +/* PR tree-optimization/113316 */
> +/* { dg-do compile { target bitint575 } } */
> +/* { dg-options "-std=c23 -O2 -w" } */
> +
> +void bar (_BitInt(535) y);
> +
> +void
> +foo (void)
> +{
> + _BitInt(535) y;
> + bar (y);
> +}
>
> Jakub
>
>
@@ -5118,14 +5118,23 @@ bitint_large_huge::lower_call (tree obj,
|| TREE_CODE (TREE_TYPE (arg)) != BITINT_TYPE
|| bitint_precision_kind (TREE_TYPE (arg)) <= bitint_prec_middle)
continue;
- int p = var_to_partition (m_map, arg);
- tree v = m_vars[p];
- gcc_assert (v != NULL_TREE);
- if (!types_compatible_p (TREE_TYPE (arg), TREE_TYPE (v)))
- v = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (arg), v);
- arg = make_ssa_name (TREE_TYPE (arg));
- gimple *g = gimple_build_assign (arg, v);
- gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+ if (SSA_NAME_IS_DEFAULT_DEF (arg)
+ && (!SSA_NAME_VAR (arg) || VAR_P (SSA_NAME_VAR (arg))))
+ {
+ tree var = create_tmp_reg (TREE_TYPE (arg));
+ arg = get_or_create_ssa_default_def (cfun, var);
+ }
+ else
+ {
+ int p = var_to_partition (m_map, arg);
+ tree v = m_vars[p];
+ gcc_assert (v != NULL_TREE);
+ if (!types_compatible_p (TREE_TYPE (arg), TREE_TYPE (v)))
+ v = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (arg), v);
+ arg = make_ssa_name (TREE_TYPE (arg));
+ gimple *g = gimple_build_assign (arg, v);
+ gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+ }
gimple_call_set_arg (stmt, i, arg);
if (m_preserved == NULL)
m_preserved = BITMAP_ALLOC (NULL);
@@ -0,0 +1,12 @@
+/* PR tree-optimization/113316 */
+/* { dg-do compile { target bitint575 } } */
+/* { dg-options "-std=c23 -O2 -w" } */
+
+void bar (_BitInt(535) y);
+
+void
+foo (void)
+{
+ _BitInt(535) y;
+ bar (y);
+}