authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-09-24 00:36:17+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-09-30 13:44:56+01:00
log3f84b6c80ed3306f040dd98b8ccba561a052167a
treeefb5b6281a62f1c704cac03e1adb2e495d6b5ed7
parentdbda011ae67982949d59258a6ebd8f36080334fa
signaturelock-open Commit is signed but in an unrecognized format.

cbe: workaround GCC miscompilation

This was causing a zig2 miscomp, which emitted slightly broken debug information, which caused extremely slow stack unwinding. We're working on fixing or reporting this upstream, but we can use this workaround for now, because GCC guarantees arithmetic signed shift.

2 files changed, 16 insertions(+), 0 deletions(-)

lib/zig.h+8
......@@ -1510,8 +1510,16 @@ static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {
15101510}
15111511
15121512static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {
1513 // This works around a GCC miscompilation, but it has the side benefit of
1514 // emitting better code. It is behind the `#if` because it depends on
1515 // arithmetic right shift, which is implementation-defined in C, but should
1516 // be guaranteed on any GCC-compatible compiler.
1517#if defined(zig_gnuc)
1518 return lhs >> rhs;
1519#else
15131520 zig_i128 sign_mask = lhs < zig_make_i128(0, 0) ? -zig_make_i128(0, 1) : zig_make_i128(0, 0);
15141521 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask;
1522#endif
15151523}
15161524
15171525static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {
stage1/zig.h+8
......@@ -1510,8 +1510,16 @@ static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {
15101510}
15111511
15121512static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {
1513 // This works around a GCC miscompilation, but it has the side benefit of
1514 // emitting better code. It is behind the `#if` because it depends on
1515 // arithmetic right shift, which is implementation-defined in C, but should
1516 // be guaranteed on any GCC-compatible compiler.
1517#if defined(zig_gnuc)
1518 return lhs >> rhs;
1519#else
15131520 zig_i128 sign_mask = lhs < zig_make_i128(0, 0) ? -zig_make_i128(0, 1) : zig_make_i128(0, 0);
15141521 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask;
1522#endif
15151523}
15161524
15171525static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {