@@ -1149,6 +1149,17 @@ static int simplify_compare_constant(struct instruction *insn, long long value)
return replace_pseudo(insn, &insn->src1, def->src);
}
break;
+ case OP_ZEXT:
+ osize = def->orig_type->bit_size;
+ bits = bits_mask(osize);
+ if (value <= bits) {
+ const struct opcode_table *op = &opcode_table[insn->opcode];
+ if (op->flags & OPF_SIGNED)
+ insn->opcode = op->sign;
+ insn->itype = def->orig_type;
+ return replace_pseudo(insn, &insn->src1, def->src);
+ }
+ break;
}
return changed;
}
@@ -9,7 +9,6 @@ int zext_gt_p(unsigned int x) { return (zext(x) > (BITS )) == 0; }
/*
* check-name: cmp-zext-uimm1
* check-command: test-linearize -Wno-decl $file
- * check-known-to-fail
*
* check-output-ignore
* check-output-returns: 1
@@ -11,7 +11,6 @@ _Bool cmpu_zext(ARGS(UINT32)) { return TEST(UINT64, UINT32, a, < , 0xffffffff);
/*
* check-name: cmp-zext
* check-command: test-linearize -Wno-decl $file
- * check-known-to-fail
*
* check-output-ignore
* check-output-returns: 1
@@ -10,7 +10,6 @@ int gtl(unsigned x) { return (((long long)x) > 0x0fffffffeULL) == (x > 0xfffff
/*
* check-name: zext-cmpu
* check-command: test-linearize -Wno-decl $file
- * check-known-to-fail
*
* check-output-ignore
* check-output-returns: 1
When doing a compare of a zero-extended value against a constant, this extension can be dropped and the comparison done on the original type if the constant is within the original range and signed compares become the corresponding unsigned one. Simplify away these sign-extensions. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> --- simplify.c | 11 +++++++++++ validation/optim/cmp-zext-uimm1.c | 1 - validation/optim/cmp-zext.c | 1 - validation/optim/zext-cmpu.c | 1 - 4 files changed, 11 insertions(+), 3 deletions(-)