@@ -2610,6 +2610,30 @@ count_auto_inc (rtx, rtx, rtx, rtx, rtx,
return 0;
}
+/* Wrapper around propagate_for_debug to deal with gen_lowpart_for_combine
+ (clobber (const_int 0)). In normal insns a clobber of const0_rtx nested
+ somewhere will cause the pattern not to be recognized, but in debug insns
+ it doesn't, one needs to use something on which volatile_insn_p is true
+ instead. */
+
+static void
+combine_propagate_for_debug (rtx_insn *insn, rtx_insn *last, rtx dest, rtx src,
+ basic_block this_basic_block)
+{
+ subrtx_iterator::array_type array;
+ FOR_EACH_SUBRTX (iter, array, src, ALL)
+ {
+ const_rtx x = *iter;
+ if (GET_CODE (x) == CLOBBER && XEXP (x, 0) == const0_rtx)
+ {
+ src = gen_rtx_UNSPEC_VOLATILE (GET_MODE (dest),
+ gen_rtvec (1, const0_rtx), -1);
+ break;
+ }
+ }
+ propagate_for_debug (insn, last, dest, src, this_basic_block);
+}
+
/* Try to combine the insns I0, I1 and I2 into I3.
Here I0, I1 and I2 appear earlier than I3.
I0 and I1 can be zero; then we combine just I2 into I3, or I1 and I2 into
@@ -4200,8 +4224,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2,
i2src while its original mode is temporarily
restored, and then clear i2scratch so that we don't
do it again later. */
- propagate_for_debug (i2, last_combined_insn, reg, i2src,
- this_basic_block);
+ combine_propagate_for_debug (i2, last_combined_insn, reg,
+ i2src, this_basic_block);
i2scratch = false;
/* Put back the new mode. */
adjust_reg_mode (reg, new_mode);
@@ -4235,12 +4259,13 @@ try_combine (rtx_insn *i3, rtx_insn *i2,
with this copy we have created; then, replace the
copy with the SUBREG of the original shared reg,
once again changed to the new mode. */
- propagate_for_debug (first, last, reg, tempreg,
- this_basic_block);
+ combine_propagate_for_debug (first, last, reg, tempreg,
+ this_basic_block);
adjust_reg_mode (reg, new_mode);
- propagate_for_debug (first, last, tempreg,
- lowpart_subreg (old_mode, reg, new_mode),
- this_basic_block);
+ combine_propagate_for_debug (first, last, tempreg,
+ lowpart_subreg (old_mode, reg,
+ new_mode),
+ this_basic_block);
}
}
}
@@ -4499,16 +4524,16 @@ try_combine (rtx_insn *i3, rtx_insn *i2,
if (newi2pat)
{
if (MAY_HAVE_DEBUG_BIND_INSNS && i2scratch)
- propagate_for_debug (i2, last_combined_insn, i2dest, i2src,
- this_basic_block);
+ combine_propagate_for_debug (i2, last_combined_insn, i2dest, i2src,
+ this_basic_block);
INSN_CODE (i2) = i2_code_number;
PATTERN (i2) = newi2pat;
}
else
{
if (MAY_HAVE_DEBUG_BIND_INSNS && i2src)
- propagate_for_debug (i2, last_combined_insn, i2dest, i2src,
- this_basic_block);
+ combine_propagate_for_debug (i2, last_combined_insn, i2dest, i2src,
+ this_basic_block);
SET_INSN_DELETED (i2);
}
@@ -4517,8 +4542,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2,
LOG_LINKS (i1) = NULL;
REG_NOTES (i1) = 0;
if (MAY_HAVE_DEBUG_BIND_INSNS)
- propagate_for_debug (i1, last_combined_insn, i1dest, i1src,
- this_basic_block);
+ combine_propagate_for_debug (i1, last_combined_insn, i1dest, i1src,
+ this_basic_block);
SET_INSN_DELETED (i1);
}
@@ -4527,8 +4552,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2,
LOG_LINKS (i0) = NULL;
REG_NOTES (i0) = 0;
if (MAY_HAVE_DEBUG_BIND_INSNS)
- propagate_for_debug (i0, last_combined_insn, i0dest, i0src,
- this_basic_block);
+ combine_propagate_for_debug (i0, last_combined_insn, i0dest, i0src,
+ this_basic_block);
SET_INSN_DELETED (i0);
}
@@ -0,0 +1,10 @@
+/* PR debug/99830 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -fno-expensive-optimizations -fno-split-wide-types -g" } */
+
+int foo (long a, __int128 b, short c, int d, unsigned e, __int128 f)
+{
+ __builtin_memmove (2 + (char *) &f, foo, 1);
+ c >>= (char) f;
+ return c;
+}