The ifcvt scratchpad patch had some modifications to the function
noce_mem_write_may_trap_or_fault_p in ifcvt, but as far as I can tell,
that function itself makes no sense whatsoever. It returns true for
MEM_READONLY_P which is sensible, but then it also goes on an unreliable
search through the address, looking for SYMBOL_REFs that are in
decl_readonly_section. Needless to say, this won't ever find anything on
targets that don't allow symbolic addresses, and is not reliable even on
targets that do. The MEM_READONLY_P test must suffice; if there's a
reason why it doesn't, we'd need to figure out why and possibly disable
if-conversion of stores more thoroughly.
As a sanity check I bootstrapped and tested the first of the two
attached patches, which changes the "return true" paths to
gcc_unreachable. Since that passed, I propose the second of the two
attached patches, which removes the function and replaces it with a
simpler check. Ok if that passes too?
Bernd
Index: gcc/ifcvt.c
===================================================================
--- gcc/ifcvt.c (revision 229049)
+++ gcc/ifcvt.c (working copy)
@@ -2868,11 +2868,12 @@ noce_mem_write_may_trap_or_fault_p (cons
return false;
break;
case LABEL_REF:
- return true;
+ gcc_unreachable ();
case SYMBOL_REF:
if (SYMBOL_REF_DECL (addr)
&& decl_readonly_section (SYMBOL_REF_DECL (addr), 0))
- return true;
+ gcc_unreachable ();
+
return false;
default:
return false;
* ifcvt.c (noce_mem_write_may_trap_or_fault_p): Delete function.
(noce_process_if_block): Don't call it, test MEM_READONLY_P and
may_trap_or_fault_p instead.
Index: gcc/ifcvt.c
===================================================================
--- gcc/ifcvt.c (revision 229049)
+++ gcc/ifcvt.c (working copy)
@@ -2828,59 +2828,6 @@ noce_operand_ok (const_rtx op)
return ! may_trap_p (op);
}
-/* Return true if a write into MEM may trap or fault. */
-
-static bool
-noce_mem_write_may_trap_or_fault_p (const_rtx mem)
-{
- rtx addr;
-
- if (MEM_READONLY_P (mem))
- return true;
-
- if (may_trap_or_fault_p (mem))
- return true;
-
- addr = XEXP (mem, 0);
-
- /* Call target hook to avoid the effects of -fpic etc.... */
- addr = targetm.delegitimize_address (addr);
-
- while (addr)
- switch (GET_CODE (addr))
- {
- case CONST:
- case PRE_DEC:
- case PRE_INC:
- case POST_DEC:
- case POST_INC:
- case POST_MODIFY:
- addr = XEXP (addr, 0);
- break;
- case LO_SUM:
- case PRE_MODIFY:
- addr = XEXP (addr, 1);
- break;
- case PLUS:
- if (CONST_INT_P (XEXP (addr, 1)))
- addr = XEXP (addr, 0);
- else
- return false;
- break;
- case LABEL_REF:
- return true;
- case SYMBOL_REF:
- if (SYMBOL_REF_DECL (addr)
- && decl_readonly_section (SYMBOL_REF_DECL (addr), 0))
- return true;
- return false;
- default:
- return false;
- }
-
- return false;
-}
-
/* Return whether we can use store speculation for MEM. TOP_BB is the
basic block above the conditional block where we are considering
doing the speculative store. We look for whether MEM is set
@@ -3210,7 +3157,8 @@ noce_process_if_block (struct noce_if_in
THEN and ELSE arms, then we can go ahead with the conversion;
either the program is broken, or the condition is always
false such that the other memory is selected. */
- if (noce_mem_write_may_trap_or_fault_p (orig_x))
+ if (may_trap_or_fault_p (orig_x)
+ || MEM_READONLY_P (orig_x))
return FALSE;
/* Avoid store speculation: given "if (...) x = a" where x is a