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" ; <[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
>