Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions target/i386/latx/optimization/hbr.c
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,20 @@ static void init_xmm_state(uint32_t xmm[XMM_NUM])
#include "tu.h"
typedef bool (*xmm_analyse_func)(TranslationBlock *, IR1_INST *, uint32_t *);

static bool tb_has_ymm_operand(TranslationBlock *tb)
{
for (int i = 0; i < tb_ir1_num(tb); ++i) {
IR1_INST *ir1 = tb_ir1_inst(tb, i);

for (int j = 0; j < ir1_get_opnd_num(ir1); ++j) {
if (ir1_opnd_is_ymm(ir1_get_opnd(ir1, j))) {
return true;
}
}
}
return false;
}

/* static int xcount, scount, ncount; */
static void tb_xmm_analyse(TranslationBlock *tb,
xmm_analyse_func analyse_func, uint32_t *xmm)
Expand All @@ -755,6 +769,23 @@ static void tb_xmm_analyse(TranslationBlock *tb,
tb->s_data->xmm_use = 0;
tb->s_data->xmm_def = 0;
IR1_INST *ir1 = NULL;

/*
* SHBR models the low 128-bit XMM value only. Optimizing an XMM
* instruction in a TB that also uses YMM can leave the upper half in a
* different physical register state across TU-internal entries. Keep all
* vector registers live and skip SHBR for these mixed-width TBs.
*/
if (tb_has_ymm_operand(tb)) {
tb->s_data->xmm_use = SHBR_XMM_ALL;
for (int i = 0; i < tb_ir1_num(tb); ++i) {
ir1 = tb_ir1_inst(tb, i);
ir1->xmm_def = 0;
ir1->xmm_use = 0;
}
return;
}

for (int i = 0; i < tb_ir1_num(tb); ++i) {
ir1 = tb_ir1_inst(tb, i);
ir1->xmm_def = 0;
Expand Down