From e2f6b280ea13e48bff86254549988e61eee37139 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 19 Jan 2018 21:43:53 -0800 Subject: Update DW_OP_plus to DW_OP_plus_uconst LLVM <= 4.0 used a non-standard interpretation of `DW_OP_plus`. In the DWARF standard, this adds two items on the expressions stack. LLVM's behavior was more like DWARF's `DW_OP_plus_uconst` -- adding a constant that follows the op. The patch series starting with [D33892] switched to the standard DWARF interpretation, so we need to follow. [D33892]: https://reviews.llvm.org/D33892 --- src/rustllvm/RustWrapper.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 95130d596e1..0fe533d447b 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -866,7 +866,14 @@ extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() { return dwarf::DW_OP_deref; } -extern "C" int64_t LLVMRustDIBuilderCreateOpPlus() { return dwarf::DW_OP_plus; } +extern "C" int64_t LLVMRustDIBuilderCreateOpPlusUconst() { +#if LLVM_VERSION_GE(5, 0) + return dwarf::DW_OP_plus_uconst; +#else + // older LLVM used `plus` to behave like `plus_uconst`. + return dwarf::DW_OP_plus; +#endif +} extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) { RawRustStringOstream OS(Str); -- cgit 1.4.1-3-g733a5 From 7188706c4fbbae660fa7eb6f2bf13130ddf1726a Mon Sep 17 00:00:00 2001 From: "A.J. Gardner" Date: Sat, 20 Jan 2018 14:32:33 -0600 Subject: Teach rustc about DW_AT_noreturn and a few more DIFlags --- src/librustc_llvm/ffi.rs | 4 ++++ src/librustc_trans/debuginfo/mod.rs | 3 +++ src/rustllvm/RustWrapper.cpp | 20 ++++++++++++++++++-- src/test/codegen/noreturnflag.rs | 29 +++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/test/codegen/noreturnflag.rs (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index b97e37f4c8f..8602c559da9 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -498,6 +498,10 @@ pub mod debuginfo { const FlagStaticMember = (1 << 12); const FlagLValueReference = (1 << 13); const FlagRValueReference = (1 << 14); + const FlagExternalTypeRef = (1 << 15); + const FlagIntroducedVirtual = (1 << 18); + const FlagBitField = (1 << 19); + const FlagNoReturn = (1 << 20); const FlagMainSubprogram = (1 << 21); } } diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index b46e12d9d5b..9071eb776d5 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -270,6 +270,9 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } None => {} }; + if sig.output().is_never() { + flags = flags | DIFlags::FlagNoReturn; + } let fn_metadata = unsafe { llvm::LLVMRustDIBuilderCreateFunction( diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 95130d596e1..2e8207d1cbb 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -457,9 +457,13 @@ enum class LLVMRustDIFlags : uint32_t { FlagStaticMember = (1 << 12), FlagLValueReference = (1 << 13), FlagRValueReference = (1 << 14), - FlagMainSubprogram = (1 << 21), + FlagExternalTypeRef = (1 << 15), + FlagIntroducedVirtual = (1 << 18), + FlagBitField = (1 << 19), + FlagNoReturn = (1 << 20), + FlagMainSubprogram = (1 << 21), // Do not add values that are not supported by the minimum LLVM - // version we support! + // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def }; inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) { @@ -545,6 +549,18 @@ static unsigned fromRust(LLVMRustDIFlags Flags) { Result |= DINode::DIFlags::FlagRValueReference; } #if LLVM_RUSTLLVM || LLVM_VERSION_GE(4, 0) + if (isSet(Flags & LLVMRustDIFlags::FlagExternalTypeRef)) { + Result |= DINode::DIFlags::FlagExternalTypeRef; + } + if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) { + Result |= DINode::DIFlags::FlagIntroducedVirtual; + } + if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) { + Result |= DINode::DIFlags::FlagBitField; + } + if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) { + Result |= DINode::DIFlags::FlagNoReturn; + } if (isSet(Flags & LLVMRustDIFlags::FlagMainSubprogram)) { Result |= DINode::DIFlags::FlagMainSubprogram; } diff --git a/src/test/codegen/noreturnflag.rs b/src/test/codegen/noreturnflag.rs new file mode 100644 index 00000000000..473fed8e046 --- /dev/null +++ b/src/test/codegen/noreturnflag.rs @@ -0,0 +1,29 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-tidy-linelength +// min-llvm-version 3.8 + +// compile-flags: -g -C no-prepopulate-passes + +// CHECK-LABEL: foo +// CHECK: {{.*}}DISubprogram{{.*}} name: "foo",{{.*}}DIFlagNoReturn{{.*}} + +#[no_mangle] +pub fn foo() -> ! { + loop {} +} + +// CHECK-LABEL: main +// CHECK: {{.*}}DISubprogram{{.*}}name: "main",{{.*}}DIFlagMainSubprogram{{.*}} + +pub fn main() { + foo(); +} -- cgit 1.4.1-3-g733a5 From e0f9b26899ea16bb2b6b966266e46698ebad9c4a Mon Sep 17 00:00:00 2001 From: "A.J. Gardner" Date: Sun, 21 Jan 2018 12:36:25 -0600 Subject: Ensure test doesn't run with llvm 3.9 --- src/rustllvm/RustWrapper.cpp | 2 +- src/test/codegen/noreturnflag.rs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 2e8207d1cbb..42ddf5663f9 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -548,7 +548,6 @@ static unsigned fromRust(LLVMRustDIFlags Flags) { if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) { Result |= DINode::DIFlags::FlagRValueReference; } -#if LLVM_RUSTLLVM || LLVM_VERSION_GE(4, 0) if (isSet(Flags & LLVMRustDIFlags::FlagExternalTypeRef)) { Result |= DINode::DIFlags::FlagExternalTypeRef; } @@ -558,6 +557,7 @@ static unsigned fromRust(LLVMRustDIFlags Flags) { if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) { Result |= DINode::DIFlags::FlagBitField; } +#if LLVM_RUSTLLVM || LLVM_VERSION_GE(4, 0) if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) { Result |= DINode::DIFlags::FlagNoReturn; } diff --git a/src/test/codegen/noreturnflag.rs b/src/test/codegen/noreturnflag.rs index 3fa7921b444..24a5a4e44cb 100644 --- a/src/test/codegen/noreturnflag.rs +++ b/src/test/codegen/noreturnflag.rs @@ -9,7 +9,7 @@ // except according to those terms. // ignore-tidy-linelength -// min-llvm-version 3.8 +// min-llvm-version 4.0 // compile-flags: -g -C no-prepopulate-passes @@ -19,8 +19,6 @@ fn foo() -> ! { loop {} } -// CHECK: {{.*}}DISubprogram{{.*}}name: "main",{{.*}}DIFlagMainSubprogram{{.*}} - pub fn main() { foo(); } -- cgit 1.4.1-3-g733a5 From 9eeecd2adad8c5c94348dbd1c61709fa49f65ff8 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 22 Jan 2018 17:28:23 -0800 Subject: llvm6: Tweak fast math intrinsics Looks like they did some refactoring of flags in the backend and this should catch us up! The "unsafe algebra" boolean has been split into a number of boolean flags for various operations, and this updates to use the `setFast` function which should hopefully have the same behavior as before. This was updated in llvm-mirror/llvm@00e900afd --- src/rustllvm/RustWrapper.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 0fe533d447b..3491e5a4aed 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -315,7 +315,11 @@ extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn, // enable fpmath flag UnsafeAlgebra extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) { if (auto I = dyn_cast(unwrap(V))) { +#if LLVM_VERSION_GE(6, 0) + I->setFast(true); +#else I->setHasUnsafeAlgebra(true); +#endif } } -- cgit 1.4.1-3-g733a5 From 6b7b6b63a928479a29d9fc1282e553e409c66934 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 22 Jan 2018 14:23:30 -0800 Subject: rustc: Upgrade to LLVM 6 The following submodules have been updated for a new version of LLVM: - `src/llvm` - `src/libcompiler_builtins` - transitively contains compiler-rt - `src/dlmalloc` This also updates the docker container for dist-i686-freebsd as the old 16.04 container is no longer capable of building LLVM. The compiler-rt/compiler-builtins and dlmalloc updates are pretty routine without much interesting happening, but the LLVM update here is of particular note. Unlike previous updates I haven't cherry-picked all existing patches we had on top of our LLVM branch as we have a [huge amount][patches4] and have at this point forgotten what most of them are for. Instead I started from the current `release_60` branch in LLVM and only applied patches that were necessary to get our tests working and building. The current set of custom rustc-specific patches included in this LLVM update are: * rust-lang/llvm@1187443 - this is how we actually implement `cfg(target_feature)` for now and continues to not be upstreamed. While a hazard for SIMD stabilization this commit is otherwise keeping the status quo of a small rustc-specific feature. * rust-lang/llvm@013f2ec - this is a rustc-specific optimization that we haven't upstreamed, notably teaching LLVM about our allocation-related routines (which aren't malloc/free). Once we stabilize the global allocator routines we will likely want to upstream this patch, but for now it seems reasonable to keep it on our fork. * rust-lang/llvm@a65bbfd - I found this necessary to fix compilation of LLVM in our 32-bit linux container. I'm not really sure why it's necessary but my guess is that it's because of the absolutely ancient glibc that we're using. In any case it's only updating pieces we're not actually using in LLVM so I'm hoping it'll turn out alright. This doesn't seem like something we'll want to upstream.c * rust-lang/llvm@77ab1f0 - this is what's actually enabling LLVM to build in our i686-freebsd container, I'm not really sure what's going on but we for sure probably don't want to upstream this and otherwise it seems not too bad for now at least. * rust-lang/llvm@9eb9267 - we currently suffer on MSVC from an [upstream bug] which although diagnosed to a particular revision isn't currently fixed upstream (and the bug itself doesn't seem too active). This commit is a partial revert of the suspected cause of this regression (found via a bisection). I'm sort of hoping that this eventually gets fixed upstream with a similar fix (which we can replace in our branch), but for now I'm also hoping it's a relatively harmless change to have. After applying these patches (plus one [backport] which should be [backported upstream][llvm-back]) I believe we should have all tests working on all platforms in our current test suite. I'm like 99% sure that we'll need some more backports as issues are reported for LLVM 6 when this propagates through nightlies, but that's sort of just par for the course nowadays! In any case though some extra scrutiny of the patches here would definitely be welcome, along with scrutiny of the "missing patches" like a [change to pass manager order](rust-lang/llvm@27174447533), [another change to pass manager order](rust-lang/llvm@c782febb7b9), some [compile fixes for sparc](rust-lang/llvm@1a83de63c42), and some [fixes for solaris](rust-lang/llvm@c2bfe0abb). [patches4]: https://github.com/rust-lang/llvm/compare/5401fdf23...rust-llvm-release-4-0-1 [backport]: https://github.com/rust-lang/llvm/commit/5c54c252db [llvm-back]: https://bugs.llvm.org/show_bug.cgi?id=36114 [upstream bug]: https://bugs.llvm.org/show_bug.cgi?id=36096 --- The update to LLVM 6 is desirable for a number of reasons, notably: * This'll allow us to keep up with the upstream wasm backend, picking up new features as they start landing. * Upstream LLVM has fixed a number of SIMD-related compilation errors, especially around AVX-512 and such. * There's a few assorted known bugs which are fixed in LLVM 5 and aren't fixed in the LLVM 4 branch we're using. * Overall it's not a great idea to stagnate with our codegen backend! This update is mostly powered by #47730 which is allowing us to update LLVM *independent* of the version of LLVM that Emscripten is locked to. This means that when compiling code for Emscripten we'll still be using the old LLVM 4 backend, but when compiling code for any other target we'll be using the new LLVM 6 target. Once Emscripten updates we may no longer need this distinction, but we're not sure when that will happen! Closes #43370 Closes #43418 Closes #47015 Closes #47683 Closes rust-lang-nursery/stdsimd#157 Closes rust-lang-nursery/rust-wasm#3 --- src/bootstrap/native.rs | 2 +- src/ci/docker/dist-i686-freebsd/Dockerfile | 2 +- src/dlmalloc | 2 +- src/libcompiler_builtins | 2 +- src/librustc_resolve/resolve_imports.rs | 7 ++++-- src/llvm | 2 +- src/rustllvm/RustWrapper.cpp | 2 ++ src/rustllvm/llvm-rebuild-trigger | 2 +- src/test/run-pass/backtrace-debuginfo.rs | 34 ++++++++++++++++++++++++------ 9 files changed, 41 insertions(+), 14 deletions(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 3f30756a568..2ea02624403 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -186,7 +186,7 @@ impl Step for Llvm { } // http://llvm.org/docs/HowToCrossCompileLLVM.html - if target != build.build { + if target != build.build && !emscripten { builder.ensure(Llvm { target: build.build, emscripten: false, diff --git a/src/ci/docker/dist-i686-freebsd/Dockerfile b/src/ci/docker/dist-i686-freebsd/Dockerfile index 686afc97289..673fa4c0c4b 100644 --- a/src/ci/docker/dist-i686-freebsd/Dockerfile +++ b/src/ci/docker/dist-i686-freebsd/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:16.04 +FROM ubuntu:18.04 RUN apt-get update && apt-get install -y --no-install-recommends \ clang \ diff --git a/src/dlmalloc b/src/dlmalloc index d3812c3acca..a2b424b6002 160000 --- a/src/dlmalloc +++ b/src/dlmalloc @@ -1 +1 @@ -Subproject commit d3812c3accaee7ad23068ed4fc089cc05c7a538f +Subproject commit a2b424b600235af58f453577c2da1b0e1de2ffa5 diff --git a/src/libcompiler_builtins b/src/libcompiler_builtins index 0a95675bab8..345447948f7 160000 --- a/src/libcompiler_builtins +++ b/src/libcompiler_builtins @@ -1 +1 @@ -Subproject commit 0a95675bab808c49f86208bacc89c5d9c53ac43f +Subproject commit 345447948f7a51eca970fa036cefd613d54a4f79 diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 07b08e2e61a..95a507ab9e3 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -1026,9 +1026,12 @@ fn import_path_to_string(names: &[SpannedIdent], if names.is_empty() { import_directive_subclass_to_string(subclass) } else { - (format!("{}::{}", + let x = format!("{}::{}", names_to_string(names), - import_directive_subclass_to_string(subclass))) + import_directive_subclass_to_string(subclass)); + assert!(!names.is_empty()); + assert!(!x.starts_with("::")); + return x } } } diff --git a/src/llvm b/src/llvm index bc344d5bc23..9f81beaf326 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit bc344d5bc23c61ff9baf82d268a0edf199933cc3 +Subproject commit 9f81beaf32608fbe1fe0f2a82f974e800e9d8c62 diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 611d63f6a4d..4dfc4029d75 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -552,9 +552,11 @@ static unsigned fromRust(LLVMRustDIFlags Flags) { if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) { Result |= DINode::DIFlags::FlagRValueReference; } +#if LLVM_VERSION_LE(4, 0) if (isSet(Flags & LLVMRustDIFlags::FlagExternalTypeRef)) { Result |= DINode::DIFlags::FlagExternalTypeRef; } +#endif if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) { Result |= DINode::DIFlags::FlagIntroducedVirtual; } diff --git a/src/rustllvm/llvm-rebuild-trigger b/src/rustllvm/llvm-rebuild-trigger index 2635ca73303..3cd044708ce 100644 --- a/src/rustllvm/llvm-rebuild-trigger +++ b/src/rustllvm/llvm-rebuild-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be (optionally) cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -2018-01-25 +2018-02-09 diff --git a/src/test/run-pass/backtrace-debuginfo.rs b/src/test/run-pass/backtrace-debuginfo.rs index e8b5f3490e5..2b82a894363 100644 --- a/src/test/run-pass/backtrace-debuginfo.rs +++ b/src/test/run-pass/backtrace-debuginfo.rs @@ -15,11 +15,14 @@ // Unfortunately, LLVM has no "disable" option for this, so we have to set // "enable" to 0 instead. -// compile-flags:-g -Cllvm-args=-enable-tail-merge=0 +// compile-flags:-g -Cllvm-args=-enable-tail-merge=0 -Cllvm-args=-opt-bisect-limit=0 // ignore-pretty issue #37195 // ignore-cloudabi spawning processes is not supported // ignore-emscripten spawning processes is not supported +// note that above `-opt-bisect-limit=0` is used to basically disable +// optimizations + use std::env; #[path = "backtrace-debuginfo-aux.rs"] mod aux; @@ -114,18 +117,26 @@ fn outer(mut counter: i32, main_pos: Pos) { inner_inlined(&mut counter, main_pos, pos!()); } -fn check_trace(output: &str, error: &str) { +fn check_trace(output: &str, error: &str) -> Result<(), String> { // reverse the position list so we can start with the last item (which was the first line) let mut remaining: Vec<&str> = output.lines().map(|s| s.trim()).rev().collect(); - assert!(error.contains("stack backtrace"), "no backtrace in the error: {}", error); + if !error.contains("stack backtrace") { + return Err(format!("no backtrace found in stderr:\n{}", error)) + } for line in error.lines() { if !remaining.is_empty() && line.contains(remaining.last().unwrap()) { remaining.pop(); } } - assert!(remaining.is_empty(), - "trace does not match position list: {}\n---\n{}", error, output); + if !remaining.is_empty() { + return Err(format!("trace does not match position list\n\ + still need to find {:?}\n\n\ + --- stdout\n{}\n\ + --- stderr\n{}", + remaining, output, error)) + } + Ok(()) } fn run_test(me: &str) { @@ -133,6 +144,7 @@ fn run_test(me: &str) { use std::process::Command; let mut i = 0; + let mut errors = Vec::new(); loop { let out = Command::new(me) .env("RUST_BACKTRACE", "full") @@ -143,10 +155,20 @@ fn run_test(me: &str) { assert!(output.contains("done."), "bad output for successful run: {}", output); break; } else { - check_trace(output, error); + if let Err(e) = check_trace(output, error) { + errors.push(e); + } } i += 1; } + if errors.len() > 0 { + for error in errors { + println!("---------------------------------------"); + println!("{}", error); + } + + panic!("found some errors"); + } } #[inline(never)] -- cgit 1.4.1-3-g733a5 From 43e8ac27d9bf645b66a15f762be6969e9fe16285 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 12 Feb 2018 08:38:46 -0800 Subject: rustc: Persist LLVM's `Linker` in Fat LTO This commit updates our Fat LTO logic to tweak our custom wrapper around LLVM's "link modules" functionality. Previously whenever the `LLVMRustLinkInExternalBitcode` function was called it would call LLVM's `Linker::linkModules` wrapper. Internally this would crate an instance of a `Linker` which internally creates an instance of an `IRMover`. Unfortunately for us the creation of `IRMover` is somewhat O(n) with the input module. This means that every time we linked a module it was O(n) with respect to the entire module we had built up! Now the modules we build up during LTO are quite large, so this quickly started creating an O(n^2) problem for us! Discovered in #48025 it turns out this has always been a problem and we just haven't noticed it. It became particularly worse recently though due to most libraries having 16x more object files than they previously did (1 -> 16). This commit fixes this performance issue by preserving the `Linker` instance across all links into the main LLVM module. This means we only create one `IRMover` and allows LTO to progress much speedier. From the `cargo-cache` project in #48025 a **full build** locally when from 5m15s to 2m24s. Looking at the timing logs each object file was linked in in single-digit millisecond rather than hundreds, clearly being a nice improvement! Closes #48025 --- src/librustc_llvm/build.rs | 1 + src/librustc_llvm/ffi.rs | 10 +++++- src/librustc_trans/back/lto.rs | 40 ++++++++++++++++++----- src/rustllvm/Linker.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++ src/rustllvm/RustWrapper.cpp | 40 ----------------------- 5 files changed, 114 insertions(+), 49 deletions(-) create mode 100644 src/rustllvm/Linker.cpp (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 49b93f3c7d6..54e3f544acb 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -155,6 +155,7 @@ fn main() { cfg.file("../rustllvm/PassWrapper.cpp") .file("../rustllvm/RustWrapper.cpp") .file("../rustllvm/ArchiveWrapper.cpp") + .file("../rustllvm/Linker.cpp") .cpp(true) .cpp_link_stdlib(None) // we handle this below .compile("rustllvm"); diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 99e43a2ddf9..e71bef512cf 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -444,6 +444,9 @@ pub type RustArchiveMemberRef = *mut RustArchiveMember_opaque; #[allow(missing_copy_implementations)] pub enum OperandBundleDef_opaque {} pub type OperandBundleDefRef = *mut OperandBundleDef_opaque; +#[allow(missing_copy_implementations)] +pub enum Linker_opaque {} +pub type LinkerRef = *mut Linker_opaque; pub type DiagnosticHandler = unsafe extern "C" fn(DiagnosticInfoRef, *mut c_void); pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_void, c_uint); @@ -1608,7 +1611,6 @@ extern "C" { pub fn LLVMRustPrintPasses(); pub fn LLVMRustSetNormalizedTarget(M: ModuleRef, triple: *const c_char); pub fn LLVMRustAddAlwaysInlinePass(P: PassManagerBuilderRef, AddLifetimes: bool); - pub fn LLVMRustLinkInExternalBitcode(M: ModuleRef, bc: *const c_char, len: size_t) -> bool; pub fn LLVMRustRunRestrictionPass(M: ModuleRef, syms: *const *const c_char, len: size_t); pub fn LLVMRustMarkAllFunctionsNounwind(M: ModuleRef); @@ -1724,4 +1726,10 @@ extern "C" { CU2: *mut *mut c_void); pub fn LLVMRustThinLTOPatchDICompileUnit(M: ModuleRef, CU: *mut c_void); pub fn LLVMRustThinLTORemoveAvailableExternally(M: ModuleRef); + + pub fn LLVMRustLinkerNew(M: ModuleRef) -> LinkerRef; + pub fn LLVMRustLinkerAdd(linker: LinkerRef, + bytecode: *const c_char, + bytecode_len: usize) -> bool; + pub fn LLVMRustLinkerFree(linker: LinkerRef); } diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs index 9ff5bcf7a33..a3327038019 100644 --- a/src/librustc_trans/back/lto.rs +++ b/src/librustc_trans/back/lto.rs @@ -247,22 +247,20 @@ fn fat_lto(cgcx: &CodegenContext, // know much about the memory management here so we err on the side of being // save and persist everything with the original module. let mut serialized_bitcode = Vec::new(); + let mut linker = Linker::new(llmod); for (bc_decoded, name) in serialized_modules { info!("linking {:?}", name); - time(cgcx.time_passes, &format!("ll link {:?}", name), || unsafe { + time(cgcx.time_passes, &format!("ll link {:?}", name), || { let data = bc_decoded.data(); - if llvm::LLVMRustLinkInExternalBitcode(llmod, - data.as_ptr() as *const libc::c_char, - data.len() as libc::size_t) { - Ok(()) - } else { + linker.add(&data).map_err(|()| { let msg = format!("failed to load bc of {:?}", name); - Err(write::llvm_err(&diag_handler, msg)) - } + write::llvm_err(&diag_handler, msg) + }) })?; timeline.record(&format!("link {:?}", name)); serialized_bitcode.push(bc_decoded); } + drop(linker); cgcx.save_temp_bitcode(&module, "lto.input"); // Internalize everything that *isn't* in our whitelist to help strip out @@ -289,6 +287,32 @@ fn fat_lto(cgcx: &CodegenContext, }]) } +struct Linker(llvm::LinkerRef); + +impl Linker { + fn new(llmod: ModuleRef) -> Linker { + unsafe { Linker(llvm::LLVMRustLinkerNew(llmod)) } + } + + fn add(&mut self, bytecode: &[u8]) -> Result<(), ()> { + unsafe { + if llvm::LLVMRustLinkerAdd(self.0, + bytecode.as_ptr() as *const libc::c_char, + bytecode.len()) { + Ok(()) + } else { + Err(()) + } + } + } +} + +impl Drop for Linker { + fn drop(&mut self) { + unsafe { llvm::LLVMRustLinkerFree(self.0); } + } +} + /// Prepare "thin" LTO to get run on these modules. /// /// The general structure of ThinLTO is quite different from the structure of diff --git a/src/rustllvm/Linker.cpp b/src/rustllvm/Linker.cpp new file mode 100644 index 00000000000..534e4b91090 --- /dev/null +++ b/src/rustllvm/Linker.cpp @@ -0,0 +1,72 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#include "llvm/Linker/Linker.h" + +#include "rustllvm.h" + +using namespace llvm; + +struct RustLinker { + Linker L; + LLVMContext &Ctx; + + RustLinker(Module &M) : + L(M), + Ctx(M.getContext()) + {} +}; + +extern "C" RustLinker* +LLVMRustLinkerNew(LLVMModuleRef DstRef) { + Module *Dst = unwrap(DstRef); + + auto Ret = llvm::make_unique(*Dst); + return Ret.release(); +} + +extern "C" void +LLVMRustLinkerFree(RustLinker *L) { + delete L; +} + +extern "C" bool +LLVMRustLinkerAdd(RustLinker *L, char *BC, size_t Len) { + std::unique_ptr Buf = + MemoryBuffer::getMemBufferCopy(StringRef(BC, Len)); + +#if LLVM_VERSION_GE(4, 0) + Expected> SrcOrError = + llvm::getLazyBitcodeModule(Buf->getMemBufferRef(), L->Ctx); + if (!SrcOrError) { + LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str()); + return false; + } + + auto Src = std::move(*SrcOrError); +#else + ErrorOr> Src = + llvm::getLazyBitcodeModule(std::move(Buf), L->Ctx); + if (!Src) { + LLVMRustSetLastError(Src.getError().message().c_str()); + return false; + } +#endif + +#if LLVM_VERSION_GE(4, 0) + if (L->L.linkInModule(std::move(Src))) { +#else + if (L->L.linkInModule(std::move(Src.get()))) { +#endif + LLVMRustSetLastError(""); + return false; + } + return true; +} diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 4dfc4029d75..27d5496f576 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -916,46 +916,6 @@ extern "C" void LLVMRustWriteValueToString(LLVMValueRef V, } } -extern "C" bool LLVMRustLinkInExternalBitcode(LLVMModuleRef DstRef, char *BC, - size_t Len) { - Module *Dst = unwrap(DstRef); - - std::unique_ptr Buf = - MemoryBuffer::getMemBufferCopy(StringRef(BC, Len)); - -#if LLVM_VERSION_GE(4, 0) - Expected> SrcOrError = - llvm::getLazyBitcodeModule(Buf->getMemBufferRef(), Dst->getContext()); - if (!SrcOrError) { - LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str()); - return false; - } - - auto Src = std::move(*SrcOrError); -#else - ErrorOr> Src = - llvm::getLazyBitcodeModule(std::move(Buf), Dst->getContext()); - if (!Src) { - LLVMRustSetLastError(Src.getError().message().c_str()); - return false; - } -#endif - - std::string Err; - - raw_string_ostream Stream(Err); - DiagnosticPrinterRawOStream DP(Stream); -#if LLVM_VERSION_GE(4, 0) - if (Linker::linkModules(*Dst, std::move(Src))) { -#else - if (Linker::linkModules(*Dst, std::move(Src.get()))) { -#endif - LLVMRustSetLastError(Err.c_str()); - return false; - } - return true; -} - // Note that the two following functions look quite similar to the // LLVMGetSectionName function. Sadly, it appears that this function only // returns a char* pointer, which isn't guaranteed to be null-terminated. The -- cgit 1.4.1-3-g733a5 From 01cc5b3e195bb01088fdd59638f0d8c6d0a78142 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Tue, 13 Mar 2018 16:46:55 +0100 Subject: add intrinsics for portable packed simd vector reductions --- src/librustc_llvm/ffi.rs | 40 ++++ src/librustc_trans/builder.rs | 75 +++++++ src/librustc_trans/intrinsic.rs | 219 ++++++++++++++++++++- src/librustc_typeck/check/intrinsic.rs | 5 + src/rustllvm/RustWrapper.cpp | 46 +++++ .../run-pass/simd-intrinsic-generic-reduction.rs | 143 ++++++++++++++ 6 files changed, 525 insertions(+), 3 deletions(-) create mode 100644 src/test/run-pass/simd-intrinsic-generic-reduction.rs (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 0ec5700f5f3..00547017349 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -1201,6 +1201,46 @@ extern "C" { Name: *const c_char) -> ValueRef; + pub fn LLVMRustBuildVectorReduceFAdd(B: BuilderRef, + Acc: ValueRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceFMul(B: BuilderRef, + Acc: ValueRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceAdd(B: BuilderRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceMul(B: BuilderRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceAnd(B: BuilderRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceOr(B: BuilderRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceXor(B: BuilderRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceMin(B: BuilderRef, + Src: ValueRef, + IsSigned: bool) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceMax(B: BuilderRef, + Src: ValueRef, + IsSigned: bool) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceFMin(B: BuilderRef, + Src: ValueRef, + IsNaN: bool) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceFMax(B: BuilderRef, + Src: ValueRef, + IsNaN: bool) + -> ValueRef; + pub fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef, Name: *const c_char) -> ValueRef; pub fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *const c_char) -> ValueRef; pub fn LLVMBuildPtrDiff(B: BuilderRef, diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index d4e05a18e3a..2c38197d68e 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -955,6 +955,81 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } + pub fn vector_reduce_fadd_fast(&self, acc: ValueRef, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.fadd_fast"); + unsafe { + let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src); + llvm::LLVMRustSetHasUnsafeAlgebra(instr); + instr + } + } + pub fn vector_reduce_fmul_fast(&self, acc: ValueRef, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.fmul_fast"); + unsafe { + let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src); + llvm::LLVMRustSetHasUnsafeAlgebra(instr); + instr + } + } + pub fn vector_reduce_add(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.add"); + unsafe { + llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) + } + } + pub fn vector_reduce_mul(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.mul"); + unsafe { + llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) + } + } + pub fn vector_reduce_and(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.and"); + unsafe { + llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) + } + } + pub fn vector_reduce_or(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.or"); + unsafe { + llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) + } + } + pub fn vector_reduce_xor(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.xor"); + unsafe { + llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) + } + } + pub fn vector_reduce_fmin_fast(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.fmin_fast"); + unsafe { + let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, false); + llvm::LLVMRustSetHasUnsafeAlgebra(instr); + instr + } + } + pub fn vector_reduce_fmax_fast(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.fmax_fast"); + unsafe { + let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, false); + llvm::LLVMRustSetHasUnsafeAlgebra(instr); + instr + } + } + pub fn vector_reduce_min(&self, src: ValueRef, is_signed: bool) -> ValueRef { + self.count_insn("vector.reduce.min"); + unsafe { + llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) + } + } + pub fn vector_reduce_max(&self, src: ValueRef, is_signed: bool) -> ValueRef { + self.count_insn("vector.reduce.max"); + unsafe { + llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) + } + } + pub fn extract_value(&self, agg_val: ValueRef, idx: u64) -> ValueRef { self.count_insn("extractvalue"); assert_eq!(idx as c_uint as u64, idx); diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 3f87ce7e047..011273f02e1 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -1018,14 +1018,22 @@ fn generic_simd_intrinsic<'a, 'tcx>( name, $($fmt)*)); } } - macro_rules! require { - ($cond: expr, $($fmt: tt)*) => { - if !$cond { + macro_rules! return_error { + ($($fmt: tt)*) => { + { emit_error!($($fmt)*); return Err(()); } } } + + macro_rules! require { + ($cond: expr, $($fmt: tt)*) => { + if !$cond { + return_error!($($fmt)*); + } + }; + } macro_rules! require_simd { ($ty: expr, $position: expr) => { require!($ty.is_simd(), "expected SIMD {} type, found non-SIMD `{}`", $position, $ty) @@ -1142,6 +1150,211 @@ fn generic_simd_intrinsic<'a, 'tcx>( return Ok(bx.extract_element(args[0].immediate(), args[1].immediate())) } + if name == "simd_reduce_add" { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_i) => { + Ok(bx.vector_reduce_add(args[0].immediate())) + }, + ty::TyUint(_u) => { + Ok(bx.vector_reduce_add(args[0].immediate())) + }, + ty::TyFloat(f) => { + // undef as accumulator makes the reduction unordered: + let acc = match f.bit_width() { + 32 => C_undef(Type::f32(bx.cx)), + 64 => C_undef(Type::f64(bx.cx)), + v => { + return_error!( + "unsupported {} from `{}` with element `{}` of size `{}` to `{}`", + "simd_reduce_add", in_ty, in_elem, v, ret_ty) + } + }; + Ok(bx.vector_reduce_fadd_fast(acc, args[0].immediate())) + } + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_add", in_ty, in_elem, ret_ty) + }, + } + } + + if name == "simd_reduce_mul" { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_i) => { + Ok(bx.vector_reduce_mul(args[0].immediate())) + }, + ty::TyUint(_u) => { + Ok(bx.vector_reduce_mul(args[0].immediate())) + }, + ty::TyFloat(f) => { + // undef as accumulator makes the reduction unordered: + let acc = match f.bit_width() { + 32 => C_undef(Type::f32(bx.cx)), + 64 => C_undef(Type::f64(bx.cx)), + v => { + return_error!( + "unsupported {} from `{}` with element `{}` of size `{}` to `{}`", + "simd_reduce_mul", in_ty, in_elem, v, ret_ty) + } + }; + Ok(bx.vector_reduce_fmul_fast(acc, args[0].immediate())) + } + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_mul", in_ty, in_elem, ret_ty) + }, + } + } + + if name == "simd_reduce_min" { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_i) => { + Ok(bx.vector_reduce_min(args[0].immediate(), true)) + }, + ty::TyUint(_u) => { + Ok(bx.vector_reduce_min(args[0].immediate(), false)) + }, + ty::TyFloat(_f) => { + Ok(bx.vector_reduce_fmin_fast(args[0].immediate())) + } + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_min", in_ty, in_elem, ret_ty) + }, + } + } + + if name == "simd_reduce_max" { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_i) => { + Ok(bx.vector_reduce_max(args[0].immediate(), true)) + }, + ty::TyUint(_u) => { + Ok(bx.vector_reduce_max(args[0].immediate(), false)) + }, + ty::TyFloat(_f) => { + Ok(bx.vector_reduce_fmax_fast(args[0].immediate())) + } + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_max", in_ty, in_elem, ret_ty) + }, + } + } + + if name == "simd_reduce_and" { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_i) => { + Ok(bx.vector_reduce_and(args[0].immediate())) + }, + ty::TyUint(_u) => { + Ok(bx.vector_reduce_and(args[0].immediate())) + }, + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_and", in_ty, in_elem, ret_ty) + }, + } + } + + if name == "simd_reduce_or" { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_i) => { + Ok(bx.vector_reduce_or(args[0].immediate())) + }, + ty::TyUint(_u) => { + Ok(bx.vector_reduce_or(args[0].immediate())) + }, + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_or", in_ty, in_elem, ret_ty) + }, + } + } + + if name == "simd_reduce_xor" { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_i) => { + Ok(bx.vector_reduce_xor(args[0].immediate())) + }, + ty::TyUint(_u) => { + Ok(bx.vector_reduce_xor(args[0].immediate())) + }, + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_xor", in_ty, in_elem, ret_ty) + }, + } + } + + if name == "simd_reduce_all" { + //require!(ret_ty == in_elem, + // "expected return type `{}` (element of input `{}`), found `{}`", + // in_elem, in_ty, ret_ty); + let i1 = Type::i1(bx.cx); + let i1xn = Type::vector(&i1, in_len as u64); + let v = bx.trunc(args[0].immediate(), i1xn); + + let red = match in_elem.sty { + ty::TyInt(_i) => { + bx.vector_reduce_and(v) + }, + ty::TyUint(_u) => { + bx.vector_reduce_and(v) + }, + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_and", in_ty, in_elem, ret_ty) + }, + }; + return Ok(bx.zext(red, Type::bool(bx.cx))); + } + + if name == "simd_reduce_any" { + //require!(ret_ty == in_elem, + // "expected return type `{}` (element of input `{}`), found `{}`", + // in_elem, in_ty, ret_ty); + let i1 = Type::i1(bx.cx); + let i1xn = Type::vector(&i1, in_len as u64); + let v = bx.trunc(args[0].immediate(), i1xn); + + let red = match in_elem.sty { + ty::TyInt(_i) => { + bx.vector_reduce_or(v) + }, + ty::TyUint(_u) => { + bx.vector_reduce_or(v) + }, + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_and", in_ty, in_elem, ret_ty) + }, + }; + return Ok(bx.zext(red, Type::bool(bx.cx))); + } + + if name == "simd_cast" { require_simd!(ret_ty, "return"); let out_len = ret_ty.simd_size(tcx); diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 2e00040d99a..f2d01c57f29 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -361,6 +361,11 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, "simd_insert" => (2, vec![param(0), tcx.types.u32, param(1)], param(0)), "simd_extract" => (2, vec![param(0), tcx.types.u32], param(1)), "simd_cast" => (2, vec![param(0)], param(1)), + "simd_reduce_all" | "simd_reduce_any" => (1, vec![param(0)], tcx.types.bool), + "simd_reduce_add" | "simd_reduce_mul" | + "simd_reduce_and" | "simd_reduce_or" | "simd_reduce_xor" | + "simd_reduce_min" | "simd_reduce_max" + => (2, vec![param(0)], param(1)), name if name.starts_with("simd_shuffle") => { match name["simd_shuffle".len()..].parse() { Ok(n) => { diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 27d5496f576..e749549201e 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1395,3 +1395,49 @@ LLVMRustModuleCost(LLVMModuleRef M) { auto f = unwrap(M)->functions(); return std::distance(std::begin(f), std::end(f)); } + +// Vector reductions: +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) { + return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src))); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) { + return wrap(unwrap(B)->CreateFMulReduce(unwrap(Acc),unwrap(Src))); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B, LLVMValueRef Src) { + return wrap(unwrap(B)->CreateAddReduce(unwrap(Src))); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceMul(LLVMBuilderRef B, LLVMValueRef Src) { + return wrap(unwrap(B)->CreateMulReduce(unwrap(Src))); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B, LLVMValueRef Src) { + return wrap(unwrap(B)->CreateAndReduce(unwrap(Src))); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceOr(LLVMBuilderRef B, LLVMValueRef Src) { + return wrap(unwrap(B)->CreateOrReduce(unwrap(Src))); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceXor(LLVMBuilderRef B, LLVMValueRef Src) { + return wrap(unwrap(B)->CreateXorReduce(unwrap(Src))); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceMin(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) { + return wrap(unwrap(B)->CreateIntMinReduce(unwrap(Src), IsSigned)); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceMax(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) { + return wrap(unwrap(B)->CreateIntMaxReduce(unwrap(Src), IsSigned)); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) { + return wrap(unwrap(B)->CreateFPMinReduce(unwrap(Src), NoNaN)); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) { + return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN)); +} diff --git a/src/test/run-pass/simd-intrinsic-generic-reduction.rs b/src/test/run-pass/simd-intrinsic-generic-reduction.rs new file mode 100644 index 00000000000..15b291ae179 --- /dev/null +++ b/src/test/run-pass/simd-intrinsic-generic-reduction.rs @@ -0,0 +1,143 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that the simd_reduce_{op} intrinsics produce the correct results. + +#![feature(repr_simd, platform_intrinsics)] +#[allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone)] +struct i32x4(pub i32, pub i32, pub i32, pub i32); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u32x4(pub u32, pub u32, pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct f32x4(pub f32, pub f32, pub f32, pub f32); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct b8x4(pub i8, pub i8, pub i8, pub i8); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct b8x16( + pub i8, pub i8, pub i8, pub i8, + pub i8, pub i8, pub i8, pub i8, + pub i8, pub i8, pub i8, pub i8, + pub i8, pub i8, pub i8, pub i8 +); + +extern "platform-intrinsic" { + fn simd_reduce_add(x: T) -> U; + fn simd_reduce_mul(x: T) -> U; + fn simd_reduce_min(x: T) -> U; + fn simd_reduce_max(x: T) -> U; + fn simd_reduce_and(x: T) -> U; + fn simd_reduce_or(x: T) -> U; + fn simd_reduce_xor(x: T) -> U; + fn simd_reduce_all(x: T) -> bool; + fn simd_reduce_any(x: T) -> bool; +} + +fn main() { + unsafe { + let x = i32x4(1, -2, 3, 4); + let r: i32 = simd_reduce_add(x); + assert!(r == 6_i32); + let r: i32 = simd_reduce_mul(x); + assert!(r == -24_i32); + let r: i32 = simd_reduce_min(x); + assert!(r == -21_i32); + let r: i32 = simd_reduce_max(x); + assert!(r == 4_i32); + + let x = i32x4(-1, -1, -1, -1); + let r: i32 = simd_reduce_and(x); + assert!(r == -1_i32); + let r: i32 = simd_reduce_or(x); + assert!(r == -1_i32); + let r: i32 = simd_reduce_xor(x); + assert!(r == 0_i32); + + let x = i32x4(-1, -1, 0, -1); + let r: i32 = simd_reduce_and(x); + assert!(r == 0_i32); + let r: i32 = simd_reduce_or(x); + assert!(r == -1_i32); + let r: i32 = simd_reduce_xor(x); + assert!(r == -1_i32); + } + + unsafe { + let x = u32x4(1, 2, 3, 4); + let r: u32 = simd_reduce_add(x); + assert!(r == 10_u32); + let r: u32 = simd_reduce_mul(x); + assert!(r == 24_u32); + let r: u32 = simd_reduce_min(x); + assert!(r == 1_u32); + let r: u32 = simd_reduce_max(x); + assert!(r == 4_u32); + + let t = u32::max_value(); + let x = u32x4(t, t, t, t); + let r: u32 = simd_reduce_and(x); + assert!(r == t); + let r: u32 = simd_reduce_or(x); + assert!(r == t); + let r: u32 = simd_reduce_xor(x); + assert!(r == 0_u32); + + let x = u32x4(t, t, 0, t); + let r: u32 = simd_reduce_and(x); + assert!(r == 0_u32); + let r: u32 = simd_reduce_or(x); + assert!(r == t); + let r: u32 = simd_reduce_xor(x); + assert!(r == t); + } + + unsafe { + let x = f32x4(1., -2., 3., 4.); + let r: f32 = simd_reduce_add(x); + assert!(r == 6_f32); + let r: f32 = simd_reduce_mul(x); + assert!(r == -24_f32); + let r: f32 = simd_reduce_min(x); + assert!(r == -2_f32); + let r: f32 = simd_reduce_max(x); + assert!(r == 4_f32); + } + + unsafe { + let x = b8x4(!0, !0, !0, !0); + let r: bool = simd_reduce_all(x); + //let r: bool = foobar(x); + assert!(r); + let r: bool = simd_reduce_any(x); + assert!(r); + + let x = b8x4(!0, !0, 0, !0); + let r: bool = simd_reduce_all(x); + assert!(!r); + let r: bool = simd_reduce_any(x); + assert!(r); + + let x = b8x4(0, 0, 0, 0); + let r: bool = simd_reduce_all(x); + assert!(!r); + let r: bool = simd_reduce_any(x); + assert!(!r); + } +} -- cgit 1.4.1-3-g733a5 From 07ce659dd03523b526cb4804b9ef882f31e9ecf3 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 14 Mar 2018 17:22:40 +0100 Subject: expose ordered/unordered/nanless intirnsics --- src/librustc_trans/builder.rs | 18 ++ src/librustc_trans/intrinsic.rs | 300 ++++++++------------- src/librustc_typeck/check/intrinsic.rs | 7 +- src/rustllvm/RustWrapper.cpp | 2 + .../run-pass/simd-intrinsic-generic-reduction.rs | 104 ++++--- 5 files changed, 202 insertions(+), 229 deletions(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index 2c38197d68e..371f53013b9 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -958,6 +958,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn vector_reduce_fadd_fast(&self, acc: ValueRef, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fadd_fast"); unsafe { + // FIXME: add a non-fast math version once + // https://bugs.llvm.org/show_bug.cgi?id=36732 + // is fixed. let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr @@ -966,6 +969,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn vector_reduce_fmul_fast(&self, acc: ValueRef, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmul_fast"); unsafe { + // FIXME: add a non-fast math version once + // https://bugs.llvm.org/show_bug.cgi?id=36732 + // is fixed. let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr @@ -1001,6 +1007,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) } } + pub fn vector_reduce_fmin(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.fmin"); + unsafe { + llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, true) + } + } + pub fn vector_reduce_fmax(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.fmax"); + unsafe { + llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, true) + } + } pub fn vector_reduce_fmin_fast(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmin_fast"); unsafe { diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 011273f02e1..8b62a1be80c 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -1150,210 +1150,134 @@ fn generic_simd_intrinsic<'a, 'tcx>( return Ok(bx.extract_element(args[0].immediate(), args[1].immediate())) } - if name == "simd_reduce_add" { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); - return match in_elem.sty { - ty::TyInt(_i) => { - Ok(bx.vector_reduce_add(args[0].immediate())) - }, - ty::TyUint(_u) => { - Ok(bx.vector_reduce_add(args[0].immediate())) - }, - ty::TyFloat(f) => { - // undef as accumulator makes the reduction unordered: - let acc = match f.bit_width() { - 32 => C_undef(Type::f32(bx.cx)), - 64 => C_undef(Type::f64(bx.cx)), - v => { - return_error!( - "unsupported {} from `{}` with element `{}` of size `{}` to `{}`", - "simd_reduce_add", in_ty, in_elem, v, ret_ty) + macro_rules! arith_red { + ($name:tt : $integer_reduce:ident, $float_reduce:ident, $ordered:expr) => { + if name == $name { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_) | ty::TyUint(_) => { + let r = bx.$integer_reduce(args[0].immediate()); + if $ordered { + // if overflow occurs, the result is the + // mathematical result modulo 2^n: + if name.contains("mul") { + Ok(bx.mul(args[1].immediate(), r)) + } else { + Ok(bx.add(args[1].immediate(), r)) + } + } else { + Ok(bx.$integer_reduce(args[0].immediate())) + } + }, + ty::TyFloat(f) => { + // ordered arithmetic reductions take an accumulator + let acc = if $ordered { + args[1].immediate() + } else { + // unordered arithmetic reductions do not: + match f.bit_width() { + 32 => C_undef(Type::f32(bx.cx)), + 64 => C_undef(Type::f64(bx.cx)), + v => { + return_error!( + "unsupported {} from `{}` with element `{}` of size `{}` to `{}`", + $name, in_ty, in_elem, v, ret_ty + ) + } + } + + }; + Ok(bx.$float_reduce(acc, args[0].immediate())) } - }; - Ok(bx.vector_reduce_fadd_fast(acc, args[0].immediate())) + _ => { + return_error!( + "unsupported {} from `{}` with element `{}` to `{}`", + $name, in_ty, in_elem, ret_ty + ) + }, + } } - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_add", in_ty, in_elem, ret_ty) - }, } } - if name == "simd_reduce_mul" { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); - return match in_elem.sty { - ty::TyInt(_i) => { - Ok(bx.vector_reduce_mul(args[0].immediate())) - }, - ty::TyUint(_u) => { - Ok(bx.vector_reduce_mul(args[0].immediate())) - }, - ty::TyFloat(f) => { - // undef as accumulator makes the reduction unordered: - let acc = match f.bit_width() { - 32 => C_undef(Type::f32(bx.cx)), - 64 => C_undef(Type::f64(bx.cx)), - v => { - return_error!( - "unsupported {} from `{}` with element `{}` of size `{}` to `{}`", - "simd_reduce_mul", in_ty, in_elem, v, ret_ty) + arith_red!("simd_reduce_add_ordered": vector_reduce_add, vector_reduce_fadd_fast, true); + arith_red!("simd_reduce_mul_ordered": vector_reduce_mul, vector_reduce_fmul_fast, true); + arith_red!("simd_reduce_add_unordered": vector_reduce_add, vector_reduce_fadd_fast, false); + arith_red!("simd_reduce_mul_unordered": vector_reduce_mul, vector_reduce_fmul_fast, false); + + macro_rules! minmax_red { + ($name:tt: $int_red:ident, $float_red:ident) => { + if name == $name { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_i) => { + Ok(bx.$int_red(args[0].immediate(), true)) + }, + ty::TyUint(_u) => { + Ok(bx.$int_red(args[0].immediate(), false)) + }, + ty::TyFloat(_f) => { + Ok(bx.$float_red(args[0].immediate())) } - }; - Ok(bx.vector_reduce_fmul_fast(acc, args[0].immediate())) + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + $name, in_ty, in_elem, ret_ty) + }, + } } - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_mul", in_ty, in_elem, ret_ty) - }, - } - } - if name == "simd_reduce_min" { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); - return match in_elem.sty { - ty::TyInt(_i) => { - Ok(bx.vector_reduce_min(args[0].immediate(), true)) - }, - ty::TyUint(_u) => { - Ok(bx.vector_reduce_min(args[0].immediate(), false)) - }, - ty::TyFloat(_f) => { - Ok(bx.vector_reduce_fmin_fast(args[0].immediate())) - } - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_min", in_ty, in_elem, ret_ty) - }, } } - if name == "simd_reduce_max" { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); - return match in_elem.sty { - ty::TyInt(_i) => { - Ok(bx.vector_reduce_max(args[0].immediate(), true)) - }, - ty::TyUint(_u) => { - Ok(bx.vector_reduce_max(args[0].immediate(), false)) - }, - ty::TyFloat(_f) => { - Ok(bx.vector_reduce_fmax_fast(args[0].immediate())) - } - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_max", in_ty, in_elem, ret_ty) - }, - } - } + minmax_red!("simd_reduce_min": vector_reduce_min, vector_reduce_fmin); + minmax_red!("simd_reduce_max": vector_reduce_max, vector_reduce_fmax); - if name == "simd_reduce_and" { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); - return match in_elem.sty { - ty::TyInt(_i) => { - Ok(bx.vector_reduce_and(args[0].immediate())) - }, - ty::TyUint(_u) => { - Ok(bx.vector_reduce_and(args[0].immediate())) - }, - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_and", in_ty, in_elem, ret_ty) - }, - } - } + minmax_red!("simd_reduce_min_nanless": vector_reduce_min, vector_reduce_fmin_fast); + minmax_red!("simd_reduce_max_nanless": vector_reduce_max, vector_reduce_fmax_fast); - if name == "simd_reduce_or" { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); - return match in_elem.sty { - ty::TyInt(_i) => { - Ok(bx.vector_reduce_or(args[0].immediate())) - }, - ty::TyUint(_u) => { - Ok(bx.vector_reduce_or(args[0].immediate())) - }, - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_or", in_ty, in_elem, ret_ty) - }, - } - } - - if name == "simd_reduce_xor" { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); - return match in_elem.sty { - ty::TyInt(_i) => { - Ok(bx.vector_reduce_xor(args[0].immediate())) - }, - ty::TyUint(_u) => { - Ok(bx.vector_reduce_xor(args[0].immediate())) - }, - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_xor", in_ty, in_elem, ret_ty) - }, + macro_rules! bitwise_red { + ($name:tt : $red:ident, $boolean:expr) => { + if name == $name { + let input = if !$boolean { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + args[0].immediate() + } else { + // boolean reductions operate on vectors of i1s: + let i1 = Type::i1(bx.cx); + let i1xn = Type::vector(&i1, in_len as u64); + bx.trunc(args[0].immediate(), i1xn) + }; + return match in_elem.sty { + ty::TyInt(_) | ty::TyUint(_) => { + let r = bx.$red(input); + Ok( + if !$boolean { + r + } else { + bx.zext(r, Type::bool(bx.cx)) + } + ) + }, + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + $name, in_ty, in_elem, ret_ty) + }, + } + } } } - if name == "simd_reduce_all" { - //require!(ret_ty == in_elem, - // "expected return type `{}` (element of input `{}`), found `{}`", - // in_elem, in_ty, ret_ty); - let i1 = Type::i1(bx.cx); - let i1xn = Type::vector(&i1, in_len as u64); - let v = bx.trunc(args[0].immediate(), i1xn); - - let red = match in_elem.sty { - ty::TyInt(_i) => { - bx.vector_reduce_and(v) - }, - ty::TyUint(_u) => { - bx.vector_reduce_and(v) - }, - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_and", in_ty, in_elem, ret_ty) - }, - }; - return Ok(bx.zext(red, Type::bool(bx.cx))); - } - - if name == "simd_reduce_any" { - //require!(ret_ty == in_elem, - // "expected return type `{}` (element of input `{}`), found `{}`", - // in_elem, in_ty, ret_ty); - let i1 = Type::i1(bx.cx); - let i1xn = Type::vector(&i1, in_len as u64); - let v = bx.trunc(args[0].immediate(), i1xn); - - let red = match in_elem.sty { - ty::TyInt(_i) => { - bx.vector_reduce_or(v) - }, - ty::TyUint(_u) => { - bx.vector_reduce_or(v) - }, - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_and", in_ty, in_elem, ret_ty) - }, - }; - return Ok(bx.zext(red, Type::bool(bx.cx))); - } - + bitwise_red!("simd_reduce_and": vector_reduce_and, false); + bitwise_red!("simd_reduce_or": vector_reduce_or, false); + bitwise_red!("simd_reduce_xor": vector_reduce_xor, false); + bitwise_red!("simd_reduce_all": vector_reduce_and, true); + bitwise_red!("simd_reduce_any": vector_reduce_or, true); if name == "simd_cast" { require_simd!(ret_ty, "return"); diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index f2d01c57f29..b87b8aa0bdb 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -362,9 +362,12 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, "simd_extract" => (2, vec![param(0), tcx.types.u32], param(1)), "simd_cast" => (2, vec![param(0)], param(1)), "simd_reduce_all" | "simd_reduce_any" => (1, vec![param(0)], tcx.types.bool), - "simd_reduce_add" | "simd_reduce_mul" | + "simd_reduce_add_ordered" | "simd_reduce_mul_ordered" + => (2, vec![param(0), param(1)], param(1)), + "simd_reduce_add_unordered" | "simd_reduce_mul_unordered" | "simd_reduce_and" | "simd_reduce_or" | "simd_reduce_xor" | - "simd_reduce_min" | "simd_reduce_max" + "simd_reduce_min" | "simd_reduce_max" | + "simd_reduce_min_nanless" | "simd_reduce_max_nanless" => (2, vec![param(0)], param(1)), name if name.starts_with("simd_shuffle") => { match name["simd_shuffle".len()..].parse() { diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index e749549201e..9d5f9042f18 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1397,6 +1397,7 @@ LLVMRustModuleCost(LLVMModuleRef M) { } // Vector reductions: +#if LLVM_VERSION_GE(6, 0) extern "C" LLVMValueRef LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) { return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src))); @@ -1441,3 +1442,4 @@ extern "C" LLVMValueRef LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) { return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN)); } +#endif diff --git a/src/test/run-pass/simd-intrinsic-generic-reduction.rs b/src/test/run-pass/simd-intrinsic-generic-reduction.rs index 15b291ae179..6755c92961b 100644 --- a/src/test/run-pass/simd-intrinsic-generic-reduction.rs +++ b/src/test/run-pass/simd-intrinsic-generic-reduction.rs @@ -39,10 +39,14 @@ struct b8x16( ); extern "platform-intrinsic" { - fn simd_reduce_add(x: T) -> U; - fn simd_reduce_mul(x: T) -> U; + fn simd_reduce_add_unordered(x: T) -> U; + fn simd_reduce_mul_unordered(x: T) -> U; + fn simd_reduce_add_ordered(x: T, acc: U) -> U; + fn simd_reduce_mul_ordered(x: T, acc: U) -> U; fn simd_reduce_min(x: T) -> U; fn simd_reduce_max(x: T) -> U; + fn simd_reduce_min_nanless(x: T) -> U; + fn simd_reduce_max_nanless(x: T) -> U; fn simd_reduce_and(x: T) -> U; fn simd_reduce_or(x: T) -> U; fn simd_reduce_xor(x: T) -> U; @@ -53,91 +57,113 @@ extern "platform-intrinsic" { fn main() { unsafe { let x = i32x4(1, -2, 3, 4); - let r: i32 = simd_reduce_add(x); - assert!(r == 6_i32); - let r: i32 = simd_reduce_mul(x); - assert!(r == -24_i32); + let r: i32 = simd_reduce_add_unordered(x); + assert_eq!(r, 6_i32); + let r: i32 = simd_reduce_mul_unordered(x); + assert_eq!(r, -24_i32); + let r: i32 = simd_reduce_add_ordered(x, -1); + assert_eq!(r, 5_i32); + let r: i32 = simd_reduce_mul_ordered(x, -1); + assert_eq!(r, 24_i32); + let r: i32 = simd_reduce_min(x); - assert!(r == -21_i32); + assert_eq!(r, -2_i32); let r: i32 = simd_reduce_max(x); - assert!(r == 4_i32); + assert_eq!(r, 4_i32); let x = i32x4(-1, -1, -1, -1); let r: i32 = simd_reduce_and(x); - assert!(r == -1_i32); + assert_eq!(r, -1_i32); let r: i32 = simd_reduce_or(x); - assert!(r == -1_i32); + assert_eq!(r, -1_i32); let r: i32 = simd_reduce_xor(x); - assert!(r == 0_i32); + assert_eq!(r, 0_i32); let x = i32x4(-1, -1, 0, -1); let r: i32 = simd_reduce_and(x); - assert!(r == 0_i32); + assert_eq!(r, 0_i32); let r: i32 = simd_reduce_or(x); - assert!(r == -1_i32); + assert_eq!(r, -1_i32); let r: i32 = simd_reduce_xor(x); - assert!(r == -1_i32); + assert_eq!(r, -1_i32); } unsafe { let x = u32x4(1, 2, 3, 4); - let r: u32 = simd_reduce_add(x); - assert!(r == 10_u32); - let r: u32 = simd_reduce_mul(x); - assert!(r == 24_u32); + let r: u32 = simd_reduce_add_unordered(x); + assert_eq!(r, 10_u32); + let r: u32 = simd_reduce_mul_unordered(x); + assert_eq!(r, 24_u32); + let r: u32 = simd_reduce_add_ordered(x, 1); + assert_eq!(r, 11_u32); + let r: u32 = simd_reduce_mul_ordered(x, 2); + assert_eq!(r, 48_u32); + let r: u32 = simd_reduce_min(x); - assert!(r == 1_u32); + assert_eq!(r, 1_u32); let r: u32 = simd_reduce_max(x); - assert!(r == 4_u32); + assert_eq!(r, 4_u32); let t = u32::max_value(); let x = u32x4(t, t, t, t); let r: u32 = simd_reduce_and(x); - assert!(r == t); + assert_eq!(r, t); let r: u32 = simd_reduce_or(x); - assert!(r == t); + assert_eq!(r, t); let r: u32 = simd_reduce_xor(x); - assert!(r == 0_u32); + assert_eq!(r, 0_u32); let x = u32x4(t, t, 0, t); let r: u32 = simd_reduce_and(x); - assert!(r == 0_u32); + assert_eq!(r, 0_u32); let r: u32 = simd_reduce_or(x); - assert!(r == t); + assert_eq!(r, t); let r: u32 = simd_reduce_xor(x); - assert!(r == t); + assert_eq!(r, t); } unsafe { let x = f32x4(1., -2., 3., 4.); - let r: f32 = simd_reduce_add(x); - assert!(r == 6_f32); - let r: f32 = simd_reduce_mul(x); - assert!(r == -24_f32); + let r: f32 = simd_reduce_add_unordered(x); + assert_eq!(r, 6_f32); + let r: f32 = simd_reduce_mul_unordered(x); + assert_eq!(r, -24_f32); + // FIXME: only works correctly for accumulator, 0: + // https://bugs.llvm.org/show_bug.cgi?id=36734 + let r: f32 = simd_reduce_add_ordered(x, 0.); + assert_eq!(r, 6_f32); + // FIXME: only works correctly for accumulator, 1: + // https://bugs.llvm.org/show_bug.cgi?id=36734 + let r: f32 = simd_reduce_mul_ordered(x, 1.); + assert_eq!(r, -24_f32); + let r: f32 = simd_reduce_min(x); - assert!(r == -2_f32); + assert_eq!(r, -2_f32); let r: f32 = simd_reduce_max(x); - assert!(r == 4_f32); + assert_eq!(r, 4_f32); + let r: f32 = simd_reduce_min_nanless(x); + assert_eq!(r, -2_f32); + let r: f32 = simd_reduce_max_nanless(x); + assert_eq!(r, 4_f32); } unsafe { let x = b8x4(!0, !0, !0, !0); let r: bool = simd_reduce_all(x); - //let r: bool = foobar(x); - assert!(r); + assert_eq!(r, true); let r: bool = simd_reduce_any(x); - assert!(r); + assert_eq!(r, true); let x = b8x4(!0, !0, 0, !0); let r: bool = simd_reduce_all(x); - assert!(!r); + assert_eq!(r, false); let r: bool = simd_reduce_any(x); - assert!(r); + assert_eq!(r, true); let x = b8x4(0, 0, 0, 0); let r: bool = simd_reduce_all(x); - assert!(!r); + assert_eq!(r, false); let r: bool = simd_reduce_any(x); - assert!(!r); + assert_eq!(r, false); } } -- cgit 1.4.1-3-g733a5 From c990fa0d880586d85e191b0691a415f9180f4e61 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 14 Mar 2018 22:12:38 +0100 Subject: add dummy symbols for LLVM<6 --- src/rustllvm/RustWrapper.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 9d5f9042f18..c647218c1ac 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1442,4 +1442,51 @@ extern "C" LLVMValueRef LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) { return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN)); } + +#else + +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef, LLVMValueRef, LLVMValueRef Src) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFMul(LLVMBuilderRef, LLVMValueRef, LLVMValueRef Src) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceAdd(LLVMBuilderRef, LLVMValueRef Src) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceMul(LLVMBuilderRef, LLVMValueRef Src) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceAnd(LLVMBuilderRef, LLVMValueRef Src) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceOr(LLVMBuilderRef, LLVMValueRef Src) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceXor(LLVMBuilderRef, LLVMValueRef Src) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceMin(LLVMBuilderRef, LLVMValueRef Src, bool) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceMax(LLVMBuilderRef, LLVMValueRef Src, bool) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFMin(LLVMBuilderRef, LLVMValueRef Src, bool) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFMax(LLVMBuilderRef, LLVMValueRef Src, bool) { + return Src; +} #endif -- cgit 1.4.1-3-g733a5 From 3125a307596db12d8b014da330373446dda5d7ca Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Thu, 15 Mar 2018 10:08:22 +0100 Subject: error on vector reduction usage if LLVM version is < 5.0 --- src/rustllvm/RustWrapper.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index c647218c1ac..cd3ae1e743b 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -21,6 +21,8 @@ #if LLVM_VERSION_GE(5, 0) #include "llvm/ADT/Optional.h" +#else +#include #endif //===----------------------------------------------------------------------=== @@ -1397,7 +1399,7 @@ LLVMRustModuleCost(LLVMModuleRef M) { } // Vector reductions: -#if LLVM_VERSION_GE(6, 0) +#if LLVM_VERSION_GE(5, 0) extern "C" LLVMValueRef LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) { return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src))); @@ -1445,48 +1447,65 @@ LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) { #else +void error_and_exit(const char* msg) { + raw_fd_ostream OS(2, false); + OS << ::std::string(msg); + std::exit(EXIT_FAILURE); +} + extern "C" LLVMValueRef LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef, LLVMValueRef, LLVMValueRef Src) { + error_and_exit("LLVMRustBuildVectorReduceFAdd requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceFMul(LLVMBuilderRef, LLVMValueRef, LLVMValueRef Src) { + error_and_exit("LLVMRustBuildVectorReduceFMul requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceAdd(LLVMBuilderRef, LLVMValueRef Src) { + error_and_exit("LLVMRustBuildVectorReduceAdd requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceMul(LLVMBuilderRef, LLVMValueRef Src) { + error_and_exit("LLVMRustBuildVectorReduceMul requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceAnd(LLVMBuilderRef, LLVMValueRef Src) { + error_and_exit("LLVMRustBuildVectorReduceAnd requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceOr(LLVMBuilderRef, LLVMValueRef Src) { + error_and_exit("LLVMRustBuildVectorReduceOr requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceXor(LLVMBuilderRef, LLVMValueRef Src) { + error_and_exit("LLVMRustBuildVectorReduceXor requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceMin(LLVMBuilderRef, LLVMValueRef Src, bool) { + error_and_exit("LLVMRustBuildVectorReduceMin requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceMax(LLVMBuilderRef, LLVMValueRef Src, bool) { + error_and_exit("LLVMRustBuildVectorReduceMax requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceFMin(LLVMBuilderRef, LLVMValueRef Src, bool) { + error_and_exit("LLVMRustBuildVectorReduceFMin requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceFMax(LLVMBuilderRef, LLVMValueRef Src, bool) { + error_and_exit("LLVMRustBuildVectorReduceFMax requires LLVM >= 5.0"); return Src; } #endif -- cgit 1.4.1-3-g733a5 From 19b81f61142fe69edb48d08e9bbfa96d389e8ffd Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Thu, 15 Mar 2018 16:51:58 +0100 Subject: error via bug! instead of stderr+terminate --- src/librustc_trans/builder.rs | 66 +++++++++++++++++++++++++++++++++++++------ src/rustllvm/RustWrapper.cpp | 61 +++++++++++++++------------------------ 2 files changed, 79 insertions(+), 48 deletions(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index 371f53013b9..3f5a9a54ff1 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -962,6 +962,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // https://bugs.llvm.org/show_bug.cgi?id=36732 // is fixed. let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceFAdd is not available in LLVM version < 5.0"); + } llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } @@ -973,6 +976,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // https://bugs.llvm.org/show_bug.cgi?id=36732 // is fixed. let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceFMul is not available in LLVM version < 5.0"); + } llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } @@ -980,49 +986,80 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn vector_reduce_add(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.add"); unsafe { - llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) + let instr = llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceAdd is not available in LLVM version < 5.0"); + } + instr } } pub fn vector_reduce_mul(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.mul"); unsafe { - llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) + let instr = llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceMul is not available in LLVM version < 5.0"); + } + instr } } pub fn vector_reduce_and(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.and"); unsafe { - llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) + let instr = llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceAnd is not available in LLVM version < 5.0"); + } + instr } } pub fn vector_reduce_or(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.or"); unsafe { - llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) + let instr = llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceOr is not available in LLVM version < 5.0"); + } + instr } } pub fn vector_reduce_xor(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.xor"); unsafe { - llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) + let instr = llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceXor is not available in LLVM version < 5.0"); + } + instr } } pub fn vector_reduce_fmin(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmin"); unsafe { - llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, true) + let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, true); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0"); + } + instr } } pub fn vector_reduce_fmax(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmax"); unsafe { - llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, true) + let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, true); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0"); + } + instr } } pub fn vector_reduce_fmin_fast(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmin_fast"); unsafe { let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, false); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0"); + } llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } @@ -1031,6 +1068,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.count_insn("vector.reduce.fmax_fast"); unsafe { let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, false); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0"); + } llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } @@ -1038,13 +1078,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn vector_reduce_min(&self, src: ValueRef, is_signed: bool) -> ValueRef { self.count_insn("vector.reduce.min"); unsafe { - llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) + let instr = llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceMin is not available in LLVM version < 5.0"); + } + instr } } pub fn vector_reduce_max(&self, src: ValueRef, is_signed: bool) -> ValueRef { self.count_insn("vector.reduce.max"); unsafe { - llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) + let instr = llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceMax is not available in LLVM version < 5.0"); + } + instr } } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index cd3ae1e743b..a5644d6f9e2 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1447,65 +1447,48 @@ LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) { #else -void error_and_exit(const char* msg) { - raw_fd_ostream OS(2, false); - OS << ::std::string(msg); - std::exit(EXIT_FAILURE); -} - extern "C" LLVMValueRef -LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef, LLVMValueRef, LLVMValueRef Src) { - error_and_exit("LLVMRustBuildVectorReduceFAdd requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceFMul(LLVMBuilderRef, LLVMValueRef, LLVMValueRef Src) { - error_and_exit("LLVMRustBuildVectorReduceFMul requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceFMul(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceAdd(LLVMBuilderRef, LLVMValueRef Src) { - error_and_exit("LLVMRustBuildVectorReduceAdd requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceAdd(LLVMBuilderRef, LLVMValueRef) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceMul(LLVMBuilderRef, LLVMValueRef Src) { - error_and_exit("LLVMRustBuildVectorReduceMul requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceMul(LLVMBuilderRef, LLVMValueRef) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceAnd(LLVMBuilderRef, LLVMValueRef Src) { - error_and_exit("LLVMRustBuildVectorReduceAnd requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceAnd(LLVMBuilderRef, LLVMValueRef) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceOr(LLVMBuilderRef, LLVMValueRef Src) { - error_and_exit("LLVMRustBuildVectorReduceOr requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceOr(LLVMBuilderRef, LLVMValueRef) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceXor(LLVMBuilderRef, LLVMValueRef Src) { - error_and_exit("LLVMRustBuildVectorReduceXor requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceXor(LLVMBuilderRef, LLVMValueRef) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceMin(LLVMBuilderRef, LLVMValueRef Src, bool) { - error_and_exit("LLVMRustBuildVectorReduceMin requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceMin(LLVMBuilderRef, LLVMValueRef, bool) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceMax(LLVMBuilderRef, LLVMValueRef Src, bool) { - error_and_exit("LLVMRustBuildVectorReduceMax requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceMax(LLVMBuilderRef, LLVMValueRef, bool) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceFMin(LLVMBuilderRef, LLVMValueRef Src, bool) { - error_and_exit("LLVMRustBuildVectorReduceFMin requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceFMin(LLVMBuilderRef, LLVMValueRef, bool) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceFMax(LLVMBuilderRef, LLVMValueRef Src, bool) { - error_and_exit("LLVMRustBuildVectorReduceFMax requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceFMax(LLVMBuilderRef, LLVMValueRef, bool) { + return nullptr; } #endif -- cgit 1.4.1-3-g733a5 From a95c8c66a72e82e2eb41bccb450e2bf5b0d67e7e Mon Sep 17 00:00:00 2001 From: Emilio Cobos Álvarez Date: Mon, 12 Mar 2018 18:11:59 +0100 Subject: librustc_llvm: Show PGO diagnostics properly. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emilio Cobos Álvarez --- src/librustc_llvm/diagnostic.rs | 5 +++++ src/librustc_llvm/ffi.rs | 1 + src/librustc_trans/back/write.rs | 9 +++++++-- src/rustllvm/RustWrapper.cpp | 3 +++ 4 files changed, 16 insertions(+), 2 deletions(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/librustc_llvm/diagnostic.rs b/src/librustc_llvm/diagnostic.rs index c5cdf656692..e73c570ed82 100644 --- a/src/librustc_llvm/diagnostic.rs +++ b/src/librustc_llvm/diagnostic.rs @@ -121,6 +121,7 @@ impl InlineAsmDiagnostic { pub enum Diagnostic { Optimization(OptimizationDiagnostic), InlineAsm(InlineAsmDiagnostic), + PGO(DiagnosticInfoRef), /// LLVM has other types that we do not wrap here. UnknownDiagnostic(DiagnosticInfoRef), @@ -160,6 +161,10 @@ impl Diagnostic { Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di)) } + Dk::PGOProfile => { + PGO(di) + } + _ => UnknownDiagnostic(di), } } diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 25506f6a86e..1271773fa02 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -322,6 +322,7 @@ pub enum DiagnosticKind { OptimizationRemarkAnalysisAliasing, OptimizationRemarkOther, OptimizationFailure, + PGOProfile, } /// LLVMRustArchiveKind diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 2a8d280ee26..99558652d69 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -498,8 +498,13 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo opt.message)); } } - - _ => (), + llvm::diagnostic::PGO(diagnostic_ref) => { + let msg = llvm::build_string(|s| { + llvm::LLVMRustWriteDiagnosticInfoToString(diagnostic_ref, s) + }).expect("non-UTF8 PGO diagnostic"); + diag_handler.note_without_error(&msg); + } + llvm::diagnostic::UnknownDiagnostic(..) => {}, } } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index a5644d6f9e2..970c1c6a011 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1021,6 +1021,7 @@ enum class LLVMRustDiagnosticKind { OptimizationRemarkAnalysisAliasing, OptimizationRemarkOther, OptimizationFailure, + PGOProfile, }; static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) { @@ -1043,6 +1044,8 @@ static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) { return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute; case DK_OptimizationRemarkAnalysisAliasing: return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing; + case DK_PGOProfile: + return LLVMRustDiagnosticKind::PGOProfile; default: return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark) ? LLVMRustDiagnosticKind::OptimizationRemarkOther -- cgit 1.4.1-3-g733a5 From 02b5851258c5a0db32d1c735d1c29e5e56f45ed1 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 24 Mar 2018 19:15:12 -0700 Subject: Polyfill LLVMBuildExactUDiv It was added 32 days after LLVM 3.9 shipped. --- src/rustllvm/RustWrapper.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index a5644d6f9e2..e815d151aeb 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1492,3 +1492,11 @@ LLVMRustBuildVectorReduceFMax(LLVMBuilderRef, LLVMValueRef, bool) { return nullptr; } #endif + +#if LLVM_VERSION_LT(4, 0) +extern "C" LLVMValueRef +LLVMBuildExactUDiv(LLVMBuilderRef B, LLVMValueRef LHS, + LLVMValueRef RHS, const char *Name) { + return wrap(unwrap(B)->CreateExactUDiv(unwrap(LHS), unwrap(RHS), Name)); +} +#endif -- cgit 1.4.1-3-g733a5 From 7d5343a6700581e318189dcd74567b348bd7f68d Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 21 Mar 2018 21:49:22 +0100 Subject: implement minmax intrinsics --- src/librustc_llvm/ffi.rs | 3 +++ src/librustc_trans/builder.rs | 13 +++++++++++++ src/librustc_trans/intrinsic.rs | 2 ++ src/librustc_typeck/check/intrinsic.rs | 3 ++- src/rustllvm/RustWrapper.cpp | 9 +++++++++ 5 files changed, 29 insertions(+), 1 deletion(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 403fe4731f1..09ff3566713 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -1247,6 +1247,9 @@ extern "C" { IsNaN: bool) -> ValueRef; + pub fn LLVMRustBuildMinNum(B: BuilderRef, LHS: ValueRef, LHS: ValueRef) -> ValueRef; + pub fn LLVMRustBuildMaxNum(B: BuilderRef, LHS: ValueRef, LHS: ValueRef) -> ValueRef; + pub fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef, Name: *const c_char) -> ValueRef; pub fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *const c_char) -> ValueRef; pub fn LLVMBuildPtrDiff(B: BuilderRef, diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index 5e2d32b3596..b5271b25b63 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -917,6 +917,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } + pub fn minnum(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + self.count_insn("minnum"); + unsafe { + llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) + } + } + pub fn maxnum(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + self.count_insn("maxnum"); + unsafe { + llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs) + } + } + pub fn select(&self, cond: ValueRef, then_val: ValueRef, else_val: ValueRef) -> ValueRef { self.count_insn("select"); unsafe { diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 2be29c08360..5c67f809114 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -1432,6 +1432,8 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, simd_and: TyUint, TyInt => and; simd_or: TyUint, TyInt => or; simd_xor: TyUint, TyInt => xor; + simd_fmax: TyFloat => maxnum; + simd_fmin: TyFloat => minnum; } span_bug!(span, "unknown SIMD intrinsic"); } diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index da37cec31cf..377e3a89184 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -355,7 +355,8 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } "simd_add" | "simd_sub" | "simd_mul" | "simd_rem" | "simd_div" | "simd_shl" | "simd_shr" | - "simd_and" | "simd_or" | "simd_xor" => { + "simd_and" | "simd_or" | "simd_xor" | + "simd_fmin" | "simd_fmax" => { (1, vec![param(0), param(0)], param(0)) } "simd_insert" => (2, vec![param(0), tcx.types.u32, param(1)], param(0)), diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index e815d151aeb..627827105cb 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1500,3 +1500,12 @@ LLVMBuildExactUDiv(LLVMBuilderRef B, LLVMValueRef LHS, return wrap(unwrap(B)->CreateExactUDiv(unwrap(LHS), unwrap(RHS), Name)); } #endif + +extern "C" LLVMValueRef +LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) { + return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS))); +} +extern "C" LLVMValueRef +LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) { + return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS))); +} -- cgit 1.4.1-3-g733a5 From 066c2ec9baac1be5e884e48813a542de8f5d64b0 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Thu, 22 Mar 2018 14:48:58 +0100 Subject: require llvm 6 --- src/librustc_trans/builder.rs | 8 ++++++-- src/rustllvm/RustWrapper.cpp | 11 +++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index b5271b25b63..241ee8a4828 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -920,13 +920,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn minnum(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { self.count_insn("minnum"); unsafe { - llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) + let instr = llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs); + bug!("LLVMRustBuildMinNum is not available in LLVM version < 6.0"); + instr } } pub fn maxnum(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { self.count_insn("maxnum"); unsafe { - llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs) + let instr = llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs); + bug!("LLVMRustBuildMaxNum is not available in LLVM version < 6.0"); + instr } } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 627827105cb..1b35f0adda6 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1501,6 +1501,7 @@ LLVMBuildExactUDiv(LLVMBuilderRef B, LLVMValueRef LHS, } #endif +#if LLVM_VERSION_GE(6, 0) extern "C" LLVMValueRef LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) { return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS))); @@ -1509,3 +1510,13 @@ extern "C" LLVMValueRef LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) { return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS))); } +#else +extern "C" LLVMValueRef +LLVMRustBuildMinNum(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) { + return nullptr; +} +extern "C" LLVMValueRef +LLVMRustBuildMaxNum(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) { + return nullptr; +} +#endif -- cgit 1.4.1-3-g733a5 From 4ff90c7e0aa60cfab0d4fd5e52fcc63a7afd81c3 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Fri, 29 Jun 2018 10:28:51 +0200 Subject: bump minimum LLVM version to 5.0 --- .travis.yml | 2 +- src/bootstrap/native.rs | 6 +- src/ci/docker/x86_64-gnu-llvm-3.9/Dockerfile | 27 --- src/ci/docker/x86_64-gnu-llvm-5.0/Dockerfile | 27 +++ src/librustc_codegen_llvm/abi.rs | 6 +- src/librustc_codegen_llvm/mir/mod.rs | 22 +-- src/rustllvm/RustWrapper.cpp | 201 +-------------------- src/test/codegen/call-metadata.rs | 2 - src/test/codegen/issue-37945.rs | 1 - src/test/codegen/issue-45466.rs | 1 - src/test/codegen/mainsubprogram.rs | 1 - src/test/codegen/mainsubprogramstart.rs | 4 - src/test/codegen/noreturnflag.rs | 1 - src/test/codegen/stack-probes.rs | 1 - src/test/codegen/vtabletype.rs | 2 +- .../simd-intrinsic-generic-reduction.rs | 1 - src/test/mir-opt/lower_128bit_test.rs | 3 - src/test/run-make-fulldeps/cross-lang-lto/Makefile | 2 - .../llvm-pass/llvm-function-pass.so.cc | 7 +- .../llvm-pass/llvm-module-pass.so.cc | 7 +- src/test/run-pass/issue-40883.rs | 1 - .../run-pass/simd-intrinsic-generic-reduction.rs | 1 - src/test/run-pass/stack-probes-lto.rs | 1 - src/test/run-pass/stack-probes.rs | 1 - src/test/run-pass/thin-lto-global-allocator.rs | 1 - src/test/run-pass/thinlto/all-crates.rs | 1 - src/test/run-pass/thinlto/dylib-works.rs | 1 - src/test/run-pass/thinlto/msvc-imp-present.rs | 1 - src/test/run-pass/thinlto/thin-lto-inlines.rs | 1 - src/test/run-pass/thinlto/thin-lto-inlines2.rs | 1 - src/test/run-pass/thinlto/weak-works.rs | 1 - 31 files changed, 42 insertions(+), 293 deletions(-) delete mode 100644 src/ci/docker/x86_64-gnu-llvm-3.9/Dockerfile create mode 100644 src/ci/docker/x86_64-gnu-llvm-5.0/Dockerfile (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/.travis.yml b/.travis.yml index ba8a39f355c..2cf10d76098 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ matrix: fast_finish: true include: # Images used in testing PR and try-build should be run first. - - env: IMAGE=x86_64-gnu-llvm-3.9 RUST_BACKTRACE=1 + - env: IMAGE=x86_64-gnu-llvm-5.0 RUST_BACKTRACE=1 if: type = pull_request OR branch = auto - env: IMAGE=dist-x86_64-linux DEPLOY=1 diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 93b8880a900..264acfacee6 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -256,12 +256,12 @@ fn check_llvm_version(builder: &Builder, llvm_config: &Path) { let version = output(cmd.arg("--version")); let mut parts = version.split('.').take(2) .filter_map(|s| s.parse::().ok()); - if let (Some(major), Some(minor)) = (parts.next(), parts.next()) { - if major > 3 || (major == 3 && minor >= 9) { + if let (Some(major), Some(_minor)) = (parts.next(), parts.next()) { + if major >= 5 { return } } - panic!("\n\nbad LLVM version: {}, need >=3.9\n\n", version) + panic!("\n\nbad LLVM version: {}, need >=5.0\n\n", version) } fn configure_cmake(builder: &Builder, diff --git a/src/ci/docker/x86_64-gnu-llvm-3.9/Dockerfile b/src/ci/docker/x86_64-gnu-llvm-3.9/Dockerfile deleted file mode 100644 index 6b818604898..00000000000 --- a/src/ci/docker/x86_64-gnu-llvm-3.9/Dockerfile +++ /dev/null @@ -1,27 +0,0 @@ -FROM ubuntu:16.04 - -RUN apt-get update && apt-get install -y --no-install-recommends \ - g++ \ - make \ - file \ - curl \ - ca-certificates \ - python2.7 \ - git \ - cmake \ - sudo \ - gdb \ - llvm-3.9-tools \ - libedit-dev \ - zlib1g-dev \ - xz-utils - -COPY scripts/sccache.sh /scripts/ -RUN sh /scripts/sccache.sh - -# using llvm-link-shared due to libffi issues -- see #34486 -ENV RUST_CONFIGURE_ARGS \ - --build=x86_64-unknown-linux-gnu \ - --llvm-root=/usr/lib/llvm-3.9 \ - --enable-llvm-link-shared -ENV RUST_CHECK_TARGET check diff --git a/src/ci/docker/x86_64-gnu-llvm-5.0/Dockerfile b/src/ci/docker/x86_64-gnu-llvm-5.0/Dockerfile new file mode 100644 index 00000000000..4f90c509726 --- /dev/null +++ b/src/ci/docker/x86_64-gnu-llvm-5.0/Dockerfile @@ -0,0 +1,27 @@ +FROM ubuntu:16.04 + +RUN apt-get update && apt-get install -y --no-install-recommends \ + g++ \ + make \ + file \ + curl \ + ca-certificates \ + python2.7 \ + git \ + cmake \ + sudo \ + gdb \ + llvm-5.0-tools \ + libedit-dev \ + zlib1g-dev \ + xz-utils + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +# using llvm-link-shared due to libffi issues -- see #34486 +ENV RUST_CONFIGURE_ARGS \ + --build=x86_64-unknown-linux-gnu \ + --llvm-root=/usr/lib/llvm-5.0 \ + --enable-llvm-link-shared +ENV RUST_CHECK_TARGET check diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 6b5baa402b4..47c13919e6e 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -666,11 +666,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> { layout::Int(..) if !scalar.is_bool() => { let range = scalar.valid_range_exclusive(bx.cx); if range.start != range.end { - // FIXME(nox): This causes very weird type errors about - // SHL operators in constants in stage 2 with LLVM 3.9. - if unsafe { llvm::LLVMRustVersionMajor() >= 4 } { - bx.range_metadata(callsite, range); - } + bx.range_metadata(callsite, range); } } _ => {} diff --git a/src/librustc_codegen_llvm/mir/mod.rs b/src/librustc_codegen_llvm/mir/mod.rs index f9be91b4f3f..608539dd3fa 100644 --- a/src/librustc_codegen_llvm/mir/mod.rs +++ b/src/librustc_codegen_llvm/mir/mod.rs @@ -22,7 +22,7 @@ use builder::Builder; use common::{CodegenCx, Funclet}; use debuginfo::{self, declare_local, VariableAccess, VariableKind, FunctionDebugContext}; use monomorphize::Instance; -use abi::{ArgAttribute, ArgTypeExt, FnType, FnTypeExt, PassMode}; +use abi::{ArgTypeExt, FnType, FnTypeExt, PassMode}; use type_::Type; use syntax_pos::{DUMMY_SP, NO_EXPANSION, BytePos, Span}; @@ -430,10 +430,6 @@ fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, None }; - let deref_op = unsafe { - [llvm::LLVMRustDIBuilderCreateOpDeref()] - }; - mir.args_iter().enumerate().map(|(arg_index, local)| { let arg_decl = &mir.local_decls[local]; @@ -543,21 +539,11 @@ fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, if arg_index > 0 || mir.upvar_decls.is_empty() { // The Rust ABI passes indirect variables using a pointer and a manual copy, so we // need to insert a deref here, but the C ABI uses a pointer and a copy using the - // byval attribute, for which LLVM does the deref itself, so we must not add it. - // Starting with D31439 in LLVM 5, it *always* does the deref itself. - let mut variable_access = VariableAccess::DirectVariable { + // byval attribute, for which LLVM always does the deref itself, + // so we must not add it. + let variable_access = VariableAccess::DirectVariable { alloca: place.llval }; - if unsafe { llvm::LLVMRustVersionMajor() < 5 } { - if let PassMode::Indirect(ref attrs) = arg.mode { - if !attrs.contains(ArgAttribute::ByVal) { - variable_access = VariableAccess::IndirectVariable { - alloca: place.llval, - address_operations: &deref_op, - }; - } - } - } declare_local( bx, diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index df8602d0803..2ac7a6a46ba 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -16,14 +16,8 @@ #include "llvm/Object/Archive.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Bitcode/BitcodeWriterPass.h" - #include "llvm/IR/CallSite.h" - -#if LLVM_VERSION_GE(5, 0) #include "llvm/ADT/Optional.h" -#else -#include -#endif //===----------------------------------------------------------------------=== // @@ -176,14 +170,7 @@ extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index, LLVMRustAttribute RustAttr) { CallSite Call = CallSite(unwrap(Instr)); Attribute Attr = Attribute::get(Call->getContext(), fromRust(RustAttr)); -#if LLVM_VERSION_GE(5, 0) Call.addAttribute(Index, Attr); -#else - AttrBuilder B(Attr); - Call.setAttributes(Call.getAttributes().addAttributes( - Call->getContext(), Index, - AttributeSet::get(Call->getContext(), Index, B))); -#endif } extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr, @@ -192,14 +179,8 @@ extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr, CallSite Call = CallSite(unwrap(Instr)); AttrBuilder B; B.addAlignmentAttr(Bytes); -#if LLVM_VERSION_GE(5, 0) Call.setAttributes(Call.getAttributes().addAttributes( Call->getContext(), Index, B)); -#else - Call.setAttributes(Call.getAttributes().addAttributes( - Call->getContext(), Index, - AttributeSet::get(Call->getContext(), Index, B))); -#endif } extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr, @@ -208,14 +189,8 @@ extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr, CallSite Call = CallSite(unwrap(Instr)); AttrBuilder B; B.addDereferenceableAttr(Bytes); -#if LLVM_VERSION_GE(5, 0) Call.setAttributes(Call.getAttributes().addAttributes( Call->getContext(), Index, B)); -#else - Call.setAttributes(Call.getAttributes().addAttributes( - Call->getContext(), Index, - AttributeSet::get(Call->getContext(), Index, B))); -#endif } extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr, @@ -224,14 +199,8 @@ extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr, CallSite Call = CallSite(unwrap(Instr)); AttrBuilder B; B.addDereferenceableOrNullAttr(Bytes); -#if LLVM_VERSION_GE(5, 0) Call.setAttributes(Call.getAttributes().addAttributes( Call->getContext(), Index, B)); -#else - Call.setAttributes(Call.getAttributes().addAttributes( - Call->getContext(), Index, - AttributeSet::get(Call->getContext(), Index, B))); -#endif } extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index, @@ -239,11 +208,7 @@ extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index, Function *A = unwrap(Fn); Attribute Attr = Attribute::get(A->getContext(), fromRust(RustAttr)); AttrBuilder B(Attr); -#if LLVM_VERSION_GE(5, 0) A->addAttributes(Index, B); -#else - A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B)); -#endif } extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn, @@ -252,11 +217,7 @@ extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn, Function *A = unwrap(Fn); AttrBuilder B; B.addAlignmentAttr(Bytes); -#if LLVM_VERSION_GE(5, 0) A->addAttributes(Index, B); -#else - A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B)); -#endif } extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index, @@ -264,11 +225,7 @@ extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index, Function *A = unwrap(Fn); AttrBuilder B; B.addDereferenceableAttr(Bytes); -#if LLVM_VERSION_GE(5, 0) A->addAttributes(Index, B); -#else - A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B)); -#endif } extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn, @@ -277,11 +234,7 @@ extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn, Function *A = unwrap(Fn); AttrBuilder B; B.addDereferenceableOrNullAttr(Bytes); -#if LLVM_VERSION_GE(5, 0) A->addAttributes(Index, B); -#else - A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B)); -#endif } extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn, @@ -291,11 +244,7 @@ extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn, Function *F = unwrap(Fn); AttrBuilder B; B.addAttribute(Name, Value); -#if LLVM_VERSION_GE(5, 0) F->addAttributes(Index, B); -#else - F->addAttributes(Index, AttributeSet::get(F->getContext(), Index, B)); -#endif } extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn, @@ -305,12 +254,7 @@ extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn, Attribute Attr = Attribute::get(F->getContext(), fromRust(RustAttr)); AttrBuilder B(Attr); auto PAL = F->getAttributes(); -#if LLVM_VERSION_GE(5, 0) auto PALNew = PAL.removeAttributes(F->getContext(), Index, B); -#else - const AttributeSet PALNew = PAL.removeAttributes( - F->getContext(), Index, AttributeSet::get(F->getContext(), Index, B)); -#endif F->setAttributes(PALNew); } @@ -360,7 +304,6 @@ enum class LLVMRustSynchronizationScope { CrossThread, }; -#if LLVM_VERSION_GE(5, 0) static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) { switch (Scope) { case LLVMRustSynchronizationScope::SingleThread: @@ -371,18 +314,6 @@ static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) { report_fatal_error("bad SynchronizationScope."); } } -#else -static SynchronizationScope fromRust(LLVMRustSynchronizationScope Scope) { - switch (Scope) { - case LLVMRustSynchronizationScope::SingleThread: - return SingleThread; - case LLVMRustSynchronizationScope::CrossThread: - return CrossThread; - default: - report_fatal_error("bad SynchronizationScope."); - } -} -#endif extern "C" LLVMValueRef LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order, @@ -422,18 +353,6 @@ extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm) typedef DIBuilder *LLVMRustDIBuilderRef; -#if LLVM_VERSION_LT(5, 0) -typedef struct LLVMOpaqueMetadata *LLVMMetadataRef; - -namespace llvm { -DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef) - -inline Metadata **unwrap(LLVMMetadataRef *Vals) { - return reinterpret_cast(Vals); -} -} -#endif - template DIT *unwrapDIPtr(LLVMMetadataRef Ref) { return (DIT *)(Ref ? unwrap(Ref) : nullptr); } @@ -492,13 +411,8 @@ inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) { return static_cast(static_cast(F) & 0x3); } -#if LLVM_VERSION_GE(4, 0) static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) { DINode::DIFlags Result = DINode::DIFlags::FlagZero; -#else -static unsigned fromRust(LLVMRustDIFlags Flags) { - unsigned Result = 0; -#endif switch (visibility(Flags)) { case LLVMRustDIFlags::FlagPrivate: @@ -554,25 +468,18 @@ static unsigned fromRust(LLVMRustDIFlags Flags) { if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) { Result |= DINode::DIFlags::FlagRValueReference; } -#if LLVM_VERSION_LE(4, 0) - if (isSet(Flags & LLVMRustDIFlags::FlagExternalTypeRef)) { - Result |= DINode::DIFlags::FlagExternalTypeRef; - } -#endif if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) { Result |= DINode::DIFlags::FlagIntroducedVirtual; } if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) { Result |= DINode::DIFlags::FlagBitField; } -#if LLVM_RUSTLLVM || LLVM_VERSION_GE(4, 0) if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) { Result |= DINode::DIFlags::FlagNoReturn; } if (isSet(Flags & LLVMRustDIFlags::FlagMainSubprogram)) { Result |= DINode::DIFlags::FlagMainSubprogram; } -#endif return Result; } @@ -612,14 +519,8 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit( unsigned RuntimeVer, const char *SplitName) { auto *File = unwrapDI(FileRef); -#if LLVM_VERSION_GE(4, 0) return wrap(Builder->createCompileUnit(Lang, File, Producer, isOptimized, Flags, RuntimeVer, SplitName)); -#else - return wrap(Builder->createCompileUnit(Lang, File->getFilename(), - File->getDirectory(), Producer, isOptimized, - Flags, RuntimeVer, SplitName)); -#endif } extern "C" LLVMMetadataRef @@ -657,11 +558,7 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(LLVMRustDIBuilderRef Builder, const char *Name, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding) { - return wrap(Builder->createBasicType(Name, SizeInBits, -#if LLVM_VERSION_LE(3, 9) - AlignInBits, -#endif - Encoding)); + return wrap(Builder->createBasicType(Name, SizeInBits, Encoding)); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType( @@ -669,9 +566,7 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType( uint64_t SizeInBits, uint32_t AlignInBits, const char *Name) { return wrap(Builder->createPointerType(unwrapDI(PointeeTy), SizeInBits, AlignInBits, -#if LLVM_VERSION_GE(5, 0) /* DWARFAddressSpace */ None, -#endif Name)); } @@ -722,7 +617,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable( LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) { llvm::GlobalVariable *InitVal = cast(unwrap(V)); -#if LLVM_VERSION_GE(4, 0) llvm::DIExpression *InitExpr = nullptr; if (llvm::ConstantInt *IntVal = llvm::dyn_cast(InitVal)) { InitExpr = Builder->createConstantValueExpression( @@ -741,12 +635,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable( InitVal->setMetadata("dbg", VarExpr); return wrap(VarExpr); -#else - return wrap(Builder->createGlobalVariable( - unwrapDI(Context), Name, LinkageName, - unwrapDI(File), LineNo, unwrapDI(Ty), IsLocalToUnit, - InitVal, unwrapDIPtr(Decl))); -#endif } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable( @@ -757,12 +645,7 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable( if (Tag == 0x100) { // DW_TAG_auto_variable return wrap(Builder->createAutoVariable( unwrapDI(Scope), Name, unwrapDI(File), LineNo, - unwrapDI(Ty), AlwaysPreserve, fromRust(Flags) -#if LLVM_VERSION_GE(4, 0) - , - AlignInBits -#endif - )); + unwrapDI(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits)); } else { return wrap(Builder->createParameterVariable( unwrapDI(Scope), Name, ArgNo, unwrapDI(File), @@ -854,15 +737,8 @@ LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, LLVMMetadataRef File, unsigned LineNo) { return wrap(Builder->createNameSpace( - unwrapDI(Scope), Name -#if LLVM_VERSION_LT(5, 0) - , - unwrapDI(File), LineNo -#endif -#if LLVM_VERSION_GE(4, 0) - , + unwrapDI(Scope), Name, false // ExportSymbols (only relevant for C++ anonymous namespaces) -#endif )); } @@ -891,12 +767,7 @@ extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() { } extern "C" int64_t LLVMRustDIBuilderCreateOpPlusUconst() { -#if LLVM_VERSION_GE(5, 0) return dwarf::DW_OP_plus_uconst; -#else - // older LLVM used `plus` to behave like `plus_uconst`. - return dwarf::DW_OP_plus; -#endif } extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) { @@ -968,21 +839,12 @@ extern "C" void LLVMRustUnpackOptimizationDiagnostic( *FunctionOut = wrap(&Opt->getFunction()); RawRustStringOstream FilenameOS(FilenameOut); -#if LLVM_VERSION_GE(5,0) DiagnosticLocation loc = Opt->getLocation(); if (loc.isValid()) { *Line = loc.getLine(); *Column = loc.getColumn(); FilenameOS << loc.getFilename(); } -#else - const DebugLoc &loc = Opt->getDebugLoc(); - if (loc) { - *Line = loc.getLine(); - *Column = loc.getCol(); - FilenameOS << cast(loc.getScope())->getFilename(); - } -#endif RawRustStringOstream MessageOS(MessageOut); MessageOS << Opt->getMsg(); @@ -1402,7 +1264,6 @@ LLVMRustModuleCost(LLVMModuleRef M) { } // Vector reductions: -#if LLVM_VERSION_GE(5, 0) extern "C" LLVMValueRef LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) { return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src))); @@ -1448,62 +1309,6 @@ LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) { return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN)); } -#else - -extern "C" LLVMValueRef -LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) { - return nullptr; -} -extern "C" LLVMValueRef -LLVMRustBuildVectorReduceFMul(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) { - return nullptr; -} -extern "C" LLVMValueRef -LLVMRustBuildVectorReduceAdd(LLVMBuilderRef, LLVMValueRef) { - return nullptr; -} -extern "C" LLVMValueRef -LLVMRustBuildVectorReduceMul(LLVMBuilderRef, LLVMValueRef) { - return nullptr; -} -extern "C" LLVMValueRef -LLVMRustBuildVectorReduceAnd(LLVMBuilderRef, LLVMValueRef) { - return nullptr; -} -extern "C" LLVMValueRef -LLVMRustBuildVectorReduceOr(LLVMBuilderRef, LLVMValueRef) { - return nullptr; -} -extern "C" LLVMValueRef -LLVMRustBuildVectorReduceXor(LLVMBuilderRef, LLVMValueRef) { - return nullptr; -} -extern "C" LLVMValueRef -LLVMRustBuildVectorReduceMin(LLVMBuilderRef, LLVMValueRef, bool) { - return nullptr; -} -extern "C" LLVMValueRef -LLVMRustBuildVectorReduceMax(LLVMBuilderRef, LLVMValueRef, bool) { - return nullptr; -} -extern "C" LLVMValueRef -LLVMRustBuildVectorReduceFMin(LLVMBuilderRef, LLVMValueRef, bool) { - return nullptr; -} -extern "C" LLVMValueRef -LLVMRustBuildVectorReduceFMax(LLVMBuilderRef, LLVMValueRef, bool) { - return nullptr; -} -#endif - -#if LLVM_VERSION_LT(4, 0) -extern "C" LLVMValueRef -LLVMBuildExactUDiv(LLVMBuilderRef B, LLVMValueRef LHS, - LLVMValueRef RHS, const char *Name) { - return wrap(unwrap(B)->CreateExactUDiv(unwrap(LHS), unwrap(RHS), Name)); -} -#endif - #if LLVM_VERSION_GE(6, 0) extern "C" LLVMValueRef LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) { diff --git a/src/test/codegen/call-metadata.rs b/src/test/codegen/call-metadata.rs index 20d42ed852d..1b92ff60226 100644 --- a/src/test/codegen/call-metadata.rs +++ b/src/test/codegen/call-metadata.rs @@ -12,8 +12,6 @@ // scalar value. // compile-flags: -C no-prepopulate-passes -// min-llvm-version 4.0 - #![crate_type = "lib"] diff --git a/src/test/codegen/issue-37945.rs b/src/test/codegen/issue-37945.rs index df02426badc..a36a50415ad 100644 --- a/src/test/codegen/issue-37945.rs +++ b/src/test/codegen/issue-37945.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// min-llvm-version 4.0 // compile-flags: -O // ignore-x86 // ignore-arm diff --git a/src/test/codegen/issue-45466.rs b/src/test/codegen/issue-45466.rs index 3702b675389..f916c1a0640 100644 --- a/src/test/codegen/issue-45466.rs +++ b/src/test/codegen/issue-45466.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// min-llvm-version 4.0 // compile-flags: -O #![crate_type="rlib"] diff --git a/src/test/codegen/mainsubprogram.rs b/src/test/codegen/mainsubprogram.rs index f0508bc90f2..2cfc20e30ca 100644 --- a/src/test/codegen/mainsubprogram.rs +++ b/src/test/codegen/mainsubprogram.rs @@ -14,7 +14,6 @@ // ignore-tidy-linelength // ignore-windows // ignore-macos -// min-llvm-version 4.0 // compile-flags: -g -C no-prepopulate-passes diff --git a/src/test/codegen/mainsubprogramstart.rs b/src/test/codegen/mainsubprogramstart.rs index 8325318f9af..62a996316c4 100644 --- a/src/test/codegen/mainsubprogramstart.rs +++ b/src/test/codegen/mainsubprogramstart.rs @@ -8,13 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// This test depends on a patch that was committed to upstream LLVM -// before 4.0, formerly backported to the Rust LLVM fork. - // ignore-tidy-linelength // ignore-windows // ignore-macos -// min-llvm-version 4.0 // compile-flags: -g -C no-prepopulate-passes diff --git a/src/test/codegen/noreturnflag.rs b/src/test/codegen/noreturnflag.rs index 7239223ca20..f66369782e5 100644 --- a/src/test/codegen/noreturnflag.rs +++ b/src/test/codegen/noreturnflag.rs @@ -10,7 +10,6 @@ // compile-flags: -g -C no-prepopulate-passes // ignore-tidy-linelength -// min-llvm-version 4.0 #![crate_type = "lib"] diff --git a/src/test/codegen/stack-probes.rs b/src/test/codegen/stack-probes.rs index 6ab71723a1d..b8c2e62abef 100644 --- a/src/test/codegen/stack-probes.rs +++ b/src/test/codegen/stack-probes.rs @@ -21,7 +21,6 @@ // ignore-wasm // ignore-emscripten // ignore-windows -// min-system-llvm-version 5.0 // compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] diff --git a/src/test/codegen/vtabletype.rs b/src/test/codegen/vtabletype.rs index b6466467548..abd1eb3e2cc 100644 --- a/src/test/codegen/vtabletype.rs +++ b/src/test/codegen/vtabletype.rs @@ -14,7 +14,7 @@ // ignore-tidy-linelength // ignore-windows // ignore-macos -// min-system-llvm-version 5.1 +// min-llvm-version 6.0 // compile-flags: -g -C no-prepopulate-passes diff --git a/src/test/compile-fail/simd-intrinsic-generic-reduction.rs b/src/test/compile-fail/simd-intrinsic-generic-reduction.rs index 57e4bb76a6c..725960a866b 100644 --- a/src/test/compile-fail/simd-intrinsic-generic-reduction.rs +++ b/src/test/compile-fail/simd-intrinsic-generic-reduction.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// min-llvm-version 5.0 // ignore-emscripten // Test that the simd_reduce_{op} intrinsics produce ok-ish error diff --git a/src/test/mir-opt/lower_128bit_test.rs b/src/test/mir-opt/lower_128bit_test.rs index 27446d6bd28..b4b54e13a69 100644 --- a/src/test/mir-opt/lower_128bit_test.rs +++ b/src/test/mir-opt/lower_128bit_test.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// asmjs can't even pass i128 as arguments or return values, so ignore it. -// this will hopefully be fixed by the LLVM 5 upgrade (#43370) -// ignore-asmjs // ignore-emscripten // compile-flags: -Z lower_128bit_ops=yes -C debug_assertions=no diff --git a/src/test/run-make-fulldeps/cross-lang-lto/Makefile b/src/test/run-make-fulldeps/cross-lang-lto/Makefile index cdc429d1f99..efe1b7072ff 100644 --- a/src/test/run-make-fulldeps/cross-lang-lto/Makefile +++ b/src/test/run-make-fulldeps/cross-lang-lto/Makefile @@ -1,5 +1,3 @@ - -# min-llvm-version 4.0 # ignore-msvc -include ../tools.mk diff --git a/src/test/run-make-fulldeps/llvm-pass/llvm-function-pass.so.cc b/src/test/run-make-fulldeps/llvm-pass/llvm-function-pass.so.cc index 880c9bce562..c0a17d920cf 100644 --- a/src/test/run-make-fulldeps/llvm-pass/llvm-function-pass.so.cc +++ b/src/test/run-make-fulldeps/llvm-pass/llvm-function-pass.so.cc @@ -28,12 +28,7 @@ namespace { bool runOnFunction(Function &F) override; -#if LLVM_VERSION_MAJOR >= 4 - StringRef -#else - const char * -#endif - getPassName() const override { + StringRef getPassName() const override { return "Some LLVM pass"; } diff --git a/src/test/run-make-fulldeps/llvm-pass/llvm-module-pass.so.cc b/src/test/run-make-fulldeps/llvm-pass/llvm-module-pass.so.cc index 280eca7e8f0..70051681ab0 100644 --- a/src/test/run-make-fulldeps/llvm-pass/llvm-module-pass.so.cc +++ b/src/test/run-make-fulldeps/llvm-pass/llvm-module-pass.so.cc @@ -27,12 +27,7 @@ namespace { bool runOnModule(Module &M) override; -#if LLVM_VERSION_MAJOR >= 4 - StringRef -#else - const char * -#endif - getPassName() const override { + StringRef getPassName() const override { return "Some LLVM pass"; } diff --git a/src/test/run-pass/issue-40883.rs b/src/test/run-pass/issue-40883.rs index feb4a88a1d1..c1f3b2028aa 100644 --- a/src/test/run-pass/issue-40883.rs +++ b/src/test/run-pass/issue-40883.rs @@ -9,7 +9,6 @@ // except according to those terms. // check that we don't have linear stack usage with multiple calls to `push` -// min-llvm-version 4.0 #![feature(test)] diff --git a/src/test/run-pass/simd-intrinsic-generic-reduction.rs b/src/test/run-pass/simd-intrinsic-generic-reduction.rs index 9a1214d3b35..8e999b7115e 100644 --- a/src/test/run-pass/simd-intrinsic-generic-reduction.rs +++ b/src/test/run-pass/simd-intrinsic-generic-reduction.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// min-llvm-version 5.0 // ignore-emscripten // Test that the simd_reduce_{op} intrinsics produce the correct results. diff --git a/src/test/run-pass/stack-probes-lto.rs b/src/test/run-pass/stack-probes-lto.rs index 3fef19c51bd..ff5413ce06c 100644 --- a/src/test/run-pass/stack-probes-lto.rs +++ b/src/test/run-pass/stack-probes-lto.rs @@ -21,7 +21,6 @@ // ignore-emscripten no processes // ignore-musl FIXME #31506 // ignore-pretty -// min-system-llvm-version 5.0 // compile-flags: -C lto // no-prefer-dynamic diff --git a/src/test/run-pass/stack-probes.rs b/src/test/run-pass/stack-probes.rs index c93dcf01939..1334ab8dc63 100644 --- a/src/test/run-pass/stack-probes.rs +++ b/src/test/run-pass/stack-probes.rs @@ -20,7 +20,6 @@ // ignore-cloudabi no processes // ignore-emscripten no processes // ignore-musl FIXME #31506 -// min-system-llvm-version 5.0 use std::mem; use std::process::Command; diff --git a/src/test/run-pass/thin-lto-global-allocator.rs b/src/test/run-pass/thin-lto-global-allocator.rs index 3a0e2fe01db..257d5bbc306 100644 --- a/src/test/run-pass/thin-lto-global-allocator.rs +++ b/src/test/run-pass/thin-lto-global-allocator.rs @@ -9,7 +9,6 @@ // except according to those terms. // compile-flags: -Z thinlto -C codegen-units=2 -// min-llvm-version 4.0 #[global_allocator] static A: std::alloc::System = std::alloc::System; diff --git a/src/test/run-pass/thinlto/all-crates.rs b/src/test/run-pass/thinlto/all-crates.rs index 772a9ec8293..8d68202d711 100644 --- a/src/test/run-pass/thinlto/all-crates.rs +++ b/src/test/run-pass/thinlto/all-crates.rs @@ -10,7 +10,6 @@ // compile-flags: -Clto=thin // no-prefer-dynamic -// min-llvm-version 4.0 fn main() { println!("hello!"); diff --git a/src/test/run-pass/thinlto/dylib-works.rs b/src/test/run-pass/thinlto/dylib-works.rs index 3f54519d0d8..06df40f6142 100644 --- a/src/test/run-pass/thinlto/dylib-works.rs +++ b/src/test/run-pass/thinlto/dylib-works.rs @@ -9,7 +9,6 @@ // except according to those terms. // aux-build:dylib.rs -// min-llvm-version 4.0 extern crate dylib; diff --git a/src/test/run-pass/thinlto/msvc-imp-present.rs b/src/test/run-pass/thinlto/msvc-imp-present.rs index 8329c7032f1..95cff2a2862 100644 --- a/src/test/run-pass/thinlto/msvc-imp-present.rs +++ b/src/test/run-pass/thinlto/msvc-imp-present.rs @@ -10,7 +10,6 @@ // aux-build:msvc-imp-present.rs // compile-flags: -Z thinlto -C codegen-units=8 -// min-llvm-version: 4.0 // no-prefer-dynamic // On MSVC we have a "hack" where we emit symbols that look like `_imp_$name` diff --git a/src/test/run-pass/thinlto/thin-lto-inlines.rs b/src/test/run-pass/thinlto/thin-lto-inlines.rs index 7a71dd2bc51..41ca983af51 100644 --- a/src/test/run-pass/thinlto/thin-lto-inlines.rs +++ b/src/test/run-pass/thinlto/thin-lto-inlines.rs @@ -9,7 +9,6 @@ // except according to those terms. // compile-flags: -Z thinlto -C codegen-units=8 -O -// min-llvm-version 4.0 // ignore-emscripten can't inspect instructions on emscripten // We want to assert here that ThinLTO will inline across codegen units. There's diff --git a/src/test/run-pass/thinlto/thin-lto-inlines2.rs b/src/test/run-pass/thinlto/thin-lto-inlines2.rs index 6020f72415d..3c0e904662a 100644 --- a/src/test/run-pass/thinlto/thin-lto-inlines2.rs +++ b/src/test/run-pass/thinlto/thin-lto-inlines2.rs @@ -10,7 +10,6 @@ // compile-flags: -C codegen-units=8 -O -C lto=thin // aux-build:thin-lto-inlines-aux.rs -// min-llvm-version 4.0 // no-prefer-dynamic // ignore-emscripten can't inspect instructions on emscripten diff --git a/src/test/run-pass/thinlto/weak-works.rs b/src/test/run-pass/thinlto/weak-works.rs index b9719e04f34..0a1b7307a46 100644 --- a/src/test/run-pass/thinlto/weak-works.rs +++ b/src/test/run-pass/thinlto/weak-works.rs @@ -10,7 +10,6 @@ // compile-flags: -C codegen-units=8 -Z thinlto // ignore-windows -// min-llvm-version 4.0 #![feature(linkage)] -- cgit 1.4.1-3-g733a5 From 23dfb42ab3010418d54f852ddad263b1e7148fab Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Mon, 9 Jul 2018 11:29:13 +0200 Subject: still support LLVM4 for emscripten --- src/rustllvm/RustWrapper.cpp | 168 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 167 insertions(+), 1 deletion(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 2ac7a6a46ba..d82410618d0 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -16,8 +16,14 @@ #include "llvm/Object/Archive.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Bitcode/BitcodeWriterPass.h" + #include "llvm/IR/CallSite.h" + +#if LLVM_VERSION_GE(5, 0) #include "llvm/ADT/Optional.h" +#else +#include +#endif //===----------------------------------------------------------------------=== // @@ -170,7 +176,14 @@ extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index, LLVMRustAttribute RustAttr) { CallSite Call = CallSite(unwrap(Instr)); Attribute Attr = Attribute::get(Call->getContext(), fromRust(RustAttr)); +#if LLVM_VERSION_GE(5, 0) Call.addAttribute(Index, Attr); +#else + AttrBuilder B(Attr); + Call.setAttributes(Call.getAttributes().addAttributes( + Call->getContext(), Index, + AttributeSet::get(Call->getContext(), Index, B))); +#endif } extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr, @@ -179,8 +192,14 @@ extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr, CallSite Call = CallSite(unwrap(Instr)); AttrBuilder B; B.addAlignmentAttr(Bytes); +#if LLVM_VERSION_GE(5, 0) Call.setAttributes(Call.getAttributes().addAttributes( Call->getContext(), Index, B)); +#else + Call.setAttributes(Call.getAttributes().addAttributes( + Call->getContext(), Index, + AttributeSet::get(Call->getContext(), Index, B))); +#endif } extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr, @@ -189,8 +208,14 @@ extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr, CallSite Call = CallSite(unwrap(Instr)); AttrBuilder B; B.addDereferenceableAttr(Bytes); +#if LLVM_VERSION_GE(5, 0) Call.setAttributes(Call.getAttributes().addAttributes( Call->getContext(), Index, B)); +#else + Call.setAttributes(Call.getAttributes().addAttributes( + Call->getContext(), Index, + AttributeSet::get(Call->getContext(), Index, B))); +#endif } extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr, @@ -199,8 +224,14 @@ extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr, CallSite Call = CallSite(unwrap(Instr)); AttrBuilder B; B.addDereferenceableOrNullAttr(Bytes); +#if LLVM_VERSION_GE(5, 0) Call.setAttributes(Call.getAttributes().addAttributes( Call->getContext(), Index, B)); +#else + Call.setAttributes(Call.getAttributes().addAttributes( + Call->getContext(), Index, + AttributeSet::get(Call->getContext(), Index, B))); +#endif } extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index, @@ -208,7 +239,11 @@ extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index, Function *A = unwrap(Fn); Attribute Attr = Attribute::get(A->getContext(), fromRust(RustAttr)); AttrBuilder B(Attr); +#if LLVM_VERSION_GE(5, 0) A->addAttributes(Index, B); +#else + A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B)); +#endif } extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn, @@ -217,7 +252,11 @@ extern "C" void LLVMRustAddAlignmentAttr(LLVMValueRef Fn, Function *A = unwrap(Fn); AttrBuilder B; B.addAlignmentAttr(Bytes); +#if LLVM_VERSION_GE(5, 0) A->addAttributes(Index, B); +#else + A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B)); +#endif } extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index, @@ -225,7 +264,11 @@ extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index, Function *A = unwrap(Fn); AttrBuilder B; B.addDereferenceableAttr(Bytes); +#if LLVM_VERSION_GE(5, 0) A->addAttributes(Index, B); +#else + A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B)); +#endif } extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn, @@ -234,7 +277,11 @@ extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn, Function *A = unwrap(Fn); AttrBuilder B; B.addDereferenceableOrNullAttr(Bytes); +#if LLVM_VERSION_GE(5, 0) A->addAttributes(Index, B); +#else + A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B)); +#endif } extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn, @@ -244,7 +291,11 @@ extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn, Function *F = unwrap(Fn); AttrBuilder B; B.addAttribute(Name, Value); +#if LLVM_VERSION_GE(5, 0) F->addAttributes(Index, B); +#else + F->addAttributes(Index, AttributeSet::get(F->getContext(), Index, B)); +#endif } extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn, @@ -254,7 +305,12 @@ extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn, Attribute Attr = Attribute::get(F->getContext(), fromRust(RustAttr)); AttrBuilder B(Attr); auto PAL = F->getAttributes(); +#if LLVM_VERSION_GE(5, 0) auto PALNew = PAL.removeAttributes(F->getContext(), Index, B); +#else + const AttributeSet PALNew = PAL.removeAttributes( + F->getContext(), Index, AttributeSet::get(F->getContext(), Index, B)); +#endif F->setAttributes(PALNew); } @@ -304,6 +360,7 @@ enum class LLVMRustSynchronizationScope { CrossThread, }; +#if LLVM_VERSION_GE(5, 0) static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) { switch (Scope) { case LLVMRustSynchronizationScope::SingleThread: @@ -314,6 +371,18 @@ static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) { report_fatal_error("bad SynchronizationScope."); } } +#else +static SynchronizationScope fromRust(LLVMRustSynchronizationScope Scope) { + switch (Scope) { + case LLVMRustSynchronizationScope::SingleThread: + return SingleThread; + case LLVMRustSynchronizationScope::CrossThread: + return CrossThread; + default: + report_fatal_error("bad SynchronizationScope."); + } +} +#endif extern "C" LLVMValueRef LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order, @@ -353,6 +422,18 @@ extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm) typedef DIBuilder *LLVMRustDIBuilderRef; +#if LLVM_VERSION_LT(5, 0) +typedef struct LLVMOpaqueMetadata *LLVMMetadataRef; + +namespace llvm { +DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef) + +inline Metadata **unwrap(LLVMMetadataRef *Vals) { + return reinterpret_cast(Vals); +} +} +#endif + template DIT *unwrapDIPtr(LLVMMetadataRef Ref) { return (DIT *)(Ref ? unwrap(Ref) : nullptr); } @@ -468,6 +549,11 @@ static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) { if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) { Result |= DINode::DIFlags::FlagRValueReference; } +#if LLVM_VERSION_LE(4, 0) + if (isSet(Flags & LLVMRustDIFlags::FlagExternalTypeRef)) { + Result |= DINode::DIFlags::FlagExternalTypeRef; + } +#endif if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) { Result |= DINode::DIFlags::FlagIntroducedVirtual; } @@ -566,7 +652,9 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType( uint64_t SizeInBits, uint32_t AlignInBits, const char *Name) { return wrap(Builder->createPointerType(unwrapDI(PointeeTy), SizeInBits, AlignInBits, +#if LLVM_VERSION_GE(5, 0) /* DWARFAddressSpace */ None, +#endif Name)); } @@ -737,8 +825,15 @@ LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, LLVMMetadataRef File, unsigned LineNo) { return wrap(Builder->createNameSpace( - unwrapDI(Scope), Name, + unwrapDI(Scope), Name +#if LLVM_VERSION_LT(5, 0) + , + unwrapDI(File), LineNo +#endif +#if LLVM_VERSION_GE(4, 0) + , false // ExportSymbols (only relevant for C++ anonymous namespaces) +#endif )); } @@ -767,7 +862,12 @@ extern "C" int64_t LLVMRustDIBuilderCreateOpDeref() { } extern "C" int64_t LLVMRustDIBuilderCreateOpPlusUconst() { +#if LLVM_VERSION_GE(5, 0) return dwarf::DW_OP_plus_uconst; +#else + // older LLVM used `plus` to behave like `plus_uconst`. + return dwarf::DW_OP_plus; +#endif } extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) { @@ -839,12 +939,21 @@ extern "C" void LLVMRustUnpackOptimizationDiagnostic( *FunctionOut = wrap(&Opt->getFunction()); RawRustStringOstream FilenameOS(FilenameOut); +#if LLVM_VERSION_GE(5,0) DiagnosticLocation loc = Opt->getLocation(); if (loc.isValid()) { *Line = loc.getLine(); *Column = loc.getColumn(); FilenameOS << loc.getFilename(); } +#else + const DebugLoc &loc = Opt->getDebugLoc(); + if (loc) { + *Line = loc.getLine(); + *Column = loc.getCol(); + FilenameOS << cast(loc.getScope())->getFilename(); + } +#endif RawRustStringOstream MessageOS(MessageOut); MessageOS << Opt->getMsg(); @@ -1264,6 +1373,7 @@ LLVMRustModuleCost(LLVMModuleRef M) { } // Vector reductions: +#if LLVM_VERSION_GE(5, 0) extern "C" LLVMValueRef LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) { return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src))); @@ -1309,6 +1419,62 @@ LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) { return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN)); } +#else + +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) { + return nullptr; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFMul(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) { + return nullptr; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceAdd(LLVMBuilderRef, LLVMValueRef) { + return nullptr; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceMul(LLVMBuilderRef, LLVMValueRef) { + return nullptr; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceAnd(LLVMBuilderRef, LLVMValueRef) { + return nullptr; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceOr(LLVMBuilderRef, LLVMValueRef) { + return nullptr; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceXor(LLVMBuilderRef, LLVMValueRef) { + return nullptr; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceMin(LLVMBuilderRef, LLVMValueRef, bool) { + return nullptr; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceMax(LLVMBuilderRef, LLVMValueRef, bool) { + return nullptr; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFMin(LLVMBuilderRef, LLVMValueRef, bool) { + return nullptr; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFMax(LLVMBuilderRef, LLVMValueRef, bool) { + return nullptr; +} +#endif + +#if LLVM_VERSION_LT(4, 0) +extern "C" LLVMValueRef +LLVMBuildExactUDiv(LLVMBuilderRef B, LLVMValueRef LHS, + LLVMValueRef RHS, const char *Name) { + return wrap(unwrap(B)->CreateExactUDiv(unwrap(LHS), unwrap(RHS), Name)); +} +#endif + #if LLVM_VERSION_GE(6, 0) extern "C" LLVMValueRef LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) { -- cgit 1.4.1-3-g733a5 From ebec156abfc25ce695227ed2c12c420244a433f8 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 10 Jul 2018 18:00:02 +0300 Subject: rustc_codegen_llvm: remove more unused functions. --- src/librustc_codegen_llvm/builder.rs | 194 +-------------------------------- src/librustc_codegen_llvm/llvm/ffi.rs | 195 ++++------------------------------ src/rustllvm/PassWrapper.cpp | 24 ----- src/rustllvm/RustWrapper.cpp | 9 -- 4 files changed, 21 insertions(+), 401 deletions(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index dbc16cbbf0d..676523b09f7 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -8,10 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![allow(dead_code)] // FFI wrappers - use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect}; -use llvm::{Opcode, IntPredicate, RealPredicate, False, OperandBundleDef}; +use llvm::{IntPredicate, RealPredicate, False, OperandBundleDef}; use llvm::{self, BasicBlock}; use common::*; use type_::Type; @@ -26,7 +24,6 @@ use std::ffi::CString; use std::ops::Range; use std::ptr; use std::ptr::NonNull; -use syntax_pos::Span; // All Builders must have an llfn associated with them #[must_use] @@ -128,12 +125,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn position_before(&self, insn: &'ll Value) { - unsafe { - llvm::LLVMPositionBuilderBefore(self.llbuilder, insn); - } - } - pub fn position_at_end(&self, llbb: &'ll BasicBlock) { unsafe { llvm::LLVMPositionBuilderAtEnd(self.llbuilder, llbb); @@ -160,14 +151,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn aggregate_ret(&self, ret_vals: &[&'ll Value]) { - unsafe { - llvm::LLVMBuildAggregateRet(self.llbuilder, - ret_vals.as_ptr(), - ret_vals.len() as c_uint); - } - } - pub fn br(&self, dest: &'ll BasicBlock) { self.count_insn("br"); unsafe { @@ -188,13 +171,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn indirect_br(&self, addr: &'ll Value, num_dests: usize) { - self.count_insn("indirectbr"); - unsafe { - llvm::LLVMBuildIndirectBr(self.llbuilder, addr, num_dests as c_uint); - } - } - pub fn invoke(&self, llfn: &'ll Value, args: &[&'ll Value], @@ -237,20 +213,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn nswadd(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.count_insn("nswadd"); - unsafe { - llvm::LLVMBuildNSWAdd(self.llbuilder, lhs, rhs, noname()) - } - } - - pub fn nuwadd(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.count_insn("nuwadd"); - unsafe { - llvm::LLVMBuildNUWAdd(self.llbuilder, lhs, rhs, noname()) - } - } - pub fn fadd(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("fadd"); unsafe { @@ -274,20 +236,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn nswsub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.count_insn("nswsub"); - unsafe { - llvm::LLVMBuildNSWSub(self.llbuilder, lhs, rhs, noname()) - } - } - - pub fn nuwsub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.count_insn("nuwsub"); - unsafe { - llvm::LLVMBuildNUWSub(self.llbuilder, lhs, rhs, noname()) - } - } - pub fn fsub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("fsub"); unsafe { @@ -311,20 +259,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn nswmul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.count_insn("nswmul"); - unsafe { - llvm::LLVMBuildNSWMul(self.llbuilder, lhs, rhs, noname()) - } - } - - pub fn nuwmul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.count_insn("nuwmul"); - unsafe { - llvm::LLVMBuildNUWMul(self.llbuilder, lhs, rhs, noname()) - } - } - pub fn fmul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("fmul"); unsafe { @@ -458,14 +392,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn binop(&self, op: Opcode, lhs: &'ll Value, rhs: &'ll Value) - -> &'ll Value { - self.count_insn("binop"); - unsafe { - llvm::LLVMBuildBinOp(self.llbuilder, op, lhs, rhs, noname()) - } - } - pub fn neg(&self, v: &'ll Value) -> &'ll Value { self.count_insn("neg"); unsafe { @@ -473,19 +399,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn nswneg(&self, v: &'ll Value) -> &'ll Value { - self.count_insn("nswneg"); - unsafe { - llvm::LLVMBuildNSWNeg(self.llbuilder, v, noname()) - } - } - - pub fn nuwneg(&self, v: &'ll Value) -> &'ll Value { - self.count_insn("nuwneg"); - unsafe { - llvm::LLVMBuildNUWNeg(self.llbuilder, v, noname()) - } - } pub fn fneg(&self, v: &'ll Value) -> &'ll Value { self.count_insn("fneg"); unsafe { @@ -523,13 +436,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn free(&self, ptr: &'ll Value) { - self.count_insn("free"); - unsafe { - llvm::LLVMBuildFree(self.llbuilder, ptr); - } - } - pub fn load(&self, ptr: &'ll Value, align: Align) -> &'ll Value { self.count_insn("load"); unsafe { @@ -658,20 +564,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn global_string(&self, _str: *const c_char) -> &'ll Value { - self.count_insn("globalstring"); - unsafe { - llvm::LLVMBuildGlobalString(self.llbuilder, _str, noname()) - } - } - - pub fn global_string_ptr(&self, _str: *const c_char) -> &'ll Value { - self.count_insn("globalstringptr"); - unsafe { - llvm::LLVMBuildGlobalStringPtr(self.llbuilder, _str, noname()) - } - } - /* Casts */ pub fn trunc(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("trunc"); @@ -757,34 +649,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn zext_or_bitcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - self.count_insn("zextorbitcast"); - unsafe { - llvm::LLVMBuildZExtOrBitCast(self.llbuilder, val, dest_ty, noname()) - } - } - - pub fn sext_or_bitcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - self.count_insn("sextorbitcast"); - unsafe { - llvm::LLVMBuildSExtOrBitCast(self.llbuilder, val, dest_ty, noname()) - } - } - - pub fn trunc_or_bitcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - self.count_insn("truncorbitcast"); - unsafe { - llvm::LLVMBuildTruncOrBitCast(self.llbuilder, val, dest_ty, noname()) - } - } - - pub fn cast(&self, op: Opcode, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - self.count_insn("cast"); - unsafe { - llvm::LLVMBuildCast(self.llbuilder, op, val, dest_ty, noname()) - } - } - pub fn pointercast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { self.count_insn("pointercast"); unsafe { @@ -799,14 +663,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn fpcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - self.count_insn("fpcast"); - unsafe { - llvm::LLVMBuildFPCast(self.llbuilder, val, dest_ty, noname()) - } - } - - /* Comparisons */ pub fn icmp(&self, op: IntPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { self.count_insn("icmp"); @@ -842,32 +698,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn add_span_comment(&self, sp: Span, text: &str) { - if self.cx.sess().asm_comments() { - let s = format!("{} ({})", - text, - self.cx.sess().codemap().span_to_string(sp)); - debug!("{}", s); - self.add_comment(&s); - } - } - - pub fn add_comment(&self, text: &str) { - if self.cx.sess().asm_comments() { - let sanitized = text.replace("$", ""); - let comment_text = format!("{} {}", "#", - sanitized.replace("\n", "\n\t# ")); - self.count_insn("inlineasm"); - let comment_text = CString::new(comment_text).unwrap(); - let asm = unsafe { - llvm::LLVMConstInlineAsm(Type::func(&[], Type::void(self.cx)), - comment_text.as_ptr(), noname(), False, - False) - }; - self.call(asm, &[], None); - } - } - pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char, inputs: &[&'ll Value], output: &'ll Type, volatile: bool, alignstack: bool, @@ -936,6 +766,7 @@ impl Builder<'a, 'll, 'tcx> { } } + #[allow(dead_code)] pub fn va_arg(&self, list: &'ll Value, ty: &'ll Type) -> &'ll Value { self.count_insn("vaarg"); unsafe { @@ -1102,27 +933,6 @@ impl Builder<'a, 'll, 'tcx> { } } - pub fn is_null(&self, val: &'ll Value) -> &'ll Value { - self.count_insn("isnull"); - unsafe { - llvm::LLVMBuildIsNull(self.llbuilder, val, noname()) - } - } - - pub fn is_not_null(&self, val: &'ll Value) -> &'ll Value { - self.count_insn("isnotnull"); - unsafe { - llvm::LLVMBuildIsNotNull(self.llbuilder, val, noname()) - } - } - - pub fn ptrdiff(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - self.count_insn("ptrdiff"); - unsafe { - llvm::LLVMBuildPtrDiff(self.llbuilder, lhs, rhs, noname()) - } - } - pub fn landing_pad(&self, ty: &'ll Type, pers_fn: &'ll Value, num_clauses: usize) -> &'ll Value { self.count_insn("landingpad"); diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index d6b6d076807..d67cc773bbc 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -22,13 +22,12 @@ use super::debuginfo::{ }; use libc::{c_uint, c_int, size_t, c_char}; -use libc::{c_longlong, c_ulonglong, c_void}; +use libc::{c_ulonglong, c_void}; use std::ptr::NonNull; use super::RustStringRef; -pub type Opcode = u32; pub type Bool = c_uint; pub const True: Bool = 1 as Bool; @@ -36,6 +35,7 @@ pub const False: Bool = 0 as Bool; #[derive(Copy, Clone, PartialEq)] #[repr(C)] +#[allow(dead_code)] // Variants constructed by C++. pub enum LLVMRustResult { Success, Failure, @@ -88,22 +88,14 @@ pub enum Visibility { Protected = 2, } -/// LLVMDiagnosticSeverity -#[derive(Copy, Clone, Debug)] -#[repr(C)] -pub enum DiagnosticSeverity { - Error = 0, - Warning = 1, - Remark = 2, - Note = 3, -} - /// LLVMDLLStorageClass #[derive(Copy, Clone)] #[repr(C)] pub enum DLLStorageClass { + #[allow(dead_code)] Default = 0, DllImport = 1, // Function to be imported from DLL. + #[allow(dead_code)] DllExport = 2, // Function to be accessible from DLL. } @@ -220,6 +212,7 @@ pub enum AtomicRmwBinOp { #[derive(Copy, Clone)] #[repr(C)] pub enum AtomicOrdering { + #[allow(dead_code)] NotAtomic = 0, Unordered = 1, Monotonic = 2, @@ -234,6 +227,8 @@ pub enum AtomicOrdering { #[derive(Copy, Clone)] #[repr(C)] pub enum SynchronizationScope { + // FIXME: figure out if this variant is needed at all. + #[allow(dead_code)] Other, SingleThread, CrossThread, @@ -243,6 +238,8 @@ pub enum SynchronizationScope { #[derive(Copy, Clone)] #[repr(C)] pub enum FileType { + // FIXME: figure out if this variant is needed at all. + #[allow(dead_code)] Other, AssemblyFile, ObjectFile, @@ -270,6 +267,8 @@ pub enum MetadataType { #[derive(Copy, Clone)] #[repr(C)] pub enum AsmDialect { + // FIXME: figure out if this variant is needed at all. + #[allow(dead_code)] Other, Att, Intel, @@ -279,6 +278,8 @@ pub enum AsmDialect { #[derive(Copy, Clone, PartialEq)] #[repr(C)] pub enum CodeGenOptLevel { + // FIXME: figure out if this variant is needed at all. + #[allow(dead_code)] Other, None, Less, @@ -303,6 +304,8 @@ pub enum RelocMode { #[derive(Copy, Clone)] #[repr(C)] pub enum CodeModel { + // FIXME: figure out if this variant is needed at all. + #[allow(dead_code)] Other, Small, Kernel, @@ -314,6 +317,7 @@ pub enum CodeModel { /// LLVMRustDiagnosticKind #[derive(Copy, Clone)] #[repr(C)] +#[allow(dead_code)] // Variants constructed by C++. pub enum DiagnosticKind { Other, InlineAsm, @@ -334,6 +338,8 @@ pub enum DiagnosticKind { #[derive(Copy, Clone)] #[repr(C)] pub enum ArchiveKind { + // FIXME: figure out if this variant is needed at all. + #[allow(dead_code)] Other, K_GNU, K_BSD, @@ -343,6 +349,7 @@ pub enum ArchiveKind { /// LLVMRustPassKind #[derive(Copy, Clone, PartialEq, Debug)] #[repr(C)] +#[allow(dead_code)] // Variants constructed by C++. pub enum PassKind { Other, Function, @@ -406,8 +413,6 @@ extern { pub type Twine; } pub type TwineRef = *mut Twine; extern { pub type DiagnosticInfo; } pub type DiagnosticInfoRef = *mut DiagnosticInfo; -extern { pub type DebugLoc; } -pub type DebugLocRef = *mut DebugLoc; extern { pub type SMDiagnostic; } pub type SMDiagnosticRef = *mut SMDiagnostic; extern { pub type RustArchiveMember; } @@ -492,9 +497,6 @@ extern "C" { pub fn LLVMGetDataLayout(M: &Module) -> *const c_char; pub fn LLVMSetDataLayout(M: &Module, Triple: *const c_char); - /// See Module::dump. - pub fn LLVMDumpModule(M: &Module); - /// See Module::setModuleInlineAsm. pub fn LLVMSetModuleInlineAsm(M: &Module, Asm: *const c_char); pub fn LLVMRustAppendModuleInlineAsm(M: &Module, Asm: *const c_char); @@ -522,7 +524,6 @@ extern "C" { ParamCount: c_uint, IsVarArg: Bool) -> &'a Type; - pub fn LLVMGetReturnType(FunctionTy: &Type) -> &Type; pub fn LLVMCountParamTypes(FunctionTy: &Type) -> c_uint; pub fn LLVMGetParamTypes(FunctionTy: &'a Type, Dest: *mut &'a Type); @@ -532,7 +533,6 @@ extern "C" { ElementCount: c_uint, Packed: Bool) -> &'a Type; - pub fn LLVMIsPackedStruct(StructTy: &Type) -> Bool; // Operations on array, pointer, and vector types (sequence types) pub fn LLVMRustArrayType(ElementType: &Type, ElementCount: u64) -> &Type; @@ -554,13 +554,8 @@ extern "C" { pub fn LLVMReplaceAllUsesWith(OldVal: &'a Value, NewVal: &'a Value); pub fn LLVMSetMetadata(Val: &'a Value, KindID: c_uint, Node: &'a Value); - // Operations on Users - pub fn LLVMGetOperand(Val: &Value, Index: c_uint) -> &Value; - // Operations on constants of any type pub fn LLVMConstNull(Ty: &Type) -> &Value; - pub fn LLVMConstICmp(Pred: IntPredicate, V1: &'a Value, V2: &'a Value) -> &'a Value; - pub fn LLVMConstFCmp(Pred: RealPredicate, V1: &'a Value, V2: &'a Value) -> &'a Value; pub fn LLVMGetUndef(Ty: &Type) -> &Value; // Operations on metadata @@ -572,7 +567,6 @@ extern "C" { pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> &Value; pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> &Value; pub fn LLVMConstIntGetZExtValue(ConstantVal: &Value) -> c_ulonglong; - pub fn LLVMConstIntGetSExtValue(ConstantVal: &Value) -> c_longlong; pub fn LLVMRustConstInt128Get(ConstantVal: &Value, SExt: bool, high: *mut u64, low: *mut u64) -> bool; pub fn LLVMConstRealGetDouble (ConstantVal: &Value, losesInfo: *mut Bool) -> f64; @@ -597,67 +591,25 @@ extern "C" { pub fn LLVMConstVector(ScalarConstantVals: *const &Value, Size: c_uint) -> &Value; // Constant expressions - pub fn LLVMSizeOf(Ty: &Type) -> &Value; - pub fn LLVMConstNeg(ConstantVal: &Value) -> &Value; - pub fn LLVMConstFNeg(ConstantVal: &Value) -> &Value; - pub fn LLVMConstNot(ConstantVal: &Value) -> &Value; - pub fn LLVMConstAdd(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstFAdd(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstSub(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstFSub(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstMul(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstFMul(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstUDiv(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstSDiv(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstFDiv(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstURem(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstSRem(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstFRem(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstAnd(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstOr(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstXor(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstShl(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstLShr(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstAShr(LHSConstant: &'a Value, RHSConstant: &'a Value) -> &'a Value; - pub fn LLVMConstGEP( - ConstantVal: &'a Value, - ConstantIndices: *const &'a Value, - NumIndices: c_uint, - ) -> &'a Value; pub fn LLVMConstInBoundsGEP( ConstantVal: &'a Value, ConstantIndices: *const &'a Value, NumIndices: c_uint, ) -> &'a Value; - pub fn LLVMConstTrunc(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; pub fn LLVMConstZExt(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; - pub fn LLVMConstUIToFP(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; - pub fn LLVMConstSIToFP(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; - pub fn LLVMConstFPToUI(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; - pub fn LLVMConstFPToSI(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; pub fn LLVMConstPtrToInt(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; pub fn LLVMConstIntToPtr(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; pub fn LLVMConstBitCast(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; pub fn LLVMConstPointerCast(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; - pub fn LLVMConstIntCast(ConstantVal: &'a Value, ToType: &'a Type, isSigned: Bool) -> &'a Value; - pub fn LLVMConstFPCast(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; pub fn LLVMConstExtractValue(AggConstant: &Value, IdxList: *const c_uint, NumIdx: c_uint) -> &Value; - pub fn LLVMConstInlineAsm(Ty: &Type, - AsmString: *const c_char, - Constraints: *const c_char, - HasSideEffects: Bool, - IsAlignStack: Bool) - -> &Value; - // Operations on global variables, functions, and aliases (globals) pub fn LLVMIsDeclaration(Global: &Value) -> Bool; pub fn LLVMRustGetLinkage(Global: &Value) -> Linkage; pub fn LLVMRustSetLinkage(Global: &Value, RustLinkage: Linkage); - pub fn LLVMGetSection(Global: &Value) -> *const c_char; pub fn LLVMSetSection(Global: &Value, Section: *const c_char); pub fn LLVMRustGetVisibility(Global: &Value) -> Visibility; pub fn LLVMRustSetVisibility(Global: &Value, Viz: Visibility); @@ -684,10 +636,6 @@ extern "C" { pub fn LLVMSetTailCall(CallInst: &Value, IsTailCall: Bool); // Operations on functions - pub fn LLVMAddFunction(M: &'a Module, Name: *const c_char, FunctionTy: &'a Type) -> &'a Value; - pub fn LLVMGetNamedFunction(M: &Module, Name: *const c_char) -> &Value; - pub fn LLVMGetFirstFunction(M: &Module) -> &Value; - pub fn LLVMGetNextFunction(Fn: &Value) -> &Value; pub fn LLVMRustGetOrInsertFunction(M: &'a Module, Name: *const c_char, FunctionTy: &'a Type) @@ -708,7 +656,6 @@ extern "C" { pub fn LLVMGetParam(Fn: &Value, Index: c_uint) -> &Value; // Operations on basic blocks - pub fn LLVMBasicBlockAsValue(BB: &BasicBlock) -> &Value; pub fn LLVMGetBasicBlockParent(BB: &BasicBlock) -> &Value; pub fn LLVMAppendBasicBlockInContext(C: &'a Context, Fn: &'a Value, @@ -717,10 +664,7 @@ extern "C" { pub fn LLVMDeleteBasicBlock(BB: &BasicBlock); // Operations on instructions - pub fn LLVMGetInstructionParent(Inst: &Value) -> &BasicBlock; pub fn LLVMGetFirstBasicBlock(Fn: &Value) -> &BasicBlock; - pub fn LLVMGetFirstInstruction(BB: &BasicBlock) -> &'a Value; - pub fn LLVMInstructionEraseFromParent(Inst: &Value); // Operations on call sites pub fn LLVMSetInstructionCallConv(Instr: &Value, CC: c_uint); @@ -742,8 +686,6 @@ extern "C" { // Instruction builders pub fn LLVMCreateBuilderInContext(C: &Context) -> &Builder; - pub fn LLVMPositionBuilder(Builder: &'a Builder, Block: &'a BasicBlock, Instr: &'a Value); - pub fn LLVMPositionBuilderBefore(Builder: &'a Builder, Instr: &'a Value); pub fn LLVMPositionBuilderAtEnd(Builder: &'a Builder, Block: &'a BasicBlock); pub fn LLVMGetInsertBlock(Builder: &Builder) -> &BasicBlock; pub fn LLVMDisposeBuilder(Builder: &Builder); @@ -756,7 +698,6 @@ extern "C" { // Terminators pub fn LLVMBuildRetVoid(B: &Builder) -> &Value; pub fn LLVMBuildRet(B: &'a Builder, V: &'a Value) -> &'a Value; - pub fn LLVMBuildAggregateRet(B: &'a Builder, RetVals: *const &'a Value, N: c_uint) -> &'a Value; pub fn LLVMBuildBr(B: &'a Builder, Dest: &'a BasicBlock) -> &'a Value; pub fn LLVMBuildCondBr(B: &'a Builder, If: &'a Value, @@ -768,7 +709,6 @@ extern "C" { Else: &'a BasicBlock, NumCases: c_uint) -> &'a Value; - pub fn LLVMBuildIndirectBr(B: &'a Builder, Addr: &'a Value, NumDests: c_uint) -> &'a Value; pub fn LLVMRustBuildInvoke(B: &'a Builder, Fn: &'a Value, Args: *const &'a Value, @@ -828,16 +768,6 @@ extern "C" { RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildNSWAdd(B: &'a Builder, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildNUWAdd(B: &'a Builder, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; pub fn LLVMBuildFAdd(B: &'a Builder, LHS: &'a Value, RHS: &'a Value, @@ -848,16 +778,6 @@ extern "C" { RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildNSWSub(B: &'a Builder, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildNUWSub(B: &'a Builder, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; pub fn LLVMBuildFSub(B: &'a Builder, LHS: &'a Value, RHS: &'a Value, @@ -868,16 +788,6 @@ extern "C" { RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildNSWMul(B: &'a Builder, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildNUWMul(B: &'a Builder, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; pub fn LLVMBuildFMul(B: &'a Builder, LHS: &'a Value, RHS: &'a Value, @@ -953,22 +863,13 @@ extern "C" { RHS: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildBinOp(B: &'a Builder, - Op: Opcode, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; pub fn LLVMBuildNeg(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildNSWNeg(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildNUWNeg(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; pub fn LLVMBuildFNeg(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; pub fn LLVMBuildNot(B: &'a Builder, V: &'a Value, Name: *const c_char) -> &'a Value; pub fn LLVMRustSetHasUnsafeAlgebra(Instr: &Value); // Memory pub fn LLVMBuildAlloca(B: &'a Builder, Ty: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildFree(B: &'a Builder, PointerVal: &'a Value) -> &'a Value; pub fn LLVMBuildLoad(B: &'a Builder, PointerVal: &'a Value, Name: *const c_char) -> &'a Value; pub fn LLVMBuildStore(B: &'a Builder, Val: &'a Value, Ptr: &'a Value) -> &'a Value; @@ -990,14 +891,6 @@ extern "C" { Idx: c_uint, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildGlobalString(B: &Builder, - Str: *const c_char, - Name: *const c_char) - -> &Value; - pub fn LLVMBuildGlobalStringPtr(B: &Builder, - Str: *const c_char, - Name: *const c_char) - -> &Value; // Casts pub fn LLVMBuildTrunc(B: &'a Builder, @@ -1060,27 +953,6 @@ extern "C" { DestTy: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildZExtOrBitCast(B: &'a Builder, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildSExtOrBitCast(B: &'a Builder, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildTruncOrBitCast(B: &'a Builder, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildCast(B: &'a Builder, - Op: Opcode, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; pub fn LLVMBuildPointerCast(B: &'a Builder, Val: &'a Value, DestTy: &'a Type, @@ -1091,11 +963,6 @@ extern "C" { DestTy: &'a Type, IsSized: bool) -> &'a Value; - pub fn LLVMBuildFPCast(B: &'a Builder, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; // Comparisons pub fn LLVMBuildICmp(B: &'a Builder, @@ -1203,14 +1070,6 @@ extern "C" { pub fn LLVMRustBuildMinNum(B: &'a Builder, LHS: &'a Value, LHS: &'a Value) -> Option<&'a Value>; pub fn LLVMRustBuildMaxNum(B: &'a Builder, LHS: &'a Value, LHS: &'a Value) -> Option<&'a Value>; - pub fn LLVMBuildIsNull(B: &'a Builder, Val: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildIsNotNull(B: &'a Builder, Val: &'a Value, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildPtrDiff(B: &'a Builder, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - // Atomic Operations pub fn LLVMRustBuildAtomicLoad(B: &'a Builder, PointerVal: &'a Value, @@ -1245,11 +1104,6 @@ extern "C" { Order: AtomicOrdering, Scope: SynchronizationScope); - - // Selected entries from the downcasts. - pub fn LLVMIsATerminatorInst(Inst: &Value) -> &Value; - pub fn LLVMIsAStoreInst(Inst: &Value) -> &Value; - /// Writes a module to the specified path. Returns 0 on success. pub fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int; @@ -1472,13 +1326,6 @@ extern "C" { Subscripts: &'a DIArray) -> &'a DIType; - pub fn LLVMRustDIBuilderCreateVectorType(Builder: &'a DIBuilder, - Size: u64, - AlignInBits: u32, - Ty: &'a DIType, - Subscripts: &'a DIArray) - -> &'a DIType; - pub fn LLVMRustDIBuilderGetOrCreateSubrange(Builder: &DIBuilder, Lo: i64, Count: i64) @@ -1696,9 +1543,6 @@ extern "C" { pub fn LLVMRustThinLTOAvailable() -> bool; pub fn LLVMRustPGOAvailable() -> bool; - pub fn LLVMRustWriteThinBitcodeToFile(PMR: PassManagerRef, - M: &Module, - BC: *const c_char) -> bool; pub fn LLVMRustThinLTOBufferCreate(M: &Module) -> *mut ThinLTOBuffer; pub fn LLVMRustThinLTOBufferFree(M: *mut ThinLTOBuffer); pub fn LLVMRustThinLTOBufferPtr(M: *const ThinLTOBuffer) -> *const c_char; @@ -1732,7 +1576,6 @@ extern "C" { len: usize, Identifier: *const c_char, ) -> Option<&Module>; - pub fn LLVMGetModuleIdentifier(M: &Module, size: *mut usize) -> *const c_char; pub fn LLVMRustThinLTOGetDICompileUnit(M: &Module, CU1: *mut *mut c_void, CU2: *mut *mut c_void); diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 85fbc4bf378..3f5550bf95f 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -828,23 +828,6 @@ LLVMRustPGOAvailable() { // and various online resources about ThinLTO to make heads or tails of all // this. -extern "C" bool -LLVMRustWriteThinBitcodeToFile(LLVMPassManagerRef PMR, - LLVMModuleRef M, - const char *BcFile) { - llvm::legacy::PassManager *PM = unwrap(PMR); - std::error_code EC; - llvm::raw_fd_ostream bc(BcFile, EC, llvm::sys::fs::F_None); - if (EC) { - LLVMRustSetLastError(EC.message().c_str()); - return false; - } - PM->add(createWriteThinLTOBitcodePass(bc)); - PM->run(*unwrap(M)); - delete PM; - return true; -} - // This is a shared data structure which *must* be threadsafe to share // read-only amongst threads. This also corresponds basically to the arguments // of the `ProcessThinLTOModule` function in the LLVM source. @@ -1259,13 +1242,6 @@ LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) { #else -extern "C" bool -LLVMRustWriteThinBitcodeToFile(LLVMPassManagerRef PMR, - LLVMModuleRef M, - const char *BcFile) { - report_fatal_error("ThinLTO not available"); -} - struct LLVMRustThinLTOData { }; diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index d82410618d0..f2b5297285c 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -750,15 +750,6 @@ LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size, DINodeArray(unwrapDI(Subscripts)))); } -extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateVectorType(LLVMRustDIBuilderRef Builder, uint64_t Size, - uint32_t AlignInBits, LLVMMetadataRef Ty, - LLVMMetadataRef Subscripts) { - return wrap( - Builder->createVectorType(Size, AlignInBits, unwrapDI(Ty), - DINodeArray(unwrapDI(Subscripts)))); -} - extern "C" LLVMMetadataRef LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo, int64_t Count) { -- cgit 1.4.1-3-g733a5 From f0bceba669159f7bac581d03412cf69ce4558685 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 17 Jul 2018 16:20:51 -0700 Subject: rustc: Handle linker diagnostic from LLVM Previously linker diagnostic were being hidden when two modules were linked together but failed to link. This commit fixes the situation by ensuring that we have a diagnostic handler installed and also adds support for handling linker diagnostics. --- src/librustc_codegen_llvm/back/lto.rs | 12 ++++++++++-- src/librustc_codegen_llvm/back/write.rs | 13 +++++++------ src/librustc_codegen_llvm/llvm/diagnostic.rs | 4 ++++ src/librustc_codegen_llvm/llvm/ffi.rs | 1 + src/rustllvm/RustWrapper.cpp | 3 +++ .../compile-fail/auxiliary/lto-duplicate-symbols1.rs | 16 ++++++++++++++++ .../compile-fail/auxiliary/lto-duplicate-symbols2.rs | 16 ++++++++++++++++ src/test/compile-fail/lto-duplicate-symbols.rs | 20 ++++++++++++++++++++ 8 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 src/test/compile-fail/auxiliary/lto-duplicate-symbols1.rs create mode 100644 src/test/compile-fail/auxiliary/lto-duplicate-symbols2.rs create mode 100644 src/test/compile-fail/lto-duplicate-symbols.rs (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index daa2fb05280..b644422e795 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -11,7 +11,7 @@ use back::bytecode::{DecodedBytecode, RLIB_BYTECODE_EXTENSION}; use back::symbol_export; use back::write::{ModuleConfig, with_llvm_pmb, CodegenContext}; -use back::write; +use back::write::{self, DiagnosticHandlers}; use errors::{FatalError, Handler}; use llvm::archive_ro::ArchiveRO; use llvm::{True, False}; @@ -234,9 +234,17 @@ fn fat_lto(cgcx: &CodegenContext, let module = modules.remove(costliest_module); let mut serialized_bitcode = Vec::new(); { - let llmod = module.llvm().expect("can't lto pre-codegened modules").llmod(); + let (llcx, llmod) = { + let llvm = module.llvm().expect("can't lto pre-codegened modules"); + (&llvm.llcx, llvm.llmod()) + }; info!("using {:?} as a base module", module.llmod_id); + // The linking steps below may produce errors and diagnostics within LLVM + // which we'd like to handle and print, so set up our diagnostic handlers + // (which get unregistered when they go out of scope below). + let _handler = DiagnosticHandlers::new(cgcx, diag_handler, llcx); + // For all other modules we codegened we'll need to link them into our own // bitcode. All modules were codegened in their own LLVM context, however, // and we want to move everything to the same LLVM context. Currently the diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index db044878fe7..209c3a23c5c 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -397,15 +397,15 @@ impl CodegenContext { } } -struct DiagnosticHandlers<'a> { +pub struct DiagnosticHandlers<'a> { data: *mut (&'a CodegenContext, &'a Handler), llcx: &'a llvm::Context, } impl<'a> DiagnosticHandlers<'a> { - fn new(cgcx: &'a CodegenContext, - handler: &'a Handler, - llcx: &'a llvm::Context) -> Self { + pub fn new(cgcx: &'a CodegenContext, + handler: &'a Handler, + llcx: &'a llvm::Context) -> Self { let data = Box::into_raw(Box::new((cgcx, handler))); unsafe { llvm::LLVMRustSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, data as *mut _); @@ -475,10 +475,11 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void opt.message)); } } - llvm::diagnostic::PGO(diagnostic_ref) => { + llvm::diagnostic::PGO(diagnostic_ref) | + llvm::diagnostic::Linker(diagnostic_ref) => { let msg = llvm::build_string(|s| { llvm::LLVMRustWriteDiagnosticInfoToString(diagnostic_ref, s) - }).expect("non-UTF8 PGO diagnostic"); + }).expect("non-UTF8 diagnostic"); diag_handler.warn(&msg); } llvm::diagnostic::UnknownDiagnostic(..) => {}, diff --git a/src/librustc_codegen_llvm/llvm/diagnostic.rs b/src/librustc_codegen_llvm/llvm/diagnostic.rs index 7f2a9d6984a..c41a5f74ae3 100644 --- a/src/librustc_codegen_llvm/llvm/diagnostic.rs +++ b/src/librustc_codegen_llvm/llvm/diagnostic.rs @@ -126,6 +126,7 @@ pub enum Diagnostic<'ll> { Optimization(OptimizationDiagnostic<'ll>), InlineAsm(InlineAsmDiagnostic<'ll>), PGO(&'ll DiagnosticInfo), + Linker(&'ll DiagnosticInfo), /// LLVM has other types that we do not wrap here. UnknownDiagnostic(&'ll DiagnosticInfo), @@ -168,6 +169,9 @@ impl Diagnostic<'ll> { Dk::PGOProfile => { PGO(di) } + Dk::Linker => { + Linker(di) + } _ => UnknownDiagnostic(di), } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 898d3d67353..989498ea92b 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -332,6 +332,7 @@ pub enum DiagnosticKind { OptimizationRemarkOther, OptimizationFailure, PGOProfile, + Linker, } /// LLVMRustArchiveKind diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index f2b5297285c..4bcb4fd7ad3 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -984,6 +984,7 @@ enum class LLVMRustDiagnosticKind { OptimizationRemarkOther, OptimizationFailure, PGOProfile, + Linker, }; static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) { @@ -1008,6 +1009,8 @@ static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) { return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing; case DK_PGOProfile: return LLVMRustDiagnosticKind::PGOProfile; + case DK_Linker: + return LLVMRustDiagnosticKind::Linker; default: return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark) ? LLVMRustDiagnosticKind::OptimizationRemarkOther diff --git a/src/test/compile-fail/auxiliary/lto-duplicate-symbols1.rs b/src/test/compile-fail/auxiliary/lto-duplicate-symbols1.rs new file mode 100644 index 00000000000..ea09327bd19 --- /dev/null +++ b/src/test/compile-fail/auxiliary/lto-duplicate-symbols1.rs @@ -0,0 +1,16 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "rlib"] + +#[no_mangle] +pub extern fn foo() {} diff --git a/src/test/compile-fail/auxiliary/lto-duplicate-symbols2.rs b/src/test/compile-fail/auxiliary/lto-duplicate-symbols2.rs new file mode 100644 index 00000000000..ea09327bd19 --- /dev/null +++ b/src/test/compile-fail/auxiliary/lto-duplicate-symbols2.rs @@ -0,0 +1,16 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "rlib"] + +#[no_mangle] +pub extern fn foo() {} diff --git a/src/test/compile-fail/lto-duplicate-symbols.rs b/src/test/compile-fail/lto-duplicate-symbols.rs new file mode 100644 index 00000000000..9c1dbfc2af9 --- /dev/null +++ b/src/test/compile-fail/lto-duplicate-symbols.rs @@ -0,0 +1,20 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:lto-duplicate-symbols1.rs +// aux-build:lto-duplicate-symbols2.rs +// error-pattern:Linking globals named 'foo': symbol multiply defined! +// compile-flags: -C lto +// no-prefer-dynamic + +extern crate lto_duplicate_symbols1; +extern crate lto_duplicate_symbols2; + +fn main() {} -- cgit 1.4.1-3-g733a5 From 02190f397ecb32bca42e5b631dc235381d01b377 Mon Sep 17 00:00:00 2001 From: Colin Pronovost Date: Wed, 23 May 2018 15:19:07 -0400 Subject: Make globals with private linkage unnamed. Fixes #50862. --- src/librustc_codegen_llvm/consts.rs | 20 +++++++++++++------- src/librustc_codegen_llvm/declare.rs | 10 +++++++++- src/librustc_codegen_llvm/llvm/ffi.rs | 1 + src/librustc_codegen_llvm/meth.rs | 2 +- src/librustc_codegen_llvm/mir/block.rs | 4 ++-- src/librustc_codegen_llvm/mir/constant.rs | 4 ++-- src/librustc_codegen_llvm/mir/place.rs | 2 +- src/rustllvm/RustWrapper.cpp | 10 ++++++++++ src/test/codegen/consts.rs | 4 ++-- src/test/codegen/remap_path_prefix/main.rs | 2 +- .../symbols-are-reasonable/Makefile | 13 ------------- .../run-make-fulldeps/symbols-are-reasonable/lib.rs | 21 --------------------- 12 files changed, 42 insertions(+), 51 deletions(-) delete mode 100644 src/test/run-make-fulldeps/symbols-are-reasonable/Makefile delete mode 100644 src/test/run-make-fulldeps/symbols-are-reasonable/lib.rs (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 72ff65361ca..21bf490beb0 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -66,16 +66,22 @@ pub fn addr_of_mut( cx: &CodegenCx<'ll, '_>, cv: &'ll Value, align: Align, - kind: &str, + kind: Option<&str>, ) -> &'ll Value { unsafe { - let name = cx.generate_local_symbol_name(kind); - let gv = declare::define_global(cx, &name[..], val_ty(cv)).unwrap_or_else(||{ - bug!("symbol `{}` is already defined", name); - }); + let gv = match kind { + Some(kind) if !cx.tcx.sess.fewer_names() => { + let name = cx.generate_local_symbol_name(kind); + let gv = declare::define_global(cx, &name[..], val_ty(cv)).unwrap_or_else(||{ + bug!("symbol `{}` is already defined", name); + }); + llvm::LLVMRustSetLinkage(gv, llvm::Linkage::PrivateLinkage); + gv + }, + _ => declare::define_private_global(cx, val_ty(cv)), + }; llvm::LLVMSetInitializer(gv, cv); set_global_alignment(cx, gv, align); - llvm::LLVMRustSetLinkage(gv, llvm::Linkage::PrivateLinkage); SetUnnamedAddr(gv, true); gv } @@ -85,7 +91,7 @@ pub fn addr_of( cx: &CodegenCx<'ll, '_>, cv: &'ll Value, align: Align, - kind: &str, + kind: Option<&str>, ) -> &'ll Value { if let Some(&gv) = cx.const_globals.borrow().get(&cv) { unsafe { diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index 9812d7f9a41..a0310eecd59 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/src/librustc_codegen_llvm/declare.rs @@ -35,7 +35,6 @@ use value::Value; use std::ffi::CString; - /// Declare a global value. /// /// If there’s a value with the same name already declared, the function will @@ -170,6 +169,15 @@ pub fn define_global(cx: &CodegenCx<'ll, '_>, name: &str, ty: &'ll Type) -> Opti } } +/// Declare a private global +/// +/// Use this function when you intend to define a global without a name. +pub fn define_private_global(cx: &CodegenCx<'ll, '_>, ty: &'ll Type) -> &'ll Value { + unsafe { + llvm::LLVMRustInsertPrivateGlobal(cx.llmod, ty) + } +} + /// Declare a Rust function with an intention to define it. /// /// Use this function when you intend to define a function. This function will diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 898d3d67353..71304453134 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -622,6 +622,7 @@ extern "C" { pub fn LLVMAddGlobal(M: &'a Module, Ty: &'a Type, Name: *const c_char) -> &'a Value; pub fn LLVMGetNamedGlobal(M: &Module, Name: *const c_char) -> Option<&Value>; pub fn LLVMRustGetOrInsertGlobal(M: &'a Module, Name: *const c_char, T: &'a Type) -> &'a Value; + pub fn LLVMRustInsertPrivateGlobal(M: &'a Module, T: &'a Type) -> &'a Value; pub fn LLVMGetFirstGlobal(M: &Module) -> Option<&Value>; pub fn LLVMGetNextGlobal(GlobalVar: &Value) -> Option<&Value>; pub fn LLVMDeleteGlobal(GlobalVar: &Value); diff --git a/src/librustc_codegen_llvm/meth.rs b/src/librustc_codegen_llvm/meth.rs index 9c0dd0dc3d8..8a1159bc477 100644 --- a/src/librustc_codegen_llvm/meth.rs +++ b/src/librustc_codegen_llvm/meth.rs @@ -106,7 +106,7 @@ pub fn get_vtable( let vtable_const = C_struct(cx, &components, false); let align = cx.data_layout().pointer_align; - let vtable = consts::addr_of(cx, vtable_const, align, "vtable"); + let vtable = consts::addr_of(cx, vtable_const, align, Some("vtable")); debuginfo::create_vtable_metadata(cx, ty, vtable); diff --git a/src/librustc_codegen_llvm/mir/block.rs b/src/librustc_codegen_llvm/mir/block.rs index 684ecfaeec8..4e389c3b915 100644 --- a/src/librustc_codegen_llvm/mir/block.rs +++ b/src/librustc_codegen_llvm/mir/block.rs @@ -377,7 +377,7 @@ impl FunctionCx<'a, 'll, 'tcx> { let file_line_col = consts::addr_of(bx.cx, file_line_col, align, - "panic_bounds_check_loc"); + Some("panic_bounds_check_loc")); (lang_items::PanicBoundsCheckFnLangItem, vec![file_line_col, index, len]) } @@ -391,7 +391,7 @@ impl FunctionCx<'a, 'll, 'tcx> { let msg_file_line_col = consts::addr_of(bx.cx, msg_file_line_col, align, - "panic_loc"); + Some("panic_loc")); (lang_items::PanicFnLangItem, vec![msg_file_line_col]) } diff --git a/src/librustc_codegen_llvm/mir/constant.rs b/src/librustc_codegen_llvm/mir/constant.rs index 341ed9df64b..e414af07c9c 100644 --- a/src/librustc_codegen_llvm/mir/constant.rs +++ b/src/librustc_codegen_llvm/mir/constant.rs @@ -56,9 +56,9 @@ pub fn scalar_to_llvm( Some(AllocType::Memory(alloc)) => { let init = const_alloc_to_llvm(cx, alloc); if alloc.runtime_mutability == Mutability::Mutable { - consts::addr_of_mut(cx, init, alloc.align, "byte_str") + consts::addr_of_mut(cx, init, alloc.align, None) } else { - consts::addr_of(cx, init, alloc.align, "byte_str") + consts::addr_of(cx, init, alloc.align, None) } } Some(AllocType::Function(fn_instance)) => { diff --git a/src/librustc_codegen_llvm/mir/place.rs b/src/librustc_codegen_llvm/mir/place.rs index abc3dbdab2f..6fa0845dd0c 100644 --- a/src/librustc_codegen_llvm/mir/place.rs +++ b/src/librustc_codegen_llvm/mir/place.rs @@ -63,7 +63,7 @@ impl PlaceRef<'ll, 'tcx> { offset: Size, ) -> PlaceRef<'ll, 'tcx> { let init = const_alloc_to_llvm(bx.cx, alloc); - let base_addr = consts::addr_of(bx.cx, init, layout.align, "byte_str"); + let base_addr = consts::addr_of(bx.cx, init, layout.align, None); let llval = unsafe { LLVMConstInBoundsGEP( consts::bitcast(base_addr, Type::i8p(bx.cx)), diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index f2b5297285c..ce865dfbec2 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -12,6 +12,7 @@ #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/DiagnosticPrinter.h" +#include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Instructions.h" #include "llvm/Object/Archive.h" #include "llvm/Object/ObjectFile.h" @@ -116,6 +117,15 @@ LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty) { return wrap(unwrap(M)->getOrInsertGlobal(Name, unwrap(Ty))); } +extern "C" LLVMValueRef +LLVMRustInsertPrivateGlobal(LLVMModuleRef M, LLVMTypeRef Ty) { + return wrap(new GlobalVariable(*unwrap(M), + unwrap(Ty), + false, + GlobalValue::PrivateLinkage, + nullptr)); +} + extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) { return wrap(Type::getMetadataTy(*unwrap(C))); } diff --git a/src/test/codegen/consts.rs b/src/test/codegen/consts.rs index 30fffbb769b..301f5544486 100644 --- a/src/test/codegen/consts.rs +++ b/src/test/codegen/consts.rs @@ -21,11 +21,11 @@ // CHECK: @STATIC = {{.*}}, align 4 // This checks the constants from inline_enum_const -// CHECK: @byte_str.{{[0-9]+}} = {{.*}}, align 2 +// CHECK: @{{[0-9]+}} = {{.*}}, align 2 // This checks the constants from {low,high}_align_const, they share the same // constant, but the alignment differs, so the higher one should be used -// CHECK: [[LOW_HIGH:@byte_str.[0-9]+]] = {{.*}}, align 4 +// CHECK: [[LOW_HIGH:@[0-9]+]] = {{.*}}, align 4 #[derive(Copy, Clone)] diff --git a/src/test/codegen/remap_path_prefix/main.rs b/src/test/codegen/remap_path_prefix/main.rs index 4fb8c37558d..dd0f89c931d 100644 --- a/src/test/codegen/remap_path_prefix/main.rs +++ b/src/test/codegen/remap_path_prefix/main.rs @@ -22,7 +22,7 @@ mod aux_mod; include!("aux_mod.rs"); // Here we check that the expansion of the file!() macro is mapped. -// CHECK: @byte_str.1 = private unnamed_addr constant <{ [34 x i8] }> <{ [34 x i8] c"/the/src/remap_path_prefix/main.rs" }>, align 1 +// CHECK: @0 = private unnamed_addr constant <{ [34 x i8] }> <{ [34 x i8] c"/the/src/remap_path_prefix/main.rs" }>, align 1 pub static FILE_PATH: &'static str = file!(); fn main() { diff --git a/src/test/run-make-fulldeps/symbols-are-reasonable/Makefile b/src/test/run-make-fulldeps/symbols-are-reasonable/Makefile deleted file mode 100644 index a6d294d2a1c..00000000000 --- a/src/test/run-make-fulldeps/symbols-are-reasonable/Makefile +++ /dev/null @@ -1,13 +0,0 @@ --include ../tools.mk - -# check that the compile generated symbols for strings, binaries, -# vtables, etc. have semisane names (e.g. `str.1234`); it's relatively -# easy to accidentally modify the compiler internals to make them -# become things like `str"str"(1234)`. - -OUT=$(TMPDIR)/lib.s - -all: - $(RUSTC) lib.rs --emit=asm --crate-type=staticlib - # just check for symbol declarations with the names we're expecting. - $(CGREP) -e 'str\.[0-9]+:' 'byte_str\.[0-9]+:' 'vtable\.[0-9]+' < $(OUT) diff --git a/src/test/run-make-fulldeps/symbols-are-reasonable/lib.rs b/src/test/run-make-fulldeps/symbols-are-reasonable/lib.rs deleted file mode 100644 index b9285b24cd6..00000000000 --- a/src/test/run-make-fulldeps/symbols-are-reasonable/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub static X: &'static str = "foobarbaz"; -pub static Y: &'static [u8] = include_bytes!("lib.rs"); - -trait Foo { fn dummy(&self) { } } -impl Foo for usize {} - -#[no_mangle] -pub extern "C" fn dummy() { - // force the vtable to be created - let _x = &1usize as &Foo; -} -- cgit 1.4.1-3-g733a5