<div dir="ltr">Thanks for posting this question, Julia.<br><br>I had a similar question about a signed min/max variant here:<br><a href="http://lists.llvm.org/pipermail/llvm-dev/2016-November/106868.html">http://lists.llvm.org/pipermail/llvm-dev/2016-November/106868.html</a><br><br>The 2nd version in each case contains a canonical max/min representation in IR, and this could enable more IR analysis. <br>A secondary advantage is that the backend recognizes the max/min in the second IR form when creating DAG nodes, <br>and this directly affects isel for many targets.<br><br>A
 possibly important difference between the earlier example and the 
current unsigned case: <br>is a select with a zero constant operand easier 
to reason about in IR than the canonical min/max?<br><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, May 16, 2017 at 5:30 AM, Koval, Julia <span dir="ltr"><<a href="mailto:julia.koval@intel.com" target="_blank">julia.koval@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
This message is a result of a discussion of backend optimization for sub(max) pattern(<a href="https://reviews.llvm.org/D25987" rel="noreferrer" target="_blank">https://reviews.llvm.<wbr>org/D25987</a>), which can be either converted to unsigned min-max or unsigned saturation instruction(if the target supports it).<br>
Currently these versions of the code produce different IR(and we need to manage both types in backend):<br>
<br>
(1.16)<br>
void foo(unsigned short *p, unsigned short max, int n) {<br>
  int i;<br>
unsigned short m;<br>
for (i = 0; i < n; i++) {<br>
    m = *--p;<br>
    *p =(m >= max ? m-max : 0);<br>
  }<br>
}<br>
<br>
(2.16)<br>
void goo(unsigned short *p, unsigned short max, int n) {<br>
  int i;<br>
  unsigned short m;<br>
  for (i = 0; i < n; i++) {<br>
    m = *--p;<br>
    unsigned short umax = m > max ? m : max;<br>
    *p =umax - max;<br>
  }<br>
}<br>
<br>
(1.16)<br>
%cmp = icmp ugt i16 %x, %y<br>
%sub2 = sub i16 %y, %x<br>
%res = select i1 %cmp, i16 0, i16 %sub2<br>
<br>
or<br>
<br>
(2.16)<br>
%cmp = icmp ugt i16 %x, %y<br>
%sel = select i1 %cmp, i16 %x, i16 %y<br>
%sub = sub i16 %sel, %x<br>
<br>
Which of these versions is canonical? I think first version is better, because it can be converted to unsigned saturation instruction(i.e. PSUBUS), using existing backend code.<br>
</blockquote></div><br></div>