summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/intel/compiler/brw_fs.cpp7
-rw-r--r--src/intel/compiler/brw_ir_fs.h1
-rw-r--r--src/intel/compiler/brw_ir_vec4.h1
-rw-r--r--src/intel/compiler/brw_reg.h49
-rw-r--r--src/intel/compiler/brw_shader.cpp6
-rw-r--r--src/intel/compiler/brw_shader.h1
-rw-r--r--src/intel/compiler/brw_vec4.cpp7
7 files changed, 72 insertions, 0 deletions
diff --git a/src/intel/compiler/brw_fs.cpp b/src/intel/compiler/brw_fs.cpp
index 6eea532f568..3d454c3db14 100644
--- a/src/intel/compiler/brw_fs.cpp
+++ b/src/intel/compiler/brw_fs.cpp
@@ -454,6 +454,13 @@ fs_reg::equals(const fs_reg &r) const
}
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
{
return stride == 1;
diff --git a/src/intel/compiler/brw_ir_fs.h b/src/intel/compiler/brw_ir_fs.h
index 54797ff0fa2..f06a33c516d 100644
--- a/src/intel/compiler/brw_ir_fs.h
+++ b/src/intel/compiler/brw_ir_fs.h
@@ -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;
/**
diff --git a/src/intel/compiler/brw_ir_vec4.h b/src/intel/compiler/brw_ir_vec4.h
index cbaff2feff4..95c5119c6c0 100644
--- a/src/intel/compiler/brw_ir_vec4.h
+++ b/src/intel/compiler/brw_ir_vec4.h
@@ -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);
diff --git a/src/intel/compiler/brw_reg.h b/src/intel/compiler/brw_reg.h
index 7ad144bdfd5..68158cc0cc8 100644
--- a/src/intel/compiler/brw_reg.h
+++ b/src/intel/compiler/brw_reg.h
@@ -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;
diff --git a/src/intel/compiler/brw_shader.cpp b/src/intel/compiler/brw_shader.cpp
index 054962bd7e3..9cdf9fcb23d 100644
--- a/src/intel/compiler/brw_shader.cpp
+++ b/src/intel/compiler/brw_shader.cpp
@@ -685,6 +685,12 @@ backend_reg::equals(const backend_reg &r) const
}
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
{
if (file != IMM)
diff --git a/src/intel/compiler/brw_shader.h b/src/intel/compiler/brw_shader.h
index fd02feb9107..7d97ddbd868 100644
--- a/src/intel/compiler/brw_shader.h
+++ b/src/intel/compiler/brw_shader.h
@@ -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;
diff --git a/src/intel/compiler/brw_vec4.cpp b/src/intel/compiler/brw_vec4.cpp
index e4838146ac1..6680410a525 100644
--- a/src/intel/compiler/brw_vec4.cpp
+++ b/src/intel/compiler/brw_vec4.cpp
@@ -376,6 +376,13 @@ src_reg::equals(const src_reg &r) const
}
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()
{
bool progress = false;