re PR rtl-optimization/89965 (wrong code with -O -mtune=nano-x2 -fcaller-saves -fexpensive-optimizations -fno-tree-dce -fno-tree-ter)

PR rtl-optimization/89965
	* dce.c: Include rtl-iter.h.
	(struct check_argument_load_data): New type.
	(check_argument_load): New function.
	(find_call_stack_args): Check for loads from stack slots still tracked
	in sp_bytes and punt if any is found.

	* gcc.target/i386/pr89965.c: New test.

From-SVN: r270323
This commit is contained in:
Jakub Jelinek 2019-04-12 18:20:21 +02:00 committed by Jakub Jelinek
parent b2e77a37a2
commit 76416d899c
4 changed files with 102 additions and 2 deletions

View File

@ -1,4 +1,11 @@
2019-04-12 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/89965
* dce.c: Include rtl-iter.h.
(struct check_argument_load_data): New type.
(check_argument_load): New function.
(find_call_stack_args): Check for loads from stack slots still tracked
in sp_bytes and punt if any is found.
* config/mips/loongson-mmiintrin.h: Fix up #error message.

View File

@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see
#include "valtrack.h"
#include "tree-pass.h"
#include "dbgcnt.h"
#include "rtl-iter.h"
/* -------------------------------------------------------------------------
@ -325,6 +326,48 @@ sp_based_mem_offset (rtx_call_insn *call_insn, const_rtx mem, bool fast)
return off;
}
/* Data for check_argument_load called via note_uses. */
struct check_argument_load_data {
bitmap sp_bytes;
HOST_WIDE_INT min_sp_off, max_sp_off;
rtx_call_insn *call_insn;
bool fast;
bool load_found;
};
/* Helper function for find_call_stack_args. Check if there are
any loads from the argument slots in between the const/pure call
and store to the argument slot, set LOAD_FOUND if any is found. */
static void
check_argument_load (rtx *loc, void *data)
{
struct check_argument_load_data *d
= (struct check_argument_load_data *) data;
subrtx_iterator::array_type array;
FOR_EACH_SUBRTX (iter, array, *loc, NONCONST)
{
const_rtx mem = *iter;
HOST_WIDE_INT size;
if (MEM_P (mem)
&& MEM_SIZE_KNOWN_P (mem)
&& MEM_SIZE (mem).is_constant (&size))
{
HOST_WIDE_INT off = sp_based_mem_offset (d->call_insn, mem, d->fast);
if (off != INTTYPE_MINIMUM (HOST_WIDE_INT)
&& off < d->max_sp_off
&& off + size > d->min_sp_off)
for (HOST_WIDE_INT byte = MAX (off, d->min_sp_off);
byte < MIN (off + size, d->max_sp_off); byte++)
if (bitmap_bit_p (d->sp_bytes, byte - d->min_sp_off))
{
d->load_found = true;
return;
}
}
}
}
/* Try to find all stack stores of CALL_INSN arguments if
ACCUMULATE_OUTGOING_ARGS. If all stack stores have been found
and it is therefore safe to eliminate the call, return true,
@ -394,8 +437,10 @@ find_call_stack_args (rtx_call_insn *call_insn, bool do_mark, bool fast,
}
/* Walk backwards, looking for argument stores. The search stops
when seeing another call, sp adjustment or memory store other than
argument store. */
when seeing another call, sp adjustment, memory store other than
argument store or a read from an argument stack slot. */
struct check_argument_load_data data
= { sp_bytes, min_sp_off, max_sp_off, call_insn, fast, false };
ret = false;
for (insn = PREV_INSN (call_insn); insn; insn = prev_insn)
{
@ -414,6 +459,10 @@ find_call_stack_args (rtx_call_insn *call_insn, bool do_mark, bool fast,
if (!set || SET_DEST (set) == stack_pointer_rtx)
break;
note_uses (&PATTERN (insn), check_argument_load, &data);
if (data.load_found)
break;
if (!MEM_P (SET_DEST (set)))
continue;

View File

@ -1,3 +1,8 @@
2019-04-12 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/89965
* gcc.target/i386/pr89965.c: New test.
2019-04-12 Marek Polacek <polacek@redhat.com>
PR c++/87603 - constexpr functions are no longer noexcept.

View File

@ -0,0 +1,39 @@
/* PR rtl-optimization/89965 */
/* { dg-do run } */
/* { dg-options "-O -mtune=nano-x2 -fcaller-saves -fexpensive-optimizations -fno-tree-dce -fno-tree-ter" } */
/* { dg-additional-options "-march=i386" { target ia32 } } */
int a;
__attribute__ ((noipa)) unsigned long long
foo (unsigned char c, unsigned d, unsigned e, unsigned long long f,
unsigned char g, unsigned h, unsigned long long i)
{
(void) d;
unsigned short j = __builtin_mul_overflow_p (~0, h, c);
e <<= e;
i >>= 7;
c *= i;
i /= 12;
a = __builtin_popcount (c);
__builtin_add_overflow (e, a, &f);
return c + f + g + j + h;
}
__attribute__ ((noipa)) void
bar (void)
{
char buf[64];
__builtin_memset (buf, 0x55, sizeof buf);
asm volatile ("" : : "r" (&buf[0]) : "memory");
}
int
main (void)
{
bar ();
unsigned long long x = foo (2, 0, 0, 0, 0, 0, 0);
if (x != 0)
__builtin_abort ();
return 0;
}