mirror of
https://github.com/danog/ir.git
synced 2024-12-02 09:38:29 +01:00
Fix impossible load fusion
This commit is contained in:
parent
009e9c4a53
commit
ffac404552
15
ir_x86.dasc
15
ir_x86.dasc
@ -1381,8 +1381,7 @@ store_int:
|
||||
&& (ctx->use_lists[insn->op3].count == 1 ||
|
||||
(ctx->use_lists[insn->op3].count == 2
|
||||
&& (ctx->ir_base[insn->op3].op == IR_ADD_OV ||
|
||||
ctx->ir_base[insn->op3].op == IR_SUB_OV)))
|
||||
&& IR_IS_TYPE_INT(ctx->ir_base[insn->op3].type)) {
|
||||
ctx->ir_base[insn->op3].op == IR_SUB_OV)))) {
|
||||
ir_insn *op_insn = &ctx->ir_base[insn->op3];
|
||||
uint32_t rule = ctx->rules[insn->op3];
|
||||
|
||||
@ -1397,6 +1396,10 @@ store_int:
|
||||
/* l = LOAD(_, a) ... v = BINOP(l, _) ... STORE(l, a, v) => SKIP ... SKIP_MEM_BINOP ... MEM_BINOP */
|
||||
ctx->rules[insn->op3] = IR_FUSED | IR_BINOP_INT;
|
||||
ctx->rules[op_insn->op1] = IR_SKIPPED | load_op;
|
||||
if (ctx->ir_base[op_insn->op2].op == IR_LOAD) {
|
||||
ir_match_fuse_addr(ctx, ctx->ir_base[op_insn->op2].op2);
|
||||
ctx->rules[op_insn->op2] = IR_LOAD_INT;
|
||||
}
|
||||
ir_match_fuse_addr(ctx, insn->op2);
|
||||
return IR_MEM_BINOP_INT;
|
||||
} else if ((ir_op_flags[op_insn->op] & IR_OP_FLAG_COMMUTATIVE)
|
||||
@ -1408,6 +1411,10 @@ store_int:
|
||||
ir_swap_ops(op_insn);
|
||||
ctx->rules[insn->op3] = IR_FUSED | IR_BINOP_INT;
|
||||
ctx->rules[op_insn->op1] = IR_SKIPPED | load_op;
|
||||
if (ctx->ir_base[op_insn->op2].op == IR_LOAD) {
|
||||
ir_match_fuse_addr(ctx, ctx->ir_base[op_insn->op2].op2);
|
||||
ctx->rules[op_insn->op2] = IR_LOAD_INT;
|
||||
}
|
||||
ir_match_fuse_addr(ctx, insn->op2);
|
||||
return IR_MEM_BINOP_INT;
|
||||
}
|
||||
@ -1469,6 +1476,10 @@ store_int:
|
||||
/* l = LOAD(_, a) ... v = SHIFT(l, _) ... STORE(l, a, v) => SKIP ... SKIP_SHIFT ... MEM_SHIFT */
|
||||
ctx->rules[insn->op3] = IR_FUSED | IR_SHIFT;
|
||||
ctx->rules[op_insn->op1] = IR_SKIPPED | load_op;
|
||||
if (ctx->ir_base[op_insn->op2].op == IR_LOAD) {
|
||||
ir_match_fuse_addr(ctx, ctx->ir_base[op_insn->op2].op2);
|
||||
ctx->rules[op_insn->op2] = IR_LOAD_INT;
|
||||
}
|
||||
return IR_MEM_SHIFT;
|
||||
}
|
||||
} else if (rule == IR_SHIFT_CONST) {
|
||||
|
22
tests/debug/memop_009.irt
Normal file
22
tests/debug/memop_009.irt
Normal file
@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
009: Memory update (binary op with mem)
|
||||
--TARGET--
|
||||
x86_64
|
||||
--ARGS--
|
||||
-S
|
||||
--CODE--
|
||||
{
|
||||
l_1 = START(l_5);
|
||||
uintptr_t y = PARAM(l_1, "x", 1);
|
||||
uintptr_t x = PARAM(l_1, "y", 2);
|
||||
int32_t y2, l_2 = LOAD(l_1, y);
|
||||
int32_t x2, l_3 = LOAD(l_2, x);
|
||||
int32_t ret = SUB(x2, y2);
|
||||
l_4 = STORE(l_3, x, ret);
|
||||
l_5 = RETURN(l_4);
|
||||
}
|
||||
--EXPECT--
|
||||
test:
|
||||
movl (%rdi), %eax
|
||||
subl %eax, (%rsi)
|
||||
retq
|
22
tests/debug/memop_010.irt
Normal file
22
tests/debug/memop_010.irt
Normal file
@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
010: Memory update (shift with mem)
|
||||
--TARGET--
|
||||
x86_64
|
||||
--ARGS--
|
||||
-S
|
||||
--CODE--
|
||||
{
|
||||
l_1 = START(l_5);
|
||||
uintptr_t y = PARAM(l_1, "x", 1);
|
||||
uintptr_t x = PARAM(l_1, "y", 2);
|
||||
int32_t y2, l_2 = LOAD(l_1, y);
|
||||
int32_t x2, l_3 = LOAD(l_2, x);
|
||||
int32_t ret = SHL(x2, y2);
|
||||
l_4 = STORE(l_3, x, ret);
|
||||
l_5 = RETURN(l_4);
|
||||
}
|
||||
--EXPECT--
|
||||
test:
|
||||
movl (%rdi), %ecx
|
||||
shll %cl, (%rsi)
|
||||
retq
|
Loading…
Reference in New Issue
Block a user