Timeline for A strange bug in my Arduino ALU
Current License: CC BY-SA 4.0
12 events
when toggle format | what | by | license | comment | |
---|---|---|---|---|---|
Jan 6, 2022 at 15:57 | comment | added | timemage |
@Majenko last night I also had trouble trying to replicate what you saw in folding. But my thoughts on it were more that regardless of what it does, you're asking it to do something undefined and it's hard to have expectations of the optimizer in such cases. I would have tested -fwrapv to check for a change. But, no original problem, no test. As you said not ultimately relevant. About the only thing I thought to add is that the literal's specified base affects whether unsigned types are considered candidates. E.g. 32768 is long, but 0x8000 is unsigned int with 16-bit systems.
|
|
Jan 6, 2022 at 12:40 | comment | added | Majenko | @EdgarBonet No, I didn't. I wouldn't expect -flto to have any effect since there's no linking. -Os might but who knows? It doesn't really matter anyway, since the exact "why" is irrelevant. Whatever the compiler decides to do or doesn't decide to do, it's still 16 bit integers unless there's a good reason for it to promote to long. | |
Jan 6, 2022 at 12:33 | comment | added | Edgar Bonet |
Mmm... weird. The avr-g++ 7.3.0 shipped with Arduino 1.8.15 does the optimization. Did you compile with -Os -flto ?
|
|
Jan 6, 2022 at 10:51 | comment | added | Majenko |
@EdgarBonet Not according to the output of avr-gcc -S in my tests. There was a long list of mul instructions to get the result.
|
|
Jan 6, 2022 at 8:25 | comment | added | Edgar Bonet |
Re “It seems avr-gcc isn't clever enough to fold 60 * 1000 as constants into a single 60000 constant”: It can't do that: that would break the rules of the language about implicit typing. But it is clever: it notices feedLimit doesn't change and folds feedLimit*60*1000 into 30528. No runtime mul calls.
|
|
Jan 6, 2022 at 0:11 | history | edited | Majenko | CC BY-SA 4.0 |
added 238 characters in body
|
Jan 6, 2022 at 0:09 | comment | added | Majenko |
@thebusybee It seems avr-gcc isn't clever enough to fold 60 * 1000 as constants into a single 60000 constant. Instead it does individual mul calls at runtime - <variable> * 60 followed by <result of previous> * 1000 . And at each stage it's working with just 2 8 bit registers per value (or just 1 in the case of 60 of course, it's not that stupid) and all results go into two registers every time. Everything truncates and truncates again. But it doesn't think to coalesce literals like that though...
|
|
Jan 5, 2022 at 22:32 | comment | added | the busybee | I don't think that a folded constant of 60000 is truncated to 27232. Did you check that in compiled code? | |
Jan 5, 2022 at 16:10 | comment | added | PMF |
Alternatively, one can use the types with explicit sizes: int8_t , int16_t , int32_t etc. These will have the expected size regardless of what CPU is used.
|
|
Jan 5, 2022 at 11:15 | vote | accept | Z Dhillon | ||
Jan 5, 2022 at 11:15 | comment | added | Z Dhillon | This was very helpful. Thank you :) | |
Jan 5, 2022 at 11:07 | history | answered | Majenko | CC BY-SA 4.0 |