[PULL 24/38] tcg/optimize: Handle min/max opcodes
Richard Henderson <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
Reviewed-by: Alex Bennée <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Signed-off-by: Richard Henderson <[email protected]> --- tcg/optimize.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tcg/optimize.c b/tcg/optimize.c index facf4c1e0f..d291c844ca 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -597,6 +597,30 @@ static uint64_t do_constant_folding_2(TCGOpcode op, TCGType type, } return (uint64_t)x % ((uint64_t)y ? : 1); + case INDEX_op_smax: + if (type == TCG_TYPE_I32) { + return MAX((int32_t)x, (int32_t)y); + } + return MAX((int64_t)x, (int64_t)y); + + case INDEX_op_smin: + if (type == TCG_TYPE_I32) { + return MIN((int32_t)x, (int32_t)y); + } + return MIN((int64_t)x, (int64_t)y); + + case INDEX_op_umax: + if (type == TCG_TYPE_I32) { + return MAX((uint32_t)x, (uint32_t)y); + } + return MAX((uint64_t)x, (uint64_t)y); + + case INDEX_op_umin: + if (type == TCG_TYPE_I32) { + return MIN((uint32_t)x, (uint32_t)y); + } + return MIN((uint64_t)x, (uint64_t)y); + default: g_assert_not_reached(); } @@ -2101,6 +2125,16 @@ static bool fold_mb(OptContext *ctx, TCGOp *op) return true; } +static bool fold_minmax(OptContext *ctx, TCGOp *op, uint64_t bound) +{ + if (fold_const2_commutative(ctx, op) || + fold_xi_to_i(ctx, op, bound) || + fold_xx_to_x(ctx, op)) { + return true; + } + return finish_folding(ctx, op); +} + static bool fold_mov(OptContext *ctx, TCGOp *op) { return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]); @@ -3258,6 +3292,14 @@ void tcg_optimize(TCGContext *s) case INDEX_op_sextract: done = fold_sextract(&ctx, op); break; + case INDEX_op_smax: + done = fold_minmax(&ctx, op, (ctx.type == TCG_TYPE_I32 + ? INT32_MAX : INT64_MAX)); + break; + case INDEX_op_smin: + done = fold_minmax(&ctx, op, (ctx.type == TCG_TYPE_I32 + ? INT32_MIN : INT64_MIN)); + break; case INDEX_op_sub: done = fold_sub(&ctx, op); break; @@ -3273,6 +3315,16 @@ void tcg_optimize(TCGContext *s) case INDEX_op_sub_vec: done = fold_sub_vec(&ctx, op); break; + case INDEX_op_umax: + /* + * Note that 32-bit constants are stored sign extended, + * so (int32_t)UINT32_MAX == -1. + */ + done = fold_minmax(&ctx, op, -1); + break; + case INDEX_op_umin: + done = fold_minmax(&ctx, op, 0); + break; case INDEX_op_xor: case INDEX_op_xor_vec: done = fold_xor(&ctx, op); -- 2.43.0