> Am 12.02.2024 um 18:47 schrieb Jakub Jelinek <ja...@redhat.com>:
> 
> Hi!
> 
> handle_cast handles the simple way all narrowing large/huge bitint to
> large/huge bitint conversions and also such widening conversions if we can
> assume that the most significant limb is processed using constant index
> and both lhs and rhs have same number of limbs.
> But, the condition whether we can rely on the most significant limb
> being processed using constant index is incorrect.
> For m_upwards_2limb it was correct (m_upwards_2limb then is the number
> of limbs handled by the loop, so if lhs_type has larger precision than
> that, it is handled with constant index), similarly if m_var_msb is set
> (on left shifts), it is never handled with constant idx.  But in other
> cases, like right shifts or non-equality comparisons, or bitquery operations
> which operate from most significant to least significant limb, all those
> can handle even the most significant limb in a loop when lhs_type has
> precision which is a multiple of limb_prec.
> 
> So, the following patch punts on the optimization in that case and goes for
> the conditionals in the loop for that case.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok

Richard 

> 2024-02-12  Jakub Jelinek  <ja...@redhat.com>
> 
>    PR tree-optimization/113849
>    * gimple-lower-bitint.cc (bitint_large_huge::handle_cast): Don't use
>    fast path for widening casts where !m_upwards_2limb and lhs_type
>    has precision which is a multiple of limb_prec.
> 
>    * gcc.dg/torture/bitint-58.c: New test.
> 
> --- gcc/gimple-lower-bitint.cc.jj    2024-02-10 12:52:10.015925212 +0100
> +++ gcc/gimple-lower-bitint.cc    2024-02-12 14:51:58.717472624 +0100
> @@ -1267,13 +1267,17 @@ bitint_large_huge::handle_cast (tree lhs
>         the most significant limb is handled in straight
>         line code.  If m_var_msb (on left shifts) or
>         if m_upwards_2limb * limb_prec is equal to
> -         lhs precision that is not the case.  */
> +         lhs precision or if not m_upwards_2limb and lhs_type
> +         has precision which is multiple of limb_prec that is
> +         not the case.  */
>      || (!m_var_msb
>          && (CEIL (TYPE_PRECISION (lhs_type), limb_prec)
>          == CEIL (TYPE_PRECISION (rhs_type), limb_prec))
> -          && (!m_upwards_2limb
> -          || (m_upwards_2limb * limb_prec
> -              < TYPE_PRECISION (lhs_type)))))
> +          && ((!m_upwards_2limb
> +           && (TYPE_PRECISION (lhs_type) % limb_prec != 0))
> +          || (m_upwards_2limb
> +              && (m_upwards_2limb * limb_prec
> +              < TYPE_PRECISION (lhs_type))))))
>    {
>      rhs1 = handle_operand (rhs1, idx);
>      if (tree_fits_uhwi_p (idx))
> --- gcc/testsuite/gcc.dg/torture/bitint-58.c.jj    2024-02-12 
> 14:58:42.105944347 +0100
> +++ gcc/testsuite/gcc.dg/torture/bitint-58.c    2024-02-12 14:44:33.280575269 
> +0100
> @@ -0,0 +1,25 @@
> +/* PR tree-optimization/113849 */
> +/* { 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" } { "" } } */
> +
> +signed char c;
> +unsigned _BitInt(512) b;
> +
> +__attribute__((noipa)) void
> +foo (unsigned _BitInt(511) a, int *x)
> +{
> +  int z = (a << 510) <= b;
> +  *x = z + c;
> +}
> +
> +int
> +main ()
> +{
> +  int x;
> +  foo (2, &x);
> +  if (x != 1)
> +    __builtin_abort ();
> +  return 0;
> +}
> 
>    Jakub
> 

Reply via email to