Merge pull request #844 from rust-lang/sync_from_rust_2026_01_28
Sync from rust 2026/01/28
This commit is contained in:
commit
30bd49283c
22 changed files with 225 additions and 94 deletions
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
|
|
@ -113,6 +113,10 @@ jobs:
|
|||
git config --global user.name "User"
|
||||
./y.sh prepare
|
||||
|
||||
- name: Add more failing tests for GCC without 128-bit integers support
|
||||
if: ${{ matrix.libgccjit_version.gcc == 'gcc-15-without-int128.deb' }}
|
||||
run: cat tests/failing-ui-tests-without-128bit-integers.txt >> tests/failing-ui-tests.txt
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
./y.sh test --release --clean --build-sysroot ${{ matrix.commands }}
|
||||
|
|
|
|||
|
|
@ -56,18 +56,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gccjit"
|
||||
version = "3.2.0"
|
||||
version = "3.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef03c8ae23826a0755b980999a553a262c61f2f585245e647192d95bf09eee79"
|
||||
checksum = "26b73d18b642ce16378af78f89664841d7eeafa113682ff5d14573424eb0232a"
|
||||
dependencies = [
|
||||
"gccjit_sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gccjit_sys"
|
||||
version = "1.2.0"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ff511da413e4a5da6f09607748395ba37525e01ba7d322cbec3efc43095dd60"
|
||||
checksum = "ee689456c013616942d5aef9a84d613cefcc3b335340d036f3650fc1a7459e15"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ default = ["master"]
|
|||
[dependencies]
|
||||
object = { version = "0.37.0", default-features = false, features = ["std", "read"] }
|
||||
tempfile = "3.20"
|
||||
gccjit = { version = "3.2.0", features = ["dlopen"] }
|
||||
gccjit = { version = "3.3.0", features = ["dlopen"] }
|
||||
#gccjit = { git = "https://github.com/rust-lang/gccjit.rs", branch = "error-dlopen", features = ["dlopen"] }
|
||||
|
||||
# Local copy.
|
||||
|
|
|
|||
|
|
@ -679,10 +679,10 @@ fn test_projects(env: &Env, args: &TestArg) -> Result<(), String> {
|
|||
create_dir(projects_path)?;
|
||||
|
||||
let nb_parts = args.nb_parts.unwrap_or(0);
|
||||
if nb_parts > 0 {
|
||||
if let Some(count) = projects.len().checked_div(nb_parts) {
|
||||
// We increment the number of tests by one because if this is an odd number, we would skip
|
||||
// one test.
|
||||
let count = projects.len() / nb_parts + 1;
|
||||
let count = count + 1;
|
||||
let current_part = args.current_part.unwrap();
|
||||
let start = current_part * count;
|
||||
// We remove the projects we don't want to test.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
// SPDX-FileCopyrightText: The Rust Project Developers (see https://thanks.rust-lang.org)
|
||||
|
||||
#![no_std]
|
||||
#![feature(allocator_api, rustc_private)]
|
||||
|
||||
|
|
|
|||
|
|
@ -748,25 +748,25 @@ extern "C" {
|
|||
pub struct VaList<'a>(&'a mut VaListImpl);
|
||||
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
#[rustc_macro_transparency = "semiopaque"]
|
||||
pub macro stringify($($t:tt)*) {
|
||||
/* compiler built-in */
|
||||
}
|
||||
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
#[rustc_macro_transparency = "semiopaque"]
|
||||
pub macro file() {
|
||||
/* compiler built-in */
|
||||
}
|
||||
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
#[rustc_macro_transparency = "semiopaque"]
|
||||
pub macro line() {
|
||||
/* compiler built-in */
|
||||
}
|
||||
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
#[rustc_macro_transparency = "semiopaque"]
|
||||
pub macro cfg() {
|
||||
/* compiler built-in */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
586d798e864fb33b1b4e842c5493a653841a7c02
|
||||
896045775f7c40fafe48c6e398f6c53bf6af889e
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2025-12-20"
|
||||
channel = "nightly-2026-01-30"
|
||||
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
|
||||
|
|
|
|||
|
|
@ -243,6 +243,8 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
|||
pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: &Arch) -> Option<FnAttribute<'gcc>> {
|
||||
let attribute = match conv {
|
||||
CanonAbi::C | CanonAbi::Rust => return None,
|
||||
// gcc/gccjit does not have anything for this.
|
||||
CanonAbi::RustPreserveNone => return None,
|
||||
CanonAbi::RustCold => FnAttribute::Cold,
|
||||
// Functions with this calling convention can only be called from assembly, but it is
|
||||
// possible to declare an `extern "custom"` block, so the backend still needs a calling
|
||||
|
|
|
|||
|
|
@ -26,11 +26,11 @@ use std::sync::atomic::Ordering;
|
|||
use gccjit::{Context, OutputKind};
|
||||
use object::read::archive::ArchiveFile;
|
||||
use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule, ThinShared};
|
||||
use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput};
|
||||
use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput, SharedEmitter};
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file};
|
||||
use rustc_data_structures::memmap::Mmap;
|
||||
use rustc_errors::DiagCtxtHandle;
|
||||
use rustc_errors::{DiagCtxt, DiagCtxtHandle};
|
||||
use rustc_log::tracing::info;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::dep_graph::WorkProduct;
|
||||
|
|
@ -112,10 +112,11 @@ fn save_as_file(obj: &[u8], path: &Path) -> Result<(), LtoBitcodeFromRlib> {
|
|||
/// for further optimization.
|
||||
pub(crate) fn run_fat(
|
||||
cgcx: &CodegenContext<GccCodegenBackend>,
|
||||
shared_emitter: &SharedEmitter,
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
modules: Vec<FatLtoInput<GccCodegenBackend>>,
|
||||
) -> ModuleCodegen<GccContext> {
|
||||
let dcx = cgcx.create_dcx();
|
||||
let dcx = DiagCtxt::new(Box::new(shared_emitter.clone()));
|
||||
let dcx = dcx.handle();
|
||||
let lto_data = prepare_lto(cgcx, each_linked_rlib_for_lto, dcx);
|
||||
/*let symbols_below_threshold =
|
||||
|
|
@ -283,14 +284,13 @@ impl ModuleBufferMethods for ModuleBuffer {
|
|||
/// can simply be copied over from the incr. comp. cache.
|
||||
pub(crate) fn run_thin(
|
||||
cgcx: &CodegenContext<GccCodegenBackend>,
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
modules: Vec<(String, ThinBuffer)>,
|
||||
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
|
||||
) -> (Vec<ThinModule<GccCodegenBackend>>, Vec<WorkProduct>) {
|
||||
let dcx = cgcx.create_dcx();
|
||||
let dcx = dcx.handle();
|
||||
let lto_data = prepare_lto(cgcx, each_linked_rlib_for_lto, dcx);
|
||||
if cgcx.opts.cg.linker_plugin_lto.enabled() {
|
||||
if cgcx.use_linker_plugin_lto {
|
||||
unreachable!(
|
||||
"We should never reach this case if the LTO step \
|
||||
is deferred to the linker"
|
||||
|
|
@ -522,8 +522,6 @@ pub fn optimize_thin_module(
|
|||
thin_module: ThinModule<GccCodegenBackend>,
|
||||
_cgcx: &CodegenContext<GccCodegenBackend>,
|
||||
) -> ModuleCodegen<GccContext> {
|
||||
//let dcx = cgcx.create_dcx();
|
||||
|
||||
//let module_name = &thin_module.shared.module_names[thin_module.idx];
|
||||
/*let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, module_name.to_str().unwrap());
|
||||
let tm = (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(&dcx, e))?;*/
|
||||
|
|
|
|||
|
|
@ -2,8 +2,11 @@ use std::{env, fs};
|
|||
|
||||
use gccjit::{Context, OutputKind};
|
||||
use rustc_codegen_ssa::back::link::ensure_removed;
|
||||
use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig};
|
||||
use rustc_codegen_ssa::back::write::{
|
||||
BitcodeSection, CodegenContext, EmitObj, ModuleConfig, SharedEmitter,
|
||||
};
|
||||
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
|
||||
use rustc_errors::DiagCtxt;
|
||||
use rustc_fs_util::link_or_copy;
|
||||
use rustc_log::tracing::debug;
|
||||
use rustc_session::config::OutputType;
|
||||
|
|
@ -15,10 +18,11 @@ use crate::{GccCodegenBackend, GccContext, LtoMode};
|
|||
|
||||
pub(crate) fn codegen(
|
||||
cgcx: &CodegenContext<GccCodegenBackend>,
|
||||
shared_emitter: &SharedEmitter,
|
||||
module: ModuleCodegen<GccContext>,
|
||||
config: &ModuleConfig,
|
||||
) -> CompiledModule {
|
||||
let dcx = cgcx.create_dcx();
|
||||
let dcx = DiagCtxt::new(Box::new(shared_emitter.clone()));
|
||||
let dcx = dcx.handle();
|
||||
|
||||
let _timer = cgcx.prof.generic_activity_with_arg("GCC_module_codegen", &*module.name);
|
||||
|
|
|
|||
|
|
@ -314,14 +314,12 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
|||
self.block.get_function()
|
||||
}
|
||||
|
||||
fn function_call(
|
||||
pub fn function_call(
|
||||
&mut self,
|
||||
func: RValue<'gcc>,
|
||||
func: Function<'gcc>,
|
||||
args: &[RValue<'gcc>],
|
||||
_funclet: Option<&Funclet>,
|
||||
) -> RValue<'gcc> {
|
||||
// TODO(antoyo): remove when the API supports a different type for functions.
|
||||
let func: Function<'gcc> = self.cx.rvalue_as_function(func);
|
||||
let args = self.check_call("call", func, args);
|
||||
|
||||
// gccjit requires to use the result of functions, even when it's not used.
|
||||
|
|
@ -514,6 +512,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||
type CodegenCx = CodegenCx<'gcc, 'tcx>;
|
||||
|
||||
fn build(cx: &'a CodegenCx<'gcc, 'tcx>, block: Block<'gcc>) -> Builder<'a, 'gcc, 'tcx> {
|
||||
*cx.current_func.borrow_mut() = Some(block.get_function());
|
||||
Builder::with_cx(cx, block)
|
||||
}
|
||||
|
||||
|
|
@ -1496,6 +1495,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||
|
||||
#[cfg(not(feature = "master"))]
|
||||
fn extract_element(&mut self, vec: RValue<'gcc>, idx: RValue<'gcc>) -> RValue<'gcc> {
|
||||
use crate::context::new_array_type;
|
||||
|
||||
let vector_type = vec
|
||||
.get_type()
|
||||
.unqualified()
|
||||
|
|
@ -1504,7 +1505,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||
let element_type = vector_type.get_element_type();
|
||||
let vec_num_units = vector_type.get_num_units();
|
||||
let array_type =
|
||||
self.context.new_array_type(self.location, element_type, vec_num_units as u64);
|
||||
new_array_type(self.context, self.location, element_type, vec_num_units as u64);
|
||||
let array = self.context.new_bitcast(self.location, vec, array_type).to_rvalue();
|
||||
self.context.new_array_access(self.location, array, idx).to_rvalue()
|
||||
}
|
||||
|
|
@ -1765,6 +1766,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||
// FIXME(antoyo): remove when having a proper API.
|
||||
let gcc_func = unsafe { std::mem::transmute::<RValue<'gcc>, Function<'gcc>>(func) };
|
||||
let call = if self.functions.borrow().values().any(|value| *value == gcc_func) {
|
||||
// TODO(antoyo): remove when the API supports a different type for functions.
|
||||
let func: Function<'gcc> = self.cx.rvalue_as_function(func);
|
||||
self.function_call(func, args, funclet)
|
||||
} else {
|
||||
// If it's a not function that was defined, it's a function pointer.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use rustc_middle::mir::Mutability;
|
|||
use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, PointerArithmetic, Scalar};
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
|
||||
use crate::context::CodegenCx;
|
||||
use crate::context::{CodegenCx, new_array_type};
|
||||
use crate::type_of::LayoutGccExt;
|
||||
|
||||
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
||||
|
|
@ -55,7 +55,7 @@ pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) ->
|
|||
0 => {
|
||||
let context = &cx.context;
|
||||
let byte_type = context.new_type::<u64>();
|
||||
let typ = context.new_array_type(None, byte_type, bytes.len() as u64 / 8);
|
||||
let typ = new_array_type(context, None, byte_type, bytes.len() as u64 / 8);
|
||||
let elements: Vec<_> = bytes
|
||||
.chunks_exact(8)
|
||||
.map(|arr| {
|
||||
|
|
@ -76,7 +76,7 @@ pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) ->
|
|||
4 => {
|
||||
let context = &cx.context;
|
||||
let byte_type = context.new_type::<u32>();
|
||||
let typ = context.new_array_type(None, byte_type, bytes.len() as u64 / 4);
|
||||
let typ = new_array_type(context, None, byte_type, bytes.len() as u64 / 4);
|
||||
let elements: Vec<_> = bytes
|
||||
.chunks_exact(4)
|
||||
.map(|arr| {
|
||||
|
|
@ -95,7 +95,7 @@ pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) ->
|
|||
_ => {
|
||||
let context = cx.context;
|
||||
let byte_type = context.new_type::<u8>();
|
||||
let typ = context.new_array_type(None, byte_type, bytes.len() as u64);
|
||||
let typ = new_array_type(context, None, byte_type, bytes.len() as u64);
|
||||
let elements: Vec<_> = bytes
|
||||
.iter()
|
||||
.map(|&byte| context.new_rvalue_from_int(byte_type, byte as i32))
|
||||
|
|
|
|||
|
|
@ -94,6 +94,8 @@ pub struct CodegenCx<'gcc, 'tcx> {
|
|||
pub instances: RefCell<FxHashMap<Instance<'tcx>, LValue<'gcc>>>,
|
||||
/// Cache function instances of monomorphic and polymorphic items
|
||||
pub function_instances: RefCell<FxHashMap<Instance<'tcx>, Function<'gcc>>>,
|
||||
/// Cache function instances of intrinsics
|
||||
pub intrinsic_instances: RefCell<FxHashMap<Instance<'tcx>, Function<'gcc>>>,
|
||||
/// Cache generated vtables
|
||||
pub vtables:
|
||||
RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), RValue<'gcc>>>,
|
||||
|
|
@ -199,8 +201,8 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||
|
||||
// TODO(antoyo): re-enable the alignment when libgccjit fixed the issue in
|
||||
// gcc_jit_context_new_array_constructor (it should not use reinterpret_cast).
|
||||
let i128_type = context.new_array_type(None, i64_type, 2)/*.get_aligned(i128_align)*/;
|
||||
let u128_type = context.new_array_type(None, u64_type, 2)/*.get_aligned(u128_align)*/;
|
||||
let i128_type = new_array_type(context, None, i64_type, 2)/*.get_aligned(i128_align)*/;
|
||||
let u128_type = new_array_type(context, None, u64_type, 2)/*.get_aligned(u128_align)*/;
|
||||
(i128_type, u128_type)
|
||||
};
|
||||
|
||||
|
|
@ -287,6 +289,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||
linkage: Cell::new(FunctionType::Internal),
|
||||
instances: Default::default(),
|
||||
function_instances: Default::default(),
|
||||
intrinsic_instances: Default::default(),
|
||||
on_stack_params: Default::default(),
|
||||
on_stack_function_params: Default::default(),
|
||||
vtables: Default::default(),
|
||||
|
|
@ -398,17 +401,13 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
|||
}
|
||||
|
||||
fn get_fn(&self, instance: Instance<'tcx>) -> Function<'gcc> {
|
||||
let func = get_fn(self, instance);
|
||||
*self.current_func.borrow_mut() = Some(func);
|
||||
func
|
||||
get_fn(self, instance)
|
||||
}
|
||||
|
||||
fn get_fn_addr(&self, instance: Instance<'tcx>) -> RValue<'gcc> {
|
||||
let func_name = self.tcx.symbol_name(instance).name;
|
||||
|
||||
let func = if self.intrinsics.borrow().contains_key(func_name) {
|
||||
self.intrinsics.borrow()[func_name]
|
||||
} else if let Some(variable) = self.get_declared_value(func_name) {
|
||||
let func = if let Some(variable) = self.get_declared_value(func_name) {
|
||||
return variable;
|
||||
} else {
|
||||
get_fn(self, instance)
|
||||
|
|
@ -609,3 +608,17 @@ fn to_gcc_tls_mode(tls_model: TlsModel) -> gccjit::TlsModel {
|
|||
TlsModel::Emulated => gccjit::TlsModel::GlobalDynamic,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_array_type<'gcc>(
|
||||
context: &'gcc Context<'gcc>,
|
||||
location: Option<Location<'gcc>>,
|
||||
typ: Type<'gcc>,
|
||||
size: u64,
|
||||
) -> Type<'gcc> {
|
||||
#[cfg(feature = "master")]
|
||||
{
|
||||
context.new_array_type_u64(location, typ, size)
|
||||
}
|
||||
#[cfg(not(feature = "master"))]
|
||||
context.new_array_type(location, typ, size)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ use rustc_target::callconv::FnAbi;
|
|||
|
||||
use crate::abi::{FnAbiGcc, FnAbiGccExt};
|
||||
use crate::context::CodegenCx;
|
||||
use crate::intrinsic::llvm;
|
||||
|
||||
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
||||
pub fn get_or_insert_global(
|
||||
|
|
@ -100,18 +99,14 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||
let return_type = self.type_i32();
|
||||
let variadic = false;
|
||||
self.linkage.set(FunctionType::Exported);
|
||||
let func = declare_raw_fn(
|
||||
declare_raw_fn(
|
||||
self,
|
||||
name,
|
||||
callconv,
|
||||
return_type,
|
||||
&[self.type_i32(), const_string],
|
||||
variadic,
|
||||
);
|
||||
// NOTE: it is needed to set the current_func here as well, because get_fn() is not called
|
||||
// for the main function.
|
||||
*self.current_func.borrow_mut() = Some(func);
|
||||
func
|
||||
)
|
||||
}
|
||||
|
||||
pub fn declare_fn(&self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Function<'gcc> {
|
||||
|
|
@ -166,19 +161,6 @@ fn declare_raw_fn<'gcc>(
|
|||
param_types: &[Type<'gcc>],
|
||||
variadic: bool,
|
||||
) -> Function<'gcc> {
|
||||
if name.starts_with("llvm.") {
|
||||
let intrinsic = match name {
|
||||
"llvm.fma.f16" => {
|
||||
// fma is not a target builtin, but a normal builtin, so we handle it differently
|
||||
// here.
|
||||
cx.context.get_builtin_function("fma")
|
||||
}
|
||||
_ => llvm::intrinsic(name, cx),
|
||||
};
|
||||
|
||||
cx.intrinsics.borrow_mut().insert(name.to_string(), intrinsic);
|
||||
return intrinsic;
|
||||
}
|
||||
let func = if cx.functions.borrow().contains_key(name) {
|
||||
cx.functions.borrow()[name]
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use gccjit::{CType, Context, Field, Function, FunctionPtrType, RValue, ToRValue,
|
|||
use rustc_codegen_ssa::traits::BuilderMethods;
|
||||
|
||||
use crate::builder::Builder;
|
||||
use crate::context::CodegenCx;
|
||||
use crate::context::{CodegenCx, new_array_type};
|
||||
|
||||
fn encode_key_128_type<'a, 'gcc, 'tcx>(
|
||||
builder: &Builder<'a, 'gcc, 'tcx>,
|
||||
|
|
@ -585,7 +585,7 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(
|
|||
"__builtin_ia32_encodekey128_u32" => {
|
||||
let mut new_args = args.to_vec();
|
||||
let m128i = builder.context.new_vector_type(builder.i64_type, 2);
|
||||
let array_type = builder.context.new_array_type(None, m128i, 6);
|
||||
let array_type = new_array_type(builder.context, None, m128i, 6);
|
||||
let result = builder.current_func().new_local(None, array_type, "result");
|
||||
new_args.push(result.get_address(None));
|
||||
args = new_args.into();
|
||||
|
|
@ -593,7 +593,7 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(
|
|||
"__builtin_ia32_encodekey256_u32" => {
|
||||
let mut new_args = args.to_vec();
|
||||
let m128i = builder.context.new_vector_type(builder.i64_type, 2);
|
||||
let array_type = builder.context.new_array_type(None, m128i, 7);
|
||||
let array_type = new_array_type(builder.context, None, m128i, 7);
|
||||
let result = builder.current_func().new_local(None, array_type, "result");
|
||||
new_args.push(result.get_address(None));
|
||||
args = new_args.into();
|
||||
|
|
@ -620,7 +620,7 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(
|
|||
let first_value = old_args.swap_remove(0);
|
||||
|
||||
let element_type = first_value.get_type();
|
||||
let array_type = builder.context.new_array_type(None, element_type, 8);
|
||||
let array_type = new_array_type(builder.context, None, element_type, 8);
|
||||
let result = builder.current_func().new_local(None, array_type, "result");
|
||||
new_args.push(result.get_address(None));
|
||||
|
||||
|
|
@ -869,7 +869,7 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>(
|
|||
builder.llbb().add_assignment(None, field1, return_value);
|
||||
let field2 = result.access_field(None, field2);
|
||||
let field2_type = field2.to_rvalue().get_type();
|
||||
let array_type = builder.context.new_array_type(None, field2_type, 6);
|
||||
let array_type = new_array_type(builder.context, None, field2_type, 6);
|
||||
let ptr = builder.context.new_cast(None, args[2], array_type.make_pointer());
|
||||
let field2_ptr =
|
||||
builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer());
|
||||
|
|
@ -891,7 +891,7 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>(
|
|||
builder.llbb().add_assignment(None, field1, return_value);
|
||||
let field2 = result.access_field(None, field2);
|
||||
let field2_type = field2.to_rvalue().get_type();
|
||||
let array_type = builder.context.new_array_type(None, field2_type, 7);
|
||||
let array_type = new_array_type(builder.context, None, field2_type, 7);
|
||||
let ptr = builder.context.new_cast(None, args[3], array_type.make_pointer());
|
||||
let field2_ptr =
|
||||
builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer());
|
||||
|
|
@ -937,7 +937,7 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>(
|
|||
builder.llbb().add_assignment(None, field1, return_value);
|
||||
let field2 = result.access_field(None, field2);
|
||||
let field2_type = field2.to_rvalue().get_type();
|
||||
let array_type = builder.context.new_array_type(None, field2_type, 8);
|
||||
let array_type = new_array_type(builder.context, None, field2_type, 8);
|
||||
let ptr = builder.context.new_cast(None, args[0], array_type.make_pointer());
|
||||
let field2_ptr =
|
||||
builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer());
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use gccjit::Type;
|
|||
use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp};
|
||||
#[cfg(feature = "master")]
|
||||
use rustc_abi::ExternAbi;
|
||||
use rustc_abi::{BackendRepr, HasDataLayout};
|
||||
use rustc_abi::{BackendRepr, HasDataLayout, WrappingRange};
|
||||
use rustc_codegen_ssa::MemFlags;
|
||||
use rustc_codegen_ssa::base::wants_msvc_seh;
|
||||
use rustc_codegen_ssa::common::IntPredicate;
|
||||
|
|
@ -20,19 +20,15 @@ use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
|
|||
use rustc_codegen_ssa::traits::MiscCodegenMethods;
|
||||
use rustc_codegen_ssa::traits::{
|
||||
ArgAbiBuilderMethods, BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods,
|
||||
IntrinsicCallBuilderMethods,
|
||||
IntrinsicCallBuilderMethods, LayoutTypeCodegenMethods,
|
||||
};
|
||||
use rustc_middle::bug;
|
||||
#[cfg(feature = "master")]
|
||||
use rustc_middle::ty::layout::FnAbiOf;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
|
||||
use rustc_middle::ty::{self, Instance, Ty};
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
use rustc_target::callconv::{ArgAbi, PassMode};
|
||||
|
||||
#[cfg(feature = "master")]
|
||||
use crate::abi::FnAbiGccExt;
|
||||
use crate::abi::GccType;
|
||||
use crate::abi::{FnAbiGccExt, GccType};
|
||||
use crate::builder::Builder;
|
||||
use crate::common::{SignType, TypeReflection};
|
||||
use crate::context::CodegenCx;
|
||||
|
|
@ -171,6 +167,7 @@ fn get_simple_function_f128<'gcc, 'tcx>(
|
|||
let f128_type = cx.type_f128();
|
||||
let func_name = match name {
|
||||
sym::ceilf128 => "ceilf128",
|
||||
sym::fabsf128 => "fabsf128",
|
||||
sym::floorf128 => "floorf128",
|
||||
sym::truncf128 => "truncf128",
|
||||
sym::roundf128 => "roundf128",
|
||||
|
|
@ -225,6 +222,7 @@ fn f16_builtin<'gcc, 'tcx>(
|
|||
let builtin_name = match name {
|
||||
sym::ceilf16 => "__builtin_ceilf",
|
||||
sym::copysignf16 => "__builtin_copysignf",
|
||||
sym::fabsf16 => "fabsf",
|
||||
sym::floorf16 => "__builtin_floorf",
|
||||
sym::fmaf16 => "fmaf",
|
||||
sym::maxnumf16 => "__builtin_fmaxf",
|
||||
|
|
@ -291,6 +289,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
|
|||
}
|
||||
sym::ceilf16
|
||||
| sym::copysignf16
|
||||
| sym::fabsf16
|
||||
| sym::floorf16
|
||||
| sym::fmaf16
|
||||
| sym::maxnumf16
|
||||
|
|
@ -359,9 +358,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
|
|||
sym::breakpoint => {
|
||||
unimplemented!();
|
||||
}
|
||||
sym::va_copy => {
|
||||
unimplemented!();
|
||||
}
|
||||
sym::va_arg => {
|
||||
unimplemented!();
|
||||
}
|
||||
|
|
@ -573,6 +569,94 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn codegen_llvm_intrinsic_call(
|
||||
&mut self,
|
||||
instance: ty::Instance<'tcx>,
|
||||
args: &[OperandRef<'tcx, Self::Value>],
|
||||
is_cleanup: bool,
|
||||
) -> Self::Value {
|
||||
let func = if let Some(&func) = self.intrinsic_instances.borrow().get(&instance) {
|
||||
func
|
||||
} else {
|
||||
let sym = self.tcx.symbol_name(instance).name;
|
||||
|
||||
let func = if let Some(func) = self.intrinsics.borrow().get(sym) {
|
||||
*func
|
||||
} else {
|
||||
self.linkage.set(FunctionType::Extern);
|
||||
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
|
||||
let fn_ty = fn_abi.gcc_type(self);
|
||||
|
||||
let func = match sym {
|
||||
"llvm.fma.f16" => {
|
||||
// fma is not a target builtin, but a normal builtin, so we handle it differently
|
||||
// here.
|
||||
self.context.get_builtin_function("fma")
|
||||
}
|
||||
_ => llvm::intrinsic(sym, self),
|
||||
};
|
||||
|
||||
self.intrinsics.borrow_mut().insert(sym.to_string(), func);
|
||||
|
||||
self.on_stack_function_params
|
||||
.borrow_mut()
|
||||
.insert(func, fn_ty.on_stack_param_indices);
|
||||
#[cfg(feature = "master")]
|
||||
for fn_attr in fn_ty.fn_attributes {
|
||||
func.add_attribute(fn_attr);
|
||||
}
|
||||
|
||||
crate::attributes::from_fn_attrs(self, func, instance);
|
||||
|
||||
func
|
||||
};
|
||||
|
||||
self.intrinsic_instances.borrow_mut().insert(instance, func);
|
||||
|
||||
func
|
||||
};
|
||||
let fn_ptr = func.get_address(None);
|
||||
let fn_ty = fn_ptr.get_type();
|
||||
|
||||
let mut call_args = vec![];
|
||||
|
||||
for arg in args {
|
||||
match arg.val {
|
||||
OperandValue::ZeroSized => {}
|
||||
OperandValue::Immediate(_) => call_args.push(arg.immediate()),
|
||||
OperandValue::Pair(a, b) => {
|
||||
call_args.push(a);
|
||||
call_args.push(b);
|
||||
}
|
||||
OperandValue::Ref(op_place_val) => {
|
||||
let mut llval = op_place_val.llval;
|
||||
// We can't use `PlaceRef::load` here because the argument
|
||||
// may have a type we don't treat as immediate, but the ABI
|
||||
// used for this call is passing it by-value. In that case,
|
||||
// the load would just produce `OperandValue::Ref` instead
|
||||
// of the `OperandValue::Immediate` we need for the call.
|
||||
llval = self.load(self.backend_type(arg.layout), llval, op_place_val.align);
|
||||
if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr {
|
||||
if scalar.is_bool() {
|
||||
self.range_metadata(llval, WrappingRange { start: 0, end: 1 });
|
||||
}
|
||||
// We store bools as `i8` so we need to truncate to `i1`.
|
||||
llval = self.to_immediate_scalar(llval, scalar);
|
||||
}
|
||||
call_args.push(llval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME directly use the llvm intrinsic adjustment functions here
|
||||
let llret = self.call(fn_ty, None, None, fn_ptr, &call_args, None, None);
|
||||
if is_cleanup {
|
||||
self.apply_attrs_to_cleanup_callsite(llret);
|
||||
}
|
||||
|
||||
llret
|
||||
}
|
||||
|
||||
fn abort(&mut self) {
|
||||
let func = self.context.get_builtin_function("abort");
|
||||
let func: RValue<'gcc> = unsafe { std::mem::transmute(func) };
|
||||
|
|
@ -606,7 +690,8 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
|
|||
}
|
||||
|
||||
fn va_end(&mut self, _va_list: RValue<'gcc>) -> RValue<'gcc> {
|
||||
unimplemented!();
|
||||
// TODO(antoyo): implement.
|
||||
self.context.new_rvalue_from_int(self.int_type, 0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,6 +121,42 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||
return Ok(bx.vector_select(vector_mask, arg1, args[2].immediate()));
|
||||
}
|
||||
|
||||
#[cfg(feature = "master")]
|
||||
if name == sym::simd_splat {
|
||||
let (out_len, out_ty) = require_simd2!(ret_ty, SimdReturn);
|
||||
|
||||
require!(
|
||||
args[0].layout.ty == out_ty,
|
||||
InvalidMonomorphization::ExpectedVectorElementType {
|
||||
span,
|
||||
name,
|
||||
expected_element: out_ty,
|
||||
vector_type: ret_ty,
|
||||
}
|
||||
);
|
||||
|
||||
let vec_ty = llret_ty.unqualified().dyncast_vector().expect("vector return type");
|
||||
let elem_ty = vec_ty.get_element_type();
|
||||
|
||||
// Cast pointer type to usize (GCC does not support pointer SIMD vectors).
|
||||
let value = args[0];
|
||||
let scalar = if value.layout.ty.is_numeric() {
|
||||
value.immediate()
|
||||
} else if value.layout.ty.is_raw_ptr() {
|
||||
bx.ptrtoint(value.immediate(), elem_ty)
|
||||
} else {
|
||||
return_error!(InvalidMonomorphization::UnsupportedOperation {
|
||||
span,
|
||||
name,
|
||||
in_ty: ret_ty,
|
||||
in_elem: value.layout.ty
|
||||
});
|
||||
};
|
||||
|
||||
let elements = vec![scalar; out_len as usize];
|
||||
return Ok(bx.context.new_rvalue_from_vector(bx.location, llret_ty, &elements));
|
||||
}
|
||||
|
||||
// every intrinsic below takes a SIMD vector as its first argument
|
||||
require_simd!(
|
||||
args[0].layout.ty,
|
||||
|
|
|
|||
17
src/lib.rs
17
src/lib.rs
|
|
@ -84,7 +84,7 @@ use gccjit::{TargetInfo, Version};
|
|||
use rustc_ast::expand::allocator::AllocatorMethod;
|
||||
use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule};
|
||||
use rustc_codegen_ssa::back::write::{
|
||||
CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn,
|
||||
CodegenContext, FatLtoInput, ModuleConfig, SharedEmitter, TargetMachineFactoryFn,
|
||||
};
|
||||
use rustc_codegen_ssa::base::codegen_crate;
|
||||
use rustc_codegen_ssa::target_features::cfg_target_feature;
|
||||
|
|
@ -288,7 +288,8 @@ impl CodegenBackend for GccCodegenBackend {
|
|||
}
|
||||
|
||||
fn provide(&self, providers: &mut Providers) {
|
||||
providers.global_backend_features = |tcx, ()| gcc_util::global_gcc_features(tcx.sess)
|
||||
providers.queries.global_backend_features =
|
||||
|tcx, ()| gcc_util::global_gcc_features(tcx.sess)
|
||||
}
|
||||
|
||||
fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box<dyn Any> {
|
||||
|
|
@ -436,23 +437,25 @@ impl WriteBackendMethods for GccCodegenBackend {
|
|||
|
||||
fn run_and_optimize_fat_lto(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
shared_emitter: &SharedEmitter,
|
||||
// FIXME(bjorn3): Limit LTO exports to these symbols
|
||||
_exported_symbols_for_lto: &[String],
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
modules: Vec<FatLtoInput<Self>>,
|
||||
) -> ModuleCodegen<Self::Module> {
|
||||
back::lto::run_fat(cgcx, each_linked_rlib_for_lto, modules)
|
||||
back::lto::run_fat(cgcx, shared_emitter, each_linked_rlib_for_lto, modules)
|
||||
}
|
||||
|
||||
fn run_thin_lto(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
dcx: DiagCtxtHandle<'_>,
|
||||
// FIXME(bjorn3): Limit LTO exports to these symbols
|
||||
_exported_symbols_for_lto: &[String],
|
||||
each_linked_rlib_for_lto: &[PathBuf],
|
||||
modules: Vec<(String, Self::ThinBuffer)>,
|
||||
cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,
|
||||
) -> (Vec<ThinModule<Self>>, Vec<WorkProduct>) {
|
||||
back::lto::run_thin(cgcx, each_linked_rlib_for_lto, modules, cached_modules)
|
||||
back::lto::run_thin(cgcx, dcx, each_linked_rlib_for_lto, modules, cached_modules)
|
||||
}
|
||||
|
||||
fn print_pass_timings(&self) {
|
||||
|
|
@ -465,7 +468,7 @@ impl WriteBackendMethods for GccCodegenBackend {
|
|||
|
||||
fn optimize(
|
||||
_cgcx: &CodegenContext<Self>,
|
||||
_dcx: DiagCtxtHandle<'_>,
|
||||
_shared_emitter: &SharedEmitter,
|
||||
module: &mut ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
) {
|
||||
|
|
@ -474,6 +477,7 @@ impl WriteBackendMethods for GccCodegenBackend {
|
|||
|
||||
fn optimize_thin(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
_shared_emitter: &SharedEmitter,
|
||||
thin: ThinModule<Self>,
|
||||
) -> ModuleCodegen<Self::Module> {
|
||||
back::lto::optimize_thin_module(thin, cgcx)
|
||||
|
|
@ -481,10 +485,11 @@ impl WriteBackendMethods for GccCodegenBackend {
|
|||
|
||||
fn codegen(
|
||||
cgcx: &CodegenContext<Self>,
|
||||
shared_emitter: &SharedEmitter,
|
||||
module: ModuleCodegen<Self::Module>,
|
||||
config: &ModuleConfig,
|
||||
) -> CompiledModule {
|
||||
back::write::codegen(cgcx, module, config)
|
||||
back::write::codegen(cgcx, shared_emitter, module, config)
|
||||
}
|
||||
|
||||
fn prepare_thin(module: ModuleCodegen<Self::Module>) -> (String, Self::ThinBuffer) {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use rustc_middle::ty::layout::TyAndLayout;
|
|||
use rustc_middle::{bug, ty};
|
||||
|
||||
use crate::common::TypeReflection;
|
||||
use crate::context::CodegenCx;
|
||||
use crate::context::{CodegenCx, new_array_type};
|
||||
use crate::type_of::LayoutGccExt;
|
||||
|
||||
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
||||
|
|
@ -311,7 +311,7 @@ impl<'gcc, 'tcx> BaseTypeCodegenMethods for CodegenCx<'gcc, 'tcx> {
|
|||
len = 0;
|
||||
}
|
||||
|
||||
self.context.new_array_type(None, ty, len)
|
||||
new_array_type(self.context, None, ty, len)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
1
tests/failing-ui-tests-without-128bit-integers.txt
Normal file
1
tests/failing-ui-tests-without-128bit-integers.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
tests/ui/simd/intrinsic/splat.rs
|
||||
|
|
@ -89,11 +89,12 @@ tests/ui/thir-print/offset_of.rs
|
|||
tests/ui/iterators/rangefrom-overflow-debug.rs
|
||||
tests/ui/iterators/rangefrom-overflow-overflow-checks.rs
|
||||
tests/ui/iterators/iter-filter-count-debug-check.rs
|
||||
tests/ui/eii/codegen_single_crate.rs
|
||||
tests/ui/eii/codegen_cross_crate.rs
|
||||
tests/ui/eii/linking/codegen_single_crate.rs
|
||||
tests/ui/eii/linking/codegen_cross_crate.rs
|
||||
tests/ui/eii/default/local_crate.rs
|
||||
tests/ui/eii/multiple_impls.rs
|
||||
tests/ui/eii/duplicate/multiple_impls.rs
|
||||
tests/ui/eii/default/call_default.rs
|
||||
tests/ui/eii/same-symbol.rs
|
||||
tests/ui/eii/linking/same-symbol.rs
|
||||
tests/ui/eii/privacy1.rs
|
||||
tests/ui/eii/default/call_impl.rs
|
||||
tests/ui/c-variadic/copy.rs
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue