C:\devel\gccnew\gcc>gccmvs -DUSE_MEMMGR -Os -S -ansi -pedantic-errors -DHAVE_CON
FIG_H -DIN_GCC -DPUREISO -I ../../pdos/pdpclib -I . -I config/i370 -I
../include
         varasm.c
(insn 117 429 118 7 (parallel [
            (set (reg:SI 64)
                (compare:SI (mem/s:BLK (plus:SI (reg/f:SI 21
virtual-stack-vars)

(const_int 456 [0x1c8])) [232 value+0 S196 A64])
                    (mem:BLK (plus:SI (reg/v/f:SI 61 [ desc ])
                            (const_int 8 [0x8])) [0 A8])))
            (use (const_int 196 [0xc4]))
        ]) -1 (nil)
    (nil))
varasm.c: In function `force_const_mem':
varasm.c:3021: internal compiler error: in instantiate_virtual_regs_lossage,
at function.c:3767

OK, so what goes on here is that GCC attempts to replace the "virtual"
register 21 (virtual-stack-vars) with some real register, that is
frame pointer + STARTING_FRAME_OFFSET.  It seems for the i370 port,
this should resolve to
 register 13 + STACK_POINTER_OFFSET + current_function_outgoing_args_size

Overall, the middle-end would therefore replace "reg 21 + 456" with
"reg 13 + X", where X is constant computed from 456 + STACK_POINTER_OFFSET
+ current_function_outgoing_args_size.

It will then re-process the insn pattern constraints to verify that the
resulting insn is still valid.  At this stage, it appears we're running
into the above error.  I'm not quite sure why this would be case, this
will require some further debugging why the insn was not recognized ...

This mystery is finally solved.

The previous workaround I had in place failed when I tried to do an
unoptimized compile of varasm.c.  I found this out when I tried speeding
up the experimental configure/make process.  However, since it was
occurring with unoptimized compiles, I thought it would be easier to
track down, and indeed, I found out that the memcmp was only
failing for values 128 and above. 127 was working fine.  That made me
suspect a signed char vs unsigned char problem.

And it's the "QI" below that was causing the grief ...

*** 699,711 ****
     {
       op2 = gen_rtx_MEM (BLKmode, copy_to_mode_reg (SImode, op2));
     }
!
!   /* one circumstance has been found where this short comparison
!      causes an internal error. Could be related to the fact that
!      both displacements were non-zero, which is unusual. So check
!      for that */
!   if (((iv1 == 0) || (iv2 == 0)) &&
!       GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) < 256)
     {
       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
               gen_rtx_SET (VOIDmode, operands[0],
--- 697,705 ----
     {
       op2 = gen_rtx_MEM (BLKmode, copy_to_mode_reg (SImode, op2));
     }
!
!   if (GET_CODE (operands[3]) == CONST_INT
!       && (unsigned)INTVAL (operands[3]) < 256)
     {
       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
               gen_rtx_SET (VOIDmode, operands[0],
***************
*** 747,753 ****
   [(set (match_operand:SI 0 "register_operand" "=d")
       (compare:SI (match_operand:BLK 1 "s_operand" "m")
                (match_operand:BLK 2 "s_operand" "m")))
!    (use (match_operand:QI 3 "immediate_operand" "I"))]
   "((unsigned) INTVAL (operands[3]) < 256)"
   "*
 {
--- 741,747 ----
   [(set (match_operand:SI 0 "register_operand" "=d")
       (compare:SI (match_operand:BLK 1 "s_operand" "m")
                (match_operand:BLK 2 "s_operand" "m")))
!    (use (match_operand:SI 3 "immediate_operand" "I"))]
   "((unsigned) INTVAL (operands[3]) < 256)"
   "*
 {

The QI must be a signed char, and thus rejecting any value greater than 127.
As you can see, I changed it to SI, which, with the constraints and tests
in place, should be fine.

Just to be sure, I did a before and after comparison of the generated
assembler for all of GCC (3.4.6) and it all checked out fine.  :-)

BFN.  Paul.

Reply via email to