What the documentation says is technically true, but somewhat misleading.
When you perform a squash and merge with GitHub, it takes the contents of your two branches and merges them, but does not create a merge commit. Instead, it creates a commit that has only one parent. This is equivalent to git merge --squash && git commit at the command line.
In your graph, this is a merge of master and feature.
This temporary commit that GitHub creates is then merged into your main branch as a fast-forward merge, since it is necessarily a superset of the main branch. That's why it is technically true, but misleading. GitHub includes this message to tell you that it doesn't create a merge commit (that is, a commit with two or more parents) but instead a single commit with just the main branch as its parent.
So essentially, squash and merge is just a merge, but with a different history. There's one commit with a single parent instead of multiple commits combined with a merge commit. For example, if you have this:
A - B - C - D (dev)
\
E - F - G (feature)
and you want to merge D and G, a normal merge would give you this:
A - B - C - D - H (dev)
\ /
E - F - G -- (feature)
and a squash merge would give you this:
A - B - C - D - H' (dev)
The contents of H and H' are identical, but the commits have different numbers of parents. This H will have been created by creating but not committing H on a temporary branch and then fast-forward merging it into dev.
This behavior can differ from squash and rebase if the squash happens first, since it's possible for one situation to have conflicts and the other not to. But in the case without conflicts, they should produce identical results almost all the time.
Whether squash-and-merge and squash-and-rebase differ depends on the type of rebase used. The older style am rebase uses patches, and so it's possible for patches to misapply if the context is identical in multiple places, which is a known defect of this approach. It also does not perform rename detection, which means that merge attempts may otherwise fail. The newer style rebase uses the merge machinery under the hood and I'm not aware of any place where it wouldn't produce an identical result (although I'm not the Git merge machinery expert) because it's essentially a merge.
Note that squash-and-rebase with the merge-based rebase or squash-and-merge is qualitatively different than rebase-and-squash, because the latter involves rebasing multiple patches, each of which could have conflicts, whereas a squash-and-rebase will consider only the old base, new base, and squashed commit. If a patch in the middle would have caused a conflict but the end result wouldn't (say, because the conflicting code was removed later in the series), then rebase-and-squash will traverse the problematic commit and conflict, whereas squash-and-rebase will not and will succeed.