xref: /llvm-project/llvm/test/Analysis/BasicAA/deoptimize.ll (revision 303c308e452c703c3d47940383ded3b2d3eefd56)
1; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
2target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
3
4@G1 = external global i32
5
6declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1)
7declare void @llvm.memmove.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1)
8declare void @llvm.experimental.deoptimize.void(...)
9declare void @unknown_but_readonly() readonly
10
11define void @test1(ptr %p) {
12  load i8, ptr %p
13  call void(...) @llvm.experimental.deoptimize.void() [ "deopt"() ]
14  ret void
15
16; CHECK-LABEL: Function: test1:
17; CHECK:  Just Ref: Ptr: i8* %p <-> call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
18}
19
20; By specification calls with deopt bundles reads through all operands and entire heap.
21; Check that global G1 is reported as Ref by memcpy/memmove calls.
22define i32 @test_memcpy_with_deopt() {
23; CHECK-LABEL: Function: test_memcpy_with_deopt:
24; CHECK: Both ModRef:  Ptr: i8* %A	<->  call void @llvm.memcpy.p0.p0.i64(ptr %A, ptr %B, i64 -1, i1 false) [ "deopt"() ]
25; CHECK: Just Ref:  Ptr: i8* %B	<->  call void @llvm.memcpy.p0.p0.i64(ptr %A, ptr %B, i64 -1, i1 false) [ "deopt"() ]
26; CHECK: Just Ref:  Ptr: i32* @G1	<->  call void @llvm.memcpy.p0.p0.i64(ptr %A, ptr %B, i64 -1, i1 false) [ "deopt"() ]
27
28  %A = alloca i8
29  %B = alloca i8
30  load i8, ptr %A
31  load i8, ptr %B
32
33  store i32 2, ptr @G1  ;; Not referenced by semantics of memcpy but still may be read due to "deopt"
34
35  call void @llvm.memcpy.p0.p0.i64(ptr %A, ptr %B, i64 -1, i1 false) [ "deopt"() ]
36
37  %C = load i32, ptr @G1
38  ret i32 %C
39}
40
41define i32 @test_memmove_with_deopt() {
42; CHECK-LABEL: Function: test_memmove_with_deopt:
43; CHECK: Both ModRef:  Ptr: i8* %A	<->  call void @llvm.memmove.p0.p0.i64(ptr %A, ptr %B, i64 -1, i1 false) [ "deopt"() ]
44; CHECK: Just Ref:  Ptr: i8* %B	<->  call void @llvm.memmove.p0.p0.i64(ptr %A, ptr %B, i64 -1, i1 false) [ "deopt"() ]
45; CHECK: Just Ref:  Ptr: i32* @G1	<->  call void @llvm.memmove.p0.p0.i64(ptr %A, ptr %B, i64 -1, i1 false) [ "deopt"() ]
46
47  %A = alloca i8
48  %B = alloca i8
49  load i8, ptr %A
50  load i8, ptr %B
51
52  store i32 2, ptr @G1  ;; Not referenced by semantics of memcpy but still may be read due to "deopt"
53
54  call void @llvm.memmove.p0.p0.i64(ptr %A, ptr %B, i64 -1, i1 false) [ "deopt"() ]
55
56  %C = load i32, ptr @G1
57  ret i32 %C
58}
59