The reason is that expressions like 1<<64 are compile time constants and are indeed computed by the compiler at compile time. No code to shift anything is emitted. 
The expression 1<<64 is evaluated by the compiler as 0, which is plausible and legit since the behavior is actually, as others have pointed out, undefined. The produced assembly for uint64_t i = (uint64_t)1 << 64; is simply to store zero in the variable's location:
QWORD PTR [rbp-16], 0
Now, for a non-compile time value code is emitted. uint64_t i2 = (uint64_t)1 << n; translates to 
    mov     rax, QWORD PTR [rbp-8]
    mov     edx, 1
    mov     ecx, eax
    sal     rdx, cl
    mov     rax, rdx
    mov     QWORD PTR [rbp-24], rax
All the boilerplate code before and after the actual SAL shift instruction is just moving the operands in place and moving the result into the variable. The important thing is that the compiler indeed emits code to shift the 1 here. Because shifting by more than 63 is illegal and pointless for 64 bit values Intel processors silently mask the shift value:
REX prefix in the form of REX.W [I must assume that that happens here] promotes operation to 64-bits and sets the mask width for CL to 6 bits.
That is, the processor internally masks n's value of 64/100'0000 with 63/11'1111, resulting in a shift value of 0. The result is, of course, the original 1.
With higher optimization levels the compiler optimizes that instruction away as well because it can infer the value of the non-volatile n, and emits 0 there as well.