<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Hi Daniel,</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Thanks for the feedback, that's interesting, and for raising the bug. <span style="color: rgb(0, 0, 0); font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt;">I will do a first finger on the pulse and see if I can address that issue on the side,
 but am not promising anything. :-)</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Cheers,</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Sjoerd.</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Daniel Way <p.waydan@gmail.com><br>
<b>Sent:</b> 22 July 2020 04:33<br>
<b>To:</b> Sjoerd Meijer <Sjoerd.Meijer@arm.com><br>
<b>Cc:</b> llvm-dev@lists.llvm.org <llvm-dev@lists.llvm.org><br>
<b>Subject:</b> Re: [llvm-dev] [ARM] Should Use Load and Store with Register Offset</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<div class="x_gmail_default" style="font-family:arial,helvetica,sans-serif">Thank you, Sjoerd.</div>
<div class="x_gmail_default" style="font-family:arial,helvetica,sans-serif"><br>
</div>
<div class="x_gmail_default" style="font-family:arial,helvetica,sans-serif">Your high-level comments are very helpful and much appreciated. I ended up rebuilding the Newlib-nano source with -Oz instead of -Os and found an overall improvement in code size. The
 final size is still larger than the gcc-arm-none-eabi toolchain. Of course there are a few caveats to this:</div>
<div class="x_gmail_default" style="">
<ul style="font-family:arial,helvetica,sans-serif">
<li>Newlib is designed around GCC;</li><li>I'm not sure I perfectly reproduced the build settings for the pre-built toolchain (macros, etc.);</li><li>and this comparison considers all libc functions, many of which may not end up in the final image.</li></ul>
<div style=""><font face="arial, helvetica, sans-serif">For now, I've submitted </font><u>BUG 46801</u> for the case when -Oz produces more instructions than -Os. I don't know if it needs to be a priority, but thought it should be recorded.</div>
<div style=""><br>
</div>
<div style="">I may try benchmarking the memcpy implementations as well as a few other libc functions, but I haven't done this before. Of course, I'll share my results if I do end up testing.</div>
<div style=""><br>
</div>
<div style="">Thank you for the help.</div>
</div>
<div>
<div dir="ltr" class="x_gmail_signature">
<div dir="ltr">
<div>Daniel Way</div>
</div>
</div>
</div>
<br>
</div>
<br>
<div class="x_gmail_quote">
<div dir="ltr" class="x_gmail_attr">On Tue, Jul 21, 2020 at 6:05 PM Sjoerd Meijer <<a href="mailto:Sjoerd.Meijer@arm.com">Sjoerd.Meijer@arm.com</a>> wrote:<br>
</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<div dir="ltr">
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Hi Daniel,</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Your observations seem valid to me. <span style="color:rgb(0,0,0); font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt">Some high-level comments from my side.</span></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<span style="color:rgb(0,0,0); font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt"><br>
</span></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<span style="color:rgb(0,0,0); font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt">As you said, the loops are quite similar. We have also observed that in general we generate more code around loops, in the function prologue and epilogue, where some
 data and arguments get moved and reshuffled etc. While this is very obvious in these micro-benchmarks, it hasn't bothered us enough yet for larger apps where this is less important (or where others things are more important). </span><span style="color:rgb(0,0,0); font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt">The
 outlier looks indeed to be Clang -Oz for memcpy_alt2, that is perhaps a "code-size bug". As I haven't looked into it, it's too early for me to blame this on just the addressing modes as there could be several things going on.</span></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<span style="color:rgb(0,0,0); font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt"><br>
</span></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<span style="color:rgb(0,0,0); font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt">Since this is a micro-benchmark, and lowering memcpy is a bit of an art ;-), for which a specialised implementation is probably available, you might want to look
 at some other codes too that are important for you. </span></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Your remarks about execution times might be right too, and as you said, probably best confirmed with benchmark numbers. <span style="font-family:Calibri,Arial,Helvetica,sans-serif; background-color:rgb(255,255,255); display:inline">In our group, we have not
 really looked into performance for the Cortex-M0, probably because it's the only v6m core (although the Cortex-m23 and Armv8-M Baseline is very similar) and code-size would be more important for us, but there might be something to be gained here.</span></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<span style="font-family:Calibri,Arial,Helvetica,sans-serif; background-color:rgb(255,255,255); display:inline"><br>
</span></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<span style="font-family:Calibri,Arial,Helvetica,sans-serif; background-color:rgb(255,255,255); display:inline">Cheers,</span></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<span style="font-family:Calibri,Arial,Helvetica,sans-serif; background-color:rgb(255,255,255); display:inline">Sjoerd.</span></div>
<div id="x_gmail-m_5502571546344790849appendonsend"></div>
<hr style="display:inline-block; width:98%">
<div id="x_gmail-m_5502571546344790849divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> Daniel Way <<a href="mailto:p.waydan@gmail.com" target="_blank">p.waydan@gmail.com</a>><br>
<b>Sent:</b> 21 July 2020 08:12<br>
<b>To:</b> Sjoerd Meijer <<a href="mailto:Sjoerd.Meijer@arm.com" target="_blank">Sjoerd.Meijer@arm.com</a>><br>
<b>Cc:</b> <a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a> <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
<b>Subject:</b> Re: [llvm-dev] [ARM] Should Use Load and Store with Register Offset</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<div style="font-family:arial,helvetica,sans-serif">
<div>Hello Sjoerd,</div>
<div><br>
</div>
<div>Thank you for your response! I was not aware that -Oz is a closer equivalent to GCC's -Os. I tried -Oz when compiling with clang and confirmed that the Clang's generated assembly is equivalent to GCC for the code snippet I posted above.</div>
<div><br>
</div>
<div>
<div style="color:rgb(0,0,0); background-color:rgb(255,255,254)">
<div><font face="monospace">clang --target=armv6m-none-eabi -Oz -fomit-frame-pointer<br>
</font></div>
<div><span style="color:rgb(0,128,128)"><font face="monospace">memcpy_alt1:</font></span></div>
<div><font face="monospace">        <span style="color:rgb(0,0,255)">push</span>    {<span style="color:rgb(72,100,170)">r4</span>, <span style="color:rgb(72,100,170)">lr</span>}</font></div>
<div><font face="monospace">        <span style="color:rgb(0,0,255)">movs</span>    <span style="color:rgb(72,100,170)">r3</span>, <span style="color:rgb(9,134,88)">#0</span></font></div>
<div><span style="color:rgb(0,128,128)"><font face="monospace">.LBB0_1:</font></span></div>
<div><font face="monospace">        <span style="color:rgb(0,0,255)">cmp</span>     <span style="color:rgb(72,100,170)">r2</span>, <span style="color:rgb(72,100,170)">r3</span></font></div>
<div><font face="monospace">        <span style="color:rgb(0,0,255)">beq</span>     <span style="color:rgb(0,128,128)">.LBB0_3</span></font></div>
<div><font face="monospace">        <span style="color:rgb(0,0,255)">ldrb</span>    <span style="color:rgb(72,100,170)">r4</span>, [<span style="color:rgb(72,100,170)">r1</span>, <span style="color:rgb(72,100,170)">r3</span>]</font></div>
<div><font face="monospace">        <span style="color:rgb(0,0,255)">strb</span>    <span style="color:rgb(72,100,170)">r4</span>, [<span style="color:rgb(72,100,170)">r0</span>, <span style="color:rgb(72,100,170)">r3</span>]</font></div>
<div><font face="monospace">        <span style="color:rgb(0,0,255)">adds</span>    <span style="color:rgb(72,100,170)">r3</span>, <span style="color:rgb(72,100,170)">r3</span>, <span style="color:rgb(9,134,88)">#1</span></font></div>
<div><font face="monospace">        <span style="color:rgb(0,0,255)">b</span>       <span style="color:rgb(0,128,128)">.LBB0_1</span></font></div>
<div><span style="color:rgb(0,128,128)"><font face="monospace">.LBB0_3:</font></span></div>
<div><font face="monospace">        <span style="color:rgb(0,0,255)">pop</span>     {<span style="color:rgb(72,100,170)">r4</span>, <span style="color:rgb(0,128,128)">pc</span>}</font></div>
</div>
</div>
<div><br>
</div>
<div>
<div dir="ltr">
<div dir="ltr">
<div>
<div>On the other hand, -O2 in GCC still uses the register-offset load and store instructions while Clang -O2 generates the same assembly as -Os: immediate-offset (0 offset) load/store followed by incrementing the base register addresses.</div>
<div>I have not tried to benchmark the Clang-generated code, it is possible that execution time is bounded by the load and store instructions and memory access latency. From an intuitive view, however, both GCC and Clang are generating code with 1 load and
 1 store, so if Clang inserts two additional adds instructions, the binary size is larger, execution
