1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Update IR

IR commit: dfd22749acb2a8cb7c728600e1d89f84cab4f99c

Fixes oss-fuzz #63548
This commit is contained in:
Dmitry Stogov
2023-10-25 08:31:13 +03:00
parent 4ae483af36
commit 1068a5f758
3 changed files with 78 additions and 55 deletions

View File

@@ -463,6 +463,22 @@ int ir_get_target_constraints(const ir_ctx *ctx, ir_ref ref, ir_target_constrain
}
flags = IR_USE_SHOULD_BE_IN_REG | IR_OP2_SHOULD_BE_IN_REG | IR_OP3_SHOULD_BE_IN_REG;
break;
case IR_COND:
insn = &ctx->ir_base[ref];
n = 0;
if (IR_IS_CONST_REF(insn->op1)) {
constraints->tmp_regs[n] = IR_TMP_REG(1, ctx->ir_base[insn->op1].type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
n++;
}
if (IR_IS_CONST_REF(insn->op2)) {
constraints->tmp_regs[n] = IR_TMP_REG(2, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
n++;
}
if (IR_IS_CONST_REF(insn->op3)) {
constraints->tmp_regs[n] = IR_TMP_REG(3, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
n++;
}
break;
case IR_COPY_INT:
case IR_COPY_FP:
flags = IR_DEF_REUSES_OP1_REG | IR_USE_MUST_BE_IN_REG;
@@ -2138,6 +2154,18 @@ static void ir_emit_cmp_fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
case IR_GT:
| cset Rw(def_reg), gt
break;
case IR_ULT:
| cset Rw(def_reg), lt
break;
case IR_UGE:
| cset Rw(def_reg), hs
break;
case IR_ULE:
| cset Rw(def_reg), le
break;
case IR_UGT:
| cset Rw(def_reg), hi
break;
}
if (IR_REG_SPILLED(ctx->regs[def][0])) {
ir_emit_store(ctx, insn->type, def, def_reg);
@@ -2212,7 +2240,11 @@ static void ir_emit_jcc(ir_ctx *ctx, uint8_t op, uint32_t b, ir_ref def, ir_insn
ir_get_true_false_blocks(ctx, b, &true_block, &false_block, &next_block);
if (true_block == next_block) {
/* swap to avoid unconditional JMP */
op ^= 1; // reverse
if (int_cmp || op == IR_EQ || op == IR_NE) {
op ^= 1; // reverse
} else {
op ^= 5; // reverse
}
true_block = false_block;
false_block = 0;
} else if (false_block == next_block) {
@@ -2276,6 +2308,18 @@ static void ir_emit_jcc(ir_ctx *ctx, uint8_t op, uint32_t b, ir_ref def, ir_insn
case IR_GT:
| bgt =>true_block
break;
case IR_ULT:
| blt =>true_block
break;
case IR_UGE:
| bhs =>true_block
break;
case IR_ULE:
| ble =>true_block
break;
case IR_UGT:
| bhi =>true_block
break;
// case IR_ULT: fprintf(stderr, "\tjb .LL%d\n", true_block); break;
// case IR_UGE: fprintf(stderr, "\tjae .LL%d\n", true_block); break;
// case IR_ULE: fprintf(stderr, "\tjbe .LL%d\n", true_block); break;
@@ -2421,15 +2465,15 @@ static void ir_emit_cond(ir_ctx *ctx, ir_ref def, ir_insn *insn)
if (IR_IS_TYPE_INT(type)) {
if (ir_type_size[type] == 8) {
| csel Rx(def_reg), Rx(op2_reg), Rx(op3_reg), eq
| csel Rx(def_reg), Rx(op2_reg), Rx(op3_reg), ne
} else {
| csel Rw(def_reg), Rw(op2_reg), Rw(op3_reg), eq
| csel Rw(def_reg), Rw(op2_reg), Rw(op3_reg), ne
}
} else{
if (type == IR_DOUBLE) {
| fcsel Rd(def_reg-IR_REG_FP_FIRST), Rd(op2_reg-IR_REG_FP_FIRST), Rd(op3_reg-IR_REG_FP_FIRST), eq
| fcsel Rd(def_reg-IR_REG_FP_FIRST), Rd(op2_reg-IR_REG_FP_FIRST), Rd(op3_reg-IR_REG_FP_FIRST), ne
} else {
| fcsel Rs(def_reg-IR_REG_FP_FIRST), Rs(op2_reg-IR_REG_FP_FIRST), Rs(op3_reg-IR_REG_FP_FIRST), eq
| fcsel Rs(def_reg-IR_REG_FP_FIRST), Rs(op2_reg-IR_REG_FP_FIRST), Rs(op3_reg-IR_REG_FP_FIRST), ne
}
}
@@ -3851,6 +3895,12 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
val_insn->const_flags |= IR_CONST_EMIT;
| adr Rx(dst_reg), =>label
continue;
} else if (val_insn->op == IR_SYM || val_insn->op == IR_FUNC) {
void *addr = (ctx->loader && ctx->loader->resolve_sym_name) ?
ctx->loader->resolve_sym_name(ctx->loader, ir_get_str(ctx, val_insn->val.i32)) :
ir_resolve_sym_name(ir_get_str(ctx, val_insn->val.i32));
ir_emit_load_imm_int(ctx, IR_ADDR, dst_reg, (intptr_t)addr);
continue;
}
IR_ASSERT(val_insn->op == IR_ADDR || val_insn->op == IR_FUNC_ADDR);
} else if (ir_type_size[type] == 1) {
@@ -3875,7 +3925,11 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
| adr Rx(tmp_reg), =>label
| str Rx(tmp_reg), [sp, #stack_offset]
} else if (val_insn->op == IR_FUNC || val_insn->op == IR_SYM) {
IR_ASSERT(0 && "sym");
void *addr = (ctx->loader && ctx->loader->resolve_sym_name) ?
ctx->loader->resolve_sym_name(ctx->loader, ir_get_str(ctx, val_insn->val.i32)) :
ir_resolve_sym_name(ir_get_str(ctx, val_insn->val.i32));
ir_emit_load_imm_int(ctx, IR_ADDR, tmp_reg, (intptr_t)addr);
| str Rx(tmp_reg), [sp, #stack_offset]
} else {
IR_ASSERT(tmp_reg != IR_REG_NONE);
ir_emit_load_imm_int(ctx, type, tmp_reg, val_insn->val.i64);

View File

@@ -1282,7 +1282,7 @@ IR_FOLD(SUB(_,NEG))
{
/* a + (-b) => a - b */
opt ^= 1; /* ADD <-> SUB */
op2 = op2_insn->op2;
op2 = op2_insn->op1;
IR_FOLD_RESTART;
}

View File

@@ -4088,17 +4088,17 @@ static void ir_emit_cmp_fp(ir_ctx *ctx, ir_ref def, ir_insn *insn)
| setb Rb(def_reg)
break;
case IR_UGE:
| setnp Rb(def_reg)
| mov Rd(tmp_reg), 0
| cmovb Rd(def_reg), Rd(tmp_reg)
| setp Rb(def_reg)
| mov Rd(tmp_reg), 1
| cmovae Rd(def_reg), Rd(tmp_reg)
break;
case IR_ULE:
| setbe Rb(def_reg)
break;
case IR_UGT:
| setnp Rb(def_reg)
| mov Rd(tmp_reg), 0
| cmovbe Rd(def_reg), Rd(tmp_reg)
| setp Rb(def_reg)
| mov Rd(tmp_reg), 1
| cmova Rd(def_reg), Rd(tmp_reg)
break;
}
if (IR_REG_SPILLED(ctx->regs[def][0])) {
@@ -4135,15 +4135,17 @@ static void ir_emit_jcc(ir_ctx *ctx, uint8_t op, uint32_t b, ir_ref def, ir_insn
uint32_t true_block, false_block, next_block;
ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state;
bool swap = 0;
ir_get_true_false_blocks(ctx, b, &true_block, &false_block, &next_block);
if (true_block == next_block) {
/* swap to avoid unconditional JMP */
op ^= 1; // reverse
if (int_cmp || op == IR_EQ || op == IR_NE) {
op ^= 1; // reverse
} else {
op ^= 5; // reverse
}
true_block = false_block;
false_block = 0;
swap = 1;
} else if (false_block == next_block) {
false_block = 0;
}
@@ -4202,9 +4204,7 @@ static void ir_emit_jcc(ir_ctx *ctx, uint8_t op, uint32_t b, ir_ref def, ir_insn
| jp =>true_block
break;
case IR_LT:
if (swap) {
| jb =>true_block
} else if (!false_block) {
if (!false_block) {
| jp >1
| jb =>true_block
|1:
@@ -4214,15 +4214,10 @@ static void ir_emit_jcc(ir_ctx *ctx, uint8_t op, uint32_t b, ir_ref def, ir_insn
}
break;
case IR_GE:
if (swap) {
| jp =>true_block
}
| jae =>true_block
break;
case IR_LE:
if (swap) {
| jbe =>true_block
} else if (!false_block) {
if (!false_block) {
| jp >1
| jbe =>true_block
|1:
@@ -4232,47 +4227,21 @@ static void ir_emit_jcc(ir_ctx *ctx, uint8_t op, uint32_t b, ir_ref def, ir_insn
}
break;
case IR_GT:
if (swap) {
| jp =>true_block
}
| ja =>true_block
break;
//
case IR_ULT:
if (swap) {
| jp =>true_block
}
| jb =>true_block
break;
case IR_UGE:
if (swap) {
| jae =>true_block
} else if (!false_block) {
| jp >1
| jae =>true_block
|1:
} else {
| jp =>false_block
| jae =>true_block
}
| jp =>true_block
| jae =>true_block
break;
case IR_ULE:
if (swap) {
| jp =>true_block
}
| jbe =>true_block
break;
case IR_UGT:
if (swap) {
| ja =>true_block
} else if (!false_block) {
| jp >1
| ja =>true_block
|1:
} else {
| jp =>false_block
| ja =>true_block
}
| jp =>true_block
| ja =>true_block
break;
}
}