<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/65041>65041</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            unnecessary `mov` added in string concatination code with >= `-O2`
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          firewave
      </td>
    </tr>
</table>

<pre>
    ```cpp
#include <string>

std::string cb();

std::string f1()
{
 std::string s;
    s += cb();
    s += ' ';
    return s;
}
```

Compiling this >= `-O2` introduces an additional `mov` within a label. There are bigger differences in the IR but it mainly seems to be a moved block.

```diff
 .LBB0_7:
+        mov     rcx, qword ptr [rbx]
         mov     r14, qword ptr [rbx + 8]
         lea r12, [r14 + 1]
         mov     eax, 15
-        cmp     qword ptr [rbx], r15
+        cmp     rcx, r15
         je      .LBB0_9
 mov     rax, qword ptr [rbx + 16]
```

```diff
@@ -55,51 +55,55 @@
   %8 = load i64, ptr %0, align 8
   %cond.i.i.i = select i1 %cmp.i.i.i.i14, i64 15, i64 %8
   %cmp.i.i = icmp ugt i64 %add.i.i, %cond.i.i.i
-  br i1 %cmp.i.i, label %if.then.i.i15, label %_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLEc.exit
+  br i1 %cmp.i.i, label %if.then.i.i15, label %nrvo.skipdtor
 
 if.then.i.i15:
   invoke void @std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long, unsigned long, char const*, unsigned long)(ptr noundef nonnull align 8 dereferenceable(32) %agg.result, i64 noundef %6, i64 noundef 0, ptr noundef null, i64 noundef 1)
-          to label %_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLEc.exit unwind label %lpad3
+          to label %.noexc16 unwind label %lpad3
 
-_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLEc.exit:
-  %9 = load ptr, ptr %agg.result, align 8
-  %arrayidx.i.i = getelementptr inbounds i8, ptr %9, i64 %6
-  store i8 32, ptr %arrayidx.i.i, align 1
-  store i64 %add.i.i, ptr %_M_string_length.i.i.i, align 8
-  %10 = load ptr, ptr %agg.result, align 8
-  %arrayidx.i.i.i = getelementptr inbounds i8, ptr %10, i64 %add.i.i
-  store i8 0, ptr %arrayidx.i.i.i, align 1
-  ret void
+.noexc16:
+  %.pre.i.i = load ptr, ptr %agg.result, align 8
+  br label %nrvo.skipdtor
 
 lpad:
-  %11 = landingpad { ptr, i32 }
+  %9 = landingpad { ptr, i32 }
 cleanup
   br label %ehcleanup
 
 lpad1:
-  %12 = landingpad { ptr, i32 }
+  %10 = landingpad { ptr, i32 }
           cleanup
- %13 = load ptr, ptr %ref.tmp, align 8
-  %14 = getelementptr inbounds %"class.std::__cxx11::basic_string", ptr %ref.tmp, i64 0, i32 2
- %cmp.i.i.i17 = icmp eq ptr %13, %14
+  %11 = load ptr, ptr %ref.tmp, align 8
+  %12 = getelementptr inbounds %"class.std::__cxx11::basic_string", ptr %ref.tmp, i64 0, i32 2
+  %cmp.i.i.i17 = icmp eq ptr %11, %12
   br i1 %cmp.i.i.i17, label %ehcleanup, label %if.then.i.i18
 
 if.then.i.i18:
-  call void @operator delete(void*)(ptr noundef %13) #7
+  call void @operator delete(void*)(ptr noundef %11) #7
   br label %ehcleanup
 
 ehcleanup:
-  %.pn = phi { ptr, i32 } [ %11, %lpad ], [ %12, %lpad1 ], [ %12, %if.then.i.i18 ]
+  %.pn = phi { ptr, i32 } [ %9, %lpad ], [ %10, %lpad1 ], [ %10, %if.then.i.i18 ]
   call void @llvm.lifetime.end.p0(i64 32, ptr nonnull %ref.tmp) #5
   br label %ehcleanup6
 
 lpad3:
-  %15 = landingpad { ptr, i32 }
+  %13 = landingpad { ptr, i32 }
           cleanup
   br label %ehcleanup6
 
+nrvo.skipdtor:
+  %14 = phi ptr [ %.pre.i.i, %.noexc16 ], [ %7, %_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED2Ev.exit ]
+ %arrayidx.i.i = getelementptr inbounds i8, ptr %14, i64 %6
+  store i8 32, ptr %arrayidx.i.i, align 1
+  store i64 %add.i.i, ptr %_M_string_length.i.i.i, align 8
+  %15 = load ptr, ptr %agg.result, align 8
+  %arrayidx.i.i.i = getelementptr inbounds i8, ptr %15, i64 %add.i.i
+  store i8 0, ptr %arrayidx.i.i.i, align 1
+  ret void
+
 ehcleanup6:
-  %.pn9 = phi { ptr, i32 } [ %15, %lpad3 ], [ %.pn, %ehcleanup ]
+  %.pn9 = phi { ptr, i32 } [ %13, %lpad3 ], [ %.pn, %ehcleanup ]
   %16 = load ptr, ptr %agg.result, align 8
 %cmp.i.i.i20 = icmp eq ptr %16, %0
   br i1 %cmp.i.i.i20, label %_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED2Ev.exit22, label %if.then.i.i21
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEWFmPozoW_jXOy1EQNmHJQx46tUgt3TsjTc_TvEQGnyS-7RiuMemqfz-yWQLZJlXV0lQvUJx98XcO8LqWO424IvGaxM8z3th9aVZbafAXP-IsL8X7iiRh-7eoKhI-k_AbYZHUhWoEAomeamuk3pHopSP6_2srSPSNRN9aKhQ5YRlhSxKt77FtacfW8qQdM5zz1YMeAIAaCFuT6PnSyoRKWOr-TYgGbWP0SB9Jn7ubPuyxv0_loZLKeWD3sgYXtFOchPN_MpKEILU1pWgKrIFr4EJIK0vNlWM5lEfH8kvavdTAQfEcVQD_3qNB4AYhl7sdGhByu0WD2imRGuwe4fu_IG8sSAsHLrV6hxrxUIMtIUfgcCiPKCBXZfEzGHs7hOBUdjEHf6zX4SZ12exquYbu51Ae_dUUb4Q9wd-_SiOgsgZIvDb5G4mfT3mbCtDFNQGXd8guxRRyMJQ5EcdIF56R3taP3DtE45Y-7-nFofLXa56yJzC9wCjGXqSLcWAZbP6F7bXNU9eIp0j51dS0ASRDBFd750o1yCIkixDmcUzYU0ydmvY2hpY0OEdYnIHrNVVyATLxCfcOsDh091zJnYZsLFCUWgTS_fGSNSosLEjqaYeqJQWyLZ5MFi7B3Z0zN1HVsns90uWw2dmekQtvxZdzbHQoVm6mRh2nb373TG4Du0ftHYknlM1__vHDpptN8fZGKWU5r2Wxac__9-KHpbTYc7Oxhktbfy9efvDvxctL9cdLEeCbtKPKf9K-NscyqH_KStjSdMnoLlOh_igBgNTH8ifCsZTCVXCArS6K9pdxJCR6cmE4wwPzKK6eHL1MOLhSZcGdWwO9xSJv68_NobHcImFZoz3AC1Cl3jkVFw-cOBSlri1h365wLAnLXJ_pstECt6BLrRul-n4DgQY7uOK5cjYjRtjSN8ZuFxisG2X7tuqVEBYn58_CvqMHS41S50x0mA0DCICDwd_UNNDoX1KLkzpVcRFdgMjUZKBLfCtock-4a5z5F3u677S5P5TLEyBU1owAYZr4CTK0ktwY_i7F23Cmd2hR4QG1dSqkzl2-a5DZSOtyBA7JoK22pUGQGURs7MHIwMkHei51ASCd-ObPLikbhXpn9x2gXA-Ghr8lDx_IBA1Hqei9v0hIeCMf1zNi0HrYGJqtb6vppHb9Vhkc3P1Y1D0cPoJxrnvPGo7S1ibXQupdxQWQdN1blxGD0_LU-bp8VAAKhVw31YCkYy9xP6WOPKTnLrKPuti3zwM-nn4m_sy9muhWPQxuA3uobnXv4l7bERYTxgrF6zp4YJgwdt2ua9Wwj4eNvB7WAJqeZjv-PTR61E11ujhLGv1otIMk-z_F2zvwv0Kmfchs3ItnWxNNJ6vCqUFvrRbZ7QUiG7dwwZUa1oeyQuOmPAhU6Oe5Rwg3p8_HclcsN3ejdBTwV_TRqb7HDuXp8fRgBpX26a728soBc3v0JPvKH8R2j-9pbESjt4iTzMJpIx_A8xE3lne8CO95Ed73As4KotTxECi5RSsPGKAWQRUSlrn2PY3TfuMat7ivS3y_LsklWkbnaBl_GC2jr6LlY-4Stp7OpvMp2OGmq2P3HjaejV0ZhtVsWqa0I39qG3tmL8d2WZw012e3qtPb12mt8jF-YrEay31xtRrSHH92zfjCehXfWq-mifnAguUFL1asc8hKLjFr-QhoxSNIiM56Lah0Rx3MXEWlhwxFnzXUvsW7g_DhYk7mHguvzsyksxzeGZks_Prb_XD22sF_bdIyeva1ZSZWkVhGSz7DFU2WEWPpIotn-9W2SKOtWKScFkvOtnkaJwXmS5oKkYUi3s7kioUsCjOWURZn4SKgLMmTPN1ulwXHSMRkEeKBSxV4HC_NbibrusFVEocLOvPe1f2nVbNyTPO82dUO-GVt65OYlVbhqtEaC6xrbt5H3wu5EChAaui_pJa64FZqbmWpoSgF-k-KF98iZ41Rq721Ve26mr0S9rqTdt_kQVEeCHt1xrvLvDLlX1hYwl59ADVhrz6G_wYAAP__mos6ew">