https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99930

--- Comment #7 from Hongtao.liu <crazylht at gmail dot com> ---
i'm testing

1 file changed, 30 insertions(+)
gcc/combine.c | 30 ++++++++++++++++++++++++++++++

modified   gcc/combine.c
@@ -1811,6 +1811,33 @@ set_nonzero_bits_and_sign_copies (rtx x, const_rtx set,
void *data)
        }
     }
 }
+
+/* Return true is reg is only defined by loading from constant pool.  */
+static int
+single_ref_from_constant_pool (rtx reg)
+{
+  gcc_assert (REG_P (reg));
+  rtx_insn* insn;
+  rtx src, set;
+
+  if (DF_REG_DEF_COUNT (REGNO (reg)) != 1)
+    return 0;
+  insn = DF_REF_INSN (DF_REG_DEF_CHAIN (REGNO (reg)));
+  if (!insn)
+    return 0;
+  set = single_set (insn);
+  if (!set)
+    return 0;
+  src = SET_SRC (set);
+
+  /* Constant pool.  */
+  if (!MEM_P (src)
+      || !SYMBOL_REF_P (XEXP (src, 0))
+      || !CONSTANT_POOL_ADDRESS_P (XEXP (src, 0)))
+    return 0;
+
+  return 1;
+}

 /* See if INSN can be combined into I3.  PRED, PRED2, SUCC and SUCC2 are
    optionally insns that were previously combined into I3 or that will be
@@ -1895,7 +1922,10 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn
*pred ATTRIBUTE_UNUSED,
                 something to tell them apart, e.g. different modes.  For
                 now, we forgo such complicated tests and simply disallow
                 combining of USES of pseudo registers with any other USE.  */
+             /* If the USE in INSN is only defined by loading from constant
+                pool, it must have identical value.  */
              if (REG_P (XEXP (elt, 0))
+                 && !single_ref_from_constant_pool (XEXP (elt, 0))
                  && GET_CODE (PATTERN (i3)) == PARALLEL)
                {
                  rtx i3pat = PATTERN (i3);

Reply via email to