To a certain degree, yes. Many security sensitive applications like Tor and Bitcoin creates a compilation process that are deterministic build. This build process allows multiple people compiling the same source code to produce the exact bit-to-bit identical build.
The big problem here is determining what is equivalent source code. You can get a long way if you strip the compiled code so that code that you get identical build if you simply rename variables, and do dead code elimination optimisation. You'd then have to avoid non deterministic optimisations, while still doing optimisations that may eliminate superficial differences between different ways people write code (e.g. for-loop vs while-loop). Disabling optimisations that may cause the compiler to produce duplicate codes would also help reduce any chance the compiler producing lots of similar code with just slight differences for optimisations (in gcc, maybe turn on optimise for size). More difficult is deciding whether code that relies on a bunch of if-statements vs code that uses class inheritance to select code path should be considered the same if they behave similarly.
Another aspect that may make such compiler more or less difficult to create is the target machine's instruction set. A register-based target machine like x86 is likely more difficult for this purpose, since you have to select certain registers with the instructions, and the are many functionally equivalent machine code that are different just by their register allocations. A stack based target machine like JVM are likely easier for this purpose as the instruction set always assume that the top of stack are ordered in specific ways, so code that works similarly would be more likely to also end up with similar machine code than register based target language. Note that many compilers actually compiles first to an intermediate language that are based on a stack machine language, before doing optimisations and register allocations.
Ultimately though, what makes this stuff really difficult is defining what are identical is very subjective and there isn't always a right answer. Things like concurrency guarantee, code that are otherwise behave identically in single thread application may behave differently in multi threaded scenario due to differences in sequence points, should they be treated as the same or different code? Or if one code uses bubble sort and the other uses quick sort, should they be considered to be the same or different code? How about code that are only different in the data type they use (e.g. int vs long, single vs double precision floats), should they be considered the same or different code. When you dig down into these issues, there are a lot of worms in this can that makes it non-obvious what should be considered equivalent vs different code.