diff --git a/gcc/testsuite/rust/execute/torture/block_expr1.rs b/gcc/testsuite/rust/execute/torture/block_expr1.rs
new file mode 100644
index 00000000000..d561f8cab59
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/block_expr1.rs
@@ -0,0 +1,8 @@
+fn main() -> i32 {
+    let ret = {
+        1;
+        2;
+        0
+    };
+    ret
+}
diff --git a/gcc/testsuite/rust/execute/torture/builtin_macro_cfg.rs b/gcc/testsuite/rust/execute/torture/builtin_macro_cfg.rs
new file mode 100644
index 00000000000..fad2daef6bc
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/builtin_macro_cfg.rs
@@ -0,0 +1,32 @@
+// { dg-additional-options "-w -frust-cfg=A" }
+// { dg-output "A\n" }
+#[rustc_builtin_macro]
+macro_rules! cfg {
+    () => {{}};
+}
+
+extern "C" {
+    fn printf(fmt: *const i8, ...);
+}
+
+fn print(s: &str) {
+    unsafe {
+        printf(
+            "%s\n" as *const str as *const i8,
+            s as *const str as *const i8,
+        );
+    }
+}
+
+fn main() -> i32 {
+    let cfg = cfg!(A);
+    if cfg {
+        print("A");
+    }
+    let cfg = cfg!(B);
+    if cfg {
+        print("B");
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/builtin_macro_concat.rs b/gcc/testsuite/rust/execute/torture/builtin_macro_concat.rs
new file mode 100644
index 00000000000..9b33924f5a1
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/builtin_macro_concat.rs
@@ -0,0 +1,29 @@
+// { dg-output "\ntest10btrue2.15\ntest10bfalse2.151\n" }
+#[rustc_builtin_macro]
+macro_rules! concat {
+    () => {{}};
+}
+
+extern "C" {
+    fn printf(fmt: *const i8, ...);
+}
+
+fn print(s: &str) {
+    unsafe {
+        printf(
+            "%s\n" as *const str as *const i8,
+            s as *const str as *const i8,
+        );
+    }
+}
+
+fn main() -> i32 {
+    let a = concat!();
+    let b = concat!("test", 10, 'b', true, 2.15);
+    let c = concat!("test", 10, 'b', false, 2.15, 1u64);
+    print(a);
+    print(b);
+    print(c);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/builtin_macro_env.rs b/gcc/testsuite/rust/execute/torture/builtin_macro_env.rs
new file mode 100644
index 00000000000..a5c80b25728
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/builtin_macro_env.rs
@@ -0,0 +1,31 @@
+// { dg-output "VALUE\nVALUE\n" }
+// { dg-set-compiler-env-var ENV_MACRO_TEST "VALUE" }
+#[rustc_builtin_macro]
+macro_rules! env {
+    () => {{}};
+}
+
+extern "C" {
+    fn printf(fmt: *const i8, ...);
+}
+
+fn print(s: &str) {
+    unsafe {
+        printf(
+            "%s\n" as *const str as *const i8,
+            s as *const str as *const i8,
+        );
+    }
+}
+
+fn main() -> i32 {
+    let val0 = env!("ENV_MACRO_TEST");
+
+    print(val0);
+
+    let val1 = env!("ENV_MACRO_TEST",);
+
+    print(val1);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/builtin_macro_include_bytes.rs b/gcc/testsuite/rust/execute/torture/builtin_macro_include_bytes.rs
new file mode 100644
index 00000000000..087f0220de5
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/builtin_macro_include_bytes.rs
@@ -0,0 +1,46 @@
+// { dg-output "104\n33\n1\n" }
+#[rustc_builtin_macro]
+macro_rules! include_bytes {
+    () => {{}};
+}
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn print_int(value: i32) {
+    let s = "%d\n\0" as *const str as *const i8;
+    unsafe {
+        printf(s, value);
+    }
+}
+
+fn main() -> i32 {
+    let bytes = include_bytes!("include.txt");
+
+    print_int(bytes[0] as i32);
+    print_int(bytes[14] as i32);
+
+    let the_bytes = b"hello, include!\n";
+
+    let x = bytes[0] == the_bytes[0]
+        && bytes[1] == the_bytes[1]
+        && bytes[2] == the_bytes[2]
+        && bytes[3] == the_bytes[3]
+        && bytes[4] == the_bytes[4]
+        && bytes[5] == the_bytes[5]
+        && bytes[6] == the_bytes[6]
+        && bytes[7] == the_bytes[7]
+        && bytes[8] == the_bytes[8]
+        && bytes[9] == the_bytes[9]
+        && bytes[10] == the_bytes[10]
+        && bytes[11] == the_bytes[11]
+        && bytes[12] == the_bytes[12]
+        && bytes[13] == the_bytes[13]
+        && bytes[14] == the_bytes[14]
+        && bytes[15] == the_bytes[15];
+
+    print_int(x as i32);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/builtin_macro_include_str.rs b/gcc/testsuite/rust/execute/torture/builtin_macro_include_str.rs
new file mode 100644
index 00000000000..6f9871d379c
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/builtin_macro_include_str.rs
@@ -0,0 +1,27 @@
+// { dg-output "hello, include!\n" }
+#[rustc_builtin_macro]
+macro_rules! include_str {
+    () => {{}};
+}
+
+extern "C" {
+    fn printf(fmt: *const i8, ...);
+}
+
+fn print(s: &str) {
+    unsafe {
+        printf(
+            "%s" as *const str as *const i8,
+            s as *const str as *const i8,
+        );
+    }
+}
+
+fn main() -> i32 {
+    // include_str! (and include_bytes!) allow for an optional trailing comma.
+    let my_str = include_str!("include.txt",);
+
+    print(my_str);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/builtin_macro_line.rs b/gcc/testsuite/rust/execute/torture/builtin_macro_line.rs
new file mode 100644
index 00000000000..02541ed52e2
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/builtin_macro_line.rs
@@ -0,0 +1,25 @@
+// { dg-output "18\n21\n" }
+extern "C" {
+    fn printf(fmt: *const i8, ...);
+}
+
+fn print(s: u32) {
+    unsafe {
+        printf("%u\n\0" as *const str as *const i8, s);
+    }
+}
+
+#[rustc_builtin_macro]
+macro_rules! line {
+    () => {{}};
+}
+
+fn main() -> i32 {
+    let a = line!();
+    print(a);
+
+    let b = line!();
+    print(b);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/builtin_macros1.rs b/gcc/testsuite/rust/execute/torture/builtin_macros1.rs
new file mode 100644
index 00000000000..5976478e426
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/builtin_macros1.rs
@@ -0,0 +1,21 @@
+// { dg-output "rust/execute/torture/builtin_macros1.rs" }
+#[rustc_builtin_macro]
+macro_rules! file {
+    () => {{}};
+}
+
+extern "C" {
+    fn printf(fmt: *const i8, ...);
+}
+
+fn print(s: &str) {
+    unsafe {
+        printf("%s\n\0" as *const str as *const i8, s);
+    }
+}
+
+fn main() -> i32 {
+    print(file!());
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/builtin_macros3.rs b/gcc/testsuite/rust/execute/torture/builtin_macros3.rs
new file mode 100644
index 00000000000..24555cbdb8a
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/builtin_macros3.rs
@@ -0,0 +1,28 @@
+// { dg-output "14\n42\n" }
+#[rustc_builtin_macro]
+macro_rules! column {
+    () => {{}};
+}
+
+extern "C" {
+    fn printf(fmt: *const i8, ...);
+}
+
+fn print(s: u32) {
+    unsafe {
+        printf("%u\n\0" as *const str as *const i8, s);
+    }
+}
+
+fn main() -> i32 {
+    let c0 = column!();
+
+    print(c0);
+
+    let c1 =                             column!();
+
+    print(c1);
+
+    0
+}
+
diff --git a/gcc/testsuite/rust/execute/torture/cfg1.rs b/gcc/testsuite/rust/execute/torture/cfg1.rs
new file mode 100644
index 00000000000..d3c56295503
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/cfg1.rs
@@ -0,0 +1,32 @@
+// { dg-additional-options "-w -frust-cfg=A" }
+// { dg-output "test1\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[cfg(A)]
+fn test() {
+    unsafe {
+        let a = "test1\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c);
+    }
+}
+
+#[cfg(B)]
+fn test() {
+    unsafe {
+        let a = "test2\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c);
+    }
+}
+
+fn main() -> i32 {
+    test();
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/cfg2.rs b/gcc/testsuite/rust/execute/torture/cfg2.rs
new file mode 100644
index 00000000000..5048bcb2791
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/cfg2.rs
@@ -0,0 +1,31 @@
+// { dg-additional-options "-w -frust-cfg=A" }
+// { dg-output "test1\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn test() {
+    #[cfg(A)]
+    unsafe {
+        let a = "test1\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c);
+    }
+
+    #[cfg(B)]
+    unsafe {
+        let a = "test2\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c);
+    }
+}
+
+fn main() -> i32 {
+    test();
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/cfg3.rs b/gcc/testsuite/rust/execute/torture/cfg3.rs
new file mode 100644
index 00000000000..89312344b23
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/cfg3.rs
@@ -0,0 +1,37 @@
+// { dg-additional-options "-w -frust-cfg=A" }
+// { dg-output "test1\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+struct Foo(i32);
+impl Foo {
+    #[cfg(A)]
+    fn test(&self) {
+        unsafe {
+            let a = "test1\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+    }
+
+    #[cfg(B)]
+    fn test(&self) {
+        unsafe {
+            let a = "test2\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+    }
+}
+
+fn main() -> i32 {
+    let a = Foo(123);
+    a.test();
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/cfg4.rs b/gcc/testsuite/rust/execute/torture/cfg4.rs
new file mode 100644
index 00000000000..d1c2a22a0ff
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/cfg4.rs
@@ -0,0 +1,38 @@
+// { dg-additional-options "-w -frust-cfg=A" }
+// { dg-output "test1\ntest2\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+struct Foo(i32);
+impl Foo {
+    #[cfg(A)]
+    fn test(&self) {
+        unsafe {
+            let a = "test1\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+    }
+
+    #[cfg(not(B))]
+    fn test2(&self) {
+        unsafe {
+            let a = "test2\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+    }
+}
+
+fn main() -> i32 {
+    let a = Foo(123);
+    a.test();
+    a.test2();
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/cfg5.rs b/gcc/testsuite/rust/execute/torture/cfg5.rs
new file mode 100644
index 00000000000..581a29bb89d
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/cfg5.rs
@@ -0,0 +1,13 @@
+// { dg-additional-options "-w -frust-cfg=A" }
+
+fn main() -> i32 {
+    let mut a = 0;
+
+    #[cfg(A)]
+    a = 3;
+
+    #[cfg(B)]
+    a = 40;
+
+    a - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/coercion1.rs b/gcc/testsuite/rust/execute/torture/coercion1.rs
new file mode 100644
index 00000000000..2cdb9bbca38
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/coercion1.rs
@@ -0,0 +1,41 @@
+/* { dg-output "123\n123\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+struct Foo(i32);
+trait Bar {
+    fn baz(&self);
+}
+
+impl Bar for Foo {
+    fn baz(&self) {
+        unsafe {
+            let a = "%i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, self.0);
+        }
+    }
+}
+
+fn static_dispatch<T: Bar>(t: &T) {
+    t.baz();
+}
+
+fn dynamic_dispatch(t: &dyn Bar) {
+    t.baz();
+}
+
+fn main() -> i32 {
+    let a;
+    a = Foo(123);
+    static_dispatch(&a);
+
+    let b: &dyn Bar;
+    b = &a;
+    dynamic_dispatch(b);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/coercion2.rs b/gcc/testsuite/rust/execute/torture/coercion2.rs
new file mode 100644
index 00000000000..12dd68ff5f7
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/coercion2.rs
@@ -0,0 +1,39 @@
+/* { dg-output "123\n123\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+struct Foo(i32);
+trait Bar {
+    fn baz(&self);
+}
+
+impl Bar for Foo {
+    fn baz(&self) {
+        unsafe {
+            let a = "%i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, self.0);
+        }
+    }
+}
+
+fn static_dispatch<T: Bar>(t: &T) {
+    t.baz();
+}
+
+fn dynamic_dispatch(t: &dyn Bar) {
+    t.baz();
+}
+
+fn main() -> i32 {
+    let a;
+    a = &Foo(123);
+
+    static_dispatch(a);
+    dynamic_dispatch(a);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/const_fold1.rs b/gcc/testsuite/rust/execute/torture/const_fold1.rs
new file mode 100644
index 00000000000..3cd6c0c77b5
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/const_fold1.rs
@@ -0,0 +1,13 @@
+// { dg-additional-options "-w" }
+const fn const_fn() -> usize {
+    4
+}
+
+const FN_TEST: usize = const_fn();
+
+const TEST: usize = 2 + FN_TEST;
+
+fn main() -> i32 {
+    let a: [_; 12] = [5; TEST * 2];
+    a[6] - 5
+}
diff --git a/gcc/testsuite/rust/execute/torture/const_fold2.rs b/gcc/testsuite/rust/execute/torture/const_fold2.rs
new file mode 100644
index 00000000000..c525648fe0b
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/const_fold2.rs
@@ -0,0 +1,16 @@
+// { dg-additional-options "-w" }
+const A: i32 = 1;
+const B: i32 = { A + 2 };
+
+const fn test() -> i32 {
+    B
+}
+
+const C: i32 = {
+    const a: i32 = 4;
+    test() + a
+};
+
+fn main() -> i32 {
+    C - 7
+}
diff --git a/gcc/testsuite/rust/execute/torture/copy_nonoverlapping1.rs b/gcc/testsuite/rust/execute/torture/copy_nonoverlapping1.rs
new file mode 100644
index 00000000000..2ae7a0869e3
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/copy_nonoverlapping1.rs
@@ -0,0 +1,17 @@
+extern "rust-intrinsic" {
+    pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+}
+
+fn main() -> i32 {
+    let i = 15;
+    let mut i_copy = 16;
+
+    let i = &i as *const i32;
+    let i_copy = &mut i_copy as *mut i32;
+
+    unsafe {
+        copy_nonoverlapping(i, i_copy, 1);
+
+        *i_copy - *i
+    }
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/execute/torture/empty_main.rs b/gcc/testsuite/rust/execute/torture/empty_main.rs
new file mode 100644
index 00000000000..6442e1e4e83
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/empty_main.rs
@@ -0,0 +1,3 @@
+fn main() -> i32 {
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/execute.exp b/gcc/testsuite/rust/execute/torture/execute.exp
new file mode 100644
index 00000000000..6dfb6d2b446
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/execute.exp
@@ -0,0 +1,33 @@
+# Copyright (C) 2021-2022 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/>.
+
+# Execute tests, torture testing.
+
+# Load support procs.
+load_lib rust-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+set saved-dg-do-what-default ${dg-do-what-default}
+
+set dg-do-what-default "run"
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.rs]] "" ""
+set dg-do-what-default ${saved-dg-do-what-default}
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/rust/execute/torture/exit_error.rs b/gcc/testsuite/rust/execute/torture/exit_error.rs
new file mode 100644
index 00000000000..c3d0d9f2480
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/exit_error.rs
@@ -0,0 +1,5 @@
+// { dg-xfail-run-if "" { *-*-* } }
+
+fn main() -> i32 {
+    1
+}
diff --git a/gcc/testsuite/rust/execute/torture/extern_mod4.rs b/gcc/testsuite/rust/execute/torture/extern_mod4.rs
new file mode 100644
index 00000000000..99b6fb5c9ba
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/extern_mod4.rs
@@ -0,0 +1,19 @@
+// { dg-additional-options "-w" }
+// { dg-output "12" }
+mod modules;
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn main() -> i32 {
+    unsafe {
+        let fmt_s = "%d\n\0";
+        let fmt_p = fmt_s as *const str;
+        let fmt_i8 = fmt_p as *const i8;
+
+        printf(fmt_i8, modules::return_12());
+    }
+
+    return 0;
+}
diff --git a/gcc/testsuite/rust/execute/torture/func1.rs b/gcc/testsuite/rust/execute/torture/func1.rs
new file mode 100644
index 00000000000..0a093d88587
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/func1.rs
@@ -0,0 +1,5 @@
+fn main() -> i32 {
+    1;
+    2;
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/helloworld1.rs b/gcc/testsuite/rust/execute/torture/helloworld1.rs
new file mode 100644
index 00000000000..d416efa33af
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/helloworld1.rs
@@ -0,0 +1,15 @@
+/* { dg-output "Hello World" }*/
+extern "C" {
+    fn puts(s: *const i8);
+}
+
+fn main() -> i32 {
+    unsafe {
+        let a = "Hello World";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        puts(c);
+    }
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/helloworld2.rs b/gcc/testsuite/rust/execute/torture/helloworld2.rs
new file mode 100644
index 00000000000..cc05f3798fa
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/helloworld2.rs
@@ -0,0 +1,15 @@
+/* { dg-output "Hello World 123\n" }*/
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn main() -> i32 {
+    unsafe {
+        let a = "Hello World %i\n";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, 123);
+    }
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/include.txt b/gcc/testsuite/rust/execute/torture/include.txt
new file mode 100644
index 00000000000..12c368778e1
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/include.txt
@@ -0,0 +1 @@
+hello, include!
diff --git a/gcc/testsuite/rust/execute/torture/index1.rs b/gcc/testsuite/rust/execute/torture/index1.rs
new file mode 100644
index 00000000000..4682978bdd0
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/index1.rs
@@ -0,0 +1,28 @@
+// { dg-additional-options "-w" }
+#[lang = "index"]
+trait Index<Idx> {
+    type Output;
+
+    fn index(&self, index: Idx) -> &Self::Output;
+}
+
+struct Foo(i32, i32);
+impl Index<isize> for Foo {
+    type Output = i32;
+
+    fn index(&self, index: isize) -> &i32 {
+        if index == 0 {
+            &self.0
+        } else {
+            &self.1
+        }
+    }
+}
+
+fn main() -> i32 {
+    let a = Foo(1, 2);
+    let b = a[0];
+    let c = a[1];
+
+    c - b - 1
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1120.rs b/gcc/testsuite/rust/execute/torture/issue-1120.rs
new file mode 100644
index 00000000000..242c94b5cb6
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-1120.rs
@@ -0,0 +1,123 @@
+// { dg-additional-options "-w" }
+extern "rust-intrinsic" {
+    #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
+    pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
+}
+
+struct FatPtr<T> {
+    data: *const T,
+    len: usize,
+}
+
+pub union Repr<T> {
+    rust: *const [T],
+    rust_mut: *mut [T],
+    raw: FatPtr<T>,
+}
+
+pub enum Option<T> {
+    None,
+    Some(T),
+}
+
+#[lang = "Range"]
+pub struct Range<Idx> {
+    pub start: Idx,
+    pub end: Idx,
+}
+
+#[lang = "const_slice_ptr"]
+impl<T> *const [T] {
+    pub const fn len(self) -> usize {
+        unsafe { Repr { rust: self }.raw.len }
+    }
+
+    pub const fn as_ptr(self) -> *const T {
+        self as *const T
+    }
+}
+
+#[lang = "const_ptr"]
+impl<T> *const T {
+    pub const unsafe fn offset(self, count: isize) -> *const T {
+        unsafe { offset(self, count) }
+    }
+
+    pub const unsafe fn add(self, count: usize) -> Self {
+        unsafe { self.offset(count as isize) }
+    }
+
+    pub const fn as_ptr(self) -> *const T {
+        self as *const T
+    }
+}
+
+const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
+    unsafe {
+        Repr {
+            raw: FatPtr { data, len },
+        }
+        .rust
+    }
+}
+
+#[lang = "index"]
+trait Index<Idx> {
+    type Output;
+
+    fn index(&self, index: Idx) -> &Self::Output;
+}
+
+pub unsafe trait SliceIndex<T> {
+    type Output;
+
+    fn get(self, slice: &T) -> Option<&Self::Output>;
+
+    unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
+
+    fn index(self, slice: &T) -> &Self::Output;
+}
+
+unsafe impl<T> SliceIndex<[T]> for Range<usize> {
+    type Output = [T];
+
+    fn get(self, slice: &[T]) -> Option<&[T]> {
+        if self.start > self.end
+        /* || self.end > slice.len() */
+        {
+            Option::None
+        } else {
+            unsafe { Option::Some(&*self.get_unchecked(slice)) }
+        }
+    }
+
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+        unsafe {
+            let a: *const T = slice.as_ptr();
+            let b: *const T = a.add(self.start);
+            slice_from_raw_parts(b, self.end - self.start)
+        }
+    }
+
+    fn index(self, slice: &[T]) -> &[T] {
+        unsafe { &*self.get_unchecked(slice) }
+    }
+}
+
+impl<T, I> Index<I> for [T]
+where
+    I: SliceIndex<[T]>,
+{
+    type Output = I::Output;
+
+    fn index(&self, index: I) -> &I::Output {
+        index.index(self)
+    }
+}
+
+fn main() -> i32 {
+    let a = [1, 2, 3, 4, 5];
+    let b = &a[1..3];
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1133.rs b/gcc/testsuite/rust/execute/torture/issue-1133.rs
new file mode 100644
index 00000000000..f2080a6e072
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-1133.rs
@@ -0,0 +1,146 @@
+// { dg-additional-options "-w" }
+extern "rust-intrinsic" {
+    #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
+    pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
+}
+
+struct FatPtr<T> {
+    data: *const T,
+    len: usize,
+}
+
+pub union Repr<T> {
+    rust: *const [T],
+    rust_mut: *mut [T],
+    raw: FatPtr<T>,
+}
+
+pub enum Option<T> {
+    None,
+    Some(T),
+}
+
+#[lang = "Range"]
+pub struct Range<Idx> {
+    pub start: Idx,
+    pub end: Idx,
+}
+
+#[lang = "const_slice_ptr"]
+impl<T> *const [T] {
+    pub const fn len(self) -> usize {
+        unsafe { Repr { rust: self }.raw.len }
+    }
+
+    pub const fn as_ptr(self) -> *const T {
+        self as *const T
+    }
+}
+
+#[lang = "const_ptr"]
+impl<T> *const T {
+    pub const unsafe fn offset(self, count: isize) -> *const T {
+        unsafe { offset(self, count) }
+    }
+
+    pub const unsafe fn add(self, count: usize) -> Self {
+        unsafe { self.offset(count as isize) }
+    }
+
+    pub const fn as_ptr(self) -> *const T {
+        self as *const T
+    }
+}
+
+const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
+    unsafe {
+        Repr {
+            raw: FatPtr { data, len },
+        }
+        .rust
+    }
+}
+
+#[lang = "index"]
+trait Index<Idx> {
+    type Output;
+
+    fn index(&self, index: Idx) -> &Self::Output;
+}
+
+pub unsafe trait SliceIndex<T> {
+    type Output;
+
+    fn get(self, slice: &T) -> Option<&Self::Output>;
+
+    unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
+
+    fn index(self, slice: &T) -> &Self::Output;
+}
+
+unsafe impl<T> SliceIndex<[T]> for usize {
+    type Output = T;
+
+    fn get(self, slice: &[T]) -> Option<&T> {
+        unsafe { Option::Some(&*self.get_unchecked(slice)) }
+    }
+
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
+        // SAFETY: the caller guarantees that `slice` is not dangling, so it
+        // cannot be longer than `isize::MAX`. They also guarantee that
+        // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
+        // so the call to `add` is safe.
+        unsafe { slice.as_ptr().add(self) }
+    }
+
+    fn index(self, slice: &[T]) -> &T {
+        // N.B., use intrinsic indexing
+        // &(*slice)[self]
+        unsafe { &*self.get_unchecked(slice) }
+    }
+}
+
+unsafe impl<T> SliceIndex<[T]> for Range<usize> {
+    type Output = [T];
+
+    fn get(self, slice: &[T]) -> Option<&[T]> {
+        if self.start > self.end
+        /* || self.end > slice.len() */
+        {
+            Option::None
+        } else {
+            unsafe { Option::Some(&*self.get_unchecked(slice)) }
+        }
+    }
+
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+        unsafe {
+            let a: *const T = slice.as_ptr();
+            let b: *const T = a.add(self.start);
+            slice_from_raw_parts(b, self.end - self.start)
+        }
+    }
+
+    fn index(self, slice: &[T]) -> &[T] {
+        unsafe { &*self.get_unchecked(slice) }
+    }
+}
+
+impl<T, I> Index<I> for [T]
+where
+    I: SliceIndex<[T]>,
+{
+    type Output = I::Output;
+
+    fn index(&self, index: I) -> &I::Output {
+        index.index(self)
+    }
+}
+
+fn main() -> i32 {
+    let a = [1, 2, 3, 4, 5];
+    let b = &a[1..3];
+    let c = b[1];
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1198.rs b/gcc/testsuite/rust/execute/torture/issue-1198.rs
new file mode 100644
index 00000000000..fce44ad1994
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-1198.rs
@@ -0,0 +1,75 @@
+/* { dg-output "foo_deref\nimm_deref\n123\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "deref"]
+pub trait Deref {
+    type Target;
+
+    fn deref(&self) -> &Self::Target;
+}
+
+impl<T> Deref for &T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe {
+            let a = "imm_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        *self
+    }
+}
+
+impl<T> Deref for &mut T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe {
+            let a = "mut_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        *self
+    }
+}
+
+struct Foo<T>(T);
+impl<T> Deref for Foo<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        unsafe {
+            let a = "foo_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        &self.0
+    }
+}
+
+fn main() -> i32 {
+    let foo: Foo<i32> = Foo(123);
+    let bar: &i32 = &foo;
+
+    unsafe {
+        let a = "%i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, *bar);
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1231.rs b/gcc/testsuite/rust/execute/torture/issue-1231.rs
new file mode 100644
index 00000000000..970e86f917a
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-1231.rs
@@ -0,0 +1,36 @@
+// { dg-additional-options "-w" }
+// { dg-output "outer\ninner\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn machin() {
+    unsafe {
+        let a = "outer\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, 123);
+    }
+}
+
+fn bidule() {
+    fn machin() {
+        unsafe {
+            let a = "inner\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, 123);
+        }
+    }
+
+    self::machin();
+    machin();
+}
+
+fn main() -> i32 {
+    bidule();
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1232.rs b/gcc/testsuite/rust/execute/torture/issue-1232.rs
new file mode 100644
index 00000000000..c56d5c18695
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-1232.rs
@@ -0,0 +1,159 @@
+// { dg-additional-options "-w" }
+// { dg-output "slice_access=3\n" }
+extern "rust-intrinsic" {
+    #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
+    fn offset<T>(dst: *const T, offset: isize) -> *const T;
+}
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+struct FatPtr<T> {
+    data: *const T,
+    len: usize,
+}
+
+pub union Repr<T> {
+    rust: *const [T],
+    rust_mut: *mut [T],
+    raw: FatPtr<T>,
+}
+
+pub enum Option<T> {
+    None,
+    Some(T),
+}
+
+#[lang = "Range"]
+pub struct Range<Idx> {
+    pub start: Idx,
+    pub end: Idx,
+}
+
+#[lang = "const_slice_ptr"]
+impl<T> *const [T] {
+    pub const fn len(self) -> usize {
+        unsafe { Repr { rust: self }.raw.len }
+    }
+
+    pub const fn as_ptr(self) -> *const T {
+        self as *const T
+    }
+}
+
+#[lang = "const_ptr"]
+impl<T> *const T {
+    pub const unsafe fn offset(self, count: isize) -> *const T {
+        unsafe { offset(self, count) }
+    }
+
+    pub const unsafe fn add(self, count: usize) -> Self {
+        unsafe { self.offset(count as isize) }
+    }
+
+    pub const fn as_ptr(self) -> *const T {
+        self as *const T
+    }
+}
+
+const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
+    unsafe {
+        Repr {
+            raw: FatPtr { data, len },
+        }
+        .rust
+    }
+}
+
+#[lang = "index"]
+trait Index<Idx> {
+    type Output;
+
+    fn index(&self, index: Idx) -> &Self::Output;
+}
+
+pub unsafe trait SliceIndex<T> {
+    type Output;
+
+    fn get(self, slice: &T) -> Option<&Self::Output>;
+
+    unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
+
+    fn index(self, slice: &T) -> &Self::Output;
+}
+
+unsafe impl<T> SliceIndex<[T]> for usize {
+    type Output = T;
+
+    fn get(self, slice: &[T]) -> Option<&T> {
+        unsafe { Option::Some(&*self.get_unchecked(slice)) }
+    }
+
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
+        // SAFETY: the caller guarantees that `slice` is not dangling, so it
+        // cannot be longer than `isize::MAX`. They also guarantee that
+        // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
+        // so the call to `add` is safe.
+        unsafe { slice.as_ptr().add(self) }
+    }
+
+    fn index(self, slice: &[T]) -> &T {
+        // N.B., use intrinsic indexing
+        // &(*slice)[self]
+        unsafe { &*self.get_unchecked(slice) }
+    }
+}
+
+unsafe impl<T> SliceIndex<[T]> for Range<usize> {
+    type Output = [T];
+
+    fn get(self, slice: &[T]) -> Option<&[T]> {
+        if self.start > self.end
+        /* || self.end > slice.len() */
+        {
+            Option::None
+        } else {
+            unsafe { Option::Some(&*self.get_unchecked(slice)) }
+        }
+    }
+
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+        unsafe {
+            let a: *const T = slice.as_ptr();
+            let b: *const T = a.add(self.start);
+            slice_from_raw_parts(b, self.end - self.start)
+        }
+    }
+
+    fn index(self, slice: &[T]) -> &[T] {
+        unsafe { &*self.get_unchecked(slice) }
+    }
+}
+
+impl<T, I> Index<I> for [T]
+where
+    I: SliceIndex<[T]>,
+{
+    type Output = I::Output;
+
+    fn index(&self, index: I) -> &I::Output {
+        index.index(self)
+    }
+}
+
+fn main() -> i32 {
+    let array = [1, 2, 3, 4, 5];
+    let slice = &array[1..3];
+    let slice_access = slice[1];
+
+    unsafe {
+        let a = "slice_access=%i\n";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, slice_access);
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1249.rs b/gcc/testsuite/rust/execute/torture/issue-1249.rs
new file mode 100644
index 00000000000..072204ea877
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-1249.rs
@@ -0,0 +1,39 @@
+// { dg-options "-w" }
+// { dg-output "1\n2\n" }
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+trait T {
+    fn foo(&self);
+}
+
+impl dyn T {
+    fn bar(&self) {
+        unsafe {
+            let a = "1\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            printf(c);
+        }
+        self.foo()
+    }
+}
+
+struct S;
+impl T for S {
+    fn foo(&self) {
+        unsafe {
+            let a = "2\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            printf(c);
+        }
+    }
+}
+
+pub fn main() -> i32 {
+    <dyn T>::bar(&S);
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1436.rs b/gcc/testsuite/rust/execute/torture/issue-1436.rs
new file mode 100644
index 00000000000..5c079a61f07
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-1436.rs
@@ -0,0 +1,172 @@
+// { dg-options "-w" }
+// { dg-output "" }
+mod intrinsics {
+    extern "rust-intrinsic" {
+        #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
+        pub fn offset<T>(ptr: *const T, count: isize) -> *const T;
+    }
+}
+
+mod mem {
+    extern "rust-intrinsic" {
+        fn size_of<T>() -> usize;
+    }
+}
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+struct FatPtr<T> {
+    data: *const T,
+    len: usize,
+}
+
+pub union Repr<T> {
+    rust: *const [T],
+    rust_mut: *mut [T],
+    raw: FatPtr<T>,
+}
+
+pub enum Option<T> {
+    None,
+    Some(T),
+}
+
+#[lang = "Range"]
+pub struct Range<Idx> {
+    pub start: Idx,
+    pub end: Idx,
+}
+
+#[lang = "const_slice_ptr"]
+impl<T> *const [T] {
+    pub const fn len(self) -> usize {
+        unsafe { Repr { rust: self }.raw.len }
+    }
+
+    pub const fn as_ptr(self) -> *const T {
+        self as *const T
+    }
+}
+
+#[lang = "const_ptr"]
+impl<T> *const T {
+    pub const unsafe fn offset(self, count: isize) -> *const T {
+        unsafe { intrinsics::offset(self, count) }
+    }
+
+    pub const unsafe fn add(self, count: usize) -> Self {
+        unsafe { self.offset(count as isize) }
+    }
+
+    pub const fn as_ptr(self) -> *const T {
+        self as *const T
+    }
+}
+
+const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
+    unsafe {
+        Repr {
+            raw: FatPtr { data, len },
+        }
+        .rust
+    }
+}
+
+#[lang = "index"]
+trait Index<Idx> {
+    type Output;
+
+    fn index(&self, index: Idx) -> &Self::Output;
+}
+
+impl<T> [T] {
+    pub const fn is_empty(&self) -> bool {
+        self.len() == 0
+    }
+
+    pub const fn len(&self) -> usize {
+        unsafe { Repr { rust: self }.raw.len }
+    }
+}
+
+pub unsafe trait SliceIndex<T> {
+    type Output;
+
+    fn get(self, slice: &T) -> Option<&Self::Output>;
+
+    unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
+
+    fn index(self, slice: &T) -> &Self::Output;
+}
+
+unsafe impl<T> SliceIndex<[T]> for usize {
+    type Output = T;
+
+    fn get(self, slice: &[T]) -> Option<&T> {
+        unsafe { Option::Some(&*self.get_unchecked(slice)) }
+    }
+
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
+        // SAFETY: the caller guarantees that `slice` is not dangling, so it
+        // cannot be longer than `isize::MAX`. They also guarantee that
+        // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
+        // so the call to `add` is safe.
+        unsafe { slice.as_ptr().add(self) }
+    }
+
+    fn index(self, slice: &[T]) -> &T {
+        unsafe { &*self.get_unchecked(slice) }
+    }
+}
+
+unsafe impl<T> SliceIndex<[T]> for Range<usize> {
+    type Output = [T];
+
+    fn get(self, slice: &[T]) -> Option<&[T]> {
+        if self.start > self.end || self.end > slice.len() {
+            Option::None
+        } else {
+            unsafe { Option::Some(&*self.get_unchecked(slice)) }
+        }
+    }
+
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+        unsafe {
+            let a: *const T = slice.as_ptr();
+            let b: *const T = a.add(self.start);
+            slice_from_raw_parts(b, self.end - self.start)
+        }
+    }
+
+    fn index(self, slice: &[T]) -> &[T] {
+        unsafe { &*self.get_unchecked(slice) }
+    }
+}
+
+impl<T, I> Index<I> for [T]
+where
+    I: SliceIndex<[T]>,
+{
+    type Output = I::Output;
+
+    fn index(&self, index: I) -> &I::Output {
+        unsafe {
+            let a = "slice-index\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        index.index(self)
+    }
+}
+
+fn main() -> i32 {
+    let a = [1, 2, 3, 4, 5];
+    let b = a[1];
+
+    b - 2
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1496.rs b/gcc/testsuite/rust/execute/torture/issue-1496.rs
new file mode 100644
index 00000000000..9f08b2ae98a
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-1496.rs
@@ -0,0 +1,75 @@
+/* { dg-output "foo_deref\nimm_deref\n123\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "deref"]
+pub trait Deref {
+    type Target;
+
+    fn deref(&self) -> &Self::Target;
+}
+
+impl<T> Deref for &T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe {
+            let a = "imm_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        *self
+    }
+}
+
+impl<T> Deref for &mut T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe {
+            let a = "mut_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        *self
+    }
+}
+
+struct Foo<T>(T);
+impl<T> Deref for Foo<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        unsafe {
+            let a = "foo_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        &self.0
+    }
+}
+
+fn main() -> i32 {
+    let foo = Foo(123);
+    let bar = &foo as &i32;
+
+    unsafe {
+        let a = "%i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, *bar);
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-647.rs b/gcc/testsuite/rust/execute/torture/issue-647.rs
new file mode 100644
index 00000000000..3f427ccb785
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-647.rs
@@ -0,0 +1,33 @@
+/* { dg-output "Hello World 123\n" }*/
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+struct Foo<T>(T);
+
+struct Bar<T> {
+    a: Foo<T>,
+    b: bool,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+fn test<T>(a: Bar<T>) -> Foo<T> {
+    a.a
+}
+
+fn main() -> i32 {
+    let a: Bar<i32> = Bar::<i32> {
+        a: Foo::<i32>(123),
+        b: true,
+    };
+    let result: Foo<i32> = test(a);
+
+    unsafe {
+        let a = "Hello World %i\n";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, result.0);
+    }
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-845.rs b/gcc/testsuite/rust/execute/torture/issue-845.rs
new file mode 100644
index 00000000000..4c689e3b6c8
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-845.rs
@@ -0,0 +1,47 @@
+// { dg-output "Foo::bar\n" }
+// { dg-additional-options "-w" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+struct Foo {}
+
+trait Bar {
+    fn bar(&self) {
+        unsafe {
+            let _a = "Bar::bar\n\0";
+            let _b = _a as *const str;
+            let _c = _b as *const i8;
+            printf(_c);
+        }
+    }
+}
+
+impl Foo {
+    fn bar(&self) {
+        unsafe {
+            let _a = "Foo::bar\n\0";
+            let _b = _a as *const str;
+            let _c = _b as *const i8;
+            printf(_c);
+        }
+    }
+}
+
+impl Bar for Foo {
+    fn bar(&self) {
+        unsafe {
+            let _a = "<Bar as Foo>::bar\n\0";
+            let _b = _a as *const str;
+            let _c = _b as *const i8;
+            printf(_c);
+        }
+    }
+}
+
+pub fn main() -> i32 {
+    let mut f = Foo {};
+    f.bar();
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-851.rs b/gcc/testsuite/rust/execute/torture/issue-851.rs
new file mode 100644
index 00000000000..3881c7a2ada
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-851.rs
@@ -0,0 +1,35 @@
+/* { dg-output "Result: 123\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+enum Foo<T> {
+    A,
+    B(T),
+}
+
+fn inspect(a: Foo<i32>) {
+    match a {
+        Foo::A => unsafe {
+            let a = "A\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        },
+        Foo::B(x) => unsafe {
+            let a = "Result: %i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, x);
+        },
+    }
+}
+
+fn main() -> i32 {
+    let a = Foo::B(123);
+    inspect(a);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-858.rs b/gcc/testsuite/rust/execute/torture/issue-858.rs
new file mode 100644
index 00000000000..5a43f3e1b1a
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-858.rs
@@ -0,0 +1,32 @@
+/* { dg-output "Result: 123\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+enum Foo<T> {
+    A,
+    B(T),
+}
+
+fn main() -> i32 {
+    let result = Foo::B(123);
+
+    match result {
+        Foo::A => unsafe {
+            let a = "A\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        },
+        Foo::B(x) => unsafe {
+            let a = "Result: %i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, x);
+        },
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-976.rs b/gcc/testsuite/rust/execute/torture/issue-976.rs
new file mode 100644
index 00000000000..42cf596fb7d
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-976.rs
@@ -0,0 +1,14 @@
+/* { dg-output "hi" } */
+fn main() -> i32 {
+    {
+        extern "C" {
+            fn puts(s: *const i8);
+        }
+
+        unsafe {
+            puts("hi\0" as *const str as *const i8);
+        }
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-995.rs b/gcc/testsuite/rust/execute/torture/issue-995.rs
new file mode 100644
index 00000000000..42570e33f74
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-995.rs
@@ -0,0 +1,9 @@
+struct Pattern(i32);
+
+fn pattern_as_arg(Pattern(value): Pattern) -> i32 {
+    value
+}
+
+fn main() -> i32 {
+    pattern_as_arg(Pattern(15)) - 15
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros1.rs b/gcc/testsuite/rust/execute/torture/macros1.rs
new file mode 100644
index 00000000000..652d2d8fe5b
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros1.rs
@@ -0,0 +1,13 @@
+macro_rules! add {
+    ($a:expr,$b:expr) => {
+        $a + $b
+    };
+}
+
+fn test() -> i32 {
+    add!(1 + 2, 3)
+}
+
+fn main() -> i32 {
+    test() - 6
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros10.rs b/gcc/testsuite/rust/execute/torture/macros10.rs
new file mode 100644
index 00000000000..155a440ee04
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros10.rs
@@ -0,0 +1,22 @@
+// { dg-output "18\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn print_int(value: i32) {
+    let s = "%d\n\0" as *const str as *const i8;
+    unsafe {
+        printf(s, value);
+    }
+}
+
+macro_rules! add_exprs {
+    ($($e:expr)*) => (0 $(+ $e)*)
+}
+
+fn main() -> i32 {
+    // 1 + 2 + 15 => 18
+    print_int(add_exprs!(1 2 15));
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros11.rs b/gcc/testsuite/rust/execute/torture/macros11.rs
new file mode 100644
index 00000000000..5bde97d3dd4
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros11.rs
@@ -0,0 +1,25 @@
+// { dg-output "2" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn print_int(value: i32) {
+    let s = "%d\n\0";
+    let s_p = s as *const str;
+    let c_p = s_p as *const i8;
+    unsafe {
+        printf(c_p, value);
+    }
+}
+
+macro_rules! add_exprs {
+    ($($e:expr)?) => (0 $(+ $e)?)
+}
+
+fn main() -> i32 {
+    // 2
+    let a = add_exprs!(2);
+    print_int(a);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros12.rs b/gcc/testsuite/rust/execute/torture/macros12.rs
new file mode 100644
index 00000000000..d310dff9ba8
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros12.rs
@@ -0,0 +1,22 @@
+// { dg-output "0\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn print_int(value: i32) {
+    let s = "%d\n\0" as *const str as *const i8;
+    unsafe {
+        printf(s, value);
+    }
+}
+
+macro_rules! add_exprs {
+    ($($e:expr)?) => (0 $(+ $e)?)
+}
+
+fn main() -> i32 {
+    // 0
+    print_int(add_exprs!());
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros13.rs b/gcc/testsuite/rust/execute/torture/macros13.rs
new file mode 100644
index 00000000000..afb20264625
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros13.rs
@@ -0,0 +1,22 @@
+// { dg-output "18\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn print_int(value: i32) {
+    let s = "%d\n\0" as *const str as *const i8;
+    unsafe {
+        printf(s, value);
+    }
+}
+
+macro_rules! add_exprs {
+    ($($e:expr)+) => (0 $(+ $e)+)
+}
+
+fn main() -> i32 {
+    // 1 + 2 + 15 => 18
+    print_int(add_exprs!(1 2 15));
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros14.rs b/gcc/testsuite/rust/execute/torture/macros14.rs
new file mode 100644
index 00000000000..00656546d4c
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros14.rs
@@ -0,0 +1,22 @@
+// { dg-output "15\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn print_int(value: i32) {
+    let s = "%d\n\0" as *const str as *const i8;
+    unsafe {
+        printf(s, value);
+    }
+}
+
+macro_rules! add_exprs {
+    ($($e:expr)*) => (15 $(+ $e)*)
+}
+
+fn main() -> i32 {
+    // 15
+    print_int(add_exprs!());
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros16.rs b/gcc/testsuite/rust/execute/torture/macros16.rs
new file mode 100644
index 00000000000..47ab2411c0d
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros16.rs
@@ -0,0 +1,14 @@
+macro_rules! add {
+    ($e:literal) => {
+        0 + $e
+    };
+    ($e:literal $($es:literal)*) => {
+        $e + add!($($es)*)
+    };
+}
+
+fn main() -> i32 {
+    let a = add!(1 2 3 10); // 16
+
+    a - 16
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros17.rs b/gcc/testsuite/rust/execute/torture/macros17.rs
new file mode 100644
index 00000000000..390352ec47f
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros17.rs
@@ -0,0 +1,17 @@
+macro_rules! two {
+    (2) => {
+        3
+    };
+}
+
+macro_rules! one {
+    (1) => {{
+        two!(2)
+    }};
+}
+
+fn main() -> i32 {
+    let a = one!(1);
+
+    a - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros18.rs b/gcc/testsuite/rust/execute/torture/macros18.rs
new file mode 100644
index 00000000000..61df17e9da5
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros18.rs
@@ -0,0 +1,14 @@
+macro_rules! add {
+    ($e:literal) => {
+        0 + $e
+    };
+    ($e:literal $($es:literal)*) => {
+        $e + add!($($es)*)
+    };
+}
+
+fn main() -> i32 {
+    let a = add!(3 4); // 7
+
+    a - 7
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros19.rs b/gcc/testsuite/rust/execute/torture/macros19.rs
new file mode 100644
index 00000000000..4732545410e
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros19.rs
@@ -0,0 +1,14 @@
+macro_rules! add {
+    ($e:expr, $($es:expr),*) => {
+        $e + add!($($es),*)
+    };
+    ($e:expr) => {
+        $e
+    };
+}
+
+fn main() -> i32 {
+    let a = add!(15, 2, 9); // 26
+
+    a - 26
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros2.rs b/gcc/testsuite/rust/execute/torture/macros2.rs
new file mode 100644
index 00000000000..ba5098710ea
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros2.rs
@@ -0,0 +1,40 @@
+// { dg-output "arg\narg\narg\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn f() {
+    unsafe {
+        let r_s = "arg\n\0";
+        let s_p = r_s as *const str;
+        let c_p = s_p as *const i8;
+
+        printf(c_p);
+    }
+}
+
+macro_rules! kw0 {
+    (keyword) => {
+        f();
+    };
+}
+
+macro_rules! kw1 {
+    (fn) => {
+        f();
+    };
+}
+
+macro_rules! kw2 {
+    (kw0 kw1 kw3) => {
+        f();
+    };
+}
+
+fn main() -> i32 {
+    kw0!(keyword);
+    kw1!(fn);
+    kw2!(kw0 kw1 kw3);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros20.rs b/gcc/testsuite/rust/execute/torture/macros20.rs
new file mode 100644
index 00000000000..97317a0879e
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros20.rs
@@ -0,0 +1,14 @@
+macro_rules! add {
+    ($e:expr , $($es:expr) , *) => {
+        $e + add!($($es) , *)
+    };
+    ($e:expr) => {
+        $e
+    };
+}
+
+fn main() -> i32 {
+    let a = add!(15, 2, 9); // 26
+
+    a - 26
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros21.rs b/gcc/testsuite/rust/execute/torture/macros21.rs
new file mode 100644
index 00000000000..2508be1a6fd
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros21.rs
@@ -0,0 +1,15 @@
+macro_rules! add_parens {
+    ($($rep:ident ( ) )*) => {
+        { 0 $(+ $rep ( ))* }
+    };
+}
+
+fn f() -> i32 {
+    1
+}
+
+fn main() -> i32 {
+    let a = add_parens!(f() f() f());
+
+    a - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros22.rs b/gcc/testsuite/rust/execute/torture/macros22.rs
new file mode 100644
index 00000000000..3f291ace98e
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros22.rs
@@ -0,0 +1,27 @@
+// { dg-output "1\n2\nNaN\n3\n" }
+
+macro_rules! print_num {
+    ($l:literal) => {{
+        unsafe {
+            printf("%d\n\0" as *const str as *const i8, $l);
+        }
+    }};
+}
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+// Check to make sure that expanding macros does not break the flow of calls
+fn main() -> i32 {
+    print_num!(1);
+    print_num!(2);
+
+    unsafe {
+        printf("NaN\n\0" as *const str as *const i8);
+    }
+
+    print_num!(3);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros23.rs b/gcc/testsuite/rust/execute/torture/macros23.rs
new file mode 100644
index 00000000000..846352d0487
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros23.rs
@@ -0,0 +1,19 @@
+trait Valuable {
+    const VALUE: i32;
+}
+
+struct Something;
+
+macro_rules! implement {
+    () => {
+        const VALUE: i32 = 18;
+    };
+}
+
+impl Valuable for Something {
+    implement!();
+}
+
+fn main() -> i32 {
+    Something::VALUE - 18
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros24.rs b/gcc/testsuite/rust/execute/torture/macros24.rs
new file mode 100644
index 00000000000..f838a83af66
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros24.rs
@@ -0,0 +1,9 @@
+macro_rules! repeat {
+    ( $( $i:literal ),* ; $( $j:literal ),* ) => (( $( ($i,$j) ),* ))
+}
+
+fn main() -> i32 {
+    let t = repeat!(1, 1; 2, 2);
+
+    t.0 .0 + t.0 .1 + t.1 .0 + t.1 .1 - 6
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros25.rs b/gcc/testsuite/rust/execute/torture/macros25.rs
new file mode 100644
index 00000000000..c2658721bdf
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros25.rs
@@ -0,0 +1,13 @@
+macro_rules! t {
+    ($t:tt) => {
+        $t
+    };
+}
+
+fn frob() -> i32 {
+    t!(15) + t!((14))
+}
+
+fn main() -> i32 {
+    frob() - 29
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros26.rs b/gcc/testsuite/rust/execute/torture/macros26.rs
new file mode 100644
index 00000000000..30f0beef0d9
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros26.rs
@@ -0,0 +1,12 @@
+macro_rules! count_tt {
+    ($t:tt) => { 1 };
+    ($t:tt $($ts:tt)*) => { 1 + count_tt!($($ts)*) };
+}
+
+fn main() -> i32 {
+    let count = count_tt!(1 2 let a = 15) + count_tt!(1 2 (let a = 15));
+    //                    ^ ^ ^^^ ^ ^ ^^              ^ ^ ^^^^^^^^^^^^
+    //                    6 token-trees               3 token-trees
+
+    count - 9
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros27.rs b/gcc/testsuite/rust/execute/torture/macros27.rs
new file mode 100644
index 00000000000..d515bb278a0
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros27.rs
@@ -0,0 +1,24 @@
+// { dg-additional-options "-frust-cfg=A" }
+
+macro_rules! attr {
+    (#[$attr:meta] $s:stmt) => {
+        #[$attr]
+        $s;
+    };
+}
+
+fn main() -> i32 {
+    let mut a = 0;
+
+    attr! {
+    #[cfg(A)]
+        a = 3
+    };
+
+    attr! {
+    #[cfg(B)]
+        a = 40
+    };
+
+    a - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros28.rs b/gcc/testsuite/rust/execute/torture/macros28.rs
new file mode 100644
index 00000000000..b011f924149
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros28.rs
@@ -0,0 +1,13 @@
+macro_rules! t {
+    () => {
+        i32
+    };
+}
+
+fn id<T>(arg: T) -> T {
+    arg
+}
+
+fn main() -> i32 {
+    id::<t!()>(15) - 15
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros29.rs b/gcc/testsuite/rust/execute/torture/macros29.rs
new file mode 100644
index 00000000000..306979b9b5b
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros29.rs
@@ -0,0 +1,24 @@
+// { dg-output "1\n" }
+#[rustc_builtin_macro]
+macro_rules! concat {
+    () => {{}};
+}
+
+extern "C" {
+    fn printf(fmt: *const i8, ...);
+}
+
+fn print(s: u32) {
+    unsafe {
+        printf("%u\n\0" as *const str as *const i8, s);
+    }
+}
+
+fn main() -> i32 {
+    let res = concat!("test2") == "test3";
+    if !res {
+        print(1);
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros3.rs b/gcc/testsuite/rust/execute/torture/macros3.rs
new file mode 100644
index 00000000000..00f6d253f50
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros3.rs
@@ -0,0 +1,61 @@
+// { dg-output "invok\ninvok\ninvok\ninvok\ninvok\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn f() {
+    unsafe {
+        let r_s = "invok\n\0";
+        let s_p = r_s as *const str;
+        let c_p = s_p as *const i8;
+
+        printf(c_p);
+    }
+}
+
+macro_rules! invocation0 {
+    (valid) => {
+        f();
+    };
+    () => {};
+}
+
+macro_rules! invocation1 {
+    (valid) => {};
+    () => {
+        f();
+    };
+}
+
+macro_rules! invocation2 {
+    (valid) => {
+        f();
+    };
+    (invalid) => {};
+}
+
+macro_rules! invocation3 {
+    (this is a valid invocation) => {
+        f();
+    };
+    (not this one) => {};
+}
+
+macro_rules! invocation4 {
+    (fn f() {}) => {
+        f();
+    };
+    (not a keyword) => {};
+}
+
+fn main() -> i32 {
+    invocation0!(valid);
+    invocation1!();
+    invocation2!(valid);
+    invocation3!(this is a valid invocation);
+    invocation4!(
+        fn f() {}
+    );
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros30.rs b/gcc/testsuite/rust/execute/torture/macros30.rs
new file mode 100644
index 00000000000..ab36f5e78af
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros30.rs
@@ -0,0 +1,25 @@
+// { dg-output "1\n" }
+#[rustc_builtin_macro]
+macro_rules! concat {
+    () => {{}};
+}
+
+extern "C" {
+    fn printf(fmt: *const i8, ...);
+}
+
+fn print(s: u32) {
+    unsafe {
+        printf("%u\n\0" as *const str as *const i8, s);
+    }
+}
+
+fn main() -> i32 {
+    let mut x = concat!("x");
+    x = concat!("y");
+    if x == "y" {
+        print(1);
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros31.rs b/gcc/testsuite/rust/execute/torture/macros31.rs
new file mode 100644
index 00000000000..483f897a92b
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros31.rs
@@ -0,0 +1,32 @@
+// { dg-additional-options "-w -frust-cfg=A" }
+// { dg-output "A\nB\n" }
+#[rustc_builtin_macro]
+macro_rules! cfg {
+    () => {{}};
+}
+
+extern "C" {
+    fn printf(fmt: *const i8, ...);
+}
+
+fn print(s: &str) {
+    unsafe {
+        printf(
+            "%s\n" as *const str as *const i8,
+            s as *const str as *const i8,
+        );
+    }
+}
+
+fn main() -> i32 {
+    let cfg = cfg!(A) || cfg!(B);
+    if cfg {
+        print("A");
+    }
+    let cfg = cfg!(A) && cfg!(B);
+    if !cfg {
+        print("B");
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros4.rs b/gcc/testsuite/rust/execute/torture/macros4.rs
new file mode 100644
index 00000000000..3303bfa58aa
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros4.rs
@@ -0,0 +1,15 @@
+macro_rules! add {
+    ($a:expr,$b:expr) => {
+        $a + $b
+    };
+    ($a:expr) => {
+        $a
+    };
+}
+
+fn main() -> i32 {
+    let mut x = add!(1);
+    x += add!(2, 3);
+
+    x - 6
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros5.rs b/gcc/testsuite/rust/execute/torture/macros5.rs
new file mode 100644
index 00000000000..822665494a4
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros5.rs
@@ -0,0 +1,13 @@
+macro_rules! add {
+    ($a:expr,$b:expr) => {{
+        $a + $b
+    }};
+}
+
+fn test() -> i32 {
+    add!(1, 2)
+}
+
+fn main() -> i32 {
+    test() - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros6.rs b/gcc/testsuite/rust/execute/torture/macros6.rs
new file mode 100644
index 00000000000..652a765d5a8
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros6.rs
@@ -0,0 +1,12 @@
+macro_rules! Test {
+    ($a:ident, $b:ty) => {
+        struct $a($b);
+    };
+}
+
+Test!(Foo, i32);
+
+fn main() -> i32 {
+    let a = Foo(123);
+    a.0 - 123
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros7.rs b/gcc/testsuite/rust/execute/torture/macros7.rs
new file mode 100644
index 00000000000..ed1f922f581
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros7.rs
@@ -0,0 +1,28 @@
+// { dg-output "any\nany\nany\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn f() {
+    let r_s = "any\n\0";
+    let s_p = r_s as *const str;
+    let c_p = s_p as *const i8;
+
+    unsafe {
+        printf(c_p);
+    }
+}
+
+macro_rules! any {
+    ($($a:expr)*) => {
+        f();
+    };
+}
+
+fn main() -> i32 {
+    any!();
+    any!(a + b);
+    any!(a + b    14 "gcc");
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros8.rs b/gcc/testsuite/rust/execute/torture/macros8.rs
new file mode 100644
index 00000000000..a12aca4910e
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros8.rs
@@ -0,0 +1,27 @@
+// { dg-output "zo1\nzo1\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn f() {
+    let r_s = "zo1\n\0";
+    let s_p = r_s as *const str;
+    let c_p = s_p as *const i8;
+
+    unsafe {
+        printf(c_p);
+    }
+}
+
+macro_rules! zero_or_one {
+    ($($a:expr)?) => {
+        f();
+    };
+}
+
+fn main() -> i32 {
+    zero_or_one!();
+    zero_or_one!(f());
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/macros9.rs b/gcc/testsuite/rust/execute/torture/macros9.rs
new file mode 100644
index 00000000000..0e3fd24e8a9
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/macros9.rs
@@ -0,0 +1,28 @@
+// { dg-output "oom\noom\noom\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn f() {
+    let r_s = "oom\n\0";
+    let s_p = r_s as *const str;
+    let c_p = s_p as *const i8;
+
+    unsafe {
+        printf(c_p);
+    }
+}
+
+macro_rules! one_or_more {
+    ($($a:expr)+) => {
+        f();
+    };
+}
+
+fn main() -> i32 {
+    one_or_more!(f());
+    one_or_more!(f() f());
+    one_or_more!(f() f() 15 + 12);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/match1.rs b/gcc/testsuite/rust/execute/torture/match1.rs
new file mode 100644
index 00000000000..e5af512f15d
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match1.rs
@@ -0,0 +1,58 @@
+// { dg-output "Foo::A\nFoo::B\nFoo::C x\nFoo::D 20 80\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+enum Foo {
+    A,
+    B,
+    C(char),
+    D { x: i32, y: i32 },
+}
+
+fn inspect(f: Foo) {
+    match f {
+        Foo::A => unsafe {
+            let a = "Foo::A\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        },
+        Foo::B => unsafe {
+            let a = "Foo::B\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        },
+        Foo::C(x) => unsafe {
+            let a = "Foo::C %c\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, x);
+        },
+        Foo::D { x, y } => unsafe {
+            let a = "Foo::D %i %i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, x, y);
+        },
+    }
+}
+
+fn main() -> i32 {
+    let a = Foo::A;
+    let b = Foo::B;
+    let c = Foo::C('x');
+    let d = Foo::D { x: 20, y: 80 };
+
+    inspect(a);
+    inspect(b);
+    inspect(c);
+    inspect(d);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/match2.rs b/gcc/testsuite/rust/execute/torture/match2.rs
new file mode 100644
index 00000000000..02cedf29b3c
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match2.rs
@@ -0,0 +1,41 @@
+// { dg-output "123\n80\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+enum Foo {
+    C(i32),
+    D { x: i32, y: i32 },
+}
+
+fn inspect(f: Foo) -> i32 {
+    match f {
+        Foo::C(x) => x,
+        Foo::D { x, y } => y,
+    }
+}
+
+fn main() -> i32 {
+    let a = Foo::C(123);
+    let b = Foo::D { x: 20, y: 80 };
+
+    let result = inspect(a);
+    unsafe {
+        let a = "%i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, result);
+    }
+
+    let result = inspect(b);
+    unsafe {
+        let a = "%i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, result);
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/match3.rs b/gcc/testsuite/rust/execute/torture/match3.rs
new file mode 100644
index 00000000000..8cded3044df
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match3.rs
@@ -0,0 +1,51 @@
+// { dg-output "Foo::A\nwildcard\nwildcard\nFoo::D 20 80\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+enum Foo {
+    A,
+    B,
+    C(char),
+    D { x: i32, y: i32 },
+}
+
+fn inspect(f: Foo) {
+    match f {
+        Foo::A => unsafe {
+            let a = "Foo::A\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        },
+        Foo::D { x, y } => unsafe {
+            let a = "Foo::D %i %i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, x, y);
+        },
+        _ => unsafe {
+            let a = "wildcard\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        },
+    }
+}
+
+fn main() -> i32 {
+    let a = Foo::A;
+    let b = Foo::B;
+    let c = Foo::C('x');
+    let d = Foo::D { x: 20, y: 80 };
+
+    inspect(a);
+    inspect(b);
+    inspect(c);
+    inspect(d);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/match_bool1.rs b/gcc/testsuite/rust/execute/torture/match_bool1.rs
new file mode 100644
index 00000000000..101dbb58571
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match_bool1.rs
@@ -0,0 +1,49 @@
+// { dg-output "182 is more than 100\n55 is less than 100\n" }
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn foo(x: bool) -> i32 {
+    match x {
+        true => {
+            return 182;
+        }
+        false => {
+            return 55;
+        }
+    }
+}
+
+fn bar(y: i32) {
+    match y < 100 {
+        true => {
+            let a = "%i is less than 100\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            unsafe {
+                printf(c, y);
+            }
+        }
+        _ => {
+            let a = "%i is more than 100\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            unsafe {
+                printf(c, y);
+            }
+        }
+    }
+}
+
+fn main() -> i32 {
+    let a = foo(true);
+    let b = foo(false);
+
+    bar(a);
+    bar(b);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/match_byte1.rs b/gcc/testsuite/rust/execute/torture/match_byte1.rs
new file mode 100644
index 00000000000..3546cfb9d8b
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match_byte1.rs
@@ -0,0 +1,56 @@
+// { dg-output "a\nseven\nquote\nelse" }
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn foo(x: u8) {
+    match x {
+        b'a' => {
+            let a = "a\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+
+        b'\x07' => {
+            let a = "seven\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+
+        b'\'' => {
+            let a = "quote\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+
+        _ => {
+            let a = "else\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+    }
+}
+
+fn main() -> i32 {
+    let x: u8 = 7;
+
+    foo(b'a');
+    foo(x);
+    foo(b'\'');
+    foo(b'\\');
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/match_char1.rs b/gcc/testsuite/rust/execute/torture/match_char1.rs
new file mode 100644
index 00000000000..fa65876a907
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match_char1.rs
@@ -0,0 +1,56 @@
+// { dg-output "amazing\nwildcard\ncompiler\nproductivity\n" }
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn foo(x: char) {
+    match x {
+        'a' => {
+            let a = "amazing\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+
+        'c' => {
+            let a = "compiler\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+
+        'p' => {
+            let a = "productivity\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+
+        _ => {
+            let a = "wildcard\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+    }
+}
+
+fn main() -> i32 {
+    let p = 'p';
+
+    foo('a');
+    foo('b');
+    foo('c');
+    foo(p);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/match_int1.rs b/gcc/testsuite/rust/execute/torture/match_int1.rs
new file mode 100644
index 00000000000..209429added
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match_int1.rs
@@ -0,0 +1,109 @@
+// { dg-output "other!\nother!\nother!\nfifteen!\nfifteen!\nother!\nother!\nfifteen!\n" }
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn foo_i32(x: i32) {
+    match x {
+        15 => {
+            let a = "fifteen!\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+
+        _ => {
+            let a = "other!\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+    }
+}
+
+fn foo_isize(x: isize) {
+    match x {
+        15 => {
+            let a = "fifteen!\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+
+        _ => {
+            let a = "other!\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+    }
+}
+
+fn foo_u32(x: u32) {
+    match x {
+        15 => {
+            let a = "fifteen!\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+
+        _ => {
+            let a = "other!\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+    }
+}
+
+fn foo_usize(x: usize) {
+    match x {
+        15 => {
+            let a = "fifteen!\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+
+        _ => {
+            let a = "other!\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+    }
+}
+
+fn main() -> i32 {
+    let x = -2;
+    foo_i32(x);
+    foo_i32(334);
+    foo_isize(-4768);
+    foo_isize(15);
+
+    let y = 127;
+    foo_u32(15);
+    foo_u32(y);
+    foo_usize(2394);
+    foo_usize(15);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/match_loop1.rs b/gcc/testsuite/rust/execute/torture/match_loop1.rs
new file mode 100644
index 00000000000..bb6aee946f6
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match_loop1.rs
@@ -0,0 +1,56 @@
+// { dg-output "E::One\nE::Two\nbreak!\n" }
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+enum E {
+    One,
+    Two,
+    Other,
+}
+
+fn foo() {
+    let mut x = E::One;
+
+    loop {
+        match x {
+            E::One => {
+                let a = "E::One\n\0";
+                let b = a as *const str;
+                let c = b as *const i8;
+                unsafe {
+                    printf(c);
+                }
+
+                x = E::Two;
+            }
+            E::Two => {
+                let a = "E::Two\n\0";
+                let b = a as *const str;
+                let c = b as *const i8;
+                unsafe {
+                    printf(c);
+                }
+
+                x = E::Other;
+            }
+            _ => {
+                let a = "break!\n\0";
+                let b = a as *const str;
+                let c = b as *const i8;
+                unsafe {
+                    printf(c);
+                }
+
+                break;
+            }
+        }
+    }
+}
+
+fn main() -> i32 {
+    foo();
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/match_range1.rs b/gcc/testsuite/rust/execute/torture/match_range1.rs
new file mode 100644
index 00000000000..82e9e34a989
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match_range1.rs
@@ -0,0 +1,37 @@
+// { dg-output "zero to END_RANGE\nzero to END_RANGE\nelse\n" }
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+const END_RANGE: i32 = 15;
+
+fn foo(x: i32) {
+    match x {
+        0..=END_RANGE => {
+            let a = "zero to END_RANGE\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+
+        _ => {
+            let a = "else\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+    }
+}
+
+fn main() -> i32 {
+    foo(11);
+    foo(15);
+    foo(21);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/match_range2.rs b/gcc/testsuite/rust/execute/torture/match_range2.rs
new file mode 100644
index 00000000000..8153f9e1c7e
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match_range2.rs
@@ -0,0 +1,45 @@
+// { dg-output "lowercase\nuppercase\nother\n" }
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+const BIG_A: char = 'A';
+const BIG_Z: char = 'Z';
+
+fn bar(x: char) {
+    match x {
+        'a'..='z' => {
+            let a = "lowercase\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+        BIG_A..=BIG_Z => {
+            let a = "uppercase\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+        _ => {
+            let a = "other\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+            unsafe {
+                printf(c);
+            }
+        }
+    }
+}
+
+fn main() -> i32 {
+    bar('b');
+    bar('X');
+    bar('!');
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/match_tuple1.rs b/gcc/testsuite/rust/execute/torture/match_tuple1.rs
new file mode 100644
index 00000000000..cb61cc0847c
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match_tuple1.rs
@@ -0,0 +1,45 @@
+// { dg-output "x:15\ny:20\n" }
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+enum Foo {
+    A,
+    B,
+}
+
+fn inspect(f: Foo, g: u8) -> i32 {
+    match (f, g) {
+        (Foo::A, 1) => {
+            return 5;
+        }
+
+        (Foo::A, 2) => {
+            return 10;
+        }
+
+        (Foo::B, 2) => {
+            return 15;
+        }
+
+        _ => {
+            return 20;
+        }
+    }
+    return 25;
+}
+
+fn main() -> i32 {
+    let x = inspect(Foo::B, 2);
+    let y = inspect(Foo::B, 1);
+
+    unsafe {
+        printf("x:%d\n" as *const str as *const i8, x);
+    }
+    unsafe {
+        printf("y:%d\n" as *const str as *const i8, y);
+    }
+
+    y - x - 5
+}
diff --git a/gcc/testsuite/rust/execute/torture/method1.rs b/gcc/testsuite/rust/execute/torture/method1.rs
new file mode 100644
index 00000000000..6af6133939b
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/method1.rs
@@ -0,0 +1,27 @@
+/* { dg-output "124\n458" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+struct Foo(i32);
+impl Foo {
+    fn bar(&self, i: i32) {
+        unsafe {
+            let a = "%i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, self.0 + i);
+        }
+    }
+}
+
+fn main() -> i32 {
+    let a = Foo(123);
+    a.bar(1);
+
+    let b = &Foo(456);
+    b.bar(2);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/method2.rs b/gcc/testsuite/rust/execute/torture/method2.rs
new file mode 100644
index 00000000000..f532b4488c6
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/method2.rs
@@ -0,0 +1,76 @@
+// { dg-additional-options "-w" }
+// { dg-output "foo_deref\nimm_deref\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "deref"]
+pub trait Deref {
+    type Target;
+
+    fn deref(&self) -> &Self::Target;
+}
+
+impl<T> Deref for &T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe {
+            let a = "imm_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        *self
+    }
+}
+
+impl<T> Deref for &mut T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe {
+            let a = "mut_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        *self
+    }
+}
+
+struct Bar(i32);
+impl Bar {
+    fn foobar(self) -> i32 {
+        self.0
+    }
+}
+
+struct Foo<T>(T);
+impl<T> Deref for Foo<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        unsafe {
+            let a = "foo_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        &self.0
+    }
+}
+
+pub fn main() -> i32 {
+    let bar = Bar(123);
+    let foo: Foo<&Bar> = Foo(&bar);
+    let foobar: i32 = foo.foobar();
+
+    foobar - 123
+}
diff --git a/gcc/testsuite/rust/execute/torture/method3.rs b/gcc/testsuite/rust/execute/torture/method3.rs
new file mode 100644
index 00000000000..0e9e8ff42a0
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/method3.rs
@@ -0,0 +1,78 @@
+// { dg-additional-options "-w" }
+// { dg-output "mut_deref\nfoobar: 123\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "deref"]
+pub trait Deref {
+    type Target;
+
+    fn deref(&self) -> &Self::Target;
+}
+
+#[lang = "deref_mut"]
+pub trait DerefMut: Deref {
+    fn deref_mut(&mut self) -> &mut Self::Target;
+}
+
+impl<T> Deref for &T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        *self
+    }
+}
+
+impl<T> Deref for &mut T {
+    type Target = T;
+    fn deref(&self) -> &T {
+        *self
+    }
+}
+
+pub struct Bar(i32);
+impl Bar {
+    pub fn foobar(&mut self) -> i32 {
+        self.0
+    }
+}
+
+pub struct Foo<T>(T);
+impl<T> Deref for Foo<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+impl<T> DerefMut for Foo<T> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        unsafe {
+            let a = "mut_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        &mut self.0
+    }
+}
+
+pub fn main() -> i32 {
+    let bar = Bar(123);
+    let mut foo: Foo<Bar> = Foo(bar);
+    let foobar = foo.foobar();
+
+    unsafe {
+        let a = "foobar: %i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, foobar);
+    }
+
+    foobar - 123
+}
diff --git a/gcc/testsuite/rust/execute/torture/method4.rs b/gcc/testsuite/rust/execute/torture/method4.rs
new file mode 100644
index 00000000000..5c6fdfe02c3
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/method4.rs
@@ -0,0 +1,78 @@
+// { dg-additional-options "-w" }
+// { dg-output "mut_deref\nfoobar: 123\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "deref"]
+pub trait Deref {
+    type Target;
+
+    fn deref(&self) -> &Self::Target;
+}
+
+#[lang = "deref_mut"]
+pub trait DerefMut: Deref {
+    fn deref_mut(&mut self) -> &mut Self::Target;
+}
+
+impl<T> Deref for &T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        *self
+    }
+}
+
+impl<T> Deref for &mut T {
+    type Target = T;
+    fn deref(&self) -> &T {
+        *self
+    }
+}
+
+pub struct Bar(i32);
+impl Bar {
+    pub fn foobar(&mut self) -> i32 {
+        self.0
+    }
+}
+
+pub struct Foo<T>(T);
+impl<T> Deref for Foo<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+impl<T> DerefMut for Foo<T> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        unsafe {
+            let a = "mut_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        &mut self.0
+    }
+}
+
+pub fn main() -> i32 {
+    let mut bar = Bar(123);
+    let mut foo: Foo<&mut Bar> = Foo(&mut bar);
+    let foobar = foo.foobar();
+
+    unsafe {
+        let a = "foobar: %i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, foobar);
+    }
+
+    foobar - 123
+}
diff --git a/gcc/testsuite/rust/execute/torture/mod1.rs b/gcc/testsuite/rust/execute/torture/mod1.rs
new file mode 100644
index 00000000000..700393850af
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/mod1.rs
@@ -0,0 +1,21 @@
+mod A {
+    pub mod B {
+        pub mod C {
+            pub struct Foo {
+                pub f: i32,
+            }
+            impl Foo {
+                pub fn new() -> Self {
+                    Foo { f: 23i32 }
+                }
+            }
+        }
+    }
+}
+
+fn main() -> i32 {
+    let a = A::B::C::Foo::new();
+    let b = A::B::C::Foo { f: -23i32 };
+
+    a.f + b.f
+}
diff --git a/gcc/testsuite/rust/execute/torture/modules/mod.rs b/gcc/testsuite/rust/execute/torture/modules/mod.rs
new file mode 100644
index 00000000000..9020aaf4bb8
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/modules/mod.rs
@@ -0,0 +1,3 @@
+fn return_12() -> i32 {
+    12
+}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_1.rs b/gcc/testsuite/rust/execute/torture/operator_overload_1.rs
new file mode 100644
index 00000000000..5a28c5f4e93
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_1.rs
@@ -0,0 +1,36 @@
+/* { dg-output "3\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "add"]
+pub trait Add<Rhs = Self> {
+    type Output;
+
+    fn add(self, rhs: Rhs) -> Self::Output;
+}
+
+impl Add for i32 {
+    type Output = i32;
+
+    fn add(self, other: i32) -> i32 {
+        let res = self + other;
+
+        unsafe {
+            let a = "%i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, res);
+        }
+
+        res
+    }
+}
+
+fn main() -> i32 {
+    let a;
+    a = 1 + 2;
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_10.rs b/gcc/testsuite/rust/execute/torture/operator_overload_10.rs
new file mode 100644
index 00000000000..f5d45db5338
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_10.rs
@@ -0,0 +1,75 @@
+/* { dg-output "foo_deref\n123\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "deref"]
+pub trait Deref {
+    type Target;
+
+    fn deref(&self) -> &Self::Target;
+}
+
+impl<T> Deref for &T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe {
+            let a = "imm_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        *self
+    }
+}
+
+impl<T> Deref for &mut T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe {
+            let a = "mut_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        *self
+    }
+}
+
+struct Foo<T>(T);
+impl<T> Deref for Foo<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        unsafe {
+            let a = "foo_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        &self.0
+    }
+}
+
+fn main() -> i32 {
+    let foo: Foo<i32> = Foo(123);
+    let bar: i32 = *foo;
+
+    unsafe {
+        let a = "%i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, bar);
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_11.rs b/gcc/testsuite/rust/execute/torture/operator_overload_11.rs
new file mode 100644
index 00000000000..1919941c486
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_11.rs
@@ -0,0 +1,37 @@
+// { dg-output "1\n" }
+// { dg-additional-options "-w" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "bitand"]
+pub trait BitAnd<Rhs = Self> {
+    type Output;
+
+    fn bitand(self, rhs: Rhs) -> Self::Output;
+}
+
+impl BitAnd for i32 {
+    type Output = i32;
+
+    fn bitand(self, other: i32) -> i32 {
+        let res = self & other;
+
+        unsafe {
+            let a = "%i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, res);
+        }
+
+        res
+    }
+}
+
+fn main() -> i32 {
+    let a;
+    a = 1 & 1;
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_12.rs b/gcc/testsuite/rust/execute/torture/operator_overload_12.rs
new file mode 100644
index 00000000000..7433330fa31
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_12.rs
@@ -0,0 +1,31 @@
+// { dg-output "1\n" }
+// { dg-additional-options "-w" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "bitand_assign"]
+pub trait BitAndAssign<Rhs = Self> {
+    fn bitand_assign(&mut self, rhs: Rhs);
+}
+
+impl BitAndAssign for i32 {
+    fn bitand_assign(&mut self, other: i32) {
+        *self &= other;
+
+        unsafe {
+            let a = "%i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, *self);
+        }
+    }
+}
+
+fn main() -> i32 {
+    let mut a = 1;
+    a &= 1;
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_2.rs b/gcc/testsuite/rust/execute/torture/operator_overload_2.rs
new file mode 100644
index 00000000000..a577718451d
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_2.rs
@@ -0,0 +1,38 @@
+/* { dg-output "3\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "add"]
+pub trait Add<Rhs = Self> {
+    type Output;
+
+    fn add(self, rhs: Rhs) -> Self::Output;
+}
+
+struct Foo(i32);
+
+impl Add for Foo {
+    type Output = Foo;
+
+    fn add(self, other: Foo) -> Foo {
+        let res = Foo(self.0 + other.0);
+
+        unsafe {
+            let a = "%i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, res.0);
+        }
+
+        res
+    }
+}
+
+fn main() -> i32 {
+    let a;
+    a = Foo(1) + Foo(2);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_3.rs b/gcc/testsuite/rust/execute/torture/operator_overload_3.rs
new file mode 100644
index 00000000000..57f58076c3e
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_3.rs
@@ -0,0 +1,55 @@
+/* { dg-output "3\n3\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "add"]
+pub trait Add<Rhs = Self> {
+    type Output;
+
+    fn add(self, rhs: Rhs) -> Self::Output;
+}
+
+impl Add for i32 {
+    type Output = i32;
+
+    fn add(self, other: i32) -> i32 {
+        let res = self + other;
+
+        unsafe {
+            let a = "%i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, res);
+        }
+
+        res
+    }
+}
+
+struct Foo(i32);
+impl Add for Foo {
+    type Output = Foo;
+
+    fn add(self, other: Foo) -> Foo {
+        let res = Foo(self.0 + other.0);
+
+        unsafe {
+            let a = "%i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, res.0);
+        }
+
+        res
+    }
+}
+
+fn main() -> i32 {
+    let a;
+    a = Foo(1) + Foo(2);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_4.rs b/gcc/testsuite/rust/execute/torture/operator_overload_4.rs
new file mode 100644
index 00000000000..ce9887b2ead
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_4.rs
@@ -0,0 +1,33 @@
+/* { dg-output "neg\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "neg"]
+pub trait Neg {
+    type Output;
+
+    fn neg(self) -> Self::Output;
+}
+
+impl Neg for i32 {
+    type Output = i32;
+
+    fn neg(self) -> i32 {
+        unsafe {
+            let a = "neg\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+        -self
+    }
+}
+
+fn main() -> i32 {
+    let a: i32 = 1;
+    let _b = -a;
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_5.rs b/gcc/testsuite/rust/execute/torture/operator_overload_5.rs
new file mode 100644
index 00000000000..a525f743680
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_5.rs
@@ -0,0 +1,33 @@
+/* { dg-output "not\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "not"]
+pub trait Not {
+    type Output;
+
+    fn not(self) -> Self::Output;
+}
+
+impl Not for i32 {
+    type Output = i32;
+
+    fn not(self) -> i32 {
+        unsafe {
+            let a = "not\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+        !self
+    }
+}
+
+fn main() -> i32 {
+    let a: i32 = 1;
+    let _b = !a;
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_6.rs b/gcc/testsuite/rust/execute/torture/operator_overload_6.rs
new file mode 100644
index 00000000000..fbd2a8fa9d3
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_6.rs
@@ -0,0 +1,37 @@
+/* { dg-output "add_assign\n3\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "add_assign"]
+pub trait AddAssign<Rhs = Self> {
+    fn add_assign(&mut self, rhs: Rhs);
+}
+
+impl AddAssign for i32 {
+    fn add_assign(&mut self, other: i32) {
+        unsafe {
+            let a = "add_assign\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+        *self += other
+    }
+}
+
+fn main() -> i32 {
+    let mut res = 1;
+    res += 2;
+
+    unsafe {
+        let a = "%i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, res);
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_7.rs b/gcc/testsuite/rust/execute/torture/operator_overload_7.rs
new file mode 100644
index 00000000000..886a7010efc
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_7.rs
@@ -0,0 +1,42 @@
+/* { dg-output "imm_deref\n123\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "deref"]
+pub trait Deref {
+    type Target;
+
+    fn deref(&self) -> &Self::Target;
+}
+
+impl<T> Deref for &T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe {
+            let a = "imm_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        *self
+    }
+}
+
+fn main() -> i32 {
+    let foo: &i32 = &123;
+    let res: i32 = *foo;
+
+    unsafe {
+        let a = "%i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, res);
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_8.rs b/gcc/testsuite/rust/execute/torture/operator_overload_8.rs
new file mode 100644
index 00000000000..862e29a4bc6
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_8.rs
@@ -0,0 +1,58 @@
+/* { dg-output "imm_deref\n123\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "deref"]
+pub trait Deref {
+    type Target;
+
+    fn deref(&self) -> &Self::Target;
+}
+
+impl<T> Deref for &T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe {
+            let a = "imm_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        *self
+    }
+}
+
+impl<T> Deref for &mut T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe {
+            let a = "mut_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        *self
+    }
+}
+
+fn main() -> i32 {
+    let foo: &i32 = &123;
+    let res: i32 = *foo;
+
+    unsafe {
+        let a = "%i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, res);
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_9.rs b/gcc/testsuite/rust/execute/torture/operator_overload_9.rs
new file mode 100644
index 00000000000..fd972e28ab3
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_9.rs
@@ -0,0 +1,58 @@
+/* { dg-output "mut_deref\n123\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "deref"]
+pub trait Deref {
+    type Target;
+
+    fn deref(&self) -> &Self::Target;
+}
+
+impl<T> Deref for &T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe {
+            let a = "imm_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        *self
+    }
+}
+
+impl<T> Deref for &mut T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe {
+            let a = "mut_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        *self
+    }
+}
+
+fn main() -> i32 {
+    let foo = &mut 123;
+    let res: i32 = *foo;
+
+    unsafe {
+        let a = "%i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, res);
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/slice-magic.rs b/gcc/testsuite/rust/execute/torture/slice-magic.rs
new file mode 100644
index 00000000000..d1132989ddb
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/slice-magic.rs
@@ -0,0 +1,106 @@
+// { dg-additional-options "-w" }
+extern "rust-intrinsic" {
+    #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
+    pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
+}
+
+struct FatPtr<T> {
+    data: *const T,
+    len: usize,
+}
+
+union Repr<T> {
+    rust: *const [T],
+    rust_mut: *mut [T],
+    raw: FatPtr<T>,
+}
+
+#[lang = "Range"]
+pub struct Range<Idx> {
+    pub start: Idx,
+    pub end: Idx,
+}
+
+#[lang = "const_slice_ptr"]
+impl<A> *const [A] {
+    pub const fn len(self) -> usize {
+        unsafe { Repr { rust: self }.raw.len }
+    }
+
+    pub const fn as_ptr(self) -> *const A {
+        self as *const A
+    }
+}
+
+#[lang = "const_ptr"]
+impl<B> *const B {
+    pub const unsafe fn offset(self, count: isize) -> *const B {
+        unsafe { offset(self, count) }
+    }
+
+    pub const unsafe fn add(self, count: usize) -> Self {
+        unsafe { self.offset(count as isize) }
+    }
+
+    pub const fn as_ptr(self) -> *const B {
+        self as *const B
+    }
+}
+
+const fn slice_from_raw_parts<C>(data: *const C, len: usize) -> *const [C] {
+    unsafe {
+        Repr {
+            raw: FatPtr { data, len },
+        }
+        .rust
+    }
+}
+
+#[lang = "index"]
+trait Index<Idx> {
+    type Output;
+
+    fn index(&self, index: Idx) -> &Self::Output;
+}
+
+pub unsafe trait SliceIndex<X> {
+    type Output;
+
+    unsafe fn get_unchecked(self, slice: *const X) -> *const Self::Output;
+
+    fn index(self, slice: &X) -> &Self::Output;
+}
+
+unsafe impl<Y> SliceIndex<[Y]> for Range<usize> {
+    type Output = [Y];
+
+    unsafe fn get_unchecked(self, slice: *const [Y]) -> *const [Y] {
+        unsafe {
+            let a: *const Y = slice.as_ptr();
+            let b: *const Y = a.add(self.start);
+            slice_from_raw_parts(b, self.end - self.start)
+        }
+    }
+
+    fn index(self, slice: &[Y]) -> &[Y] {
+        unsafe { &*self.get_unchecked(slice) }
+    }
+}
+
+impl<T, I> Index<I> for [T]
+where
+    I: SliceIndex<[T]>,
+{
+    type Output = I::Output;
+
+    fn index(&self, index: I) -> &I::Output {
+        index.index(self)
+    }
+}
+
+fn main() -> i32 {
+    let a = [1, 2, 3, 4, 5];
+    let b = &a[1..3];
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/slice-magic2.rs b/gcc/testsuite/rust/execute/torture/slice-magic2.rs
new file mode 100644
index 00000000000..64a566185fa
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/slice-magic2.rs
@@ -0,0 +1,106 @@
+// { dg-additional-options "-w" }
+extern "rust-intrinsic" {
+    #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
+    pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
+}
+
+struct FatPtr<T> {
+    data: *const T,
+    len: usize,
+}
+
+union Repr<T> {
+    rust: *const [T],
+    rust_mut: *mut [T],
+    raw: FatPtr<T>,
+}
+
+#[lang = "Range"]
+pub struct Range<Idx> {
+    pub start: Idx,
+    pub end: Idx,
+}
+
+#[lang = "const_slice_ptr"]
+impl<T> *const [T] {
+    pub const fn len(self) -> usize {
+        unsafe { Repr { rust: self }.raw.len }
+    }
+
+    pub const fn as_ptr(self) -> *const T {
+        self as *const T
+    }
+}
+
+#[lang = "const_ptr"]
+impl<T> *const T {
+    pub const unsafe fn offset(self, count: isize) -> *const T {
+        unsafe { offset(self, count) }
+    }
+
+    pub const unsafe fn add(self, count: usize) -> Self {
+        unsafe { self.offset(count as isize) }
+    }
+
+    pub const fn as_ptr(self) -> *const T {
+        self as *const T
+    }
+}
+
+const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
+    unsafe {
+        Repr {
+            raw: FatPtr { data, len },
+        }
+        .rust
+    }
+}
+
+#[lang = "index"]
+trait Index<Idx> {
+    type Output;
+
+    fn index(&self, index: Idx) -> &Self::Output;
+}
+
+pub unsafe trait SliceIndex<T> {
+    type Output;
+
+    unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
+
+    fn index(self, slice: &T) -> &Self::Output;
+}
+
+unsafe impl<T> SliceIndex<[T]> for Range<usize> {
+    type Output = [T];
+
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+        unsafe {
+            let a: *const T = slice.as_ptr();
+            let b: *const T = a.add(self.start);
+            slice_from_raw_parts(b, self.end - self.start)
+        }
+    }
+
+    fn index(self, slice: &[T]) -> &[T] {
+        unsafe { &*self.get_unchecked(slice) }
+    }
+}
+
+impl<T, I> Index<I> for [T]
+where
+    I: SliceIndex<[T]>,
+{
+    type Output = I::Output;
+
+    fn index(&self, index: I) -> &I::Output {
+        index.index(self)
+    }
+}
+
+fn main() -> i32 {
+    let a = [1, 2, 3, 4, 5];
+    let b = &a[1..3];
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/slice1.rs b/gcc/testsuite/rust/execute/torture/slice1.rs
new file mode 100644
index 00000000000..a0488b3912c
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/slice1.rs
@@ -0,0 +1,27 @@
+// { dg-additional-options "-w" }
+struct FatPtr<T> {
+    data: *const T,
+    len: usize,
+}
+
+union Repr<T> {
+    rust: *const [T],
+    rust_mut: *mut [T],
+    raw: FatPtr<T>,
+}
+
+const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
+    unsafe {
+        let a = FatPtr { data, len };
+        let b = Repr { raw: a };
+        b.rust
+    }
+}
+
+fn main() -> i32 {
+    let a = 123;
+    let b: *const i32 = &a;
+    let c = slice_from_raw_parts(b, 1);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/str-layout1.rs b/gcc/testsuite/rust/execute/torture/str-layout1.rs
new file mode 100644
index 00000000000..80bdc2a9c9f
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/str-layout1.rs
@@ -0,0 +1,57 @@
+// { dg-additional-options "-w" }
+// { dg-output "t1sz=5 t2sz=10" }
+mod mem {
+    extern "rust-intrinsic" {
+        #[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
+        fn transmute<T, U>(_: T) -> U;
+    }
+}
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+struct FatPtr<T> {
+    data: *const T,
+    len: usize,
+}
+
+pub union Repr<T> {
+    rust: *const [T],
+    rust_mut: *mut [T],
+    raw: FatPtr<T>,
+}
+
+impl<T> [T] {
+    pub const fn len(&self) -> usize {
+        unsafe { Repr { rust: self }.raw.len }
+    }
+}
+
+impl str {
+    pub const fn len(&self) -> usize {
+        self.as_bytes().len()
+    }
+
+    pub const fn as_bytes(&self) -> &[u8] {
+        unsafe { mem::transmute(self) }
+    }
+}
+
+fn main() -> i32 {
+    let t1: &str = "TEST1";
+    let t2: &str = &"TEST_12345";
+
+    let t1sz = t1.len();
+    let t2sz = t2.len();
+
+    unsafe {
+        let a = "t1sz=%i t2sz=%i\n";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, t1sz as i32, t2sz as i32);
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/str-zero.rs b/gcc/testsuite/rust/execute/torture/str-zero.rs
new file mode 100644
index 00000000000..e7fba0d1372
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/str-zero.rs
@@ -0,0 +1,26 @@
+/* { dg-output "bar foo baz foobar\n" } */
+extern "C"
+{
+  fn printf(s: *const i8, ...);
+  fn memchr(s: *const i8, c: u8, n: usize) -> *const i8;
+}
+
+pub fn main () -> i32
+{
+  let f = "%s %s %s %s\n\0";
+  let s = "bar\0\
+           foo\
+           \x00\
+           baz\u{0000}\
+           foobar\0";
+  let cf = f as *const str as *const i8;
+  let cs = s as *const str as *const i8;
+  unsafe
+    {
+      let cs2 = memchr (cs, b'f', 5);
+      let cs3 = memchr (cs2, b'b', 5);
+      let cs4 = memchr (cs3, b'f', 5);
+      printf (cf, cs, cs2, cs3, cs4);
+    }
+  0
+}
diff --git a/gcc/testsuite/rust/execute/torture/trait1.rs b/gcc/testsuite/rust/execute/torture/trait1.rs
new file mode 100644
index 00000000000..dc3cc471c33
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait1.rs
@@ -0,0 +1,52 @@
+/* { dg-output "S::f\nT1::f\nT2::f\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+struct S;
+
+impl S {
+    fn f() {
+        unsafe {
+            let a = "S::f\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+    }
+}
+
+trait T1 {
+    fn f() {
+        unsafe {
+            let a = "T1::f\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+    }
+}
+impl T1 for S {}
+
+trait T2 {
+    fn f() {
+        unsafe {
+            let a = "T2::f\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+    }
+}
+impl T2 for S {}
+
+fn main() -> i32 {
+    S::f();
+    <S as T1>::f();
+    <S as T2>::f();
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/trait10.rs b/gcc/testsuite/rust/execute/torture/trait10.rs
new file mode 100644
index 00000000000..e581e324bbf
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait10.rs
@@ -0,0 +1,41 @@
+/* { dg-output "123\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+struct Foo(i32);
+trait Bar {
+    fn baz(&self);
+}
+
+impl Bar for Foo {
+    fn baz(&self) {
+        unsafe {
+            let a = "%i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, self.0);
+        }
+    }
+}
+
+struct S;
+impl S {
+    fn dynamic_dispatch(self, t: &dyn Bar) {
+        // { dg-warning "unused name" "" { target *-*-* } .-1 }
+        t.baz();
+    }
+}
+
+pub fn main() -> i32 {
+    let a;
+    a = &Foo(123);
+
+    let b;
+    b = S;
+
+    b.dynamic_dispatch(a);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/trait11.rs b/gcc/testsuite/rust/execute/torture/trait11.rs
new file mode 100644
index 00000000000..283c9ecd0ed
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait11.rs
@@ -0,0 +1,38 @@
+/* { dg-output "3\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+trait FnLike<A, R> {
+    fn call(&self, arg: A) -> R;
+}
+
+struct S;
+impl<'a, T> FnLike<&'a T, &'a T> for S {
+    fn call(&self, arg: &'a T) -> &'a T {
+        // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+        arg
+    }
+}
+
+fn indirect<F>(f: F)
+where
+    F: for<'a> FnLike<&'a isize, &'a isize>,
+{
+    let x = 3;
+    let y = f.call(&x);
+
+    unsafe {
+        let a = "%i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, *y);
+    }
+}
+
+fn main() -> i32 {
+    indirect(S);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/trait12.rs b/gcc/testsuite/rust/execute/torture/trait12.rs
new file mode 100644
index 00000000000..68b0a4014ad
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait12.rs
@@ -0,0 +1,38 @@
+/* { dg-output "3\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+trait FnLike<A, R> {
+    fn call(&self, arg: A) -> R;
+}
+
+type FnObject<'b> = dyn for<'a> FnLike<&'a isize, &'a isize> + 'b;
+
+struct Identity;
+
+impl<'a, T> FnLike<&'a T, &'a T> for Identity {
+    fn call(&self, arg: &'a T) -> &'a T {
+        // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+        arg
+    }
+}
+
+fn call_repeatedly(f: &FnObject) {
+    let x = 3;
+    let y = f.call(&x);
+
+    unsafe {
+        let a = "%i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, *y);
+    }
+}
+
+fn main() -> i32 {
+    call_repeatedly(&Identity);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/trait13.rs b/gcc/testsuite/rust/execute/torture/trait13.rs
new file mode 100644
index 00000000000..3071da27a6a
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait13.rs
@@ -0,0 +1,48 @@
+/* { dg-output "123\n456\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+struct Foo(i32);
+trait Bar {
+    fn baz(&self);
+
+    fn qux(&self) {
+        // { dg-warning "unused name" "" { target *-*-* } .-1 }
+        unsafe {
+            let a = "%i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, 456);
+        }
+    }
+}
+
+impl Bar for Foo {
+    fn baz(&self) {
+        unsafe {
+            let a = "%i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, self.0);
+        }
+    }
+}
+
+fn dynamic_dispatch(t: &dyn Bar) {
+    t.baz();
+    t.qux();
+}
+
+fn main() -> i32 {
+    let a;
+    a = Foo(123);
+
+    let b: &dyn Bar;
+    b = &a;
+    dynamic_dispatch(b);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/trait2.rs b/gcc/testsuite/rust/execute/torture/trait2.rs
new file mode 100644
index 00000000000..c96615fa891
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait2.rs
@@ -0,0 +1,37 @@
+/* { dg-output "Bar::A = 456\n<Foo as Bar>::A = 456\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+trait Foo {
+    const A: i32 = 123;
+}
+
+struct Bar;
+impl Foo for Bar {
+    const A: i32 = 456;
+}
+
+fn main() -> i32 {
+    let a;
+    a = Bar::A;
+
+    unsafe {
+        let _a = "Bar::A = %i\n\0";
+        let _b = _a as *const str;
+        let _c = _b as *const i8;
+        printf(_c, a);
+    }
+
+    let b;
+    b = <Bar as Foo>::A;
+
+    unsafe {
+        let _a = "<Foo as Bar>::A = %i\n\0";
+        let _b = _a as *const str;
+        let _c = _b as *const i8;
+        printf(_c, b);
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/trait3.rs b/gcc/testsuite/rust/execute/torture/trait3.rs
new file mode 100644
index 00000000000..accfa9d0a36
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait3.rs
@@ -0,0 +1,43 @@
+/* { dg-output "123, 777" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+trait A {
+    fn a() -> i32 {
+        123
+    }
+}
+
+trait B: A {
+    fn b() -> i32 {
+        <T as A>::a() + 456
+    }
+}
+
+struct T;
+// { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+
+impl A for T {
+    fn a() -> i32 {
+        321
+    }
+}
+
+struct S;
+impl A for S {}
+impl B for S {}
+
+fn main() -> i32 {
+    let aa = S::a();
+    let bb = S::b();
+
+    unsafe {
+        let a = "%i, %i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, aa, bb);
+    }
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/trait4.rs b/gcc/testsuite/rust/execute/torture/trait4.rs
new file mode 100644
index 00000000000..8c0d257cd7e
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait4.rs
@@ -0,0 +1,34 @@
+/* { dg-output "123\n" }*/
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+struct Foo(i32);
+trait Bar {
+    fn baz(&self);
+}
+
+impl Bar for Foo {
+    fn baz(&self) {
+        unsafe {
+            let a = "%i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, self.0);
+        }
+    }
+}
+
+fn type_bound<T: Bar>(t: &T) {
+    t.baz();
+}
+
+fn main() -> i32 {
+    let a;
+
+    a = &Foo(123);
+    type_bound(a);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/trait5.rs b/gcc/testsuite/rust/execute/torture/trait5.rs
new file mode 100644
index 00000000000..49f11a6085a
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait5.rs
@@ -0,0 +1,39 @@
+/* { dg-output "123\n123\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+struct Foo(i32);
+trait Bar {
+    fn baz(&self);
+}
+
+impl Bar for Foo {
+    fn baz(&self) {
+        unsafe {
+            let a = "%i\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c, self.0);
+        }
+    }
+}
+
+fn static_dispatch<T: Bar>(t: &T) {
+    t.baz();
+}
+
+fn dynamic_dispatch(t: &dyn Bar) {
+    t.baz();
+}
+
+fn main() -> i32 {
+    let a = &Foo(123);
+    static_dispatch(a);
+
+    let b: &dyn Bar = a;
+    dynamic_dispatch(b);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/trait6.rs b/gcc/testsuite/rust/execute/torture/trait6.rs
new file mode 100644
index 00000000000..c83d6666c87
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait6.rs
@@ -0,0 +1,39 @@
+/* { dg-output "123\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+pub trait Foo {
+    type A;
+
+    fn bar(self) -> Self::A;
+}
+
+struct S(i32);
+impl Foo for S {
+    type A = i32;
+
+    fn bar(self) -> Self::A {
+        self.0
+    }
+}
+
+fn test_bar<T: Foo>(x: T) -> T::A {
+    x.bar()
+}
+
+fn main() -> i32 {
+    let a;
+    a = S(123);
+
+    let bar: i32 = test_bar::<S>(a);
+    unsafe {
+        let a = "%i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, bar);
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/trait7.rs b/gcc/testsuite/rust/execute/torture/trait7.rs
new file mode 100644
index 00000000000..064f88d5de9
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait7.rs
@@ -0,0 +1,39 @@
+/* { dg-output "123\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+pub trait Foo {
+    type A;
+
+    fn bar(self) -> Self::A;
+}
+
+struct S(i32);
+impl Foo for S {
+    type A = i32;
+
+    fn bar(self) -> Self::A {
+        self.0
+    }
+}
+
+fn test_bar<T: Foo>(x: T) -> T::A {
+    x.bar()
+}
+
+fn main() -> i32 {
+    let a;
+    a = S(123);
+
+    let bar: i32 = test_bar(a);
+    unsafe {
+        let a = "%i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, bar);
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/trait8.rs b/gcc/testsuite/rust/execute/torture/trait8.rs
new file mode 100644
index 00000000000..14392ff0cca
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait8.rs
@@ -0,0 +1,39 @@
+/* { dg-output "123\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+pub trait Foo {
+    type A;
+
+    fn bar(&self) -> Self::A;
+}
+
+struct S(i32);
+impl Foo for S {
+    type A = i32;
+
+    fn bar(&self) -> Self::A {
+        self.0
+    }
+}
+
+fn test_bar<T: Foo>(x: T) -> T::A {
+    x.bar()
+}
+
+fn main() -> i32 {
+    let a;
+    a = S(123);
+
+    let bar: i32 = test_bar(a);
+    unsafe {
+        let a = "%i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, bar);
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/trait9.rs b/gcc/testsuite/rust/execute/torture/trait9.rs
new file mode 100644
index 00000000000..c0e6d36f183
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait9.rs
@@ -0,0 +1,35 @@
+/* { dg-output "3\n" } */
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+trait FnLike<A, R> {
+    fn call(&self, arg: A) -> R;
+}
+
+struct S;
+impl<T> FnLike<&T, &T> for S {
+    fn call(&self, arg: &T) -> &T {
+        // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+        arg
+    }
+}
+
+fn indirect<F: FnLike<&isize, &isize>>(f: F) {
+    let x = 3;
+    let y = f.call(&x);
+
+    unsafe {
+        let a = "%i\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c, *y);
+    }
+}
+
+fn main() -> i32 {
+    indirect(S);
+
+    0
+}
diff --git a/gcc/testsuite/rust/execute/torture/transmute1.rs b/gcc/testsuite/rust/execute/torture/transmute1.rs
new file mode 100644
index 00000000000..b9ec38ca618
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/transmute1.rs
@@ -0,0 +1,23 @@
+// { dg-additional-options "-w" }
+
+extern "rust-intrinsic" {
+    fn transmute<T, U>(value: T) -> U;
+}
+
+struct WrapI {
+    inner: i32,
+}
+
+struct WrapF {
+    inner: f32,
+}
+
+fn main() -> i32 {
+    let f = 15.4f32;
+    let f_wrap = WrapF { inner: f };
+
+    let fst = unsafe { transmute::<f32, i32>(f) };
+    let snd = unsafe { transmute::<WrapF, WrapI>(f_wrap) };
+
+    fst - snd.inner
+}
diff --git a/gcc/testsuite/rust/execute/torture/wrapping_op1.rs b/gcc/testsuite/rust/execute/torture/wrapping_op1.rs
new file mode 100644
index 00000000000..64b37085ab7
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/wrapping_op1.rs
@@ -0,0 +1,14 @@
+extern "rust-intrinsic" {
+    pub fn wrapping_add<T>(l: T, r: T) -> T;
+}
+
+fn five() -> u8 {
+    5
+}
+
+fn main() -> u8 {
+    let l = 255;
+    let r = five();
+
+    unsafe { wrapping_add(l, r) - 4 }
+}
diff --git a/gcc/testsuite/rust/execute/torture/wrapping_op2.rs b/gcc/testsuite/rust/execute/torture/wrapping_op2.rs
new file mode 100644
index 00000000000..f9990157894
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/wrapping_op2.rs
@@ -0,0 +1,20 @@
+extern "rust-intrinsic" {
+    pub fn wrapping_add<T>(l: T, r: T) -> T;
+    pub fn wrapping_sub<T>(l: T, r: T) -> T;
+    pub fn wrapping_mul<T>(l: T, r: T) -> T;
+}
+
+fn five() -> u8 {
+    5
+}
+
+fn main() -> u8 {
+    let l = 255;
+    let r = five();
+
+    let ret0 = unsafe { wrapping_add(l, r) - 4 }; // 4
+    let ret1 = unsafe { wrapping_sub(r, l) - 6 }; // 6
+    let ret2 = unsafe { wrapping_mul(r, l) - 251 }; // 251
+
+    ret0 + ret1 + ret2
+}
diff --git a/gcc/testsuite/rust/execute/xfail/macro1.rs b/gcc/testsuite/rust/execute/xfail/macro1.rs
new file mode 100644
index 00000000000..eab5a0285cf
--- /dev/null
+++ b/gcc/testsuite/rust/execute/xfail/macro1.rs
@@ -0,0 +1,32 @@
+// { dg-output "macro\nmacro\nmacro\nmacro\n" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn f() {
+    let r_s = "macro\n\0";
+    let s_p = r_s as *const str;
+    let c_p = s_p as *const i8;
+
+    printf(c_p);
+}
+
+macro_rules! empty0 {
+    () => ( f() );
+}
+
+macro_rules! empty1 {
+    {} => { f() };
+}
+
+macro_rules! empty2 {
+    [] => [ f() ];
+}
+
+// using multiple parens/brackets/curlies variants allows us to make sure we
+// parse everything properly
+fn main() {
+    empty0!();
+    empty1!{};
+    empty2![];
+}
