The compiler doesn't have to pop the frame with an add — if the function allocates dynamic amounts of memory, the compiler will generally save SP and store it back. But I believe the sub/add pattern is micro-architecturally favored for things like the OOO forwarding I mention above, so the compiler emits it when it can