diff options
author | Ian Romanick <[email protected]> | 2015-04-07 16:11:37 -0700 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2018-03-26 08:50:43 -0700 |
commit | 8f83eea71e233227d34dc8547dac79d2912c2311 (patch) | |
tree | 15ff575b7bd14e99b83402c00d390e960763b406 /src | |
parent | a21da49e5c55f8e61253503d865cef936125ea5f (diff) |
i965: Add negative_equals methods
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 <[email protected]>
Reviewed-by: Alejandro PiƱeiro <[email protected]> [v3]
Reviewed-by: Matt Turner <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/intel/compiler/brw_fs.cpp | 7 | ||||
-rw-r--r-- | src/intel/compiler/brw_ir_fs.h | 1 | ||||
-rw-r--r-- | src/intel/compiler/brw_ir_vec4.h | 1 | ||||
-rw-r--r-- | src/intel/compiler/brw_reg.h | 49 | ||||
-rw-r--r-- | src/intel/compiler/brw_shader.cpp | 6 | ||||
-rw-r--r-- | src/intel/compiler/brw_shader.h | 1 | ||||
-rw-r--r-- | src/intel/compiler/brw_vec4.cpp | 7 |
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; |