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