agx: fix incorrect 16-bit promotions with comparisons
hardware seems to sign extend with a signed comparison, which I guess is reasonable! so our logic was busted if we had a zero-extend source with a signed comparison. this broke someone's OpenCL app, and could probably be hit from GLES/Vulkan too... on fossil-db, only parallel-rdp affected: Totals from 312 (0.58% of 53701) affected shaders: Instrs: 404772 -> 405697 (+0.23%); split: -0.01%, +0.24% CodeSize: 2863314 -> 2868998 (+0.20%); split: -0.01%, +0.21% Spills: 40239 -> 40286 (+0.12%); split: -0.02%, +0.14% Fills: 33763 -> 33810 (+0.14%); split: -0.03%, +0.17% ALU: 290757 -> 291071 (+0.11%); split: -0.02%, +0.13% FSCIB: 261844 -> 262652 (+0.31%); split: -0.02%, +0.33% IC: 230312 -> 230336 (+0.01%); split: -0.01%, +0.02% GPRs: 24656 -> 24648 (-0.03%); split: -0.05%, +0.02% Reported-by: RowanG Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35949>
This commit is contained in:
@@ -247,13 +247,30 @@ agx_optimizer_fmov_rev(agx_instr *I, agx_instr *use)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
agx_icond_is_unsigned(enum agx_icond cond)
|
||||
{
|
||||
switch (cond) {
|
||||
case AGX_ICOND_UEQ:
|
||||
case AGX_ICOND_ULT:
|
||||
case AGX_ICOND_UGT:
|
||||
return true;
|
||||
|
||||
case AGX_ICOND_SEQ:
|
||||
case AGX_ICOND_SLT:
|
||||
case AGX_ICOND_SGT:
|
||||
return false;
|
||||
}
|
||||
|
||||
unreachable("invalid condition");
|
||||
}
|
||||
|
||||
static bool
|
||||
agx_supports_zext(agx_instr *I, unsigned s)
|
||||
{
|
||||
switch (I->op) {
|
||||
case AGX_OPCODE_IADD:
|
||||
case AGX_OPCODE_IMAD:
|
||||
case AGX_OPCODE_ICMP:
|
||||
case AGX_OPCODE_INTL:
|
||||
case AGX_OPCODE_FFS:
|
||||
case AGX_OPCODE_BITREV:
|
||||
@@ -268,9 +285,15 @@ agx_supports_zext(agx_instr *I, unsigned s)
|
||||
case AGX_OPCODE_ICMP_BALLOT:
|
||||
case AGX_OPCODE_ICMP_QUAD_BALLOT:
|
||||
return true;
|
||||
|
||||
case AGX_OPCODE_ICMP:
|
||||
case AGX_OPCODE_ICMPSEL:
|
||||
/* Only the comparisons can be extended, not the selection */
|
||||
return s < 2;
|
||||
/* Only the comparisons can be extended, not the selection. And we can
|
||||
* only zero-extend with unsigned comparison. Presumably the hardware
|
||||
* sign-extends with signed comparisons but we don't handle that yet.
|
||||
*/
|
||||
return (s < 2) && agx_icond_is_unsigned(I->icond);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user