diff options
author | Francisco Jerez <[email protected]> | 2019-01-16 19:01:04 -0800 |
---|---|---|
committer | Francisco Jerez <[email protected]> | 2019-02-21 14:07:25 -0800 |
commit | e2f475ddffabff5cbe2bcff78ff42ce899869b29 (patch) | |
tree | 4863f8441d8a398fa2b72a798c0575563fa3db4b /src/intel/compiler | |
parent | c3c27762f787a93ee3f27189bef8d7cdcb3a6cab (diff) |
intel/fs: Lower integer multiply correctly when destination stride equals 4.
Because the "low" temporary needs to be accessed with word type and
twice the original stride, attempting to preserve the alignment of the
original destination can potentially lead to instructions with illegal
destination stride greater than four. Because the CHV/BXT alignment
restrictions are now being enforced by the regioning lowering pass run
after lower_integer_multiplication(), there is no real need to
preserve the original strides anymore.
Note that this bug can be reproduced on stable branches, but
back-porting would be non-trivial, because the fix relies on the
regioning lowering pass recently introduced.
Tested-by: Anuj Phogat <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src/intel/compiler')
-rw-r--r-- | src/intel/compiler/brw_fs.cpp | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/src/intel/compiler/brw_fs.cpp b/src/intel/compiler/brw_fs.cpp index 4a8f8ea5740..b4730c3d3e4 100644 --- a/src/intel/compiler/brw_fs.cpp +++ b/src/intel/compiler/brw_fs.cpp @@ -3996,18 +3996,22 @@ fs_visitor::lower_integer_multiplication() bool needs_mov = false; fs_reg orig_dst = inst->dst; + + /* Get a new VGRF for the "low" 32x16-bit multiplication result if + * reusing the original destination is impossible due to hardware + * restrictions, source/destination overlap, or it being the null + * register. + */ fs_reg low = inst->dst; if (orig_dst.is_null() || orig_dst.file == MRF || regions_overlap(inst->dst, inst->size_written, inst->src[0], inst->size_read(0)) || regions_overlap(inst->dst, inst->size_written, - inst->src[1], inst->size_read(1))) { + inst->src[1], inst->size_read(1)) || + inst->dst.stride >= 4) { needs_mov = true; - /* Get a new VGRF but keep the same stride as inst->dst */ low = fs_reg(VGRF, alloc.allocate(regs_written(inst)), inst->dst.type); - low.stride = inst->dst.stride; - low.offset = inst->dst.offset % REG_SIZE; } /* Get a new VGRF but keep the same stride as inst->dst */ |