Ad: Fix PR middle-end/45416, missing opt for (a&(1<<C))!=0 to (a>>C)&1
Richard Guenther
richard.guenther@gmail.com
Mon Dec 12 09:49:00 GMT 2011
On Mon, Dec 12, 2011 at 12:13 AM, Georg-Johann Lay <avr@gjlay.de> wrote:
> Bringing this over from gcc-patches@
>
> Jakub Jelinek wrote:
>>
>> On Fri, Dec 09, 2011 at 01:50:37PM +0100, Georg-Johann Lay wrote:
>>
>>> No, not OK.
>>>
>>> This leads to unacceptable code for devices that cannot shift easily
>>> like,
>>> e.g.AVR. This target can only shift by 1 and shifts with big offsets have
>>> to be performed by means of a loop at runtime.
>>
>>
>> Andrew's patch only restored what GCC has been doing before.
>> If this is too expensive on AVR, you should just arrange in the backend to
>> combine that
>> ((x>>C)&1) != 0
>> into more efficient code sequence,
>
>
> Would you please outline how to do that?
>
> Suppose the following C code:
>
> char test_bit (long long x)
> {
> if (x & 0x400)
> return 1;
> else
> return 0;
> }
>
> Notice that with the patch, optabs generate __lshrdi3 libgcc call.
> So you will have to get rid of the libgcc call.
As we are looking at the tree pattern (spanning multiple gimple
stmts) for a bit-test expansion should be dispatched to a routine
in optabs.c that can properly check for the availability of instructions
on the machine.
I agree, emitting a libcall is bad, it's nearly impossible to recover
from that.
Richard.
> Without the patch, the generated code is 3 instructions:
>
> test_bit:
> ldi r24,lo8(1) ; 22 *movqi/2 [length = 1]
> sbrs r19,2 ; 32 *sbrx_branchqi [length = 2]
> ldi r24,lo8(0) ; 33 *movqi/1 [length = 1]
> .L2:
> ret ; 61 return [length = 1]
>
> Situations for other modes are not better.
>
>> otherwise people who write
>> if ((x >> 18) & 1)
>> bar ();
>> in the source will get suboptimal code.
>>
>> Jakub
>
>
> Well, that just depends on what people you care for and what people you
> ignore...
>
> I still don't see why optimizing code for platform X is allowed to lead to
> code bloat for platform Y.
>
> The problem is:
>
> * There is no canonical representation for "extract bit" or "move bit"
> or "test bit" in the tree passes.
>
> * tree -> RTL lowering does not care for RTX costs for the
> different ways "testing a bit" etc. can be represented.
>
> If there was a canonical representation of these operations, a backend
> wouldn't even notice if the tree passes chose a different, more convenient
> canonicalization.
>
> The very problem is obviously that various ways to extract/test/move a bit
> are not worked out during tree -> RTL expansion and that writing RTX costs
> is paper waste.
>
> What you are saying is: "Just change your backend if the code gets bad."
>
> Maybe next week there is yet another change for platform Z and operation Q.
> Again, the backend needs to be reworked and expand to be reverse engineered
> to reveal what is this week's favourite style of expanding Q?
>
> Really, if this is how architectural goal or development roadmap looks like,
> then contributing to GCC is just waste of time.
>
> Johann
More information about the Gcc
mailing list