authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-09-10 22:25:55-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-09-10 22:40:26-04:00
loge313b387a039fe4471462db0a63eea9b29c84a96
tree9ba8337cb78f657be61c998ba70e4e26b734f82b
parent1a0a9d7d59b78e5d97142d867bece78fc477e9a7

x86_64: delete usages of avx2 `vpack?s??`

This instruction actually has fairly useless semantics, and even the cases that were semantically correct could save 1 cycle of latency by using a different sequnce involving the avx version instead. Closes #25174

2 files changed, 325 insertions(+), 57 deletions(-)

src/arch/x86_64/CodeGen.zig+119-37
...@@ -22283,8 +22283,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -22283,8 +22283,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
22283 .{ ._, .vp_w, .movsxb, .dst0y, .src0x, ._, ._ },22283 .{ ._, .vp_w, .movsxb, .dst0y, .src0x, ._, ._ },
22284 .{ ._, .vp_w, .movsxb, .tmp0y, .src1x, ._, ._ },22284 .{ ._, .vp_w, .movsxb, .tmp0y, .src1x, ._, ._ },
22285 .{ ._, .vp_w, .mull, .dst0y, .dst0y, .tmp0y, ._ },22285 .{ ._, .vp_w, .mull, .dst0y, .dst0y, .tmp0y, ._ },
22286 .{ ._, .vp_b, .ackssw, .dst0y, .dst0y, .dst0y, ._ },22286 .{ ._, .v_i128, .extract, .tmp0x, .dst0y, .ui(1), ._ },
22287 .{ ._, .v_q, .perm, .dst0y, .dst0y, .ui(0b10_00_10_00), ._ },22287 .{ ._, .vp_b, .ackssw, .dst0x, .dst0x, .tmp0x, ._ },
22288 } },22288 } },
22289 }, .{22289 }, .{
22290 .required_features = .{ .avx, null, null, null },22290 .required_features = .{ .avx, null, null, null },
...@@ -22414,8 +22414,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -22414,8 +22414,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
22414 .{ ._, .vp_w, .movzxb, .dst0y, .src0x, ._, ._ },22414 .{ ._, .vp_w, .movzxb, .dst0y, .src0x, ._, ._ },
22415 .{ ._, .vp_w, .movzxb, .tmp0y, .src1x, ._, ._ },22415 .{ ._, .vp_w, .movzxb, .tmp0y, .src1x, ._, ._ },
22416 .{ ._, .vp_w, .mull, .dst0y, .dst0y, .tmp0y, ._ },22416 .{ ._, .vp_w, .mull, .dst0y, .dst0y, .tmp0y, ._ },
22417 .{ ._, .vp_b, .ackusw, .dst0y, .dst0y, .dst0y, ._ },22417 .{ ._, .v_i128, .extract, .tmp0x, .dst0y, .ui(1), ._ },
22418 .{ ._, .v_q, .perm, .dst0y, .dst0y, .ui(0b10_00_10_00), ._ },22418 .{ ._, .vp_b, .ackusw, .dst0x, .dst0x, .tmp0x, ._ },
22419 } },22419 } },
22420 }, .{22420 }, .{
22421 .required_features = .{ .avx2, null, null, null },22421 .required_features = .{ .avx2, null, null, null },
...@@ -22447,8 +22447,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -22447,8 +22447,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
22447 .{ .@"0:", .vp_w, .movsxb, .tmp1y, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },22447 .{ .@"0:", .vp_w, .movsxb, .tmp1y, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
22448 .{ ._, .vp_w, .movsxb, .tmp2y, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },22448 .{ ._, .vp_w, .movsxb, .tmp2y, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
22449 .{ ._, .vp_w, .mull, .tmp1y, .tmp1y, .tmp2y, ._ },22449 .{ ._, .vp_w, .mull, .tmp1y, .tmp1y, .tmp2y, ._ },
22450 .{ ._, .vp_b, .ackssw, .tmp1y, .tmp1y, .tmp1y, ._ },22450 .{ ._, .v_i128, .extract, .tmp2x, .tmp1y, .ui(1), ._ },
22451 .{ ._, .v_q, .perm, .tmp1y, .tmp1y, .ui(0b10_00_10_00), ._ },22451 .{ ._, .vp_b, .ackssw, .tmp1x, .tmp1x, .tmp2x, ._ },
22452 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },22452 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
22453 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },22453 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
22454 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },22454 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
...@@ -22659,8 +22659,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -22659,8 +22659,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
22659 .{ .@"0:", .vp_w, .movzxb, .tmp1y, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },22659 .{ .@"0:", .vp_w, .movzxb, .tmp1y, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },
22660 .{ ._, .vp_w, .movzxb, .tmp2y, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },22660 .{ ._, .vp_w, .movzxb, .tmp2y, .memia(.src1x, .tmp0, .add_unaligned_size), ._, ._ },
22661 .{ ._, .vp_w, .mull, .tmp1y, .tmp1y, .tmp2y, ._ },22661 .{ ._, .vp_w, .mull, .tmp1y, .tmp1y, .tmp2y, ._ },
22662 .{ ._, .vp_b, .ackusw, .tmp1y, .tmp1y, .tmp1y, ._ },22662 .{ ._, .v_i128, .extract, .tmp2x, .tmp1y, .ui(1), ._ },
22663 .{ ._, .v_q, .perm, .tmp1y, .tmp1y, .ui(0b10_00_10_00), ._ },22663 .{ ._, .vp_b, .ackusw, .tmp1x, .tmp1x, .tmp2x, ._ },
22664 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },22664 .{ ._, .v_dqa, .mov, .memia(.dst0x, .tmp0, .add_unaligned_size), .tmp1x, ._, ._ },
22665 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },22665 .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
22666 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },22666 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
...@@ -82559,7 +82559,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -82559,7 +82559,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
82559 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },82559 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
82560 .{ .type = .u16, .kind = .{ .rc = .general_purpose } },82560 .{ .type = .u16, .kind = .{ .rc = .general_purpose } },
82561 .{ .kind = .{ .rc = .sse } },82561 .{ .kind = .{ .rc = .sse } },
82562 .unused,82562 .{ .kind = .{ .rc = .sse } },
82563 .unused,82563 .unused,
82564 .unused,82564 .unused,
82565 .unused,82565 .unused,
...@@ -82576,8 +82576,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -82576,8 +82576,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
82576 .{ ._, ._, .xor, .tmp1d, .tmp1d, ._, ._ },82576 .{ ._, ._, .xor, .tmp1d, .tmp1d, ._, ._ },
82577 .{ .@"0:", .v_dqu, .mov, .tmp3y, .memia(.src0y, .tmp0, .add_size), ._, ._ },82577 .{ .@"0:", .v_dqu, .mov, .tmp3y, .memia(.src0y, .tmp0, .add_size), ._, ._ },
82578 .{ ._, .vp_w, .cmpeq, .tmp3y, .tmp3y, .memia(.src1y, .tmp0, .add_size), ._ },82578 .{ ._, .vp_w, .cmpeq, .tmp3y, .tmp3y, .memia(.src1y, .tmp0, .add_size), ._ },
82579 .{ ._, .vp_b, .ackssw, .tmp3y, .tmp3y, .tmp3y, ._ },82579 .{ ._, .v_i128, .extract, .tmp4x, .tmp3y, .ui(1), ._ },
82580 .{ ._, .vp_b, .movmsk, .tmp2d, .tmp3y, ._, ._ },82580 .{ ._, .vp_b, .ackssw, .tmp3x, .tmp3x, .tmp4x, ._ },
82581 .{ ._, .vp_b, .movmsk, .tmp2d, .tmp3x, ._, ._ },
82581 .{ ._, ._, .mov, .memi(.dst0w, .tmp1), .tmp2w, ._, ._ },82582 .{ ._, ._, .mov, .memi(.dst0w, .tmp1), .tmp2w, ._, ._ },
82582 .{ ._, ._, .lea, .tmp1d, .lead(.tmp1, 2), ._, ._ },82583 .{ ._, ._, .lea, .tmp1d, .lead(.tmp1, 2), ._, ._ },
82583 .{ ._, ._, .add, .tmp0p, .si(32), ._, ._ },82584 .{ ._, ._, .add, .tmp0p, .si(32), ._, ._ },
...@@ -82588,8 +82589,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -82588,8 +82589,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
82588 .{ ._, ._, .xor, .tmp1d, .tmp1d, ._, ._ },82589 .{ ._, ._, .xor, .tmp1d, .tmp1d, ._, ._ },
82589 .{ .@"0:", .v_dqu, .mov, .tmp3y, .memia(.src0y, .tmp0, .add_size), ._, ._ },82590 .{ .@"0:", .v_dqu, .mov, .tmp3y, .memia(.src0y, .tmp0, .add_size), ._, ._ },
82590 .{ ._, .vp_w, .cmpeq, .tmp3y, .tmp3y, .memia(.src1y, .tmp0, .add_size), ._ },82591 .{ ._, .vp_w, .cmpeq, .tmp3y, .tmp3y, .memia(.src1y, .tmp0, .add_size), ._ },
82591 .{ ._, .vp_b, .ackssw, .tmp3y, .tmp3y, .tmp3y, ._ },82592 .{ ._, .v_i128, .extract, .tmp4x, .tmp3y, .ui(1), ._ },
82592 .{ ._, .vp_b, .movmsk, .tmp2d, .tmp3y, ._, ._ },82593 .{ ._, .vp_b, .ackssw, .tmp3x, .tmp3x, .tmp4x, ._ },
82594 .{ ._, .vp_b, .movmsk, .tmp2d, .tmp3x, ._, ._ },
82593 .{ ._, ._, .not, .tmp2d, ._, ._, ._ },82595 .{ ._, ._, .not, .tmp2d, ._, ._, ._ },
82594 .{ ._, ._, .mov, .memi(.dst0w, .tmp1), .tmp2w, ._, ._ },82596 .{ ._, ._, .mov, .memi(.dst0w, .tmp1), .tmp2w, ._, ._ },
82595 .{ ._, ._, .lea, .tmp1d, .lead(.tmp1, 2), ._, ._ },82597 .{ ._, ._, .lea, .tmp1d, .lead(.tmp1, 2), ._, ._ },
...@@ -90324,7 +90326,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -90324,7 +90326,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
90324 }, .{90326 }, .{
90325 .required_features = .{ .avx, null, null, null },90327 .required_features = .{ .avx, null, null, null },
90326 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .word } }, .any, .any },90328 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .word } }, .any, .any },
90327 .dst_constraints = .{ .{ .scalar_int = .{ .of = .qword, .is = .byte } }, .any },90329 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .qword, .is = .byte } }, .any },
90328 .patterns = &.{90330 .patterns = &.{
90329 .{ .src = .{ .to_sse, .none, .none } },90331 .{ .src = .{ .to_sse, .none, .none } },
90330 },90332 },
...@@ -90346,7 +90348,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -90346,7 +90348,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
90346 }, .{90348 }, .{
90347 .required_features = .{ .sse2, null, null, null },90349 .required_features = .{ .sse2, null, null, null },
90348 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .word } }, .any, .any },90350 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .word } }, .any, .any },
90349 .dst_constraints = .{ .{ .scalar_int = .{ .of = .qword, .is = .byte } }, .any },90351 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .qword, .is = .byte } }, .any },
90350 .patterns = &.{90352 .patterns = &.{
90351 .{ .src = .{ .to_mut_sse, .none, .none } },90353 .{ .src = .{ .to_mut_sse, .none, .none } },
90352 },90354 },
...@@ -90361,20 +90363,46 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -90361,20 +90363,46 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
90361 .patterns = &.{90363 .patterns = &.{
90362 .{ .src = .{ .to_sse, .none, .none } },90364 .{ .src = .{ .to_sse, .none, .none } },
90363 },90365 },
90364 .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 },
90365 .each = .{ .once = &.{90379 .each = .{ .once = &.{
90366 .{ ._, .vp_b, .ackssw, .dst0y, .src0y, .dst0y, ._ },90380 .{ ._, .v_f128, .extract, .dst0x, .src0y, .ui(1), ._ },
90381 .{ ._, .vp_b, .ackssw, .dst0x, .src0x, .dst0x, ._ },
90367 } },90382 } },
90368 }, .{90383 }, .{
90369 .required_features = .{ .avx2, null, null, null },90384 .required_features = .{ .avx2, null, null, null },
90370 .src_constraints = .{ .{ .scalar_int = .{ .of = .yword, .is = .word } }, .any, .any },90385 .src_constraints = .{ .{ .scalar_int = .{ .of = .yword, .is = .word } }, .any, .any },
90371 .dst_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .byte } }, .any },90386 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .xword, .is = .byte } }, .any },
90372 .patterns = &.{90387 .patterns = &.{
90373 .{ .src = .{ .to_sse, .none, .none } },90388 .{ .src = .{ .to_sse, .none, .none } },
90374 },90389 },
90375 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },90390 .dst_temps = .{ .{ .rc = .sse }, .unused },
90376 .each = .{ .once = &.{90391 .each = .{ .once = &.{
90377 .{ ._, .vp_b, .ackusw, .dst0y, .src0y, .dst0y, ._ },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 },
90403 .each = .{ .once = &.{
90404 .{ ._, .v_f128, .extract, .dst0x, .src0y, .ui(1), ._ },
90405 .{ ._, .vp_b, .ackusw, .dst0x, .src0x, .dst0x, ._ },
90378 } },90406 } },
90379 }, .{90407 }, .{
90380 .required_features = .{ .slow_incdec, null, null, null },90408 .required_features = .{ .slow_incdec, null, null, null },
...@@ -90448,7 +90476,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -90448,7 +90476,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
90448 }, .{90476 }, .{
90449 .required_features = .{ .avx, null, null, null },90477 .required_features = .{ .avx, null, null, null },
90450 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .dword } }, .any, .any },90478 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .dword } }, .any, .any },
90451 .dst_constraints = .{ .{ .scalar_int = .{ .of = .dword, .is = .byte } }, .any },90479 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .dword, .is = .byte } }, .any },
90452 .patterns = &.{90480 .patterns = &.{
90453 .{ .src = .{ .to_sse, .none, .none } },90481 .{ .src = .{ .to_sse, .none, .none } },
90454 },90482 },
...@@ -90472,7 +90500,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -90472,7 +90500,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
90472 }, .{90500 }, .{
90473 .required_features = .{ .sse4_1, null, null, null },90501 .required_features = .{ .sse4_1, null, null, null },
90474 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .dword } }, .any, .any },90502 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .dword } }, .any, .any },
90475 .dst_constraints = .{ .{ .scalar_int = .{ .of = .dword, .is = .byte } }, .any },90503 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .dword, .is = .byte } }, .any },
90476 .patterns = &.{90504 .patterns = &.{
90477 .{ .src = .{ .to_mut_sse, .none, .none } },90505 .{ .src = .{ .to_mut_sse, .none, .none } },
90478 },90506 },
...@@ -90488,22 +90516,50 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -90488,22 +90516,50 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
90488 .patterns = &.{90516 .patterns = &.{
90489 .{ .src = .{ .to_sse, .none, .none } },90517 .{ .src = .{ .to_sse, .none, .none } },
90490 },90518 },
90491 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },90519 .dst_temps = .{ .{ .rc = .sse }, .unused },
90492 .each = .{ .once = &.{90520 .each = .{ .once = &.{
90493 .{ ._, .vp_w, .ackssd, .dst0y, .src0y, .dst0y, ._ },90521 .{ ._, .v_i128, .extract, .dst0x, .src0y, .ui(1), ._ },
90494 .{ ._, .vp_b, .ackssw, .dst0y, .dst0y, .dst0y, ._ },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, ._ },
90495 } },90537 } },
90496 }, .{90538 }, .{
90497 .required_features = .{ .avx2, null, null, null },90539 .required_features = .{ .avx2, null, null, null },
90498 .src_constraints = .{ .{ .scalar_int = .{ .of = .yword, .is = .dword } }, .any, .any },90540 .src_constraints = .{ .{ .scalar_int = .{ .of = .yword, .is = .dword } }, .any, .any },
90499 .dst_constraints = .{ .{ .scalar_int = .{ .of = .qword, .is = .byte } }, .any },90541 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .qword, .is = .byte } }, .any },
90500 .patterns = &.{90542 .patterns = &.{
90501 .{ .src = .{ .to_sse, .none, .none } },90543 .{ .src = .{ .to_sse, .none, .none } },
90502 },90544 },
90503 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },90545 .dst_temps = .{ .{ .rc = .sse }, .unused },
90546 .each = .{ .once = &.{
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 },
90504 .each = .{ .once = &.{90559 .each = .{ .once = &.{
90505 .{ ._, .vp_w, .ackusd, .dst0y, .src0y, .dst0y, ._ },90560 .{ ._, .v_f128, .extract, .dst0x, .src0y, .ui(1), ._ },
90506 .{ ._, .vp_b, .ackusw, .dst0y, .dst0y, .dst0y, ._ },90561 .{ ._, .vp_w, .ackusd, .dst0x, .src0x, .dst0x, ._ },
90562 .{ ._, .vp_b, .ackusw, .dst0x, .dst0x, .dst0x, ._ },
90507 } },90563 } },
90508 }, .{90564 }, .{
90509 .required_features = .{ .slow_incdec, null, null, null },90565 .required_features = .{ .slow_incdec, null, null, null },
...@@ -90722,7 +90778,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -90722,7 +90778,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
90722 }, .{90778 }, .{
90723 .required_features = .{ .avx, null, null, null },90779 .required_features = .{ .avx, null, null, null },
90724 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .dword } }, .any, .any },90780 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .dword } }, .any, .any },
90725 .dst_constraints = .{ .{ .scalar_int = .{ .of = .qword, .is = .word } }, .any },90781 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .qword, .is = .word } }, .any },
90726 .patterns = &.{90782 .patterns = &.{
90727 .{ .src = .{ .to_sse, .none, .none } },90783 .{ .src = .{ .to_sse, .none, .none } },
90728 },90784 },
...@@ -90744,7 +90800,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -90744,7 +90800,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
90744 }, .{90800 }, .{
90745 .required_features = .{ .sse4_1, null, null, null },90801 .required_features = .{ .sse4_1, null, null, null },
90746 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .dword } }, .any, .any },90802 .src_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .dword } }, .any, .any },
90747 .dst_constraints = .{ .{ .scalar_int = .{ .of = .qword, .is = .word } }, .any },90803 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .qword, .is = .word } }, .any },
90748 .patterns = &.{90804 .patterns = &.{
90749 .{ .src = .{ .to_mut_sse, .none, .none } },90805 .{ .src = .{ .to_mut_sse, .none, .none } },
90750 },90806 },
...@@ -90759,20 +90815,46 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -90759,20 +90815,46 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
90759 .patterns = &.{90815 .patterns = &.{
90760 .{ .src = .{ .to_sse, .none, .none } },90816 .{ .src = .{ .to_sse, .none, .none } },
90761 },90817 },
90762 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },90818 .dst_temps = .{ .{ .rc = .sse }, .unused },
90763 .each = .{ .once = &.{90819 .each = .{ .once = &.{
90764 .{ ._, .vp_w, .ackssd, .dst0y, .src0y, .dst0y, ._ },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 },
90831 .each = .{ .once = &.{
90832 .{ ._, .v_f128, .extract, .dst0x, .src0y, .ui(1), ._ },
90833 .{ ._, .vp_w, .ackssd, .dst0x, .src0x, .dst0x, ._ },
90765 } },90834 } },
90766 }, .{90835 }, .{
90767 .required_features = .{ .avx2, null, null, null },90836 .required_features = .{ .avx2, null, null, null },
90768 .src_constraints = .{ .{ .scalar_int = .{ .of = .yword, .is = .dword } }, .any, .any },90837 .src_constraints = .{ .{ .scalar_int = .{ .of = .yword, .is = .dword } }, .any, .any },
90769 .dst_constraints = .{ .{ .scalar_int = .{ .of = .xword, .is = .word } }, .any },90838 .dst_constraints = .{ .{ .scalar_unsigned_int = .{ .of = .xword, .is = .word } }, .any },
90770 .patterns = &.{90839 .patterns = &.{
90771 .{ .src = .{ .to_sse, .none, .none } },90840 .{ .src = .{ .to_sse, .none, .none } },
90772 },90841 },
90773 .dst_temps = .{ .{ .mut_rc = .{ .ref = .src0, .rc = .sse } }, .unused },90842 .dst_temps = .{ .{ .rc = .sse }, .unused },
90774 .each = .{ .once = &.{90843 .each = .{ .once = &.{
90775 .{ ._, .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, ._ },
90776 } },90858 } },
90777 }, .{90859 }, .{
90778 .src_constraints = .{ .{ .multiple_scalar_int = .{ .of = .dword, .is = .dword } }, .any, .any },90860 .src_constraints = .{ .{ .multiple_scalar_int = .{ .of = .dword, .is = .dword } }, .any, .any },
...@@ -92413,7 +92495,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -92413,7 +92495,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
92413 .clobbers = .{ .eflags = true },92495 .clobbers = .{ .eflags = true },
92414 .each = .{ .once = &.{92496 .each = .{ .once = &.{
92415 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },92497 .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_unaligned_size), ._, ._ },
92416 .{ .@"0:", .vp_d, .movzxb, .tmp1y, .memia(.src0x, .tmp0, .add_unaligned_size), ._, ._ },92498 .{ .@"0:", .vp_d, .movzxb, .tmp1y, .memia(.src0q, .tmp0, .add_unaligned_size), ._, ._ },
92417 .{ ._, .v_dqa, .mov, .memsia(.dst0y, .@"4", .tmp0, .add_unaligned_size), .tmp1y, ._, ._ },92499 .{ ._, .v_dqa, .mov, .memsia(.dst0y, .@"4", .tmp0, .add_unaligned_size), .tmp1y, ._, ._ },
92418 .{ ._, ._, .add, .tmp0p, .si(8), ._, ._ },92500 .{ ._, ._, .add, .tmp0p, .si(8), ._, ._ },
92419 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },92501 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
test/behavior/cast.zig+206-20
...@@ -607,26 +607,212 @@ test "@intCast on vector" {...@@ -607,26 +607,212 @@ test "@intCast on vector" {
607607
608 const S = struct {608 const S = struct {
609 fn doTheTest() !void {609 fn doTheTest() !void {
610 // Upcast (implicit, equivalent to @intCast)610 {
611 var up0: @Vector(2, u8) = [_]u8{ 0x55, 0xaa };611 // Upcast (implicit, equivalent to @intCast)
612 _ = &up0;612 var up0: @Vector(2, u8) = .{ 0x55, 0xaa };
613 const up1: @Vector(2, u16) = up0;613 _ = &up0;
614 const up2: @Vector(2, u32) = up0;614 const up1: @Vector(2, u16) = up0;
615 const up3: @Vector(2, u64) = up0;615 const up2: @Vector(2, u32) = up0;
616 // Downcast (safety-checked)616 const up3: @Vector(2, u64) = up0;
617 var down0 = up3;617
618 _ = &down0;618 try expect(mem.eql(u16, &@as([2]u16, up1), &[2]u16{ 0x55, 0xaa }));
619 const down1: @Vector(2, u32) = @intCast(down0);619 try expect(mem.eql(u32, &@as([2]u32, up2), &[2]u32{ 0x55, 0xaa }));
620 const down2: @Vector(2, u16) = @intCast(down0);620 try expect(mem.eql(u64, &@as([2]u64, up3), &[2]u64{ 0x55, 0xaa }));
621 const down3: @Vector(2, u8) = @intCast(down0);621
622622 {
623 try expect(mem.eql(u16, &@as([2]u16, up1), &[2]u16{ 0x55, 0xaa }));623 // Downcast (safety-checked)
624 try expect(mem.eql(u32, &@as([2]u32, up2), &[2]u32{ 0x55, 0xaa }));624 const down2: @Vector(2, u32) = @intCast(up3);
625 try expect(mem.eql(u64, &@as([2]u64, up3), &[2]u64{ 0x55, 0xaa }));625 const down1: @Vector(2, u16) = @intCast(up3);
626626 const down0: @Vector(2, u8) = @intCast(up3);
627 try expect(mem.eql(u32, &@as([2]u32, down1), &[2]u32{ 0x55, 0xaa }));627
628 try expect(mem.eql(u16, &@as([2]u16, down2), &[2]u16{ 0x55, 0xaa }));628 try expect(mem.eql(u32, &@as([2]u32, down2), &[2]u32{ 0x55, 0xaa }));
629 try expect(mem.eql(u8, &@as([2]u8, down3), &[2]u8{ 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 }
630 }816 }
631 };817 };
632818