123 lines
4.2 KiB
Diff
123 lines
4.2 KiB
Diff
|
2019-01-17 Jakub Jelinek <jakub@redhat.com>
|
||
|
|
||
|
PR bootstrap/88714
|
||
|
* config/arm/ldrdstrd.md: If alias sets on the SImode MEMs are
|
||
|
different, clear alias set on the DImode MEM. Clear MEM_EXPR.
|
||
|
|
||
|
* gcc.c-torture/execute/pr88714.c: New test.
|
||
|
|
||
|
--- gcc/config/arm/ldrdstrd.md.jj 2019-01-16 09:35:03.851334889 +0100
|
||
|
+++ gcc/config/arm/ldrdstrd.md 2019-01-17 17:37:40.860791779 +0100
|
||
|
@@ -39,6 +39,10 @@ (define_peephole2 ; ldrd
|
||
|
/* In ARM state, the destination registers of LDRD/STRD must be
|
||
|
consecutive. We emit DImode access. */
|
||
|
operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
|
||
|
+ if (MEM_ALIAS_SET (operands[2])
|
||
|
+ && MEM_ALIAS_SET (operands[2]) != MEM_ALIAS_SET (operands[3]))
|
||
|
+ set_mem_alias_set (operands[2], 0);
|
||
|
+ set_mem_expr (operands[2], NULL_TREE);
|
||
|
operands[2] = adjust_address (operands[2], DImode, 0);
|
||
|
/* Emit [(set (match_dup 0) (match_dup 2))] */
|
||
|
emit_insn (gen_rtx_SET (operands[0], operands[2]));
|
||
|
@@ -71,6 +75,10 @@ (define_peephole2 ; strd
|
||
|
/* In ARM state, the destination registers of LDRD/STRD must be
|
||
|
consecutive. We emit DImode access. */
|
||
|
operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
|
||
|
+ if (MEM_ALIAS_SET (operands[2])
|
||
|
+ && MEM_ALIAS_SET (operands[2]) != MEM_ALIAS_SET (operands[3]))
|
||
|
+ set_mem_alias_set (operands[2], 0);
|
||
|
+ set_mem_expr (operands[2], NULL_TREE);
|
||
|
operands[2] = adjust_address (operands[2], DImode, 0);
|
||
|
/* Emit [(set (match_dup 2) (match_dup 0))] */
|
||
|
emit_insn (gen_rtx_SET (operands[2], operands[0]));
|
||
|
@@ -106,6 +114,10 @@ (define_peephole2 ; strd of constants
|
||
|
else if (TARGET_ARM)
|
||
|
{
|
||
|
rtx tmp = gen_rtx_REG (DImode, REGNO (operands[0]));
|
||
|
+ if (MEM_ALIAS_SET (operands[2])
|
||
|
+ && MEM_ALIAS_SET (operands[2]) != MEM_ALIAS_SET (operands[3]))
|
||
|
+ set_mem_alias_set (operands[2], 0);
|
||
|
+ set_mem_expr (operands[2], NULL_TREE);
|
||
|
operands[2] = adjust_address (operands[2], DImode, 0);
|
||
|
/* Emit the pattern:
|
||
|
[(set (match_dup 0) (match_dup 4))
|
||
|
@@ -149,6 +161,10 @@ (define_peephole2 ; strd of constants
|
||
|
else if (TARGET_ARM)
|
||
|
{
|
||
|
rtx tmp = gen_rtx_REG (DImode, REGNO (operands[0]));
|
||
|
+ if (MEM_ALIAS_SET (operands[2])
|
||
|
+ && MEM_ALIAS_SET (operands[2]) != MEM_ALIAS_SET (operands[3]))
|
||
|
+ set_mem_alias_set (operands[2], 0);
|
||
|
+ set_mem_expr (operands[2], NULL_TREE);
|
||
|
operands[2] = adjust_address (operands[2], DImode, 0);
|
||
|
/* Emit the pattern
|
||
|
[(set (match_dup 0) (match_dup 4))
|
||
|
@@ -203,6 +219,10 @@ (define_peephole2 ; swap the destination
|
||
|
else
|
||
|
{
|
||
|
operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
|
||
|
+ if (MEM_ALIAS_SET (operands[2])
|
||
|
+ && MEM_ALIAS_SET (operands[2]) != MEM_ALIAS_SET (operands[3]))
|
||
|
+ set_mem_alias_set (operands[2], 0);
|
||
|
+ set_mem_expr (operands[2], NULL_TREE);
|
||
|
operands[2] = adjust_address (operands[2], DImode, 0);
|
||
|
}
|
||
|
}
|
||
|
@@ -238,6 +258,10 @@ (define_peephole2 ; swap the destination
|
||
|
else
|
||
|
{
|
||
|
operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
|
||
|
+ if (MEM_ALIAS_SET (operands[2])
|
||
|
+ && MEM_ALIAS_SET (operands[2]) != MEM_ALIAS_SET (operands[3]))
|
||
|
+ set_mem_alias_set (operands[2], 0);
|
||
|
+ set_mem_expr (operands[2], NULL_TREE);
|
||
|
operands[2] = adjust_address (operands[2], DImode, 0);
|
||
|
}
|
||
|
}
|
||
|
--- gcc/testsuite/gcc.c-torture/execute/pr88714.c.jj 2019-01-17 17:39:42.074828164 +0100
|
||
|
+++ gcc/testsuite/gcc.c-torture/execute/pr88714.c 2019-01-17 17:21:26.810575783 +0100
|
||
|
@@ -0,0 +1,43 @@
|
||
|
+/* PR bootstrap/88714 */
|
||
|
+
|
||
|
+struct S { int a, b, c; int *d; };
|
||
|
+struct T { int *e, *f, *g; } *t = 0;
|
||
|
+int *o = 0;
|
||
|
+
|
||
|
+__attribute__((noipa))
|
||
|
+void bar (int *x, int y, int z, int w)
|
||
|
+{
|
||
|
+ if (w == -1)
|
||
|
+ {
|
||
|
+ if (x != 0 || y != 0 || z != 0)
|
||
|
+ __builtin_abort ();
|
||
|
+ }
|
||
|
+ else if (w != 0 || x != t->g || y != 0 || z != 12)
|
||
|
+ __builtin_abort ();
|
||
|
+}
|
||
|
+
|
||
|
+__attribute__((noipa)) void
|
||
|
+foo (struct S *x, struct S *y, int *z, int w)
|
||
|
+{
|
||
|
+ *o = w;
|
||
|
+ if (w)
|
||
|
+ bar (0, 0, 0, -1);
|
||
|
+ x->d = z;
|
||
|
+ if (y->d)
|
||
|
+ y->c = y->c + y->d[0];
|
||
|
+ bar (t->g, 0, y->c, 0);
|
||
|
+}
|
||
|
+
|
||
|
+int
|
||
|
+main ()
|
||
|
+{
|
||
|
+ int a[4] = { 8, 9, 10, 11 };
|
||
|
+ struct S s = { 1, 2, 3, &a[0] };
|
||
|
+ struct T u = { 0, 0, &a[3] };
|
||
|
+ o = &a[2];
|
||
|
+ t = &u;
|
||
|
+ foo (&s, &s, &a[1], 5);
|
||
|
+ if (s.c != 12 || s.d != &a[1])
|
||
|
+ __builtin_abort ();
|
||
|
+ return 0;
|
||
|
+}
|