| author | |
| committer | |
| log | 12584fac6c6798acfd4ff783a43ee37cbbaf9ef0 |
| tree | 0cd9755c1335362565de75cc83da16565fb84ecb |
| parent | dd0fbcc6027c19fdb195aa32101475f50a3fbc75 |
| signature | Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM |
For integers up to 64 bits, the generated code used += and *=,
but the C type might be bigger than the Zig type.
For example, a sum or product of u1, u7 or i3 integers would end
up out of range.
Fix this by using zig_addw and zig_mulw if the integer bit width
doesn't match the C type.2 files changed, 5 insertions(+), 2 deletions(-)
src/codegen/c.zig+3-2| ... | ... | @@ -6875,6 +6875,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6875 | 6875 | }, |
| 6876 | 6876 | .big => .{ false, true }, |
| 6877 | 6877 | } else .{ false, false }; |
| 6878 | const operator_wraps = use_operator and scalar_ty.intInfo(zcu).bits == 8 * scalar_ty.abiSize(zcu); | |
| 6878 | 6879 | const op: union(enum) { |
| 6879 | 6880 | const Func = struct { operation: []const u8, info: BuiltinInfo = .none }; |
| 6880 | 6881 | builtin: Func, |
| ... | ... | @@ -6895,12 +6896,12 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6895 | 6896 | else => unreachable, |
| 6896 | 6897 | }, |
| 6897 | 6898 | .Add => switch (scalar_ty.zigTypeTag(zcu)) { |
| 6898 | .int => if (use_operator) .{ .infix = " += " } else .{ .builtin = .{ .operation = "addw", .info = .bits } }, | |
| 6899 | .int => if (operator_wraps) .{ .infix = " += " } else .{ .builtin = .{ .operation = "addw", .info = .bits } }, | |
| 6899 | 6900 | .float => .{ .builtin = .{ .operation = "add" } }, |
| 6900 | 6901 | else => unreachable, |
| 6901 | 6902 | }, |
| 6902 | 6903 | .Mul => switch (scalar_ty.zigTypeTag(zcu)) { |
| 6903 | .int => if (use_operator) .{ .infix = " *= " } else .{ .builtin = .{ .operation = "mulw", .info = .bits } }, | |
| 6904 | .int => if (operator_wraps) .{ .infix = " *= " } else .{ .builtin = .{ .operation = "mulw", .info = .bits } }, | |
| 6904 | 6905 | .float => .{ .builtin = .{ .operation = "mul" } }, |
| 6905 | 6906 | else => unreachable, |
| 6906 | 6907 | }, |
test/behavior/vector.zig+2| ... | ... | @@ -962,6 +962,7 @@ test "vector reduce operation" { |
| 962 | 962 | try testReduce(.Add, [4]u64{ 9, 99, 999, 9999 }, @as(u64, 11106)); |
| 963 | 963 | try testReduce(.Add, [4]i128{ -9, -99, -999, -9999 }, @as(i128, -11106)); |
| 964 | 964 | try testReduce(.Add, [4]u128{ 9, 99, 999, 9999 }, @as(u128, 11106)); |
| 965 | try testReduce(.Add, [4]u7{ 100, 100, 0, 0 }, @as(u7, 72)); | |
| 965 | 966 | try testReduce(.Add, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 42.9)); |
| 966 | 967 | try testReduce(.Add, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 42.9)); |
| 967 | 968 | try testReduce(.Add, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 42.9)); |
| ... | ... | @@ -1010,6 +1011,7 @@ test "vector reduce operation" { |
| 1010 | 1011 | try testReduce(.Mul, [4]u64{ 9, 99, 999, 9999 }, @as(u64, 8900199891)); |
| 1011 | 1012 | try testReduce(.Mul, [4]i128{ -9, -99, -999, 9999 }, @as(i128, -8900199891)); |
| 1012 | 1013 | try testReduce(.Mul, [4]u128{ 9, 99, 999, 9999 }, @as(u128, 8900199891)); |
| 1014 | try testReduce(.Mul, [4]i3{ 3, 2, 1, 1 }, @as(i3, -2)); | |
| 1013 | 1015 | try testReduce(.Mul, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 58430.7)); |
| 1014 | 1016 | try testReduce(.Mul, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 58430.7)); |
| 1015 | 1017 | try testReduce(.Mul, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 58430.7)); |