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

            Bug ID: 102279
           Summary: Bad codegen with ILP32, packed struct field pointer,
                    static variable
           Product: gcc
           Version: 10.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: nyphbl8d at gmail dot com
  Target Milestone: ---

Created attachment 51435
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51435&action=edit
preprocessed source

When using a packed struct with AArch64 ILP32, -O2, and packed struct field
manipulation by pointer, gcc can produce bad assembly output.

The preprocessed Linux-native test case source is attached.

The original test case was compiled with:
aarch64-rtems6-gcc (GCC) 10.3.1 20210409 (RTEMS 6, RSB
d162b7de619779d29a27b95bfd10a2441c2e5dca-modified, Newlib 4f81149)

aarch64-rtems6-gcc -c -o align_test.o -D__rtems__ -D_GNU_SOURCE -O2 -g -Wall
-I../new-install/aarch64-rtems6/xilinx_zynqmp_ilp32_zu3eg/lib/include
-mcpu=cortex-a53 -mabi=ilp32 -ffunction-sections -fdata-sections align_test.c

The Linux-native test case was compiled with:
https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads
aarch64-none-linux-gnu-gcc (GNU Toolchain for the A-profile Architecture
10.3-2021.07 (arm-10.29)) 10.3.1 20210621

./gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc
align_test.linux.c -o align_test.linux.o -c -mabi=ilp32 -O2 -mcpu=cortex-a53
-Wall -ffunction-sections -fdata-sections --save-temps


This code should produce 0x12341234, but instead produces 0x1234abcd under
RTEMS running under QEMU and on hardware. I was not able to run the code under
Linux on an ARM64 machine, but the assembly looks equally broken based on my
reading and understanding.

Linux-native source align_test.linux.c:
#include <stdio.h>
#include <stdint.h>

#pragma pack(1)
struct S
{
    uint32_t field1;
    uint16_t field2;
};
#pragma pack()

int main() {
  static int static_int = 0;
  uint16_t *word_ptr;
  struct S m;
  m.field1 = 0x1234ABCD + static_int;
  word_ptr = (uint16_t *) &(m.field1);
  word_ptr[0] = word_ptr[1];
  printf("0x%x\n", m.field1);
  static_int++;
  return 0;
}

I'm happy to provide any other information required and I have source, object
files, and disassembly ready to share if necessary.

These resolve the problem:
* Removing the pack pragmas
* Changing -O2 to -O0 (-Os still displays bad codegen)
* Switching the data manipulation to bitshifting
* Removing "static_int++"
* Removing field2
* Adding "uint16_t field3;" after field2

Reply via email to