[2/2] Add tests for the vartrace pass
diff mbox series

Message ID 20191111074026.26013-2-andi@firstfloor.org
State New
Headers show
Series
  • [1/2] Add a pass to automatically add ptwrite instrumentation
Related show

Commit Message

Andi Kleen Nov. 11, 2019, 7:40 a.m. UTC
From: Andi Kleen <ak@linux.intel.com>

So far they are mostly i386 target specific. Later they could
be moved up to architecture specific if some other architecture
adds vartracing. This would need abstracing the scanning
for the trace function.

gcc/testsuite/:

2019-11-10  Andi Kleen  <ak@linux.intel.com>

	* g++.dg/vartrace-3.C: New test.
	* g++.dg/vartrace-ret.C: New test.
	* g++.dg/vartrace-ret2.C: New test.
	* gcc.target/i386/vartrace-1.c: New test.
	* gcc.target/i386/vartrace-10.c: New test.
	* gcc.target/i386/vartrace-11.c: New test.
	* gcc.target/i386/vartrace-12.c: New test.
	* gcc.target/i386/vartrace-13.c: New test.
	* gcc.target/i386/vartrace-14.c: New test.
	* gcc.target/i386/vartrace-15.c: New test.
	* gcc.target/i386/vartrace-16.c: New test.
	* gcc.target/i386/vartrace-17.c: New test.
	* gcc.target/i386/vartrace-18.c: New test.
	* gcc.target/i386/vartrace-19.c: New test.
	* gcc.target/i386/vartrace-20.c: New test.
	* gcc.target/i386/vartrace-21.c: New test.
	* gcc.target/i386/vartrace-22.c: New test.
	* gcc.target/i386/vartrace-23.c: New test.
	* gcc.target/i386/vartrace-2.c: New test.
	* gcc.target/i386/vartrace-3.c: New test.
	* gcc.target/i386/vartrace-4.c: New test.
	* gcc.target/i386/vartrace-5.c: New test.
	* gcc.target/i386/vartrace-6.c: New test.
	* gcc.target/i386/vartrace-7.c: New test.
	* gcc.target/i386/vartrace-8.c: New test.
	* gcc.target/i386/vartrace-9.c: New test.
---
 gcc/testsuite/g++.dg/vartrace-3.C           | 14 ++++
 gcc/testsuite/g++.dg/vartrace-ret.C         | 17 +++++
 gcc/testsuite/g++.dg/vartrace-ret2.C        | 24 +++++++
 gcc/testsuite/gcc.target/i386/vartrace-1.c  | 41 +++++++++++
 gcc/testsuite/gcc.target/i386/vartrace-10.c | 13 ++++
 gcc/testsuite/gcc.target/i386/vartrace-11.c | 16 +++++
 gcc/testsuite/gcc.target/i386/vartrace-12.c | 16 +++++
 gcc/testsuite/gcc.target/i386/vartrace-13.c | 18 +++++
 gcc/testsuite/gcc.target/i386/vartrace-14.c | 17 +++++
 gcc/testsuite/gcc.target/i386/vartrace-15.c | 12 ++++
 gcc/testsuite/gcc.target/i386/vartrace-16.c | 12 ++++
 gcc/testsuite/gcc.target/i386/vartrace-17.c | 23 ++++++
 gcc/testsuite/gcc.target/i386/vartrace-18.c | 21 ++++++
 gcc/testsuite/gcc.target/i386/vartrace-19.c | 24 +++++++
 gcc/testsuite/gcc.target/i386/vartrace-2.c  |  9 +++
 gcc/testsuite/gcc.target/i386/vartrace-20.c | 32 +++++++++
 gcc/testsuite/gcc.target/i386/vartrace-21.c | 79 +++++++++++++++++++++
 gcc/testsuite/gcc.target/i386/vartrace-22.c | 17 +++++
 gcc/testsuite/gcc.target/i386/vartrace-23.c | 38 ++++++++++
 gcc/testsuite/gcc.target/i386/vartrace-3.c  |  9 +++
 gcc/testsuite/gcc.target/i386/vartrace-4.c  | 13 ++++
 gcc/testsuite/gcc.target/i386/vartrace-5.c  | 11 +++
 gcc/testsuite/gcc.target/i386/vartrace-6.c  | 13 ++++
 gcc/testsuite/gcc.target/i386/vartrace-7.c  | 11 +++
 gcc/testsuite/gcc.target/i386/vartrace-8.c  | 11 +++
 gcc/testsuite/gcc.target/i386/vartrace-9.c  | 10 +++
 gcc/testsuite/gcc.target/vartrace-19.c      | 23 ++++++
 27 files changed, 544 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/vartrace-3.C
 create mode 100644 gcc/testsuite/g++.dg/vartrace-ret.C
 create mode 100644 gcc/testsuite/g++.dg/vartrace-ret2.C
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-10.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-11.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-12.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-13.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-14.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-15.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-16.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-17.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-18.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-19.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-20.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-21.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-22.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-23.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-4.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-5.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-6.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-7.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-8.c
 create mode 100644 gcc/testsuite/gcc.target/i386/vartrace-9.c
 create mode 100644 gcc/testsuite/gcc.target/vartrace-19.c

