void Switch4(int x) {
switch (x & 7) {
}
}
>>
.globl _Switch4
.def _Switch4; .scl 2; .type 32; .endef
_Switch4:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
andl $7, %eax
cmpl $7, %eax
ja L12
jmp *L11(,%eax,4)
cmpl+ja are redundant in both cases.
Do you think it is possible for gcc to optimize them away?
I believe VRP could be taught about inferring ranges from bit_and_expr and
similar operations. Right?
Yes, but the range check is not emitted until trees are expanded to RTL.
combine does a lot of simplifications, but unfortunately not this one.
It is also quite hard to teach combine to *remove* jumps, though it
has some ability to turn conditional jumps into unconditional.
The attached patch would at least cause simplify-rtx.c to realize that
(gtu (reg:SI 61) (const_int 7)) is false, but not cause any code
generation improvement.
Paolo
Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/simplify-rtx.c,v
retrieving revision 1.230.2.6
diff -u -r1.230.2.6 simplify-rtx.c
--- simplify-rtx.c 24 Apr 2005 22:15:04 -0000 1.230.2.6
+++ simplify-rtx.c 22 Aug 2005 12:23:03 -0000
@@ -2912,6 +2912,7 @@
if (GET_CODE (op1) == CONST_INT)
{
+ HOST_WIDE_INT mask;
if (INTVAL (op1) == 0 && COMPARISON_P (op0))
{
/* If op0 is a comparison, extract the comparison arguments form it.
*/
@@ -2931,6 +2932,46 @@
XEXP (op0, 0), XEXP (op0, 1));
}
}
+
+
+ mask = nonzero_bits (op0, cmp_mode);
+ switch (code)
+ {
+ case GE:
+ if (mask < 0)
+ break;
+ /* fall through */
+ case GEU:
+ if (INTVAL (op1) > mask)
+ return const0_rtx;
+
+ case GT:
+ if (mask < 0)
+ break;
+ /* fall through */
+ case GTU:
+ if (INTVAL (op1) >= mask)
+ return const0_rtx;
+
+ case LE:
+ if (mask < 0)
+ break;
+ /* fall through */
+ case LEU:
+ if (INTVAL (op1) >= mask)
+ return const_true_rtx;
+
+ case LT:
+ if (mask < 0)
+ break;
+ /* fall through */
+ case LTU:
+ if (INTVAL (op1) > mask)
+ return const_true_rtx;
+ break;
+ default:
+ break;
+ }
}
/* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1)) */