xref: /llvm-project/llvm/test/Transforms/NewGVN/edge.ll (revision 229640343e400394b315c6798c7c19e8a9bd188c)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt -passes=newgvn -S < %s | FileCheck %s
3
4define i32 @f1(i32 %x) {
5; CHECK-LABEL: define i32 @f1(
6; CHECK-SAME: i32 [[X:%.*]]) {
7; CHECK-NEXT:  bb0:
8; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X]], 0
9; CHECK-NEXT:    br i1 [[CMP]], label [[BB2:%.*]], label [[BB1:%.*]]
10; CHECK:       bb1:
11; CHECK-NEXT:    br label [[BB2]]
12; CHECK:       bb2:
13; CHECK-NEXT:    ret i32 [[X]]
14;
15bb0:
16  %cmp = icmp eq i32 %x, 0
17  br i1 %cmp, label %bb2, label %bb1
18bb1:
19  br label %bb2
20bb2:
21  %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ]
22  %foo = add i32 %cond, %x
23  ret i32 %foo
24}
25
26define i32 @f2(i32 %x) {
27; CHECK-LABEL: define i32 @f2(
28; CHECK-SAME: i32 [[X:%.*]]) {
29; CHECK-NEXT:  bb0:
30; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X]], 0
31; CHECK-NEXT:    br i1 [[CMP]], label [[BB1:%.*]], label [[BB2:%.*]]
32; CHECK:       bb1:
33; CHECK-NEXT:    br label [[BB2]]
34; CHECK:       bb2:
35; CHECK-NEXT:    ret i32 [[X]]
36;
37bb0:
38  %cmp = icmp ne i32 %x, 0
39  br i1 %cmp, label %bb1, label %bb2
40bb1:
41  br label %bb2
42bb2:
43  %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ]
44  %foo = add i32 %cond, %x
45  ret i32 %foo
46}
47
48define i32 @f3(i32 %x) {
49; CHECK-LABEL: define i32 @f3(
50; CHECK-SAME: i32 [[X:%.*]]) {
51; CHECK-NEXT:  bb0:
52; CHECK-NEXT:    switch i32 [[X]], label [[BB1:%.*]] [
53; CHECK-NEXT:      i32 0, label [[BB2:%.*]]
54; CHECK-NEXT:    ]
55; CHECK:       bb1:
56; CHECK-NEXT:    br label [[BB2]]
57; CHECK:       bb2:
58; CHECK-NEXT:    ret i32 [[X]]
59;
60bb0:
61  switch i32 %x, label %bb1 [ i32 0, label %bb2]
62bb1:
63  br label %bb2
64bb2:
65  %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ]
66  %foo = add i32 %cond, %x
67  ret i32 %foo
68}
69
70declare void @g(i1)
71define void @f4(ptr %x)  {
72; CHECK-LABEL: define void @f4(
73; CHECK-SAME: ptr [[X:%.*]]) {
74; CHECK-NEXT:  bb0:
75; CHECK-NEXT:    [[Y:%.*]] = icmp eq ptr null, [[X]]
76; CHECK-NEXT:    br i1 [[Y]], label [[BB2:%.*]], label [[BB1:%.*]]
77; CHECK:       bb1:
78; CHECK-NEXT:    br label [[BB2]]
79; CHECK:       bb2:
80; CHECK-NEXT:    call void @g(i1 [[Y]])
81; CHECK-NEXT:    ret void
82;
83bb0:
84  %y = icmp eq ptr null, %x
85  br i1 %y, label %bb2, label %bb1
86bb1:
87  br label %bb2
88bb2:
89  %zed = icmp eq ptr null, %x
90  call void @g(i1 %zed)
91  ret void
92}
93
94define double @fcmp_oeq_not_zero(double %x, double %y) {
95; CHECK-LABEL: define double @fcmp_oeq_not_zero(
96; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
97; CHECK-NEXT:  entry:
98; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[Y]], 2.000000e+00
99; CHECK-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[RETURN:%.*]]
100; CHECK:       if:
101; CHECK-NEXT:    [[DIV:%.*]] = fdiv double [[X]], 2.000000e+00
102; CHECK-NEXT:    br label [[RETURN]]
103; CHECK:       return:
104; CHECK-NEXT:    [[RETVAL:%.*]] = phi double [ [[DIV]], [[IF]] ], [ [[X]], [[ENTRY:%.*]] ]
105; CHECK-NEXT:    ret double [[RETVAL]]
106;
107entry:
108  %cmp = fcmp oeq double %y, 2.0
109  br i1 %cmp, label %if, label %return
110
111if:
112  %div = fdiv double %x, %y
113  br label %return
114
115return:
116  %retval = phi double [ %div, %if ], [ %x, %entry ]
117  ret double %retval
118
119}
120
121define double @fcmp_une_not_zero(double %x, double %y) {
122; CHECK-LABEL: define double @fcmp_une_not_zero(
123; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
124; CHECK-NEXT:  entry:
125; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[Y]], 2.000000e+00
126; CHECK-NEXT:    br i1 [[CMP]], label [[RETURN:%.*]], label [[ELSE:%.*]]
127; CHECK:       else:
128; CHECK-NEXT:    [[DIV:%.*]] = fdiv double [[X]], 2.000000e+00
129; CHECK-NEXT:    br label [[RETURN]]
130; CHECK:       return:
131; CHECK-NEXT:    [[RETVAL:%.*]] = phi double [ [[DIV]], [[ELSE]] ], [ [[X]], [[ENTRY:%.*]] ]
132; CHECK-NEXT:    ret double [[RETVAL]]
133;
134entry:
135  %cmp = fcmp une double %y, 2.0
136  br i1 %cmp, label %return, label %else
137
138else:
139  %div = fdiv double %x, %y
140  br label %return
141
142return:
143  %retval = phi double [ %div, %else ], [ %x, %entry ]
144  ret double %retval
145
146}
147
148; PR22376 - We can't propagate zero constants because -0.0
149; compares equal to 0.0. If %y is -0.0 in this test case,
150; we would produce the wrong sign on the infinity return value.
151define double @fcmp_oeq_zero(double %x, double %y) {
152; CHECK-LABEL: define double @fcmp_oeq_zero(
153; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
154; CHECK-NEXT:  entry:
155; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00
156; CHECK-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[RETURN:%.*]]
157; CHECK:       if:
158; CHECK-NEXT:    [[DIV:%.*]] = fdiv double [[X]], [[Y]]
159; CHECK-NEXT:    br label [[RETURN]]
160; CHECK:       return:
161; CHECK-NEXT:    [[RETVAL:%.*]] = phi double [ [[DIV]], [[IF]] ], [ [[X]], [[ENTRY:%.*]] ]
162; CHECK-NEXT:    ret double [[RETVAL]]
163;
164entry:
165  %cmp = fcmp oeq double %y, 0.0
166  br i1 %cmp, label %if, label %return
167
168if:
169  %div = fdiv double %x, %y
170  br label %return
171
172return:
173  %retval = phi double [ %div, %if ], [ %x, %entry ]
174  ret double %retval
175
176}
177
178define double @fcmp_une_zero(double %x, double %y) {
179; CHECK-LABEL: define double @fcmp_une_zero(
180; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
181; CHECK-NEXT:  entry:
182; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[Y]], -0.000000e+00
183; CHECK-NEXT:    br i1 [[CMP]], label [[RETURN:%.*]], label [[ELSE:%.*]]
184; CHECK:       else:
185; CHECK-NEXT:    [[DIV:%.*]] = fdiv double [[X]], [[Y]]
186; CHECK-NEXT:    br label [[RETURN]]
187; CHECK:       return:
188; CHECK-NEXT:    [[RETVAL:%.*]] = phi double [ [[DIV]], [[ELSE]] ], [ [[X]], [[ENTRY:%.*]] ]
189; CHECK-NEXT:    ret double [[RETVAL]]
190;
191entry:
192  %cmp = fcmp une double %y, -0.0
193  br i1 %cmp, label %return, label %else
194
195else:
196  %div = fdiv double %x, %y
197  br label %return
198
199return:
200  %retval = phi double [ %div, %else ], [ %x, %entry ]
201  ret double %retval
202
203}
204
205; We also cannot propagate a value if it's not a constant.
206; This is because the value could be 0.0 or -0.0.
207
208define double @fcmp_oeq_maybe_zero(double %x, double %y, double %z1, double %z2) {
209; CHECK-LABEL: define double @fcmp_oeq_maybe_zero(
210; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]], double [[Z1:%.*]], double [[Z2:%.*]]) {
211; CHECK-NEXT:  entry:
212; CHECK-NEXT:    [[Z:%.*]] = fadd double [[Z1]], [[Z2]]
213; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[Y]], [[Z]]
214; CHECK-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[RETURN:%.*]]
215; CHECK:       if:
216; CHECK-NEXT:    [[DIV:%.*]] = fdiv double [[X]], [[Z]]
217; CHECK-NEXT:    br label [[RETURN]]
218; CHECK:       return:
219; CHECK-NEXT:    [[RETVAL:%.*]] = phi double [ [[DIV]], [[IF]] ], [ [[X]], [[ENTRY:%.*]] ]
220; CHECK-NEXT:    ret double [[RETVAL]]
221;
222entry:
223  %z = fadd double %z1, %z2
224  %cmp = fcmp oeq double %y, %z
225  br i1 %cmp, label %if, label %return
226
227if:
228  %div = fdiv double %x, %z
229  br label %return
230
231return:
232  %retval = phi double [ %div, %if ], [ %x, %entry ]
233  ret double %retval
234
235}
236
237define double @fcmp_une_maybe_zero(double %x, double %y, double %z1, double %z2) {
238; CHECK-LABEL: define double @fcmp_une_maybe_zero(
239; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]], double [[Z1:%.*]], double [[Z2:%.*]]) {
240; CHECK-NEXT:  entry:
241; CHECK-NEXT:    [[Z:%.*]] = fadd double [[Z1]], [[Z2]]
242; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[Y]], [[Z]]
243; CHECK-NEXT:    br i1 [[CMP]], label [[RETURN:%.*]], label [[ELSE:%.*]]
244; CHECK:       else:
245; CHECK-NEXT:    [[DIV:%.*]] = fdiv double [[X]], [[Z]]
246; CHECK-NEXT:    br label [[RETURN]]
247; CHECK:       return:
248; CHECK-NEXT:    [[RETVAL:%.*]] = phi double [ [[DIV]], [[ELSE]] ], [ [[X]], [[ENTRY:%.*]] ]
249; CHECK-NEXT:    ret double [[RETVAL]]
250;
251entry:
252  %z = fadd double %z1, %z2
253  %cmp = fcmp une double %y, %z
254  br i1 %cmp, label %return, label %else
255
256else:
257  %div = fdiv double %x, %z
258  br label %return
259
260return:
261  %retval = phi double [ %div, %else ], [ %x, %entry ]
262  ret double %retval
263
264}
265