authorgravatar for xavierb@gmail.comXavier Bouchoux <xavierb@gmail.com> 2023-06-22 06:51:25+00:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-25 18:14:10-07:00
log5ab185460282eedb6e1d673041a4579eaacbc6ad
tree57aeacff851cc445215f6384b0877ea222e60b42
parent71dfce31bb8153300ff24f77ddc52521fe330266

codegen/llvm: fix memset with vectors smaller than one byte

The special case to take advantage of llvm's intrinsic was generating invalid llvm ir: ``` Invalid bitcast %60 = bitcast <2 x i2> %59 to i8, !dbg !3122 thread 145453 panic: LLVM module verification failed ```

2 files changed, 53 insertions(+), 2 deletions(-)

src/codegen/llvm.zig+4-2
......@@ -8637,9 +8637,11 @@ pub const FuncGen = struct {
86378637 return result_ptr;
86388638 }
86398639
8640 if (llvm_dest_ty.isStruct(&o.builder)) {
8640 if (llvm_dest_ty.isStruct(&o.builder) or
8641 ((operand_ty.zigTypeTag(mod) == .Vector or inst_ty.zigTypeTag(mod) == .Vector) and operand_ty.bitSize(mod) != inst_ty.bitSize(mod)))
8642 {
86418643 // Both our operand and our result are values, not pointers,
8642 // but LLVM won't let us bitcast struct values.
8644 // but LLVM won't let us bitcast struct values or vectors with padding bits.
86438645 // Therefore, we store operand to alloca, then load for result.
86448646 const alignment = Builder.Alignment.fromByteUnits(
86458647 @max(operand_ty.abiAlignment(mod), inst_ty.abiAlignment(mod)),
test/behavior/vector.zig+49
......@@ -1324,6 +1324,55 @@ test "store to vector in slice" {
13241324 try expectEqual(v[1], v[0]);
13251325}
13261326
1327test "store vector with memset" {
1328 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1329 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1330 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1331 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1332 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1333 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
1334 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1335
1336 if (builtin.zig_backend == .stage2_llvm) {
1337 switch (builtin.target.cpu.arch) {
1338 .wasm32,
1339 .mips,
1340 .mipsel,
1341 .mips64,
1342 .mips64el,
1343 .riscv64,
1344 .powerpc,
1345 => {
1346 // LLVM 16 ERROR: "Converting bits to bytes lost precision"
1347 // https://github.com/ziglang/zig/issues/16177
1348 return error.SkipZigTest;
1349 },
1350 else => {},
1351 }
1352 }
1353
1354 var a: [5]@Vector(2, i1) = undefined;
1355 var b: [5]@Vector(2, u2) = undefined;
1356 var c: [5]@Vector(2, i4) = undefined;
1357 var d: [5]@Vector(2, u8) = undefined;
1358 var e: [5]@Vector(2, i9) = undefined;
1359 var ka = @Vector(2, i1){ -1, 0 };
1360 var kb = @Vector(2, u2){ 0, 1 };
1361 var kc = @Vector(2, i4){ 2, 3 };
1362 var kd = @Vector(2, u8){ 4, 5 };
1363 var ke = @Vector(2, i9){ 6, 7 };
1364 @memset(&a, ka);
1365 @memset(&b, kb);
1366 @memset(&c, kc);
1367 @memset(&d, kd);
1368 @memset(&e, ke);
1369 try std.testing.expectEqual(ka, a[0]);
1370 try std.testing.expectEqual(kb, b[1]);
1371 try std.testing.expectEqual(kc, c[2]);
1372 try std.testing.expectEqual(kd, d[3]);
1373 try std.testing.expectEqual(ke, e[4]);
1374}
1375
13271376test "addition of vectors represented as strings" {
13281377 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
13291378 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO