diff mbox series

[v2,17/48] tcg/optimize: Split out fold_brcond2

Message ID 20211007195456.1168070-18-richard.henderson@linaro.org
State New
Headers show
Series tcg: optimize redundant sign extensions | expand

Commit Message

Richard Henderson Oct. 7, 2021, 7:54 p.m. UTC
Reduce some code duplication by folding the NE and EQ cases.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/optimize.c | 161 +++++++++++++++++++++++++------------------------
 1 file changed, 83 insertions(+), 78 deletions(-)

Comments

Luis Fernando Fujita Pires Oct. 20, 2021, 10:27 p.m. UTC | #1
From: Richard Henderson <richard.henderson@linaro.org>
> Reduce some code duplication by folding the NE and EQ cases.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  tcg/optimize.c | 161 +++++++++++++++++++++++++------------------------
>  1 file changed, 83 insertions(+), 78 deletions(-)

> +    case TCG_COND_NE:
> +        inv = 1;
> +        QEMU_FALLTHROUGH;
> +    case TCG_COND_EQ:
> +        /*
> +         * Simplify EQ/NE comparisons where one of the pairs
> +         * can be simplified.
> +         */
> +        i = do_constant_folding_cond(INDEX_op_brcond_i32, op->args[0],
> +                                     op->args[2], cond);
> +        switch (i ^ inv) {
> +        case 0:
> +            goto do_brcond_false;

I believe this should go to do_brcond_true when cond==TCG_COND_NE.

> +        i = do_constant_folding_cond(INDEX_op_brcond_i32, op->args[1],
> +                                     op->args[3], cond);
> +        switch (i ^ inv) {
> +        case 0:
> +            goto do_brcond_false;

Same here.

--
Luis Pires
Instituto de Pesquisas ELDORADO
Aviso Legal - Disclaimer <https://www.eldorado.org.br/disclaimer.html>
Richard Henderson Oct. 21, 2021, 2:32 a.m. UTC | #2
On 10/20/21 3:27 PM, Luis Fernando Fujita Pires wrote:
> From: Richard Henderson <richard.henderson@linaro.org>
>> Reduce some code duplication by folding the NE and EQ cases.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>>   tcg/optimize.c | 161 +++++++++++++++++++++++++------------------------
>>   1 file changed, 83 insertions(+), 78 deletions(-)
> 
>> +    case TCG_COND_NE:
>> +        inv = 1;
>> +        QEMU_FALLTHROUGH;
>> +    case TCG_COND_EQ:
>> +        /*
>> +         * Simplify EQ/NE comparisons where one of the pairs
>> +         * can be simplified.
>> +         */
>> +        i = do_constant_folding_cond(INDEX_op_brcond_i32, op->args[0],
>> +                                     op->args[2], cond);
>> +        switch (i ^ inv) {
>> +        case 0:
>> +            goto do_brcond_false;
> 
> I believe this should go to do_brcond_true when cond==TCG_COND_NE.

Good eyes, thanks.
This needs to be more like setcond2, with do_brcond_const.

r~
diff mbox series

Patch

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 0eaa0127f3..266787957f 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -714,6 +714,86 @@  static bool fold_andc(OptContext *ctx, TCGOp *op)
     return fold_const2(ctx, op);
 }
 
+static bool fold_brcond2(OptContext *ctx, TCGOp *op)
+{
+    TCGCond cond = op->args[4];
+    int i = do_constant_folding_cond2(&op->args[0], &op->args[2], cond);
+    TCGArg label = op->args[5];
+    int inv = 0;
+
+    if (i == 0) {
+        goto do_brcond_false;
+    } else if (i > 0) {
+        goto do_brcond_true;
+    }
+
+    switch (cond) {
+    case TCG_COND_LT:
+    case TCG_COND_GE:
+        /*
+         * Simplify LT/GE comparisons vs zero to a single compare
+         * vs the high word of the input.
+         */
+        if (arg_is_const(op->args[2]) && arg_info(op->args[2])->val == 0 &&
+            arg_is_const(op->args[3]) && arg_info(op->args[3])->val == 0) {
+            goto do_brcond_high;
+        }
+        break;
+
+    case TCG_COND_NE:
+        inv = 1;
+        QEMU_FALLTHROUGH;
+    case TCG_COND_EQ:
+        /*
+         * Simplify EQ/NE comparisons where one of the pairs
+         * can be simplified.
+         */
+        i = do_constant_folding_cond(INDEX_op_brcond_i32, op->args[0],
+                                     op->args[2], cond);
+        switch (i ^ inv) {
+        case 0:
+            goto do_brcond_false;
+        case 1:
+            goto do_brcond_high;
+        }
+
+        i = do_constant_folding_cond(INDEX_op_brcond_i32, op->args[1],
+                                     op->args[3], cond);
+        switch (i ^ inv) {
+        case 0:
+            goto do_brcond_false;
+        case 1:
+            op->opc = INDEX_op_brcond_i32;
+            op->args[1] = op->args[2];
+            op->args[2] = cond;
+            op->args[3] = label;
+            break;
+        }
+        break;
+
+    default:
+        break;
+
+    do_brcond_true:
+        op->opc = INDEX_op_br;
+        op->args[0] = label;
+        break;
+
+    do_brcond_high:
+        op->opc = INDEX_op_brcond_i32;
+        op->args[0] = op->args[1];
+        op->args[1] = op->args[3];
+        op->args[2] = cond;
+        op->args[3] = label;
+        break;
+    }
+    return false;
+
+ do_brcond_false:
+    tcg_op_remove(ctx->tcg, op);
+    return true;
+}
+
 static bool fold_call(OptContext *ctx, TCGOp *op)
 {
     TCGContext *s = ctx->tcg;
@@ -1629,84 +1709,6 @@  void tcg_optimize(TCGContext *s)
             }
             break;
 
-        case INDEX_op_brcond2_i32:
-            i = do_constant_folding_cond2(&op->args[0], &op->args[2],
-                                          op->args[4]);
-            if (i == 0) {
-            do_brcond_false:
-                tcg_op_remove(s, op);
-                continue;
-            }
-            if (i > 0) {
-            do_brcond_true:
-                op->opc = opc = INDEX_op_br;
-                op->args[0] = op->args[5];
-                break;
-            }
-            if ((op->args[4] == TCG_COND_LT || op->args[4] == TCG_COND_GE)
-                 && arg_is_const(op->args[2])
-                 && arg_info(op->args[2])->val == 0
-                 && arg_is_const(op->args[3])
-                 && arg_info(op->args[3])->val == 0) {
-                /* Simplify LT/GE comparisons vs zero to a single compare
-                   vs the high word of the input.  */
-            do_brcond_high:
-                op->opc = opc = INDEX_op_brcond_i32;
-                op->args[0] = op->args[1];
-                op->args[1] = op->args[3];
-                op->args[2] = op->args[4];
-                op->args[3] = op->args[5];
-                break;
-            }
-            if (op->args[4] == TCG_COND_EQ) {
-                /* Simplify EQ comparisons where one of the pairs
-                   can be simplified.  */
-                i = do_constant_folding_cond(INDEX_op_brcond_i32,
-                                             op->args[0], op->args[2],
-                                             TCG_COND_EQ);
-                if (i == 0) {
-                    goto do_brcond_false;
-                } else if (i > 0) {
-                    goto do_brcond_high;
-                }
-                i = do_constant_folding_cond(INDEX_op_brcond_i32,
-                                             op->args[1], op->args[3],
-                                             TCG_COND_EQ);
-                if (i == 0) {
-                    goto do_brcond_false;
-                } else if (i < 0) {
-                    break;
-                }
-            do_brcond_low:
-                memset(&ctx.temps_used, 0, sizeof(ctx.temps_used));
-                op->opc = INDEX_op_brcond_i32;
-                op->args[1] = op->args[2];
-                op->args[2] = op->args[4];
-                op->args[3] = op->args[5];
-                break;
-            }
-            if (op->args[4] == TCG_COND_NE) {
-                /* Simplify NE comparisons where one of the pairs
-                   can be simplified.  */
-                i = do_constant_folding_cond(INDEX_op_brcond_i32,
-                                             op->args[0], op->args[2],
-                                             TCG_COND_NE);
-                if (i == 0) {
-                    goto do_brcond_high;
-                } else if (i > 0) {
-                    goto do_brcond_true;
-                }
-                i = do_constant_folding_cond(INDEX_op_brcond_i32,
-                                             op->args[1], op->args[3],
-                                             TCG_COND_NE);
-                if (i == 0) {
-                    goto do_brcond_low;
-                } else if (i > 0) {
-                    goto do_brcond_true;
-                }
-            }
-            break;
-
         default:
             break;
 
@@ -1722,6 +1724,9 @@  void tcg_optimize(TCGContext *s)
         CASE_OP_32_64_VEC(andc):
             done = fold_andc(&ctx, op);
             break;
+        case INDEX_op_brcond2_i32:
+            done = fold_brcond2(&ctx, op);
+            break;
         CASE_OP_32_64(ctpop):
             done = fold_ctpop(&ctx, op);
             break;