diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -189,12 +189,15 @@ // If the false value simplified to false, then the result of the compare // is equal to "Cond && TCmp". This also catches the case when the false // value simplified to false and the true value to true, returning "Cond". - if (match(FCmp, m_Zero())) + // Folding select to and/or isn't poison-safe in general; impliesPoison + // checks whether folding it does not convert a well-defined value into + // poison. + if (match(FCmp, m_Zero()) && impliesPoison(TCmp, Cond)) if (Value *V = SimplifyAndInst(Cond, TCmp, Q, MaxRecurse)) return V; // If the true value simplified to true, then the result of the compare // is equal to "Cond || FCmp". - if (match(TCmp, m_One())) + if (match(TCmp, m_One()) && impliesPoison(FCmp, Cond)) if (Value *V = SimplifyOrInst(Cond, FCmp, Q, MaxRecurse)) return V; // Finally, if the false value simplified to true and the true value to diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/test/Transforms/InstCombine/icmp.ll @@ -3935,7 +3935,7 @@ define i1 @thread_cmp_over_select_with_poison_trueval(i1 %b) { ; CHECK-LABEL: @thread_cmp_over_select_with_poison_trueval( -; CHECK-NEXT: ret i1 poison +; CHECK-NEXT: ret i1 false ; %s = select i1 %b, i32 poison, i32 0 %tobool = icmp ne i32 %s, 0 @@ -3944,7 +3944,7 @@ define i1 @thread_cmp_over_select_with_poison_falseval(i1 %b) { ; CHECK-LABEL: @thread_cmp_over_select_with_poison_falseval( -; CHECK-NEXT: ret i1 poison +; CHECK-NEXT: ret i1 true ; %s = select i1 %b, i32 1, i32 poison %tobool = icmp ne i32 %s, 0