When MemCpyOpt is handling aggregate type values, if an instruction (let's call it P) between the targeting load (L) and store (S) clobbers the source pointer of L, it will try to hoist S before P. This process will also hoist S's data dependency instructions.
However, the current implementation has a bug that if one of S's dependency instructions is also a user of P, MemCpyOpt will not prevent it from being hoisted above P and cause a use-before-define error. For example, in the newly added test file (i.e. aggregate-type-crash.ll), it will try to hoist both store %my_struct %1, %my_struct* %3 and its dependent, %3 = bitcast i8* %2 to %my_struct*, above %2 = call i8* @my_malloc(%my_struct* %0). Creating the following BB:
entry: %1 = bitcast i8* %4 to %my_struct* %2 = bitcast %my_struct* %1 to i8* %3 = bitcast %my_struct* %0 to i8* call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %2, i8* align 4 %3, i64 8, i1 false) %4 = call i8* @my_malloc(%my_struct* %0) ret void
Where there is a use-before-define error between %1 and %4.
Update: The compiler for the Pony Programming Language also encounter the same bug