The PIC24, PIC30, PIC33 (all 16bit cpus) use a gcc-based compiler.
The PIC32 (32bit MIPS-core cpu) uses a gcc-based compiler. (and has an Arduino-like board and environment available in the form of the "ChipKit" products.)
Both of those can use free C compilers that produce reasonably good code. The MIPS CPU in particular has been supported outside of the Microchip range for quite a long time; it would be difficult to get it to produce bad code.
The PIC10, PIC12, PIC16, and PIC18 8-bit CPUs use an entirely different compiler. The free version from Microchip, for these CPUs, rather than being code-size limited like many free compiler versions, instead turns off optimization. ALL optimization; examples of spectacularly bad code have been posted. (I don't understand it. Microchip has other examples of quite reasonable behavior (in particular, their IDE runs on Windows, Mac, and Linux.) I have heard (but not confirmed) that the free USB code that microchip provides does not fit
in the target CPU when compiled with the free compiler, for example.
I shouldn't think GCC itself would have many optimizations
You would be wrong. Many things can be optimized well above the specifics of code generation for any particular CPU. And I gather that one of the strengths of gcc is that they have implemented an abstraction of a cpu that makes it easy to add new CPUs and "instantly" get reasonable code. (In this case it doesn't matter much, because the 8-bit PIC architecture is SO far NOT compatible with that abstraction, and (essentially) could not possible be supported by gcc at all.)