Skip to content

Commit

Permalink
vmgen: respect overflow checks for 64-bit negation (#1408)
Browse files Browse the repository at this point in the history
## Summary

Negation of 64-bit integers didn't respect the overflow check setting,
resulting in overflow defects even when the checks are disabled. This
is now fixed.

Fixes #1406.

## Details

The VM presently doesn't support unchecked negation. For ease of
implementation, unchecked negation is emulated in bytecode as
`not(x) + 1`.
  • Loading branch information
zerbina authored Aug 8, 2024
1 parent c46ddf2 commit e0963b8
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 2 deletions.
17 changes: 15 additions & 2 deletions compiler/vm/vmgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3018,8 +3018,21 @@ proc gen(c: var TCtx; n: CgNode; dest: var TDest) =
clearDest(c, n, dest)
of cnkNeg:
prepare(c, dest, n.typ)
let a = c.genx(n[0])
c.gABC(n, pick(n, opcUnaryMinusInt, opcUnaryMinusFloat), dest, a)
let
a = c.genx(n[0])
op = pick(n, opcUnaryMinusInt, opcUnaryMinusFloat)
if op == opcUnaryMinusInt:
# the VM has no built-in unchecked integer negation, so it's emulated in
# an overflow-safe manner
# XXX: this is sub-optimal. In the future, all VM integer operations
# should be unchecked
c.gABC(n, opcBitnotInt, dest, a) # invert
let tmp = c.getTemp(slotTempInt)
c.gABx(n, opcLdImmInt, tmp, 1)
c.gABC(n, opcAddu, dest, dest, tmp) # + 1 (two's complement)
c.freeTemp(tmp)
else:
c.gABC(n, op, dest, a)
c.freeTemp(a)
of cnkAdd: binaryArith(c, n, n[0], n[1], dest, opcAddu, opcAddFloat)
of cnkSub: binaryArith(c, n, n[0], n[1], dest, opcSubu, opcSubFloat)
Expand Down
10 changes: 10 additions & 0 deletions tests/overflw/tunchecked_negation_32.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
discard """
description: '''
Ensure that disabling overflow checks works for 32-bit integer negations
'''
targets: "c js vm"
matrix: "--overflowChecks:off"
"""

var x = low(int32)
discard -x
10 changes: 10 additions & 0 deletions tests/overflw/tunchecked_negation_64.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
discard """
description: '''
Ensure that disabling overflow checks works for 64-bit integer negations
'''
targets: "c js vm"
matrix: "--overflowChecks:off"
"""

var x = low(int64)
discard -x

0 comments on commit e0963b8

Please sign in to comment.