https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98692
--- Comment #14 from Will Schmidt <willschm at gcc dot gnu.org> --- Using gdb/vgdb to view the valgrind shadow register values, it looks like the uninitialized values are being loaded in via the _restgpr0_25 call being made at the end of isVariable(). Dump of assembler code for function isVariable(char*): 0x00000000100006ac <+0>: lis r2,4098 0x00000000100006b0 <+4>: addi r2,r2,32512 0x00000000100006b4 <+8>: mflr r0 0x00000000100006b8 <+12>: addis r9,r2,-2 0x00000000100006bc <+16>: addi r9,r9,-30152 (here: r1 is 0x1fff00e440 ; shadow registers r24..r31 show zero). 0x00000000100006c0 <+20>: bl 0x10000820 <_savegpr0_25> savegpr0_25 stores r25 thru r31 into the stack (offset of r1) 0x00000000100006c4 <+24>: stdu r1,-128(r1) And stack pointer updates itself. r1 is now 0x1fff00e3c0 0x00000000100006c8 <+28>: ld r29,0(r9) 0x00000000100006cc <+32>: ld r28,8(r9) 0x00000000100006d0 <+36>: nop 0x00000000100006d4 <+40>: mr r30,r3 0x00000000100006d8 <+44>: ld r27,16(r9) 0x00000000100006dc <+48>: li r31,0 0x00000000100006e0 <+52>: addi r25,r2,-32456 0x00000000100006e4 <+56>: addi r26,r1,32 0x00000000100006e8 <+60>: std r29,32(r1) 0x00000000100006ec <+64>: std r28,40(r1) 0x00000000100006f0 <+68>: rldicr r9,r31,3,60 0x00000000100006f4 <+72>: li r5,2 0x00000000100006f8 <+76>: std r27,48(r1) 0x00000000100006fc <+80>: mr r3,r30 0x0000000010000700 <+84>: ldx r4,r26,r9 0x0000000010000704 <+88>: bl 0x100004c0 <00000023.plt_call.strncmp@@GLIBC_2.17> 0x0000000010000708 <+92>: ld r2,24(r1) 0x000000001000070c <+96>: mr. r9,r3 0x0000000010000710 <+100>: bne 0x10000718 <isVariable(char*)+108> 0x0000000010000714 <+104>: stw r9,0(r25) 0x0000000010000718 <+108>: cmpldi r31,1 0x000000001000071c <+112>: bne 0x10000728 <isVariable(char*)+124> r1 still 0x1fff00e3c0 0x0000000010000720 <+116>: addi r1,r1,128 now r1 is 0x1fff00e440 0x0000000010000724 <+120>: b 0x10000844 <_restgpr0_25> and as we progress through restoring the regs, the valgrind shadow registers are indicating the values are uninitialized as they are restored off the stack (r1). 0x10000964 <_restgpr0_25>: ld r25,-56(r1) (gdb) p/x $r25s1 $29 = 0xffffffffffffffff (gdb) p/x $r26s1 $31 = 0x0 => 0x10000968 <_restgpr0_26>: ld r26,-48(r1) (gdb) p/x $r26s1 $32 = 0xffffffffffffffff 0x1000096c <_restgpr0_27>: ld r27,-40(r1) 0x10000970 <_restgpr0_28>: ld r28,-32(r1) 0x10000974 <_restgpr0_29>: ld r0,16(r1) The _restgpr* and _savegpr* functions are not referenced when the test is built at other optimization levels. (I've looked at disassembly from -O0 .. -O4). I do note that the _restgpr and _savegpr functions are called differently. savegpr is called with bl while the restgpr is called via a direct branch; i can't immediately tell if this is by design or if it is in error. 100007d0: 71 01 00 48 bl 10000940 <_savegpr0_25> 10000834: 30 01 00 48 b 10000964 <_restgpr0_25>