summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJose Fonseca <[email protected]>2016-04-13 15:41:55 +0100
committerJose Fonseca <[email protected]>2016-04-13 16:42:55 +0100
commit9586468c03ba9d0c488882eba1d870acd7adfd9e (patch)
tree1d27d1bcd51ccae86dc3307c9da5d8e7681e1ec6
parentdd0a296895e9cf20399d038e9232d3d3b3fcc355 (diff)
gallivm: Workaround LLVM PR 27332.
The credit for finding and isolating this bug goes to Vinson and Roland. The buggy LLVM versions were found by doing opt -instcombine llvm-pr27332.ll > /dev/null where llvm-pr27332.ll is the IR from https://llvm.org/bugs/show_bug.cgi?id=27332#c3 Reviewed-by: Roland Scheidegger <[email protected]>
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_arit.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
index 9cb745e4cfe..beff4143fd8 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
@@ -1492,9 +1492,20 @@ lp_build_abs(struct lp_build_context *bld,
return a;
if(type.floating) {
- char intrinsic[32];
- lp_format_intrinsic(intrinsic, sizeof intrinsic, "llvm.fabs", vec_type);
- return lp_build_intrinsic_unary(builder, intrinsic, vec_type, a);
+ if (0x0306 <= HAVE_LLVM && HAVE_LLVM < 0x0309) {
+ /* Workaround llvm.org/PR27332 */
+ LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->gallivm, type);
+ unsigned long long absMask = ~(1ULL << (type.width - 1));
+ LLVMValueRef mask = lp_build_const_int_vec(bld->gallivm, type, ((unsigned long long) absMask));
+ a = LLVMBuildBitCast(builder, a, int_vec_type, "");
+ a = LLVMBuildAnd(builder, a, mask, "");
+ a = LLVMBuildBitCast(builder, a, vec_type, "");
+ return a;
+ } else {
+ char intrinsic[32];
+ lp_format_intrinsic(intrinsic, sizeof intrinsic, "llvm.fabs", vec_type);
+ return lp_build_intrinsic_unary(builder, intrinsic, vec_type, a);
+ }
}
if(type.width*type.length == 128 && util_cpu_caps.has_ssse3) {