Fix incorrect TARGET_MEM_REF alignment (PR 84419)

expand_call_mem_ref checks for TARGET_MEM_REFs that have compatible
type, but it didn't then go on to install the specific type we need,
which might have different alignment due to:

  if (TYPE_ALIGN (type) != align)
    type = build_aligned_type (type, align);

This was causing masked stores to be incorrectly marked as
aligned on AVX512.

2018-02-20  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	PR tree-optimization/84419
	* internal-fn.c (expand_call_mem_ref): Create a TARGET_MEM_REF
	with the required type if its current type is compatible but
	different.

gcc/testsuite/
	PR tree-optimization/84419
	* gcc.dg/vect/pr84419.c: New test.

From-SVN: r257847
This commit is contained in:
Richard Sandiford 2018-02-20 14:44:24 +00:00 committed by Richard Sandiford
parent ef7866a3f1
commit 9bd958c5f3
4 changed files with 37 additions and 1 deletions

View File

@ -1,3 +1,10 @@
2018-02-20 Richard Sandiford <richard.sandiford@linaro.org>
PR tree-optimization/84419
* internal-fn.c (expand_call_mem_ref): Create a TARGET_MEM_REF
with the required type if its current type is compatible but
different.
2018-02-20 Jakub Jelinek <jakub@redhat.com>
PR middle-end/82004

View File

@ -2444,11 +2444,14 @@ expand_call_mem_ref (tree type, gcall *stmt, int index)
&& types_compatible_p (TREE_TYPE (mem), type))
{
tree offset = TMR_OFFSET (mem);
if (alias_ptr_type != TREE_TYPE (offset) || !integer_zerop (offset))
if (type != TREE_TYPE (mem)
|| alias_ptr_type != TREE_TYPE (offset)
|| !integer_zerop (offset))
{
mem = copy_node (mem);
TMR_OFFSET (mem) = wide_int_to_tree (alias_ptr_type,
wi::to_poly_wide (offset));
TREE_TYPE (mem) = type;
}
return mem;
}

View File

@ -1,3 +1,8 @@
2018-02-20 Richard Sandiford <richard.sandiford@linaro.org>
PR tree-optimization/84419
* gcc.dg/vect/pr84419.c: New test.
2018-02-20 Jakub Jelinek <jakub@redhat.com>
PR middle-end/82004

View File

@ -0,0 +1,21 @@
#include <string.h>
#define SIZE 400
int foo[SIZE];
char bar[SIZE];
void __attribute__ ((noinline)) foo_func(void)
{
int i;
for (i = 1; i < SIZE; i++)
if (bar[i])
foo[i] = 1;
}
int main()
{
memset(bar, 1, sizeof(bar));
foo_func();
return 0;
}