From 3e87f2d6dd6a38e650b77445a38c9ebbe7988e23 Mon Sep 17 00:00:00 2001 From: Shiva Chen Date: Tue, 21 Apr 2015 05:23:08 +0000 Subject: [PATCH] re PR rtl-optimization/64916 (ira.c update_equiv_regs patch causes gcc/testsuite/gcc.target/arm/pr43920-2.c regression) PR rtl-optimization/64916 * cfgcleanup.c (values_equal_p): New function. (can_replace_by): Use it. From-SVN: r222256 --- gcc/ChangeLog | 6 ++++++ gcc/cfgcleanup.c | 48 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 659ac0133ab..47089f366c4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-04-20 Shiva Chen + + PR rtl-optimization/64916 + * cfgcleanup.c (values_equal_p): New function. + (can_replace_by): Use it. + 2015-04-20 Paolo Carlini PR c++/65801 diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index cee152e90ce..93f682f6847 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -1038,6 +1038,45 @@ equal_different_set_p (rtx p1, rtx s1, rtx p2, rtx s2) return true; } + +/* NOTE1 is the REG_EQUAL note, if any, attached to an insn + that is a single_set with a SET_SRC of SRC1. Similarly + for NOTE2/SRC2. + + So effectively NOTE1/NOTE2 are an alternate form of + SRC1/SRC2 respectively. + + Return nonzero if SRC1 or NOTE1 has the same constant + integer value as SRC2 or NOTE2. Else return zero. */ +static int +values_equal_p (rtx note1, rtx note2, rtx src1, rtx src2) +{ + if (note1 + && note2 + && CONST_INT_P (XEXP (note1, 0)) + && rtx_equal_p (XEXP (note1, 0), XEXP (note2, 0))) + return 1; + + if (!note1 + && !note2 + && CONST_INT_P (src1) + && CONST_INT_P (src2) + && rtx_equal_p (src1, src2)) + return 1; + + if (note1 + && CONST_INT_P (src2) + && rtx_equal_p (XEXP (note1, 0), src2)) + return 1; + + if (note2 + && CONST_INT_P (src1) + && rtx_equal_p (XEXP (note2, 0), src1)) + return 1; + + return 0; +} + /* Examine register notes on I1 and I2 and return: - dir_forward if I1 can be replaced by I2, or - dir_backward if I2 can be replaced by I1, or @@ -1066,8 +1105,11 @@ can_replace_by (rtx_insn *i1, rtx_insn *i2) set dest to the same value. */ note1 = find_reg_equal_equiv_note (i1); note2 = find_reg_equal_equiv_note (i2); - if (!note1 || !note2 || !rtx_equal_p (XEXP (note1, 0), XEXP (note2, 0)) - || !CONST_INT_P (XEXP (note1, 0))) + + src1 = SET_SRC (s1); + src2 = SET_SRC (s2); + + if (!values_equal_p (note1, note2, src1, src2)) return dir_none; if (!equal_different_set_p (PATTERN (i1), s1, PATTERN (i2), s2)) @@ -1079,8 +1121,6 @@ can_replace_by (rtx_insn *i1, rtx_insn *i2) (set (dest) (reg)) because we don't know if the reg is live and has the same value at the location of replacement. */ - src1 = SET_SRC (s1); - src2 = SET_SRC (s2); c1 = CONST_INT_P (src1); c2 = CONST_INT_P (src2); if (c1 && c2)