authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-05-31 23:14:48-04:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-06-01 08:24:01+01:00
log9edfccb9a7d23dbf02444023d042d5008a39462e
tree3eafb1c2bed9f2170d6861ca466dca9e6d74392a
parentec579aa0f372b2054ad659aaacd190c1a986d7f2
signaturelock-open Commit is signed but in an unrecognized format.

Legalize: implement scalarization of overflow intrinsics


19 files changed, 350 insertions(+), 98 deletions(-)

lib/std/simd.zig-1
...@@ -455,7 +455,6 @@ pub fn prefixScan(comptime op: std.builtin.ReduceOp, comptime hop: isize, vec: a...@@ -455,7 +455,6 @@ pub fn prefixScan(comptime op: std.builtin.ReduceOp, comptime hop: isize, vec: a
455}455}
456456
457test "vector prefix scan" {457test "vector prefix scan" {
458 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
459 if ((builtin.cpu.arch == .armeb or builtin.cpu.arch == .thumbeb) and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/22060458 if ((builtin.cpu.arch == .armeb or builtin.cpu.arch == .thumbeb) and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/22060
460 if (builtin.cpu.arch == .aarch64_be and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21893459 if (builtin.cpu.arch == .aarch64_be and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21893
461 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest;460 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest;
src/Air/Legalize.zig+191-7
...@@ -33,6 +33,10 @@ pub const Feature = enum {...@@ -33,6 +33,10 @@ pub const Feature = enum {
33 scalarize_mod_optimized,33 scalarize_mod_optimized,
34 scalarize_max,34 scalarize_max,
35 scalarize_min,35 scalarize_min,
36 scalarize_add_with_overflow,
37 scalarize_sub_with_overflow,
38 scalarize_mul_with_overflow,
39 scalarize_shl_with_overflow,
36 scalarize_bit_and,40 scalarize_bit_and,
37 scalarize_bit_or,41 scalarize_bit_or,
38 scalarize_shr,42 scalarize_shr,
...@@ -129,6 +133,10 @@ pub const Feature = enum {...@@ -129,6 +133,10 @@ pub const Feature = enum {
129 .mod_optimized => .scalarize_mod_optimized,133 .mod_optimized => .scalarize_mod_optimized,
130 .max => .scalarize_max,134 .max => .scalarize_max,
131 .min => .scalarize_min,135 .min => .scalarize_min,
136 .add_with_overflow => .scalarize_add_with_overflow,
137 .sub_with_overflow => .scalarize_sub_with_overflow,
138 .mul_with_overflow => .scalarize_mul_with_overflow,
139 .shl_with_overflow => .scalarize_shl_with_overflow,
132 .bit_and => .scalarize_bit_and,140 .bit_and => .scalarize_bit_and,
133 .bit_or => .scalarize_bit_or,141 .bit_or => .scalarize_bit_or,
134 .shr => .scalarize_shr,142 .shr => .scalarize_shr,
...@@ -279,10 +287,15 @@ fn legalizeBody(l: *Legalize, body_start: usize, body_len: usize) Error!void {...@@ -279,10 +287,15 @@ fn legalizeBody(l: *Legalize, body_start: usize, body_len: usize) Error!void {
279 },287 },
280 .ptr_add,288 .ptr_add,
281 .ptr_sub,289 .ptr_sub,
282 .add_with_overflow,290 => {},
291 inline .add_with_overflow,
283 .sub_with_overflow,292 .sub_with_overflow,
284 .mul_with_overflow,293 .mul_with_overflow,
285 .shl_with_overflow,294 .shl_with_overflow,
295 => |air_tag| if (l.features.contains(comptime .scalarize(air_tag))) {
296 const ty_pl = l.air_instructions.items(.data)[@intFromEnum(inst)].ty_pl;
297 if (ty_pl.ty.toType().fieldType(0, zcu).isVector(zcu)) continue :inst l.replaceInst(inst, .block, try l.scalarizeOverflowBlockPayload(inst));
298 },
286 .alloc,299 .alloc,
287 => {},300 => {},
288 .inferred_alloc,301 .inferred_alloc,
...@@ -518,7 +531,7 @@ fn legalizeBody(l: *Legalize, body_start: usize, body_len: usize) Error!void {...@@ -518,7 +531,7 @@ fn legalizeBody(l: *Legalize, body_start: usize, body_len: usize) Error!void {
518 switch (vector_ty.vectorLen(zcu)) {531 switch (vector_ty.vectorLen(zcu)) {
519 0 => unreachable,532 0 => unreachable,
520 1 => continue :inst l.replaceInst(inst, .bitcast, .{ .ty_op = .{533 1 => continue :inst l.replaceInst(inst, .bitcast, .{ .ty_op = .{
521 .ty = Air.internedToRef(vector_ty.scalarType(zcu).toIntern()),534 .ty = Air.internedToRef(vector_ty.childType(zcu).toIntern()),
522 .operand = reduce.operand,535 .operand = reduce.operand,
523 } }),536 } }),
524 else => break :done,537 else => break :done,
...@@ -646,7 +659,7 @@ fn scalarizeBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index, comptime form:...@@ -646,7 +659,7 @@ fn scalarizeBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index, comptime form:
646 .ty_op => loop.block.add(l, .{659 .ty_op => loop.block.add(l, .{
647 .tag = orig.tag,660 .tag = orig.tag,
648 .data = .{ .ty_op = .{661 .data = .{ .ty_op = .{
649 .ty = Air.internedToRef(orig.data.ty_op.ty.toType().scalarType(zcu).toIntern()),662 .ty = Air.internedToRef(res_ty.childType(zcu).toIntern()),
650 .operand = loop.block.add(l, .{663 .operand = loop.block.add(l, .{
651 .tag = .array_elem_val,664 .tag = .array_elem_val,
652 .data = .{ .bin_op = .{665 .data = .{ .bin_op = .{
...@@ -745,7 +758,7 @@ fn scalarizeBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index, comptime form:...@@ -745,7 +758,7 @@ fn scalarizeBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index, comptime form:
745 .shuffle_two => unwrapped.operand_a,758 .shuffle_two => unwrapped.operand_a,
746 };759 };
747 const operand_a_len = l.typeOf(operand_a).vectorLen(zcu);760 const operand_a_len = l.typeOf(operand_a).vectorLen(zcu);
748 const elem_ty = unwrapped.result_ty.scalarType(zcu);761 const elem_ty = res_ty.childType(zcu);
749 var res_elem: Result = .init(l, elem_ty, &loop.block);762 var res_elem: Result = .init(l, elem_ty, &loop.block);
750 res_elem.block = .init(loop.block.stealCapacity(extra_insts));763 res_elem.block = .init(loop.block.stealCapacity(extra_insts));
751 {764 {
...@@ -945,7 +958,7 @@ fn scalarizeBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index, comptime form:...@@ -945,7 +958,7 @@ fn scalarizeBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index, comptime form:
945 },958 },
946 .select => {959 .select => {
947 const extra = l.extraData(Air.Bin, orig.data.pl_op.payload).data;960 const extra = l.extraData(Air.Bin, orig.data.pl_op.payload).data;
948 var res_elem: Result = .init(l, l.typeOf(extra.lhs).scalarType(zcu), &loop.block);961 var res_elem: Result = .init(l, l.typeOf(extra.lhs).childType(zcu), &loop.block);
949 res_elem.block = .init(loop.block.stealCapacity(extra_insts));962 res_elem.block = .init(loop.block.stealCapacity(extra_insts));
950 {963 {
951 var select_cond_br: CondBr = .init(l, res_elem.block.add(l, .{964 var select_cond_br: CondBr = .init(l, res_elem.block.add(l, .{
...@@ -1043,6 +1056,176 @@ fn scalarizeBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index, comptime form:...@@ -1043,6 +1056,176 @@ fn scalarizeBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index, comptime form:
1043 .payload = try l.addBlockBody(res_block.body()),1056 .payload = try l.addBlockBody(res_block.body()),
1044 } };1057 } };
1045}1058}
1059fn scalarizeOverflowBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Error!Air.Inst.Data {
1060 const pt = l.pt;
1061 const zcu = pt.zcu;
1062
1063 const orig = l.air_instructions.get(@intFromEnum(orig_inst));
1064 const res_ty = l.typeOfIndex(orig_inst);
1065 const wrapped_res_ty = res_ty.fieldType(0, zcu);
1066 const wrapped_res_scalar_ty = wrapped_res_ty.childType(zcu);
1067 const res_len = wrapped_res_ty.vectorLen(zcu);
1068
1069 var inst_buf: [21]Air.Inst.Index = undefined;
1070 try l.air_instructions.ensureUnusedCapacity(zcu.gpa, inst_buf.len);
1071
1072 var res_block: Block = .init(&inst_buf);
1073 {
1074 const res_alloc_inst = res_block.add(l, .{
1075 .tag = .alloc,
1076 .data = .{ .ty = try pt.singleMutPtrType(res_ty) },
1077 });
1078 const ptr_wrapped_res_inst = res_block.add(l, .{
1079 .tag = .struct_field_ptr_index_0,
1080 .data = .{ .ty_op = .{
1081 .ty = Air.internedToRef((try pt.singleMutPtrType(wrapped_res_ty)).toIntern()),
1082 .operand = res_alloc_inst.toRef(),
1083 } },
1084 });
1085 const ptr_overflow_res_inst = res_block.add(l, .{
1086 .tag = .struct_field_ptr_index_1,
1087 .data = .{ .ty_op = .{
1088 .ty = Air.internedToRef((try pt.singleMutPtrType(res_ty.fieldType(1, zcu))).toIntern()),
1089 .operand = res_alloc_inst.toRef(),
1090 } },
1091 });
1092 const index_alloc_inst = res_block.add(l, .{
1093 .tag = .alloc,
1094 .data = .{ .ty = .ptr_usize },
1095 });
1096 _ = res_block.add(l, .{
1097 .tag = .store,
1098 .data = .{ .bin_op = .{
1099 .lhs = index_alloc_inst.toRef(),
1100 .rhs = .zero_usize,
1101 } },
1102 });
1103
1104 var loop: Loop = .init(l, &res_block);
1105 loop.block = .init(res_block.stealRemainingCapacity());
1106 {
1107 const cur_index_inst = loop.block.add(l, .{
1108 .tag = .load,
1109 .data = .{ .ty_op = .{
1110 .ty = .usize_type,
1111 .operand = index_alloc_inst.toRef(),
1112 } },
1113 });
1114 const extra = l.extraData(Air.Bin, orig.data.ty_pl.payload).data;
1115 const res_elem = loop.block.add(l, .{
1116 .tag = orig.tag,
1117 .data = .{ .ty_pl = .{
1118 .ty = Air.internedToRef(try zcu.intern_pool.getTupleType(zcu.gpa, pt.tid, .{
1119 .types = &.{ wrapped_res_scalar_ty.toIntern(), .u1_type },
1120 .values = &(.{.none} ** 2),
1121 })),
1122 .payload = try l.addExtra(Air.Bin, .{
1123 .lhs = loop.block.add(l, .{
1124 .tag = .array_elem_val,
1125 .data = .{ .bin_op = .{
1126 .lhs = extra.lhs,
1127 .rhs = cur_index_inst.toRef(),
1128 } },
1129 }).toRef(),
1130 .rhs = loop.block.add(l, .{
1131 .tag = .array_elem_val,
1132 .data = .{ .bin_op = .{
1133 .lhs = extra.rhs,
1134 .rhs = cur_index_inst.toRef(),
1135 } },
1136 }).toRef(),
1137 }),
1138 } },
1139 });
1140 _ = loop.block.add(l, .{
1141 .tag = .vector_store_elem,
1142 .data = .{ .vector_store_elem = .{
1143 .vector_ptr = ptr_overflow_res_inst.toRef(),
1144 .payload = try l.addExtra(Air.Bin, .{
1145 .lhs = cur_index_inst.toRef(),
1146 .rhs = loop.block.add(l, .{
1147 .tag = .struct_field_val,
1148 .data = .{ .ty_pl = .{
1149 .ty = .u1_type,
1150 .payload = try l.addExtra(Air.StructField, .{
1151 .struct_operand = res_elem.toRef(),
1152 .field_index = 1,
1153 }),
1154 } },
1155 }).toRef(),
1156 }),
1157 } },
1158 });
1159 _ = loop.block.add(l, .{
1160 .tag = .vector_store_elem,
1161 .data = .{ .vector_store_elem = .{
1162 .vector_ptr = ptr_wrapped_res_inst.toRef(),
1163 .payload = try l.addExtra(Air.Bin, .{
1164 .lhs = cur_index_inst.toRef(),
1165 .rhs = loop.block.add(l, .{
1166 .tag = .struct_field_val,
1167 .data = .{ .ty_pl = .{
1168 .ty = Air.internedToRef(wrapped_res_scalar_ty.toIntern()),
1169 .payload = try l.addExtra(Air.StructField, .{
1170 .struct_operand = res_elem.toRef(),
1171 .field_index = 0,
1172 }),
1173 } },
1174 }).toRef(),
1175 }),
1176 } },
1177 });
1178
1179 var loop_cond_br: CondBr = .init(l, (try loop.block.addCmp(
1180 l,
1181 .lt,
1182 cur_index_inst.toRef(),
1183 try pt.intRef(.usize, res_len - 1),
1184 .{},
1185 )).toRef(), &loop.block, .{});
1186 loop_cond_br.then_block = .init(loop.block.stealRemainingCapacity());
1187 {
1188 _ = loop_cond_br.then_block.add(l, .{
1189 .tag = .store,
1190 .data = .{ .bin_op = .{
1191 .lhs = index_alloc_inst.toRef(),
1192 .rhs = loop_cond_br.then_block.add(l, .{
1193 .tag = .add,
1194 .data = .{ .bin_op = .{
1195 .lhs = cur_index_inst.toRef(),
1196 .rhs = .one_usize,
1197 } },
1198 }).toRef(),
1199 } },
1200 });
1201 _ = loop_cond_br.then_block.add(l, .{
1202 .tag = .repeat,
1203 .data = .{ .repeat = .{ .loop_inst = loop.inst } },
1204 });
1205 }
1206 loop_cond_br.else_block = .init(loop_cond_br.then_block.stealRemainingCapacity());
1207 _ = loop_cond_br.else_block.add(l, .{
1208 .tag = .br,
1209 .data = .{ .br = .{
1210 .block_inst = orig_inst,
1211 .operand = loop_cond_br.else_block.add(l, .{
1212 .tag = .load,
1213 .data = .{ .ty_op = .{
1214 .ty = Air.internedToRef(res_ty.toIntern()),
1215 .operand = res_alloc_inst.toRef(),
1216 } },
1217 }).toRef(),
1218 } },
1219 });
1220 try loop_cond_br.finish(l);
1221 }
1222 try loop.finish(l);
1223 }
1224 return .{ .ty_pl = .{
1225 .ty = Air.internedToRef(res_ty.toIntern()),
1226 .payload = try l.addBlockBody(res_block.body()),
1227 } };
1228}
10461229
1047fn safeIntcastBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Error!Air.Inst.Data {1230fn safeIntcastBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Error!Air.Inst.Data {
1048 const pt = l.pt;1231 const pt = l.pt;
...@@ -1535,8 +1718,9 @@ fn addBlockBody(l: *Legalize, body: []const Air.Inst.Index) Error!u32 {...@@ -1535,8 +1718,9 @@ fn addBlockBody(l: *Legalize, body: []const Air.Inst.Index) Error!u32 {
1535 return @intCast(l.air_extra.items.len);1718 return @intCast(l.air_extra.items.len);
1536}1719}
15371720
1538// inline to propagate comptime `tag`s1721/// Returns `tag` to remind the caller to `continue :inst` the result.
1539inline fn replaceInst(l: *Legalize, inst: Air.Inst.Index, tag: Air.Inst.Tag, data: Air.Inst.Data) Air.Inst.Tag {1722/// This is inline to propagate the comptime-known `tag`.
1723inline fn replaceInst(l: *Legalize, inst: Air.Inst.Index, comptime tag: Air.Inst.Tag, data: Air.Inst.Data) Air.Inst.Tag {
1540 const orig_ty = if (std.debug.runtime_safety) l.typeOfIndex(inst) else {};1724 const orig_ty = if (std.debug.runtime_safety) l.typeOfIndex(inst) else {};
1541 l.air_instructions.set(@intFromEnum(inst), .{ .tag = tag, .data = data });1725 l.air_instructions.set(@intFromEnum(inst), .{ .tag = tag, .data = data });
1542 if (std.debug.runtime_safety) assert(l.typeOfIndex(inst).toIntern() == orig_ty.toIntern());1726 if (std.debug.runtime_safety) assert(l.typeOfIndex(inst).toIntern() == orig_ty.toIntern());
src/arch/x86_64/CodeGen.zig+78-47
...@@ -53,6 +53,10 @@ pub fn legalizeFeatures(target: *const std.Target) *const Air.Legalize.Features...@@ -53,6 +53,10 @@ pub fn legalizeFeatures(target: *const std.Target) *const Air.Legalize.Features
53 .scalarize_div_exact_optimized = use_old,53 .scalarize_div_exact_optimized = use_old,
54 .scalarize_max = use_old,54 .scalarize_max = use_old,
55 .scalarize_min = use_old,55 .scalarize_min = use_old,
56 .scalarize_add_with_overflow = true,
57 .scalarize_sub_with_overflow = true,
58 .scalarize_mul_with_overflow = true,
59 .scalarize_shl_with_overflow = true,
56 .scalarize_bit_and = use_old,60 .scalarize_bit_and = use_old,
57 .scalarize_bit_or = use_old,61 .scalarize_bit_or = use_old,
58 .scalarize_shr = true,62 .scalarize_shr = true,
...@@ -283,7 +287,7 @@ pub const MCValue = union(enum) {...@@ -283,7 +287,7 @@ pub const MCValue = union(enum) {
283 /// Payload is a frame address.287 /// Payload is a frame address.
284 lea_frame: bits.FrameAddr,288 lea_frame: bits.FrameAddr,
285 /// Supports integer_per_element abi289 /// Supports integer_per_element abi
286 elementwise_regs_then_frame: packed struct { regs: u3, frame_off: i29, frame_index: FrameIndex },290 elementwise_args: packed struct { regs: u3, frame_off: i29, frame_index: FrameIndex },
287 /// This indicates that we have already allocated a frame index for this instruction,291 /// This indicates that we have already allocated a frame index for this instruction,
288 /// but it has not been spilled there yet in the current control flow.292 /// but it has not been spilled there yet in the current control flow.
289 /// Payload is a frame index.293 /// Payload is a frame index.
...@@ -305,7 +309,7 @@ pub const MCValue = union(enum) {...@@ -305,7 +309,7 @@ pub const MCValue = union(enum) {
305 .lea_direct,309 .lea_direct,
306 .lea_got,310 .lea_got,
307 .lea_frame,311 .lea_frame,
308 .elementwise_regs_then_frame,312 .elementwise_args,
309 .reserved_frame,313 .reserved_frame,
310 .air_ref,314 .air_ref,
311 => false,315 => false,
...@@ -420,7 +424,7 @@ pub const MCValue = union(enum) {...@@ -420,7 +424,7 @@ pub const MCValue = union(enum) {
420 .lea_direct,424 .lea_direct,
421 .lea_got,425 .lea_got,
422 .lea_frame,426 .lea_frame,
423 .elementwise_regs_then_frame,427 .elementwise_args,
424 .reserved_frame,428 .reserved_frame,
425 .air_ref,429 .air_ref,
426 => unreachable, // not in memory430 => unreachable, // not in memory
...@@ -454,7 +458,7 @@ pub const MCValue = union(enum) {...@@ -454,7 +458,7 @@ pub const MCValue = union(enum) {
454 .load_got,458 .load_got,
455 .load_frame,459 .load_frame,
456 .load_symbol,460 .load_symbol,
457 .elementwise_regs_then_frame,461 .elementwise_args,
458 .reserved_frame,462 .reserved_frame,
459 .air_ref,463 .air_ref,
460 => unreachable, // not dereferenceable464 => unreachable, // not dereferenceable
...@@ -474,7 +478,7 @@ pub const MCValue = union(enum) {...@@ -474,7 +478,7 @@ pub const MCValue = union(enum) {
474 .unreach,478 .unreach,
475 .dead,479 .dead,
476 .undef,480 .undef,
477 .elementwise_regs_then_frame,481 .elementwise_args,
478 .reserved_frame,482 .reserved_frame,
479 .air_ref,483 .air_ref,
480 => unreachable, // not valid484 => unreachable, // not valid
...@@ -528,7 +532,7 @@ pub const MCValue = union(enum) {...@@ -528,7 +532,7 @@ pub const MCValue = union(enum) {
528 .load_got,532 .load_got,
529 .lea_got,533 .lea_got,
530 .lea_frame,534 .lea_frame,
531 .elementwise_regs_then_frame,535 .elementwise_args,
532 .reserved_frame,536 .reserved_frame,
533 .lea_symbol,537 .lea_symbol,
534 => unreachable,538 => unreachable,
...@@ -612,7 +616,7 @@ pub const MCValue = union(enum) {...@@ -612,7 +616,7 @@ pub const MCValue = union(enum) {
612 .load_got => |pl| try writer.print("[got:{d}]", .{pl}),616 .load_got => |pl| try writer.print("[got:{d}]", .{pl}),
613 .lea_got => |pl| try writer.print("got:{d}", .{pl}),617 .lea_got => |pl| try writer.print("got:{d}", .{pl}),
614 .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }),618 .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }),
615 .elementwise_regs_then_frame => |pl| try writer.print("elementwise:{d}:[{} + 0x{x}]", .{619 .elementwise_args => |pl| try writer.print("elementwise:{d}:[{} + 0x{x}]", .{
616 pl.regs, pl.frame_index, pl.frame_off,620 pl.regs, pl.frame_index, pl.frame_off,
617 }),621 }),
618 .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }),622 .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }),
...@@ -645,7 +649,7 @@ const InstTracking = struct {...@@ -645,7 +649,7 @@ const InstTracking = struct {
645 .lea_symbol,649 .lea_symbol,
646 => result,650 => result,
647 .dead,651 .dead,
648 .elementwise_regs_then_frame,652 .elementwise_args,
649 .reserved_frame,653 .reserved_frame,
650 .air_ref,654 .air_ref,
651 => unreachable,655 => unreachable,
...@@ -754,7 +758,7 @@ const InstTracking = struct {...@@ -754,7 +758,7 @@ const InstTracking = struct {
754 .register_overflow,758 .register_overflow,
755 .register_mask,759 .register_mask,
756 .indirect,760 .indirect,
757 .elementwise_regs_then_frame,761 .elementwise_args,
758 .air_ref,762 .air_ref,
759 => unreachable,763 => unreachable,
760 }764 }
...@@ -168424,7 +168428,7 @@ fn load(self: *CodeGen, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerE...@@ -168424,7 +168428,7 @@ fn load(self: *CodeGen, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerE
168424 .register_quadruple,168428 .register_quadruple,
168425 .register_overflow,168429 .register_overflow,
168426 .register_mask,168430 .register_mask,
168427 .elementwise_regs_then_frame,168431 .elementwise_args,
168428 .reserved_frame,168432 .reserved_frame,
168429 => unreachable, // not a valid pointer168433 => unreachable, // not a valid pointer
168430 .immediate,168434 .immediate,
...@@ -168642,7 +168646,7 @@ fn store(...@@ -168642,7 +168646,7 @@ fn store(
168642 .register_quadruple,168646 .register_quadruple,
168643 .register_overflow,168647 .register_overflow,
168644 .register_mask,168648 .register_mask,
168645 .elementwise_regs_then_frame,168649 .elementwise_args,
168646 .reserved_frame,168650 .reserved_frame,
168647 => unreachable, // not a valid pointer168651 => unreachable, // not a valid pointer
168648 .immediate,168652 .immediate,
...@@ -169128,7 +169132,7 @@ fn genUnOpMir(self: *CodeGen, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv:...@@ -169128,7 +169132,7 @@ fn genUnOpMir(self: *CodeGen, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv:
169128 .lea_direct,169132 .lea_direct,
169129 .lea_got,169133 .lea_got,
169130 .lea_frame,169134 .lea_frame,
169131 .elementwise_regs_then_frame,169135 .elementwise_args,
169132 .reserved_frame,169136 .reserved_frame,
169133 .air_ref,169137 .air_ref,
169134 => unreachable, // unmodifiable destination169138 => unreachable, // unmodifiable destination
...@@ -170799,7 +170803,7 @@ fn genBinOp(...@@ -170799,7 +170803,7 @@ fn genBinOp(
170799 .load_got,170803 .load_got,
170800 .lea_got,170804 .lea_got,
170801 .lea_frame,170805 .lea_frame,
170802 .elementwise_regs_then_frame,170806 .elementwise_args,
170803 .reserved_frame,170807 .reserved_frame,
170804 .air_ref,170808 .air_ref,
170805 => unreachable,170809 => unreachable,
...@@ -171982,7 +171986,7 @@ fn genBinOpMir(...@@ -171982,7 +171986,7 @@ fn genBinOpMir(
171982 .lea_got,171986 .lea_got,
171983 .lea_frame,171987 .lea_frame,
171984 .lea_symbol,171988 .lea_symbol,
171985 .elementwise_regs_then_frame,171989 .elementwise_args,
171986 .reserved_frame,171990 .reserved_frame,
171987 .air_ref,171991 .air_ref,
171988 => unreachable, // unmodifiable destination171992 => unreachable, // unmodifiable destination
...@@ -172018,7 +172022,7 @@ fn genBinOpMir(...@@ -172018,7 +172022,7 @@ fn genBinOpMir(
172018 .undef,172022 .undef,
172019 .register_overflow,172023 .register_overflow,
172020 .register_mask,172024 .register_mask,
172021 .elementwise_regs_then_frame,172025 .elementwise_args,
172022 .reserved_frame,172026 .reserved_frame,
172023 => unreachable,172027 => unreachable,
172024 .register,172028 .register,
...@@ -172178,7 +172182,7 @@ fn genBinOpMir(...@@ -172178,7 +172182,7 @@ fn genBinOpMir(
172178 .undef,172182 .undef,
172179 .register_overflow,172183 .register_overflow,
172180 .register_mask,172184 .register_mask,
172181 .elementwise_regs_then_frame,172185 .elementwise_args,
172182 .reserved_frame,172186 .reserved_frame,
172183 .air_ref,172187 .air_ref,
172184 => unreachable,172188 => unreachable,
...@@ -172274,7 +172278,7 @@ fn genBinOpMir(...@@ -172274,7 +172278,7 @@ fn genBinOpMir(
172274 .undef,172278 .undef,
172275 .register_overflow,172279 .register_overflow,
172276 .register_mask,172280 .register_mask,
172277 .elementwise_regs_then_frame,172281 .elementwise_args,
172278 .reserved_frame,172282 .reserved_frame,
172279 .air_ref,172283 .air_ref,
172280 => unreachable,172284 => unreachable,
...@@ -172405,7 +172409,7 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv...@@ -172405,7 +172409,7 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv
172405 .lea_direct,172409 .lea_direct,
172406 .lea_got,172410 .lea_got,
172407 .lea_frame,172411 .lea_frame,
172408 .elementwise_regs_then_frame,172412 .elementwise_args,
172409 .reserved_frame,172413 .reserved_frame,
172410 .air_ref,172414 .air_ref,
172411 => unreachable, // unmodifiable destination172415 => unreachable, // unmodifiable destination
...@@ -172437,7 +172441,7 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv...@@ -172437,7 +172441,7 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv
172437 .register_quadruple,172441 .register_quadruple,
172438 .register_overflow,172442 .register_overflow,
172439 .register_mask,172443 .register_mask,
172440 .elementwise_regs_then_frame,172444 .elementwise_args,
172441 .reserved_frame,172445 .reserved_frame,
172442 .air_ref,172446 .air_ref,
172443 => unreachable,172447 => unreachable,
...@@ -172557,7 +172561,7 @@ fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -172557,7 +172561,7 @@ fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void {
172557 try self.genCopy(arg_ty, dst_mcv, src_mcv, .{});172561 try self.genCopy(arg_ty, dst_mcv, src_mcv, .{});
172558 break :result dst_mcv;172562 break :result dst_mcv;
172559 },172563 },
172560 .elementwise_regs_then_frame => |regs_frame_addr| {172564 .elementwise_args => |regs_frame_addr| {
172561 try self.spillEflagsIfOccupied();172565 try self.spillEflagsIfOccupied();
172562172566
172563 const fn_info = zcu.typeToFunc(self.fn_type).?;172567 const fn_info = zcu.typeToFunc(self.fn_type).?;
...@@ -172661,7 +172665,7 @@ fn genLocalDebugInfo(...@@ -172661,7 +172665,7 @@ fn genLocalDebugInfo(
172661 .arg, .dbg_arg_inline, .dbg_var_val => |tag| {172665 .arg, .dbg_arg_inline, .dbg_var_val => |tag| {
172662 switch (mcv) {172666 switch (mcv) {
172663 .none => try self.asmAir(.dbg_local, inst),172667 .none => try self.asmAir(.dbg_local, inst),
172664 .unreach, .dead, .elementwise_regs_then_frame, .reserved_frame, .air_ref => unreachable,172668 .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable,
172665 .immediate => |imm| try self.asmAirImmediate(.dbg_local, inst, .u(imm)),172669 .immediate => |imm| try self.asmAirImmediate(.dbg_local, inst, .u(imm)),
172666 .lea_frame => |frame_addr| try self.asmAirFrameAddress(.dbg_local, inst, frame_addr),172670 .lea_frame => |frame_addr| try self.asmAirFrameAddress(.dbg_local, inst, frame_addr),
172667 .lea_symbol => |sym_off| try self.asmAirImmediate(.dbg_local, inst, .rel(sym_off)),172671 .lea_symbol => |sym_off| try self.asmAirImmediate(.dbg_local, inst, .rel(sym_off)),
...@@ -172684,7 +172688,7 @@ fn genLocalDebugInfo(...@@ -172684,7 +172688,7 @@ fn genLocalDebugInfo(
172684 },172688 },
172685 .dbg_var_ptr => switch (mcv) {172689 .dbg_var_ptr => switch (mcv) {
172686 else => unreachable,172690 else => unreachable,
172687 .unreach, .dead, .elementwise_regs_then_frame, .reserved_frame, .air_ref => unreachable,172691 .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable,
172688 .lea_frame => |frame_addr| try self.asmAirMemory(.dbg_local, inst, .{172692 .lea_frame => |frame_addr| try self.asmAirMemory(.dbg_local, inst, .{
172689 .base = .{ .frame = frame_addr.index },172693 .base = .{ .frame = frame_addr.index },
172690 .mod = .{ .rm = .{172694 .mod = .{ .rm = .{
...@@ -172853,7 +172857,7 @@ fn genCall(self: *CodeGen, info: union(enum) {...@@ -172853,7 +172857,7 @@ fn genCall(self: *CodeGen, info: union(enum) {
172853 try self.genCopy(arg_ty, dst_arg, src_arg, opts);172857 try self.genCopy(arg_ty, dst_arg, src_arg, opts);
172854 try self.freeValue(src_arg);172858 try self.freeValue(src_arg);
172855 },172859 },
172856 .elementwise_regs_then_frame => |regs_frame_addr| {172860 .elementwise_args => |regs_frame_addr| {
172857 const index_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);172861 const index_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
172858 const index_lock = self.register_manager.lockRegAssumeUnused(index_reg);172862 const index_lock = self.register_manager.lockRegAssumeUnused(index_reg);
172859 defer self.register_manager.unlockReg(index_lock);172863 defer self.register_manager.unlockReg(index_lock);
...@@ -172962,7 +172966,7 @@ fn genCall(self: *CodeGen, info: union(enum) {...@@ -172962,7 +172966,7 @@ fn genCall(self: *CodeGen, info: union(enum) {
172962 .indirect => |reg_off| try self.genSetReg(reg_off.reg, .usize, .{172966 .indirect => |reg_off| try self.genSetReg(reg_off.reg, .usize, .{
172963 .lea_frame = .{ .index = frame_index, .off = -reg_off.off },172967 .lea_frame = .{ .index = frame_index, .off = -reg_off.off },
172964 }, .{}),172968 }, .{}),
172965 .elementwise_regs_then_frame => |regs_frame_addr| {172969 .elementwise_args => |regs_frame_addr| {
172966 const src_mem: Memory = if (src_arg.isBase()) try src_arg.mem(self, .{ .size = .dword }) else .{172970 const src_mem: Memory = if (src_arg.isBase()) try src_arg.mem(self, .{ .size = .dword }) else .{
172967 .base = .{ .reg = try self.copyToTmpRegister(172971 .base = .{ .reg = try self.copyToTmpRegister(
172968 .usize,172972 .usize,
...@@ -173350,7 +173354,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v...@@ -173350,7 +173354,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v
173350 .lea_got,173354 .lea_got,
173351 .lea_frame,173355 .lea_frame,
173352 .lea_symbol,173356 .lea_symbol,
173353 .elementwise_regs_then_frame,173357 .elementwise_args,
173354 .reserved_frame,173358 .reserved_frame,
173355 .air_ref,173359 .air_ref,
173356 => unreachable,173360 => unreachable,
...@@ -173405,7 +173409,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v...@@ -173405,7 +173409,7 @@ fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !v
173405 .lea_direct,173409 .lea_direct,
173406 .lea_got,173410 .lea_got,
173407 .lea_frame,173411 .lea_frame,
173408 .elementwise_regs_then_frame,173412 .elementwise_args,
173409 .reserved_frame,173413 .reserved_frame,
173410 .air_ref,173414 .air_ref,
173411 => unreachable,173415 => unreachable,
...@@ -173810,7 +173814,7 @@ fn isNull(self: *CodeGen, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue)...@@ -173810,7 +173814,7 @@ fn isNull(self: *CodeGen, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue)
173810 .lea_direct,173814 .lea_direct,
173811 .lea_got,173815 .lea_got,
173812 .lea_symbol,173816 .lea_symbol,
173813 .elementwise_regs_then_frame,173817 .elementwise_args,
173814 .reserved_frame,173818 .reserved_frame,
173815 .air_ref,173819 .air_ref,
173816 => unreachable,173820 => unreachable,
...@@ -175867,7 +175871,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C...@@ -175867,7 +175871,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C
175867 .lea_got,175871 .lea_got,
175868 .lea_frame,175872 .lea_frame,
175869 .lea_symbol,175873 .lea_symbol,
175870 .elementwise_regs_then_frame,175874 .elementwise_args,
175871 .reserved_frame,175875 .reserved_frame,
175872 .air_ref,175876 .air_ref,
175873 => unreachable, // unmodifiable destination175877 => unreachable, // unmodifiable destination
...@@ -175878,7 +175882,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C...@@ -175878,7 +175882,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C
175878 .dead,175882 .dead,
175879 .undef,175883 .undef,
175880 .register_overflow,175884 .register_overflow,
175881 .elementwise_regs_then_frame,175885 .elementwise_args,
175882 .reserved_frame,175886 .reserved_frame,
175883 => unreachable,175887 => unreachable,
175884 .immediate,175888 .immediate,
...@@ -176056,7 +176060,7 @@ fn genSetReg(...@@ -176056,7 +176060,7 @@ fn genSetReg(
176056 .none,176060 .none,
176057 .unreach,176061 .unreach,
176058 .dead,176062 .dead,
176059 .elementwise_regs_then_frame,176063 .elementwise_args,
176060 .reserved_frame,176064 .reserved_frame,
176061 => unreachable,176065 => unreachable,
176062 .undef => if (opts.safety) switch (dst_reg.class()) {176066 .undef => if (opts.safety) switch (dst_reg.class()) {
...@@ -176593,7 +176597,7 @@ fn genSetMem(...@@ -176593,7 +176597,7 @@ fn genSetMem(
176593 .none,176597 .none,
176594 .unreach,176598 .unreach,
176595 .dead,176599 .dead,
176596 .elementwise_regs_then_frame,176600 .elementwise_args,
176597 .reserved_frame,176601 .reserved_frame,
176598 => unreachable,176602 => unreachable,
176599 .undef => if (opts.safety) try self.genInlineMemset(176603 .undef => if (opts.safety) try self.genInlineMemset(
...@@ -180885,7 +180889,7 @@ fn resolveCallingConventionValues(...@@ -180885,7 +180889,7 @@ fn resolveCallingConventionValues(
180885180889
180886 result.stack_byte_count =180890 result.stack_byte_count =
180887 std.mem.alignForward(u31, result.stack_byte_count, frame_elem_align);180891 std.mem.alignForward(u31, result.stack_byte_count, frame_elem_align);
180888 arg_mcv[arg_mcv_i] = .{ .elementwise_regs_then_frame = .{180892 arg_mcv[arg_mcv_i] = .{ .elementwise_args = .{
180889 .regs = remaining_param_int_regs,180893 .regs = remaining_param_int_regs,
180890 .frame_off = @intCast(result.stack_byte_count),180894 .frame_off = @intCast(result.stack_byte_count),
180891 .frame_index = stack_frame_base,180895 .frame_index = stack_frame_base,
...@@ -181510,7 +181514,7 @@ const Temp = struct {...@@ -181510,7 +181514,7 @@ const Temp = struct {
181510 .load_got,181514 .load_got,
181511 .lea_got,181515 .lea_got,
181512 .lea_frame,181516 .lea_frame,
181513 .elementwise_regs_then_frame,181517 .elementwise_args,
181514 .reserved_frame,181518 .reserved_frame,
181515 .air_ref,181519 .air_ref,
181516 => false,181520 => false,
...@@ -181945,7 +181949,7 @@ const Temp = struct {...@@ -181945,7 +181949,7 @@ const Temp = struct {
181945 .register_quadruple,181949 .register_quadruple,
181946 .register_overflow,181950 .register_overflow,
181947 .register_mask,181951 .register_mask,
181948 .elementwise_regs_then_frame,181952 .elementwise_args,
181949 .reserved_frame,181953 .reserved_frame,
181950 .air_ref,181954 .air_ref,
181951 => unreachable, // not a valid pointer181955 => unreachable, // not a valid pointer
...@@ -186669,19 +186673,46 @@ const Temp = struct {...@@ -186669,19 +186673,46 @@ const Temp = struct {
186669 if (cg.reused_operands.isSet(op_index)) continue;186673 if (cg.reused_operands.isSet(op_index)) continue;
186670 try cg.processDeath(op_ref.toIndexAllowNone() orelse continue);186674 try cg.processDeath(op_ref.toIndexAllowNone() orelse continue);
186671 }186675 }
186672 if (cg.liveness.isUnused(inst)) try temp.die(cg) else switch (temp.unwrap(cg)) {186676 if (cg.liveness.isUnused(inst)) try temp.die(cg) else {
186673 .ref, .err_ret_trace => {186677 switch (temp.unwrap(cg)) {
186674 const result = try cg.allocRegOrMem(inst, true);186678 .ref, .err_ret_trace => {
186675 try cg.genCopy(cg.typeOfIndex(inst), result, temp.tracking(cg).short, .{});186679 const temp_mcv = temp.tracking(cg).short;
186676 tracking_log.debug("{} => {} (birth)", .{ inst, result });186680 const result = result: switch (temp_mcv) {
186677 cg.inst_tracking.putAssumeCapacityNoClobber(inst, .init(result));186681 .none, .unreach, .dead, .elementwise_args, .reserved_frame, .air_ref => unreachable,
186678 },186682 .undef, .immediate, .lea_frame => temp_mcv,
186679 .temp => |temp_index| {186683 .eflags,
186680 const temp_tracking = temp_index.tracking(cg);186684 .register,
186681 tracking_log.debug("{} => {} (birth)", .{ inst, temp_tracking.short });186685 .register_pair,
186682 cg.inst_tracking.putAssumeCapacityNoClobber(inst, .init(temp_tracking.short));186686 .register_triple,
186683 assert(cg.reuseTemp(inst, temp_index.toIndex(), temp_tracking));186687 .register_quadruple,
186684 },186688 .register_offset,
186689 .register_overflow,
186690 .register_mask,
186691 .memory,
186692 .load_symbol,
186693 .lea_symbol,
186694 .indirect,
186695 .load_direct,
186696 .lea_direct,
186697 .load_got,
186698 .lea_got,
186699 .load_frame,
186700 => {
186701 const result = try cg.allocRegOrMem(inst, true);
186702 try cg.genCopy(cg.typeOfIndex(inst), result, temp_mcv, .{});
186703 break :result result;
186704 },
186705 };
186706 tracking_log.debug("{} => {} (birth)", .{ inst, result });
186707 cg.inst_tracking.putAssumeCapacityNoClobber(inst, .init(result));
186708 },
186709 .temp => |temp_index| {
186710 const temp_tracking = temp_index.tracking(cg);
186711 tracking_log.debug("{} => {} (birth)", .{ inst, temp_tracking.short });
186712 cg.inst_tracking.putAssumeCapacityNoClobber(inst, .init(temp_tracking.short));
186713 assert(cg.reuseTemp(inst, temp_index.toIndex(), temp_tracking));
186714 },
186715 }
186685 }186716 }
186686 for (0.., op_refs, op_temps) |op_index, op_ref, op_temp| {186717 for (0.., op_refs, op_temps) |op_index, op_ref, op_temp| {
186687 if (op_temp.index != temp.index) continue;186718 if (op_temp.index != temp.index) continue;
test/behavior/floatop.zig+36-12
...@@ -14,9 +14,11 @@ fn epsForType(comptime T: type) T {...@@ -14,9 +14,11 @@ fn epsForType(comptime T: type) T {
14}14}
1515
16test "add f16" {16test "add f16" {
17 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
18 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;17 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1918
19 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
20 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest;
21
20 try testAdd(f16);22 try testAdd(f16);
21 try comptime testAdd(f16);23 try comptime testAdd(f16);
22}24}
...@@ -123,10 +125,12 @@ fn testMul(comptime T: type) !void {...@@ -123,10 +125,12 @@ fn testMul(comptime T: type) !void {
123125
124test "cmp f16" {126test "cmp f16" {
125 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO127 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
126 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
127 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;128 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
128 if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234129 if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
129130
131 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
132 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest;
133
130 try testCmp(f16);134 try testCmp(f16);
131 try comptime testCmp(f16);135 try comptime testCmp(f16);
132}136}
...@@ -338,9 +342,11 @@ test "different sized float comparisons" {...@@ -338,9 +342,11 @@ test "different sized float comparisons" {
338 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO342 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
339 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO343 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
340 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO344 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
341 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
342 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;345 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
343346
347 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
348 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest;
349
344 try testDifferentSizedFloatComparisons();350 try testDifferentSizedFloatComparisons();
345 try comptime testDifferentSizedFloatComparisons();351 try comptime testDifferentSizedFloatComparisons();
346}352}
...@@ -386,10 +392,12 @@ test "@sqrt f16" {...@@ -386,10 +392,12 @@ test "@sqrt f16" {
386 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO392 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
387 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO393 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
388 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO394 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
389 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
390 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;395 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
391 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;396 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
392397
398 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
399 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest;
400
393 try testSqrt(f16);401 try testSqrt(f16);
394 try comptime testSqrt(f16);402 try comptime testSqrt(f16);
395}403}
...@@ -1129,9 +1137,11 @@ test "@abs f16" {...@@ -1129,9 +1137,11 @@ test "@abs f16" {
1129 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1137 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1130 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1138 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1131 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1139 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1132 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1133 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1140 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11341141
1142 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1143 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest;
1144
1135 try testFabs(f16);1145 try testFabs(f16);
1136 try comptime testFabs(f16);1146 try comptime testFabs(f16);
1137}1147}
...@@ -1263,9 +1273,11 @@ test "@floor f32/f64" {...@@ -1263,9 +1273,11 @@ test "@floor f32/f64" {
1263 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1273 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1264 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1274 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1265 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1275 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1266 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1267 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1276 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12681277
1278 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1279 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
1280
1269 try testFloor(f32);1281 try testFloor(f32);
1270 try comptime testFloor(f32);1282 try comptime testFloor(f32);
1271 try testFloor(f64);1283 try testFloor(f64);
...@@ -1329,7 +1341,9 @@ test "@floor with vectors" {...@@ -1329,7 +1341,9 @@ test "@floor with vectors" {
1329 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1341 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1330 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1342 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1331 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1343 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1332 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;1344
1345 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1346 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
13331347
1334 try testFloorWithVectors();1348 try testFloorWithVectors();
1335 try comptime testFloorWithVectors();1349 try comptime testFloorWithVectors();
...@@ -1360,9 +1374,11 @@ test "@ceil f32/f64" {...@@ -1360,9 +1374,11 @@ test "@ceil f32/f64" {
1360 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1374 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1361 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1375 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1362 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1376 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1363 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1364 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1377 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13651378
1379 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1380 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
1381
1366 try testCeil(f32);1382 try testCeil(f32);
1367 try comptime testCeil(f32);1383 try comptime testCeil(f32);
1368 try testCeil(f64);1384 try testCeil(f64);
...@@ -1426,7 +1442,9 @@ test "@ceil with vectors" {...@@ -1426,7 +1442,9 @@ test "@ceil with vectors" {
1426 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1442 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1427 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1443 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1428 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1444 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1429 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;1445
1446 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1447 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
14301448
1431 try testCeilWithVectors();1449 try testCeilWithVectors();
1432 try comptime testCeilWithVectors();1450 try comptime testCeilWithVectors();
...@@ -1457,9 +1475,11 @@ test "@trunc f32/f64" {...@@ -1457,9 +1475,11 @@ test "@trunc f32/f64" {
1457 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1475 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1458 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1476 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1459 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1477 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1460 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1461 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1478 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14621479
1480 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1481 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
1482
1463 try testTrunc(f32);1483 try testTrunc(f32);
1464 try comptime testTrunc(f32);1484 try comptime testTrunc(f32);
1465 try testTrunc(f64);1485 try testTrunc(f64);
...@@ -1523,7 +1543,9 @@ test "@trunc with vectors" {...@@ -1523,7 +1543,9 @@ test "@trunc with vectors" {
1523 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1543 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1524 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1544 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1525 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1545 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1526 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;1546
1547 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1548 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
15271549
1528 try testTruncWithVectors();1550 try testTruncWithVectors();
1529 try comptime testTruncWithVectors();1551 try comptime testTruncWithVectors();
...@@ -1543,9 +1565,11 @@ test "neg f16" {...@@ -1543,9 +1565,11 @@ test "neg f16" {
1543 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1565 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1544 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1566 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1545 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1567 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1546 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1547 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1568 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15481569
1570 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1571 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest;
1572
1549 if (builtin.os.tag == .freebsd) {1573 if (builtin.os.tag == .freebsd) {
1550 // TODO file issue to track this failure1574 // TODO file issue to track this failure
1551 return error.SkipZigTest;1575 return error.SkipZigTest;
test/behavior/math.zig+7-3
...@@ -471,10 +471,12 @@ test "division" {...@@ -471,10 +471,12 @@ test "division" {
471 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO471 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
472 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO472 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
473 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO473 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
474 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
475 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;474 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
476 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;475 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
477476
477 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
478 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest;
479
478 try testIntDivision();480 try testIntDivision();
479 try comptime testIntDivision();481 try comptime testIntDivision();
480482
...@@ -1619,10 +1621,10 @@ test "vector integer addition" {...@@ -1619,10 +1621,10 @@ test "vector integer addition" {
1619 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1621 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1620 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1622 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1621 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1623 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1622 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1623 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1624 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1624 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1625 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1625 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1626 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1627 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
16261628
1627 const S = struct {1629 const S = struct {
1628 fn doTheTest() !void {1630 fn doTheTest() !void {
...@@ -1926,7 +1928,9 @@ test "float vector division of comptime zero by runtime nan is nan" {...@@ -1926,7 +1928,9 @@ test "float vector division of comptime zero by runtime nan is nan" {
1926 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1928 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1927 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1929 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1928 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1930 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1929 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;1931
1932 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1933 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
19301934
1931 const ct_zero: @Vector(1, f32) = .{0};1935 const ct_zero: @Vector(1, f32) = .{0};
1932 var rt_nan: @Vector(1, f32) = .{math.nan(f32)};1936 var rt_nan: @Vector(1, f32) = .{math.nan(f32)};
test/behavior/maximum_minimum.zig-1
...@@ -204,7 +204,6 @@ test "@min/@max notices vector bounds" {...@@ -204,7 +204,6 @@ test "@min/@max notices vector bounds" {
204 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO204 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
205 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO205 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
206 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;206 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
207 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
208207
209 var x: @Vector(2, u16) = .{ 140, 40 };208 var x: @Vector(2, u16) = .{ 140, 40 };
210 const y: @Vector(2, u64) = .{ 5, 100 };209 const y: @Vector(2, u64) = .{ 5, 100 };
test/behavior/muladd.zig+9-3
...@@ -6,10 +6,12 @@ test "@mulAdd" {...@@ -6,10 +6,12 @@ test "@mulAdd" {
6 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO6 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;9 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;10 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1211
12 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
13 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .fma)) return error.SkipZigTest;
14
13 try comptime testMulAdd();15 try comptime testMulAdd();
14 try testMulAdd();16 try testMulAdd();
15}17}
...@@ -137,10 +139,12 @@ test "vector f32" {...@@ -137,10 +139,12 @@ test "vector f32" {
137 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO139 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
138 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO140 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
139 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO141 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
140 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
141 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;142 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
142 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;143 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
143144
145 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
146 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .fma)) return error.SkipZigTest;
147
144 try comptime vector32();148 try comptime vector32();
145 try vector32();149 try vector32();
146}150}
...@@ -163,10 +167,12 @@ test "vector f64" {...@@ -163,10 +167,12 @@ test "vector f64" {
163 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO167 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
164 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO168 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
165 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO169 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
166 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
167 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;170 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
168 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;171 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
169172
173 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
174 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .fma)) return error.SkipZigTest;
175
170 try comptime vector64();176 try comptime vector64();
171 try vector64();177 try vector64();
172}178}
test/behavior/vector.zig+8-10
...@@ -75,12 +75,12 @@ test "vector bin compares with mem.eql" {...@@ -75,12 +75,12 @@ test "vector bin compares with mem.eql" {
7575
76test "vector int operators" {76test "vector int operators" {
77 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO77 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
78 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
79 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO78 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
80 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO79 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
81 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO80 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
82 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;81 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
83 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;82 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
83 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
8484
85 const S = struct {85 const S = struct {
86 fn doTheTest() !void {86 fn doTheTest() !void {
...@@ -248,9 +248,11 @@ test "array to vector with element type coercion" {...@@ -248,9 +248,11 @@ test "array to vector with element type coercion" {
248 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO248 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
249 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO249 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
250 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;250 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
251 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
252 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;251 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
253252
253 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
254 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest;
255
254 const S = struct {256 const S = struct {
255 fn doTheTest() !void {257 fn doTheTest() !void {
256 var foo: f16 = 3.14;258 var foo: f16 = 3.14;
...@@ -285,11 +287,11 @@ test "peer type resolution with coercible element types" {...@@ -285,11 +287,11 @@ test "peer type resolution with coercible element types" {
285287
286test "tuple to vector" {288test "tuple to vector" {
287 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO289 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
288 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
289 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO290 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
290 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO291 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
291 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO292 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
292 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;293 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
294 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
293295
294 const S = struct {296 const S = struct {
295 fn doTheTest() !void {297 fn doTheTest() !void {
...@@ -682,12 +684,12 @@ test "vector bitwise not operator" {...@@ -682,12 +684,12 @@ test "vector bitwise not operator" {
682684
683test "vector shift operators" {685test "vector shift operators" {
684 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO686 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
685 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
686 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO687 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
687 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO688 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
688 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO689 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
689 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;690 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
690 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;691 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
692 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
691693
692 const S = struct {694 const S = struct {
693 fn doTheTestShift(x: anytype, y: anytype) !void {695 fn doTheTestShift(x: anytype, y: anytype) !void {
...@@ -1036,12 +1038,12 @@ test "saturating shift-left" {...@@ -1036,12 +1038,12 @@ test "saturating shift-left" {
10361038
1037test "multiplication-assignment operator with an array operand" {1039test "multiplication-assignment operator with an array operand" {
1038 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1040 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1039 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1040 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1041 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1041 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1042 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1042 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1043 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1043 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1044 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1044 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1045 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1046 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
10451047
1046 const S = struct {1048 const S = struct {
1047 fn doTheTest() !void {1049 fn doTheTest() !void {
...@@ -1058,7 +1060,6 @@ test "multiplication-assignment operator with an array operand" {...@@ -1058,7 +1060,6 @@ test "multiplication-assignment operator with an array operand" {
10581060
1059test "@addWithOverflow" {1061test "@addWithOverflow" {
1060 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1062 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1061 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1062 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1063 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1063 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1064 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1064 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1065 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1109,7 +1110,6 @@ test "@addWithOverflow" {...@@ -1109,7 +1110,6 @@ test "@addWithOverflow" {
11091110
1110test "@subWithOverflow" {1111test "@subWithOverflow" {
1111 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1112 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1112 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1113 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1113 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1114 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1114 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1115 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1115 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1144,7 +1144,6 @@ test "@subWithOverflow" {...@@ -1144,7 +1144,6 @@ test "@subWithOverflow" {
11441144
1145test "@mulWithOverflow" {1145test "@mulWithOverflow" {
1146 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1146 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1147 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1148 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1147 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1149 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1148 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1150 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1149 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1168,7 +1167,6 @@ test "@mulWithOverflow" {...@@ -1168,7 +1167,6 @@ test "@mulWithOverflow" {
11681167
1169test "@shlWithOverflow" {1168test "@shlWithOverflow" {
1170 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1169 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1171 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1172 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1170 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1173 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1171 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1174 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1172 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1307,7 +1305,7 @@ test "zero multiplicand" {...@@ -1307,7 +1305,7 @@ test "zero multiplicand" {
1307 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1305 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1308 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1306 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1309 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO1307 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
1310 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1308 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
13111309
1312 const zeros = @Vector(2, u32){ 0.0, 0.0 };1310 const zeros = @Vector(2, u32){ 0.0, 0.0 };
1313 var ones = @Vector(2, u32){ 1.0, 1.0 };1311 var ones = @Vector(2, u32){ 1.0, 1.0 };
test/behavior/x86_64/binary.zig+8-4
...@@ -5244,31 +5244,34 @@ test min {...@@ -5244,31 +5244,34 @@ test min {
5244 try test_min.testFloatVectors();5244 try test_min.testFloatVectors();
5245}5245}
52465246
5247inline fn addWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, u1 } {5247inline fn addWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, ChangeScalar(Type, u1) } {
5248 return @addWithOverflow(lhs, rhs);5248 return @addWithOverflow(lhs, rhs);
5249}5249}
5250test addWithOverflow {5250test addWithOverflow {
5251 const test_add_with_overflow = binary(addWithOverflow, .{});5251 const test_add_with_overflow = binary(addWithOverflow, .{});
5252 try test_add_with_overflow.testInts();5252 try test_add_with_overflow.testInts();
5253 try test_add_with_overflow.testIntVectors();
5253}5254}
52545255
5255inline fn subWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, u1 } {5256inline fn subWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, ChangeScalar(Type, u1) } {
5256 return @subWithOverflow(lhs, rhs);5257 return @subWithOverflow(lhs, rhs);
5257}5258}
5258test subWithOverflow {5259test subWithOverflow {
5259 const test_sub_with_overflow = binary(subWithOverflow, .{});5260 const test_sub_with_overflow = binary(subWithOverflow, .{});
5260 try test_sub_with_overflow.testInts();5261 try test_sub_with_overflow.testInts();
5262 try test_sub_with_overflow.testIntVectors();
5261}5263}
52625264
5263inline fn mulWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, u1 } {5265inline fn mulWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, ChangeScalar(Type, u1) } {
5264 return @mulWithOverflow(lhs, rhs);5266 return @mulWithOverflow(lhs, rhs);
5265}5267}
5266test mulWithOverflow {5268test mulWithOverflow {
5267 const test_mul_with_overflow = binary(mulWithOverflow, .{});5269 const test_mul_with_overflow = binary(mulWithOverflow, .{});
5268 try test_mul_with_overflow.testInts();5270 try test_mul_with_overflow.testInts();
5271 try test_mul_with_overflow.testIntVectors();
5269}5272}
52705273
5271inline fn shlWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, u1 } {5274inline fn shlWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Type, ChangeScalar(Type, u1) } {
5272 const bit_cast_rhs: AsSignedness(Type, .unsigned) = @bitCast(rhs);5275 const bit_cast_rhs: AsSignedness(Type, .unsigned) = @bitCast(rhs);
5273 const truncate_rhs: Log2Int(Type) = @truncate(bit_cast_rhs);5276 const truncate_rhs: Log2Int(Type) = @truncate(bit_cast_rhs);
5274 return @shlWithOverflow(lhs, if (comptime cast(Log2Int(Scalar(Type)), @bitSizeOf(Scalar(Type)))) |bits| truncate_rhs % splat(Log2Int(Type), bits) else truncate_rhs);5277 return @shlWithOverflow(lhs, if (comptime cast(Log2Int(Scalar(Type)), @bitSizeOf(Scalar(Type)))) |bits| truncate_rhs % splat(Log2Int(Type), bits) else truncate_rhs);
...@@ -5276,6 +5279,7 @@ inline fn shlWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Ty...@@ -5276,6 +5279,7 @@ inline fn shlWithOverflow(comptime Type: type, lhs: Type, rhs: Type) struct { Ty
5276test shlWithOverflow {5279test shlWithOverflow {
5277 const test_shl_with_overflow = binary(shlWithOverflow, .{});5280 const test_shl_with_overflow = binary(shlWithOverflow, .{});
5278 try test_shl_with_overflow.testInts();5281 try test_shl_with_overflow.testInts();
5282 try test_shl_with_overflow.testIntVectors();
5279}5283}
52805284
5281inline fn equal(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs == rhs) {5285inline fn equal(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs == rhs) {
test/cases/safety/memmove_len_mismatch.zig+1-1
...@@ -15,5 +15,5 @@ pub fn main() !void {...@@ -15,5 +15,5 @@ pub fn main() !void {
15 return error.TestFailed;15 return error.TestFailed;
16}16}
17// run17// run
18// backend=llvm18// backend=stage2,llvm
19// target=native19// target=native
test/cases/safety/slice_cast_change_len_0.zig+2-1
...@@ -23,4 +23,5 @@ pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noretu...@@ -23,4 +23,5 @@ pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noretu
23const std = @import("std");23const std = @import("std");
2424
25// run25// run
26// backend=llvm26// backend=stage2,llvm
27// target=x86_64-linux
test/cases/safety/slice_cast_change_len_1.zig+2-1
...@@ -23,4 +23,5 @@ pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noretu...@@ -23,4 +23,5 @@ pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noretu
23const std = @import("std");23const std = @import("std");
2424
25// run25// run
26// backend=llvm26// backend=stage2,llvm
27// target=x86_64-linux
test/cases/safety/slice_cast_change_len_2.zig+2-1
...@@ -23,4 +23,5 @@ pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noretu...@@ -23,4 +23,5 @@ pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noretu
23const std = @import("std");23const std = @import("std");
2424
25// run25// run
26// backend=llvm26// backend=stage2,llvm
27// target=x86_64-linux
test/cases/safety/truncating vector cast.zig +1-1
...@@ -17,5 +17,5 @@ pub fn main() !void {...@@ -17,5 +17,5 @@ pub fn main() !void {
17}17}
1818
19// run19// run
20// backend=llvm20// backend=stage2,llvm
21// target=native21// target=native
test/cases/safety/unsigned-signed vector cast.zig +1-1
...@@ -17,5 +17,5 @@ pub fn main() !void {...@@ -17,5 +17,5 @@ pub fn main() !void {
17}17}
1818
19// run19// run
20// backend=llvm20// backend=stage2,llvm
21// target=native21// target=native
test/cases/safety/vector integer addition overflow.zig +1-1
...@@ -18,5 +18,5 @@ fn add(a: @Vector(4, i32), b: @Vector(4, i32)) @Vector(4, i32) {...@@ -18,5 +18,5 @@ fn add(a: @Vector(4, i32), b: @Vector(4, i32)) @Vector(4, i32) {
18 return a + b;18 return a + b;
19}19}
20// run20// run
21// backend=llvm21// backend=stage2,llvm
22// target=native22// target=native
test/cases/safety/vector integer multiplication overflow.zig +1-1
...@@ -18,5 +18,5 @@ fn mul(a: @Vector(4, u8), b: @Vector(4, u8)) @Vector(4, u8) {...@@ -18,5 +18,5 @@ fn mul(a: @Vector(4, u8), b: @Vector(4, u8)) @Vector(4, u8) {
18 return a * b;18 return a * b;
19}19}
20// run20// run
21// backend=llvm21// backend=stage2,llvm
22// target=native22// target=native
test/cases/safety/vector integer negation overflow.zig +1-1
...@@ -18,5 +18,5 @@ fn neg(a: @Vector(4, i16)) @Vector(4, i16) {...@@ -18,5 +18,5 @@ fn neg(a: @Vector(4, i16)) @Vector(4, i16) {
18 return -a;18 return -a;
19}19}
20// run20// run
21// backend=llvm21// backend=stage2,llvm
22// target=native22// target=native
test/cases/safety/vector integer subtraction overflow.zig +1-1
...@@ -18,5 +18,5 @@ fn sub(a: @Vector(4, u32), b: @Vector(4, u32)) @Vector(4, u32) {...@@ -18,5 +18,5 @@ fn sub(a: @Vector(4, u32), b: @Vector(4, u32)) @Vector(4, u32) {
18 return a - b;18 return a - b;
19}19}
20// run20// run
21// backend=llvm21// backend=stage2,llvm
22// target=native22// target=native