summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg
diff options
context:
space:
mode:
authoraldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4>2011-11-08 11:13:41 +0000
committeraldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4>2011-11-08 11:13:41 +0000
commit4c0315d05fa0f707875686abc4f91f7a979a7c7b (patch)
treee07de8d0b6265f8d72388d335bd471022e753d57 /gcc/testsuite/gcc.dg
parentbf09288ee7b5f264f28081a84fde4c6aa1ac5c82 (diff)
downloadgcc-4c0315d05fa0f707875686abc4f91f7a979a7c7b.tar.gz
Merge from transactional-memory branch.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181154 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/testsuite/gcc.dg')
-rw-r--r--gcc/testsuite/gcc.dg/tm/20091013.c13
-rw-r--r--gcc/testsuite/gcc.dg/tm/20091221.c15
-rw-r--r--gcc/testsuite/gcc.dg/tm/20100125.c17
-rw-r--r--gcc/testsuite/gcc.dg/tm/20100519.c17
-rw-r--r--gcc/testsuite/gcc.dg/tm/20100524-2.c20
-rw-r--r--gcc/testsuite/gcc.dg/tm/20100603.c21
-rw-r--r--gcc/testsuite/gcc.dg/tm/20100609.c14
-rw-r--r--gcc/testsuite/gcc.dg/tm/20100610.c90
-rw-r--r--gcc/testsuite/gcc.dg/tm/20100615-2.c19
-rw-r--r--gcc/testsuite/gcc.dg/tm/20100615.c42
-rw-r--r--gcc/testsuite/gcc.dg/tm/20110216.c15
-rw-r--r--gcc/testsuite/gcc.dg/tm/alias-1.c40
-rw-r--r--gcc/testsuite/gcc.dg/tm/alias-2.c42
-rw-r--r--gcc/testsuite/gcc.dg/tm/data-1.c48
-rw-r--r--gcc/testsuite/gcc.dg/tm/data-2.c22
-rw-r--r--gcc/testsuite/gcc.dg/tm/debug-1.c26
-rw-r--r--gcc/testsuite/gcc.dg/tm/indirect-1.c9
-rw-r--r--gcc/testsuite/gcc.dg/tm/ipa-1.c14
-rw-r--r--gcc/testsuite/gcc.dg/tm/ipa-2.c14
-rw-r--r--gcc/testsuite/gcc.dg/tm/ipa-3.c12
-rw-r--r--gcc/testsuite/gcc.dg/tm/irrevocable-1.c16
-rw-r--r--gcc/testsuite/gcc.dg/tm/irrevocable-2.c21
-rw-r--r--gcc/testsuite/gcc.dg/tm/irrevocable-3.c14
-rw-r--r--gcc/testsuite/gcc.dg/tm/irrevocable-4.c16
-rw-r--r--gcc/testsuite/gcc.dg/tm/irrevocable-5.c27
-rw-r--r--gcc/testsuite/gcc.dg/tm/irrevocable-6.c34
-rw-r--r--gcc/testsuite/gcc.dg/tm/irrevocable-7.c13
-rw-r--r--gcc/testsuite/gcc.dg/tm/memopt-1.c29
-rw-r--r--gcc/testsuite/gcc.dg/tm/memopt-10.c28
-rw-r--r--gcc/testsuite/gcc.dg/tm/memopt-11.c29
-rw-r--r--gcc/testsuite/gcc.dg/tm/memopt-12.c34
-rw-r--r--gcc/testsuite/gcc.dg/tm/memopt-13.c15
-rw-r--r--gcc/testsuite/gcc.dg/tm/memopt-15.c30
-rw-r--r--gcc/testsuite/gcc.dg/tm/memopt-2.c15
-rw-r--r--gcc/testsuite/gcc.dg/tm/memopt-3.c20
-rw-r--r--gcc/testsuite/gcc.dg/tm/memopt-4.c24
-rw-r--r--gcc/testsuite/gcc.dg/tm/memopt-5.c23
-rw-r--r--gcc/testsuite/gcc.dg/tm/memopt-6.c20
-rw-r--r--gcc/testsuite/gcc.dg/tm/memopt-7.c22
-rw-r--r--gcc/testsuite/gcc.dg/tm/memopt-8.c26
-rw-r--r--gcc/testsuite/gcc.dg/tm/memopt-9.c29
-rw-r--r--gcc/testsuite/gcc.dg/tm/memset-2.c17
-rw-r--r--gcc/testsuite/gcc.dg/tm/memset.c24
-rw-r--r--gcc/testsuite/gcc.dg/tm/nested-1.c28
-rw-r--r--gcc/testsuite/gcc.dg/tm/nested-2.c19
-rw-r--r--gcc/testsuite/gcc.dg/tm/opt-1.c43
-rw-r--r--gcc/testsuite/gcc.dg/tm/opt-2.c14
-rw-r--r--gcc/testsuite/gcc.dg/tm/pr45985.c14
-rw-r--r--gcc/testsuite/gcc.dg/tm/pr46567-2.c18
-rw-r--r--gcc/testsuite/gcc.dg/tm/pr46567.c18
-rw-r--r--gcc/testsuite/gcc.dg/tm/pr46654.c26
-rw-r--r--gcc/testsuite/gcc.dg/tm/pr47520.c29
-rw-r--r--gcc/testsuite/gcc.dg/tm/pr47690.c14
-rw-r--r--gcc/testsuite/gcc.dg/tm/pr47905.c14
-rw-r--r--gcc/testsuite/gcc.dg/tm/props-1.c19
-rw-r--r--gcc/testsuite/gcc.dg/tm/props-2.c20
-rw-r--r--gcc/testsuite/gcc.dg/tm/props-3.c15
-rw-r--r--gcc/testsuite/gcc.dg/tm/props-4.c27
-rw-r--r--gcc/testsuite/gcc.dg/tm/tm.exp39
-rw-r--r--gcc/testsuite/gcc.dg/tm/unsafe.c13
-rw-r--r--gcc/testsuite/gcc.dg/tm/unused.c15
-rw-r--r--gcc/testsuite/gcc.dg/tm/vector-1.c18
-rw-r--r--gcc/testsuite/gcc.dg/tm/wrap-2.c16
-rw-r--r--gcc/testsuite/gcc.dg/tm/wrap-3.c14
-rw-r--r--gcc/testsuite/gcc.dg/tm/wrap-4.c15
65 files changed, 1484 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/tm/20091013.c b/gcc/testsuite/gcc.dg/tm/20091013.c
new file mode 100644
index 00000000000..d9b3b0ed3bc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/20091013.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O2" } */
+
+extern long ringo(long int);
+int g,i;
+
+f()
+{
+ __transaction_relaxed {
+ for (i=0; i < 10; ++i)
+ ringo(g);
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tm/20091221.c b/gcc/testsuite/gcc.dg/tm/20091221.c
new file mode 100644
index 00000000000..1d75d153a2c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/20091221.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-tree-tmedge" } */
+
+int i;
+extern void virgin () __attribute__((transaction_pure));
+
+foo()
+{
+ __transaction_atomic {
+ virgin(i);
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "readOnly" 1 "tmedge" } } */
+/* { dg-final { cleanup-tree-dump "tmedge" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/20100125.c b/gcc/testsuite/gcc.dg/tm/20100125.c
new file mode 100644
index 00000000000..3f1dd10fea2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/20100125.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O -fdump-tree-tmmark" } */
+
+/* Test that the call to george() doesn't end up inside the transaction. */
+
+int trxn;
+
+void set_remove(int * val)
+{
+ __transaction_atomic {
+ trxn = 5;
+ }
+ george();
+}
+
+/* { dg-final { scan-tree-dump-times "getTMCloneOrIrrevocable" 0 "tmmark" } } */
+/* { dg-final { cleanup-tree-dump "tmmark" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/20100519.c b/gcc/testsuite/gcc.dg/tm/20100519.c
new file mode 100644
index 00000000000..009b7901a39
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/20100519.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O" } */
+
+typedef struct coordinate {
+ double x;
+} coordinate_t;
+
+coordinate_t elementPtrC[3];
+
+__attribute__((transaction_safe))
+void TMelement_alloc (coordinate_t* coordinates, int numCoordinate)
+{
+ int i;
+ for (i = 0; i < numCoordinate; i++) {
+ elementPtrC[i] = coordinates[i];
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tm/20100524-2.c b/gcc/testsuite/gcc.dg/tm/20100524-2.c
new file mode 100644
index 00000000000..a3578cb2797
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/20100524-2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O0" } */
+
+typedef struct {
+ int value[5];
+} type_t;
+
+__attribute__((transaction_safe))
+type_t func_move ();
+
+__attribute__((transaction_safe))
+type_t func_push (int type)
+{
+ type_t trace;
+
+ if (type == 9)
+ trace = func_move();
+
+ return trace;
+}
diff --git a/gcc/testsuite/gcc.dg/tm/20100603.c b/gcc/testsuite/gcc.dg/tm/20100603.c
new file mode 100644
index 00000000000..3061063394d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/20100603.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O -fdump-tree-optimized" } */
+
+int jj;
+
+__attribute__((transaction_safe))
+static void poof ()
+{
+ if (jj)
+ return;
+ poof();
+}
+
+__attribute__((transaction_safe))
+void TMlist_free ()
+{
+ poof();
+}
+
+/* { dg-final { scan-tree-dump-times "Function poof ._ZGTt4poof" 1 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/20100609.c b/gcc/testsuite/gcc.dg/tm/20100609.c
new file mode 100644
index 00000000000..760f81ec6dd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/20100609.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O" } */
+
+extern void funcNoReturn() __attribute__ ((__noreturn__));
+
+int later;
+
+void MyFunc()
+{
+ __transaction_relaxed {
+ funcNoReturn();
+ later=8;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tm/20100610.c b/gcc/testsuite/gcc.dg/tm/20100610.c
new file mode 100644
index 00000000000..0985b9ebc23
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/20100610.c
@@ -0,0 +1,90 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O3" } */
+
+/* The function calculateCircumCircle() should get inlined into the TM
+ clone for TMelement_alloc(), so we don't need to generate a TM
+ clone for calculateCircumCircle(). We also don't need to put its
+ entry into the clone table since it's static. */
+
+/* { dg-final { scan-assembler-not "ZGTt21calculateCircumCircle" } } */
+
+extern double sqrt(double) __attribute__((transaction_pure));
+extern void *xmalloc(int) __attribute__((transaction_safe));
+
+typedef struct coordinate {
+ double x;
+ double y;
+} coordinate_t;
+typedef struct element {
+ coordinate_t coordinates[3];
+ long numCoordinate;
+ coordinate_t circumCenter;
+ double circumRadius;
+} element_t;
+
+__attribute__((transaction_safe))
+double
+coordinate_distance (coordinate_t* coordinatePtr, coordinate_t* aPtr)
+{
+ return sqrt( coordinatePtr->x );
+}
+
+__attribute__((transaction_safe))
+static void
+calculateCircumCircle (element_t* elementPtr)
+{
+ long numCoordinate = elementPtr->numCoordinate;
+ coordinate_t* coordinates = elementPtr->coordinates;
+ coordinate_t* circumCenterPtr = &elementPtr->circumCenter;
+ ((void) (0));
+ if (numCoordinate == 2) {
+ circumCenterPtr->x = (coordinates[0].x + coordinates[1].x) / 2.0;
+ circumCenterPtr->y = (coordinates[0].y + coordinates[1].y) / 2.0;
+ }
+ else {
+ double ax = coordinates[0].x;
+ double ay = coordinates[0].y;
+ double bx = coordinates[1].x;
+ double by = coordinates[1].y;
+ double cx = coordinates[2].x;
+ double cy = coordinates[2].y;
+ double bxDelta = bx - ax;
+ double byDelta = by - ay;
+ double cxDelta = cx - ax;
+ double cyDelta = cy - ay;
+ double bDistance2 = (bxDelta * bxDelta) + (byDelta * byDelta);
+ double cDistance2 = (cxDelta * cxDelta) + (cyDelta * cyDelta);
+ double xNumerator = (byDelta * cDistance2) - (cyDelta * bDistance2);
+ double yNumerator = (bxDelta * cDistance2) - (cxDelta * bDistance2);
+ double denominator = 2 * ((bxDelta * cyDelta) - (cxDelta * byDelta));
+ double rx = ax - (xNumerator / denominator);
+ double ry = ay + (yNumerator / denominator);
+ circumCenterPtr->x = rx;
+ circumCenterPtr->y = ry;
+ }
+ elementPtr->circumRadius = coordinate_distance(circumCenterPtr,
+ &coordinates[0]);
+}
+
+element_t*
+element_alloc (coordinate_t* coordinates, long numCoordinate)
+{
+ element_t* elementPtr;
+ elementPtr = (element_t*)xmalloc(sizeof(element_t));
+ if (elementPtr) {
+ calculateCircumCircle(elementPtr);
+ }
+ return elementPtr;
+}
+
+__attribute__((transaction_safe))
+element_t*
+TMelement_alloc (coordinate_t* coordinates, long numCoordinate)
+{
+ element_t* elementPtr;
+ elementPtr = (element_t*)xmalloc(sizeof(element_t));
+ if (elementPtr) {
+ calculateCircumCircle(elementPtr);
+ }
+ return elementPtr;
+}
diff --git a/gcc/testsuite/gcc.dg/tm/20100615-2.c b/gcc/testsuite/gcc.dg/tm/20100615-2.c
new file mode 100644
index 00000000000..4341e7d35ea
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/20100615-2.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O" } */
+
+__attribute__((transaction_safe))
+void Info_RemoveKey (char *s)
+{
+ char *o = 0;
+ while (1)
+ {
+ s++;
+ while (*s)
+ {
+ if (!*s)
+ return;
+ *o++ = *s++;
+ }
+ *o = 0;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tm/20100615.c b/gcc/testsuite/gcc.dg/tm/20100615.c
new file mode 100644
index 00000000000..3d9e4684e5d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/20100615.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O" } */
+
+/* Since the non TM version of new_node() gets optimized away, it
+ shouldn't appear in the clone table either. */
+/* { dg-final { scan-assembler-not "tm_clone_table" } } */
+
+#define NULL 0
+extern void *malloc (__SIZE_TYPE__);
+
+__attribute__((transaction_pure))
+void exit(int status);
+
+typedef struct node {
+} node_t;
+
+__attribute__((transaction_safe))
+static node_t *new_node(node_t *next)
+{
+ node_t *node;
+ node = (node_t *)malloc(sizeof(node_t));
+ if (node == NULL) {
+ exit(1);
+ }
+ return NULL;
+}
+
+static node_t *set_new()
+{
+ node_t *min, *max;
+ __transaction_atomic {
+ max = new_node(NULL);
+ min = new_node(max);
+ }
+ return min;
+}
+
+int main(int argc, char **argv)
+{
+ set_new();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tm/20110216.c b/gcc/testsuite/gcc.dg/tm/20110216.c
new file mode 100644
index 00000000000..22edae0fb4c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/20110216.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+
+int george;
+
+__attribute__((transaction_callable))
+void q1()
+{
+ __transaction_atomic {
+ george=999;
+ }
+ q1();
+}
+
+/* { dg-final { scan-assembler-not "_ITM_getTMCloneOrIrrevocable" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/alias-1.c b/gcc/testsuite/gcc.dg/tm/alias-1.c
new file mode 100644
index 00000000000..364aa714086
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/alias-1.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-tree-ealias -O" } */
+
+typedef __UINTPTR_TYPE__ ptrcast;
+
+#if (__SIZEOF_POINTER__ == 4)
+#define TM_LOAD __builtin__ITM_RU4
+#define TM_STORE __builtin__ITM_WU4
+#elif (__SIZEOF_POINTER__ == 8)
+#define TM_LOAD __builtin__ITM_RU8
+#define TM_STORE __builtin__ITM_WU8
+#else
+#error Add target support here
+#endif
+
+struct mystruct_type {
+ ptrcast *ptr;
+} *mystruct;
+
+ptrcast *someptr, **pp;
+ptrcast ui;
+
+void f(void)
+{
+ __transaction_atomic {
+ ui = TM_LOAD (&mystruct);
+ mystruct = (struct mystruct_type *) ui;
+ ui = TM_LOAD (&someptr);
+ someptr = (ptrcast *) ui;
+ ui = (ptrcast) someptr;
+ pp = &mystruct->ptr;
+ TM_STORE (pp, ui);
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "mystruct = \{ .*ESCAPED" 1 "ealias" } } */
+/* { dg-final { scan-tree-dump-times "someptr = same as mystruct" 1 "ealias" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "ui\..* = same as mystruct" 1 "ealias" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "pp\..* = same as mystruct" 1 "ealias" { xfail *-*-* } } } */
+/* { dg-final { cleanup-tree-dump "ealias" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/alias-2.c b/gcc/testsuite/gcc.dg/tm/alias-2.c
new file mode 100644
index 00000000000..761a99c2ab0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/alias-2.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-tree-ealias -O" } */
+
+typedef __UINTPTR_TYPE__ ptrcast;
+
+#if (__SIZEOF_POINTER__ == 4)
+#define TM_LOAD __builtin__ITM_RU4
+#define TM_STORE __builtin__ITM_WU4
+#elif (__SIZEOF_POINTER__ == 8)
+#define TM_LOAD __builtin__ITM_RU8
+#define TM_STORE __builtin__ITM_WU8
+#else
+#error Add target support here
+#endif
+
+void candy ();
+
+struct mystruct_type {
+ ptrcast *ptr;
+} *mystruct, *mystruct2;
+
+ptrcast *someptr, **pp;
+ptrcast ui;
+
+void tootsie_roll () __attribute__((transaction_wrap (candy)));
+void tootsie_roll ()
+{
+ ui = TM_LOAD (&mystruct);
+ mystruct2 = (struct mystruct_type *) ui;
+
+ pp = &mystruct2->ptr;
+}
+
+void foo()
+{
+ candy();
+}
+
+/* { dg-final { scan-tree-dump-times "ui\..* = same as mystruct" 1 "ealias" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "mystruct.*ESCAPED" 1 "ealias" } } */
+/* { dg-final { scan-tree-dump-times "pp = same as mystruct" 1 "ealias" { xfail *-*-* } } } */
+/* { dg-final { cleanup-tree-dump "ealias" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/data-1.c b/gcc/testsuite/gcc.dg/tm/data-1.c
new file mode 100644
index 00000000000..16061476e08
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/data-1.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+/* Test read and write on all basic types. */
+
+static char gc;
+static signed char gsc;
+static unsigned char guc;
+
+static short gs;
+static unsigned short gus;
+
+static int gi;
+static unsigned int gui;
+
+static long gl;
+static unsigned long gul;
+
+static long long gll;
+static unsigned long long gull;
+
+static float gf;
+static double gd;
+static long double gld;
+
+void f(void)
+{
+ __transaction_atomic {
+ gc++;
+ gsc++;
+ guc++;
+
+ gs++;
+ gus++;
+
+ gi++;
+ gui++;
+
+ gl++;
+ gul++;
+
+ gll++;
+ gull++;
+
+ gf++;
+ gd++;
+ gld++;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tm/data-2.c b/gcc/testsuite/gcc.dg/tm/data-2.c
new file mode 100644
index 00000000000..3e2a604bfb3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/data-2.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+/* Test read and write on all basic types. */
+
+struct S
+{
+ int x[10];
+};
+
+static struct S g;
+
+extern void fill (struct S *);
+
+void f(void)
+{
+ struct S l;
+ fill(&l);
+
+ __transaction_atomic {
+ g = l;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tm/debug-1.c b/gcc/testsuite/gcc.dg/tm/debug-1.c
new file mode 100644
index 00000000000..fae5d6bed42
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/debug-1.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O0 -fdump-tree-tmmark-lineno" } */
+
+/* Test that instrumented statements have correct location info. */
+
+int a,b, c, z;
+
+testing(){
+ c=9;
+}
+
+main() {
+ b = 9898;
+ __transaction_relaxed {
+ z = c;
+ a = 888;
+ testing();
+ }
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times ": 13:.*b = 9898" 1 "tmmark" } } */
+/* { dg-final { scan-tree-dump-times ": 14:.*__transaction" 1 "tmmark" } } */
+/* { dg-final { scan-tree-dump-times ": 15:.*ITM_WU. \\(&z" 1 "tmmark" } } */
+/* { dg-final { scan-tree-dump-times ": 16:.*ITM_WU. \\(&a" 1 "tmmark" } } */
+/* { dg-final { cleanup-tree-dump "tmmark" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/indirect-1.c b/gcc/testsuite/gcc.dg/tm/indirect-1.c
new file mode 100644
index 00000000000..eade848bd8b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/indirect-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+
+void foo(void (*fn)(void))
+{
+ __transaction_relaxed {
+ fn();
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tm/ipa-1.c b/gcc/testsuite/gcc.dg/tm/ipa-1.c
new file mode 100644
index 00000000000..ec1cdca7032
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/ipa-1.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-tree-tmmark-asmname" } */
+
+void foo(void) __attribute__((transaction_safe));
+
+void bar(void)
+{
+ __transaction_atomic {
+ foo();
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "_ZGTt3foo" 1 "tmmark" } } */
+/* { dg-final { cleanup-tree-dump "tmmark" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/ipa-2.c b/gcc/testsuite/gcc.dg/tm/ipa-2.c
new file mode 100644
index 00000000000..e7a02cb1926
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/ipa-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-tree-tmmark-asmname" } */
+
+void foo(void);
+
+void bar(void)
+{
+ __transaction_relaxed {
+ foo();
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "_ZGTt3foo" 0 "tmmark" } } */
+/* { dg-final { cleanup-tree-dump "tmmark" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/ipa-3.c b/gcc/testsuite/gcc.dg/tm/ipa-3.c
new file mode 100644
index 00000000000..cb1b433bcbd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/ipa-3.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+
+static int x;
+
+void __attribute__((transaction_callable))
+foo(void)
+{
+ x++;
+}
+
+/* { dg-final { scan-assembler "_ZGTt3foo" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/irrevocable-1.c b/gcc/testsuite/gcc.dg/tm/irrevocable-1.c
new file mode 100644
index 00000000000..60f629133ee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/irrevocable-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O" } */
+
+int global;
+int george;
+
+extern crap() __attribute__((transaction_unsafe));
+
+foo()
+{
+ __transaction_relaxed {
+ global++;
+ crap();
+ george++;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tm/irrevocable-2.c b/gcc/testsuite/gcc.dg/tm/irrevocable-2.c
new file mode 100644
index 00000000000..17ac8a5f0c0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/irrevocable-2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-tree-tmedge" } */
+
+/* Test that a direct call to __builtin__ITM_changeTransactionMode()
+ sets the irrevocable bit. */
+
+int global;
+int george;
+
+foo()
+{
+ __transaction_relaxed {
+ global++;
+ __builtin__ITM_changeTransactionMode (0);
+ george++;
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "doesGoIrrevocable" 1 "tmedge" } } */
+/* { dg-final { scan-tree-dump-times "hasNoIrrevocable" 0 "tmedge" } } */
+/* { dg-final { cleanup-tree-dump "tmedge" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/irrevocable-3.c b/gcc/testsuite/gcc.dg/tm/irrevocable-3.c
new file mode 100644
index 00000000000..c0854794803
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/irrevocable-3.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-tree-tmmark" } */
+
+extern void bar(void) __attribute__((transaction_callable));
+
+foo()
+{
+ __transaction_relaxed {
+ bar();
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "GTMA_MAY_ENTER_IRREVOCABLE" 1 "tmmark" } } */
+/* { dg-final { cleanup-tree-dump "tmmark" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/irrevocable-4.c b/gcc/testsuite/gcc.dg/tm/irrevocable-4.c
new file mode 100644
index 00000000000..ee759b84ef0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/irrevocable-4.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-tree-tmmark" } */
+
+void orig(void);
+void xyz(void) __attribute__((transaction_wrap (orig)));
+
+
+foo()
+{
+ __transaction_relaxed {
+ orig();
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "GTMA_MAY_ENTER_IRREVOCABLE" 1 "tmmark" } } */
+/* { dg-final { cleanup-tree-dump "tmmark" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/irrevocable-5.c b/gcc/testsuite/gcc.dg/tm/irrevocable-5.c
new file mode 100644
index 00000000000..155879f1a21
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/irrevocable-5.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-ipa-tmipa -O" } */
+
+int a;
+
+void foo(void) __attribute__((transaction_safe));
+void bar(void) __attribute__((transaction_safe));
+void danger(void) __attribute__((transaction_unsafe));
+
+void wildthing()
+{
+ /* All blocks should be propagated as irrevocable. */
+ __transaction_relaxed {
+ if (a)
+ foo();
+ else
+ bar();
+ danger();
+ }
+}
+
+/* { dg-final { scan-ipa-dump-times "GTMA_DOES_GO_IRREVOCABLE" 1 "tmipa" } } */
+/* { dg-final { scan-ipa-dump-times "bb 3 goes irr" 1 "tmipa" } } */
+/* { dg-final { scan-ipa-dump-times "bb 4 goes irr" 1 "tmipa" } } */
+/* { dg-final { scan-ipa-dump-times "bb 5 goes irr" 1 "tmipa" } } */
+/* { dg-final { scan-ipa-dump-times "bb 6 goes irr" 1 "tmipa" } } */
+/* { dg-final { cleanup-ipa-dump "tmipa" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/irrevocable-6.c b/gcc/testsuite/gcc.dg/tm/irrevocable-6.c
new file mode 100644
index 00000000000..2399131210b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/irrevocable-6.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-ipa-tmipa -O" } */
+
+int a, trxn, eee;
+
+void foo(void) __attribute__((transaction_safe));
+void bar(void) __attribute__((transaction_safe));
+void danger(void) __attribute__((transaction_unsafe));
+
+void wildthing()
+{
+ /* All blocks should be propagated as irrevocable. */
+ __transaction_relaxed {
+ if (eee) {
+ if (a)
+ foo();
+ else
+ bar();
+ danger();
+ } else {
+ danger();
+ }
+ }
+}
+
+/* { dg-final { scan-ipa-dump-times "GTMA_DOES_GO_IRREVOCABLE" 1 "tmipa" } } */
+/* { dg-final { scan-ipa-dump-times "bb 3 goes irr" 1 "tmipa" } } */
+/* { dg-final { scan-ipa-dump-times "bb 4 goes irr" 1 "tmipa" } } */
+/* { dg-final { scan-ipa-dump-times "bb 5 goes irr" 1 "tmipa" } } */
+/* { dg-final { scan-ipa-dump-times "bb 6 goes irr" 1 "tmipa" } } */
+/* { dg-final { scan-ipa-dump-times "bb 7 goes irr" 1 "tmipa" } } */
+/* { dg-final { scan-ipa-dump-times "bb 8 goes irr" 1 "tmipa" } } */
+/* { dg-final { scan-ipa-dump-times "bb 9 goes irr" 1 "tmipa" } } */
+/* { dg-final { cleanup-ipa-dump "tmipa" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/irrevocable-7.c b/gcc/testsuite/gcc.dg/tm/irrevocable-7.c
new file mode 100644
index 00000000000..ea8a00f0c55
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/irrevocable-7.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-ipa-tmipa" } */
+
+extern void bark(void);
+
+__attribute__((transaction_callable))
+int foo()
+{
+ bark();
+}
+
+/* { dg-final { scan-ipa-dump-times "changeTransactionMode \\(0\\)" 1 "tmipa" } } */
+/* { dg-final { cleanup-ipa-dump "tmipa" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/memopt-1.c b/gcc/testsuite/gcc.dg/tm/memopt-1.c
new file mode 100644
index 00000000000..5388a81e282
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/memopt-1.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O -fdump-tree-tmmemopt" } */
+
+long g, xxx, yyy;
+extern george() __attribute__((transaction_callable));
+extern ringo(long int);
+int i;
+
+f()
+{
+ __transaction_relaxed {
+ g = 666;
+ george();
+ if (i == 9)
+ goto bye;
+ xxx=8;
+ yyy=9;
+ for (i=0; i < 10; ++i)
+ ringo(g);
+ bye:
+ ringo(g);
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "transforming: .*_ITM_RaWU8 \\(&g\\);" 1 "tmmemopt" } } */
+/* { dg-final { scan-tree-dump-times "transforming: .*_ITM_WaRU4 \\(&i," 1 "tmmemopt" } } */
+/* { dg-final { scan-tree-dump-times "transforming: .*_ITM_RaWU4 \\(&i\\);" 1 "tmmemopt" } } */
+/* { dg-final { scan-tree-dump-times "transforming: .*_ITM_WaWU4 \\(&i," 1 "tmmemopt" } } */
+/* { dg-final { cleanup-tree-dump "tmmemopt" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/memopt-10.c b/gcc/testsuite/gcc.dg/tm/memopt-10.c
new file mode 100644
index 00000000000..5caa6b53d6b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/memopt-10.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O -fdump-tree-tmmark" } */
+
+extern int something(void) __attribute__((transaction_safe));
+extern void *malloc (__SIZE_TYPE__) __attribute__((malloc,transaction_safe));
+
+int f()
+{
+ int *p;
+
+ p = malloc (sizeof (*p) * 100);
+
+ __transaction_atomic {
+ /* p[5] is thread private, but not transaction local since the
+ malloc is outside of the transaction. We can use the logging
+ functions for this. */
+ p[5] = 123;
+
+ if (something())
+ __transaction_cancel;
+ }
+ return p[5];
+}
+
+/* { dg-final { scan-tree-dump-times "ITM_LU" 0 "tmmark" } } */
+/* { dg-final { scan-tree-dump-times "ITM_WU" 0 "tmmark" } } */
+/* { dg-final { scan-tree-dump-times "tm_save" 1 "tmmark" } } */
+/* { dg-final { cleanup-tree-dump "tmmark" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/memopt-11.c b/gcc/testsuite/gcc.dg/tm/memopt-11.c
new file mode 100644
index 00000000000..07972a4fd4e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/memopt-11.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O -fdump-tree-tmmark" } */
+
+extern int something(void) __attribute__((transaction_safe));
+extern void *malloc (__SIZE_TYPE__) __attribute__((malloc,transaction_safe));
+
+int f()
+{
+ int *p;
+
+ p = malloc (sizeof (*p) * 100);
+ foo(p[5]);
+
+ __transaction_atomic {
+ /* p[5] is thread private, however the SSA_NAME that holds the
+ address dominates the entire transaction (transaction
+ invariant) so we can use a save/restore pair. */
+ p[5] = 123;
+
+ if (something())
+ __transaction_cancel;
+ }
+ return p[5];
+}
+
+/* { dg-final { scan-tree-dump-times "ITM_LU" 0 "tmmark" } } */
+/* { dg-final { scan-tree-dump-times "ITM_WU" 0 "tmmark" } } */
+/* { dg-final { scan-tree-dump-times "tm_save" 1 "tmmark" } } */
+/* { dg-final { cleanup-tree-dump "tmmark" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/memopt-12.c b/gcc/testsuite/gcc.dg/tm/memopt-12.c
new file mode 100644
index 00000000000..5520ecef27a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/memopt-12.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O -fdump-tree-tmmark" } */
+
+extern int test(void) __attribute__((transaction_safe));
+extern void *malloc (__SIZE_TYPE__) __attribute__((malloc,transaction_safe));
+
+struct large { int foo[500]; };
+
+int f()
+{
+ int *p1, *p2, *p3;
+
+ p1 = malloc (sizeof (*p1)*5000);
+ __transaction_atomic {
+ *p1 = 0;
+
+ p2 = malloc (sizeof (*p2)*6000);
+ *p2 = 1;
+
+ /* p3 = PHI (p1, p2) */
+ if (test())
+ p3 = p1;
+ else
+ p3 = p2;
+
+ /* Since both p1 and p2 are thread-private, we can inherit the
+ logging already done. No ITM_W* instrumentation necessary. */
+ *p3 = 555;
+ }
+ return p3[something()];
+}
+
+/* { dg-final { scan-tree-dump-times "ITM_WU" 0 "tmmark" } } */
+/* { dg-final { cleanup-tree-dump "tmmark" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/memopt-13.c b/gcc/testsuite/gcc.dg/tm/memopt-13.c
new file mode 100644
index 00000000000..6e93b7feaea
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/memopt-13.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O -fdump-tree-tmmark" } */
+
+struct large { int x[100]; };
+struct large large_global;
+extern struct large function (void) __attribute__((transaction_safe));
+
+void f()
+{
+ __transaction_atomic {
+ large_global = function();
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "memmoveRtWt \\\(&large_global," 1 "tmmark" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/memopt-15.c b/gcc/testsuite/gcc.dg/tm/memopt-15.c
new file mode 100644
index 00000000000..975c794337c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/memopt-15.c
@@ -0,0 +1,30 @@
+/* { dg-do compile { target { x86_64-*-linux* } } } */
+/* { dg-options "-fgnu-tm -O" } */
+
+/* Test the TM vector logging functions. */
+
+typedef int __attribute__((vector_size (16))) vectype;
+extern int something(void) __attribute__((transaction_safe));
+extern void *malloc (__SIZE_TYPE__) __attribute__((malloc,transaction_safe));
+
+vectype vecky;
+
+vectype f()
+{
+ vectype *p;
+
+ p = malloc (sizeof (*p) * 100);
+
+ __transaction_atomic {
+ /* p[5] is thread private, but not transaction local since the
+ malloc is outside of the transaction. We can use the logging
+ functions for this. */
+ p[5] = vecky;
+
+ if (something())
+ __transaction_cancel;
+ }
+ return p[5];
+}
+
+/* { dg-final { scan-assembler "_ITM_LM128" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/memopt-2.c b/gcc/testsuite/gcc.dg/tm/memopt-2.c
new file mode 100644
index 00000000000..08aa9acdcbc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/memopt-2.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O -fdump-tree-tmmemopt" } */
+
+char c;
+
+void f(void)
+{
+ __transaction_atomic {
+ ++c;
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "transforming.*RfWU1 \\(&c" 1 "tmmemopt" } } */
+/* { dg-final { scan-tree-dump-times "transforming.*WaWU1 \\(&c" 1 "tmmemopt" } } */
+/* { dg-final { cleanup-tree-dump "tmmemopt" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/memopt-3.c b/gcc/testsuite/gcc.dg/tm/memopt-3.c
new file mode 100644
index 00000000000..62a3e0e9f2a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/memopt-3.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O -fdump-tree-tmmark" } */
+
+struct large { int x[100]; };
+extern int test(void) __attribute__((transaction_safe));
+
+int f()
+{
+ int i = readint();
+ struct large lala = { 0 };
+ __transaction_atomic {
+ lala.x[i] = 666;
+ if (test())
+ __transaction_cancel;
+ }
+ return lala.x[0];
+}
+
+/* { dg-final { scan-tree-dump-times "logging: lala.x\\\[i_1\\\]" 1 "tmmark" { xfail *-*-* } } } */
+/* { dg-final { cleanup-tree-dump "tmmark" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/memopt-4.c b/gcc/testsuite/gcc.dg/tm/memopt-4.c
new file mode 100644
index 00000000000..92849718441
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/memopt-4.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O -fdump-tree-tmedge" } */
+
+/* Test thread-local memory optimizations: save/restore pairs. */
+
+struct large { int x[100]; };
+struct large bark();
+extern int test (void) __attribute__((transaction_safe));
+
+int f()
+{
+ int i = readint();
+ struct large lala = bark();
+ __transaction_atomic {
+ lala.x[55] = 666;
+ if (test())
+ __transaction_cancel;
+ }
+ return lala.x[i];
+}
+
+/* { dg-final { scan-tree-dump-times "tm_save.\[0-9_\]+ = lala.x\\\[55\\\]" 1 "tmedge" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "lala.x\\\[55\\\] = tm_save" 1 "tmedge" { xfail *-*-* } } } */
+/* { dg-final { cleanup-tree-dump "tmedge" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/memopt-5.c b/gcc/testsuite/gcc.dg/tm/memopt-5.c
new file mode 100644
index 00000000000..7b377a58035
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/memopt-5.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O -fdump-tree-tmedge --param tm-max-aggregate-size=1" } */
+
+/* Test thread-local memory optimizations: logging function. */
+
+struct large { int x[100]; };
+struct large bark();
+extern int test (void) __attribute__((transaction_safe));
+
+int f()
+{
+ int i = readint();
+ struct large lala = bark();
+ __transaction_atomic {
+ lala.x[55] = 666;
+ if (test())
+ __transaction_cancel;
+ }
+ return lala.x[i];
+}
+
+/* { dg-final { scan-tree-dump-times "ITM_LU\[0-9\] \\\(&lala.x\\\[55\\\]" 1 "tmedge" { xfail *-*-* } } } */
+/* { dg-final { cleanup-tree-dump "tmedge" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/memopt-6.c b/gcc/testsuite/gcc.dg/tm/memopt-6.c
new file mode 100644
index 00000000000..f4343736772
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/memopt-6.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O -fdump-tree-tmedge --param tm-max-aggregate-size=1" } */
+
+struct large { int x[100]; };
+struct large bark();
+extern int test (void) __attribute__((transaction_safe));
+struct large lacopy;
+
+int f()
+{
+ int i = readint();
+ struct large lala = bark();
+ __transaction_atomic {
+ lala.x[55] = 666;
+ lala = lacopy; /* Aggregate instrumentation. */
+ }
+ return lala.x[i];
+}
+
+/* { dg-final { scan-tree-dump-times "memmoveRtWt \\\(&lala, &lacopy" 1 "tmedge" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/memopt-7.c b/gcc/testsuite/gcc.dg/tm/memopt-7.c
new file mode 100644
index 00000000000..f8af2a95e66
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/memopt-7.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O -fdump-tree-tmedge --param tm-max-aggregate-size=999" } */
+
+/* Test save/restore pairs for aggregates. */
+
+struct large { int x[100]; };
+extern struct large foobie (void) __attribute__((transaction_safe));
+int asdf;
+
+int f()
+{
+ struct large lala;
+ struct large lacopy = foobie();
+ __transaction_atomic {
+ lala = lacopy;
+ }
+ return lala.x[asdf];
+}
+
+/* { dg-final { scan-tree-dump-times "tm_save.\[0-9_\]+ = lala" 1 "tmedge" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "lala = tm_save" 1 "tmedge" { xfail *-*-* } } } */
+/* { dg-final { cleanup-tree-dump "tmedge" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/memopt-8.c b/gcc/testsuite/gcc.dg/tm/memopt-8.c
new file mode 100644
index 00000000000..10320e78950
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/memopt-8.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O -fdump-tree-tmmark" } */
+
+extern int something(void) __attribute__((transaction_safe));
+extern int escape(int *) __attribute__((transaction_safe));
+extern void *malloc (__SIZE_TYPE__) __attribute__((malloc,transaction_safe));
+
+int f()
+{
+ int *p;
+
+ __transaction_atomic {
+ p = malloc (sizeof (*p) * 100);
+ escape (p);
+
+ /* This should be instrumented because P escapes. */
+ p[5] = 123;
+
+ if (something())
+ __transaction_cancel;
+ }
+ return p[5];
+}
+
+/* { dg-final { scan-tree-dump-times "ITM_WU" 1 "tmmark" } } */
+/* { dg-final { cleanup-tree-dump "tmmark" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/memopt-9.c b/gcc/testsuite/gcc.dg/tm/memopt-9.c
new file mode 100644
index 00000000000..0c34f20b926
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/memopt-9.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O -fdump-tree-tmmark" } */
+
+extern int something(void) __attribute__((transaction_safe));
+extern void *malloc (__SIZE_TYPE__) __attribute__((malloc,transaction_safe));
+
+struct large { int foo[500]; };
+
+int f()
+{
+ int *p;
+ struct large *lp;
+
+ __transaction_atomic {
+ p = malloc (sizeof (*p) * 100);
+ lp = malloc (sizeof (*lp) * 100);
+
+ /* No instrumentation necessary; P and LP are transaction local. */
+ p[5] = 123;
+ lp->foo[66] = 123;
+
+ if (something())
+ __transaction_cancel;
+ }
+ return p[5];
+}
+
+/* { dg-final { scan-tree-dump-times "ITM_WU" 0 "tmmark" } } */
+/* { dg-final { cleanup-tree-dump "tmmark" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/memset-2.c b/gcc/testsuite/gcc.dg/tm/memset-2.c
new file mode 100644
index 00000000000..743ada13783
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/memset-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-tree-tmlower" } */
+
+char array[4];
+
+void *memset(void *s, int c, __SIZE_TYPE__);
+
+int main()
+{
+ __transaction_atomic {
+ memset(array, 'b', sizeof(4));
+ }
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "GTMA_HAVE_STORE" 1 "tmlower" } } */
+/* { dg-final { cleanup-tree-dump "tmlower" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/memset.c b/gcc/testsuite/gcc.dg/tm/memset.c
new file mode 100644
index 00000000000..3b73ec6ee74
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/memset.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+
+extern void *memset (void *, int, __SIZE_TYPE__);
+
+char array[4] = "aaaa";
+
+__attribute__((transaction_safe))
+void *my_memset()
+{
+ return memset(array,'b',4);
+}
+
+
+int main()
+{
+
+ __transaction_atomic {
+ my_memset();
+ }
+ return 0;
+}
+
+/* { dg-final { scan-assembler "_ITM_memsetW" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/nested-1.c b/gcc/testsuite/gcc.dg/tm/nested-1.c
new file mode 100644
index 00000000000..afadb83c183
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/nested-1.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+
+extern int foo(int) __attribute__((transaction_safe));
+void bar(void)
+{
+ __transaction_atomic {
+ if (foo(1))
+ __transaction_atomic {
+ if (foo(2))
+ __transaction_atomic {
+ if (foo(3))
+ __transaction_atomic {
+ if (foo(4))
+ foo(5);
+ else
+ __transaction_cancel;
+ }
+ else
+ __transaction_cancel;
+ }
+ else
+ __transaction_cancel;
+ }
+ else
+ __transaction_cancel;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tm/nested-2.c b/gcc/testsuite/gcc.dg/tm/nested-2.c
new file mode 100644
index 00000000000..205ca8d7eac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/nested-2.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+
+void foobar(void)
+{
+ __transaction_atomic {
+ foobar();
+ }
+}
+
+void doit(void) __attribute__((transaction_safe));
+
+__attribute__((transaction_callable))
+void callable(void)
+{
+ __transaction_atomic {
+ doit();
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tm/opt-1.c b/gcc/testsuite/gcc.dg/tm/opt-1.c
new file mode 100644
index 00000000000..87a8c72bd43
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/opt-1.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O" } */
+
+extern void usleep (int) __attribute__((transaction_pure));
+extern int rand(void) __attribute__((pure, transaction_pure));
+extern int printf (const char *, ...);
+extern void *malloc (__SIZE_TYPE__) __attribute__((malloc));
+extern void xyzzy (void * (*)(void *));
+
+typedef struct
+{
+ int id;
+} parm;
+
+int gvar;
+
+void *hello(void *arg)
+{
+ parm *p=(parm *)arg;
+ int tmp = p->id;
+ int tmp3;
+ printf ("Thread reads %d.\n", tmp);
+ __transaction_atomic
+ {
+ int tmp2 = gvar;
+ usleep ((int) (10.0*rand()/(10+1.0))/100);
+ gvar = tmp + tmp2;
+ tmp3 = gvar;
+ }
+ printf("tmp3 = %d\n", tmp3);
+ return 0;
+}
+
+int
+main()
+{
+ int i, n = rand();
+
+ for (i=0; i<n; i++)
+ xyzzy (hello);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tm/opt-2.c b/gcc/testsuite/gcc.dg/tm/opt-2.c
new file mode 100644
index 00000000000..d9e2b8a6db0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/opt-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O2" } */
+
+int foo(int *arr, int v)
+{
+ int r = 0;
+ int i;
+ __transaction_atomic {
+ for (i = 0; i < 10; ++i)
+ if (arr[i] < 27)
+ r += arr[i] += v;
+ }
+ return r;
+}
diff --git a/gcc/testsuite/gcc.dg/tm/pr45985.c b/gcc/testsuite/gcc.dg/tm/pr45985.c
new file mode 100644
index 00000000000..c8118406776
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/pr45985.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+
+__attribute__((transaction_unsafe))
+void illegal();
+
+static int a = 0;
+void func()
+{
+ __transaction_relaxed {
+ if( a == 0)
+ illegal();
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tm/pr46567-2.c b/gcc/testsuite/gcc.dg/tm/pr46567-2.c
new file mode 100644
index 00000000000..bfe0078bfdb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/pr46567-2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+
+int funky();
+int global;
+
+void SeqfileGetLine()
+{
+ funky();
+}
+
+__attribute__((transaction_callable)) void readLoop()
+{
+ SeqfileGetLine();
+ if (global)
+ funky();
+
+}
diff --git a/gcc/testsuite/gcc.dg/tm/pr46567.c b/gcc/testsuite/gcc.dg/tm/pr46567.c
new file mode 100644
index 00000000000..bcc59adf509
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/pr46567.c
@@ -0,0 +1,18 @@
+__attribute__((transaction_callable))
+static void SeqfileGetLine ()
+{
+ SSIGetFilePosition ();
+}
+
+__attribute__((transaction_callable))
+static void readLoop (int addfirst)
+{
+ if (!addfirst)
+ {
+ if (!addfirst)
+ {
+ SSIGetFilePosition ();
+ }
+ SeqfileGetLine ();
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tm/pr46654.c b/gcc/testsuite/gcc.dg/tm/pr46654.c
new file mode 100644
index 00000000000..bb63b685844
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/pr46654.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+
+extern void baz(int);
+
+int y;
+void foo(volatile int x)
+{
+ __transaction_atomic {
+ x = 5; /* { dg-error "invalid volatile use of 'x' inside transaction" } */
+ x += y;
+ y++;
+ }
+ baz(x);
+}
+
+
+volatile int i = 0;
+
+void george()
+{
+ __transaction_atomic {
+ if (i == 2) /* { dg-error "invalid volatile use of 'i' inside transaction" } */
+ i = 1;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tm/pr47520.c b/gcc/testsuite/gcc.dg/tm/pr47520.c
new file mode 100644
index 00000000000..80b976bd4cb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/pr47520.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O" } */
+
+struct ReadSeqVars
+{
+ int format;
+ char *ss;
+};
+
+void rms_feof(struct ReadSeqVars *);
+
+__attribute__((transaction_callable)) int ReadSeq(struct ReadSeqVars *V)
+{
+ if (V->format > 1)
+ {
+ if ((V->format != 2) && (V->ss != (void*)0) )
+ {
+ V->format = 3;
+ }
+ }
+ else
+ {
+ int i = 0;
+ for (i = 0; i < 1; i++)
+ {
+ }
+ rms_feof(V);
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tm/pr47690.c b/gcc/testsuite/gcc.dg/tm/pr47690.c
new file mode 100644
index 00000000000..d18e2e11fb8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/pr47690.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+
+int george;
+
+void q1()
+{
+ __transaction_atomic {
+ george=999;
+ }
+ q1();
+}
+
+/* { dg-final { scan-assembler-not "ZGTt2q1" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/pr47905.c b/gcc/testsuite/gcc.dg/tm/pr47905.c
new file mode 100644
index 00000000000..c4b254930c1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/pr47905.c
@@ -0,0 +1,14 @@
+/* { dg-do compile }
+ { dg-options "-fgnu-tm" } */
+
+void funcA();
+void funcB();
+
+void *thread()
+{
+ __transaction_relaxed
+ {
+ funcA();
+ };
+ funcB();
+}
diff --git a/gcc/testsuite/gcc.dg/tm/props-1.c b/gcc/testsuite/gcc.dg/tm/props-1.c
new file mode 100644
index 00000000000..89690240486
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/props-1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-tree-tmedge -fdump-tree-tmlower" } */
+
+int global;
+
+foo(int local)
+{
+ __transaction_atomic {
+ local++;
+ if (++global == 10)
+ __transaction_cancel;
+ }
+}
+
+/* { dg-final { scan-tree-dump-times " instrumentedCode" 1 "tmedge" } } */
+/* { dg-final { scan-tree-dump-times "hasNoAbort" 0 "tmedge" } } */
+/* { dg-final { scan-tree-dump-times "GTMA_HAVE_ABORT" 1 "tmlower" } } */
+/* { dg-final { cleanup-tree-dump "tmedge" } } */
+/* { dg-final { cleanup-tree-dump "tmlower" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/props-2.c b/gcc/testsuite/gcc.dg/tm/props-2.c
new file mode 100644
index 00000000000..56a3ffa1367
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/props-2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-ipa-tmipa" } */
+
+/* Test that irrevocability gets set for the obvious case. */
+
+int global;
+int george;
+
+extern crap() __attribute__((transaction_unsafe));
+
+foo(){
+ __transaction_relaxed {
+ global++;
+ crap();
+ george++;
+ }
+}
+
+/* { dg-final { scan-ipa-dump-times "GTMA_MAY_ENTER_IRREVOCABLE" 1 "tmipa" } } */
+/* { dg-final { cleanup-ipa-dump "tmipa" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/props-3.c b/gcc/testsuite/gcc.dg/tm/props-3.c
new file mode 100644
index 00000000000..48f2230cdd2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/props-3.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-ipa-tmipa" } */
+
+/* Test that indirect calls set the irrevocable bit. */
+
+void (*indirect)(void);
+
+foo(){
+ __transaction_relaxed {
+ (*indirect)();
+ }
+}
+
+/* { dg-final { scan-ipa-dump-times "GTMA_MAY_ENTER_IRREVOCABLE" 1 "tmipa" } } */
+/* { dg-final { cleanup-ipa-dump "tmipa" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/props-4.c b/gcc/testsuite/gcc.dg/tm/props-4.c
new file mode 100644
index 00000000000..c9d0c2b2887
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/props-4.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-tree-tmedge -fdump-tree-tmmark" } */
+
+int a, b;
+
+void __attribute((transaction_may_cancel_outer,noinline)) cancel1()
+{
+ __transaction_cancel [[outer]];
+}
+
+void
+foo(void)
+{
+ __transaction_atomic [[outer]] {
+ a = 2;
+ __transaction_atomic {
+ b = 2;
+ cancel1();
+ }
+ }
+}
+
+/* { dg-final { scan-tree-dump-times " instrumentedCode" 1 "tmedge" } } */
+/* { dg-final { scan-tree-dump-times "hasNoAbort" 0 "tmedge" } } */
+/* { dg-final { scan-tree-dump-times "LABEL=<L0>" 1 "tmmark" } } */
+/* { dg-final { cleanup-tree-dump "tmedge" } } */
+/* { dg-final { cleanup-tree-dump "tmmark" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/tm.exp b/gcc/testsuite/gcc.dg/tm/tm.exp
new file mode 100644
index 00000000000..3d24481d5a8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/tm.exp
@@ -0,0 +1,39 @@
+# Copyright (C) 2009, 2011 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Run the tests that are shared with C++ testing.
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/tm/*c]] \
+ "" $DEFAULT_CFLAGS
+# Run the C-only tests.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
+ "" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gcc.dg/tm/unsafe.c b/gcc/testsuite/gcc.dg/tm/unsafe.c
new file mode 100644
index 00000000000..824368a1a34
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/unsafe.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+
+__attribute__((transaction_callable))
+static int func ()
+{
+ return 12345;
+}
+
+int main()
+{
+ __transaction_atomic { return func(); } /* { dg-error "unsafe function call .func. " } */
+}
diff --git a/gcc/testsuite/gcc.dg/tm/unused.c b/gcc/testsuite/gcc.dg/tm/unused.c
new file mode 100644
index 00000000000..7c8aa3e778d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/unused.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -Wall" } */
+
+__attribute__((transaction_safe))
+static int unused_func () /* { dg-warning "defined but not used" } */
+{
+ return 12345;
+}
+
+int main()
+{
+ return 0;
+}
+
+/* { dg-final { scan-assembler "_ZGTt11unused_func:" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/vector-1.c b/gcc/testsuite/gcc.dg/tm/vector-1.c
new file mode 100644
index 00000000000..2dc43b0a517
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/vector-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O3" } */
+
+/* On x86-64, the vectorizer creates V2DI uses which we must handle.
+ Similarly for other vector architectures. */
+
+void ** newElements;
+
+__attribute__((transaction_safe))
+long
+TMqueue_push (void** queuePtr)
+{
+ long src;
+ for (src = 1; src < 9; src++) {
+ newElements[src+1] = queuePtr[src];
+ }
+ return 1;
+}
diff --git a/gcc/testsuite/gcc.dg/tm/wrap-2.c b/gcc/testsuite/gcc.dg/tm/wrap-2.c
new file mode 100644
index 00000000000..29486335a44
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/wrap-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm" } */
+
+#define W(X) __attribute__((transaction_wrap(X)))
+void f1(void);
+void f2(int);
+int i3;
+int f7(void);
+
+void g1(void) W(f1);
+void g2(void) W(f2); /* { dg-error "is not compatible" } */
+void g3(void) W(i3); /* { dg-error "is not a function" } */
+void g4(void) W(f4); /* { dg-error "is not a function" } */
+void g5(void) W(1); /* { dg-error "not an identifier" } */
+void g6(void) W("f1"); /* { dg-error "not an identifier" } */
+void g7(void) W(f7); /* { dg-error "is not compatible" } */
diff --git a/gcc/testsuite/gcc.dg/tm/wrap-3.c b/gcc/testsuite/gcc.dg/tm/wrap-3.c
new file mode 100644
index 00000000000..0734436809f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/wrap-3.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-tree-optimized" } */
+
+void free (void *);
+void wrapper (void *) __attribute__((transaction_wrap (free)));
+void *p;
+
+void foo()
+{
+ __transaction_relaxed { free (p); }
+}
+
+/* { dg-final { scan-tree-dump-times "free" 0 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tm/wrap-4.c b/gcc/testsuite/gcc.dg/tm/wrap-4.c
new file mode 100644
index 00000000000..9e1e70c544f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/wrap-4.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -fdump-tree-optimized -O2" } */
+
+static void candy() { candycane(); }
+
+static void tootsie_roll () __attribute__((transaction_wrap (candy)));
+static void tootsie_roll () { bark(); }
+
+void foo()
+{
+ __transaction_relaxed { candy(); }
+}
+
+/* { dg-final { scan-tree-dump-times "candy" 0 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */