ac/nir: add a workaround for bitfield_extract when count is 0
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Thu, 19 Jul 2018 18:27:11 +0000 (20:27 +0200)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Thu, 19 Jul 2018 18:41:10 +0000 (20:41 +0200)
LLVM 7 returns incorrect results when count is 0, something
has been broken since LLVM 6. Of course, the best solution is
to fix LLVM but this workaround works as expected for now.

Original workaround by Philippe Rebohle.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107276
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
src/amd/common/ac_nir_to_llvm.c

index 83d8b9a4425e892318ac04a49912021319bf4393..10d1773850924971e3dc8f69cdca0743bde192ae 100644 (file)
@@ -418,10 +418,24 @@ static LLVMValueRef emit_bitfield_extract(struct ac_llvm_context *ctx,
                                          const LLVMValueRef srcs[3])
 {
        LLVMValueRef result;
-       LLVMValueRef icond = LLVMBuildICmp(ctx->builder, LLVMIntEQ, srcs[2], LLVMConstInt(ctx->i32, 32, false), "");
 
-       result = ac_build_bfe(ctx, srcs[0], srcs[1], srcs[2], is_signed);
-       result = LLVMBuildSelect(ctx->builder, icond, srcs[0], result, "");
+       if (HAVE_LLVM < 0x0700) {
+               LLVMValueRef icond = LLVMBuildICmp(ctx->builder, LLVMIntEQ, srcs[2], LLVMConstInt(ctx->i32, 32, false), "");
+               result = ac_build_bfe(ctx, srcs[0], srcs[1], srcs[2], is_signed);
+               result = LLVMBuildSelect(ctx->builder, icond, srcs[0], result, "");
+       } else {
+               /* FIXME: LLVM 7 returns incorrect result when count is 0.
+                * https://bugs.freedesktop.org/show_bug.cgi?id=107276
+                */
+               LLVMValueRef zero = LLVMConstInt(ctx->i32, 0, false);
+               LLVMValueRef icond1 = LLVMBuildICmp(ctx->builder, LLVMIntEQ, srcs[2], LLVMConstInt(ctx->i32, 32, false), "");
+               LLVMValueRef icond2 = LLVMBuildICmp(ctx->builder, LLVMIntEQ, srcs[2], zero, "");
+
+               result = ac_build_bfe(ctx, srcs[0], srcs[1], srcs[2], is_signed);
+               result = LLVMBuildSelect(ctx->builder, icond1, srcs[0], result, "");
+               result = LLVMBuildSelect(ctx->builder, icond2, zero, result, "");
+       }
+
        return result;
 }