1; RUN: opt -instcombine -early-cse -earlycse-debug-hash -S < %s | FileCheck %s
2
3
4; CHECK-LABEL: define i8* @simplifyNullLaunder()
5define i8* @simplifyNullLaunder() {
6; CHECK-NEXT: ret i8* null
7  %b2 = call i8* @llvm.launder.invariant.group.p0i8(i8* null)
8  ret i8* %b2
9}
10
11; CHECK-LABEL: define i8* @dontSimplifyNullLaunderNoNullOpt()
12define i8* @dontSimplifyNullLaunderNoNullOpt() #0 {
13; CHECK-NEXT: call i8* @llvm.launder.invariant.group.p0i8(i8* null)
14  %b2 = call i8* @llvm.launder.invariant.group.p0i8(i8* null)
15  ret i8* %b2
16}
17
18; CHECK-LABEL: define i8 addrspace(42)* @dontsimplifyNullLaunderForDifferentAddrspace()
19define i8 addrspace(42)* @dontsimplifyNullLaunderForDifferentAddrspace() {
20; CHECK: %b2 = call i8 addrspace(42)* @llvm.launder.invariant.group.p42i8(i8 addrspace(42)* null)
21; CHECK: ret i8 addrspace(42)* %b2
22  %b2 = call i8 addrspace(42)* @llvm.launder.invariant.group.p42i8(i8 addrspace(42)* null)
23  ret i8 addrspace(42)* %b2
24}
25
26; CHECK-LABEL: define i8* @simplifyUndefLaunder()
27define i8* @simplifyUndefLaunder() {
28; CHECK-NEXT: ret i8* undef
29  %b2 = call i8* @llvm.launder.invariant.group.p0i8(i8* undef)
30  ret i8* %b2
31}
32
33; CHECK-LABEL: define i8 addrspace(42)* @simplifyUndefLaunder2()
34define i8 addrspace(42)* @simplifyUndefLaunder2() {
35; CHECK-NEXT: ret i8 addrspace(42)* undef
36  %b2 = call i8 addrspace(42)* @llvm.launder.invariant.group.p42i8(i8 addrspace(42)* undef)
37  ret i8 addrspace(42)* %b2
38}
39
40; CHECK-LABEL: define i8* @simplifyNullStrip()
41define i8* @simplifyNullStrip() {
42; CHECK-NEXT: ret i8* null
43  %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* null)
44  ret i8* %b2
45}
46
47; CHECK-LABEL: define i8* @dontSimplifyNullStripNonNullOpt()
48define i8* @dontSimplifyNullStripNonNullOpt() #0 {
49; CHECK-NEXT: call i8* @llvm.strip.invariant.group.p0i8(i8* null)
50  %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* null)
51  ret i8* %b2
52}
53
54; CHECK-LABEL: define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace()
55define i8 addrspace(42)* @dontsimplifyNullStripForDifferentAddrspace() {
56; CHECK: %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null)
57; CHECK: ret i8 addrspace(42)* %b2
58  %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* null)
59  ret i8 addrspace(42)* %b2
60}
61
62; CHECK-LABEL: define i8* @simplifyUndefStrip()
63define i8* @simplifyUndefStrip() {
64; CHECK-NEXT: ret i8* undef
65  %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* undef)
66  ret i8* %b2
67}
68
69; CHECK-LABEL: define i8 addrspace(42)* @simplifyUndefStrip2()
70define i8 addrspace(42)* @simplifyUndefStrip2() {
71; CHECK-NEXT: ret i8 addrspace(42)* undef
72  %b2 = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* undef)
73  ret i8 addrspace(42)* %b2
74}
75
76; CHECK-LABEL: define i8* @simplifyLaunderOfLaunder(
77define i8* @simplifyLaunderOfLaunder(i8* %a) {
78; CHECK:   call i8* @llvm.launder.invariant.group.p0i8(i8* %a)
79; CHECK-NOT: llvm.launder.invariant.group
80  %a2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %a)
81  %a3 = call i8* @llvm.launder.invariant.group.p0i8(i8* %a2)
82  ret i8* %a3
83}
84
85; CHECK-LABEL: define i8* @simplifyStripOfLaunder(
86define i8* @simplifyStripOfLaunder(i8* %a) {
87; CHECK-NOT: llvm.launder.invariant.group
88; CHECK:   call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
89  %a2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %a)
90  %a3 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a2)
91  ret i8* %a3
92}
93
94; CHECK-LABEL: define i1 @simplifyForCompare(
95define i1 @simplifyForCompare(i8* %a) {
96  %a2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %a)
97
98  %a3 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a2)
99  %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
100  %c = icmp eq i8* %a3, %b2
101; CHECK: ret i1 true
102  ret i1 %c
103}
104
105; CHECK-LABEL: define i16* @skipWithDifferentTypes(
106define i16* @skipWithDifferentTypes(i8* %a) {
107  %a2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %a)
108  %c1 = bitcast i8* %a2 to i16*
109
110  ; CHECK: %[[b:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
111  %a3 = call i16* @llvm.strip.invariant.group.p0i16(i16* %c1)
112  ; CHECK-NEXT: %[[r:.*]] = bitcast i8* %[[b]] to i16*
113  ; CHECK-NEXT: ret i16* %[[r]]
114  ret i16* %a3
115}
116
117; CHECK-LABEL: define i16 addrspace(42)* @skipWithDifferentTypesAddrspace(
118define i16 addrspace(42)* @skipWithDifferentTypesAddrspace(i8 addrspace(42)* %a) {
119  %a2 = call i8 addrspace(42)* @llvm.launder.invariant.group.p42i8(i8 addrspace(42)* %a)
120  %c1 = bitcast i8 addrspace(42)* %a2 to i16 addrspace(42)*
121
122  ; CHECK: %[[b:.*]] = call i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)* %a)
123  %a3 = call i16 addrspace(42)* @llvm.strip.invariant.group.p42i16(i16 addrspace(42)* %c1)
124  ; CHECK-NEXT: %[[r:.*]] = bitcast i8 addrspace(42)* %[[b]] to i16 addrspace(42)*
125  ; CHECK-NEXT: ret i16 addrspace(42)* %[[r]]
126  ret i16 addrspace(42)* %a3
127}
128
129; CHECK-LABEL: define i16 addrspace(42)* @skipWithDifferentTypesDifferentAddrspace(
130define i16 addrspace(42)* @skipWithDifferentTypesDifferentAddrspace(i8* %a) {
131  %cast = addrspacecast i8* %a to i8 addrspace(42)*
132  %a2 = call i8 addrspace(42)* @llvm.launder.invariant.group.p42i8(i8 addrspace(42)* %cast)
133  %c1 = bitcast i8 addrspace(42)* %a2 to i16 addrspace(42)*
134
135  ; CHECK: %[[b:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
136  %a3 = call i16 addrspace(42)* @llvm.strip.invariant.group.p42i16(i16 addrspace(42)* %c1)
137  ; CHECK-NEXT: %[[r:.*]] = bitcast i8* %[[b]] to i16*
138  ; CHECK-NEXT: %[[r2:.*]] = addrspacecast i16* %[[r]] to i16 addrspace(42)*
139  ; CHECK-NEXT: ret i16 addrspace(42)* %[[r2]]
140  ret i16 addrspace(42)* %a3
141}
142
143declare i8* @llvm.launder.invariant.group.p0i8(i8*)
144declare i8 addrspace(42)* @llvm.launder.invariant.group.p42i8(i8 addrspace(42)*)
145declare i8* @llvm.strip.invariant.group.p0i8(i8*)
146declare i8 addrspace(42)* @llvm.strip.invariant.group.p42i8(i8 addrspace(42)*)
147declare i16* @llvm.strip.invariant.group.p0i16(i16* %c1)
148declare i16 addrspace(42)* @llvm.strip.invariant.group.p42i16(i16 addrspace(42)* %c1)
149
150attributes #0 = { null_pointer_is_valid }
151