Neither of these statements is always true. If you pass a value of known static type into an existential, then the compiler can see that and still specialize the function based on the type going in. Similarly, if you call the generic function with a dynamic type, the compiler does not necessarily know what that type is, and may not be able to specialize. Both functions accept a generic type and a value of that type; the existential form just packs them into a single value instead of two separate arguments.
There is an "existential specializer" pass that turns some functions with existential arguments into their generic forms, which allows generic specialization passes to further optimize them. You could maybe use @inline(never) to suppress specialization, but there still isn't a fully designed and developed suite of attributes for controlling optimizer behavior.