This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR target/33923


This is a regression present in 4.3 on IA-64/Linux.  The compiler chokes on an 
invalid instruction generated by reload at -O3

pr33923.c: In function 'brl_readCommand':
pr33923.c:73: error: insn does not satisfy its constraints:
(insn 8165 2623 3131 8 pr33923.c:50 (set (reg:SI 63 loc31)
        (reg:SI 326 b6 [1409])) 4 {*movsi_internal} (nil))
pr33923.c:73: internal compiler error: in reload_cse_simplify_operands, at 
postreload.c:395
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

because the branch register cannot be accessed in any other modes than DImode.
This is exposed by PRE generating a bunch of SSA names and thus stressing the 
register allocator.


In .lreg:

(insn 3130 5304 4695 10 pr33923.c:50 (set (subreg:DI (reg:SI 1409) 0)
        (and:DI (reg:DI 1408)
            (subreg:DI (reg:SI 1358 [ currentModifiers.24 ]) 0))) 293 {anddi3} 
(expr_list:REG_DEAD (reg:DI 1408)
        (nil)))

(insn 3131 2623 4356 10 pr33923.c:50 (set (reg:BI 1410)
        (ne:BI (reg:SI 1409)
            (const_int 0 [0x0]))) 298 {*cmpsi_normal} (expr_list:REG_DEAD 
(reg:SI 1409)
        (nil)))

  Register 1409 costs: ADDL_REGS:0 GR_REGS:0 FP_REGS:100 FR_REGS:100 
GR_AND_BR_REGS:100 GR_AND_FR_REGS:100 ALL_REGS:100 MEM:200
;; Register 1409 in 326.

In .greg:

Reloads for insn # 3131
Reload 0: reload_in (SI) = (reg:SI 326 b6 [1409])
	GR_REGS, RELOAD_FOR_INPUT (opnum = 2)
	reload_in_reg: (reg:SI 326 b6 [1409])
	reload_reg_rtx: (reg:SI 63 loc31)

(insn 8165 2623 3131 8 pr33923.c:50 (set (reg:SI 63 loc31)
        (reg:SI 326 b6 [1409])) 4 {*movsi_internal} (nil))

(insn 3131 8165 8166 8 pr33923.c:50 (set (reg:BI 264 p8 [1410])
        (ne:BI (reg:SI 63 loc31)
            (const_int 0 [0x0]))) 298 {*cmpsi_normal} (nil))


Fixed by preventing the BR_REGS class from being selected if the pseudo is
subject to a mode change.

Bootstrapped/regtested on ia64-suse-linux, OK for mainline?


2007-11-03  Eric Botcazou  <ebotcazou@libertysurf.fr

	PR target/33923
	* config/ia64/ia64.h (CANNOT_CHANGE_MODE_CLASS): Forbid mode changes
	for registers in BR_REGS class.


2007-11-03  Eric Botcazou  <ebotcazou@libertysurf.fr

	* gcc.c-torture/compile/20071103-1.c: New test.


-- 
Eric Botcazou
Index: config/ia64/ia64.h
===================================================================
--- config/ia64/ia64.h	(revision 129844)
+++ config/ia64/ia64.h	(working copy)
@@ -887,12 +887,16 @@ enum reg_class
    : (((CLASS) == FR_REGS || (CLASS) == FP_REGS) && (MODE) == XCmode) ? 2 \
    : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
 
-/* In FP regs, we can't change FP values to integer values and vice versa,
+/* In BR regs, we can't change the DImode at all.
+   In FP regs, we can't change FP values to integer values and vice versa,
    but we can change e.g. DImode to SImode, and V2SFmode into DImode.  */
 
 #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) 		\
-  (SCALAR_FLOAT_MODE_P (FROM) != SCALAR_FLOAT_MODE_P (TO)	\
-   ? reg_classes_intersect_p (CLASS, FR_REGS) : 0)
+  (reg_classes_intersect_p (CLASS, BR_REGS)			\
+   ? (FROM) != (TO)						\
+   : (SCALAR_FLOAT_MODE_P (FROM) != SCALAR_FLOAT_MODE_P (TO)	\
+      ? reg_classes_intersect_p (CLASS, FR_REGS)		\
+      : 0))
 
 /* Basic Stack Layout */
 
/* PR target/33923 */
/* Testcase by Martin Michlmayr <tbm@cyrius.com> */

static int pendingCommand;
static int currentModifiers;
typedef struct
{
  int (*updateKeys) (int *keyPressed);
}
ProtocolOperations;
static const ProtocolOperations *protocol;
brl_readCommand (void)
{
  unsigned long int keys;
  int command;
  int keyPressed;
  unsigned char routingKeys[200];
  int routingKeyCount;
  signed char rightVerticalSensor;
  if (pendingCommand != (-1))
    {
      return command;
    }
  if (!protocol->updateKeys (&keyPressed))
    {
      if (rightVerticalSensor >= 0)
        keys |= 1;
      if ((routingKeyCount == 0) && keys)
        {
          if (currentModifiers)
            {
            doChord:switch (keys);
            }
          else
            {
            doCharacter:
              command = 0X2200;
              if (keys & 0X01UL)
                command |= 0001;
              if (keys & 0X02UL)
                command |= 0002;
              if (keys & 0X04UL)
                command |= 0004;
              if (keys & 0X08UL)
                command |= 0010;
              if (keys & 0X10UL)
                command |= 0020;
              if (keys & 0X20UL)
                command |= 0040;
              if (currentModifiers & (0X0010 | 0X0200))
                command |= 0100;
              if (currentModifiers & 0X0040)
                command |= 0200;
              if (currentModifiers & 0X0100)
                command |= 0X020000;
              if (currentModifiers & 0X0400)
                command |= 0X080000;
              if (currentModifiers & 0X0800)
                command |= 0X040000;
            }
          unsigned char key1 = routingKeys[0];
          if (key1 == 0)
            {
            } else if (key1 == 1)
            if (keys)
              {
                currentModifiers |= 0X0010;
                goto doCharacter;
              }
        }
    }
  return command;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]