Skip to content

Fix to 128 bit int unaligned loads #684

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 27, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/builder.rs
Original file line number Diff line number Diff line change
@@ -924,7 +924,12 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
// dereference after a drop, for instance.
// FIXME(antoyo): this check that we don't call get_aligned() a second time on a type.
// Ideally, we shouldn't need to do this check.
let aligned_type = if pointee_ty == self.cx.u128_type || pointee_ty == self.cx.i128_type {
// FractalFir: the `align == self.int128_align` check ensures we *do* call `get_aligned` if
// the alignment of a `u128`/`i128` is not the one mandated by the ABI. This ensures we handle
// under-aligned loads correctly.
let aligned_type = if (pointee_ty == self.cx.u128_type || pointee_ty == self.cx.i128_type)
&& align == self.int128_align
{
pointee_ty
} else {
pointee_ty.get_aligned(align.bytes())
10 changes: 9 additions & 1 deletion src/context.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ use std::collections::HashMap;
use gccjit::{
Block, CType, Context, Function, FunctionPtrType, FunctionType, LValue, Location, RValue, Type,
};
use rustc_abi::{HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
use rustc_abi::{Align, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
use rustc_codegen_ssa::base::wants_msvc_seh;
use rustc_codegen_ssa::errors as ssa_errors;
use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, MiscCodegenMethods};
@@ -135,6 +135,9 @@ pub struct CodegenCx<'gcc, 'tcx> {

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

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

let mut cx = Self {
int128_align: tcx
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(tcx.types.i128))
.expect("Can't get the layout of `i128`")
.align
.abi,
const_cache: Default::default(),
codegen_unit,
context,
31 changes: 31 additions & 0 deletions tests/run/packed_u128.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Compiler:
//
// Run-time:
// status: 0

#![feature(no_core)]
#![no_std]
#![no_core]
#![no_main]

extern crate mini_core;
use intrinsics::black_box;
use mini_core::*;
#[repr(packed(1))]
pub struct ScalarInt {
data: u128,
size: u8,
}
#[inline(never)]
#[no_mangle]
fn read_data(a: &ScalarInt) {
black_box(a.data);
}

#[no_mangle]
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
let data =
[black_box(ScalarInt { data: 0, size: 1 }), black_box(ScalarInt { data: 0, size: 1 })];
read_data(&data[1]);
0
}