Commit 4cb5fed10b

Andrew Kelley <andrew@ziglang.org>
2021-10-21 00:11:27
AstGen: make the index variable of `inline for` a `alloc_comptime`
Before it was being emitted as an `alloc` which caused inline for loops to not work correctly.
1 parent 361217b
src/AstGen.zig
@@ -5735,7 +5735,8 @@ fn forExpr(
     const len = try parent_gz.addUnNode(.indexable_ptr_len, array_ptr, for_full.ast.cond_expr);
 
     const index_ptr = blk: {
-        const index_ptr = try parent_gz.addUnNode(.alloc, .usize_type, node);
+        const alloc_tag: Zir.Inst.Tag = if (is_inline) .alloc_comptime else .alloc;
+        const index_ptr = try parent_gz.addUnNode(alloc_tag, .usize_type, node);
         // initialize to zero
         _ = try parent_gz.addBin(.store, index_ptr, .zero_usize);
         break :blk index_ptr;
test/behavior/eval.zig
@@ -368,3 +368,25 @@ test "return 0 from function that has u0 return type" {
         }
     }
 }
+
+test "statically initialized struct" {
+    st_init_str_foo.x += 1;
+    try expect(st_init_str_foo.x == 14);
+}
+const StInitStrFoo = struct {
+    x: i32,
+    y: bool,
+};
+var st_init_str_foo = StInitStrFoo{
+    .x = 13,
+    .y = true,
+};
+
+test "inline for with same type but different values" {
+    var res: usize = 0;
+    inline for ([_]type{ [2]u8, [1]u8, [2]u8 }) |T| {
+        var a: T = undefined;
+        res += a.len;
+    }
+    try expect(res == 5);
+}
test/behavior/eval_stage1.zig
@@ -12,27 +12,10 @@ pub const Vec3 = struct {
 };
 pub fn vec3(x: f32, y: f32, z: f32) Vec3 {
     return Vec3{
-        .data = [_]f32{
-            x,
-            y,
-            z,
-        },
+        .data = [_]f32{ x, y, z },
     };
 }
 
-test "statically initialized struct" {
-    st_init_str_foo.x += 1;
-    try expect(st_init_str_foo.x == 14);
-}
-const StInitStrFoo = struct {
-    x: i32,
-    y: bool,
-};
-var st_init_str_foo = StInitStrFoo{
-    .x = 13,
-    .y = true,
-};
-
 test "inlined loop has array literal with elided runtime scope on first iteration but not second iteration" {
     var runtime = [1]i32{3};
     comptime var i: usize = 0;
@@ -301,15 +284,6 @@ fn testVarInsideInlineLoop(args: anytype) !void {
     }
 }
 
-test "inline for with same type but different values" {
-    var res: usize = 0;
-    inline for ([_]type{ [2]u8, [1]u8, [2]u8 }) |T| {
-        var a: T = undefined;
-        res += a.len;
-    }
-    try expect(res == 5);
-}
-
 test "bit shift a u1" {
     var x: u1 = 1;
     var y = x << 0;
test/behavior/floatop.zig
@@ -7,403 +7,6 @@ const Vector = std.meta.Vector;
 
 const epsilon = 0.000001;
 
-test "@sqrt" {
-    comptime try testSqrt();
-    try testSqrt();
-}
-
-fn testSqrt() !void {
-    {
-        var a: f16 = 4;
-        try expect(@sqrt(a) == 2);
-    }
-    {
-        var a: f32 = 9;
-        try expect(@sqrt(a) == 3);
-        var b: f32 = 1.1;
-        try expect(math.approxEqAbs(f32, @sqrt(b), 1.0488088481701516, epsilon));
-    }
-    {
-        var a: f64 = 25;
-        try expect(@sqrt(a) == 5);
-    }
-    {
-        const a: comptime_float = 25.0;
-        try expect(@sqrt(a) == 5.0);
-    }
-    // TODO https://github.com/ziglang/zig/issues/4026
-    //{
-    //    var a: f128 = 49;
-    //try expect(@sqrt(a) == 7);
-    //}
-    {
-        var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 };
-        var result = @sqrt(v);
-        try expect(math.approxEqAbs(f32, @sqrt(@as(f32, 1.1)), result[0], epsilon));
-        try expect(math.approxEqAbs(f32, @sqrt(@as(f32, 2.2)), result[1], epsilon));
-        try expect(math.approxEqAbs(f32, @sqrt(@as(f32, 3.3)), result[2], epsilon));
-        try expect(math.approxEqAbs(f32, @sqrt(@as(f32, 4.4)), result[3], epsilon));
-    }
-}
-
-test "more @sqrt f16 tests" {
-    // TODO these are not all passing at comptime
-    try expect(@sqrt(@as(f16, 0.0)) == 0.0);
-    try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 2.0)), 1.414214, epsilon));
-    try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 3.6)), 1.897367, epsilon));
-    try expect(@sqrt(@as(f16, 4.0)) == 2.0);
-    try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 7.539840)), 2.745877, epsilon));
-    try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 19.230934)), 4.385309, epsilon));
-    try expect(@sqrt(@as(f16, 64.0)) == 8.0);
-    try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 64.1)), 8.006248, epsilon));
-    try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 8942.230469)), 94.563370, epsilon));
-
-    // special cases
-    try expect(math.isPositiveInf(@sqrt(@as(f16, math.inf(f16)))));
-    try expect(@sqrt(@as(f16, 0.0)) == 0.0);
-    try expect(@sqrt(@as(f16, -0.0)) == -0.0);
-    try expect(math.isNan(@sqrt(@as(f16, -1.0))));
-    try expect(math.isNan(@sqrt(@as(f16, math.nan(f16)))));
-}
-
-test "@sin" {
-    comptime try testSin();
-    try testSin();
-}
-
-fn testSin() !void {
-    // TODO test f128, and c_longdouble
-    // https://github.com/ziglang/zig/issues/4026
-    {
-        var a: f16 = 0;
-        try expect(@sin(a) == 0);
-    }
-    {
-        var a: f32 = 0;
-        try expect(@sin(a) == 0);
-    }
-    {
-        var a: f64 = 0;
-        try expect(@sin(a) == 0);
-    }
-    {
-        var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 };
-        var result = @sin(v);
-        try expect(math.approxEqAbs(f32, @sin(@as(f32, 1.1)), result[0], epsilon));
-        try expect(math.approxEqAbs(f32, @sin(@as(f32, 2.2)), result[1], epsilon));
-        try expect(math.approxEqAbs(f32, @sin(@as(f32, 3.3)), result[2], epsilon));
-        try expect(math.approxEqAbs(f32, @sin(@as(f32, 4.4)), result[3], epsilon));
-    }
-}
-
-test "@cos" {
-    comptime try testCos();
-    try testCos();
-}
-
-fn testCos() !void {
-    // TODO test f128, and c_longdouble
-    // https://github.com/ziglang/zig/issues/4026
-    {
-        var a: f16 = 0;
-        try expect(@cos(a) == 1);
-    }
-    {
-        var a: f32 = 0;
-        try expect(@cos(a) == 1);
-    }
-    {
-        var a: f64 = 0;
-        try expect(@cos(a) == 1);
-    }
-    {
-        var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 };
-        var result = @cos(v);
-        try expect(math.approxEqAbs(f32, @cos(@as(f32, 1.1)), result[0], epsilon));
-        try expect(math.approxEqAbs(f32, @cos(@as(f32, 2.2)), result[1], epsilon));
-        try expect(math.approxEqAbs(f32, @cos(@as(f32, 3.3)), result[2], epsilon));
-        try expect(math.approxEqAbs(f32, @cos(@as(f32, 4.4)), result[3], epsilon));
-    }
-}
-
-test "@exp" {
-    comptime try testExp();
-    try testExp();
-}
-
-fn testExp() !void {
-    // TODO test f128, and c_longdouble
-    // https://github.com/ziglang/zig/issues/4026
-    {
-        var a: f16 = 0;
-        try expect(@exp(a) == 1);
-    }
-    {
-        var a: f32 = 0;
-        try expect(@exp(a) == 1);
-    }
-    {
-        var a: f64 = 0;
-        try expect(@exp(a) == 1);
-    }
-    {
-        var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
-        var result = @exp(v);
-        try expect(math.approxEqAbs(f32, @exp(@as(f32, 1.1)), result[0], epsilon));
-        try expect(math.approxEqAbs(f32, @exp(@as(f32, 2.2)), result[1], epsilon));
-        try expect(math.approxEqAbs(f32, @exp(@as(f32, 0.3)), result[2], epsilon));
-        try expect(math.approxEqAbs(f32, @exp(@as(f32, 0.4)), result[3], epsilon));
-    }
-}
-
-test "@exp2" {
-    comptime try testExp2();
-    try testExp2();
-}
-
-fn testExp2() !void {
-    // TODO test f128, and c_longdouble
-    // https://github.com/ziglang/zig/issues/4026
-    {
-        var a: f16 = 2;
-        try expect(@exp2(a) == 4);
-    }
-    {
-        var a: f32 = 2;
-        try expect(@exp2(a) == 4);
-    }
-    {
-        var a: f64 = 2;
-        try expect(@exp2(a) == 4);
-    }
-    {
-        var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
-        var result = @exp2(v);
-        try expect(math.approxEqAbs(f32, @exp2(@as(f32, 1.1)), result[0], epsilon));
-        try expect(math.approxEqAbs(f32, @exp2(@as(f32, 2.2)), result[1], epsilon));
-        try expect(math.approxEqAbs(f32, @exp2(@as(f32, 0.3)), result[2], epsilon));
-        try expect(math.approxEqAbs(f32, @exp2(@as(f32, 0.4)), result[3], epsilon));
-    }
-}
-
-test "@log" {
-    // Old musl (and glibc?), and our current math.ln implementation do not return 1
-    // so also accept those values.
-    comptime try testLog();
-    try testLog();
-}
-
-fn testLog() !void {
-    // TODO test f128, and c_longdouble
-    // https://github.com/ziglang/zig/issues/4026
-    {
-        var a: f16 = e;
-        try expect(math.approxEqAbs(f16, @log(a), 1, epsilon));
-    }
-    {
-        var a: f32 = e;
-        try expect(@log(a) == 1 or @log(a) == @bitCast(f32, @as(u32, 0x3f7fffff)));
-    }
-    {
-        var a: f64 = e;
-        try expect(@log(a) == 1 or @log(a) == @bitCast(f64, @as(u64, 0x3ff0000000000000)));
-    }
-    {
-        var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
-        var result = @log(v);
-        try expect(math.approxEqAbs(f32, @log(@as(f32, 1.1)), result[0], epsilon));
-        try expect(math.approxEqAbs(f32, @log(@as(f32, 2.2)), result[1], epsilon));
-        try expect(math.approxEqAbs(f32, @log(@as(f32, 0.3)), result[2], epsilon));
-        try expect(math.approxEqAbs(f32, @log(@as(f32, 0.4)), result[3], epsilon));
-    }
-}
-
-test "@log2" {
-    comptime try testLog2();
-    try testLog2();
-}
-
-fn testLog2() !void {
-    // TODO test f128, and c_longdouble
-    // https://github.com/ziglang/zig/issues/4026
-    {
-        var a: f16 = 4;
-        try expect(@log2(a) == 2);
-    }
-    {
-        var a: f32 = 4;
-        try expect(@log2(a) == 2);
-    }
-    {
-        var a: f64 = 4;
-        try expect(@log2(a) == 2);
-    }
-    {
-        var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
-        var result = @log2(v);
-        try expect(math.approxEqAbs(f32, @log2(@as(f32, 1.1)), result[0], epsilon));
-        try expect(math.approxEqAbs(f32, @log2(@as(f32, 2.2)), result[1], epsilon));
-        try expect(math.approxEqAbs(f32, @log2(@as(f32, 0.3)), result[2], epsilon));
-        try expect(math.approxEqAbs(f32, @log2(@as(f32, 0.4)), result[3], epsilon));
-    }
-}
-
-test "@log10" {
-    comptime try testLog10();
-    try testLog10();
-}
-
-fn testLog10() !void {
-    // TODO test f128, and c_longdouble
-    // https://github.com/ziglang/zig/issues/4026
-    {
-        var a: f16 = 100;
-        try expect(@log10(a) == 2);
-    }
-    {
-        var a: f32 = 100;
-        try expect(@log10(a) == 2);
-    }
-    {
-        var a: f64 = 1000;
-        try expect(@log10(a) == 3);
-    }
-    {
-        var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
-        var result = @log10(v);
-        try expect(math.approxEqAbs(f32, @log10(@as(f32, 1.1)), result[0], epsilon));
-        try expect(math.approxEqAbs(f32, @log10(@as(f32, 2.2)), result[1], epsilon));
-        try expect(math.approxEqAbs(f32, @log10(@as(f32, 0.3)), result[2], epsilon));
-        try expect(math.approxEqAbs(f32, @log10(@as(f32, 0.4)), result[3], epsilon));
-    }
-}
-
-test "@fabs" {
-    comptime try testFabs();
-    try testFabs();
-}
-
-fn testFabs() !void {
-    // TODO test f128, and c_longdouble
-    // https://github.com/ziglang/zig/issues/4026
-    {
-        var a: f16 = -2.5;
-        var b: f16 = 2.5;
-        try expect(@fabs(a) == 2.5);
-        try expect(@fabs(b) == 2.5);
-    }
-    {
-        var a: f32 = -2.5;
-        var b: f32 = 2.5;
-        try expect(@fabs(a) == 2.5);
-        try expect(@fabs(b) == 2.5);
-    }
-    {
-        var a: f64 = -2.5;
-        var b: f64 = 2.5;
-        try expect(@fabs(a) == 2.5);
-        try expect(@fabs(b) == 2.5);
-    }
-    {
-        var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
-        var result = @fabs(v);
-        try expect(math.approxEqAbs(f32, @fabs(@as(f32, 1.1)), result[0], epsilon));
-        try expect(math.approxEqAbs(f32, @fabs(@as(f32, -2.2)), result[1], epsilon));
-        try expect(math.approxEqAbs(f32, @fabs(@as(f32, 0.3)), result[2], epsilon));
-        try expect(math.approxEqAbs(f32, @fabs(@as(f32, -0.4)), result[3], epsilon));
-    }
-}
-
-test "@floor" {
-    comptime try testFloor();
-    try testFloor();
-}
-
-fn testFloor() !void {
-    // TODO test f128, and c_longdouble
-    // https://github.com/ziglang/zig/issues/4026
-    {
-        var a: f16 = 2.1;
-        try expect(@floor(a) == 2);
-    }
-    {
-        var a: f32 = 2.1;
-        try expect(@floor(a) == 2);
-    }
-    {
-        var a: f64 = 3.5;
-        try expect(@floor(a) == 3);
-    }
-    {
-        var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
-        var result = @floor(v);
-        try expect(math.approxEqAbs(f32, @floor(@as(f32, 1.1)), result[0], epsilon));
-        try expect(math.approxEqAbs(f32, @floor(@as(f32, -2.2)), result[1], epsilon));
-        try expect(math.approxEqAbs(f32, @floor(@as(f32, 0.3)), result[2], epsilon));
-        try expect(math.approxEqAbs(f32, @floor(@as(f32, -0.4)), result[3], epsilon));
-    }
-}
-
-test "@ceil" {
-    comptime try testCeil();
-    try testCeil();
-}
-
-fn testCeil() !void {
-    // TODO test f128, and c_longdouble
-    // https://github.com/ziglang/zig/issues/4026
-    {
-        var a: f16 = 2.1;
-        try expect(@ceil(a) == 3);
-    }
-    {
-        var a: f32 = 2.1;
-        try expect(@ceil(a) == 3);
-    }
-    {
-        var a: f64 = 3.5;
-        try expect(@ceil(a) == 4);
-    }
-    {
-        var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
-        var result = @ceil(v);
-        try expect(math.approxEqAbs(f32, @ceil(@as(f32, 1.1)), result[0], epsilon));
-        try expect(math.approxEqAbs(f32, @ceil(@as(f32, -2.2)), result[1], epsilon));
-        try expect(math.approxEqAbs(f32, @ceil(@as(f32, 0.3)), result[2], epsilon));
-        try expect(math.approxEqAbs(f32, @ceil(@as(f32, -0.4)), result[3], epsilon));
-    }
-}
-
-test "@trunc" {
-    comptime try testTrunc();
-    try testTrunc();
-}
-
-fn testTrunc() !void {
-    // TODO test f128, and c_longdouble
-    // https://github.com/ziglang/zig/issues/4026
-    {
-        var a: f16 = 2.1;
-        try expect(@trunc(a) == 2);
-    }
-    {
-        var a: f32 = 2.1;
-        try expect(@trunc(a) == 2);
-    }
-    {
-        var a: f64 = -3.5;
-        try expect(@trunc(a) == -3);
-    }
-    {
-        var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
-        var result = @trunc(v);
-        try expect(math.approxEqAbs(f32, @trunc(@as(f32, 1.1)), result[0], epsilon));
-        try expect(math.approxEqAbs(f32, @trunc(@as(f32, -2.2)), result[1], epsilon));
-        try expect(math.approxEqAbs(f32, @trunc(@as(f32, 0.3)), result[2], epsilon));
-        try expect(math.approxEqAbs(f32, @trunc(@as(f32, -0.4)), result[3], epsilon));
-    }
-}
-
 test "floating point comparisons" {
     try testFloatComparisons();
     comptime try testFloatComparisons();
test/behavior/floatop_stage1.zig
@@ -0,0 +1,405 @@
+const std = @import("std");
+const expect = std.testing.expect;
+const math = std.math;
+const pi = std.math.pi;
+const e = std.math.e;
+const Vector = std.meta.Vector;
+
+const epsilon = 0.000001;
+
+test "@sqrt" {
+    comptime try testSqrt();
+    try testSqrt();
+}
+
+fn testSqrt() !void {
+    {
+        var a: f16 = 4;
+        try expect(@sqrt(a) == 2);
+    }
+    {
+        var a: f32 = 9;
+        try expect(@sqrt(a) == 3);
+        var b: f32 = 1.1;
+        try expect(math.approxEqAbs(f32, @sqrt(b), 1.0488088481701516, epsilon));
+    }
+    {
+        var a: f64 = 25;
+        try expect(@sqrt(a) == 5);
+    }
+    {
+        const a: comptime_float = 25.0;
+        try expect(@sqrt(a) == 5.0);
+    }
+    // TODO https://github.com/ziglang/zig/issues/4026
+    //{
+    //    var a: f128 = 49;
+    //try expect(@sqrt(a) == 7);
+    //}
+    {
+        var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 };
+        var result = @sqrt(v);
+        try expect(math.approxEqAbs(f32, @sqrt(@as(f32, 1.1)), result[0], epsilon));
+        try expect(math.approxEqAbs(f32, @sqrt(@as(f32, 2.2)), result[1], epsilon));
+        try expect(math.approxEqAbs(f32, @sqrt(@as(f32, 3.3)), result[2], epsilon));
+        try expect(math.approxEqAbs(f32, @sqrt(@as(f32, 4.4)), result[3], epsilon));
+    }
+}
+
+test "more @sqrt f16 tests" {
+    // TODO these are not all passing at comptime
+    try expect(@sqrt(@as(f16, 0.0)) == 0.0);
+    try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 2.0)), 1.414214, epsilon));
+    try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 3.6)), 1.897367, epsilon));
+    try expect(@sqrt(@as(f16, 4.0)) == 2.0);
+    try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 7.539840)), 2.745877, epsilon));
+    try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 19.230934)), 4.385309, epsilon));
+    try expect(@sqrt(@as(f16, 64.0)) == 8.0);
+    try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 64.1)), 8.006248, epsilon));
+    try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 8942.230469)), 94.563370, epsilon));
+
+    // special cases
+    try expect(math.isPositiveInf(@sqrt(@as(f16, math.inf(f16)))));
+    try expect(@sqrt(@as(f16, 0.0)) == 0.0);
+    try expect(@sqrt(@as(f16, -0.0)) == -0.0);
+    try expect(math.isNan(@sqrt(@as(f16, -1.0))));
+    try expect(math.isNan(@sqrt(@as(f16, math.nan(f16)))));
+}
+
+test "@sin" {
+    comptime try testSin();
+    try testSin();
+}
+
+fn testSin() !void {
+    // TODO test f128, and c_longdouble
+    // https://github.com/ziglang/zig/issues/4026
+    {
+        var a: f16 = 0;
+        try expect(@sin(a) == 0);
+    }
+    {
+        var a: f32 = 0;
+        try expect(@sin(a) == 0);
+    }
+    {
+        var a: f64 = 0;
+        try expect(@sin(a) == 0);
+    }
+    {
+        var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 };
+        var result = @sin(v);
+        try expect(math.approxEqAbs(f32, @sin(@as(f32, 1.1)), result[0], epsilon));
+        try expect(math.approxEqAbs(f32, @sin(@as(f32, 2.2)), result[1], epsilon));
+        try expect(math.approxEqAbs(f32, @sin(@as(f32, 3.3)), result[2], epsilon));
+        try expect(math.approxEqAbs(f32, @sin(@as(f32, 4.4)), result[3], epsilon));
+    }
+}
+
+test "@cos" {
+    comptime try testCos();
+    try testCos();
+}
+
+fn testCos() !void {
+    // TODO test f128, and c_longdouble
+    // https://github.com/ziglang/zig/issues/4026
+    {
+        var a: f16 = 0;
+        try expect(@cos(a) == 1);
+    }
+    {
+        var a: f32 = 0;
+        try expect(@cos(a) == 1);
+    }
+    {
+        var a: f64 = 0;
+        try expect(@cos(a) == 1);
+    }
+    {
+        var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 };
+        var result = @cos(v);
+        try expect(math.approxEqAbs(f32, @cos(@as(f32, 1.1)), result[0], epsilon));
+        try expect(math.approxEqAbs(f32, @cos(@as(f32, 2.2)), result[1], epsilon));
+        try expect(math.approxEqAbs(f32, @cos(@as(f32, 3.3)), result[2], epsilon));
+        try expect(math.approxEqAbs(f32, @cos(@as(f32, 4.4)), result[3], epsilon));
+    }
+}
+
+test "@exp" {
+    comptime try testExp();
+    try testExp();
+}
+
+fn testExp() !void {
+    // TODO test f128, and c_longdouble
+    // https://github.com/ziglang/zig/issues/4026
+    {
+        var a: f16 = 0;
+        try expect(@exp(a) == 1);
+    }
+    {
+        var a: f32 = 0;
+        try expect(@exp(a) == 1);
+    }
+    {
+        var a: f64 = 0;
+        try expect(@exp(a) == 1);
+    }
+    {
+        var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
+        var result = @exp(v);
+        try expect(math.approxEqAbs(f32, @exp(@as(f32, 1.1)), result[0], epsilon));
+        try expect(math.approxEqAbs(f32, @exp(@as(f32, 2.2)), result[1], epsilon));
+        try expect(math.approxEqAbs(f32, @exp(@as(f32, 0.3)), result[2], epsilon));
+        try expect(math.approxEqAbs(f32, @exp(@as(f32, 0.4)), result[3], epsilon));
+    }
+}
+
+test "@exp2" {
+    comptime try testExp2();
+    try testExp2();
+}
+
+fn testExp2() !void {
+    // TODO test f128, and c_longdouble
+    // https://github.com/ziglang/zig/issues/4026
+    {
+        var a: f16 = 2;
+        try expect(@exp2(a) == 4);
+    }
+    {
+        var a: f32 = 2;
+        try expect(@exp2(a) == 4);
+    }
+    {
+        var a: f64 = 2;
+        try expect(@exp2(a) == 4);
+    }
+    {
+        var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
+        var result = @exp2(v);
+        try expect(math.approxEqAbs(f32, @exp2(@as(f32, 1.1)), result[0], epsilon));
+        try expect(math.approxEqAbs(f32, @exp2(@as(f32, 2.2)), result[1], epsilon));
+        try expect(math.approxEqAbs(f32, @exp2(@as(f32, 0.3)), result[2], epsilon));
+        try expect(math.approxEqAbs(f32, @exp2(@as(f32, 0.4)), result[3], epsilon));
+    }
+}
+
+test "@log" {
+    // Old musl (and glibc?), and our current math.ln implementation do not return 1
+    // so also accept those values.
+    comptime try testLog();
+    try testLog();
+}
+
+fn testLog() !void {
+    // TODO test f128, and c_longdouble
+    // https://github.com/ziglang/zig/issues/4026
+    {
+        var a: f16 = e;
+        try expect(math.approxEqAbs(f16, @log(a), 1, epsilon));
+    }
+    {
+        var a: f32 = e;
+        try expect(@log(a) == 1 or @log(a) == @bitCast(f32, @as(u32, 0x3f7fffff)));
+    }
+    {
+        var a: f64 = e;
+        try expect(@log(a) == 1 or @log(a) == @bitCast(f64, @as(u64, 0x3ff0000000000000)));
+    }
+    {
+        var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
+        var result = @log(v);
+        try expect(math.approxEqAbs(f32, @log(@as(f32, 1.1)), result[0], epsilon));
+        try expect(math.approxEqAbs(f32, @log(@as(f32, 2.2)), result[1], epsilon));
+        try expect(math.approxEqAbs(f32, @log(@as(f32, 0.3)), result[2], epsilon));
+        try expect(math.approxEqAbs(f32, @log(@as(f32, 0.4)), result[3], epsilon));
+    }
+}
+
+test "@log2" {
+    comptime try testLog2();
+    try testLog2();
+}
+
+fn testLog2() !void {
+    // TODO test f128, and c_longdouble
+    // https://github.com/ziglang/zig/issues/4026
+    {
+        var a: f16 = 4;
+        try expect(@log2(a) == 2);
+    }
+    {
+        var a: f32 = 4;
+        try expect(@log2(a) == 2);
+    }
+    {
+        var a: f64 = 4;
+        try expect(@log2(a) == 2);
+    }
+    {
+        var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
+        var result = @log2(v);
+        try expect(math.approxEqAbs(f32, @log2(@as(f32, 1.1)), result[0], epsilon));
+        try expect(math.approxEqAbs(f32, @log2(@as(f32, 2.2)), result[1], epsilon));
+        try expect(math.approxEqAbs(f32, @log2(@as(f32, 0.3)), result[2], epsilon));
+        try expect(math.approxEqAbs(f32, @log2(@as(f32, 0.4)), result[3], epsilon));
+    }
+}
+
+test "@log10" {
+    comptime try testLog10();
+    try testLog10();
+}
+
+fn testLog10() !void {
+    // TODO test f128, and c_longdouble
+    // https://github.com/ziglang/zig/issues/4026
+    {
+        var a: f16 = 100;
+        try expect(@log10(a) == 2);
+    }
+    {
+        var a: f32 = 100;
+        try expect(@log10(a) == 2);
+    }
+    {
+        var a: f64 = 1000;
+        try expect(@log10(a) == 3);
+    }
+    {
+        var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 };
+        var result = @log10(v);
+        try expect(math.approxEqAbs(f32, @log10(@as(f32, 1.1)), result[0], epsilon));
+        try expect(math.approxEqAbs(f32, @log10(@as(f32, 2.2)), result[1], epsilon));
+        try expect(math.approxEqAbs(f32, @log10(@as(f32, 0.3)), result[2], epsilon));
+        try expect(math.approxEqAbs(f32, @log10(@as(f32, 0.4)), result[3], epsilon));
+    }
+}
+
+test "@fabs" {
+    comptime try testFabs();
+    try testFabs();
+}
+
+fn testFabs() !void {
+    // TODO test f128, and c_longdouble
+    // https://github.com/ziglang/zig/issues/4026
+    {
+        var a: f16 = -2.5;
+        var b: f16 = 2.5;
+        try expect(@fabs(a) == 2.5);
+        try expect(@fabs(b) == 2.5);
+    }
+    {
+        var a: f32 = -2.5;
+        var b: f32 = 2.5;
+        try expect(@fabs(a) == 2.5);
+        try expect(@fabs(b) == 2.5);
+    }
+    {
+        var a: f64 = -2.5;
+        var b: f64 = 2.5;
+        try expect(@fabs(a) == 2.5);
+        try expect(@fabs(b) == 2.5);
+    }
+    {
+        var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
+        var result = @fabs(v);
+        try expect(math.approxEqAbs(f32, @fabs(@as(f32, 1.1)), result[0], epsilon));
+        try expect(math.approxEqAbs(f32, @fabs(@as(f32, -2.2)), result[1], epsilon));
+        try expect(math.approxEqAbs(f32, @fabs(@as(f32, 0.3)), result[2], epsilon));
+        try expect(math.approxEqAbs(f32, @fabs(@as(f32, -0.4)), result[3], epsilon));
+    }
+}
+
+test "@floor" {
+    comptime try testFloor();
+    try testFloor();
+}
+
+fn testFloor() !void {
+    // TODO test f128, and c_longdouble
+    // https://github.com/ziglang/zig/issues/4026
+    {
+        var a: f16 = 2.1;
+        try expect(@floor(a) == 2);
+    }
+    {
+        var a: f32 = 2.1;
+        try expect(@floor(a) == 2);
+    }
+    {
+        var a: f64 = 3.5;
+        try expect(@floor(a) == 3);
+    }
+    {
+        var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
+        var result = @floor(v);
+        try expect(math.approxEqAbs(f32, @floor(@as(f32, 1.1)), result[0], epsilon));
+        try expect(math.approxEqAbs(f32, @floor(@as(f32, -2.2)), result[1], epsilon));
+        try expect(math.approxEqAbs(f32, @floor(@as(f32, 0.3)), result[2], epsilon));
+        try expect(math.approxEqAbs(f32, @floor(@as(f32, -0.4)), result[3], epsilon));
+    }
+}
+
+test "@ceil" {
+    comptime try testCeil();
+    try testCeil();
+}
+
+fn testCeil() !void {
+    // TODO test f128, and c_longdouble
+    // https://github.com/ziglang/zig/issues/4026
+    {
+        var a: f16 = 2.1;
+        try expect(@ceil(a) == 3);
+    }
+    {
+        var a: f32 = 2.1;
+        try expect(@ceil(a) == 3);
+    }
+    {
+        var a: f64 = 3.5;
+        try expect(@ceil(a) == 4);
+    }
+    {
+        var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
+        var result = @ceil(v);
+        try expect(math.approxEqAbs(f32, @ceil(@as(f32, 1.1)), result[0], epsilon));
+        try expect(math.approxEqAbs(f32, @ceil(@as(f32, -2.2)), result[1], epsilon));
+        try expect(math.approxEqAbs(f32, @ceil(@as(f32, 0.3)), result[2], epsilon));
+        try expect(math.approxEqAbs(f32, @ceil(@as(f32, -0.4)), result[3], epsilon));
+    }
+}
+
+test "@trunc" {
+    comptime try testTrunc();
+    try testTrunc();
+}
+
+fn testTrunc() !void {
+    // TODO test f128, and c_longdouble
+    // https://github.com/ziglang/zig/issues/4026
+    {
+        var a: f16 = 2.1;
+        try expect(@trunc(a) == 2);
+    }
+    {
+        var a: f32 = 2.1;
+        try expect(@trunc(a) == 2);
+    }
+    {
+        var a: f64 = -3.5;
+        try expect(@trunc(a) == -3);
+    }
+    {
+        var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 };
+        var result = @trunc(v);
+        try expect(math.approxEqAbs(f32, @trunc(@as(f32, 1.1)), result[0], epsilon));
+        try expect(math.approxEqAbs(f32, @trunc(@as(f32, -2.2)), result[1], epsilon));
+        try expect(math.approxEqAbs(f32, @trunc(@as(f32, 0.3)), result[2], epsilon));
+        try expect(math.approxEqAbs(f32, @trunc(@as(f32, -0.4)), result[3], epsilon));
+    }
+}
test/behavior/for.zig
@@ -2,3 +2,61 @@ const std = @import("std");
 const expect = std.testing.expect;
 const expectEqual = std.testing.expectEqual;
 const mem = std.mem;
