aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2024-01-22 10:48:11 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2025-02-07 15:51:01 +0100
commit35020629914b4d3af6195d33e1a68e8b1c8c2fa3 (patch)
tree640af0a249d5bde7ef53731be6a0a33a9529be58
parent059fad25fda352e3b8d79d0c7ad681d08516d8d5 (diff)
downloadqemu-35020629914b4d3af6195d33e1a68e8b1c8c2fa3.zip
qemu-35020629914b4d3af6195d33e1a68e8b1c8c2fa3.tar.gz
qemu-35020629914b4d3af6195d33e1a68e8b1c8c2fa3.tar.bz2
tcg/optimize: optimize TSTNE using smask and zmask
Generalize the existing optimization of "TSTNE x,sign" and "TSTNE x,-1". This can be useful for example in the i386 frontend, which will generate tests of zero-extended registers against 0xffffffff. Ironically, on x86 hosts this is a very slight pessimization in the very case it's meant to optimize because brcond_i64 cc_dst,$0xffffffff,tsteq,$L1 (test %ebx, %ebx) is 1 byte smaller than brcond_i64 cc_dst,$0x0,eq,$L1 (test %rbx, %rbx). However, in general it is an improvement, especially if it avoids placing a large immediate in the constant pool. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--tcg/optimize.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/tcg/optimize.c b/tcg/optimize.c
index 8c6303e..bca11cc 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -766,6 +766,7 @@ static int do_constant_folding_cond1(OptContext *ctx, TCGOp *op, TCGArg dest,
TCGArg *p1, TCGArg *p2, TCGArg *pcond)
{
TCGCond cond;
+ TempOptInfo *i1;
bool swap;
int r;
@@ -783,19 +784,21 @@ static int do_constant_folding_cond1(OptContext *ctx, TCGOp *op, TCGArg dest,
return -1;
}
+ i1 = arg_info(*p1);
+
/*
* TSTNE x,x -> NE x,0
- * TSTNE x,-1 -> NE x,0
+ * TSTNE x,i -> NE x,0 if i includes all nonzero bits of x
*/
- if (args_are_copies(*p1, *p2) || arg_is_const_val(*p2, -1)) {
+ if (args_are_copies(*p1, *p2) ||
+ (arg_is_const(*p2) && (i1->z_mask & ~arg_info(*p2)->val) == 0)) {
*p2 = arg_new_constant(ctx, 0);
*pcond = tcg_tst_eqne_cond(cond);
return -1;
}
- /* TSTNE x,sign -> LT x,0 */
- if (arg_is_const_val(*p2, (ctx->type == TCG_TYPE_I32
- ? INT32_MIN : INT64_MIN))) {
+ /* TSTNE x,i -> LT x,0 if i only includes sign bit copies */
+ if (arg_is_const(*p2) && (arg_info(*p2)->val & ~i1->s_mask) == 0) {
*p2 = arg_new_constant(ctx, 0);
*pcond = tcg_tst_ltge_cond(cond);
return -1;