i965/fs: Fix off-by-one region overlap comparison in copy propagation.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_fs_channel_expressions.cpp
index 78a82406ad7ea6d01bae15c1a8c78ccfd2f1652b..3d2e61963d83e54ee2d257027deef7a31f23359d 100644 (file)
@@ -41,9 +41,9 @@
  * we do retain the vector types in that case.
  */
 
-#include "glsl/ir.h"
-#include "glsl/ir_expression_flattening.h"
-#include "glsl/nir/glsl_types.h"
+#include "compiler/glsl/ir.h"
+#include "compiler/glsl/ir_expression_flattening.h"
+#include "compiler/glsl_types.h"
 
 class ir_channel_expressions_visitor : public ir_hierarchical_visitor {
 public:
@@ -72,12 +72,20 @@ channel_expressions_predicate(ir_instruction *ir)
       return false;
 
    switch (expr->operation) {
+      case ir_unop_pack_half_2x16:
+      case ir_unop_pack_snorm_2x16:
+      case ir_unop_pack_snorm_4x8:
+      case ir_unop_pack_unorm_2x16:
+      case ir_unop_pack_unorm_4x8:
+         return false;
+
       /* these opcodes need to act on the whole vector,
        * just like texturing.
        */
       case ir_unop_interpolate_at_centroid:
       case ir_binop_interpolate_at_offset:
       case ir_binop_interpolate_at_sample:
+      case ir_unop_pack_double_2x32:
          return false;
       default:
          break;
@@ -143,7 +151,7 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
    ir_expression *expr = ir->rhs->as_expression();
    bool found_vector = false;
    unsigned int i, vector_elements = 1;
-   ir_variable *op_var[3];
+   ir_variable *op_var[4];
 
    if (!expr)
       return visit_continue;
@@ -162,9 +170,16 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
       return visit_continue;
 
    switch (expr->operation) {
+      case ir_unop_pack_half_2x16:
+      case ir_unop_pack_snorm_2x16:
+      case ir_unop_pack_snorm_4x8:
+      case ir_unop_pack_unorm_2x16:
+      case ir_unop_pack_unorm_4x8:
       case ir_unop_interpolate_at_centroid:
       case ir_binop_interpolate_at_offset:
       case ir_binop_interpolate_at_sample:
+      /* We scalarize these in NIR, so no need to do it here */
+      case ir_unop_pack_double_2x32:
          return visit_continue;
 
       default:
@@ -223,6 +238,13 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
    case ir_unop_i2b:
    case ir_unop_b2i:
    case ir_unop_u2f:
+   case ir_unop_d2f:
+   case ir_unop_f2d:
+   case ir_unop_d2i:
+   case ir_unop_i2d:
+   case ir_unop_d2u:
+   case ir_unop_u2d:
+   case ir_unop_d2b:
    case ir_unop_trunc:
    case ir_unop_ceil:
    case ir_unop_floor:
@@ -277,6 +299,7 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
    case ir_binop_gequal:
    case ir_binop_equal:
    case ir_binop_nequal:
+   case ir_binop_ldexp:
       for (i = 0; i < vector_elements; i++) {
         ir_rvalue *op0 = get_element(op_var[0], i);
         ir_rvalue *op1 = get_element(op_var[1], i);
@@ -345,20 +368,6 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
    case ir_unop_noise:
       unreachable("noise should have been broken down to function call");
 
-   case ir_binop_bfm: {
-      /* Does not need to be scalarized, since its result will be identical
-       * for all channels.
-       */
-      ir_rvalue *op0 = get_element(op_var[0], 0);
-      ir_rvalue *op1 = get_element(op_var[1], 0);
-
-      assign(ir, 0, new(mem_ctx) ir_expression(expr->operation,
-                                               element_type,
-                                               op0,
-                                               op1));
-      break;
-   }
-
    case ir_binop_ubo_load:
    case ir_unop_get_buffer_size:
       unreachable("not yet supported");
@@ -380,22 +389,21 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
       }
       break;
 
-   case ir_triop_bfi: {
-      /* Only a single BFM is needed for multiple BFIs. */
-      ir_rvalue *op0 = get_element(op_var[0], 0);
-
+   case ir_quadop_bitfield_insert:
       for (i = 0; i < vector_elements; i++) {
+         ir_rvalue *op0 = get_element(op_var[0], i);
          ir_rvalue *op1 = get_element(op_var[1], i);
          ir_rvalue *op2 = get_element(op_var[2], i);
+         ir_rvalue *op3 = get_element(op_var[3], i);
 
          assign(ir, i, new(mem_ctx) ir_expression(expr->operation,
                                                   element_type,
-                                                  op0->clone(mem_ctx, NULL),
+                                                  op0,
                                                   op1,
-                                                  op2));
+                                                  op2,
+                                                  op3));
       }
       break;
-   }
 
    case ir_unop_pack_snorm_2x16:
    case ir_unop_pack_snorm_4x8:
@@ -407,34 +415,24 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
    case ir_unop_unpack_unorm_2x16:
    case ir_unop_unpack_unorm_4x8:
    case ir_unop_unpack_half_2x16:
-   case ir_binop_ldexp:
    case ir_binop_vector_extract:
    case ir_triop_vector_insert:
-   case ir_quadop_bitfield_insert:
    case ir_quadop_vector:
    case ir_unop_ssbo_unsized_array_length:
       unreachable("should have been lowered");
 
-   case ir_unop_unpack_half_2x16_split_x:
-   case ir_unop_unpack_half_2x16_split_y:
-   case ir_binop_pack_half_2x16_split:
    case ir_unop_interpolate_at_centroid:
    case ir_binop_interpolate_at_offset:
    case ir_binop_interpolate_at_sample:
+   case ir_unop_unpack_double_2x32:
       unreachable("not reached: expression operates on scalars only");
 
    case ir_unop_pack_double_2x32:
-   case ir_unop_unpack_double_2x32:
+      unreachable("not reached: to be lowered in NIR, should've been skipped");
+
    case ir_unop_frexp_sig:
    case ir_unop_frexp_exp:
-   case ir_unop_d2f:
-   case ir_unop_f2d:
-   case ir_unop_d2i:
-   case ir_unop_i2d:
-   case ir_unop_d2u:
-   case ir_unop_u2d:
-   case ir_unop_d2b:
-      unreachable("no fp64 support yet");
+      unreachable("should have been lowered by lower_instructions");
    }
 
    ir->remove();