[Bug ipa/68273] New: Wrong code on mips/mipsel with -fno-ipa-sra
aurelien at aurel32 dot net
gcc-bugzilla@gcc.gnu.org
Tue Nov 10 14:46:00 GMT 2015
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
More information about the Gcc-bugs
mailing list