@samitouri / QOSamiQemu / commits / db9be9b136

tcg/optimize: Handle min/max opcodes

Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Richard Henderson committed Aug 11, 2026 at 15:42 UTC db9be9b136cb5a68e8d545d87e9ee3afbb6bbe0d
1 file changed +52
tcg/optimize.c
+52
@@ -597,6 +597,30 @@ static uint64_t do_constant_folding_2(TCGOpcode op, TCGType type,
597 }
598 return (uint64_t)x % ((uint64_t)y ? : 1);
599
600 + case INDEX_op_smax:
601 + if (type == TCG_TYPE_I32) {
602 + return MAX((int32_t)x, (int32_t)y);
603 + }
604 + return MAX((int64_t)x, (int64_t)y);
605 +
606 + case INDEX_op_smin:
607 + if (type == TCG_TYPE_I32) {
608 + return MIN((int32_t)x, (int32_t)y);
609 + }
610 + return MIN((int64_t)x, (int64_t)y);
611 +
612 + case INDEX_op_umax:
613 + if (type == TCG_TYPE_I32) {
614 + return MAX((uint32_t)x, (uint32_t)y);
615 + }
616 + return MAX((uint64_t)x, (uint64_t)y);
617 +
618 + case INDEX_op_umin:
619 + if (type == TCG_TYPE_I32) {
620 + return MIN((uint32_t)x, (uint32_t)y);
621 + }
622 + return MIN((uint64_t)x, (uint64_t)y);
623 +
624 default:
625 g_assert_not_reached();
626 }
@@ -2101,6 +2125,16 @@ static bool fold_mb(OptContext *ctx, TCGOp *op)
2125 return true;
2126 }
2127
2128 +static bool fold_minmax(OptContext *ctx, TCGOp *op, uint64_t bound)
2129 +{
2130 + if (fold_const2_commutative(ctx, op) ||
2131 + fold_xi_to_i(ctx, op, bound) ||
2132 + fold_xx_to_x(ctx, op)) {
2133 + return true;
2134 + }
2135 + return finish_folding(ctx, op);
2136 +}
2137 +
2138 static bool fold_mov(OptContext *ctx, TCGOp *op)
2139 {
2140 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]);
@@ -3258,6 +3292,14 @@ void tcg_optimize(TCGContext *s)
3292 case INDEX_op_sextract:
3293 done = fold_sextract(&ctx, op);
3294 break;
3295 + case INDEX_op_smax:
3296 + done = fold_minmax(&ctx, op, (ctx.type == TCG_TYPE_I32
3297 + ? INT32_MAX : INT64_MAX));
3298 + break;
3299 + case INDEX_op_smin:
3300 + done = fold_minmax(&ctx, op, (ctx.type == TCG_TYPE_I32
3301 + ? INT32_MIN : INT64_MIN));
3302 + break;
3303 case INDEX_op_sub:
3304 done = fold_sub(&ctx, op);
3305 break;
@@ -3273,6 +3315,16 @@ void tcg_optimize(TCGContext *s)
3315 case INDEX_op_sub_vec:
3316 done = fold_sub_vec(&ctx, op);
3317 break;
3318 + case INDEX_op_umax:
3319 + /*
3320 + * Note that 32-bit constants are stored sign extended,
3321 + * so (int32_t)UINT32_MAX == -1.
3322 + */
3323 + done = fold_minmax(&ctx, op, -1);
3324 + break;
3325 + case INDEX_op_umin:
3326 + done = fold_minmax(&ctx, op, 0);
3327 + break;
3328 case INDEX_op_xor:
3329 case INDEX_op_xor_vec:
3330 done = fold_xor(&ctx, op);