aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/cfgcleanup.c48
2 files changed, 50 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 659ac013..47089f3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2015-04-20 Shiva Chen <shiva0217@gmail.com>
+
+ PR rtl-optimization/64916
+ * cfgcleanup.c (values_equal_p): New function.
+ (can_replace_by): Use it.
+
2015-04-20 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/65801
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index cee152e..93f682f 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)