The thing about IO is that it solves one problem well: interfacing with an imperative sequential world. Old manners like stream handling functions are just plain awkward and need some kind rendezvous; uniqueness typing is fast, composable, but a bit awkward too, and -truth be told- better encapsulated in its own monad probably anyway.
There also is certainly a case that banning benign side effects might have a lot more to do with the fact that that is inherently difficult in a lazy pure language (and compiler for that) than that it's so bad for the average programmer.
The thing against the IO monad is not that there's anything wrong with it. Just that it kind of locks programmers into a style of programming, I believe, functional programming is just trying to avoid, i.e., imperative programming.