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.
This test doesn't fail with legacy reload.
Same error in .s with x86_64-linux-gnu to hppa-linux-gnu cross. So, it's unlikely the compiler has been miscompiled.
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))]
(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.
I'm working on trying to split the code after reload.
(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.
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.
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.
Although a similar fail still occurs (PR117248), the pr37992.C test no longer fails.