i965/fs: Allow SIMD16 on pre-SNB when try_replace_with_sel is successful
authorIan Romanick <ian.d.romanick@intel.com>
Fri, 23 Jan 2015 20:31:05 +0000 (12:31 -0800)
committerIan Romanick <ian.d.romanick@intel.com>
Sat, 24 Jan 2015 01:34:47 +0000 (17:34 -0800)
If try_replace_with_sel is able to replace the flow control with a SEL
instruction, then there is no flow control... failing SIMD16 because
of nonexistent flow control is wrong.

No piglit regressions on any i965 platform in Jenkins.

total instructions in shared programs: 4382707 -> 4382707 (0.00%)
instructions in affected programs:     0 -> 0
helped:                                0
HURT:                                  0
GAINED:                                2089
LOST:                                  0

No other platforms affected in shader-db.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_fs.h
src/mesa/drivers/dri/i965/brw_fs_nir.cpp
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp

index 1de10bb4b8570d28f05d7ec2f33abf2cff38037d..419fe48f1aa97ba325526963f857d67fee3bc23c 100644 (file)
@@ -535,7 +535,7 @@ public:
    bool try_emit_saturate(ir_expression *ir);
    bool try_emit_line(ir_expression *ir);
    bool try_emit_mad(ir_expression *ir);
-   void try_replace_with_sel();
+   bool try_replace_with_sel();
    bool opt_peephole_sel();
    bool opt_peephole_predicated_break();
    bool opt_saturate_propagation();
index 0eb137fe2d3bd085de1440a06e07f8b82ef8421d..de0d780e43863f79459e3ba1de428b81cc30d2cb 100644 (file)
@@ -435,10 +435,6 @@ fs_visitor::nir_emit_cf_list(exec_list *list)
 void
 fs_visitor::nir_emit_if(nir_if *if_stmt)
 {
-   if (brw->gen < 6) {
-      no16("Can't support (non-uniform) control flow on SIMD16\n");
-   }
-
    /* first, put the condition into f0 */
    fs_inst *inst = emit(MOV(reg_null_d,
                             retype(get_nir_src(if_stmt->condition),
@@ -456,7 +452,9 @@ fs_visitor::nir_emit_if(nir_if *if_stmt)
 
    emit(BRW_OPCODE_ENDIF);
 
-   try_replace_with_sel();
+   if (!try_replace_with_sel() && brw->gen < 6) {
+      no16("Can't support (non-uniform) control flow on SIMD16\n");
+   }
 }
 
 void
index 9805b552f87db94800b9db76e93950189ffa964c..f5d73838763d924a52fe3c62cf73ecfcd3413668 100644 (file)
@@ -2741,7 +2741,7 @@ fs_visitor::emit_if_gen6(ir_if *ir)
  *
  * If src0 is an immediate value, we promote it to a temporary GRF.
  */
-void
+bool
 fs_visitor::try_replace_with_sel()
 {
    fs_inst *endif_inst = (fs_inst *) instructions.get_tail();
@@ -2755,7 +2755,7 @@ fs_visitor::try_replace_with_sel()
    fs_inst *match = (fs_inst *) endif_inst->prev;
    for (int i = 0; i < 4; i++) {
       if (match->is_head_sentinel() || match->opcode != opcodes[4-i-1])
-         return;
+         return false;
       match = (fs_inst *) match->prev;
    }
 
@@ -2797,16 +2797,16 @@ fs_visitor::try_replace_with_sel()
          sel->predicate = if_inst->predicate;
          sel->predicate_inverse = if_inst->predicate_inverse;
       }
+
+      return true;
    }
+
+   return false;
 }
 
 void
 fs_visitor::visit(ir_if *ir)
 {
-   if (brw->gen < 6) {
-      no16("Can't support (non-uniform) control flow on SIMD16\n");
-   }
-
    /* Don't point the annotation at the if statement, because then it plus
     * the then and else blocks get printed.
     */
@@ -2836,7 +2836,9 @@ fs_visitor::visit(ir_if *ir)
 
    emit(BRW_OPCODE_ENDIF);
 
-   try_replace_with_sel();
+   if (!try_replace_with_sel() && brw->gen < 6) {
+      no16("Can't support (non-uniform) control flow on SIMD16\n");
+   }
 }
 
 void