Skip to content

Commit db002a0

Browse files
committed
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 by llvm/llvm-project@1558bb8. * ~~https://bugs.llvm.org/show_bug.cgi?id=51476 (Miscompile on AArch64 due to incorrect comparison elimination)~~ Fixed by llvm/llvm-project@81b1065. * 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`
2 parents e7f7fe4 + 306259c commit db002a0

30 files changed

+201
-168
lines changed

Diff for: .gitmodules

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
[submodule "src/llvm-project"]
3535
path = src/llvm-project
3636
url = https://github.com/rust-lang/llvm-project.git
37-
branch = rustc/12.0-2021-07-10
37+
branch = rustc/13.0-2021-08-08
3838
[submodule "src/doc/embedded-book"]
3939
path = src/doc/embedded-book
4040
url = https://github.com/rust-embedded/book.git

Diff for: compiler/rustc_codegen_llvm/src/back/write.rs

+3-40
Original file line numberDiff line numberDiff line change
@@ -296,39 +296,8 @@ unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void
296296
}
297297
let (cgcx, _) = *(user as *const (&CodegenContext<LlvmCodegenBackend>, &Handler));
298298

299-
// Recover the post-substitution assembly code from LLVM for better
300-
// diagnostics.
301-
let mut have_source = false;
302-
let mut buffer = String::new();
303-
let mut level = llvm::DiagnosticLevel::Error;
304-
let mut loc = 0;
305-
let mut ranges = [0; 8];
306-
let mut num_ranges = ranges.len() / 2;
307-
let msg = llvm::build_string(|msg| {
308-
buffer = llvm::build_string(|buffer| {
309-
have_source = llvm::LLVMRustUnpackSMDiagnostic(
310-
diag,
311-
msg,
312-
buffer,
313-
&mut level,
314-
&mut loc,
315-
ranges.as_mut_ptr(),
316-
&mut num_ranges,
317-
);
318-
})
319-
.expect("non-UTF8 inline asm");
320-
})
321-
.expect("non-UTF8 SMDiagnostic");
322-
323-
let source = have_source.then(|| {
324-
let mut spans = vec![InnerSpan::new(loc as usize, loc as usize)];
325-
for i in 0..num_ranges {
326-
spans.push(InnerSpan::new(ranges[i * 2] as usize, ranges[i * 2 + 1] as usize));
327-
}
328-
(buffer, spans)
329-
});
330-
331-
report_inline_asm(cgcx, msg, level, cookie, source);
299+
let smdiag = llvm::diagnostic::SrcMgrDiagnostic::unpack(diag);
300+
report_inline_asm(cgcx, smdiag.message, smdiag.level, cookie, smdiag.source);
332301
}
333302

334303
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
339308

340309
match llvm::diagnostic::Diagnostic::unpack(info) {
341310
llvm::diagnostic::InlineAsm(inline) => {
342-
report_inline_asm(
343-
cgcx,
344-
llvm::twine_to_string(inline.message),
345-
inline.level,
346-
inline.cookie,
347-
None,
348-
);
311+
report_inline_asm(cgcx, inline.message, inline.level, inline.cookie, inline.source);
349312
}
350313

351314
llvm::diagnostic::Optimization(opt) => {

Diff for: compiler/rustc_codegen_llvm/src/base.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -157,16 +157,18 @@ pub fn compile_codegen_unit(
157157
}
158158

159159
// Finalize code coverage by injecting the coverage map. Note, the coverage map will
160-
// also be added to the `llvm.used` variable, created next.
160+
// also be added to the `llvm.compiler.used` variable, created next.
161161
if cx.sess().instrument_coverage() {
162162
cx.coverageinfo_finalize();
163163
}
164164

165-
// Create the llvm.used variable
166-
// This variable has type [N x i8*] and is stored in the llvm.metadata section
165+
// Create the llvm.used and llvm.compiler.used variables.
167166
if !cx.used_statics().borrow().is_empty() {
168167
cx.create_used_variable()
169168
}
169+
if !cx.compiler_used_statics().borrow().is_empty() {
170+
cx.create_compiler_used_variable()
171+
}
170172

171173
// Finalize debuginfo
172174
if cx.sess().opts.debuginfo != DebugInfo::None {

Diff for: compiler/rustc_codegen_llvm/src/consts.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,13 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
474474
}
475475

476476
if attrs.flags.contains(CodegenFnAttrFlags::USED) {
477-
self.add_used_global(g);
477+
// The semantics of #[used] in Rust only require the symbol to make it into the
478+
// object file. It is explicitly allowed for the linker to strip the symbol if it
479+
// is dead. As such, use llvm.compiler.used instead of llvm.used.
480+
// Additionally, https://reviews.llvm.org/D97448 in LLVM 13 started emitting unique
481+
// sections with SHF_GNU_RETAIN flag for llvm.used symbols, which may trigger bugs
482+
// in some versions of the gold linker.
483+
self.add_compiler_used_global(g);
478484
}
479485
}
480486
}
@@ -484,4 +490,11 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
484490
let cast = unsafe { llvm::LLVMConstPointerCast(global, self.type_i8p()) };
485491
self.used_statics.borrow_mut().push(cast);
486492
}
493+
494+
/// Add a global value to a list to be stored in the `llvm.compiler.used` variable,
495+
/// an array of i8*.
496+
fn add_compiler_used_global(&self, global: &'ll Value) {
497+
let cast = unsafe { llvm::LLVMConstPointerCast(global, self.type_i8p()) };
498+
self.compiler_used_statics.borrow_mut().push(cast);
499+
}
487500
}