Patch
diff mbox series

diff --git a/gcc/testsuite/g++.dg/vartrace-3.C b/gcc/testsuite/g++.dg/vartrace-3.C
new file mode 100644
index 00000000000..217db297baa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vartrace-3.C
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -mptwrite -fvartrace=args " } */
+/* { dg-final { scan-assembler "ptwrite" } } */
+
+int a;
+int b(int c) 
+{
+  if (a)
+    c += 1;
+  else
+    c += b(a);
+  b(c);
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/vartrace-ret.C b/gcc/testsuite/g++.dg/vartrace-ret.C
new file mode 100644
index 00000000000..5824e3f3738
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vartrace-ret.C
@@ -0,0 +1,17 @@ 
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -mptwrite -fvartrace=returns " } */
+/* { dg-final { scan-assembler-not "ptwrite" } } */
+
+class foo { 
+public:
+    short a;
+    short b;
+};
+
+foo f1()
+{
+    foo x = { 1, 2 };
+    return x;
+}
+
+
diff --git a/gcc/testsuite/g++.dg/vartrace-ret2.C b/gcc/testsuite/g++.dg/vartrace-ret2.C
new file mode 100644
index 00000000000..56842d75fb6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vartrace-ret2.C
@@ -0,0 +1,24 @@ 
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -mptwrite -fvartrace " } */
+/* { dg-final { scan-assembler "ptwrite" } } */
+
+typedef int a;
+enum b
+{ };
+struct ac
+{
+  a operator () (a, a, a, a, a, a);
+};
+struct c
+{
+  ac ag;
+} extern ai[];
+a d;
+void
+l (a e)
+{
+  b f;
+  a g, h, i, j, k;
+  e = d;
+  ai[f].ag (e, g, h, i, j, k);
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-1.c b/gcc/testsuite/gcc.target/i386/vartrace-1.c
new file mode 100644
index 00000000000..dde60c12d54
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-1.c
@@ -0,0 +1,41 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mptwrite -fvartrace -fvartrace=locals" } */
+/* { dg-final { scan-assembler "ptwrite" } } */
+
+int foo;
+
+extern void f2 (void);
+
+void
+f0 (void)
+{
+  foo += 1;
+}
+
+int
+f3 (int a)
+{
+  return a * 2;
+}
+
+extern void extfunc (int);
+
+int
+f4 (int a, int b)
+{
+  extfunc (a);
+  extfunc (b);
+  return a + b;
+}
+
+void
+f5 (int a)
+{
+}
+
+int
+f (int a, int b)
+{
+  f2 ();
+  return a + b + foo;
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-10.c b/gcc/testsuite/gcc.target/i386/vartrace-10.c
new file mode 100644
index 00000000000..37f2ede23ee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-10.c
@@ -0,0 +1,13 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mptwrite -fvartrace" } */
+/* { dg-final { scan-assembler-not "ptwrite" } } */
+
+int a __attribute__ ((no_vartrace));
+
+extern void f2 (int);
+
+void
+f (void)
+{
+  f2 (a);
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-11.c b/gcc/testsuite/gcc.target/i386/vartrace-11.c
new file mode 100644
index 00000000000..fc25170e0ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-11.c
@@ -0,0 +1,16 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mptwrite" } */
+/* { dg-final { scan-assembler-times "ptwrite" 1 } } */
+
+struct foo
+{
+  __attribute__ ((vartrace)) int field;
+};
+
+struct foo a;
+
+int
+f (void)
+{
+  return a.field;
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-12.c b/gcc/testsuite/gcc.target/i386/vartrace-12.c
new file mode 100644
index 00000000000..6f428bbabe2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-12.c
@@ -0,0 +1,16 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mptwrite" } */
+/* { dg-final { scan-assembler-times "ptwrite" 1 } } */
+
+struct foo
+{
+  int field;
+} __attribute__ ((vartrace));
+
+struct foo a;
+
+int
+f (void)
+{
+  return a.field;
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-13.c b/gcc/testsuite/gcc.target/i386/vartrace-13.c
new file mode 100644
index 00000000000..94802596d72
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-13.c
@@ -0,0 +1,18 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mptwrite -fvartrace" } */
+/* { dg-final { scan-assembler-not "ptwrite" } } */
+
+struct foo
+{
+  int field;
+} __attribute__ ((no_vartrace));
+
+struct foo a;
+
+extern void f2 (int);
+
+int
+f (void)
+{
+  f2 (a.field);
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-14.c b/gcc/testsuite/gcc.target/i386/vartrace-14.c
new file mode 100644
index 00000000000..d4db8bf735b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-14.c
@@ -0,0 +1,17 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mptwrite -fvartrace" } */
+/* { dg-final { scan-assembler-not "ptwrite" } } */
+
+struct foo 
+{
+  int __attribute__((no_vartrace)) field;
+};
+
+struct foo a;
+
+extern void f2(int);
+
+int f(void)
+{
+  f2 (a.field);
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-15.c b/gcc/testsuite/gcc.target/i386/vartrace-15.c
new file mode 100644
index 00000000000..02067a016e3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-15.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mptwrite -fvartrace" } */
+/* { dg-final { scan-assembler-not "ptwrite" } } */
+
+struct {
+  int __attribute__((vartrace)) x;
+} v;
+
+__attribute__((target("no-ptwrite"))) int f(void)
+{
+  return v.x;
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-16.c b/gcc/testsuite/gcc.target/i386/vartrace-16.c
new file mode 100644
index 00000000000..4cb91089786
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-16.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile } */
+/* { dg-options "" } */
+/* { dg-final { scan-assembler-times "ptwrite" 1 } } */
+
+struct {
+  int __attribute__((vartrace)) x;
+} v;
+
+__attribute__((target("ptwrite"))) int f(void)
+{
+  return v.x;
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-17.c b/gcc/testsuite/gcc.target/i386/vartrace-17.c
new file mode 100644
index 00000000000..68de67ced11
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-17.c
@@ -0,0 +1,23 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fvartrace -mptwrite -fdump-tree-vartrace" } */
+
+/* { dg-final { scan-tree-dump-times "(?n)read_args.*insert.*ptwrite" 3 "vartrace" } } */
+int read_args(int a, int b)
+{
+  return a+b;
+}
+
+int x;
+
+/* { dg-final { scan-tree-dump-times "(?n)global.*insert.*ptwrite" 5 "vartrace" } }*/
+int global(int a)
+{
+  x += a;
+  return x + a;
+}
+
+/* { dg-final { scan-tree-dump-times "(?n)pointer_ref.*insert.*ptwrite" 2 "vartrace" } }*/
+int pointer_ref(int *f)
+{
+  return *f++;
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-18.c b/gcc/testsuite/gcc.target/i386/vartrace-18.c
new file mode 100644
index 00000000000..8b6b4107461
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-18.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fvartrace=reads -mptwrite -fdump-tree-vartrace" } */
+/* Source: Martin Sebor */
+
+int global __attribute__((no_vartrace));
+int array[10];
+
+/* { dg-final { scan-tree-dump-times "(?n)array.*insert.*ptwrite" 1 "vartrace" } } */
+int trace_array(void)
+{
+  return array[global];
+}
+
+int array2[10] __attribute__((no_vartrace));
+int global2;
+
+/* { dg-final { scan-tree-dump-times "(?n)global.*insert.*ptwrite" 1 "vartrace" } } */
+int trace_global(void)
+{
+  return array2[global2];
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-19.c b/gcc/testsuite/gcc.target/i386/vartrace-19.c
new file mode 100644
index 00000000000..ca728ecac6a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-19.c
@@ -0,0 +1,24 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fvartrace -fvartrace=locals -mptwrite -fdump-tree-vartrace" } */
+/* { dg-final { scan-assembler-times "ptwrite" 4 } } */
+
+int global;
+int global2;
+
+/* { dg-final { scan-tree-dump-times "(?n)asm_read.*insert.*ptwrite" 1 "vartrace" } } */
+void asm_read(int i)
+{
+  asm("nop" :: "r" (i) : "memory");
+}
+
+/* { dg-final { scan-tree-dump-times "(?n)asm_write.*insert.*ptwrite" 1 "vartrace" } } */
+void asm_write(void)
+{
+  asm("nop" : "=m" (global) :: "memory");
+}
+
+/* { dg-final { scan-tree-dump-times "(?n)asm_rw.*insert.*ptwrite" 2 "vartrace" } } */
+void asm_rw(void)
+{
+  asm("nop" : "=m" (global) : "r" (global2) : "memory");
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-2.c b/gcc/testsuite/gcc.target/i386/vartrace-2.c
new file mode 100644
index 00000000000..29398457abd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-2.c
@@ -0,0 +1,9 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mptwrite -fvartrace=args" } */
+/* { dg-final { scan-assembler-times "ptwrite" 1 } } */
+
+int
+f (int a)
+{
+  return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-20.c b/gcc/testsuite/gcc.target/i386/vartrace-20.c
new file mode 100644
index 00000000000..3e7d012f03f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-20.c
@@ -0,0 +1,32 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fvartrace=reads -mptwrite -fdump-tree-vartrace" } */
+
+int global;
+
+/* { dg-final { scan-tree-dump-times "(?n)fswitch.*insert.*ptwrite" 1 "vartrace" } }*/
+int fswitch(void)
+{
+  switch (global)
+    {
+    case 1:
+      return 1;
+    default:
+      return 0;
+    }
+}
+
+/* { dg-final { scan-tree-dump-times "(?n)fif.*insert.*ptwrite" 1 "vartrace" } }*/
+int fif(void)
+{
+  if (global > 0)
+    return 1;
+  return 0;
+}
+
+int (*fptr)(void);
+
+/* { dg-final { scan-tree-dump-times "(?n)findcall.*insert.*ptwrite" 1 "vartrace" } }*/
+int findcall(void)
+{
+  return fptr();
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-21.c b/gcc/testsuite/gcc.target/i386/vartrace-21.c
new file mode 100644
index 00000000000..bc129ea9c82
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-21.c
@@ -0,0 +1,79 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fvartrace=reads,writes -mptwrite -fdump-tree-vartrace" } */
+
+/* Expect a single ptwrite for each function */
+
+/* { dg-final { scan-tree-dump-times "(?n)ptr_write.*insert.*ptwrite" 1 "vartrace" } }*/
+void ptr_write (int *p)
+{
+  *p = 1;
+}
+
+/* { dg-final { scan-tree-dump-times "(?n)ptr_read.*insert.*ptwrite" 1 "vartrace" } }*/
+int ptr_read (int *p)
+{
+  return *p;
+}
+
+/* { dg-final { scan-tree-dump-times "(?n)array_read.*insert.*ptwrite" 1 "vartrace" } }*/
+int array_read (int *p, int index)
+{
+  return p[index];
+}
+
+/* { dg-final { scan-tree-dump-times "(?n)array_write.*insert.*ptwrite" 1 "vartrace" } }*/
+int array_write (int *p, int index)
+{
+  p[index] = 1;
+}
+
+struct foo {
+  int x;
+};
+
+/* { dg-final { scan-tree-dump-times "(?n)sfield_read.*insert.*ptwrite" 1 "vartrace" } }*/
+int sfield_read(struct foo *p)
+{
+  return p->x;
+}
+
+/* { dg-final { scan-tree-dump-times "(?n)sfield_write.*insert.*ptwrite" 1 "vartrace" } }*/
+void sfield_write(struct foo *p, int arg)
+{
+  p->x = arg;
+}
+
+union bar {
+  int a;
+  int b;
+};
+
+/* { dg-final { scan-tree-dump-times "(?n)union_read.*insert.*ptwrite" 1 "vartrace" } }*/
+
+int union_read(union bar *p)
+{
+  return p->b;
+}
+
+/* { dg-final { scan-tree-dump-times "(?n)union_write.*insert.*ptwrite" 1 "vartrace" } }*/
+void union_write(union bar *p, int arg)
+{
+  p->a = arg;
+}
+
+struct bf {
+  unsigned f : 2;
+};
+
+/* { dg-final { scan-tree-dump-times "(?n)array_read.*insert.*ptwrite" 1 "vartrace" } }*/
+int bitfield_read(struct bf *p)
+{
+  return p->f;
+}
+
+/* { dg-final { scan-tree-dump-times "(?n)bitfield_write.*insert.*ptwrite" 1 "vartrace" } }*/
+
+void bitfield_write(struct bf *p, int arg)
+{
+  p->f = arg;
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-22.c b/gcc/testsuite/gcc.target/i386/vartrace-22.c
new file mode 100644
index 00000000000..a11ded6ab1d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-22.c
@@ -0,0 +1,17 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fvartrace=off -mptwrite" } */
+/* { dg-final { scan-assembler-not "ptwrite" } } */
+
+int foo;
+
+__attribute__((vartrace)) void f(void)
+{
+  foo++;
+}
+
+int foo2 __attribute__((vartrace));
+
+void f2(void)
+{
+  foo++;
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-23.c b/gcc/testsuite/gcc.target/i386/vartrace-23.c
new file mode 100644
index 00000000000..5702fde5f56
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-23.c
@@ -0,0 +1,38 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fvartrace -mptwrite -fdump-tree-vartrace" } */
+
+/* { dg-final { scan-tree-dump-times "(?n)ffloat.*insert.*ptwrite" 2 "vartrace" } }*/
+float ffloat(float x)
+{
+  return x + 1;
+}
+
+/* { dg-final { scan-tree-dump-times "(?n)fdouble.*insert.*ptwrite" 2 "vartrace" } }*/
+double fdouble(double x)
+{
+  return x + 1;
+}
+
+/* { dg-final { scan-tree-dump-times "(?n)fchar.*insert.*ptwrite" 2 "vartrace" } }*/
+char fchar(char x)
+{
+  return x + 1;
+}
+
+/* { dg-final { scan-tree-dump-times "(?n)fshort.*insert.*ptwrite" 2 "vartrace" } }*/
+short fshort(short x)
+{
+  return x + 1;
+}
+
+/* { dg-final { scan-tree-dump-times "(?n)fuchar.*insert.*ptwrite" 2 "vartrace" } }*/
+unsigned char fuchar(unsigned char x)
+{
+  return x + 1;
+}
+
+/* { dg-final { scan-tree-dump-times "(?n)fushort.*insert.*ptwrite" 2 "vartrace" } }*/
+unsigned short fushort(unsigned short x)
+{
+  return x + 1;
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-3.c b/gcc/testsuite/gcc.target/i386/vartrace-3.c
new file mode 100644
index 00000000000..20d7ab044f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-3.c
@@ -0,0 +1,9 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mptwrite -fvartrace=returns" } */
+/* { dg-final { scan-assembler-times "ptwrite" 1 } } */
+
+int
+f (int a)
+{
+  return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-4.c b/gcc/testsuite/gcc.target/i386/vartrace-4.c
new file mode 100644
index 00000000000..85ca6dc13e0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-4.c
@@ -0,0 +1,13 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mptwrite -fvartrace=reads" } */
+/* { dg-final { scan-assembler-times "ptwrite" 1 } } */
+
+int a;
+
+extern void f2 (int);
+
+int
+f (void)
+{
+  f2 (a);
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-5.c b/gcc/testsuite/gcc.target/i386/vartrace-5.c
new file mode 100644
index 00000000000..3ef42a23503
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-5.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mptwrite -fvartrace=writes" } */
+/* { dg-final { scan-assembler-times "ptwrite" 1 } } */
+
+int a;
+
+void
+f (void)
+{
+  a++;
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-6.c b/gcc/testsuite/gcc.target/i386/vartrace-6.c
new file mode 100644
index 00000000000..b0bcd1be88f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-6.c
@@ -0,0 +1,13 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mptwrite -fvartrace=reads,locals" } */
+/* { dg-final { scan-assembler "ptwrite" } } */
+
+extern void f2 (int);
+
+void
+f (void)
+{
+  int i;
+  for (i = 0; i < 10; i++)
+    f2 (i);
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-7.c b/gcc/testsuite/gcc.target/i386/vartrace-7.c
new file mode 100644
index 00000000000..e2fe2f3708e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-7.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mptwrite" } */
+/* { dg-final { scan-assembler-times "ptwrite" 1 } } */
+
+int a __attribute__ ((vartrace));
+
+int
+f (void)
+{
+  return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-8.c b/gcc/testsuite/gcc.target/i386/vartrace-8.c
new file mode 100644
index 00000000000..22453dd9ca6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-8.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mptwrite" } */
+/* { dg-final { scan-assembler-times "ptwrite" 1 } } */
+
+int a;
+
+__attribute__ ((vartrace))
+     int f (void)
+{
+  return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/vartrace-9.c b/gcc/testsuite/gcc.target/i386/vartrace-9.c
new file mode 100644
index 00000000000..9216b0776b9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vartrace-9.c
@@ -0,0 +1,10 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mptwrite -fvartrace" } */
+/* { dg-final { scan-assembler-not "ptwrite" } } */
+
+int a;
+
+__attribute__ ((no_vartrace)) int f (void)
+{
+  return a;
+}
diff --git a/gcc/testsuite/gcc.target/vartrace-19.c b/gcc/testsuite/gcc.target/vartrace-19.c
new file mode 100644
index 00000000000..7de0324fd34
--- /dev/null
+++ b/gcc/testsuite/gcc.target/vartrace-19.c
@@ -0,0 +1,23 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fvartrace=reads,writes -mptwrite" } */
+/* { dg-final { scan-assembler-times "ptwrite" 7 } } */
+/* XXX: should be 4 ptwrites, but right now we generate redundant ones */
+
+int global;
+int global2;
+
+__attribute__((vartrace))
+void f1(int i)
+{
+  asm("nop" :: "r" (i) : "memory");
+}
+
+void f2(void)
+{
+  asm("nop" : "=m" (global) :: "memory");
+}
+
+void f3(void)
+{
+  asm("nop" : "=m" (global) : "r" (global2) : "memory");
+}