Skip to content

Commit 0f7d148

Browse files
committed
[InstCombine] Add shared helper for logical and bitwise and/or (NFC)
Add a helper for shared folds between logical and bitwise and/or and move the and/or of icmp and fcmp folds in there. This makes it easier to extend to more folds. A possible extension would be to base the current and/or of icmp reassociation logic on this helper, so that it for example also applies to fcmp.
1 parent 4a2bd78 commit 0f7d148

File tree

3 files changed

+37
-33
lines changed

3 files changed

+37
-33
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

+31-16
Original file line numberDiff line numberDiff line change
@@ -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+
35263544
static 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

llvm/lib/Transforms/InstCombine/InstCombineInternal.h

+3
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,9 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
425425
Instruction *foldLogicOfIsFPClass(BinaryOperator &Operator, Value *LHS,
426426
Value *RHS);
427427

428+
Value *foldBooleanAndOr(Value *LHS, Value *RHS, Instruction &I, bool IsAnd,
429+
bool IsLogical);
430+
428431
Instruction *
429432
canonicalizeConditionalNegationViaMathToSelect(BinaryOperator &i);
430433

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

+3-17
Original file line numberDiff line numberDiff line change
@@ -3143,12 +3143,6 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {
31433143
SI, Builder.CreateLogicalOr(A, Builder.CreateOr(B, FalseVal)));
31443144
}
31453145

3146-
if (auto *LHS = dyn_cast<FCmpInst>(CondVal))
3147-
if (auto *RHS = dyn_cast<FCmpInst>(FalseVal))
3148-
if (Value *V = foldLogicOfFCmps(LHS, RHS, /*IsAnd*/ false,
3149-
/*IsSelectLogical*/ true))
3150-
return replaceInstUsesWith(SI, V);
3151-
31523146
// (A && B) || (C && B) --> (A || C) && B
31533147
if (match(CondVal, m_LogicalAnd(m_Value(A), m_Value(B))) &&
31543148
match(FalseVal, m_LogicalAnd(m_Value(C), m_Value(D))) &&
@@ -3191,12 +3185,6 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {
31913185
SI, Builder.CreateLogicalAnd(A, Builder.CreateAnd(B, TrueVal)));
31923186
}
31933187

3194-
if (auto *LHS = dyn_cast<FCmpInst>(CondVal))
3195-
if (auto *RHS = dyn_cast<FCmpInst>(TrueVal))
3196-
if (Value *V = foldLogicOfFCmps(LHS, RHS, /*IsAnd*/ true,
3197-
/*IsSelectLogical*/ true))
3198-
return replaceInstUsesWith(SI, V);
3199-
32003188
// (A || B) && (C || B) --> (A && C) || B
32013189
if (match(CondVal, m_LogicalOr(m_Value(A), m_Value(B))) &&
32023190
match(TrueVal, m_LogicalOr(m_Value(C), m_Value(D))) &&
@@ -3305,11 +3293,9 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {
33053293
return replaceInstUsesWith(SI, Op1);
33063294
}
33073295

3308-
if (auto *ICmp0 = dyn_cast<ICmpInst>(CondVal))
3309-
if (auto *ICmp1 = dyn_cast<ICmpInst>(Op1))
3310-
if (auto *V = foldAndOrOfICmps(ICmp0, ICmp1, SI, IsAnd,
3311-
/* IsLogical */ true))
3312-
return replaceInstUsesWith(SI, V);
3296+
if (auto *V = foldBooleanAndOr(CondVal, Op1, SI, IsAnd,
3297+
/*IsLogical=*/true))
3298+
return replaceInstUsesWith(SI, V);
33133299
}
33143300

33153301
// select (a || b), c, false -> select a, c, false

0 commit comments

Comments
 (0)