@@ -938,22 +938,29 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
938
938
fn load ( & mut self , pointee_ty : Type < ' gcc > , ptr : RValue < ' gcc > , align : Align ) -> RValue < ' gcc > {
939
939
let block = self . llbb ( ) ;
940
940
let function = block. get_function ( ) ;
941
+ // FractalFir: In some cases, we *should* skip the call to get_aligned.
942
+ // For example, calling `get_aligned` on a i8 is pointless(since it can only be 1 aligned)
943
+ // Calling get_aligned on a `u128`/`i128` leads to issues(TODO: ask Anton what *kind* of issues,
944
+ // describe them in detail).
945
+ // So, we skip the call to `get_aligned` in such a case. *Ideally*, we could do this for all the types,
946
+ // but the GCC APIs to facilitate this just aren't quite there yet.
947
+
948
+ // This checks that we only skip `get_aligned` on 128 bit ints if they have the correct alignment.
949
+ // Otherwise, this may be an under-aligned load, so we will still call get_aligned.
950
+ let mut can_skip_align = ( pointee_ty == self . cx . u128_type
951
+ || pointee_ty == self . cx . i128_type )
952
+ && align == self . int128_align ;
953
+ // We can skip the call to `get_aligned` for byte-sized types with alignment of 1.
954
+ can_skip_align |=
955
+ ( pointee_ty == self . cx . u8_type || pointee_ty == self . cx . i8_type ) && align. bytes ( ) == 1 ;
956
+ // Skip the call to `get_aligned` when possible.
957
+ let aligned_type =
958
+ if can_skip_align { pointee_ty } else { pointee_ty. get_aligned ( align. bytes ( ) ) } ;
959
+
960
+ let ptr = self . context . new_cast ( self . location , ptr, aligned_type. make_pointer ( ) ) ;
941
961
// NOTE: instead of returning the dereference here, we have to assign it to a variable in
942
962
// the current basic block. Otherwise, it could be used in another basic block, causing a
943
963
// dereference after a drop, for instance.
944
- // FIXME(antoyo): this check that we don't call get_aligned() a second time on a type.
945
- // Ideally, we shouldn't need to do this check.
946
- // FractalFir: the `align == self.int128_align` check ensures we *do* call `get_aligned` if
947
- // the alignment of a `u128`/`i128` is not the one mandated by the ABI. This ensures we handle
948
- // under-aligned loads correctly.
949
- let aligned_type = if ( pointee_ty == self . cx . u128_type || pointee_ty == self . cx . i128_type )
950
- && align == self . int128_align
951
- {
952
- pointee_ty
953
- } else {
954
- pointee_ty. get_aligned ( align. bytes ( ) )
955
- } ;
956
- let ptr = self . context . new_cast ( self . location , ptr, aligned_type. make_pointer ( ) ) ;
957
964
let deref = ptr. dereference ( self . location ) . to_rvalue ( ) ;
958
965
let loaded_value = function. new_local (
959
966
self . location ,
0 commit comments