Home | History | Annotate | Download | only in OperandBundles
      1 ; RUN: opt -S -basicaa -gvn < %s | FileCheck %s
      2 
      3 declare void @argmemonly_function(i32 *) argmemonly
      4 
      5 define i32 @test0(i32* %P, i32* noalias %P2) {
      6 ; CHECK-LABEL: @test0(
      7   %v1 = load i32, i32* %P
      8 ; CHECK: %v1 = load i32, i32* %P
      9   call void @argmemonly_function(i32* %P2) [ "tag"() ]
     10 ; CHECK: call void @argmemonly_function(
     11   %v2 = load i32, i32* %P
     12 ; CHECK: %v2 = load i32, i32* %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 
     19 define i32 @test1(i32* %P, i32* noalias %P2) {
     20 ; CHECK-LABEL: @test1(
     21   %v1 = load i32, i32* %P
     22   call void @argmemonly_function(i32* %P2) argmemonly [ "tag"() ]
     23 ; CHECK: call void @argmemonly_function(
     24   %v2 = load i32, i32* %P
     25   %diff = sub i32 %v1, %v2
     26   ret i32 %diff
     27 ; CHECK: ret i32 0
     28 }
     29 
     30 define i32 @test2(i32* %P, i32* 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.  However LLVM currently cannot
     37 ; describe the "does not write to non-args, and reads the entire heap" effect on
     38 ; a callsite.
     39 
     40 ; CHECK-LABEL: @test2(
     41   %v1 = load i32, i32* %P
     42 ; CHECK: %v1 = load i32, i32* %P
     43   call void @argmemonly_function(i32* %P2) [ "deopt"() ]
     44 ; CHECK: call void @argmemonly_function(
     45   %v2 = load i32, i32* %P
     46 ; CHECK: %v2 = load i32, i32* %P
     47   %diff = sub i32 %v1, %v2
     48 ; CHECK: %diff = sub i32 %v1, %v2
     49   ret i32 %diff
     50 ; CHECK: ret i32 %diff
     51 }
     52