[Bug target/74563] New: [5 regression] Classic MIPS16 (non-MIPS16e) function return broken
macro@linux-mips.org
gcc-bugzilla@gcc.gnu.org
Thu Aug 11 18:48:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=74563
Bug ID: 74563
Summary: [5 regression] Classic MIPS16 (non-MIPS16e) function
return broken
Product: gcc
Version: 6.1.1
Status: UNCONFIRMED
Severity: major
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: macro@linux-mips.org
CC: matthew.fortune at imgtec dot com
Target Milestone: ---
Target: mips-mti-linux-gnu
This is a regression from GCC 5, present in GCC 6 and in current trunk.
Non-leaf classic MIPS16 (non-MIPS16e) function epilogue uses $7 as the
return register, because there is no hardware instruction available to
load $31 directly from the stack. This used to work up to GCC 5, but
now function epilogue still loads $7 with the return address, however
it then uses JR $31 to attempt a function return. This obviously
cannot work as in a non-leaf function typically $31 does not hold the
return address anymore.
To reproduce this simple program can be used:
$ cat jal16.c
void f2(void);
void f1(void)
{
f2();
}
$ gcc -mips1 -mips16 -O2 -S jal16.c
$ cat jal16.s
With GCC 5 I get this correct result:
.file 1 "jal16.c"
.section .mdebug.abi32
.previous
.nan legacy
.module fp=32
.module nooddspreg
.abicalls
.option pic0
.text
.align 2
.globl f1
.set mips16
.set nomicromips
.ent f1
.type f1, @function
f1:
.frame $sp,32,$31 # vars= 0, regs= 1/0, args= 16, gp= 8
.mask 0x80000000,-4
.fmask 0x00000000,0
addiu $sp,-32
sw $31,28($sp)
jal f2
lw $7,28($sp)
.set noreorder
.set nomacro
j $7
addiu $sp,32
.set macro
.set reorder
.end f1
.size f1, .-f1
.ident "GCC: (GNU) 5.4.1 20160810"
With GCC 6 I get this bad one instead:
.file 1 "jal16.c"
.section .mdebug.abi32
.previous
.nan legacy
.module fp=32
.module nooddspreg
.abicalls
.option pic0
.text
.align 2
.globl f1
.set mips16
.set nomicromips
.ent f1
.type f1, @function
f1:
.frame $sp,32,$31 # vars= 0, regs= 1/0, args= 16, gp= 8
.mask 0x80000000,-4
.fmask 0x00000000,0
addiu $sp,-32
sw $31,28($sp)
jal f2
lw $7,28($sp)
.set noreorder
.set nomacro
jr $31
addiu $sp,32
.set macro
.set reorder
.end f1
.size f1, .-f1
.ident "GCC: (GNU) 6.1.1 20160810"
Notice the difference:
--- jal16-gcc5.s 2016-08-11 14:22:24.996749000 +0100
+++ jal16-gcc6.s 2016-08-11 18:59:38.472543000 +0100
@@ -23,11 +23,11 @@
lw $7,28($sp)
.set noreorder
.set nomacro
- j $7
+ jr $31
addiu $sp,32
.set macro
.set reorder
.end f1
.size f1, .-f1
- .ident "GCC: (GNU) 5.4.1 20160810"
+ .ident "GCC: (GNU) 6.1.1 20160810"
This is a fatal bug making the MIPS16 compiler unusable and therefore
requiring hightened attention, although only affecting an ISA level
which is not as important these days anymore, so setting severity to
major rather than critical/blocker.
More information about the Gcc-bugs
mailing list