Re: [Mesa-dev] [PATCH v6 30/35] intel/compiler: validate region restrictions for half-float conversions

2019-04-10 Thread Francisco Jerez
"Juan A. Suarez Romero"  writes:

> From: Iago Toral Quiroga 
>
> v2:
>  - Consider implicit conversions in 2-src instructions too (Curro)
>  - For restrictions that involve destination stride requirements
>only validate them for Align1, since Align16 always requires
>packed data.
>  - Skip general rule for the dst/execution type size ratio for
>mixed float instructions on CHV and SKL+, these have their own
>set of rules that we'll be validated separately.
>
> v3 (Curro):
>  - Do not check src1 type in single-source instructions.
>  - Check restriction on src1.
>  - Remove invalid test.

Reviewed-by: Francisco Jerez 

> ---
>  src/intel/compiler/brw_eu_validate.c| 155 +++-
>  src/intel/compiler/test_eu_validate.cpp | 116 ++
>  2 files changed, 270 insertions(+), 1 deletion(-)
>
> diff --git a/src/intel/compiler/brw_eu_validate.c 
> b/src/intel/compiler/brw_eu_validate.c
> index bd0e48a5e5c..54bffb3af03 100644
> --- a/src/intel/compiler/brw_eu_validate.c
> +++ b/src/intel/compiler/brw_eu_validate.c
> @@ -469,6 +469,66 @@ is_packed(unsigned vstride, unsigned width, unsigned 
> hstride)
> return false;
>  }
>  
> +/**
> + * Returns whether an instruction is an explicit or implicit conversion
> + * to/from half-float.
> + */
> +static bool
> +is_half_float_conversion(const struct gen_device_info *devinfo,
> + const brw_inst *inst)
> +{
> +   enum brw_reg_type dst_type = brw_inst_dst_type(devinfo, inst);
> +
> +   unsigned num_sources = num_sources_from_inst(devinfo, inst);
> +   enum brw_reg_type src0_type = brw_inst_src0_type(devinfo, inst);
> +
> +   if (dst_type != src0_type &&
> +   (dst_type == BRW_REGISTER_TYPE_HF || src0_type == 
> BRW_REGISTER_TYPE_HF)) {
> +  return true;
> +   } else if (num_sources > 1) {
> +  enum brw_reg_type src1_type = brw_inst_src1_type(devinfo, inst);
> +  return dst_type != src1_type &&
> +(dst_type == BRW_REGISTER_TYPE_HF ||
> + src1_type == BRW_REGISTER_TYPE_HF);
> +   }
> +
> +   return false;
> +}
> +
> +/*
> + * Returns whether an instruction is using mixed float operation mode
> + */
> +static bool
> +is_mixed_float(const struct gen_device_info *devinfo, const brw_inst *inst)
> +{
> +   if (devinfo->gen < 8)
> +  return false;
> +
> +   if (inst_is_send(devinfo, inst))
> +  return false;
> +
> +   unsigned opcode = brw_inst_opcode(devinfo, inst);
> +   const struct opcode_desc *desc = brw_opcode_desc(devinfo, opcode);
> +   if (desc->ndst == 0)
> +  return false;
> +
> +   /* FIXME: support 3-src instructions */
> +   unsigned num_sources = num_sources_from_inst(devinfo, inst);
> +   assert(num_sources < 3);
> +
> +   enum brw_reg_type dst_type = brw_inst_dst_type(devinfo, inst);
> +   enum brw_reg_type src0_type = brw_inst_src0_type(devinfo, inst);
> +
> +   if (num_sources == 1)
> +  return types_are_mixed_float(src0_type, dst_type);
> +
> +   enum brw_reg_type src1_type = brw_inst_src1_type(devinfo, inst);
> +
> +   return types_are_mixed_float(src0_type, src1_type) ||
> +  types_are_mixed_float(src0_type, dst_type) ||
> +  types_are_mixed_float(src1_type, dst_type);
> +}
> +
>  /**
>   * Checks restrictions listed in "General Restrictions Based on Operand 
> Types"
>   * in the "Register Region Restrictions" section.
> @@ -539,7 +599,100 @@ general_restrictions_based_on_operand_types(const 
> struct gen_device_info *devinf
> exec_type_size == 8 && dst_type_size == 4)
>dst_type_size = 8;
>  
> -   if (exec_type_size > dst_type_size) {
> +   if (is_half_float_conversion(devinfo, inst)) {
> +  /**
> +   * A helper to validate used in the validation of the following 
> restriction
> +   * from the BDW+ PRM, Volume 2a, Command Reference, Instructions - MOV:
> +   *
> +   *"There is no direct conversion from HF to DF or DF to HF.
> +   * There is no direct conversion from HF to Q/UQ or Q/UQ to HF."
> +   *
> +   * Even if these restrictions are listed for the MOV instruction, we
> +   * validate this more generally, since there is the possibility
> +   * of implicit conversions from other instructions, such us implicit
> +   * conversion from integer to HF with the ADD instruction in SKL+.
> +   */
> +  enum brw_reg_type src0_type = brw_inst_src0_type(devinfo, inst);
> +  enum brw_reg_type src1_type = num_sources > 1 ?
> +brw_inst_src1_type(devinfo, inst) : 0;
> +  ERROR_IF(dst_type == BRW_REGISTER_TYPE_HF &&
> +   (type_sz(src0_type) == 8 ||
> +(num_sources > 1 && type_sz(src1_type) == 8)),
> +   "There are no direct conversions between 64-bit types and 
> HF");
> +
> +  ERROR_IF(type_sz(dst_type) == 8 &&
> +   (src0_type == BRW_REGISTER_TYPE_HF ||
> +(num_sources > 1 && src1_type == BRW_REGISTER_TYPE_HF)),
> +   

[Mesa-dev] [PATCH v6 30/35] intel/compiler: validate region restrictions for half-float conversions

2019-04-03 Thread Juan A. Suarez Romero
From: Iago Toral Quiroga 

v2:
 - Consider implicit conversions in 2-src instructions too (Curro)
 - For restrictions that involve destination stride requirements
   only validate them for Align1, since Align16 always requires
   packed data.
 - Skip general rule for the dst/execution type size ratio for
   mixed float instructions on CHV and SKL+, these have their own
   set of rules that we'll be validated separately.

v3 (Curro):
 - Do not check src1 type in single-source instructions.
 - Check restriction on src1.
 - Remove invalid test.
---
 src/intel/compiler/brw_eu_validate.c| 155 +++-
 src/intel/compiler/test_eu_validate.cpp | 116 ++
 2 files changed, 270 insertions(+), 1 deletion(-)

diff --git a/src/intel/compiler/brw_eu_validate.c 
b/src/intel/compiler/brw_eu_validate.c
index bd0e48a5e5c..54bffb3af03 100644
--- a/src/intel/compiler/brw_eu_validate.c
+++ b/src/intel/compiler/brw_eu_validate.c
@@ -469,6 +469,66 @@ is_packed(unsigned vstride, unsigned width, unsigned 
hstride)
return false;
 }
 
+/**
+ * Returns whether an instruction is an explicit or implicit conversion
+ * to/from half-float.
+ */
+static bool
+is_half_float_conversion(const struct gen_device_info *devinfo,
+ const brw_inst *inst)
+{
+   enum brw_reg_type dst_type = brw_inst_dst_type(devinfo, inst);
+
+   unsigned num_sources = num_sources_from_inst(devinfo, inst);
+   enum brw_reg_type src0_type = brw_inst_src0_type(devinfo, inst);
+
+   if (dst_type != src0_type &&
+   (dst_type == BRW_REGISTER_TYPE_HF || src0_type == 
BRW_REGISTER_TYPE_HF)) {
+  return true;
+   } else if (num_sources > 1) {
+  enum brw_reg_type src1_type = brw_inst_src1_type(devinfo, inst);
+  return dst_type != src1_type &&
+(dst_type == BRW_REGISTER_TYPE_HF ||
+ src1_type == BRW_REGISTER_TYPE_HF);
+   }
+
+   return false;
+}
+
+/*
+ * Returns whether an instruction is using mixed float operation mode
+ */
+static bool
+is_mixed_float(const struct gen_device_info *devinfo, const brw_inst *inst)
+{
+   if (devinfo->gen < 8)
+  return false;
+
+   if (inst_is_send(devinfo, inst))
+  return false;
+
+   unsigned opcode = brw_inst_opcode(devinfo, inst);
+   const struct opcode_desc *desc = brw_opcode_desc(devinfo, opcode);
+   if (desc->ndst == 0)
+  return false;
+
+   /* FIXME: support 3-src instructions */
+   unsigned num_sources = num_sources_from_inst(devinfo, inst);
+   assert(num_sources < 3);
+
+   enum brw_reg_type dst_type = brw_inst_dst_type(devinfo, inst);
+   enum brw_reg_type src0_type = brw_inst_src0_type(devinfo, inst);
+
+   if (num_sources == 1)
+  return types_are_mixed_float(src0_type, dst_type);
+
+   enum brw_reg_type src1_type = brw_inst_src1_type(devinfo, inst);
+
+   return types_are_mixed_float(src0_type, src1_type) ||
+  types_are_mixed_float(src0_type, dst_type) ||
+  types_are_mixed_float(src1_type, dst_type);
+}
+
 /**
  * Checks restrictions listed in "General Restrictions Based on Operand Types"
  * in the "Register Region Restrictions" section.
@@ -539,7 +599,100 @@ general_restrictions_based_on_operand_types(const struct 
gen_device_info *devinf
exec_type_size == 8 && dst_type_size == 4)
   dst_type_size = 8;
 
-   if (exec_type_size > dst_type_size) {
+   if (is_half_float_conversion(devinfo, inst)) {
+  /**
+   * A helper to validate used in the validation of the following 
restriction
+   * from the BDW+ PRM, Volume 2a, Command Reference, Instructions - MOV:
+   *
+   *"There is no direct conversion from HF to DF or DF to HF.
+   * There is no direct conversion from HF to Q/UQ or Q/UQ to HF."
+   *
+   * Even if these restrictions are listed for the MOV instruction, we
+   * validate this more generally, since there is the possibility
+   * of implicit conversions from other instructions, such us implicit
+   * conversion from integer to HF with the ADD instruction in SKL+.
+   */
+  enum brw_reg_type src0_type = brw_inst_src0_type(devinfo, inst);
+  enum brw_reg_type src1_type = num_sources > 1 ?
+brw_inst_src1_type(devinfo, inst) : 0;
+  ERROR_IF(dst_type == BRW_REGISTER_TYPE_HF &&
+   (type_sz(src0_type) == 8 ||
+(num_sources > 1 && type_sz(src1_type) == 8)),
+   "There are no direct conversions between 64-bit types and HF");
+
+  ERROR_IF(type_sz(dst_type) == 8 &&
+   (src0_type == BRW_REGISTER_TYPE_HF ||
+(num_sources > 1 && src1_type == BRW_REGISTER_TYPE_HF)),
+   "There are no direct conversions between 64-bit types and HF");
+
+  /* From the BDW+ PRM:
+   *
+   *   "Conversion between Integer and HF (Half Float) must be
+   *DWord-aligned and strided by a DWord on the destination."
+   *
+   * Also, the above restrictions seems to be expanded on CHV and