I'm having the same issue. I had 8 or 9 legitimate alarms set, as well, but now there are somewhere between 1500 and 2000 with a couple hundred duplicates of each one. The number of duplicates is growing, too, but I can't tell if the additions happen each time I sync the phone or each time the clock program is reloaded on the phone. I noticed this first on my 3G after upgrading it, and it is also happening on the iPhone 4 having all my data transferred from a backup made of the 3G running 4.0. I've also noticed that if I try to delete them from my phone, at some point the clock program becomes nearly unresponsive causing even other programs than the clock to crash and requiring the phone to be resynced.
I've seen a couple of people mentioning similar issues in other threads that sound like they could be related or even the same, and they are always talking about upgrades on the same phone. There doesn't seem to be anyone affected who transferred directly from a 3.x device to a new 4.0 device.
While not a solution, here's at least my suggestion of why it's happening. I've poked around a bit in the backup files stored on my laptop from this phone (under ~/Library/Application Support/MobileSync), and I've found two different plist files in the same backup storing the alarms in two slightly different formats.
This is purely conjecture, but I would guess what happened is the location & format between 3.x and 4.0 of where the alarm data is stored changed. The "upgrade" isn't a complicated process that mulls over and handles situations like this during the install. It's just a wholesale firmware replacement. Any changes like this would probably need to be handled by the actual programs themselves when they're running on the phone. Something in the upgrade process that's supposed to translate the old format to the new format is broken leaving behind the old data instead of removing it after the conversion, and every so often some trigger in the clock program (like a check for new data after a sync or just the initial loading when the phone restarts) is causing it to see that old 3.1 style data still there, redo the conversion process, and reimport what it finds as another set of duplicates.
That's only a guess, though, and as it's a one-way backup-only folder I can't edit them and resync to see if cutting them out of the data files on the laptop will remove them from the phone. Even if this is wrong, though, I can't imagine how it could be anything too far different from this. That would be a very simple bug to introduce into the code that would be specialized enough to be easy to overlook in testing. Again, that's all just a guess.
While I'm making wild speculations: I'm guessing the problem with the phone needing to be resynced when deleting several alarms is from one of these files on the phone storing the alarm data getting corrupted. If I was a betting man, I'd say this is likely due to corruption making the XML of the plist malformed from different threads writing changes to it simultaneously because it's so huge from all these entries and seeking through the file to update it is taking longer than anyone would reasonably expect and test for or program to protect against. Because, honestly, who thinks while coding something like this, "I need to make sure the user is safe when editing 2000 alarms..."