Bug 117770 - FAIL: g++.dg/torture/pr37922.C -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
Summary: FAIL: g++.dg/torture/pr37922.C -O3 -fomit-frame-pointer -funroll-loops -fpe...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 15.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: ra, wrong-code
Depends on:
Blocks:
 
Reported: 2024-11-25 16:34 UTC by John David Anglin
Modified: 2024-12-23 22:36 UTC (History)
2 users (show)

See Also:
Host: hppa*-*-linux*
Target: hppa*-*-linux*
Build: hppa*-*-linux*
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Reload RTL dump (169.71 KB, application/x-gzip)
2024-11-25 16:34 UTC, John David Anglin
Details

Note You need to log in before you can comment on or make changes to this bug.
Description John David Anglin 2024-11-25 16:34:02 UTC
Created attachment 59698 [details]
Reload RTL dump

spawn -ignore SIGHUP /home/dave/gnu/gcc/objdir/gcc/testsuite/g++1/../../xg++ -B/
home/dave/gnu/gcc/objdir/gcc/testsuite/g++1/../../ /home/dave/gnu/gcc/gcc/gcc/te
stsuite/g++.dg/torture/pr37922.C -fdiagnostics-plain-output -nostdinc++ -I/home/
dave/gnu/gcc/objdir/hppa-linux-gnu/libstdc++-v3/include/hppa-linux-gnu -I/home/d
ave/gnu/gcc/objdir/hppa-linux-gnu/libstdc++-v3/include -I/home/dave/gnu/gcc/gcc/
libstdc++-v3/libsupc++ -I/home/dave/gnu/gcc/gcc/libstdc++-v3/include/backward -I
/home/dave/gnu/gcc/gcc/libstdc++-v3/testsuite/util -fmessage-length=0 -O3 -fomit
-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions -fpic -L/
home/dave/gnu/gcc/objdir/hppa-linux-gnu/./libstdc++-v3/src/.libs -B/home/dave/gn
u/gcc/objdir/hppa-linux-gnu/./libstdc++-v3/src/.libs -L/home/dave/gnu/gcc/objdir
/hppa-linux-gnu/./libstdc++-v3/src/.libs -L/home/dave/gnu/gcc/objdir/hppa-linux-
gnu/./libstdc++-v3/src/experimental/.libs -lm -o ./pr37922.exe
PASS: g++.dg/torture/pr37922.C   -O3 -fomit-frame-pointer -funroll-loops -fpeel-
loops -ftracer -finline-functions  (test for excess errors)
Setting LD_LIBRARY_PATH to .:/home/dave/gnu/gcc/objdir/hppa-linux-gnu/./libstdc+
+-v3/src/.libs:/home/dave/gnu/gcc/objdir/hppa-linux-gnu/./libstdc++-v3/src/.libs
:/home/dave/gnu/gcc/objdir/hppa-linux-gnu/./libstdc++-v3/src/experimental/.libs:
/home/dave/gnu/gcc/objdir/gcc/testsuite/g++1/../..:.:/home/dave/gnu/gcc/objdir/h
ppa-linux-gnu/./libstdc++-v3/src/.libs:/home/dave/gnu/gcc/objdir/hppa-linux-gnu/./libstdc++-v3/src/.libs:/home/dave/gnu/gcc/objdir/hppa-linux-gnu/./libstdc++-v3/src/experimental/.libs:/home/dave/gnu/gcc/objdir/gcc/testsuite/g++1/../..:/home/dave/gnu/gcc/objdir/hppa-linux-gnu/libstdc++-v3/src/.libs:/home/dave/gnu/gcc/objdir/hppa-linux-gnu/libssp/.libs:/home/dave/gnu/gcc/objdir/hppa-linux-gnu/libgomp/.libs:/home/dave/gnu/gcc/objdir/hppa-linux-gnu/libatomic/.libs:/home/dave/gnu/gcc/objdir/./gcc:/home/dave/gnu/gcc/objdir/./prev-gcc:/home/dave/gnu/gcc/objdir/hppa-linux-gnu/libstdc++-v3/src/.libs:/home/dave/gnu/gcc/objdir/hppa-linux-gnu/libssp/.libs:/home/dave/gnu/gcc/objdir/hppa-linux-gnu/libgomp/.libs:/home/dave/gnu/gcc/objdir/hppa-linux-gnu/libatomic/.libs:/home/dave/gnu/gcc/objdir/./gcc:/home/dave/gnu/gcc/objdir/./prev-gcc
Execution timeout is: 300
spawn [open ...]
FAIL: g++.dg/torture/pr37922.C   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  execution test

dave@mx3210:~/gnu/gcc/objdir/gcc/testsuite/g++1/lra$ ./pr37922.exe
Floating point exception (core dumped)

Reading symbols from pr37922.exe...
(gdb) r
Starting program: /home/dave/gnu/gcc/objdir/gcc/testsuite/g++1/lra/pr37922.exe
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.

Program received signal SIGFPE, Arithmetic exception.
$$divoI () at ../../../gcc/libgcc/config/pa/milli64.S:452
452             addit,= 0,arg1,r0       /*  trap if divisor == 0 */
(gdb) bt
#0  $$divoI () at ../../../gcc/libgcc/config/pa/milli64.S:452
#1  0x00010f44 in unsigned int form_t<int>(mat_ref<int, mat_grid>&, mat_ref<int, mat_grid> const&) ()
#2  0x00010910 in rot_mx_info::rot_mx_info(rot_mx const&) ()
#3  0x0001041c in main ()
(gdb) frame 1
#1  0x00010f44 in unsigned int form_t<int>(mat_ref<int, mat_grid>&, mat_ref<int, mat_grid> const&) ()
(gdb) disass $pc-48,$pc+16
Dump of assembler code from 0x10f14 to 0x10f54:
   0x00010f14 <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1296>:  stw r4,-10(sp)
   0x00010f18 <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1300>:  fldw -10(sp),fr22
   0x00010f1c <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1304>:  xmpyu fr22,fr4,fr10
   0x00010f20 <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1308>:  fstd fr10,-10(sp)
   0x00010f24 <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1312>:  ldw -10(sp),r25
   0x00010f28 <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1316>:  ldw -c(sp),r26
   0x00010f2c <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1320>:  add,l r21,r26,ret1
   0x00010f30 <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1324>:  copy r26,r10
   0x00010f34 <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1328>:  ldw,s ret1(r20),r8
   0x00010f38 <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1332>:  copy r8,r26
   0x00010f3c <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1336>:  b,l 0x12414 <$$divoI+4>,r31
   0x00010f40 <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1340>:  nop
=> 0x00010f44 <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1344>:  stw ret1,-10(sp)
   0x00010f48 <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1348>:  cmpb,<> r0,ret1,0x1117c <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1912>
--Type <RET> for more, q to quit, c to continue without paging--
   0x00010f4c <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1352>:  fldw -10(sp),fr4R
   0x00010f50 <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1356>:  fstw fr22,-10(sp)
End of assembler dump.

form_t is miscompiled by LRA.  The initialization of register r25 is clobbered
by this floating-point to general register copy:

   0x00010f20 <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1308>:  fstd fr10,-10(sp)
   0x00010f24 <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1312>:  ldw -10(sp),r25
   0x00010f28 <_Z6form_tIiEjR7mat_refIT_8mat_gridERKS3_+1316>:  ldw -c(sp),r26

Here is the relevant RTL from the reload pass:

