[Bug middle-end/71942] [ARM] Zero-extending whats allready zero-extended even when -O3
mikael.rosbacke at gmail dot com
gcc-bugzilla@gcc.gnu.org
Tue Nov 7 18:23:00 GMT 2017
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71942
--- Comment #8 from Mikael Rosbacke <mikael.rosbacke at gmail dot com> ---
Previous bug i filed was marked as a duplicate of this. Collecting my
information from that report here. Same basic problem, slightly different
symptom.
--- old text ---
I used the following code on arm-gcc 6.3 compiler (using Matt godbolts compiler
explorer)
#include<cstdint>
volatile uint32_t reg32;
volatile uint16_t reg16;
void test16()
{
volatile uint16_t* reg_p = ®16;
uint16_t mask = 0x800u;
*reg_p &= (uint16_t)~mask;
}
void test32()
{
volatile uint32_t* reg_p = ®32;
uint32_t mask = 0x800u;
*reg_p &= (uint32_t)~mask;
}
And I got the following assembler: (arguments: -std=c99 -mthumb -Os
-mcpu=cortex-m4)
test16():
ldr r2, .L2
ldrh r3, [r2]
bic r3, r3, #2048
lsls r3, r3, #16
lsrs r3, r3, #16
strh r3, [r2] @ movhi
bx lr
.L2:
.word .LANCHOR0
test32():
ldr r2, .L5
ldr r3, [r2, #4]
bic r3, r3, #2048
str r3, [r2, #4]
bx lr
.L5:
.word .LANCHOR0
reg16:
reg32:
The case for 32 bit seems fine. load value, clear bits and then write it back.
The second case have 2 extra instructions, lsls/lsrs. I assume these are for
clearing bit 16-31. However the value is written using a half word instruction
so bit 16-31 should not matter.
This particular case is very common on microcontrollers when accessing hardware
registers. Using '-Os' to save flash memory and then operating bit field in
registers makes this come up often, sometimes in interrupt handlers where
timing is important.
Would like the lsls/lsrs instructions removed unless there is a good reason to
have them there.
Thanks in advance,
--- Mikael R
More information about the Gcc-bugs
mailing list