authorgravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-10-05 05:34:45-07:00
committergravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-11-10 12:22:40-07:00
logfbda15632dfb4ddfd931b5acc0c36a3122b7e464
tree4dbf5629d9dcfc77a57f31d72bbf067927d9142e
parenta2f4de1663f815ae8c202ba6a8c68b0658b7d23f

stage2 sema: Make vector constants when operating on vectors

Resolves https://github.com/ziglang/zig/issues/13058

2 files changed, 145 insertions(+), 31 deletions(-)

src/Sema.zig+79-26
...@@ -8957,9 +8957,21 @@ fn intCast(...@@ -8957,9 +8957,21 @@ fn intCast(
8957 const wanted_bits = wanted_info.bits;8957 const wanted_bits = wanted_info.bits;
89588958
8959 if (wanted_bits == 0) {8959 if (wanted_bits == 0) {
8960 const zero_inst = try sema.addConstant(sema.typeOf(operand), Value.zero);8960 const ok = if (is_vector) ok: {
8961 const is_in_range = try block.addBinOp(.cmp_eq, operand, zero_inst);8961 const zeros = try Value.Tag.repeated.create(sema.arena, Value.zero);
8962 try sema.addSafetyCheck(block, is_in_range, .cast_truncated_data);8962 const zero_inst = try sema.addConstant(sema.typeOf(operand), zeros);
8963 const is_in_range = try block.addCmpVector(operand, zero_inst, .eq, try sema.addType(operand_ty));
8964 const all_in_range = try block.addInst(.{
8965 .tag = .reduce,
8966 .data = .{ .reduce = .{ .operand = is_in_range, .operation = .And } },
8967 });
8968 break :ok all_in_range;
8969 } else ok: {
8970 const zero_inst = try sema.addConstant(sema.typeOf(operand), Value.zero);
8971 const is_in_range = try block.addBinOp(.cmp_lte, operand, zero_inst);
8972 break :ok is_in_range;
8973 };
8974 try sema.addSafetyCheck(block, ok, .cast_truncated_data);
8963 }8975 }
8964 }8976 }
89658977
...@@ -12376,6 +12388,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -12376,6 +12388,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
12376 .override = &[_]LazySrcLoc{ lhs_src, rhs_src },12388 .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
12377 });12389 });
1237812390
12391 const is_vector = resolved_type.zigTypeTag() == .Vector;
12392
12379 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);12393 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
12380 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);12394 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1238112395
...@@ -12439,7 +12453,10 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -12439,7 +12453,10 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
12439 if (maybe_lhs_val) |lhs_val| {12453 if (maybe_lhs_val) |lhs_val| {
12440 if (!lhs_val.isUndef()) {12454 if (!lhs_val.isUndef()) {
12441 if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {12455 if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {
12442 return sema.addConstant(resolved_type, Value.zero);12456 const zero_val = if (is_vector) b: {
12457 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);
12458 } else Value.zero;
12459 return sema.addConstant(resolved_type, zero_val);
12443 }12460 }
12444 }12461 }
12445 }12462 }
...@@ -12532,6 +12549,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12532,6 +12549,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12532 .override = &[_]LazySrcLoc{ lhs_src, rhs_src },12549 .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
12533 });12550 });
1253412551
12552 const is_vector = resolved_type.zigTypeTag() == .Vector;
12553
12535 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);12554 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
12536 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);12555 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1253712556
...@@ -12569,7 +12588,10 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12569,7 +12588,10 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12569 return sema.failWithUseOfUndef(block, rhs_src);12588 return sema.failWithUseOfUndef(block, rhs_src);
12570 } else {12589 } else {
12571 if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {12590 if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {
12572 return sema.addConstant(resolved_type, Value.zero);12591 const zero_val = if (is_vector) b: {
12592 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);
12593 } else Value.zero;
12594 return sema.addConstant(resolved_type, zero_val);
12573 }12595 }
12574 }12596 }
12575 }12597 }
...@@ -12691,6 +12713,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12691,6 +12713,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12691 .override = &[_]LazySrcLoc{ lhs_src, rhs_src },12713 .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
12692 });12714 });
1269312715
12716 const is_vector = resolved_type.zigTypeTag() == .Vector;
12717
12694 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);12718 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
12695 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);12719 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1269612720
...@@ -12730,7 +12754,10 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12730,7 +12754,10 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12730 if (maybe_lhs_val) |lhs_val| {12754 if (maybe_lhs_val) |lhs_val| {
12731 if (!lhs_val.isUndef()) {12755 if (!lhs_val.isUndef()) {
12732 if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {12756 if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {
12733 return sema.addConstant(resolved_type, Value.zero);12757 const zero_val = if (is_vector) b: {
12758 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);
12759 } else Value.zero;
12760 return sema.addConstant(resolved_type, zero_val);
12734 }12761 }
12735 }12762 }
12736 }12763 }
...@@ -12803,6 +12830,8 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12803,6 +12830,8 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12803 .override = &[_]LazySrcLoc{ lhs_src, rhs_src },12830 .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
12804 });12831 });
1280512832
12833 const is_vector = resolved_type.zigTypeTag() == .Vector;
12834
12806 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);12835 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
12807 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);12836 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1280812837
...@@ -12842,7 +12871,10 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12842,7 +12871,10 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12842 if (maybe_lhs_val) |lhs_val| {12871 if (maybe_lhs_val) |lhs_val| {
12843 if (!lhs_val.isUndef()) {12872 if (!lhs_val.isUndef()) {
12844 if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {12873 if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {
12845 return sema.addConstant(resolved_type, Value.zero);12874 const zero_val = if (is_vector) b: {
12875 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);
12876 } else Value.zero;
12877 return sema.addConstant(resolved_type, zero_val);
12846 }12878 }
12847 }12879 }
12848 }12880 }
...@@ -13042,6 +13074,8 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13042,6 +13074,8 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13042 .override = &[_]LazySrcLoc{ lhs_src, rhs_src },13074 .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
13043 });13075 });
1304413076
13077 const is_vector = resolved_type.zigTypeTag() == .Vector;
13078
13045 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);13079 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
13046 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);13080 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1304713081
...@@ -13078,7 +13112,10 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13078,7 +13112,10 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13078 return sema.failWithUseOfUndef(block, lhs_src);13112 return sema.failWithUseOfUndef(block, lhs_src);
13079 }13113 }
13080 if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {13114 if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {
13081 return sema.addConstant(resolved_type, Value.zero);13115 const zero_val = if (is_vector) b: {
13116 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);
13117 } else Value.zero;
13118 return sema.addConstant(resolved_type, zero_val);
13082 }13119 }
13083 } else if (lhs_scalar_ty.isSignedInt()) {13120 } else if (lhs_scalar_ty.isSignedInt()) {
13084 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);13121 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
...@@ -13087,25 +13124,19 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13087,25 +13124,19 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13087 if (rhs_val.isUndef()) {13124 if (rhs_val.isUndef()) {
13088 return sema.failWithUseOfUndef(block, rhs_src);13125 return sema.failWithUseOfUndef(block, rhs_src);
13089 }13126 }
13090 if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {13127 switch (try rhs_val.orderAgainstZeroAdvanced(sema.kit(block, src))) {
13091 return sema.failWithDivideByZero(block, rhs_src);13128 .lt => return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty),
13129 .eq => return sema.failWithDivideByZero(block, rhs_src),
13130 .gt => {},
13092 }13131 }
13093 if (maybe_lhs_val) |lhs_val| {13132 if (maybe_lhs_val) |lhs_val| {
13094 const rem_result = try sema.intRem(block, resolved_type, lhs_val, lhs_src, rhs_val, rhs_src);13133 const rem_result = try sema.intRem(block, resolved_type, lhs_val, lhs_src, rhs_val, rhs_src);
13095 // If this answer could possibly be different by doing `intMod`,13134 // If this answer could possibly be different by doing `intMod`,
13096 // we must emit a compile error. Otherwise, it's OK.13135 // we must emit a compile error. Otherwise, it's OK.
13097 if ((try rhs_val.compareWithZeroAdvanced(.lt, sema.kit(block, src))) != (try lhs_val.compareWithZeroAdvanced(.lt, sema.kit(block, src))) and13136 if ((try lhs_val.compareWithZeroAdvanced(.lt, sema.kit(block, src))) and
13098 !(try rem_result.compareWithZeroAdvanced(.eq, sema.kit(block, src))))13137 !(try rem_result.compareWithZeroAdvanced(.eq, sema.kit(block, src))))
13099 {13138 {
13100 const bad_src = if (try lhs_val.compareWithZeroAdvanced(.lt, sema.kit(block, src)))13139 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
13101 lhs_src
13102 else
13103 rhs_src;
13104 return sema.failWithModRemNegative(block, bad_src, lhs_ty, rhs_ty);
13105 }
13106 if (try lhs_val.compareWithZeroAdvanced(.lt, sema.kit(block, src))) {
13107 // Negative
13108 return sema.addConstant(resolved_type, Value.zero);
13109 }13140 }
13110 return sema.addConstant(resolved_type, rem_result);13141 return sema.addConstant(resolved_type, rem_result);
13111 }13142 }
...@@ -13671,6 +13702,8 @@ fn analyzeArithmetic(...@@ -13671,6 +13702,8 @@ fn analyzeArithmetic(
13671 .override = &[_]LazySrcLoc{ lhs_src, rhs_src },13702 .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
13672 });13703 });
1367313704
13705 const is_vector = resolved_type.zigTypeTag() == .Vector;
13706
13674 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);13707 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
13675 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);13708 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1367613709
...@@ -13897,7 +13930,10 @@ fn analyzeArithmetic(...@@ -13897,7 +13930,10 @@ fn analyzeArithmetic(
13897 if (maybe_lhs_val) |lhs_val| {13930 if (maybe_lhs_val) |lhs_val| {
13898 if (!lhs_val.isUndef()) {13931 if (!lhs_val.isUndef()) {
13899 if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {13932 if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {
13900 return sema.addConstant(resolved_type, Value.zero);13933 const zero_val = if (is_vector) b: {
13934 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);
13935 } else Value.zero;
13936 return sema.addConstant(resolved_type, zero_val);
13901 }13937 }
13902 if (try sema.compare(block, src, lhs_val, .eq, Value.one, resolved_type)) {13938 if (try sema.compare(block, src, lhs_val, .eq, Value.one, resolved_type)) {
13903 return casted_rhs;13939 return casted_rhs;
...@@ -13914,7 +13950,10 @@ fn analyzeArithmetic(...@@ -13914,7 +13950,10 @@ fn analyzeArithmetic(
13914 }13950 }
13915 }13951 }
13916 if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {13952 if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {
13917 return sema.addConstant(resolved_type, Value.zero);13953 const zero_val = if (is_vector) b: {
13954 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);
13955 } else Value.zero;
13956 return sema.addConstant(resolved_type, zero_val);
13918 }13957 }
13919 if (try sema.compare(block, src, rhs_val, .eq, Value.one, resolved_type)) {13958 if (try sema.compare(block, src, rhs_val, .eq, Value.one, resolved_type)) {
13920 return casted_lhs;13959 return casted_lhs;
...@@ -13951,7 +13990,10 @@ fn analyzeArithmetic(...@@ -13951,7 +13990,10 @@ fn analyzeArithmetic(
13951 if (maybe_lhs_val) |lhs_val| {13990 if (maybe_lhs_val) |lhs_val| {
13952 if (!lhs_val.isUndef()) {13991 if (!lhs_val.isUndef()) {
13953 if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {13992 if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {
13954 return sema.addConstant(resolved_type, Value.zero);13993 const zero_val = if (is_vector) b: {
13994 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);
13995 } else Value.zero;
13996 return sema.addConstant(resolved_type, zero_val);
13955 }13997 }
13956 if (try sema.compare(block, src, lhs_val, .eq, Value.one, resolved_type)) {13998 if (try sema.compare(block, src, lhs_val, .eq, Value.one, resolved_type)) {
13957 return casted_rhs;13999 return casted_rhs;
...@@ -13964,7 +14006,10 @@ fn analyzeArithmetic(...@@ -13964,7 +14006,10 @@ fn analyzeArithmetic(
13964 return sema.addConstUndef(resolved_type);14006 return sema.addConstUndef(resolved_type);
13965 }14007 }
13966 if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {14008 if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {
13967 return sema.addConstant(resolved_type, Value.zero);14009 const zero_val = if (is_vector) b: {
14010 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);
14011 } else Value.zero;
14012 return sema.addConstant(resolved_type, zero_val);
13968 }14013 }
13969 if (try sema.compare(block, src, rhs_val, .eq, Value.one, resolved_type)) {14014 if (try sema.compare(block, src, rhs_val, .eq, Value.one, resolved_type)) {
13970 return casted_lhs;14015 return casted_lhs;
...@@ -13988,7 +14033,10 @@ fn analyzeArithmetic(...@@ -13988,7 +14033,10 @@ fn analyzeArithmetic(
13988 if (maybe_lhs_val) |lhs_val| {14033 if (maybe_lhs_val) |lhs_val| {
13989 if (!lhs_val.isUndef()) {14034 if (!lhs_val.isUndef()) {
13990 if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {14035 if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {
13991 return sema.addConstant(resolved_type, Value.zero);14036 const zero_val = if (is_vector) b: {
14037 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);
14038 } else Value.zero;
14039 return sema.addConstant(resolved_type, zero_val);
13992 }14040 }
13993 if (try sema.compare(block, src, lhs_val, .eq, Value.one, resolved_type)) {14041 if (try sema.compare(block, src, lhs_val, .eq, Value.one, resolved_type)) {
13994 return casted_rhs;14042 return casted_rhs;
...@@ -14000,7 +14048,10 @@ fn analyzeArithmetic(...@@ -14000,7 +14048,10 @@ fn analyzeArithmetic(
14000 return sema.addConstUndef(resolved_type);14048 return sema.addConstUndef(resolved_type);
14001 }14049 }
14002 if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {14050 if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) {
14003 return sema.addConstant(resolved_type, Value.zero);14051 const zero_val = if (is_vector) b: {
14052 break :b try Value.Tag.repeated.create(sema.arena, Value.zero);
14053 } else Value.zero;
14054 return sema.addConstant(resolved_type, zero_val);
14004 }14055 }
14005 if (try sema.compare(block, src, rhs_val, .eq, Value.one, resolved_type)) {14056 if (try sema.compare(block, src, rhs_val, .eq, Value.one, resolved_type)) {
14006 return casted_lhs;14057 return casted_lhs;
...@@ -31735,6 +31786,8 @@ fn floatToIntScalar(...@@ -31735,6 +31786,8 @@ fn floatToIntScalar(
3173531786
31736/// Asserts the value is an integer, and the destination type is ComptimeInt or Int.31787/// Asserts the value is an integer, and the destination type is ComptimeInt or Int.
31737/// Vectors are also accepted. Vector results are reduced with AND.31788/// Vectors are also accepted. Vector results are reduced with AND.
31789///
31790/// If provided, `vector_index` reports the first element that failed the range check.
31738fn intFitsInType(31791fn intFitsInType(
31739 sema: *Sema,31792 sema: *Sema,
31740 block: *Block,31793 block: *Block,
test/behavior/vector.zig+66-5
...@@ -1136,11 +1136,6 @@ test "array of vectors is copied" {...@@ -1136,11 +1136,6 @@ test "array of vectors is copied" {
1136}1136}
11371137
1138test "byte vector initialized in inline function" {1138test "byte vector initialized in inline function" {
1139 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1140 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1141 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1142 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1143
1144 const S = struct {1139 const S = struct {
1145 inline fn boolx4(e0: bool, e1: bool, e2: bool, e3: bool) @Vector(4, bool) {1140 inline fn boolx4(e0: bool, e1: bool, e2: bool, e3: bool) @Vector(4, bool) {
1146 return .{ e0, e1, e2, e3 };1141 return .{ e0, e1, e2, e3 };
...@@ -1170,3 +1165,69 @@ test "byte vector initialized in inline function" {...@@ -1170,3 +1165,69 @@ test "byte vector initialized in inline function" {
11701165
1171 try expect(S.all(S.boolx4(true, true, true, true)));1166 try expect(S.all(S.boolx4(true, true, true, true)));
1172}1167}
1168
1169test "zero divisor" {
1170 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; // TODO
1173 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1174
1175 const zeros = @Vector(2, f32){ 0.0, 0.0 };
1176 const ones = @Vector(2, f32){ 1.0, 1.0 };
1177
1178 const v1 = zeros / ones;
1179 const v2 = @divExact(zeros, ones);
1180 const v3 = @divTrunc(zeros, ones);
1181 const v4 = @divFloor(zeros, ones);
1182
1183 _ = v1[0];
1184 _ = v2[0];
1185 _ = v3[0];
1186 _ = v4[0];
1187}
1188
1189test "zero multiplicand" {
1190 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1191 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1192 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1193 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1194 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1195
1196 const zeros = @Vector(2, u32){ 0.0, 0.0 };
1197 var ones = @Vector(2, u32){ 1.0, 1.0 };
1198
1199 _ = (ones * zeros)[0];
1200 _ = (zeros * zeros)[0];
1201 _ = (zeros * ones)[0];
1202
1203 _ = (ones *| zeros)[0];
1204 _ = (zeros *| zeros)[0];
1205 _ = (zeros *| ones)[0];
1206
1207 _ = (ones *% zeros)[0];
1208 _ = (zeros *% zeros)[0];
1209 _ = (zeros *% ones)[0];
1210}
1211
1212test "@intCast to u0" {
1213 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1214 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1215 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1216 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1217 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1218
1219 var zeros = @Vector(2, u32){ 0, 0 };
1220 const casted = @intCast(@Vector(2, u0), zeros);
1221
1222 _ = casted[0];
1223}
1224
1225test "modRem with zero divisor" {
1226 comptime {
1227 var zeros = @Vector(2, u32){ 0, 0 };
1228 const ones = @Vector(2, u32){ 1, 1 };
1229
1230 zeros %= ones;
1231 _ = zeros[0];
1232 }
1233}