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);