about summary refs log tree commit diff
path: root/compiler/rustc_codegen_gcc/tests
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_gcc/tests')
-rw-r--r--compiler/rustc_codegen_gcc/tests/failing-ice-tests.txt40
-rw-r--r--compiler/rustc_codegen_gcc/tests/failing-lto-tests.txt33
-rw-r--r--compiler/rustc_codegen_gcc/tests/failing-run-make-tests.txt42
-rw-r--r--compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt124
-rw-r--r--compiler/rustc_codegen_gcc/tests/failing-ui-tests12.txt47
-rw-r--r--compiler/rustc_codegen_gcc/tests/hello-world/Cargo.lock14
-rw-r--r--compiler/rustc_codegen_gcc/tests/hello-world/Cargo.toml12
-rw-r--r--compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.lock5
-rw-r--r--compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.toml9
-rw-r--r--compiler/rustc_codegen_gcc/tests/hello-world/mylib/src/lib.rs7
-rw-r--r--compiler/rustc_codegen_gcc/tests/hello-world/src/main.rs5
-rw-r--r--compiler/rustc_codegen_gcc/tests/lang_tests_common.rs148
-rw-r--r--compiler/rustc_codegen_gcc/tests/lang_tests_debug.rs5
-rw-r--r--compiler/rustc_codegen_gcc/tests/lang_tests_release.rs5
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/abort1.rs55
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/abort2.rs57
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/array.rs43
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/asm.rs184
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/assign.rs162
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/closure.rs64
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/condition.rs41
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/empty_main.rs40
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/exit.rs50
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/exit_code.rs40
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs36
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/gep.rs10
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/int.rs330
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/int_overflow.rs23
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/mut_ref.rs174
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/operations.rs242
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs35
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/return-tuple.rs73
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/slice.rs36
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/static.rs114
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/structs.rs71
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/tuple.rs52
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/volatile.rs26
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/volatile2.rs113
38 files changed, 2567 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_gcc/tests/failing-ice-tests.txt b/compiler/rustc_codegen_gcc/tests/failing-ice-tests.txt
new file mode 100644
index 00000000000..ff1b6f14894
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/failing-ice-tests.txt
@@ -0,0 +1,40 @@
+tests/ui/treat-err-as-bug/span_delayed_bug.rs
+tests/ui/treat-err-as-bug/err.rs
+tests/ui/simd/not-out-of-bounds.rs
+tests/ui/simd/monomorphize-shuffle-index.rs
+tests/ui/simd/masked-load-store-build-fail.rs
+tests/ui/simd/intrinsic/generic-shuffle.rs
+tests/ui/simd/intrinsic/generic-elements.rs
+tests/ui/simd/intrinsic/generic-cast.rs
+tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs
+tests/ui/simd/intrinsic/generic-arithmetic-2.rs
+tests/ui/panics/default-backtrace-ice.rs
+tests/ui/mir/lint/storage-live.rs
+tests/ui/layout/valid_range_oob.rs
+tests/ui/higher-ranked/trait-bounds/future.rs
+tests/ui/consts/const-eval/const-eval-query-stack.rs
+tests/ui/simd/masked-load-store.rs
+tests/ui/simd/issue-39720.rs
+tests/ui/simd/intrinsic/ptr-cast.rs
+tests/ui/sepcomp/sepcomp-statics.rs
+tests/ui/sepcomp/sepcomp-fns.rs
+tests/ui/sepcomp/sepcomp-fns-backwards.rs
+tests/ui/sepcomp/sepcomp-extern.rs
+tests/ui/sepcomp/sepcomp-cci.rs
+tests/ui/lto/thin-lto-inlines2.rs
+tests/ui/lto/weak-works.rs
+tests/ui/lto/thin-lto-inlines.rs
+tests/ui/lto/thin-lto-global-allocator.rs
+tests/ui/lto/msvc-imp-present.rs
+tests/ui/lto/dylib-works.rs
+tests/ui/lto/all-crates.rs
+tests/ui/issues/issue-47364.rs
+tests/ui/functions-closures/parallel-codegen-closures.rs
+tests/ui/sepcomp/sepcomp-unwind.rs
+tests/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs
+tests/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs
+tests/ui/unwind-no-uwtable.rs
+tests/ui/delegation/fn-header.rs
+tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
+tests/ui/simd/masked-load-store.rs
+tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs
diff --git a/compiler/rustc_codegen_gcc/tests/failing-lto-tests.txt b/compiler/rustc_codegen_gcc/tests/failing-lto-tests.txt
new file mode 100644
index 00000000000..b9126fb73a7
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/failing-lto-tests.txt
@@ -0,0 +1,33 @@
+tests/ui/lint/unsafe_code/forge_unsafe_block.rs
+tests/ui/lint/unused-qualification-in-derive-expansion.rs
+tests/ui/macros/macro-quote-test.rs
+tests/ui/macros/proc_macro.rs
+tests/ui/panic-runtime/lto-unwind.rs
+tests/ui/resolve/derive-macro-1.rs
+tests/ui/resolve/derive-macro-2.rs
+tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-pretty.rs
+tests/ui/rfcs/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs
+tests/ui/rfcs/rfc-3348-c-string-literals/edition-spans.rs
+tests/ui/rust-2018/suggestions-not-always-applicable.rs
+tests/ui/rust-2021/reserved-prefixes-via-macro.rs
+tests/ui/underscore-imports/duplicate.rs
+tests/ui/async-await/issues/issue-60674.rs
+tests/ui/attributes/main-removed-2/main.rs
+tests/ui/cfg/assume-incomplete-release/assume-incomplete.rs
+tests/ui/crate-loading/cross-compiled-proc-macro.rs
+tests/ui/derives/derive-marker-tricky.rs
+tests/ui/diagnostic_namespace/existing_proc_macros.rs
+tests/ui/fmt/format-args-capture-issue-106408.rs
+tests/ui/fmt/indoc-issue-106408.rs
+tests/ui/hygiene/issue-77523-def-site-async-await.rs
+tests/ui/inherent-impls-overlap-check/no-overlap.rs
+tests/ui/enum-discriminant/issue-46519.rs
+tests/ui/issues/issue-45731.rs
+tests/ui/lint/test-allow-dead-extern-static-no-warning.rs
+tests/ui/macros/macro-comma-behavior-rpass.rs
+tests/ui/macros/rfc-2011-nicer-assert-messages/assert-with-custom-errors-does-not-create-unnecessary-code.rs
+tests/ui/macros/rfc-2011-nicer-assert-messages/feature-gate-generic_assert.rs
+tests/ui/macros/stringify.rs
+tests/ui/reexport-test-harness-main.rs
+tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-in-test.rs
+tests/ui/binding/fn-arg-incomplete-pattern-drop-order.rs
diff --git a/compiler/rustc_codegen_gcc/tests/failing-run-make-tests.txt b/compiler/rustc_codegen_gcc/tests/failing-run-make-tests.txt
new file mode 100644
index 00000000000..842533cd3c6
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/failing-run-make-tests.txt
@@ -0,0 +1,42 @@
+tests/run-make/a-b-a-linker-guard/
+tests/run-make/CURRENT_RUSTC_VERSION/
+tests/run-make/cross-lang-lto/
+tests/run-make/cross-lang-lto-upstream-rlibs/
+tests/run-make/doctests-keep-binaries/
+tests/run-make/doctests-runtool/
+tests/run-make/emit-shared-files/
+tests/run-make/exit-code/
+tests/run-make/issue-22131/
+tests/run-make/issue-64153/
+tests/run-make/llvm-ident/
+tests/run-make/native-link-modifier-bundle/
+tests/run-make/remap-path-prefix-dwarf/
+tests/run-make/repr128-dwarf/
+tests/run-make/rlib-format-packed-bundled-libs/
+tests/run-make/rlib-format-packed-bundled-libs-2/
+tests/run-make/rustdoc-determinism/
+tests/run-make/rustdoc-error-lines/
+tests/run-make/rustdoc-map-file/
+tests/run-make/rustdoc-output-path/
+tests/run-make/rustdoc-scrape-examples-invalid-expr/
+tests/run-make/rustdoc-scrape-examples-multiple/
+tests/run-make/rustdoc-scrape-examples-ordering/
+tests/run-make/rustdoc-scrape-examples-remap/
+tests/run-make/rustdoc-scrape-examples-test/
+tests/run-make/rustdoc-scrape-examples-whitespace/
+tests/run-make/rustdoc-scrape-examples-macros/
+tests/run-make/rustdoc-with-out-dir-option/
+tests/run-make/rustdoc-verify-output-files/
+tests/run-make/rustdoc-themes/
+tests/run-make/rustdoc-with-short-out-dir-option/
+tests/run-make/rustdoc-with-output-option/
+tests/run-make/arguments-non-c-like-enum/
+tests/run-make/c-link-to-rust-staticlib/
+tests/run-make/foreign-double-unwind/
+tests/run-make/foreign-exceptions/
+tests/run-make/glibc-staticlib-args/
+tests/run-make/issue-36710/
+tests/run-make/issue-68794-textrel-on-minimal-lib/
+tests/run-make/lto-smoke-c/
+tests/run-make/return-non-c-like-enum/
+
diff --git a/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt b/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt
new file mode 100644
index 00000000000..082958bfe1f
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt
@@ -0,0 +1,124 @@
+tests/ui/allocator/no_std-alloc-error-handler-custom.rs
+tests/ui/allocator/no_std-alloc-error-handler-default.rs
+tests/ui/asm/may_unwind.rs
+tests/ui/asm/x86_64/multiple-clobber-abi.rs
+tests/ui/functions-closures/parallel-codegen-closures.rs
+tests/ui/linkage-attr/linkage1.rs
+tests/ui/lto/dylib-works.rs
+tests/ui/numbers-arithmetic/saturating-float-casts.rs
+tests/ui/sepcomp/sepcomp-cci.rs
+tests/ui/sepcomp/sepcomp-extern.rs
+tests/ui/sepcomp/sepcomp-fns-backwards.rs
+tests/ui/sepcomp/sepcomp-fns.rs
+tests/ui/sepcomp/sepcomp-statics.rs
+tests/ui/asm/x86_64/may_unwind.rs
+tests/ui/catch-unwind-bang.rs
+tests/ui/drop/dynamic-drop-async.rs
+tests/ui/cfg/cfg-panic-abort.rs
+tests/ui/drop/repeat-drop.rs
+tests/ui/coroutine/panic-drops-resume.rs
+tests/ui/fmt/format-args-capture.rs
+tests/ui/coroutine/panic-drops.rs
+tests/ui/intrinsics/panic-uninitialized-zeroed.rs
+tests/ui/iterators/iter-sum-overflow-debug.rs
+tests/ui/iterators/iter-sum-overflow-overflow-checks.rs
+tests/ui/mir/mir_calls_to_shims.rs
+tests/ui/mir/mir_drop_order.rs
+tests/ui/mir/mir_let_chains_drop_order.rs
+tests/ui/oom_unwind.rs
+tests/ui/panic-runtime/abort-link-to-unwinding-crates.rs
+tests/ui/panic-runtime/abort.rs
+tests/ui/panic-runtime/link-to-abort.rs
+tests/ui/unwind-no-uwtable.rs
+tests/ui/parser/unclosed-delimiter-in-dep.rs
+tests/ui/consts/missing_span_in_backtrace.rs
+tests/ui/drop/dynamic-drop.rs
+tests/ui/issues/issue-40883.rs
+tests/ui/issues/issue-43853.rs
+tests/ui/issues/issue-47364.rs
+tests/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs
+tests/ui/rfcs/rfc-1857-stabilize-drop-order/drop-order.rs
+tests/ui/rfcs/rfc-2091-track-caller/std-panic-locations.rs
+tests/ui/simd/issue-17170.rs
+tests/ui/simd/issue-39720.rs
+tests/ui/alloc-error/default-alloc-error-hook.rs
+tests/ui/coroutine/panic-safe.rs
+tests/ui/issues/issue-14875.rs
+tests/ui/issues/issue-29948.rs
+tests/ui/panics/nested_panic_caught.rs
+tests/ui/process/println-with-broken-pipe.rs
+tests/ui/lto/thin-lto-inlines2.rs
+tests/ui/lto/weak-works.rs
+tests/ui/panic-runtime/lto-abort.rs 
+tests/ui/lto/thin-lto-inlines.rs
+tests/ui/lto/thin-lto-global-allocator.rs
+tests/ui/lto/msvc-imp-present.rs
+tests/ui/lto/lto-thin-rustc-loads-linker-plugin.rs
+tests/ui/lto/all-crates.rs
+tests/ui/async-await/deep-futures-are-freeze.rs
+tests/ui/coroutine/resume-after-return.rs
+tests/ui/simd/masked-load-store.rs
+tests/ui/simd/repr_packed.rs
+tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs
+tests/ui/consts/try-operator.rs
+tests/ui/coroutine/unwind-abort-mix.rs
+tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs
+tests/ui/impl-trait/equality-in-canonical-query.rs
+tests/ui/consts/issue-miri-1910.rs
+tests/ui/mir/mir_heavy_promoted.rs
+tests/ui/consts/const_cmp_type_id.rs
+tests/ui/consts/issue-73976-monomorphic.rs
+tests/ui/consts/issue-94675.rs
+tests/ui/traits/const-traits/const-drop-fail.rs
+tests/ui/traits/const-traits/const-drop.rs
+tests/ui/runtime/on-broken-pipe/child-processes.rs
+tests/ui/sanitizer/cfi/assoc-ty-lifetime-issue-123053.rs
+tests/ui/sanitizer/cfi/async-closures.rs
+tests/ui/sanitizer/cfi/closures.rs
+tests/ui/sanitizer/cfi/complex-receiver.rs
+tests/ui/sanitizer/cfi/coroutine.rs
+tests/ui/sanitizer/cfi/drop-in-place.rs
+tests/ui/sanitizer/cfi/drop-no-principal.rs
+tests/ui/sanitizer/cfi/fn-ptr.rs
+tests/ui/sanitizer/cfi/self-ref.rs
+tests/ui/sanitizer/cfi/supertraits.rs
+tests/ui/sanitizer/cfi/virtual-auto.rs
+tests/ui/sanitizer/cfi/sized-associated-ty.rs
+tests/ui/sanitizer/cfi/can-reveal-opaques.rs
+tests/ui/sanitizer/kcfi-mangling.rs
+tests/ui/statics/const_generics.rs
+tests/ui/backtrace/dylib-dep.rs
+tests/ui/errors/pic-linker.rs
+tests/ui/delegation/fn-header.rs
+tests/ui/consts/zst_no_llvm_alloc.rs
+tests/ui/consts/const-eval/parse_ints.rs
+tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
+tests/ui/simd/intrinsic/generic-as.rs
+tests/ui/backtrace/backtrace.rs
+tests/ui/lifetimes/tail-expr-lock-poisoning.rs
+tests/ui/runtime/rt-explody-panic-payloads.rs
+tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs
+tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs
+tests/ui/codegen/equal-pointers-unequal/as-cast/inline1.rs
+tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs
+tests/ui/codegen/equal-pointers-unequal/as-cast/inline2.rs
+tests/ui/codegen/equal-pointers-unequal/as-cast/print3.rs
+tests/ui/codegen/equal-pointers-unequal/as-cast/segfault.rs
+tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs
+tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs
+tests/ui/codegen/equal-pointers-unequal/as-cast/zero.rs
+tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.rs
+tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs
+tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs
+tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.rs
+tests/ui/codegen/equal-pointers-unequal/exposed-provenance/segfault.rs
+tests/ui/codegen/equal-pointers-unequal/exposed-provenance/zero.rs
+tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs
+tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs
+tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs
+tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.rs
+tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs
+tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs
+tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs
+tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs
+tests/ui/simd/simd-bitmask-notpow2.rs
diff --git a/compiler/rustc_codegen_gcc/tests/failing-ui-tests12.txt b/compiler/rustc_codegen_gcc/tests/failing-ui-tests12.txt
new file mode 100644
index 00000000000..b10d4bc82aa
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/failing-ui-tests12.txt
@@ -0,0 +1,47 @@
+tests/ui/asm/x86_64/issue-96797.rs
+tests/ui/intrinsics/const-eval-select-x86_64.rs
+tests/ui/packed/packed-struct-drop-aligned.rs
+tests/ui/packed/packed-struct-generic-layout.rs
+tests/ui/packed/packed-struct-layout.rs
+tests/ui/packed/packed-struct-optimized-enum.rs
+tests/ui/packed/packed-struct-size.rs
+tests/ui/packed/packed-struct-vec.rs
+tests/ui/packed/packed-tuple-struct-layout.rs
+tests/ui/simd/array-type.rs
+tests/ui/simd/intrinsic/float-minmax-pass.rs
+tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
+tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
+tests/ui/simd/intrinsic/generic-cast-pass.rs
+tests/ui/simd/intrinsic/generic-cast-pointer-width.rs
+tests/ui/simd/intrinsic/generic-comparison-pass.rs
+tests/ui/simd/intrinsic/generic-elements-pass.rs
+tests/ui/simd/intrinsic/generic-reduction-pass.rs
+tests/ui/simd/intrinsic/generic-select-pass.rs
+tests/ui/simd/intrinsic/inlining-issue67557-ice.rs
+tests/ui/simd/intrinsic/inlining-issue67557.rs
+tests/ui/simd/shuffle.rs
+tests/ui/simd/simd-bitmask.rs
+tests/ui/iterators/iter-step-overflow-debug.rs
+tests/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs
+tests/ui/privacy/reachable-unnameable-items.rs
+tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-in-test.rs
+tests/ui/async-await/async-fn-size-moved-locals.rs
+tests/ui/async-await/async-fn-size-uninit-locals.rs
+tests/ui/cfg/cfg-panic.rs
+tests/ui/coroutine/size-moved-locals.rs
+tests/ui/macros/rfc-2011-nicer-assert-messages/all-not-available-cases.rs
+tests/ui/simd/intrinsic/generic-gather-pass.rs
+tests/ui/simd/issue-85915-simd-ptrs.rs
+tests/ui/simd/issue-89193.rs
+tests/ui/issues/issue-68010-large-zst-consts.rs
+tests/ui/rust-2018/proc-macro-crate-in-paths.rs
+tests/ui/target-feature/missing-plusminus.rs
+tests/ui/sse2.rs
+tests/ui/codegen/issue-79865-llvm-miscompile.rs
+tests/ui/std-backtrace.rs
+tests/ui/mir/alignment/packed.rs
+tests/ui/intrinsics/intrinsics-integer.rs
+tests/ui/asm/x86_64/evex512-implicit-feature.rs
+tests/ui/packed/dyn-trait.rs
+tests/ui/packed/issue-118537-field-offset-ice.rs
+tests/ui/stable-mir-print/basic_function.rs
diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.lock b/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.lock
new file mode 100644
index 00000000000..fe252db4425
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.lock
@@ -0,0 +1,14 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "hello_world"
+version = "0.0.0"
+dependencies = [
+ "mylib",
+]
+
+[[package]]
+name = "mylib"
+version = "0.1.0"
diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.toml b/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.toml
new file mode 100644
index 00000000000..c6e22f642f6
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/hello-world/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "hello_world"
+edition = "2024"
+
+[dependencies]
+mylib = { path = "mylib" }
+
+[profile.dev]
+lto = "thin"
+
+[profile.release]
+lto = "fat"
diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.lock b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.lock
new file mode 100644
index 00000000000..c8a0bfc6354
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.lock
@@ -0,0 +1,5 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "mylib"
+version = "0.1.0"
diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.toml b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.toml
new file mode 100644
index 00000000000..d15f62bfb6d
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "mylib"
+version = "0.1.0"
+authors = ["Antoni Boucher <bouanto@zoho.com>"]
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/mylib/src/lib.rs b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/src/lib.rs
new file mode 100644
index 00000000000..8d3d111bd19
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/hello-world/mylib/src/lib.rs
@@ -0,0 +1,7 @@
+pub fn my_func(a: i32, b: i32) -> i32 {
+    let mut res = a;
+    for i in a..b {
+        res += i;
+    }
+    res
+}
diff --git a/compiler/rustc_codegen_gcc/tests/hello-world/src/main.rs b/compiler/rustc_codegen_gcc/tests/hello-world/src/main.rs
new file mode 100644
index 00000000000..71c78d364ac
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/hello-world/src/main.rs
@@ -0,0 +1,5 @@
+use mylib::my_func;
+
+fn main() {
+    println!("{}", my_func(5, 10));
+}
diff --git a/compiler/rustc_codegen_gcc/tests/lang_tests_common.rs b/compiler/rustc_codegen_gcc/tests/lang_tests_common.rs
new file mode 100644
index 00000000000..fafb7be55ce
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/lang_tests_common.rs
@@ -0,0 +1,148 @@
+//! The common code for `tests/lang_tests_*.rs`
+
+use std::{
+    env::{self, current_dir},
+    path::{Path, PathBuf},
+    process::Command,
+};
+
+use boml::Toml;
+use lang_tester::LangTester;
+use tempfile::TempDir;
+
+/// Controls the compile options (e.g., optimization level) used to compile
+/// test code.
+#[allow(dead_code)] // Each test crate picks one variant
+pub enum Profile {
+    Debug,
+    Release,
+}
+
+pub fn main_inner(profile: Profile) {
+    let tempdir = TempDir::new().expect("temp dir");
+    let current_dir = current_dir().expect("current dir");
+    let current_dir = current_dir.to_str().expect("current dir").to_string();
+
+    let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
+
+    let gcc_path = std::fs::read_to_string(manifest_dir.join("config.toml"))
+        .ok()
+        .and_then(|v| {
+            let toml = Toml::parse(&v).expect("Failed to parse `config.toml`");
+            toml.get_string("gcc-path").map(PathBuf::from).ok()
+        })
+        .unwrap_or_else(|| {
+            // then we try to retrieve it from the `target` folder.
+            let commit = include_str!("../libgccjit.version").trim();
+            Path::new("build/libgccjit").join(commit)
+        });
+
+    let gcc_path = Path::new(&gcc_path)
+        .canonicalize()
+        .expect("failed to get absolute path of `gcc-path`")
+        .display()
+        .to_string();
+    env::set_var("LD_LIBRARY_PATH", gcc_path);
+
+    fn rust_filter(path: &Path) -> bool {
+        path.is_file() && path.extension().expect("extension").to_str().expect("to_str") == "rs"
+    }
+
+    #[cfg(feature = "master")]
+    fn filter(filename: &Path) -> bool {
+        rust_filter(filename)
+    }
+
+    #[cfg(not(feature = "master"))]
+    fn filter(filename: &Path) -> bool {
+        if let Some(filename) = filename.to_str() {
+            if filename.ends_with("gep.rs") {
+                return false;
+            }
+        }
+        rust_filter(filename)
+    }
+
+    LangTester::new()
+        .test_dir("tests/run")
+        .test_path_filter(filter)
+        .test_extract(|path| {
+            let lines = std::fs::read_to_string(path)
+                .expect("read file")
+                .lines()
+                .skip_while(|l| !l.starts_with("//"))
+                .take_while(|l| l.starts_with("//"))
+                .map(|l| &l[2..])
+                .collect::<Vec<_>>()
+                .join("\n");
+            lines
+        })
+        .test_cmds(move |path| {
+            // Test command 1: Compile `x.rs` into `tempdir/x`.
+            let mut exe = PathBuf::new();
+            exe.push(&tempdir);
+            exe.push(path.file_stem().expect("file_stem"));
+            let mut compiler = Command::new("rustc");
+            compiler.args([
+                &format!("-Zcodegen-backend={}/target/debug/librustc_codegen_gcc.so", current_dir),
+                "--sysroot",
+                &format!("{}/build/build_sysroot/sysroot/", current_dir),
+                "-C",
+                "link-arg=-lc",
+                "--extern",
+                "mini_core=target/out/libmini_core.rlib",
+                "-o",
+                exe.to_str().expect("to_str"),
+                path.to_str().expect("to_str"),
+            ]);
+
+            // TODO(antoyo): find a way to send this via a cli argument.
+            let test_target = std::env::var("CG_GCC_TEST_TARGET");
+            if let Ok(ref target) = test_target {
+                compiler.args(["--target", target]);
+                let linker = format!("{}-gcc", target);
+                compiler.args(&[format!("-Clinker={}", linker)]);
+                let mut env_path = std::env::var("PATH").unwrap_or_default();
+                // TODO(antoyo): find a better way to add the PATH necessary locally.
+                env_path = format!("/opt/m68k-unknown-linux-gnu/bin:{}", env_path);
+                compiler.env("PATH", env_path);
+            }
+
+            if let Some(flags) = option_env!("TEST_FLAGS") {
+                for flag in flags.split_whitespace() {
+                    compiler.arg(flag);
+                }
+            }
+            match profile {
+                Profile::Debug => {}
+                Profile::Release => {
+                    compiler.args(["-C", "opt-level=3", "-C", "lto=no"]);
+                }
+            }
+            // Test command 2: run `tempdir/x`.
+            if test_target.is_ok() {
+                let vm_parent_dir = std::env::var("CG_GCC_VM_DIR")
+                    .map(PathBuf::from)
+                    .unwrap_or_else(|_| std::env::current_dir().unwrap());
+                let vm_dir = "vm";
+                let exe_filename = exe.file_name().unwrap();
+                let vm_home_dir = vm_parent_dir.join(vm_dir).join("home");
+                let vm_exe_path = vm_home_dir.join(exe_filename);
+                // FIXME(antoyo): panicking here makes the test pass.
+                let inside_vm_exe_path = PathBuf::from("/home").join(exe_filename);
+                let mut copy = Command::new("sudo");
+                copy.arg("cp");
+                copy.args([&exe, &vm_exe_path]);
+
+                let mut runtime = Command::new("sudo");
+                runtime.args(["chroot", vm_dir, "qemu-m68k-static"]);
+                runtime.arg(inside_vm_exe_path);
+                runtime.current_dir(vm_parent_dir);
+                vec![("Compiler", compiler), ("Copy", copy), ("Run-time", runtime)]
+            } else {
+                let runtime = Command::new(exe);
+                vec![("Compiler", compiler), ("Run-time", runtime)]
+            }
+        })
+        .run();
+}
diff --git a/compiler/rustc_codegen_gcc/tests/lang_tests_debug.rs b/compiler/rustc_codegen_gcc/tests/lang_tests_debug.rs
new file mode 100644
index 00000000000..96bd74883ff
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/lang_tests_debug.rs
@@ -0,0 +1,5 @@
+mod lang_tests_common;
+
+fn main() {
+    lang_tests_common::main_inner(lang_tests_common::Profile::Debug);
+}
diff --git a/compiler/rustc_codegen_gcc/tests/lang_tests_release.rs b/compiler/rustc_codegen_gcc/tests/lang_tests_release.rs
new file mode 100644
index 00000000000..35d5d60c33e
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/lang_tests_release.rs
@@ -0,0 +1,5 @@
+mod lang_tests_common;
+
+fn main() {
+    lang_tests_common::main_inner(lang_tests_common::Profile::Release);
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/abort1.rs b/compiler/rustc_codegen_gcc/tests/run/abort1.rs
new file mode 100644
index 00000000000..696197d7377
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/abort1.rs
@@ -0,0 +1,55 @@
+// Compiler:
+//
+// Run-time:
+//   status: signal
+
+#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
+#![allow(internal_features)]
+
+#![no_std]
+#![no_core]
+
+/*
+ * Core
+ */
+
+// Because we don't have core yet.
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "copy"]
+trait Copy {
+}
+
+impl Copy for isize {}
+
+#[lang = "receiver"]
+trait Receiver {
+}
+
+#[lang = "freeze"]
+pub(crate) unsafe auto trait Freeze {}
+
+mod intrinsics {
+    use super::Sized;
+
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
+    }
+}
+
+/*
+ * Code
+ */
+
+fn test_fail() -> ! {
+    unsafe { intrinsics::abort() };
+}
+
+#[start]
+fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+    test_fail();
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/abort2.rs b/compiler/rustc_codegen_gcc/tests/run/abort2.rs
new file mode 100644
index 00000000000..714cd6c0f38
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/abort2.rs
@@ -0,0 +1,57 @@
+// Compiler:
+//
+// Run-time:
+//   status: signal
+
+#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
+#![allow(internal_features)]
+
+#![no_std]
+#![no_core]
+
+/*
+ * Core
+ */
+
+// Because we don't have core yet.
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "copy"]
+trait Copy {
+}
+
+impl Copy for isize {}
+
+#[lang = "receiver"]
+trait Receiver {
+}
+
+#[lang = "freeze"]
+pub(crate) unsafe auto trait Freeze {}
+
+mod intrinsics {
+    use super::Sized;
+
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
+    }
+}
+
+/*
+ * Code
+ */
+
+fn fail() -> i32 {
+    unsafe { intrinsics::abort() };
+    0
+}
+
+#[start]
+fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+    fail();
+    0
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/array.rs b/compiler/rustc_codegen_gcc/tests/run/array.rs
new file mode 100644
index 00000000000..c3c08c29c6d
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/array.rs
@@ -0,0 +1,43 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+//   stdout: 42
+//     7
+//     5
+//     10
+
+#![feature(no_core, start)]
+
+#![no_std]
+#![no_core]
+
+extern crate mini_core;
+
+mod libc {
+    #[link(name = "c")]
+    extern "C" {
+        pub fn printf(format: *const i8, ...) -> i32;
+        pub fn puts(s: *const u8) -> i32;
+    }
+}
+
+static mut ONE: usize = 1;
+
+fn make_array() -> [u8; 3] {
+    [42, 10, 5]
+}
+
+#[start]
+fn main(argc: isize, _argv: *const *const u8) -> isize {
+    let array = [42, 7, 5];
+    let array2 = make_array();
+    unsafe {
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, array[ONE - 1]);
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, array[ONE]);
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, array[ONE + 1]);
+
+        libc::printf(b"%d\n\0" as *const u8 as *const i8, array2[argc as usize] as u32);
+    }
+    0
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/asm.rs b/compiler/rustc_codegen_gcc/tests/run/asm.rs
new file mode 100644
index 00000000000..4e05d026868
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/asm.rs
@@ -0,0 +1,184 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+
+#[cfg(target_arch = "x86_64")]
+use std::arch::{asm, global_asm};
+
+#[cfg(target_arch = "x86_64")]
+global_asm!(
+    "
+    .global add_asm
+add_asm:
+     mov rax, rdi
+     add rax, rsi
+     ret"
+);
+
+extern "C" {
+    fn add_asm(a: i64, b: i64) -> i64;
+}
+
+#[cfg(target_arch = "x86_64")]
+pub unsafe fn mem_cpy(dst: *mut u8, src: *const u8, len: usize) {
+    asm!(
+        "rep movsb",
+        inout("rdi") dst => _,
+        inout("rsi") src => _,
+        inout("rcx") len => _,
+        options(preserves_flags, nostack)
+    );
+}
+
+#[cfg(target_arch = "x86_64")]
+fn asm() {
+    unsafe {
+        asm!("nop");
+    }
+
+    let x: u64;
+    unsafe {
+        asm!("mov $5, {}",
+            out(reg) x,
+            options(att_syntax)
+        );
+    }
+    assert_eq!(x, 5);
+
+    let x: u64;
+    let input: u64 = 42;
+    unsafe {
+        asm!("mov {input}, {output}",
+             "add $1, {output}",
+            input = in(reg) input,
+            output = out(reg) x,
+            options(att_syntax)
+        );
+    }
+    assert_eq!(x, 43);
+
+    let x: u64;
+    unsafe {
+        asm!("mov {}, 6",
+            out(reg) x,
+        );
+    }
+    assert_eq!(x, 6);
+
+    let x: u64;
+    let input: u64 = 42;
+    unsafe {
+        asm!("mov {output}, {input}",
+             "add {output}, 1",
+            input = in(reg) input,
+            output = out(reg) x,
+        );
+    }
+    assert_eq!(x, 43);
+
+    // check inout(reg_class) x
+    let mut x: u64 = 42;
+    unsafe {
+        asm!("add {0}, {0}",
+            inout(reg) x
+        );
+    }
+    assert_eq!(x, 84);
+
+    // check inout("reg") x
+    let mut x: u64 = 42;
+    unsafe {
+        asm!("add r11, r11",
+            inout("r11") x
+        );
+    }
+    assert_eq!(x, 84);
+
+    // check a mix of
+    // in("reg")
+    // inout(class) x => y
+    // inout (class) x
+    let x: u64 = 702;
+    let y: u64 = 100;
+    let res: u64;
+    let mut rem: u64 = 0;
+    unsafe {
+        asm!("div r11",
+            in("r11") y,
+            inout("eax") x => res,
+            inout("edx") rem,
+        );
+    }
+    assert_eq!(res, 7);
+    assert_eq!(rem, 2);
+
+    // check const
+    let mut x: u64 = 42;
+    unsafe {
+        asm!("add {}, {}",
+            inout(reg) x,
+            const 1
+        );
+    }
+    assert_eq!(x, 43);
+
+    // check const (ATT syntax)
+    let mut x: u64 = 42;
+    unsafe {
+        asm!("add ${}, {}",
+            const 1,
+            inout(reg) x,
+            options(att_syntax)
+        );
+    }
+    assert_eq!(x, 43);
+
+    // check sym fn
+    extern "C" fn foo() -> u64 {
+        42
+    }
+    let x: u64;
+    unsafe {
+        asm!("call {}", sym foo, lateout("rax") x);
+    }
+    assert_eq!(x, 42);
+
+    // check sym fn (ATT syntax)
+    let x: u64;
+    unsafe {
+        asm!("call {}", sym foo, lateout("rax") x, options(att_syntax));
+    }
+    assert_eq!(x, 42);
+
+    // check sym static
+    static FOO: u64 = 42;
+    let x: u64;
+    unsafe {
+        asm!("mov {1}, qword ptr [rip + {0}]", sym FOO, lateout(reg) x);
+    }
+    assert_eq!(x, 42);
+
+    // check sym static (ATT syntax)
+    let x: u64;
+    unsafe {
+        asm!("movq {0}(%rip), {1}", sym FOO, lateout(reg) x, options(att_syntax));
+    }
+    assert_eq!(x, 42);
+
+    assert_eq!(unsafe { add_asm(40, 2) }, 42);
+
+    let array1 = [1u8, 2, 3];
+    let mut array2 = [0u8, 0, 0];
+    unsafe {
+        mem_cpy(array2.as_mut_ptr(), array1.as_ptr(), 3);
+    }
+    assert_eq!(array1, array2);
+}
+
+#[cfg(not(target_arch = "x86_64"))]
+fn asm() {}
+
+fn main() {
+    asm();
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/assign.rs b/compiler/rustc_codegen_gcc/tests/run/assign.rs
new file mode 100644
index 00000000000..2a47f0c2966
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/assign.rs
@@ -0,0 +1,162 @@
+// Compiler:
+//
+// Run-time:
+//   stdout: 2
+//     7 8
+//     10
+
+#![allow(internal_features, unused_attributes)]
+#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs, track_caller)]
+
+#![no_std]
+#![no_core]
+
+/*
+ * Core
+ */
+
+// Because we don't have core yet.
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "copy"]
+trait Copy {
+}
+
+impl Copy for isize {}
+impl Copy for *mut i32 {}
+impl Copy for usize {}
+impl Copy for u8 {}
+impl Copy for i8 {}
+impl Copy for i32 {}
+
+#[lang = "receiver"]
+trait Receiver {
+}
+
+#[lang = "freeze"]
+pub(crate) unsafe auto trait Freeze {}
+
+#[lang = "panic_location"]
+struct PanicLocation {
+    file: &'static str,
+    line: u32,
+    column: u32,
+}
+
+mod libc {
+    #[link(name = "c")]
+    extern "C" {
+        pub fn puts(s: *const u8) -> i32;
+        pub fn fflush(stream: *mut i32) -> i32;
+        pub fn printf(format: *const i8, ...) -> i32;
+
+        pub static stdout: *mut i32;
+    }
+}
+
+mod intrinsics {
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
+    }
+}
+
+#[lang = "panic"]
+#[track_caller]
+#[no_mangle]
+pub fn panic(_msg: &'static str) -> ! {
+    unsafe {
+        libc::puts("Panicking\0" as *const str as *const u8);
+        libc::fflush(libc::stdout);
+        intrinsics::abort();
+    }
+}
+
+#[lang = "add"]
+trait Add<RHS = Self> {
+    type Output;
+
+    fn add(self, rhs: RHS) -> Self::Output;
+}
+
+impl Add for u8 {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+impl Add for i8 {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+impl Add for i32 {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+impl Add for usize {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+impl Add for isize {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+#[track_caller]
+#[lang = "panic_const_add_overflow"]
+pub fn panic_const_add_overflow() -> ! {
+    panic("attempt to add with overflow");
+}
+
+/*
+ * Code
+ */
+
+fn inc_ref(num: &mut isize) -> isize {
+    *num = *num + 5;
+    *num + 1
+}
+
+fn inc(num: isize) -> isize {
+    num + 1
+}
+
+
+#[start]
+fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+    argc = inc(argc);
+    unsafe {
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, argc);
+    }
+
+    let b = inc_ref(&mut argc);
+    unsafe {
+        libc::printf(b"%ld %ld\n\0" as *const u8 as *const i8, argc, b);
+    }
+
+    argc = 10;
+    unsafe {
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, argc);
+    }
+    0
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/closure.rs b/compiler/rustc_codegen_gcc/tests/run/closure.rs
new file mode 100644
index 00000000000..46c47bc54ed
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/closure.rs
@@ -0,0 +1,64 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+//   stdout: Arg: 1
+//     Argument: 1
+//     String arg: 1
+//     Int argument: 2
+//     Both args: 11
+
+#![feature(no_core, start)]
+
+#![no_std]
+#![no_core]
+
+extern crate mini_core;
+
+mod libc {
+    #[link(name = "c")]
+    extern "C" {
+        pub fn printf(format: *const i8, ...) -> i32;
+    }
+}
+
+#[start]
+fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+    let string = "Arg: %d\n\0";
+    let mut closure = || {
+        unsafe {
+            libc::printf(string as *const str as *const i8, argc);
+        }
+    };
+    closure();
+
+    let mut closure = || {
+        unsafe {
+            libc::printf("Argument: %d\n\0" as *const str as *const i8, argc);
+        }
+    };
+    closure();
+
+    let mut closure = |string| {
+        unsafe {
+            libc::printf(string as *const str as *const i8, argc);
+        }
+    };
+    closure("String arg: %d\n\0");
+
+    let mut closure = |arg: isize| {
+        unsafe {
+            libc::printf("Int argument: %d\n\0" as *const str as *const i8, arg);
+        }
+    };
+    closure(argc + 1);
+
+    let mut closure = |string, arg: isize| {
+        unsafe {
+            libc::printf(string as *const str as *const i8, arg);
+        }
+    };
+    closure("Both args: %d\n\0", argc + 10);
+
+    0
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/condition.rs b/compiler/rustc_codegen_gcc/tests/run/condition.rs
new file mode 100644
index 00000000000..039ef94eaa7
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/condition.rs
@@ -0,0 +1,41 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+//   stdout: true
+//     1
+
+#![feature(no_core, start)]
+
+#![no_std]
+#![no_core]
+
+extern crate mini_core;
+
+mod libc {
+    #[link(name = "c")]
+    extern "C" {
+        pub fn printf(format: *const i8, ...) -> i32;
+    }
+}
+
+#[start]
+fn main(argc: isize, _argv: *const *const u8) -> isize {
+    unsafe {
+        if argc == 1 {
+            libc::printf(b"true\n\0" as *const u8 as *const i8);
+        }
+
+        let string =
+            match argc {
+                1 => b"1\n\0",
+                2 => b"2\n\0",
+                3 => b"3\n\0",
+                4 => b"4\n\0",
+                5 => b"5\n\0",
+                _ => b"_\n\0",
+            };
+        libc::printf(string as *const u8 as *const i8);
+    }
+    0
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/empty_main.rs b/compiler/rustc_codegen_gcc/tests/run/empty_main.rs
new file mode 100644
index 00000000000..e66a859ad69
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/empty_main.rs
@@ -0,0 +1,40 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+
+#![feature(auto_traits, lang_items, no_core, start)]
+#![allow(internal_features)]
+
+#![no_std]
+#![no_core]
+
+/*
+ * Core
+ */
+
+// Because we don't have core yet.
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "copy"]
+trait Copy {
+}
+
+impl Copy for isize {}
+
+#[lang = "receiver"]
+trait Receiver {
+}
+
+#[lang = "freeze"]
+pub(crate) unsafe auto trait Freeze {}
+
+/*
+ * Code
+ */
+
+#[start]
+fn main(_argc: isize, _argv: *const *const u8) -> isize {
+    0
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/exit.rs b/compiler/rustc_codegen_gcc/tests/run/exit.rs
new file mode 100644
index 00000000000..bf1cbeef302
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/exit.rs
@@ -0,0 +1,50 @@
+// Compiler:
+//
+// Run-time:
+//   status: 2
+
+#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
+#![allow(internal_features)]
+
+#![no_std]
+#![no_core]
+
+mod libc {
+    #[link(name = "c")]
+    extern "C" {
+        pub fn exit(status: i32);
+    }
+}
+
+/*
+ * Core
+ */
+
+// Because we don't have core yet.
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "copy"]
+trait Copy {
+}
+
+impl Copy for isize {}
+
+#[lang = "receiver"]
+trait Receiver {
+}
+
+#[lang = "freeze"]
+pub(crate) unsafe auto trait Freeze {}
+
+/*
+ * Code
+ */
+
+#[start]
+fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+    unsafe {
+        libc::exit(2);
+    }
+    0
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/exit_code.rs b/compiler/rustc_codegen_gcc/tests/run/exit_code.rs
new file mode 100644
index 00000000000..be7a233efda
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/exit_code.rs
@@ -0,0 +1,40 @@
+// Compiler:
+//
+// Run-time:
+//   status: 1
+
+#![feature(auto_traits, lang_items, no_core, start)]
+#![allow(internal_features)]
+
+#![no_std]
+#![no_core]
+
+/*
+ * Core
+ */
+
+// Because we don't have core yet.
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "copy"]
+trait Copy {
+}
+
+impl Copy for isize {}
+
+#[lang = "receiver"]
+trait Receiver {
+}
+
+#[lang = "freeze"]
+pub(crate) unsafe auto trait Freeze {}
+
+/*
+ * Code
+ */
+
+#[start]
+fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+    1
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs b/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs
new file mode 100644
index 00000000000..ed1bf72bb27
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs
@@ -0,0 +1,36 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+//   stdout: 1
+
+#![feature(no_core, start)]
+
+#![no_std]
+#![no_core]
+
+extern crate mini_core;
+
+mod libc {
+    #[link(name = "c")]
+    extern "C" {
+        pub fn printf(format: *const i8, ...) -> i32;
+    }
+}
+
+fn i16_as_i8(a: i16) -> i8 {
+    a as i8
+}
+
+fn call_func(func: fn(i16) -> i8, param: i16) -> i8 {
+    func(param)
+}
+
+#[start]
+fn main(argc: isize, _argv: *const *const u8) -> isize {
+    unsafe {
+        let result = call_func(i16_as_i8, argc as i16) as isize;
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, result);
+    }
+    0
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/gep.rs b/compiler/rustc_codegen_gcc/tests/run/gep.rs
new file mode 100644
index 00000000000..c3d1672cff5
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/gep.rs
@@ -0,0 +1,10 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+
+fn main() {
+    let mut value = (1, 1);
+    let ptr = &mut value as *mut (i32, i32);
+    println!("{:?}", ptr.wrapping_offset(10));
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/int.rs b/compiler/rustc_codegen_gcc/tests/run/int.rs
new file mode 100644
index 00000000000..bfe73c38435
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/int.rs
@@ -0,0 +1,330 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+
+#![feature(const_black_box)]
+
+/*
+ * Code
+ */
+
+fn main() {
+    use std::hint::black_box;
+
+    macro_rules! check {
+        ($ty:ty, $expr:expr) => {
+            {
+                const EXPECTED: $ty = $expr;
+                assert_eq!($expr, EXPECTED);
+            }
+        };
+    }
+
+    check!(u32, (2220326408_u32 + black_box(1)) >> (32 - 6));
+
+    /// Generate `check!` tests for integer types at least as wide as 128 bits.
+    macro_rules! check_ops128 {
+        () => {
+            check_ops64!();
+
+            // Shifts.
+            check!(T, VAL1 << black_box(64));
+            check!(T, VAL1 << black_box(81));
+            check!(T, VAL3 << black_box(63));
+            check!(T, VAL3 << black_box(64));
+
+            check!(T, VAL1 >> black_box(64));
+            check!(T, VAL2 >> black_box(64));
+            check!(T, VAL3 >> black_box(64));
+            check!(T, VAL3 >> black_box(81));
+        };
+    }
+
+    /// Generate `check!` tests for integer types at least as wide as 64 bits.
+    macro_rules! check_ops64 {
+        () => {
+            check_ops32!();
+
+            // Shifts.
+            check!(T, VAL2 << black_box(33));
+            check!(T, VAL2 << black_box(49));
+            check!(T, VAL2 << black_box(61));
+            check!(T, VAL2 << black_box(63));
+
+            check!(T, VAL3 << black_box(33));
+            check!(T, VAL3 << black_box(49));
+            check!(T, VAL3 << black_box(61));
+
+            check!(T, VAL1 >> black_box(33));
+            check!(T, VAL1 >> black_box(49));
+            check!(T, VAL1 >> black_box(61));
+            check!(T, VAL1 >> black_box(63));
+
+            check!(T, VAL2 >> black_box(33));
+            check!(T, VAL2 >> black_box(49));
+            check!(T, VAL2 >> black_box(61));
+            check!(T, VAL2 >> black_box(63));
+
+            check!(T, VAL3 >> black_box(33));
+            check!(T, VAL3 >> black_box(49));
+            check!(T, VAL3 >> black_box(61));
+            check!(T, VAL3 >> black_box(63));
+        };
+    }
+
+    /// Generate `check!` tests for integer types at least as wide as 32 bits.
+    macro_rules! check_ops32 {
+        () => {
+            // Shifts.
+            check!(T, VAL2 << black_box(1));
+            check!(T, VAL2 << black_box(0));
+
+            check!(T, VAL3 << black_box(1));
+            check!(T, VAL3 << black_box(0));
+
+            check!(T, VAL1.wrapping_shl(black_box(0)));
+            check!(T, VAL1.wrapping_shl(black_box(1)));
+            check!(T, VAL1.wrapping_shl(black_box(33)));
+            check!(T, VAL1.wrapping_shl(black_box(49)));
+            check!(T, VAL1.wrapping_shl(black_box(61)));
+            check!(T, VAL1.wrapping_shl(black_box(63)));
+            check!(T, VAL1.wrapping_shl(black_box(64)));
+            check!(T, VAL1.wrapping_shl(black_box(81)));
+
+            check!(Option<T>, VAL1.checked_shl(black_box(0)));
+            check!(Option<T>, VAL1.checked_shl(black_box(1)));
+            check!(Option<T>, VAL1.checked_shl(black_box(33)));
+            check!(Option<T>, VAL1.checked_shl(black_box(49)));
+            check!(Option<T>, VAL1.checked_shl(black_box(61)));
+            check!(Option<T>, VAL1.checked_shl(black_box(63)));
+            check!(Option<T>, VAL1.checked_shl(black_box(64)));
+            check!(Option<T>, VAL1.checked_shl(black_box(81)));
+
+            check!(T, VAL1 >> black_box(0));
+            check!(T, VAL1 >> black_box(1));
+
+            check!(T, VAL2 >> black_box(1));
+            check!(T, VAL2 >> black_box(0));
+
+            check!(T, VAL3 >> black_box(0));
+            check!(T, VAL3 >> black_box(1));
+
+            check!(T, VAL1.wrapping_shr(black_box(0)));
+            check!(T, VAL1.wrapping_shr(black_box(1)));
+            check!(T, VAL1.wrapping_shr(black_box(33)));
+            check!(T, VAL1.wrapping_shr(black_box(49)));
+            check!(T, VAL1.wrapping_shr(black_box(61)));
+            check!(T, VAL1.wrapping_shr(black_box(63)));
+            check!(T, VAL1.wrapping_shr(black_box(64)));
+            check!(T, VAL1.wrapping_shr(black_box(81)));
+
+            check!(Option<T>, VAL1.checked_shr(black_box(0)));
+            check!(Option<T>, VAL1.checked_shr(black_box(1)));
+            check!(Option<T>, VAL1.checked_shr(black_box(33)));
+            check!(Option<T>, VAL1.checked_shr(black_box(49)));
+            check!(Option<T>, VAL1.checked_shr(black_box(61)));
+            check!(Option<T>, VAL1.checked_shr(black_box(63)));
+            check!(Option<T>, VAL1.checked_shr(black_box(64)));
+            check!(Option<T>, VAL1.checked_shr(black_box(81)));
+
+            // Casts
+            check!(u64, (VAL1 >> black_box(1)) as u64);
+
+            // Addition.
+            check!(T, VAL1 + black_box(1));
+            check!(T, VAL2 + black_box(1));
+            check!(T, VAL2 + (VAL2 + black_box(1)));
+            check!(T, VAL3 + black_box(1));
+
+            check!(Option<T>, VAL1.checked_add(black_box(1)));
+            check!(Option<T>, VAL2.checked_add(black_box(1)));
+            check!(Option<T>, VAL2.checked_add(VAL2 + black_box(1)));
+            check!(Option<T>, VAL3.checked_add(T::MAX));
+            check!(Option<T>, VAL3.checked_add(T::MIN));
+
+            check!(T, VAL1.wrapping_add(black_box(1)));
+            check!(T, VAL2.wrapping_add(black_box(1)));
+            check!(T, VAL2.wrapping_add(VAL2 + black_box(1)));
+            check!(T, VAL3.wrapping_add(T::MAX));
+            check!(T, VAL3.wrapping_add(T::MIN));
+
+            check!((T, bool), VAL1.overflowing_add(black_box(1)));
+            check!((T, bool), VAL2.overflowing_add(black_box(1)));
+            check!((T, bool), VAL2.overflowing_add(VAL2 + black_box(1)));
+            check!((T, bool), VAL3.overflowing_add(T::MAX));
+            check!((T, bool), VAL3.overflowing_add(T::MIN));
+
+            check!(T, VAL1.saturating_add(black_box(1)));
+            check!(T, VAL2.saturating_add(black_box(1)));
+            check!(T, VAL2.saturating_add(VAL2 + black_box(1)));
+            check!(T, VAL3.saturating_add(T::MAX));
+            check!(T, VAL3.saturating_add(T::MIN));
+
+            // Subtraction
+            check!(T, VAL1 - black_box(1));
+            check!(T, VAL2 - black_box(1));
+            check!(T, VAL3 - black_box(1));
+
+            check!(Option<T>, VAL1.checked_sub(black_box(1)));
+            check!(Option<T>, VAL2.checked_sub(black_box(1)));
+            check!(Option<T>, VAL2.checked_sub(VAL2 + black_box(1)));
+            check!(Option<T>, VAL3.checked_sub(T::MAX));
+            check!(Option<T>, VAL3.checked_sub(T::MIN));
+
+            check!(T, VAL1.wrapping_sub(black_box(1)));
+            check!(T, VAL2.wrapping_sub(black_box(1)));
+            check!(T, VAL2.wrapping_sub(VAL2 + black_box(1)));
+            check!(T, VAL3.wrapping_sub(T::MAX));
+            check!(T, VAL3.wrapping_sub(T::MIN));
+
+            check!((T, bool), VAL1.overflowing_sub(black_box(1)));
+            check!((T, bool), VAL2.overflowing_sub(black_box(1)));
+            check!((T, bool), VAL2.overflowing_sub(VAL2 + black_box(1)));
+            check!((T, bool), VAL3.overflowing_sub(T::MAX));
+            check!((T, bool), VAL3.overflowing_sub(T::MIN));
+
+            check!(T, VAL1.saturating_sub(black_box(1)));
+            check!(T, VAL2.saturating_sub(black_box(1)));
+            check!(T, VAL2.saturating_sub(VAL2 + black_box(1)));
+            check!(T, VAL3.saturating_sub(T::MAX));
+            check!(T, VAL3.saturating_sub(T::MIN));
+
+            // Multiplication
+            check!(T, VAL1 * black_box(2));
+            check!(T, VAL1 * (black_box(1) + VAL2));
+            check!(T, VAL2 * black_box(2));
+            check!(T, VAL2 * (black_box(1) + VAL2));
+            check!(T, VAL3 * black_box(1));
+            check!(T, VAL4 * black_box(2));
+            check!(T, VAL5 * black_box(2));
+
+            check!(Option<T>, VAL1.checked_mul(black_box(2)));
+            check!(Option<T>, VAL1.checked_mul(black_box(1) + VAL2));
+            check!(Option<T>, VAL3.checked_mul(VAL3));
+            check!(Option<T>, VAL4.checked_mul(black_box(2)));
+            check!(Option<T>, VAL5.checked_mul(black_box(2)));
+
+            check!(T, VAL1.wrapping_mul(black_box(2)));
+            check!(T, VAL1.wrapping_mul((black_box(1) + VAL2)));
+            check!(T, VAL3.wrapping_mul(VAL3));
+            check!(T, VAL4.wrapping_mul(black_box(2)));
+            check!(T, VAL5.wrapping_mul(black_box(2)));
+
+            check!((T, bool), VAL1.overflowing_mul(black_box(2)));
+            check!((T, bool), VAL1.overflowing_mul(black_box(1) + VAL2));
+            check!((T, bool), VAL3.overflowing_mul(VAL3));
+            check!((T, bool), VAL4.overflowing_mul(black_box(2)));
+            check!((T, bool), VAL5.overflowing_mul(black_box(2)));
+
+            check!(T, VAL1.saturating_mul(black_box(2)));
+            check!(T, VAL1.saturating_mul(black_box(1) + VAL2));
+            check!(T, VAL3.saturating_mul(VAL3));
+            check!(T, VAL4.saturating_mul(black_box(2)));
+            check!(T, VAL5.saturating_mul(black_box(2)));
+
+            // Division.
+            check!(T, VAL1 / black_box(2));
+            check!(T, VAL1 / black_box(3));
+
+            check!(T, VAL2 / black_box(2));
+            check!(T, VAL2 / black_box(3));
+
+            check!(T, VAL3 / black_box(2));
+            check!(T, VAL3 / black_box(3));
+            check!(T, VAL3 / (black_box(1) + VAL4));
+            check!(T, VAL3 / (black_box(1) + VAL2));
+
+            check!(T, VAL4 / black_box(2));
+            check!(T, VAL4 / black_box(3));
+
+            check!(Option<T>, VAL1.checked_div(black_box(2)));
+            check!(Option<T>, VAL1.checked_div(black_box(1) + VAL2));
+            check!(Option<T>, VAL3.checked_div(VAL3));
+            check!(Option<T>, VAL4.checked_div(black_box(2)));
+            check!(Option<T>, VAL5.checked_div(black_box(2)));
+            check!(Option<T>, (T::MIN).checked_div(black_box(0 as T).wrapping_sub(1)));
+            check!(Option<T>, VAL5.checked_div(black_box(0))); // var5 / 0
+
+            check!(T, VAL1.wrapping_div(black_box(2)));
+            check!(T, VAL1.wrapping_div(black_box(1) + VAL2));
+            check!(T, VAL3.wrapping_div(VAL3));
+            check!(T, VAL4.wrapping_div(black_box(2)));
+            check!(T, VAL5.wrapping_div(black_box(2)));
+            check!(T, (T::MIN).wrapping_div(black_box(0 as T).wrapping_sub(1)));
+
+            check!((T, bool), VAL1.overflowing_div(black_box(2)));
+            check!((T, bool), VAL1.overflowing_div(black_box(1) + VAL2));
+            check!((T, bool), VAL3.overflowing_div(VAL3));
+            check!((T, bool), VAL4.overflowing_div(black_box(2)));
+            check!((T, bool), VAL5.overflowing_div(black_box(2)));
+            check!((T, bool), (T::MIN).overflowing_div(black_box(0 as T).wrapping_sub(1)));
+
+            check!(T, VAL1.saturating_div(black_box(2)));
+            check!(T, VAL1.saturating_div((black_box(1) + VAL2)));
+            check!(T, VAL3.saturating_div(VAL3));
+            check!(T, VAL4.saturating_div(black_box(2)));
+            check!(T, VAL5.saturating_div(black_box(2)));
+            check!(T, (T::MIN).saturating_div((0 as T).wrapping_sub(black_box(1))));
+        };
+    }
+
+    {
+        type T = u32;
+        const VAL1: T = 14162_u32;
+        const VAL2: T = 14556_u32;
+        const VAL3: T = 323656954_u32;
+        const VAL4: T = 2023651954_u32;
+        const VAL5: T = 1323651954_u32;
+        check_ops32!();
+    }
+
+    {
+        type T = i32;
+        const VAL1: T = 13456_i32;
+        const VAL2: T = 10475_i32;
+        const VAL3: T = 923653954_i32;
+        const VAL4: T = 993198738_i32;
+        const VAL5: T = 1023653954_i32;
+        check_ops32!();
+    }
+
+    {
+        type T = u64;
+        const VAL1: T = 134217856_u64;
+        const VAL2: T = 104753732_u64;
+        const VAL3: T = 12323651988970863954_u64;
+        const VAL4: T = 7323651988970863954_u64;
+        const VAL5: T = 8323651988970863954_u64;
+        check_ops64!();
+    }
+
+    {
+        type T = i64;
+        const VAL1: T = 134217856_i64;
+        const VAL2: T = 104753732_i64;
+        const VAL3: T = 6323651988970863954_i64;
+        const VAL4: T = 2323651988970863954_i64;
+        const VAL5: T = 3323651988970863954_i64;
+        check_ops64!();
+    }
+
+    {
+        type T = u128;
+        const VAL1: T = 134217856_u128;
+        const VAL2: T = 10475372733397991552_u128;
+        const VAL3: T = 193236519889708027473620326106273939584_u128;
+        const VAL4: T = 123236519889708027473620326106273939584_u128;
+        const VAL5: T = 153236519889708027473620326106273939584_u128;
+        check_ops128!();
+    }
+    {
+        type T = i128;
+        const VAL1: T = 134217856_i128;
+        const VAL2: T = 10475372733397991552_i128;
+        const VAL3: T = 83236519889708027473620326106273939584_i128;
+        const VAL4: T = 63236519889708027473620326106273939584_i128;
+        const VAL5: T = 73236519889708027473620326106273939584_i128;
+        check_ops128!();
+    }
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/int_overflow.rs b/compiler/rustc_codegen_gcc/tests/run/int_overflow.rs
new file mode 100644
index 00000000000..78872159f62
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/int_overflow.rs
@@ -0,0 +1,23 @@
+// Compiler:
+//
+// Run-time:
+//   stdout: Success
+//   status: signal
+
+fn main() {
+    std::panic::set_hook(Box::new(|_| {
+        println!("Success");
+        std::process::abort();
+    }));
+
+    let arg_count = std::env::args().count();
+    let int = isize::MAX;
+    let _int = int + arg_count as isize;  // overflow
+
+    // If overflow checking is disabled, we should reach here.
+    #[cfg(not(debug_assertions))]
+    unsafe {
+        println!("Success");
+        std::process::abort();
+    }
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs b/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs
new file mode 100644
index 00000000000..3ae79338216
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs
@@ -0,0 +1,174 @@
+
+// Compiler:
+//
+// Run-time:
+//   stdout: 2
+//     7
+//     6
+//     11
+
+#![allow(internal_features, unused_attributes)]
+#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs, track_caller)]
+
+#![no_std]
+#![no_core]
+
+/*
+ * Core
+ */
+
+// Because we don't have core yet.
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "copy"]
+trait Copy {
+}
+
+impl Copy for isize {}
+impl Copy for *mut i32 {}
+impl Copy for usize {}
+impl Copy for u8 {}
+impl Copy for i8 {}
+impl Copy for i32 {}
+
+#[lang = "receiver"]
+trait Receiver {
+}
+
+#[lang = "freeze"]
+pub(crate) unsafe auto trait Freeze {}
+
+#[lang = "panic_location"]
+struct PanicLocation {
+    file: &'static str,
+    line: u32,
+    column: u32,
+}
+
+mod libc {
+    #[link(name = "c")]
+    extern "C" {
+        pub fn puts(s: *const u8) -> i32;
+        pub fn fflush(stream: *mut i32) -> i32;
+        pub fn printf(format: *const i8, ...) -> i32;
+
+        pub static stdout: *mut i32;
+    }
+}
+
+mod intrinsics {
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
+    }
+}
+
+#[lang = "panic"]
+#[track_caller]
+#[no_mangle]
+pub fn panic(_msg: &'static str) -> ! {
+    unsafe {
+        libc::puts("Panicking\0" as *const str as *const u8);
+        libc::fflush(libc::stdout);
+        intrinsics::abort();
+    }
+}
+
+#[lang = "add"]
+trait Add<RHS = Self> {
+    type Output;
+
+    fn add(self, rhs: RHS) -> Self::Output;
+}
+
+impl Add for u8 {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+impl Add for i8 {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+impl Add for i32 {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+impl Add for usize {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+impl Add for isize {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+#[track_caller]
+#[lang = "panic_const_add_overflow"]
+pub fn panic_const_add_overflow() -> ! {
+    panic("attempt to add with overflow");
+}
+
+/*
+ * Code
+ */
+
+struct Test {
+    field: isize,
+}
+
+fn test(num: isize) -> Test {
+    Test {
+        field: num + 1,
+    }
+}
+
+fn update_num(num: &mut isize) {
+    *num = *num + 5;
+}
+
+#[start]
+fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+    let mut test = test(argc);
+    unsafe {
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.field);
+    }
+    update_num(&mut test.field);
+    unsafe {
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.field);
+    }
+
+    update_num(&mut argc);
+    unsafe {
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, argc);
+    }
+
+    let refe = &mut argc;
+    *refe = *refe + 5;
+    unsafe {
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, argc);
+    }
+
+    0
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/operations.rs b/compiler/rustc_codegen_gcc/tests/run/operations.rs
new file mode 100644
index 00000000000..0e44fc580b8
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/operations.rs
@@ -0,0 +1,242 @@
+// Compiler:
+//
+// Run-time:
+//   stdout: 41
+//     39
+//     10
+
+#![allow(internal_features, unused_attributes)]
+#![feature(auto_traits, lang_items, no_core, start, intrinsics, arbitrary_self_types, rustc_attrs)]
+
+#![no_std]
+#![no_core]
+
+/*
+ * Core
+ */
+
+// Because we don't have core yet.
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "copy"]
+trait Copy {
+}
+
+impl Copy for isize {}
+impl Copy for *mut i32 {}
+impl Copy for usize {}
+impl Copy for u8 {}
+impl Copy for i8 {}
+impl Copy for i16 {}
+impl Copy for i32 {}
+
+#[lang = "deref"]
+pub trait Deref {
+    type Target: ?Sized;
+
+    fn deref(&self) -> &Self::Target;
+}
+
+#[lang = "legacy_receiver"]
+trait LegacyReceiver {
+}
+
+#[lang = "freeze"]
+pub(crate) unsafe auto trait Freeze {}
+
+#[lang = "panic_location"]
+struct PanicLocation {
+    file: &'static str,
+    line: u32,
+    column: u32,
+}
+
+mod libc {
+    #[link(name = "c")]
+    extern "C" {
+        pub fn printf(format: *const i8, ...) -> i32;
+        pub fn puts(s: *const u8) -> i32;
+        pub fn fflush(stream: *mut i32) -> i32;
+
+        pub static stdout: *mut i32;
+    }
+}
+
+mod intrinsics {
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
+    }
+}
+
+#[lang = "panic"]
+#[track_caller]
+#[no_mangle]
+pub fn panic(_msg: &'static str) -> ! {
+    unsafe {
+        libc::puts("Panicking\0" as *const str as *const u8);
+        libc::fflush(libc::stdout);
+        intrinsics::abort();
+    }
+}
+
+#[lang = "add"]
+trait Add<RHS = Self> {
+    type Output;
+
+    fn add(self, rhs: RHS) -> Self::Output;
+}
+
+impl Add for u8 {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+impl Add for i8 {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+impl Add for i32 {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+impl Add for usize {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+impl Add for isize {
+    type Output = Self;
+
+    fn add(self, rhs: Self) -> Self {
+        self + rhs
+    }
+}
+
+#[lang = "sub"]
+pub trait Sub<RHS = Self> {
+    type Output;
+
+    fn sub(self, rhs: RHS) -> Self::Output;
+}
+
+impl Sub for usize {
+    type Output = Self;
+
+    fn sub(self, rhs: Self) -> Self {
+        self - rhs
+    }
+}
+
+impl Sub for isize {
+    type Output = Self;
+
+    fn sub(self, rhs: Self) -> Self {
+        self - rhs
+    }
+}
+
+impl Sub for u8 {
+    type Output = Self;
+
+    fn sub(self, rhs: Self) -> Self {
+        self - rhs
+    }
+}
+
+impl Sub for i8 {
+    type Output = Self;
+
+    fn sub(self, rhs: Self) -> Self {
+        self - rhs
+    }
+}
+
+impl Sub for i16 {
+    type Output = Self;
+
+    fn sub(self, rhs: Self) -> Self {
+        self - rhs
+    }
+}
+
+#[lang = "mul"]
+pub trait Mul<RHS = Self> {
+    type Output;
+
+    #[must_use]
+    fn mul(self, rhs: RHS) -> Self::Output;
+}
+
+impl Mul for u8 {
+    type Output = Self;
+
+    fn mul(self, rhs: Self) -> Self::Output {
+        self * rhs
+    }
+}
+
+impl Mul for usize {
+    type Output = Self;
+
+    fn mul(self, rhs: Self) -> Self::Output {
+        self * rhs
+    }
+}
+
+impl Mul for isize {
+    type Output = Self;
+
+    fn mul(self, rhs: Self) -> Self::Output {
+        self * rhs
+    }
+}
+
+#[track_caller]
+#[lang = "panic_const_add_overflow"]
+pub fn panic_const_add_overflow() -> ! {
+    panic("attempt to add with overflow");
+}
+
+#[track_caller]
+#[lang = "panic_const_sub_overflow"]
+pub fn panic_const_sub_overflow() -> ! {
+    panic("attempt to subtract with overflow");
+}
+
+#[track_caller]
+#[lang = "panic_const_mul_overflow"]
+pub fn panic_const_mul_overflow() -> ! {
+    panic("attempt to multiply with overflow");
+}
+
+/*
+ * Code
+ */
+
+#[start]
+fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+    unsafe {
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, 40 + argc);
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, 40 - argc);
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, 10 * argc);
+    }
+    0
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs b/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs
new file mode 100644
index 00000000000..2b8812ad51c
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs
@@ -0,0 +1,35 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+//   stdout: 1
+
+#![feature(no_core, start)]
+
+#![no_std]
+#![no_core]
+
+extern crate mini_core;
+
+mod libc {
+    #[link(name = "c")]
+    extern "C" {
+        pub fn printf(format: *const i8, ...) -> i32;
+    }
+}
+
+static mut ONE: usize = 1;
+
+fn make_array() -> [u8; 3] {
+    [42, 10, 5]
+}
+
+#[start]
+fn main(argc: isize, _argv: *const *const u8) -> isize {
+    unsafe {
+        let ptr = ONE as *mut usize;
+        let value = ptr as usize;
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, value);
+    }
+    0
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs b/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs
new file mode 100644
index 00000000000..f2a5a2e4384
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/return-tuple.rs
@@ -0,0 +1,73 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+//   stdout: 10
+//     10
+//     42
+
+#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
+#![allow(internal_features)]
+
+#![no_std]
+#![no_core]
+
+#[lang = "copy"]
+pub unsafe trait Copy {}
+
+impl Copy for bool {}
+impl Copy for u8 {}
+impl Copy for u16 {}
+impl Copy for u32 {}
+impl Copy for u64 {}
+impl Copy for usize {}
+impl Copy for i8 {}
+impl Copy for i16 {}
+impl Copy for i32 {}
+impl Copy for isize {}
+impl Copy for f32 {}
+impl Copy for char {}
+
+mod libc {
+    #[link(name = "c")]
+    extern "C" {
+        pub fn printf(format: *const i8, ...) -> i32;
+    }
+}
+
+/*
+ * Core
+ */
+
+// Because we don't have core yet.
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "legacy_receiver"]
+trait LegacyReceiver {
+}
+
+#[lang = "freeze"]
+pub(crate) unsafe auto trait Freeze {}
+
+/*
+ * Code
+ */
+
+fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u32) {
+    (
+        a as u8, a as u16, a as u32, a as usize, a as i8, a as i16, a as i32, a as isize, b as u8,
+        b as u32,
+    )
+}
+
+#[start]
+fn main(argc: isize, _argv: *const *const u8) -> isize {
+    let (a, b, c, d, e, f, g, h, i, j) = int_cast(10, 42);
+    unsafe {
+        libc::printf(b"%d\n\0" as *const u8 as *const i8, c);
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, d);
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, j);
+    }
+    0
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/slice.rs b/compiler/rustc_codegen_gcc/tests/run/slice.rs
new file mode 100644
index 00000000000..fba93fc1554
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/slice.rs
@@ -0,0 +1,36 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+//   stdout: 5
+
+#![feature(no_core, start)]
+
+#![no_std]
+#![no_core]
+
+extern crate mini_core;
+
+mod libc {
+    #[link(name = "c")]
+    extern "C" {
+        pub fn printf(format: *const i8, ...) -> i32;
+    }
+}
+
+static mut TWO: usize = 2;
+
+fn index_slice(s: &[u32]) -> u32 {
+    unsafe {
+        s[TWO]
+    }
+}
+
+#[start]
+fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+    let array = [42, 7, 5];
+    unsafe {
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, index_slice(&array));
+    }
+    0
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/static.rs b/compiler/rustc_codegen_gcc/tests/run/static.rs
new file mode 100644
index 00000000000..a17ea2a4893
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/static.rs
@@ -0,0 +1,114 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+//   stdout: 10
+//      14
+//      1
+//      12
+//      12
+//      1
+
+#![feature(auto_traits, lang_items, no_core, start, intrinsics, rustc_attrs)]
+#![allow(internal_features)]
+
+#![no_std]
+#![no_core]
+
+/*
+ * Core
+ */
+
+// Because we don't have core yet.
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "destruct"]
+pub trait Destruct {}
+
+#[lang = "drop"]
+pub trait Drop {}
+
+#[lang = "copy"]
+trait Copy {
+}
+
+impl Copy for isize {}
+impl<T: ?Sized> Copy for *mut T {}
+
+#[lang = "receiver"]
+trait Receiver {
+}
+
+#[lang = "freeze"]
+pub(crate) unsafe auto trait Freeze {}
+
+mod intrinsics {
+    use super::Sized;
+
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
+    }
+}
+
+mod libc {
+    #[link(name = "c")]
+    extern "C" {
+        pub fn printf(format: *const i8, ...) -> i32;
+    }
+}
+
+#[lang = "structural_peq"]
+pub trait StructuralPartialEq {}
+
+#[lang = "drop_in_place"]
+#[allow(unconditional_recursion)]
+pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
+    // Code here does not matter - this is replaced by the
+    // real drop glue by the compiler.
+    drop_in_place(to_drop);
+}
+
+/*
+ * Code
+ */
+
+struct Test {
+    field: isize,
+}
+
+struct WithRef {
+    refe: &'static Test,
+}
+
+static mut CONSTANT: isize = 10;
+
+static mut TEST: Test = Test {
+    field: 12,
+};
+
+static mut TEST2: Test = Test {
+    field: 14,
+};
+
+static mut WITH_REF: WithRef = WithRef {
+    refe: unsafe { &TEST },
+};
+
+#[start]
+fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+    unsafe {
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, CONSTANT);
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, TEST2.field);
+        TEST2.field = argc;
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, TEST2.field);
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, WITH_REF.refe.field);
+        WITH_REF.refe = &TEST2;
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, TEST.field);
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, WITH_REF.refe.field);
+    }
+    0
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/structs.rs b/compiler/rustc_codegen_gcc/tests/run/structs.rs
new file mode 100644
index 00000000000..d6455667400
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/structs.rs
@@ -0,0 +1,71 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+//   stdout: 1
+//     2
+
+#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
+#![allow(internal_features)]
+
+#![no_std]
+#![no_core]
+
+/*
+ * Core
+ */
+
+// Because we don't have core yet.
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "copy"]
+trait Copy {
+}
+
+impl Copy for isize {}
+
+#[lang = "receiver"]
+trait Receiver {
+}
+
+#[lang = "freeze"]
+pub(crate) unsafe auto trait Freeze {}
+
+mod libc {
+    #[link(name = "c")]
+    extern "C" {
+        pub fn printf(format: *const i8, ...) -> i32;
+    }
+}
+
+/*
+ * Code
+ */
+
+struct Test {
+    field: isize,
+}
+
+struct Two {
+    two: isize,
+}
+
+fn one() -> isize {
+    1
+}
+
+#[start]
+fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+    let test = Test {
+        field: one(),
+    };
+    let two = Two {
+        two: 2,
+    };
+    unsafe {
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.field);
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, two.two);
+    }
+    0
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/tuple.rs b/compiler/rustc_codegen_gcc/tests/run/tuple.rs
new file mode 100644
index 00000000000..8a7d85ae867
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/tuple.rs
@@ -0,0 +1,52 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+//   stdout: 3
+
+#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
+#![allow(internal_features)]
+
+#![no_std]
+#![no_core]
+
+/*
+ * Core
+ */
+
+// Because we don't have core yet.
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "copy"]
+trait Copy {
+}
+
+impl Copy for isize {}
+
+#[lang = "receiver"]
+trait Receiver {
+}
+
+#[lang = "freeze"]
+pub(crate) unsafe auto trait Freeze {}
+
+mod libc {
+    #[link(name = "c")]
+    extern "C" {
+        pub fn printf(format: *const i8, ...) -> i32;
+    }
+}
+
+/*
+ * Code
+ */
+
+#[start]
+fn main(mut argc: isize, _argv: *const *const u8) -> isize {
+    let test: (isize, isize, isize) = (3, 1, 4);
+    unsafe {
+        libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.0);
+    }
+    0
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/volatile.rs b/compiler/rustc_codegen_gcc/tests/run/volatile.rs
new file mode 100644
index 00000000000..8b043312593
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/volatile.rs
@@ -0,0 +1,26 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+
+use std::mem::MaybeUninit;
+
+#[derive(Debug)]
+struct Struct {
+    pointer: *const (),
+    func: unsafe fn(*const ()),
+}
+
+fn func(ptr: *const ()) {
+}
+
+fn main() {
+    let mut x = MaybeUninit::<&Struct>::uninit();
+    x.write(&Struct {
+        pointer: std::ptr::null(),
+        func,
+    });
+    let x = unsafe { x.assume_init() };
+    let value = unsafe { (x as *const Struct).read_volatile() };
+    println!("{:?}", value);
+}
diff --git a/compiler/rustc_codegen_gcc/tests/run/volatile2.rs b/compiler/rustc_codegen_gcc/tests/run/volatile2.rs
new file mode 100644
index 00000000000..a177b817ab3
--- /dev/null
+++ b/compiler/rustc_codegen_gcc/tests/run/volatile2.rs
@@ -0,0 +1,113 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+
+mod libc {
+    #[link(name = "c")]
+    extern "C" {
+        pub fn puts(s: *const u8) -> i32;
+
+        pub fn sigaction(signum: i32, act: *const sigaction, oldact: *mut sigaction) -> i32;
+        pub fn mmap(addr: *mut (), len: usize, prot: i32, flags: i32, fd: i32, offset: i64) -> *mut ();
+        pub fn mprotect(addr: *mut (), len: usize, prot: i32) -> i32;
+    }
+
+    pub const PROT_READ: i32 = 1;
+    pub const PROT_WRITE: i32 = 2;
+    pub const MAP_PRIVATE: i32 = 0x0002;
+    pub const MAP_ANONYMOUS: i32 = 0x0020;
+    pub const MAP_FAILED: *mut u8 = !0 as *mut u8;
+
+    /// glibc sigaction
+    #[repr(C)]
+    pub struct sigaction {
+        pub sa_sigaction: Option<unsafe extern "C" fn(i32, *mut (), *mut ())>,
+        pub sa_mask: [u32; 32],
+        pub sa_flags: i32,
+        pub sa_restorer: Option<unsafe extern "C" fn()>,
+    }
+
+    pub const SA_SIGINFO: i32 = 0x00000004;
+    pub const SIGSEGV: i32 = 11;
+}
+
+static mut COUNT: u32 = 0;
+static mut STORAGE: *mut u8 = core::ptr::null_mut();
+const PAGE_SIZE: usize = 1 << 15;
+
+fn main() {
+    unsafe {
+        // Register a segfault handler
+        libc::sigaction(
+            libc::SIGSEGV,
+            &libc::sigaction {
+                sa_sigaction: Some(segv_handler),
+                sa_flags: libc::SA_SIGINFO,
+                ..core::mem::zeroed()
+            },
+            core::ptr::null_mut(),
+        );
+
+        STORAGE = libc::mmap(
+            core::ptr::null_mut(),
+            PAGE_SIZE * 2,
+            0,
+            libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
+            -1,
+            0,
+        ).cast();
+        if STORAGE == libc::MAP_FAILED {
+            panic!("error: mmap failed");
+        }
+
+        let p_count = (&mut COUNT) as *mut u32;
+        p_count.write_volatile(0);
+
+        // Trigger segfaults
+        STORAGE.add(0).write_volatile(1);
+        STORAGE.add(PAGE_SIZE).write_volatile(1);
+        STORAGE.add(0).write_volatile(1);
+        STORAGE.add(PAGE_SIZE).write_volatile(1);
+        STORAGE.add(0).write_volatile(1);
+        STORAGE.add(PAGE_SIZE).write_volatile(1);
+        STORAGE.add(0).read_volatile();
+        STORAGE.add(PAGE_SIZE).read_volatile();
+        STORAGE.add(0).read_volatile();
+        STORAGE.add(PAGE_SIZE).read_volatile();
+        STORAGE.add(0).read_volatile();
+        STORAGE.add(PAGE_SIZE).read_volatile();
+        STORAGE.add(0).write_volatile(1);
+        STORAGE.add(PAGE_SIZE).write_volatile(1);
+
+        // The segfault handler should have been called for every `write_volatile` and
+        // `read_volatile` in `STORAGE`. If the compiler ignores volatility, some of these writes
+        // will be combined, causing a different number of segfaults.
+        //
+        // This `p_count` read is done by a volatile read. If the compiler
+        // ignores volatility, the compiler will speculate that `*p_count` is
+        // unchanged and remove this check, failing the test.
+        if p_count.read_volatile() != 14 {
+            panic!("error: segfault count mismatch: {}", p_count.read_volatile());
+        }
+    }
+}
+
+unsafe extern "C" fn segv_handler(_: i32, _: *mut (), _: *mut ()) {
+    let p_count = (&mut COUNT) as *mut u32;
+    p_count.write_volatile(p_count.read_volatile() + 1);
+    let count = p_count.read_volatile();
+
+    // Toggle the protected page so that the handler will be called for
+    // each `write_volatile`
+    libc::mprotect(
+        STORAGE.cast(),
+        PAGE_SIZE,
+        if count % 2 == 1 { libc::PROT_READ | libc::PROT_WRITE } else { 0 },
+    );
+    libc::mprotect(
+        STORAGE.add(PAGE_SIZE).cast(),
+        PAGE_SIZE,
+        if count % 2 == 0 { libc::PROT_READ | libc::PROT_WRITE } else { 0 },
+    );
+}