This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GCC turns &~ into | due to undefined bit-shift without warning


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.struebe@redheads.de | Web: www.redheads.de

Geschäftsführer: Andreas Hanke
Sitz der Gesellschaft: Lauf
Amtsgericht Nürnberg HRB 22681
Ust-ID: DE 249436843


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]