Why GCC (6.3.1 and newer) does not update the value of a changeable pointer

Asked by Reda on 2019-10-29

In the following code snippet, the ARM GCC (version 6.3.1 and newer) generates assembly as the pointer is not changing and saves it R2 and does not update it again

========================= C Code ===============================
typedef unsigned short U16;
typedef unsigned char U8;

typedef struct LinkNode
    struct LinkNode* prev;
    struct LinkNode* next;
} LinkNode_s;

typedef struct PduNode
    LinkNode_s pduLinks;
    U16 sn;
} PduNode_s;

typedef struct
    U16 sn;
    PduNode_s* pduNodePtr;
} StateVar_s;

static inline U8 GetNext(
    LinkNode_s* aCurrentNodePtr,
    LinkNode_s** aNodePtr)
    *aNodePtr = aCurrentNodePtr->next;

    return 1;

void func(
    StateVar_s* aStateVarPtr)
        GetNext((LinkNode_s*)(aStateVarPtr->pduNodePtr), (LinkNode_s**)(&aStateVarPtr->pduNodePtr));
    } while (0 != aStateVarPtr->pduNodePtr);

GCC version 8.3.1 and 6.3.1 generated assembly:
00000000 <func>:
   0: 6842 ldr r2, [r0, #4]
   2: 6853 ldr r3, [r2, #4]
   4: 6043 str r3, [r0, #4]
   6: 2b00 cmp r3, #0
   8: d1fb bne.n 2 <func+0x2>
   a: 4770 bx lr

However the generated code from GCC 4.9.3 is handling the pointer correctly and load it each time
00000000 <func>:
   0: 6843 ldr r3, [r0, #4]
   2: 685b ldr r3, [r3, #4]
   4: 6043 str r3, [r0, #4]
   6: 2b00 cmp r3, #0
   8: d1fa bne.n 0 <func>
   a: 4770 bx lr

The command I use for compilation is:
arm-none-eabi-gcc -c -mcpu=Cortex-M0 -mthumb -Os -o gcc_issue.o gcc_issue.c

The original code is much complicated and this issue causes the code to do incorrect behavior

Why the old GCC generates correct assembly while the newer versions do not?

Question information

English Edit question
GNU Arm Embedded Toolchain Edit question
No assignee Edit question
Solved by:
Last query:
Last reply:
john (jkovach) said : #1

I didn't go through the code, but have you considered strict aliasing? Try adding '-fno-strict-aliasing' to the command line.

Reda (rm-dev) said : #2

It seems it solved my issue !!
Thanks John :)