Bug 57032 - [4.9/5/6 Regression]: internal compiler error: Max. number of generated reload insns per insn is achieved (90)
Summary: [4.9/5/6 Regression]: internal compiler error: Max. number of generated reloa...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.9.0
: P4 normal
Target Milestone: 6.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ra
Depends on:
Blocks: 66207
  Show dependency treegraph
 
Reported: 2013-04-22 14:35 UTC by Uroš Bizjak
Modified: 2015-05-19 16:00 UTC (History)
4 users (show)

See Also:
Host:
Target: alpha-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-04-22 00:00:00


Attachments
Preprocessed source (26.09 KB, application/octet-stream)
2013-04-22 14:35 UTC, Uroš Bizjak
Details
WIP patch (fixes "Q" constraint) (862 bytes, patch)
2015-04-09 19:48 UTC, Uroš Bizjak
Details | Diff
Preprocessed source for QImode subreg reload problem (21.04 KB, text/plain)
2015-04-09 19:52 UTC, Uroš Bizjak
Details
Reduced testcase for QImode subreg reload problem (633 bytes, text/plain)
2015-04-14 16:48 UTC, Uroš Bizjak
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Uroš Bizjak 2013-04-22 14:35:01 UTC
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.
Comment 1 Uroš Bizjak 2013-04-22 15:20:38 UTC
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.
Comment 2 Uroš Bizjak 2013-04-22 17:22:17 UTC
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
Comment 3 Uroš Bizjak 2013-04-22 21:00:26 UTC
Suspended, until LRA is reenabled on alpha.
Comment 4 Jakub Jelinek 2014-04-22 11:37:06 UTC
GCC 4.9.0 has been released
Comment 5 Jakub Jelinek 2014-07-16 13:30:56 UTC
GCC 4.9.1 has been released.
Comment 6 Oleg Endo 2014-09-13 23:19:58 UTC
While trying to switch SH to LRA (PR 55212) I ran into something that looks similar.
Comment 7 Jakub Jelinek 2014-10-30 10:41:19 UTC
GCC 4.9.2 has been released.
Comment 8 Uroš Bizjak 2015-04-08 08:28:46 UTC
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?
Comment 9 Richard Henderson 2015-04-09 17:31:25 UTC
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))")))
Comment 10 Uroš Bizjak 2015-04-09 19:46:53 UTC
(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.
Comment 11 Uroš Bizjak 2015-04-09 19:48:35 UTC
Created attachment 35281 [details]
WIP patch (fixes "Q" constraint)
Comment 12 Uroš Bizjak 2015-04-09 19:52:59 UTC
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.
Comment 13 Uroš Bizjak 2015-04-09 19:56:39 UTC
(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
Comment 14 Uroš Bizjak 2015-04-14 16:48:48 UTC
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,
Comment 15 uros 2015-05-18 16:34:55 UTC
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
Comment 16 Uroš Bizjak 2015-05-18 17:40:52 UTC
This particular problem is now fixed.