<div dir="ltr"><div dir="ltr">Thanks Sanjoy,<div><br></div><div>It looks it works only up to 32-bit integers (<a href="http://llvm.org/doxygen/InstCombineCompares_8cpp_source.html#l01255">http://llvm.org/doxygen/InstCombineCompares_8cpp_source.html#l01255</a>).<br>I will need it also for 64-bit integers.<br><br>Even if the pattern match would handle the 64-bit case I would need to use 128-bit types what is not portable still.</div><div><br></div><div>// P.</div></div></div><br><div class="gmail_quote"><div dir="ltr">On Thu, Nov 22, 2018 at 6:54 PM Sanjoy Das <<a href="mailto:sanjoy@playingwithpointers.com">sanjoy@playingwithpointers.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Going by InstCombiner::foldICmpWithConstant,<br>
<a href="https://gcc.godbolt.org/z/To_qmm" rel="noreferrer" target="_blank">https://gcc.godbolt.org/z/To_qmm</a> should work.<br>
<br>
-- Sanjoy<br>
On Tue, Nov 20, 2018 at 2:46 AM Paweł Bylica via llvm-dev<br>
<<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br>
><br>
> Hi LLVM, clang,<br>
><br>
> I'm trying to write a portable version of __builtin_add_overflow() it a way that the compiler would<br>
> recognize the pattern and use the add_overflow intrinsic / the best possible machine instruction.<br>
><br>
> Here are docs about these builtins: <a href="https://clang.llvm.org/docs/LanguageExtensions.html#checked-arithmetic-builtins" rel="noreferrer" target="_blank">https://clang.llvm.org/docs/LanguageExtensions.html#checked-arithmetic-builtins</a>.<br>
><br>
> With unsigned types this is easy:<br>
><br>
> int uaddo_native(unsigned a, unsigned b, unsigned* s)<br>
> {<br>
> return __builtin_add_overflow(a, b, s);<br>
> }<br>
><br>
> int uaddo_portable(unsigned a, unsigned b, unsigned* s)<br>
> {<br>
> *s = a + b;<br>
> return *s < a;<br>
> }<br>
><br>
> We get exactly the same assembly:<br>
> uaddo_native: # @uaddo_native<br>
> xor eax, eax<br>
> add edi, esi<br>
> setb al<br>
> mov dword ptr [rdx], edi<br>
> ret<br>
> uaddo_portable: # @uaddo_portable<br>
> xor eax, eax<br>
> add edi, esi<br>
> setb al<br>
> mov dword ptr [rdx], edi<br>
> ret<br>
><br>
> But with signed types it is not so easy. I tried 2 versions, but the result is quite far away from the optimal assembly.<br>
><br>
><br>
> int saddo_native(int a, int b, int* s)<br>
> {<br>
> return __builtin_add_overflow(a, b, s);<br>
> }<br>
><br>
> int saddo_portable(int a, int b, int* s)<br>
> {<br>
> *s = (unsigned)a + (unsigned)b;<br>
> return (a > 0) ? *s <= b : *s > b;<br>
> }<br>
><br>
> int saddo_portable2(int a, int b, int* s)<br>
> {<br>
> *s = (unsigned)a + (unsigned)b;<br>
> int cond = a > 0;<br>
> int check = *s > b;<br>
> return (cond & !check) | (!cond & check);<br>
> }<br>
><br>
> Assembly:<br>
><br>
> saddo_native: # @saddo_native<br>
> xor eax, eax<br>
> add edi, esi<br>
> seto al<br>
> mov dword ptr [rdx], edi<br>
> ret<br>
> saddo_portable: # @saddo_portable<br>
> lea eax, [rsi + rdi]<br>
> mov dword ptr [rdx], eax<br>
> cmp eax, esi<br>
> setle al<br>
> setg cl<br>
> test edi, edi<br>
> jg .LBB3_2<br>
> mov eax, ecx<br>
> .LBB3_2:<br>
> movzx eax, al<br>
> ret<br>
> saddo_portable2: # @saddo_portable2<br>
> lea eax, [rsi + rdi]<br>
> mov dword ptr [rdx], eax<br>
> test edi, edi<br>
> setg cl<br>
> cmp eax, esi<br>
> setg al<br>
> xor al, cl<br>
> movzx eax, al<br>
> ret<br>
><br>
><br>
> Do you know the trick to force the compiler to use the seto instruction?<br>
><br>
> I also noticed that the transformation for uaddo_portable happens in CodeGen, not in IR.<br>
><br>
> Bests,<br>
> Paweł<br>
><br>
><br>
> _______________________________________________<br>
> LLVM Developers mailing list<br>
> <a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>