This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR target/33923
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 3 Nov 2007 21:41:57 +0100
- Subject: [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;
}