Summary: | [4.9/5/6 Regression]: internal compiler error: Max. number of generated reload insns per insn is achieved (90) | ||
---|---|---|---|
Product: | gcc | Reporter: | Uroš Bizjak <ubizjak> |
Component: | rtl-optimization | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | dimhen, jasonwucj, rth, vmakarov |
Priority: | P4 | Keywords: | ra |
Version: | 4.9.0 | ||
Target Milestone: | 6.0 | ||
Host: | Target: | alpha-linux-gnu | |
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | 2013-04-22 00:00:00 | |
Bug Depends on: | |||
Bug Blocks: | 66207 | ||
Attachments: |
Preprocessed source
WIP patch (fixes "Q" constraint) Preprocessed source for QImode subreg reload problem Reduced testcase for QImode subreg reload problem |
For some reason, LRA does not fix-up (insn 12): (insn 12 11 13 2 (set (reg/v:DI 72 [ hi ]) (unsigned_fix:DI (reg:DF 83 [ D.5360 ]))) ../../../gcc-svn/trunk/libgcc/libgcc2.c:1334 138 {*fix_truncdfdi2} (expr_list:REG_DEAD (reg:DF 83 [ D.5360 ]) (nil))) with a spill to memory via *movdi combo (as is the case with reload): cvttq/c $f10,$f10 # 12 *fix_truncdfdi2 [length = 4] stt $f10,0($30) # 60 *movdi/12 [length = 4] ldq $1,0($30) # 61 *movdi/8 [length = 4] But ignores the above alternative and goes with: 12: r108:DI=uns_fix(r83:DF) REG_DEAD r83:DF Inserting insn reload after: 58: r72:DI=r108:DI Creating newreg=109, assigning class NO_REGS to secondary r109 58: r109:DI=r108:DI Inserting the sec. move after: 59: r72:DI=r109:DI Choosing alt 7 in insn 59: (0) r (1) m Choosing alt 0 in insn 13: (2) rJ Choosing alt 0 in insn 14: (0) =f (1) f Creating newreg=110 from oldreg=72, assigning class FLOAT_REGS to r110 14: r87:DF=float(r110:DI) Inserting insn reload before: 60: r110:DI=r72:DI Creating newreg=111, assigning class NO_REGS to secondary r111 60: r111:DI=r72:DI Inserting the sec. move after: 61: r110:DI=r111:DI Choosing alt 9 in insn 61: (0) *f (1) *fJ Creating newreg=112 from oldreg=111, assigning class FLOAT_REGS to r112 61: r110:DI=r112:DI Inserting insn reload before: 62: r112:DI=r111:DI Choosing alt 9 in insn 62: (0) *f (1) *fJ Creating newreg=113 from oldreg=111, assigning class FLOAT_REGS to r113 62: r112:DI=r113:DI Inserting insn reload before: 63: r113:DI=r111:DI ... This creates a reload loop. Fixed by revert: Author: uros Date: Mon Apr 22 16:58:30 2013 New Revision: 198145 URL: http://gcc.gnu.org/viewcvs?rev=198145&root=gcc&view=rev Log: PR target/57032 Revert: 2013-03-17 Uros Bizjak <ubizjak@gmail.com> * config/alpha/alpha.c (TARGET_LRA_P): New define. Modified: trunk/gcc/ChangeLog trunk/gcc/config/alpha/alpha.c Suspended, until LRA is reenabled on alpha. GCC 4.9.0 has been released GCC 4.9.1 has been released. While trying to switch SH to LRA (PR 55212) I ran into something that looks similar. GCC 4.9.2 has been released. This is not a LRA problem. The problem is in definition of "Q" constraint, AKA "normal_memory_operand": (define_constraint "Q" "@internal A normal_memory_operand" (match_operand 0 "normal_memory_operand")) ;; Return 1 is OP is a memory location that is not a reference ;; (using an AND) to an unaligned location. Take into account ;; what reload will do. (define_special_predicate "normal_memory_operand" (ior (match_test "op = resolve_reload_operand (op), 0") (and (match_code "mem") (match_test "GET_CODE (XEXP (op, 0)) != AND")))) This constraint calls "resolve_reload_operand": /* Used by aligned_memory_operand and unaligned_memory_operand to resolve what reload is going to do with OP if it's a register. */ rtx resolve_reload_operand (rtx op) { if (reload_in_progress) { rtx tmp = op; if (GET_CODE (tmp) == SUBREG) tmp = SUBREG_REG (tmp); if (REG_P (tmp) && REGNO (tmp) >= FIRST_PSEUDO_REGISTER) { op = reg_equiv_memory_loc (REGNO (tmp)); if (op == 0) return 0; } } return op; } LRA does not set reload_in_progress, and also doesn't allow to use reg_equiv_memory_loc. So, the "Q" constraint is effectively dead when LRA is used. Using the "m" constraint instead of "Q" in: (define_insn "*movdi" [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,r, m, *f,*f, Q, r,*f") (match_operand:DI 1 "input_operand" "rJ,K,L,T,s,n,s,m,rJ,*fJ, Q,*f,*f, r"))] "register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode)" solves this particular failure. Probably we need to redefine "Q" as a memory constraint. Also {aligned,unaligned,normal}_memory_operand shouldn't use resolve_reload_operand anymore. Richard, do you have any insight into this issue? I think all of the bits touching reload internals stems from the non-existence of define_memory_constraint when the port was first written. I suspect that this is fixable with nothing more than (define_memory_constraint "Q" "@internal normal memory operand" (and (match_code "mem") (match_test "GET_CODE (XEXP (op, 0)) != AND") (match_test "memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0), MEM_ADDR_SPACE (op))"))) (In reply to Richard Henderson from comment #9) > I think all of the bits touching reload internals stems > from the non-existence of define_memory_constraint when > the port was first written. > > I suspect that this is fixable with nothing more than > > (define_memory_constraint "Q" > "@internal normal memory operand" > (and (match_code "mem") > (match_test "GET_CODE (XEXP (op, 0)) != AND") > (match_test "memory_address_addr_space_p > (GET_MODE (op), XEXP (op, 0), > MEM_ADDR_SPACE (op))"))) Great, this fix brings bootstrap way further to libgomp, but now crashes with: /space/homedirs/uros/gcc-svn/trunk/libgomp/team.c: In function ‘gomp_team_start’: /space/homedirs/uros/gcc-svn/trunk/libgomp/team.c:836:1: internal compiler error: Max. number of generated reload insns per insn is achieved (90) However, this is different problem, and this one indeed looks like RA problem. There, RA wants to reload: (insn 280 2259 279 17 (set (reg:DI 364) (ashift:DI (zero_extend:DI (subreg/s/u:QI (reg/v:DI 98 [ bind ]) 0)) (ashift:DI (reg/f:DI 362) (const_int 3 [0x3])))) /space/homedirs/uros/gcc-svn/trunk/libgomp/team.c:334 83 {insbl} (nil)) and creates reload loop trying to move QImode subreg of DImode value to QI reg: Choosing alt 0 in insn 280: (0) =r (1) r (2) rI {insbl} Creating newreg=1020, assigning class GENERAL_REGS to r1020 280: r364:DI=zero_extend(r1020:QI)<<r362:DI<<0x3 Inserting insn reload before: 2443: r1020:QI=r98:DI#0 0 Non pseudo reload: reject++ alt=0,overall=607,losers=1,rld_nregs=1 0 Non pseudo reload: reject++ alt=1: Bad operand -- refuse Choosing alt 0 in insn 2443: (0) =r (1) rJ {*movqi} Creating newreg=1021, assigning class GENERAL_REGS to r1021 2443: r1020:QI=r1021:QI Inserting insn reload before: 2444: r1021:QI=r98:DI#0 0 Non pseudo reload: reject++ alt=0,overall=607,losers=1,rld_nregs=1 0 Non pseudo reload: reject++ alt=1: Bad operand -- refuse Choosing alt 0 in insn 2444: (0) =r (1) rJ {*movqi} Creating newreg=1022, assigning class GENERAL_REGS to r1022 2444: r1021:QI=r1022:QI Inserting insn reload before: ... I'll post the WIP patch and preprocessed source in a moment. Created attachment 35281 [details]
WIP patch (fixes "Q" constraint)
Created attachment 35282 [details]
Preprocessed source for QImode subreg reload problem
$ /space/uros/gcc-build-nobwx/gcc/cc1 -O2 -quiet team.i
/space/homedirs/uros/gcc-svn/trunk/libgomp/team.c: In function ‘gomp_team_start’:
/space/homedirs/uros/gcc-svn/trunk/libgomp/team.c:836:1: internal compiler error: Max. number of generated reload insns per insn is achieved (90)
}
^
0x1209d580b lra_constraints(bool)
/space/homedirs/uros/gcc-svn/trunk/gcc/lra-constraints.c:4366
0x1209b5f0b lra(_IO_FILE*)
/space/homedirs/uros/gcc-svn/trunk/gcc/lra.c:2315
0x12093b4e7 do_reload
/space/homedirs/uros/gcc-svn/trunk/gcc/ira.c:5418
0x12093bc1f execute
/space/homedirs/uros/gcc-svn/trunk/gcc/ira.c:5589
Please submit a full bug report,
this problem can also be triggered by a cross from x86_64-linux-gnu.
(In reply to Uroš Bizjak from comment #12) > this problem can also be triggered by a cross from x86_64-linux-gnu. (gdb) f 1 #1 0x00000000008d5315 in lra_constraints (first_p=true) at /home/uros/gcc-svn/trunk/gcc/lra-constraints.c:4366 4366 MAX_RELOAD_INSNS_NUMBER); (gdb) p debug_rtx (curr_insn) (insn 2226 1952 2225 17 (set (reg:QI 1110) (subreg/s/u:QI (reg/v:DI 98 [ bind ]) 0)) /space/homedirs/uros/gcc-svn/trunk/libgomp/team.c:334 229 {*movqi} (nil)) $5 = void Created attachment 35312 [details]
Reduced testcase for QImode subreg reload problem
Reduced testcase, compile with -O2 for alpha-linux-target:
tt.c: In function ‘gomp_team_start’:
tt.c:80:1: internal compiler error: Max. number of generated reload insns per insn is achieved (90)
}
^
0x8d5314 lra_constraints(bool)
/home/uros/gcc-svn/trunk/gcc/lra-constraints.c:4366
0x8c1d8c lra(_IO_FILE*)
/home/uros/gcc-svn/trunk/gcc/lra.c:2315
0x883879 do_reload
/home/uros/gcc-svn/trunk/gcc/ira.c:5418
0x883879 execute
/home/uros/gcc-svn/trunk/gcc/ira.c:5589
Please submit a full bug report,
Author: uros Date: Mon May 18 16:34:23 2015 New Revision: 223298 URL: https://gcc.gnu.org/viewcvs?rev=223298&root=gcc&view=rev Log: PR target/57032 * config/alpha/constraints.md (Q): Rewrite as define_memory_constraint. Check for a memory location that is not a reference (using an AND) to an unaligned location here. * config/alpha/predicates.md (normal_memory_operand): Remove. Modified: trunk/gcc/ChangeLog trunk/gcc/config/alpha/constraints.md trunk/gcc/config/alpha/predicates.md This particular problem is now fixed. |
Created attachment 29914 [details] Preprocessed source Attached preprocessed source fails to compile for alpha-linux-gnu target. The failure can be reproduced on a cross from x86_64-pc-linux-gnu, configured with: ../gcc-svn/trunk/configure --target=alpha-linux-gnu --with-long-double-128 ~/gcc-build-alpha/gcc/xgcc -B ~/gcc-build-alpha/gcc -O2 libgcc2.i ../../../gcc-svn/trunk/libgcc/libgcc2.c: In function ‘__fixunssfti’: ../../../gcc-svn/trunk/libgcc/libgcc2.c:1382:1: internal compiler error: Max. number of generated reload insns per insn is achieved (90) 0x7aa777 lra_constraints(bool) ../../gcc-svn/trunk/gcc/lra-constraints.c:3538 0x79ce9c lra(_IO_FILE*) ../../gcc-svn/trunk/gcc/lra.c:2268 0x7645c0 do_reload ../../gcc-svn/trunk/gcc/ira.c:4619 0x7645c0 rest_of_handle_reload ../../gcc-svn/trunk/gcc/ira.c:4731 Please submit a full bug report, with preprocessed source if appropriate.