(insn 291 289 3075 78 (set (reg:SI 25 %r25)
        (mem:SI (plus:SI (mult:SI (reg:SI 31 %r31 [353])
                    (const_int 4 [0x4]))
                (reg/f:SI 20 %r20 [orig:415 _57 ] [415])) [1 *_147+0 S4 A32])) "
/home/dave/gnu/gcc/gcc/gcc/testsuite/g++.dg/torture/pr37922.C":356:17 discrim 4
42 {*pa.md:2195}
     (nil))
(insn 3075 291 3134 78 (set (reg:DI 70 %fr23 [349])
        (mult:DI (zero_extend:DI (reg/v:SI 68 %fr22 [orig:246 _449 ] [246]))
            (zero_extend:DI (reg:SI 74 %fr25 [orig:259 prephitmp_473 ] [259]))))
 "/home/dave/gnu/gcc/gcc/gcc/testsuite/g++.dg/torture/pr37922.C":309:27 discrim
3 128 {umulsidi3}
     (nil))
(insn 3134 3075 285 78 (set (reg:DI 25 %r25 [349])
        (reg:DI 70 %fr23 [349])) "/home/dave/gnu/gcc/gcc/gcc/testsuite/g++.dg/to
rture/pr37922.C":309:27 discrim 3 81 {*pa.md:4264}
     (nil))
(insn 285 3134 286 78 (set (reg:SI 31 %r31 [350])
        (plus:SI (reg/v:SI 21 %r21 [orig:202 j ] [202])
            (reg:SI 26 %r26 [orig:349+4 ] [349]))) "/home/dave/gnu/gcc/gcc/gcc/t
estsuite/g++.dg/torture/pr37922.C":309:27 discrim 3 120 {addsi3}
     (nil))
(insn 286 285 284 78 (set (reg:SI 7 %r7 [orig:104 _14 ] [104])
        (mem:SI (plus:SI (mult:SI (reg:SI 31 %r31 [350])
                    (const_int 4 [0x4]))
                (reg/f:SI 20 %r20 [orig:415 _57 ] [415])) [1 *_152+0 S4 A32])) "
/home/dave/gnu/gcc/gcc/gcc/testsuite/g++.dg/torture/pr37922.C":356:28 discrim 2
42 {*pa.md:2195}
     (nil))
(insn 284 286 290 78 (set (reg:SI 10 %r10 [orig:178 _149 ] [178])
        (reg:SI 26 %r26 [orig:349+4 ] [349])) "/home/dave/gnu/gcc/gcc/gcc/testsu
ite/g++.dg/torture/pr37922.C":239:16 42 {*pa.md:2195}
     (expr_list:REG_EQUAL (mult:SI (reg/v:SI 68 %fr22 [orig:246 _449 ] [246])
            (reg:SI 74 %fr25 [orig:259 prephitmp_473 ] [259]))
        (nil)))
(insn 290 284 288 78 (set (reg:SI 26 %r26)
        (reg:SI 7 %r7 [orig:104 _14 ] [104])) "/home/dave/gnu/gcc/gcc/gcc/testsu
ite/g++.dg/torture/pr37922.C":356:17 discrim 4 42 {*pa.md:2195}
     (nil))
(insn 288 290 292 78 (set (reg:SI 8 %r8 [orig:351 _144 ] [351])
        (reg:SI 6 %r6 [orig:416+4 ] [416])) "/home/dave/gnu/gcc/gcc/gcc/testsuit
e/g++.dg/torture/pr37922.C":239:16 42 {*pa.md:2195}
     (nil))
(insn 292 288 294 78 (parallel [
            (set (reg:SI 29 %r29)
                (div:SI (reg:SI 26 %r26)
                    (reg:SI 25 %r25)))
            (clobber (reg:SI 1 %r1 [354]))
            (clobber (reg:SI 11 %r11 [355]))
            (clobber (reg:SI 26 %r26))
            (clobber (reg:SI 25 %r25))
            (clobber (reg:SI 31 %r31))
        ]) "/home/dave/gnu/gcc/gcc/gcc/testsuite/g++.dg/torture/pr37922.C":356:17 discrim 4 130 {*pa.md:5745}
     (expr_list:REG_EQUAL (div:SI (reg:SI 7 %r7 [orig:104 _14 ] [104])
            (reg:SI 25 %r25))
        (nil)))

As a result r25 is zero and we get a divide by zero exception.
Comment 1 John David Anglin 2024-11-25 16:38:42 UTC
This test doesn't fail with legacy reload.
Comment 2 John David Anglin 2024-11-25 17:52:50 UTC
Same error in .s with x86_64-linux-gnu to hppa-linux-gnu cross.  So, it's
unlikely the compiler has been miscompiled.
Comment 3 John David Anglin 2024-11-25 19:09:47 UTC
I suspect explicitly setting hard registers prior to reload confuses
LRA:

;;; Division and mod.
(define_expand "divsi3"
  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
   (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
              (clobber (match_dup 3))
              (clobber (match_dup 4))
              (clobber (reg:SI 26))
              (clobber (reg:SI 25))
              (clobber (match_dup 5))])
   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
Comment 4 Vladimir Makarov 2024-11-28 14:39:08 UTC
(In reply to John David Anglin from comment #3)
> I suspect explicitly setting hard registers prior to reload confuses
> LRA:
> 
> ;;; Division and mod.
> (define_expand "divsi3"
>   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
>    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
>    (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
>               (clobber (match_dup 3))
>               (clobber (match_dup 4))
>               (clobber (reg:SI 26))
>               (clobber (reg:SI 25))
>               (clobber (match_dup 5))])
>    (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]

Thank you for your report and detail analysis.

I'll work on it as it might be a general problem affecting some other targets.
Comment 5 John David Anglin 2024-11-28 15:48:22 UTC
I'm working on trying to split the code after reload.
Comment 6 Vladimir Makarov 2024-11-28 16:39:45 UTC
(In reply to John David Anglin from comment #5)
> I'm working on trying to split the code after reload.

OK. But there is a still LRA bug which incorrectly makes r25 dead before the division insn and analogous problem might occur on other targets.

I hope to fix the LRA bug on this week or on the beginning of the next week.
Comment 7 GCC Commits 2024-11-29 19:59:33 UTC
The master branch has been updated by Vladimir Makarov <vmakarov@gcc.gnu.org>:

https://gcc.gnu.org/g:e79583cef924f5fb5de551bd61da7b5fdee5c690

commit r15-5802-ge79583cef924f5fb5de551bd61da7b5fdee5c690
Author: Vladimir N. Makarov <vmakarov@redhat.com>
Date:   Fri Nov 29 14:58:47 2024 -0500

    [PR117770][LRA]: Check hard regs corresponding insn operands for hard reg clobbers
    
    When LRA processes early clobbered hard regs explicitly present in the
    insn description, it checks that the hard reg is also used as input.
    If the hard reg is not an input also, it is marked as dying.  For the
    check LRA processed only input hard reg also explicitly present in the
    insn description.  For given PR, the hard reg is used as input as the
    operand and is not present explicitly in the insn description and
    therefore LRA marked the hard reg as dying.  This results in wrong
    allocation and wrong code.  The patch solves the problem by processing
    hard regs used as the insn operand.
    
    gcc/ChangeLog:
    
            PR rtl-optimization/117770
            * lra-lives.cc: Include ira-int.h.
            (process_bb_lives): Check hard regs corresponding insn operands
            for dying hard wired reg clobbers.
Comment 8 John David Anglin 2024-12-04 02:23:11 UTC
The change breaks bootstrap.  See PR 117248.

When the instructions to setup the argument registers for millicode
calls are split out before reload, they sometimes are deleted.  This
affects SImode modsi3, umodsi3, divsi3 and udivsi3.
Comment 9 John David Anglin 2024-12-23 22:36:57 UTC
Although a similar fail still occurs (PR117248), the pr37992.C test
no longer fails.