Left-shifting -1 2 bits yields -4, which is the correct byte offset to add to get the -1st position.
Left-shifting will only yield a positive number if i is extremely large such that the result overflows. But that could only happen if you were trying to access beyond the -229th index (assuming 32-bit ints), which is of course too large (small?) of an index to ask for in the first place.
By the way, accessing a negative index is only valid if you're starting with a pointer that's midway through an object and the negative index is still accessing valid memory. A[-1] would invoke undefined behavior. A better example would be:
int *p = &A[3];
int i = -1;
int test = p[i];
Here p[-1] resolves to (&A[3])[-1] which is equivalent to A[2]. That's a valid index, so p[-1] is legal.
Also, while in assembly code it's fine, it should be noted that left shifting negative numbers in C is undefined. Don't try to write -1 << 2 in your C code. The compiler can do it on our behalf but we're not allowed to write it ourselves.
What if you shift 100001 one time to the left? You will get 000010, which is positive in my books.
That would only be the case if ints were 6-bits wide. Per the C standard they must at least 16-bits wide, and in modern computers are usually 32-bits, and sometimes 64.
Let's say we were on a 16-bit system. 100001 would actually be one of these two numbers:
0000000000100001. This is 33, a positive number.
1111111111100001. This is -31, a negative number. Shifting it left would retain all but one of the leading 1 bits and remain negative.