diff llvm/test/Feature/OperandBundles/basic-aa-argmemonly.ll @ 150:1d019706d866

LLVM10
author anatofuz
date Thu, 13 Feb 2020 15:10:13 +0900
parents
children 2e18cbf3894f
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/llvm/test/Feature/OperandBundles/basic-aa-argmemonly.ll	Thu Feb 13 15:10:13 2020 +0900
@@ -0,0 +1,51 @@
+; RUN: opt -S -basicaa -gvn < %s | FileCheck %s
+
+declare void @argmemonly_function(i32 *) argmemonly
+
+define i32 @test0(i32* %P, i32* noalias %P2) {
+; CHECK-LABEL: @test0(
+  %v1 = load i32, i32* %P
+; CHECK: %v1 = load i32, i32* %P
+  call void @argmemonly_function(i32* %P2) [ "tag"() ]
+; CHECK: call void @argmemonly_function(
+  %v2 = load i32, i32* %P
+; CHECK: %v2 = load i32, i32* %P
+  %diff = sub i32 %v1, %v2
+; CHECK: %diff = sub i32 %v1, %v2
+  ret i32 %diff
+; CHECK: ret i32 %diff
+}
+
+define i32 @test1(i32* %P, i32* noalias %P2) {
+; CHECK-LABEL: @test1(
+  %v1 = load i32, i32* %P
+  call void @argmemonly_function(i32* %P2) argmemonly [ "tag"() ]
+; CHECK: call void @argmemonly_function(
+  %v2 = load i32, i32* %P
+  %diff = sub i32 %v1, %v2
+  ret i32 %diff
+; CHECK: ret i32 0
+}
+
+define i32 @test2(i32* %P, i32* noalias %P2) {
+; Note: in this test we //can// GVN %v1 and %v2 into one value in theory.  Calls
+; with deopt operand bundles are not argmemonly because they *read* the entire
+; heap, but they don't write to any location in the heap if the callee does not
+; deoptimize the caller.  This fact, combined with the fact that
+; @argmemonly_function is, well, an argmemonly function, can be used to conclude
+; that %P is not written to at the callsite.  However LLVM currently cannot
+; describe the "does not write to non-args, and reads the entire heap" effect on
+; a callsite.
+
+; CHECK-LABEL: @test2(
+  %v1 = load i32, i32* %P
+; CHECK: %v1 = load i32, i32* %P
+  call void @argmemonly_function(i32* %P2) [ "deopt"() ]
+; CHECK: call void @argmemonly_function(
+  %v2 = load i32, i32* %P
+; CHECK: %v2 = load i32, i32* %P
+  %diff = sub i32 %v1, %v2
+; CHECK: %diff = sub i32 %v1, %v2
+  ret i32 %diff
+; CHECK: ret i32 %diff
+}