Commit 5b43fed1 by Richard Henderson

re PR rtl-optimization/5878 (gcc 3.1 breaks on C code generated by the Mercury compiler)

	PR 5878
	* config/arc/arc.h, config/cris/cris.h, config/i386/i386.h,
	config/m68k/m68k.h, config/s390/s390.h, config/sparc/sparc.h
	(PIC_OFFSET_TABLE_REGNUM): Conditionalize on flag_pic.

	* config/arm/arm.h config/i386/i386.h, config/m68k/m68k.h,
	config/sparc/sparc.h (CONDITIONAL_REGISTER_USAGE): Set
	PIC_OFFSET_TABLE_REGNUM based on INVALID_REGNUM not flag_pic.

	* config/arc/arc.h (CONDITIONAL_REGISTER_USAGE): New.
	* config/arm/arm.c (arm_pic_register): Init to INVALID_REGNUM.
	(arm_override_options): Set arm_pic_register if TARGET_APCS_STACK
	also.  Don't set it if not flag_pic.
	* config/i386/i386.c (ix86_save_reg): Trust PIC_OFFSET_TABLE_REGNUM
	to be INVALID_REGNUM when not used.

	* gcc.dg/20020312-2.c: New.

From-SVN: r50713
parent 56d4fe31
2002-03-12 Richard Henderson <rth@redhat.com>
* config/arc/arc.h, config/cris/cris.h, config/i386/i386.h,
config/m68k/m68k.h, config/s390/s390.h, config/sparc/sparc.h
(PIC_OFFSET_TABLE_REGNUM): Conditionalize on flag_pic.
* config/arm/arm.h config/i386/i386.h, config/m68k/m68k.h,
config/sparc/sparc.h (CONDITIONAL_REGISTER_USAGE): Set
PIC_OFFSET_TABLE_REGNUM based on INVALID_REGNUM not flag_pic.
* config/arc/arc.h (CONDITIONAL_REGISTER_USAGE): New.
* config/arm/arm.c (arm_pic_register): Init to INVALID_REGNUM.
(arm_override_options): Set arm_pic_register if TARGET_APCS_STACK
also. Don't set it if not flag_pic.
* config/i386/i386.c (ix86_save_reg): Trust PIC_OFFSET_TABLE_REGNUM
to be INVALID_REGNUM when not used.
2002-03-13 Aldy Hernandez <aldyh@redhat.com>
* expmed.c (store_bit_field): Reset alias set for memory.
......
......@@ -355,6 +355,16 @@ if (GET_MODE_CLASS (MODE) == MODE_INT \
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, \
27, 28, 29, 30 }
/* Macro to conditionally modify fixed_regs/call_used_regs. */
#define CONDITIONAL_REGISTER_USAGE \
do { \
if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
{ \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
} \
} while (0)
/* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE.
This is ordinarily the length in words of a value of mode MODE
......@@ -1152,7 +1162,7 @@ do { \
pointer and frame pointer registers. If this macro is not defined, it
is up to the machine-dependent files to allocate such a register (if
necessary). */
#define PIC_OFFSET_TABLE_REGNUM 26
#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 26 : INVALID_REGNUM)
/* Define this macro if the register defined by PIC_OFFSET_TABLE_REGNUM is
clobbered by calls. Do not define this macro if PIC_OFFSET_TABLE_REGNUM
......
......@@ -268,7 +268,7 @@ enum machine_mode output_memory_reference_mode;
/* The register number to be used for the PIC offset register. */
const char * arm_pic_register_string = NULL;
int arm_pic_register = 9;
int arm_pic_register = INVALID_REGNUM;
/* Set to 1 when a return insn is output, this means that the epilogue
is not needed. */
......@@ -651,8 +651,8 @@ arm_override_options ()
/* If stack checking is disabled, we can use r10 as the PIC register,
which keeps r9 available. */
if (flag_pic && !TARGET_APCS_STACK)
arm_pic_register = 10;
if (flag_pic)
arm_pic_register = TARGET_APCS_STACK ? 9 : 10;
if (TARGET_APCS_FLOAT)
warning ("passing floating point arguments in fp regs not yet supported");
......@@ -713,15 +713,13 @@ arm_override_options ()
if (arm_pic_register_string != NULL)
{
int pic_register;
int pic_register = decode_reg_name (arm_pic_register_string);
if (!flag_pic)
warning ("-mpic-register= is useless without -fpic");
pic_register = decode_reg_name (arm_pic_register_string);
/* Prevent the user from choosing an obviously stupid PIC register. */
if (pic_register < 0 || call_used_regs[pic_register]
else if (pic_register < 0 || call_used_regs[pic_register]
|| pic_register == HARD_FRAME_POINTER_REGNUM
|| pic_register == STACK_POINTER_REGNUM
|| pic_register >= PC_REGNUM)
......
......@@ -838,7 +838,7 @@ extern const char * structure_size_string;
regno <= LAST_ARM_FP_REGNUM; ++regno) \
fixed_regs[regno] = call_used_regs[regno] = 1; \
} \
if (flag_pic) \
if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
{ \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
......
......@@ -1468,7 +1468,7 @@ call_ ## FUNC (void) \
/* Node: PIC */
#define PIC_OFFSET_TABLE_REGNUM 0
#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 0 : INVALID_REGNUM)
#define LEGITIMATE_PIC_OPERAND_P(X) cris_legitimate_pic_operand (X)
......
......@@ -3880,9 +3880,7 @@ ix86_save_reg (regno, maybe_eh_return)
int regno;
int maybe_eh_return;
{
if (flag_pic
&& ! TARGET_64BIT
&& regno == PIC_OFFSET_TABLE_REGNUM
if (regno == PIC_OFFSET_TABLE_REGNUM
&& (current_function_uses_pic_offset_table
|| current_function_uses_const_pool
|| current_function_calls_eh_return))
......
......@@ -937,7 +937,7 @@ do { \
call_used_regs[i] = (call_used_regs[i] \
& (TARGET_64BIT ? 2 : 1)) != 0; \
} \
if (flag_pic && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
{ \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
......@@ -1113,11 +1113,11 @@ do { \
#define STATIC_CHAIN_REGNUM (TARGET_64BIT ? FIRST_REX_INT_REG + 10 - 8 : 2)
/* Register to hold the addressing base for position independent
code access to data items.
We don't use PIC pointer for 64bit mode. Define the regnum to
dummy value to prevent gcc from pessimizing code dealing with EBX.
*/
#define PIC_OFFSET_TABLE_REGNUM (TARGET_64BIT ? INVALID_REGNUM : 3)
code access to data items. We don't use PIC pointer for 64bit
mode. Define the regnum to dummy value to prevent gcc from
pessimizing code dealing with EBX. */
#define PIC_OFFSET_TABLE_REGNUM \
(TARGET_64BIT || !flag_pic ? INVALID_REGNUM : 3)
/* Register in which address to store a structure value
arrives in the function. On the 386, the prologue
......
......@@ -387,7 +387,7 @@ extern int target_flags;
#endif
/* This defines the register which is used to hold the offset table for PIC. */
#define PIC_OFFSET_TABLE_REGNUM 13
#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 13 : INVALID_REGNUM)
#ifndef SUPPORT_SUN_FPA
......@@ -487,9 +487,9 @@ extern int target_flags;
if (TEST_HARD_REG_BIT (x, i)) \
fixed_regs[i] = call_used_regs[i] = 1; \
} \
if (flag_pic) \
if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] \
= call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;\
= call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
}
#else
#define CONDITIONAL_REGISTER_USAGE \
......@@ -503,9 +503,9 @@ extern int target_flags;
if (TEST_HARD_REG_BIT (x, i)) \
fixed_regs[i] = call_used_regs[i] = 1; \
} \
if (flag_pic) \
if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] \
= call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;\
= call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
}
#endif /* defined SUPPORT_SUN_FPA */
......
......@@ -249,7 +249,7 @@ if (INTEGRAL_MODE_P (MODE) && \
GPR 14: Return registers holds the return address
GPR 15: Stack pointer */
#define PIC_OFFSET_TABLE_REGNUM 12
#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 12 : INVALID_REGNUM)
#define BASE_REGISTER 13
#define RETURN_REGNUM 14
#define STACK_POINTER_REGNUM 15
......
......@@ -984,7 +984,7 @@ if (TARGET_ARCH64 \
#define CONDITIONAL_REGISTER_USAGE \
do \
{ \
if (flag_pic) \
if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
{ \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
......@@ -1159,7 +1159,7 @@ extern int sparc_mode_class[];
/* Register which holds offset table for position-independent
data references. */
#define PIC_OFFSET_TABLE_REGNUM 23
#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 23 : INVALID_REGNUM)
/* Pick a default value we can notice from override_options:
!v9: Default is on.
......
/* PR 5878.
We ICEd in verify_local_live_at_start because we incorrectly forced
the PIC register live between BAR and BAZ. We did this because the
definition of PIC_OFFSET_TABLE_REGNUM was incorrectly not INVALID_REGNUM
when !flag_pic for most targets. */
/* { dg-do run } */
/* { dg-options "-O -fno-pic" } */
#if #cpu(a29k)
/* No pic register. */
#elif defined(__alpha__)
/* PIC register is $29, but is used even without -fpic. */
#elif defined(__arc__)
# define PIC_REG "26"
#elif defined(__arm__)
# define PIC_REG "9"
#elif defined(AVR)
/* No pic register. */
#elif defined(__clipper__)
/* No pic register. */
#elif defined(__convex__)
/* No pic register. */
#elif defined(__cris__)
# define PIC_REG "0"
#elif defined(__D30V__)
/* No pic register. */
#elif defined(__dsp1600__)
/* No pic register. */
#elif defined(__elxsi__)
/* No pic register. */
#elif defined(__fr30__)
/* No pic register. */
#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__)
/* No pic register. */
#elif #cpu(i370)
/* No pic register. */
#elif defined(__i386__)
# define PIC_REG "ebx"
#elif defined(__i860__)
/* No pic register. */
#elif defined(__i960__)
/* No pic register. */
#elif defined(__ia64__)
/* PIC register is r1, but is used even without -fpic. */
#elif defined(__M32R__)
/* No pic register. */
#elif defined(__m68k__)
# define PIC_REG "a5"
#elif defined(__m88k__)
# define PIC_REG "25"
#elif defined(__mc68hc1x__)
/* No pic register. */
#elif defined(__mcore__)
/* No pic register. */
#elif defined(__mips__)
/* PIC register is $28, but is used even without -fpic. */
#elif defined(__mn10200__)
/* No pic register. */
#elif defined(__mn10300__)
/* No pic register. */
#elif #cpu(ns32k)
/* No pic register. */
#elif defined(__parisc__)
/* PIC register is %r27 or %r19, but is used even without -fpic. */
#elif defined(__pdp11__)
/* No pic register. */
#elif defined(__pj__)
/* No pic register. */
#elif defined(__powerpc__)
# ifdef __darwin__
# define PIC_REG "31"
# else
# define PIC_REG "30"
# endif
#elif defined(__ibm032__) /* aka romp */
/* No pic register. */
#elif defined(__s390__)
# define PIC_REG "12"
#elif defined(__sparc__)
# define PIC_REG "l7"
#elif defined(__v850)
/* No pic register. */
#elif defined(__vax__)
/* No pic register. */
#elif defined(__we32000__)
/* No pic register. */
#elif defined(__xstormy16__)
/* No pic register. */
#elif defined(__XTENSA__)
/* No pic register. */
#else
# error "Modify the test for your target."
#endif
#ifdef PIC_REG
register void *reg __asm__(PIC_REG);
#else
/* We really need a global register variable set to the PIC register
to expose the bug. Oh well, let the test case not fail. */
static void *reg;
#endif
void * __attribute__((noinline))
dummy (void *x)
{
return x;
}
void
f (void)
{
goto *dummy (&&bar);
for (;;)
{
foo:
reg = (void *) 1;
if (!reg)
goto baz;
reg = &&foo;
}
bar:
baz:
reg = 0;
}
int
main()
{
void *old_reg = reg;
reg = (void *) 1;
f ();
if (reg)
abort ();
reg = old_reg;
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment