Rollup merge of #145071 - cuviper:min-llvm-20, r=nikic
Update the minimum external LLVM to 20 With this change, we'll have stable support for LLVM 20 and 21. For reference, the previous increase to LLVM 19 was rust-lang/rust#139275. cc ```@rust-lang/wg-llvm``` r? nikic
This commit is contained in:
commit
f104ecfba6
47 changed files with 153 additions and 597 deletions
|
|
@ -1091,16 +1091,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
ty: Ty<'tcx>,
|
||||
lhs: Self::Value,
|
||||
rhs: Self::Value,
|
||||
) -> Option<Self::Value> {
|
||||
// FIXME: See comment on the definition of `three_way_compare`.
|
||||
if crate::llvm_util::get_version() < (20, 0, 0) {
|
||||
return None;
|
||||
}
|
||||
|
||||
) -> Self::Value {
|
||||
let size = ty.primitive_size(self.tcx);
|
||||
let name = if ty.is_signed() { "llvm.scmp" } else { "llvm.ucmp" };
|
||||
|
||||
Some(self.call_intrinsic(name, &[self.type_i8(), self.type_ix(size.bits())], &[lhs, rhs]))
|
||||
self.call_intrinsic(name, &[self.type_i8(), self.type_ix(size.bits())], &[lhs, rhs])
|
||||
}
|
||||
|
||||
/* Miscellaneous instructions */
|
||||
|
|
|
|||
|
|
@ -172,35 +172,6 @@ pub(crate) 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 < (20, 0, 0) {
|
||||
if sess.target.arch == "aarch64" || sess.target.arch.starts_with("arm64") {
|
||||
// LLVM 20 defines three additional address spaces for alternate
|
||||
// pointer kinds used in Windows.
|
||||
// See https://github.com/llvm/llvm-project/pull/111879
|
||||
target_data_layout =
|
||||
target_data_layout.replace("-p270:32:32-p271:32:32-p272:64:64", "");
|
||||
}
|
||||
if sess.target.arch.starts_with("sparc") {
|
||||
// LLVM 20 updates the sparc layout to correctly align 128 bit integers to 128 bit.
|
||||
// See https://github.com/llvm/llvm-project/pull/106951
|
||||
target_data_layout = target_data_layout.replace("-i128:128", "");
|
||||
}
|
||||
if sess.target.arch.starts_with("mips64") {
|
||||
// LLVM 20 updates the mips64 layout to correctly align 128 bit integers to 128 bit.
|
||||
// See https://github.com/llvm/llvm-project/pull/112084
|
||||
target_data_layout = target_data_layout.replace("-i128:128", "");
|
||||
}
|
||||
if sess.target.arch.starts_with("powerpc64") {
|
||||
// LLVM 20 updates the powerpc64 layout to correctly align 128 bit integers to 128 bit.
|
||||
// See https://github.com/llvm/llvm-project/pull/118004
|
||||
target_data_layout = target_data_layout.replace("-i128:128", "");
|
||||
}
|
||||
if sess.target.arch.starts_with("wasm32") || sess.target.arch.starts_with("wasm64") {
|
||||
// LLVM 20 updates the wasm(32|64) layout to correctly align 128 bit integers to 128 bit.
|
||||
// See https://github.com/llvm/llvm-project/pull/119204
|
||||
target_data_layout = target_data_layout.replace("-i128:128", "");
|
||||
}
|
||||
}
|
||||
if llvm_version < (21, 0, 0) {
|
||||
if sess.target.arch == "nvptx64" {
|
||||
// LLVM 21 updated the default layout on nvptx: https://github.com/llvm/llvm-project/pull/124961
|
||||
|
|
|
|||
|
|
@ -246,9 +246,6 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
|
|||
("aarch64", "pmuv3") => Some(LLVMFeature::new("perfmon")),
|
||||
("aarch64", "paca") => Some(LLVMFeature::new("pauth")),
|
||||
("aarch64", "pacg") => Some(LLVMFeature::new("pauth")),
|
||||
// Before LLVM 20 those two features were packaged together as b16b16
|
||||
("aarch64", "sve-b16b16") if get_version().0 < 20 => Some(LLVMFeature::new("b16b16")),
|
||||
("aarch64", "sme-b16b16") if get_version().0 < 20 => Some(LLVMFeature::new("b16b16")),
|
||||
("aarch64", "flagm2") => Some(LLVMFeature::new("altnzcv")),
|
||||
// Rust ties fp and neon together.
|
||||
("aarch64", "neon") => Some(LLVMFeature::with_dependencies(
|
||||
|
|
@ -262,57 +259,17 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
|
|||
// Filter out features that are not supported by the current LLVM version
|
||||
("aarch64", "fpmr") => None, // only existed in 18
|
||||
("arm", "fp16") => Some(LLVMFeature::new("fullfp16")),
|
||||
// NVPTX targets added in LLVM 20
|
||||
("nvptx64", "sm_100") if get_version().0 < 20 => None,
|
||||
("nvptx64", "sm_100a") if get_version().0 < 20 => None,
|
||||
("nvptx64", "sm_101") if get_version().0 < 20 => None,
|
||||
("nvptx64", "sm_101a") if get_version().0 < 20 => None,
|
||||
("nvptx64", "sm_120") if get_version().0 < 20 => None,
|
||||
("nvptx64", "sm_120a") if get_version().0 < 20 => None,
|
||||
("nvptx64", "ptx86") if get_version().0 < 20 => None,
|
||||
("nvptx64", "ptx87") if get_version().0 < 20 => None,
|
||||
// Filter out features that are not supported by the current LLVM version
|
||||
("loongarch64", "div32" | "lam-bh" | "lamcas" | "ld-seq-sa" | "scq")
|
||||
if get_version().0 < 20 =>
|
||||
{
|
||||
None
|
||||
}
|
||||
("loongarch32" | "loongarch64", "32s") if get_version().0 < 21 => None,
|
||||
// Filter out features that are not supported by the current LLVM version
|
||||
("riscv32" | "riscv64", "zacas" | "rva23u64" | "supm") if get_version().0 < 20 => None,
|
||||
(
|
||||
"s390x",
|
||||
"message-security-assist-extension12"
|
||||
| "concurrent-functions"
|
||||
| "miscellaneous-extensions-4"
|
||||
| "vector-enhancements-3"
|
||||
| "vector-packed-decimal-enhancement-3",
|
||||
) if get_version().0 < 20 => None,
|
||||
// Enable the evex512 target feature if an avx512 target feature is enabled.
|
||||
("x86", s) if s.starts_with("avx512") => Some(LLVMFeature::with_dependencies(
|
||||
s,
|
||||
smallvec![TargetFeatureFoldStrength::EnableOnly("evex512")],
|
||||
)),
|
||||
// Support for `wide-arithmetic` will first land in LLVM 20 as part of
|
||||
// llvm/llvm-project#111598
|
||||
("wasm32" | "wasm64", "wide-arithmetic") if get_version() < (20, 0, 0) => None,
|
||||
("sparc", "leoncasa") => Some(LLVMFeature::new("hasleoncasa")),
|
||||
// In LLVM 19, there is no `v8plus` feature and `v9` means "SPARC-V9 instruction available and SPARC-V8+ ABI used".
|
||||
// https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp#L27-L28
|
||||
// Before LLVM 19, there was no `v8plus` feature and `v9` means "SPARC-V9 instruction available".
|
||||
// https://github.com/llvm/llvm-project/blob/llvmorg-18.1.0/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp#L26
|
||||
("sparc", "v8plus") if get_version().0 == 19 => Some(LLVMFeature::new("v9")),
|
||||
("powerpc", "power8-crypto") => Some(LLVMFeature::new("crypto")),
|
||||
// These new `amx` variants and `movrs` were introduced in LLVM20
|
||||
("x86", "amx-avx512" | "amx-fp8" | "amx-movrs" | "amx-tf32" | "amx-transpose")
|
||||
if get_version().0 < 20 =>
|
||||
{
|
||||
None
|
||||
}
|
||||
("x86", "movrs") if get_version().0 < 20 => None,
|
||||
("x86", "avx10.1") => Some(LLVMFeature::new("avx10.1-512")),
|
||||
("x86", "avx10.2") if get_version().0 < 20 => None,
|
||||
("x86", "avx10.2") if get_version().0 >= 20 => Some(LLVMFeature::new("avx10.2-512")),
|
||||
("x86", "avx10.2") => Some(LLVMFeature::new("avx10.2-512")),
|
||||
("x86", "apxf") => Some(LLVMFeature::with_dependencies(
|
||||
"egpr",
|
||||
smallvec![
|
||||
|
|
@ -716,17 +673,7 @@ pub(crate) fn global_llvm_features(
|
|||
};
|
||||
|
||||
// Features implied by an implicit or explicit `--target`.
|
||||
features.extend(
|
||||
sess.target
|
||||
.features
|
||||
.split(',')
|
||||
.filter(|v| !v.is_empty())
|
||||
// Drop +v8plus feature introduced in LLVM 20.
|
||||
// (Hard-coded target features do not go through `to_llvm_feature` since they already
|
||||
// are LLVM feature names, hence we need a special case here.)
|
||||
.filter(|v| *v != "+v8plus" || get_version() >= (20, 0, 0))
|
||||
.map(String::from),
|
||||
);
|
||||
features.extend(sess.target.features.split(',').filter(|v| !v.is_empty()).map(String::from));
|
||||
|
||||
if wants_wasm_eh(sess) && sess.panic_strategy() == PanicStrategy::Unwind {
|
||||
features.push("+exception-handling".into());
|
||||
|
|
|
|||
|
|
@ -901,36 +901,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
}
|
||||
}
|
||||
mir::BinOp::Cmp => {
|
||||
use std::cmp::Ordering;
|
||||
assert!(!is_float);
|
||||
if let Some(value) = bx.three_way_compare(lhs_ty, lhs, rhs) {
|
||||
return value;
|
||||
}
|
||||
let pred = |op| base::bin_op_to_icmp_predicate(op, is_signed);
|
||||
if bx.cx().tcx().sess.opts.optimize == OptLevel::No {
|
||||
// FIXME: This actually generates tighter assembly, and is a classic trick
|
||||
// <https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign>
|
||||
// However, as of 2023-11 it optimizes worse in things like derived
|
||||
// `PartialOrd`, so only use it in debug for now. Once LLVM can handle it
|
||||
// better (see <https://github.com/llvm/llvm-project/issues/73417>), it'll
|
||||
// be worth trying it in optimized builds as well.
|
||||
let is_gt = bx.icmp(pred(mir::BinOp::Gt), lhs, rhs);
|
||||
let gtext = bx.zext(is_gt, bx.type_i8());
|
||||
let is_lt = bx.icmp(pred(mir::BinOp::Lt), lhs, rhs);
|
||||
let ltext = bx.zext(is_lt, bx.type_i8());
|
||||
bx.unchecked_ssub(gtext, ltext)
|
||||
} else {
|
||||
// These operations are those expected by `tests/codegen-llvm/integer-cmp.rs`,
|
||||
// from <https://github.com/rust-lang/rust/pull/63767>.
|
||||
let is_lt = bx.icmp(pred(mir::BinOp::Lt), lhs, rhs);
|
||||
let is_ne = bx.icmp(pred(mir::BinOp::Ne), lhs, rhs);
|
||||
let ge = bx.select(
|
||||
is_ne,
|
||||
bx.cx().const_i8(Ordering::Greater as i8),
|
||||
bx.cx().const_i8(Ordering::Equal as i8),
|
||||
);
|
||||
bx.select(is_lt, bx.cx().const_i8(Ordering::Less as i8), ge)
|
||||
}
|
||||
bx.three_way_compare(lhs_ty, lhs, rhs)
|
||||
}
|
||||
mir::BinOp::AddWithOverflow
|
||||
| mir::BinOp::SubWithOverflow
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use std::ops::Deref;
|
|||
|
||||
use rustc_abi::{Align, Scalar, Size, WrappingRange};
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::{AtomicOrdering, Instance, Ty};
|
||||
use rustc_session::config::OptLevel;
|
||||
|
|
@ -405,15 +406,41 @@ pub trait BuilderMethods<'a, 'tcx>:
|
|||
fn fcmp(&mut self, op: RealPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
|
||||
/// Returns `-1` if `lhs < rhs`, `0` if `lhs == rhs`, and `1` if `lhs > rhs`.
|
||||
// FIXME: Move the default implementation from `codegen_scalar_binop` into this method and
|
||||
// remove the `Option` return once LLVM 20 is the minimum version.
|
||||
fn three_way_compare(
|
||||
&mut self,
|
||||
_ty: Ty<'tcx>,
|
||||
_lhs: Self::Value,
|
||||
_rhs: Self::Value,
|
||||
) -> Option<Self::Value> {
|
||||
None
|
||||
ty: Ty<'tcx>,
|
||||
lhs: Self::Value,
|
||||
rhs: Self::Value,
|
||||
) -> Self::Value {
|
||||
// FIXME: This implementation was designed around LLVM's ability to optimize, but `cg_llvm`
|
||||
// overrides this to just use `@llvm.scmp`/`ucmp` since LLVM 20. This default impl should be
|
||||
// reevaluated with respect to the remaining backends like cg_gcc, whether they might use
|
||||
// specialized implementations as well, or continue to use a generic implementation here.
|
||||
use std::cmp::Ordering;
|
||||
let pred = |op| crate::base::bin_op_to_icmp_predicate(op, ty.is_signed());
|
||||
if self.cx().sess().opts.optimize == OptLevel::No {
|
||||
// This actually generates tighter assembly, and is a classic trick:
|
||||
// <https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign>.
|
||||
// However, as of 2023-11 it optimized worse in LLVM in things like derived
|
||||
// `PartialOrd`, so we were only using it in debug. Since LLVM now uses its own
|
||||
// intrinsics, it may be be worth trying it in optimized builds for other backends.
|
||||
let is_gt = self.icmp(pred(mir::BinOp::Gt), lhs, rhs);
|
||||
let gtext = self.zext(is_gt, self.type_i8());
|
||||
let is_lt = self.icmp(pred(mir::BinOp::Lt), lhs, rhs);
|
||||
let ltext = self.zext(is_lt, self.type_i8());
|
||||
self.unchecked_ssub(gtext, ltext)
|
||||
} else {
|
||||
// These operations were better optimized by LLVM, before `@llvm.scmp`/`ucmp` in 20.
|
||||
// See <https://github.com/rust-lang/rust/pull/63767>.
|
||||
let is_lt = self.icmp(pred(mir::BinOp::Lt), lhs, rhs);
|
||||
let is_ne = self.icmp(pred(mir::BinOp::Ne), lhs, rhs);
|
||||
let ge = self.select(
|
||||
is_ne,
|
||||
self.cx().const_i8(Ordering::Greater as i8),
|
||||
self.cx().const_i8(Ordering::Equal as i8),
|
||||
);
|
||||
self.select(is_lt, self.cx().const_i8(Ordering::Less as i8), ge)
|
||||
}
|
||||
}
|
||||
|
||||
fn memcpy(
|
||||
|
|
|
|||
|
|
@ -344,7 +344,6 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
|||
Options.EmitStackSizeSection = EmitStackSizeSection;
|
||||
|
||||
if (ArgsCstrBuff != nullptr) {
|
||||
#if LLVM_VERSION_GE(20, 0)
|
||||
size_t buffer_offset = 0;
|
||||
assert(ArgsCstrBuff[ArgsCstrBuffLen - 1] == '\0');
|
||||
auto Arg0 = std::string(ArgsCstrBuff);
|
||||
|
|
@ -362,33 +361,6 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
|||
OS.flush();
|
||||
Options.MCOptions.Argv0 = Arg0;
|
||||
Options.MCOptions.CommandlineArgs = CommandlineArgs;
|
||||
#else
|
||||
size_t buffer_offset = 0;
|
||||
assert(ArgsCstrBuff[ArgsCstrBuffLen - 1] == '\0');
|
||||
|
||||
const size_t arg0_len = std::strlen(ArgsCstrBuff);
|
||||
char *arg0 = new char[arg0_len + 1];
|
||||
memcpy(arg0, ArgsCstrBuff, arg0_len);
|
||||
arg0[arg0_len] = '\0';
|
||||
buffer_offset += arg0_len + 1;
|
||||
|
||||
const size_t num_cmd_arg_strings = std::count(
|
||||
&ArgsCstrBuff[buffer_offset], &ArgsCstrBuff[ArgsCstrBuffLen], '\0');
|
||||
|
||||
std::string *cmd_arg_strings = new std::string[num_cmd_arg_strings];
|
||||
for (size_t i = 0; i < num_cmd_arg_strings; ++i) {
|
||||
assert(buffer_offset < ArgsCstrBuffLen);
|
||||
const size_t len = std::strlen(ArgsCstrBuff + buffer_offset);
|
||||
cmd_arg_strings[i] = std::string(&ArgsCstrBuff[buffer_offset], len);
|
||||
buffer_offset += len + 1;
|
||||
}
|
||||
|
||||
assert(buffer_offset == ArgsCstrBuffLen);
|
||||
|
||||
Options.MCOptions.Argv0 = arg0;
|
||||
Options.MCOptions.CommandLineArgs =
|
||||
llvm::ArrayRef<std::string>(cmd_arg_strings, num_cmd_arg_strings);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LLVM_VERSION_GE(21, 0)
|
||||
|
|
@ -402,12 +374,6 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
|||
}
|
||||
|
||||
extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
|
||||
#if LLVM_VERSION_LT(20, 0)
|
||||
MCTargetOptions &MCOptions = unwrap(TM)->Options.MCOptions;
|
||||
delete[] MCOptions.Argv0;
|
||||
delete[] MCOptions.CommandLineArgs.data();
|
||||
#endif
|
||||
|
||||
delete unwrap(TM);
|
||||
}
|
||||
|
||||
|
|
@ -688,14 +654,9 @@ extern "C" LLVMRustResult LLVMRustOptimize(
|
|||
// the PassBuilder does not create a pipeline.
|
||||
std::vector<std::function<void(ModulePassManager &, OptimizationLevel)>>
|
||||
PipelineStartEPCallbacks;
|
||||
#if LLVM_VERSION_GE(20, 0)
|
||||
std::vector<std::function<void(ModulePassManager &, OptimizationLevel,
|
||||
ThinOrFullLTOPhase)>>
|
||||
OptimizerLastEPCallbacks;
|
||||
#else
|
||||
std::vector<std::function<void(ModulePassManager &, OptimizationLevel)>>
|
||||
OptimizerLastEPCallbacks;
|
||||
#endif
|
||||
|
||||
if (!IsLinkerPluginLTO && SanitizerOptions && SanitizerOptions->SanitizeCFI &&
|
||||
!NoPrepopulatePasses) {
|
||||
|
|
@ -747,12 +708,8 @@ extern "C" LLVMRustResult LLVMRustOptimize(
|
|||
SanitizerOptions->SanitizeDataFlowABIList +
|
||||
SanitizerOptions->SanitizeDataFlowABIListLen);
|
||||
OptimizerLastEPCallbacks.push_back(
|
||||
#if LLVM_VERSION_GE(20, 0)
|
||||
[ABIListFiles](ModulePassManager &MPM, OptimizationLevel Level,
|
||||
ThinOrFullLTOPhase phase) {
|
||||
#else
|
||||
[ABIListFiles](ModulePassManager &MPM, OptimizationLevel Level) {
|
||||
#endif
|
||||
MPM.addPass(DataFlowSanitizerPass(ABIListFiles));
|
||||
});
|
||||
}
|
||||
|
|
@ -763,66 +720,48 @@ extern "C" LLVMRustResult LLVMRustOptimize(
|
|||
SanitizerOptions->SanitizeMemoryRecover,
|
||||
/*CompileKernel=*/false,
|
||||
/*EagerChecks=*/true);
|
||||
OptimizerLastEPCallbacks.push_back(
|
||||
#if LLVM_VERSION_GE(20, 0)
|
||||
[Options](ModulePassManager &MPM, OptimizationLevel Level,
|
||||
ThinOrFullLTOPhase phase) {
|
||||
#else
|
||||
[Options](ModulePassManager &MPM, OptimizationLevel Level) {
|
||||
#endif
|
||||
MPM.addPass(MemorySanitizerPass(Options));
|
||||
});
|
||||
OptimizerLastEPCallbacks.push_back([Options](ModulePassManager &MPM,
|
||||
OptimizationLevel Level,
|
||||
ThinOrFullLTOPhase phase) {
|
||||
MPM.addPass(MemorySanitizerPass(Options));
|
||||
});
|
||||
}
|
||||
|
||||
if (SanitizerOptions->SanitizeThread) {
|
||||
OptimizerLastEPCallbacks.push_back(
|
||||
#if LLVM_VERSION_GE(20, 0)
|
||||
[](ModulePassManager &MPM, OptimizationLevel Level,
|
||||
ThinOrFullLTOPhase phase) {
|
||||
#else
|
||||
[](ModulePassManager &MPM, OptimizationLevel Level) {
|
||||
#endif
|
||||
MPM.addPass(ModuleThreadSanitizerPass());
|
||||
MPM.addPass(
|
||||
createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
|
||||
});
|
||||
OptimizerLastEPCallbacks.push_back([](ModulePassManager &MPM,
|
||||
OptimizationLevel Level,
|
||||
ThinOrFullLTOPhase phase) {
|
||||
MPM.addPass(ModuleThreadSanitizerPass());
|
||||
MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
|
||||
});
|
||||
}
|
||||
|
||||
if (SanitizerOptions->SanitizeAddress ||
|
||||
SanitizerOptions->SanitizeKernelAddress) {
|
||||
OptimizerLastEPCallbacks.push_back(
|
||||
#if LLVM_VERSION_GE(20, 0)
|
||||
[SanitizerOptions, TM](ModulePassManager &MPM,
|
||||
OptimizationLevel Level,
|
||||
ThinOrFullLTOPhase phase) {
|
||||
#else
|
||||
[SanitizerOptions, TM](ModulePassManager &MPM,
|
||||
OptimizationLevel Level) {
|
||||
#endif
|
||||
auto CompileKernel = SanitizerOptions->SanitizeKernelAddress;
|
||||
AddressSanitizerOptions opts = AddressSanitizerOptions{
|
||||
CompileKernel,
|
||||
SanitizerOptions->SanitizeAddressRecover ||
|
||||
SanitizerOptions->SanitizeKernelAddressRecover,
|
||||
/*UseAfterScope=*/true,
|
||||
AsanDetectStackUseAfterReturnMode::Runtime,
|
||||
};
|
||||
MPM.addPass(AddressSanitizerPass(
|
||||
opts,
|
||||
/*UseGlobalGC*/ true,
|
||||
// UseOdrIndicator should be false on windows machines
|
||||
// https://reviews.llvm.org/D137227
|
||||
!TM->getTargetTriple().isOSWindows()));
|
||||
});
|
||||
OptimizerLastEPCallbacks.push_back([SanitizerOptions,
|
||||
TM](ModulePassManager &MPM,
|
||||
OptimizationLevel Level,
|
||||
ThinOrFullLTOPhase phase) {
|
||||
auto CompileKernel = SanitizerOptions->SanitizeKernelAddress;
|
||||
AddressSanitizerOptions opts = AddressSanitizerOptions{
|
||||
CompileKernel,
|
||||
SanitizerOptions->SanitizeAddressRecover ||
|
||||
SanitizerOptions->SanitizeKernelAddressRecover,
|
||||
/*UseAfterScope=*/true,
|
||||
AsanDetectStackUseAfterReturnMode::Runtime,
|
||||
};
|
||||
MPM.addPass(
|
||||
AddressSanitizerPass(opts,
|
||||
/*UseGlobalGC*/ true,
|
||||
// UseOdrIndicator should be false on windows
|
||||
// machines https://reviews.llvm.org/D137227
|
||||
!TM->getTargetTriple().isOSWindows()));
|
||||
});
|
||||
}
|
||||
if (SanitizerOptions->SanitizeHWAddress) {
|
||||
OptimizerLastEPCallbacks.push_back(
|
||||
#if LLVM_VERSION_GE(20, 0)
|
||||
[SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level,
|
||||
ThinOrFullLTOPhase phase) {
|
||||
#else
|
||||
[SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) {
|
||||
#endif
|
||||
HWAddressSanitizerOptions opts(
|
||||
/*CompileKernel=*/false,
|
||||
SanitizerOptions->SanitizeHWAddressRecover,
|
||||
|
|
@ -904,11 +843,7 @@ extern "C" LLVMRustResult LLVMRustOptimize(
|
|||
for (const auto &C : PipelineStartEPCallbacks)
|
||||
C(MPM, OptLevel);
|
||||
for (const auto &C : OptimizerLastEPCallbacks)
|
||||
#if LLVM_VERSION_GE(20, 0)
|
||||
C(MPM, OptLevel, ThinOrFullLTOPhase::None);
|
||||
#else
|
||||
C(MPM, OptLevel);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ExtraPassesLen) {
|
||||
|
|
@ -1185,11 +1120,7 @@ struct LLVMRustThinLTOData {
|
|||
|
||||
// Not 100% sure what these are, but they impact what's internalized and
|
||||
// what's inlined across modules, I believe.
|
||||
#if LLVM_VERSION_GE(20, 0)
|
||||
FunctionImporter::ImportListsTy ImportLists;
|
||||
#else
|
||||
DenseMap<StringRef, FunctionImporter::ImportMapTy> ImportLists;
|
||||
#endif
|
||||
DenseMap<StringRef, FunctionImporter::ExportSetTy> ExportLists;
|
||||
DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries;
|
||||
StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
|
||||
|
|
@ -1531,13 +1462,8 @@ extern "C" void LLVMRustComputeLTOCacheKey(RustStringRef KeyOut,
|
|||
const auto &ExportList = Data->ExportLists.lookup(ModId);
|
||||
const auto &ResolvedODR = Data->ResolvedODR.lookup(ModId);
|
||||
const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(ModId);
|
||||
#if LLVM_VERSION_GE(20, 0)
|
||||
DenseSet<GlobalValue::GUID> CfiFunctionDefs;
|
||||
DenseSet<GlobalValue::GUID> CfiFunctionDecls;
|
||||
#else
|
||||
std::set<GlobalValue::GUID> CfiFunctionDefs;
|
||||
std::set<GlobalValue::GUID> CfiFunctionDecls;
|
||||
#endif
|
||||
|
||||
// Based on the 'InProcessThinBackend' constructor in LLVM
|
||||
#if LLVM_VERSION_GE(21, 0)
|
||||
|
|
@ -1556,15 +1482,9 @@ extern "C" void LLVMRustComputeLTOCacheKey(RustStringRef KeyOut,
|
|||
GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));
|
||||
#endif
|
||||
|
||||
#if LLVM_VERSION_GE(20, 0)
|
||||
Key = llvm::computeLTOCacheKey(conf, Data->Index, ModId, ImportList,
|
||||
ExportList, ResolvedODR, DefinedGlobals,
|
||||
CfiFunctionDefs, CfiFunctionDecls);
|
||||
#else
|
||||
llvm::computeLTOCacheKey(Key, conf, Data->Index, ModId, ImportList,
|
||||
ExportList, ResolvedODR, DefinedGlobals,
|
||||
CfiFunctionDefs, CfiFunctionDecls);
|
||||
#endif
|
||||
|
||||
auto OS = RawRustStringOstream(KeyOut);
|
||||
OS << Key.str();
|
||||
|
|
|
|||
|
|
@ -619,11 +619,11 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) {
|
|||
let version = get_llvm_version(builder, llvm_config);
|
||||
let mut parts = version.split('.').take(2).filter_map(|s| s.parse::<u32>().ok());
|
||||
if let (Some(major), Some(_minor)) = (parts.next(), parts.next())
|
||||
&& major >= 19
|
||||
&& major >= 20
|
||||
{
|
||||
return;
|
||||
}
|
||||
panic!("\n\nbad LLVM version: {version}, need >=19\n\n")
|
||||
panic!("\n\nbad LLVM version: {version}, need >=20\n\n")
|
||||
}
|
||||
|
||||
fn configure_cmake(
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ To run a specific CI job locally, you can use the `citool` Rust crate:
|
|||
cargo run --manifest-path src/ci/citool/Cargo.toml run-local <job-name>
|
||||
```
|
||||
|
||||
For example, to run the `x86_64-gnu-llvm-19-1` job:
|
||||
For example, to run the `x86_64-gnu-llvm-20-1` job:
|
||||
```
|
||||
cargo run --manifest-path src/ci/citool/Cargo.toml run-local x86_64-gnu-llvm-19-1
|
||||
cargo run --manifest-path src/ci/citool/Cargo.toml run-local x86_64-gnu-llvm-20-1
|
||||
```
|
||||
|
||||
The job will output artifacts in an `obj/<image-name>` dir at the root of a repository. Note
|
||||
|
|
@ -27,10 +27,10 @@ Docker image executed in the given CI job.
|
|||
while locally, to the `obj/<image-name>` directory. This is primarily to prevent
|
||||
strange linker errors when using multiple Docker images.
|
||||
|
||||
For some Linux workflows (for example `x86_64-gnu-llvm-19-N`), the process is more involved. You will need to see which script is executed for the given workflow inside the [`jobs.yml`](../github-actions/jobs.yml) file and pass it through the `DOCKER_SCRIPT` environment variable. For example, to reproduce the `x86_64-gnu-llvm-19-3` workflow, you can run the following script:
|
||||
For some Linux workflows (for example `x86_64-gnu-llvm-20-N`), the process is more involved. You will need to see which script is executed for the given workflow inside the [`jobs.yml`](../github-actions/jobs.yml) file and pass it through the `DOCKER_SCRIPT` environment variable. For example, to reproduce the `x86_64-gnu-llvm-20-3` workflow, you can run the following script:
|
||||
|
||||
```
|
||||
DOCKER_SCRIPT=x86_64-gnu-llvm3.sh ./src/ci/docker/run.sh x86_64-gnu-llvm-19
|
||||
DOCKER_SCRIPT=x86_64-gnu-llvm3.sh ./src/ci/docker/run.sh x86_64-gnu-llvm-20
|
||||
```
|
||||
|
||||
## Local Development
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM ubuntu:24.10
|
||||
FROM ubuntu:25.04
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
|
|
@ -15,8 +15,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
cmake \
|
||||
sudo \
|
||||
gdb \
|
||||
llvm-19-tools \
|
||||
llvm-19-dev \
|
||||
llvm-20-tools \
|
||||
llvm-20-dev \
|
||||
libedit-dev \
|
||||
libssl-dev \
|
||||
pkg-config \
|
||||
|
|
@ -43,7 +43,7 @@ ENV EXTERNAL_LLVM 1
|
|||
# Using llvm-link-shared due to libffi issues -- see #34486
|
||||
ENV RUST_CONFIGURE_ARGS \
|
||||
--build=aarch64-unknown-linux-gnu \
|
||||
--llvm-root=/usr/lib/llvm-19 \
|
||||
--llvm-root=/usr/lib/llvm-20 \
|
||||
--enable-llvm-link-shared \
|
||||
--set rust.randomize-layout=true \
|
||||
--set rust.thin-lto-import-instr-limit=10
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
FROM ubuntu:24.10
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
bzip2 \
|
||||
g++ \
|
||||
gcc-multilib \
|
||||
make \
|
||||
ninja-build \
|
||||
file \
|
||||
curl \
|
||||
ca-certificates \
|
||||
python3 \
|
||||
git \
|
||||
cmake \
|
||||
sudo \
|
||||
gdb \
|
||||
llvm-19-tools \
|
||||
llvm-19-dev \
|
||||
libedit-dev \
|
||||
libssl-dev \
|
||||
pkg-config \
|
||||
zlib1g-dev \
|
||||
xz-utils \
|
||||
nodejs \
|
||||
mingw-w64 \
|
||||
# libgccjit dependencies
|
||||
flex \
|
||||
libmpfr-dev \
|
||||
libgmp-dev \
|
||||
libmpc3 \
|
||||
libmpc-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install powershell (universal package) so we can test x.ps1 on Linux
|
||||
# FIXME: need a "universal" version that supports libicu74, but for now it still works to ignore that dep.
|
||||
RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/powershell_7.3.1-1.deb_amd64.deb" > powershell.deb && \
|
||||
dpkg --ignore-depends=libicu72 -i powershell.deb && \
|
||||
rm -f powershell.deb
|
||||
|
||||
COPY scripts/sccache.sh /scripts/
|
||||
RUN sh /scripts/sccache.sh
|
||||
|
||||
# We are disabling CI LLVM since this builder is intentionally using a host
|
||||
# LLVM, rather than the typical src/llvm-project LLVM.
|
||||
ENV NO_DOWNLOAD_CI_LLVM 1
|
||||
ENV EXTERNAL_LLVM 1
|
||||
|
||||
# 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-19 \
|
||||
--enable-llvm-link-shared \
|
||||
--set rust.randomize-layout=true \
|
||||
--set rust.thin-lto-import-instr-limit=10
|
||||
|
||||
COPY scripts/shared.sh /scripts/
|
||||
|
||||
COPY scripts/x86_64-gnu-llvm.sh /scripts/
|
||||
COPY scripts/x86_64-gnu-llvm2.sh /scripts/
|
||||
COPY scripts/x86_64-gnu-llvm3.sh /scripts/
|
||||
COPY scripts/stage_2_test_set1.sh /scripts/
|
||||
COPY scripts/stage_2_test_set2.sh /scripts/
|
||||
|
||||
ENV SCRIPT "Must specify DOCKER_SCRIPT for this image"
|
||||
|
|
@ -122,19 +122,19 @@ pr:
|
|||
# tidy. This speeds up the PR CI job by ~1 minute.
|
||||
SKIP_SUBMODULES: src/gcc
|
||||
<<: *job-linux-4c
|
||||
- name: x86_64-gnu-llvm-19
|
||||
- name: x86_64-gnu-llvm-20
|
||||
env:
|
||||
ENABLE_GCC_CODEGEN: "1"
|
||||
DOCKER_SCRIPT: x86_64-gnu-llvm.sh
|
||||
<<: *job-linux-4c
|
||||
- name: aarch64-gnu-llvm-19-1
|
||||
- name: aarch64-gnu-llvm-20-1
|
||||
env:
|
||||
IMAGE: aarch64-gnu-llvm-19
|
||||
IMAGE: aarch64-gnu-llvm-20
|
||||
DOCKER_SCRIPT: stage_2_test_set1.sh
|
||||
<<: *job-aarch64-linux
|
||||
- name: aarch64-gnu-llvm-19-2
|
||||
- name: aarch64-gnu-llvm-20-2
|
||||
env:
|
||||
IMAGE: aarch64-gnu-llvm-19
|
||||
IMAGE: aarch64-gnu-llvm-20
|
||||
DOCKER_SCRIPT: stage_2_test_set2.sh
|
||||
<<: *job-aarch64-linux
|
||||
- name: x86_64-gnu-tools
|
||||
|
|
@ -397,31 +397,6 @@ auto:
|
|||
DOCKER_SCRIPT: x86_64-gnu-llvm3.sh
|
||||
<<: *job-linux-4c
|
||||
|
||||
# The x86_64-gnu-llvm-19 job is split into multiple jobs to run tests in parallel.
|
||||
# x86_64-gnu-llvm-19-1 skips tests that run in x86_64-gnu-llvm-19-{2,3}.
|
||||
- name: x86_64-gnu-llvm-19-1
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
IMAGE: x86_64-gnu-llvm-19
|
||||
DOCKER_SCRIPT: stage_2_test_set2.sh
|
||||
<<: *job-linux-4c
|
||||
|
||||
# Skip tests that run in x86_64-gnu-llvm-19-{1,3}
|
||||
- name: x86_64-gnu-llvm-19-2
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
IMAGE: x86_64-gnu-llvm-19
|
||||
DOCKER_SCRIPT: x86_64-gnu-llvm2.sh
|
||||
<<: *job-linux-4c
|
||||
|
||||
# Skip tests that run in x86_64-gnu-llvm-19-{1,2}
|
||||
- name: x86_64-gnu-llvm-19-3
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
IMAGE: x86_64-gnu-llvm-19
|
||||
DOCKER_SCRIPT: x86_64-gnu-llvm3.sh
|
||||
<<: *job-linux-4c
|
||||
|
||||
- name: x86_64-gnu-nopt
|
||||
<<: *job-linux-4c
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,6 @@
|
|||
//@ assembly-output: emit-asm
|
||||
//@ compile-flags: --target riscv64imac-unknown-none-elf -Ctarget-feature=+f,+d
|
||||
//@ needs-llvm-components: riscv
|
||||
//@ revisions: LLVM-PRE-20 LLVM-POST-20
|
||||
//@ [LLVM-PRE-20] max-llvm-major-version: 19
|
||||
//@ [LLVM-POST-20] min-llvm-version: 20
|
||||
|
||||
#![feature(no_core, lang_items, f16)]
|
||||
#![crate_type = "lib"]
|
||||
|
|
@ -28,11 +25,8 @@ pub extern "C" fn read_f16(x: &f16) -> f16 {
|
|||
// CHECK-LABEL: read_f32
|
||||
#[no_mangle]
|
||||
pub extern "C" fn read_f32(x: &f32) -> f32 {
|
||||
// LLVM-PRE-20: flw fa5, 0(a0)
|
||||
// LLVM-PRE-20-NEXT: fmv.x.w a0, fa5
|
||||
// LLVM-PRE-20-NEXT: ret
|
||||
// LLVM-POST-20: lw a0, 0(a0)
|
||||
// LLVM-POST-20-NEXT: ret
|
||||
// CHECK: lw a0, 0(a0)
|
||||
// CHECK-NEXT: ret
|
||||
*x
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
//@ assembly-output: emit-asm
|
||||
//@ compile-flags: --crate-type=lib -Copt-level=3 -C target-cpu=x86-64-v4
|
||||
//@ compile-flags: -C llvm-args=-x86-asm-syntax=intel
|
||||
//@ min-llvm-version: 20
|
||||
|
||||
#![no_std]
|
||||
#![feature(bigint_helper_methods)]
|
||||
|
|
|
|||
|
|
@ -1,12 +1,6 @@
|
|||
//@ revisions: LLVM-PRE-20-DEBUG LLVM-20-DEBUG LLVM-PRE-20-OPTIM LLVM-20-OPTIM
|
||||
//@ [LLVM-PRE-20-DEBUG] compile-flags: -C opt-level=0
|
||||
//@ [LLVM-PRE-20-DEBUG] max-llvm-major-version: 19
|
||||
//@ [LLVM-20-DEBUG] compile-flags: -C opt-level=0
|
||||
//@ [LLVM-20-DEBUG] min-llvm-version: 20
|
||||
//@ [LLVM-PRE-20-OPTIM] compile-flags: -C opt-level=3
|
||||
//@ [LLVM-PRE-20-OPTIM] max-llvm-major-version: 19
|
||||
//@ [LLVM-20-OPTIM] compile-flags: -C opt-level=3
|
||||
//@ [LLVM-20-OPTIM] min-llvm-version: 20
|
||||
//@ revisions: DEBUG OPTIM
|
||||
//@ [DEBUG] compile-flags: -C opt-level=0
|
||||
//@ [OPTIM] compile-flags: -C opt-level=3
|
||||
//@ assembly-output: emit-asm
|
||||
//@ compile-flags: --crate-type=lib -C llvm-args=-x86-asm-syntax=intel
|
||||
//@ only-x86_64
|
||||
|
|
@ -19,61 +13,22 @@ use std::intrinsics::three_way_compare;
|
|||
#[no_mangle]
|
||||
// CHECK-LABEL: signed_cmp:
|
||||
pub fn signed_cmp(a: i16, b: i16) -> std::cmp::Ordering {
|
||||
// LLVM-PRE-20-DEBUG: cmp
|
||||
// LLVM-PRE-20-DEBUG: setg
|
||||
// LLVM-PRE-20-DEBUG: and
|
||||
// LLVM-PRE-20-DEBUG: cmp
|
||||
// LLVM-PRE-20-DEBUG: setl
|
||||
// LLVM-PRE-20-DEBUG: and
|
||||
// LLVM-PRE-20-DEBUG: sub
|
||||
//
|
||||
// LLVM-20-DEBUG: sub
|
||||
// LLVM-20-DEBUG: setl
|
||||
// LLVM-20-DEBUG: setg
|
||||
// LLVM-20-DEBUG: sub
|
||||
// LLVM-20-DEBUG: ret
|
||||
|
||||
// LLVM-PRE-20-OPTIM: xor
|
||||
// LLVM-PRE-20-OPTIM: cmp
|
||||
// LLVM-PRE-20-OPTIM: setne
|
||||
// LLVM-PRE-20-OPTIM: mov
|
||||
// LLVM-PRE-20-OPTIM: cmovge
|
||||
// LLVM-PRE-20-OPTIM: ret
|
||||
//
|
||||
// LLVM-20-OPTIM: cmp
|
||||
// LLVM-20-OPTIM: setl
|
||||
// LLVM-20-OPTIM: setg
|
||||
// LLVM-20-OPTIM: sub
|
||||
// LLVM-20-OPTIM: ret
|
||||
// DEBUG: sub
|
||||
// OPTIM: cmp
|
||||
// CHECK: setl
|
||||
// CHECK: setg
|
||||
// CHECK: sub
|
||||
// CHECK: ret
|
||||
three_way_compare(a, b)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
// CHECK-LABEL: unsigned_cmp:
|
||||
pub fn unsigned_cmp(a: u16, b: u16) -> std::cmp::Ordering {
|
||||
// LLVM-PRE-20-DEBUG: cmp
|
||||
// LLVM-PRE-20-DEBUG: seta
|
||||
// LLVM-PRE-20-DEBUG: and
|
||||
// LLVM-PRE-20-DEBUG: cmp
|
||||
// LLVM-PRE-20-DEBUG: setb
|
||||
// LLVM-PRE-20-DEBUG: and
|
||||
// LLVM-PRE-20-DEBUG: sub
|
||||
//
|
||||
// LLVM-20-DEBUG: sub
|
||||
// LLVM-20-DEBUG: seta
|
||||
// LLVM-20-DEBUG: sbb
|
||||
// LLVM-20-DEBUG: ret
|
||||
|
||||
// LLVM-PRE-20-OPTIM: xor
|
||||
// LLVM-PRE-20-OPTIM: cmp
|
||||
// LLVM-PRE-20-OPTIM: setne
|
||||
// LLVM-PRE-20-OPTIM: mov
|
||||
// LLVM-PRE-20-OPTIM: cmovae
|
||||
// LLVM-PRE-20-OPTIM: ret
|
||||
//
|
||||
// LLVM-20-OPTIM: cmp
|
||||
// LLVM-20-OPTIM: seta
|
||||
// LLVM-20-OPTIM: sbb
|
||||
// LLVM-20-OPTIM: ret
|
||||
// DEBUG: sub
|
||||
// OPTIM: cmp
|
||||
// CHECK: seta
|
||||
// CHECK: sbb
|
||||
// CHECK: ret
|
||||
three_way_compare(a, b)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
//@ compile-flags: -C opt-level=1
|
||||
//@ min-llvm-version: 20
|
||||
|
||||
// The `derive(PartialOrd)` for a 2-field type doesn't override `lt`/`le`/`gt`/`ge`.
|
||||
// This double-checks that the `Option<Ordering>` intermediate values used
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
//@ compile-flags: -C opt-level=1 -Z merge-functions=disabled
|
||||
//@ min-llvm-version: 20
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
//@ compile-flags: -Copt-level=0 -Cno-prepopulate-passes
|
||||
//@ min-llvm-version: 19
|
||||
//@ only-64bit
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
//@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled
|
||||
//@ min-llvm-version: 20
|
||||
//@ only-64bit
|
||||
//@ revisions: LLVM20 LLVM21
|
||||
//@ [LLVM21] min-llvm-version: 21
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
// This is test for more optimal Ord implementation for integers.
|
||||
// See <https://github.com/rust-lang/rust/issues/63758> for more info.
|
||||
|
||||
//@ revisions: llvm-pre-20 llvm-20
|
||||
//@ [llvm-20] min-llvm-version: 20
|
||||
//@ [llvm-pre-20] max-llvm-major-version: 19
|
||||
//@ compile-flags: -C opt-level=3 -Zmerge-functions=disabled
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
|
@ -13,50 +10,29 @@ use std::cmp::Ordering;
|
|||
// CHECK-LABEL: @cmp_signed
|
||||
#[no_mangle]
|
||||
pub fn cmp_signed(a: i64, b: i64) -> Ordering {
|
||||
// llvm-20: call{{.*}} i8 @llvm.scmp.i8.i64
|
||||
// llvm-pre-20: icmp slt
|
||||
// llvm-pre-20: icmp ne
|
||||
// llvm-pre-20: zext i1
|
||||
// llvm-pre-20: select i1
|
||||
// CHECK: call{{.*}} i8 @llvm.scmp.i8.i64
|
||||
a.cmp(&b)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @cmp_unsigned
|
||||
#[no_mangle]
|
||||
pub fn cmp_unsigned(a: u32, b: u32) -> Ordering {
|
||||
// llvm-20: call{{.*}} i8 @llvm.ucmp.i8.i32
|
||||
// llvm-pre-20: icmp ult
|
||||
// llvm-pre-20: icmp ne
|
||||
// llvm-pre-20: zext i1
|
||||
// llvm-pre-20: select i1
|
||||
// CHECK: call{{.*}} i8 @llvm.ucmp.i8.i32
|
||||
a.cmp(&b)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @cmp_char
|
||||
#[no_mangle]
|
||||
pub fn cmp_char(a: char, b: char) -> Ordering {
|
||||
// llvm-20: call{{.*}} i8 @llvm.ucmp.i8.i32
|
||||
// llvm-pre-20: icmp ult
|
||||
// llvm-pre-20: icmp ne
|
||||
// llvm-pre-20: zext i1
|
||||
// llvm-pre-20: select i1
|
||||
// CHECK: call{{.*}} i8 @llvm.ucmp.i8.i32
|
||||
a.cmp(&b)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @cmp_tuple
|
||||
#[no_mangle]
|
||||
pub fn cmp_tuple(a: (i16, u16), b: (i16, u16)) -> Ordering {
|
||||
// llvm-20-DAG: call{{.*}} i8 @llvm.ucmp.i8.i16
|
||||
// llvm-20-DAG: call{{.*}} i8 @llvm.scmp.i8.i16
|
||||
// llvm-20: ret i8
|
||||
// llvm-pre-20: icmp slt
|
||||
// llvm-pre-20: icmp ne
|
||||
// llvm-pre-20: zext i1
|
||||
// llvm-pre-20: select i1
|
||||
// llvm-pre-20: icmp ult
|
||||
// llvm-pre-20: icmp ne
|
||||
// llvm-pre-20: zext i1
|
||||
// llvm-pre-20: select i1
|
||||
// llvm-pre-20: select i1
|
||||
// CHECK-DAG: call{{.*}} i8 @llvm.ucmp.i8.i16
|
||||
// CHECK-DAG: call{{.*}} i8 @llvm.scmp.i8.i16
|
||||
// CHECK: ret i8
|
||||
a.cmp(&b)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
//@ [DEBUG] compile-flags: -C opt-level=0
|
||||
//@ [OPTIM] compile-flags: -C opt-level=3
|
||||
//@ compile-flags: -C no-prepopulate-passes
|
||||
//@ min-llvm-version: 20
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(core_intrinsics)]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
//@ compile-flags: -Copt-level=3
|
||||
//@ min-llvm-version: 20
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
//@ compile-flags: -Copt-level=3
|
||||
//@ revisions: host x86-64 x86-64-v3
|
||||
//@ min-llvm-version: 20
|
||||
|
||||
//@[host] ignore-x86_64
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
//@ compile-flags: -Copt-level=3
|
||||
//@ min-llvm-version: 20
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// Ensure that a modulo operation with an operand that is known to be
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
// use a larger value to prevent unrolling.
|
||||
|
||||
//@ compile-flags: -Copt-level=3
|
||||
//@ min-llvm-version: 20
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
//@ compile-flags: -Copt-level=3
|
||||
//@ min-llvm-version: 20
|
||||
#![crate_type = "lib"]
|
||||
|
||||
/// Ensure the function is properly optimized
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
//@ revisions: REGULAR LLVM21
|
||||
//@ min-llvm-version: 20
|
||||
//@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled
|
||||
//@ [LLVM21] min-llvm-version: 21
|
||||
#![crate_type = "lib"]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
//@ compile-flags: -Copt-level=3
|
||||
//@ min-llvm-version: 20
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// This test verifies that LLVM 20 properly optimizes the bounds check
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
//@ compile-flags: -Copt-level=3 -Z merge-functions=disabled
|
||||
//@ only-x86_64
|
||||
//@ min-llvm-version: 20
|
||||
//@ ignore-std-debug-assertions (`ptr::swap_nonoverlapping` has one which blocks some optimizations)
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
//@ compile-flags: -Copt-level=3 -Z merge-functions=disabled
|
||||
//@ edition: 2021
|
||||
//@ only-x86_64
|
||||
//@ revisions: NINETEEN TWENTY
|
||||
//@[NINETEEN] exact-llvm-major-version: 19
|
||||
//@[TWENTY] min-llvm-version: 20
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(try_blocks)]
|
||||
|
|
@ -17,13 +14,9 @@ pub fn option_nop_match_32(x: Option<u32>) -> Option<u32> {
|
|||
// CHECK: start:
|
||||
// CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i32 %0 to i1
|
||||
|
||||
// NINETEEN-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i32 %0, i32 0
|
||||
// NINETEEN-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } poison, i32 [[SELECT]], 0
|
||||
// NINETEEN-NEXT: [[REG3:%.*]] = insertvalue { i32, i32 } [[REG2]], i32 %1, 1
|
||||
|
||||
// TWENTY-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i32 %1, i32 undef
|
||||
// TWENTY-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0
|
||||
// TWENTY-NEXT: [[REG3:%.*]] = insertvalue { i32, i32 } [[REG2]], i32 [[SELECT]], 1
|
||||
// CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i32 %1, i32 undef
|
||||
// CHECK-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0
|
||||
// CHECK-NEXT: [[REG3:%.*]] = insertvalue { i32, i32 } [[REG2]], i32 [[SELECT]], 1
|
||||
|
||||
// CHECK-NEXT: ret { i32, i32 } [[REG3]]
|
||||
match x {
|
||||
|
|
@ -36,8 +29,8 @@ pub fn option_nop_match_32(x: Option<u32>) -> Option<u32> {
|
|||
#[no_mangle]
|
||||
pub fn option_nop_traits_32(x: Option<u32>) -> Option<u32> {
|
||||
// CHECK: start:
|
||||
// TWENTY-NEXT: %[[IS_SOME:.+]] = trunc nuw i32 %0 to i1
|
||||
// TWENTY-NEXT: select i1 %[[IS_SOME]], i32 %1, i32 undef
|
||||
// CHECK-NEXT: %[[IS_SOME:.+]] = trunc nuw i32 %0 to i1
|
||||
// CHECK-NEXT: select i1 %[[IS_SOME]], i32 %1, i32 undef
|
||||
// CHECK-NEXT: insertvalue { i32, i32 }
|
||||
// CHECK-NEXT: insertvalue { i32, i32 }
|
||||
// CHECK-NEXT: ret { i32, i32 }
|
||||
|
|
@ -96,13 +89,9 @@ pub fn option_nop_match_64(x: Option<u64>) -> Option<u64> {
|
|||
// CHECK: start:
|
||||
// CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i64 %0 to i1
|
||||
|
||||
// NINETEEN-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i64 %0, i64 0
|
||||
// NINETEEN-NEXT: [[REG2:%.*]] = insertvalue { i64, i64 } poison, i64 [[SELECT]], 0
|
||||
// NINETEEN-NEXT: [[REG3:%.*]] = insertvalue { i64, i64 } [[REG2]], i64 %1, 1
|
||||
|
||||
// TWENTY-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i64 %1, i64 undef
|
||||
// TWENTY-NEXT: [[REG2:%.*]] = insertvalue { i64, i64 } poison, i64 %0, 0
|
||||
// TWENTY-NEXT: [[REG3:%.*]] = insertvalue { i64, i64 } [[REG2]], i64 [[SELECT]], 1
|
||||
// CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i64 %1, i64 undef
|
||||
// CHECK-NEXT: [[REG2:%.*]] = insertvalue { i64, i64 } poison, i64 %0, 0
|
||||
// CHECK-NEXT: [[REG3:%.*]] = insertvalue { i64, i64 } [[REG2]], i64 [[SELECT]], 1
|
||||
|
||||
// CHECK-NEXT: ret { i64, i64 } [[REG3]]
|
||||
match x {
|
||||
|
|
@ -115,8 +104,8 @@ pub fn option_nop_match_64(x: Option<u64>) -> Option<u64> {
|
|||
#[no_mangle]
|
||||
pub fn option_nop_traits_64(x: Option<u64>) -> Option<u64> {
|
||||
// CHECK: start:
|
||||
// TWENTY-NEXT: %[[TRUNC:[0-9]+]] = trunc nuw i64 %0 to i1
|
||||
// TWENTY-NEXT: %[[SEL:\.[0-9]+]] = select i1 %[[TRUNC]], i64 %1, i64 undef
|
||||
// CHECK-NEXT: %[[TRUNC:[0-9]+]] = trunc nuw i64 %0 to i1
|
||||
// CHECK-NEXT: %[[SEL:\.[0-9]+]] = select i1 %[[TRUNC]], i64 %1, i64 undef
|
||||
// CHECK-NEXT: insertvalue { i64, i64 }
|
||||
// CHECK-NEXT: insertvalue { i64, i64 }
|
||||
// CHECK-NEXT: ret { i64, i64 }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
//@ compile-flags: -Copt-level=0 -Cno-prepopulate-passes
|
||||
//@ min-llvm-version: 19
|
||||
//@ only-64bit
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
//@ add-core-stubs
|
||||
//@ revisions: sparc sparcv8plus sparc_cpu_v9 sparc_feature_v8plus sparc_cpu_v9_feature_v8plus
|
||||
//@[sparc] compile-flags: --target sparc-unknown-none-elf
|
||||
//@[sparc] needs-llvm-components: sparc
|
||||
//@[sparcv8plus] compile-flags: --target sparc-unknown-linux-gnu
|
||||
//@[sparcv8plus] needs-llvm-components: sparc
|
||||
//@[sparc_cpu_v9] compile-flags: --target sparc-unknown-none-elf -C target-cpu=v9
|
||||
//@[sparc_cpu_v9] needs-llvm-components: sparc
|
||||
//@[sparc_feature_v8plus] compile-flags: --target sparc-unknown-none-elf -C target-feature=+v8plus
|
||||
//@[sparc_feature_v8plus] needs-llvm-components: sparc
|
||||
//@[sparc_cpu_v9_feature_v8plus] compile-flags: --target sparc-unknown-none-elf -C target-cpu=v9 -C target-feature=+v8plus
|
||||
//@[sparc_cpu_v9_feature_v8plus] needs-llvm-components: sparc
|
||||
//@ exact-llvm-major-version: 19
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
#![feature(no_core, rustc_attrs, lang_items)]
|
||||
#![no_core]
|
||||
|
||||
extern crate minicore;
|
||||
use minicore::*;
|
||||
|
||||
#[rustc_builtin_macro]
|
||||
macro_rules! compile_error {
|
||||
() => {};
|
||||
}
|
||||
|
||||
#[cfg(all(not(target_feature = "v8plus"), not(target_feature = "v9")))]
|
||||
compile_error!("-v8plus,-v9");
|
||||
//[sparc]~^ ERROR -v8plus,-v9
|
||||
|
||||
// FIXME: sparc_cpu_v9 should be in "-v8plus,+v9" group (fixed in LLVM 20)
|
||||
#[cfg(all(target_feature = "v8plus", target_feature = "v9"))]
|
||||
compile_error!("+v8plus,+v9");
|
||||
//[sparcv8plus,sparc_cpu_v9_feature_v8plus,sparc_cpu_v9]~^ ERROR +v8plus,+v9
|
||||
|
||||
// FIXME: should be rejected
|
||||
#[cfg(all(target_feature = "v8plus", not(target_feature = "v9")))]
|
||||
compile_error!("+v8plus,-v9 (FIXME)");
|
||||
//[sparc_feature_v8plus]~^ ERROR +v8plus,-v9 (FIXME)
|
||||
|
||||
#[cfg(all(not(target_feature = "v8plus"), target_feature = "v9"))]
|
||||
compile_error!("-v8plus,+v9");
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
error: -v8plus,-v9
|
||||
--> $DIR/sparcv8plus-llvm19.rs:28:1
|
||||
|
|
||||
LL | compile_error!("-v8plus,-v9");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
error: +v8plus,+v9
|
||||
--> $DIR/sparcv8plus-llvm19.rs:33:1
|
||||
|
|
||||
LL | compile_error!("+v8plus,+v9");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
error: +v8plus,+v9
|
||||
--> $DIR/sparcv8plus-llvm19.rs:33:1
|
||||
|
|
||||
LL | compile_error!("+v8plus,+v9");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
error: +v8plus,-v9 (FIXME)
|
||||
--> $DIR/sparcv8plus-llvm19.rs:38:1
|
||||
|
|
||||
LL | compile_error!("+v8plus,-v9 (FIXME)");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
error: +v8plus,+v9
|
||||
--> $DIR/sparcv8plus-llvm19.rs:33:1
|
||||
|
|
||||
LL | compile_error!("+v8plus,+v9");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -10,7 +10,6 @@
|
|||
//@[sparc_feature_v8plus] needs-llvm-components: sparc
|
||||
//@[sparc_cpu_v9_feature_v8plus] compile-flags: --target sparc-unknown-none-elf -C target-cpu=v9 -C target-feature=+v8plus
|
||||
//@[sparc_cpu_v9_feature_v8plus] needs-llvm-components: sparc
|
||||
//@ min-llvm-version: 20
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
#![feature(no_core, rustc_attrs, lang_items)]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: -v8plus,-v9
|
||||
--> $DIR/sparcv8plus.rs:28:1
|
||||
--> $DIR/sparcv8plus.rs:27:1
|
||||
|
|
||||
LL | compile_error!("-v8plus,-v9");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: -v8plus,+v9
|
||||
--> $DIR/sparcv8plus.rs:41:1
|
||||
--> $DIR/sparcv8plus.rs:40:1
|
||||
|
|
||||
LL | compile_error!("-v8plus,+v9");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: +v8plus,+v9
|
||||
--> $DIR/sparcv8plus.rs:32:1
|
||||
--> $DIR/sparcv8plus.rs:31:1
|
||||
|
|
||||
LL | compile_error!("+v8plus,+v9");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: +v8plus,-v9 (FIXME)
|
||||
--> $DIR/sparcv8plus.rs:37:1
|
||||
--> $DIR/sparcv8plus.rs:36:1
|
||||
|
|
||||
LL | compile_error!("+v8plus,-v9 (FIXME)");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: +v8plus,+v9
|
||||
--> $DIR/sparcv8plus.rs:32:1
|
||||
--> $DIR/sparcv8plus.rs:31:1
|
||||
|
|
||||
LL | compile_error!("+v8plus,+v9");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,35 +1,35 @@
|
|||
error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:27:18
|
||||
--> $DIR/bad-reg.rs:26:18
|
||||
|
|
||||
LL | asm!("", out("$r0") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$tp`: reserved for TLS
|
||||
--> $DIR/bad-reg.rs:29:18
|
||||
--> $DIR/bad-reg.rs:28:18
|
||||
|
|
||||
LL | asm!("", out("$tp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:31:18
|
||||
--> $DIR/bad-reg.rs:30:18
|
||||
|
|
||||
LL | asm!("", out("$sp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$r21`: reserved by the ABI
|
||||
--> $DIR/bad-reg.rs:33:18
|
||||
--> $DIR/bad-reg.rs:32:18
|
||||
|
|
||||
LL | asm!("", out("$r21") _);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:35:18
|
||||
--> $DIR/bad-reg.rs:34:18
|
||||
|
|
||||
LL | asm!("", out("$fp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:37:18
|
||||
--> $DIR/bad-reg.rs:36:18
|
||||
|
|
||||
LL | asm!("", out("$r31") _);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,59 +1,59 @@
|
|||
error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:27:18
|
||||
--> $DIR/bad-reg.rs:26:18
|
||||
|
|
||||
LL | asm!("", out("$r0") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$tp`: reserved for TLS
|
||||
--> $DIR/bad-reg.rs:29:18
|
||||
--> $DIR/bad-reg.rs:28:18
|
||||
|
|
||||
LL | asm!("", out("$tp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:31:18
|
||||
--> $DIR/bad-reg.rs:30:18
|
||||
|
|
||||
LL | asm!("", out("$sp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$r21`: reserved by the ABI
|
||||
--> $DIR/bad-reg.rs:33:18
|
||||
--> $DIR/bad-reg.rs:32:18
|
||||
|
|
||||
LL | asm!("", out("$r21") _);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:35:18
|
||||
--> $DIR/bad-reg.rs:34:18
|
||||
|
|
||||
LL | asm!("", out("$fp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:37:18
|
||||
--> $DIR/bad-reg.rs:36:18
|
||||
|
|
||||
LL | asm!("", out("$r31") _);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: register class `freg` requires at least one of the following target features: d, f
|
||||
--> $DIR/bad-reg.rs:41:26
|
||||
--> $DIR/bad-reg.rs:40:26
|
||||
|
|
||||
LL | asm!("/* {} */", in(freg) f);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: register class `freg` requires at least one of the following target features: d, f
|
||||
--> $DIR/bad-reg.rs:43:26
|
||||
--> $DIR/bad-reg.rs:42:26
|
||||
|
|
||||
LL | asm!("/* {} */", out(freg) _);
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: register class `freg` requires at least one of the following target features: d, f
|
||||
--> $DIR/bad-reg.rs:45:26
|
||||
--> $DIR/bad-reg.rs:44:26
|
||||
|
|
||||
LL | asm!("/* {} */", in(freg) d);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: register class `freg` requires at least one of the following target features: d, f
|
||||
--> $DIR/bad-reg.rs:47:26
|
||||
--> $DIR/bad-reg.rs:46:26
|
||||
|
|
||||
LL | asm!("/* {} */", out(freg) d);
|
||||
| ^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,35 +1,35 @@
|
|||
error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:27:18
|
||||
--> $DIR/bad-reg.rs:26:18
|
||||
|
|
||||
LL | asm!("", out("$r0") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$tp`: reserved for TLS
|
||||
--> $DIR/bad-reg.rs:29:18
|
||||
--> $DIR/bad-reg.rs:28:18
|
||||
|
|
||||
LL | asm!("", out("$tp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:31:18
|
||||
--> $DIR/bad-reg.rs:30:18
|
||||
|
|
||||
LL | asm!("", out("$sp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$r21`: reserved by the ABI
|
||||
--> $DIR/bad-reg.rs:33:18
|
||||
--> $DIR/bad-reg.rs:32:18
|
||||
|
|
||||
LL | asm!("", out("$r21") _);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:35:18
|
||||
--> $DIR/bad-reg.rs:34:18
|
||||
|
|
||||
LL | asm!("", out("$fp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:37:18
|
||||
--> $DIR/bad-reg.rs:36:18
|
||||
|
|
||||
LL | asm!("", out("$r31") _);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,59 +1,59 @@
|
|||
error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:27:18
|
||||
--> $DIR/bad-reg.rs:26:18
|
||||
|
|
||||
LL | asm!("", out("$r0") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$tp`: reserved for TLS
|
||||
--> $DIR/bad-reg.rs:29:18
|
||||
--> $DIR/bad-reg.rs:28:18
|
||||
|
|
||||
LL | asm!("", out("$tp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:31:18
|
||||
--> $DIR/bad-reg.rs:30:18
|
||||
|
|
||||
LL | asm!("", out("$sp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$r21`: reserved by the ABI
|
||||
--> $DIR/bad-reg.rs:33:18
|
||||
--> $DIR/bad-reg.rs:32:18
|
||||
|
|
||||
LL | asm!("", out("$r21") _);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:35:18
|
||||
--> $DIR/bad-reg.rs:34:18
|
||||
|
|
||||
LL | asm!("", out("$fp") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:37:18
|
||||
--> $DIR/bad-reg.rs:36:18
|
||||
|
|
||||
LL | asm!("", out("$r31") _);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: register class `freg` requires at least one of the following target features: d, f
|
||||
--> $DIR/bad-reg.rs:41:26
|
||||
--> $DIR/bad-reg.rs:40:26
|
||||
|
|
||||
LL | asm!("/* {} */", in(freg) f);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: register class `freg` requires at least one of the following target features: d, f
|
||||
--> $DIR/bad-reg.rs:43:26
|
||||
--> $DIR/bad-reg.rs:42:26
|
||||
|
|
||||
LL | asm!("/* {} */", out(freg) _);
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: register class `freg` requires at least one of the following target features: d, f
|
||||
--> $DIR/bad-reg.rs:45:26
|
||||
--> $DIR/bad-reg.rs:44:26
|
||||
|
|
||||
LL | asm!("/* {} */", in(freg) d);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: register class `freg` requires at least one of the following target features: d, f
|
||||
--> $DIR/bad-reg.rs:47:26
|
||||
--> $DIR/bad-reg.rs:46:26
|
||||
|
|
||||
LL | asm!("/* {} */", out(freg) d);
|
||||
| ^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
//@ add-core-stubs
|
||||
//@ needs-asm-support
|
||||
//@ revisions: loongarch32_ilp32d loongarch32_ilp32s loongarch64_lp64d loongarch64_lp64s
|
||||
//@ min-llvm-version: 20
|
||||
//@[loongarch32_ilp32d] compile-flags: --target loongarch32-unknown-none
|
||||
//@[loongarch32_ilp32d] needs-llvm-components: loongarch
|
||||
//@[loongarch32_ilp32s] compile-flags: --target loongarch32-unknown-none-softfloat
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue