String literals have a one-pass escaping at parse time, so that

    "foo\\bar\nbaz"

is an encoded way to express

    foo\bar
    baz

And the result of that ordinary pass is what gsub receives.

Then, at runtime gsub inspects its argument and looks in turn for
occurrences of \1, \& and friends. That is gsub's contract, and has no
relationship with string literals parsing.

You need double-scaping for \1 and friends to skip both passes, one
related to literals, and the other one related to how gsub works.