<i>could</i> be slower, and there's no improvement in register utilization over GCC.</div>
<div><br>
</div>
<div>I wanted to try a couple other variants of memcpy-like functions. The <a href="https://godbolt.org/z/d7P6rG" target="_blank">https://godbolt.org/z/d7P6rG</a> link includes
<font face="monospace">memcpy_alt2</font><font face="arial, helvetica, sans-serif"> which copies data from src to dst starting at the high address and
</font><font face="monospace">memcpy_silly</font><font face="arial, helvetica, sans-serif"> which copies
</font><font face="monospace">src</font><font face="arial, helvetica, sans-serif"> to
</font><font face="monospace">dst<0-4></font><font face="arial, helvetica, sans-serif">. Here is the behavior I have noticed from GCC and Clang.</font></div>
<div><br>
</div>
<div><b><font face="monospace">memcpy_alt2</font></b></div>
<div>
<ul>
<li>With -Os, GCC generates just 6 instructions. -O2 generates 7 but reduces branching to once per loop.</li><li>Clang with -Os or -O2 does a decent job of using a common register to offset the load and store bases. It adds some overhead, though, by pre-decrementing the base registers. 10 instructions generated.</li><li>Clang with -Oz is pathological, generating 13 instructions. It uses register-offset load/store instructions, but uses different registers for the offsets.</li></ul>
</div>
<div><font face="monospace"><b>memcpy_silly</b></font></div>
<div>
<ul>
<li>I created this case to see if clang would select load/store with a common offset register once enough load instructions were added.</li><li>Clang with -Os or -O2 does not seem to care about register-offset load/store and prefers to increment each base register address.</li><li>Clang with -Oz performs the optimization I want. It produces the same number of instructions as GCC, and avoids an issue where GCC has to re-read the same value from the stack each time through the loop.</li></ul>
<div><br>
</div>
<div><font face="arial, helvetica, sans-serif">I really think that, when limited to the Thumb1 ISA, register-offset load and store instructions should be used at -Oz, -Os, and -O2 optimization levels. Explicitly incrementing a register holding the base address
 seems unnecessary when the value seems wasteful and I cannot see how it will improve execution time in the examples I'm investigating. Id like to know if I'm wrong in assuming that </font><font face="monospace">LDR Rd, [Rn, Rm]</font><font face="arial, helvetica, sans-serif">
 and </font><font face="monospace">LDR Rd, [Rn, #<imm>]</font><font face="arial, helvetica, sans-serif"> have the same execution time, but based on the Cortex-M0+ TRM they should both require 2 clock cycles.</font></div>
<div><br>
</div>
<div>Best regards,</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div dir="ltr">
<div dir="ltr">
<div><br>
</div>
<div>Daniel Way</div>
</div>
</div>
</div>
<br>
</div>
<br>
<div>
<div dir="ltr">On Mon, Jul 20, 2020 at 6:15 PM Sjoerd Meijer <<a href="mailto:Sjoerd.Meijer@arm.com" target="_blank">Sjoerd.Meijer@arm.com</a>> wrote:<br>
</div>
<blockquote style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<div dir="ltr">
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Hello Daniel,</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
LLVM and GCC's optimisation levels are not really equivalent. <span style="color:rgb(0,0,0); font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt">In Clang, -Os makes a performance and code-size trade off. In GCC, -Os is minimising code-size, which
 is equivalent to -Oz with Clang. I have't looked into details yet, but changing -Os to -Oz in the godbolt link gives the codegen you're looking for?</span></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Cheers,</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Sjoerd.</div>
<div id="x_gmail-m_5502571546344790849x_gmail-m_-6516534409932401643gmail-m_-3127318562264846581appendonsend">
</div>
<hr style="display:inline-block; width:98%">
<div id="x_gmail-m_5502571546344790849x_gmail-m_-6516534409932401643gmail-m_-3127318562264846581divRplyFwdMsg" dir="ltr">
<font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> llvm-dev <<a href="mailto:llvm-dev-bounces@lists.llvm.org" target="_blank">llvm-dev-bounces@lists.llvm.org</a>> on behalf of Daniel Way via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
<b>Sent:</b> 20 July 2020 06:54<br>
<b>To:</b> <a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a> <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
<b>Subject:</b> [llvm-dev] [ARM] Should Use Load and Store with Register Offset</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<div style="font-family:arial,helvetica,sans-serif">Hello LLVM Community (specifically anyone working with ARM Cortex-M),</div>
<div style="font-family:arial,helvetica,sans-serif"><br>
</div>
<div style="font-family:arial,helvetica,sans-serif">While trying to compile the Newlib C library I found that Clang10 was generating slightly larger binaries than the libc from the prebuilt gcc-arm-none-eabi toolchain. I looked at a few specific functions (memcpy,
 strcpy, etc.) and noticed that LLVM does not tend to generate load/store instructions with a register offset (e.g. ldr Rd, [Rn, Rm] form) and instead prefers the immediate offset form.</div>
<div style="font-family:arial,helvetica,sans-serif"><br>
</div>
<div style="font-family:arial,helvetica,sans-serif">When copying a contiguous sequence of bytes, this results in additional instructions to modify the base address. <a href="https://godbolt.org/z/T1xhae" target="_blank">https://godbolt.org/z/T1xhae</a></div>
<div style="font-family:arial,helvetica,sans-serif"><br>
</div>
<div style="font-family:arial,helvetica,sans-serif">
<div style="color:rgb(0,0,0); background-color:rgb(255,255,254); font-family:"Consolas, "">
<div><span style="color:rgb(0,0,255)">void</span>* memcpy_alt1(<span style="color:rgb(0,0,255)">void</span>* dst, <span style="color:rgb(0,0,255)">const</span> <span style="color:rgb(0,0,255)">void</span>* src, size_t len) {</div>
<div>    <span style="color:rgb(0,0,255)">char</span>* save = (<span style="color:rgb(0,0,255)">char</span>*)dst;</div>
<div>    <span style="color:rgb(0,0,255)">for</span> (size_t i = <span style="color:rgb(9,134,88)">0</span>; i < len; ++i)</div>
<div>        *((<span style="color:rgb(0,0,255)">char</span>*)(dst + i)) = *((<span style="color:rgb(0,0,255)">char</span>*)(src + i));</div>
<div>    <span style="color:rgb(0,0,255)">return</span> save;</div>
<div>}</div>
<div><br>
</div>
<div>clang --target=armv6m-none-eabi -Os -fomit-frame-pointer</div>
<div>
<div>
<div><span style="color:rgb(0,128,128)">memcpy_alt1:</span></div>
<div>        <span style="color:rgb(0,0,255)">push</span>    {<span style="color:rgb(72,100,170)">r4</span>, <span style="color:rgb(72,100,170)">lr</span>}</div>
<div>        <span style="color:rgb(0,0,255)">cmp</span>     <span style="color:rgb(72,100,170)">r2</span>, <span style="color:rgb(9,134,88)">#0</span></div>
<div>        <span style="color:rgb(0,0,255)">beq</span>     <span style="color:rgb(0,128,128)">.LBB0_3</span></div>
<div>        <span style="color:rgb(0,0,255)">mov</span>     <span style="color:rgb(72,100,170)">r3</span>, <span style="color:rgb(72,100,170)">r0</span></div>
<div><span style="color:rgb(0,128,128)">.LBB0_2:</span></div>
<div>        <span style="color:rgb(0,0,255)">ldrb</span>    <span style="color:rgb(72,100,170)">r4</span>, [<span style="color:rgb(72,100,170)">r1</span>]</div>
<div>        <span style="color:rgb(0,0,255)">strb</span>    <span style="color:rgb(72,100,170)">r4</span>, [<span style="color:rgb(72,100,170)">r3</span>]</div>
<div>        <span style="color:rgb(0,0,255)">adds</span>    <span style="color:rgb(72,100,170)">r1</span>, <span style="color:rgb(72,100,170)">r1</span>, <span style="color:rgb(9,134,88)">#1</span></div>
<div>        <span style="color:rgb(0,0,255)">adds</span>    <span style="color:rgb(72,100,170)">r3</span>, <span style="color:rgb(72,100,170)">r3</span>, <span style="color:rgb(9,134,88)">#1</span></div>
<div>        <span style="color:rgb(0,0,255)">subs</span>    <span style="color:rgb(72,100,170)">r2</span>, <span style="color:rgb(72,100,170)">r2</span>, <span style="color:rgb(9,134,88)">#1</span></div>
<div>        <span style="color:rgb(0,0,255)">bne</span>     <span style="color:rgb(0,128,128)">.LBB0_2</span></div>
<div><span style="color:rgb(0,128,128)">.LBB0_3:</span></div>
<div>        <span style="color:rgb(0,0,255)">pop</span>     {<span style="color:rgb(72,100,170)">r4</span>, <span style="color:rgb(0,128,128)">pc</span>}</div>
</div>
</div>
<div><br>
</div>
<div>arm-none-eabi-gcc -march=armv6-m -Os</div>
<div>
<div>
<div><span style="color:rgb(0,128,128)">memcpy_alt1:</span></div>
<div>        <span style="color:rgb(0,0,255)">movs</span>    <span style="color:rgb(72,100,170)">r3</span>, <span style="color:rgb(9,134,88)">#0</span></div>
<div>        <span style="color:rgb(0,0,255)">push</span>    {<span style="color:rgb(72,100,170)">r4</span>, <span style="color:rgb(72,100,170)">lr</span>}</div>
<div><span style="color:rgb(0,128,128)">.L2:</span></div>
<div>        <span style="color:rgb(0,0,255)">cmp</span>     <span style="color:rgb(72,100,170)">r3</span>, <span style="color:rgb(72,100,170)">r2</span></div>
<div>        <span style="color:rgb(0,0,255)">bne</span>     <span style="color:rgb(0,128,128)">.L3</span></div>
<div>        <span style="color:rgb(0,0,255)">pop</span>     {<span style="color:rgb(72,100,170)">r4</span>, <span style="color:rgb(0,128,128)">pc</span>}</div>
<div><span style="color:rgb(0,128,128)">.L3:</span></div>
<div>        <span style="color:rgb(0,0,255)">ldrb</span>    <span style="color:rgb(72,100,170)">r4</span>, [<span style="color:rgb(72,100,170)">r1</span>, <span style="color:rgb(72,100,170)">r3</span>]</div>
<div>        <span style="color:rgb(0,0,255)">strb</span>    <span style="color:rgb(72,100,170)">r4</span>, [<span style="color:rgb(72,100,170)">r0</span>, <span style="color:rgb(72,100,170)">r3</span>]</div>
<div>        <span style="color:rgb(0,0,255)">adds</span>    <span style="color:rgb(72,100,170)">r3</span>, <span style="color:rgb(72,100,170)">r3</span>, <span style="color:rgb(9,134,88)">#1</span></div>
<div>        <span style="color:rgb(0,0,255)">b</span>       <span style="color:rgb(0,128,128)">.L2</span></div>
</div>
</div>
</div>
</div>
<div style="font-family:arial,helvetica,sans-serif"><br>
</div>
<div style="font-family:arial,helvetica,sans-serif">Because this code appears in a loop that could be copying hundreds of bytes, I want to add an optimization that will prioritize load/store instructions with register offsets when the offset is used multiple
 times. I have not worked on LLVM before, so I'd like advice about where to start.</div>
<div>
<ul style="font-family:arial,helvetica,sans-serif">
<li>The generated code is correct, just sub-optimal so is it appropriate to submit a bug report?</li><li>Is anyone already tackling this change or is there someone with more experience interested in collaborating?</li><li>Is this optimization better performed early during instruction selection or late using c++ (i.e. ARMLoadStoreOptimizer.cpp)</li><li>What is the potential to cause harm to other parts of the code gen, specifically for other arm targets. I'm working with armv6m, but armv7m offers base register updating in a single instruction. I don't want to break other useful optimizations.</li></ul>
<div style="font-family:arial,helvetica,sans-serif">So far, I am reading through the LLVM documentation to see where a change could be applied. I have also:</div>
<div>
<ul>
<li style="font-family:arial,helvetica,sans-serif">Compiled with -S -emit-llvm (see Godbolt link)<br>
There is an identifiable pattern where a getelementptr function is followed by a load or store. When multiple getelementptr functions appear with the same virtual register offset, maybe this should match a tLDRr or tSTRr.</li><li><font face="arial, helvetica, sans-serif">Ran LLC with  </font>--print-machineinstrs <br>
It appears that tLDRBi and tSTRBi are selected very early and never replaced by the equivalent t<LDRB|STRB>r instructions.</li></ul>
<div>Thank you,</div>
</div>
</div>
<div style="font-family:arial,helvetica,sans-serif"><br>
</div>
<div>
<div dir="ltr">
<div dir="ltr">
<div>Daniel Way</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</body>
</html>