glsl: lower builtins to mediump that always return mediump or lowp
[mesa.git] / src / compiler / glsl / tests / lower_precision_test.py
index 6d6e127171141f266113fcb23371c7ddf4f05cc8..a6ad95031356a0b591bb051467d8e67afbe1f03c 100644 (file)
@@ -31,7 +31,7 @@ Test = namedtuple("Test", "name source match_re")
 
 
 TESTS = [
-    Test("simple division",
+    Test("f32 simple division",
          """
          uniform mediump float a, b;
 
@@ -41,6 +41,36 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
+    Test("i32 simple division",
+         """
+         #version 300 es
+         precision mediump float;
+         precision mediump int;
+         uniform mediump int a, b;
+
+         out vec4 color;
+
+         void main()
+         {
+                 color = vec4(a / b);
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 simple division",
+         """
+         #version 300 es
+         precision mediump float;
+         precision mediump int;
+         uniform mediump uint a, b;
+
+         out vec4 color;
+
+         void main()
+         {
+                 color = vec4(a / b);
+         }
+         """,
+         r'\(expression +uint16_t +/'),
     Test("dot",
          """
          uniform mediump vec2 a, b;
@@ -51,7 +81,7 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +dot\b'),
-    Test("array with const index",
+    Test("f32 array with const index",
          """
          precision mediump float;
 
@@ -63,7 +93,39 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("array with uniform index",
+    Test("i32 array with const index",
+         """
+         #version 300 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int in_simple[2];
+
+         out vec4 color;
+
+         void main()
+         {
+                 color = vec4(in_simple[0] / in_simple[1]);
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 array with const index",
+         """
+         #version 300 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint in_simple[2];
+
+         out vec4 color;
+
+         void main()
+         {
+                 color = vec4(in_simple[0] / in_simple[1]);
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 array with uniform index",
          """
          precision mediump float;
 
@@ -76,7 +138,41 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("array-of-array with const index",
+    Test("i32 array with uniform index",
+         """
+         #version 300 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int in_simple[2];
+         uniform int i0, i1;
+
+         out vec4 color;
+
+         void main()
+         {
+                 color = vec4(in_simple[i0] / in_simple[i1]);
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 array with uniform index",
+         """
+         #version 300 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint in_simple[2];
+         uniform int i0, i1;
+
+         out vec4 color;
+
+         void main()
+         {
+                 color = vec4(in_simple[i0] / in_simple[i1]);
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 array-of-array with const index",
          """
          #version 310 es
          precision mediump float;
@@ -91,7 +187,39 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("array-of-array with uniform index",
+    Test("i32 array-of-array with const index",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int in_aoa[2][2];
+
+         layout(location = 0) out highp int out_color;
+
+         void main()
+         {
+                 out_color = in_aoa[0][0] / in_aoa[1][1];
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 array-of-array with const index",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint in_aoa[2][2];
+
+         layout(location = 0) out highp uint out_color;
+
+         void main()
+         {
+                 out_color = in_aoa[0][0] / in_aoa[1][1];
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 array-of-array with uniform index",
          """
          #version 310 es
          precision mediump float;
@@ -107,7 +235,41 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("array index",
+    Test("i32 array-of-array with uniform index",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int in_aoa[2][2];
+         uniform int i0, i1;
+
+         layout(location = 0) out highp int out_color;
+
+         void main()
+         {
+                 out_color = in_aoa[i0][i0] / in_aoa[i1][i1];
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 array-of-array with uniform index",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint in_aoa[2][2];
+         uniform int i0, i1;
+
+         layout(location = 0) out highp uint out_color;
+
+         void main()
+         {
+                 out_color = in_aoa[i0][i0] / in_aoa[i1][i1];
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 array index",
          """
          uniform mediump float a, b;
          uniform mediump float values[2];
@@ -118,7 +280,24 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("function",
+    Test("i32 array index",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform mediump int a, b;
+         uniform mediump int values[2];
+
+         out highp int color;
+
+         void main()
+         {
+                 color = values[a / b];
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("f32 function",
          """
          precision mediump float;
 
@@ -142,209 +321,1313 @@ TESTS = [
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("function mediump args",
+    Test("i32 function",
          """
+         #version 310 es
          precision mediump float;
+         precision mediump int;
 
-         uniform float a, b;
+         uniform int a, b;
 
-         mediump float
-         do_div(float x, float y)
+         mediump int
+         get_a()
          {
-                 return x / y;
+                 return a;
+         }
+
+         int
+         get_b()
+         {
+                 return b;
          }
 
+         out highp int color;
+
          void main()
          {
-                 gl_FragColor = vec4(do_div(a, b));
+                 color = get_a() / get_b();
          }
          """,
-         r'\(expression +float16_t +/'),
-    Test("function highp args",
+         r'\(expression +int16_t +/'),
+    Test("u32 function",
          """
+         #version 310 es
          precision mediump float;
+         precision mediump int;
 
-         uniform float a, b;
+         uniform uint a, b;
 
-         mediump float
-         do_div(highp float x, highp float y)
+         mediump uint
+         get_a()
          {
-                 return x / y;
+                 return a;
+         }
+
+         uint
+         get_b()
+         {
+                 return b;
          }
 
+         out highp uint color;
+
          void main()
          {
-                 gl_FragColor = vec4(do_div(a, b));
+                 color = get_a() / get_b();
          }
          """,
-         r'\(expression +float +/'),
-    Test("function inout different precision highp",
+         r'\(expression +uint16_t +/'),
+    Test("f32 function mediump args",
          """
-         uniform mediump float a, b;
+         precision mediump float;
 
-         void
-         do_div(inout highp float x, highp float y)
+         uniform float a, b;
+
+         mediump float
+         do_div(float x, float y)
          {
-                 x = x / y;
+                 return x / y;
          }
 
          void main()
          {
-                 mediump float temp = a;
-                 do_div(temp, b);
-                 gl_FragColor = vec4(temp);
+                 gl_FragColor = vec4(do_div(a, b));
          }
          """,
-         r'\(expression +float +/'),
-    Test("function inout different precision mediump",
+         r'\(expression +float16_t +/'),
+    Test("i32 function mediump args",
          """
-         uniform highp float a, b;
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
 
-         void
-         do_div(inout mediump float x, mediump float y)
+         uniform int a, b;
+
+         mediump int
+         do_div(int x, int y)
          {
-                 x = x / y;
+                 return x / y;
          }
 
+         out highp int color;
+
          void main()
          {
-                 highp float temp = a;
-                 do_div(temp, b);
-                 gl_FragColor = vec4(temp);
+                 color = do_div(a, b);
          }
          """,
-         r'\(expression +float16_t +/'),
-    Test("if",
+         r'\(expression +int16_t +/'),
+    Test("u32 function mediump args",
          """
+         #version 310 es
          precision mediump float;
+         precision mediump int;
 
-         uniform float a, b;
+         uniform uint a, b;
 
-         void
-         main()
+         mediump uint
+         do_div(uint x, uint y)
          {
-                 if (a / b < 0.31)
-                         gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
-                 else
-                         gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+                 return x / y;
          }
-         """,
-         r'\(expression +float16_t +/'),
-    Test("matrix",
-         """
-         precision mediump float;
 
-         uniform vec2 a;
-         uniform mat2 b;
+         out highp uint color;
 
          void main()
          {
-             gl_FragColor = vec4(b * a, 0.0, 0.0);
+                 color = do_div(a, b);
          }
          """,
-         r'\(expression +f16vec2 \*.*\bf16mat2\b'),
-    Test("simple struct deref",
+         r'\(expression +uint16_t +/'),
+    Test("f32 function highp args",
          """
          precision mediump float;
 
-         struct simple {
-                 float a, b;
-         };
+         uniform float a, b;
 
-         uniform simple in_simple;
+         mediump float
+         do_div(highp float x, highp float y)
+         {
+                 return x / y;
+         }
 
          void main()
          {
-                 gl_FragColor = vec4(in_simple.a / in_simple.b);
+                 gl_FragColor = vec4(do_div(a, b));
          }
          """,
-         r'\(expression +float16_t +/'),
-    Test("embedded struct deref",
+         r'\(expression +float +/'),
+    Test("i32 function highp args",
          """
+         #version 310 es
          precision mediump float;
+         precision mediump int;
 
-         struct simple {
-                 float a, b;
-         };
+         uniform int a, b;
 
-         struct embedded {
-                 simple a, b;
-         };
+         mediump int
+         do_div(highp int x, highp int y)
+         {
+                 return x / y;
+         }
 
-         uniform embedded in_embedded;
+         out highp int color;
 
          void main()
          {
-                 gl_FragColor = vec4(in_embedded.a.a / in_embedded.b.b);
+                  color = do_div(a, b);
          }
          """,
-         r'\(expression +float16_t +/'),
-    Test("arrayed struct deref",
+         r'\(expression +int +/'),
+    Test("u32 function highp args",
          """
+         #version 310 es
          precision mediump float;
+         precision mediump int;
 
-         struct simple {
-                 float a, b;
-         };
+         uniform uint a, b;
 
-         struct arrayed {
-                 simple a[2];
-         };
+         mediump uint
+         do_div(highp uint x, highp uint y)
+         {
+                 return x / y;
+         }
 
-         uniform arrayed in_arrayed;
+         out highp uint color;
 
          void main()
          {
-                 gl_FragColor = vec4(in_arrayed.a[0].a / in_arrayed.a[1].b);
+                  color = do_div(a, b);
          }
          """,
-         r'\(expression +float16_t +/'),
-    Test("mixed precision not lowered",
+         r'\(expression +uint +/'),
+    Test("f32 function inout different precision highp",
          """
-         uniform mediump float a;
-         uniform highp float b;
+         uniform mediump float a, b;
+
+         void
+         do_div(inout highp float x, highp float y)
+         {
+                 x = x / y;
+         }
 
          void main()
          {
-                 gl_FragColor = vec4(a / b);
+                 mediump float temp = a;
+                 do_div(temp, b);
+                 gl_FragColor = vec4(temp);
          }
          """,
          r'\(expression +float +/'),
-    Test("texture sample",
+    Test("i32 function inout different precision highp",
          """
-         precision mediump float;
+         #version 310 es
+         uniform mediump int a, b;
 
-         uniform sampler2D tex;
-         uniform vec2 coord;
-         uniform float divisor;
+         void
+         do_div(inout highp int x, highp int y)
+         {
+                 x = x / y;
+         }
+
+         out mediump int color;
 
          void main()
          {
-                 gl_FragColor = texture2D(tex, coord) / divisor;
+                 mediump int temp = a;
+                 do_div(temp, b);
+                 color = temp;
          }
          """,
-         r'\(expression +f16vec4 +/'),
-    Test("expression in lvalue",
+         r'\(expression +int +/'),
+    Test("u32 function inout different precision highp",
          """
-         uniform mediump float a, b;
+         #version 310 es
+         uniform mediump uint a, b;
 
-         void main()
+         void
+         do_div(inout highp uint x, highp uint y)
          {
-                 gl_FragColor = vec4(1.0);
-                 gl_FragColor[int(a / b)] = 0.5;
+                 x = x / y;
+         }
+
+         out mediump uint color;
+
+         void main()
+         {
+                 mediump uint temp = a;
+                 do_div(temp, b);
+                 color = temp;
+         }
+         """,
+         r'\(expression +uint +/'),
+    Test("f32 function inout different precision mediump",
+         """
+         uniform highp float a, b;
+
+         void
+         do_div(inout mediump float x, mediump float y)
+         {
+                 x = x / y;
+         }
+
+         void main()
+         {
+                 highp float temp = a;
+                 do_div(temp, b);
+                 gl_FragColor = vec4(temp);
          }
          """,
          r'\(expression +float16_t +/'),
-    Test("builtin with const arg",
+    Test("i32 function inout different precision mediump",
          """
-         uniform mediump float a;
+         #version 310 es
+         uniform highp int a, b;
+
+         out highp int color;
+
+         void
+         do_div(inout mediump int x, mediump int y)
+         {
+                 x = x / y;
+         }
 
          void main()
          {
-                 gl_FragColor = vec4(min(a, 3.0));
+                 highp int temp = a;
+                 do_div(temp, b);
+                 color = temp;
          }
          """,
-         r'\(expression +float16_t min'),
+         r'\(expression +int16_t +/'),
+    Test("u32 function inout different precision mediump",
+         """
+         #version 310 es
+         uniform highp uint a, b;
+
+         out highp uint color;
+
+         void
+         do_div(inout mediump uint x, mediump uint y)
+         {
+                 x = x / y;
+         }
+
+         void main()
+         {
+                 highp uint temp = a;
+                 do_div(temp, b);
+                 color = temp;
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 if",
+         """
+         precision mediump float;
+
+         uniform float a, b;
+
+         void
+         main()
+         {
+                 if (a / b < 0.31)
+                         gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
+                 else
+                         gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+         }
+         """,
+         r'\(expression +float16_t +/'),
+    Test("i32 if",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int a, b;
+
+         out vec4 color;
+
+         void
+         main()
+         {
+                 if (a / b < 10)
+                         color = vec4(0.0, 1.0, 0.0, 1.0);
+                 else
+                         color = vec4(1.0, 0.0, 0.0, 1.0);
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 if",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint a, b;
+
+         out vec4 color;
+
+         void
+         main()
+         {
+                 if (a / b < 10u)
+                         color = vec4(0.0, 1.0, 0.0, 1.0);
+                 else
+                         color = vec4(1.0, 0.0, 0.0, 1.0);
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("matrix",
+         """
+         precision mediump float;
+
+         uniform vec2 a;
+         uniform mat2 b;
+
+         void main()
+         {
+             gl_FragColor = vec4(b * a, 0.0, 0.0);
+         }
+         """,
+         r'\(expression +f16vec2 \*.*\bf16mat2\b'),
+    Test("f32 simple struct deref",
+         """
+         precision mediump float;
+
+         struct simple {
+                 float a, b;
+         };
+
+         uniform simple in_simple;
+
+         void main()
+         {
+                 gl_FragColor = vec4(in_simple.a / in_simple.b);
+         }
+         """,
+         r'\(expression +float16_t +/'),
+    Test("i32 simple struct deref",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         struct simple {
+                 int a, b;
+         };
+
+         uniform simple in_simple;
+
+         out highp int color;
+
+         void main()
+         {
+                 color = in_simple.a / in_simple.b;
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 simple struct deref",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         struct simple {
+                 uint a, b;
+         };
+
+         uniform simple in_simple;
+
+         out highp uint color;
+
+         void main()
+         {
+                 color = in_simple.a / in_simple.b;
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 embedded struct deref",
+         """
+         precision mediump float;
+
+         struct simple {
+                 float a, b;
+         };
+
+         struct embedded {
+                 simple a, b;
+         };
+
+         uniform embedded in_embedded;
+
+         void main()
+         {
+                 gl_FragColor = vec4(in_embedded.a.a / in_embedded.b.b);
+         }
+         """,
+         r'\(expression +float16_t +/'),
+    Test("i32 embedded struct deref",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         struct simple {
+                 int a, b;
+         };
+
+         struct embedded {
+                 simple a, b;
+         };
+
+         uniform embedded in_embedded;
+
+         out highp int color;
+
+         void main()
+         {
+                 color = in_embedded.a.a / in_embedded.b.b;
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 embedded struct deref",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         struct simple {
+                 uint a, b;
+         };
+
+         struct embedded {
+                 simple a, b;
+         };
+
+         uniform embedded in_embedded;
+
+         out highp uint color;
+
+         void main()
+         {
+                 color = in_embedded.a.a / in_embedded.b.b;
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 arrayed struct deref",
+         """
+         precision mediump float;
+
+         struct simple {
+                 float a, b;
+         };
+
+         struct arrayed {
+                 simple a[2];
+         };
+
+         uniform arrayed in_arrayed;
+
+         void main()
+         {
+                 gl_FragColor = vec4(in_arrayed.a[0].a / in_arrayed.a[1].b);
+         }
+         """,
+         r'\(expression +float16_t +/'),
+    Test("i32 arrayed struct deref",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         struct simple {
+                 int a, b;
+         };
+
+         struct arrayed {
+                 simple a[2];
+         };
+
+         uniform arrayed in_arrayed;
+
+         out highp int color;
+
+         void main()
+         {
+                 color = in_arrayed.a[0].a / in_arrayed.a[1].b;
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("u32 arrayed struct deref",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         struct simple {
+                 uint a, b;
+         };
+
+         struct arrayed {
+                 simple a[2];
+         };
+
+         uniform arrayed in_arrayed;
+
+         out highp uint color;
+
+         void main()
+         {
+                 color = in_arrayed.a[0].a / in_arrayed.a[1].b;
+         }
+         """,
+         r'\(expression +uint16_t +/'),
+    Test("f32 mixed precision not lowered",
+         """
+         uniform mediump float a;
+         uniform highp float b;
+
+         void main()
+         {
+                 gl_FragColor = vec4(a / b);
+         }
+         """,
+         r'\(expression +float +/'),
+    Test("i32 mixed precision not lowered",
+         """
+         #version 310 es
+         uniform mediump int a;
+         uniform highp int b;
+
+         out mediump int color;
+
+         void main()
+         {
+                 color = a / b;
+         }
+         """,
+         r'\(expression +int +/'),
+    Test("u32 mixed precision not lowered",
+         """
+         #version 310 es
+         uniform mediump uint a;
+         uniform highp uint b;
+
+         out mediump uint color;
+
+         void main()
+         {
+                 color = a / b;
+         }
+         """,
+         r'\(expression +uint +/'),
+    Test("f32 sampler array",
+         """
+         #version 320 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform sampler2D tex[2];
+         // highp shouldn't affect the return value of texture2D
+         uniform highp vec2 coord;
+         uniform float divisor;
+         uniform int index;
+
+         out highp vec4 color;
+
+         void main()
+         {
+                 color = texture2D(tex[index], coord) / divisor;
+         }
+         """,
+         r'\(expression +f16vec4 +/.*\(tex +f16vec4 +'),
+    Test("f32 texture sample",
+         """
+         precision mediump float;
+
+         uniform sampler2D tex;
+         // highp shouldn't affect the return value of texture2D
+         uniform highp vec2 coord;
+         uniform float divisor;
+
+         void main()
+         {
+                 gl_FragColor = texture2D(tex, coord) / divisor;
+         }
+         """,
+         r'\(expression +f16vec4 +/.*\(tex +f16vec4 +'),
+    Test("i32 texture sample",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform mediump isampler2D tex;
+         // highp shouldn't affect the return value of texture
+         uniform highp vec2 coord;
+         uniform int divisor;
+
+         out highp ivec4 color;
+
+         void main()
+         {
+                 color = texture(tex, coord) / divisor;
+         }
+         """,
+         r'\(expression +i16vec4 +/.*\(tex +i16vec4 +'),
+    Test("u32 texture sample",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform mediump usampler2D tex;
+         // highp shouldn't affect the return value of texture
+         uniform highp vec2 coord;
+         uniform uint divisor;
+
+         out highp uvec4 color;
+
+         void main()
+         {
+                 color = texture(tex, coord) / divisor;
+         }
+         """,
+         r'\(expression +u16vec4 +/.*\(tex +u16vec4 +'),
+    Test("f32 image array",
+         """
+         #version 320 es
+         precision mediump float;
+
+         layout(rgba16f) readonly uniform mediump image2D img[2];
+         // highp shouldn't affect the return value of imageLoad
+         uniform highp ivec2 coord;
+         uniform float divisor;
+
+         out highp vec4 color;
+
+         void main()
+         {
+                 color = imageLoad(img[1], coord) / divisor;
+         }
+         """,
+         r'\(expression +f16vec4 +/'),
+    Test("f32 image load",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         layout(rgba16f) readonly uniform mediump image2D img;
+         // highp shouldn't affect the return value of imageLoad
+         uniform highp ivec2 coord;
+         uniform float divisor;
+
+         out highp vec4 color;
+
+         void main()
+         {
+                 color = imageLoad(img, coord) / divisor;
+         }
+         """,
+         r'\(expression +f16vec4 +/'),
+    Test("i32 image load",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         layout(rgba16i) readonly uniform mediump iimage2D img;
+         // highp shouldn't affect the return value of imageLoad
+         uniform highp ivec2 coord;
+         uniform int divisor;
+
+         out highp ivec4 color;
+
+         void main()
+         {
+                 color = imageLoad(img, coord) / divisor;
+         }
+         """,
+         r'\(expression +i16vec4 +/'),
+    Test("u32 image load",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         layout(rgba16ui) readonly uniform mediump uimage2D img;
+         // highp shouldn't affect the return value of imageLoad
+         uniform highp ivec2 coord;
+         uniform uint divisor;
+
+         out highp uvec4 color;
+
+         void main()
+         {
+                 color = imageLoad(img, coord) / divisor;
+         }
+         """,
+         r'\(expression +u16vec4 +/'),
+    Test("f32 expression in lvalue",
+         """
+         uniform mediump float a, b;
+
+         void main()
+         {
+                 gl_FragColor = vec4(1.0);
+                 gl_FragColor[int(a / b)] = 0.5;
+         }
+         """,
+         r'\(expression +float16_t +/'),
+    Test("i32 expression in lvalue",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform mediump int a, b;
+
+         out vec4 color;
+
+         void main()
+         {
+                 color = vec4(1.0);
+                 color[a / b] = 0.5;
+         }
+         """,
+         r'\(expression +int16_t +/'),
+    Test("f32 builtin with const arg",
+         """
+         uniform mediump float a;
+
+         void main()
+         {
+                 gl_FragColor = vec4(min(a, 3.0));
+         }
+         """,
+         r'\(expression +float16_t min'),
+    Test("i32 builtin with const arg",
+         """
+         #version 310 es
+         uniform mediump int a;
+
+         out highp int color;
+
+         void main()
+         {
+                 color = min(a, 3);
+         }
+         """,
+         r'\(expression +int16_t min'),
+    Test("u32 builtin with const arg",
+         """
+         #version 310 es
+         uniform mediump uint a;
+
+         out highp uint color;
+
+         void main()
+         {
+                 color = min(a, 3u);
+         }
+         """,
+         r'\(expression +uint16_t min'),
+    Test("dFdx",
+         """
+         #version 300 es
+         precision mediump float;
+
+         in vec4 var;
+         out vec4 color;
+
+         void main()
+         {
+                 color = dFdx(var);
+         }
+         """,
+         r'\(expression +f16vec4 +dFdx +\(expression +f16vec4'),
+    Test("dFdy",
+         """
+         #version 300 es
+         precision mediump float;
+
+         in vec4 var;
+         out vec4 color;
+
+         void main()
+         {
+                 color = dFdy(var);
+         }
+         """,
+         r'\(expression +f16vec4 +dFdy +\(expression +f16vec4'),
+    Test("textureSize",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform mediump sampler2D tex;
+         out ivec2 color;
+
+         void main()
+         {
+                 color = textureSize(tex, 0) * ivec2(2);
+         }
+         """,
+         r'expression ivec2 \* \(txs ivec2 \(var_ref tex'),
+    Test("floatBitsToInt",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform float val;
+         out int color;
+
+         void main()
+         {
+                 color = floatBitsToInt(val + 1.0) + 1;
+         }
+         """,
+         r'expression int bitcast_f2i \(expression float'),
+    Test("floatBitsToUint",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform float val;
+         out uint color;
+
+         void main()
+         {
+                 color = floatBitsToUint(val + 1.0) + 1u;
+         }
+         """,
+         r'expression uint bitcast_f2u \(expression float'),
+    Test("intBitsToFloat",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int val;
+         out float color;
+
+         void main()
+         {
+                 color = intBitsToFloat(val + 1) + 1.0;
+         }
+         """,
+         r'expression float bitcast_i2f \(expression int'),
+    Test("uintBitsToFloat",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint val;
+         out float color;
+
+         void main()
+         {
+                 color = uintBitsToFloat(val + 1u) + 1.0;
+         }
+         """,
+         r'expression float bitcast_u2f \(expression uint'),
+    Test("bitfieldReverse",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int val;
+         out int color;
+
+         void main()
+         {
+                 color = bitfieldReverse(val + 1) + 1;
+         }
+         """,
+         r'expression int bitfield_reverse \(expression int'),
+    Test("frexp",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform float val;
+         out float color;
+         out int color2;
+
+         void main()
+         {
+                 int y;
+                 float x = frexp(val + 1.0, y);
+                 color = x + 1.0;
+                 color2 = y + 1;
+         }
+         """,
+         r'assign  \(x\) \(var_ref x\)  \(expression float f162f'),
+    Test("ldexp",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform float val;
+         uniform int exp;
+         out float color;
+
+         void main()
+         {
+                 color = ldexp(val + 1.0, exp + 1) + 1.0;
+         }
+         """,
+         r'expression float ldexp \(expression float'),
+    Test("uaddCarry",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint x, y;
+         out uint color;
+
+         void main()
+         {
+                 lowp uint carry;
+                 color = uaddCarry(x * 2u, y * 2u, carry) * 2u;
+                 color *= carry;
+         }
+         """,
+         r'expression uint \+ \(var_ref x\) \(var_ref y'),
+    Test("usubBorrow",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint x, y;
+         out uint color;
+
+         void main()
+         {
+                 lowp uint borrow;
+                 color = usubBorrow(x * 2u, y * 2u, borrow) * 2u;
+                 color *= borrow;
+         }
+         """,
+         r'expression uint \+ \(var_ref x\) \(expression uint neg'),
+    Test("imulExtended",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform int x, y;
+         out int color;
+
+         void main()
+         {
+                 int msb, lsb;
+                 imulExtended(x + 2, y + 2, msb, lsb);
+                 color = msb + lsb;
+         }
+         """,
+         r'expression int64_t \* \(expression int'),
+    Test("umulExtended",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint x, y;
+         out uint color;
+
+         void main()
+         {
+                 uint msb, lsb;
+                 umulExtended(x + 2u, y + 2u, msb, lsb);
+                 color = msb + lsb;
+         }
+         """,
+         r'expression uint64_t \* \(expression uint'),
+    Test("unpackUnorm2x16",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint val;
+         out vec2 color;
+
+         void main()
+         {
+                 color = unpackUnorm2x16(val + 1u) + vec2(1.0);
+         }
+         """,
+         r'expression vec2 unpackUnorm2x16 \(expression uint'),
+    Test("unpackSnorm2x16",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform uint val;
+         out vec2 color;
+
+         void main()
+         {
+                 color = unpackSnorm2x16(val + 1u) + vec2(1.0);
+         }
+         """,
+         r'expression vec2 unpackSnorm2x16 \(expression uint'),
+    Test("packUnorm2x16",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform vec2 val;
+         out uint color;
+
+         void main()
+         {
+                 color = packUnorm2x16(val + vec2(1.0)) + 1u;
+         }
+         """,
+         r'expression uint packUnorm2x16 \(expression vec2'),
+    Test("packSnorm2x16",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform vec2 val;
+         out uint color;
+
+         void main()
+         {
+                 color = packSnorm2x16(val + vec2(1.0)) + 1u;
+         }
+         """,
+         r'expression uint packSnorm2x16 \(expression vec2'),
+    Test("packHalf2x16",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform vec2 val;
+         out uint color;
+
+         void main()
+         {
+                 color = packHalf2x16(val + vec2(1.0)) + 1u;
+         }
+         """,
+         r'expression uint packHalf2x16 \(expression vec2'),
+    Test("packUnorm4x8",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform vec4 val;
+         out uint color;
+
+         void main()
+         {
+                 color = packUnorm4x8(val + vec4(1.0)) + 1u;
+         }
+         """,
+         r'expression uint packUnorm4x8 \(expression vec4'),
+    Test("packSnorm4x8",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform vec4 val;
+         out uint color;
+
+         void main()
+         {
+                 color = packSnorm4x8(val + vec4(1.0)) + 1u;
+         }
+         """,
+         r'expression uint packSnorm4x8 \(expression vec4'),
+    Test("interpolateAtCentroid",
+         """
+         #version 320 es
+         precision mediump float;
+         precision mediump int;
+
+         in float val;
+         out float color;
+
+         void main()
+         {
+                 color = interpolateAtCentroid(val) + 1.0;
+         }
+         """,
+         r'expression float16_t interpolate_at_centroid \(expression float16_t'),
+    Test("interpolateAtOffset",
+         """
+         #version 320 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform highp vec2 offset;
+         in float val;
+         out float color;
+
+         void main()
+         {
+                 color = interpolateAtOffset(val, offset) + 1.0;
+         }
+         """,
+         r'expression float16_t interpolate_at_offset \(expression float16_t'),
+    Test("interpolateAtSample",
+         """
+         #version 320 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform highp int sample_index;
+         in float val;
+         out float color;
+
+         void main()
+         {
+                 color = interpolateAtSample(val, sample_index) + 1.0;
+         }
+         """,
+         r'expression float16_t interpolate_at_sample \(expression float16_t'),
+    Test("bitfieldExtract",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform highp int offset, bits;
+         uniform int val;
+         out int color;
+
+         void main()
+         {
+                 color = bitfieldExtract(val, offset, bits) + 1;
+         }
+         """,
+         r'expression int16_t bitfield_extract \(expression int16_t'),
+    Test("bitfieldInsert",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform highp int offset, bits;
+         uniform int val, val2;
+         out int color;
+
+         void main()
+         {
+                 color = bitfieldInsert(val, val2, offset, bits) + 1;
+         }
+         """,
+         r'expression int16_t bitfield_insert \(expression int16_t'),
+    Test("bitCount",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform highp int val;
+         out int color;
+
+         void main()
+         {
+                 color = bitCount(val) + 1;
+         }
+         """,
+         r'expression int16_t \+ \(expression int16_t i2imp \(expression int bit_count \(var_ref val'),
+    Test("findLSB",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform highp int val;
+         out int color;
+
+         void main()
+         {
+                 color = findLSB(val) + 1;
+         }
+         """,
+         r'expression int16_t \+ \(expression int16_t i2imp \(expression int find_lsb \(var_ref val'),
+    Test("findMSB",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform highp int val;
+         out int color;
+
+         void main()
+         {
+                 color = findMSB(val) + 1;
+         }
+         """,
+         r'expression int16_t \+ \(expression int16_t i2imp \(expression int find_msb \(var_ref val'),
+    Test("unpackHalf2x16",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform highp uint val;
+         out vec2 color;
+
+         void main()
+         {
+                 color = unpackHalf2x16(val) + vec2(1.0);
+         }
+         """,
+         r'expression f16vec2 \+ \(expression f16vec2 f2fmp \(expression vec2 unpackHalf2x16 \(var_ref val'),
+    Test("unpackUnorm4x8",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform highp uint val;
+         out vec4 color;
+
+         void main()
+         {
+                 color = unpackUnorm4x8(val) + vec4(1.0);
+         }
+         """,
+         r'expression f16vec4 \+ \(expression f16vec4 f2fmp \(expression vec4 unpackUnorm4x8 \(var_ref val'),
+    Test("unpackSnorm4x8",
+         """
+         #version 310 es
+         precision mediump float;
+         precision mediump int;
+
+         uniform highp uint val;
+         out vec4 color;
+
+         void main()
+         {
+                 color = unpackSnorm4x8(val) + vec4(1.0);
+         }
+         """,
+         r'expression f16vec4 \+ \(expression f16vec4 f2fmp \(expression vec4 unpackSnorm4x8 \(var_ref val'),
 ]
 
 
@@ -364,6 +1647,7 @@ def run_test(standalone_compiler, test):
     ir = compile_shader(standalone_compiler, test.source)
 
     if re.search(test.match_re, ir) is None:
+        print(ir)
         return False
 
     return True