https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81273
Bug ID: 81273 Summary: Wrong code generated for ARM setting volatile struct field with a literal Product: gcc Version: 6.3.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: ldeboer at gateway dot net.au Target Milestone: --- struct __attribute__((__packed__)) TimerRegisters { volatile uint32_t Load; //0x00 volatile uint32_t Value; //0x04 }; uint32_t base_addr = 0x3F000000; #define TIMER ((struct TimerRegisters*)(base_addr + 0xB400)) void ShowBug (void){ TIMER->Load = 0x400; // -02 compile and look at code } void ShowFix1 (void){ *(volatile uint32_t*)ARMTIMER->Load = 0x400; } void ShowFix2 (void){ volatile uint32_t temp = 0x400; ARMTIMER->Load = temp; } Code generated you can see the two fixes produce markedly different and correct code. Fun trying to write to hardware registers with this bug. 383 .section .text.ShowBug,"ax",%progbits 384 .align 2 385 .global ShowBug 386 .syntax unified 387 .arm 388 .fpu neon-vfpv4 389 .type ShowBug, %function 390 ShowBug: 391 @ args = 0, pretend = 0, frame = 0 392 @ frame_needed = 0, uses_anonymous_args = 0 393 @ link register save eliminated. 394 0000 003000E3 movw r3, #:lower16:.LANCHOR0 395 0004 003040E3 movt r3, #:upper16:.LANCHOR0 396 0008 0020A0E3 mov r2, #0 397 000c 0410A0E3 mov r1, #4 398 0010 003093E5 ldr r3, [r3] 399 0014 2D3B83E2 add r3, r3, #46080 400 0018 0000D3E5 ldrb r0, [r3] @ zero_extendqisi2 401 001c 0020C3E5 strb r2, [r3] 402 0020 0100D3E5 ldrb r0, [r3, #1] @ zero_extendqisi2 403 0024 0110C3E5 strb r1, [r3, #1] 404 0028 0210D3E5 ldrb r1, [r3, #2] @ zero_extendqisi2 405 002c 0220C3E5 strb r2, [r3, #2] 406 0030 0310D3E5 ldrb r1, [r3, #3] @ zero_extendqisi2 407 0034 0320C3E5 strb r2, [r3, #3] 408 0038 1EFF2FE1 bx lr 409 .size ShowBug, .-ShowBug 410 .section .text.ShowFix1,"ax",%progbits 411 .align 2 412 .global ShowFix1 413 .syntax unified 414 .arm 415 .fpu neon-vfpv4 416 .type ShowFix1, %function 417 ShowFix1: 418 @ args = 0, pretend = 0, frame = 0 419 @ frame_needed = 0, uses_anonymous_args = 0 420 @ link register save eliminated. 421 0000 003000E3 movw r3, #:lower16:RPi_IO_Base_Addr 422 0004 003040E3 movt r3, #:upper16:RPi_IO_Base_Addr 423 0008 012BA0E3 mov r2, #1024 424 000c 003093E5 ldr r3, [r3] 425 0010 2D3B83E2 add r3, r3, #46080 426 0014 003093E5 ldr r3, [r3] @ unaligned 427 0018 002083E5 str r2, [r3] 428 001c 1EFF2FE1 bx lr 429 .size ShowFix1, .-ShowFix1 430 .section .text.ShowFix2,"ax",%progbits 431 .align 2 432 .global ShowFix2 433 .syntax unified 434 .arm 435 .fpu neon-vfpv4 436 .type ShowFix2, %function 437 ShowFix2: 438 @ args = 0, pretend = 0, frame = 8 439 @ frame_needed = 0, uses_anonymous_args = 0 440 @ link register save eliminated. 441 0000 003000E3 movw r3, #:lower16:RPi_IO_Base_Addr 442 0004 003040E3 movt r3, #:upper16:RPi_IO_Base_Addr 443 0008 08D04DE2 sub sp, sp, #8 444 000c 012BA0E3 mov r2, #1024 445 0010 003093E5 ldr r3, [r3] 446 0014 04208DE5 str r2, [sp, #4] 447 0018 2D3B83E2 add r3, r3, #46080 448 001c 04209DE5 ldr r2, [sp, #4] 449 0020 002083E5 str r2, [r3] @ unaligned 450 0024 08D08DE2 add sp, sp, #8 451 @ sp needed 452 0028 1EFF2FE1 bx lr 453 .size ShowFix2, .-ShowFix2