public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix ICE in ia64 speculation support
@ 2007-09-13 17:42 Maxim Kuvyrkov
  2007-09-20 20:47 ` Vladimir Makarov
  0 siblings, 1 reply; 13+ messages in thread
From: Maxim Kuvyrkov @ 2007-09-13 17:42 UTC (permalink / raw)
  To: Vladimir Makarov; +Cc: Andrey Belevantsev, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 917 bytes --]

Hi,

This patch fixes minor bug in ia64 speculation support.

The issue is that may_trap_p () can return different results given 
normal instruction and its speculative version.  E.g., this occurs for 
(set (reg:DF) (mem:DF)) and (set (reg:DF) (unspec:DF [(mem:DF)] 
DATA_SPEC)).  The latter is a speculative variant of the former and 
may_trap_p () always returns 'true' for the speculative version because 
unspec:DF is considered a random floating point operation that might trap.

This causes an assert, that checks that a speculative insn can stay 
speculative, fail.  The fix is to use original pattern when calling 
may_trap_p ().

The bug was reported by Andrey and implicates itself only with '-O2 
-funroll-loops' (the options tested by default do not include this 
combination).  The testcase is a copy of 
gcc.c-torture/execute/20040709-1.c but with forced -funroll-loops.

OK for trunk?


Thanks,

Maxim

[-- Attachment #2: bonzo.ChangeLog --]
[-- Type: text/plain, Size: 290 bytes --]

2007-09-13  Maxim Kuvyrkov  <maxim@codesourcery.com>

	* haifa-sched.c (sched_insn_is_legitimate_for_speculation): Use
	original pattern of changed instructions to stabilize analysis.

2007-09-13  Maxim Kuvyrkov  <maxim@codesourcery.com>

	* gcc.c-torture/compile/20040709-2.c: New test.
	

[-- Attachment #3: bonzo.patch --]
[-- Type: text/plain, Size: 5339 bytes --]

Index: haifa-sched.c
===================================================================
--- haifa-sched.c	(revision 181504)
+++ haifa-sched.c	(working copy)
@@ -4034,9 +4034,21 @@ sched_insn_is_legitimate_for_speculation
   if (side_effects_p (PATTERN (insn)))
     return false;
 
-  if ((ds & BE_IN_SPEC)
-      && may_trap_p (PATTERN (insn)))
-    return false;
+  if (ds & BE_IN_SPEC)
+    {
+      rtx pat;
+
+      if (ORIG_PAT (insn) != NULL_RTX)
+	/* Use original pattern of instruction as current [speculative]
+	   pattern might be identified as trap risky even when it is,
+	   in fact, not.  */
+	pat = ORIG_PAT (insn);
+      else
+	pat = PATTERN (insn);
+
+      if (may_trap_p (pat))
+	return false;
+    }
 
   return true;
 }
Index: testsuite/gcc.c-torture/compile/20040709-2.c
===================================================================
--- testsuite/gcc.c-torture/compile/20040709-2.c	(revision 0)
+++ testsuite/gcc.c-torture/compile/20040709-2.c	(revision 0)
@@ -0,0 +1,149 @@
+/* { dg-options "-funroll-loops" { target ia64-*-* } } */
+
+/* Check for ia64 data speculation failure with '-O2 -funroll-loops'.  */
+
+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 ();					\
+}
+
+struct A { unsigned int i : 6, l : 1, j : 10, k : 15; }; T(A)
+struct B { unsigned int i : 6, j : 11, k : 15; unsigned int l; }; T(B)
+struct C { unsigned int l; unsigned int i : 6, j : 11, k : 15; }; T(C)
+struct D { unsigned long long l : 6, i : 6, j : 23, k : 29; }; T(D)
+struct E { unsigned long long l, i : 12, j : 23, k : 29; }; T(E)
+struct F { unsigned long long i : 12, j : 23, k : 29, l; }; T(F)
+struct G { unsigned int i : 12, j : 13, k : 7; unsigned long long l; }; T(G)
+struct H { unsigned int i : 12, j : 11, k : 9; unsigned long long l; }; T(H)
+struct I { unsigned short i : 1, j : 6, k : 9; unsigned long long l; }; T(I)
+struct J { unsigned short i : 1, j : 8, k : 7; unsigned short l; }; T(J)
+struct K { unsigned int k : 6, l : 1, j : 10, i : 15; }; T(K)
+struct L { unsigned int k : 6, j : 11, i : 15; unsigned int l; }; T(L)
+struct M { unsigned int l; unsigned int k : 6, j : 11, i : 15; }; T(M)
+struct N { unsigned long long l : 6, k : 6, j : 23, i : 29; }; T(N)
+struct O { unsigned long long l, k : 12, j : 23, i : 29; }; T(O)
+struct P { unsigned long long k : 12, j : 23, i : 29, l; }; T(P)
+struct Q { unsigned int k : 12, j : 13, i : 7; unsigned long long l; }; T(Q)
+struct R { unsigned int k : 12, j : 11, i : 9; unsigned long long l; }; T(R)
+struct S { unsigned short k : 1, j : 6, i : 9; unsigned long long l; }; T(S)
+struct T { unsigned short k : 1, j : 8, i : 7; unsigned short l; }; T(T)
+struct U { unsigned short j : 6, k : 1, i : 9; unsigned long long l; }; T(U)
+struct V { unsigned short j : 8, k : 1, i : 7; unsigned short l; }; T(V)
+struct W { long double l; unsigned int k : 12, j : 13, i : 7; }; T(W)
+struct X { unsigned int k : 12, j : 13, i : 7; long double l; }; T(X)
+struct Y { unsigned int k : 12, j : 11, i : 9; long double l; }; T(Y)
+struct 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);
+}

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Fix ICE in ia64 speculation support
  2007-09-13 17:42 [PATCH] Fix ICE in ia64 speculation support Maxim Kuvyrkov
@ 2007-09-20 20:47 ` Vladimir Makarov
  2007-09-20 21:51   ` Vladimir Makarov
  0 siblings, 1 reply; 13+ messages in thread
From: Vladimir Makarov @ 2007-09-20 20:47 UTC (permalink / raw)
  To: Maxim Kuvyrkov; +Cc: Andrey Belevantsev, gcc-patches

Maxim Kuvyrkov wrote:
> Hi,
>
> This patch fixes minor bug in ia64 speculation support.
>
> The issue is that may_trap_p () can return different results given 
> normal instruction and its speculative version.  E.g., this occurs for 
> (set (reg:DF) (mem:DF)) and (set (reg:DF) (unspec:DF [(mem:DF)] 
> DATA_SPEC)).  The latter is a speculative variant of the former and 
> may_trap_p () always returns 'true' for the speculative version 
> because unspec:DF is considered a random floating point operation that 
> might trap.
>
> This causes an assert, that checks that a speculative insn can stay 
> speculative, fail.  The fix is to use original pattern when calling 
> may_trap_p ().
>
> The bug was reported by Andrey and implicates itself only with '-O2 
> -funroll-loops' (the options tested by default do not include this 
> combination).  The testcase is a copy of 
> gcc.c-torture/execute/20040709-1.c but with forced -funroll-loops.
>
> OK for trunk?
>
>
Sorry, I can reproduce the bug.  I've tried today repository.  No luck.

I think that right solution would be make may_trap_p to understand that 
the insn is speculative.  But without reproducing the bug, I can not be 
sure about my proposal.

Vlad

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Fix ICE in ia64 speculation support
  2007-09-20 20:47 ` Vladimir Makarov
