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:
parent
b2e77a37a2
commit
76416d899c
@ -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.
|
||||
|
||||
|
53
gcc/dce.c
53
gcc/dce.c
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
39
gcc/testsuite/gcc.target/i386/pr89965.c
Normal file
39
gcc/testsuite/gcc.target/i386/pr89965.c
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user