Post B4FZfCrsQt699ZuCPo by dnkl@social.treehouse.systems
(DIR) More posts by dnkl@social.treehouse.systems
(DIR) Post #B4FXxFYEzlCqmPCGIq by sertonix@social.treehouse.systems
0 likes, 0 repeats
Does anybody know why gcc and clang can't optimize away this bit shift on most architectures?uint16_t test(uint16_t *buf) { return (uint16_t)((char *)buf)[0] | ((uint16_t)((char *)buf)[1] << 8);}I tested with godbolt.org and it only really showed good optimizations on powerpc.On all little endian systems this should be equivalent to just *buf which has much shorter assembly.
(DIR) Post #B4FXxFkIGwqbNmpt5c by dnkl@social.treehouse.systems
0 likes, 0 repeats
@sertonixchar is usually signed. If I cast to uint8_t instead, the whole function is a single movzwl (+ret) on x86.
(DIR) Post #B4FYrbaWFZ6PLH8PwW by sertonix@social.treehouse.systems
0 likes, 0 repeats
@dnkl Thanks! But I am a bit surprised it works since the cast to uint16_t should make the char sign not matter.
(DIR) Post #B4FZfCf7CKtEVzw0WW by mei@donotsta.re
0 likes, 0 repeats
@sertonix @dnkl it does in fact matter
(DIR) Post #B4FZfCrsQt699ZuCPo by dnkl@social.treehouse.systems
0 likes, 0 repeats
@meiWhen a signed value is promoted/expanded to a wider type, the sign is extended too, even if the target type is unsigned. I.e your cast to uint16_t can be seen as a double cast, first to int16_t, then to uint16_t.@sertonix