@ 2007-09-20 21:51   ` Vladimir Makarov
  2007-09-21  9:18     ` Maxim Kuvyrkov
  0 siblings, 1 reply; 13+ messages in thread
From: Vladimir Makarov @ 2007-09-20 21:51 UTC (permalink / raw)
  To: Vladimir Makarov; +Cc: Maxim Kuvyrkov, Andrey Belevantsev, gcc-patches

Vladimir Makarov wrote:
> Maxim Kuvyrkov wrote:
>>
>> The issue is that may_trap_p () can return different results given 
>> normal instruction and its speculative version.  E.g., this occurs 
>> for (set (reg:DF) (mem:DF)) and (set (reg:DF) (unspec:DF [(mem:DF)] 
>> DATA_SPEC)).  The latter is a speculative variant of the former and 
>> may_trap_p () always returns 'true' for the speculative version 
>> because unspec:DF is considered a random floating point operation 
>> that might trap.
>>
>> This causes an assert, that checks that a speculative insn can stay 
>> speculative, fail.  The fix is to use original pattern when calling 
>> may_trap_p ().
>>
>>
> Sorry, I can reproduce the bug.  I've tried today repository.  No luck.
>
                     ^ should be 'can not'
> I think that right solution would be make may_trap_p to understand 
> that the insn is speculative.  But without reproducing the bug, I can 
> not be sure about my proposal.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Fix ICE in ia64 speculation support
  2007-09-20 21:51   ` Vladimir Makarov
@ 2007-09-21  9:18     ` Maxim Kuvyrkov
  2007-09-21  9:38       ` Paolo Bonzini
  0 siblings, 1 reply; 13+ messages in thread
From: Maxim Kuvyrkov @ 2007-09-21  9:18 UTC (permalink / raw)
  To: Vladimir Makarov; +Cc: Andrey Belevantsev, gcc-patches

Vladimir Makarov wrote:
> Vladimir Makarov wrote:
>> Maxim Kuvyrkov wrote:
>>>
>>> The issue is that may_trap_p () can return different results given 
>>> normal instruction and its speculative version.  E.g., this occurs 
>>> for (set (reg:DF) (mem:DF)) and (set (reg:DF) (unspec:DF [(mem:DF)] 
>>> DATA_SPEC)).  The latter is a speculative variant of the former and 
>>> may_trap_p () always returns 'true' for the speculative version 
>>> because unspec:DF is considered a random floating point operation 
>>> that might trap.
>>>
>>> This causes an assert, that checks that a speculative insn can stay 
>>> speculative, fail.  The fix is to use original pattern when calling 
>>> may_trap_p ().
>>>
>>>
>> Sorry, I can reproduce the bug.  I've tried today repository.  No luck.
>>
>                     ^ should be 'can not'
>> I think that right solution would be make may_trap_p to understand 
>> that the insn is speculative.  But without reproducing the bug, I can 
>> not be sure about my proposal.

Yep, the bug doesn't implicate itself on the trunk, the revision where 
it can be observed is 128037 (2007-09-02).

The right solution (and I'm working on it in my spare time), IMHO, would 
be to move the whole logic of determining if insn can be speculative to 
the backend and use instruction attributes to query for information. 
This way we will use target-provided information to answer the question 
if a particular insn can be executed with, possibly, wrong arguments 
instead of immediately falling back to the default answer 'yes, if it 
won't trap'.

At the moment the logic for determining if insn can begin speculation is 
in the backend, but logic responsible for be_in speculation is in 
machine-independent code.  You can sense a mismatch here :)

OK, back to the immediate problem: speculative load appears to be trap 
risky to the rtl analyzer due to use of (unspec) in its pattern.  UNSPEC 
is placed into speculative loads to distinguish them from regular ones. 
  What else, besides UNSPEC, can we use to make insn emit different asm, 
but still have the same RTL meaning?  I can think of only one 
alternative: use a parallel with a nop, e.g., (parallel [(set (reg) 
(mem)) (const_int 0)]).  I think this is uglier than unspec, plus rtl 
analyzers favor parallel less than unspec.  I appreciate any advice here.

At the moment though (considering Stage 3 et all), I can't come up with 
a better solution than using original pattern of speculative load for 
getting feedback from rtl analyzer.


Thanks,

Maxim

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Fix ICE in ia64 speculation support
  2007-09-21  9:18     ` Maxim Kuvyrkov
@ 2007-09-21  9:38       ` Paolo Bonzini
  2007-09-21  9:53         ` Maxim Kuvyrkov
  0 siblings, 1 reply; 13+ messages in thread
From: Paolo Bonzini @ 2007-09-21  9:38 UTC (permalink / raw)
  To: Maxim Kuvyrkov; +Cc: Vladimir Makarov, Andrey Belevantsev, gcc-patches


> OK, back to the immediate problem: speculative load appears to be trap 
> risky to the rtl analyzer due to use of (unspec) in its pattern.  UNSPEC 
> is placed into speculative loads to distinguish them from regular ones. 
>  What else, besides UNSPEC, can we use to make insn emit different asm, 
> but still have the same RTL meaning?  I can think of only one 
> alternative: use a parallel with a nop, e.g., (parallel [(set (reg) 
> (mem)) (const_int 0)]).  I think this is uglier than unspec, plus rtl 
> analyzers favor parallel less than unspec.  I appreciate any advice here.

It seems to me that only UNSPEC_VOLATILE is counted as possibly 
trapping.  The problem is than the UNSPEC recurs inside the MEM and that 
one is marked as trapping.  You could add a target hook like 
unspec_may_trap_p, with a patch like this:

Index: rtlanal.c
===================================================================
--- rtlanal.c   (revision 126191)
+++ rtlanal.c   (working copy)
@@ -2206,8 +2206,11 @@ may_trap_p_1 (rtx x, unsigned flags)
      case SCRATCH:
        return 0;

-    case ASM_INPUT:
+    case UNSPEC:
      case UNSPEC_VOLATILE:
+      return targetm.unspec_may_trap_p (x, flags);
+
+    case ASM_INPUT:
      case TRAP_IF:
        return 1;


and a default implementation of

   int j;
   if (GET_CODE (x) == UNSPEC_VOLATILE)
     return 1;

   for (j = 0; j < XVECLEN (x, 0); j++)
     if (may_trap_p_1 (XVECEXP (x, 0, j), flags))
       return 1;

The ia64 back-end could special case the unspec like this:

   if (XINT (x, 1) == ...)
     return 0;

   return default_unspec_may_trap_p (x);

