gallivm: Update comments and prototype of vector-selects.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Sat, 18 Feb 2012 12:02:17 +0000 (12:02 +0000)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Thu, 1 Mar 2012 06:00:48 +0000 (06:00 +0000)
No runtime behavior change. As vector selects are still not very well
supported by LLVM.

src/gallium/auxiliary/gallivm/lp_bld_logic.c

index f7e6fbaff1a2aaad405167986db40fb0bcd1610a..69796149aaa6978750ad7246f1f228437dceb7fa 100644 (file)
@@ -458,6 +458,33 @@ lp_build_select(struct lp_build_context *bld,
       mask = LLVMBuildTrunc(builder, mask, LLVMInt1TypeInContext(lc), "");
       res = LLVMBuildSelect(builder, mask, a, b, "");
    }
+   else if (0) {
+      /* Generate a vector select.
+       *
+       * XXX: Using vector selects would avoid emitting intrinsics, but they aren't
+       * properly supported yet.
+       *
+       * LLVM 3.0 includes experimental support provided the -promote-elements
+       * options is passed to LLVM's command line (e.g., via
+       * llvm::cl::ParseCommandLineOptions), but resulting code quality is much
+       * worse, probably because some optimization passes don't know how to
+       * handle vector selects.
+       *
+       * See also:
+       * - http://lists.cs.uiuc.edu/pipermail/llvmdev/2011-October/043659.html
+       */
+
+      /* Convert the mask to a vector of booleans.
+       * XXX: There are two ways to do this. Decide what's best.
+       */
+      if (1) {
+         LLVMTypeRef bool_vec_type = LLVMVectorType(LLVMInt1TypeInContext(lc), type.length);
+         mask = LLVMBuildTrunc(builder, mask, bool_vec_type, "");
+      } else {
+         mask = LLVMBuildICmp(builder, LLVMIntNE, mask, LLVMConstNull(bld->int_vec_type), "");
+      }
+      res = LLVMBuildSelect(builder, mask, a, b, "");
+   }
    else if (util_cpu_caps.has_sse4_1 &&
             type.width * type.length == 128 &&
             !LLVMIsConstant(a) &&
@@ -538,13 +565,11 @@ lp_build_select_aos(struct lp_build_context *bld,
       return bld->undef;
 
    /*
-    * There are three major ways of accomplishing this:
-    * - with a shuffle,
-    * - with a select,
-    * - or with a bit mask.
+    * There are two major ways of accomplishing this:
+    * - with a shuffle
+    * - with a select
     *
-    * Select isn't supported for vector types yet.
-    * The flip between these is empirical and might need to be.
+    * The flip between these is empirical and might need to be adjusted.
     */
    if (n <= 4) {
       /*
@@ -562,21 +587,7 @@ lp_build_select_aos(struct lp_build_context *bld,
       return LLVMBuildShuffleVector(builder, a, b, LLVMConstVector(shuffles, n), "");
    }
    else {
-#if 0
-      /* XXX: Unfortunately select of vectors do not work */
-      /* Use a select */
-      LLVMTypeRef elem_type = LLVMInt1Type();
-      LLVMValueRef cond_vec[LP_MAX_VECTOR_LENGTH];
-
-      for(j = 0; j < n; j += 4)
-         for(i = 0; i < 4; ++i)
-            cond_vec[j + i] = LLVMConstInt(elem_type,
-                                           mask & (1 << i) ? 1 : 0, 0);
-
-      return LLVMBuildSelect(builder, LLVMConstVector(cond_vec, n), a, b, "");
-#else
       LLVMValueRef mask_vec = lp_build_const_mask_aos(bld->gallivm, type, mask);
       return lp_build_select(bld, mask_vec, a, b);
-#endif
    }
 }