In general, I don't think either Clang or GCC is capable of getting rid of malloc/free or new/delete outside of a special case for completely dead stores. They aren't capable of doing escape analysis and lowering it to a stack allocation / virtual registers so it won't go away.
Last time I checked, the GCC dead store elimination also only works for malloc/free and only when the code is buggy and lacks an out-of-memory check. Clang is better at this, but it lacks a way to turn this into a dead store anyway. It can't work with malloc/new directly either.
So yes, I'm sure it understands that it's just an add. It knows the memory returned from new/malloc doesn't alias anything else. It just has absolutely no way to get rid of it by lowering it to something else and also has no way to get rid of it in a single step. Not implemented.
I think part of the reason lowering dynamic allocations to stack allocations / virtual registers isn't implemented is to avoid the risk of causing a stack overflow. They can and should probably do a very conservative version of it which would end up optimizing this away at least.
There could definitely be a pass for it or SROA could be taught to rip apart malloc allocations like it can do with stack allocations. There's one take on a separate pass at https://reviews.llvm.org/D53362 along with links to some previous work. Main issue is not wasting too much stack.
It's just not quite simple enough that it could be eliminated as an intermediate and considered a dead store. It's providing a "useful" form of storage. I'm not sure how realistic it would be to eliminate it without any heap-to-stack (followed by mem2reg) allocation conversion.