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.

Reply via email to