Diff for: compiler/rustc_codegen_llvm/src/context.rs

+40-15
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ pub struct CodegenCx<'ll, 'tcx> {
7575
/// See <https://llvm.org/docs/LangRef.html#the-llvm-used-global-variable> for details
7676
pub used_statics: RefCell<Vec<&'ll Value>>,
7777

78+
/// Statics that will be placed in the llvm.compiler.used variable
79+
/// See <https://llvm.org/docs/LangRef.html#the-llvm-compiler-used-global-variable> for details
80+
pub compiler_used_statics: RefCell<Vec<&'ll Value>>,
81+
7882
/// Mapping of non-scalar types to llvm types and field remapping if needed.
7983
pub type_lowering: RefCell<FxHashMap<(Ty<'tcx>, Option<VariantIdx>), TypeLowering<'ll>>>,
8084

@@ -115,10 +119,6 @@ fn to_llvm_tls_model(tls_model: TlsModel) -> llvm::ThreadLocalMode {
115119
}
116120
}
117121

118-
fn strip_powerpc64_vectors(data_layout: String) -> String {
119-
data_layout.replace("-v256:256:256-v512:512:512", "")
120-
}
121-
122122
pub unsafe fn create_module(
123123
tcx: TyCtxt<'_>,
124124
llcx: &'ll llvm::Context,
@@ -130,7 +130,18 @@ pub unsafe fn create_module(
130130

131131
let mut target_data_layout = sess.target.data_layout.clone();
132132
if llvm_util::get_version() < (12, 0, 0) && sess.target.arch == "powerpc64" {
133-
target_data_layout = strip_powerpc64_vectors(target_data_layout);
133+
target_data_layout = target_data_layout.replace("-v256:256:256-v512:512:512", "");
134+
}
135+
if llvm_util::get_version() < (13, 0, 0) {
136+
if sess.target.arch == "powerpc64" {
137+
target_data_layout = target_data_layout.replace("-S128", "");
138+
}
139+
if sess.target.arch == "wasm32" {
140+
target_data_layout = "e-m:e-p:32:32-i64:64-n32:64-S128".to_string();
141+
}
142+
if sess.target.arch == "wasm64" {
143+
target_data_layout = "e-m:e-p:64:64-i64:64-n32:64-S128".to_string();
144+
}
134145
}
135146

136147
// Ensure the data-layout values hardcoded remain the defaults.
@@ -318,6 +329,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
318329
const_globals: Default::default(),
319330
statics_to_rauw: RefCell::new(Vec::new()),
320331
used_statics: RefCell::new(Vec::new()),
332+
compiler_used_statics: RefCell::new(Vec::new()),
321333
type_lowering: Default::default(),
322334
scalar_lltypes: Default::default(),
323335
pointee_infos: Default::default(),
@@ -340,6 +352,18 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
340352
pub fn coverage_context(&'a self) -> Option<&'a coverageinfo::CrateCoverageContext<'ll, 'tcx>> {
341353
self.coverage_cx.as_ref()
342354
}
355+
356+
fn create_used_variable_impl(&self, name: &'static CStr, values: &[&'ll Value]) {
357+
let section = cstr!("llvm.metadata");
358+
let array = self.const_array(&self.type_ptr_to(self.type_i8()), values);
359+
360+
unsafe {
361+
let g = llvm::LLVMAddGlobal(self.llmod, self.val_ty(array), name.as_ptr());
362+
llvm::LLVMSetInitializer(g, array);
363+
llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage);
364+
llvm::LLVMSetSection(g, section.as_ptr());
365+
}
366+
}
343367
}
344368

345369
impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
@@ -430,6 +454,10 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
430454
&self.used_statics
431455
}
432456

