unsigned int *stack_alignment;
};
-/* SET stores into OP, a MEM linked to parameter BASE. Return true if
- SET stores BASE's argument register into OP. This is a spill: the
- callee saves its own register argument to the stack. It is not a
- stack argument set up by the caller:
-
- (set (mem/c:V2DI (plus:DI (reg/f:DI 7 sp)
- (const_int -16 [0xfffffffffffffff0])) [4 a1+0 S16 A128])
- (reg:V2DI 20 xmm0 [ a1 ]))
- */
-
-static bool
-ix86_spill_register_argument_p (const_rtx set, const_rtx op, tree base)
-{
- rtx src = SET_SRC (set);
-
- /* Not a hard register store, so not a spill. */
- if (!REG_P (src) || !HARD_REGISTER_P (src))
- return false;
-
- rtx dest = SET_DEST (set);
- tree reg_expr = REG_EXPR (src);
-
- /* If spilling an SSA_NAME into OP, the argument-linked memory is
- also used to store a local variable. */
- return dest == op && (reg_expr == base
- || (reg_expr
- && TREE_CODE (reg_expr) == SSA_NAME));
-}
-
-/* Return true if OP, found in PAT, is a stack argument set up by the
- caller. Return false if OP is a register argument that the callee
- spilled to its own stack frame. Both cases share the same MEM_EXPR,
- so we must check PAT to tell them apart. */
+/* Return true if OP is a stack argument set up by the caller. */
static bool
-ix86_argument_passed_on_stack_p (const_rtx op, const_rtx pat)
+ix86_argument_passed_on_stack_p (const_rtx op)
{
tree mem_expr = MEM_EXPR (op);
if (!mem_expr)
if (TREE_CODE (var) != PARM_DECL)
return false;
- /* PAT is always a single SET here: note_stores splits PARALLEL
- patterns into separate SETs before calling this function. */
- if (GET_CODE (pat) == SET)
- return !ix86_spill_register_argument_p (pat, op, var);
-
- return true;
+ /* For PARM_DECL, DECL_INCOMING_RTL holds an RTL for the stack slot
+ or register where the data was actually passed. Return true if
+ OP is passed in memory. */
+ return DECL_INCOMING_RTL (var) && MEM_P (DECL_INCOMING_RTL (var));
}
/* Update the maximum stack slot alignment from memory alignment in PAT. */
responsible to align the outgoing stack for arguments
passed on stack. */
if (reg_mentioned_p (p->reg, XEXP (op, 0))
- && !ix86_argument_passed_on_stack_p (op, pat))
+ && !ix86_argument_passed_on_stack_p (op))
{
unsigned int alignment = MEM_ALIGN (op);
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-O2 -march=x86-64" } */
+
+typedef signed char A[[gnu::vector_size (2)]];
+typedef short B[[gnu::vector_size (16)]];
+int a, b, c, d;
+B e;
+[[gnu::vector_size(8 * sizeof (int))]] int f;
+_Bool g;
+
+__attribute__((noipa, noinline, target("avx2")))
+void *
+foo (long long x, _Bool y, int z, B w)
+{
+ A h = {};
+ short i = h[z];
+ f = 0 % f;
+ w = e;
+ d = w[g];
+ h = ((union { short s; A t; }) { i }).t;
+ b = 3 / x;
+ h = __builtin_shufflevector (h, h, 3, 2);
+lab:
+ c = h[0];
+ if (y)
+ return 0;
+ y = 1;
+ h = ~h;
+ goto lab;
+}
+
+int
+main (void)
+{
+ if (__builtin_cpu_supports ("avx2"))
+ foo (3355934481768670720LL, 0, a, e);
+
+ return 0;
+}
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-O2 -march=x86-64" } */
+
+typedef signed char A[[gnu::vector_size (2)]];
+typedef short B[[gnu::vector_size (16)]];
+int a, b, c, d;
+B e;
+[[gnu::vector_size(8 * sizeof (int))]] int f;
+_Bool g;
+
+__attribute__((noipa, noinline, target("avx2")))
+void *
+foo (float f1, float f2, float f3, float f4, float f5, float f6, float f7,
+ float f8, long long x, _Bool y, int z, B w)
+{
+ A h = {};
+ short i = h[z];
+ f = 0 % f;
+ w = e;
+ d = w[g];
+ h = ((union { short s; A t; }) { i }).t;
+ b = 3 / x;
+ h = __builtin_shufflevector (h, h, 3, 2);
+lab:
+ c = h[0];
+ if (y)
+ return 0;
+ y = 1;
+ h = ~h;
+ goto lab;
+}
+
+int
+main (void)
+{
+ if (__builtin_cpu_supports ("avx2"))
+ foo (1, 2, 3, 4, 5, 6, 7, 8, 3355934481768670720LL, 0, a, e);
+
+ return 0;
+}
--- /dev/null
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -march=x86-64-v3" } */
+/* { dg-final { scan-assembler "and\[lq\]?\[\\t \]+\\$-32,\[\\t \]*%\[re\]?sp" } } */
+/* { dg-final { scan-assembler "vmovdqa\[\\t \]+%ymm" } } */
+
+typedef signed char A[[gnu::vector_size (2)]];
+typedef short B[[gnu::vector_size (32)]];
+int a, b, c, d;
+B e;
+[[gnu::vector_size(8 * sizeof (int))]] int f;
+_Bool g;
+
+[[gnu::noipa]] void *
+foo (float f1, float f2, float f3, float f4, float f5, float f6, float f7,
+ long long x, _Bool y, int z, B w)
+{
+ A h = {};
+ short i = h[z];
+ f = 0 % f;
+ w = e;
+ d = w[g];
+ h = ((union { short s; A t; }) { i }).t;
+ b = 3 / x;
+ h = __builtin_shufflevector (h, h, 3, 2);
+lab:
+ c = h[0];
+ if (y)
+ return 0;
+ y = 1;
+ h = ~h;
+ goto lab;
+}
--- /dev/null
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -march=x86-64-v3" } */
+/* { dg-final { scan-assembler "and\[lq\]?\[\\t \]+\\$-32,\[\\t \]*%\[re\]?sp" { target ia32 } } } */
+/* { dg-final { scan-assembler-not "and\[lq\]?\[\\t \]+\\$-32,\[\\t \]*%\[re\]?sp" { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "vmovdqa\[\\t \]+%ymm" } } */
+
+typedef signed char A[[gnu::vector_size (2)]];
+typedef short B[[gnu::vector_size (32)]];
+int a, b, c, d;
+B e;
+[[gnu::vector_size(8 * sizeof (int))]] int f;
+_Bool g;
+
+[[gnu::noipa]] void *
+foo (float f1, float f2, float f3, float f4, float f5, float f6, float f7,
+ float f8, long long x, _Bool y, int z, B w)
+{
+ A h = {};
+ short i = h[z];
+ f = 0 % f;
+ w = e;
+ d = w[g];
+ h = ((union { short s; A t; }) { i }).t;
+ b = 3 / x;
+ h = __builtin_shufflevector (h, h, 3, 2);
+lab:
+ c = h[0];
+ if (y)
+ return 0;
+ y = 1;
+ h = ~h;
+ goto lab;
+}