<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi Tim,<div class=""><br class=""></div><div class="">After looking at it a bit further, I think this is a Clang thing.  Clang issues “align 2” if the struct has at least one int (2 bytes), but also if the entire struct size is multiple of 2. For example a struct with 4 char members. In these cases the LLVM backend correctly creates word sized load/stores (2 bytes). </div><div class=""><br class=""></div><div class="">However, Clang issues “align 1” for the remaining cases, for example for 3 byte structs with 3 char members. The LLVM backend just follows what’s dictated by Clang regarding alignment and thus it creates 2 byte or 1 byte load/stores instructions accordingly. I have not found a way to override this in LLVM. Any suggestions are appreciated. </div><div class=""><br class=""></div><div class="">I have also posted this problem in the cfe-def list.<br class=""><div class=""><br class="webkit-block-placeholder"></div><div class="">
<div style="color: rgb(0, 0, 0); letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">John Lluch<br class=""><br class="">Tel: 620 28 45 13</div></div></div>
</div>
<br class=""><div><blockquote type="cite" class=""><div class="">On 13 May 2019, at 11:17, Joan Lluch <<a href="mailto:joan.lluch@icloud.com" class="">joan.lluch@icloud.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">I had already adjusted MaxStoresPerMemcpy to my preferred value, and this works great but for the cases where load/stores are used on non-size aligned structs the odd behaviour still happens. For my 3-char, 3-byte struct test, the memcpy replacement appears to consist on a single byte load and store of the last char (this is correct), followed by a 16 bit move of the first two chars, this is also correct, but the odd thing is that the 16 bit move is performed by picking bytes separately from the source struct, then combining them into 16 bit values by means of shifts, swap, and or, then moved as words to the destination. I don’t know why simple 16 bit load and stores are used instead. Will try to track findOptimalMemOpLowering with the debugger to see if I see some light. So thanks for pointing that out to me. <br class=""><div class=""><div class="">
<div style="letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">John<br class=""><br class="">Tel: 620 28 45 13</div></div></div>
</div>
<br class=""><div class=""><blockquote type="cite" class=""><div class="">On 13 May 2019, at 09:33, Tim Northover <<a href="mailto:t.p.northover@gmail.com" class="">t.p.northover@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Hi Joan,<br class=""><br class="">On Mon, 13 May 2019 at 07:53, Joan Lluch <<a href="mailto:joan.lluch@icloud.com" class="">joan.lluch@icloud.com</a>> wrote:<br class=""><blockquote type="cite" class="">The reason I want structs to be aligned/padded to 2 bytes is because my architecture only has 16 bit operations. I can read (sign and zero extended) and write (truncated) 8 bit data from/to memory, but all intermediate operations in registers are performed in 16 bit registers.<br class=""></blockquote><br class="">This is very normal. Mostly it's at 32-bits rather than 16, but it<br class="">applies to basically every RISC architecture so LLVM should handle it<br class="">well without adjusting the alignment requirements of types.<br class=""><br class=""><blockquote type="cite" class="">This causes LLVM to generate odd tricks such as shifts and byte-swaps, when trying to replace struct ‘memcpy’s by word sized load/store instructions.<br class=""></blockquote><br class="">That sounds odd, as if you've not taught the backend to use those<br class="">8-bit loads and stores so it's trying to emulate them with word-sized<br class="">ones (early Alpha chips genuinely didn't have byte access so had to do<br class="">that kind of thing). You can (and should) probably fix that.<br class=""><br class="">Also, there are a few customization points where you can control how<br class="">memcpy is implemented. The function "findOptimalMemOpLowering" lets<br class="">you control the type used for the loads and stores, and<br class="">MaxStoresPerMemcpy controls when LLVM will call the real memcpy. If<br class="">you want even more control you can implement EmitTargetCodeForMemcpy<br class="">to do the whole thing.<br class=""><br class="">Cheers.<br class=""><br class="">Tim.<br class=""></div></div></blockquote></div><br class=""></div></div></div></div></blockquote></div><br class=""></div></body></html>