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(
7 ; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq ptr [[PTR:%.*]], null
8 ; CHECK-NEXT: br i1 [[ISNULL]], label [[RETURN:%.*]], label [[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]]
15 ; CHECK-NEXT: ret ptr [[PTR]]
18 %isnull = icmp eq ptr %ptr, null
19 br i1 %isnull, label %return, label %else
22 %lb = load i32, ptr %b
23 %add = add nsw i32 %lb, 1
24 store i32 %add, ptr %b
28 %r = phi ptr [ %ptr, %else ], [ null, %entry ]
32 define ptr @simplify_phi_common_value_op1(ptr %ptr, ptr %b) {
33 ; CHECK-LABEL: @simplify_phi_common_value_op1(
35 ; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq ptr [[PTR:%.*]], null
36 ; CHECK-NEXT: br i1 [[ISNULL]], label [[RETURN:%.*]], label [[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]]
43 ; CHECK-NEXT: ret ptr [[PTR]]
46 %isnull = icmp eq ptr %ptr, null
47 br i1 %isnull, label %return, label %else
50 %lb = load i32, ptr %b
52 store i32 %add, ptr %b
56 %r = phi ptr [ null, %entry], [ %ptr, %else ]
60 define i8 @simplify_phi_multiple_constants(i8 %x, ptr %b) {
61 ; CHECK-LABEL: @simplify_phi_multiple_constants(
63 ; CHECK-NEXT: [[IS0:%.*]] = icmp eq i8 [[X:%.*]], 0
64 ; CHECK-NEXT: br i1 [[IS0]], label [[RETURN:%.*]], label [[ELSE1:%.*]]
66 ; CHECK-NEXT: [[IS42:%.*]] = icmp eq i8 [[X]], 42
67 ; CHECK-NEXT: br i1 [[IS42]], label [[RETURN]], label [[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]]
74 ; CHECK-NEXT: ret i8 [[X]]
77 %is0 = icmp eq i8 %x, 0
78 br i1 %is0, label %return, label %else1
81 %is42 = icmp eq i8 %x, 42
82 br i1 %is42, label %return, label %else2
85 %lb = load i32, ptr %b
87 store i32 %add, ptr %b
91 %r = phi i8 [ 0, %entry], [ %x, %else2 ], [ 42, %else1 ]
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(
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:%.*]]
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]]
107 ; CHECK-NEXT: ret ptr [[PTR]]
110 %ptr = getelementptr i8, ptr %ptr_op, i32 %i
111 %isnull = icmp eq ptr %ptr, null
112 br i1 %isnull, label %return, label %else
115 %lb = load i32, ptr %b
116 %add = add nsw i32 %lb, 1
117 store i32 %add, ptr %b
121 %r = phi ptr [ %ptr, %else ], [ null, %entry ]
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(
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:%.*]]
137 ; CHECK-NEXT: br label [[BB3]]
139 ; CHECK-NEXT: [[R:%.*]] = phi i32 [ -2147483648, [[BB2]] ], [ [[SUB]], [[ENTRY:%.*]] ]
140 ; CHECK-NEXT: ret i32 [[R]]
143 %sub = sub nsw i32 0, %arg
144 %cmp = icmp eq i32 %arg, -2147483648
145 br i1 %cmp, label %bb2, label %bb3
151 %r = phi i32 [ -2147483648, %bb2 ], [ %sub, %entry ]
155 ; Same as previous test case, but without nowrap flags.
156 define i32 @PR43802_without_nowrap(i32 %arg) {
157 ; CHECK-LABEL: @PR43802_without_nowrap(
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:%.*]]
163 ; CHECK-NEXT: br label [[BB3]]
165 ; CHECK-NEXT: [[SUB:%.*]] = phi i32 [ -2147483648, [[BB2]] ], [ [[SUB1]], [[ENTRY:%.*]] ]
166 ; CHECK-NEXT: ret i32 [[SUB]]
169 %sub = sub i32 0, %arg
170 %cmp = icmp eq i32 %arg, -2147483648
171 br i1 %cmp, label %bb2, label %bb3
177 %r = phi i32 [ -2147483648, %bb2 ], [ %sub, %entry ]
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:%.*]]
191 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[Y]], 0
192 ; CHECK-NEXT: br i1 [[CMP2]], label [[JOIN1]], label [[ELSE2:%.*]]
194 ; CHECK-NEXT: br label [[JOIN2:%.*]]
196 ; CHECK-NEXT: br label [[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
216 %phi = phi i8 [ 0, %join1 ], [ %y, %else2 ]