Skip to content

Code generation fixes found by differential testing - #383

Merged
davidgiven merged 3 commits into
davidgiven:defaultfrom
maarten-boot:upstream/codegen-fixes
Oct 31, 2026
Merged

davidgiven merged 3 commits into
davidgiven:defaultfrom
maarten-boot:upstream/codegen-fixes

Conversation

@maarten-boot

Copy link
Copy Markdown
Contributor

I compiled random C programs (integer arithmetic of all widths,
conversions, comparisons, guarded division, shifts, loops, switches,
arrays, structs) with gcc and with the ACK at -O0 to -O4 and compared
the output. These are the differences that are not specific to my
target; each commit has a test in tests/plat/core that fails without
it.

  • cemcom.ansi: unary - of an unsigned constant was not cut to the
    type's size (~ was), so -(unsigned long)1371337135 / 193754694
    folded to 717414569 instead of 15. Fails on all four tested
    platforms.
  • em_opt:
    • repl_mul (-ml) kept the multiplier in a 64-bit unsigned long: x * 0xFFFFFFFFUL became a shift by 64 and gave 0 on
      linux68k.
    • loc loc adu/sbu/mlu/sli/slu (and the ldc forms) folded to
      constants that do not fit the word, and loc loc loc cii/ciu
      folded without sign-extending the constant ((int8_t)16384 stayed
      16384). Both show at -O3, when ego propagates constants: the tests
      fail on linux68k, linuxppc and pc86.
  • m68020 ncg table (linux68k):
    • the memory1 coercion (clr, move.b) kept the condition codes
      of the byte as those of the register: (uint8_t)l / 16 with
      l = -300 gave 14.
    • x & (a op b) was done as "clear bit 0 of x if false", only right
      for x of 0 or 1: (x >> s) & (a < b) with x = -8017 gave -8017.

Tested: make with PLATS = all, all tests pass on cpm, linux68k,
linuxppc and pc86; without the fixes the new tests fail as described.
Independent of #381 and #382.

🤖 Generated with Claude Code

maarten-boot and others added 3 commits October 31, 2026 14:50
~ of an unsigned constant was masked to the type's size, unary - was not,
so the folded value kept the bits above it (the compiler's arithmetic is
64-bit): -(unsigned long)1371337135 / 193754694 folded to 717414569
instead of 15. Mask the result of both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- peephole.c, repl_mul (-ml): the multiplier is held in a 64-bit
  unsigned long, so "ldc -1 mlu 4" had 64 one bits and became a shift by
  64: x * 0xFFFFFFFFUL was 0 on linux68k. Mask it to the operand size.
- patterns: loc loc adu/sbu/mlu/sli/slu and ldc loc sli/slu folded to a
  constant that does not fit the word; later folds (a shift right, a
  division) then used the bits above it. Fold only when the result fits.
- patterns: loc loc loc cii with a source smaller than the word folded to
  the constant without sign-extending it ((int8_t)16384 stayed 16384), and
  the word to double-word cii/ciu folds took constants in unsigned form
  (loc 45219) as positive. Fold only when the constant fits the source.

The fold bugs show at -O3, when ego propagates constants into these
sequences.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- from memory1 (clr, then move.b into the register): move.b sets the
  condition codes for the byte, but they were taken for the register, so
  a following signed test used the byte's sign: (uint8_t)l / 16 with
  l = -300 gave 14 instead of 13. killcc after the move.
- txxand, txxand_ouch, cmxtxxand (tXX and, cmX tXX and): x & (a op b) was
  done as "clear bit 0 of x if false", which is only right when x is 0 or
  1: (x >> s) & (a < b) with x = -8017 gave -8017. Now and #1 first and
  clr if false.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
maarten-boot added a commit to maarten-boot/ack that referenced this pull request Oct 31, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@davidgiven

Copy link
Copy Markdown
Owner

Merging; thanks.

@davidgiven
davidgiven merged commit dcdc582 into davidgiven:default Oct 31, 2026
@maarten-boot
maarten-boot deleted the upstream/codegen-fixes branch November 2, 2026 17:58
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.

2 participants