gallivm: Workaround http://llvm.org/PR18600
authorJosé Fonseca <jfonseca@vmware.com>
Fri, 24 Jan 2014 14:25:46 +0000 (14:25 +0000)
committerJosé Fonseca <jfonseca@vmware.com>
Tue, 28 Jan 2014 14:27:27 +0000 (14:27 +0000)
We have code generation paths that carry out swizzles of AoS vectors via
bitwise shifts, as these tend to generate more efficient code than
straightforward byte shuffles.  But when the input is a constant the
additional bitwise arithmetic operations somehow don't really get
constant propagated properly, evenutally causing assertion failure in
InstCombine pass.

Therefore avoid the bug by using the trivial shuffles for constant
inputs.

Although the sample LLVM IR can cause a crash with any LLVM version,
this was only seen in practice with LLVM 3.2.

Reviewed-by: Matthew McClure <mcclurem@vmware.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
src/gallium/auxiliary/gallivm/lp_bld_swizzle.c

index 79116bcf39110b6fdd0beb56fc61f6f866d4e98a..9557e1c10de796ae54687dc7baedd423d46d2369 100644 (file)
@@ -180,7 +180,8 @@ lp_build_swizzle_scalar_aos(struct lp_build_context *bld,
    /* XXX: SSE3 has PSHUFB which should be better than bitmasks, but forcing
     * using shuffles here actually causes worst results. More investigation is
     * needed. */
-   if (type.width >= 16) {
+   if (LLVMIsConstant(a) ||
+       type.width >= 16) {
       /*
        * Shuffle.
        */
@@ -398,7 +399,8 @@ lp_build_swizzle_aos(struct lp_build_context *bld,
       }
    }
 
-   if (type.width >= 16) {
+   if (LLVMIsConstant(a) ||
+       type.width >= 16) {
       /*
        * Shuffle.
        */