https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68273
Bug ID: 68273 Summary: Wrong code on mips/mipsel with -fno-ipa-sra Product: gcc Version: 5.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: ipa Assignee: unassigned at gcc dot gnu.org Reporter: aurelien at aurel32 dot net Target Milestone: --- Host: mipsel-linux-gnu Target: mipsel-linux-gnu Build: mipsel-linux-gnu Created attachment 36676 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36676&action=edit preprocessed source gsoap version 2.8.22 does not compile correctly on mips and mipsel with GCC 5.2.1 or trunk, while it compiles correctly on GCC 4.9. The resulting binary segfaults. A bit of analysis shows this is due to wrong code optimization at -O2 level, and more specifically with the -fipa-sra option, which calls functions with arguments in the wrong register. I have not been able to get a simple testcase yet, but it is possible to reproduce the issue with the attached preprocessed code. The problem occurs in this function: case 34: # 436 "soapcpp2_yacc.y" { if ((yyvsp[-1].rec).sto & Stypedef) { sprintf(errbuf, "invalid typedef qualifier for '%s'", (yyvsp[0].sym)->name); semwarn(errbuf); } printf("%p\n", (yyvsp[0].sym)); p = enter(sp->table, (yyvsp[0].sym)); p->info.typ = (yyvsp[-1].rec).typ; p->info.sto = (yyvsp[-1].rec).sto; p->info.hasval = False; p->info.offset = sp->offset; if (sp->grow) sp->offset += p->info.typ->width; else if (p->info.typ->width > sp->offset) sp->offset = p->info.typ->width; sp->entry = p; } # 2290 "soapcpp2_yacc.c" break; When compiled with -O2, GCC outputs the following corresponding code: $L380: lw $25,%call16(__printf_chk)($28) lw $21,%got(sp)($28) lui $5,%hi($LC37) move $6,$7 addiu $5,$5,%lo($LC37) sw $7,13452($sp) .reloc 1f,R_MIPS_JALR,__printf_chk 1: jalr $25 li $4,1 # 0x1 lw $28,88($sp) lw $2,0($21) lw $7,13452($sp) lw $4,0($2) lw $25,%call16(enter)($28) nop .reloc 1f,R_MIPS_JALR,enter 1: jalr $25 move $6,$7 Note how the second argument is loaded in $6 (ie a2) instead of $5 (ie a1) when calling enter. When compiled with -O2 -fno-ipa-sra the correct register is used: -O2 -fno-ipa-sra $L387: lw $25,%call16(__printf_chk)($28) lw $21,%got(sp)($28) lui $5,%hi($LC37) move $6,$7 sw $7,13500($sp) addiu $5,$5,%lo($LC37) .reloc 1f,R_MIPS_JALR,__printf_chk 1: jalr $25 li $4,1 # 0x1 lw $28,136($sp) lw $2,0($21) lw $7,13500($sp) lw $4,0($2) lw $25,%call16(enter)($28) nop .reloc 1f,R_MIPS_JALR,enter 1: jalr $25 move $5,$7 However it is first loaded to $7 for no obvious reason, especially this is not a saved register, so its value is lost after the call. I am note sure it is something related, but loading the value through this intermediate register is due to the use of -O2, this is not the case -O1: $L370: lw $2,0($16) nop sw $2,13476($sp) move $6,$2 lui $5,%hi($LC37) addiu $5,$5,%lo($LC37) li $4,1 # 0x1 lw $25,%call16(__printf_chk)($28) nop .reloc 1f,R_MIPS_JALR,__printf_chk 1: jalr $25 nop lw $28,136($sp) nop lw $17,%got(sp)($28) nop lw $2,0($17) lw $5,13476($sp) lw $4,0($2) lw $25,%call16(enter)($28) nop .reloc 1f,R_MIPS_JALR,enter 1: jalr $25 nop