commit 1ccc0e54d9cd80c7d17dd1ba82e9271090eba986 (tree)
parent 1a1a4d3d2558976232455614601a8b234f7c30cd
Author: Motiejus <motiejus@jakstys.lt>
Date: Sat, 7 Mar 2026 08:05:02 +0000
sema: add comptime folding to zirByteSwap
For comptime-known integer operands with bit-aligned widths, compute
the byte-swapped value at comptime rather than emitting AIR.
Matches src/Sema.zig zirByteSwap: arith.byteSwap() comptime path.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Diffstat:
1 file changed, 38 insertions(+), 0 deletions(-)
diff --git a/stage0/sema.c b/stage0/sema.c
@@ -1311,6 +1311,44 @@ static AirInstRef zirByteSwap(Sema* sema, SemaBlock* block, uint32_t inst) {
ZirInstRef operand_ref = sema->code.inst_datas[inst].un_node.operand;
AirInstRef operand = resolveInst(sema, operand_ref);
TypeIndex operand_ty = semaTypeOf(sema, operand);
+
+ // Comptime folding: if operand is a comptime-known integer, compute
+ // the byte-swapped value at comptime.
+ // Ported from src/Sema.zig zirByteSwap: arith.byteSwap() call.
+ uint64_t val_lo, val_hi;
+ bool val_neg;
+ if (isComptimeIntWide(sema, operand, &val_lo, &val_hi, &val_neg)) {
+ uint16_t bits = 0;
+ if (sema->ip->items[operand_ty].tag == IP_KEY_INT_TYPE)
+ bits = sema->ip->items[operand_ty].data.int_type.bits;
+ if (bits > 0 && bits % 8 == 0) {
+ // Byte-swap: reverse the bytes.
+ uint64_t r_lo = 0, r_hi = 0;
+ if (bits <= 64) {
+ for (uint16_t b = 0; b < bits / 8; b++) {
+ uint16_t src_byte = (uint16_t)((bits / 8) - 1 - b);
+ uint8_t byte_val = (uint8_t)(val_lo >> (src_byte * 8));
+ r_lo |= (uint64_t)byte_val << (b * 8);
+ }
+ } else {
+ // 128-bit case: lo holds bytes 0-7, hi holds bytes 8-15.
+ for (uint16_t b = 0; b < 8; b++) {
+ uint16_t src = (uint16_t)(15 - b);
+ uint8_t bv = (src < 8)
+ ? (uint8_t)(val_lo >> (src * 8))
+ : (uint8_t)(val_hi >> ((src - 8) * 8));
+ r_lo |= (uint64_t)bv << (b * 8);
+ }
+ for (uint16_t b = 0; b < 8; b++) {
+ uint16_t src = (uint16_t)(7 - b);
+ uint8_t bv = (uint8_t)(val_lo >> (src * 8));
+ r_hi |= (uint64_t)bv << (b * 8);
+ }
+ }
+ return internComptimeInt(sema, operand_ty, r_lo, r_hi);
+ }
+ }
+
AirInstData data;
memset(&data, 0, sizeof(data));
data.ty_op.ty_ref = AIR_REF_FROM_IP(operand_ty);