[PATCH] Fixup PHI nodes in LowerSwitch

Marcello Maggioni hayarms at gmail.com
Wed Jul 9 03:46:56 PDT 2014


Thank you very much Philip for your very useful comments as always :)

Answers inline.

================
Comment at: lib/Transforms/Utils/LowerSwitch.cpp:138
@@ +137,3 @@
+ for (BasicBlock::iterator I = Succ->begin(),
+                           E = Succ->getFirstNonPHIOrDbgOrLifetime();
+      I != E; ++I) {
----------------
Philip Reames wrote:
> I know this was discussed in another review, but I'm pretty sure this is not necessary.  I have no objection to you using this construct - i.e. go ahead and submit - but it would be good to clarify on llvm-dev and revisit if need be.  If this construct is actually required, I have quite a bit of out of tree code to fix.  :)
Does anybody have a reference to this, so that we can be sure that getFirstNonPhi() can be used 100% safe? I also like more that solution (of course) if it is correct :)

================
Comment at: lib/Transforms/Utils/LowerSwitch.cpp:145
@@ +144,3 @@
+
+   int BlockIdx = PN->getBasicBlockIndex(OrigBlock);
+   assert(BlockIdx != -1 && "Switch didn't go to this successor??");
----------------
Philip Reames wrote:
> Oh, I just noticed this.  A single basic block can reach a successor with different values.  (e.g. consider a switch which simply forwards the case value, before that's optimized away) 
> 
> The getBasicBlockIndex will return the first such edge, not all edges.  You probably want to write:
> for each incoming edge: update if bb == predecessor
> 
> It would be good to add a test case for this if possible.  If you believe this is not possible, add a comment and assert that checks that.  (i.e. after the update, no remaining incoming edge from OrigBlock.)
> 
> 
What do you mean exactly with this? You mean something like this? 

define i32 @foo(i32 %a) nounwind uwtable readnone ssp {
  switch i32 %a, label %2 [
    i32 1, label %3
    i32 2, label %1
    i32 3, label %3
  ]

; <label>:1                                       ; preds = %0
  br label %3

; <label>:2                                       ; preds = %0
  br label %3

; <label>:3                                       ; preds = %0, %3, %2, %1
  %.0 = phi i32 [ 2, %2 ], [ 9, %0 ], [ 15, %1 ], [ 10, %0 ]
  ret i32 %.0
}

If this is the case the verifier on code like this gives this error:

PHI node has multiple entries for the same basic block with different incoming values!
  %.0 = phi i32 [ 2, %2 ], [ 9, %0 ], [ 15, %1 ], [ 10, %0 ]
label %0
i32 10
i32 9

You specified for different values in your comment, this seems to not be possible. With THE SAME value though I think it is (the verifier doesn't complain if i change the PHI to "%.0 = phi i32 [ 2, %2 ], [ 9, %0 ], [ 15, %1 ], [ 10, %0 ]").
 I don't know if it can actually happen at the LowerSwitch phase, which is very low in the stack and after basically all IR optimizations, but considering that it is a possibility might be worth implementing it the way you specified (with the loop over all the incoming edges).

================
Comment at: test/Transforms/LowerSwitch/2014-06-23-PHIlowering.ll:2
@@ +1,3 @@
+; RUN: opt < %s -lowerswitch -S | FileCheck %s
+; CHECK: phi i32 [ 1, %NodeBlock ], [ 2, %1 ]
+; CHECK: phi i32 [ 0, %NewDefault ]
----------------
Philip Reames wrote:
> Please add a check-label or otherwise give context here.  Where are these phis expected? What should be around them?
> 
> Also, could you place them in the body of the test function?  That way, we can add more tests to this file.  You'll need to add a CHECK: test
Will do in the next revision!

http://reviews.llvm.org/D4298






More information about the llvm-commits mailing list