<div dir="ltr">Just to offer some random pieces of data:<div>From a GVN/CSE/etc perspective, the non-zext'd versions are the most likely to be optimized, and of the non-zext'd versions, the icmp/select is the most likely to be optimized.</div><div><br></div><div>Especially when combined as part of larger IR.   That is, an "and of zext'd icmp and regular icmp" is less likely to be optimized.</div><div>I mean this from the perspective of "be able to deduce later things about it".<br></div><div><br></div><div>But past that, i'd say pretty much any of them are fine.</div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Jul 1, 2017 at 11:45 AM, Sanjay Patel via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>I'm looking at the output of memcmp() expansion (D34904), and I noticed that there are many ways to produce the common positive/zero/negative comparison result in IR. <br><br>For the following 6 functionally equivalent C source functions, we produce 6 different versions of IR which leads to 6 different asm outputs for x86. Which of these should we choose as canonical IR form?<br><br></div><div>1. Two selects<br></div><div>int zero_negone_one(int x, int y) {<br>  if (x == y) return 0; <br>  if (x < y) return -1;<br>  return 1;<br>}<br><br>define i32 @zero_negone_one(i32, i32) {<br>  %3 = icmp eq i32 %0, %1<br>  %4 = icmp slt i32 %0, %1<br>  %5 = select i1 %4, i32 -1, i32 1<br>  %6 = select i1 %3, i32 0, i32 %5<br>  ret i32 %6<br>}<br><br><br></div><div>2. Two selects, but different<br></div><div>int zero_one_negone(int x, int y) {<br>  if (x == y) return 0; <br>  if (x > y) return 1;<br>  return -1;<br>}<br><br>define i32 @zero_one_negone(i32, i32) {<br>  %3 = icmp eq i32 %0, %1<br>  %4 = icmp sgt i32 %0, %1<br>  %5 = select i1 %4, i32 1, i32 -1<br>  %6 = select i1 %3, i32 0, i32 %5<br>  ret i32 %6<br>}<br><br><br></div><div>3. Select and zext<br></div><div>int negone_one_zero(int x, int y) {<br>  if (x < y) return -1;<br>  if (x > y) return 1;<br>  return 0;<br>}<br><br>define i32 @negone_one_zero(i32, i32)  {<br>  %3 = icmp slt i32 %0, %1<br>  %4 = icmp sgt i32 %0, %1<br>  %5 = zext i1 %4 to i32<br>  %6 = select i1 %3, i32 -1, i32 %5<br>  ret i32 %6<br>}<br><br><br></div><div>4. Select and sext<br>int negone_zero_one(int x, int y) {<br>  int sel = x < y ? -1 : 0;<br>  if (x > y) return 1;<br>  return sel;<br>}<br><br>define i32 @negone_zero_one(i32, i32) {<br>  %3 = icmp sgt i32 %0, %1<br>  %4 = icmp slt i32 %0, %1<br>  %5 = sext i1 %4 to i32<br>  %6 = select i1 %3, i32 1, i32 %5<br>  ret i32 %6<br>}<br><br><br></div><div>5. Subs and shifts<br></div><div>int neg101_sub_shifty(int x, int y) {<br>  int r = (x - y) >> 31;<br>  r += (unsigned)(y - x) >> 31;<br>  return r;<br>}<br><br>define i32 @neg101_sub_shifty(i32, i32) {<br>  %3 = sub nsw i32 %0, %1<br>  %4 = ashr i32 %3, 31<br>  %5 = sub nsw i32 %1, %0<br>  %6 = lshr i32 %5, 31<br>  %7 = add nsw i32 %4, %6<br>  ret i32 %7<br>}<br><br><br></div><div>6. Zexts and sub<br></div><div>int neg101_cmp_sub(int x, int y) {<br>  return (x>y) - (x<y);<br>}<br><br>define i32 @neg101_cmp_sub(i32, i32) {<br>  %3 = icmp sgt i32 %0, %1<br>  %4 = zext i1 %3 to i32<br>  %5 = icmp slt i32 %0, %1<br>  %6 = zext i1 %5 to i32<br>  %7 = sub nsw i32 %4, %6<br>  ret i32 %7<br>}<br><br><br><a href="https://godbolt.org/g/UnM9H7" target="_blank">https://godbolt.org/g/UnM9H7</a><br><br>Show these are logically equivalent:<br><a href="http://rise4fun.com/Alive/b4D" target="_blank">http://rise4fun.com/Alive/b4D</a><br><br></div>Recent patch related to this pattern:<br><a href="https://reviews.llvm.org/D34278" target="_blank">https://reviews.llvm.org/<wbr>D34278</a><br></div>
<br>______________________________<wbr>_________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org">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/<wbr>mailman/listinfo/llvm-dev</a><br>
<br></blockquote></div><br></div>