mirror of git://gcc.gnu.org/git/gcc.git
re PR rtl-optimization/78812 (Wrong code generation due to hoisting memory load across function call)
PR tree-optimizatin/78812 * rtl.h (contains_mem_rtx_p): Prototype. * ifcvt.c (containts_mem_rtx_p): Move from here to... * rtlanal.c (contains_mem_rtx_p): Here and remvoe static linkage. * gcse.c (prune_expressions): Use contains_mem_rtx_p to discover and prune MEMs that are not at the toplevel of a SET_SRC rtx. Look through ZERO_EXTEND and SIGN_EXTEND when trying to avoid pruning MEMs. PR tree-optimization/78812 * g++.dg/torture/pr78812.C: New test. From-SVN: r244093
This commit is contained in:
parent
0f9cf7ff83
commit
d80c6d02fd
|
|
@ -1,3 +1,14 @@
|
||||||
|
2017-01-04 Jeff Law <law@redhat.com>
|
||||||
|
|
||||||
|
PR tree-optimizatin/78812
|
||||||
|
* rtl.h (contains_mem_rtx_p): Prototype.
|
||||||
|
* ifcvt.c (containts_mem_rtx_p): Move from here to...
|
||||||
|
* rtlanal.c (contains_mem_rtx_p): Here and remvoe static linkage.
|
||||||
|
* gcse.c (prune_expressions): Use contains_mem_rtx_p to discover
|
||||||
|
and prune MEMs that are not at the toplevel of a SET_SRC rtx. Look
|
||||||
|
through ZERO_EXTEND and SIGN_EXTEND when trying to avoid pruning
|
||||||
|
MEMs.
|
||||||
|
|
||||||
2017-01-04 Alexandre Oliva <aoliva@redhat.com>
|
2017-01-04 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
|
||||||
* input.c (assert_char_at_range): Default-initialize
|
* input.c (assert_char_at_range): Default-initialize
|
||||||
|
|
|
||||||
31
gcc/gcse.c
31
gcc/gcse.c
|
|
@ -1709,7 +1709,7 @@ prune_expressions (bool pre_p)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pre_p && MEM_P (expr->expr))
|
if (!pre_p && contains_mem_rtx_p (expr->expr))
|
||||||
/* Note memory references that can be clobbered by a call.
|
/* Note memory references that can be clobbered by a call.
|
||||||
We do not split abnormal edges in hoisting, so would
|
We do not split abnormal edges in hoisting, so would
|
||||||
a memory reference get hoisted along an abnormal edge,
|
a memory reference get hoisted along an abnormal edge,
|
||||||
|
|
@ -1717,15 +1717,28 @@ prune_expressions (bool pre_p)
|
||||||
constant memory references can be hoisted along abnormal
|
constant memory references can be hoisted along abnormal
|
||||||
edges. */
|
edges. */
|
||||||
{
|
{
|
||||||
if (GET_CODE (XEXP (expr->expr, 0)) == SYMBOL_REF
|
rtx x = expr->expr;
|
||||||
&& CONSTANT_POOL_ADDRESS_P (XEXP (expr->expr, 0)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (MEM_READONLY_P (expr->expr)
|
/* Common cases where we might find the MEM which may allow us
|
||||||
&& !MEM_VOLATILE_P (expr->expr)
|
to avoid pruning the expression. */
|
||||||
&& MEM_NOTRAP_P (expr->expr))
|
while (GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)
|
||||||
/* Constant memory reference, e.g., a PIC address. */
|
x = XEXP (x, 0);
|
||||||
continue;
|
|
||||||
|
/* If we found the MEM, go ahead and look at it to see if it has
|
||||||
|
properties that allow us to avoid pruning its expression out
|
||||||
|
of the tables. */
|
||||||
|
if (MEM_P (x))
|
||||||
|
{
|
||||||
|
if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
|
||||||
|
&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (MEM_READONLY_P (x)
|
||||||
|
&& !MEM_VOLATILE_P (x)
|
||||||
|
&& MEM_NOTRAP_P (x))
|
||||||
|
/* Constant memory reference, e.g., a PIC address. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* ??? Optimally, we would use interprocedural alias
|
/* ??? Optimally, we would use interprocedural alias
|
||||||
analysis to determine if this mem is actually killed
|
analysis to determine if this mem is actually killed
|
||||||
|
|
|
||||||
13
gcc/ifcvt.c
13
gcc/ifcvt.c
|
|
@ -3010,19 +3010,6 @@ noce_operand_ok (const_rtx op)
|
||||||
return ! may_trap_p (op);
|
return ! may_trap_p (op);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if X contains a MEM subrtx. */
|
|
||||||
|
|
||||||
static bool
|
|
||||||
contains_mem_rtx_p (rtx x)
|
|
||||||
{
|
|
||||||
subrtx_iterator::array_type array;
|
|
||||||
FOR_EACH_SUBRTX (iter, array, x, ALL)
|
|
||||||
if (MEM_P (*iter))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return true iff basic block TEST_BB is valid for noce if-conversion.
|
/* Return true iff basic block TEST_BB is valid for noce if-conversion.
|
||||||
The condition used in this if-conversion is in COND.
|
The condition used in this if-conversion is in COND.
|
||||||
In practice, check that TEST_BB ends with a single set
|
In practice, check that TEST_BB ends with a single set
|
||||||
|
|
|
||||||
|
|
@ -3090,6 +3090,7 @@ extern bool rtx_referenced_p (const_rtx, const_rtx);
|
||||||
extern bool tablejump_p (const rtx_insn *, rtx_insn **, rtx_jump_table_data **);
|
extern bool tablejump_p (const rtx_insn *, rtx_insn **, rtx_jump_table_data **);
|
||||||
extern int computed_jump_p (const rtx_insn *);
|
extern int computed_jump_p (const rtx_insn *);
|
||||||
extern bool tls_referenced_p (const_rtx);
|
extern bool tls_referenced_p (const_rtx);
|
||||||
|
extern bool contains_mem_rtx_p (rtx x);
|
||||||
|
|
||||||
/* Overload for refers_to_regno_p for checking a single register. */
|
/* Overload for refers_to_regno_p for checking a single register. */
|
||||||
inline bool
|
inline bool
|
||||||
|
|
|
||||||
|
|
@ -685,6 +685,19 @@ rtx_addr_can_trap_p (const_rtx x)
|
||||||
return rtx_addr_can_trap_p_1 (x, 0, 0, VOIDmode, false);
|
return rtx_addr_can_trap_p_1 (x, 0, 0, VOIDmode, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return true if X contains a MEM subrtx. */
|
||||||
|
|
||||||
|
bool
|
||||||
|
contains_mem_rtx_p (rtx x)
|
||||||
|
{
|
||||||
|
subrtx_iterator::array_type array;
|
||||||
|
FOR_EACH_SUBRTX (iter, array, x, ALL)
|
||||||
|
if (MEM_P (*iter))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return true if X is an address that is known to not be zero. */
|
/* Return true if X is an address that is known to not be zero. */
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
2017-01-04 Jeff Law <law@redhat.com>
|
||||||
|
|
||||||
|
PR tree-optimization/78812
|
||||||
|
* g++.dg/torture/pr78812.C: New test.
|
||||||
|
|
||||||
2017-01-04 Michael Meissner <meissner@linux.vnet.ibm.com>
|
2017-01-04 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||||
|
|
||||||
PR target/71977
|
PR target/71977
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
// { dg-do run }
|
||||||
|
// { dg-options "-fpic" { target fpic } }
|
||||||
|
|
||||||
|
struct T
|
||||||
|
{
|
||||||
|
bool a;
|
||||||
|
T () : a (false) {}
|
||||||
|
~T () { if (!a) __builtin_abort (); }
|
||||||
|
};
|
||||||
|
|
||||||
|
__attribute__((noinline))
|
||||||
|
void
|
||||||
|
test (T &x)
|
||||||
|
{
|
||||||
|
x.a = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
T T;
|
||||||
|
test (T);
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue