Skip to content

#23909 adds __addvsi3, __subvsi3, __mulvsi3, subvdi3 to compiler_rt #24000

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jun 1, 2025
Merged
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ set(ZIG_STAGE2_SOURCES
lib/compiler_rt/absvsi2.zig
lib/compiler_rt/absvti2.zig
lib/compiler_rt/adddf3.zig
lib/compiler_rt/addvsi3.zig
lib/compiler_rt/addf3.zig
lib/compiler_rt/addo.zig
lib/compiler_rt/addsf3.zig
Expand Down Expand Up @@ -323,6 +324,7 @@ set(ZIG_STAGE2_SOURCES
lib/compiler_rt/mulo.zig
lib/compiler_rt/mulsf3.zig
lib/compiler_rt/multf3.zig
lib/compiler_rt/mulvsi3.zig
lib/compiler_rt/mulxf3.zig
lib/compiler_rt/negXi2.zig
lib/compiler_rt/negdf2.zig
Expand All @@ -346,6 +348,8 @@ set(ZIG_STAGE2_SOURCES
lib/compiler_rt/subo.zig
lib/compiler_rt/subsf3.zig
lib/compiler_rt/subtf3.zig
lib/compiler_rt/subvsi3.zig
lib/compiler_rt/subvdi3.zig
lib/compiler_rt/subxf3.zig
lib/compiler_rt/tan.zig
lib/compiler_rt/trig.zig
Expand Down
5 changes: 5 additions & 0 deletions lib/compiler_rt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ comptime {
_ = @import("compiler_rt/absvti2.zig");
_ = @import("compiler_rt/negv.zig");

_ = @import("compiler_rt/addvsi3.zig");
_ = @import("compiler_rt/subvsi3.zig");
_ = @import("compiler_rt/subvdi3.zig");
_ = @import("compiler_rt/mulvsi3.zig");

_ = @import("compiler_rt/addo.zig");
_ = @import("compiler_rt/subo.zig");
_ = @import("compiler_rt/mulo.zig");
Expand Down
15 changes: 15 additions & 0 deletions lib/compiler_rt/addvsi3.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const addv = @import("addo.zig");
const common = @import("./common.zig");

pub const panic = common.panic;

comptime {
@export(&__addvsi3, .{ .name = "__addvsi3", .linkage = common.linkage, .visibility = common.visibility });
}

pub fn __addvsi3(a: i32, b: i32) callconv(.c) i32 {
var overflow: c_int = 0;
const sum = addv.__addosi4(a, b, &overflow);
if (overflow == 1) @panic("compiler-rt: integer overflow");
return sum;
}
18 changes: 18 additions & 0 deletions lib/compiler_rt/addvsi3_test.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const testing = @import("std").testing;

const __addvsi3 = @import("addvsi3.zig").__addvsi3;

fn test__addvsi3(a: i32, b: i32, expected: i32) !void {
const result = __addvsi3(a, b);
try testing.expectEqual(expected, result);
}

test "addvsi3" {
// const min: i32 = -2147483648
// const max: i32 = 2147483647
// TODO write panic handler for testing panics
// try test__addvsi3(-2147483648, -1, -1); // panic
// try test__addvsi3(2147483647, 1, 1); // panic
try test__addvsi3(-2147483647, -1, -2147483648);
try test__addvsi3(2147483646, 1, 2147483647);
}
35 changes: 35 additions & 0 deletions lib/compiler_rt/mulvsi3.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const common = @import("./common.zig");

pub const panic = common.panic;

comptime {
@export(&__mulvsi3, .{ .name = "__mulvsi3", .linkage = common.linkage, .visibility = common.visibility });
}

pub fn __mulvsi3(a: i32, b: i32) callconv(.c) i32 {
const bits = 32;
if (a == -2147483648) {
if (b == 0 or b == 1)
return a * b;
@panic("compiler-rt: interger overflow");
}
if (b == -2147483648) {
if (a == 0 or a == 1)
return a * b;
@panic("compiler-rt: interger overflow");
}
const sa = a >> (bits - 1);
const abs_a = (a ^ sa) - sa;
const sb = b >> (bits - 1);
const abs_b = (b ^ sb) - sb;
if (abs_a < 2 or abs_b < 2)
return a * b;
if (sa == sb) {
if (abs_a > @divTrunc(2147483647, abs_b))
@panic("compiler-rt: interger overflow");
} else {
if (abs_a > @divTrunc(-2147483648, -abs_b))
@panic("compiler-rt: interger overflow");
}
return a * b;
}
18 changes: 18 additions & 0 deletions lib/compiler_rt/mulvsi3_test.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const testing = @import("std").testing;

const __mulvsi3 = @import("mulvsi3.zig").__mulvsi3;

fn test__mulvsi3(a: i32, b: i32, expected: i32) !void {
const result = __mulvsi3(a, b);
try testing.expectEqual(expected, result);
}

test "mulvsi3" {
// min i32 = -2147483648
// max i32 = 2147483647
// TODO write panic handler for testing panics
// try test__mulvsi3(-2147483648, -1, -1); // panic
// try test__mulvsi3(2147483647, 1, 1); // panic
try test__mulvsi3(-1073741824, 2, -2147483648);
try test__mulvsi3(1073741823, 2, 2147483646); // one too less for corner case 2147483647
}
20 changes: 20 additions & 0 deletions lib/compiler_rt/subvdi3.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const common = @import("./common.zig");

pub const panic = common.panic;

comptime {
@export(&__subvdi3, .{ .name = "__subvdi3", .linkage = common.linkage, .visibility = common.visibility });
}

pub fn __subvdi3(a: i64, b: i64) callconv(.c) i64 {
// first allow overflow to panic with a reference to compiler-rt
const sum: i64 = a -% b;
if (b >= 0) {
if (sum > a)
@panic("compiler-rt: integer overflow");
} else {
if (sum <= a)
@panic("compiler-rt: integer overflow");
}
return sum;
}
18 changes: 18 additions & 0 deletions lib/compiler_rt/subvdi3_test.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const testing = @import("std").testing;

const __subvdi3 = @import("subvdi3.zig").__subvdi3;

fn test__subvdi3(a: i64, b: i64, expected: i64) !void {
const result = __subvdi3(a, b);
try testing.expectEqual(expected, result);
}

test "subvdi3" {
// min i64 = -9223372036854775808
// max i64 = 9223372036854775807
// TODO write panic handler for testing panics
// try test__subvdi3(-9223372036854775808, -1, -1); // panic
// try test__addvdi3(9223372036854775807, 1, 1); // panic
try test__subvdi3(-9223372036854775807, 1, -9223372036854775808);
try test__subvdi3(9223372036854775806, -1, 9223372036854775807);
}
20 changes: 20 additions & 0 deletions lib/compiler_rt/subvsi3.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const common = @import("./common.zig");

pub const panic = common.panic;

comptime {
@export(&__subvsi3, .{ .name = "__subvsi3", .linkage = common.linkage, .visibility = common.visibility });
}

pub fn __subvsi3(a: i32, b: i32) callconv(.c) i32 {
// first allow overflow to panic with a reference to compiler-rt
const sum: i32 = a -% b;
if (b >= 0) {
if (sum > a)
@panic("compiler-rt: integer overflow");
} else {
if (sum <= a)
@panic("compiler-rt: integer overflow");
}
return sum;
}
18 changes: 18 additions & 0 deletions lib/compiler_rt/subvsi3_test.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const testing = @import("std").testing;

const __subvsi3 = @import("subvsi3.zig").__subvsi3;

fn test__subvsi3(a: i32, b: i32, expected: i32) !void {
const result = __subvsi3(a, b);
try testing.expectEqual(expected, result);
}

test "subvsi3" {
// min i32 = -2147483648
// max i32 = 2147483647
// TODO write panic handler for testing panics
// try test__subvsi3(-2147483648, -1, -1); // panic
// try test__subvsi3(2147483647, 1, 1); // panic
try test__subvsi3(-2147483647, 1, -2147483648);
try test__subvsi3(2147483646, -1, 2147483647);
}