Skip to content

Commit fa04326

Browse files
committed
Update the minimum external LLVM to 20
1 parent 2fd855f commit fa04326

40 files changed

+129
-573
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,16 +1085,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
10851085
ty: Ty<'tcx>,
10861086
lhs: Self::Value,
10871087
rhs: Self::Value,
1088-
) -> Option<Self::Value> {
1089-
// FIXME: See comment on the definition of `three_way_compare`.
1090-
if crate::llvm_util::get_version() < (20, 0, 0) {
1091-
return None;
1092-
}
1093-
1088+
) -> Self::Value {
10941089
let size = ty.primitive_size(self.tcx);
10951090
let name = if ty.is_signed() { "llvm.scmp" } else { "llvm.ucmp" };
10961091

1097-
Some(self.call_intrinsic(name, &[self.type_i8(), self.type_ix(size.bits())], &[lhs, rhs]))
1092+
self.call_intrinsic(name, &[self.type_i8(), self.type_ix(size.bits())], &[lhs, rhs])
10981093
}
10991094

11001095
/* Miscellaneous instructions */

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -173,35 +173,6 @@ pub(crate) unsafe fn create_module<'ll>(
173173
let mut target_data_layout = sess.target.data_layout.to_string();
174174
let llvm_version = llvm_util::get_version();
175175

