gallivm: add a log function that handles edge cases
authorZack Rusin <zackr@vmware.com>
Thu, 18 Jul 2013 07:32:02 +0000 (03:32 -0400)
committerZack Rusin <zackr@vmware.com>
Fri, 19 Jul 2013 20:29:18 +0000 (16:29 -0400)
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>
src/gallium/auxiliary/gallivm/lp_bld_arit.c
src/gallium/auxiliary/gallivm/lp_bld_arit.h

index 2ce287f938aac2b30193d724b3f1e48cd835a5d4..98409c3be8620371d903e279792f5567d9ba0b5f 100644 (file)
@@ -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.
index 6b9e0d1caf65e2ecff519c14d3a222567408b0f1..35119d18f7b05219e0903d697a0a76846aa3bdd5 100644 (file)
@@ -291,6 +291,10 @@ LLVMValueRef
 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);