On Wed, 17 Jan 2024, Jakub Jelinek wrote:

> Hi!
> 
> The following testcase is miscompiled because the bitint lowering emits a
>   .MULBITINT (&a, 1024, &a, 1024, &x, 1024);
> call.  The bug is in the overlap between the destination and source, that is
> something the libgcc routines don't handle, they use the source arrays
> during the entire algorithms which computes the destination array(s).
> For the mapping of SSA_NAMEs to VAR_DECLs the code already supports that
> correctly, but the checking whether a load from memory can be used directly
> without a temporary even when earlier we decided to merge the
> multiplication/division/modulo etc. with a store didn't.
> 
> The following patch implements that.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

> 2024-01-17  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR tree-optimization/113421
>       * gimple-lower-bitint.cc (stmt_needs_operand_addr): Adjust function
>       comment.
>       (bitint_dom_walker::before_dom_children): Add g temporary to simplify
>       formatting.  Start at vop rather than cvop even if stmt is a store
>       and needs_operand_addr.
> 
>       * gcc.dg/torture/bitint-50.c: New test.
> 
> --- gcc/gimple-lower-bitint.cc.jj     2024-01-16 12:32:56.617721208 +0100
> +++ gcc/gimple-lower-bitint.cc        2024-01-16 17:33:04.046476302 +0100
> @@ -5455,7 +5455,8 @@ vuse_eq (ao_ref *, tree vuse1, void *dat
>  
>  /* Return true if STMT uses a library function and needs to take
>     address of its inputs.  We need to avoid bit-fields in those
> -   cases.  */
> +   cases.  Similarly, we need to avoid overlap between destination
> +   and source limb arrays.  */
>  
>  bool
>  stmt_needs_operand_addr (gimple *stmt)
> @@ -5574,7 +5575,8 @@ bitint_dom_walker::before_dom_children (
>         else if (!bitmap_bit_p (m_loads, SSA_NAME_VERSION (s)))
>           continue;
>  
> -       tree rhs1 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (s));
> +       gimple *g = SSA_NAME_DEF_STMT (s);
> +       tree rhs1 = gimple_assign_rhs1 (g);
>         if (needs_operand_addr
>             && TREE_CODE (rhs1) == COMPONENT_REF
>             && DECL_BIT_FIELD_TYPE (TREE_OPERAND (rhs1, 1)))
> @@ -5596,15 +5598,14 @@ bitint_dom_walker::before_dom_children (
>  
>         ao_ref ref;
>         ao_ref_init (&ref, rhs1);
> -       tree lvop = gimple_vuse (SSA_NAME_DEF_STMT (s));
> +       tree lvop = gimple_vuse (g);
>         unsigned limit = 64;
>         tree vuse = cvop;
>         if (vop != cvop
>             && is_gimple_assign (stmt)
>             && gimple_store_p (stmt)
> -           && !operand_equal_p (lhs,
> -                                gimple_assign_rhs1 (SSA_NAME_DEF_STMT (s)),
> -                                0))
> +           && (needs_operand_addr
> +               || !operand_equal_p (lhs, gimple_assign_rhs1 (g), 0)))
>           vuse = vop;
>         if (vuse != lvop
>             && walk_non_aliased_vuses (&ref, vuse, false, vuse_eq,
> --- gcc/testsuite/gcc.dg/torture/bitint-50.c.jj       2024-01-16 
> 17:35:16.084622119 +0100
> +++ gcc/testsuite/gcc.dg/torture/bitint-50.c  2024-01-16 17:35:06.701753879 
> +0100
> @@ -0,0 +1,31 @@
> +/* PR tree-optimization/113421 */
> +/* { dg-do run { target bitint } } */
> +/* { dg-options "-std=c23 -pedantic-errors" } */
> +/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
> +/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */
> +
> +#if __BITINT_MAXWIDTH__ >= 1024
> +unsigned _BitInt(1024) a = -5wb;
> +
> +__attribute__((noipa)) void
> +foo (unsigned _BitInt(1024) x)
> +{
> +  a *= x;
> +}
> +#else
> +int a = 30;
> +
> +void
> +foo (int)
> +{
> +}
> +#endif
> +
> +int
> +main ()
> +{
> +  foo (-6wb);
> +  if (a != 30wb)
> +    __builtin_abort ();
> +  return 0;
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to