Commit 99e91aae authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Fold "boolean not"-like Selects into branches.

Fold a Select that negates a boolean value, i.e. returning true in the
false case and vice versa, into Branch users, similar to what we already
do for Branch nodes with BooleanNot inputs.

BUG=v8:5267

Review-Url: https://codereview.chromium.org/2308303003
Cr-Commit-Position: refs/heads/master@{#39149}
parent cf3a4a70
...@@ -77,8 +77,12 @@ Reduction CommonOperatorReducer::ReduceBranch(Node* node) { ...@@ -77,8 +77,12 @@ Reduction CommonOperatorReducer::ReduceBranch(Node* node) {
// Swap IfTrue/IfFalse on {branch} if {cond} is a BooleanNot and use the input // Swap IfTrue/IfFalse on {branch} if {cond} is a BooleanNot and use the input
// to BooleanNot as new condition for {branch}. Note we assume that {cond} was // to BooleanNot as new condition for {branch}. Note we assume that {cond} was
// already properly optimized before we get here (as guaranteed by the graph // already properly optimized before we get here (as guaranteed by the graph
// reduction logic). // reduction logic). The same applies if {cond} is a Select acting as boolean
if (cond->opcode() == IrOpcode::kBooleanNot) { // not (i.e. true being returned in the false case and vice versa).
if (cond->opcode() == IrOpcode::kBooleanNot ||
(cond->opcode() == IrOpcode::kSelect &&
DecideCondition(cond->InputAt(1)) == Decision::kFalse &&
DecideCondition(cond->InputAt(2)) == Decision::kTrue)) {
for (Node* const use : node->uses()) { for (Node* const use : node->uses()) {
switch (use->opcode()) { switch (use->opcode()) {
case IrOpcode::kIfTrue: case IrOpcode::kIfTrue:
......
...@@ -158,6 +158,26 @@ TEST_F(CommonOperatorReducerTest, BranchWithBooleanNot) { ...@@ -158,6 +158,26 @@ TEST_F(CommonOperatorReducerTest, BranchWithBooleanNot) {
} }
} }
TEST_F(CommonOperatorReducerTest, BranchWithSelect) {
Node* const value = Parameter(0);
TRACED_FOREACH(BranchHint, hint, kBranchHints) {
Node* const control = graph()->start();
Node* const branch = graph()->NewNode(
common()->Branch(hint),
graph()->NewNode(common()->Select(MachineRepresentation::kTagged),
value, FalseConstant(), TrueConstant()),
control);
Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
Reduction const r = Reduce(branch);
ASSERT_TRUE(r.Changed());
EXPECT_EQ(branch, r.replacement());
EXPECT_THAT(branch, IsBranch(value, control));
EXPECT_THAT(if_false, IsIfTrue(branch));
EXPECT_THAT(if_true, IsIfFalse(branch));
EXPECT_EQ(NegateBranchHint(hint), BranchHintOf(branch->op()));
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Merge // Merge
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment