This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
m68k: handle register conflict with PRE_DEC in notice_update_cc
- From: Andreas Schwab <schwab at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 22 Oct 2013 14:36:54 +0200
- Subject: m68k: handle register conflict with PRE_DEC in notice_update_cc
- Authentication-results: sourceware.org; auth=none
When compiling libxml2 with -O2 -fomit-frame-pointer the following pair
of insns is generated:
(insn 113 112 114 (set (mem:SI (pre_dec:SI (reg/f:SI 15 %sp)) [0 S4 A16])
(mem/c:SI (plus:SI (reg/f:SI 15 %sp)
(const_int 44 [0x2c])) [5 strict+0 S4 A32])) xpath.i:269 38 {*movsi_m68k2}
(expr_list:REG_ARGS_SIZE (const_int 12 [0xc])
(nil)))
(insn 114 113 115 (set (cc0)
(compare (mem/c:SI (plus:SI (reg/f:SI 15 %sp)
(const_int 44 [0x2c])) [5 inf+0 S4 A32])
(const_int 0 [0]))) xpath.i:269 4 {*tstsi_internal_68020_cf}
(nil))
For rtl_equal_p (mem/c:SI (plus:SI (reg/f:SI 15 %sp) (const_int 44
[0x2c])) [5 strict+0 S4 A32]) and (mem/c:SI (plus:SI (reg/f:SI 15 %sp)
(const_int 44 [0x2c])) [5 inf+0 S4 A32]) look the same, so
final_scan_insn thinks the latter insn is a redundant test. But since
pre_dec has modified %sp the two mems refer to two different stack
slots. notice_update_cc should not register the src operand in the
first insn as a CC status setter in this case.
Bootstrapped and tested on m68k-suse-linux, committed to trunk.
Andreas.
* config/m68k/m68k.c (notice_update_cc): Handle register conflict
with PRE_DEC.
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index 5e3236f..7035504 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -4209,6 +4209,13 @@ notice_update_cc (rtx exp, rtx insn)
&& cc_status.value2
&& reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
cc_status.value2 = 0;
+ /* Check for PRE_DEC in dest modifying a register used in src. */
+ if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM
+ && GET_CODE (XEXP (cc_status.value1, 0)) == PRE_DEC
+ && cc_status.value2
+ && reg_overlap_mentioned_p (XEXP (XEXP (cc_status.value1, 0), 0),
+ cc_status.value2))
+ cc_status.value2 = 0;
if (((cc_status.value1 && FP_REG_P (cc_status.value1))
|| (cc_status.value2 && FP_REG_P (cc_status.value2))))
cc_status.flags = CC_IN_68881;
--
1.8.4.1
--
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."