intel: Don't propagate conditional modifiers if a UD source is negated

This fixes a bug uncovered by my NIR integer division by constant
optimization series.

Fixes: 19f9cb72c8 "i965/fs: Add pass to propagate conditional..."
Fixes: 627f94b72e "i965/vec4: adding vec4_cmod_propagation..."
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
Jason Ekstrand 2018-10-08 12:22:35 -05:00
parent 328d4d080b
commit 4ba445e011
5 changed files with 50 additions and 0 deletions

View File

@ -395,6 +395,25 @@ fs_inst::can_do_source_mods(const struct gen_device_info *devinfo)
return true;
}
bool
fs_inst::can_do_cmod()
{
if (!backend_instruction::can_do_cmod())
return false;
/* The accumulator result appears to get used for the conditional modifier
* generation. When negating a UD value, there is a 33rd bit generated for
* the sign in the accumulator value, so now you can't check, for example,
* equality with a 32-bit value. See piglit fs-op-neg-uvec4.
*/
for (unsigned i = 0; i < sources; i++) {
if (type_is_unsigned_int(src[i].type) && src[i].negate)
return false;
}
return true;
}
bool
fs_inst::can_change_types() const
{

View File

@ -354,6 +354,7 @@ public:
unsigned components_read(unsigned i) const;
unsigned size_read(int arg) const;
bool can_do_source_mods(const struct gen_device_info *devinfo);
bool can_do_cmod();
bool can_change_types() const;
bool has_source_and_destination_hazard() const;

View File

@ -291,6 +291,7 @@ public:
int swizzle, int swizzle_mask);
void reswizzle(int dst_writemask, int swizzle);
bool can_do_source_mods(const struct gen_device_info *devinfo);
bool can_do_cmod();
bool can_do_writemask(const struct gen_device_info *devinfo);
bool can_change_types() const;
bool has_source_and_destination_hazard() const;

View File

@ -376,6 +376,15 @@ brw_int_type(unsigned sz, bool is_signed)
}
}
static inline bool
type_is_unsigned_int(enum brw_reg_type tp)
{
return tp == BRW_REGISTER_TYPE_UB ||
tp == BRW_REGISTER_TYPE_UW ||
tp == BRW_REGISTER_TYPE_UD ||
tp == BRW_REGISTER_TYPE_UQ;
}
/**
* Construct a brw_reg.
* \param file one of the BRW_x_REGISTER_FILE values

View File

@ -257,6 +257,26 @@ vec4_instruction::can_do_source_mods(const struct gen_device_info *devinfo)
return true;
}
bool
vec4_instruction::can_do_cmod()
{
if (!backend_instruction::can_do_cmod())
return false;
/* The accumulator result appears to get used for the conditional modifier
* generation. When negating a UD value, there is a 33rd bit generated for
* the sign in the accumulator value, so now you can't check, for example,
* equality with a 32-bit value. See piglit fs-op-neg-uvec4.
*/
for (unsigned i = 0; i < 3; i++) {
if (src[i].file != BAD_FILE &&
type_is_unsigned_int(src[i].type) && src[i].negate)
return false;
}
return true;
}
bool
vec4_instruction::can_do_writemask(const struct gen_device_info *devinfo)
{