@@ -237,6 +237,53 @@ Poison values can be replaced with any value of type (undef, concrete values,
237237or a ``freeze `` instruction).
238238
239239
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+
240287 The Freeze Instruction
241288======================
242289Both undef and poison values sometimes propagate too much down an expression
0 commit comments