This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/88085] New: User alignments on var decls not respected if smaller than type alignment
- From: "krebbel at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 19 Nov 2018 10:03:12 +0000
- Subject: [Bug middle-end/88085] New: User alignments on var decls not respected if smaller than type alignment
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88085
Bug ID: 88085
Summary: User alignments on var decls not respected if smaller
than type alignment
Product: gcc
Version: 9.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: krebbel at gcc dot gnu.org
Target Milestone: ---
typedef int __attribute__((vector_size(16))) v4si;
v4si a4 __attribute__((aligned(4)));
void
foo (v4si a)
{
a4 += a;
}
-O3 -dP
MEM_ALIGN for variable a4 is 128 bits although it is emitted with an alignment
requirement of just 4: .comm a4,16,4
It works when moving the aligned attribute over to the typedef instead.
foo:
#(insn:TI 6 3 7 2 (set (reg:V4SI 20 xmm0 [85])
# (plus:V4SI (reg:V4SI 20 xmm0 [86])
# (mem/c:V4SI (symbol_ref:DI ("a4") [flags 0x2] <var_decl
0x7ff6d222eab0 a4>) [1 a4+0 S16 A128]))) "t.c":8:6 3122 {*addv4si3}
# (expr_list:REG_EQUIV (mem/c:V4SI (symbol_ref:DI ("a4") [flags 0x2]
<var_decl 0x7ff6d222eab0 a4>) [1 a4+0 S16 A128])
# (nil)))
paddd a4(%rip), %xmm0 # 6 [c=12 l=8] *addv4si3/0
#(insn:TI 7 6 18 2 (set (mem/c:V4SI (symbol_ref:DI ("a4") [flags 0x2] <var_decl
0x7ff6d222eab0 a4>) [1 a4+0 S16 A128])
# (reg:V4SI 20 xmm0 [85])) "t.c":8:6 1198 {movv4si_internal}
# (expr_list:REG_DEAD (reg:V4SI 20 xmm0 [85])
# (nil)))
movaps %xmm0, a4(%rip) # 7 [c=4 l=7] movv4si_internal/3
#(jump_insn:TI 14 18 15 2 (simple_return) "t.c":9:1 688
{simple_return_internal}
# (nil)
# -> simple_return)
ret # 14 [c=0 l=1] simple_return_internal
.size foo, .-foo
.comm a4,16,4
.ident "GCC: (GNU) 9.0.0 20181114 (experimental)"
set_mem_attributes_minus_bitpos in emit-rtl.c:
This code sets the alignment field based on the type alignment:
/* ??? If T is a type, respecting mode alignment may *also* be wrong
e.g. if the type carries an alignment attribute. Should we be
able to simply always use TYPE_ALIGN? */
}
/* We can set the alignment from the type if we are making an object or if
this is an INDIRECT_REF. */
if (objectp || TREE_CODE (t) == INDIRECT_REF)
attrs.align = MAX (attrs.align, TYPE_ALIGN (type));
This code later would use the alignment in the aligned attribute (in obj_align)
but ignores it if it is lower than the alignment we already have?! As expected
setting bigger alignments on the var decl works.
/* If this is an indirect reference, record it. */
else if (TREE_CODE (t) == MEM_REF
|| TREE_CODE (t) == TARGET_MEM_REF)
{
attrs.expr = t;
attrs.offset_known_p = true;
attrs.offset = 0;
apply_bitpos = bitpos;
}
/* Compute the alignment. */
unsigned int obj_align;
unsigned HOST_WIDE_INT obj_bitpos;
get_object_alignment_1 (t, &obj_align, &obj_bitpos);
unsigned int diff_align = known_alignment (obj_bitpos - bitpos);
if (diff_align != 0)
obj_align = MIN (obj_align, diff_align);
attrs.align = MAX (attrs.align, obj_align);
}