Skip to content

Commit d80802b

Browse files
authored
Merge pull request #684 from FractalFir/master
Fix to 128 bit int unaligned loads
2 parents 9aec231 + 1afdb55 commit d80802b

File tree

3 files changed

+46
-2
lines changed

3 files changed

+46
-2
lines changed

src/builder.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,12 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
924924
// dereference after a drop, for instance.
925925
// FIXME(antoyo): this check that we don't call get_aligned() a second time on a type.
926926
// Ideally, we shouldn't need to do this check.
927-
let aligned_type = if pointee_ty == self.cx.u128_type || pointee_ty == self.cx.i128_type {
927+
// FractalFir: the `align == self.int128_align` check ensures we *do* call `get_aligned` if
928+
// the alignment of a `u128`/`i128` is not the one mandated by the ABI. This ensures we handle
929+
// under-aligned loads correctly.
930+
let aligned_type = if (pointee_ty == self.cx.u128_type || pointee_ty == self.cx.i128_type)
931+
&& align == self.int128_align
932+
{
928933
pointee_ty
929934
} else {
930935
pointee_ty.get_aligned(align.bytes())

src/context.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::collections::HashMap;
44
use gccjit::{
55
Block, CType, Context, Function, FunctionPtrType, FunctionType, LValue, Location, RValue, Type,
66
};
7-
use rustc_abi::{HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
7+
use rustc_abi::{Align, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
88
use rustc_codegen_ssa::base::wants_msvc_seh;
99
use rustc_codegen_ssa::errors as ssa_errors;
1010
use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, MiscCodegenMethods};
@@ -135,6 +135,9 @@ pub struct CodegenCx<'gcc, 'tcx> {
135135

136136
#[cfg(feature = "master")]
137137
pub cleanup_blocks: RefCell<FxHashSet<Block<'gcc>>>,
138+
/// The alignment of a u128/i128 type.
139+
// We cache this, since it is needed for alignment checks during loads.
140+
pub int128_align: Align,
138141
}
139142

140143
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
@@ -226,6 +229,11 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
226229
}
227230

228231
let mut cx = Self {
232+
int128_align: tcx
233+
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(tcx.types.i128))
234+
.expect("Can't get the layout of `i128`")
235+
.align
236+
.abi,
229237
const_cache: Default::default(),
230238
codegen_unit,
231239
context,

tests/run/packed_u128.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Compiler:
2+
//
3+
// Run-time:
4+
// status: 0
5+
6+
#![feature(no_core)]
7+
#![no_std]
8+
#![no_core]
9+
#![no_main]
10+
11+
extern crate mini_core;
12+
use intrinsics::black_box;
13+
use mini_core::*;
14+
#[repr(packed(1))]
15+
pub struct ScalarInt {
16+
data: u128,
17+
size: u8,
18+
}
19+
#[inline(never)]
20+
#[no_mangle]
21+
fn read_data(a: &ScalarInt) {
22+
black_box(a.data);
23+
}
24+
25+
#[no_mangle]
26+
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
27+
let data =
28+
[black_box(ScalarInt { data: 0, size: 1 }), black_box(ScalarInt { data: 0, size: 1 })];
29+
read_data(&data[1]);
30+
0
31+
}

0 commit comments

Comments
 (0)