https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71942

            Bug ID: 71942
           Summary: [ARM] Zero-extending whats allready zero-extended even
                    when -O3
           Product: gcc
           Version: 5.4.1
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: albrecht.guendel at web dot de
  Target Milestone: ---

Hi, 
i came across the insertion of an redundant instruction while toggleing a pin
on an ARM-Microcontroller: 

while(1) GPIOA->ODR = (GPIOA->ODR ^ static_cast<uint16_t>(1u<<Pin));

This just exors a Bit in a memory maped register thats 16bit wide (type of ODR
is uint16_t) so that a pin physically toggles.

The generated Code with -O3 for the exor-operation reads like this:

ldrh    r3, [r2, #20] //reads a half word (16bit, GPIOA->ODR) into r3 and
                        zero-extent the upper half word of r3.
uxth    r3, r3        //Zeroextrent the upper halfword AGAIN
eor.w   r3, r3, #1    //finally exor the lower 16bit of the register
strh    r3, [r2, #20] //store the lower 16bit of the register back to
                        the periphery
Clearly there is an unnecessary uxth instruction..

This might be a fundamental problem with the optimizer not recognizing that
a) only 16bit operations are done and the upper 16bit are "dont care"
b) the ldrh allready zero-extends the loaded value so that uxth is implicitly
done allready.

Reply via email to