nir: Fix output swizzle in get_mul_for_src
authorSamuel Iglesias Gonsalvez <siglesias@igalia.com>
Thu, 11 Jun 2015 10:32:26 +0000 (12:32 +0200)
committerJason Ekstrand <jason.ekstrand@intel.com>
Mon, 3 Aug 2015 16:40:50 +0000 (09:40 -0700)
Avoid copying an overwritten swizzle, use the original values.

Example:

   Former swizzle[] = xyzw
   src->swizzle[] = zyxx

The expected output swizzle = zyxx but if we reuse swizzle in the loop,
then output swizzle would be zyzz.

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
src/glsl/nir/nir_opt_peephole_ffma.c

index 798506b7595b18e8f8ab7792adb406bb1f30190c..a823adbb4651e7680167b0b958b9ce0f62228ec0 100644 (file)
@@ -76,6 +76,7 @@ static nir_alu_instr *
 get_mul_for_src(nir_alu_src *src, int num_components,
                 uint8_t swizzle[4], bool *negate, bool *abs)
 {
+   uint8_t swizzle_tmp[4];
    assert(src->src.is_ssa && !src->abs && !src->negate);
 
    nir_instr *instr = src->src.ssa->parent_instr;
@@ -116,8 +117,18 @@ get_mul_for_src(nir_alu_src *src, int num_components,
    if (!alu)
       return NULL;
 
+   /* Copy swizzle data before overwriting it to avoid setting a wrong swizzle.
+    *
+    * Example:
+    *   Former swizzle[] = xyzw
+    *   src->swizzle[] = zyxx
+    *
+    *   Expected output swizzle = zyxx
+    *   If we reuse swizzle in the loop, then output swizzle would be zyzz.
+    */
+   memcpy(swizzle_tmp, swizzle, 4*sizeof(uint8_t));
    for (unsigned i = 0; i < num_components; i++)
-      swizzle[i] = swizzle[src->swizzle[i]];
+      swizzle[i] = swizzle_tmp[src->swizzle[i]];
 
    return alu;
 }