<html>
    <head>
      <base href="https://bugs.freedesktop.org/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Priority</th>
          <td>medium
          </td>
        </tr>

        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - mid3 generates slow code for constant arguments"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=76861">76861</a>
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>idr@freedesktop.org
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>mid3 generates slow code for constant arguments
          </td>
        </tr>

        <tr>
          <th>QA Contact</th>
          <td>intel-3d-bugs@lists.freedesktop.org
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>idr@freedesktop.org
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Other
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>git
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>glsl-compiler
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>Mesa
          </td>
        </tr></table>
      <p>
        <div>
        <pre>mid3 (from GL_AMD_shader_trinary_minmax) generate slow code if two of the
arguments are constants.  The code

    a = mid3(b, 1, 3);

should generate the same code as

    a = clamp(b, 1, 3);

Instead it generates

    (assign  (xyzw) (var_ref a)  (expression vec4 max (expression vec4 min
(var_ref b) (constant vec4 (1.0 1.0 1.0 1.0)) ) (expression vec4 max
(expression vec4 min (var_ref b0) (constant vec4 (3.0 3.0 3.0 3.0)) ) (constant
vec4 (1.0 1.0 1.0 1.0)) ) ) ) 

I think the correct fix for this is to add an ir_triop_mid opcode and a
lowering pass (in lower_instructions.cpp).  The lowering pass would then need
to be smart enough to do the right thing when some of the operands are
constants.

min3 and max3 may have similar problems.

The mid3 issue is likely to become a bigger problem in the future.  Emil
Persson (aka Humus) suggested that PS3 / Xbox1 developers use mid3 as a general
purpose clamp during his GDC2014 presentation.  See
<a href="https://www.youtube.com/watch?v=UJq96XZURHw">https://www.youtube.com/watch?v=UJq96XZURHw</a></pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are the QA Contact for the bug.</li>
      </ul>
    </body>
</html>