Skip to content

Commit 080fc1d

Browse files
committed
refactor into foldIntrinsicUsingDistributiveLaws
1 parent fe32b6f commit 080fc1d

File tree

1 file changed

+25
-39
lines changed

1 file changed

+25
-39
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 25 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,7 +1554,11 @@ static bool leftDistributesOverRight(Instruction::BinaryOps LOp, bool HasNUW,
15541554
switch (ROp) {
15551555
case Intrinsic::umax:
15561556
case Intrinsic::umin:
1557-
return HasNUW && LOp == Instruction::Add;
1557+
if (HasNUW && LOp == Instruction::Add)
1558+
return true;
1559+
if (HasNUW && LOp == Instruction::Shl)
1560+
return true;
1561+
return false;
15581562
case Intrinsic::smax:
15591563
case Intrinsic::smin:
15601564
return HasNSW && LOp == Instruction::Add;
@@ -1592,29 +1596,34 @@ foldIntrinsicUsingDistributiveLaws(IntrinsicInst *II,
15921596
if (!leftDistributesOverRight(InnerOpcode, HasNUW, HasNSW, TopLevelOpcode))
15931597
return nullptr;
15941598

1595-
assert(II->isCommutative() && Op0->isCommutative() &&
1596-
"Only inner and outer commutative op codes are supported.");
1597-
15981599
Value *A = Op0->getOperand(0);
15991600
Value *B = Op0->getOperand(1);
16001601
Value *C = Op1->getOperand(0);
16011602
Value *D = Op1->getOperand(1);
16021603

1603-
// Attempts to swap variables such that A always equals C
1604-
if (A != C && A != D)
1605-
std::swap(A, B);
1606-
if (A == C || A == D) {
1607-
if (A != C)
1608-
std::swap(C, D);
1604+
// Attempts to swap variables such that A equals C or B equals D,
1605+
// if the inner operation is commutative.
1606+
if (Op0->isCommutative() && A != C && B != D && A == D)
1607+
std::swap(C, D);
1608+
1609+
if (A != C && B != D)
1610+
return nullptr;
1611+
1612+
BinaryOperator *NewBinop;
1613+
if (A == C) {
16091614
Value *NewIntrinsic = Builder.CreateBinaryIntrinsic(TopLevelOpcode, B, D);
1610-
BinaryOperator *NewBinop =
1611-
cast<BinaryOperator>(Builder.CreateBinOp(InnerOpcode, NewIntrinsic, A));
1612-
NewBinop->setHasNoSignedWrap(HasNSW);
1613-
NewBinop->setHasNoUnsignedWrap(HasNUW);
1614-
return NewBinop;
1615+
NewBinop =
1616+
cast<BinaryOperator>(Builder.CreateBinOp(InnerOpcode, A, NewIntrinsic));
1617+
} else { // B == D
1618+
Value *NewIntrinsic = Builder.CreateBinaryIntrinsic(TopLevelOpcode, A, C);
1619+
NewBinop =
1620+
cast<BinaryOperator>(Builder.CreateBinOp(InnerOpcode, NewIntrinsic, B));
16151621
}
16161622

1617-
return nullptr;
1623+
NewBinop->setHasNoUnsignedWrap(HasNUW);
1624+
NewBinop->setHasNoSignedWrap(HasNSW);
1625+
1626+
return NewBinop;
16181627
}
16191628

16201629
/// CallInst simplification. This mostly only handles folding of intrinsic
@@ -1888,29 +1897,6 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
18881897
return I;
18891898
}
18901899

1891-
Value *CommonShlOperand;
1892-
BinaryOperator *NewShl = nullptr;
1893-
// umax(nuw_shl(z, x), nuw_shl(z, y)) -> nuw_shl(z, umax(x, y))
1894-
// umin(nuw_shl(z, x), nuw_shl(z, y)) -> nuw_shl(z, umin(x, y))
1895-
if (match(I0, m_OneUse(m_NUWShl(m_Value(CommonShlOperand), m_Value(X)))) &&
1896-
match(I1,
1897-
m_OneUse(m_NUWShl(m_Deferred(CommonShlOperand), m_Value(Y))))) {
1898-
Value *MaxMin = Builder.CreateBinaryIntrinsic(IID, X, Y);
1899-
NewShl = BinaryOperator::CreateNUWShl(CommonShlOperand, MaxMin);
1900-
} else if (match(I0, m_OneUse(m_NUWShl(m_Value(X),
1901-
m_Value(CommonShlOperand)))) &&
1902-
match(I1, m_OneUse(m_NUWShl(m_Value(Y),
1903-
m_Deferred(CommonShlOperand))))) {
1904-
Value *MaxMin = Builder.CreateBinaryIntrinsic(IID, X, Y);
1905-
NewShl = BinaryOperator::CreateNUWShl(MaxMin, CommonShlOperand);
1906-
}
1907-
if (NewShl) {
1908-
if (cast<BinaryOperator>(I0)->hasNoSignedWrap() &&
1909-
cast<BinaryOperator>(I1)->hasNoSignedWrap())
1910-
NewShl->setHasNoSignedWrap();
1911-
return NewShl;
1912-
}
1913-
19141900
// If both operands of unsigned min/max are sign-extended, it is still ok
19151901
// to narrow the operation.
19161902
[[fallthrough]];

0 commit comments

Comments
 (0)