1; RUN: opt -early-cse -earlycse-debug-hash -S < %s | FileCheck %s
2; RUN: opt -basic-aa -early-cse-memssa -S < %s | FileCheck %s
3; Same as GVN/edge.ll, but updated to reflect EarlyCSE's less powerful
4; implementation.  EarlyCSE currently doesn't exploit equality comparisons
5; against constants.
6
7define i32 @f1(i32 %x) {
8  ; CHECK-LABEL: define i32 @f1(
9bb0:
10  %cmp = icmp eq i32 %x, 0
11  br i1 %cmp, label %bb2, label %bb1
12bb1:
13  br label %bb2
14bb2:
15  %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ]
16  %foo = add i32 %cond, %x
17  ret i32 %foo
18  ; CHECK: bb2:
19  ; CHECK: %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ]
20}
21
22define i32 @f2(i32 %x) {
23  ; CHECK-LABEL: define i32 @f2(
24bb0:
25  %cmp = icmp ne i32 %x, 0
26  br i1 %cmp, label %bb1, label %bb2
27bb1:
28  br label %bb2
29bb2:
30  %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ]
31  %foo = add i32 %cond, %x
32  ret i32 %foo
33  ; CHECK: bb2:
34  ; CHECK: %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ]
35}
36
37define i32 @f3(i32 %x) {
38  ; CHECK-LABEL: define i32 @f3(
39bb0:
40  switch i32 %x, label %bb1 [ i32 0, label %bb2]
41bb1:
42  br label %bb2
43bb2:
44  %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ]
45  %foo = add i32 %cond, %x
46  ret i32 %foo
47  ; CHECK: bb2:
48  ; CHECK: %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ]
49}
50
51declare void @g(i1)
52define void @f4(i8 * %x)  {
53; CHECK-LABEL: define void @f4(
54bb0:
55  %y = icmp eq i8* null, %x
56  br i1 %y, label %bb2, label %bb1
57bb1:
58  br label %bb2
59bb2:
60  %zed = icmp eq i8* null, %x
61  call void @g(i1 %zed)
62; CHECK: call void @g(i1 %y)
63  ret void
64}
65
66define double @fcmp_oeq_not_zero(double %x, double %y) {
67entry:
68  %cmp = fcmp oeq double %y, 2.0
69  br i1 %cmp, label %if, label %return
70
71if:
72  %div = fdiv double %x, %y
73  br label %return
74
75return:
76  %retval = phi double [ %div, %if ], [ %x, %entry ]
77  ret double %retval
78
79; CHECK-LABEL: define double @fcmp_oeq_not_zero(
80; CHECK: %div = fdiv double %x, %y
81}
82
83define double @fcmp_une_not_zero(double %x, double %y) {
84entry:
85  %cmp = fcmp une double %y, 2.0
86  br i1 %cmp, label %return, label %else
87
88else:
89  %div = fdiv double %x, %y
90  br label %return
91
92return:
93  %retval = phi double [ %div, %else ], [ %x, %entry ]
94  ret double %retval
95
96; CHECK-LABEL: define double @fcmp_une_not_zero(
97; CHECK: %div = fdiv double %x, %y
98}
99
100; PR22376 - We can't propagate zero constants because -0.0
101; compares equal to 0.0. If %y is -0.0 in this test case,
102; we would produce the wrong sign on the infinity return value.
103define double @fcmp_oeq_zero(double %x, double %y) {
104entry:
105  %cmp = fcmp oeq double %y, 0.0
106  br i1 %cmp, label %if, label %return
107
108if:
109  %div = fdiv double %x, %y
110  br label %return
111
112return:
113  %retval = phi double [ %div, %if ], [ %x, %entry ]
114  ret double %retval
115
116; CHECK-LABEL: define double @fcmp_oeq_zero(
117; CHECK: %div = fdiv double %x, %y
118}
119
120define double @fcmp_une_zero(double %x, double %y) {
121entry:
122  %cmp = fcmp une double %y, -0.0
123  br i1 %cmp, label %return, label %else
124
125else:
126  %div = fdiv double %x, %y
127  br label %return
128
129return:
130  %retval = phi double [ %div, %else ], [ %x, %entry ]
131  ret double %retval
132
133; CHECK-LABEL: define double @fcmp_une_zero(
134; CHECK: %div = fdiv double %x, %y
135}
136
137; We also cannot propagate a value if it's not a constant.
138; This is because the value could be 0.0 or -0.0.
139
140define double @fcmp_oeq_maybe_zero(double %x, double %y, double %z1, double %z2) {
141entry:
142 %z = fadd double %z1, %z2
143 %cmp = fcmp oeq double %y, %z
144 br i1 %cmp, label %if, label %return
145
146if:
147 %div = fdiv double %x, %z
148 br label %return
149
150return:
151 %retval = phi double [ %div, %if ], [ %x, %entry ]
152 ret double %retval
153
154; CHECK-LABEL: define double @fcmp_oeq_maybe_zero(
155; CHECK: %div = fdiv double %x, %z
156}
157
158define double @fcmp_une_maybe_zero(double %x, double %y, double %z1, double %z2) {
159entry:
160 %z = fadd double %z1, %z2
161 %cmp = fcmp une double %y, %z
162 br i1 %cmp, label %return, label %else
163
164else:
165 %div = fdiv double %x, %z
166 br label %return
167
168return:
169 %retval = phi double [ %div, %else ], [ %x, %entry ]
170 ret double %retval
171
172; CHECK-LABEL: define double @fcmp_une_maybe_zero(
173; CHECK: %div = fdiv double %x, %z
174}
175