From 2303be5ff1b7a6d75af6a1d1513dae9c051be29b Mon Sep 17 00:00:00 2001 From: Andrii Simiklit Date: Thu, 7 May 2020 12:46:28 +0300 Subject: [PATCH] i965/vec4: Ignore swizzle of VGRF for use by var_range_end() Issue description from Matt's commit e7c376ad: "var_range_end(v, n) loops over the n components of variable number v and finds the maximum value, giving the last use of any component of v. Therefore it expects v to correspond to the variable associated with the .x channel of the VGRF. var_from_reg() however returns the variable for the first channel of the VGRF, post-swizzle. So, if the last register had a swizzle with y, z, or w in the swizzle component, we would read out of bounds. For any other register, we would read liveness information from the next register. The fix is to convert the src_reg to a dst_reg in order to call the dst_reg version of var_from_reg() that doesn't consider the swizzle." Closes: #3003 Fixes: 48dfb30f ('intel/compiler: Move all live interval analysis results into vec4_live_variables') Reviewed-by: Matt Turner Signed-off-by: Andrii Simiklit Part-of: (cherry picked from commit d1b746284985a34e61c315ba586c789c607ac3ba) --- .pick_status.json | 2 +- src/intel/compiler/brw_vec4_cse.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index f15622641ed..d7ed60c9a28 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -2362,7 +2362,7 @@ "description": "i965/vec4: Ignore swizzle of VGRF for use by var_range_end()", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "master_sha": null, "because_sha": "48dfb30f9231c22a6af6885dbc9ef86dc2edde1e" }, diff --git a/src/intel/compiler/brw_vec4_cse.cpp b/src/intel/compiler/brw_vec4_cse.cpp index 585676a9042..accc037af8d 100644 --- a/src/intel/compiler/brw_vec4_cse.cpp +++ b/src/intel/compiler/brw_vec4_cse.cpp @@ -288,7 +288,7 @@ vec4_visitor::opt_cse_local(bblock_t *block, const vec4_live_variables &live) * more -- a sure sign they'll fail operands_match(). */ if (src->file == VGRF) { - if (live.var_range_end(var_from_reg(alloc, *src), 8) < ip) { + if (live.var_range_end(var_from_reg(alloc, dst_reg(*src)), 8) < ip) { entry->remove(); ralloc_free(entry); break;