(Hmm, requires making may_trap_p_1 public, it's static now).

Paolo

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Fix ICE in ia64 speculation support
  2007-09-21  9:38       ` Paolo Bonzini
@ 2007-09-21  9:53         ` Maxim Kuvyrkov
  2007-09-21 10:43           ` Paolo Bonzini
  0 siblings, 1 reply; 13+ messages in thread
From: Maxim Kuvyrkov @ 2007-09-21  9:53 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Vladimir Makarov, Andrey Belevantsev, gcc-patches

Paolo Bonzini wrote:
> 
>> OK, back to the immediate problem: speculative load appears to be trap 
>> risky to the rtl analyzer due to use of (unspec) in its pattern.  
>> UNSPEC is placed into speculative loads to distinguish them from 
>> regular ones.  What else, besides UNSPEC, can we use to make insn emit 
>> different asm, but still have the same RTL meaning?  I can think of 
>> only one alternative: use a parallel with a nop, e.g., (parallel [(set 
>> (reg) (mem)) (const_int 0)]).  I think this is uglier than unspec, 
>> plus rtl analyzers favor parallel less than unspec.  I appreciate any 
>> advice here.
> 
> It seems to me that only UNSPEC_VOLATILE is counted as possibly 
> trapping.

The case is (set (reg) (UNSPEC:<fp_mode> (mem))), which is trapping 
because it is a floating point operation (it doesn't even get to 
analyzing the mem).

> The problem is than the UNSPEC recurs inside the MEM and that 
> one is marked as trapping.  You could add a target hook like 
> unspec_may_trap_p, with a patch like this:

This is how the same problem is solved on sel-sched-branch.  I agree 
that it won't hurt to teach may_trap_p to ask target about UNSPECs.

> 
> Index: rtlanal.c
> ===================================================================
> --- rtlanal.c   (revision 126191)
> +++ rtlanal.c   (working copy)
> @@ -2206,8 +2206,11 @@ may_trap_p_1 (rtx x, unsigned flags)
>      case SCRATCH:
>        return 0;
> 
> -    case ASM_INPUT:
> +    case UNSPEC:
>      case UNSPEC_VOLATILE:
> +      return targetm.unspec_may_trap_p (x, flags);
> +
> +    case ASM_INPUT:
>      case TRAP_IF:
>        return 1;
> 
> 
> and a default implementation of
> 
>   int j;
>   if (GET_CODE (x) == UNSPEC_VOLATILE)
>     return 1;
> 
>   for (j = 0; j < XVECLEN (x, 0); j++)
>     if (may_trap_p_1 (XVECEXP (x, 0, j), flags))
>       return 1;
> 
> The ia64 back-end could special case the unspec like this:
> 
>   if (XINT (x, 1) == ...)
>     return 0;
> 
>   return default_unspec_may_trap_p (x);
> 
> (Hmm, requires making may_trap_p_1 public, it's static now).

Not if default_unspec_may_trap_p () is defined in rtlanal.c .


Thanks,

Maxim

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Fix ICE in ia64 speculation support
  2007-09-21  9:53         ` Maxim Kuvyrkov
@ 2007-09-21 10:43           ` Paolo Bonzini
  2007-10-14 18:04             ` Maxim Kuvyrkov
  0 siblings, 1 reply; 13+ messages in thread
From: Paolo Bonzini @ 2007-09-21 10:43 UTC (permalink / raw)
  To: Maxim Kuvyrkov
  Cc: Paolo Bonzini, Vladimir Makarov, Andrey Belevantsev, gcc-patches

Maxim Kuvyrkov wrote:
> Paolo Bonzini wrote:
>>
>>> OK, back to the immediate problem: speculative load appears to be 
>>> trap risky to the rtl analyzer due to use of (unspec) in its 
>>> pattern.  UNSPEC is placed into speculative loads to distinguish them 
>>> from regular ones.  What else, besides UNSPEC, can we use to make 
>>> insn emit different asm, but still have the same RTL meaning?  I can 
>>> think of only one alternative: use a parallel with a nop, e.g., 
>>> (parallel [(set (reg) (mem)) (const_int 0)]).  I think this is uglier 
>>> than unspec, plus rtl analyzers favor parallel less than unspec.  I 
>>> appreciate any advice here.
>>
>> It seems to me that only UNSPEC_VOLATILE is counted as possibly trapping.
> 
> The case is (set (reg) (UNSPEC:<fp_mode> (mem))), which is trapping 
> because it is a floating point operation (it doesn't even get to 
> analyzing the mem).

Huh.  So, the default definition should be:

   int j;
   if (GET_CODE (x) == UNSPEC_VOLATILE
       || (SCALAR_FLOAT_MODE_P (GET_MODE (x))
           && flag_trapping_math))
     return 1;

   for (j = 0; j < XVECLEN (x, 0); j++)
     if (may_trap_p_1 (XVECEXP (x, 0, j), flags))
       return 1;

>> (Hmm, requires making may_trap_p_1 public, it's static now).
> 
> Not if default_unspec_may_trap_p () is defined in rtlanal.c .

But it is usually in targhooks.c, and anyway it may be necessary to call 
it from the hook in the future, e.g. if an unspec has two mems, and only 
one should be special cased.  Unless you want something as disgusting 
as^W^W^W like this:

    int result;
    rtx save = XVECEXP (x, 0, 0);
    XVECEXP (x, 0, 0) = const0_rtx;
    result = default_unspec_may_trap_p (x, flags);
    XVECEXP (x, 0, 0) = save;
    return result;

Paolo

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Fix ICE in ia64 speculation support
  2007-09-21 10:43           ` Paolo Bonzini
@ 2007-10-14 18:04             ` Maxim Kuvyrkov
  2007-10-15  8:06               ` Paolo Bonzini
  2007-10-15  8:17               ` Eric Botcazou
  0 siblings, 2 replies; 13+ messages in thread
From: Maxim Kuvyrkov @ 2007-10-14 18:04 UTC (permalink / raw)
  To: bonzini; +Cc: Vladimir Makarov, Andrey Belevantsev, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1089 bytes --]

Paolo Bonzini wrote:

...

> Huh.  So, the default definition should be:
> 
>   int j;
>   if (GET_CODE (x) == UNSPEC_VOLATILE
>       || (SCALAR_FLOAT_MODE_P (GET_MODE (x))
>           && flag_trapping_math))
>     return 1;
> 
>   for (j = 0; j < XVECLEN (x, 0); j++)
>     if (may_trap_p_1 (XVECEXP (x, 0, j), flags))
>       return 1;
> 
>>> (Hmm, requires making may_trap_p_1 public, it's static now).
>>
>> Not if default_unspec_may_trap_p () is defined in rtlanal.c .
> 
> But it is usually in targhooks.c, and anyway it may be necessary to call 
> it from the hook in the future, e.g. if an unspec has two mems, and only 
> one should be special cased.  Unless you want something as disgusting 
> as^W^W^W like this:
> 
>    int result;
>    rtx save = XVECEXP (x, 0, 0);
>    XVECEXP (x, 0, 0) = const0_rtx;
>    result = default_unspec_may_trap_p (x, flags);
>    XVECEXP (x, 0, 0) = save;
>    return result;

Hi,

Here is a patch implementing Paolo's approach.  At the moment I'm 
bootstrapping / regtesting it on {x86_64 and ia64}-unknown-linux-gnu.

OK for trunk?


--
Maxim

[-- Attachment #2: bonzini.ChangeLog --]
[-- Type: text/plain, Size: 750 bytes --]

2007-09-13  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.
	* 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-09-13  Paolo Bonzini  <bonzini@gnu.org>
	    Maxim Kuvyrkov  <maxim@codesourcery.com>

	* gcc.c-torture/compile/20040709-2.c: New test.
	

[-- Attachment #3: bonzini.patch --]
[-- Type: text/plain, Size: 9860 bytes --]

Index: target.h
===================================================================
--- target.h	(revision 129295)
+++ target.h	(working copy)
@@ -652,6 +652,10 @@ struct gcc_target
      value.  */
   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
      to represent where to find the register pieces.  Define this hook
      if the register and its mode are represented in Dwarf in
Index: target-def.h
===================================================================
--- target-def.h	(revision 129295)
+++ target-def.h	(working copy)
@@ -480,6 +480,8 @@
 #define TARGET_MANGLE_TYPE hook_constcharptr_const_tree_null
 #define TARGET_ALLOCATE_INITIAL_VALUE NULL
 
+#define TARGET_UNSPEC_MAY_TRAP_P default_unspec_may_trap_p
+
 #ifndef TARGET_SET_CURRENT_FUNCTION
 #define TARGET_SET_CURRENT_FUNCTION hook_void_tree
 #endif
@@ -741,6 +743,7 @@
   TARGET_RTX_COSTS,				\
   TARGET_ADDRESS_COST,				\
   TARGET_ALLOCATE_INITIAL_VALUE,		\
+  TARGET_UNSPEC_MAY_TRAP_P,                     \
   TARGET_DWARF_REGISTER_SPAN,                   \
   TARGET_INIT_DWARF_REG_SIZES_EXTRA,		\
   TARGET_FIXED_CONDITION_CODE_REGS,		\
Index: targhooks.c
===================================================================
--- targhooks.c	(revision 129295)
+++ targhooks.c	(working copy)
@@ -75,6 +75,28 @@ default_external_libcall (rtx fun ATTRIB
 #endif
 }
 
+int
+default_unspec_may_trap_p (const_rtx x, unsigned flags)
+{
+  int i;
+  int n;
+
+  if (GET_CODE (x) == UNSPEC_VOLATILE
+      /* Any floating arithmetic may trap.  */
+      || (SCALAR_FLOAT_MODE_P (GET_MODE (x))
+	  && flag_trapping_math))
+    return 1;
+
+  n = XVECLEN (x, 0);
+  for (i = 0; i < n; ++i)
+    {
+      if (may_trap_p_1 (XVECEXP (x, 0, i), flags))
+	return 1;
+    }
+
+  return 0;
+}
+
 enum machine_mode
 default_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
 {
Index: targhooks.h
===================================================================
--- targhooks.h	(revision 129295)
+++ targhooks.h	(working copy)
@@ -19,6 +19,8 @@ along with GCC; see the file COPYING3.  
 
 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,
 						      enum machine_mode);
 
Index: rtlanal.c
===================================================================
--- rtlanal.c	(revision 129295)
+++ rtlanal.c	(working copy)
@@ -2182,7 +2182,7 @@ enum may_trap_p_flags
    cannot trap at its current location, but it might become trapping if moved
    elsewhere.  */
 
-static int
+int
 may_trap_p_1 (const_rtx x, unsigned flags)
 {
   int i;
@@ -2209,8 +2209,11 @@ may_trap_p_1 (const_rtx x, unsigned flag
     case SCRATCH:
       return 0;
 
-    case ASM_INPUT:
+    case UNSPEC:
     case UNSPEC_VOLATILE:
+      return targetm.unspec_may_trap_p (x, flags);
+
+    case ASM_INPUT:
     case TRAP_IF:
       return 1;
 
Index: rtl.h
===================================================================
--- rtl.h	(revision 129295)
+++ rtl.h	(working copy)
@@ -1739,6 +1739,7 @@ extern void remove_reg_equal_equiv_notes
 extern int side_effects_p (const_rtx);
 extern int volatile_refs_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_after_code_motion_p (const_rtx);
 extern int may_trap_or_fault_p (const_rtx);
Index: config/ia64/ia64.c
===================================================================
--- config/ia64/ia64.c	(revision 129295)
+++ config/ia64/ia64.c	(working copy)
@@ -203,6 +203,7 @@ static int ia64_arg_partial_bytes (CUMUL
 static bool ia64_function_ok_for_sibcall (tree, tree);
 static bool ia64_return_in_memory (const_tree, const_tree);
 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 bool ia64_handle_option (size_t, const char *, int);
 static struct machine_function * ia64_init_machine_status (void);
@@ -409,6 +410,9 @@ static const struct attribute_spec ia64_
 #undef TARGET_ADDRESS_COST
 #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
 #define TARGET_MACHINE_DEPENDENT_REORG ia64_reorg
 
@@ -5073,6 +5077,29 @@ ia64_secondary_reload_class (enum reg_cl
 }
 
 \f
+/* 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);
+}
+
+\f
 /* Parse the -mfixed-range= option string.  */
 
 static void
Index: testsuite/gcc.c-torture/compile/20040709-2.c
===================================================================
--- testsuite/gcc.c-torture/compile/20040709-2.c	(revision 0)
+++ testsuite/gcc.c-torture/compile/20040709-2.c	(revision 0)
@@ -0,0 +1,149 @@
+/* { dg-options "-funroll-loops" { target ia64-*-* } } */
+
+/* Check for ia64 data speculation failure with '-O2 -funroll-loops'.  */
+
+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 ();					\
+}
+
+struct A { unsigned int i : 6, l : 1, j : 10, k : 15; }; T(A)
+struct B { unsigned int i : 6, j : 11, k : 15; unsigned int l; }; T(B)
+struct C { unsigned int l; unsigned int i : 6, j : 11, k : 15; }; T(C)
+struct D { unsigned long long l : 6, i : 6, j : 23, k : 29; }; T(D)
+struct E { unsigned long long l, i : 12, j : 23, k : 29; }; T(E)
+struct F { unsigned long long i : 12, j : 23, k : 29, l; }; T(F)
+struct G { unsigned int i : 12, j : 13, k : 7; unsigned long long l; }; T(G)
+struct H { unsigned int i : 12, j : 11, k : 9; unsigned long long l; }; T(H)
+struct I { unsigned short i : 1, j : 6, k : 9; unsigned long long l; }; T(I)
+struct J { unsigned short i : 1, j : 8, k : 7; unsigned short l; }; T(J)
+struct K { unsigned int k : 6, l : 1, j : 10, i : 15; }; T(K)
+struct L { unsigned int k : 6, j : 11, i : 15; unsigned int l; }; T(L)
+struct M { unsigned int l; unsigned int k : 6, j : 11, i : 15; }; T(M)
+struct N { unsigned long long l : 6, k : 6, j : 23, i : 29; }; T(N)
+struct O { unsigned long long l, k : 12, j : 23, i : 29; }; T(O)
+struct P { unsigned long long k : 12, j : 23, i : 29, l; }; T(P)
+struct Q { unsigned int k : 12, j : 13, i : 7; unsigned long long l; }; T(Q)
+struct R { unsigned int k : 12, j : 11, i : 9; unsigned long long l; }; T(R)
+struct S { unsigned short k : 1, j : 6, i : 9; unsigned long long l; }; T(S)
+struct T { unsigned short k : 1, j : 8, i : 7; unsigned short l; }; T(T)
+struct U { unsigned short j : 6, k : 1, i : 9; unsigned long long l; }; T(U)
+struct V { unsigned short j : 8, k : 1, i : 7; unsigned short l; }; T(V)
+struct W { long double l; unsigned int k : 12, j : 13, i : 7; }; T(W)
+struct X { unsigned int k : 12, j : 13, i : 7; long double l; }; T(X)
+struct Y { unsigned int k : 12, j : 11, i : 9; long double l; }; T(Y)
+struct 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);
+}

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Fix ICE in ia64 speculation support
  2007-10-14 18:04             ` Maxim Kuvyrkov
@ 2007-10-15  8:06               ` Paolo Bonzini
  2007-10-15  8:17               ` Eric Botcazou
  1 sibling, 0 replies; 13+ messages in thread
From: Paolo Bonzini @ 2007-10-15  8:06 UTC (permalink / raw)
  To: gcc-patches


> OK for trunk?

I cannot approve it but it looks fine except for missing documentation.

Paolo

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Fix ICE in ia64 speculation support
  2007-10-14 18:04             ` Maxim Kuvyrkov
  2007-10-15  8:06               ` Paolo Bonzini
@ 2007-10-15  8:17               ` Eric Botcazou
  2007-10-15 10:52                 ` Maxim Kuvyrkov
  1 sibling, 1 reply; 13+ messages in thread
From: Eric Botcazou @ 2007-10-15  8:17 UTC (permalink / raw)
  To: Maxim Kuvyrkov; +Cc: gcc-patches, bonzini, Vladimir Makarov, Andrey Belevantsev

> Here is a patch implementing Paolo's approach.  At the moment I'm
> bootstrapping / regtesting it on {x86_64 and ia64}-unknown-linux-gnu.
>
> OK for trunk?

The middle-end part is OK if you add the proper documentation for the hook in 
doc/tm.texi and get rid of the 'n' in default_unspec_may_trap_p (i.e. write 
the loop like in may_trap_p_1).

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Fix ICE in ia64 speculation support
  2007-10-15  8:17               ` Eric Botcazou
@ 2007-10-15 10:52                 ` Maxim Kuvyrkov
  2007-10-15 21:57                   ` Jim Wilson
  0 siblings, 1 reply; 13+ messages in thread
From: Maxim Kuvyrkov @ 2007-10-15 10:52 UTC (permalink / raw)
  To: Eric Botcazou
  Cc: James E Wilson, bonzini, Vladimir Makarov, Andrey Belevantsev,
	gcc-patches

[-- Attachment #1: Type: text/plain, Size: 521 bytes --]

Eric Botcazou wrote:
>> Here is a patch implementing Paolo's approach.  At the moment I'm
>> bootstrapping / regtesting it on {x86_64 and ia64}-unknown-linux-gnu.
>>
>> OK for trunk?
> 
> The middle-end part is OK if you add the proper documentation for the hook in 
> doc/tm.texi and get rid of the 'n' in default_unspec_may_trap_p (i.e. write 
> the loop like in may_trap_p_1).

Here is an updated patch.

Jim, sorry I missed to CC you on the original message.  Is ia64 part of 
the patch OK with you?


Thanks,

Maxim

[-- Attachment #2: bonzini.ChangeLog --]
[-- Type: text/plain, Size: 812 bytes --]

2007-09-13  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-09-13  Paolo Bonzini  <bonzini@gnu.org>
	    Maxim Kuvyrkov  <maxim@codesourcery.com>

	* gcc.c-torture/compile/20040709-2.c: New test.
	

[-- Attachment #3: bonzini.patch --]
[-- Type: text/plain, Size: 10854 bytes --]

Index: target.h
===================================================================
--- target.h	(revision 129295)
+++ target.h	(working copy)
@@ -652,6 +652,10 @@ struct gcc_target
      value.  */
   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
      to represent where to find the register pieces.  Define this hook
      if the register and its mode are represented in Dwarf in
Index: target-def.h
===================================================================
--- target-def.h	(revision 129295)
+++ target-def.h	(working copy)
@@ -480,6 +480,8 @@
 #define TARGET_MANGLE_TYPE hook_constcharptr_const_tree_null
 #define TARGET_ALLOCATE_INITIAL_VALUE NULL
 
+#define TARGET_UNSPEC_MAY_TRAP_P default_unspec_may_trap_p
+
 #ifndef TARGET_SET_CURRENT_FUNCTION
 #define TARGET_SET_CURRENT_FUNCTION hook_void_tree
 #endif
@@ -741,6 +743,7 @@
   TARGET_RTX_COSTS,				\
   TARGET_ADDRESS_COST,				\
   TARGET_ALLOCATE_INITIAL_VALUE,		\
+  TARGET_UNSPEC_MAY_TRAP_P,                     \
   TARGET_DWARF_REGISTER_SPAN,                   \
   TARGET_INIT_DWARF_REG_SIZES_EXTRA,		\
   TARGET_FIXED_CONDITION_CODE_REGS,		\
Index: targhooks.c
===================================================================
--- targhooks.c	(revision 129295)
+++ targhooks.c	(working copy)
@@ -75,6 +75,26 @@ default_external_libcall (rtx fun ATTRIB
 #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
 default_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
 {
Index: targhooks.h
===================================================================
--- targhooks.h	(revision 129295)
+++ targhooks.h	(working copy)
@@ -19,6 +19,8 @@ along with GCC; see the file COPYING3.  
 
 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,
 						      enum machine_mode);
 
Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 129295)
+++ doc/tm.texi	(working copy)
@@ -10151,6 +10151,13 @@ The default value of this hook is @code{
 allocation.
 @end deftypefn
 
+@deftypefn {Target Hook} int TARGET_UNSPEC_MAY_TRAP_P (const_rtx @var{x}, unsigned @var{flags})
+This target hook returns nonzero if unspec[_volatile] @var{x} might cause
+a trap.  Targets can use this hook to enhance precision of analysis
+for unspecs.  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})
 The compiler invokes this hook whenever it changes its current function 
 context (@code{cfun}).  You can define this function if
Index: rtlanal.c
===================================================================
--- rtlanal.c	(revision 129295)
+++ rtlanal.c	(working copy)
@@ -2182,7 +2182,7 @@ enum may_trap_p_flags
    cannot trap at its current location, but it might become trapping if moved
    elsewhere.  */
 
-static int
+int
 may_trap_p_1 (const_rtx x, unsigned flags)
 {
   int i;
@@ -2209,8 +2209,11 @@ may_trap_p_1 (const_rtx x, unsigned flag
     case SCRATCH:
       return 0;
 
-    case ASM_INPUT:
+    case UNSPEC:
     case UNSPEC_VOLATILE:
+      return targetm.unspec_may_trap_p (x, flags);
+
+    case ASM_INPUT:
     case TRAP_IF:
       return 1;
 
Index: rtl.h
===================================================================
--- rtl.h	(revision 129295)
+++ rtl.h	(working copy)
@@ -1739,6 +1739,7 @@ extern void remove_reg_equal_equiv_notes
 extern int side_effects_p (const_rtx);
 extern int volatile_refs_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_after_code_motion_p (const_rtx);
 extern int may_trap_or_fault_p (const_rtx);
Index: config/ia64/ia64.c
===================================================================
--- config/ia64/ia64.c	(revision 129295)
+++ config/ia64/ia64.c	(working copy)
@@ -203,6 +203,7 @@ static int ia64_arg_partial_bytes (CUMUL
 static bool ia64_function_ok_for_sibcall (tree, tree);
 static bool ia64_return_in_memory (const_tree, const_tree);
 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 bool ia64_handle_option (size_t, const char *, int);
 static struct machine_function * ia64_init_machine_status (void);
@@ -409,6 +410,9 @@ static const struct attribute_spec ia64_
 #undef TARGET_ADDRESS_COST
 #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
 #define TARGET_MACHINE_DEPENDENT_REORG ia64_reorg
 
@@ -5073,6 +5077,29 @@ ia64_secondary_reload_class (enum reg_cl
 }
 
 \f
+/* 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);
+}
+
+\f
 /* Parse the -mfixed-range= option string.  */
 
 static void
Index: testsuite/gcc.c-torture/compile/20040709-2.c
===================================================================
--- testsuite/gcc.c-torture/compile/20040709-2.c	(revision 0)
+++ testsuite/gcc.c-torture/compile/20040709-2.c	(revision 0)
@@ -0,0 +1,150 @@
+/* { dg-options "-funroll-loops -Wno-overflow" { target ia64-*-* } } */
+
+/* Check for ia64 data speculation failure with '-O2 -funroll-loops'.  */
+
+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);
+}

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Fix ICE in ia64 speculation support
  2007-10-15 10:52                 ` Maxim Kuvyrkov
@ 2007-10-15 21:57                   ` Jim Wilson
  2007-10-16  9:51                     ` Maxim Kuvyrkov
  0 siblings, 1 reply; 13+ messages in thread
From: Jim Wilson @ 2007-10-15 21:57 UTC (permalink / raw)
  To: Maxim Kuvyrkov
  Cc: Eric Botcazou, bonzini, Vladimir Makarov, Andrey Belevantsev,
	gcc-patches

On Mon, 2007-10-15 at 14:16 +0400, Maxim Kuvyrkov wrote:
> Jim, sorry I missed to CC you on the original message.  Is ia64 part of 
> the patch OK with you?

Yes, it is OK.

You might consider putting the testcase in gcc.target/ia64 since it is
very IA-64 specific.  You won't get multiple runs with different
optimizations here, but I suspect you really only need one run with -O2
or whatever to show the problem.

In the docs, unspec and unspec_volatile should be inside @code{}, and
you shouldn't be using [] to try to abbreviate here.  I'd suggest
something like this:

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.
-- 
Jim Wilson, GNU Tools Support, http://www.specifix.com


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] Fix ICE in ia64 speculation support
  2007-10-15 21:57                   ` Jim Wilson
@ 2007-10-16  9:51                     ` Maxim Kuvyrkov
  0 siblings, 0 replies; 13+ messages in thread
From: Maxim Kuvyrkov @ 2007-10-16  9:51 UTC (permalink / raw)
  To: Jim Wilson
  Cc: Eric Botcazou, bonzini, Vladimir Makarov, Andrey Belevantsev,
	gcc-patches

Jim Wilson wrote:
> On Mon, 2007-10-15 at 14:16 +0400, Maxim Kuvyrkov wrote:
>> Jim, sorry I missed to CC you on the original message.  Is ia64 part of 
>> the patch OK with you?
> 
> Yes, it is OK.
> 
> You might consider putting the testcase in gcc.target/ia64 since it is
> very IA-64 specific.  You won't get multiple runs with different
> optimizations here, but I suspect you really only need one run with -O2
> or whatever to show the problem.
> 
> In the docs, unspec and unspec_volatile should be inside @code{}, and
> you shouldn't be using [] to try to abbreviate here.  I'd suggest
> something like this:
> 
> 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.

Thanks.

Committed with the above fixes.

--
Maxim

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2007-10-16  9:15 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-09-13 17:42 [PATCH] Fix ICE in ia64 speculation support Maxim Kuvyrkov
2007-09-20 20:47 ` Vladimir Makarov
2007-09-20 21:51   ` Vladimir Makarov
2007-09-21  9:18     ` Maxim Kuvyrkov
2007-09-21  9:38       ` Paolo Bonzini
2007-09-21  9:53         ` Maxim Kuvyrkov
2007-09-21 10:43           ` Paolo Bonzini
2007-10-14 18:04             ` Maxim Kuvyrkov
2007-10-15  8:06               ` Paolo Bonzini
2007-10-15  8:17               ` Eric Botcazou
2007-10-15 10:52                 ` Maxim Kuvyrkov
2007-10-15 21:57                   ` Jim Wilson
2007-10-16  9:51                     ` Maxim Kuvyrkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).