@@ -1546,6 +1546,19 @@ static void ir_match_fuse_load_cmp_int(ir_ctx *ctx, ir_insn *insn, ir_ref root)
1546
1546
}
1547
1547
}
1548
1548
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
+
1549
1562
static void ir_match_fuse_load_cmp_fp(ir_ctx *ctx, ir_insn *insn, ir_ref root)
1550
1563
{
1551
1564
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)
1621
1634
1622
1635
if (op1_insn->op == IR_AND && ctx->use_lists[insn->op1].count == 1) {
1623
1636
/* 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);
1625
1638
ctx->rules[insn->op1] = IR_FUSED | IR_TEST_INT;
1626
1639
return IR_TESTCC_INT;
1627
1640
} else if ((op1_insn->op == IR_OR || op1_insn->op == IR_AND || op1_insn->op == IR_XOR) ||
@@ -2242,7 +2255,7 @@ store_int:
2242
2255
2243
2256
if (op1_insn->op == IR_AND && ctx->use_lists[op2_insn->op1].count == 1) {
2244
2257
/* 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);
2246
2259
ctx->rules[op2_insn->op1] = IR_FUSED | IR_TEST_INT;
2247
2260
ctx->rules[insn->op2] = IR_FUSED | IR_SIMPLE | IR_NOP;
2248
2261
return IR_TEST_AND_BRANCH_INT;
@@ -2273,7 +2286,7 @@ store_int:
2273
2286
}
2274
2287
} else if (op2_insn->op == IR_AND) {
2275
2288
/* 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);
2277
2290
ctx->rules[insn->op2] = IR_FUSED | IR_TEST_INT;
2278
2291
return IR_TEST_AND_BRANCH_INT;
2279
2292
} else if (op2_insn->op == IR_OVERFLOW) {
@@ -2443,7 +2456,7 @@ store_int:
2443
2456
}
2444
2457
} else if (op2_insn->op == IR_AND) { // TODO: OR, XOR. etc
2445
2458
/* 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);
2447
2460
ctx->rules[insn->op2] = IR_FUSED | IR_TEST_INT;
2448
2461
return IR_GUARD_TEST_INT;
2449
2462
} else if (op2_insn->op == IR_OVERFLOW) {
0 commit comments