<div dir="ltr"><div>On trunk we never generate MULX. We used to blindly use it anytime bmi2 was enabled, but its a longer encoding and isn't a guaranteed register allocation improvement. So I took it out a few weeks ago. We need a more precise heuristic for when to use it.</div><div><br></div><div>LLVM trunk will never generate ADCX/ADOX either. This was removed in September. We used to inconsistently generate them when adx was enabled unless we could use the RMW form or the immediate form of ADC. But that didn't really make any sense. The only reason to use ADCX or ADOX is when you want to carefully manage the flags to have two interleaved dependency chains. But that would require a special analysis to determine when to do that and we don't have that.</div><br clear="all"><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">~Craig</div></div><br></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Dec 31, 2018 at 1:21 PM Arthur O'Dwyer <<a href="mailto:arthur.j.odwyer@gmail.com">arthur.j.odwyer@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">On Sun, Dec 30, 2018 at 4:46 PM Paweł Bylica <<a href="mailto:chfast@gmail.com" target="_blank">chfast@gmail.com</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">Hi Arthur, Craig,<div><br></div><div>Thanks for you comments about GCC/Clang intrinsics. I never considered using them, but they might be better alternative to inline assembly.<br>Is there a one for regular MUL?<br></div></div></div></blockquote><div><br></div><div>I'm not sure, but I think there currently does not exist any intrinsic to generate the top half of a 64x64=128 multiply, except for `_mulx_64`.<br></div><div>If Clang stopped requiring `-mbmi2`, I would then expect the `_mulx_64` intrinsic to generate a regular MUL instruction; similar to how_addcarry_u64 generates ADCX/ADOX when available/useful and a regular ADC otherwise.</div><div>MSVC calls this intrinsic `<a href="https://docs.microsoft.com/en-us/cpp/intrinsics/umul128?view=vs-2017" target="_blank">_umul128</a>`, and on MSVC it does generate a regular MUL instruction rather than forcing MULX.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div>Anyway, I want to go the opposite direction. [...] <span style="background-color:rgb(255,255,254)">mulx() helper without using __int128 type in a way that a compiler would recognize that it should use MUL/MULX instruction.</span><div style="background-color:rgb(255,255,254)"><div>A possible implementation looks like [SNIPPED]</div></div></div></div></div></blockquote><div> </div><div>Interesting trivia: There are at least three ways to write the final "return" statement in this function. Clang generates different code for each one of them. If someone does pursue writing an InstCombine optimization for this, it would be good to generate the same efficient code for all three versions.</div><div><a href="https://godbolt.org/z/-Cozee" target="_blank">https://godbolt.org/z/-Cozee</a> (LLVM IR: <a href="https://godbolt.org/z/_1pDoz" target="_blank">https://godbolt.org/z/_1pDoz</a>)</div><div><br></div><div>–Arthur</div></div></div></div></div></div></div></div></div>
</blockquote></div>