Module: Mesa
Branch: staging/22.1
Commit: a5e133250f9d82dd5bb2c0d9b5219a306029fd00
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=a5e133250f9d82dd5bb2c0d9b5219a306029fd00

Author: Autumn on Tape <[email protected]>
Date:   Fri Apr  1 13:03:30 2022 -0700

gallivm: use shufflevector for shuffles when index is constant data

This checks if index is a ConstantAggregateZero, ConstantDataSequential,
or UndefValue and emits a single shufflevector instead of a loop if so.

Signed-off-by: Autumn on Tape <[email protected]>
Reviewed-by: Dave Airlie <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13671>

---

 src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c | 38 ++++++++++++++++----------
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c 
b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c
index cb8a2c31e1f..8b22c43cd57 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c
@@ -2121,26 +2121,34 @@ static void emit_shuffle(struct lp_build_nir_context 
*bld_base, LLVMValueRef src
    uint32_t bit_size = nir_src_bit_size(instr->src[0]);
    struct lp_build_context *int_bld = get_int_bld(bld_base, true, bit_size);
 
-   LLVMValueRef res_store = lp_build_alloca(gallivm, int_bld->vec_type, "");
-   struct lp_build_loop_state loop_state;
-   lp_build_loop_begin(&loop_state, gallivm, lp_build_const_int32(gallivm, 0));
+   bool index_is_constant_data = LLVMIsAConstantAggregateZero(index) || 
LLVMIsAConstantDataSequential(index) || LLVMIsAUndefValue(index);
 
-   LLVMValueRef index_value = LLVMBuildExtractElement(builder, index, 
loop_state.counter, "");
+   if (index_is_constant_data) {
+      /* freeze `src` in case inactive invocations contain poison */
+      src = LLVMBuildFreeze(builder, src, "");
+      result[0] = LLVMBuildShuffleVector(builder, src, 
LLVMGetUndef(LLVMTypeOf(src)), index, "");
+   } else {
+      LLVMValueRef res_store = lp_build_alloca(gallivm, int_bld->vec_type, "");
+      struct lp_build_loop_state loop_state;
+      lp_build_loop_begin(&loop_state, gallivm, lp_build_const_int32(gallivm, 
0));
 
-   LLVMValueRef src_value = LLVMBuildExtractElement(builder, src, index_value, 
"");
-   /* freeze `src_value` in case an out-of-bounds index or an index into an
-    * inactive invocation results in poison
-    */
-   src_value = LLVMBuildFreeze(builder, src_value, "");
+      LLVMValueRef index_value = LLVMBuildExtractElement(builder, index, 
loop_state.counter, "");
 
-   LLVMValueRef res = LLVMBuildLoad(builder, res_store, "");
-   res = LLVMBuildInsertElement(builder, res, src_value, loop_state.counter, 
"");
-   LLVMBuildStore(builder, res, res_store);
+      LLVMValueRef src_value = LLVMBuildExtractElement(builder, src, 
index_value, "");
+      /* freeze `src_value` in case an out-of-bounds index or an index into an
+       * inactive invocation results in poison
+       */
+      src_value = LLVMBuildFreeze(builder, src_value, "");
 
-   lp_build_loop_end_cond(&loop_state, lp_build_const_int32(gallivm, 
bld_base->uint_bld.type.length),
-                          NULL, LLVMIntUGE);
+      LLVMValueRef res = LLVMBuildLoad(builder, res_store, "");
+      res = LLVMBuildInsertElement(builder, res, src_value, 
loop_state.counter, "");
+      LLVMBuildStore(builder, res, res_store);
+
+      lp_build_loop_end_cond(&loop_state, lp_build_const_int32(gallivm, 
bld_base->uint_bld.type.length),
+                             NULL, LLVMIntUGE);
 
-   result[0] = LLVMBuildLoad(builder, res_store, "");
+      result[0] = LLVMBuildLoad(builder, res_store, "");
+   }
 }
 #endif
 

Reply via email to