diff --git a/gcc/testsuite/g++.dg/pph/c1attr-warn-unused-result.cc b/gcc/testsuite/g++.dg/pph/c1attr-warn-unused-result.cc
new file mode 100644
index 0000000..921d294
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pph/c1attr-warn-unused-result.cc
@@ -0,0 +1,2 @@
+/* { dg-options "-w" } */
+#include "c1attr-warn-unused-result.h"
diff --git a/gcc/testsuite/g++.dg/pph/c1attr-warn-unused-result.h b/gcc/testsuite/g++.dg/pph/c1attr-warn-unused-result.h
new file mode 100644
index 0000000..bfa2903
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pph/c1attr-warn-unused-result.h
@@ -0,0 +1,189 @@
+#ifndef __PPH_GUARD_H
+#define __PPH_GUARD_H
+/* { dg-options "-w" } */
+
+#define WUR __attribute__((warn_unused_result))
+#define WURAI __attribute__((warn_unused_result, always_inline)) inline
+typedef WUR int (*fnt) (void);
+
+typedef struct { long i; } A;
+typedef struct { long i; long j; } B;
+typedef struct { char big[1024]; fnt fn; } C;
+
+WUR int check1 (void);
+WUR void check2 (void);
+int foo WUR;
+int bar (void);
+extern WURAI int check3 (void) { return bar (); }
+WUR A check4 (void);
+WUR B check5 (void);
+WUR C check6 (void);
+A bar7 (void);
+B bar8 (void);
+C bar9 (void);
+extern WURAI A check7 (void) { return bar7 (); }
+extern WURAI B check8 (void) { return bar8 (); }
+extern WURAI C check9 (void) { return bar9 (); }
+/* This is useful for checking whether return value of statement
+   expressions (returning int in this case) is used.  */
+extern WURAI int check_int_result (int res) { return res; }
+#define GU(v) ({ int e = 0; (v) = bar (); if ((v) < 23) e = 14; e; })
+fnt fnptr;
+WUR int check10 (void);
+int baz (void);
+extern WURAI int check11 (void) { return baz (); }
+int k;
+
+void
+test (void)
+{
+  int i = 0, j;
+  const fnt pcheck1 = check1;
+  const fnt pcheck3 = check3;
+  A a;
+  B b;
+  C c;
+  if (check1 ())
+    return;
+  i += check1 ();
+  i += ({ check1 (); });
+  check1 ();
+  (void) check1 ();
+  check1 (), bar ();
+  check2 ();
+  (void) check2 ();
+  check2 (), bar ();
+  if (check3 ())
+    return;
+  i += check3 ();
+  i += ({ check3 (); });
+  check3 ();
+  (void) check3 ();
+  check3 (), bar ();
+  a = check4 ();
+  if (a.i)
+    return;
+  if (check4 ().i)
+    return;
+  if (({ check4 (); }).i)
+    return;
+  check4 ();
+  (void) check4 ();
+  check4 (), bar ();
+  b = check5 ();
+  if (b.i + b.j)
+    return;
+  if (check5 ().j)
+    return;
+  if (({ check5 (); }).j)
+    return;
+  check5 ();
+  (void) check5 ();
+  check5 (), bar ();
+  c = check6 ();
+  if (c.big[12] + c.big[29])
+    return;
+  if (check6 ().big[27])
+    return;
+  if (({ check6 (); }).big[0])
+    return;
+  check6 ();
+  (void) check6 ();
+  check6 (), bar ();
+  a = check7 ();
+  if (a.i)
+    return;
+  if (check7 ().i)
+    return;
+  if (({ check7 (); }).i)
+    return;
+  check7 ();
+  (void) check7 ();
+  check7 (), bar ();
+  b = check8 ();
+  if (b.i + b.j)
+    return;
+  if (check8 ().j)
+    return;
+  if (({ check8 (); }).j)
+    return;
+  check8 ();
+  (void) check8 ();
+  check8 (), bar ();
+  c = check9 ();
+  if (c.big[12] + c.big[29])
+    return;
+  if (check9 ().big[27])
+    return;
+  if (({ check9 (); }).big[0])
+    return;
+  check9 ();
+  (void) check9 ();
+  check9 (), bar ();
+  if (check_int_result (GU (j)))
+    return;
+  i += check_int_result (GU (j));
+  i += ({ check_int_result (GU (j)); });
+  check_int_result (GU (j));
+  (void) check_int_result (GU (j));
+  check_int_result (GU (j)), bar ();
+  if (fnptr ())
+    return;
+  i += fnptr ();
+  i += ({ fnptr (); });
+  fnptr ();
+  (void) fnptr ();
+  fnptr (), bar ();
+  fnptr = check1;
+  if (fnptr ())
+    return;
+  i += fnptr ();
+  i += ({ fnptr (); });
+  fnptr ();
+  (void) fnptr ();
+  fnptr (), bar ();
+  fnptr = check3;
+  if (fnptr ())
+    return;
+  i += fnptr ();
+  i += ({ fnptr (); });
+  fnptr ();
+  (void) fnptr ();
+  fnptr (), bar ();
+  if (bar9 ().fn ())
+    return;
+  i += bar9 ().fn ();
+  i += ({ bar9 ().fn (); });
+  bar9 ().fn ();
+  (void) bar9 ().fn ();
+  bar9 ().fn (), bar ();
+  if ((k ? check1 : check10) ())
+    return;
+  i += (k ? check1 : check10) ();
+  i += ({ (k ? check1 : check10) (); });
+  (k ? check1 : check10) ();
+  (void) (k ? check1 : check10) ();
+  (k ? check1 : check10) (), bar ();
+  if ((k ? check3 : check11) ())
+    return;
+  i += (k ? check3 : check11) ();
+  i += ({ (k ? check3 : check11) (); });
+  (k ? check3 : check11) ();
+  (void) (k ? check3 : check11) ();
+  (k ? check3 : check11) (), bar ();
+  if (pcheck1 ())
+    return;
+  i += pcheck1 ();
+  i += ({ pcheck1 (); });
+  pcheck1 ();
+  (void) pcheck1 ();
+  pcheck1 (), bar ();
+  if (pcheck3 ())
+    return;
+  i += pcheck3 ();
+  i += ({ pcheck3 (); });
+  pcheck3 ();
+  (void) pcheck3 ();
+  pcheck3 (), bar ();
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/pph/c1builtin-integral-1.cc b/gcc/testsuite/g++.dg/pph/c1builtin-integral-1.cc
new file mode 100644
index 0000000..bf53219
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pph/c1builtin-integral-1.cc
@@ -0,0 +1 @@
+#include "c1builtin-integral-1.h"
diff --git a/gcc/testsuite/g++.dg/pph/c1builtin-integral-1.h b/gcc/testsuite/g++.dg/pph/c1builtin-integral-1.h
new file mode 100644
index 0000000..46577b8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pph/c1builtin-integral-1.h
@@ -0,0 +1,71 @@
+#ifndef __PPH_GUARD_H
+#define __PPH_GUARD_H
+/* Copyright (C) 2004  Free Software Foundation.
+
+   Verify that integral FP expressions are optimized.
+
+   Written by Kaveh Ghazi, 2004-03-16.  */
+
+/* We need -ffinite-math-only so that we can fold "foo != foo", where
+   foo is a floating point expression.  We need -fno-math-errno so
+   that various math functions are marked const/pure and can be
+   folded.  */
+/* { dg-options "-ffinite-math-only -fno-math-errno" } */
+
+extern int link_failure (int);
+
+/* Test that the various FP truncation builtins detect integral
+   arguments.  */
+#define CHECK_FN(MATHFN) \
+ if (__builtin_##MATHFN(i1) != i1) link_failure (__LINE__); \
+ if (__builtin_##MATHFN##f(i1) != i1) link_failure (__LINE__); \
+ if (__builtin_##MATHFN##l(i1) != i1) link_failure (__LINE__);
+
+#define CHECK_FN_RET(MATHFN, RET) \
+ if (__builtin_##MATHFN(i1) != (RET)(double)i1) link_failure (__LINE__); \
+ if (__builtin_##MATHFN##f(i1) != (RET)(float)i1) link_failure (__LINE__); \
+ if (__builtin_##MATHFN##l(i1) != (RET)(long double)i1) link_failure (__LINE__);
+
+  /* Check that various other integral expressions are detected.  */
+#define CHECK_EXPR(EXPR,NAME) \
+ if (__builtin_ceill(EXPR) != (EXPR)) link_failure (__LINE__); \
+ if (__builtin_lroundl(EXPR) != (long)(long double)(EXPR)) link_failure (__LINE__);
+
+void __attribute__ ((__noinline__)) test (int i1, int i2)
+{
+  CHECK_FN(ceil);
+  CHECK_FN(floor);
+  CHECK_FN(nearbyint);
+  CHECK_FN(rint);
+  CHECK_FN(round);
+  CHECK_FN(trunc);
+  CHECK_FN_RET(lround, long);
+  CHECK_FN_RET(llround, long long);
+  CHECK_FN_RET(lrint, long);
+  CHECK_FN_RET(llrint, long long);
+  CHECK_FN_RET(lceil, long);
+  CHECK_FN_RET(llceil, long long);
+  CHECK_FN_RET(lfloor, long);
+  CHECK_FN_RET(llfloor, long long);
+
+  CHECK_EXPR (5.0, REAL_CST);
+  CHECK_EXPR (5.0F, REAL_CSTf);
+  CHECK_EXPR (5.0L, REAL_CSTl);
+  CHECK_EXPR ((double)i1, FLOAT_EXPR);
+  CHECK_EXPR ((float)i1, FLOAT_EXPRf);
+  CHECK_EXPR ((long double)i1, FLOAT_EXPRl);
+  CHECK_EXPR (__builtin_fabs(i1), ABS_EXPR);
+  CHECK_EXPR (__builtin_fabsf(i1), ABS_EXPRf);
+  CHECK_EXPR (__builtin_fabsl(i1), ABS_EXPRl);
+  CHECK_EXPR (((void)i1,(double)i2), COMPOUND_EXPR);
+  CHECK_EXPR ((double)i1+i2, PLUS_EXPR);
+  CHECK_EXPR ((double)i1-i2, MINUS_EXPR);
+  CHECK_EXPR ((double)i1*i2, MULT_EXPR);
+}
+
+int main (void)
+{
+  test (1, 2);
+  return 0;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/pph/c1builtin-object-size-2.cc b/gcc/testsuite/g++.dg/pph/c1builtin-object-size-2.cc
new file mode 100644
index 0000000..615e7da
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pph/c1builtin-object-size-2.cc
@@ -0,0 +1,2 @@
+/* { dg-options "-O2 -w -fpermissive" } */
+#include "c1builtin-object-size-2.h"
diff --git a/gcc/testsuite/g++.dg/pph/c1builtin-object-size-2.h b/gcc/testsuite/g++.dg/pph/c1builtin-object-size-2.h
new file mode 100644
index 0000000..a1636e9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pph/c1builtin-object-size-2.h
@@ -0,0 +1,395 @@
+#ifndef __PPH_GUARD_H
+#define __PPH_GUARD_H
+/* { dg-options "-w -fpermissive" }  */
+
+typedef __SIZE_TYPE__ size_t;
+extern void abort (void);
+extern void exit (int);
+extern void *malloc (size_t);
+extern void *calloc (size_t, size_t);
+extern void *alloca (size_t);
+extern void *memcpy (void *, const void *, size_t);
+extern void *memset (void *, int, size_t);
+extern char *strcpy (char *, const char *);
+
+struct A
+{
+  char a[10];
+  int b;
+  char c[10];
+} y, w[4];
+
+extern char exta[];
+extern char extb[30];
+extern struct A extc[];
+struct A zerol[0];
+
+void
+__attribute__ ((noinline))
+test1 (void *q, int x)
+{
+  struct A a;
+  void *p = &a.a[3], *r;
+  char var[x + 10];
+  struct A vara[x + 10];
+  if (x < 0)
+    r = &a.a[9];
+  else
+    r = &a.c[1];
+  if (__builtin_object_size (p, 1) != sizeof (a.a) - 3)
+    abort ();
+  if (__builtin_object_size (&a.c[9], 1)
+      != sizeof (a.c) - 9)
+    abort ();
+  if (__builtin_object_size (q, 1) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (r, 1) != sizeof (a.c) - 1)
+    abort ();
+  if (x < 6)
+    r = &w[2].a[1];
+  else
+    r = &a.a[6];
+  if (__builtin_object_size (&y, 1) != sizeof (y))
+    abort ();
+  if (__builtin_object_size (w, 1) != sizeof (w))
+    abort ();
+  if (__builtin_object_size (&y.b, 1) != sizeof (a.b))
+    abort ();
+  if (__builtin_object_size (r, 1) != sizeof (a.a) - 1)
+    abort ();
+  if (x < 20)
+    r = malloc (30);
+  else
+    r = calloc (2, 16);
+  if (__builtin_object_size (r, 1) != 2 * 16)
+    abort ();
+  if (x < 20)
+    r = malloc (30);
+  else
+    r = calloc (2, 14);
+  if (__builtin_object_size (r, 1) != 30)
+    abort ();
+  if (x < 30)
+    r = malloc (sizeof (a));
+  else
+    r = &a.a[3];
+  if (__builtin_object_size (r, 1) != sizeof (a))
+    abort ();
+  r = memcpy (r, "a", 2);
+  if (__builtin_object_size (r, 1) != sizeof (a))
+    abort ();
+  r = memcpy (r + 2, "b", 2) + 2;
+  if (__builtin_object_size (r, 1) != sizeof (a) - 4)
+    abort ();
+  r = &a.a[4];
+  r = memset (r, 'a', 2);
+  if (__builtin_object_size (r, 1) != sizeof (a.a) - 4)
+    abort ();
+  r = memset (r + 2, 'b', 2) + 2;
+  if (__builtin_object_size (r, 1) != sizeof (a.a) - 8)
+    abort ();
+  r = &a.a[1];
+  r = strcpy (r, "ab");
+  if (__builtin_object_size (r, 1) != sizeof (a.a) - 1)
+    abort ();
+  r = strcpy (r + 2, "cd") + 2;
+  if (__builtin_object_size (r, 1) != sizeof (a.a) - 5)
+    abort ();
+  if (__builtin_object_size (exta, 1) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (exta + 10, 1) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (&exta[5], 1) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (extb, 1) != sizeof (extb))
+    abort ();
+  if (__builtin_object_size (extb + 10, 1) != sizeof (extb) - 10)
+    abort ();
+  if (__builtin_object_size (&extb[5], 1) != sizeof (extb) - 5)
+    abort ();
+  if (__builtin_object_size (extc, 1) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (extc + 10, 1) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (&extc[5], 1) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (&extc->a, 1) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (&(extc + 10)->b, 1) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (&extc[5].c[3], 1) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (var, 1) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (var + 10, 1) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (&var[5], 1) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (vara, 1) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (vara + 10, 1) != (size_t) -1)
+    abort ();    
+  if (__builtin_object_size (&vara[5], 1) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (&vara[0].a, 1) != sizeof (vara[0].a))
+    abort ();
+  if (__builtin_object_size (&vara[10].a[0], 1) != sizeof (vara[0].a))
+    abort ();
+  if (__builtin_object_size (&vara[5].a[4], 1) != sizeof (vara[0].a) - 4)
+    abort ();
+  if (__builtin_object_size (&vara[5].b, 1) != sizeof (vara[0].b))
+    abort ();
+  if (__builtin_object_size (&vara[7].c[7], 1) != sizeof (vara[0].c) - 7)
+    abort ();
+  if (__builtin_object_size (zerol, 1) != 0)
+    abort ();
+  if (__builtin_object_size (&zerol, 1) != 0)
+    abort ();
+  if (__builtin_object_size (&zerol[0], 1) != 0)
+    abort ();
+  if (__builtin_object_size (zerol[0].a, 1) != 0)
+    abort ();
+  if (__builtin_object_size (&zerol[0].a[0], 1) != 0)
+    abort ();
+  if (__builtin_object_size (&zerol[0].b, 1) != 0)
+    abort ();
+  if (__builtin_object_size ("abcdefg", 1) != sizeof ("abcdefg"))
+    abort ();
+  if (__builtin_object_size ("abcd\0efg", 1) != sizeof ("abcd\0efg"))
+    abort ();
+  if (__builtin_object_size (&"abcd\0efg", 1) != sizeof ("abcd\0efg"))
+    abort ();
+  if (__builtin_object_size (&"abcd\0efg"[0], 1) != sizeof ("abcd\0efg"))
+    abort ();
+  if (__builtin_object_size (&"abcd\0efg"[4], 1) != sizeof ("abcd\0efg") - 4)
+    abort ();
+  if (__builtin_object_size ("abcd\0efg" + 5, 1) != sizeof ("abcd\0efg") - 5)
+    abort ();
+  if (__builtin_object_size (L"abcdefg", 1) != sizeof (L"abcdefg"))
+    abort ();
+  r = (char *) L"abcd\0efg";
+  if (__builtin_object_size (r + 2, 1) != sizeof (L"abcd\0efg") - 2)
+    abort ();
+}
+
+size_t l1 = 1;
+
+void
+__attribute__ ((noinline))
+test2 (void)
+{
+  struct B { char buf1[10]; char buf2[10]; } a;
+  char *r, buf3[20];
+  int i;
+
+  if (sizeof (a) != 20)
+    return;
+
+  r = buf3;
+  for (i = 0; i < 4; ++i)
+    {
+      if (i == l1 - 1)
+	r = &a.buf1[1];
+      else if (i == l1)
+	r = &a.buf2[7];
+      else if (i == l1 + 1)
+	r = &buf3[5];
+      else if (i == l1 + 2)
+	r = &a.buf1[9];
+    }
+  if (__builtin_object_size (r, 1) != sizeof (buf3))
+    abort ();
+  r = &buf3[20];
+  for (i = 0; i < 4; ++i)
+    {
+      if (i == l1 - 1)
+	r = &a.buf1[7];
+      else if (i == l1)
+	r = &a.buf2[7];
+      else if (i == l1 + 1)
+	r = &buf3[5];
+      else if (i == l1 + 2)
+	r = &a.buf1[9];
+    }
+  if (__builtin_object_size (r, 1) != sizeof (buf3) - 5)
+    abort ();
+  r += 8;
+  if (__builtin_object_size (r, 1) != sizeof (buf3) - 13)
+    abort ();
+  if (__builtin_object_size (r + 6, 1) != sizeof (buf3) - 19)
+    abort ();
+}
+
+void
+__attribute__ ((noinline))
+test3 (void)
+{
+  char buf4[10];
+  struct B { struct A a[2]; struct A b; char c[4]; char d; double e;
+	     _Complex double f; } x;
+  double y;
+  _Complex double z;
+  double *dp;
+
+  if (__builtin_object_size (buf4, 1) != sizeof (buf4))
+    abort ();
+  if (__builtin_object_size (&buf4, 1) != sizeof (buf4))
+    abort ();
+  if (__builtin_object_size (&buf4[0], 1) != sizeof (buf4))
+    abort ();
+  if (__builtin_object_size (&buf4[1], 1) != sizeof (buf4) - 1)
+    abort ();
+  if (__builtin_object_size (&x, 1) != sizeof (x))
+    abort ();
+  if (__builtin_object_size (&x.a, 1) != sizeof (x.a))
+    abort ();
+  if (__builtin_object_size (&x.a[0], 1) != sizeof (x.a))
+    abort ();
+  if (__builtin_object_size (&x.a[0].a, 1) != sizeof (x.a[0].a))
+    abort ();
+  if (__builtin_object_size (&x.a[0].a[0], 1) != sizeof (x.a[0].a))
+    abort ();
+  if (__builtin_object_size (&x.a[0].a[3], 1) != sizeof (x.a[0].a) - 3)
+    abort ();
+  if (__builtin_object_size (&x.a[0].b, 1) != sizeof (x.a[0].b))
+    abort ();
+  if (__builtin_object_size (&x.a[1].c, 1) != sizeof (x.a[1].c))
+    abort ();
+  if (__builtin_object_size (&x.a[1].c[0], 1) != sizeof (x.a[1].c))
+    abort ();
+  if (__builtin_object_size (&x.a[1].c[3], 1) != sizeof (x.a[1].c) - 3)
+    abort ();
+  if (__builtin_object_size (&x.b, 1) != sizeof (x.b))
+    abort ();
+  if (__builtin_object_size (&x.b.a, 1) != sizeof (x.b.a))
+    abort ();
+  if (__builtin_object_size (&x.b.a[0], 1) != sizeof (x.b.a))
+    abort ();
+  if (__builtin_object_size (&x.b.a[3], 1) != sizeof (x.b.a) - 3)
+    abort ();
+  if (__builtin_object_size (&x.b.b, 1) != sizeof (x.b.b))
+    abort ();
+  if (__builtin_object_size (&x.b.c, 1) != sizeof (x.b.c))
+    abort ();
+  if (__builtin_object_size (&x.b.c[0], 1) != sizeof (x.b.c))
+    abort ();
+  if (__builtin_object_size (&x.b.c[3], 1) != sizeof (x.b.c) - 3)
+    abort ();
+  if (__builtin_object_size (&x.c, 1) != sizeof (x.c))
+    abort ();
+  if (__builtin_object_size (&x.c[0], 1) != sizeof (x.c))
+    abort ();
+  if (__builtin_object_size (&x.c[1], 1) != sizeof (x.c) - 1)
+    abort ();
+  if (__builtin_object_size (&x.d, 1) != sizeof (x.d))
+    abort ();
+  if (__builtin_object_size (&x.e, 1) != sizeof (x.e))
+    abort ();
+  if (__builtin_object_size (&x.f, 1) != sizeof (x.f))
+    abort ();
+  dp = &__real__ x.f;
+  if (__builtin_object_size (dp, 1) != sizeof (x.f) / 2)
+    abort ();
+  dp = &__imag__ x.f;
+  if (__builtin_object_size (dp, 1) != sizeof (x.f) / 2)
+    abort ();
+  dp = &y;
+  if (__builtin_object_size (dp, 1) != sizeof (y))
+    abort ();
+  if (__builtin_object_size (&z, 1) != sizeof (z))
+      abort ();
+  dp = &__real__ z;
+  if (__builtin_object_size (dp, 1) != sizeof (z) / 2)
+    abort ();
+  dp = &__imag__ z;
+  if (__builtin_object_size (dp, 1) != sizeof (z) / 2)
+    abort ();
+}
+
+struct S { unsigned int a; };
+
+char *
+__attribute__ ((noinline))
+test4 (char *x, int y)
+{
+  register int i;
+  struct A *p;
+
+  for (i = 0; i < y; i++)
+    {
+      p = (struct A *) x;
+      x = (char *) &p[1];
+      if (__builtin_object_size (p, 1) != (size_t) -1)
+	abort ();
+    }
+  return x;
+}
+
+void
+__attribute__ ((noinline))
+test5 (size_t x)
+{
+  struct T { char buf[64]; char buf2[64]; } t;
+  char *p = &t.buf[8];
+  size_t i;
+
+  for (i = 0; i < x; ++i)
+    p = p + 4;
+  if (__builtin_object_size (p, 1) != sizeof (t.buf) - 8)
+    abort ();
+  memset (p, ' ', sizeof (t.buf) - 8 - 4 * 4);
+}
+
+void
+__attribute__ ((noinline))
+test6 (void)
+{
+  char buf[64];
+  struct T { char buf[64]; char buf2[64]; } t;
+  char *p = &buf[64], *q = &t.buf[64];
+
+  if (__builtin_object_size (p + 64, 1) != 0)
+    abort ();
+  if (__builtin_object_size (q + 0, 1) != 0)
+    abort ();
+  if (__builtin_object_size (q + 64, 1) != 0)
+    abort ();
+}
+
+void
+__attribute__ ((noinline))
+test7 (void)
+{
+  struct T { char buf[10]; char buf2[10]; } t;
+  char *p = &t.buf2[-4];
+  char *q = &t.buf2[0];
+  if (__builtin_object_size (p, 1) != 0)
+    abort ();
+  if (__builtin_object_size (q, 1) != sizeof (t.buf2))
+    abort ();
+  q = &t.buf[10];
+  if (__builtin_object_size (q, 1) != 0)
+    abort ();
+  q = &t.buf[11];
+  if (__builtin_object_size (q, 1) != 0)
+    abort ();
+  p = &t.buf[-4];
+  if (__builtin_object_size (p, 1) != 0)
+    abort ();
+}
+
+int
+main (void)
+{
+  struct S s[10];
+  __asm ("" : "=r" (l1) : "0" (l1));
+  test1 (main, 6);
+  test2 ();
+  test3 ();
+  test4 ((char *) s, 10);
+  test5 (4);
+  test6 ();
+  test7 ();
+  exit (0);
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/pph/c1eabi1.cc b/gcc/testsuite/g++.dg/pph/c1eabi1.cc
new file mode 100644
index 0000000..5680787
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pph/c1eabi1.cc
@@ -0,0 +1,4 @@
+/* { dg-options "-w -fpermissive" } */
+/* { dg-xfail-if "ICEs the compiler during PPH read" { "*-*-*" } } */
+/* { dg-prune-output "In file included.*" } */
+#include "c1eabi1.h"
diff --git a/gcc/testsuite/g++.dg/pph/c1eabi1.h b/gcc/testsuite/g++.dg/pph/c1eabi1.h
new file mode 100644
index 0000000..3ac35ce
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pph/c1eabi1.h
@@ -0,0 +1,345 @@
+#ifndef __PPH_GUARD_H
+#define __PPH_GUARD_H
+/* { dg-options "-w -fpermissive" } */
+/* { dg-xfail-if "ICEs the compiler during PPH read" { "*-*-*" } } */
+/* { dg-prune-output "In file included.*" } */
+/* This file tests most of the non-C++ run-time helper functions
+   described in Section 4 of the "Run-Time ABI for the ARM
+   Architecture".  These are basic tests; they do not try to validate
+   all of the corner cases in these routines.  
+
+   The functions not tested here are:
+
+     __aeabi_cdcmpeq
+     __aeabi_cdcmple
+     __aeabi_cdrcmple
+     __aeabi_cfcmpeq
+     __aeabi_cfcmple
+     __aeabi_cfrcmple
+     __aeabi_ldivmod
+     __aeabi_uldivmod
+     __aeabi_idivmod
+     __aeabi_uidivmod
+
+   These functions have non-standard calling conventions that would
+   require the use of inline assembly to test.  It would be good to
+   add such tests, but they have not yet been implemented.  
+
+   There are also no tests for the "division by zero", "memory copying,
+   clearing, and setting" functions.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+/* All these functions are defined to use the base ABI, so use the
+   attribute to ensure the tests use the base ABI to call them even
+   when the VFP ABI is otherwise in effect.  */
+#define PCS __attribute__((pcs("aapcs")))
+
+#define decl_float(code, type)						\
+  extern type __aeabi_ ## code ## add (type, type) PCS;			\
+  extern type __aeabi_ ## code ## div (type, type) PCS;			\
+  extern type __aeabi_ ## code ## mul (type, type) PCS;			\
+  extern type __aeabi_ ## code ## neg (type) PCS;			\
+  extern type __aeabi_ ## code ## rsub (type, type) PCS;		\
+  extern type __aeabi_ ## code ## sub (type, type) PCS;			\
+  extern int __aeabi_ ## code ## cmpeq (type, type) PCS;		\
+  extern int __aeabi_ ## code ## cmplt (type, type) PCS;		\
+  extern int __aeabi_ ## code ## cmple (type, type) PCS;		\
+  extern int __aeabi_ ## code ## cmpge (type, type) PCS;		\
+  extern int __aeabi_ ## code ## cmpgt (type, type) PCS;		\
+  extern int __aeabi_ ## code ## cmpun (type, type) PCS;		\
+  extern int __aeabi_ ## code ## 2iz (type) PCS;			\
+  extern unsigned int __aeabi_ ## code ## 2uiz (type) PCS;		\
+  extern long long __aeabi_ ## code ## 2lz (type) PCS;			\
+  extern unsigned long long __aeabi_ ## code ## 2ulz (type) PCS;	\
+  extern type __aeabi_i2 ## code (int) PCS;				\
+  extern type __aeabi_ui2 ## code (int) PCS;				\
+  extern type __aeabi_l2 ## code (long long) PCS;			\
+  extern type __aeabi_ul2 ## code (unsigned long long) PCS;		\
+									\
+  type code ## zero = 0.0;						\
+  type code ## one = 1.0;						\
+  type code ## two = 2.0;						\
+  type code ## four = 4.0;						\
+  type code ## minus_one = -1.0;					\
+  type code ## minus_two = -2.0;					\
+  type code ## minus_four = -4.0;					\
+  type code ## epsilon = 1E-32;						\
+  type code ## NaN = 0.0 / 0.0;
+
+decl_float (d, double)
+decl_float (f, float)
+
+extern float __aeabi_d2f (double) PCS;
+extern double __aeabi_f2d (float) PCS;
+extern long long __aeabi_lmul (long long, long long);
+extern long long __aeabi_llsl (long long, int);
+extern long long __aeabi_llsr (long long, int);
+extern long long __aeabi_lasr (long long, int);
+extern int __aeabi_lcmp (long long, long long);
+extern int __aeabi_ulcmp (unsigned long long, unsigned long long);
+extern int __aeabi_idiv (int, int);
+extern unsigned int __aeabi_uidiv (unsigned int, unsigned int);
+extern int __aeabi_uread4 (void *);
+extern int __aeabi_uwrite4 (int, void *);
+extern long long __aeabi_uread8 (void *);
+extern long long __aeabi_uwrite8 (long long, void *);
+
+#define eq(a, b, type, abs, epsilon, format)			\
+  {								\
+    type a1;							\
+    type b1;							\
+								\
+    a1 = a;							\
+    b1 = b;							\
+    if (abs (a1 - b1) > epsilon)				\
+    {								\
+      fprintf (stderr, "%d: Test %s == %s\n", __LINE__, #a, #b);	\
+      fprintf (stderr, "%d: " format " != " format "\n",	\
+	       __LINE__, a1, b1);				\
+      abort ();							\
+    }								\
+  }
+
+#define ieq(a, b) eq (a, b, int, abs, 0, "%d")
+#define ueq(a, b) eq (a, b, unsigned int, abs, 0, "%u")
+#define leq(a, b) eq (a, b, long long, abs, 0, "%lld")
+#define uleq(a, b) eq (a, b, unsigned long long, abs, 0, "%llu")
+#define feq(a, b) eq (a, b, float, fabs, fepsilon, "%f")
+#define deq(a, b) eq (a, b, double, fabs, depsilon, "%g")
+
+#define NUM_CMP_VALUES 6
+
+/* Values picked to cover a range of small, large, positive and negative.  */
+static unsigned int cmp_val[NUM_CMP_VALUES] = 
+{
+  0,
+  1,
+  0x40000000,
+  0x80000000,
+  0xc0000000,
+  0xffffffff
+};
+
+/* All combinations for each of the above values. */
+#define ulcmp(l, s, m) \
+    s, l, l, l, l, l,  m, s, l, l, l, l, \
+    m, m, s, l, l, l,  m, m, m, s, l, l, \
+    m, m, m, m, s, l,  m, m, m, m, m, s
+
+#define lcmp(l, s, m) \
+    s, l, l, m, m, m,  m, s, l, m, m, m, \
+    m, m, s, m, m, m,  l, l, l, s, l, l, \
+    l, l, l, m, s, l,  l, l, l, m, m, s
+
+/* All combinations of the above for high/low words.  */
+static int lcmp_results[] =
+{
+  lcmp(ulcmp(-1, -1, -1), ulcmp(-1, 0, 1), ulcmp(1, 1, 1))
+};
+
+static int ulcmp_results[] =
+{
+  ulcmp(ulcmp(-1, -1, -1), ulcmp(-1, 0, 1), ulcmp(1, 1, 1))
+};
+
+static int signof(int i)
+{
+  if (i < 0)
+    return -1;
+
+  if (i == 0)
+    return 0;
+
+  return 1;
+}
+
+int main () {
+  unsigned char bytes[256];
+  int i, j, k, n;
+  int *result;
+
+  /* Table 2.  Double-precision floating-point arithmetic.  */
+  deq (__aeabi_dadd (dzero, done), done);
+  deq (__aeabi_dadd (done, done), dtwo);
+  deq (__aeabi_ddiv (dminus_four, dminus_two), dtwo);
+  deq (__aeabi_ddiv (dminus_two, dtwo), dminus_one);
+  deq (__aeabi_dmul (dtwo, dtwo), dfour);
+  deq (__aeabi_dmul (dminus_one, dminus_two), dtwo);
+  deq (__aeabi_dneg (dminus_one), done);
+  deq (__aeabi_dneg (dfour), dminus_four);
+  deq (__aeabi_drsub (done, dzero), dminus_one);
+  deq (__aeabi_drsub (dtwo, dminus_two), dminus_four);
+  deq (__aeabi_dsub (dzero, done), dminus_one);
+  deq (__aeabi_dsub (dminus_two, dtwo), dminus_four);
+
+  /* Table 3.  Double-precision floating-point comparisons.  */
+  ieq (__aeabi_dcmpeq (done, done), 1);
+  ieq (__aeabi_dcmpeq (done, dzero), 0);
+  ieq (__aeabi_dcmpeq (dNaN, dzero), 0);
+  ieq (__aeabi_dcmpeq (dNaN, dNaN), 0);
+
+  ieq (__aeabi_dcmplt (dzero, done), 1);
+  ieq (__aeabi_dcmplt (done, dzero), 0);
+  ieq (__aeabi_dcmplt (dzero, dzero), 0);
+  ieq (__aeabi_dcmplt (dzero, dNaN), 0);
+  ieq (__aeabi_dcmplt (dNaN, dNaN), 0);
+
+  ieq (__aeabi_dcmple (dzero, done), 1);
+  ieq (__aeabi_dcmple (done, dzero), 0);
+  ieq (__aeabi_dcmple (dzero, dzero), 1);
+  ieq (__aeabi_dcmple (dzero, dNaN), 0);
+  ieq (__aeabi_dcmple (dNaN, dNaN), 0);
+
+  ieq (__aeabi_dcmpge (dzero, done), 0);
+  ieq (__aeabi_dcmpge (done, dzero), 1);
+  ieq (__aeabi_dcmpge (dzero, dzero), 1);
+  ieq (__aeabi_dcmpge (dzero, dNaN), 0);
+  ieq (__aeabi_dcmpge (dNaN, dNaN), 0);
+
+  ieq (__aeabi_dcmpgt (dzero, done), 0);
+  ieq (__aeabi_dcmpgt (done, dzero), 1);
+  ieq (__aeabi_dcmplt (dzero, dzero), 0);
+  ieq (__aeabi_dcmpgt (dzero, dNaN), 0);
+  ieq (__aeabi_dcmpgt (dNaN, dNaN), 0);
+
+  ieq (__aeabi_dcmpun (done, done), 0);
+  ieq (__aeabi_dcmpun (done, dzero), 0);
+  ieq (__aeabi_dcmpun (dNaN, dzero), 1);
+  ieq (__aeabi_dcmpun (dNaN, dNaN), 1);
+
+  /* Table 4.  Single-precision floating-point arithmetic.  */
+  feq (__aeabi_fadd (fzero, fone), fone);
+  feq (__aeabi_fadd (fone, fone), ftwo);
+  feq (__aeabi_fdiv (fminus_four, fminus_two), ftwo);
+  feq (__aeabi_fdiv (fminus_two, ftwo), fminus_one);
+  feq (__aeabi_fmul (ftwo, ftwo), ffour);
+  feq (__aeabi_fmul (fminus_one, fminus_two), ftwo);
+  feq (__aeabi_fneg (fminus_one), fone);
+  feq (__aeabi_fneg (ffour), fminus_four);
+  feq (__aeabi_frsub (fone, fzero), fminus_one);
+  feq (__aeabi_frsub (ftwo, fminus_two), fminus_four);
+  feq (__aeabi_fsub (fzero, fone), fminus_one);
+  feq (__aeabi_fsub (fminus_two, ftwo), fminus_four);
+
+  /* Table 5.  Single-precision floating-point comparisons.  */
+  ieq (__aeabi_fcmpeq (fone, fone), 1);
+  ieq (__aeabi_fcmpeq (fone, fzero), 0);
+  ieq (__aeabi_fcmpeq (fNaN, fzero), 0);
+  ieq (__aeabi_fcmpeq (fNaN, fNaN), 0);
+
+  ieq (__aeabi_fcmplt (fzero, fone), 1);
+  ieq (__aeabi_fcmplt (fone, fzero), 0);
+  ieq (__aeabi_fcmplt (fzero, fzero), 0);
+  ieq (__aeabi_fcmplt (fzero, fNaN), 0);
+  ieq (__aeabi_fcmplt (fNaN, fNaN), 0);
+
+  ieq (__aeabi_fcmple (fzero, fone), 1);
+  ieq (__aeabi_fcmple (fone, fzero), 0);
+  ieq (__aeabi_fcmple (fzero, fzero), 1);
+  ieq (__aeabi_fcmple (fzero, fNaN), 0);
+  ieq (__aeabi_fcmple (fNaN, fNaN), 0);
+
+  ieq (__aeabi_fcmpge (fzero, fone), 0);
+  ieq (__aeabi_fcmpge (fone, fzero), 1);
+  ieq (__aeabi_fcmpge (fzero, fzero), 1);
+  ieq (__aeabi_fcmpge (fzero, fNaN), 0);
+  ieq (__aeabi_fcmpge (fNaN, fNaN), 0);
+
+  ieq (__aeabi_fcmpgt (fzero, fone), 0);
+  ieq (__aeabi_fcmpgt (fone, fzero), 1);
+  ieq (__aeabi_fcmplt (fzero, fzero), 0);
+  ieq (__aeabi_fcmpgt (fzero, fNaN), 0);
+  ieq (__aeabi_fcmpgt (fNaN, fNaN), 0);
+
+  ieq (__aeabi_fcmpun (fone, fone), 0);
+  ieq (__aeabi_fcmpun (fone, fzero), 0);
+  ieq (__aeabi_fcmpun (fNaN, fzero), 1);
+  ieq (__aeabi_fcmpun (fNaN, fNaN), 1);
+
+  /* Table 6.  Floating-point to integer conversions.  */
+  ieq (__aeabi_d2iz (dminus_one), -1);
+  ueq (__aeabi_d2uiz (done), 1);
+  leq (__aeabi_d2lz (dminus_two), -2LL);
+  uleq (__aeabi_d2ulz (dfour), 4LL);
+  ieq (__aeabi_f2iz (fminus_one), -1);
+  ueq (__aeabi_f2uiz (fone), 1);
+  leq (__aeabi_f2lz (fminus_two), -2LL);
+  uleq (__aeabi_f2ulz (ffour), 4LL);
+
+  /* Table 7.  Conversions between floating types.  */
+  feq (__aeabi_d2f (dtwo), ftwo);
+  deq (__aeabi_f2d (fminus_four), dminus_four);
+
+  /* Table 8.  Integer to floating-point conversions.  */
+  deq (__aeabi_i2d (-1), dminus_one);
+  deq (__aeabi_ui2d (2), dtwo);
+  deq (__aeabi_l2d (-1), dminus_one);
+  deq (__aeabi_ul2d (2ULL), dtwo);
+  feq (__aeabi_i2f (-1), fminus_one);
+  feq (__aeabi_ui2f (2), ftwo);
+  feq (__aeabi_l2f (-1), fminus_one);
+  feq (__aeabi_ul2f (2ULL), ftwo);
+
+  /* Table 9.  Long long functions.  */
+  leq (__aeabi_lmul (4LL, -1LL), -4LL);
+  leq (__aeabi_llsl (2LL, 1), 4LL);
+  leq (__aeabi_llsr (-1LL, 63), 1);
+  leq (__aeabi_lasr (-1LL, 63), -1);
+
+  result = lcmp_results;
+  for (i = 0; i < NUM_CMP_VALUES; i++)
+    for (j = 0; j < NUM_CMP_VALUES; j++)
+      for (k = 0; k < NUM_CMP_VALUES; k++)
+	for (n = 0; n < NUM_CMP_VALUES; n++)
+	  {
+	    ieq (signof (__aeabi_lcmp
+			  (((long long)cmp_val[i] << 32) | cmp_val[k],
+			   ((long long)cmp_val[j] << 32) | cmp_val[n])),
+			   *result);
+	    result++;
+	  }
+  result = ulcmp_results;
+  for (i = 0; i < NUM_CMP_VALUES; i++)
+    for (j = 0; j < NUM_CMP_VALUES; j++)
+      for (k = 0; k < NUM_CMP_VALUES; k++)
+	for (n = 0; n < NUM_CMP_VALUES; n++)
+	  {
+	    ieq (signof (__aeabi_ulcmp
+			  (((long long)cmp_val[i] << 32) | cmp_val[k],
+			   ((long long)cmp_val[j] << 32) | cmp_val[n])),
+			   *result);
+	    result++;
+	  }
+
+  ieq (__aeabi_idiv (-550, 11), -50);
+  ueq (__aeabi_uidiv (4000000000U, 1000000U), 4000U);
+
+  for (i = 0; i < 256; i++)
+    bytes[i] = i;
+
+#ifdef __ARMEB__
+  ieq (__aeabi_uread4 (bytes + 1), 0x01020304U);
+  leq (__aeabi_uread8 (bytes + 3), 0x030405060708090aLL);
+  ieq (__aeabi_uwrite4 (0x66778899U, bytes + 5), 0x66778899U);
+  leq (__aeabi_uwrite8 (0x2030405060708090LL, bytes + 15),
+       0x2030405060708090LL);
+#else
+  ieq (__aeabi_uread4 (bytes + 1), 0x04030201U);
+  leq (__aeabi_uread8 (bytes + 3), 0x0a09080706050403LL);
+  ieq (__aeabi_uwrite4 (0x99887766U, bytes + 5), 0x99887766U);
+  leq (__aeabi_uwrite8 (0x9080706050403020LL, bytes + 15),
+       0x9080706050403020LL);
+#endif
+
+  for (i = 0; i < 4; i++)
+    ieq (bytes[5 + i], (6 + i) * 0x11);
+
+  for (i = 0; i < 8; i++)
+    ieq (bytes[15 + i], (2 + i) * 0x10);
+
+  exit (0);		
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/pph/c1meteor-contest.cc b/gcc/testsuite/g++.dg/pph/c1meteor-contest.cc
new file mode 100644
index 0000000..bb097ac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pph/c1meteor-contest.cc
@@ -0,0 +1,2 @@
+/* { dg-options "-w" }  */
+#include "c1meteor-contest.h"
diff --git a/gcc/testsuite/g++.dg/pph/c1meteor-contest.h b/gcc/testsuite/g++.dg/pph/c1meteor-contest.h
new file mode 100644
index 0000000..3c465ab
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pph/c1meteor-contest.h
@@ -0,0 +1,630 @@
+/* { dg-options "-w" }  */
+#ifndef __PPH_GUARD_H
+#define __PPH_GUARD_H
+/*
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+    * Neither the name of "The Computer Language Benchmarks Game" nor the
+    name of "The Computer Language Shootout Benchmarks" nor the names of
+    its contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* The Computer Language Benchmarks Game
+ * http://shootout.alioth.debian.org/
+ *
+ * contributed by Christian Vosteen
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#define TRUE 1
+#define FALSE 0
+
+/* The board is a 50 cell hexagonal pattern.  For    . . . . .
+ * maximum speed the board will be implemented as     . . . . .
+ * 50 bits, which will fit into a 64 bit long long   . . . . .
+ * int.                                               . . . . .
+ *                                                   . . . . .
+ * I will represent 0's as empty cells and 1's        . . . . .
+ * as full cells.                                    . . . . .
+ *                                                    . . . . .
+ *                                                   . . . . .
+ *                                                    . . . . .
+ */
+
+unsigned long long board = 0xFFFC000000000000ULL;
+
+/* The puzzle pieces must be specified by the path followed
+ * from one end to the other along 12 hexagonal directions.
+ *
+ *   Piece 0   Piece 1   Piece 2   Piece 3   Piece 4
+ *
+ *  O O O O    O   O O   O O O     O O O     O   O
+ *         O    O O           O       O       O O
+ *                           O         O         O
+ *
+ *   Piece 5   Piece 6   Piece 7   Piece 8   Piece 9
+ *
+ *    O O O     O O       O O     O O        O O O O
+ *       O O       O O       O       O O O        O
+ *                  O       O O
+ *
+ * I had to make it 12 directions because I wanted all of the
+ * piece definitions to fit into the same size arrays.  It is
+ * not possible to define piece 4 in terms of the 6 cardinal
+ * directions in 4 moves.
+ */
+
+#define E     0
+#define ESE   1
+#define SE    2
+#define S     3
+#define SW    4
+#define WSW   5
+#define W     6
+#define WNW   7
+#define NW    8
+#define N     9
+#define NE    10
+#define ENE   11
+#define PIVOT 12
+
+char piece_def[10][4] = {
+   {  E,  E,  E, SE},
+   { SE,  E, NE,  E},
+   {  E,  E, SE, SW},
+   {  E,  E, SW, SE},
+   { SE,  E, NE,  S},
+   {  E,  E, SW,  E},
+   {  E, SE, SE, NE},
+   {  E, SE, SE,  W},
+   {  E, SE,  E,  E},
+   {  E,  E,  E, SW}
+};
+
+
+/* To minimize the amount of work done in the recursive solve function below,
+ * I'm going to allocate enough space for all legal rotations of each piece
+ * at each position on the board. That's 10 pieces x 50 board positions x
+ * 12 rotations.  However, not all 12 rotations will fit on every cell, so
+ * I'll have to keep count of the actual number that do.
+ * The pieces are going to be unsigned long long ints just like the board so
+ * they can be bitwise-anded with the board to determine if they fit.
+ * I'm also going to record the next possible open cell for each piece and
+ * location to reduce the burden on the solve function.
+ */
+unsigned long long pieces[10][50][12];
+int piece_counts[10][50];
+char next_cell[10][50][12];
+
+/* Returns the direction rotated 60 degrees clockwise */
+char rotate(char dir) {
+   return (dir + 2) % PIVOT;
+}
+
+/* Returns the direction flipped on the horizontal axis */
+char flip(char dir) {
+   return (PIVOT - dir) % PIVOT;
+}
+
+
+/* Returns the new cell index from the specified cell in the
+ * specified direction.  The index is only valid if the
+ * starting cell and direction have been checked by the
+ * out_of_bounds function first.
+ */
+char shift(char cell, char dir) {
+   switch(dir) {
+      case E:
+         return cell + 1;
+      case ESE:
+         if((cell / 5) % 2)
+            return cell + 7;
+         else
+            return cell + 6;
+      case SE:
+         if((cell / 5) % 2)
+            return cell + 6;
+         else
+            return cell + 5;
+      case S:
+         return cell + 10;
+      case SW:
+         if((cell / 5) % 2)
+            return cell + 5;
+         else
+            return cell + 4;
+      case WSW:
+         if((cell / 5) % 2)
+            return cell + 4;
+         else
+            return cell + 3;
+      case W:
+         return cell - 1;
+      case WNW:
+         if((cell / 5) % 2)
+            return cell - 6;
+         else
+            return cell - 7;
+      case NW:
+         if((cell / 5) % 2)
+            return cell - 5;
+         else
+            return cell - 6;
+      case N:
+         return cell - 10;
+      case NE:
+         if((cell / 5) % 2)
+            return cell - 4;
+         else
+            return cell - 5;
+      case ENE:
+         if((cell / 5) % 2)
+            return cell - 3;
+         else
+            return cell - 4;
+      default:
+         return cell;
+   }
+}
+
+/* Returns wether the specified cell and direction will land outside
+ * of the board.  Used to determine if a piece is at a legal board
+ * location or not.
+ */
+char out_of_bounds(char cell, char dir) {
+   char i;
+   switch(dir) {
+      case E:
+         return cell % 5 == 4;
+      case ESE:
+         i = cell % 10;
+         return i == 4 || i == 8 || i == 9 || cell >= 45;
+      case SE:
+         return cell % 10 == 9 || cell >= 45;
+      case S:
+         return cell >= 40;
+      case SW:
+         return cell % 10 == 0 || cell >= 45;
+      case WSW:
+         i = cell % 10;
+         return i == 0 || i == 1 || i == 5 || cell >= 45;
+      case W:
+         return cell % 5 == 0;
+      case WNW:
+         i = cell % 10;
+         return i == 0 || i == 1 || i == 5 || cell < 5;
+      case NW:
+         return cell % 10 == 0 || cell < 5;
+      case N:
+         return cell < 10;
+      case NE:
+         return cell % 10 == 9 || cell < 5;
+      case ENE:
+         i = cell % 10;
+         return i == 4 || i == 8 || i == 9 || cell < 5;
+      default:
+         return FALSE;
+   }
+}
+
+/* Rotate a piece 60 degrees clockwise */
+void rotate_piece(int piece) {
+   int i;
+   for(i = 0; i < 4; i++)
+      piece_def[piece][i] = rotate(piece_def[piece][i]);
+}
+
+/* Flip a piece along the horizontal axis */
+void flip_piece(int piece) {
+   int i;
+   for(i = 0; i < 4; i++)
+      piece_def[piece][i] = flip(piece_def[piece][i]);
+}
+
+/* Convenience function to quickly calculate all of the indices for a piece */
+void calc_cell_indices(char *cell, int piece, char index) {
+   cell[0] = index;
+   cell[1] = shift(cell[0], piece_def[piece][0]);
+   cell[2] = shift(cell[1], piece_def[piece][1]);
+   cell[3] = shift(cell[2], piece_def[piece][2]);
+   cell[4] = shift(cell[3], piece_def[piece][3]);
+}
+
+/* Convenience function to quickly calculate if a piece fits on the board */
+int cells_fit_on_board(char *cell, int piece) {
+   return (!out_of_bounds(cell[0], piece_def[piece][0]) &&
+         !out_of_bounds(cell[1], piece_def[piece][1]) &&
+         !out_of_bounds(cell[2], piece_def[piece][2]) &&
+         !out_of_bounds(cell[3], piece_def[piece][3]));
+}
+
+/* Returns the lowest index of the cells of a piece.
+ * I use the lowest index that a piece occupies as the index for looking up
+ * the piece in the solve function.
+ */
+char minimum_of_cells(char *cell) {
+   char minimum = cell[0];
+   minimum = cell[1] < minimum ? cell[1] : minimum;
+   minimum = cell[2] < minimum ? cell[2] : minimum;
+   minimum = cell[3] < minimum ? cell[3] : minimum;
+   minimum = cell[4] < minimum ? cell[4] : minimum;
+   return minimum;
+}
+
+/* Calculate the lowest possible open cell if the piece is placed on the board.
+ * Used to later reduce the amount of time searching for open cells in the
+ * solve function.
+ */
+char first_empty_cell(char *cell, char minimum) {
+   char first_empty = minimum;
+   while(first_empty == cell[0] || first_empty == cell[1] ||
+         first_empty == cell[2] || first_empty == cell[3] ||
+         first_empty == cell[4])
+      first_empty++;
+   return first_empty;
+}
+
+/* Generate the unsigned long long int that will later be anded with the
+ * board to determine if it fits.
+ */
+unsigned long long bitmask_from_cells(char *cell) {
+   unsigned long long piece_mask = 0ULL;
+   int i;
+   for(i = 0; i < 5; i++)
+      piece_mask |= 1ULL << cell[i];
+   return piece_mask;
+}
+
+/* Record the piece and other important information in arrays that will
+ * later be used by the solve function.
+ */
+void record_piece(int piece, int minimum, char first_empty,
+      unsigned long long piece_mask) {
+   pieces[piece][minimum][piece_counts[piece][minimum]] = piece_mask;
+   next_cell[piece][minimum][piece_counts[piece][minimum]] = first_empty;
+   piece_counts[piece][minimum]++;
+}
+
+
+/* Fill the entire board going cell by cell.  If any cells are "trapped"
+ * they will be left alone.
+ */
+void fill_contiguous_space(char *board, int index) {
+   if(board[index] == 1)
+      return;
+   board[index] = 1;
+   if(!out_of_bounds(index, E))
+      fill_contiguous_space(board, shift(index, E));
+   if(!out_of_bounds(index, SE))
+      fill_contiguous_space(board, shift(index, SE));
+   if(!out_of_bounds(index, SW))
+      fill_contiguous_space(board, shift(index, SW));
+   if(!out_of_bounds(index, W))
+      fill_contiguous_space(board, shift(index, W));
+   if(!out_of_bounds(index, NW))
+      fill_contiguous_space(board, shift(index, NW));
+   if(!out_of_bounds(index, NE))
+      fill_contiguous_space(board, shift(index, NE));
+}
+
+
+/* To thin the number of pieces, I calculate if any of them trap any empty
+ * cells at the edges.  There are only a handful of exceptions where the
+ * the board can be solved with the trapped cells.  For example:  piece 8 can
+ * trap 5 cells in the corner, but piece 3 can fit in those cells, or piece 0
+ * can split the board in half where both halves are viable.
+ */
+int has_island(char *cell, int piece) {
+   char temp_board[50];
+   char c;
+   int i;
+   for(i = 0; i < 50; i++)
+      temp_board[i] = 0;
+   for(i = 0; i < 5; i++)
+      temp_board[((int)cell[i])] = 1;
+   i = 49;
+   while(temp_board[i] == 1)
+      i--;
+   fill_contiguous_space(temp_board, i);
+   c = 0;
+   for(i = 0; i < 50; i++)
+      if(temp_board[i] == 0)
+         c++;
+   if(c == 0 || (c == 5 && piece == 8) || (c == 40 && piece == 8) ||
+         (c % 5 == 0 && piece == 0))
+      return FALSE;
+   else
+      return TRUE;
+}
+
+
+/* Calculate all six rotations of the specified piece at the specified index.
+ * We calculate only half of piece 3's rotations.  This is because any solution
+ * found has an identical solution rotated 180 degrees.  Thus we can reduce the
+ * number of attempted pieces in the solve algorithm by not including the 180-
+ * degree-rotated pieces of ONE of the pieces.  I chose piece 3 because it gave
+ * me the best time ;)
+ */
+ void calc_six_rotations(char piece, char index) {
+   char rotation, cell[5];
+   char minimum, first_empty;
+   unsigned long long piece_mask;
+
+   for(rotation = 0; rotation < 6; rotation++) {
+      if(piece != 3 || rotation < 3) {
+         calc_cell_indices(cell, piece, index);
+         if(cells_fit_on_board(cell, piece) && !has_island(cell, piece)) {
+            minimum = minimum_of_cells(cell);
+            first_empty = first_empty_cell(cell, minimum);
+            piece_mask = bitmask_from_cells(cell);
+            record_piece(piece, minimum, first_empty, piece_mask);
+         }
+      }
+      rotate_piece(piece);
+   }
+}
+
+/* Calculate every legal rotation for each piece at each board location. */
+void calc_pieces(void) {
+   char piece, index;
+
+   for(piece = 0; piece < 10; piece++) {
+      for(index = 0; index < 50; index++) {
+         calc_six_rotations(piece, index);
+         flip_piece(piece);
+         calc_six_rotations(piece, index);
+      }
+   }
+}
+
+
+
+/* Calculate all 32 possible states for a 5-bit row and all rows that will
+ * create islands that follow any of the 32 possible rows.  These pre-
+ * calculated 5-bit rows will be used to find islands in a partially solved
+ * board in the solve function.
+ */
+#define ROW_MASK 0x1F
+#define TRIPLE_MASK 0x7FFF
+char all_rows[32] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+      17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
+int bad_even_rows[32][32];
+int bad_odd_rows[32][32];
+int bad_even_triple[32768];
+int bad_odd_triple[32768];
+
+int rows_bad(char row1, char row2, int even) {
+   /* even is referring to row1 */
+   int i, in_zeroes, group_okay;
+   char block, row2_shift;
+   /* Test for blockages at same index and shifted index */
+   if(even)
+      row2_shift = ((row2 << 1) & ROW_MASK) | 0x01;
+   else
+      row2_shift = (row2 >> 1) | 0x10;
+   block = ((row1 ^ row2) & row2) & ((row1 ^ row2_shift) & row2_shift);
+   /* Test for groups of 0's */
+   in_zeroes = FALSE;
+   group_okay = FALSE;
+   for(i = 0; i < 5; i++) {
+      if(row1 & (1 << i)) {
+         if(in_zeroes) {
+            if(!group_okay)
+               return TRUE;
+            in_zeroes = FALSE;
+            group_okay = FALSE;
+         }
+      } else {
+         if(!in_zeroes)
+            in_zeroes = TRUE;
+         if(!(block & (1 << i)))
+            group_okay = TRUE;
+      }
+   }
+   if(in_zeroes)
+      return !group_okay;
+   else
+      return FALSE;
+}
+
+/* Check for cases where three rows checked sequentially cause a false
+ * positive.  One scenario is when 5 cells may be surrounded where piece 5
+ * or 7 can fit.  The other scenario is when piece 2 creates a hook shape.
+ */
+int triple_is_okay(char row1, char row2, char row3, int even) {
+   if(even) {
+      /* There are four cases:
+       * row1: 00011  00001  11001  10101
+       * row2: 01011  00101  10001  10001
+       * row3: 011??  00110  ?????  ?????
+       */
+      return ((row1 == 0x03) && (row2 == 0x0B) && ((row3 & 0x1C) == 0x0C)) ||
+            ((row1 == 0x01) && (row2 == 0x05) && (row3 == 0x06)) ||
+            ((row1 == 0x19) && (row2 == 0x11)) ||
+            ((row1 == 0x15) && (row2 == 0x11));
+   } else {
+      /* There are two cases:
+       * row1: 10011  10101
+       * row2: 10001  10001
+       * row3: ?????  ?????
+       */
+      return ((row1 == 0x13) && (row2 == 0x11)) ||
+            ((row1 == 0x15) && (row2 == 0x11));
+   }
+}
+
+
+void calc_rows(void) {
+   int row1, row2, row3;
+   int result1, result2;
+   for(row1 = 0; row1 < 32; row1++) {
+      for(row2 = 0; row2 < 32; row2++) {
+         bad_even_rows[row1][row2] = rows_bad(row1, row2, TRUE);
+         bad_odd_rows[row1][row2] = rows_bad(row1, row2, FALSE);
+      }
+   }
+   for(row1 = 0; row1 < 32; row1++) {
+      for(row2 = 0; row2 < 32; row2++) {
+         for(row3 = 0; row3 < 32; row3++) {
+            result1 = bad_even_rows[row1][row2];
+            result2 = bad_odd_rows[row2][row3];
+            if(result1 == FALSE && result2 == TRUE
+                  && triple_is_okay(row1, row2, row3, TRUE))
+               bad_even_triple[row1+(row2*32)+(row3*1024)] = FALSE;
+            else
+               bad_even_triple[row1+(row2*32)+(row3*1024)] = result1 || result2;
+
+            result1 = bad_odd_rows[row1][row2];
+            result2 = bad_even_rows[row2][row3];
+            if(result1 == FALSE && result2 == TRUE
+                  && triple_is_okay(row1, row2, row3, FALSE))
+               bad_odd_triple[row1+(row2*32)+(row3*1024)] = FALSE;
+            else
+               bad_odd_triple[row1+(row2*32)+(row3*1024)] = result1 || result2;
+         }
+      }
+   }
+}
+
+
+
+/* Calculate islands while solving the board.
+ */
+int boardHasIslands(char cell) {
+   /* Too low on board, don't bother checking */
+   if(cell >= 40)
+      return FALSE;
+   int current_triple = (board >> ((cell / 5) * 5)) & TRIPLE_MASK;
+   if((cell / 5) % 2)
+      return bad_odd_triple[current_triple];
+   else
+      return bad_even_triple[current_triple];
+}
+
+
+/* The recursive solve algorithm.  Try to place each permutation in the upper-
+ * leftmost empty cell.  Mark off available pieces as it goes along.
+ * Because the board is a bit mask, the piece number and bit mask must be saved
+ * at each successful piece placement.  This data is used to create a 50 char
+ * array if a solution is found.
+ */
+short avail = 0x03FF;
+char sol_nums[10];
+unsigned long long sol_masks[10];
+signed char solutions[2100][50];
+int solution_count = 0;
+int max_solutions = 2100;
+
+void record_solution(void) {
+   int sol_no, index;
+   unsigned long long sol_mask;
+   for(sol_no = 0; sol_no < 10; sol_no++) {
+      sol_mask = sol_masks[sol_no];
+      for(index = 0; index < 50; index++) {
+         if(sol_mask & 1ULL) {
+            solutions[solution_count][index] = sol_nums[sol_no];
+            /* Board rotated 180 degrees is a solution too! */
+            solutions[solution_count+1][49-index] = sol_nums[sol_no];
+         }
+         sol_mask = sol_mask >> 1;
+      }
+   }
+   solution_count += 2;
+}
+
+void solve(int depth, int cell) {
+   int piece, rotation, max_rots;
+   unsigned long long *piece_mask;
+   short piece_no_mask;
+
+   if(solution_count >= max_solutions)
+      return;
+
+   while(board & (1ULL << cell))
+      cell++;
+
+   for(piece = 0; piece < 10; piece++) {
+      piece_no_mask = 1 << piece;
+      if(!(avail & piece_no_mask))
+         continue;
+      avail ^= piece_no_mask;
+      max_rots = piece_counts[piece][cell];
+      piece_mask = pieces[piece][cell];
+      for(rotation = 0; rotation < max_rots; rotation++) {
+         if(!(board & *(piece_mask + rotation))) {
+            sol_nums[depth] = piece;
+            sol_masks[depth] = *(piece_mask + rotation);
+            if(depth == 9) {
+               /* Solution found!!!!!11!!ONE! */
+               record_solution();
+               avail ^= piece_no_mask;
+               return;
+            }
+            board |= *(piece_mask + rotation);
+            if(!boardHasIslands(next_cell[piece][cell][rotation]))
+               solve(depth + 1, next_cell[piece][cell][rotation]);
+            board ^= *(piece_mask + rotation);
+         }
+      }
+      avail ^= piece_no_mask;
+   }
+}
+
+
+/* qsort comparator - used to find first and last solutions */
+int solution_sort(const void *elem1, const void *elem2) {
+   signed char *char1 = (signed char *) elem1;
+   signed char *char2 = (signed char *) elem2;
+   int i = 0;
+   while(i < 50 && char1[i] == char2[i])
+      i++;
+   return char1[i] - char2[i];
+}
+
+
+/* pretty print a board in the specified hexagonal format */
+void pretty(signed char *b) {
+   int i;
+   for(i = 0; i < 50; i += 10) {
+      printf("%c %c %c %c %c \n %c %c %c %c %c \n", b[i]+'0', b[i+1]+'0',
+            b[i+2]+'0', b[i+3]+'0', b[i+4]+'0', b[i+5]+'0', b[i+6]+'0',
+            b[i+7]+'0', b[i+8]+'0', b[i+9]+'0');
+   }
+   printf("\n");
+}
+
+int main(int argc, char **argv) {
+   if(argc > 1)
+      max_solutions = atoi(argv[1]);
+   calc_pieces();
+   calc_rows();
+   solve(0, 0);
+   printf("%d solutions found\n\n", solution_count);
+   qsort(solutions, solution_count, 50 * sizeof(signed char), solution_sort);
+   pretty(solutions[0]);
+   pretty(solutions[solution_count-1]);
+   return 0;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/pph/c1pr36533.cc b/gcc/testsuite/g++.dg/pph/c1pr36533.cc
new file mode 100644
index 0000000..b44e8c9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pph/c1pr36533.cc
@@ -0,0 +1,2 @@
+/* { dg-options "-w -fpermissive" } */
+#include "c1pr36533.h"
diff --git a/gcc/testsuite/g++.dg/pph/c1pr36533.h b/gcc/testsuite/g++.dg/pph/c1pr36533.h
new file mode 100644
index 0000000..6c6a6ae
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pph/c1pr36533.h
@@ -0,0 +1,176 @@
+#ifndef __PPH_GUARD_H
+#define __PPH_GUARD_H
+/* PR target/36533 */
+/* { dg-options "-w -fpermissive" } */
+#include <string.h>
+#include <sys/mman.h>
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+typedef struct S1
+{
+  unsigned long s1;
+  struct S1 *s2;
+  char *s3;
+} S1;
+
+typedef struct
+{
+  unsigned int s4;
+  unsigned int s5;
+  int s6;
+  unsigned int *s7;
+} S2;
+
+typedef struct
+{
+  unsigned int s8;
+  unsigned short s9;
+  unsigned char s10;
+  unsigned char s11;
+  char s12[255];
+} S3;
+
+typedef struct
+{
+  unsigned int s4;
+  unsigned short s13;
+  unsigned short s14;
+} S4;
+
+typedef struct
+{
+  char s15[16];
+  unsigned long s16;
+} S5;
+
+typedef struct
+{
+  char s15[48];
+  S5 *s17;
+} S6;
+
+typedef struct
+{
+  S1 *s18;
+} S7;
+
+__attribute__((regparm (3), noinline)) int
+fn1 (const char *x, void *y, S1 *z)
+{
+  asm volatile ("" : : : "memory");
+  return *x + (y != 0);
+}
+
+__attribute__((regparm (3), noinline)) int
+fn2 (const char *x, int y, S2 *z)
+{
+  asm volatile ("" : : : "memory");
+  return 0;
+}
+
+static inline __attribute__ ((always_inline)) unsigned int
+fn4 (unsigned short x)
+{
+  unsigned len = x;
+  if (len == ((1 << 16) - 1))
+    return 1 << 16;
+  return len;
+}
+
+static inline __attribute__ ((always_inline)) S3 *
+fn3 (S3 *p)
+{
+  return (S3 *) ((char *) p + fn4 (p->s9));
+}
+
+__attribute__((regparm (3), noinline)) int
+fn5 (void)
+{
+  asm volatile ("" : : : "memory");
+  return 0;
+}
+
+static inline __attribute__ ((always_inline)) int
+fn6 (S3 *w, int x, S2 *y, S4 *z)
+{
+  int a = 2;
+  char *b = (char *) w;
+  S2 c = *y;
+
+  while ((char *) w < b + x - 2 * sizeof (S4))
+    {
+      if (w->s10 && w->s8)
+	{
+	  fn2 (w->s12, w->s10, &c);
+	  z--;
+	  z->s4 = c.s4;
+	  z->s13 = (unsigned short) ((char *) w - b);
+	  z->s14 = w->s9;
+	  a++;
+	  fn5 ();
+	}
+
+      w = fn3 (w);
+    }
+  return a;
+}
+
+__attribute__((regparm (3), noinline)) unsigned int
+test (void *u, S6 *v, S1 **w, S7 *x, S2 *y, S1 *z)
+{
+  unsigned b = v->s17->s16;
+  unsigned a;
+  S4 *c;
+  unsigned d, e, f, i;
+
+  fn1 (__func__, u, x->s18);
+  c = (S4 *) (z->s3 + b);
+  a = fn6 ((S3 *) (*w)->s3, b, y, c);
+  c -= a;
+  f = 0;
+  e = 2;
+  for (i = a - 1; ; i--)
+    {
+      if (f + (unsigned short) (c[i].s14 / 2) > b / 2)
+	break;
+      f += c[i].s14;
+      e++;
+    }
+  d = a - e;
+  return c[d].s4;
+}
+
+int main (void)
+{
+  char *p = mmap (NULL, 131072, PROT_READ | PROT_WRITE,
+		  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  S1 wb, z, *w;
+  S6 v;
+  S7 x;
+  S2 y;
+  S5 vb;
+  S4 s4;
+  if (p == MAP_FAILED)
+    return 0;
+  if (munmap (p + 65536, 65536) < 0)
+    return 0;
+  memset (&wb, 0, sizeof (wb));
+  memset (&z, 0, sizeof (z));
+  memset (&v, 0, sizeof (v));
+  memset (&x, 0, sizeof (x));
+  memset (&y, 0, sizeof (y));
+  memset (&vb, 0, sizeof (vb));
+  memset (&s4, 0, sizeof (s4));
+  s4.s14 = 254;
+  z.s3 = p + 65536 - 2 * sizeof (S4);
+  w = &wb;
+  v.s17 = &vb;
+  vb.s16 = 2 * sizeof (S4);
+  memcpy (z.s3, &s4, sizeof (s4));
+  memcpy (z.s3 + sizeof (s4), &s4, sizeof (s4));
+  test ((void *) 0, &v, &w, &x, &y, &z);
+  return 0;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/pph/c1pr44948-1a.cc b/gcc/testsuite/g++.dg/pph/c1pr44948-1a.cc
new file mode 100644
index 0000000..f3f0427
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pph/c1pr44948-1a.cc
@@ -0,0 +1 @@
+#include "c1pr44948-1a.h"
diff --git a/gcc/testsuite/g++.dg/pph/c1pr44948-1a.h b/gcc/testsuite/g++.dg/pph/c1pr44948-1a.h
new file mode 100644
index 0000000..0f69443
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pph/c1pr44948-1a.h
@@ -0,0 +1,18 @@
+#ifndef __PPH_GUARD_H
+#define __PPH_GUARD_H
+/* PR target/44948 */
+/* { dg-options "-O -Wno-psabi -mtune=generic" } */
+
+#pragma GCC target ("avx")
+
+struct A { long b[8] __attribute__((aligned (32))); };
+void foo (long double, struct A);
+
+int
+main (void)
+{
+  struct A a = { { 0, 1, 2, 3, 4, 5, 6, 7 } };
+  foo (8.0L, a);
+  return 0;
+}
+#endif
