Skip to content

Commit

Permalink
Merge pull request #13074 from topolarity/stage2-opt
Browse files Browse the repository at this point in the history
stage2: Miscellaneous fixes to vector arithmetic and copy elision
  • Loading branch information
andrewrk committed Jan 9, 2023
1 parent b931889 commit 48798da
Show file tree
Hide file tree
Showing 12 changed files with 522 additions and 257 deletions.
6 changes: 3 additions & 3 deletions src/RangeSet.zig
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ pub fn add(
src: SwitchProngSrc,
) !?SwitchProngSrc {
for (self.ranges.items) |range| {
if (last.compare(.gte, range.first, ty, self.module) and
first.compare(.lte, range.last, ty, self.module))
if (last.compareAll(.gte, range.first, ty, self.module) and
first.compareAll(.lte, range.last, ty, self.module))
{
return range.src; // They overlap.
}
Expand All @@ -53,7 +53,7 @@ const LessThanContext = struct { ty: Type, module: *Module };

/// Assumes a and b do not overlap
fn lessThan(ctx: LessThanContext, a: Range, b: Range) bool {
return a.first.compare(.lt, b.first, ctx.ty, ctx.module);
return a.first.compareAll(.lt, b.first, ctx.ty, ctx.module);
}

pub fn spans(self: *RangeSet, first: Value, last: Value, ty: Type) !bool {
Expand Down
367 changes: 207 additions & 160 deletions src/Sema.zig

Large diffs are not rendered by default.

218 changes: 142 additions & 76 deletions src/codegen/llvm.zig

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions src/type.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5463,13 +5463,13 @@ pub const Type = extern union {
}
const S = struct {
fn fieldWithRange(int_ty: Type, int_val: Value, end: usize, m: *Module) ?usize {
if (int_val.compareWithZero(.lt)) return null;
if (int_val.compareAllWithZero(.lt)) return null;
var end_payload: Value.Payload.U64 = .{
.base = .{ .tag = .int_u64 },
.data = end,
};
const end_val = Value.initPayload(&end_payload.base);
if (int_val.compare(.gte, end_val, int_ty, m)) return null;
if (int_val.compareAll(.gte, end_val, int_ty, m)) return null;
return @intCast(usize, int_val.toUnsignedInt(m.getTarget()));
}
};
Expand Down Expand Up @@ -6455,12 +6455,12 @@ pub const Type = extern union {
if (!d.mutable and d.pointee_type.eql(Type.u8, mod)) {
switch (d.size) {
.Slice => {
if (sent.compareWithZero(.eq)) {
if (sent.compareAllWithZero(.eq)) {
return Type.initTag(.const_slice_u8_sentinel_0);
}
},
.Many => {
if (sent.compareWithZero(.eq)) {
if (sent.compareAllWithZero(.eq)) {
return Type.initTag(.manyptr_const_u8_sentinel_0);
}
},
Expand Down
20 changes: 11 additions & 9 deletions src/value.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2039,8 +2039,8 @@ pub const Value = extern union {
}

/// Asserts the values are comparable. Both operands have type `ty`.
/// Vector results will be reduced with AND.
pub fn compare(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, mod: *Module) bool {
/// For vectors, returns true if comparison is true for ALL elements.
pub fn compareAll(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, mod: *Module) bool {
if (ty.zigTypeTag() == .Vector) {
var i: usize = 0;
while (i < ty.vectorLen()) : (i += 1) {
Expand Down Expand Up @@ -2069,21 +2069,23 @@ pub const Value = extern union {
}

/// Asserts the value is comparable.
/// Vector results will be reduced with AND.
pub fn compareWithZero(lhs: Value, op: std.math.CompareOperator) bool {
return compareWithZeroAdvanced(lhs, op, null) catch unreachable;
/// For vectors, returns true if comparison is true for ALL elements.
///
/// Note that `!compareAllWithZero(.eq, ...) != compareAllWithZero(.neq, ...)`
pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator) bool {
return compareAllWithZeroAdvanced(lhs, op, null) catch unreachable;
}

pub fn compareWithZeroAdvanced(
pub fn compareAllWithZeroAdvanced(
lhs: Value,
op: std.math.CompareOperator,
sema_kit: ?Module.WipAnalysis,
) Module.CompileError!bool {
switch (lhs.tag()) {
.repeated => return lhs.castTag(.repeated).?.data.compareWithZeroAdvanced(op, sema_kit),
.repeated => return lhs.castTag(.repeated).?.data.compareAllWithZeroAdvanced(op, sema_kit),
.aggregate => {
for (lhs.castTag(.aggregate).?.data) |elem_val| {
if (!(try elem_val.compareWithZeroAdvanced(op, sema_kit))) return false;
if (!(try elem_val.compareAllWithZeroAdvanced(op, sema_kit))) return false;
}
return true;
},
Expand Down Expand Up @@ -3081,7 +3083,7 @@ pub const Value = extern union {
.int_i64,
.int_big_positive,
.int_big_negative,
=> compareWithZero(self, .eq),
=> compareAllWithZero(self, .eq),

.undef => unreachable,
.unreachable_value => unreachable,
Expand Down
5 changes: 5 additions & 0 deletions test/behavior.zig
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ test {
_ = @import("behavior/bugs/12003.zig");
_ = @import("behavior/bugs/12025.zig");
_ = @import("behavior/bugs/12033.zig");
_ = @import("behavior/bugs/12043.zig");
_ = @import("behavior/bugs/12430.zig");
_ = @import("behavior/bugs/12486.zig");
_ = @import("behavior/bugs/12488.zig");
Expand All @@ -104,7 +105,10 @@ test {
_ = @import("behavior/bugs/12945.zig");
_ = @import("behavior/bugs/12972.zig");
_ = @import("behavior/bugs/12984.zig");
_ = @import("behavior/bugs/13064.zig");
_ = @import("behavior/bugs/13065.zig");
_ = @import("behavior/bugs/13068.zig");
_ = @import("behavior/bugs/13069.zig");
_ = @import("behavior/bugs/13112.zig");
_ = @import("behavior/bugs/13128.zig");
_ = @import("behavior/bugs/13164.zig");
Expand Down Expand Up @@ -210,6 +214,7 @@ test {
builtin.zig_backend != .stage2_wasm and
builtin.zig_backend != .stage2_c)
{
_ = @import("behavior/bugs/13063.zig");
_ = @import("behavior/bugs/11227.zig");
_ = @import("behavior/export.zig");
}
Expand Down
12 changes: 12 additions & 0 deletions test/behavior/bugs/12043.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const std = @import("std");
const expect = std.testing.expect;

var ok = false;
fn foo(x: anytype) void {
ok = x;
}
test {
const x = &foo;
x(true);
try expect(ok);
}
16 changes: 16 additions & 0 deletions test/behavior/bugs/13063.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const std = @import("std");
const expect = std.testing.expect;

var pos = [2]f32{ 0.0, 0.0 };
test "store to global array" {
try expect(pos[1] == 0.0);
pos = [2]f32{ 0.0, 1.0 };
try expect(pos[1] == 1.0);
}

var vpos = @Vector(2, f32){ 0.0, 0.0 };
test "store to global vector" {
try expect(vpos[1] == 0.0);
vpos = @Vector(2, f32){ 0.0, 1.0 };
try expect(vpos[1] == 1.0);
}
17 changes: 17 additions & 0 deletions test/behavior/bugs/13064.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const std = @import("std");
const builtin = @import("builtin");
const expect = std.testing.expect;

test {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO

var x: [10][10]u32 = undefined;

x[0][1] = 0;
const a = x[0];
x[0][1] = 15;

try expect(a[1] == 0);
}
22 changes: 22 additions & 0 deletions test/behavior/bugs/13065.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const std = @import("std");
const builtin = @import("builtin");
const expect = std.testing.expect;

const U = union(enum) {
array: [10]u32,
other: u32,
};

test {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO

var x = U{ .array = undefined };

x.array[1] = 0;
const a = x.array;
x.array[1] = 15;

try expect(a[1] == 0);
}
17 changes: 17 additions & 0 deletions test/behavior/bugs/13069.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const std = @import("std");
const builtin = @import("builtin");
const expect = std.testing.expect;

test {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO

var opt_x: ?[3]f32 = [_]f32{0.0} ** 3;

const x = opt_x.?;
opt_x.?[0] = 15.0;

try expect(x[0] == 0.0);
}
71 changes: 66 additions & 5 deletions test/behavior/vector.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1136,11 +1136,6 @@ test "array of vectors is copied" {
}

test "byte vector initialized in inline function" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO

const S = struct {
inline fn boolx4(e0: bool, e1: bool, e2: bool, e3: bool) @Vector(4, bool) {
return .{ e0, e1, e2, e3 };
Expand Down Expand Up @@ -1170,3 +1165,69 @@ test "byte vector initialized in inline function" {

try expect(S.all(S.boolx4(true, true, true, true)));
}

test "zero divisor" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO

const zeros = @Vector(2, f32){ 0.0, 0.0 };
const ones = @Vector(2, f32){ 1.0, 1.0 };

const v1 = zeros / ones;
const v2 = @divExact(zeros, ones);
const v3 = @divTrunc(zeros, ones);
const v4 = @divFloor(zeros, ones);

_ = v1[0];
_ = v2[0];
_ = v3[0];
_ = v4[0];
}

test "zero multiplicand" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO

const zeros = @Vector(2, u32){ 0.0, 0.0 };
var ones = @Vector(2, u32){ 1.0, 1.0 };

_ = (ones * zeros)[0];
_ = (zeros * zeros)[0];
_ = (zeros * ones)[0];

_ = (ones *| zeros)[0];
_ = (zeros *| zeros)[0];
_ = (zeros *| ones)[0];

_ = (ones *% zeros)[0];
_ = (zeros *% zeros)[0];
_ = (zeros *% ones)[0];
}

test "@intCast to u0" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO

var zeros = @Vector(2, u32){ 0, 0 };
const casted = @intCast(@Vector(2, u0), zeros);

_ = casted[0];
}

test "modRem with zero divisor" {
comptime {
var zeros = @Vector(2, u32){ 0, 0 };
const ones = @Vector(2, u32){ 1, 1 };

zeros %= ones;
_ = zeros[0];
}
}

0 comments on commit 48798da

Please sign in to comment.