blob: a2183d0457c7d6ad0db9353ff730802601e0a7a8 [file] [log] [blame]
Sanjoy Dasea343822015-11-04 23:21:06 +00001; RUN: opt -S -dse < %s | FileCheck %s
2
3declare void @f()
4declare noalias i8* @malloc(i32) nounwind
5
6define void @test_0() {
7; CHECK-LABEL: @test_0(
8 %m = call i8* @malloc(i32 24)
9 tail call void @f() [ "unknown"(i8* %m) ]
10; CHECK: store i8 -19, i8* %m
11 store i8 -19, i8* %m
12 ret void
13}
14
15define i8* @test_1() {
16; CHECK-LABEL: @test_1(
17 %m = call i8* @malloc(i32 24)
18 tail call void @f() [ "unknown"(i8* %m) ]
19 store i8 -19, i8* %m
20 tail call void @f()
21 store i8 101, i8* %m
22
23; CHECK: tail call void @f() [ "unknown"(i8* %m) ]
24; CHECK: store i8 -19, i8* %m
25; CHECK: tail call void @f()
26; CHECK: store i8 101, i8* %m
27
28 ret i8* %m
29}
Sanjoy Dasbcd15032015-11-26 01:16:05 +000030
31define void @test_2() {
32; Since the deopt operand bundle does not escape %m (see caveat below), it is
33; legal to elide the final store that location.
34
35; CHECK-LABEL: @test_2(
36 %m = call i8* @malloc(i32 24)
37 tail call void @f() [ "deopt"(i8* %m) ]
38 store i8 -19, i8* %m
39 ret void
40
41; CHECK: tail call void @f() [ "deopt"(i8* %m) ]
Benjamin Kramerdb9e0b62017-01-22 20:28:56 +000042; CHECK-NEXT: ret void
Sanjoy Dasbcd15032015-11-26 01:16:05 +000043}
44
45define i8* @test_3() {
46; Since the deopt operand bundle does not escape %m (see caveat below), @f
47; cannot observe the stores to %m
48
49; CHECK-LABEL: @test_3(
50 %m = call i8* @malloc(i32 24)
51 tail call void @f() [ "deopt"(i8* %m) ]
52 store i8 -19, i8* %m
53 tail call void @f()
54 store i8 101, i8* %m
55 ret i8* %m
56}
57
58
59; Caveat: technically, %m can only escape if the calling function is deoptimized
60; at the call site (i.e. the call returns to the "deopt" continuation). Since
61; the calling function body will be invalidated in that case, the calling
62; function can be optimized under the assumption that %m does not escape.