diff --git a/ir_check.c b/ir_check.c index 3b42fdd..650b3ef 100644 --- a/ir_check.c +++ b/ir_check.c @@ -37,7 +37,7 @@ void ir_check(ir_ctx *ctx) { //TODO: ir_ref i, j, n, *p, use; - ir_insn *insn; + ir_insn *insn, *use_insn; uint32_t flags; bool ok = 1; @@ -57,12 +57,13 @@ void ir_check(ir_ctx *ctx) fprintf(stderr, "ir_base[%d].ops[%d] insn reference (%d) is out of range\n", i, j, use); ok = 0; } + use_insn = &ctx->ir_base[use]; switch (IR_OPND_KIND(flags, j)) { case IR_OPND_DATA: - if (ctx->ir_base[use].op == IR_VAR - || !(ir_op_flags[ctx->ir_base[use].op] & IR_OP_FLAG_DATA)) { - if (!(ir_op_flags[ctx->ir_base[use].op] & IR_OP_FLAG_MEM) - || ctx->ir_base[use].type == IR_VOID) { + if (use_insn->op == IR_VAR + || !(ir_op_flags[use_insn->op] & IR_OP_FLAG_DATA)) { + if (!(ir_op_flags[use_insn->op] & IR_OP_FLAG_MEM) + || use_insn->type == IR_VOID) { fprintf(stderr, "ir_base[%d].ops[%d] reference (%d) must be DATA\n", i, j, use); ok = 0; } @@ -72,15 +73,64 @@ void ir_check(ir_ctx *ctx) fprintf(stderr, "ir_base[%d].ops[%d] invalid forward reference (%d)\n", i, j, use); ok = 0; } + if (flags & IR_OP_FLAG_DATA) { + switch (insn->op) { + case IR_COND: + if (j == 1) { + break; + } + case IR_ADD: + case IR_SUB: + case IR_MUL: + case IR_DIV: + case IR_MOD: + case IR_NEG: + case IR_ABS: + case IR_ADD_OV: + case IR_SUB_OV: + case IR_MUL_OV: + case IR_NOT: + case IR_OR: + case IR_AND: + case IR_XOR: + case IR_SHL: + case IR_SHR: + case IR_SAR: + case IR_ROL: + case IR_ROR: + case IR_BSWAP: + case IR_MIN: + case IR_MAX: + case IR_PHI: + case IR_COPY: + case IR_PI: + if (insn->type != use_insn->type) { + if (j == 2 + && (insn->op == IR_SHL + || insn->op == IR_SHR + || insn->op == IR_SAR + || insn->op == IR_ROL + || insn->op == IR_ROR) + && ir_type_size[use_insn->type] < ir_type_size[insn->type]) { + /* second argument of SHIFT may be incompatible with result */ + break; + } + fprintf(stderr, "ir_base[%d].ops[%d] (%d) type is incompatible with result type (%d != %d)\n", + i, j, use, use_insn->type, insn->type); + ok = 0; + } + break; + } + } break; case IR_OPND_CONTROL: if (flags & IR_OP_FLAG_BB_START) { - if (!(ir_op_flags[ctx->ir_base[use].op] & IR_OP_FLAG_BB_END)) { + if (!(ir_op_flags[use_insn->op] & IR_OP_FLAG_BB_END)) { fprintf(stderr, "ir_base[%d].ops[%d] reference (%d) must be BB_END\n", i, j, use); ok = 0; } } else { - if (ir_op_flags[ctx->ir_base[use].op] & IR_OP_FLAG_BB_END) { + if (ir_op_flags[use_insn->op] & IR_OP_FLAG_BB_END) { fprintf(stderr, "ir_base[%d].ops[%d] reference (%d) must not be BB_END\n", i, j, use); ok = 0; } @@ -92,7 +142,7 @@ void ir_check(ir_ctx *ctx) ok = 0; } case IR_OPND_CONTROL_REF: - if (!(ir_op_flags[ctx->ir_base[use].op] & IR_OP_FLAG_CONTROL)) { + if (!(ir_op_flags[use_insn->op] & IR_OP_FLAG_CONTROL)) { fprintf(stderr, "ir_base[%d].ops[%d] reference (%d) must be CONTROL\n", i, j, use); ok = 0; } diff --git a/tests/010.irt b/tests/010.irt index 3410240..a288f6a 100644 --- a/tests/010.irt +++ b/tests/010.irt @@ -18,12 +18,12 @@ bool d_7 = NE(d_6, c_4); l_8 = IF(l_5, d_7); l_9 = IF_TRUE(l_8); - uint32_t d_10 = COPY(c_5); + int32_t d_10 = COPY(c_5); l_11 = END(l_9); l_12 = IF_FALSE(l_8); l_13 = END(l_12); l_14 = MERGE(l_11, l_13); - uint32_t d_15 = PHI(l_14, d_10, d_6); + int32_t d_15 = PHI(l_14, d_10, d_6); l_16 = IF(l_14, d_2); l_17 = IF_TRUE(l_16); l_18 = LOOP_END(l_17, l_5); diff --git a/tests/013.irt b/tests/013.irt index bbe479b..83fa8f9 100644 --- a/tests/013.irt +++ b/tests/013.irt @@ -11,7 +11,7 @@ int32_t c_5 = 2; l_1 = START(l_33); bool d_2 = PARAM(l_1, "cond", 0); - bool d_3 = PARAM(l_1, "z", 1); + int32_t d_3 = PARAM(l_1, "z", 1); bool d_4 = COPY(c_4); bool d_5 = COPY(d_3); l_6 = END(l_1); @@ -52,7 +52,7 @@ int32_t c_5 = 2; l_1 = START(l_29); bool d_2 = PARAM(l_1, "cond", 0); - bool d_3 = PARAM(l_1, "z", 1); + int32_t d_3 = PARAM(l_1, "z", 1); l_4 = END(l_1); l_5 = LOOP_BEGIN(l_4, l_27); NOP; diff --git a/tests/016.irt b/tests/016.irt index dab12da..74e42e2 100644 --- a/tests/016.irt +++ b/tests/016.irt @@ -18,12 +18,12 @@ bool d_7 = NE(d_6, c_4); l_8 = IF(l_5, d_7); l_9 = IF_TRUE(l_8); - uint32_t d_10 = COPY(c_5); + int32_t d_10 = COPY(c_5); l_11 = END(l_9); l_12 = IF_FALSE(l_8); l_13 = END(l_12); l_14 = MERGE(l_11, l_13); - uint32_t d_15 = PHI(l_14, d_10, d_6); + int32_t d_15 = PHI(l_14, d_10, d_6); l_16 = IF(l_14, d_2); l_17 = IF_TRUE(l_16); l_18 = LOOP_END(l_17, l_5); diff --git a/tests/019.irt b/tests/019.irt index 5d3a533..dabc3ef 100644 --- a/tests/019.irt +++ b/tests/019.irt @@ -9,7 +9,7 @@ int32_t c_5 = 2; l_1 = START(l_33); bool d_2 = PARAM(l_1, "cond", 0); - bool d_3 = PARAM(l_1, "z", 1); + int32_t d_3 = PARAM(l_1, "z", 1); bool d_4 = COPY(c_4); bool d_5 = COPY(d_3); l_6 = END(l_1); @@ -49,7 +49,7 @@ int32_t c_4 = 1; l_1 = START(l_10); bool d_2 = PARAM(l_1, "cond", 0); - bool d_3 = PARAM(l_1, "z", 1); + int32_t d_3 = PARAM(l_1, "z", 1); l_4 = END(l_1); l_5 = LOOP_BEGIN(l_4, l_8); l_6 = IF(l_5, d_2); diff --git a/tests/debug/combo_001.irt b/tests/debug/combo_001.irt index ca51566..a750176 100644 --- a/tests/debug/combo_001.irt +++ b/tests/debug/combo_001.irt @@ -22,12 +22,12 @@ x86_64 bool b = NE(x_1, i_1); ll_4 = IF(ll_3, b); ll_5 = IF_TRUE(ll_4); - uint32_t x_2 = COPY(i_2); + int32_t x_2 = COPY(i_2); ll_6 = END(ll_5); ll_7 = IF_FALSE(ll_4); ll_72 = END(ll_7); ll_8 = MERGE(ll_6, ll_72); - uint32_t x_3 = PHI(ll_8, x_2, x_1); + int32_t x_3 = PHI(ll_8, x_2, x_1); ll_10 = IF(ll_8, cond); ll_11 = IF_TRUE(ll_10); ll_12 = LOOP_END(ll_11, ll_3); diff --git a/tests/debug/combo_002.irt b/tests/debug/combo_002.irt index e2a8029..57b4a2b 100644 --- a/tests/debug/combo_002.irt +++ b/tests/debug/combo_002.irt @@ -14,7 +14,7 @@ x86_64 int32_t c_5 = 2; l_1 = START(l_33); bool d_2 = PARAM(l_1, "cond", 0); - bool d_3 = PARAM(l_1, "z", 1); + int32_t d_3 = PARAM(l_1, "z", 1); bool d_4 = COPY(c_4); bool d_5 = COPY(d_3); l_6 = END(l_1); diff --git a/tests/debug/combo_004.irt b/tests/debug/combo_004.irt index 497bc32..43f9b1e 100644 --- a/tests/debug/combo_004.irt +++ b/tests/debug/combo_004.irt @@ -22,12 +22,12 @@ x86_64 bool b = NE(x_1, i_1); ll_4 = IF(ll_3, b); ll_5 = IF_TRUE(ll_4); - uint32_t x_2 = COPY(i_2); + int32_t x_2 = COPY(i_2); ll_6 = END(ll_5); ll_7 = IF_FALSE(ll_4); ll_72 = END(ll_7); ll_8 = MERGE(ll_6, ll_72); - uint32_t x_3 = PHI(ll_8, x_2, x_1); + int32_t x_3 = PHI(ll_8, x_2, x_1); ll_10 = IF(ll_8, cond); ll_11 = IF_TRUE(ll_10); ll_12 = LOOP_END(ll_11, ll_3);