+
+test "continue in for loop" {
+    const array = [_]i32{ 1, 2, 3, 4, 5 };
+    var sum: i32 = 0;
+    for (array) |x| {
+        sum += x;
+        if (x < 3) {
+            continue;
+        }
+        break;
+    }
+    if (sum != 6) unreachable;
+}
+
+test "break from outer for loop" {
+    try testBreakOuter();
+    comptime try testBreakOuter();
+}
+
+fn testBreakOuter() !void {
+    var array = "aoeu";
+    var count: usize = 0;
+    outer: for (array) |_| {
+        for (array) |_| {
+            count += 1;
+            break :outer;
+        }
+    }
+    try expect(count == 1);
+}
+
+test "continue outer for loop" {
+    try testContinueOuter();
+    comptime try testContinueOuter();
+}
+
+fn testContinueOuter() !void {
+    var array = "aoeu";
+    var counter: usize = 0;
+    outer: for (array) |_| {
+        for (array) |_| {
+            counter += 1;
+            continue :outer;
+        }
+    }
+    try expect(counter == array.len);
+}
+
+test "ignore lval with underscore (for loop)" {
+    for ([_]void{}) |_, i| {
+        _ = i;
+        for ([_]void{}) |_, j| {
+            _ = j;
+            break;
+        }
+        break;
+    }
+}
test/behavior/for_stage1.zig
@@ -3,19 +3,6 @@ const expect = std.testing.expect;
 const expectEqual = std.testing.expectEqual;
 const mem = std.mem;
 
