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: [email protected] | Web: www.redheads.de
Geschäftsführer: Andreas Hanke
Sitz der Gesellschaft: Lauf
Amtsgericht Nürnberg HRB 22681
Ust-ID: DE 249436843