This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
GCC turns &~ into | due to undefined bit-shift without warning
- From: Moritz Strübe <moritz dot struebe at redheads dot de>
- To: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Cc: Nicolai Steinkamp <nicolai dot steinkamp at redheads dot de>
- Date: Mon, 11 Mar 2019 08:49:30 +0000
- Subject: 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