1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -basicaa -gvn < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Workerdeclare void @argmemonly_function(i32 *) argmemonly 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Workerdefine i32 @test0(i32* %P, i32* noalias %P2) { 6*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test0( 7*9880d681SAndroid Build Coastguard Worker %v1 = load i32, i32* %P 8*9880d681SAndroid Build Coastguard Worker; CHECK: %v1 = load i32, i32* %P 9*9880d681SAndroid Build Coastguard Worker call void @argmemonly_function(i32* %P2) [ "tag"() ] 10*9880d681SAndroid Build Coastguard Worker; CHECK: call void @argmemonly_function( 11*9880d681SAndroid Build Coastguard Worker %v2 = load i32, i32* %P 12*9880d681SAndroid Build Coastguard Worker; CHECK: %v2 = load i32, i32* %P 13*9880d681SAndroid Build Coastguard Worker %diff = sub i32 %v1, %v2 14*9880d681SAndroid Build Coastguard Worker; CHECK: %diff = sub i32 %v1, %v2 15*9880d681SAndroid Build Coastguard Worker ret i32 %diff 16*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %diff 17*9880d681SAndroid Build Coastguard Worker} 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Workerdefine i32 @test1(i32* %P, i32* noalias %P2) { 20*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1( 21*9880d681SAndroid Build Coastguard Worker %v1 = load i32, i32* %P 22*9880d681SAndroid Build Coastguard Worker call void @argmemonly_function(i32* %P2) argmemonly [ "tag"() ] 23*9880d681SAndroid Build Coastguard Worker; CHECK: call void @argmemonly_function( 24*9880d681SAndroid Build Coastguard Worker %v2 = load i32, i32* %P 25*9880d681SAndroid Build Coastguard Worker %diff = sub i32 %v1, %v2 26*9880d681SAndroid Build Coastguard Worker ret i32 %diff 27*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0 28*9880d681SAndroid Build Coastguard Worker} 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Workerdefine i32 @test2(i32* %P, i32* noalias %P2) { 31*9880d681SAndroid Build Coastguard Worker; Note: in this test we //can// GVN %v1 and %v2 into one value in theory. Calls 32*9880d681SAndroid Build Coastguard Worker; with deopt operand bundles are not argmemonly because they *read* the entire 33*9880d681SAndroid Build Coastguard Worker; heap, but they don't write to any location in the heap if the callee does not 34*9880d681SAndroid Build Coastguard Worker; deoptimize the caller. This fact, combined with the fact that 35*9880d681SAndroid Build Coastguard Worker; @argmemonly_function is, well, an argmemonly function, can be used to conclude 36*9880d681SAndroid Build Coastguard Worker; that %P is not written to at the callsite. However LLVM currently cannot 37*9880d681SAndroid Build Coastguard Worker; describe the "does not write to non-args, and reads the entire heap" effect on 38*9880d681SAndroid Build Coastguard Worker; a callsite. 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2( 41*9880d681SAndroid Build Coastguard Worker %v1 = load i32, i32* %P 42*9880d681SAndroid Build Coastguard Worker; CHECK: %v1 = load i32, i32* %P 43*9880d681SAndroid Build Coastguard Worker call void @argmemonly_function(i32* %P2) [ "deopt"() ] 44*9880d681SAndroid Build Coastguard Worker; CHECK: call void @argmemonly_function( 45*9880d681SAndroid Build Coastguard Worker %v2 = load i32, i32* %P 46*9880d681SAndroid Build Coastguard Worker; CHECK: %v2 = load i32, i32* %P 47*9880d681SAndroid Build Coastguard Worker %diff = sub i32 %v1, %v2 48*9880d681SAndroid Build Coastguard Worker; CHECK: %diff = sub i32 %v1, %v2 49*9880d681SAndroid Build Coastguard Worker ret i32 %diff 50*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %diff 51*9880d681SAndroid Build Coastguard Worker} 52