I know nothing about GCC internals, but it appears that it knows which bits are used in expressions:
unsigned char foo(int x) { return (x + 1) & 0x0f & 0x0c & 0x3ff; } .file "test.c" .section .text .p2align 4,,15 .globl _foo _foo: pushl %ebp movl %esp, %ebp movb 8(%ebp), %al popl %ebp incl %eax andl $12, %eax ret .ident "GCC: (GNU) 4.0.0" Why can't this information be used to optimize comparisons? Does it work only for consecutive ands? Or is it just an early constant folding: return (x + 1) & (0x0f & 0x0c & 0x3ff & 0xff); ? Piotr ----- Original Message ----- From: "Paolo Bonzini" <[EMAIL PROTECTED]> To: "GCC Development" <gcc@gcc.gnu.org>; <[EMAIL PROTECTED]>; "Diego Novillo" <[EMAIL PROTECTED]>; "Giovanni Bajo" <[EMAIL PROTECTED]> Sent: Monday, August 22, 2005 2:24 PM Subject: Re: Redundant limit check for switch > >>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 >