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.