diff options
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_logic.c | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_logic.c b/src/gallium/auxiliary/gallivm/lp_bld_logic.c index f7e6fbaff1a..69796149aaa 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_logic.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.c @@ -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 } } |