given an empty BB to convert, and we can't handle that. */
gcc_assert (!insn_info.is_empty ());
- /* Now fixup the assignments. */
- for (unsigned i = 0; i < insn_info.length (); i++)
- if (insn_info[i]->target != insn_info[i]->temporary)
- noce_emit_move_insn (insn_info[i]->target, insn_info[i]->temporary);
+ /* Now fixup the assignments.
+ PR116405: Iterate in reverse order and keep track of the targets so that
+ a move does not overwrite a subsequent value when multiple instructions
+ have the same target. */
+ unsigned i;
+ noce_multiple_sets_info *info;
+ bitmap set_targets = BITMAP_ALLOC (®_obstack);
+ FOR_EACH_VEC_ELT_REVERSE (insn_info, i, info)
+ {
+ gcc_checking_assert (REG_P (info->target));
+
+ if (info->target != info->temporary
+ && !bitmap_bit_p (set_targets, REGNO (info->target)))
+ noce_emit_move_insn (info->target, info->temporary);
+
+ bitmap_set_bit (set_targets, REGNO (info->target));
+ }
+ BITMAP_FREE (set_targets);
/* Actually emit the sequence if it isn't too expensive. */
rtx_insn *seq = get_insns ();
--- /dev/null
+/* PR rtl-optimization/116372 */
+/* { dg-do run } */
+/* { dg-options "-O1" } */
+/* { dg-additional-options "-march=z13" { target s390x-*-* } } */
+
+long x = -0x7fffffff - 1;
+int main (void)
+{
+ long y = x % (-0xf - 1);
+ if (-0x7fffffff - 1 + y == x == 0)
+ __builtin_abort ();
+ return 0;
+}
--- /dev/null
+/* PR rtl-optimization/116405 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-ssa-phiopt -fno-tree-dce" } */
+
+int printf(const char *, ...);
+int a, b = 2, c = 1;
+unsigned d, e;
+int main() {
+ L:
+ a = -1 / c;
+ d = ~(b && (c && ~e) & b);
+ printf("0\n");
+ c = 0;
+ if (d != -1)
+ goto L;
+ return 0;
+}