diff --git a/src/builder.rs b/src/builder.rs
index 4e2163201fd..893a2bc9a23 100644
--- a/src/builder.rs
+++ b/src/builder.rs
@@ -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())
diff --git a/src/context.rs b/src/context.rs
index 10494a4be55..51c2be85d51 100644
--- a/src/context.rs
+++ b/src/context.rs
@@ -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,
diff --git a/tests/run/packed_u128.rs b/tests/run/packed_u128.rs
new file mode 100644
index 00000000000..b7cc6e21023
--- /dev/null
+++ b/tests/run/packed_u128.rs
@@ -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
+}