llvmpipe: convert double to long long instead of unsigned long long
authorOded Gabbay <oded.gabbay@gmail.com>
Thu, 3 Sep 2015 16:00:26 +0000 (19:00 +0300)
committerIlia Mirkin <imirkin@alum.mit.edu>
Fri, 4 Sep 2015 21:37:17 +0000 (17:37 -0400)
round(val*dscale) produces a double result, as val and dscale are double.
However, LLVMConstInt receives unsigned long long, so there is an
implicit conversion from double to unsigned long long.
This is an undefined behavior. Therefore, we need to first explicitly
convert the round result to long long, and then let the compiler handle
conversion from that to unsigned long long.

This bug manifests itself in POWER, where all IMM values of -1 are being
converted to 0 implicitly, causing a wrong LLVM IR output.

Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
CC: "10.6 11.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
src/gallium/auxiliary/gallivm/lp_bld_const.c

index 0f5a8f8e851a7d54b32b6a54769327761f528272..9cd7c5553cf09f74c2a174f070537c72dde28d90 100644 (file)
@@ -311,7 +311,7 @@ lp_build_const_elem(struct gallivm_state *gallivm,
    else {
       double dscale = lp_const_scale(type);
 
-      elem = LLVMConstInt(elem_type, round(val*dscale), 0);
+      elem = LLVMConstInt(elem_type, (long long) round(val*dscale), 0);
    }
 
    return elem;