-test "continue in for loop" {
-    const array = [_]i32{ 1, 2, 3, 4, 5 };
-    var sum: i32 = 0;
-    for (array) |x| {
-        sum += x;
-        if (x < 3) {
-            continue;
-        }
-        break;
-    }
-    if (sum != 6) unreachable;
-}
-
 test "for loop with pointer elem var" {
     const source = "abcdefg";
     var target: [source.len]u8 = undefined;
@@ -78,40 +65,6 @@ test "basic for loop" {
     try expect(mem.eql(u8, buffer[0..buf_index], &expected_result));
 }
 
-test "break from outer for loop" {
-    try testBreakOuter();
-    comptime try testBreakOuter();
-}
-
-fn testBreakOuter() !void {
-    var array = "aoeu";
-    var count: usize = 0;
-    outer: for (array) |_| {
-        for (array) |_| {
-            count += 1;
-            break :outer;
-        }
-    }
-    try expect(count == 1);
-}
-
-test "continue outer for loop" {
-    try testContinueOuter();
-    comptime try testContinueOuter();
-}
-
-fn testContinueOuter() !void {
-    var array = "aoeu";
-    var counter: usize = 0;
-    outer: for (array) |_| {
-        for (array) |_| {
-            counter += 1;
-            continue :outer;
-        }
-    }
-    try expect(counter == array.len);
-}
-
 test "2 break statements and an else" {
     const S = struct {
         fn entry(t: bool, f: bool) !void {
@@ -172,14 +125,3 @@ test "for on slice with allowzero ptr" {
     try S.doTheTest(&[_]u8{ 1, 2, 3, 4 });
     comptime try S.doTheTest(&[_]u8{ 1, 2, 3, 4 });
 }
-
-test "ignore lval with underscore (for loop)" {
-    for ([_]void{}) |_, i| {
-        _ = i;
-        for ([_]void{}) |_, j| {
-            _ = j;
-            break;
-        }
-        break;
-    }
-}
test/behavior.zig
@@ -32,6 +32,7 @@ test {
     _ = @import("behavior/enum.zig");
     _ = @import("behavior/error.zig");
     _ = @import("behavior/eval.zig");
+    _ = @import("behavior/floatop.zig");
     _ = @import("behavior/for.zig");
     _ = @import("behavior/generics.zig");
     _ = @import("behavior/hasdecl.zig");
@@ -123,7 +124,7 @@ test {
         _ = @import("behavior/error_stage1.zig");
         _ = @import("behavior/eval_stage1.zig");
         _ = @import("behavior/field_parent_ptr.zig");
-        _ = @import("behavior/floatop.zig");
+        _ = @import("behavior/floatop_stage1.zig");
         _ = @import("behavior/fn.zig");
         _ = @import("behavior/fn_delegation.zig");
         _ = @import("behavior/fn_in_struct_in_comptime.zig");