@@ -2722,13 +2722,15 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
27222722 return BinaryOperator::CreateAnd (Builder.CreateNot (A), B);
27232723 }
27242724
2725+ if (Value *Res =
2726+ foldBooleanAndOr (Op0, Op1, I, /* IsAnd=*/ true , /* IsLogical=*/ false ))
2727+ return replaceInstUsesWith (I, Res);
2728+
27252729 {
27262730 ICmpInst *LHS = dyn_cast<ICmpInst>(Op0);
27272731 ICmpInst *RHS = dyn_cast<ICmpInst>(Op1);
2728- if (LHS && RHS)
2729- if (Value *Res = foldAndOrOfICmps (LHS, RHS, I, /* IsAnd */ true ))
2730- return replaceInstUsesWith (I, Res);
27312732
2733+ // TODO: Base this on foldBooleanAndOr instead?
27322734 // TODO: Make this recursive; it's a little tricky because an arbitrary
27332735 // number of 'and' instructions might have to be created.
27342736 if (LHS && match (Op1, m_OneUse (m_LogicalAnd (m_Value (X), m_Value (Y))))) {
@@ -2767,11 +2769,6 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
27672769 }
27682770 }
27692771
2770- if (FCmpInst *LHS = dyn_cast<FCmpInst>(I.getOperand (0 )))
2771- if (FCmpInst *RHS = dyn_cast<FCmpInst>(I.getOperand (1 )))
2772- if (Value *Res = foldLogicOfFCmps (LHS, RHS, /* IsAnd*/ true ))
2773- return replaceInstUsesWith (I, Res);
2774-
27752772 if (Instruction *FoldedFCmps = reassociateFCmps (I, Builder))
27762773 return FoldedFCmps;
27772774
@@ -3523,6 +3520,27 @@ Value *InstCombinerImpl::foldAndOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
35233520 return foldAndOrOfICmpsUsingRanges (LHS, RHS, IsAnd);
35243521}
35253522
3523+ // / If IsLogical is true, then the and/or is in select form and the transform
3524+ // / must be poison-safe.
3525+ Value *InstCombinerImpl::foldBooleanAndOr (Value *LHS, Value *RHS,
3526+ Instruction &I, bool IsAnd,
3527+ bool IsLogical) {
3528+ if (!LHS->getType ()->isIntOrIntVectorTy (1 ))
3529+ return nullptr ;
3530+
3531+ if (auto *LHSCmp = dyn_cast<ICmpInst>(LHS))
3532+ if (auto *RHSCmp = dyn_cast<ICmpInst>(RHS))
3533+ if (Value *Res = foldAndOrOfICmps (LHSCmp, RHSCmp, I, IsAnd, IsLogical))
3534+ return Res;
3535+
3536+ if (auto *LHSCmp = dyn_cast<FCmpInst>(LHS))
3537+ if (auto *RHSCmp = dyn_cast<FCmpInst>(RHS))
3538+ if (Value *Res = foldLogicOfFCmps (LHSCmp, RHSCmp, IsAnd, IsLogical))
3539+ return Res;
3540+
3541+ return nullptr ;
3542+ }
3543+
35263544static Value *foldOrOfInversions (BinaryOperator &I,
35273545 InstCombiner::BuilderTy &Builder) {
35283546 assert (I.getOpcode () == Instruction::Or &&
@@ -3804,13 +3822,15 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
38043822 if (SwappedForXor)
38053823 std::swap (Op0, Op1);
38063824
3825+ if (Value *Res =
3826+ foldBooleanAndOr (Op0, Op1, I, /* IsAnd=*/ false , /* IsLogical=*/ false ))
3827+ return replaceInstUsesWith (I, Res);
3828+
38073829 {
38083830 ICmpInst *LHS = dyn_cast<ICmpInst>(Op0);
38093831 ICmpInst *RHS = dyn_cast<ICmpInst>(Op1);
3810- if (LHS && RHS)
3811- if (Value *Res = foldAndOrOfICmps (LHS, RHS, I, /* IsAnd */ false ))
3812- return replaceInstUsesWith (I, Res);
38133832
3833+ // TODO: Base this on foldBooleanAndOr instead?
38143834 // TODO: Make this recursive; it's a little tricky because an arbitrary
38153835 // number of 'or' instructions might have to be created.
38163836 Value *X, *Y;
@@ -3850,11 +3870,6 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
38503870 }
38513871 }
38523872
3853- if (FCmpInst *LHS = dyn_cast<FCmpInst>(I.getOperand (0 )))
3854- if (FCmpInst *RHS = dyn_cast<FCmpInst>(I.getOperand (1 )))
3855- if (Value *Res = foldLogicOfFCmps (LHS, RHS, /* IsAnd*/ false ))
3856- return replaceInstUsesWith (I, Res);
3857-
38583873 if (Instruction *FoldedFCmps = reassociateFCmps (I, Builder))
38593874 return FoldedFCmps;
38603875
0 commit comments