Can I, without locking, safely call List.AddRange(r) from multiple threads? If not, what sort of trouble would I run into?
No it is not thread-safe.
Thread A could call AddRange on your list. It could iterate partially over the collection and switch threads.
Thread B could call Add/Remove, etc. before Thread A has finished.