Skip to content

Instantly share code, notes, and snippets.

@amosr
Created January 30, 2016 02:30
Show Gist options
  • Save amosr/38f14b11068c335fd6cc to your computer and use it in GitHub Desktop.
Save amosr/38f14b11068c335fd6cc to your computer and use it in GitHub Desktop.
UInt can't hold (2^63)+1
amos@localhost option-test $ swiftc uint.swift && ./main
2^62 = 4611686018427387904
2^63 - 1 = 9223372036854775807
Illegal instruction
# Running with -Ounchecked gives wrong result.. (last two numbers are same)
amos@localhost option-test $ swiftc tx1-uint.swift -Ounchecked && ./main
2^62 = 4611686018427387904
2^63 - 1 = 9223372036854775807
2^63 = 9223372036854775807
// Cleaned up assembly, with no prints
main:
.cfi_startproc
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq _TZvOs7Process5_argcVs5Int32@GOTPCREL(%rip), %rax
movl %edi, (%rax)
movq globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_token4@GOTPCREL(%rip), %rdi
movq globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_func4@GOTPCREL(%rip), %rsi
callq swift_once@PLT
movq _TZvOs7Process11_unsafeArgvGSpGSpVs4Int8__@GOTPCREL(%rip), %rax
movq %rbx, (%rax)
xorl %ecx, %ecx
movl $1, %eax
movq _Tv4main3numSi@GOTPCREL(%rip), %rdx
movq _Tv4main2itSi@GOTPCREL(%rip), %rsi
.LBB0_1:
addq %rax, %rax
// Jump if addq overflows
// This treats rax as a signed int64, so going from 2^63 - 1 to 2^63 is treated as an overflow
jo .LBB0_8
movq %rax, (%rdx)
incq %rcx
jo .LBB0_8
movq %rcx, (%rsi)
cmpq $62, %rcx
jl .LBB0_1
movq %rax, %rcx
decq %rcx
// the overflow flag will be set for 2^63 - 1, but not for 0 - 1.
jo .LBB0_8
movq _Tv4main13num_minus_oneSi@GOTPCREL(%rip), %rdx
movq %rcx, (%rdx)
addq %rcx, %rax
jo .LBB0_8
movq _Tv4main12num_one_lessSi@GOTPCREL(%rip), %rcx
movq %rax, (%rcx)
incq %rax
jo .LBB0_8
movq _Tv4main6num_63Si@GOTPCREL(%rip), %rcx
movq %rax, (%rcx)
xorl %eax, %eax
addq $8, %rsp
popq %rbx
popq %rbp
retq
// "Illegal instruction"
.LBB0_8:
ud2
var it = 0
var num = 1
while it < 62 {
num = num * 2
it = it + 1
}
print("2^62 = \(num)")
var num_minus_one = num - 1
var num_one_less = num + num_minus_one
print("2^63 - 1 = \(num_one_less)")
var num_63 = num_one_less + 1
print("2^63 = \(num_63)")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment