Skip to content
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

Wrong alignment on memory loads with non-default alignment #4236

Open
JohanEngelen opened this issue Oct 11, 2022 · 3 comments
Open

Wrong alignment on memory loads with non-default alignment #4236

JohanEngelen opened this issue Oct 11, 2022 · 3 comments

Comments

@JohanEngelen
Copy link
Member

I was very surprised to find this bug, so I hope I am wrong.

Testcase (https://d.godbolt.org/z/aYoM9odTo):

struct S {
    byte i;
    align(1) long data;
}
long foo_s( S* d) { return d.data; }

Is compiled to:

%example.S = type <{ i8, i64 }>

define i64 @_D7example5foo_sFPSQr1SZl(%example.S* %d_arg) #0 !dbg !4 {
  %d = alloca %example.S*, align 8                ; [#uses = 2, size/byte = 8]
  store %example.S* %d_arg, %example.S** %d, align 8, !dbg !7 ; [debug line = app/example.d:6:6]
  %1 = load %example.S*, %example.S** %d, align 8, !dbg !8 ; [#uses = 1] [debug line = app/example.d:6:21]
  %2 = getelementptr inbounds %example.S, %example.S* %1, i32 0, i32 1 ; [#uses = 2, type = i64*]
  %3 = load i64, i64* %2, align 8, !dbg !8        ; [#uses = 0] [debug line = app/example.d:6:21]
  %4 = load i64, i64* %2, align 8, !dbg !8        ; [#uses = 1] [debug line = app/example.d:6:21]
  ret i64 %4, !dbg !8                             ; [debug line = app/example.d:6:21]
}

Note the align 8 on loading d.data, whereas it should be align 1. This works on x86 but may break on CPU architecturers where some instructrions do not support unaligned loads.

@p0nce
Copy link
Contributor

p0nce commented Oct 11, 2022

I don't plan on relying on this :) I think I'll just use void* and mark the functions as @system, will keep compat with copy-pasted code, and some of the other intrinsics are @system as per their signature

@JohanEngelen JohanEngelen changed the title Wrong alignment on memory loads of aggregate fields with non-default alignment Wrong alignment on memory loads with non-default alignment Jan 22, 2023
@JohanEngelen
Copy link
Member Author

JohanEngelen commented Jan 22, 2023

This issue is probably pervasive throughout LDC.

align(1) float float1;
extern(C) auto fooglobalglobal() {
    return float1; // also does not create IR with align(1)
}

For the struct field, the frontend .alignof property is also wrong (https://issues.dlang.org/show_bug.cgi?id=23649)

struct S {
    byte i;
    align(1) long data;
}

void foo( S* d) {
    pragma(msg, d.data.alignof); // prints 8UL
}

@JohanEngelen
Copy link
Member Author

Example lit test:

// RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll

struct S {
    byte i;
    align(1) long data;
}

// CHECK-LABEL: define{{.*}} @foofoofoo
extern(C) long foofoofoo(S *d) {
    // CHECK: load i64, {{i64\*|ptr}} %2, align 1
    return d.data;
// CHECK-LABEL: ret i64
}

align(1) float float1;
// CHECK-LABEL: define{{.*}} @fooglobalglobal
extern(C) auto fooglobalglobal() {
    // CHECK: load float, {{float\*|ptr}} @_D18align_loads_gh42366float1f, align 1
    return float1;
// CHECK-LABEL: ret float
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants