150
|
1 ; RUN: opt -S -early-cse < %s | FileCheck %s
|
|
2
|
|
3 ; While it is normally okay to do memory optimizations over calls to
|
|
4 ; @readonly_function and @readnone_function, we cannot do that if
|
|
5 ; they're carrying unknown operand bundles since the presence of
|
|
6 ; unknown operand bundles implies arbitrary memory effects.
|
|
7
|
|
8 declare void @readonly_function() readonly nounwind
|
|
9 declare void @readnone_function() readnone nounwind
|
|
10
|
|
11 define i32 @test0(i32* %x) {
|
|
12 ; CHECK-LABEL: @test0(
|
|
13 entry:
|
|
14 store i32 100, i32* %x
|
|
15 ; CHECK: store i32 100, i32* %x
|
|
16 call void @readonly_function() [ "tag"() ]
|
|
17 ; CHECK: call void @readonly_function()
|
|
18
|
|
19 %v = load i32, i32* %x
|
|
20 ; CHECK: %v = load i32, i32* %x
|
|
21 ; CHECK: ret i32 %v
|
|
22 ret i32 %v
|
|
23 }
|
|
24
|
|
25 define i32 @test1(i32* %x) {
|
|
26 ; CHECK: @test1(
|
|
27 entry:
|
|
28 store i32 100, i32* %x
|
|
29 ; CHECK: store i32 100, i32* %x
|
|
30 call void @readonly_function() readonly [ "tag"() ]
|
|
31 ; CHECK-NOT: call void @readonly_function
|
|
32 %v = load i32, i32* %x
|
|
33 ret i32 %v
|
|
34 ; CHECK: ret i32 100
|
|
35 }
|
|
36
|
|
37 define i32 @test3(i32* %x) {
|
|
38 ; CHECK-LABEL: @test3(
|
|
39 entry:
|
|
40 store i32 100, i32* %x
|
|
41 ; CHECK: store i32 100, i32* %x
|
|
42 call void @readonly_function()
|
|
43 ; CHECK-NOT: call void @readonly_function
|
|
44 %v = load i32, i32* %x
|
|
45 ret i32 %v
|
|
46 ; CHECK: ret i32 100
|
|
47 }
|
|
48
|
|
49 define void @test4(i32* %x) {
|
|
50 ; CHECK-LABEL: @test4(
|
|
51 entry:
|
|
52 store i32 100, i32* %x
|
|
53 ; CHECK: store i32 100, i32* %x
|
|
54 call void @readnone_function() [ "tag"() ]
|
|
55 ; CHECK: call void @readnone_function
|
|
56 store i32 200, i32* %x
|
|
57 ; CHECK: store i32 200, i32* %x
|
|
58 ret void
|
|
59 }
|
|
60
|
|
61 define void @test5(i32* %x) {
|
|
62 ; CHECK-LABEL: @test5(
|
|
63 entry:
|
|
64 store i32 100, i32* %x
|
|
65 ; CHECK-NOT: store i32 100, i32* %x
|
|
66 ; CHECK-NOT: call void @readnone_function
|
|
67 call void @readnone_function() readnone [ "tag"() ]
|
|
68 store i32 200, i32* %x
|
|
69 ; CHECK: store i32 200, i32* %x
|
|
70 ret void
|
|
71 }
|
|
72
|
|
73 define void @test6(i32* %x) {
|
|
74 ; The "deopt" operand bundle does not make the call to
|
|
75 ; @readonly_function read-write; and so the nounwind readonly call can
|
|
76 ; be deleted.
|
|
77
|
|
78 ; CHECK-LABEL: @test6(
|
|
79 entry:
|
|
80
|
|
81 ; CHECK-NEXT: entry:
|
|
82 ; CHECK-NEXT: store i32 200, i32* %x
|
|
83 ; CHECK-NEXT: ret void
|
|
84
|
|
85 store i32 100, i32* %x
|
|
86 call void @readonly_function() [ "deopt"() ]
|
|
87 store i32 200, i32* %x
|
|
88 ret void
|
|
89 }
|