i965: Add negative_equals methods
authorIan Romanick <ian.d.romanick@intel.com>
Tue, 7 Apr 2015 23:11:37 +0000 (16:11 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Mon, 26 Mar 2018 15:50:43 +0000 (08:50 -0700)
This method is similar to the existing ::equals methods.  Instead of
testing that two src_regs are equal to each other, it tests that one is
the negation of the other.

v2: Simplify various checks based on suggestions from Matt.  Use
src_reg::type instead of fixed_hw_reg.type in a check.  Also suggested
by Matt.

v3: Rebase on 3 years.  Fix some problems with negative_equals with VF
constants.  Add fs_reg::negative_equals.

v4: Replace the existing default case with BRW_REGISTER_TYPE_UB,
BRW_REGISTER_TYPE_B, and BRW_REGISTER_TYPE_NF.  Suggested by Matt.
Expand the FINISHME comment to better explain why it isn't already
finished.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Alejandro PiƱeiro <apinheiro@igalia.com> [v3]
Reviewed-by: Matt Turner <mattst88@gmail.com>
src/intel/compiler/brw_fs.cpp
src/intel/compiler/brw_ir_fs.h
src/intel/compiler/brw_ir_vec4.h
src/intel/compiler/brw_reg.h
src/intel/compiler/brw_shader.cpp
src/intel/compiler/brw_shader.h
src/intel/compiler/brw_vec4.cpp

index 6eea532f56840f343343a52bcb1c476f90737626..3d454c3db1476f0feba80e9494dc8030f740ae67 100644 (file)
@@ -453,6 +453,13 @@ fs_reg::equals(const fs_reg &r) const
            stride == r.stride);
 }
 
+bool
+fs_reg::negative_equals(const fs_reg &r) const
+{
+   return (this->backend_reg::negative_equals(r) &&
+           stride == r.stride);
+}
+
 bool
 fs_reg::is_contiguous() const
 {
index 54797ff0fa2a636ebfbc8e69ee081873e9f72e55..f06a33c516d205599a5c0c682d6181586d76b65f 100644 (file)
@@ -41,6 +41,7 @@ public:
    fs_reg(enum brw_reg_file file, int nr, enum brw_reg_type type);
 
    bool equals(const fs_reg &r) const;
+   bool negative_equals(const fs_reg &r) const;
    bool is_contiguous() const;
 
    /**
index cbaff2feff4f20a1881c88644808d2be3377de14..95c5119c6c0c2eaafab730004cd4296d6dc73a9f 100644 (file)
@@ -43,6 +43,7 @@ public:
    src_reg(struct ::brw_reg reg);
 
    bool equals(const src_reg &r) const;
+   bool negative_equals(const src_reg &r) const;
 
    src_reg(class vec4_visitor *v, const struct glsl_type *type);
    src_reg(class vec4_visitor *v, const struct glsl_type *type, int size);
index 7ad144bdfd5dd7a0b1a33e08972a2bc7cba1526f..68158cc0cc8750f3f6508ae17f9c29da73c940e1 100644 (file)
@@ -255,6 +255,55 @@ brw_regs_equal(const struct brw_reg *a, const struct brw_reg *b)
    return a->bits == b->bits && (df ? a->u64 == b->u64 : a->ud == b->ud);
 }
 
+static inline bool
+brw_regs_negative_equal(const struct brw_reg *a, const struct brw_reg *b)
+{
+   if (a->file == IMM) {
+      if (a->bits != b->bits)
+         return false;
+
+      switch (a->type) {
+      case BRW_REGISTER_TYPE_UQ:
+      case BRW_REGISTER_TYPE_Q:
+         return a->d64 == -b->d64;
+      case BRW_REGISTER_TYPE_DF:
+         return a->df == -b->df;
+      case BRW_REGISTER_TYPE_UD:
+      case BRW_REGISTER_TYPE_D:
+         return a->d == -b->d;
+      case BRW_REGISTER_TYPE_F:
+         return a->f == -b->f;
+      case BRW_REGISTER_TYPE_VF:
+         /* It is tempting to treat 0 as a negation of 0 (and -0 as a negation
+          * of -0).  There are occasions where 0 or -0 is used and the exact
+          * bit pattern is desired.  At the very least, changing this to allow
+          * 0 as a negation of 0 causes some fp64 tests to fail on IVB.
+          */
+         return a->ud == (b->ud ^ 0x80808080);
+      case BRW_REGISTER_TYPE_UW:
+      case BRW_REGISTER_TYPE_W:
+      case BRW_REGISTER_TYPE_UV:
+      case BRW_REGISTER_TYPE_V:
+      case BRW_REGISTER_TYPE_HF:
+         /* FINISHME: Implement support for these types once there is
+          * something in the compiler that can generate them.  Until then,
+          * they cannot be tested.
+          */
+         return false;
+      case BRW_REGISTER_TYPE_UB:
+      case BRW_REGISTER_TYPE_B:
+      case BRW_REGISTER_TYPE_NF:
+         unreachable("not reached");
+      }
+   } else {
+      struct brw_reg tmp = *a;
+
+      tmp.negate = !tmp.negate;
+
+      return brw_regs_equal(&tmp, b);
+   }
+}
+
 struct brw_indirect {
    unsigned addr_subnr:4;
    int addr_offset:10;
index 054962bd7e3f59f01f5cd9d0f0fb7b48a161db72..9cdf9fcb23dbf433c50aaddf6b3ac1d50f743b01 100644 (file)
@@ -684,6 +684,12 @@ backend_reg::equals(const backend_reg &r) const
    return brw_regs_equal(this, &r) && offset == r.offset;
 }
 
+bool
+backend_reg::negative_equals(const backend_reg &r) const
+{
+   return brw_regs_negative_equal(this, &r) && offset == r.offset;
+}
+
 bool
 backend_reg::is_zero() const
 {
index fd02feb9107a711f1185fdf5d50d3e1b4e3a1330..7d97ddbd86828507d6b4a8e8ecd6d7ddc1de9504 100644 (file)
@@ -59,6 +59,7 @@ struct backend_reg : private brw_reg
    }
 
    bool equals(const backend_reg &r) const;
+   bool negative_equals(const backend_reg &r) const;
 
    bool is_zero() const;
    bool is_one() const;
index e4838146ac15cb6638002a435e5a9b8135afd89a..6680410a5255488d67e467d67b2d371305a74ce4 100644 (file)
@@ -375,6 +375,13 @@ src_reg::equals(const src_reg &r) const
           !reladdr && !r.reladdr);
 }
 
+bool
+src_reg::negative_equals(const src_reg &r) const
+{
+   return this->backend_reg::negative_equals(r) &&
+          !reladdr && !r.reladdr;
+}
+
 bool
 vec4_visitor::opt_vector_float()
 {