Si bien los threads comparten la memoria y por lo tanto no precisan de un servicio de memoria compartida si podrían usar algún servicio de sincronización del sistema operativo (por ejemplo para tener una región crítica entre threads). El concepto de IPC no es necesariamente excluyente con el uso de threads.
Si hay dos procesos distintos que quieren comunicarse deben usar alguno de los servicios de IPC del sistema operativo, no importa si ellos mismos usan threads o no.
Los threads de usuario no pueden sincronizarse usando servicios de IPC del sistema operativo porque si un thread se bloquea esperando por otro va a quedar en deadlock el proceso entero dado que todos los threads del proceso se bloquean juntos. En ese caso la biblioteca de threads a nivel de usuario va a atener que brindar algún servicio de sincronización entre los threads en caso de que sea necesario.