Commit 76416d89 by Jakub Jelinek Committed by Jakub Jelinek

re PR rtl-optimization/89965 (wrong code with -O -mtune=nano-x2 -fcaller-saves…

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
parent b2e77a37
2019-04-12 Jakub Jelinek <jakub@redhat.com> 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. * config/mips/loongson-mmiintrin.h: Fix up #error message.
......
...@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see
#include "valtrack.h" #include "valtrack.h"
#include "tree-pass.h" #include "tree-pass.h"
#include "dbgcnt.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) ...@@ -325,6 +326,48 @@ sp_based_mem_offset (rtx_call_insn *call_insn, const_rtx mem, bool fast)
return off; 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 /* Try to find all stack stores of CALL_INSN arguments if
ACCUMULATE_OUTGOING_ARGS. If all stack stores have been found ACCUMULATE_OUTGOING_ARGS. If all stack stores have been found
and it is therefore safe to eliminate the call, return true, 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, ...@@ -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 /* Walk backwards, looking for argument stores. The search stops
when seeing another call, sp adjustment or memory store other than when seeing another call, sp adjustment, memory store other than
argument store. */ 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; ret = false;
for (insn = PREV_INSN (call_insn); insn; insn = prev_insn) 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, ...@@ -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) if (!set || SET_DEST (set) == stack_pointer_rtx)
break; break;
note_uses (&PATTERN (insn), check_argument_load, &data);
if (data.load_found)
break;
if (!MEM_P (SET_DEST (set))) if (!MEM_P (SET_DEST (set)))
continue; continue;
......
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> 2019-04-12 Marek Polacek <polacek@redhat.com>
PR c++/87603 - constexpr functions are no longer noexcept. PR c++/87603 - constexpr functions are no longer noexcept.
......
/* 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment