Skip to content

Building with Drelease-fast=true causes extern C structs to contain garbage #14262

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

Closed
AlxHnr opened this issue Jan 10, 2023 · 3 comments
Closed
Labels
bug Observed behavior contradicts documented or intended behavior

Comments

@AlxHnr
Copy link
Contributor

AlxHnr commented Jan 10, 2023

Zig Version

0.11.0-dev.1253+fcee1bf99

Steps to Reproduce and Observed Behavior

Self-contained testcase can be found here: https://github.com/AlxHnr/zig-compiler-testcase

Building the code with zig build -Drelease-fast=true test causes the tests to fail due to scrambled data. Building without optimizations (zig build test) works just fine.

Here is the offending code which you can find in the repo linked above.

const std = @import("std");

pub const Vector3 = extern struct {
    x: f32,
    y: f32,
    z: f32,
};

pub extern fn Vector3RotateByAxisAngle(v: Vector3, axis: Vector3, angle: f32) Vector3;

test {
    const vector = Vector3{ .x = 12, .y = 9, .z = 3 };
    const up = Vector3{ .x = 0, .y = 1, .z = 0 };
    const result = Vector3RotateByAxisAngle(vector, up, 0.001);

    try std.testing.expectApproxEqRel(@as(f32, 12.0029945), result.x, 0.00001);
    try std.testing.expectApproxEqRel(@as(f32, 9), result.y, 0.00001);
    try std.testing.expectApproxEqRel(@as(f32, 2.98799848), result.z, 0.00001);
}

Expected Behavior

Optimized release builds behave the same as debug builds.

More informations

Platform: Fedora Linux 36

This seems to be a regression of #1481. There it claims the following:

[X] x86_64: struct & union parameters <= 16 bytes which are all floats

@AlxHnr AlxHnr added the bug Observed behavior contradicts documented or intended behavior label Jan 10, 2023
@Vexu Vexu added this to the 0.11.0 milestone Jan 11, 2023
@Vexu
Copy link
Member

Vexu commented Jan 11, 2023

Likely duplicate of #13830

@Vexu Vexu closed this as completed Jan 11, 2023
@Vexu Vexu removed this from the 0.11.0 milestone Jan 11, 2023
@AlxHnr
Copy link
Contributor Author

AlxHnr commented Jan 11, 2023

Can we be sure it is f32 specific? This behavior doesn't occur with larger structs containing 4, 6, 7 or 16 floats. (passed/returned by value from and to the C side).

@Vexu
Copy link
Member

Vexu commented Jan 11, 2023

It's not f32 specific but caused by alignment differences between f32 and f64. The failure only happens on release modes because LLVM sees that we're doing sketchy stuff and goes to town on removing instructions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior
Projects
None yet
Development

No branches or pull requests

2 participants