The problem with directives is not on day 1, they're awesome on day 1. The problem is usually that the directives are in the wrong place 10 years later.
Loop unrolling directives went through that process in just a few years, from giving a nice speedup, to compilers being able to mostly match the directive, to the directive causing slowdowns, to compilers ignoring that directive.
... at which point you can edit a single point in the source code to fix it, either defining hot-path to be equivalent to eval, removing it outright, or altering it to be better. Isn't that the point of abstraction?
Loop unrolling directives went through that process in just a few years, from giving a nice speedup, to compilers being able to mostly match the directive, to the directive causing slowdowns, to compilers ignoring that directive.