Hey, I have the following code:
#include <stdint.h> void LL_ADC_SetChannelSingleDiff(uint32_t * val, uint32_t Channel, uint32_t SingleDiff) { *val = (*val & (~(Channel & 0x7FFFFU))) | ((Channel & 0x7FFFFU ) & (0x7FFFFU << (SingleDiff & 0x20U))); } void test(uint32_t * testvar) { LL_ADC_SetChannelSingleDiff(testvar, 0x2 ,0x7FU ); } Starting with gcc 6 and -O2 this code produces an or-instruction instead of an and-not-instruction: https://godbolt.org/z/kGtBfW x86-64 -O1: LL_ADC_SetChannelSingleDiff: and esi, 524287 or DWORD PTR [rdi], esi ret test: and DWORD PTR [rdi], -3 ret x86-64 -O1: LL_ADC_SetChannelSingleDiff: and esi, 524287 or DWORD PTR [rdi], esi ret test: or DWORD PTR [rdi], 2 ret Considering that C11 6.5.7#3 ("If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.") is not very widely known, as it "normally" just works, inverting the intent is quite unexpected. Is there any option that would have helped me with this? Should this be a bug? I know, from the C standard point of view this is ok, but inverting the behavior without warning is really bad in terms of user experience. Clang does the same, but IMO that does not make things any better. Cheers Morty -- Redheads Ltd. Softwaredienstleistungen Schillerstr. 14 90409 Nürnberg Telefon: +49 (0)911 180778-50 E-Mail: moritz.stru...@redheads.de | Web: www.redheads.de Geschäftsführer: Andreas Hanke Sitz der Gesellschaft: Lauf Amtsgericht Nürnberg HRB 22681 Ust-ID: DE 249436843