summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
diff options
context:
space:
mode:
authorRoman Lebedev <lebedev.ri@gmail.com>2020-01-04 17:24:20 +0300
committerRoman Lebedev <lebedev.ri@gmail.com>2020-01-04 17:30:51 +0300
commit6d05bc2e3a9b54fde53aa5cbd83cc7c1d432cac1 (patch)
tree5cd5fd1aa6a32e0ca9bbd48d535b74ca434918b9 /llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
parent772ede3d5d552e0214473f247f7f98f15e596fe5 (diff)
downloadbcm5719-llvm-6d05bc2e3a9b54fde53aa5cbd83cc7c1d432cac1.tar.gz
bcm5719-llvm-6d05bc2e3a9b54fde53aa5cbd83cc7c1d432cac1.zip
[NFCI][InstCombine] Refactor 'sink negation into select if that folds one hand of select to 0' fold
I would think it's better than having two practically identical folds next to eachother, but then generalization isn't all that pretty due to the fact that we need to produce different `sub` each time.. This change is no-functional-changes-intended refactoring.
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp75
1 files changed, 35 insertions, 40 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index c723ba0a683..36d9b80eea2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1899,57 +1899,52 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
}
{
- // If we are subtracting the select with one hand matching the value
- // we are subtracting from, sink subtraction into hands of select:
+ // If we have a subtraction between some value and a select between
+ // said value and something else, sink subtraction into select hands, i.e.:
+ // sub (select %Cond, %TrueVal, %FalseVal), %Op1
+ // ->
+ // select %Cond, (sub %TrueVal, %Op1), (sub %FalseVal, %Op1)
+ // or
// sub %Op0, (select %Cond, %TrueVal, %FalseVal)
// ->
// select %Cond, (sub %Op0, %TrueVal), (sub %Op0, %FalseVal)
// This will result in select between new subtraction and 0.
- Value *Cond, *TrueVal, *FalseVal;
- if (match(Op1, m_OneUse(m_Select(m_Value(Cond), m_Value(TrueVal),
- m_Value(FalseVal)))) &&
- (Op0 == TrueVal || Op0 == FalseVal)) {
+ auto SinkSubIntoSelect =
+ [Ty = I.getType()](Value *Select, Value *OtherHandOfSub,
+ auto SubBuilder) -> Instruction * {
+ Value *Cond, *TrueVal, *FalseVal;
+ if (!match(Select, m_OneUse(m_Select(m_Value(Cond), m_Value(TrueVal),
+ m_Value(FalseVal)))))
+ return nullptr;
+ if (OtherHandOfSub != TrueVal && OtherHandOfSub != FalseVal)
+ return nullptr;
// While it is really tempting to just create two subtractions and let
// InstCombine fold one of those to 0, it isn't possible to do so
// because of worklist visitation order. So ugly it is.
- bool SubtractingFromTrueVal = Op0 == TrueVal;
- Value *NewSub =
- Builder.CreateSub(Op0, SubtractingFromTrueVal ? FalseVal : TrueVal);
- Constant *Zero = Constant::getNullValue(I.getType());
+ bool OtherHandOfSubIsTrueVal = OtherHandOfSub == TrueVal;
+ Value *NewSub = SubBuilder(OtherHandOfSubIsTrueVal ? FalseVal : TrueVal);
+ Constant *Zero = Constant::getNullValue(Ty);
SelectInst *NewSel =
- SelectInst::Create(Cond, SubtractingFromTrueVal ? Zero : NewSub,
- SubtractingFromTrueVal ? NewSub : Zero);
+ SelectInst::Create(Cond, OtherHandOfSubIsTrueVal ? Zero : NewSub,
+ OtherHandOfSubIsTrueVal ? NewSub : Zero);
// Preserve prof metadata if any.
- NewSel->copyMetadata(cast<Instruction>(*Op1));
+ NewSel->copyMetadata(cast<Instruction>(*Select));
return NewSel;
- }
- }
-
- {
- // If we are subtracting from select with one hand matching the value
- // we are subtracting, sink subtraction into hands of select:
- // sub (select %Cond, %TrueVal, %FalseVal), %Op1
- // ->
- // select %Cond, (sub %TrueVal, %Op1), (sub %FalseVal, %Op1)
- // This will result in select between new subtraction and 0.
- Value *Cond, *TrueVal, *FalseVal;
- if (match(Op0, m_OneUse(m_Select(m_Value(Cond), m_Value(TrueVal),
- m_Value(FalseVal)))) &&
- (Op1 == TrueVal || Op1 == FalseVal)) {
- // While it is really tempting to just create two subtractions and let
- // InstCombine fold one of those to 0, it isn't possible to do so
- // because of worklist visitation order. So ugly it is.
- bool SubtractingTrueVal = Op1 == TrueVal;
- Value *NewSub =
- Builder.CreateSub(SubtractingTrueVal ? FalseVal : TrueVal, Op1);
- Constant *Zero = Constant::getNullValue(I.getType());
- SelectInst *NewSel =
- SelectInst::Create(Cond, SubtractingTrueVal ? Zero : NewSub,
- SubtractingTrueVal ? NewSub : Zero);
- // Preserve prof metadata if any.
- NewSel->copyMetadata(cast<Instruction>(*Op0));
+ };
+ if (Instruction *NewSel = SinkSubIntoSelect(
+ /*Select=*/Op0, /*OtherHandOfSub=*/Op1,
+ [Builder = &Builder, Op1](Value *OtherHandOfSelect) {
+ return Builder->CreateSub(OtherHandOfSelect,
+ /*OtherHandOfSub=*/Op1);
+ }))
+ return NewSel;
+ if (Instruction *NewSel = SinkSubIntoSelect(
+ /*Select=*/Op1, /*OtherHandOfSub=*/Op0,
+ [Builder = &Builder, Op0](Value *OtherHandOfSelect) {
+ return Builder->CreateSub(/*OtherHandOfSub=*/Op0,
+ OtherHandOfSelect);
+ }))
return NewSel;
- }
}
if (Op1->hasOneUse()) {
OpenPOWER on IntegriCloud