[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / Transforms / CorrelatedValuePropagation / phi-common-val.ll
blob7e712947e37ad9d071797d883d028ddff994b3de
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
4 define ptr @simplify_phi_common_value_op0(ptr %ptr, ptr %b) {
5 ; CHECK-LABEL: @simplify_phi_common_value_op0(
6 ; CHECK-NEXT:  entry:
7 ; CHECK-NEXT:    [[ISNULL:%.*]] = icmp eq ptr [[PTR:%.*]], null
8 ; CHECK-NEXT:    br i1 [[ISNULL]], label [[RETURN:%.*]], label [[ELSE:%.*]]
9 ; CHECK:       else:
10 ; CHECK-NEXT:    [[LB:%.*]] = load i32, ptr [[B:%.*]], align 4
11 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[LB]], 1
12 ; CHECK-NEXT:    store i32 [[ADD]], ptr [[B]], align 4
13 ; CHECK-NEXT:    br label [[RETURN]]
14 ; CHECK:       return:
15 ; CHECK-NEXT:    ret ptr [[PTR]]
17 entry:
18   %isnull = icmp eq ptr %ptr, null
19   br i1 %isnull, label %return, label %else
21 else:
22   %lb = load i32, ptr %b
23   %add = add nsw i32 %lb, 1
24   store i32 %add, ptr %b
25   br label %return
27 return:
28   %r = phi ptr [ %ptr, %else ], [ null, %entry ]
29   ret ptr %r
32 define ptr @simplify_phi_common_value_op1(ptr %ptr, ptr %b) {
33 ; CHECK-LABEL: @simplify_phi_common_value_op1(
34 ; CHECK-NEXT:  entry:
35 ; CHECK-NEXT:    [[ISNULL:%.*]] = icmp eq ptr [[PTR:%.*]], null
36 ; CHECK-NEXT:    br i1 [[ISNULL]], label [[RETURN:%.*]], label [[ELSE:%.*]]
37 ; CHECK:       else:
38 ; CHECK-NEXT:    [[LB:%.*]] = load i32, ptr [[B:%.*]], align 4
39 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[LB]], 1
40 ; CHECK-NEXT:    store i32 [[ADD]], ptr [[B]], align 4
41 ; CHECK-NEXT:    br label [[RETURN]]
42 ; CHECK:       return:
43 ; CHECK-NEXT:    ret ptr [[PTR]]
45 entry:
46   %isnull = icmp eq ptr %ptr, null
47   br i1 %isnull, label %return, label %else
49 else:
50   %lb = load i32, ptr %b
51   %add = add i32 %lb, 1
52   store i32 %add, ptr %b
53   br label %return
55 return:
56   %r = phi ptr [ null, %entry], [ %ptr, %else ]
57   ret ptr %r
60 define i8 @simplify_phi_multiple_constants(i8 %x, ptr %b) {
61 ; CHECK-LABEL: @simplify_phi_multiple_constants(
62 ; CHECK-NEXT:  entry:
63 ; CHECK-NEXT:    [[IS0:%.*]] = icmp eq i8 [[X:%.*]], 0
64 ; CHECK-NEXT:    br i1 [[IS0]], label [[RETURN:%.*]], label [[ELSE1:%.*]]
65 ; CHECK:       else1:
66 ; CHECK-NEXT:    [[IS42:%.*]] = icmp eq i8 [[X]], 42
67 ; CHECK-NEXT:    br i1 [[IS42]], label [[RETURN]], label [[ELSE2:%.*]]
68 ; CHECK:       else2:
69 ; CHECK-NEXT:    [[LB:%.*]] = load i32, ptr [[B:%.*]], align 4
70 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[LB]], 1
71 ; CHECK-NEXT:    store i32 [[ADD]], ptr [[B]], align 4
72 ; CHECK-NEXT:    br label [[RETURN]]
73 ; CHECK:       return:
74 ; CHECK-NEXT:    ret i8 [[X]]
76 entry:
77   %is0 = icmp eq i8 %x, 0
78   br i1 %is0, label %return, label %else1
80 else1:
81   %is42 = icmp eq i8 %x, 42
82   br i1 %is42, label %return, label %else2
84 else2:
85   %lb = load i32, ptr %b
86   %add = add i32 %lb, 1
87   store i32 %add, ptr %b
88   br label %return
90 return:
91   %r = phi i8 [ 0, %entry], [ %x, %else2 ], [ 42, %else1 ]
92   ret i8 %r
95 define ptr @simplify_phi_common_value_from_instruction(ptr %ptr_op, ptr %b, i32 %i) {
96 ; CHECK-LABEL: @simplify_phi_common_value_from_instruction(
97 ; CHECK-NEXT:  entry:
98 ; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr [[PTR_OP:%.*]], i32 [[I:%.*]]
99 ; CHECK-NEXT:    [[ISNULL:%.*]] = icmp eq ptr [[PTR]], null
100 ; CHECK-NEXT:    br i1 [[ISNULL]], label [[RETURN:%.*]], label [[ELSE:%.*]]
101 ; CHECK:       else:
102 ; CHECK-NEXT:    [[LB:%.*]] = load i32, ptr [[B:%.*]], align 4
103 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[LB]], 1
104 ; CHECK-NEXT:    store i32 [[ADD]], ptr [[B]], align 4
105 ; CHECK-NEXT:    br label [[RETURN]]
106 ; CHECK:       return:
107 ; CHECK-NEXT:    ret ptr [[PTR]]
109 entry:
110   %ptr = getelementptr i8, ptr %ptr_op, i32 %i
111   %isnull = icmp eq ptr %ptr, null
112   br i1 %isnull, label %return, label %else
114 else:
115   %lb = load i32, ptr %b
116   %add = add nsw i32 %lb, 1
117   store i32 %add, ptr %b
118   br label %return
120 return:
121   %r = phi ptr [ %ptr, %else ], [ null, %entry ]
122   ret ptr %r
125 ; The sub has 'nsw', so it is not safe to propagate that value along
126 ; the bb2 edge because that would propagate poison to the return.
127 ; FIXME: In this particular case, it would be possible to perform the
128 ; transform if we drop nowrap flags from the sub.
130 define i32 @PR43802(i32 %arg) {
131 ; CHECK-LABEL: @PR43802(
132 ; CHECK-NEXT:  entry:
133 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 0, [[ARG:%.*]]
134 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[ARG]], -2147483648
135 ; CHECK-NEXT:    br i1 [[CMP]], label [[BB2:%.*]], label [[BB3:%.*]]
136 ; CHECK:       bb2:
137 ; CHECK-NEXT:    br label [[BB3]]
138 ; CHECK:       bb3:
139 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ -2147483648, [[BB2]] ], [ [[SUB]], [[ENTRY:%.*]] ]
140 ; CHECK-NEXT:    ret i32 [[R]]
142 entry:
143   %sub = sub nsw i32 0, %arg
144   %cmp = icmp eq i32 %arg, -2147483648
145   br i1 %cmp, label %bb2, label %bb3
147 bb2:
148   br label %bb3
150 bb3:
151   %r = phi i32 [ -2147483648, %bb2 ], [ %sub, %entry ]
152   ret i32 %r
155 ; Same as previous test case, but without nowrap flags.
156 define i32 @PR43802_without_nowrap(i32 %arg) {
157 ; CHECK-LABEL: @PR43802_without_nowrap(
158 ; CHECK-NEXT:  entry:
159 ; CHECK-NEXT:    [[SUB1:%.*]] = sub nsw i32 0, [[ARG:%.*]]
160 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[ARG]], -2147483648
161 ; CHECK-NEXT:    br i1 [[CMP]], label [[BB2:%.*]], label [[BB3:%.*]]
162 ; CHECK:       bb2:
163 ; CHECK-NEXT:    br label [[BB3]]
164 ; CHECK:       bb3:
165 ; CHECK-NEXT:    [[SUB:%.*]] = phi i32 [ -2147483648, [[BB2]] ], [ [[SUB1]], [[ENTRY:%.*]] ]
166 ; CHECK-NEXT:    ret i32 [[SUB]]
168 entry:
169   %sub = sub i32 0, %arg
170   %cmp = icmp eq i32 %arg, -2147483648
171   br i1 %cmp, label %bb2, label %bb3
173 bb2:
174   br label %bb3
176 bb3:
177   %r = phi i32 [ -2147483648, %bb2 ], [ %sub, %entry ]
178   ret i32 %r
181 ; Similar to the previous case, we know that %y is always poison on the
182 ; entry -> join1 edge, and thus always zero or poison on the join1 -> join2
183 ; edge. We need to make sure that we don't replace zero with "zero or poison".
185 define i8 @pr50399(i8 %x) {
186 ; CHECK-LABEL: @pr50399(
187 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], -100
188 ; CHECK-NEXT:    [[Y:%.*]] = add nsw i8 [[X]], -100
189 ; CHECK-NEXT:    br i1 [[CMP]], label [[JOIN1:%.*]], label [[ELSE:%.*]]
190 ; CHECK:       else:
191 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[Y]], 0
192 ; CHECK-NEXT:    br i1 [[CMP2]], label [[JOIN1]], label [[ELSE2:%.*]]
193 ; CHECK:       join1:
194 ; CHECK-NEXT:    br label [[JOIN2:%.*]]
195 ; CHECK:       else2:
196 ; CHECK-NEXT:    br label [[JOIN2]]
197 ; CHECK:       join2:
198 ; CHECK-NEXT:    [[PHI:%.*]] = phi i8 [ 0, [[JOIN1]] ], [ [[Y]], [[ELSE2]] ]
199 ; CHECK-NEXT:    ret i8 [[PHI]]
201   %cmp = icmp slt i8 %x, -100
202   %y = add nsw i8 %x, -100
203   br i1 %cmp, label %join1, label %else
205 else:                                               ; preds = %cond.end9
206   %cmp2 = icmp eq i8 %y, 0
207   br i1 %cmp2, label %join1, label %else2
209 join1:
210   br label %join2
212 else2:                                         ; preds = %bb
213   br label %join2
215 join2:
216   %phi = phi i8 [ 0, %join1 ], [ %y, %else2 ]
217   ret i8 %phi