Boost logo

Boost :

From: Phil Endecott (spam_from_boost_dev_at_[hidden])
Date: 2007-09-11 06:43:45


Michael Marcin wrote:
> Phil Endecott wrote:
>> Guillaume Melquiond wrote:
>>> #include <algorithm>
>>>
>>> std::pair<unsigned, bool> full_add(unsigned a, unsigned b)
>>> { return std::make_pair(a + b, a + b < a); }
>>>
>>> bool no_overflow(unsigned a, unsigned b)
>>> { return !full_add(a, b).second; }
>>
>> Here's what I get on ARM:
>>
>> _Z8full_addjj:
>> adds r2, r1, r2
>> movcc r1, #0
>> movcs r1, #1
>> str r2, [r0, #0]
>> strb r1, [r0, #4]
>> mov pc, lr
>>
>> _Z11no_overflowjj:
>> cmn r0, r1
>> movcs r0, #0
>> movcc r0, #1
>> mov pc, lr
>>
>>
>
> RVCT 2.2 with --arm and -O2
>
> Gives:
>
> _Z8full_addjj PROC
> PUSH {r2,r3,lr}
> ADD r2,r1,r2
> CMP r2,r1
> MOVCS r1,#0
> MOVCC r1,#1
> STR r1,[sp,#0]
> STR r2,[sp,#4]
> STR r2,[r0,#0]
> LDRB r1,[sp,#0]
> STRB r1,[r0,#4]
> POP {r3,r12,pc}
> ENDP
>
> _Z11no_overflowjj PROC
> PUSH {r0-r3,lr}
> MOV r2,r1
> MOV r1,r0
> ADD r0,sp,#8
> BL _Z8full_addjj
> LDR r0,[sp,#8]
> LDR r1,[sp,#0xc]
> STM sp,{r0,r1}
> LDRB r0,[sp,#4]
> RSBS r0,r0,#1
> MOVCC r0,#0
> POP {r1-r3,r12,pc}
> ENDP
>
> Seems just a tad worse than what you got :)
> What GCC did you use?

$ arm-linux-gnu-g++ --version
arm-linux-gnu-g++ (GCC) 4.1.2 20061028 (prerelease) (Debian 4.1.1-19)

It looks like your compiler is not inlining full_add inside
no_overflow, and is doing a lot of spurious argument save/restore.
There's also some strange store-as-word/load-as-byte going on for the
bool. But the core is this

> ADD r2,r1,r2
> CMP r2,r1
> MOVCS r1,#0
> MOVCC r1,#1

which compares with

>> adds r2, r1, r2
>> movcc r1, #0
>> movcs r1, #1

So either it doesn't know that the add and compare can be merged into
an adds (a peephole optimisation I would think) or it is confused by
the inversion of the carry bit.

Regards,

Phil.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk