ac/nir: fix lsb emission
authorConnor Abbott <cwabbott0@gmail.com>
Tue, 1 Aug 2017 01:28:45 +0000 (18:28 -0700)
committerConnor Abbott <cwabbott0@gmail.com>
Tue, 1 Aug 2017 19:20:49 +0000 (12:20 -0700)
This makes it match radeonsi. The LLVM backend itself will emit the
correct instruction, but LLVM might do incorrect optimizations since it
thinks the output is undefined when the input is 0, even though it's not
supposed to be. We really need a new intrinsic, or for the backend to
become smarter and recognize this pattern.

Cc: mesa-stable@lists.freedesktop.org
Reviewed-by: Bas Nieuwenhuizen <basni@google.com>
src/amd/common/ac_nir_to_llvm.c

index 530b5817af39462f6adaf96f2711a6ccf86ebfaa..19b1ef07155d97ddea0124381ca9e87b3d4ee16d 100644 (file)
@@ -1187,7 +1187,17 @@ static LLVMValueRef emit_find_lsb(struct ac_llvm_context *ctx,
                 */
                LLVMConstInt(ctx->i1, 1, false),
        };
-       return ac_build_intrinsic(ctx, "llvm.cttz.i32", ctx->i32, params, 2, AC_FUNC_ATTR_READNONE);
+
+       LLVMValueRef lsb = ac_build_intrinsic(ctx, "llvm.cttz.i32", ctx->i32,
+                                             params, 2,
+                                             AC_FUNC_ATTR_READNONE);
+
+       /* TODO: We need an intrinsic to skip this conditional. */
+       /* Check for zero: */
+       return LLVMBuildSelect(ctx->builder, LLVMBuildICmp(ctx->builder,
+                                                          LLVMIntEQ, src0,
+                                                          ctx->i32_0, ""),
+                              LLVMConstInt(ctx->i32, -1, 0), lsb, "");
 }
 
 static LLVMValueRef emit_ifind_msb(struct ac_llvm_context *ctx,