https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81538
--- Comment #8 from John David Anglin <danglin at gcc dot gnu.org> --- Created attachment 41897 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41897&action=edit miniperl debug session The flow and optimization of the Perl_custom_op_get_field function is quite complex. Two switch statements are merged and it appears that ultimately the wrong case is selected to load the return value. On entry, register %r3 contains the value 0x5aedb0. %r3 is not modified in the routine but it is eventually used to load the return value. 0x0001ab70 <Perl_custom_op_get_field+672>: ldw 10(r3),ret0 It seems there is some confusion as to where the variable xop resides. When we hit the following statement, we have 14879 if(field == XOPe_xop_ptr) {(gdb) disass $pc-16,$pc+16 Dump of assembler code from 0x1aa28 to 0x1aa48: 0x0001aa28 <Perl_custom_op_get_field+344>: b,l 0x3b410,rp 0x0001aa2c <Perl_custom_op_get_field+348>: stw r0,0(r8) 0x0001aa30 <Perl_custom_op_get_field+352>: movb,<> ret0,r13,0x1aa74 <Perl_c ustom_op_get_field+420> 0x0001aa34 <Perl_custom_op_get_field+356>: ldi 14,r25 => 0x0001aa38 <Perl_custom_op_get_field+360>: cmpib,= 0,r5,0x1ab94 <Perl_custo m_op_get_field+708> 0x0001aa3c <Perl_custom_op_get_field+364>: ldil L%186800,ret0 0x0001aa40 <Perl_custom_op_get_field+368>: ldo -1(r5),r5 0x0001aa44 <Perl_custom_op_get_field+372>: ldil L%1a800,ret0 End of assembler dump. (gdb) info address xop Symbol "xop" is multi-location: Range 0x1a988-0x1a9a4: a variable in $r3 Range 0x1a9ac-0x1a9b8: a variable in $r3 Range 0x1aa38-0x1aa40: a complex DWARF expression: 0: DW_OP_addr 0x186a88 5: DW_OP_stack_value Range 0x1aa44-0x1aa74: a variable in $r3 Range 0x1aa84-0x1ab94: a variable in $r3 Range 0x1ab94-0x1ab9c: a complex DWARF expression: 0: DW_OP_addr 0x186a88 5: DW_OP_stack_value Range 0x1ab9c-0x1abb4: a variable in $r3 . (gdb) p/x $r3 $2 = 0x5aedb0 (gdb) p xop $3 = (XOP *) 0x186a88 <xop_null> The variable he is always 0 in this call. So, nominally xop should point at xop_null. After we execute the switch statement, gdb thinks we are at line 14896: (gdb) stepi Perl_custom_op_get_field (my_perl=0x1e3008, o=0x5aee58, field=XOPe_xop_peep) at op.c:14896 14896 break; (gdb) disass $pc-16,$pc+16 Dump of assembler code from 0x1ab5c to 0x1ab7c: 0x0001ab5c <Perl_custom_op_get_field+652>: b,l 0x1a9b8 <Perl_custom_op_get_field+232>,r0 0x0001ab60 <Perl_custom_op_get_field+656>: ldw 8(r3),ret0 0x0001ab64 <Perl_custom_op_get_field+660>: b,l 0x1a9b8 <Perl_custom_op_get_field+232>,r0 0x0001ab68 <Perl_custom_op_get_field+664>: ldw 4(r3),ret0 => 0x0001ab6c <Perl_custom_op_get_field+668>: b,l 0x1a9b8 <Perl_custom_op_get_field+232>,r0 0x0001ab70 <Perl_custom_op_get_field+672>: ldw 10(r3),ret0 0x0001ab74 <Perl_custom_op_get_field+676>: b,l 0x1a9b8 <Perl_custom_op_get_field+232>,r0 0x0001ab78 <Perl_custom_op_get_field+680>: ldw c(r3),ret0 Line 14896 is in the first switch expression. This should result in xop->xop_peep being returned. However, here xop is supposed in register %r3. However, the flags value from xop_null is 0. So, the code should be returning XOPd_xop_peep (ie., ((Perl_cpeep_t)0)).