authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-09-17 21:15:03-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-09-17 21:15:03-07:00
log8e9f2f02d22fe3e2def100fbe5a84d21ed877359
tree62482282123e002b03cddfd03bf7b4ff41d2661d
parentd2e4ad613bc73527a29ea4813024c540d8f6c793
parenta2ba7dd1c2c3b2be88b9d3c30ff2735c87a3d6d3
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #25201 from jacobly0/x86_64-addsat

x86_64: fix strictness edge cases in `+|`

3 files changed, 498 insertions(+), 95 deletions(-)

src/arch/x86_64/CodeGen.zig+148-67
......@@ -7263,10 +7263,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
72637263 .{ ._, ._, .lea, .tmp0p, .mem(.tmp1), ._, ._ },
72647264 .{ ._, .vp_d, .add, .dst0x, .src0x, .src1x, ._ },
72657265 .{ ._, .vp_d, .sra, .tmp2x, .src0x, .ui(31), ._ },
7266 .{ ._, .vp_d, .cmpgt, .tmp3x, .dst0x, .src0x, ._ },
7266 .{ ._, .vp_d, .cmpgt, .tmp3x, .src0x, .dst0x, ._ },
72677267 .{ ._, .vp_, .xor, .tmp2x, .tmp2x, .lea(.tmp0x), ._ },
72687268 .{ ._, .vp_, .xor, .tmp3x, .tmp3x, .src1x, ._ },
7269 .{ ._, .v_ps, .blendv, .dst0x, .tmp2x, .dst0x, .tmp3x },
7269 .{ ._, .v_ps, .blendv, .dst0x, .dst0x, .tmp2x, .tmp3x },
72707270 } },
72717271 }, .{
72727272 .required_features = .{ .sse4_1, null, null, null },
......@@ -7332,10 +7332,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
73327332 .{ ._, ._, .lea, .tmp0p, .mem(.tmp1), ._, ._ },
73337333 .{ ._, .vp_d, .add, .dst0y, .src0y, .src1y, ._ },
73347334 .{ ._, .vp_d, .sra, .tmp2y, .src0y, .ui(31), ._ },
7335 .{ ._, .vp_d, .cmpgt, .tmp3y, .dst0y, .src0y, ._ },
7335 .{ ._, .vp_d, .cmpgt, .tmp3y, .src0y, .dst0y, ._ },
73367336 .{ ._, .vp_, .xor, .tmp2y, .tmp2y, .lea(.tmp0y), ._ },
73377337 .{ ._, .vp_, .xor, .tmp3y, .tmp3y, .src1y, ._ },
7338 .{ ._, .v_ps, .blendv, .dst0y, .tmp2y, .dst0y, .tmp3y },
7338 .{ ._, .v_ps, .blendv, .dst0y, .dst0y, .tmp2y, .tmp3y },
73397339 } },
73407340 }, .{
73417341 .required_features = .{ .avx, null, null, null },
......@@ -7615,10 +7615,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76157615 .{ ._, .vp_, .xor, .tmp2x, .tmp2x, .tmp2x, ._ },
76167616 .{ ._, .vp_q, .add, .dst0x, .src0x, .src1x, ._ },
76177617 .{ ._, .vp_q, .cmpgt, .tmp2x, .tmp2x, .src0x, ._ },
7618 .{ ._, .vp_q, .cmpgt, .tmp3x, .dst0x, .src0x, ._ },
7618 .{ ._, .vp_q, .cmpgt, .tmp3x, .src0x, .dst0x, ._ },
76197619 .{ ._, .vp_, .xor, .tmp2x, .tmp2x, .lea(.tmp0x), ._ },
76207620 .{ ._, .vp_, .xor, .tmp3x, .tmp3x, .src1x, ._ },
7621 .{ ._, .v_pd, .blendv, .dst0x, .tmp2x, .dst0x, .tmp3x },
7621 .{ ._, .v_pd, .blendv, .dst0x, .dst0x, .tmp2x, .tmp3x },
76227622 } },
76237623 }, .{
76247624 .required_features = .{ .sse4_2, null, null, null },
......@@ -7685,10 +7685,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76857685 .{ ._, .vp_, .xor, .tmp2y, .tmp2y, .tmp2y, ._ },
76867686 .{ ._, .vp_q, .add, .dst0y, .src0y, .src1y, ._ },
76877687 .{ ._, .vp_q, .cmpgt, .tmp2y, .tmp2y, .src0y, ._ },
7688 .{ ._, .vp_q, .cmpgt, .tmp3y, .dst0y, .src0y, ._ },
7688 .{ ._, .vp_q, .cmpgt, .tmp3y, .src0y, .dst0y, ._ },
76897689 .{ ._, .vp_, .xor, .tmp2y, .tmp2y, .lea(.tmp0y), ._ },
76907690 .{ ._, .vp_, .xor, .tmp3y, .tmp3y, .src1y, ._ },
7691 .{ ._, .v_pd, .blendv, .dst0y, .tmp2y, .dst0y, .tmp3y },
7691 .{ ._, .v_pd, .blendv, .dst0y, .dst0y, .tmp2y, .tmp3y },
76927692 } },
76937693 }, .{
76947694 .required_features = .{ .avx2, null, null, null },
......@@ -7724,8 +7724,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
77247724 .{ ._, .vp_b, .blendv, .dst0x, .dst0x, .tmp2x, .tmp3x },
77257725 .{ ._, .vp_q, .cmpeq, .tmp3x, .tmp3x, .tmp3x, ._ },
77267726 .{ ._, .vp_, .xor, .tmp2x, .tmp2x, .tmp3x, ._ },
7727 .{ ._, .vp_q, .cmpgt, .tmp3x, .dst0x, .tmp2x, ._ },
7728 .{ ._, .vp_b, .blendv, .dst0x, .dst0x, .tmp2x, .tmp3x },
7727 .{ ._, .vp_q, .cmpgt, .tmp3x, .tmp2x, .dst0x, ._ },
7728 .{ ._, .vp_b, .blendv, .dst0x, .tmp2x, .dst0x, .tmp3x },
77297729 } },
77307730 }, .{
77317731 .required_features = .{ .avx, null, null, null },
......@@ -7761,8 +7761,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
77617761 .{ ._, .vp_b, .blendv, .dst0x, .dst0x, .tmp2x, .tmp3x },
77627762 .{ ._, .vp_q, .cmpeq, .tmp3x, .tmp3x, .tmp3x, ._ },
77637763 .{ ._, .vp_, .xor, .tmp2x, .tmp2x, .tmp3x, ._ },
7764 .{ ._, .vp_q, .cmpgt, .tmp3x, .dst0x, .tmp2x, ._ },
7765 .{ ._, .vp_b, .blendv, .dst0x, .dst0x, .tmp2x, .tmp3x },
7764 .{ ._, .vp_q, .cmpgt, .tmp3x, .tmp2x, .dst0x, ._ },
7765 .{ ._, .vp_b, .blendv, .dst0x, .tmp2x, .dst0x, .tmp3x },
77667766 } },
77677767 }, .{
77687768 .required_features = .{ .sse4_2, null, null, null },
......@@ -7837,8 +7837,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
78377837 .{ ._, .vp_b, .blendv, .dst0y, .dst0y, .tmp2y, .tmp3y },
78387838 .{ ._, .vp_q, .cmpeq, .tmp3y, .tmp3y, .tmp3y, ._ },
78397839 .{ ._, .vp_, .xor, .tmp2y, .tmp2y, .tmp3y, ._ },
7840 .{ ._, .vp_q, .cmpgt, .tmp3y, .dst0y, .tmp2y, ._ },
7841 .{ ._, .vp_b, .blendv, .dst0y, .dst0y, .tmp2y, .tmp3y },
7840 .{ ._, .vp_q, .cmpgt, .tmp3y, .tmp2y, .dst0y, ._ },
7841 .{ ._, .vp_b, .blendv, .dst0y, .tmp2y, .dst0y, .tmp3y },
78427842 } },
78437843 }, .{
78447844 .required_features = .{ .avx2, null, null, null },
......@@ -10714,10 +10714,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1071410714 .{ ._, .v_dqa, .mov, .tmp4y, .memia(.src1y, .tmp0, .add_unaligned_size), ._, ._ },
1071510715 .{ ._, .vp_d, .add, .tmp5y, .tmp3y, .tmp4y, ._ },
1071610716 .{ ._, .vp_d, .sra, .tmp6y, .tmp3y, .ui(31), ._ },
10717 .{ ._, .vp_d, .cmpgt, .tmp3y, .tmp5y, .tmp3y, ._ },
10717 .{ ._, .vp_d, .cmpgt, .tmp3y, .tmp3y, .tmp5y, ._ },
1071810718 .{ ._, .vp_, .xor, .tmp6y, .tmp6y, .tmp2y, ._ },
1071910719 .{ ._, .vp_, .xor, .tmp3y, .tmp3y, .tmp4y, ._ },
10720 .{ ._, .v_ps, .blendv, .tmp3y, .tmp6y, .tmp5y, .tmp3y },
10720 .{ ._, .v_ps, .blendv, .tmp3y, .tmp5y, .tmp6y, .tmp3y },
1072110721 .{ ._, .v_dqa, .mov, .memia(.dst0y, .tmp0, .add_unaligned_size), .tmp3y, ._, ._ },
1072210722 .{ ._, ._, .add, .tmp0p, .si(32), ._, ._ },
1072310723 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
......@@ -10755,10 +10755,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1075510755 .{ ._, .v_dqa, .mov, .tmp4x, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
1075610756 .{ ._, .vp_d, .add, .tmp5x, .tmp3x, .tmp4x, ._ },
1075710757 .{ ._, .vp_d, .sra, .tmp6x, .tmp3x, .ui(31), ._ },
10758 .{ ._, .vp_d, .cmpgt, .tmp3x, .tmp5x, .tmp3x, ._ },
10758 .{ ._, .vp_d, .cmpgt, .tmp3x, .tmp3x, .tmp5x, ._ },
1075910759 .{ ._, .vp_, .xor, .tmp6x, .tmp6x, .tmp2x, ._ },
1076010760 .{ ._, .vp_, .xor, .tmp3x, .tmp3x, .tmp4x, ._ },
10761 .{ ._, .v_ps, .blendv, .tmp3x, .tmp6x, .tmp5x, .tmp3x },
10761 .{ ._, .v_ps, .blendv, .tmp3x, .tmp5x, .tmp6x, .tmp3x },
1076210762 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp3x, ._, ._ },
1076310763 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
1076410764 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
......@@ -11543,10 +11543,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1154311543 .{ ._, .vp_, .xor, .tmp5y, .tmp5y, .tmp5y, ._ },
1154411544 .{ ._, .vp_q, .add, .tmp6y, .tmp3y, .tmp4y, ._ },
1154511545 .{ ._, .vp_q, .cmpgt, .tmp5y, .tmp5y, .tmp3y, ._ },
11546 .{ ._, .vp_q, .cmpgt, .tmp3y, .tmp6y, .tmp3y, ._ },
11546 .{ ._, .vp_q, .cmpgt, .tmp3y, .tmp3y, .tmp6y, ._ },
1154711547 .{ ._, .vp_, .xor, .tmp5y, .tmp5y, .tmp2y, ._ },
1154811548 .{ ._, .vp_, .xor, .tmp3y, .tmp3y, .tmp4y, ._ },
11549 .{ ._, .v_pd, .blendv, .tmp5y, .tmp5y, .tmp6y, .tmp3y },
11549 .{ ._, .v_pd, .blendv, .tmp5y, .tmp6y, .tmp5y, .tmp3y },
1155011550 .{ ._, .v_dqa, .mov, .memia(.dst0y, .tmp0, .add_unaligned_size), .tmp5y, ._, ._ },
1155111551 .{ ._, ._, .add, .tmp0p, .si(32), ._, ._ },
1155211552 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
......@@ -11585,10 +11585,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1158511585 .{ ._, .vp_, .xor, .tmp5x, .tmp5x, .tmp5x, ._ },
1158611586 .{ ._, .vp_q, .add, .tmp6x, .tmp3x, .tmp4x, ._ },
1158711587 .{ ._, .vp_q, .cmpgt, .tmp5x, .tmp5x, .tmp3x, ._ },
11588 .{ ._, .vp_q, .cmpgt, .tmp3x, .tmp6x, .tmp3x, ._ },
11588 .{ ._, .vp_q, .cmpgt, .tmp3x, .tmp3x, .tmp6x, ._ },
1158911589 .{ ._, .vp_, .xor, .tmp5x, .tmp5x, .tmp2x, ._ },
1159011590 .{ ._, .vp_, .xor, .tmp3x, .tmp3x, .tmp4x, ._ },
11591 .{ ._, .v_pd, .blendv, .tmp5x, .tmp5x, .tmp6x, .tmp3x },
11591 .{ ._, .v_pd, .blendv, .tmp5x, .tmp6x, .tmp5x, .tmp3x },
1159211592 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp5x, ._, ._ },
1159311593 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
1159411594 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
......@@ -11607,11 +11607,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1160711607 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
1160811608 .{ .type = .i64, .kind = .{ .smax_mem = .{ .ref = .src0, .vectorize_to = .none } } },
1160911609 .{ .type = .vector_2_i64, .kind = .{ .rc = .sse } },
11610 .{ .type = .vector_2_i64, .kind = .{ .reg = .xmm0 } },
1161011611 .{ .type = .vector_2_i64, .kind = .{ .rc = .sse } },
1161111612 .{ .type = .vector_2_i64, .kind = .{ .rc = .sse } },
1161211613 .{ .type = .vector_2_i64, .kind = .{ .rc = .sse } },
11613 .{ .type = .vector_2_i64, .kind = .{ .rc = .sse } },
11614 .{ .type = .vector_2_i64, .kind = .{ .reg = .xmm0 } },
11614 .unused,
1161511615 .unused,
1161611616 .unused,
1161711617 .unused,
......@@ -11628,12 +11628,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1162811628 .{ ._, ._dqa, .mov, .tmp6x, .tmp3x, ._, ._ },
1162911629 .{ ._, .p_q, .add, .tmp6x, .tmp4x, ._, ._ },
1163011630 .{ ._, .p_q, .cmpgt, .tmp5x, .tmp3x, ._, ._ },
11631 .{ ._, ._dqa, .mov, .tmp7x, .tmp6x, ._, ._ },
11632 .{ ._, .p_q, .cmpgt, .tmp7x, .tmp3x, ._, ._ },
11631 .{ ._, .p_q, .cmpgt, .tmp3x, .tmp6x, ._, ._ },
1163311632 .{ ._, .p_, .xor, .tmp5x, .tmp2x, ._, ._ },
11634 .{ ._, .p_, .xor, .tmp7x, .tmp4x, ._, ._ },
11635 .{ ._, ._pd, .blendv, .tmp5x, .tmp6x, .tmp7x, ._ },
11636 .{ ._, ._dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp5x, ._, ._ },
11633 .{ ._, .p_, .xor, .tmp3x, .tmp4x, ._, ._ },
11634 .{ ._, ._pd, .blendv, .tmp6x, .tmp5x, .tmp3x, ._ },
11635 .{ ._, ._dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp6x, ._, ._ },
1163711636 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
1163811637 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
1163911638 } },
......@@ -22284,8 +22283,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2228422283 .{ ._, .vp_w, .movsxb, .dst0y, .src0x, ._, ._ },
2228522284 .{ ._, .vp_w, .movsxb, .tmp0y, .src1x, ._, ._ },
2228622285 .{ ._, .vp_w, .mull, .dst0y, .dst0y, .tmp0y, ._ },
22287 .{ ._, .vp_b, .ackssw, .dst0y, .dst0y, .dst0y, ._ },
22288 .{ ._, .v_q, .perm, .dst0y, .dst0y, .ui(0b10_00_10_00), ._ },
22286 .{ ._, .v_i128, .extract, .tmp0x, .dst0y, .ui(1), ._ },
22287 .{ ._, .vp_b, .ackssw, .dst0x, .dst0x, .tmp0x, ._ },
2228922288 } },
2229022289 }, .{
2229122290 .required_features = .{ .avx, null, null, null },
......@@ -22415,8 +22414,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2241522414 .{ ._, .vp_w, .movzxb, .dst0y, .src0x, ._, ._ },
2241622415 .{ ._, .vp_w, .movzxb, .tmp0y, .src1x, ._, ._ },
2241722416 .{ ._, .vp_w, .mull, .dst0y, .dst0y, .tmp0y, ._ },
22418 .{ ._, .vp_b, .ackusw, .dst0y, .dst0y, .dst0y, ._ },
22419 .{ ._, .v_q, .perm, .dst0y, .dst0y, .ui(0b10_00_10_00), ._ },
22417 .{ ._, .v_i128, .extract, .tmp0x, .dst0y, .ui(1), ._ },
22418 .{ ._, .vp_b, .ackusw, .dst0x, .dst0x, .tmp0x, ._ },
2242022419 } },
2242122420 }, .{
2242222421 .required_features = .{ .avx2, null, null, null },
......@@ -22448,8 +22447,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2244822447 .{ .@"0:", .vp_w, .movsxb, .tmp1y, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
2244922448 .{ ._, .vp_w, .movsxb, .tmp2y, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
2245022449 .{ ._, .vp_w, .mull, .tmp1y, .tmp1y, .tmp2y, ._ },
22451 .{ ._, .vp_b, .ackssw, .tmp1y, .tmp1y, .tmp1y, ._ },
22452 .{ ._, .v_q, .perm, .tmp1y, .tmp1y, .ui(0b10_00_10_00), ._ },
22450 .{ ._, .v_i128, .extract, .tmp2x, .tmp1y, .ui(1), ._ },
22451 .{ ._, .vp_b, .ackssw, .tmp1x, .tmp1x, .tmp2x, ._ },
2245322452 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
2245422453 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
2245522454 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
......@@ -22660,8 +22659,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2266022659 .{ .@"0:", .vp_w, .movzxb, .tmp1y, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
2266122660 .{ ._, .vp_w, .movzxb, .tmp2y, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
2266222661 .{ ._, .vp_w, .mull, .tmp1y, .tmp1y, .tmp2y, ._ },
22663 .{ ._, .vp_b, .ackusw, .tmp1y, .tmp1y, .tmp1y, ._ },
22664 .{ ._, .v_q, .perm, .tmp1y, .tmp1y, .ui(0b10_00_10_00), ._ },
22662 .{ ._, .v_i128, .extract, .tmp2x, .tmp1y, .ui(1), ._ },
22663 .{ ._, .vp_b, .ackusw, .tmp1x, .tmp1x, .tmp2x, ._ },
2266522664 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
2266622665 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
2266722666 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
......@@ -82560,7 +82559,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8256082559 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
8256182560 .{ .type = .u16, .kind = .{ .rc = .general_purpose } },
8256282561 .{ .kind = .{ .rc = .sse } },
82563 .unused,
82562 .{ .kind = .{ .rc = .sse } },
8256482563 .unused,
8256582564 .unused,
8256682565 .unused,
......@@ -82577,8 +82576,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8257782576 .{ ._, ._, .xor, .tmp1d, .tmp1d, ._, ._ },
8257882577 .{ .@"0:", .v_dqu, .mov, .tmp3y, .memia(.src0y, .tmp0, .add_size), ._, ._ },
8257982578 .{ ._, .vp_w, .cmpeq, .tmp3y, .tmp3y, .memia(.src1y, .tmp0, .add_size), ._ },
82580 .{ ._, .vp_b, .ackssw, .tmp3y, .tmp3y, .tmp3y, ._ },
82581 .{ ._, .vp_b, .movmsk, .tmp2d, .tmp3y, ._, ._ },
82579 .{ ._, .v_i128, .extract, .tmp4x, .tmp3y, .ui(1), ._ },
82580 .{ ._, .vp_b, .ackssw, .tmp3x, .tmp3x, .tmp4x, ._ },
82581 .{ ._, .vp_b, .movmsk, .tmp2d, .tmp3x, ._, ._ },
8258282582 .{ ._, ._, .mov, .memi(.dst0w, .tmp1), .tmp2w, ._, ._ },
8258382583 .{ ._, ._, .lea, .tmp1d, .lead(.tmp1, 2), ._, ._ },
8258482584 .{ ._, ._, .add, .tmp0p, .si(32), ._, ._ },
......@@ -82589,8 +82589,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8258982589 .{ ._, ._, .xor, .tmp1d, .tmp1d, ._, ._ },
8259082590 .{ .@"0:", .v_dqu, .mov, .tmp3y, .memia(.src0y, .tmp0, .add_size), ._, ._ },
8259182591 .{ ._, .vp_w, .cmpeq, .tmp3y, .tmp3y, .memia(.src1y, .tmp0, .add_size), ._ },
82592 .{ ._, .vp_b, .ackssw, .tmp3y, .tmp3y, .tmp3y, ._ },
82593 .{ ._, .vp_b, .movmsk, .tmp2d, .tmp3y, ._, ._ },
82592 .{ ._, .v_i128, .extract, .tmp4x, .tmp3y, .ui(1), ._ },
82593 .{ ._, .vp_b, .ackssw, .tmp3x, .tmp3x, .tmp4x, ._ },
82594 .{ ._, .vp_b, .movmsk, .tmp2d, .tmp3x, ._, ._ },
8259482595 .{ ._, ._, .not, .tmp2d, ._, ._, ._ },
8259582596 .{ ._, ._, .mov, .memi(.dst0w, .tmp1), .tmp2w, ._, ._ },
8259682597 .{ ._, ._, .lea, .tmp1d, .lead(.tmp1, 2), ._, ._ },
......@@ -90325,7 +90326,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9032590326 }, .{
9032690327 .required_features = .{ .avx, null, null, null },
9032790328 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .word } }, .any, .any },
90328 .dst_constraints = .{ .{ .scalar_int = .{ .of = .qword, .is = .byte } }, .any },
90329 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .qword, .is = .byte } }, .any },
9032990330 .patterns = &.{
9033090331 .{ .src = .{ .to_sse, .none, .none } },
9033190332 },
......@@ -90347,7 +90348,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9034790348 }, .{
9034890349 .required_features = .{ .sse2, null, null, null },
9034990350 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .word } }, .any, .any },
90350 .dst_constraints = .{ .{ .scalar_int = .{ .of = .qword, .is = .byte } }, .any },
90351 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .qword, .is = .byte } }, .any },
9035190352 .patterns = &.{
9035290353 .{ .src = .{ .to_mut_sse, .none, .none } },
9035390354 },
......@@ -90362,20 +90363,46 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9036290363 .patterns = &.{
9036390364 .{ .src = .{ .to_sse, .none, .none } },
9036490365 },
90365 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },
90366 .dst_temps = .{ .{ .rc = .sse }, .unused },
90367 .each = .{ .once = &.{
90368 .{ ._, .v_i128, .extract, .dst0x, .src0y, .ui(1), ._ },
90369 .{ ._, .vp_b, .ackssw, .dst0x, .src0x, .dst0x, ._ },
90370 } },
90371 }, .{
90372 .required_features = .{ .avx, null, null, null },
90373 .src_constraints = .{ .{ .scalar_int = .{ .of = .yword, .is = .word } }, .any, .any },
90374 .dst_constraints = .{ .{ .scalar_signed_int = .{ .of = .xword, .is = .byte } }, .any },
90375 .patterns = &.{
90376 .{ .src = .{ .to_sse, .none, .none } },
90377 },
90378 .dst_temps = .{ .{ .rc = .sse }, .unused },
9036690379 .each = .{ .once = &.{
90367 .{ ._, .vp_b, .ackssw, .dst0y, .src0y, .dst0y, ._ },
90380 .{ ._, .v_f128, .extract, .dst0x, .src0y, .ui(1), ._ },
90381 .{ ._, .vp_b, .ackssw, .dst0x, .src0x, .dst0x, ._ },
9036890382 } },
9036990383 }, .{
9037090384 .required_features = .{ .avx2, null, null, null },
9037190385 .src_constraints = .{ .{ .scalar_int = .{ .of = .yword, .is = .word } }, .any, .any },
90372 .dst_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .byte } }, .any },
90386 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .xword, .is = .byte } }, .any },
9037390387 .patterns = &.{
9037490388 .{ .src = .{ .to_sse, .none, .none } },
9037590389 },
90376 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },
90390 .dst_temps = .{ .{ .rc = .sse }, .unused },
90391 .each = .{ .once = &.{
90392 .{ ._, .v_i128, .extract, .dst0x, .src0y, .ui(1), ._ },
90393 .{ ._, .vp_b, .ackusw, .dst0x, .src0x, .dst0x, ._ },
90394 } },
90395 }, .{
90396 .required_features = .{ .avx, null, null, null },
90397 .src_constraints = .{ .{ .scalar_int = .{ .of = .yword, .is = .word } }, .any, .any },
90398 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .xword, .is = .byte } }, .any },
90399 .patterns = &.{
90400 .{ .src = .{ .to_sse, .none, .none } },
90401 },
90402 .dst_temps = .{ .{ .rc = .sse }, .unused },
9037790403 .each = .{ .once = &.{
90378 .{ ._, .vp_b, .ackusw, .dst0y, .src0y, .dst0y, ._ },
90404 .{ ._, .v_f128, .extract, .dst0x, .src0y, .ui(1), ._ },
90405 .{ ._, .vp_b, .ackusw, .dst0x, .src0x, .dst0x, ._ },
9037990406 } },
9038090407 }, .{
9038190408 .required_features = .{ .slow_incdec, null, null, null },
......@@ -90449,7 +90476,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9044990476 }, .{
9045090477 .required_features = .{ .avx, null, null, null },
9045190478 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .dword } }, .any, .any },
90452 .dst_constraints = .{ .{ .scalar_int = .{ .of = .dword, .is = .byte } }, .any },
90479 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .dword, .is = .byte } }, .any },
9045390480 .patterns = &.{
9045490481 .{ .src = .{ .to_sse, .none, .none } },
9045590482 },
......@@ -90473,7 +90500,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9047390500 }, .{
9047490501 .required_features = .{ .sse4_1, null, null, null },
9047590502 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .dword } }, .any, .any },
90476 .dst_constraints = .{ .{ .scalar_int = .{ .of = .dword, .is = .byte } }, .any },
90503 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .dword, .is = .byte } }, .any },
9047790504 .patterns = &.{
9047890505 .{ .src = .{ .to_mut_sse, .none, .none } },
9047990506 },
......@@ -90489,22 +90516,50 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9048990516 .patterns = &.{
9049090517 .{ .src = .{ .to_sse, .none, .none } },
9049190518 },
90492 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },
90519 .dst_temps = .{ .{ .rc = .sse }, .unused },
9049390520 .each = .{ .once = &.{
90494 .{ ._, .vp_w, .ackssd, .dst0y, .src0y, .dst0y, ._ },
90495 .{ ._, .vp_b, .ackssw, .dst0y, .dst0y, .dst0y, ._ },
90521 .{ ._, .v_i128, .extract, .dst0x, .src0y, .ui(1), ._ },
90522 .{ ._, .vp_w, .ackssd, .dst0x, .src0x, .dst0x, ._ },
90523 .{ ._, .vp_b, .ackssw, .dst0x, .dst0x, .dst0x, ._ },
90524 } },
90525 }, .{
90526 .required_features = .{ .avx, null, null, null },
90527 .src_constraints = .{ .{ .scalar_int = .{ .of = .yword, .is = .dword } }, .any, .any },
90528 .dst_constraints = .{ .{ .scalar_signed_int = .{ .of = .qword, .is = .byte } }, .any },
90529 .patterns = &.{
90530 .{ .src = .{ .to_sse, .none, .none } },
90531 },
90532 .dst_temps = .{ .{ .rc = .sse }, .unused },
90533 .each = .{ .once = &.{
90534 .{ ._, .v_f128, .extract, .dst0x, .src0y, .ui(1), ._ },
90535 .{ ._, .vp_w, .ackssd, .dst0x, .src0x, .dst0x, ._ },
90536 .{ ._, .vp_b, .ackssw, .dst0x, .dst0x, .dst0x, ._ },
9049690537 } },
9049790538 }, .{
9049890539 .required_features = .{ .avx2, null, null, null },
9049990540 .src_constraints = .{ .{ .scalar_int = .{ .of = .yword, .is = .dword } }, .any, .any },
90500 .dst_constraints = .{ .{ .scalar_int = .{ .of = .qword, .is = .byte } }, .any },
90541 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .qword, .is = .byte } }, .any },
9050190542 .patterns = &.{
9050290543 .{ .src = .{ .to_sse, .none, .none } },
9050390544 },
90504 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },
90545 .dst_temps = .{ .{ .rc = .sse }, .unused },
9050590546 .each = .{ .once = &.{
90506 .{ ._, .vp_w, .ackusd, .dst0y, .src0y, .dst0y, ._ },
90507 .{ ._, .vp_b, .ackusw, .dst0y, .dst0y, .dst0y, ._ },
90547 .{ ._, .v_i128, .extract, .dst0x, .src0y, .ui(1), ._ },
90548 .{ ._, .vp_w, .ackusd, .dst0x, .src0x, .dst0x, ._ },
90549 .{ ._, .vp_b, .ackusw, .dst0x, .dst0x, .dst0x, ._ },
90550 } },
90551 }, .{
90552 .required_features = .{ .avx, null, null, null },
90553 .src_constraints = .{ .{ .scalar_int = .{ .of = .yword, .is = .dword } }, .any, .any },
90554 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .qword, .is = .byte } }, .any },
90555 .patterns = &.{
90556 .{ .src = .{ .to_sse, .none, .none } },
90557 },
90558 .dst_temps = .{ .{ .rc = .sse }, .unused },
90559 .each = .{ .once = &.{
90560 .{ ._, .v_f128, .extract, .dst0x, .src0y, .ui(1), ._ },
90561 .{ ._, .vp_w, .ackusd, .dst0x, .src0x, .dst0x, ._ },
90562 .{ ._, .vp_b, .ackusw, .dst0x, .dst0x, .dst0x, ._ },
9050890563 } },
9050990564 }, .{
9051090565 .required_features = .{ .slow_incdec, null, null, null },
......@@ -90723,7 +90778,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9072390778 }, .{
9072490779 .required_features = .{ .avx, null, null, null },
9072590780 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .dword } }, .any, .any },
90726 .dst_constraints = .{ .{ .scalar_int = .{ .of = .qword, .is = .word } }, .any },
90781 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .qword, .is = .word } }, .any },
9072790782 .patterns = &.{
9072890783 .{ .src = .{ .to_sse, .none, .none } },
9072990784 },
......@@ -90745,7 +90800,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9074590800 }, .{
9074690801 .required_features = .{ .sse4_1, null, null, null },
9074790802 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .dword } }, .any, .any },
90748 .dst_constraints = .{ .{ .scalar_int = .{ .of = .qword, .is = .word } }, .any },
90803 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .qword, .is = .word } }, .any },
9074990804 .patterns = &.{
9075090805 .{ .src = .{ .to_mut_sse, .none, .none } },
9075190806 },
......@@ -90760,20 +90815,46 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9076090815 .patterns = &.{
9076190816 .{ .src = .{ .to_sse, .none, .none } },
9076290817 },
90763 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },
90818 .dst_temps = .{ .{ .rc = .sse }, .unused },
90819 .each = .{ .once = &.{
90820 .{ ._, .v_i128, .extract, .dst0x, .src0y, .ui(1), ._ },
90821 .{ ._, .vp_w, .ackssd, .dst0x, .src0x, .dst0x, ._ },
90822 } },
90823 }, .{
90824 .required_features = .{ .avx, null, null, null },
90825 .src_constraints = .{ .{ .scalar_int = .{ .of = .yword, .is = .dword } }, .any, .any },
90826 .dst_constraints = .{ .{ .scalar_signed_int = .{ .of = .xword, .is = .word } }, .any },
90827 .patterns = &.{
90828 .{ .src = .{ .to_sse, .none, .none } },
90829 },
90830 .dst_temps = .{ .{ .rc = .sse }, .unused },
9076490831 .each = .{ .once = &.{
90765 .{ ._, .vp_w, .ackssd, .dst0y, .src0y, .dst0y, ._ },
90832 .{ ._, .v_f128, .extract, .dst0x, .src0y, .ui(1), ._ },
90833 .{ ._, .vp_w, .ackssd, .dst0x, .src0x, .dst0x, ._ },
9076690834 } },
9076790835 }, .{
9076890836 .required_features = .{ .avx2, null, null, null },
9076990837 .src_constraints = .{ .{ .scalar_int = .{ .of = .yword, .is = .dword } }, .any, .any },
90770 .dst_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .word } }, .any },
90838 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .xword, .is = .word } }, .any },
9077190839 .patterns = &.{
9077290840 .{ .src = .{ .to_sse, .none, .none } },
9077390841 },
90774 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },
90842 .dst_temps = .{ .{ .rc = .sse }, .unused },
9077590843 .each = .{ .once = &.{
90776 .{ ._, .vp_w, .ackusd, .dst0y, .src0y, .dst0y, ._ },
90844 .{ ._, .v_i128, .extract, .dst0x, .src0y, .ui(1), ._ },
90845 .{ ._, .vp_w, .ackusd, .dst0x, .src0x, .dst0x, ._ },
90846 } },
90847 }, .{
90848 .required_features = .{ .avx, null, null, null },
90849 .src_constraints = .{ .{ .scalar_int = .{ .of = .yword, .is = .dword } }, .any, .any },
90850 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .xword, .is = .word } }, .any },
90851 .patterns = &.{
90852 .{ .src = .{ .to_sse, .none, .none } },
90853 },
90854 .dst_temps = .{ .{ .rc = .sse }, .unused },
90855 .each = .{ .once = &.{
90856 .{ ._, .v_f128, .extract, .dst0x, .src0y, .ui(1), ._ },
90857 .{ ._, .vp_w, .ackusd, .dst0x, .src0x, .dst0x, ._ },
9077790858 } },
9077890859 }, .{
9077990860 .src_constraints = .{ .{ .multiple_scalar_int = .{ .of = .dword, .is = .dword } }, .any, .any },
......@@ -92414,7 +92495,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9241492495 .clobbers = .{ .eflags = true },
9241592496 .each = .{ .once = &.{
9241692497 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
92417 .{ .@"0:", .vp_d, .movzxb, .tmp1y, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
92498 .{ .@"0:", .vp_d, .movzxb, .tmp1y, .memia(.src0q, .tmp0, .add_unaligned_size), ._, ._ },
9241892499 .{ ._, .v_dqa, .mov, .memsia(.dst0y, .@"4", .tmp0, .add_unaligned_size), .tmp1y, ._, ._ },
9241992500 .{ ._, ._, .add, .tmp0p, .si(8), ._, ._ },
9242092501 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
......@@ -165240,7 +165321,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
165240165321 .dst_temps = .{ .mem, .unused },
165241165322 .each = .{ .once = &.{
165242165323 .{ ._, ._, .mov, .tmp0d, .sia(-16, .dst0, .add_size), ._, ._ },
165243 .{ ._, .v_ps, .shuf, .tmp1x, .tmp1x, .src0x, .ui(0b00_00_00_00) },
165324 .{ ._, .v_ps, .shuf, .tmp1x, .src0x, .src0x, .ui(0b00_00_00_00) },
165244165325 .{ .@"0:", .v_ps, .mova, .memi(.dst0x, .tmp0), .tmp1x, ._, ._ },
165245165326 .{ ._, ._, .sub, .tmp0d, .si(16), ._, ._ },
165246165327 .{ ._, ._nb, .j, .@"0b", ._, ._, ._ },
test/behavior/cast.zig+206-20
......@@ -607,26 +607,212 @@ test "@intCast on vector" {
607607
608608 const S = struct {
609609 fn doTheTest() !void {
610 // Upcast (implicit, equivalent to @intCast)
611 var up0: @Vector(2, u8) = [_]u8{ 0x55, 0xaa };
612 _ = &up0;
613 const up1: @Vector(2, u16) = up0;
614 const up2: @Vector(2, u32) = up0;
615 const up3: @Vector(2, u64) = up0;
616 // Downcast (safety-checked)
617 var down0 = up3;
618 _ = &down0;
619 const down1: @Vector(2, u32) = @intCast(down0);
620 const down2: @Vector(2, u16) = @intCast(down0);
621 const down3: @Vector(2, u8) = @intCast(down0);
622
623 try expect(mem.eql(u16, &@as([2]u16, up1), &[2]u16{ 0x55, 0xaa }));
624 try expect(mem.eql(u32, &@as([2]u32, up2), &[2]u32{ 0x55, 0xaa }));
625 try expect(mem.eql(u64, &@as([2]u64, up3), &[2]u64{ 0x55, 0xaa }));
626
627 try expect(mem.eql(u32, &@as([2]u32, down1), &[2]u32{ 0x55, 0xaa }));
628 try expect(mem.eql(u16, &@as([2]u16, down2), &[2]u16{ 0x55, 0xaa }));
629 try expect(mem.eql(u8, &@as([2]u8, down3), &[2]u8{ 0x55, 0xaa }));
610 {
611 // Upcast (implicit, equivalent to @intCast)
612 var up0: @Vector(2, u8) = .{ 0x55, 0xaa };
613 _ = &up0;
614 const up1: @Vector(2, u16) = up0;
615 const up2: @Vector(2, u32) = up0;
616 const up3: @Vector(2, u64) = up0;
617
618 try expect(mem.eql(u16, &@as([2]u16, up1), &[2]u16{ 0x55, 0xaa }));
619 try expect(mem.eql(u32, &@as([2]u32, up2), &[2]u32{ 0x55, 0xaa }));
620 try expect(mem.eql(u64, &@as([2]u64, up3), &[2]u64{ 0x55, 0xaa }));
621
622 {
623 // Downcast (safety-checked)
624 const down2: @Vector(2, u32) = @intCast(up3);
625 const down1: @Vector(2, u16) = @intCast(up3);
626 const down0: @Vector(2, u8) = @intCast(up3);
627
628 try expect(mem.eql(u32, &@as([2]u32, down2), &[2]u32{ 0x55, 0xaa }));
629 try expect(mem.eql(u16, &@as([2]u16, down1), &[2]u16{ 0x55, 0xaa }));
630 try expect(mem.eql(u8, &@as([2]u8, down0), &[2]u8{ 0x55, 0xaa }));
631 }
632
633 {
634 // Downcast (safety-checked)
635 const down1: @Vector(2, u16) = @intCast(up2);
636 const down0: @Vector(2, u8) = @intCast(up2);
637
638 try expect(mem.eql(u16, &@as([2]u16, down1), &[2]u16{ 0x55, 0xaa }));
639 try expect(mem.eql(u8, &@as([2]u8, down0), &[2]u8{ 0x55, 0xaa }));
640 }
641
642 {
643 // Downcast (safety-checked)
644 const down0: @Vector(2, u8) = @intCast(up1);
645
646 try expect(mem.eql(u8, &@as([2]u8, down0), &[2]u8{ 0x55, 0xaa }));
647 }
648 }
649 {
650 // Upcast (implicit, equivalent to @intCast)
651 var up0: @Vector(4, u8) = .{ 0x00, 0x55, 0xaa, 0xff };
652 _ = &up0;
653 const up1: @Vector(4, u16) = up0;
654 const up2: @Vector(4, u32) = up0;
655 const up3: @Vector(4, u64) = up0;
656
657 try expect(mem.eql(u16, &@as([4]u16, up1), &[4]u16{ 0x00, 0x55, 0xaa, 0xff }));
658 try expect(mem.eql(u32, &@as([4]u32, up2), &[4]u32{ 0x00, 0x55, 0xaa, 0xff }));
659 try expect(mem.eql(u64, &@as([4]u64, up3), &[4]u64{ 0x00, 0x55, 0xaa, 0xff }));
660
661 {
662 // Downcast (safety-checked)
663 const down2: @Vector(4, u32) = @intCast(up3);
664 const down1: @Vector(4, u16) = @intCast(up3);
665 const down0: @Vector(4, u8) = @intCast(up3);
666
667 try expect(mem.eql(u32, &@as([4]u32, down2), &[4]u32{ 0x00, 0x55, 0xaa, 0xff }));
668 try expect(mem.eql(u16, &@as([4]u16, down1), &[4]u16{ 0x00, 0x55, 0xaa, 0xff }));
669 try expect(mem.eql(u8, &@as([4]u8, down0), &[4]u8{ 0x00, 0x55, 0xaa, 0xff }));
670 }
671
672 {
673 // Downcast (safety-checked)
674 const down1: @Vector(4, u16) = @intCast(up2);
675 const down0: @Vector(4, u8) = @intCast(up2);
676
677 try expect(mem.eql(u16, &@as([4]u16, down1), &[4]u16{ 0x00, 0x55, 0xaa, 0xff }));
678 try expect(mem.eql(u8, &@as([4]u8, down0), &[4]u8{ 0x00, 0x55, 0xaa, 0xff }));
679 }
680
681 {
682 // Downcast (safety-checked)
683 const down0: @Vector(4, u8) = @intCast(up1);
684
685 try expect(mem.eql(u8, &@as([4]u8, down0), &[4]u8{ 0x00, 0x55, 0xaa, 0xff }));
686 }
687 }
688 {
689 // Upcast (implicit, equivalent to @intCast)
690 var up0: @Vector(8, u8) = .{
691 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
692 };
693 _ = &up0;
694 const up1: @Vector(8, u16) = up0;
695 const up2: @Vector(8, u32) = up0;
696 const up3: @Vector(8, u64) = up0;
697
698 try expect(mem.eql(u16, &@as([8]u16, up1), &[8]u16{
699 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
700 }));
701 try expect(mem.eql(u32, &@as([8]u32, up2), &[8]u32{
702 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
703 }));
704 try expect(mem.eql(u64, &@as([8]u64, up3), &[8]u64{
705 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
706 }));
707
708 {
709 // Downcast (safety-checked)
710 const down2: @Vector(8, u32) = @intCast(up3);
711 const down1: @Vector(8, u16) = @intCast(up3);
712 const down0: @Vector(8, u8) = @intCast(up3);
713
714 try expect(mem.eql(u32, &@as([8]u32, down2), &[8]u32{
715 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
716 }));
717 try expect(mem.eql(u16, &@as([8]u16, down1), &[8]u16{
718 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
719 }));
720 try expect(mem.eql(u8, &@as([8]u8, down0), &[8]u8{
721 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
722 }));
723 }
724
725 {
726 // Downcast (safety-checked)
727 const down1: @Vector(8, u16) = @intCast(up2);
728 const down0: @Vector(8, u8) = @intCast(up2);
729
730 try expect(mem.eql(u16, &@as([8]u16, down1), &[8]u16{
731 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
732 }));
733 try expect(mem.eql(u8, &@as([8]u8, down0), &[8]u8{
734 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
735 }));
736 }
737
738 {
739 // Downcast (safety-checked)
740 const down0: @Vector(8, u8) = @intCast(up1);
741
742 try expect(mem.eql(u8, &@as([8]u8, down0), &[8]u8{
743 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
744 }));
745 }
746 }
747 {
748 // Upcast (implicit, equivalent to @intCast)
749 var up0: @Vector(16, u8) = .{
750 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
751 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
752 };
753 _ = &up0;
754 const up1: @Vector(16, u16) = up0;
755 const up2: @Vector(16, u32) = up0;
756 const up3: @Vector(16, u64) = up0;
757
758 try expect(mem.eql(u16, &@as([16]u16, up1), &[16]u16{
759 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
760 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
761 }));
762 try expect(mem.eql(u32, &@as([16]u32, up2), &[16]u32{
763 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
764 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
765 }));
766 try expect(mem.eql(u64, &@as([16]u64, up3), &[16]u64{
767 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
768 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
769 }));
770
771 {
772 // Downcast (safety-checked)
773 const down2: @Vector(16, u32) = @intCast(up3);
774 const down1: @Vector(16, u16) = @intCast(up3);
775 const down0: @Vector(16, u8) = @intCast(up3);
776
777 try expect(mem.eql(u32, &@as([16]u32, down2), &[16]u32{
778 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
779 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
780 }));
781 try expect(mem.eql(u16, &@as([16]u16, down1), &[16]u16{
782 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
783 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
784 }));
785 try expect(mem.eql(u8, &@as([16]u8, down0), &[16]u8{
786 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
787 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
788 }));
789 }
790
791 {
792 // Downcast (safety-checked)
793 const down1: @Vector(16, u16) = @intCast(up2);
794 const down0: @Vector(16, u8) = @intCast(up2);
795
796 try expect(mem.eql(u16, &@as([16]u16, down1), &[16]u16{
797 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
798 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
799 }));
800 try expect(mem.eql(u8, &@as([16]u8, down0), &[16]u8{
801 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
802 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
803 }));
804 }
805
806 {
807 // Downcast (safety-checked)
808 const down0: @Vector(16, u8) = @intCast(up1);
809
810 try expect(mem.eql(u8, &@as([16]u8, down0), &[16]u8{
811 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
812 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
813 }));
814 }
815 }
630816 }
631817 };
632818
test/behavior/vector.zig+144-8
......@@ -970,6 +970,73 @@ test "saturating add" {
970970 const expected = i8x3{ 127, 127, 127 };
971971 try expect(mem.eql(i8, &@as([3]i8, expected), &@as([3]i8, result)));
972972 }
973 try testElemType(i4);
974 try testElemType(u4);
975 try testElemType(i8);
976 try testElemType(u8);
977 try testElemType(i12);
978 try testElemType(u12);
979 try testElemType(i16);
980 try testElemType(u16);
981 try testElemType(i24);
982 try testElemType(u24);
983 try testElemType(i32);
984 try testElemType(u32);
985 try testElemType(i48);
986 try testElemType(u48);
987 try testElemType(i64);
988 try testElemType(u64);
989 }
990 fn testElemType(comptime Elem: type) !void {
991 const min = std.math.minInt(Elem);
992 const max = std.math.maxInt(Elem);
993
994 var v: @Vector(4, Elem) = .{ 0, 1, 0, 1 };
995 v +|= .{ 0, 0, 1, 1 };
996 try expect(v[0] == 0);
997 try expect(v[1] == 1);
998 try expect(v[2] == 1);
999 try expect(v[3] == 2);
1000
1001 v = .{ 0, max, 1, max };
1002 v +|= .{ max, 0, max, 1 };
1003 try expect(v[0] == max);
1004 try expect(v[1] == max);
1005 try expect(v[2] == max);
1006 try expect(v[3] == max);
1007
1008 v = .{ 1, max - 1, max / 2, max };
1009 v +|= .{ max - 1, 1, max / 2, max };
1010 try expect(v[0] == max);
1011 try expect(v[1] == max);
1012 try expect(v[2] == max - 1);
1013 try expect(v[3] == max);
1014
1015 switch (@typeInfo(Elem).int.signedness) {
1016 .signed => {
1017 v = .{ -1, -1, 0, -1 };
1018 v +|= .{ 1, 0, -1, -1 };
1019 try expect(v[0] == 0);
1020 try expect(v[1] == -1);
1021 try expect(v[2] == -1);
1022 try expect(v[3] == -2);
1023
1024 v = .{ 0, min, -1, min };
1025 v +|= .{ min, 0, min, -1 };
1026 try expect(v[0] == min);
1027 try expect(v[1] == min);
1028 try expect(v[2] == min);
1029 try expect(v[3] == min);
1030
1031 v = .{ -1, min + 1, min / 2, min };
1032 v +|= .{ min + 1, -1, min / 2, min };
1033 try expect(v[0] == min);
1034 try expect(v[1] == min);
1035 try expect(v[2] == min);
1036 try expect(v[3] == min);
1037 },
1038 .unsigned => {},
1039 }
9731040 }
9741041 };
9751042 try S.doTheTest();
......@@ -986,14 +1053,83 @@ test "saturating subtraction" {
9861053
9871054 const S = struct {
9881055 fn doTheTest() !void {
989 // Broken out to avoid https://github.com/ziglang/zig/issues/11251
990 const u8x3 = @Vector(3, u8);
991 var lhs = u8x3{ 0, 0, 0 };
992 var rhs = u8x3{ 255, 255, 255 };
993 _ = .{ &lhs, &rhs };
994 const result = lhs -| rhs;
995 const expected = u8x3{ 0, 0, 0 };
996 try expect(mem.eql(u8, &@as([3]u8, expected), &@as([3]u8, result)));
1056 {
1057 // Broken out to avoid https://github.com/ziglang/zig/issues/11251
1058 const u8x3 = @Vector(3, u8);
1059 var lhs = u8x3{ 0, 0, 0 };
1060 var rhs = u8x3{ 255, 255, 255 };
1061 _ = .{ &lhs, &rhs };
1062 const result = lhs -| rhs;
1063 const expected = u8x3{ 0, 0, 0 };
1064 try expect(mem.eql(u8, &@as([3]u8, expected), &@as([3]u8, result)));
1065 }
1066 try testElemType(i4);
1067 try testElemType(u4);
1068 try testElemType(i8);
1069 try testElemType(u8);
1070 try testElemType(i12);
1071 try testElemType(u12);
1072 try testElemType(i16);
1073 try testElemType(u16);
1074 try testElemType(i24);
1075 try testElemType(u24);
1076 try testElemType(i32);
1077 try testElemType(u32);
1078 try testElemType(i48);
1079 try testElemType(u48);
1080 try testElemType(i64);
1081 try testElemType(u64);
1082 }
1083 fn testElemType(comptime Elem: type) !void {
1084 const min = std.math.minInt(Elem);
1085 const max = std.math.maxInt(Elem);
1086
1087 var v: @Vector(4, Elem) = .{ 0, 1, 0, 1 };
1088 v -|= .{ 0, 0, 1, 1 };
1089 try expect(v[0] == 0);
1090 try expect(v[1] == 1);
1091 try expect(v[2] == @max(min, -1));
1092 try expect(v[3] == 0);
1093
1094 v = .{ 0, max, 1, max };
1095 v -|= .{ max, 0, max, 1 };
1096 try expect(v[0] == @min(min + 1, 0));
1097 try expect(v[1] == max);
1098 try expect(v[2] == @min(min + 2, 0));
1099 try expect(v[3] == max - 1);
1100
1101 v = .{ 1, max - 1, max / 2, max };
1102 v -|= .{ max - 1, 1, max / 2, max };
1103 try expect(v[0] == @min(min + 3, 0));
1104 try expect(v[1] == max - 2);
1105 try expect(v[2] == 0);
1106 try expect(v[3] == 0);
1107
1108 switch (@typeInfo(Elem).int.signedness) {
1109 .signed => {
1110 v = .{ -1, -1, 0, -1 };
1111 v -|= .{ -1, 0, 1, 1 };
1112 try expect(v[0] == 0);
1113 try expect(v[1] == -1);
1114 try expect(v[2] == -1);
1115 try expect(v[3] == -2);
1116
1117 v = .{ 0, min, -1, min };
1118 v -|= .{ max, 0, max, 1 };
1119 try expect(v[0] == min + 1);
1120 try expect(v[1] == min);
1121 try expect(v[2] == min);
1122 try expect(v[3] == min);
1123
1124 v = .{ -1, min + 1, min / 2, min };
1125 v -|= .{ max, 1, max / 2, max };
1126 try expect(v[0] == min);
1127 try expect(v[1] == min);
1128 try expect(v[2] == min + 1);
1129 try expect(v[3] == min);
1130 },
1131 .unsigned => {},
1132 }
9971133 }
9981134 };
9991135 try S.doTheTest();