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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ebotcazou at gcc dot gnu.org

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I guess the first question is if it is valid for expand_expr that requests some
mode to return a rtx with some completely different mode.  If not, then the bug
is somewhere in normal_inner_ref: code:
        if (GET_CODE (op0) == CONCAT && !must_force_mem)
          {
            if (bitpos == 0
                && bitsize == GET_MODE_BITSIZE (GET_MODE (op0)))
              { 
                if (reversep)
                  op0 = flip_storage_order (GET_MODE (op0), op0);
                return op0;
              }
If bitpos/bitsize indicate the real or imaginary part of the CONCAT, then we
don't return and let the later code handle the mode changes, but for this early
out we don't really consider what the mode is.
E.g. when handling VIEW_CONVERT_EXPR, as in e.g.
typedef float V __attribute__((vector_size (16)));
typedef _Complex float DC __attribute__((mode (DC)));
DC foo (void);
V bar ()
{
  return ((union U { DC c; V v; }) { .c = foo () }).v;
}
V baz ()
{
  DC c = foo ();
  return *(V *)&c;
}
we do:
          if (target == 0 || GET_MODE (target) != TYPE_MODE (inner_type))
            target
              = assign_stack_temp_for_type
                (TYPE_MODE (inner_type),
                 GET_MODE_SIZE (TYPE_MODE (inner_type)), inner_type);

          emit_move_insn (target, op0);
because op0 is not a MEM.

Reply via email to