[llvm] 7f4c940 - [CodeGen] Postprocess PHI nodes for callbr

Bill Wendling via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 24 14:34:36 PDT 2020


Author: Bill Wendling
Date: 2020-09-24T14:34:28-07:00
New Revision: 7f4c940bd0b526f25e11c51bb4d58a85024330ae

URL: https://github.com/llvm/llvm-project/commit/7f4c940bd0b526f25e11c51bb4d58a85024330ae
DIFF: https://github.com/llvm/llvm-project/commit/7f4c940bd0b526f25e11c51bb4d58a85024330ae.diff

LOG: [CodeGen] Postprocess PHI nodes for callbr

When processing PHI nodes after a callbr, we need to make sure that the
PHI nodes on the default branch are resolved after the callbr
(inserted after INLINEASM_BR). The PHI node values on the indirect
branches are processed before the INLINEASM_BR.

Differential Revision: https://reviews.llvm.org/D86260

Added: 
    llvm/test/CodeGen/X86/callbr-asm-phi-nodes.ll

Modified: 
    llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
    llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index dcfa6e405c74..8ef8ed9cae1c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1084,9 +1084,8 @@ SDValue SelectionDAGBuilder::getControlRoot() {
 
 void SelectionDAGBuilder::visit(const Instruction &I) {
   // Set up outgoing PHI node register values before emitting the terminator.
-  if (I.isTerminator()) {
-    HandlePHINodesInSuccessorBlocks(I.getParent());
-  }
+  if (I.isTerminator())
+    HandlePHINodesInSuccessorBlocks(I.getParent(), true);
 
   // Increase the SDNodeOrder if dealing with a non-debug instruction.
   if (!isa<DbgInfoIntrinsic>(I))
@@ -2839,6 +2838,9 @@ void SelectionDAGBuilder::visitCallBr(const CallBrInst &I) {
   visitInlineAsm(I);
   CopyToExportRegsIfNeeded(&I);
 
+  // Set up outgoing PHI node register values before emitting the branch.
+  HandlePHINodesInSuccessorBlocks(I.getParent(), false);
+
   // Retrieve successors.
   MachineBasicBlock *Return = FuncInfo.MBBMap[I.getDefaultDest()];
 
@@ -9990,10 +9992,10 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
 /// directly add them, because expansion might result in multiple MBB's for one
 /// BB.  As such, the start of the BB might correspond to a 
diff erent MBB than
 /// the end.
-void
-SelectionDAGBuilder::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {
+void SelectionDAGBuilder::HandlePHINodesInSuccessorBlocks(
+    const BasicBlock *LLVMBB, bool Preprocess) {
   const Instruction *TI = LLVMBB->getTerminator();
-
+  const CallBrInst *CI = dyn_cast<CallBrInst>(TI);
   SmallPtrSet<MachineBasicBlock *, 4> SuccsHandled;
 
   // Check PHI nodes in successors that expect a value to be available from this
@@ -10001,6 +10003,21 @@ SelectionDAGBuilder::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {
   for (unsigned succ = 0, e = TI->getNumSuccessors(); succ != e; ++succ) {
     const BasicBlock *SuccBB = TI->getSuccessor(succ);
     if (!isa<PHINode>(SuccBB->begin())) continue;
+
+    if (CI) {
+      if (Preprocess) {
+        // Don't push PHI node values back before an INLINEASM_BR instruction on
+        // the default branch.
+        if (SuccBB == CI->getDefaultDest())
+          continue;
+      } else {
+        // Don't push PHI node values back after an INLINEASM_BR instruction on
+        // the indirect branch.
+        if (SuccBB != CI->getDefaultDest())
+          continue;
+      }
+    }
+
     MachineBasicBlock *SuccMBB = FuncInfo.MBBMap[SuccBB];
 
     // If this terminator has multiple identical successors (common for

diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
index 4904134a7d40..6e8ff1b7f161 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -783,7 +783,8 @@ class SelectionDAGBuilder {
   void processIntegerCallValue(const Instruction &I,
                                SDValue Value, bool IsSigned);
 
-  void HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB);
+  void HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB,
+                                       bool Preprocess);
 
   void emitInlineAsmError(const CallBase &Call, const Twine &Message);
 

diff  --git a/llvm/test/CodeGen/X86/callbr-asm-phi-nodes.ll b/llvm/test/CodeGen/X86/callbr-asm-phi-nodes.ll
new file mode 100644
index 000000000000..3e5e5767afdd
--- /dev/null
+++ b/llvm/test/CodeGen/X86/callbr-asm-phi-nodes.ll
@@ -0,0 +1,28 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=i686-- -verify-machineinstrs < %s | FileCheck %s
+
+ at var = global i32 0, align 4
+
+define i32 @test1() {
+; CHECK-LABEL: test1:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    jmp .Ltmp0
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:  # %bb.2:
+; CHECK-NEXT:    retl
+; CHECK-NEXT:  .Ltmp0: # Block address taken
+; CHECK-NEXT:  .LBB0_1:
+; CHECK-NEXT:    movl $1, %eax
+; CHECK-NEXT:    retl
+  callbr void asm sideeffect "jmp ${1:l}", "*m,X,~{dirflag},~{fpsr},~{flags}"(i32* nonnull @var, i8* blockaddress(@test1, %1))
+          to label %2 [label %1]
+
+1:                                                ; preds = %0
+  br label %2
+
+2:                                                ; preds = %0, %1
+  %3 = phi i32 [ 1, %1 ], [ 0, %0 ]
+  ret i32 %3
+}


        


More information about the llvm-commits mailing list