]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR rtl-optimization/64916
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 21 Apr 2015 05:23:08 +0000 (05:23 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 21 Apr 2015 05:23:08 +0000 (05:23 +0000)
        * cfgcleanup.c (values_equal_p): New function.
        (can_replace_by): Use it.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@222256 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cfgcleanup.c

index 659ac0133abff5646f9350d4450418438d36a6e5..47089f366c4dc0d0f150934f5a73309c7e865199 100644 (file)
@@ -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
index cee152e90cea44e21e94e8c1b83e69ab4340e562..93f682f6847817facb81d4b073231c3ecc93c206 100644 (file)
@@ -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)