xref: /llvm-project/llvm/test/Feature/OperandBundles/dse.ll (revision 1842a2909e80da9432c5d79a95ec2c331bd99744)
1; RUN: opt -S -passes=dse < %s | FileCheck %s
2
3declare void @f()
4declare noalias ptr @malloc(i32) nounwind
5
6define void @test_0() {
7; CHECK-LABEL: @test_0(
8  %m = call ptr @malloc(i32 24)
9  tail call void @f() [ "unknown"(ptr %m) ]
10; CHECK: store i8 -19, ptr %m
11  store i8 -19, ptr %m
12  ret void
13}
14
15define ptr @test_1() {
16; CHECK-LABEL: @test_1(
17  %m = call ptr @malloc(i32 24)
18  tail call void @f() [ "unknown"(ptr %m) ]
19  store i8 -19, ptr %m
20  tail call void @f()
21  store i8 101, ptr %m
22
23; CHECK: tail call void @f() [ "unknown"(ptr %m) ]
24; CHECK: store i8 -19, ptr %m
25; CHECK: tail call void @f()
26; CHECK: store i8 101, ptr %m
27
28  ret ptr %m
29}
30
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 ptr @malloc(i32 24)
37  tail call void @f() [ "deopt"(ptr %m) ]
38  store i8 -19, ptr %m
39  ret void
40
41; CHECK:  tail call void @f() [ "deopt"(ptr %m) ]
42; CHECK-NEXT:  ret void
43}
44
45define ptr @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 ptr @malloc(i32 24)
51  tail call void @f() [ "deopt"(ptr %m) ]
52  store i8 -19, ptr %m
53  tail call void @f()
54  store i8 101, ptr %m
55  ret ptr %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.
63