On Thu, 31 Oct 2024, Jakub Jelinek wrote:

> Hi!
> 
> The following testcase ICEs, because when trying to expand the
> VIEW_CONVERT_EXPR operand which is SSA_NAME defined to
> V32QI or V4DI MEM_REF which is aligned just to 8 bytes we force
> it as unaligned into a register, but then try to call extract_bit_field
> from the V32QI or V4DI register to BLKmode.  extract_bit_field doesn't
> obviously support BLKmode extraction and so ICEs.
> 
> The second hunk fixes the ICE by not calling extract_bit_field when
> it can't handle it, the last if will handle it properly by storing
> it to memory and using BLKmode access to the copy.
> 
> The first hunk is an optimization, if mode is BLKmode, by setting
> inner_reference_p argument to expand_expr_real we avoid the
> expand_misaligned_mem_ref calls which load it from memory into a register.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2024-10-31  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR middle-end/117354
>       * expr.cc (expand_expr_real_1) <case VIEW_CONVERT_EXPR>: Pass
>       true as inner_reference_p argument to expand_expr_real if
>       mode is BLKmode.  Don't call extract_bit_field if mode is BLKmode.
> 
>       * gcc.dg/bitint-113.c: New test.
> 
> --- gcc/expr.cc.jj    2024-10-25 10:00:29.450768114 +0200
> +++ gcc/expr.cc       2024-10-30 14:16:58.624455194 +0100
> @@ -12468,7 +12468,7 @@ expand_expr_real_1 (tree exp, rtx target
>  
>        if (!op0)
>       op0 = expand_expr_real (treeop0, NULL_RTX, VOIDmode, modifier,
> -                             NULL, inner_reference_p);
> +                             NULL, inner_reference_p || mode == BLKmode);
>  
>        /* If the input and output modes are both the same, we are done.  */
>        if (mode == GET_MODE (op0))
> @@ -12505,7 +12505,7 @@ expand_expr_real_1 (tree exp, rtx target
>       op0 = convert_modes (mode, GET_MODE (op0), op0,
>                            TYPE_UNSIGNED (TREE_TYPE (treeop0)));
>        /* If the output type is a bit-field type, do an extraction.  */
> -      else if (reduce_bit_field)
> +      else if (reduce_bit_field && mode != BLKmode)
>       return extract_bit_field (op0, TYPE_PRECISION (type), 0,
>                                 TYPE_UNSIGNED (type), NULL_RTX,
>                                 mode, mode, false, NULL);
> --- gcc/testsuite/gcc.dg/bitint-113.c.jj      2024-10-30 14:32:39.153442458 
> +0100
> +++ gcc/testsuite/gcc.dg/bitint-113.c 2024-10-30 14:34:41.036768474 +0100
> @@ -0,0 +1,40 @@
> +/* PR middle-end/117354 */
> +/* { dg-do compile { target bitint } } */
> +/* { dg-options "-O2" } */
> +/* { dg-additional-options "-mavx2" { target x86_64-*-* i?86-*-* } } */
> +
> +#if __BITINT_MAXWIDTH__ >= 256
> +#define N 256
> +#else
> +#define N 64
> +#endif
> +
> +struct S {
> +  unsigned char y;
> +  _BitInt(N) x;
> +} s;
> +
> +__attribute__((noipa)) static void
> +foo (const char *, _BitInt(N))
> +{
> +}
> +
> +__attribute__((noipa)) static void
> +bar (_BitInt(N))
> +{
> +}
> +
> +static void
> +baz (void *p)
> +{
> +  foo ("bazbazbazb", s.x);
> +  __builtin_memcpy (p, &s.x, sizeof s.x);
> +}
> +
> +int
> +main ()
> +{
> +  void *ptr = &s.x;
> +  baz (&s.x);
> +  bar (*(_BitInt(N) *) ptr);
> +}
> 
>       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