@@ -237,6 +237,53 @@ Poison values can be replaced with any value of type (undef, concrete values,
237
237
or a ``freeze `` instruction).
238
238
239
239
240
+ Propagation of Poison Through Select
241
+ ------------------------------------
242
+ Most instructions return poison if any of their inputs is poison.
243
+ A notable exception is the ``select `` instruction, which is poison if and
244
+ only if the condition is poison or the selected value is poison.
245
+ This means that ``select `` acts as a barrier for poison propagation, which
246
+ impacts which optimizations can be performed.
247
+
248
+ For example, consider the following function:
249
+
250
+ .. code-block :: llvm
251
+
252
+ define i1 @fn(i32 %x, i32 %y) {
253
+ %cmp1 = icmp ne i32 %x, 0
254
+ %cmp2 = icmp ugt i32 %x, %y
255
+ %and = select i1 %cmp1, i1 %cmp2, i1 false
256
+ ret i1 %and
257
+ }
258
+
259
+ It is not correct to optimize the ``select `` into an ``and `` because when
260
+ ``%cmp1 `` is false, the ``select `` is only poison if ``%x `` is poison, while
261
+ the ``and `` below is poison if either ``%x `` or ``%y `` are poison.
262
+
263
+ .. code-block :: llvm
264
+
265
+ define i1 @fn(i32 %x, i32 %y) {
266
+ %cmp1 = icmp ne i32 %x, 0
267
+ %cmp2 = icmp ugt i32 %x, %y
268
+ %and = and i1 %cmp1, %cmp2 ;; poison if %x or %y are poison
269
+ ret i1 %and
270
+ }
271
+
272
+ However, the optimization is possible if all operands of the values are used in
273
+ the condition (notice the flipped operands in the ``select ``):
274
+
275
+ .. code-block :: llvm
276
+
277
+ define i1 @fn(i32 %x, i32 %y) {
278
+ %cmp1 = icmp ne i32 %x, 0
279
+ %cmp2 = icmp ugt i32 %x, %y
280
+ %and = select i1 %cmp2, i1 %cmp1, i1 false
281
+ ; ok to replace with:
282
+ %and = and i1 %cmp1, %cmp2
283
+ ret i1 %and
284
+ }
285
+
286
+
240
287
The Freeze Instruction
241
288
======================
242
289
Both undef and poison values sometimes propagate too much down an expression
0 commit comments