@@ -2584,8 +2584,9 @@ Value *InstCombinerImpl::matchSelectFromAndOr(Value *A, Value *C, Value *B,
2584
2584
2585
2585
// (icmp eq X, 0) | (icmp ult Other, X) -> (icmp ule Other, X-1)
2586
2586
// (icmp ne X, 0) & (icmp uge Other, X) -> (icmp ugt Other, X-1)
2587
- Value *foldAndOrOfICmpEqZeroAndICmp (ICmpInst *LHS, ICmpInst *RHS, bool IsAnd,
2588
- IRBuilderBase &Builder) {
2587
+ static Value *foldAndOrOfICmpEqZeroAndICmp (ICmpInst *LHS, ICmpInst *RHS,
2588
+ bool IsAnd, bool IsLogical,
2589
+ IRBuilderBase &Builder) {
2589
2590
ICmpInst::Predicate LPred =
2590
2591
IsAnd ? LHS->getInversePredicate () : LHS->getPredicate ();
2591
2592
ICmpInst::Predicate RPred =
@@ -2604,6 +2605,8 @@ Value *foldAndOrOfICmpEqZeroAndICmp(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd,
2604
2605
else
2605
2606
return nullptr ;
2606
2607
2608
+ if (IsLogical)
2609
+ Other = Builder.CreateFreeze (Other);
2607
2610
return Builder.CreateICmp (
2608
2611
IsAnd ? ICmpInst::ICMP_ULT : ICmpInst::ICMP_UGE,
2609
2612
Builder.CreateAdd (LHS0, Constant::getAllOnesValue (LHS0->getType ())),
@@ -2652,14 +2655,14 @@ Value *InstCombinerImpl::foldAndOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
2652
2655
if (Value *V = foldLogOpOfMaskedICmps (LHS, RHS, IsAnd, IsLogical, Builder))
2653
2656
return V;
2654
2657
2655
- // TODO: One of these directions is fine with logical and/or, the other could
2656
- // be supported by inserting freeze.
2657
- if (!IsLogical) {
2658
- if (Value *V = foldAndOrOfICmpEqZeroAndICmp (LHS, RHS, IsAnd, Builder))
2659
- return V;
2660
- if (Value *V = foldAndOrOfICmpEqZeroAndICmp (RHS, LHS, IsAnd, Builder))
2661
- return V;
2662
- }
2658
+ if (Value *V =
2659
+ foldAndOrOfICmpEqZeroAndICmp (LHS, RHS, IsAnd, IsLogical, Builder))
2660
+ return V;
2661
+ // We can treat logical like bitwise here, because both operands are used on
2662
+ // the LHS, and as such poison from both will propagate.
2663
+ if (Value *V = foldAndOrOfICmpEqZeroAndICmp (RHS, LHS, IsAnd,
2664
+ /* IsLogical */ false , Builder))
2665
+ return V;
2663
2666
2664
2667
// TODO: Verify whether this is safe for logical and/or.
2665
2668
if (!IsLogical) {
0 commit comments