For some reason, even if /etc/init.d/dmcrypt has before swap, it still runs after swap, which makes encrypted swaps fail to mount on boot. I can fix it by adding want dmcrypt to /etc/init.d/swap, but, of course, every time there's an OpenRC update, I'm back to square one.
The default pacman behaviour is to leave changed files alone and create a /etc/init.d/swap.pacnew instead. To explicitly protect a file, put this in /etc/pacman.conf:
NoUpgrade = etc/init.d/swap