Hi,
I'm trying to get AA results for two pointers, but it seems that AA
cannot look though a memcpy. For example:
define dso_local spir_func void @fun() {
entry:
; Store an address of `var'
%var = alloca i32, align 4
store i32 42, i32* %var, align 4
%var.addr = alloca i32*, align 8
store i32* %var, i32** %var.addr, align 8
; Memcpy `var.addr' to `var.addr.tmp'
%var.addr.tmp = alloca i32*, align 8
%0 = bitcast i32** %var.addr.tmp to i8*
%1 = bitcast i32** %var.addr to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %0, i8* align 8 %1, i64 8, i1 false)
; Load a copy of `var'
%var.tmp = load i32*, i32** %var.addr.tmp
%should.be.42 = load i32, i32* %var.tmp
ret void
}
; Function Attrs: argmemonly nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1) #1
attributes #1 = { argmemonly nounwind }
I run it with opt, and get the following:
$ opt -basicaa -print-alias-sets memcpy.ll -disable-output
Alias sets for function 'fun':
Alias Set Tracker: 3 alias sets for 6 pointer values.
AliasSet[0x5b5df0, 2] may alias, Mod/Ref Pointers: (i32* %var, LocationSize::precise(4)), (i32* %var.tmp, LocationSize::precise(4))
AliasSet[0x5b5e90, 2] must alias, Mod/Ref Pointers: (i32** %var.addr, LocationSize::precise(8)), (i8* %1, LocationSize::precise(8))
AliasSet[0x5b7390, 2] must alias, Mod/Ref Pointers: (i8* %0, LocationSize::precise(8)), (i32** %var.addr.tmp, LocationSize::precise(8))
So AA says that %var and %var.tmp "may alias", but I'd expect to get a
"must alias". What can be done to determine that %var and %var.tmp are
actually the same pointer in this case?