[PATCH] D47203: [LowerSwitch] Fixed faulty PHI node in switch default block

Karl-Johan Karlsson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri May 25 16:11:17 PDT 2018


Ka-Ka updated this revision to Diff 148685.
Ka-Ka added a comment.

Reduced the size of the testcase.


Repository:
  rL LLVM

https://reviews.llvm.org/D47203

Files:
  lib/Transforms/Utils/LowerSwitch.cpp
  test/Transforms/Util/lowerswitch.ll


Index: test/Transforms/Util/lowerswitch.ll
===================================================================
--- test/Transforms/Util/lowerswitch.ll
+++ test/Transforms/Util/lowerswitch.ll
@@ -242,3 +242,25 @@
 unreachable:                                      ; preds = %cleanup
   unreachable
 }
+
+; Test that the PHI node in cleanup17 is removed as the switch default block is
+; not reachable.
+define void @test4() {
+; CHECK-LABEL: @test4
+entry:
+  switch i32 undef, label %cleanup17 [
+    i32 0, label %return
+    i32 9, label %return
+  ]
+
+cleanup17:
+; CHECK: cleanup17:
+; CHECK-NOT: phi i16 [ undef, %entry ]
+; CHECK: return:
+
+  %retval.4 = phi i16 [ undef, %entry ]
+  unreachable
+
+return:
+  ret void
+}
Index: lib/Transforms/Utils/LowerSwitch.cpp
===================================================================
--- lib/Transforms/Utils/LowerSwitch.cpp
+++ lib/Transforms/Utils/LowerSwitch.cpp
@@ -74,7 +74,7 @@
 
     LowerSwitch() : FunctionPass(ID) {
       initializeLowerSwitchPass(*PassRegistry::getPassRegistry());
-    } 
+    }
 
     bool runOnFunction(Function &F) override;
 
@@ -211,6 +211,20 @@
   }
 }
 
+/// Remove the first occurrence of the "switch statement" BB in the PHI
+/// nodes
+static void removeEntryFromPhis(BasicBlock *SuccBB, BasicBlock *OrigBB) {
+  for (BasicBlock::iterator I = SuccBB->begin(),
+                            IE = SuccBB->getFirstNonPHI()->getIterator();
+       I != IE;) {
+    PHINode *PN = cast<PHINode>(I);
+    ++I; // To avoid invalid iterator if PHI node are removed below
+    int BlockIdx = PN->getBasicBlockIndex(OrigBB);
+    assert(BlockIdx != -1 && "Switch didn't go to this successor??");
+    PN->removeIncomingValue((unsigned)BlockIdx, true);
+  }
+}
+
 /// Convert the switch statement into a binary lookup of the case values.
 /// The function recursively builds this tree. LowerBound and UpperBound are
 /// used to keep track of the bounds for Val that have already been checked by
@@ -327,7 +341,7 @@
     } else if (Leaf.Low->isZero()) {
       // Val >= 0 && Val <= Hi --> Val <=u Hi
       Comp = new ICmpInst(*NewLeaf, ICmpInst::ICMP_ULE, Val, Leaf.High,
-                          "SwitchLeaf");      
+                          "SwitchLeaf");
     } else {
       // Emit V-Lo <=u Hi-Lo
       Constant* NegLo = ConstantExpr::getNeg(Leaf.Low);
@@ -354,7 +368,7 @@
     for (uint64_t j = 0; j < Range; ++j) {
       PN->removeIncomingValue(OrigBlock);
     }
-    
+
     int BlockIdx = PN->getBasicBlockIndex(OrigBlock);
     assert(BlockIdx != -1 && "Switch didn't go to this successor??");
     PN->setIncomingBlock((unsigned)BlockIdx, NewLeaf);
@@ -495,6 +509,10 @@
     }
 #endif
 
+    // As the default block in the switch is unreachable, update the PHI nodes
+    // (remove the entry to the default block) to reflect this.
+    removeEntryFromPhis(Default, OrigBlock);
+
     // Use the most popular block as the new default, reducing the number of
     // cases.
     assert(MaxPop > 0 && PopSucc);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D47203.148685.patch
Type: text/x-patch
Size: 3014 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180525/f5655d87/attachment.bin>


More information about the llvm-commits mailing list