diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 87ed52c31b..b030a5cc7e 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -8637,9 +8637,11 @@ pub const FuncGen = struct { return result_ptr; } - if (llvm_dest_ty.isStruct(&o.builder)) { + if (llvm_dest_ty.isStruct(&o.builder) or + ((operand_ty.zigTypeTag(mod) == .Vector or inst_ty.zigTypeTag(mod) == .Vector) and operand_ty.bitSize(mod) != inst_ty.bitSize(mod))) + { // Both our operand and our result are values, not pointers, - // but LLVM won't let us bitcast struct values. + // but LLVM won't let us bitcast struct values or vectors with padding bits. // Therefore, we store operand to alloca, then load for result. const alignment = Builder.Alignment.fromByteUnits( @max(operand_ty.abiAlignment(mod), inst_ty.abiAlignment(mod)), diff --git a/test/behavior/vector.zig b/test/behavior/vector.zig index c838843eb9..ef44db4218 100644 --- a/test/behavior/vector.zig +++ b/test/behavior/vector.zig @@ -1324,6 +1324,55 @@ test "store to vector in slice" { try expectEqual(v[1], v[0]); } +test "store vector with memset" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + + if (builtin.zig_backend == .stage2_llvm) { + switch (builtin.target.cpu.arch) { + .wasm32, + .mips, + .mipsel, + .mips64, + .mips64el, + .riscv64, + .powerpc, + => { + // LLVM 16 ERROR: "Converting bits to bytes lost precision" + // https://github.com/ziglang/zig/issues/16177 + return error.SkipZigTest; + }, + else => {}, + } + } + + var a: [5]@Vector(2, i1) = undefined; + var b: [5]@Vector(2, u2) = undefined; + var c: [5]@Vector(2, i4) = undefined; + var d: [5]@Vector(2, u8) = undefined; + var e: [5]@Vector(2, i9) = undefined; + var ka = @Vector(2, i1){ -1, 0 }; + var kb = @Vector(2, u2){ 0, 1 }; + var kc = @Vector(2, i4){ 2, 3 }; + var kd = @Vector(2, u8){ 4, 5 }; + var ke = @Vector(2, i9){ 6, 7 }; + @memset(&a, ka); + @memset(&b, kb); + @memset(&c, kc); + @memset(&d, kd); + @memset(&e, ke); + try std.testing.expectEqual(ka, a[0]); + try std.testing.expectEqual(kb, b[1]); + try std.testing.expectEqual(kc, c[2]); + try std.testing.expectEqual(kd, d[3]); + try std.testing.expectEqual(ke, e[4]); +} + test "addition of vectors represented as strings" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO