Skip to content

feat(t27b): integer shifts with an untyped literal on the left - #6289

Merged
gHashTag merged 1 commit into
masterfrom
claude/t27b-shifts
Oct 4, 2026
Merged

gHashTag merged 1 commit into
masterfrom
claude/t27b-shifts

Conversation

@gHashTag

@gHashTag gHashTag commented Oct 4, 2026

Copy link
Copy Markdown
Owner

Closes #6288
Refs #6063

What

  • t27b already lowered typed << / >>. A runtime amount uses LSLV, ASRV or LSRV and traps ShiftRange outside 0..bits, the way Zig's @intCast panics. A constant amount uses the lsl/asr/lsr immediates. >> is ASR on signed types and LSR on unsigned ones.
  • The missing shape was an untyped literal shifted by a non-literal amount (1 << n). It was the first rejection in 36 corpus files.
  • cli/t27b/src/lower.rs now mirrors compiler.rs shift_runtime_rhs. The literal is pinned to the declared integer type of the local it initializes, else to u32, else to u64.
  • A constant amount out of range for that type is refused by name, because it is a Zig compile error. It is never masked.
  • Typed shifts that are constant on both sides fold in the operand's type and drop bits, as Zig's << does.
  • t27c's optimizer folds literal-only trees, and propagates literal local consts, only in some positions of a function body. So an amount built only from literals and local names may reach Zig as a literal (comptime_int) or not (pinned).
    • t27b accepts it only where both readings give the same value.
    • Otherwise it refuses with "untyped literal shift whose width depends on t27c constant folding".
    • Checked case: 0xFF << (20 + 8) returning u64 gives 0xFF0000000 in the reference. Pinning blindly would give 0xF0000000.
  • <<= / >>=: the t27c parser rejects them ("Unexpected token in expression: Equals"), so the front-end never produces them.

Tests

  • tests/encoder.rs: 6 new rows checked against clang words. They cover lsl x3, x4, x5, lsr w7, w8, w9, asr x10, x11, x12, lsl w17, w16, w8, lsr x0, x16, #63 and lsl w0, w16, #31. The case count is now 157.
  • tests/differential.rs:
    • shift_source_programs_run_in_both_engines covers a literal pinned to i32 / u64 / u32, u64 for a literal past u32, i8 wrap, signed vs unsigned >>, a module const amount, compound y = y << n, and folded literal-only amounts.
      • Verdicts match t27c test-report: shift_basics passes, and shift_amount_too_wide, shift_negative_amount and shift_literal_pinned_to_u32 trap (reference: 1 pass, 3 FAIL).
    • shift_refusals_name_the_construct.
  • cargo test -p t27b: all green, nothing ignored.

Corpus (t27b corpus specs)

before (origin/master 591c5b4) after
pass 191 (1217 tests, 176 invariants) 223 (1332 tests, 190 invariants)
pass_vacuous 279 279
fail 3 3
rejected 743 711
front-end error 40 40
JIT/interpreter mismatch 0 0
  • Exactly 32 files moved from rejected to pass. No other file changed status.
  • Each of the 32 passes under /tmp/t27shared/release/t27c test-report with the same test count as t27b:
    • tnf17 34/34 and xilinx7/packets 12/12;
    • gft_deep_demo, d_e21_test, d_srl_blink and led_diagnostic;
    • 26 specs/ternary/gft_* files.
  • The other 4 of the 36 now stop on other constructs: StmtExpr x2, StmtAssign(undeclared) and StmtForRange.

Top 5 blockers after (t27b corpus specs --blockers, greedy order, 502 files pass already):

step +files construct
1 28 StmtExpr
2 24 StmtAssign(undeclared)
3 19 ExprCall(assert with message)
4 18 ExprIdentifier statement
5 15 FnDecl

🤖 Generated with Claude Code

t27b pins an untyped literal shifted by a non-literal amount to the
type t27c's Zig backend gives it (the declared integer type of the
local, else u32, else u64), as compiler.rs shift_runtime_rhs does. A
constant amount out of range is refused by name, never masked; a
runtime one traps ShiftRange like Zig's @intcast. A literal-only amount
whose folded and pinned readings differ is refused, since t27c's
optimizer folds it only in some positions.

Encoder rows for LSLV/LSRV/ASRV and the immediates; shift_
differential tests. Corpus: pass 191 -> 223, 0 mismatches.

Closes #6288

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-04 22:03:58 UTC

Summary

Status Count
Total Open PRs 44
PRs with Failing Checks 32
PRs with All Checks Green 12
READY 11
FAILING 32
PENDING 0
NO CHECKS YET 0

These columns do not partition: 11 + 32 + 0 + 0 = 43, and there are 44 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=8597b6ded596 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

t27b: integer shifts << >> (first rejection in 36 specs, +32 greedy)

1 participant