[PATCH] D39011: [SimplifyCFG] try harder to forward switch condition to phi (PR34471)

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 22 09:52:33 PDT 2017


This revision was automatically updated to reflect the committed changes.
Closed by commit rL316293: [SimplifyCFG] try harder to forward switch condition to phi (PR34471) (authored by spatel).

Changed prior to commit:
  https://reviews.llvm.org/D39011?vs=119348&id=119788#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D39011

Files:
  llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
  llvm/trunk/test/Transforms/SimplifyCFG/ForwardSwitchConditionToPHI.ll


Index: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
===================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
+++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -4450,16 +4450,46 @@
 static bool ForwardSwitchConditionToPHI(SwitchInst *SI) {
   typedef DenseMap<PHINode *, SmallVector<int, 4>> ForwardingNodesMap;
   ForwardingNodesMap ForwardingNodes;
-
+  BasicBlock *SwitchBlock = SI->getParent();
+  bool Changed = false;
   for (auto &Case : SI->cases()) {
     ConstantInt *CaseValue = Case.getCaseValue();
     BasicBlock *CaseDest = Case.getCaseSuccessor();
+
+    // Replace phi operands in successor blocks that are using the constant case
+    // value rather than the switch condition variable:
+    //   switchbb:
+    //   switch i32 %x, label %default [
+    //     i32 17, label %succ
+    //   ...
+    //   succ:
+    //     %r = phi i32 ... [ 17, %switchbb ] ...
+    // -->
+    //     %r = phi i32 ... [ %x, %switchbb ] ...
+
+    for (Instruction &InstInCaseDest : *CaseDest) {
+      auto *Phi = dyn_cast<PHINode>(&InstInCaseDest);
+      if (!Phi) break;
+
+      // This only works if there is exactly 1 incoming edge from the switch to
+      // a phi. If there is >1, that means multiple cases of the switch map to 1
+      // value in the phi, and that phi value is not the switch condition. Thus,
+      // this transform would not make sense (the phi would be invalid because
+      // a phi can't have different incoming values from the same block).
+      int SwitchBBIdx = Phi->getBasicBlockIndex(SwitchBlock);
+      if (Phi->getIncomingValue(SwitchBBIdx) == CaseValue &&
+          count(Phi->blocks(), SwitchBlock) == 1) {
+        Phi->setIncomingValue(SwitchBBIdx, SI->getCondition());
+        Changed = true;
+      }
+    }
+
+    // Collect phi nodes that are indirectly using this switch's case constants.
     int PhiIdx;
     if (auto *Phi = FindPHIForConditionForwarding(CaseValue, CaseDest, &PhiIdx))
       ForwardingNodes[Phi].push_back(PhiIdx);
   }
 
-  bool Changed = false;
   for (auto &ForwardingNode : ForwardingNodes) {
     PHINode *Phi = ForwardingNode.first;
     SmallVectorImpl<int> &Indexes = ForwardingNode.second;
Index: llvm/trunk/test/Transforms/SimplifyCFG/ForwardSwitchConditionToPHI.ll
===================================================================
--- llvm/trunk/test/Transforms/SimplifyCFG/ForwardSwitchConditionToPHI.ll
+++ llvm/trunk/test/Transforms/SimplifyCFG/ForwardSwitchConditionToPHI.ll
@@ -50,17 +50,13 @@
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    switch i32 [[X:%.*]], label [[ELSE3:%.*]] [
 ; CHECK-NEXT:    i32 17, label [[RETURN:%.*]]
-; CHECK-NEXT:    i32 19, label [[IF19:%.*]]
-; CHECK-NEXT:    i32 42, label [[IF42:%.*]]
+; CHECK-NEXT:    i32 19, label [[RETURN]]
+; CHECK-NEXT:    i32 42, label [[RETURN]]
 ; CHECK-NEXT:    ]
-; CHECK:       if19:
-; CHECK-NEXT:    br label [[RETURN]]
-; CHECK:       if42:
-; CHECK-NEXT:    br label [[RETURN]]
 ; CHECK:       else3:
 ; CHECK-NEXT:    br label [[RETURN]]
 ; CHECK:       return:
-; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[X]], [[IF19]] ], [ [[X]], [[IF42]] ], [ 0, [[ELSE3]] ], [ 17, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[R:%.*]] = phi i32 [ 0, [[ELSE3]] ], [ [[X]], [[ENTRY:%.*]] ], [ [[X]], [[ENTRY]] ], [ [[X]], [[ENTRY]] ]
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
 entry:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D39011.119788.patch
Type: text/x-patch
Size: 3381 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171022/289eb9ee/attachment.bin>


More information about the llvm-commits mailing list