From: Wolfgang Bumiller Date: Sat, 22 Dec 2012 19:05:15 +0000 (+0100) Subject: fix -fshort-logic to cast to true boolean values X-Git-Tag: 0.2~12^2~3 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=eb952f11998adc144e7fa558619a2920e68f0265;p=xonotic%2Fgmqcc.git fix -fshort-logic to cast to true boolean values --- diff --git a/ast.c b/ast.c index 2eb9faa..5dc131e 100644 --- a/ast.c +++ b/ast.c @@ -1699,7 +1699,7 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va return true; } - if (OPTS_FLAG(SHORT_LOGIC) && + if ((OPTS_FLAG(SHORT_LOGIC) || OPTS_FLAG(PERL_LOGIC)) && (self->op == INSTR_AND || self->op == INSTR_OR)) { /* short circuit evaluation */ @@ -1750,12 +1750,50 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va vec_push(func->ir_func->blocks, merge); func->curblock = merge; - phi = ir_block_create_phi(func->curblock, ast_ctx(self), ast_function_label(func, "sce_value"), TYPE_FLOAT); + phi = ir_block_create_phi(func->curblock, ast_ctx(self), + ast_function_label(func, "sce_value"), + self->expression.vtype); ir_phi_add(phi, from_left, left); ir_phi_add(phi, from_right, right); *out = ir_phi_value(phi); if (!*out) return false; + + if (!OPTS_FLAG(PERL_LOGIC)) { + /* cast-to-bool */ + if (OPTS_FLAG(CORRECT_LOGIC) && (*out)->vtype == TYPE_VECTOR) { + *out = ir_block_create_unary(func->curblock, ast_ctx(self), + ast_function_label(func, "sce_bool_v"), + INSTR_NOT_V, *out); + if (!*out) + return false; + *out = ir_block_create_unary(func->curblock, ast_ctx(self), + ast_function_label(func, "sce_bool"), + INSTR_NOT_F, *out); + if (!*out) + return false; + } + else if (OPTS_FLAG(FALSE_EMPTY_STRINGS) && (*out)->vtype == TYPE_STRING) { + *out = ir_block_create_unary(func->curblock, ast_ctx(self), + ast_function_label(func, "sce_bool_s"), + INSTR_NOT_S, *out); + if (!*out) + return false; + *out = ir_block_create_unary(func->curblock, ast_ctx(self), + ast_function_label(func, "sce_bool"), + INSTR_NOT_F, *out); + if (!*out) + return false; + } + else { + *out = ir_block_create_binop(func->curblock, ast_ctx(self), + ast_function_label(func, "sce_bool"), + INSTR_AND, *out, *out); + if (!*out) + return false; + } + } + self->expression.outr = *out; return true; } diff --git a/tests/correct-vs-short-1.tmpl b/tests/correct-vs-short-1.tmpl new file mode 100644 index 0000000..9a2ac9b --- /dev/null +++ b/tests/correct-vs-short-1.tmpl @@ -0,0 +1,14 @@ +I: correct-vs-short.qc +D: correct-logic vs short-logic without perl-logic +T: -execute +C: -std=fteqcc +M: X & | B +M: 0 0 0, 0 0 0 :: 0 0 0 +M: 0 0 0, 5 0 0 :: 0 2 1 +M: 5 0 0, 0 0 0 :: 0 2 1 +M: 5 0 0, 5 0 0 :: 2 2 2 +M: Y & | B +M: 0 0 0, 0 0 0 :: 0 0 0 +M: 0 0 0, 0 5 0 :: 0 0 0 +M: 0 5 0, 0 0 0 :: 0 0 0 +M: 0 5 0, 0 5 0 :: 0 0 0 diff --git a/tests/correct-vs-short-2.tmpl b/tests/correct-vs-short-2.tmpl new file mode 100644 index 0000000..09897e5 --- /dev/null +++ b/tests/correct-vs-short-2.tmpl @@ -0,0 +1,14 @@ +I: correct-vs-short.qc +D: correct-logic vs short-logic without perl-logic +T: -execute +C: -std=fteqcc -fcorrect-logic +M: X & | B +M: 0 0 0, 0 0 0 :: 0 0 0 +M: 0 0 0, 5 0 0 :: 0 2 1 +M: 5 0 0, 0 0 0 :: 0 2 1 +M: 5 0 0, 5 0 0 :: 2 2 2 +M: Y & | B +M: 0 0 0, 0 0 0 :: 0 0 0 +M: 0 0 0, 0 5 0 :: 0 2 1 +M: 0 5 0, 0 0 0 :: 0 2 1 +M: 0 5 0, 0 5 0 :: 2 2 2 diff --git a/tests/correct-vs-short-3.tmpl b/tests/correct-vs-short-3.tmpl new file mode 100644 index 0000000..787ae22 --- /dev/null +++ b/tests/correct-vs-short-3.tmpl @@ -0,0 +1,14 @@ +I: correct-vs-short.qc +D: correct-logic vs short-logic without perl-logic +T: -execute +C: -std=fteqcc -fcorrect-logic -fshort-logic +M: X & | B +M: 0 0 0, 0 0 0 :: 0 0 0 +M: 0 0 0, 5 0 0 :: 0 2 1 +M: 5 0 0, 0 0 0 :: 0 2 1 +M: 5 0 0, 5 0 0 :: 2 2 2 +M: Y & | B +M: 0 0 0, 0 0 0 :: 0 0 0 +M: 0 0 0, 0 5 0 :: 0 2 1 +M: 0 5 0, 0 0 0 :: 0 2 1 +M: 0 5 0, 0 5 0 :: 2 2 2 diff --git a/tests/correct-vs-short.qc b/tests/correct-vs-short.qc new file mode 100644 index 0000000..81f9b7a --- /dev/null +++ b/tests/correct-vs-short.qc @@ -0,0 +1,21 @@ +void print(...) = #1; +string ftos (float) = #2; + +void test(vector a, vector b) { + print(ftos((a && b) + (a && b)), " "); + print(ftos((a || b) + (a || b)), " "); + print(ftos((a && b) + (a || b)), "\n"); +} + +void main() { + print("X & | B\n"); + print("0 0 0, 0 0 0 :: "); test('0 0 0', '0 0 0'); + print("0 0 0, 5 0 0 :: "); test('0 0 0', '5 0 0'); + print("5 0 0, 0 0 0 :: "); test('5 0 0', '0 0 0'); + print("5 0 0, 5 0 0 :: "); test('5 0 0', '5 0 0'); + print("Y & | B\n"); + print("0 0 0, 0 0 0 :: "); test('0 0 0', '0 0 0'); + print("0 0 0, 0 5 0 :: "); test('0 0 0', '0 5 0'); + print("0 5 0, 0 0 0 :: "); test('0 5 0', '0 0 0'); + print("0 5 0, 0 5 0 :: "); test('0 5 0', '0 5 0'); +}