By its nature abstraction reduces the communcation of information, both to the programmer and to the lower layers of the system (the compiler, libraries, and runtime system). In favor of abstraction, this generally allows the lower layers to assume that the programmer is not concerned with any unspecified behavior, providing greater flexibility in supplying the behavior that is specified.
An example of a potential benefit from this "don't care" aspect is in data layout. In C (low abstraction), the compiler is more constrained in data layout optimizations. Even if the compiler could discern (e.g., through profile information) that hot/cold or false-sharing-avoidance optimizations would be beneficial, it is generally prevented from applying such. (There is some freedom in specifying "as if", i.e., treating the specification more abstractly, but deriving all the potential side effects adds a burden to the compiler.)
A more abstract specification is also more robust against changes in tradeoffs and uses. The lower layers are less constrained in reoptimizing the program for new system characteristics or new uses. A more concrete specification must either be rewritten by a programmer or additional effort must be made by the lower layers to guarantee "as if" behavior.
The performance hindering aspect of information hiding abstraction is "can't express", which the lower layers will typically handle as "don't know." This means that the lower layers must discern information useful for optimization from other means such as typical general use, use targeted by the language or library, or specific profile information.
The impact of information hiding works in the other direction as well. The programmer can be more productive by not having to consider and specify every detail, but the programmer may have less information about the impact of higher level design choices.
On the other hand, when code is more specific (less abstract), the lower layers of the system can more simply do what they are told to do as they are told to do it. If the code is well-written for its targeted use, it will fit its targeted use well. A less abstract language (or programming paradigm) allows the programmer to optimize the implementation by detailed design and by the use of information which is not easily communicated in a given language to the lower layers.
As has been noted, less abstract languages (or programming techniques) are attractive when additional programmer skill and effort can produce worthwhile results. When more programmer effort and skill are applied, results will typically be better. In addition, a language system which is used less for performance-critical applications (instead emphasizing development effort or reliability — bounds checks and garbage collection are not just about programmer productivity but about correctness, reducing via abstraction the mental load on the programmer can improve reliability) will have less pressure to improve performance.
Specificity (lower abstraction) also works against the principle of don't repeat yourself, but tailoring code to a specific use is a common optimization technique. This reduced abstraction has obvious reliability and programming effort implications.
The abstractions provided by a language may also include undesired or unnecessary work with constrained ability to choose a less heavyweight abstraction. While unnecessary work can sometimes be discovered and removed by the lower layers (e.g., bounds checks may be extracted from the body of a loop and entirely removed in some cases), determining that such is a valid optimization requires more "skill and effort" by the compiler.
Language age and popularity are also noteworthy factors both in availability of skilled programmers and the quality of the lower layers of the system (including mature libraries and code examples).
Another conflating factor in such comparisons is the somewhat orthogonal difference between ahead-of-time compilation and just-in-time compilation. While just-in-time compilation may more easily exploit profile information (not relying on the programmer to provide profile runs) and system-specific optimization (ahead-of-time compilation may target broader compatibility), the overhead of aggressive optimization is accounted as part of the runtime performance. JIT results can be cached (reducing the overhead for commonly used code) but typically not persistently.
For ahead-of-time compilation, binary reoptimization can provide some advantages of JIT compilation, but traditional binary distribution formats drop most source-code information potentially forcing the system to attempt to discern intent from a specific implementation.
(Install-time compilation/finalization is an intermediate choice with intermediate trade-offs.)
Lower abstraction languages, because of their emphasis on programmer control, favor the use of ahead-of-time compilation. Install-time compilation might be tolerated, though link-time implementation selection would provide greater programmer control. JIT compilation sacrifices significant control.
There is also the issue of benchmarking methodology. Equal effort/skill is effectively impossible to establish, but even if such could be achieved the language goals would bias the results. If a low maximum programming time was required, a program for a less abstract language might fail even to be completely written compared to a simple idiomatic expression in a more abstract language. If a high maximum programming time/effort was allowed, lower-abstraction languages would have an advantage. Benchmarks presenting best-effort results would naturally be biased in favor of less abstract languages.
It is sometimes possible to program in a less idiomatic manner in a language to gain the advantages of other programming paradigms, but even when the expressive power is available the tradeoffs for doing such may not be favorable.