@@ -1546,6 +1546,19 @@ static void ir_match_fuse_load_cmp_int(ir_ctx *ctx, ir_insn *insn, ir_ref root)
15461546 }
15471547}
15481548
1549+ static void ir_match_fuse_load_test_int(ir_ctx *ctx, ir_insn *insn, ir_ref root)
1550+ {
1551+ if (IR_IS_CONST_REF(insn->op2)) {
1552+ if (!IR_IS_SYM_CONST(ctx->ir_base[insn->op2].op)
1553+ && (ir_type_size[insn->type] != 8 || IR_IS_32BIT(ctx->ir_base[insn->op2].type, ctx->ir_base[insn->op2].val))) {
1554+ ir_match_fuse_load(ctx, insn->op1, root);
1555+ }
1556+ } else if (!ir_match_try_fuse_load(ctx, insn->op2, root)
1557+ && ir_match_try_fuse_load(ctx, insn->op1, root)) {
1558+ ir_swap_ops(insn);
1559+ }
1560+ }
1561+
15491562static void ir_match_fuse_load_cmp_fp(ir_ctx *ctx, ir_insn *insn, ir_ref root)
15501563{
15511564 if (insn->op != IR_EQ && insn->op != IR_NE) {
@@ -1621,7 +1634,7 @@ static uint32_t ir_match_insn(ir_ctx *ctx, ir_ref ref)
16211634
16221635 if (op1_insn->op == IR_AND && ctx->use_lists[insn->op1].count == 1) {
16231636 /* v = AND(_, _); CMP(v, 0) => SKIP_TEST; TEST */
1624- ir_match_fuse_load_cmp_int (ctx, op1_insn, ref);
1637+ ir_match_fuse_load_test_int (ctx, op1_insn, ref);
16251638 ctx->rules[insn->op1] = IR_FUSED | IR_TEST_INT;
16261639 return IR_TESTCC_INT;
16271640 } else if ((op1_insn->op == IR_OR || op1_insn->op == IR_AND || op1_insn->op == IR_XOR) ||
@@ -2242,7 +2255,7 @@ store_int:
22422255
22432256 if (op1_insn->op == IR_AND && ctx->use_lists[op2_insn->op1].count == 1) {
22442257 /* v = AND(_, _); c = CMP(v, 0) ... IF(c) => SKIP_TEST; SKIP ... TEST_AND_BRANCH */
2245- ir_match_fuse_load_cmp_int (ctx, op1_insn, ref);
2258+ ir_match_fuse_load_test_int (ctx, op1_insn, ref);
22462259 ctx->rules[op2_insn->op1] = IR_FUSED | IR_TEST_INT;
22472260 ctx->rules[insn->op2] = IR_FUSED | IR_SIMPLE | IR_NOP;
22482261 return IR_TEST_AND_BRANCH_INT;
@@ -2273,7 +2286,7 @@ store_int:
22732286 }
22742287 } else if (op2_insn->op == IR_AND) {
22752288 /* c = AND(_, _) ... IF(c) => SKIP_TEST ... TEST_AND_BRANCH */
2276- ir_match_fuse_load_cmp_int (ctx, op2_insn, ref);
2289+ ir_match_fuse_load_test_int (ctx, op2_insn, ref);
22772290 ctx->rules[insn->op2] = IR_FUSED | IR_TEST_INT;
22782291 return IR_TEST_AND_BRANCH_INT;
22792292 } else if (op2_insn->op == IR_OVERFLOW) {
@@ -2443,7 +2456,7 @@ store_int:
24432456 }
24442457 } else if (op2_insn->op == IR_AND) { // TODO: OR, XOR. etc
24452458 /* c = AND(_, _) ... GUARD(c) => SKIP_TEST ... GUARD_TEST */
2446- ir_match_fuse_load_cmp_int (ctx, op2_insn, ref);
2459+ ir_match_fuse_load_test_int (ctx, op2_insn, ref);
24472460 ctx->rules[insn->op2] = IR_FUSED | IR_TEST_INT;
24482461 return IR_GUARD_TEST_INT;
24492462 } else if (op2_insn->op == IR_OVERFLOW) {
0 commit comments