Commit 215b063c by Paolo Bonzini Committed by Maxim Kuvyrkov

target.h (unspec_may_trap_p): New target hook.

2007-10-16  Paolo Bonzini  <bonzini@gnu.org>
	    Maxim Kuvyrkov  <maxim@codesourcery.com>

	* target.h (unspec_may_trap_p): New target hook.
	* target-def.h (TARGET_UNSPEC_MAY_TRAP_P): New macro.
	* targhooks.c (default_unspec_may_trap_p): Default implementation of
	the hook.
	* targhooks.h (default_unspec_may_trap_p): Declare it.
	* doc/tm.texi (TARGET_UNSPEC_MAY_TRAP_P): Document new hook.
	* rtlanal.c (may_trap_p_1): Use new hook.  Make global.
	* rtl.h (may_trap_p_1): Declare.
	
	* config/ia64/ia64.c (ia64_unspec_may_trap_p): New function to
	override default hook implementation.
	(TARGET_UNSPEC_MAY_TRAP_P): Override default implementation of the
	hook.
	
	* gcc.target/ia64/20040709-2.c: New test.

Co-Authored-By: Maxim Kuvyrkov <maxim@codesourcery.com>

From-SVN: r129378
parent 50f2fe3a
2007-10-16 Paolo Bonzini <bonzini@gnu.org>
Maxim Kuvyrkov <maxim@codesourcery.com>
* target.h (unspec_may_trap_p): New target hook.
* target-def.h (TARGET_UNSPEC_MAY_TRAP_P): New macro.
* targhooks.c (default_unspec_may_trap_p): Default implementation of
the hook.
* targhooks.h (default_unspec_may_trap_p): Declare it.
* doc/tm.texi (TARGET_UNSPEC_MAY_TRAP_P): Document new hook.
* rtlanal.c (may_trap_p_1): Use new hook. Make global.
* rtl.h (may_trap_p_1): Declare.
* config/ia64/ia64.c (ia64_unspec_may_trap_p): New function to
override default hook implementation.
(TARGET_UNSPEC_MAY_TRAP_P): Override default implementation of the
hook.
2007-10-16 Manuel Lopez-Ibanez <manu@gcc.gnu.org> 2007-10-16 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
* doc/invoke.texi (Wextra): Move it just after Wall, list the * doc/invoke.texi (Wextra): Move it just after Wall, list the
...@@ -203,6 +203,7 @@ static int ia64_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, ...@@ -203,6 +203,7 @@ static int ia64_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
static bool ia64_function_ok_for_sibcall (tree, tree); static bool ia64_function_ok_for_sibcall (tree, tree);
static bool ia64_return_in_memory (const_tree, const_tree); static bool ia64_return_in_memory (const_tree, const_tree);
static bool ia64_rtx_costs (rtx, int, int, int *); static bool ia64_rtx_costs (rtx, int, int, int *);
static int ia64_unspec_may_trap_p (const_rtx, unsigned);
static void fix_range (const char *); static void fix_range (const char *);
static bool ia64_handle_option (size_t, const char *, int); static bool ia64_handle_option (size_t, const char *, int);
static struct machine_function * ia64_init_machine_status (void); static struct machine_function * ia64_init_machine_status (void);
...@@ -409,6 +410,9 @@ static const struct attribute_spec ia64_attribute_table[] = ...@@ -409,6 +410,9 @@ static const struct attribute_spec ia64_attribute_table[] =
#undef TARGET_ADDRESS_COST #undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST hook_int_rtx_0 #define TARGET_ADDRESS_COST hook_int_rtx_0
#undef TARGET_UNSPEC_MAY_TRAP_P
#define TARGET_UNSPEC_MAY_TRAP_P ia64_unspec_may_trap_p
#undef TARGET_MACHINE_DEPENDENT_REORG #undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG ia64_reorg #define TARGET_MACHINE_DEPENDENT_REORG ia64_reorg
...@@ -5073,6 +5077,29 @@ ia64_secondary_reload_class (enum reg_class class, ...@@ -5073,6 +5077,29 @@ ia64_secondary_reload_class (enum reg_class class,
} }
/* Implement targetm.unspec_may_trap_p hook. */
static int
ia64_unspec_may_trap_p (const_rtx x, unsigned flags)
{
if (GET_CODE (x) == UNSPEC)
{
switch (XINT (x, 1))
{
case UNSPEC_LDA:
case UNSPEC_LDS:
case UNSPEC_LDSA:
case UNSPEC_LDCCLR:
case UNSPEC_CHKACLR:
case UNSPEC_CHKS:
/* These unspecs are just wrappers. */
return may_trap_p_1 (XVECEXP (x, 0, 0), flags);
}
}
return default_unspec_may_trap_p (x, flags);
}
/* Parse the -mfixed-range= option string. */ /* Parse the -mfixed-range= option string. */
static void static void
......
...@@ -10151,6 +10151,15 @@ The default value of this hook is @code{NULL}, which disables any special ...@@ -10151,6 +10151,15 @@ The default value of this hook is @code{NULL}, which disables any special
allocation. allocation.
@end deftypefn @end deftypefn
@deftypefn {Target Hook} int TARGET_UNSPEC_MAY_TRAP_P (const_rtx @var{x}, unsigned @var{flags})
This target hook returns nonzero if @var{x}, an @code{unspec} or
@code{unspec_volatile} operation, might cause a trap. Targets can use
this hook to enhance precision of analysis for @code{unspec} and
@code{unspec_volatile} operations. You may call @code{may_trap_p_1}
to analyze inner elements of @var{x} in which case @var{flags} should be
passed along.
@end deftypefn
@deftypefn {Target Hook} void TARGET_SET_CURRENT_FUNCTION (tree @var{decl}) @deftypefn {Target Hook} void TARGET_SET_CURRENT_FUNCTION (tree @var{decl})
The compiler invokes this hook whenever it changes its current function The compiler invokes this hook whenever it changes its current function
context (@code{cfun}). You can define this function if context (@code{cfun}). You can define this function if
......
...@@ -1739,6 +1739,7 @@ extern void remove_reg_equal_equiv_notes (rtx); ...@@ -1739,6 +1739,7 @@ extern void remove_reg_equal_equiv_notes (rtx);
extern int side_effects_p (const_rtx); extern int side_effects_p (const_rtx);
extern int volatile_refs_p (const_rtx); extern int volatile_refs_p (const_rtx);
extern int volatile_insn_p (const_rtx); extern int volatile_insn_p (const_rtx);
extern int may_trap_p_1 (const_rtx, unsigned);
extern int may_trap_p (const_rtx); extern int may_trap_p (const_rtx);
extern int may_trap_after_code_motion_p (const_rtx); extern int may_trap_after_code_motion_p (const_rtx);
extern int may_trap_or_fault_p (const_rtx); extern int may_trap_or_fault_p (const_rtx);
......
...@@ -2182,7 +2182,7 @@ enum may_trap_p_flags ...@@ -2182,7 +2182,7 @@ enum may_trap_p_flags
cannot trap at its current location, but it might become trapping if moved cannot trap at its current location, but it might become trapping if moved
elsewhere. */ elsewhere. */
static int int
may_trap_p_1 (const_rtx x, unsigned flags) may_trap_p_1 (const_rtx x, unsigned flags)
{ {
int i; int i;
...@@ -2209,8 +2209,11 @@ may_trap_p_1 (const_rtx x, unsigned flags) ...@@ -2209,8 +2209,11 @@ may_trap_p_1 (const_rtx x, unsigned flags)
case SCRATCH: case SCRATCH:
return 0; return 0;
case ASM_INPUT: case UNSPEC:
case UNSPEC_VOLATILE: case UNSPEC_VOLATILE:
return targetm.unspec_may_trap_p (x, flags);
case ASM_INPUT:
case TRAP_IF: case TRAP_IF:
return 1; return 1;
......
...@@ -480,6 +480,8 @@ ...@@ -480,6 +480,8 @@
#define TARGET_MANGLE_TYPE hook_constcharptr_const_tree_null #define TARGET_MANGLE_TYPE hook_constcharptr_const_tree_null
#define TARGET_ALLOCATE_INITIAL_VALUE NULL #define TARGET_ALLOCATE_INITIAL_VALUE NULL
#define TARGET_UNSPEC_MAY_TRAP_P default_unspec_may_trap_p
#ifndef TARGET_SET_CURRENT_FUNCTION #ifndef TARGET_SET_CURRENT_FUNCTION
#define TARGET_SET_CURRENT_FUNCTION hook_void_tree #define TARGET_SET_CURRENT_FUNCTION hook_void_tree
#endif #endif
...@@ -741,6 +743,7 @@ ...@@ -741,6 +743,7 @@
TARGET_RTX_COSTS, \ TARGET_RTX_COSTS, \
TARGET_ADDRESS_COST, \ TARGET_ADDRESS_COST, \
TARGET_ALLOCATE_INITIAL_VALUE, \ TARGET_ALLOCATE_INITIAL_VALUE, \
TARGET_UNSPEC_MAY_TRAP_P, \
TARGET_DWARF_REGISTER_SPAN, \ TARGET_DWARF_REGISTER_SPAN, \
TARGET_INIT_DWARF_REG_SIZES_EXTRA, \ TARGET_INIT_DWARF_REG_SIZES_EXTRA, \
TARGET_FIXED_CONDITION_CODE_REGS, \ TARGET_FIXED_CONDITION_CODE_REGS, \
......
...@@ -652,6 +652,10 @@ struct gcc_target ...@@ -652,6 +652,10 @@ struct gcc_target
value. */ value. */
rtx (* allocate_initial_value) (rtx x); rtx (* allocate_initial_value) (rtx x);
/* Return nonzero if evaluating UNSPEC[_VOLATILE] X might cause a trap.
FLAGS has the same meaning as in rtlanal.c: may_trap_p_1. */
int (* unspec_may_trap_p) (const_rtx x, unsigned flags);
/* Given a register, this hook should return a parallel of registers /* Given a register, this hook should return a parallel of registers
to represent where to find the register pieces. Define this hook to represent where to find the register pieces. Define this hook
if the register and its mode are represented in Dwarf in if the register and its mode are represented in Dwarf in
......
...@@ -75,6 +75,26 @@ default_external_libcall (rtx fun ATTRIBUTE_UNUSED) ...@@ -75,6 +75,26 @@ default_external_libcall (rtx fun ATTRIBUTE_UNUSED)
#endif #endif
} }
int
default_unspec_may_trap_p (const_rtx x, unsigned flags)
{
int i;
if (GET_CODE (x) == UNSPEC_VOLATILE
/* Any floating arithmetic may trap. */
|| (SCALAR_FLOAT_MODE_P (GET_MODE (x))
&& flag_trapping_math))
return 1;
for (i = 0; i < XVECLEN (x, 0); ++i)
{
if (may_trap_p_1 (XVECEXP (x, 0, i), flags))
return 1;
}
return 0;
}
enum machine_mode enum machine_mode
default_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2) default_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
{ {
......
...@@ -19,6 +19,8 @@ along with GCC; see the file COPYING3. If not see ...@@ -19,6 +19,8 @@ along with GCC; see the file COPYING3. If not see
extern void default_external_libcall (rtx); extern void default_external_libcall (rtx);
extern int default_unspec_may_trap_p (const_rtx, unsigned);
extern enum machine_mode default_cc_modes_compatible (enum machine_mode, extern enum machine_mode default_cc_modes_compatible (enum machine_mode,
enum machine_mode); enum machine_mode);
......
2007-10-15 Paolo Bonzini <bonzini@gnu.org>
Maxim Kuvyrkov <maxim@codesourcery.com>
* gcc.target/ia64/20040709-2.c: New test.
2007-10-15 Steven G. Kargl <kargl@gcc.gnu.org> 2007-10-15 Steven G. Kargl <kargl@gcc.gnu.org>
* gfortran.dg/gamma_5.f90: xfail on FreeBSD * gfortran.dg/gamma_5.f90: xfail on FreeBSD
/* Check for ia64 data speculation failure with '-O2 -funroll-loops'. */
/* { dg-do compile } */
/* { dg-options "-O2 -funroll-loops -Wno-overflow" } */
extern void abort (void);
extern void exit (int);
unsigned int
myrnd (void)
{
static unsigned int s = 1388815473;
s *= 1103515245;
s += 12345;
return (s / 65536) % 2048;
}
#define T(S) \
struct S s##S; \
struct S retme##S (struct S x) \
{ \
return x; \
} \
\
unsigned int fn1##S (unsigned int x) \
{ \
struct S y = s##S; \
y.k += x; \
y = retme##S (y); \
return y.k; \
} \
\
unsigned int fn2##S (unsigned int x) \
{ \
struct S y = s##S; \
y.k += x; \
y.k %= 15; \
return y.k; \
} \
\
unsigned int retit##S (void) \
{ \
return s##S.k; \
} \
\
unsigned int fn3##S (unsigned int x) \
{ \
s##S.k += x; \
return retit##S (); \
} \
\
void test##S (void) \
{ \
int i; \
unsigned int mask, v, a, r; \
struct S x; \
char *p = (char *) &s##S; \
for (i = 0; i < sizeof (s##S); ++i) \
*p++ = myrnd (); \
if (__builtin_classify_type (s##S.l) == 8) \
s##S.l = 5.25; \
s##S.k = -1; \
mask = s##S.k; \
v = myrnd (); \
a = myrnd (); \
s##S.k = v; \
x = s##S; \
r = fn1##S (a); \
if (x.i != s##S.i || x.j != s##S.j \
|| x.k != s##S.k || x.l != s##S.l \
|| ((v + a) & mask) != r) \
abort (); \
v = myrnd (); \
a = myrnd (); \
s##S.k = v; \
x = s##S; \
r = fn2##S (a); \
if (x.i != s##S.i || x.j != s##S.j \
|| x.k != s##S.k || x.l != s##S.l \
|| ((((v + a) & mask) % 15) & mask) != r) \
abort (); \
v = myrnd (); \
a = myrnd (); \
s##S.k = v; \
x = s##S; \
r = fn3##S (a); \
if (x.i != s##S.i || x.j != s##S.j \
|| s##S.k != r || x.l != s##S.l \
|| ((v + a) & mask) != r) \
abort (); \
}
#define pck __attribute__((packed))
struct pck A { unsigned short i : 1, l : 1, j : 3, k : 11; }; T(A)
struct pck B { unsigned short i : 4, j : 1, k : 11; unsigned int l; }; T(B)
struct pck C { unsigned int l; unsigned short i : 4, j : 1, k : 11; }; T(C)
struct pck D { unsigned long long l : 6, i : 6, j : 23, k : 29; }; T(D)
struct pck E { unsigned long long l, i : 12, j : 23, k : 29; }; T(E)
struct pck F { unsigned long long i : 12, j : 23, k : 29, l; }; T(F)
struct pck G { unsigned short i : 1, j : 1, k : 6; unsigned long long l; }; T(G)
struct pck H { unsigned short i : 6, j : 2, k : 8; unsigned long long l; }; T(H)
struct pck I { unsigned short i : 1, j : 6, k : 1; unsigned long long l; }; T(I)
struct pck J { unsigned short i : 1, j : 8, k : 7; unsigned short l; }; T(J)
struct pck K { unsigned int k : 6, l : 1, j : 10, i : 15; }; T(K)
struct pck L { unsigned int k : 6, j : 11, i : 15; unsigned int l; }; T(L)
struct pck M { unsigned int l; unsigned short k : 6, j : 11, i : 15; }; T(M)
struct pck N { unsigned long long l : 6, k : 6, j : 23, i : 29; }; T(N)
struct pck O { unsigned long long l, k : 12, j : 23, i : 29; }; T(O)
struct pck P { unsigned long long k : 12, j : 23, i : 29, l; }; T(P)
struct pck Q { unsigned short k : 12, j : 1, i : 3; unsigned long long l; }; T(Q)
struct pck R { unsigned short k : 2, j : 11, i : 3; unsigned long long l; }; T(R)
struct pck S { unsigned short k : 1, j : 6, i : 9; unsigned long long l; }; T(S)
struct pck T { unsigned short k : 1, j : 8, i : 7; unsigned short l; }; T(T)
struct pck U { unsigned short j : 6, k : 1, i : 9; unsigned long long l; }; T(U)
struct pck V { unsigned short j : 8, k : 1, i : 7; unsigned short l; }; T(V)
struct pck W { long double l; unsigned int k : 12, j : 13, i : 7; }; T(W)
struct pck X { unsigned int k : 12, j : 13, i : 7; long double l; }; T(X)
struct pck Y { unsigned int k : 12, j : 11, i : 9; long double l; }; T(Y)
struct pck Z { long double l; unsigned int j : 13, i : 7, k : 12; }; T(Z)
int
main (void)
{
testA ();
testB ();
testC ();
testD ();
testE ();
testF ();
testG ();
testH ();
testI ();
testJ ();
testK ();
testL ();
testM ();
testN ();
testO ();
testP ();
testQ ();
testR ();
testS ();
testT ();
testU ();
testV ();
testW ();
testX ();
testY ();
testZ ();
exit (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