[PATCH] D11648: InstCombinePHI: Partial simplification of identity operations

James Molloy james.molloy at arm.com
Mon Aug 3 02:51:29 PDT 2015


jmolloy added a subscriber: jmolloy.
jmolloy requested changes to this revision.
jmolloy added a reviewer: jmolloy.
jmolloy added a comment.
This revision now requires changes to proceed.

Hi Jakub,

Thanks for working on this! I've got a bunch of comments from this first round of review.

Cheers,

James


================
Comment at: lib/Transforms/InstCombine/InstCombinePHI.cpp:784
@@ -783,1 +783,3 @@
 
+// If PHI node has two edges and the PHI node is used in instructions like
+// add, sub, mul, div, shifts; if one of incoming values is a constant
----------------
"if *a* PHI node"

================
Comment at: lib/Transforms/InstCombine/InstCombinePHI.cpp:787
@@ +786,3 @@
+// that makes the instruction and identity operation, we can move this
+// instruction into one of the basic blocks.
+// Because of such a transformation, the identity operation won't be
----------------
"we can hoist this instruction into only one of the incoming blocks"

The use of "hoist" is important, I think.

================
Comment at: lib/Transforms/InstCombine/InstCombinePHI.cpp:795
@@ +794,3 @@
+                                                 InstCombiner &IC) {
+  if (!PNUser.isBinaryOp())
+    return nullptr;
----------------
There are a lot of ternary operators (x ? y : z) going on in this function, and it's a bit difficult to assert that they're all correct.

What I'd like to see is some ascii-art of the situation, with each of the nodes having a name. Then variables refer to those names later, which means I don't get confused which node OpOperandIdx refers to!

    C        V
      \      /
       Phi
    X  |
     \  |
       Op

Something like that? ^

================
Comment at: lib/Transforms/InstCombine/InstCombinePHI.cpp:809
@@ +808,3 @@
+    return nullptr;
+  case Instruction::Add: {
+    if (!C.isZeroValue())
----------------
Remove braces and put break on its own line.

================
Comment at: lib/Transforms/InstCombine/InstCombinePHI.cpp:817
@@ +816,3 @@
+  case Instruction::LShr:
+  case Instruction::AShr: {
+    if (!C.isZeroValue() || (OpOperandIdx == 1))
----------------
Same as line 809, and for the rest.

================
Comment at: lib/Transforms/InstCombine/InstCombinePHI.cpp:818
@@ +817,3 @@
+  case Instruction::AShr: {
+    if (!C.isZeroValue() || (OpOperandIdx == 1))
+      return nullptr;
----------------
No parens () around the second expression.

================
Comment at: lib/Transforms/InstCombine/InstCombinePHI.cpp:838
@@ +837,3 @@
+  if (const auto *Incoming = dyn_cast<Instruction>(&IncomingVal))
+    if (!IC.getDominatorTree()->dominates(Incoming, Terminator))
+      return nullptr;
----------------
You need to handle the case where dyn_cast returns nullptr here.

================
Comment at: lib/Transforms/InstCombine/InstCombinePHI.cpp:843
@@ +842,3 @@
+  // as an incoming value of the PHI node.
+  if (const auto *Operand =
+          dyn_cast<Instruction>(PNUser.getOperand(OpOperandIdx)))
----------------
Same as line 838.

================
Comment at: lib/Transforms/InstCombine/InstCombinePHI.cpp:846
@@ +845,3 @@
+    if (!IC.getDominatorTree()->dominates(Operand, Terminator) ||
+        !IC.getDominatorTree()->dominates(Operand, &PN))
+      return nullptr;
----------------
I think this second check is unnecessary. As the terminator leads to the block with the PHI in, any instruction that dominates the terminator must also dominate PN.

================
Comment at: lib/Transforms/InstCombine/InstCombinePHI.cpp:856
@@ +855,3 @@
+  for (const auto &U : PNUser.uses())
+    if (IC.getDominatorTree()->dominates(Terminator, U))
+      return nullptr;
----------------
What is this doing? What situation can cause whatever this is checking against?

================
Comment at: lib/Transforms/InstCombine/InstCombinePHI.cpp:865
@@ +864,3 @@
+  IRBuilder<> Builder(Terminator);
+  auto *NewInst = cast<BinaryOperator>(Builder.CreateBinOp(
+      (Instruction::BinaryOps)PNUser.getOpcode(), LHS, RHS));
----------------
Better to use a cast<> rather than a C-style cast for PNUser.getOpcode(); that's safer:

    auto *NewInst = Builder.CreateBinOp(cast<BinaryOperator>(PNUser).getOpcode(), LHS, RHS);
    cast<BinaryOperator>(NewInst)->copyIRFlags(&PNUser);


Repository:
  rL LLVM

http://reviews.llvm.org/D11648







More information about the llvm-commits mailing list