summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Fonseca <[email protected]>2009-08-31 10:22:36 +0100
committerJosé Fonseca <[email protected]>2009-08-31 10:22:36 +0100
commit241c3a1d8001fc5a30e2af4b4636b48e6f99690a (patch)
tree2a14a75e5e10c450cfb441bc5e55aba4df378653
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.
-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 d6dfd853422..8631efd6c3e 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;
}