about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock8
-rw-r--r--Cargo.toml2
-rw-r--r--build_system/src/utils.rs2
-rw-r--r--libgccjit.version2
-rw-r--r--patches/libgccjit12/0001-core-Disable-portable-simd-test.patch3
-rw-r--r--src/abi.rs1
-rw-r--r--src/archive.rs24
-rw-r--r--src/base.rs3
-rw-r--r--src/builder.rs22
-rw-r--r--src/common.rs4
-rw-r--r--src/consts.rs1
-rw-r--r--src/gcc_util.rs8
-rw-r--r--src/lib.rs16
-rw-r--r--tests/failing-ui-tests.txt1
-rw-r--r--tests/failing-ui-tests12.txt1
-rw-r--r--tests/run/volatile2.rs113
16 files changed, 179 insertions, 32 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 6b06e7d7f27..9a50733b216 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -28,18 +28,18 @@ dependencies = [
 
 [[package]]
 name = "gccjit"
-version = "2.2.0"
+version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bb376e98c82d9284c3a17fc1d6bf9bc921055418950238d7a553c27a7e1f6ab"
+checksum = "72fd91f4adbf02b53cfc73c97bc33c5f253009043f30c56a5ec08dd5c8094dc8"
 dependencies = [
  "gccjit_sys",
 ]
 
 [[package]]
 name = "gccjit_sys"
-version = "0.3.0"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93b4b1be553b5df790bf25ca2a1d6add81727dc29f8d5c8742468ed306d621d1"
+checksum = "0fb7b8f48a75e2cfe78c3d9a980b32771c34ffd12d196021ab3f98c49fbd2f0d"
 dependencies = [
  "libc",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index 4828b7ddb16..da108e9d9bf 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,7 +22,7 @@ master = ["gccjit/master"]
 default = ["master"]
 
 [dependencies]
-gccjit = "2.2"
+gccjit = "2.4"
 #gccjit = { git = "https://github.com/rust-lang/gccjit.rs" }
 
 # Local copy.
diff --git a/build_system/src/utils.rs b/build_system/src/utils.rs
index 401c23948e5..e338d1b4992 100644
--- a/build_system/src/utils.rs
+++ b/build_system/src/utils.rs
@@ -1,7 +1,7 @@
 use std::collections::HashMap;
-use std::ffi::OsStr;
 #[cfg(unix)]
 use std::ffi::c_int;
+use std::ffi::OsStr;
 use std::fmt::Debug;
 use std::fs;
 #[cfg(unix)]
diff --git a/libgccjit.version b/libgccjit.version
index b9bbbd324c3..ff58accec1d 100644
--- a/libgccjit.version
+++ b/libgccjit.version
@@ -1 +1 @@
-e744a9459d33864067214741daf5c5bc2a7b88c6
+45648c2edd4ecd862d9f08196d3d6c6ccba79f07
diff --git a/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch b/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch
index 01461987ffb..9ef5e0e4f46 100644
--- a/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch
+++ b/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch
@@ -27,5 +27,4 @@ index b71786c..cf484d5 100644
  mod slice;
  mod str;
  mod str_lossy;
--- 
-2.45.2
+-- 2.45.2
diff --git a/src/abi.rs b/src/abi.rs
index 14fc23593f0..3e06720f87f 100644
--- a/src/abi.rs
+++ b/src/abi.rs
@@ -4,6 +4,7 @@ use gccjit::{ToLValue, ToRValue, Type};
 use rustc_codegen_ssa::traits::{AbiBuilderMethods, BaseTypeCodegenMethods};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::bug;
+use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::LayoutOf;
 #[cfg(feature = "master")]
diff --git a/src/archive.rs b/src/archive.rs
new file mode 100644
index 00000000000..0cee05f1cea
--- /dev/null
+++ b/src/archive.rs
@@ -0,0 +1,24 @@
+use std::path::Path;
+
+use rustc_codegen_ssa::back::archive::{
+    ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder, DEFAULT_OBJECT_READER,
+};
+use rustc_session::Session;
+
+pub(crate) struct ArArchiveBuilderBuilder;
+
+impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
+    fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
+        Box::new(ArArchiveBuilder::new(sess, &DEFAULT_OBJECT_READER))
+    }
+
+    fn create_dll_import_lib(
+        &self,
+        _sess: &Session,
+        _lib_name: &str,
+        _import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
+        _output_path: &Path,
+    ) {
+        unimplemented!("creating dll imports is not yet supported");
+    }
+}
diff --git a/src/base.rs b/src/base.rs
index 18aa32754e1..508cb74ff64 100644
--- a/src/base.rs
+++ b/src/base.rs
@@ -199,12 +199,13 @@ pub fn compile_codegen_unit(
             let f32_type_supported = target_info.supports_target_dependent_type(CType::Float32);
             let f64_type_supported = target_info.supports_target_dependent_type(CType::Float64);
             let f128_type_supported = target_info.supports_target_dependent_type(CType::Float128);
+            let u128_type_supported = target_info.supports_target_dependent_type(CType::UInt128t);
             // TODO: improve this to avoid passing that many arguments.
             let cx = CodegenCx::new(
                 &context,
                 cgu,
                 tcx,
-                target_info.supports_128bit_int(),
+                u128_type_supported,
                 f16_type_supported,
                 f32_type_supported,
                 f64_type_supported,
diff --git a/src/builder.rs b/src/builder.rs
index 9a142326ad1..a9f0edd2667 100644
--- a/src/builder.rs
+++ b/src/builder.rs
@@ -1102,18 +1102,24 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
         val: RValue<'gcc>,
         ptr: RValue<'gcc>,
         align: Align,
-        _flags: MemFlags,
+        flags: MemFlags,
     ) -> RValue<'gcc> {
         let ptr = self.check_store(val, ptr);
         let destination = ptr.dereference(self.location);
         // NOTE: libgccjit does not support specifying the alignment on the assignment, so we cast
         // to type so it gets the proper alignment.
         let destination_type = destination.to_rvalue().get_type().unqualified();
-        let aligned_type = destination_type.get_aligned(align.bytes()).make_pointer();
-        let aligned_destination = self.cx.context.new_bitcast(self.location, ptr, aligned_type);
-        let aligned_destination = aligned_destination.dereference(self.location);
-        self.llbb().add_assignment(self.location, aligned_destination, val);
-        // TODO(antoyo): handle align and flags.
+        let align = if flags.contains(MemFlags::UNALIGNED) { 1 } else { align.bytes() };
+        let mut modified_destination_type = destination_type.get_aligned(align);
+        if flags.contains(MemFlags::VOLATILE) {
+            modified_destination_type = modified_destination_type.make_volatile();
+        }
+
+        let modified_ptr =
+            self.cx.context.new_cast(self.location, ptr, modified_destination_type.make_pointer());
+        let modified_destination = modified_ptr.dereference(self.location);
+        self.llbb().add_assignment(self.location, modified_destination, val);
+        // TODO(antoyo): handle `MemFlags::NONTEMPORAL`.
         // NOTE: dummy value here since it's never used. FIXME(antoyo): API should not return a value here?
         // When adding support for NONTEMPORAL, make sure to not just emit MOVNT on x86; see the
         // LLVM backend for details.
@@ -1236,13 +1242,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
     }
 
     fn ptrtoint(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> {
-        let usize_value = self.cx.const_bitcast(value, self.cx.type_isize());
+        let usize_value = self.cx.context.new_cast(None, value, self.cx.type_isize());
         self.intcast(usize_value, dest_ty, false)
     }
 
     fn inttoptr(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> {
         let usize_value = self.intcast(value, self.cx.type_isize(), false);
-        self.cx.const_bitcast(usize_value, dest_ty)
+        self.cx.context.new_cast(None, usize_value, dest_ty)
     }
 
     fn bitcast(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> {
diff --git a/src/common.rs b/src/common.rs
index 0d3e7083d56..3025c8c9085 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -240,10 +240,10 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
                     }
                 };
                 let ptr_type = base_addr.get_type();
-                let base_addr = self.const_bitcast(base_addr, self.usize_type);
+                let base_addr = self.context.new_cast(None, base_addr, self.usize_type);
                 let offset =
                     self.context.new_rvalue_from_long(self.usize_type, offset.bytes() as i64);
-                let ptr = self.const_bitcast(base_addr + offset, ptr_type);
+                let ptr = self.context.new_cast(None, base_addr + offset, ptr_type);
                 if !matches!(layout.primitive(), Pointer(_)) {
                     self.const_bitcast(ptr.dereference(None).to_rvalue(), ty)
                 } else {
diff --git a/src/consts.rs b/src/consts.rs
index 6dc2f4ed668..ddb9e8336f4 100644
--- a/src/consts.rs
+++ b/src/consts.rs
@@ -404,7 +404,6 @@ fn check_and_apply_linkage<'gcc, 'tcx>(
         // TODO(antoyo): set linkage.
         let value = cx.const_ptrcast(global1.get_address(None), gcc_type);
         global2.global_set_initializer_rvalue(value);
-        // TODO(antoyo): use global_set_initializer() when it will work.
         global2
     } else {
         // Generate an external declaration.
diff --git a/src/gcc_util.rs b/src/gcc_util.rs
index 65279c9495a..17bb1b4ca0b 100644
--- a/src/gcc_util.rs
+++ b/src/gcc_util.rs
@@ -39,10 +39,10 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
     // Features implied by an implicit or explicit `--target`.
     features.extend(
         sess.target
-            .features
-            .split(',')
-            .filter(|v| !v.is_empty() && backend_feature_name(v).is_some())
-            .map(String::from),
+        .features
+        .split(',')
+        .filter(|v| !v.is_empty() && backend_feature_name(v).is_some())
+        .map(String::from),
     );
 
     // -Ctarget-features
diff --git a/src/lib.rs b/src/lib.rs
index 452e92bffa2..8a50b8b30ea 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -140,8 +140,16 @@ impl TargetInfo {
         false
     }
 
-    fn supports_128bit_int(&self) -> bool {
-        self.supports_128bit_integers.load(Ordering::SeqCst)
+    fn supports_target_dependent_type(&self, typ: CType) -> bool {
+        match typ {
+            CType::UInt128t | CType::Int128t => {
+                if self.supports_128bit_integers.load(Ordering::SeqCst) {
+                    return true;
+                }
+            }
+            _ => (),
+        }
+        false
     }
 
     fn supports_target_dependent_type(&self, _typ: CType) -> bool {
@@ -165,10 +173,6 @@ impl LockedTargetInfo {
         self.info.lock().expect("lock").cpu_supports(feature)
     }
 
-    fn supports_128bit_int(&self) -> bool {
-        self.info.lock().expect("lock").supports_128bit_int()
-    }
-
     fn supports_target_dependent_type(&self, typ: CType) -> bool {
         self.info.lock().expect("lock").supports_target_dependent_type(typ)
     }
diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt
index 457072b1a5b..6dc1c2066f6 100644
--- a/tests/failing-ui-tests.txt
+++ b/tests/failing-ui-tests.txt
@@ -91,6 +91,7 @@ tests/ui/delegation/fn-header.rs
 tests/ui/consts/zst_no_llvm_alloc.rs
 tests/ui/consts/const-eval/parse_ints.rs
 tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
+tests/ui/simd/intrinsic/generic-as.rs
 tests/ui/backtrace/backtrace.rs
 tests/ui/lifetimes/tail-expr-lock-poisoning.rs
 tests/ui/runtime/rt-explody-panic-payloads.rs
diff --git a/tests/failing-ui-tests12.txt b/tests/failing-ui-tests12.txt
index 1d9bdaa552c..b10d4bc82aa 100644
--- a/tests/failing-ui-tests12.txt
+++ b/tests/failing-ui-tests12.txt
@@ -11,7 +11,6 @@ tests/ui/simd/array-type.rs
 tests/ui/simd/intrinsic/float-minmax-pass.rs
 tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
 tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
-tests/ui/simd/intrinsic/generic-as.rs
 tests/ui/simd/intrinsic/generic-cast-pass.rs
 tests/ui/simd/intrinsic/generic-cast-pointer-width.rs
 tests/ui/simd/intrinsic/generic-comparison-pass.rs
diff --git a/tests/run/volatile2.rs b/tests/run/volatile2.rs
new file mode 100644
index 00000000000..a177b817ab3
--- /dev/null
+++ b/tests/run/volatile2.rs
@@ -0,0 +1,113 @@
+// Compiler:
+//
+// Run-time:
+//   status: 0
+
+mod libc {
+    #[link(name = "c")]
+    extern "C" {
+        pub fn puts(s: *const u8) -> i32;
+
+        pub fn sigaction(signum: i32, act: *const sigaction, oldact: *mut sigaction) -> i32;
+        pub fn mmap(addr: *mut (), len: usize, prot: i32, flags: i32, fd: i32, offset: i64) -> *mut ();
+        pub fn mprotect(addr: *mut (), len: usize, prot: i32) -> i32;
+    }
+
+    pub const PROT_READ: i32 = 1;
+    pub const PROT_WRITE: i32 = 2;
+    pub const MAP_PRIVATE: i32 = 0x0002;
+    pub const MAP_ANONYMOUS: i32 = 0x0020;
+    pub const MAP_FAILED: *mut u8 = !0 as *mut u8;
+
+    /// glibc sigaction
+    #[repr(C)]
+    pub struct sigaction {
+        pub sa_sigaction: Option<unsafe extern "C" fn(i32, *mut (), *mut ())>,
+        pub sa_mask: [u32; 32],
+        pub sa_flags: i32,
+        pub sa_restorer: Option<unsafe extern "C" fn()>,
+    }
+
+    pub const SA_SIGINFO: i32 = 0x00000004;
+    pub const SIGSEGV: i32 = 11;
+}
+
+static mut COUNT: u32 = 0;
+static mut STORAGE: *mut u8 = core::ptr::null_mut();
+const PAGE_SIZE: usize = 1 << 15;
+
+fn main() {
+    unsafe {
+        // Register a segfault handler
+        libc::sigaction(
+            libc::SIGSEGV,
+            &libc::sigaction {
+                sa_sigaction: Some(segv_handler),
+                sa_flags: libc::SA_SIGINFO,
+                ..core::mem::zeroed()
+            },
+            core::ptr::null_mut(),
+        );
+
+        STORAGE = libc::mmap(
+            core::ptr::null_mut(),
+            PAGE_SIZE * 2,
+            0,
+            libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
+            -1,
+            0,
+        ).cast();
+        if STORAGE == libc::MAP_FAILED {
+            panic!("error: mmap failed");
+        }
+
+        let p_count = (&mut COUNT) as *mut u32;
+        p_count.write_volatile(0);
+
+        // Trigger segfaults
+        STORAGE.add(0).write_volatile(1);
+        STORAGE.add(PAGE_SIZE).write_volatile(1);
+        STORAGE.add(0).write_volatile(1);
+        STORAGE.add(PAGE_SIZE).write_volatile(1);
+        STORAGE.add(0).write_volatile(1);
+        STORAGE.add(PAGE_SIZE).write_volatile(1);
+        STORAGE.add(0).read_volatile();
+        STORAGE.add(PAGE_SIZE).read_volatile();
+        STORAGE.add(0).read_volatile();
+        STORAGE.add(PAGE_SIZE).read_volatile();
+        STORAGE.add(0).read_volatile();
+        STORAGE.add(PAGE_SIZE).read_volatile();
+        STORAGE.add(0).write_volatile(1);
+        STORAGE.add(PAGE_SIZE).write_volatile(1);
+
+        // The segfault handler should have been called for every `write_volatile` and
+        // `read_volatile` in `STORAGE`. If the compiler ignores volatility, some of these writes
+        // will be combined, causing a different number of segfaults.
+        //
+        // This `p_count` read is done by a volatile read. If the compiler
+        // ignores volatility, the compiler will speculate that `*p_count` is
+        // unchanged and remove this check, failing the test.
+        if p_count.read_volatile() != 14 {
+            panic!("error: segfault count mismatch: {}", p_count.read_volatile());
+        }
+    }
+}
+
+unsafe extern "C" fn segv_handler(_: i32, _: *mut (), _: *mut ()) {
+    let p_count = (&mut COUNT) as *mut u32;
+    p_count.write_volatile(p_count.read_volatile() + 1);
+    let count = p_count.read_volatile();
+
+    // Toggle the protected page so that the handler will be called for
+    // each `write_volatile`
+    libc::mprotect(
+        STORAGE.cast(),
+        PAGE_SIZE,
+        if count % 2 == 1 { libc::PROT_READ | libc::PROT_WRITE } else { 0 },
+    );
+    libc::mprotect(
+        STORAGE.add(PAGE_SIZE).cast(),
+        PAGE_SIZE,
+        if count % 2 == 0 { libc::PROT_READ | libc::PROT_WRITE } else { 0 },
+    );
+}