Auto merge of #87570 - nikic:llvm-13, r=nagisa
Upgrade to LLVM 13 Work in progress update to LLVM 13. Main changes: * InlineAsm diagnostics reported using SrcMgr diagnostic kind are now handled. Previously these used a separate diag handler. * Codegen tests are updated for additional attributes. * Some data layouts have changed. * Switch `#[used]` attribute from `llvm.used` to `llvm.compiler.used` to avoid SHF_GNU_RETAIN flag introduced in https://reviews.llvm.org/D97448, which appears to trigger a bug in older versions of gold. * Set `LLVM_INCLUDE_TESTS=OFF` to avoid Python 3.6 requirement. Upstream issues: * ~~https://bugs.llvm.org/show_bug.cgi?id=51210 (InlineAsm diagnostic reporting for module asm)~~ Fixed by1558bb80c0
. * ~~https://bugs.llvm.org/show_bug.cgi?id=51476 (Miscompile on AArch64 due to incorrect comparison elimination)~~ Fixed by81b106584f
. * https://bugs.llvm.org/show_bug.cgi?id=51207 (Can't set custom section flags anymore). Problematic change reverted in our fork, https://reviews.llvm.org/D107216 posted for upstream revert. * https://bugs.llvm.org/show_bug.cgi?id=51211 (Regression in codegen for #83623). This is an optimization regression that we may likely have to eat for this release. The fix for #83623 was based on an incorrect premise, and this needs to be properly addressed in the MergeICmps pass. The [compile-time impact](https://perf.rust-lang.org/compare.html?start=ef9549b6c0efb7525c9b012148689c8d070f9bc0&end=0983094463497eec22d550dad25576a894687002) is mixed, but quite positive as LLVM upgrades go. The LLVM 13 final release is scheduled for Sep 21st. The current nightly is scheduled for stable release on Oct 21st. r? `@ghost`
This commit is contained in:
commit
db002a06ae
30 changed files with 202 additions and 169 deletions
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -34,7 +34,7 @@
|
|||
[submodule "src/llvm-project"]
|
||||
path = src/llvm-project
|
||||
url = https://github.com/rust-lang/llvm-project.git
|
||||
branch = rustc/12.0-2021-07-10
|
||||
branch = rustc/13.0-2021-08-08
|
||||
[submodule "src/doc/embedded-book"]
|
||||
path = src/doc/embedded-book
|
||||
url = https://github.com/rust-embedded/book.git
|
||||
|
|
|
@ -296,39 +296,8 @@ unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void
|
|||
}
|
||||
let (cgcx, _) = *(user as *const (&CodegenContext<LlvmCodegenBackend>, &Handler));
|
||||
|
||||
// Recover the post-substitution assembly code from LLVM for better
|
||||
// diagnostics.
|
||||
let mut have_source = false;
|
||||
let mut buffer = String::new();
|
||||
let mut level = llvm::DiagnosticLevel::Error;
|
||||
let mut loc = 0;
|
||||
let mut ranges = [0; 8];
|
||||
let mut num_ranges = ranges.len() / 2;
|
||||
let msg = llvm::build_string(|msg| {
|
||||
buffer = llvm::build_string(|buffer| {
|
||||
have_source = llvm::LLVMRustUnpackSMDiagnostic(
|
||||
diag,
|
||||
msg,
|
||||
buffer,
|
||||
&mut level,
|
||||
&mut loc,
|
||||
ranges.as_mut_ptr(),
|
||||
&mut num_ranges,
|
||||
);
|
||||
})
|
||||
.expect("non-UTF8 inline asm");
|
||||
})
|
||||
.expect("non-UTF8 SMDiagnostic");
|
||||
|
||||
let source = have_source.then(|| {
|
||||
let mut spans = vec![InnerSpan::new(loc as usize, loc as usize)];
|
||||
for i in 0..num_ranges {
|
||||
spans.push(InnerSpan::new(ranges[i * 2] as usize, ranges[i * 2 + 1] as usize));
|
||||
}
|
||||
(buffer, spans)
|
||||
});
|
||||
|
||||
report_inline_asm(cgcx, msg, level, cookie, source);
|
||||
let smdiag = llvm::diagnostic::SrcMgrDiagnostic::unpack(diag);
|
||||
report_inline_asm(cgcx, smdiag.message, smdiag.level, cookie, smdiag.source);
|
||||
}
|
||||
|
||||
unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) {
|
||||
|
@ -339,13 +308,7 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
|
|||
|
||||
match llvm::diagnostic::Diagnostic::unpack(info) {
|
||||
llvm::diagnostic::InlineAsm(inline) => {
|
||||
report_inline_asm(
|
||||
cgcx,
|
||||
llvm::twine_to_string(inline.message),
|
||||
inline.level,
|
||||
inline.cookie,
|
||||
None,
|
||||
);
|
||||
report_inline_asm(cgcx, inline.message, inline.level, inline.cookie, inline.source);
|
||||
}
|
||||
|
||||
llvm::diagnostic::Optimization(opt) => {
|
||||
|
|
|
@ -157,16 +157,18 @@ pub fn compile_codegen_unit(
|
|||
}
|
||||
|
||||
// Finalize code coverage by injecting the coverage map. Note, the coverage map will
|
||||
// also be added to the `llvm.used` variable, created next.
|
||||
// also be added to the `llvm.compiler.used` variable, created next.
|
||||
if cx.sess().instrument_coverage() {
|
||||
cx.coverageinfo_finalize();
|
||||
}
|
||||
|
||||
// Create the llvm.used variable
|
||||
// This variable has type [N x i8*] and is stored in the llvm.metadata section
|
||||
// Create the llvm.used and llvm.compiler.used variables.
|
||||
if !cx.used_statics().borrow().is_empty() {
|
||||
cx.create_used_variable()
|
||||
}
|
||||
if !cx.compiler_used_statics().borrow().is_empty() {
|
||||
cx.create_compiler_used_variable()
|
||||
}
|
||||
|
||||
// Finalize debuginfo
|
||||
if cx.sess().opts.debuginfo != DebugInfo::None {
|
||||
|
|
|
@ -474,7 +474,13 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
|
|||
}
|
||||
|
||||
if attrs.flags.contains(CodegenFnAttrFlags::USED) {
|
||||
self.add_used_global(g);
|
||||
// The semantics of #[used] in Rust only require the symbol to make it into the
|
||||
// object file. It is explicitly allowed for the linker to strip the symbol if it
|
||||
// is dead. As such, use llvm.compiler.used instead of llvm.used.
|
||||
// Additionally, https://reviews.llvm.org/D97448 in LLVM 13 started emitting unique
|
||||
// sections with SHF_GNU_RETAIN flag for llvm.used symbols, which may trigger bugs
|
||||
// in some versions of the gold linker.
|
||||
self.add_compiler_used_global(g);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -484,4 +490,11 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
|
|||
let cast = unsafe { llvm::LLVMConstPointerCast(global, self.type_i8p()) };
|
||||
self.used_statics.borrow_mut().push(cast);
|
||||
}
|
||||
|
||||
/// Add a global value to a list to be stored in the `llvm.compiler.used` variable,
|
||||
/// an array of i8*.
|
||||
fn add_compiler_used_global(&self, global: &'ll Value) {
|
||||
let cast = unsafe { llvm::LLVMConstPointerCast(global, self.type_i8p()) };
|
||||
self.compiler_used_statics.borrow_mut().push(cast);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,10 @@ pub struct CodegenCx<'ll, 'tcx> {
|
|||
/// See <https://llvm.org/docs/LangRef.html#the-llvm-used-global-variable> for details
|
||||
pub used_statics: RefCell<Vec<&'ll Value>>,
|
||||
|
||||
/// Statics that will be placed in the llvm.compiler.used variable
|
||||
/// See <https://llvm.org/docs/LangRef.html#the-llvm-compiler-used-global-variable> for details
|
||||
pub compiler_used_statics: RefCell<Vec<&'ll Value>>,
|
||||
|
||||
/// Mapping of non-scalar types to llvm types and field remapping if needed.
|
||||
pub type_lowering: RefCell<FxHashMap<(Ty<'tcx>, Option<VariantIdx>), TypeLowering<'ll>>>,
|
||||
|
||||
|
@ -115,10 +119,6 @@ fn to_llvm_tls_model(tls_model: TlsModel) -> llvm::ThreadLocalMode {
|
|||
}
|
||||
}
|
||||
|
||||
fn strip_powerpc64_vectors(data_layout: String) -> String {
|
||||
data_layout.replace("-v256:256:256-v512:512:512", "")
|
||||
}
|
||||
|
||||
pub unsafe fn create_module(
|
||||
tcx: TyCtxt<'_>,
|
||||
llcx: &'ll llvm::Context,
|
||||
|
@ -130,7 +130,18 @@ pub unsafe fn create_module(
|
|||
|
||||
let mut target_data_layout = sess.target.data_layout.clone();
|
||||
if llvm_util::get_version() < (12, 0, 0) && sess.target.arch == "powerpc64" {
|
||||
target_data_layout = strip_powerpc64_vectors(target_data_layout);
|
||||
target_data_layout = target_data_layout.replace("-v256:256:256-v512:512:512", "");
|
||||
}
|
||||
if llvm_util::get_version() < (13, 0, 0) {
|
||||
if sess.target.arch == "powerpc64" {
|
||||
target_data_layout = target_data_layout.replace("-S128", "");
|
||||
}
|
||||
if sess.target.arch == "wasm32" {
|
||||
target_data_layout = "e-m:e-p:32:32-i64:64-n32:64-S128".to_string();
|
||||
}
|
||||
if sess.target.arch == "wasm64" {
|
||||
target_data_layout = "e-m:e-p:64:64-i64:64-n32:64-S128".to_string();
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the data-layout values hardcoded remain the defaults.
|
||||
|
@ -318,6 +329,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
|
|||
const_globals: Default::default(),
|
||||
statics_to_rauw: RefCell::new(Vec::new()),
|
||||
used_statics: RefCell::new(Vec::new()),
|
||||
compiler_used_statics: RefCell::new(Vec::new()),
|
||||
type_lowering: Default::default(),
|
||||
scalar_lltypes: Default::default(),
|
||||
pointee_infos: Default::default(),
|
||||
|
@ -340,6 +352,18 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
|
|||
pub fn coverage_context(&'a self) -> Option<&'a coverageinfo::CrateCoverageContext<'ll, 'tcx>> {
|
||||
self.coverage_cx.as_ref()
|
||||
}
|
||||
|
||||
fn create_used_variable_impl(&self, name: &'static CStr, values: &[&'ll Value]) {
|
||||
let section = cstr!("llvm.metadata");
|
||||
let array = self.const_array(&self.type_ptr_to(self.type_i8()), values);
|
||||
|
||||
unsafe {
|
||||
let g = llvm::LLVMAddGlobal(self.llmod, self.val_ty(array), name.as_ptr());
|
||||
llvm::LLVMSetInitializer(g, array);
|
||||
llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage);
|
||||
llvm::LLVMSetSection(g, section.as_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
|
@ -430,6 +454,10 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
&self.used_statics
|
||||
}
|
||||
|
||||
fn compiler_used_statics(&self) -> &RefCell<Vec<&'ll Value>> {
|
||||
&self.compiler_used_statics
|
||||
}
|
||||
|
||||
fn set_frame_pointer_type(&self, llfn: &'ll Value) {
|
||||
attributes::set_frame_pointer_type(self, llfn)
|
||||
}
|
||||
|
@ -440,17 +468,14 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
}
|
||||
|
||||
fn create_used_variable(&self) {
|
||||
let name = cstr!("llvm.used");
|
||||
let section = cstr!("llvm.metadata");
|
||||
let array =
|
||||
self.const_array(&self.type_ptr_to(self.type_i8()), &*self.used_statics.borrow());
|
||||
self.create_used_variable_impl(cstr!("llvm.used"), &*self.used_statics.borrow());
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let g = llvm::LLVMAddGlobal(self.llmod, self.val_ty(array), name.as_ptr());
|
||||
llvm::LLVMSetInitializer(g, array);
|
||||
llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage);
|
||||
llvm::LLVMSetSection(g, section.as_ptr());
|
||||
}
|
||||
fn create_compiler_used_variable(&self) {
|
||||
self.create_used_variable_impl(
|
||||
cstr!("llvm.compiler.used"),
|
||||
&*self.compiler_used_statics.borrow(),
|
||||
);
|
||||
}
|
||||
|
||||
fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
|
||||
|
|
|
@ -352,8 +352,8 @@ impl ModuleLlvm {
|
|||
impl Drop for ModuleLlvm {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
llvm::LLVMContextDispose(&mut *(self.llcx as *mut _));
|
||||
llvm::LLVMRustDisposeTargetMachine(&mut *(self.tm as *mut _));
|
||||
llvm::LLVMContextDispose(&mut *(self.llcx as *mut _));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@ pub use self::OptimizationDiagnosticKind::*;
|
|||
use crate::value::Value;
|
||||
use libc::c_uint;
|
||||
|
||||
use super::{DiagnosticInfo, Twine};
|
||||
use super::{DiagnosticInfo, SMDiagnostic};
|
||||
use rustc_span::InnerSpan;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum OptimizationDiagnosticKind {
|
||||
|
@ -86,36 +87,91 @@ impl OptimizationDiagnostic<'ll> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct InlineAsmDiagnostic<'ll> {
|
||||
pub struct SrcMgrDiagnostic {
|
||||
pub level: super::DiagnosticLevel,
|
||||
pub cookie: c_uint,
|
||||
pub message: &'ll Twine,
|
||||
pub instruction: Option<&'ll Value>,
|
||||
pub message: String,
|
||||
pub source: Option<(String, Vec<InnerSpan>)>,
|
||||
}
|
||||
|
||||
impl InlineAsmDiagnostic<'ll> {
|
||||
unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self {
|
||||
impl SrcMgrDiagnostic {
|
||||
pub unsafe fn unpack(diag: &SMDiagnostic) -> SrcMgrDiagnostic {
|
||||
// Recover the post-substitution assembly code from LLVM for better
|
||||
// diagnostics.
|
||||
let mut have_source = false;
|
||||
let mut buffer = String::new();
|
||||
let mut level = super::DiagnosticLevel::Error;
|
||||
let mut loc = 0;
|
||||
let mut ranges = [0; 8];
|
||||
let mut num_ranges = ranges.len() / 2;
|
||||
let message = super::build_string(|message| {
|
||||
buffer = super::build_string(|buffer| {
|
||||
have_source = super::LLVMRustUnpackSMDiagnostic(
|
||||
diag,
|
||||
message,
|
||||
buffer,
|
||||
&mut level,
|
||||
&mut loc,
|
||||
ranges.as_mut_ptr(),
|
||||
&mut num_ranges,
|
||||
);
|
||||
})
|
||||
.expect("non-UTF8 inline asm");
|
||||
})
|
||||
.expect("non-UTF8 SMDiagnostic");
|
||||
|
||||
SrcMgrDiagnostic {
|
||||
message,
|
||||
level,
|
||||
source: have_source.then(|| {
|
||||
let mut spans = vec![InnerSpan::new(loc as usize, loc as usize)];
|
||||
for i in 0..num_ranges {
|
||||
spans.push(InnerSpan::new(ranges[i * 2] as usize, ranges[i * 2 + 1] as usize));
|
||||
}
|
||||
(buffer, spans)
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InlineAsmDiagnostic {
|
||||
pub level: super::DiagnosticLevel,
|
||||
pub cookie: c_uint,
|
||||
pub message: String,
|
||||
pub source: Option<(String, Vec<InnerSpan>)>,
|
||||
}
|
||||
|
||||
impl InlineAsmDiagnostic {
|
||||
unsafe fn unpackInlineAsm(di: &'ll DiagnosticInfo) -> Self {
|
||||
let mut cookie = 0;
|
||||
let mut message = None;
|
||||
let mut instruction = None;
|
||||
let mut level = super::DiagnosticLevel::Error;
|
||||
|
||||
super::LLVMRustUnpackInlineAsmDiagnostic(
|
||||
di,
|
||||
&mut level,
|
||||
&mut cookie,
|
||||
&mut message,
|
||||
&mut instruction,
|
||||
);
|
||||
super::LLVMRustUnpackInlineAsmDiagnostic(di, &mut level, &mut cookie, &mut message);
|
||||
|
||||
InlineAsmDiagnostic { level, cookie, message: message.unwrap(), instruction }
|
||||
InlineAsmDiagnostic {
|
||||
level,
|
||||
cookie,
|
||||
message: super::twine_to_string(message.unwrap()),
|
||||
source: None,
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn unpackSrcMgr(di: &'ll DiagnosticInfo) -> Self {
|
||||
let mut cookie = 0;
|
||||
let smdiag = SrcMgrDiagnostic::unpack(super::LLVMRustGetSMDiagnostic(di, &mut cookie));
|
||||
InlineAsmDiagnostic {
|
||||
level: smdiag.level,
|
||||
cookie,
|
||||
message: smdiag.message,
|
||||
source: smdiag.source,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Diagnostic<'ll> {
|
||||
Optimization(OptimizationDiagnostic<'ll>),
|
||||
InlineAsm(InlineAsmDiagnostic<'ll>),
|
||||
InlineAsm(InlineAsmDiagnostic),
|
||||
PGO(&'ll DiagnosticInfo),
|
||||
Linker(&'ll DiagnosticInfo),
|
||||
Unsupported(&'ll DiagnosticInfo),
|
||||
|
@ -130,7 +186,7 @@ impl Diagnostic<'ll> {
|
|||
let kind = super::LLVMRustGetDiagInfoKind(di);
|
||||
|
||||
match kind {
|
||||
Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpack(di)),
|
||||
Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpackInlineAsm(di)),
|
||||
|
||||
Dk::OptimizationRemark => {
|
||||
Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di))
|
||||
|
@ -162,6 +218,8 @@ impl Diagnostic<'ll> {
|
|||
Dk::Linker => Linker(di),
|
||||
Dk::Unsupported => Unsupported(di),
|
||||
|
||||
Dk::SrcMgr => InlineAsm(InlineAsmDiagnostic::unpackSrcMgr(di)),
|
||||
|
||||
_ => UnknownDiagnostic(di),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -490,6 +490,7 @@ pub enum DiagnosticKind {
|
|||
PGOProfile,
|
||||
Linker,
|
||||
Unsupported,
|
||||
SrcMgr,
|
||||
}
|
||||
|
||||
/// LLVMRustDiagnosticLevel
|
||||
|
@ -2264,13 +2265,17 @@ extern "C" {
|
|||
level_out: &mut DiagnosticLevel,
|
||||
cookie_out: &mut c_uint,
|
||||
message_out: &mut Option<&'a Twine>,
|
||||
instruction_out: &mut Option<&'a Value>,
|
||||
);
|
||||
|
||||
#[allow(improper_ctypes)]
|
||||
pub fn LLVMRustWriteDiagnosticInfoToString(DI: &DiagnosticInfo, s: &RustString);
|
||||
pub fn LLVMRustGetDiagInfoKind(DI: &DiagnosticInfo) -> DiagnosticKind;
|
||||
|
||||
pub fn LLVMRustGetSMDiagnostic(
|
||||
DI: &'a DiagnosticInfo,
|
||||
cookie_out: &mut c_uint,
|
||||
) -> &'a SMDiagnostic;
|
||||
|
||||
pub fn LLVMRustSetInlineAsmDiagnosticHandler(
|
||||
C: &Context,
|
||||
H: InlineAsmDiagHandler,
|
||||
|
|
|
@ -16,9 +16,11 @@ pub trait MiscMethods<'tcx>: BackendTypes {
|
|||
fn sess(&self) -> &Session;
|
||||
fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx>;
|
||||
fn used_statics(&self) -> &RefCell<Vec<Self::Value>>;
|
||||
fn compiler_used_statics(&self) -> &RefCell<Vec<Self::Value>>;
|
||||
fn set_frame_pointer_type(&self, llfn: Self::Function);
|
||||
fn apply_target_cpu_attr(&self, llfn: Self::Function);
|
||||
fn create_used_variable(&self);
|
||||
fn create_compiler_used_variable(&self);
|
||||
/// Declares the extern "C" main function for the entry point. Returns None if the symbol already exists.
|
||||
fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function>;
|
||||
}
|
||||
|
|
|
@ -6,17 +6,15 @@ pub trait StaticMethods: BackendTypes {
|
|||
fn static_addr_of(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value;
|
||||
fn codegen_static(&self, def_id: DefId, is_mutable: bool);
|
||||
|
||||
/// Mark the given global value as "used", to prevent a backend from potentially removing a
|
||||
/// static variable that may otherwise appear unused.
|
||||
///
|
||||
/// Static variables in Rust can be annotated with the `#[used]` attribute to direct the `rustc`
|
||||
/// compiler to mark the variable as a "used global".
|
||||
///
|
||||
/// ```no_run
|
||||
/// #[used]
|
||||
/// static FOO: u32 = 0;
|
||||
/// ```
|
||||
/// Mark the given global value as "used", to prevent the compiler and linker from potentially
|
||||
/// removing a static variable that may otherwise appear unused.
|
||||
fn add_used_global(&self, global: Self::Value);
|
||||
|
||||
/// Same as add_used_global(), but only prevent the compiler from potentially removing an
|
||||
/// otherwise unused symbol. The linker is still permitted to drop it.
|
||||
///
|
||||
/// This corresponds to the semantics of the `#[used]` attribute.
|
||||
fn add_compiler_used_global(&self, global: Self::Value);
|
||||
}
|
||||
|
||||
pub trait StaticBuilderMethods: BackendTypes {
|
||||
|
|
|
@ -178,7 +178,7 @@ declare_features! (
|
|||
/// Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`.
|
||||
/// This defines the behavior of panics.
|
||||
(accepted, panic_handler, "1.30.0", Some(44489), None),
|
||||
/// Allows `#[used]` to preserve symbols (see llvm.used).
|
||||
/// Allows `#[used]` to preserve symbols (see llvm.compiler.used).
|
||||
(accepted, used, "1.30.0", Some(40289), None),
|
||||
/// Allows `crate` in paths.
|
||||
(accepted, crate_in_paths, "1.30.0", Some(45477), None),
|
||||
|
|
|
@ -1114,15 +1114,13 @@ extern "C" void
|
|||
LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
|
||||
LLVMRustDiagnosticLevel *LevelOut,
|
||||
unsigned *CookieOut,
|
||||
LLVMTwineRef *MessageOut,
|
||||
LLVMValueRef *InstructionOut) {
|
||||
LLVMTwineRef *MessageOut) {
|
||||
// Undefined to call this not on an inline assembly diagnostic!
|
||||
llvm::DiagnosticInfoInlineAsm *IA =
|
||||
static_cast<llvm::DiagnosticInfoInlineAsm *>(unwrap(DI));
|
||||
|
||||
*CookieOut = IA->getLocCookie();
|
||||
*MessageOut = wrap(&IA->getMsgStr());
|
||||
*InstructionOut = wrap(IA->getInstruction());
|
||||
|
||||
switch (IA->getSeverity()) {
|
||||
case DS_Error:
|
||||
|
@ -1165,6 +1163,7 @@ enum class LLVMRustDiagnosticKind {
|
|||
PGOProfile,
|
||||
Linker,
|
||||
Unsupported,
|
||||
SrcMgr,
|
||||
};
|
||||
|
||||
static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
|
||||
|
@ -1193,6 +1192,10 @@ static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
|
|||
return LLVMRustDiagnosticKind::Linker;
|
||||
case DK_Unsupported:
|
||||
return LLVMRustDiagnosticKind::Unsupported;
|
||||
#if LLVM_VERSION_GE(13, 0)
|
||||
case DK_SrcMgr:
|
||||
return LLVMRustDiagnosticKind::SrcMgr;
|
||||
#endif
|
||||
default:
|
||||
return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
|
||||
? LLVMRustDiagnosticKind::OptimizationRemarkOther
|
||||
|
@ -1280,6 +1283,17 @@ extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
|
|||
#endif
|
||||
}
|
||||
|
||||
extern "C" LLVMSMDiagnosticRef LLVMRustGetSMDiagnostic(
|
||||
LLVMDiagnosticInfoRef DI, unsigned *Cookie) {
|
||||
#if LLVM_VERSION_GE(13, 0)
|
||||
llvm::DiagnosticInfoSrcMgr *SM = static_cast<llvm::DiagnosticInfoSrcMgr *>(unwrap(DI));
|
||||
*Cookie = SM->getLocCookie();
|
||||
return wrap(&SM->getSMDiag());
|
||||
#else
|
||||
report_fatal_error("Shouldn't get called on older versions");
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef,
|
||||
RustStringRef MessageOut,
|
||||
RustStringRef BufferOut,
|
||||
|
|
|
@ -14,7 +14,7 @@ pub fn target() -> Target {
|
|||
Target {
|
||||
llvm_target: "powerpc64-unknown-linux-gnu".to_string(),
|
||||
pointer_width: 64,
|
||||
data_layout: "E-m:e-i64:64-n32:64-v256:256:256-v512:512:512".to_string(),
|
||||
data_layout: "E-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512".to_string(),
|
||||
arch: "powerpc64".to_string(),
|
||||
options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base },
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ pub fn target() -> Target {
|
|||
Target {
|
||||
llvm_target: "powerpc64-unknown-linux-musl".to_string(),
|
||||
pointer_width: 64,
|
||||
data_layout: "E-m:e-i64:64-n32:64-v256:256:256-v512:512:512".to_string(),
|
||||
data_layout: "E-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512".to_string(),
|
||||
arch: "powerpc64".to_string(),
|
||||
options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base },
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ pub fn target() -> Target {
|
|||
Target {
|
||||
llvm_target: "powerpc64-unknown-linux-gnu".to_string(),
|
||||
pointer_width: 64,
|
||||
data_layout: "E-m:e-i64:64-n32:64-v256:256:256-v512:512:512".to_string(),
|
||||
data_layout: "E-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512".to_string(),
|
||||
arch: "powerpc64".to_string(),
|
||||
options: TargetOptions { endian: Endian::Big, ..base },
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ pub fn target() -> Target {
|
|||
Target {
|
||||
llvm_target: "powerpc64le-unknown-linux-gnu".to_string(),
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i64:64-n32:64-v256:256:256-v512:512:512".to_string(),
|
||||
data_layout: "e-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512".to_string(),
|
||||
arch: "powerpc64".to_string(),
|
||||
options: TargetOptions { mcount: "_mcount".to_string(), ..base },
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ pub fn target() -> Target {
|
|||
Target {
|
||||
llvm_target: "powerpc64le-unknown-linux-musl".to_string(),
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-i64:64-n32:64-v256:256:256-v512:512:512".to_string(),
|
||||
data_layout: "e-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512".to_string(),
|
||||
arch: "powerpc64".to_string(),
|
||||
options: TargetOptions { mcount: "_mcount".to_string(), ..base },
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ pub fn target() -> Target {
|
|||
Target {
|
||||
llvm_target: "wasm32-unknown-emscripten".to_string(),
|
||||
pointer_width: 32,
|
||||
data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(),
|
||||
data_layout: "e-m:e-p:32:32-i64:64-f128:64-n32:64-S128-ni:1:10:20".to_string(),
|
||||
arch: "wasm32".to_string(),
|
||||
options: opts,
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ pub fn target() -> Target {
|
|||
Target {
|
||||
llvm_target: "wasm32-unknown-unknown".to_string(),
|
||||
pointer_width: 32,
|
||||
data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(),
|
||||
data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20".to_string(),
|
||||
arch: "wasm32".to_string(),
|
||||
options,
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ pub fn target() -> Target {
|
|||
Target {
|
||||
llvm_target: "wasm32-wasi".to_string(),
|
||||
pointer_width: 32,
|
||||
data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(),
|
||||
data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20".to_string(),
|
||||
arch: "wasm32".to_string(),
|
||||
options,
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ pub fn target() -> Target {
|
|||
Target {
|
||||
llvm_target: "wasm64-unknown-unknown".to_string(),
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:e-p:64:64-i64:64-n32:64-S128".to_string(),
|
||||
data_layout: "e-m:e-p:64:64-i64:64-n32:64-S128-ni:1:10:20".to_string(),
|
||||
arch: "wasm64".to_string(),
|
||||
options,
|
||||
}
|
||||
|
|
|
@ -180,6 +180,7 @@ impl Step for Llvm {
|
|||
.define("LLVM_INCLUDE_EXAMPLES", "OFF")
|
||||
.define("LLVM_INCLUDE_DOCS", "OFF")
|
||||
.define("LLVM_INCLUDE_BENCHMARKS", "OFF")
|
||||
.define("LLVM_INCLUDE_TESTS", "OFF")
|
||||
.define("LLVM_ENABLE_TERMINFO", "OFF")
|
||||
.define("LLVM_ENABLE_LIBEDIT", "OFF")
|
||||
.define("LLVM_ENABLE_BINDINGS", "OFF")
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 260e0f8682098faab68af9c608534756ad378365
|
||||
Subproject commit e6c5dd473b7da567dc20ed3a635ca4dd2c6b7fb6
|
|
@ -29,7 +29,7 @@ pub fn array_eq_value_still_passed_by_pointer(a: [u16; 9], b: [u16; 9]) -> bool
|
|||
// CHECK-NEXT: start:
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: %[[CMP:.+]] = tail call i32 @{{bcmp|memcmp}}(i8* nonnull dereferenceable(18) %{{.+}}, i8* nonnull dereferenceable(18) %{{.+}}, i64 18)
|
||||
// CHECK-NEXT: %[[CMP:.+]] = tail call i32 @{{bcmp|memcmp}}(i8* {{.*}} dereferenceable(18) %{{.+}}, i8* {{.*}} dereferenceable(18) %{{.+}}, i64 18)
|
||||
// CHECK-NEXT: %[[EQ:.+]] = icmp eq i32 %[[CMP]], 0
|
||||
// CHECK-NEXT: ret i1 %[[EQ]]
|
||||
a == b
|
||||
|
@ -41,7 +41,7 @@ pub fn array_eq_long(a: &[u16; 1234], b: &[u16; 1234]) -> bool {
|
|||
// CHECK-NEXT: start:
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: %[[CMP:.+]] = tail call i32 @{{bcmp|memcmp}}(i8* nonnull dereferenceable(2468) %{{.+}}, i8* nonnull dereferenceable(2468) %{{.+}}, i64 2468)
|
||||
// CHECK-NEXT: %[[CMP:.+]] = tail call i32 @{{bcmp|memcmp}}(i8* {{.*}} dereferenceable(2468) %{{.+}}, i8* {{.*}} dereferenceable(2468) %{{.+}}, i64 2468)
|
||||
// CHECK-NEXT: %[[EQ:.+]] = icmp eq i32 %[[CMP]], 0
|
||||
// CHECK-NEXT: ret i1 %[[EQ]]
|
||||
a == b
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
// This test checks that jumps generated by logical operators can be optimized away
|
||||
|
||||
// compile-flags: -Copt-level=3
|
||||
// only-64bit
|
||||
|
||||
#![crate_type="lib"]
|
||||
|
||||
pub struct Blueprint {
|
||||
pub fuel_tank_size: u32,
|
||||
pub payload: u32,
|
||||
pub wheel_diameter: u32,
|
||||
pub wheel_width: u32,
|
||||
pub storage: u32,
|
||||
}
|
||||
|
||||
// && chains should not prevent SIMD optimizations for primitives
|
||||
impl PartialEq for Blueprint{
|
||||
fn eq(&self, other: &Self)->bool{
|
||||
// CHECK-NOT: call{{.*}}bcmp
|
||||
// CHECK-NOT: call{{.*}}memcmp
|
||||
// CHECK-NOT: br {{.*}}
|
||||
self.fuel_tank_size == other.fuel_tank_size
|
||||
&& self.payload == other.payload
|
||||
&& self.wheel_diameter == other.wheel_diameter
|
||||
&& self.wheel_width == other.wheel_width
|
||||
&& self.storage == other.storage
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub struct Blueprint2 {
|
||||
pub fuel_tank_size: u32,
|
||||
pub payload: u32,
|
||||
pub wheel_diameter: u32,
|
||||
pub wheel_width: u32,
|
||||
pub storage: u32,
|
||||
}
|
||||
|
||||
// Derived PartialEq should not generate jumps and should use SIMD
|
||||
#[no_mangle]
|
||||
pub fn partial_eq_should_not_jump(a: &Blueprint2, b:&Blueprint2)->bool{
|
||||
// CHECK-NOT: call{{.*}}bcmp
|
||||
// CHECK-NOT: call{{.*}}memcmp
|
||||
// CHECK-NOT: br {{.*}}
|
||||
a==b
|
||||
}
|
|
@ -8,6 +8,6 @@ use std::iter;
|
|||
// CHECK-LABEL: @repeat_take_collect
|
||||
#[no_mangle]
|
||||
pub fn repeat_take_collect() -> Vec<u8> {
|
||||
// CHECK: call void @llvm.memset.p0i8.i{{[0-9]+}}(i8* {{(nonnull )?}}align 1{{.*}} %{{[0-9]+}}, i8 42, i{{[0-9]+}} 100000, i1 false)
|
||||
// CHECK: call void @llvm.memset.p0i8.i{{[0-9]+}}(i8* {{.*}}align 1{{.*}} %{{[0-9]+}}, i8 42, i{{[0-9]+}} 100000, i1 false)
|
||||
iter::repeat(42).take(100000).collect()
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ DEFINE_INTERNAL=define internal
|
|||
ifdef IS_WINDOWS
|
||||
LLVM_FILECHECK_OPTIONS=\
|
||||
-check-prefixes=CHECK,WINDOWS \
|
||||
-DPRIVATE_GLOBAL='internal global' \
|
||||
-DDEFINE_INTERNAL='$(DEFINE_INTERNAL)' \
|
||||
-DCOMDAT_IF_SUPPORTED='$(COMDAT_IF_SUPPORTED)' \
|
||||
-DINSTR_PROF_DATA='.lprfd$$M' \
|
||||
|
@ -36,7 +35,6 @@ ifdef IS_WINDOWS
|
|||
else
|
||||
LLVM_FILECHECK_OPTIONS=\
|
||||
-check-prefixes=CHECK \
|
||||
-DPRIVATE_GLOBAL='private global' \
|
||||
-DDEFINE_INTERNAL='$(DEFINE_INTERNAL)' \
|
||||
-DCOMDAT_IF_SUPPORTED='$(COMDAT_IF_SUPPORTED)' \
|
||||
-DINSTR_PROF_DATA='$(DATA_SECTION_PREFIX)__llvm_prf_data$(INSTR_PROF_DATA_SUFFIX)' \
|
||||
|
|
|
@ -11,27 +11,25 @@ CHECK-SAME: section "[[INSTR_PROF_COVMAP]]", align 8
|
|||
|
||||
WINDOWS: @__llvm_profile_runtime = external global i32
|
||||
|
||||
CHECK: @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = [[PRIVATE_GLOBAL]]
|
||||
CHECK-SAME: section "[[INSTR_PROF_CNTS]]", align 8
|
||||
CHECK: @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = {{private|internal}} global
|
||||
CHECK-SAME: section "[[INSTR_PROF_CNTS]]"{{.*}}, align 8
|
||||
|
||||
CHECK: @__profd__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = [[PRIVATE_GLOBAL]]
|
||||
CHECK: @__profd__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = {{private|internal}} global
|
||||
CHECK-SAME: @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called,
|
||||
CHECK-SAME: section "[[INSTR_PROF_DATA]]", align 8
|
||||
CHECK-SAME: section "[[INSTR_PROF_DATA]]"{{.*}}, align 8
|
||||
|
||||
CHECK: @__profc__R{{[a-zA-Z0-9_]+}}testprog4main = [[PRIVATE_GLOBAL]]
|
||||
CHECK-SAME: section "[[INSTR_PROF_CNTS]]", align 8
|
||||
CHECK: @__profc__R{{[a-zA-Z0-9_]+}}testprog4main = {{private|internal}} global
|
||||
CHECK-SAME: section "[[INSTR_PROF_CNTS]]"{{.*}}, align 8
|
||||
|
||||
CHECK: @__profd__R{{[a-zA-Z0-9_]+}}testprog4main = [[PRIVATE_GLOBAL]]
|
||||
CHECK: @__profd__R{{[a-zA-Z0-9_]+}}testprog4main = {{private|internal}} global
|
||||
CHECK-SAME: @__profc__R{{[a-zA-Z0-9_]+}}testprog4main,
|
||||
CHECK-SAME: section "[[INSTR_PROF_DATA]]", align 8
|
||||
CHECK-SAME: section "[[INSTR_PROF_DATA]]"{{.*}}, align 8
|
||||
|
||||
CHECK: @__llvm_prf_nm = private constant
|
||||
CHECK-SAME: section "[[INSTR_PROF_NAME]]", align 1
|
||||
|
||||
CHECK: @llvm.used = appending global
|
||||
CHECK-SAME: i8* bitcast ({ {{.*}} }* @__llvm_coverage_mapping to i8*)
|
||||
WINDOWS-SAME: i8* bitcast (i32 ()* @__llvm_profile_runtime_user to i8*)
|
||||
CHECK-SAME: i8* bitcast ({ {{.*}} }* @__profd__R{{[a-zA-Z0-9_]*}}testprog4main to i8*)
|
||||
CHECK-SAME: i8* getelementptr inbounds ({{.*}}* @__llvm_prf_nm, i32 0, i32 0)
|
||||
CHECK-SAME: section "llvm.metadata"
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// build-fail
|
||||
// ignore-emscripten no asm! support
|
||||
// The error message differs slightly between LLVM versions
|
||||
// min-llvm-version: 13.0
|
||||
// Regression test for #69092
|
||||
|
||||
#![feature(llvm_asm)]
|
||||
|
@ -7,5 +9,5 @@
|
|||
|
||||
fn main() {
|
||||
unsafe { llvm_asm!(".ascii \"Xen\0\""); }
|
||||
//~^ ERROR: expected string in '.ascii' directive
|
||||
//~^ ERROR: expected string
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: expected string in '.ascii' directive
|
||||
--> $DIR/issue-69092.rs:9:14
|
||||
error: expected string
|
||||
--> $DIR/issue-69092.rs:11:14
|
||||
|
|
||||
LL | unsafe { llvm_asm!(".ascii \"Xen\0\""); }
|
||||
| ^
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue