[PATCH] D36175: [InstSimplify] Accept more loop-invariant cases in ThreadBinOpOverPHI

Ulrich Weigand via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 1 13:40:16 PDT 2017


uweigand created this revision.

The ThreadBinOpOverPHI routine attempts to detect loop-invariant values
by ignoring a PHI node input that equals the PHI node itself.

However, we can accept a slightly more general case: if we perform
some operation on the PHI node, and the result of that operation on
the PHI input equals the operation performed on the PHI node itself,
the result of the operation is loop invariant (even if the PHI node
itself is not), and we can still do the simplifcation.

See the attached test case for an example, where "phi & -256" is
loop invariant and can be simplified even though phi itself is not.


https://reviews.llvm.org/D36175

Files:
  lib/Analysis/InstructionSimplify.cpp
  test/Transforms/InstSimplify/phi.ll


Index: test/Transforms/InstSimplify/phi.ll
===================================================================
--- test/Transforms/InstSimplify/phi.ll
+++ test/Transforms/InstSimplify/phi.ll
@@ -22,3 +22,25 @@
   %e = icmp eq i32 %d, 0
   ret i1 %e
 }
+
+define i32 @test2(i1 %c1, i1 %c2, i32 %x) {
+; CHECK-LABEL: @test2
+; CHECK-NEXT:    [[Y:%.*]] = and i32 %x, -256
+; CHECK:    ret i32 [[Y]]
+;
+  %y = and i32 %x, -256
+  br i1 %c1, label %true, label %false
+true:
+  %a = or i32 %y, 1
+  br label %loop
+false:
+  %b = or i32 %y, 2
+  br label %loop
+loop:
+  %p = phi i32 [ %a, %true ], [ %b, %false ], [ %r, %loop ]
+  %r = and i32 %p, -256
+  br i1 %c2, label %ret, label %loop
+ret:
+  ret i32 %r
+}
+
Index: lib/Analysis/InstructionSimplify.cpp
===================================================================
--- lib/Analysis/InstructionSimplify.cpp
+++ lib/Analysis/InstructionSimplify.cpp
@@ -461,6 +461,12 @@
     Value *V = PI == LHS ?
       SimplifyBinOp(Opcode, Incoming, RHS, Q, MaxRecurse) :
       SimplifyBinOp(Opcode, LHS, Incoming, Q, MaxRecurse);
+    // If the simplified operation is equal to the original operation on the
+    // PHI node, it can likewise be safely skipped.
+    if (BinaryOperator *Op = dyn_cast_or_null<BinaryOperator>(V))
+      if (Op->getOpcode() == Opcode &&
+          Op->getOperand(0) == LHS && Op->getOperand(1) == RHS)
+      continue;
     // If the operation failed to simplify, or simplified to a different value
     // to previously, then give up.
     if (!V || (CommonValue && V != CommonValue))


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D36175.109196.patch
Type: text/x-patch
Size: 1564 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170801/7f86f26c/attachment.bin>


More information about the llvm-commits mailing list