summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2009-08-31 10:22:36 +0100
committerJosé Fonseca <jfonseca@vmware.com>2009-08-31 10:22:36 +0100
commit241c3a1d8001fc5a30e2af4b4636b48e6f99690a (patch)
tree2a14a75e5e10c450cfb441bc5e55aba4df378653 /src/gallium/drivers/llvmpipe
parent45fb66ab7bc1cbb150e055826dc61b542739cc35 (diff)
llvmpipe: Fallback to element-wise comparisons when no comparison intrinsic is available.
Although selection of vector elements is valid LLVM IR, no machine target supports it yet. This is a last-resort option, but it allows llvmpipe to be used on any target supported by LLVM without modifications. Obviously better performance is attainable by emitting SIMD intrinsics where otherwise LLVM doesn't.
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_logic.c47
1 files changed, 45 insertions, 2 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_logic.c b/src/gallium/drivers/llvmpipe/lp_bld_logic.c
index d6dfd85342..8631efd6c3 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_logic.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_logic.c
@@ -51,6 +51,8 @@ lp_build_cmp(struct lp_build_context *bld,
LLVMValueRef zeros = LLVMConstNull(int_vec_type);
LLVMValueRef ones = LLVMConstAllOnes(int_vec_type);
LLVMValueRef cond;
+ LLVMValueRef res;
+ unsigned i;
if(func == PIPE_FUNC_NEVER)
return zeros;
@@ -67,7 +69,6 @@ lp_build_cmp(struct lp_build_context *bld,
LLVMValueRef args[3];
unsigned cc;
boolean swap;
- LLVMValueRef res;
swap = FALSE;
switch(func) {
@@ -218,7 +219,28 @@ lp_build_cmp(struct lp_build_context *bld,
assert(0);
return bld->undef;
}
+
+#if 0
+ /* XXX: Although valid IR, no LLVM target currently support this */
cond = LLVMBuildFCmp(bld->builder, op, a, b, "");
+ res = LLVMBuildSelect(bld->builder, cond, ones, zeros, "");
+#else
+ debug_printf("%s: warning: using slow element-wise vector comparison\n",
+ __FUNCTION__);
+ res = LLVMGetUndef(int_vec_type);
+ for(i = 0; i < type.length; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ cond = LLVMBuildFCmp(bld->builder, op,
+ LLVMBuildExtractElement(bld->builder, a, index, ""),
+ LLVMBuildExtractElement(bld->builder, b, index, ""),
+ "");
+ cond = LLVMBuildSelect(bld->builder, cond,
+ LLVMConstExtractElement(ones, index),
+ LLVMConstExtractElement(zeros, index),
+ "");
+ res = LLVMBuildInsertElement(bld->builder, res, cond, index, "");
+ }
+#endif
}
else {
LLVMIntPredicate op;
@@ -245,10 +267,31 @@ lp_build_cmp(struct lp_build_context *bld,
assert(0);
return bld->undef;
}
+
+#if 0
+ /* XXX: Although valid IR, no LLVM target currently support this */
cond = LLVMBuildICmp(bld->builder, op, a, b, "");
+ res = LLVMBuildSelect(bld->builder, cond, ones, zeros, "");
+#else
+ debug_printf("%s: warning: using slow element-wise vector comparison\n",
+ __FUNCTION__);
+ res = LLVMGetUndef(int_vec_type);
+ for(i = 0; i < type.length; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ cond = LLVMBuildICmp(bld->builder, op,
+ LLVMBuildExtractElement(bld->builder, a, index, ""),
+ LLVMBuildExtractElement(bld->builder, b, index, ""),
+ "");
+ cond = LLVMBuildSelect(bld->builder, cond,
+ LLVMConstExtractElement(ones, index),
+ LLVMConstExtractElement(zeros, index),
+ "");
+ res = LLVMBuildInsertElement(bld->builder, res, cond, index, "");
+ }
+#endif
}
- return LLVMBuildSelect(bld->builder, cond, ones, zeros, "");
+ return res;
}