Consider: #include <cassert> struct Val { int *A, B; Val() : A(0), B(2) {} }; Val foo(); void bar(Val X, Val Y); void test(Val Op) { bar(Op, foo()); } on X86. We currently generate really horrible code, because we are not able to eliminate any intermediate 'Val' objects. We should do the right thing in three places, but don't do any of them: 1. llvm-gcc4 is lowering the 'pass struct by value' code into bad code that casts the address of the struct to a long*, then loads/stores the entire struct at once. It doesn't need to do this. In this specific case on X86, it can pass the two elements and get the same effect. 2. ScalarRepl doesn't understand the pointer cast in this case, because one element of the struct is a pointer (it handles {int,int} fine). 3. The code generator should handle this, because the 'long' load/stores gets split into 2x i32 loads, which should be forward prop'd. However, because it's not using (even trivial) alias analysis, it doesn't get this. We should fix this problem at all of these levels. -Chris
#3 is taken care of when Jim's CodeGen AA stuff is enabled. -Chris
Fixed, patches here: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20061002/038407.html http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20061002/038409.html Testcase here: Transforms/ScalarRepl/union-pointer.ll -Chris