aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrancisco Jerez <[email protected]>2019-01-15 13:35:30 -0800
committerFrancisco Jerez <[email protected]>2019-01-18 16:09:39 -0800
commitc84ec70b3a72a3640a40e72689d72da8337e9801 (patch)
tree842792ff9255ecbfaa6473e4504c05baadbbb235
parent9e669ed22b52857495593b92537d53c9ead7d424 (diff)
intel/fs: Promote execution type to 32-bit when any half-float conversion is needed.
The docs are fairly incomplete and inconsistent about it, but this seems to be the reason why half-float destinations are required to be DWORD-aligned on BDW+ projects. This way the regioning lowering pass will make sure that the destination components of W to HF and HF to W conversions are aligned like the corresponding conversion operation with 32-bit execution data type. Tested-by: Iago Toral Quiroga <[email protected]> Reviewed-by: Iago Toral Quiroga <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]>
-rw-r--r--src/intel/compiler/brw_ir_fs.h21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/intel/compiler/brw_ir_fs.h b/src/intel/compiler/brw_ir_fs.h
index 3c23fb375e4..08e3d83d910 100644
--- a/src/intel/compiler/brw_ir_fs.h
+++ b/src/intel/compiler/brw_ir_fs.h
@@ -477,6 +477,27 @@ get_exec_type(const fs_inst *inst)
assert(exec_type != BRW_REGISTER_TYPE_B);
+ /* Promotion of the execution type to 32-bit for conversions from or to
+ * half-float seems to be consistent with the following text from the
+ * Cherryview PRM Vol. 7, "Execution Data Type":
+ *
+ * "When single precision and half precision floats are mixed between
+ * source operands or between source and destination operand [..] single
+ * precision float is the execution datatype."
+ *
+ * and from "Register Region Restrictions":
+ *
+ * "Conversion between Integer and HF (Half Float) must be DWord aligned
+ * and strided by a DWord on the destination."
+ */
+ if (type_sz(exec_type) == 2 &&
+ inst->dst.type != exec_type) {
+ if (exec_type == BRW_REGISTER_TYPE_HF)
+ exec_type = BRW_REGISTER_TYPE_F;
+ else if (inst->dst.type == BRW_REGISTER_TYPE_HF)
+ exec_type = BRW_REGISTER_TYPE_D;
+ }
+
return exec_type;
}