diff --git a/gcc/regrename.c b/gcc/regrename.c
index fe72fcc362413e2eaefe8f5fc377464395e338aa..c34ea6be76b36e56df58c814d747a03f2f2b277a 100644
--- a/gcc/regrename.c
+++ b/gcc/regrename.c
@@ -394,10 +394,15 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
 			  this_head, *unavailable))
     return this_head->tied_chain->regno;
 
-  /* If this insn is a noop move, then do not rename in this chain as doing so
-     would inhibit removal of the noop move.  */
-  if (noop_move_p (this_head->first->insn))
-    return best_new_reg;
+  /* If the first non-debug insn is a noop move, then do not rename in this
+     chain as doing so would inhibit removal of the noop move.  */
+  for (struct du_chain *tmp = this_head->first; tmp; tmp = tmp->next_use)
+    if (DEBUG_INSN_P (tmp->insn))
+      continue;
+    else if (noop_move_p (tmp->insn))
+      return best_new_reg;
+    else
+      break;
 
   /* If PREFERRED_CLASS is not NO_REGS, we iterate in the first pass
      over registers that belong to PREFERRED_CLASS and try to find the
diff --git a/gcc/testsuite/g++.dg/opt/pr103756.C b/gcc/testsuite/g++.dg/opt/pr103756.C
new file mode 100644
index 0000000000000000000000000000000000000000..d6d75966d74efeb6a0b8fb019841dd506924c0e1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr103756.C
@@ -0,0 +1,57 @@
+// PR rtl-optimization/103756
+// { dg-do compile }
+// { dg-options "-std=c++17 -O -fcompare-debug -fconserve-stack -frename-registers -fno-tree-ch -fira-algorithm=priority" }
+
+char __copy_move_b___trans_tmp_9;
+template <typename> struct __iterator_traits;
+template <typename _Tp> struct __iterator_traits<_Tp *> {
+  typedef _Tp &reference;
+};
+template <typename _Iterator> struct reverse_iterator {
+  _Iterator current;
+  reverse_iterator();
+  reverse_iterator(reverse_iterator &__x) : current(__x.current) {}
+  _Iterator base() { return current; }
+  typename __iterator_traits<_Iterator>::reference operator*() {
+    return *current;
+  }
+  reverse_iterator operator--() {
+    ++current;
+    return *this;
+  }
+};
+template <typename _IteratorL, typename _IteratorR>
+auto operator-(_IteratorL __x, _IteratorR __y) {
+  return __y - __x.base();
+}
+struct __copy_move_backward {
+  template <typename _BI1, typename _BI2>
+  static _BI2 __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result) {
+    typename __n = __last - __first;
+    for (; __n > 0; --__n) {
+      reverse_iterator __trans_tmp_8 = --__result;
+      *__trans_tmp_8 = __copy_move_b___trans_tmp_9;
+    }
+    return __result;
+  }
+};
+template <int, typename _BI1, typename _BI2>
+inline _BI2 __copy_move_backward_a2(_BI1 __first, _BI1 __last, _BI2 __result) {
+  return __copy_move_backward::__copy_move_b(__first, __last, __result);
+}
+template <int _IsMove, typename _BI1, typename _BI2>
+_BI2 __copy_move_backward_a1(_BI1 __last, _BI2 __result) {
+  _BI1 __first;
+  return __copy_move_backward_a2<_IsMove>(__first, __last, __result);
+}
+template <int _IsMove, typename _II, typename _OI>
+void __copy_move_backward_a(_II, _OI __result) {
+  reverse_iterator<unsigned char *> __trans_tmp_7 =
+      __copy_move_backward_a1<_IsMove>(__trans_tmp_7, __result);
+}
+template <typename _BI1, typename _BI2>
+void move_backward(_BI1 __first, _BI2 __result) {
+  __copy_move_backward_a<true>(__first, __result);
+}
+reverse_iterator<unsigned char *> __rotate___first;
+void __rotate() { move_backward(__rotate___first, __rotate___first); }