summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Rusin <zackr@vmware.com>2013-07-18 03:32:02 -0400
committerZack Rusin <zackr@vmware.com>2013-07-19 16:29:18 -0400
commitf7c06785d08156320836ee94552e7f89e1542647 (patch)
tree35d718c0112585aa719445fc179fe54e52e37858
parent018c69ac56ee0579b5d4f138340444b326c4e6dc (diff)
gallivm: add a log function that handles edge cases
Same as log2_safe, which means that it can handle infs, 0s and nans. Signed-off-by: Zack Rusin <zackr@vmware.com> Reviewed-by: Jose Fonseca <jfonseca@vmware.com> Reviewed-by: Roland Scheidegger <sroland@vmware.com>
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_arit.c17
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_arit.h4
2 files changed, 21 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
index 2ce287f938a..98409c3be86 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
@@ -3080,6 +3080,7 @@ lp_build_exp(struct lp_build_context *bld,
/**
* Generate log(x)
+ * Behavior is undefined with infs, 0s and nans
*/
LLVMValueRef
lp_build_log(struct lp_build_context *bld,
@@ -3094,6 +3095,22 @@ lp_build_log(struct lp_build_context *bld,
return lp_build_mul(bld, log2, lp_build_log2(bld, x));
}
+/**
+ * Generate log(x) that handles edge cases (infs, 0s and nans)
+ */
+LLVMValueRef
+lp_build_log_safe(struct lp_build_context *bld,
+ LLVMValueRef x)
+{
+ /* log(2) */
+ LLVMValueRef log2 = lp_build_const_vec(bld->gallivm, bld->type,
+ 0.69314718055994529);
+
+ assert(lp_check_value(bld->type, x));
+
+ return lp_build_mul(bld, log2, lp_build_log2_safe(bld, x));
+}
+
/**
* Generate polynomial.
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.h b/src/gallium/auxiliary/gallivm/lp_bld_arit.h
index 6b9e0d1caf6..35119d18f7b 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.h
@@ -292,6 +292,10 @@ lp_build_log(struct lp_build_context *bld,
LLVMValueRef a);
LLVMValueRef
+lp_build_log_safe(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+LLVMValueRef
lp_build_exp2(struct lp_build_context *bld,
LLVMValueRef a);