I reduced the above case to this:

; test.ll
define i8* @test() {
%x1 = malloc i8, i32 16
%x2 = bitcast i8* %x1 to i8**
store i8* %x1, i8** %x2
ret i8* %x1

$ llvm-as test.ll
$ opt -instcombine test.bc -o testopt.bc
$ llc test.bc
$ llc testopt.bc
$ diff -u test.s testopt.s
-movl $16, (%esp)
+movl $8, (%esp)
call malloc

I'm afraid that I'm not up to fixing this myself. Please help!

Excellent reduction. It turns out that the reason for this is that the LLVM module doesn't have a target data string, so it's assuming (for historical reasons) that the target data layout matches SparcV9, which has 64-bit pointers. I committed a fix as r45003 of clang.

Be aware that the target layout info is currently stubbed out (see TargetInfo::getTargetDescription in clang), so it will always be fixed to what darwin/x86 expects (little-endian 32-bit etc). This should be close enough to work fine for linux/i386, but it would be better to improve the clang target interface to return the right strings.