diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 8f3e3917fc0bf0a15dbaa5261dd9dcac9fd4f972..30b7f30feaec4e2d33c844815960064d6aa5f44a 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -31,16 +31,19 @@ const bindings = if (build_options.have_llvm) else @compileError("LLVM unavailable"); -pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features { - return comptime &.initMany(&.{ - .expand_int_from_float_safe, - .expand_int_from_float_optimized_safe, +pub fn legalizeFeatures(target: *const std.Target) ?*const Air.Legalize.Features { + return switch (target.cpu.arch.endian()) { + inline else => |endian| comptime &.init(.{ + .expand_int_from_float_safe = true, + .expand_int_from_float_optimized_safe = true, - .scalarize_bit_cast_array, - // Needed because LLVM's `bitcast` on vectors is endian-specific unless the source and dest - // types are vectors with equal length (hence also with equal bits-per-element). - .scalarize_bit_cast_vector_non_elementwise, - }); + .scalarize_bit_cast_array = true, + // LLVM's `bitcast` on vectors places element 0 in the least significant bits on + // little-endian targets, which matches our semantics; but it does the opposite on + // big-endian targets, so in that case we need to scalarize. + .scalarize_bit_cast_vector_non_elementwise = endian != .little, + }), + }; } fn subArchName(target: *const std.Target, comptime family: std.Target.Cpu.Arch.Family, mappings: anytype) ?[]const u8 {