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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jsm28 at gcc dot gnu.org,
                   |                            |rguenth at gcc dot gnu.org
          Component|tree-optimization           |middle-end

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
The issue is that array_ref_element_size of the [i] ref returns 24.  Even when
inside just

unsigned long long foo(int i)
{
  return bid_Kx192[i].w[0];
}

and RTL expansion get_inner_reference produces for offset
(sizetype) i_2(D) * 24 resulting in

foo:
.LFB0:
        .cfi_startproc
        movslq  %edi, %rdi
        leaq    (%rdi,%rdi,2), %rax
        movq    bid_Kx192(,%rax,8), %rax
        ret

Now the issue with SCCVN is that it expects TYPE_SIZE_UNIT to be exactly
dividable by TYPE_ALIGN_UNIT which it isn't (we divide 24 by 16):

            /* But record element size in units of the type alignment.  */
            temp.op2 = TREE_OPERAND (ref, 3);
            temp.align = eltype->type_common.align;
            if (! temp.op2)
              temp.op2 = size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (eltype),
                                     size_int (TYPE_ALIGN_UNIT (eltype)));

that is, for this ARRAY_REF there exists no valid value to put in
TREE_OPERAND (ref, 3), the aligned size tree operand used by
array_ref_element_size.

IMHO this should never happen.

The IL claims the array elements are all aligned to 16 bytes but they are
obviously not.

Joseph?  Who's at fault here?

(side-note, the wide-int code treats EXACT_DIV_EXPR just like TRUNC_DIV_EXPR
reporting no error).

Reply via email to