176-
if llvm_version < (20, 0, 0) {
177-
if sess.target.arch == "aarch64" || sess.target.arch.starts_with("arm64") {
178-
// LLVM 20 defines three additional address spaces for alternate
179-
// pointer kinds used in Windows.
180-
// See https://github.com/llvm/llvm-project/pull/111879
181-
target_data_layout =
182-
target_data_layout.replace("-p270:32:32-p271:32:32-p272:64:64", "");
183-
}
184-
if sess.target.arch.starts_with("sparc") {
185-
// LLVM 20 updates the sparc layout to correctly align 128 bit integers to 128 bit.
186-
// See https://github.com/llvm/llvm-project/pull/106951
187-
target_data_layout = target_data_layout.replace("-i128:128", "");
188-
}
189-
if sess.target.arch.starts_with("mips64") {
190-
// LLVM 20 updates the mips64 layout to correctly align 128 bit integers to 128 bit.
191-
// See https://github.com/llvm/llvm-project/pull/112084
192-
target_data_layout = target_data_layout.replace("-i128:128", "");
193-
}
194-
if sess.target.arch.starts_with("powerpc64") {
195-
// LLVM 20 updates the powerpc64 layout to correctly align 128 bit integers to 128 bit.
196-
// See https://github.com/llvm/llvm-project/pull/118004
197-
target_data_layout = target_data_layout.replace("-i128:128", "");
198-
}
199-
if sess.target.arch.starts_with("wasm32") || sess.target.arch.starts_with("wasm64") {
200-
// LLVM 20 updates the wasm(32|64) layout to correctly align 128 bit integers to 128 bit.
201-
// See https://github.com/llvm/llvm-project/pull/119204
202-
target_data_layout = target_data_layout.replace("-i128:128", "");
203-
}
204-
}
205176
if llvm_version < (21, 0, 0) {
206177
if sess.target.arch == "nvptx64" {
207178
// LLVM 21 updated the default layout on nvptx: https://github.com/llvm/llvm-project/pull/124961

compiler/rustc_codegen_llvm/src/llvm_util.rs

Lines changed: 2 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,6 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
246246
("aarch64", "pmuv3") => Some(LLVMFeature::new("perfmon")),
247247
("aarch64", "paca") => Some(LLVMFeature::new("pauth")),
248248
("aarch64", "pacg") => Some(LLVMFeature::new("pauth")),
249-
// Before LLVM 20 those two features were packaged together as b16b16
250-
("aarch64", "sve-b16b16") if get_version().0 < 20 => Some(LLVMFeature::new("b16b16")),
251-
("aarch64", "sme-b16b16") if get_version().0 < 20 => Some(LLVMFeature::new("b16b16")),
252249
("aarch64", "flagm2") => Some(LLVMFeature::new("altnzcv")),
253250
// Rust ties fp and neon together.
254251
("aarch64", "neon") => Some(LLVMFeature::with_dependencies(
@@ -262,56 +259,15 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
262259
// Filter out features that are not supported by the current LLVM version
263260
("aarch64", "fpmr") => None, // only existed in 18
264261
("arm", "fp16") => Some(LLVMFeature::new("fullfp16")),
265-
// NVPTX targets added in LLVM 20
266-
("nvptx64", "sm_100") if get_version().0 < 20 => None,
267-
("nvptx64", "sm_100a") if get_version().0 < 20 => None,
268-
("nvptx64", "sm_101") if get_version().0 < 20 => None,
269-
("nvptx64", "sm_101a") if get_version().0 < 20 => None,
270-
("nvptx64", "sm_120") if get_version().0 < 20 => None,
271-
("nvptx64", "sm_120a") if get_version().0 < 20 => None,
272-
("nvptx64", "ptx86") if get_version().0 < 20 => None,
273-
("nvptx64", "ptx87") if get_version().0 < 20 => None,
274-
// Filter out features that are not supported by the current LLVM version
275-
("loongarch64", "div32" | "lam-bh" | "lamcas" | "ld-seq-sa" | "scq")
276-
if get_version().0 < 20 =>
277-
{
278-
None
279-
}
280-
// Filter out features that are not supported by the current LLVM version
281-
("riscv32" | "riscv64", "zacas") if get_version().0 < 20 => None,
282-
(
283-
"s390x",
284-
"message-security-assist-extension12"
285-
| "concurrent-functions"
286-
| "miscellaneous-extensions-4"
287-
| "vector-enhancements-3"
288-
| "vector-packed-decimal-enhancement-3",
289-
) if get_version().0 < 20 => None,
290262
// Enable the evex512 target feature if an avx512 target feature is enabled.
291263
("x86", s) if s.starts_with("avx512") => Some(LLVMFeature::with_dependencies(
292264
s,
293265
smallvec![TargetFeatureFoldStrength::EnableOnly("evex512")],
294266
)),
295-
// Support for `wide-arithmetic` will first land in LLVM 20 as part of
296-
// llvm/llvm-project#111598
297-
("wasm32" | "wasm64", "wide-arithmetic") if get_version() < (20, 0, 0) => None,
298267
("sparc", "leoncasa") => Some(LLVMFeature::new("hasleoncasa")),
299-
// In LLVM 19, there is no `v8plus` feature and `v9` means "SPARC-V9 instruction available and SPARC-V8+ ABI used".
300-
// https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp#L27-L28
301-
// Before LLVM 19, there was no `v8plus` feature and `v9` means "SPARC-V9 instruction available".
302-
// https://github.com/llvm/llvm-project/blob/llvmorg-18.1.0/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp#L26
303-
("sparc", "v8plus") if get_version().0 == 19 => Some(LLVMFeature::new("v9")),
304268
("powerpc", "power8-crypto") => Some(LLVMFeature::new("crypto")),
305-
// These new `amx` variants and `movrs` were introduced in LLVM20
306-
("x86", "amx-avx512" | "amx-fp8" | "amx-movrs" | "amx-tf32" | "amx-transpose")
307-
if get_version().0 < 20 =>
308-
{
309-
None
310-
}
311-
("x86", "movrs") if get_version().0 < 20 => None,
312269
("x86", "avx10.1") => Some(LLVMFeature::new("avx10.1-512")),
313-
("x86", "avx10.2") if get_version().0 < 20 => None,
314-
("x86", "avx10.2") if get_version().0 >= 20 => Some(LLVMFeature::new("avx10.2-512")),
270+
("x86", "avx10.2") => Some(LLVMFeature::new("avx10.2-512")),
315271
("x86", "apxf") => Some(LLVMFeature::with_dependencies(
316272
"egpr",
317273
smallvec![
@@ -713,17 +669,7 @@ pub(crate) fn global_llvm_features(
713669
};
714670

715671
// Features implied by an implicit or explicit `--target`.
716-
features.extend(
717-
sess.target
718-
.features
719-
.split(',')
720-
.filter(|v| !v.is_empty())
721-
// Drop +v8plus feature introduced in LLVM 20.
722-
// (Hard-coded target features do not go through `to_llvm_feature` since they already
723-
// are LLVM feature names, hence we need a special case here.)
724-
.filter(|v| *v != "+v8plus" || get_version() >= (20, 0, 0))
725-
.map(String::from),
726-
);
672+
features.extend(sess.target.features.split(',').filter(|v| !v.is_empty()).map(String::from));
727673

728674
if wants_wasm_eh(sess) && sess.panic_strategy() == PanicStrategy::Unwind {
729675
features.push("+exception-handling".into());

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -895,36 +895,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
895895
}
896896
}
897897
mir::BinOp::Cmp => {
898-
use std::cmp::Ordering;
899898
assert!(!is_float);
900-
if let Some(value) = bx.three_way_compare(lhs_ty, lhs, rhs) {
901-
return value;
902-
}
903-
let pred = |op| base::bin_op_to_icmp_predicate(op, is_signed);
904-
if bx.cx().tcx().sess.opts.optimize == OptLevel::No {
905-
// FIXME: This actually generates tighter assembly, and is a classic trick
906-
// <https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign>
907-
// However, as of 2023-11 it optimizes worse in things like derived
908-
// `PartialOrd`, so only use it in debug for now. Once LLVM can handle it
909-
// better (see <https://github.com/llvm/llvm-project/issues/73417>), it'll
910-
// be worth trying it in optimized builds as well.
911-
let is_gt = bx.icmp(pred(mir::BinOp::Gt), lhs, rhs);
912-
let gtext = bx.zext(is_gt, bx.type_i8());
913-
let is_lt = bx.icmp(pred(mir::BinOp::Lt), lhs, rhs);
914-
let ltext = bx.zext(is_lt, bx.type_i8());
915-
bx.unchecked_ssub(gtext, ltext)
916-
} else {
917-
// These operations are those expected by `tests/codegen-llvm/integer-cmp.rs`,
918-
// from <https://github.com/rust-lang/rust/pull/63767>.
919-
let is_lt = bx.icmp(pred(mir::BinOp::Lt), lhs, rhs);
920-
let is_ne = bx.icmp(pred(mir::BinOp::Ne), lhs, rhs);
921-
let ge = bx.select(
922-
is_ne,
923-
bx.cx().const_i8(Ordering::Greater as i8),
924-
bx.cx().const_i8(Ordering::Equal as i8),
925-
);
926-
bx.select(is_lt, bx.cx().const_i8(Ordering::Less as i8), ge)
927-
}
899+
bx.three_way_compare(lhs_ty, lhs, rhs)
928900
}
929901
mir::BinOp::AddWithOverflow
930902
| mir::BinOp::SubWithOverflow

compiler/rustc_codegen_ssa/src/traits/builder.rs

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::ops::Deref;
33

44
use rustc_abi::{Align, Scalar, Size, WrappingRange};
55
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
6+
use rustc_middle::mir;
67
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
78
use rustc_middle::ty::{AtomicOrdering, Instance, Ty};
89
use rustc_session::config::OptLevel;
@@ -405,15 +406,38 @@ pub trait BuilderMethods<'a, 'tcx>:
405406
fn fcmp(&mut self, op: RealPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
406407

407408
/// Returns `-1` if `lhs < rhs`, `0` if `lhs == rhs`, and `1` if `lhs > rhs`.
408-
// FIXME: Move the default implementation from `codegen_scalar_binop` into this method and
409-
// remove the `Option` return once LLVM 20 is the minimum version.
410409
fn three_way_compare(
411410
&mut self,
412-
_ty: Ty<'tcx>,
413-
_lhs: Self::Value,
414-
_rhs: Self::Value,
415-
) -> Option<Self::Value> {
416-
None
411+
ty: Ty<'tcx>,
412+
lhs: Self::Value,
413+
rhs: Self::Value,
414+
) -> Self::Value {
415+
use std::cmp::Ordering;
416+
let pred = |op| crate::base::bin_op_to_icmp_predicate(op, ty.is_signed());
417+
if self.cx().sess().opts.optimize == OptLevel::No {
418+
// FIXME: This actually generates tighter assembly, and is a classic trick
419+
// <https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign>
420+
// However, as of 2023-11 it optimizes worse in things like derived
421+
// `PartialOrd`, so only use it in debug for now. Once LLVM can handle it
422+
// better (see <https://github.com/llvm/llvm-project/issues/73417>), it'll
423+
// be worth trying it in optimized builds as well.
424+
let is_gt = self.icmp(pred(mir::BinOp::Gt), lhs, rhs);
425+
let gtext = self.zext(is_gt, self.type_i8());
426+
let is_lt = self.icmp(pred(mir::BinOp::Lt), lhs, rhs);
427+
let ltext = self.zext(is_lt, self.type_i8());
428+
self.unchecked_ssub(gtext, ltext)
429+
} else {
430+
// These operations are those expected by `tests/codegen-llvm/integer-cmp.rs`,
431+
// from <https://github.com/rust-lang/rust/pull/63767>.
432+
let is_lt = self.icmp(pred(mir::BinOp::Lt), lhs, rhs);
433+
let is_ne = self.icmp(pred(mir::BinOp::Ne), lhs, rhs);
434+
let ge = self.select(
435+
is_ne,
436+
self.cx().const_i8(Ordering::Greater as i8),
437+
self.cx().const_i8(Ordering::Equal as i8),
438+
);
439+
self.select(is_lt, self.cx().const_i8(Ordering::Less as i8), ge)
440+
}
417441
}
418442

419443
fn memcpy(

0 commit comments

Comments
 (0)