Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the minimum external LLVM to 13 #100460

Merged
merged 1 commit into from
Aug 16, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ jobs:
- name: mingw-check
os: ubuntu-20.04-xl
env: {}
- name: x86_64-gnu-llvm-12
- name: x86_64-gnu-llvm-13
os: ubuntu-20.04-xl
env: {}
- name: x86_64-gnu-tools
@@ -274,11 +274,11 @@ jobs:
- name: x86_64-gnu-distcheck
os: ubuntu-20.04-xl
env: {}
- name: x86_64-gnu-llvm-12
- name: x86_64-gnu-llvm-13
env:
RUST_BACKTRACE: 1
os: ubuntu-20.04-xl
- name: x86_64-gnu-llvm-12-stage1
- name: x86_64-gnu-llvm-13-stage1
env:
RUST_BACKTRACE: 1
os: ubuntu-20.04-xl
8 changes: 0 additions & 8 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@ use crate::builder::Builder;
use crate::common::Funclet;
use crate::context::CodegenCx;
use crate::llvm;
use crate::llvm_util;
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
@@ -419,13 +418,6 @@ pub(crate) fn inline_asm_call<'ll>(
let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons.as_ptr().cast(), cons.len());
debug!("constraint verification result: {:?}", constraints_ok);
if constraints_ok {
if unwind && llvm_util::get_version() < (13, 0, 0) {
bx.cx.sess().span_fatal(
line_spans[0],
"unwinding from inline assembly is only supported on llvm >= 13.",
);
}

let v = llvm::LLVMRustInlineAsm(
fty,
asm.as_ptr().cast(),
15 changes: 1 addition & 14 deletions compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ use crate::back::profiling::{
use crate::base;
use crate::common;
use crate::consts;
use crate::llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic};
use crate::llvm::{self, DiagnosticInfo, PassManager};
use crate::llvm_util;
use crate::type_::Type;
use crate::LlvmCodegenBackend;
@@ -304,17 +304,14 @@ impl<'a> DiagnosticHandlers<'a> {
remark_passes.as_ptr(),
remark_passes.len(),
);
llvm::LLVMRustSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, data.cast());
DiagnosticHandlers { data, llcx, old_handler }
}
}
}

impl<'a> Drop for DiagnosticHandlers<'a> {
fn drop(&mut self) {
use std::ptr::null_mut;
unsafe {
llvm::LLVMRustSetInlineAsmDiagnosticHandler(self.llcx, inline_asm_handler, null_mut());
llvm::LLVMRustContextSetDiagnosticHandler(self.llcx, self.old_handler);
drop(Box::from_raw(self.data));
}
@@ -342,16 +339,6 @@ fn report_inline_asm(
cgcx.diag_emitter.inline_asm_error(cookie as u32, msg, level, source);
}

unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void, cookie: c_uint) {
if user.is_null() {
return;
}
let (cgcx, _) = *(user as *const (&CodegenContext<LlvmCodegenBackend>, &Handler));

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) {
if user.is_null() {
return;
79 changes: 25 additions & 54 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@ use crate::common::Funclet;
use crate::context::CodegenCx;
use crate::llvm::{self, BasicBlock, False};
use crate::llvm::{AtomicOrdering, AtomicRmwBinOp, SynchronizationScope};
use crate::llvm_util;
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
@@ -1038,25 +1037,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
dst: &'ll Value,
cmp: &'ll Value,
src: &'ll Value,
mut order: rustc_codegen_ssa::common::AtomicOrdering,
order: rustc_codegen_ssa::common::AtomicOrdering,
failure_order: rustc_codegen_ssa::common::AtomicOrdering,
weak: bool,
) -> &'ll Value {
let weak = if weak { llvm::True } else { llvm::False };
if llvm_util::get_version() < (13, 0, 0) {
use rustc_codegen_ssa::common::AtomicOrdering::*;
// Older llvm has the pre-C++17 restriction on
// success and failure memory ordering,
// requiring the former to be at least as strong as the latter.
// So, for llvm 12, we upgrade the success ordering to a stronger
// one if necessary.
match (order, failure_order) {
(Relaxed, Acquire) => order = Acquire,
(Release, Acquire) => order = AcquireRelease,
(_, SequentiallyConsistent) => order = SequentiallyConsistent,
_ => {}
}
}
unsafe {
llvm::LLVMRustBuildAtomicCmpXchg(
self.llbuilder,
@@ -1444,51 +1429,37 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
}
}

fn fptoint_sat_broken_in_llvm(&self) -> bool {
match self.tcx.sess.target.arch.as_ref() {
// FIXME - https://bugs.llvm.org/show_bug.cgi?id=50083
"riscv64" => llvm_util::get_version() < (13, 0, 0),
_ => false,
}
}

fn fptoint_sat(
&mut self,
signed: bool,
val: &'ll Value,
dest_ty: &'ll Type,
) -> Option<&'ll Value> {
if !self.fptoint_sat_broken_in_llvm() {
let src_ty = self.cx.val_ty(val);
let (float_ty, int_ty, vector_length) = if self.cx.type_kind(src_ty) == TypeKind::Vector
{
assert_eq!(self.cx.vector_length(src_ty), self.cx.vector_length(dest_ty));
(
self.cx.element_type(src_ty),
self.cx.element_type(dest_ty),
Some(self.cx.vector_length(src_ty)),
)
} else {
(src_ty, dest_ty, None)
};
let float_width = self.cx.float_width(float_ty);
let int_width = self.cx.int_width(int_ty);

let instr = if signed { "fptosi" } else { "fptoui" };
let name = if let Some(vector_length) = vector_length {
format!(
"llvm.{}.sat.v{}i{}.v{}f{}",
instr, vector_length, int_width, vector_length, float_width
)
} else {
format!("llvm.{}.sat.i{}.f{}", instr, int_width, float_width)
};
let f =
self.declare_cfn(&name, llvm::UnnamedAddr::No, self.type_func(&[src_ty], dest_ty));
Some(self.call(self.type_func(&[src_ty], dest_ty), f, &[val], None))
let src_ty = self.cx.val_ty(val);
let (float_ty, int_ty, vector_length) = if self.cx.type_kind(src_ty) == TypeKind::Vector {
assert_eq!(self.cx.vector_length(src_ty), self.cx.vector_length(dest_ty));
(
self.cx.element_type(src_ty),
self.cx.element_type(dest_ty),
Some(self.cx.vector_length(src_ty)),
)
} else {
None
}
(src_ty, dest_ty, None)
};
let float_width = self.cx.float_width(float_ty);
let int_width = self.cx.int_width(int_ty);

let instr = if signed { "fptosi" } else { "fptoui" };
let name = if let Some(vector_length) = vector_length {
format!(
"llvm.{}.sat.v{}i{}.v{}f{}",
instr, vector_length, int_width, vector_length, float_width
)
} else {
format!("llvm.{}.sat.i{}.f{}", instr, int_width, float_width)
};
let f = self.declare_cfn(&name, llvm::UnnamedAddr::No, self.type_func(&[src_ty], dest_ty));
Some(self.call(self.type_func(&[src_ty], dest_ty), f, &[val], None))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this always return Some now?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For LLVM, yes, and that's passed directly back through BuilderMethods::fptoui_sat/fptosi_sat. But the GCC version of those methods still returns None. So I guess the fallback in cg_ssa will only be used by GCC, and maybe that could be pushed down into something GCC-specific.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #100653.

}

pub(crate) fn landing_pad(
11 changes: 0 additions & 11 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
@@ -142,17 +142,6 @@ pub unsafe fn create_module<'ll>(

let mut target_data_layout = sess.target.data_layout.to_string();
let llvm_version = llvm_util::get_version();
if llvm_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();
}
}
if llvm_version < (14, 0, 0) {
if sess.target.llvm_target == "i686-pc-windows-msvc"
|| sess.target.llvm_target == "i586-pc-windows-msvc"
6 changes: 0 additions & 6 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
@@ -2410,12 +2410,6 @@ extern "C" {
cookie_out: &mut c_uint,
) -> &'a SMDiagnostic;

pub fn LLVMRustSetInlineAsmDiagnosticHandler(
C: &Context,
H: InlineAsmDiagHandlerTy,
CX: *mut c_void,
);

#[allow(improper_ctypes)]
pub fn LLVMRustUnpackSMDiagnostic(
d: &SMDiagnostic,
10 changes: 0 additions & 10 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
@@ -92,16 +92,6 @@ unsafe fn configure_llvm(sess: &Session) {
add("-generate-arange-section", false);
}

// Disable the machine outliner by default in LLVM versions 11 and LLVM
// version 12, where it leads to miscompilation.
//
// Ref:
// - https://github.com/rust-lang/rust/issues/85351
// - https://reviews.llvm.org/D103167
if llvm_util::get_version() < (13, 0, 0) {
add("-enable-machine-outliner=never", false);
}

match sess.opts.unstable_opts.merge_functions.unwrap_or(sess.target.merge_functions) {
MergeFunctions::Disabled | MergeFunctions::Trampolines => {}
MergeFunctions::Aliases => {
11 changes: 0 additions & 11 deletions compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
Original file line number Diff line number Diff line change
@@ -24,17 +24,10 @@ extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer(
const char* const Filenames[],
size_t FilenamesLen,
RustStringRef BufferOut) {
#if LLVM_VERSION_GE(13,0)
SmallVector<std::string,32> FilenameRefs;
for (size_t i = 0; i < FilenamesLen; i++) {
FilenameRefs.push_back(std::string(Filenames[i]));
}
#else
SmallVector<StringRef,32> FilenameRefs;
for (size_t i = 0; i < FilenamesLen; i++) {
FilenameRefs.push_back(StringRef(Filenames[i]));
}
#endif
auto FilenamesWriter = coverage::CoverageFilenamesSectionWriter(
makeArrayRef(FilenameRefs));
RawRustStringOstream OS(BufferOut);
@@ -109,9 +102,5 @@ extern "C" void LLVMRustCoverageWriteMappingVarNameToString(RustStringRef Str) {
}

extern "C" uint32_t LLVMRustCoverageMappingVersion() {
#if LLVM_VERSION_GE(13, 0)
return coverage::CovMapVersion::Version6;
#else
return coverage::CovMapVersion::Version5;
#endif
}
18 changes: 1 addition & 17 deletions compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
Original file line number Diff line number Diff line change
@@ -869,19 +869,11 @@ LLVMRustOptimizeWithNewPassManager(
PGOOptions::NoCSAction, DebugInfoForProfiling);
}

#if LLVM_VERSION_GE(13, 0)
PassBuilder PB(TM, PTO, PGOOpt, &PIC);
LoopAnalysisManager LAM;
FunctionAnalysisManager FAM;
CGSCCAnalysisManager CGAM;
ModuleAnalysisManager MAM;
#else
PassBuilder PB(DebugPassManager, TM, PTO, PGOOpt, &PIC);
LoopAnalysisManager LAM(DebugPassManager);
FunctionAnalysisManager FAM(DebugPassManager);
CGSCCAnalysisManager CGAM(DebugPassManager);
ModuleAnalysisManager MAM(DebugPassManager);
#endif

FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); });

@@ -1015,11 +1007,7 @@ LLVMRustOptimizeWithNewPassManager(
}
}

#if LLVM_VERSION_GE(13, 0)
ModulePassManager MPM;
#else
ModulePassManager MPM(DebugPassManager);
#endif
bool NeedThinLTOBufferPasses = UseThinLTOBuffers;
if (!NoPrepopulatePasses) {
// The pre-link pipelines don't support O0 and require using budilO0DefaultPipeline() instead.
@@ -1434,17 +1422,13 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
Ret->ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
};

#if LLVM_VERSION_GE(13,0)
// Uses FromPrevailing visibility scheme which works for many binary
// formats. We probably could and should use ELF visibility scheme for many of
// our targets, however.
lto::Config conf;
thinLTOResolvePrevailingInIndex(conf, Ret->Index, isPrevailing, recordNewLinkage,
Ret->GUIDPreservedSymbols);
#else
thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage,
Ret->GUIDPreservedSymbols);
#endif

// Here we calculate an `ExportedGUIDs` set for use in the `isExported`
// callback below. This callback below will dictate the linkage for all
// summaries in the index, and we basically just only want to ensure that dead
Loading