[llvm-dev] Possible MemCpyOpt bug?
Bryant Wong via llvm-dev
llvm-dev at lists.llvm.org
Thu Nov 17 11:00:06 PST 2016
Hi all,
I think I've managed to trick the legacy MemCpyOpt (MCO) into an incorrect
transform, but I would like to confirm the validity of my counterexample
before
working on the fix. Suppose the following IR:
%T = type { i32, i32 }
define void @f(%T* %a, %T* %b, %T* %c, %T* %d) {
%val = load %T, %T* %a, !alias.scope !{!10}
; store1
; Aliases the load
store %T { i32 22, i32 22 }, %T* %b, !alias.scope !{!11}
; store2
; Aliases the store below and the load. No-alias with above store
store %T { i32 44, i32 44 }, %T* %c, !alias.scope !{!12},
!noalias !{!11}
; store3
; MCO wants to combine this store with the load into a memcpy
store %T %val, %T* %d, !alias.scope !{!13}, !noalias !{!10, !11}
ret void
}
!0 = !{!0}
!1 = !{!1}
!2 = !{!2}
!3 = !{!3}
!10 = !{ !10, !0 }
!11 = !{ !11, !1 }
!12 = !{ !12, !2 }
!13 = !{ !13, !3 }
Have I used the metadata nodes correctly? The goal is to make:
- load may-alias store1
- load may-alias store2
- store2 may-alias store3
`-print-may-aliases` seems confirm this:
opt -disable-output -basicaa -scoped-noalias -aa-eval
-evaluate-aa-metadata -print-may-aliases ohgod.ll
Function: f: 4 pointers, 0 call sites
MayAlias: %T* %a, %T* %b
MayAlias: %T* %a, %T* %c
MayAlias: %T* %b, %T* %c
MayAlias: %T* %a, %T* %d
MayAlias: %T* %b, %T* %d
MayAlias: %T* %c, %T* %d
MayAlias: %val = load %T, %T* %a, !alias.scope !0 <-> store %T {
i32 23, i32 23 }, %T* %b, !alias.scope !3
MayAlias: %val = load %T, %T* %a, !alias.scope !0 <-> store %T {
i32 44, i32 44 }, %T* %c, !alias.scope !6, !noalias !3
MayAlias: store %T %val, %T* %d, !alias.scope !9, !noalias !12
<-> store %T { i32 44, i32 44 }, %T* %c, !alias.scope !6, !noalias !3
The problem is that MCO happily moves store2 + store3 above store1 (this is
fine) and then the load below store2 (this is not fine) in order to combine
load + store3 into a memcpy:
opt -S -basicaa -scoped-noalias -aa-eval -evaluate-aa-metadata
-memcpyopt
%T = type { i32, i32 }
define void @f(%T* %a, %T* %b, %T* %c, %T* %d) {
; store2
store %T { i32 44, i32 44 }, %T* %c, !alias.scope !0, !noalias !3
; combined from load + store3
call void @llvm.memcpy.p0i8.p0i8.i64(i8* (bitcast %T* %d to i8*),
i8* (bitcast %T* %a to i8*),
i64 8, i32 4, i1 false)
; store1
store %T { i32 23, i32 23 }, %T* %b, !alias.scope !3
ret void
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161117/639c0121/attachment.html>
More information about the llvm-dev
mailing list