re PR middle-end/52419 (Wrong expansion of misaligned vector store)
PR middle-end/52419 * expr.c (expand_assignment): If doing misaligned store that doesn't cover all mode bits, perform a RMW cycle. * gcc.dg/torture/pr52419.c: New test. From-SVN: r184666
This commit is contained in:
parent
598e67d7a0
commit
a3017cf147
@ -1,5 +1,9 @@
|
||||
2012-02-29 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/52419
|
||||
* expr.c (expand_assignment): If doing misaligned store that doesn't
|
||||
cover all mode bits, perform a RMW cycle.
|
||||
|
||||
PR tree-optimization/52429
|
||||
* tree-parloops.c (separate_decls_in_region_debug): Return early
|
||||
if var is LABEL_DECL.
|
||||
|
57
gcc/expr.c
57
gcc/expr.c
@ -4666,6 +4666,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
|
||||
int volatilep = 0;
|
||||
tree tem;
|
||||
bool misalignp;
|
||||
rtx mem = NULL_RTX;
|
||||
|
||||
push_temp_slots ();
|
||||
tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
|
||||
@ -4686,8 +4687,44 @@ expand_assignment (tree to, tree from, bool nontemporal)
|
||||
&& ((icode = optab_handler (movmisalign_optab, mode))
|
||||
!= CODE_FOR_nothing))
|
||||
{
|
||||
enum machine_mode address_mode;
|
||||
rtx op0;
|
||||
struct expand_operand ops[2];
|
||||
addr_space_t as = TYPE_ADDR_SPACE
|
||||
(TREE_TYPE (TREE_TYPE (TREE_OPERAND (tem, 0))));
|
||||
tree base = TREE_OPERAND (tem, 0);
|
||||
|
||||
misalignp = true;
|
||||
to_rtx = gen_reg_rtx (mode);
|
||||
|
||||
address_mode = targetm.addr_space.address_mode (as);
|
||||
op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_NORMAL);
|
||||
op0 = convert_memory_address_addr_space (address_mode, op0, as);
|
||||
if (!integer_zerop (TREE_OPERAND (tem, 1)))
|
||||
{
|
||||
rtx off = immed_double_int_const (mem_ref_offset (tem),
|
||||
address_mode);
|
||||
op0 = simplify_gen_binary (PLUS, address_mode, op0, off);
|
||||
}
|
||||
op0 = memory_address_addr_space (mode, op0, as);
|
||||
mem = gen_rtx_MEM (mode, op0);
|
||||
set_mem_attributes (mem, tem, 0);
|
||||
set_mem_addr_space (mem, as);
|
||||
if (TREE_THIS_VOLATILE (tem))
|
||||
MEM_VOLATILE_P (mem) = 1;
|
||||
|
||||
/* If the misaligned store doesn't overwrite all bits, perform
|
||||
rmw cycle on MEM. */
|
||||
if (bitsize != GET_MODE_BITSIZE (mode))
|
||||
{
|
||||
create_input_operand (&ops[0], to_rtx, mode);
|
||||
create_fixed_operand (&ops[1], mem);
|
||||
/* The movmisalign<mode> pattern cannot fail, else the assignment
|
||||
would silently be omitted. */
|
||||
expand_insn (icode, 2, ops);
|
||||
|
||||
mem = copy_rtx (mem);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4842,26 +4879,6 @@ expand_assignment (tree to, tree from, bool nontemporal)
|
||||
if (misalignp)
|
||||
{
|
||||
struct expand_operand ops[2];
|
||||
enum machine_mode address_mode;
|
||||
rtx op0, mem;
|
||||
addr_space_t as = TYPE_ADDR_SPACE
|
||||
(TREE_TYPE (TREE_TYPE (TREE_OPERAND (tem, 0))));
|
||||
tree base = TREE_OPERAND (tem, 0);
|
||||
address_mode = targetm.addr_space.address_mode (as);
|
||||
op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_NORMAL);
|
||||
op0 = convert_memory_address_addr_space (address_mode, op0, as);
|
||||
if (!integer_zerop (TREE_OPERAND (tem, 1)))
|
||||
{
|
||||
rtx off = immed_double_int_const (mem_ref_offset (tem),
|
||||
address_mode);
|
||||
op0 = simplify_gen_binary (PLUS, address_mode, op0, off);
|
||||
}
|
||||
op0 = memory_address_addr_space (mode, op0, as);
|
||||
mem = gen_rtx_MEM (mode, op0);
|
||||
set_mem_attributes (mem, tem, 0);
|
||||
set_mem_addr_space (mem, as);
|
||||
if (TREE_THIS_VOLATILE (tem))
|
||||
MEM_VOLATILE_P (mem) = 1;
|
||||
|
||||
create_fixed_operand (&ops[0], mem);
|
||||
create_input_operand (&ops[1], to_rtx, mode);
|
||||
|
@ -1,5 +1,8 @@
|
||||
2012-02-29 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/52419
|
||||
* gcc.dg/torture/pr52419.c: New test.
|
||||
|
||||
PR tree-optimization/52429
|
||||
* gcc.dg/torture/pr52429.c: New test.
|
||||
* g++.dg/opt/pr52429.C: New test.
|
||||
|
32
gcc/testsuite/gcc.dg/torture/pr52419.c
Normal file
32
gcc/testsuite/gcc.dg/torture/pr52419.c
Normal file
@ -0,0 +1,32 @@
|
||||
/* PR middle-end/52419 */
|
||||
/* { dg-do run } */
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
typedef long long V
|
||||
__attribute__ ((vector_size (2 * sizeof (long long)), may_alias));
|
||||
|
||||
typedef struct S { V b; } P __attribute__((aligned (1)));
|
||||
|
||||
struct __attribute__((packed)) T { char c; P s; };
|
||||
|
||||
__attribute__((noinline, noclone)) void
|
||||
foo (P *p)
|
||||
{
|
||||
p->b[1] = 5;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
V a = { 3, 4 };
|
||||
struct T t;
|
||||
|
||||
t.s.b = a;
|
||||
foo (&t.s);
|
||||
|
||||
if (t.s.b[0] != 3 || t.s.b[1] != 5)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user