https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115860
Bug ID: 115860
Summary: Register pairs and regrename
Product: gcc
Version: 15.0
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: stefansf at gcc dot gnu.org
Target Milestone: ---
Target: s390*-*-*
FAIL: c-c++-common/ubsan/float-cast-overflow-7.c -O2 execution test
FAIL: c-c++-common/ubsan/float-cast-overflow-7.c -O2 -flto
-fno-use-linker-plugin -flto-partition=none execution test
FAIL: c-c++-common/ubsan/float-cast-overflow-7.c -O2 -flto
-fuse-linker-plugin -fno-fat-lto-objects execution test
Although bisect stops at r15-1579-g792f97b44ffc5e this does not seem to be
directly related but rather shows a latent bug.
Reduced example:
__attribute__ ((noinline))
signed long cvt_sl_ld (long double x)
{
return x;
}
int main ()
{
if (cvt_sl_ld (0x7fffffffffffffffL) != 0x7fffffffffffffffL)
__builtin_abort ();
return 0;
}
Prior pass rnreg we have
(insn 91 38 36 5 (set (reg:FPRX2 16 %f0 [orig:76 x ] [76])
(const_double:FPRX2 0.0 [0x0.0p+0]))
"float-cast-overflow-7-reduced.c":5:55 discrim 2 1507 {*movfprx2_64}
(expr_list:REG_EQUAL (const_double:FPRX2 0.0 [0x0.0p+0])
(nil)))
(insn 36 91 37 5 (set (subreg:DF (reg:FPRX2 16 %f0 [orig:76 x ] [76]) 0)
(mem/c:DF (plus:DI (reg/f:DI 15 %r15)
(const_int 160 [0xa0])) [7 %sfp+-32 S8 A64]))
"float-cast-overflow-7-reduced.c":5:55 discrim 2 1512 {*movdf_64dfp}
(nil))
(insn 37 36 43 5 (set (subreg:DF (reg:FPRX2 16 %f0 [orig:76 x ] [76]) 8)
(mem/c:DF (plus:DI (reg/f:DI 15 %r15)
(const_int 168 [0xa8])) [7 %sfp+-24 S8 A64]))
"float-cast-overflow-7-reduced.c":5:55 discrim 2 1512 {*movdf_64dfp}
(nil))
(insn 43 37 44 5 (parallel [
(set (reg/i:DI 2 %r2)
(fix:DI (reg:FPRX2 16 %f0 [orig:76 x ] [76])))
(unspec:DI [
(const_int 5 [0x5])
] UNSPEC_ROUND)
(clobber (reg:CC 33 %cc))
]) "float-cast-overflow-7-reduced.c":5:58 1702 {*fix_truncfprx2di2_bfp}
(expr_list:REG_DEAD (reg:FPRX2 16 %f0 [orig:76 x ] [76])
(expr_list:REG_UNUSED (reg:CC 33 %cc)
(nil))))
and afterwards:
(insn 91 38 36 5 (set (reg:FPRX2 16 %f0 [orig:76 x ] [76])
(const_double:FPRX2 0.0 [0x0.0p+0]))
"float-cast-overflow-7-reduced.c":5:55 discrim 2 1507 {*movfprx2_64}
(expr_list:REG_EQUAL (const_double:FPRX2 0.0 [0x0.0p+0])
(nil)))
(insn 36 91 37 5 (set (subreg:DF (reg:FPRX2 16 %f0 [orig:76 x ] [76]) 0)
(mem/c:DF (plus:DI (reg/f:DI 15 %r15)
(const_int 160 [0xa0])) [7 %sfp+-32 S8 A64]))
"float-cast-overflow-7-reduced.c":5:55 discrim 2 1512 {*movdf_64dfp}
(nil))
(insn 37 36 43 5 (set (subreg:DF (reg:FPRX2 20 %f1 [orig:76 x ] [76]) 8)
(mem/c:DF (plus:DI (reg/f:DI 15 %r15)
(const_int 168 [0xa8])) [7 %sfp+-24 S8 A64]))
"float-cast-overflow-7-reduced.c":5:55 discrim 2 1512 {*movdf_64dfp}
(nil))
(insn 43 37 44 5 (parallel [
(set (reg/i:DI 2 %r2)
(fix:DI (reg:FPRX2 20 %f1 [orig:76 x ] [76])))
(unspec:DI [
(const_int 5 [0x5])
] UNSPEC_ROUND)
(clobber (reg:CC 33 %cc))
]) "float-cast-overflow-7-reduced.c":5:58 1702 {*fix_truncfprx2di2_bfp}
(expr_list:REG_DEAD (reg:FPRX2 16 %f0 [orig:76 x ] [76])
(expr_list:REG_UNUSED (reg:CC 33 %cc)
(nil))))
For insn 37 and 43 register f0 is renamed to f1 which is wrong, i.e., in
expressions
(subreg:DF (reg:FPRX2 20 %f1 [orig:76 x ] [76]) 8)
and
(fix:DI (reg:FPRX2 20 %f1 [orig:76 x ] [76]))
it should be f0 since this is a register pair.
Creating chain %f0 (12) at insn 91
Closing chain %f0 (12) at insn 36 (terminate_write, superset)
Creating chain %f0 (13) at insn 36
Closing chain %f0 (13) at insn 37 (terminate_write, superset)
Creating chain %f0 (14) at insn 37
Closing chain %f0 (14) at insn 43 (terminate_dead, superset)
...
Register %f0 in insn 37deferring rescan insn with uid = 37.
deferring rescan insn with uid = 43.
, renamed as %f1
The chain for f0 is prematurely terminated due to writes into one register of a
register pair resulting in a chain containing only insn 37 and 43 for f0.