457+
fn compiler_used_statics(&self) -> &RefCell<Vec<&'ll Value>> {
458+
&self.compiler_used_statics
459+
}
460+
433461
fn set_frame_pointer_type(&self, llfn: &'ll Value) {
434462
attributes::set_frame_pointer_type(self, llfn)
435463
}
@@ -440,17 +468,14 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
440468
}
441469

442470
fn create_used_variable(&self) {
443-
let name = cstr!("llvm.used");
444-
let section = cstr!("llvm.metadata");
445-
let array =
446-
self.const_array(&self.type_ptr_to(self.type_i8()), &*self.used_statics.borrow());
471+
self.create_used_variable_impl(cstr!("llvm.used"), &*self.used_statics.borrow());
472+
}
447473

448-
unsafe {
449-
let g = llvm::LLVMAddGlobal(self.llmod, self.val_ty(array), name.as_ptr());
450-
llvm::LLVMSetInitializer(g, array);
451-
llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage);
452-
llvm::LLVMSetSection(g, section.as_ptr());
453-
}
474+
fn create_compiler_used_variable(&self) {
475+
self.create_used_variable_impl(
476+
cstr!("llvm.compiler.used"),
477+
&*self.compiler_used_statics.borrow(),
478+
);
454479
}
455480

456481
fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {

Diff for: compiler/rustc_codegen_llvm/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,8 @@ impl ModuleLlvm {
352352
impl Drop for ModuleLlvm {
353353
fn drop(&mut self) {
354354
unsafe {
355-
llvm::LLVMContextDispose(&mut *(self.llcx as *mut _));
356355
llvm::LLVMRustDisposeTargetMachine(&mut *(self.tm as *mut _));
356+
llvm::LLVMContextDispose(&mut *(self.llcx as *mut _));
357357
}
358358
}
359359
}

Diff for: compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs

+76-18
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ pub use self::OptimizationDiagnosticKind::*;
66
use crate::value::Value;
77
use libc::c_uint;
88

9-
use super::{DiagnosticInfo, Twine};
9+
use super::{DiagnosticInfo, SMDiagnostic};
10+
use rustc_span::InnerSpan;
1011

1112
#[derive(Copy, Clone)]
1213
pub enum OptimizationDiagnosticKind {
@@ -86,36 +87,91 @@ impl OptimizationDiagnostic<'ll> {
8687
}
8788
}
8889

89-
#[derive(Copy, Clone)]
90-
pub struct InlineAsmDiagnostic<'ll> {
90+
pub struct SrcMgrDiagnostic {
91+
pub level: super::DiagnosticLevel,
92+
pub message: String,
93+
pub source: Option<(String, Vec<InnerSpan>)>,
94+
}
95+
96+
impl SrcMgrDiagnostic {
97+
pub unsafe fn unpack(diag: &SMDiagnostic) -> SrcMgrDiagnostic {
98+
// Recover the post-substitution assembly code from LLVM for better
99+
// diagnostics.
100+
let mut have_source = false;
101+
let mut buffer = String::new();
102+
let mut level = super::DiagnosticLevel::Error;
103+
let mut loc = 0;
104+
let mut ranges = [0; 8];
105+
let mut num_ranges = ranges.len() / 2;
106+
let message = super::build_string(|message| {
107+
buffer = super::build_string(|buffer| {
108+
have_source = super::LLVMRustUnpackSMDiagnostic(
109+
diag,
110+
message,
111+
buffer,
112+
&mut level,
113+
&mut loc,
114+
ranges.as_mut_ptr(),
115+
&mut num_ranges,
116+
);
117+
})
118+
.expect("non-UTF8 inline asm");
119+
})
120+
.expect("non-UTF8 SMDiagnostic");
121+
122+
SrcMgrDiagnostic {
123+
message,
124+
level,
125+
source: have_source.then(|| {
126+
let mut spans = vec![InnerSpan::new(loc as usize, loc as usize)];
127+
for i in 0..num_ranges {
128+
spans.push(InnerSpan::new(ranges[i * 2] as usize, ranges[i * 2 + 1] as usize));
129+
}
130+
(buffer, spans)
131+
}),
132+
}
133+
}
134+
}
135+
136+
#[derive(Clone)]
137+
pub struct InlineAsmDiagnostic {
91138
pub level: super::DiagnosticLevel,
92139
pub cookie: c_uint,
93-
pub message: &'ll Twine,
94-
pub instruction: Option<&'ll Value>,
140+
pub message: String,
141+
pub source: Option<(String, Vec<InnerSpan>)>,
95142
}
96143

97-
impl InlineAsmDiagnostic<'ll> {
98-
unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self {
144+
impl InlineAsmDiagnostic {
145+
unsafe fn unpackInlineAsm(di: &'ll DiagnosticInfo) -> Self {
99146
let mut cookie = 0;
100147
let mut message = None;
101-
let mut instruction = None;
102148
let mut level = super::DiagnosticLevel::Error;
103149

104-
super::LLVMRustUnpackInlineAsmDiagnostic(
105-
di,
106-
&mut level,
107-
&mut cookie,
108-
&mut message,
109-
&mut instruction,
110-
);
150+
super::LLVMRustUnpackInlineAsmDiagnostic(di, &mut level, &mut cookie, &mut message);
111151

112-
InlineAsmDiagnostic { level, cookie, message: message.unwrap(), instruction }
152+
InlineAsmDiagnostic {
153+
level,
154+
cookie,
155+
message: super::twine_to_string(message.unwrap()),
156+
source: None,
157+
}
158+
}
159+
160+
unsafe fn unpackSrcMgr(di: &'ll DiagnosticInfo) -> Self {
161+
let mut cookie = 0;
162+
let smdiag = SrcMgrDiagnostic::unpack(super::LLVMRustGetSMDiagnostic(di, &mut cookie));
163+
InlineAsmDiagnostic {
164+
level: smdiag.level,
165+
cookie,
166+
message: smdiag.message,
167+
source: smdiag.source,
168+
}
113169
}
114170
}
115171

116172
pub enum Diagnostic<'ll> {
117173
Optimization(OptimizationDiagnostic<'ll>),
118-
InlineAsm(InlineAsmDiagnostic<'ll>),
174+
InlineAsm(InlineAsmDiagnostic),
119175
PGO(&'ll DiagnosticInfo),
120176
Linker(&'ll DiagnosticInfo),
121177
Unsupported(&'ll DiagnosticInfo),
@@ -130,7 +186,7 @@ impl Diagnostic<'ll> {
130186
let kind = super::LLVMRustGetDiagInfoKind(di);
131187

132188
match kind {
133-
Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpack(di)),
189+
Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpackInlineAsm(di)),
134190

135191
Dk::OptimizationRemark => {
136192
Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di))
@@ -162,6 +218,8 @@ impl Diagnostic<'ll> {
162218
Dk::Linker => Linker(di),
163219
Dk::Unsupported => Unsupported(di),
164220

221+
Dk::SrcMgr => InlineAsm(InlineAsmDiagnostic::unpackSrcMgr(di)),
222+
165223
_ => UnknownDiagnostic(di),
166224
}
167225
}

Diff for: compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,7 @@ pub enum DiagnosticKind {
490490
PGOProfile,
491491
Linker,
492492
Unsupported,
493+
SrcMgr,
493494
}
494495

495496
/// LLVMRustDiagnosticLevel
@@ -2264,13 +2265,17 @@ extern "C" {
22642265
level_out: &mut DiagnosticLevel,
22652266
cookie_out: &mut c_uint,
22662267
message_out: &mut Option<&'a Twine>,
2267-
instruction_out: &mut Option<&'a Value>,
22682268
);
22692269

22702270
#[allow(improper_ctypes)]
22712271
pub fn LLVMRustWriteDiagnosticInfoToString(DI: &DiagnosticInfo, s: &RustString);
22722272
pub fn LLVMRustGetDiagInfoKind(DI: &DiagnosticInfo) -> DiagnosticKind;
22732273

2274+
pub fn LLVMRustGetSMDiagnostic(
2275+
DI: &'a DiagnosticInfo,
2276+
cookie_out: &mut c_uint,
2277+
) -> &'a SMDiagnostic;
2278+
22742279
pub fn LLVMRustSetInlineAsmDiagnosticHandler(
22752280
C: &Context,
22762281
H: InlineAsmDiagHandler,

0 commit comments

Comments
 (0)