https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108489

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2023-01-23
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
Hmm, I get a crash in

  poly_int64 decl_bitsize;
  if (mode == VOIDmode
      || (mode != BLKmode && ! direct_store[(int) mode]
          && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
          && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
      || REG_P (target)
      || GET_CODE (target) == SUBREG
      /* If the field isn't aligned enough to store as an ordinary memref,
         store it as a bit field.  */
      || (mode != BLKmode
          && ((((MEM_ALIGN (target) < GET_MODE_ALIGNMENT (mode))
                || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode)))
               && targetm.slow_unaligned_access (mode, MEM_ALIGN (target)))
              || !multiple_p (bitpos, BITS_PER_UNIT)))

because we access MEM_ALIGN (target) on

(parallel:TI [
        (expr_list:REG_DEP_TRUE (reg:SI 83 [ <retval> ])
            (const_int 0 [0]))
        (expr_list:REG_DEP_TRUE (reg:DI 84 [ <retval>+8 ])
            (const_int 8 [0x8]))
    ])

looks like we don't expect a PARALLEL target here at all (the else expects a
MEM), then we should test that, or the caller needs to handle this.  If
I simply adjust the guard with the following I get

diff --git a/gcc/expr.cc b/gcc/expr.cc
index 15be1c8db99..4ef11d0d8f7 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -7649,8 +7649,7 @@ store_field (rtx target, poly_int64 bitsize, poly_int64
bitpos,
       || (mode != BLKmode && ! direct_store[(int) mode]
          && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
          && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
-      || REG_P (target)
-      || GET_CODE (target) == SUBREG
+      || !MEM_P (target)
       /* If the field isn't aligned enough to store as an ordinary memref,
         store it as a bit field.  */
       || (mode != BLKmode

t.C: In function 'ReturnObject example()':
t.C:24:1: error: unrecognizable insn:
   24 |   }
      | ^
(insn 12 11 13 2 (set (reg:TI 86)
        (parallel:TI [
                (expr_list:REG_DEP_TRUE (reg:SI 83 [ <retval> ])
                    (const_int 0 [0]))
                (expr_list:REG_DEP_TRUE (reg:DI 84 [ <retval>+8 ])
                    (const_int 8 [0x8]))
            ])) -1
     (nil))
during RTL pass: vregs

so it seems the PARALLEL target needs more explicit handling.

Reply via email to