[llvm] [Reg2Mem] Handle CallBr instructions (PR #90953)

via llvm-commits llvm-commits at lists.llvm.org
Sat May 4 03:00:34 PDT 2024


https://github.com/XChy updated https://github.com/llvm/llvm-project/pull/90953

>From 9bc4d0564426ebcd5e1af69c34fd570f75f016ae Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Fri, 3 May 2024 16:37:48 +0800
Subject: [PATCH] [Reg2Mem] Handle CallBr instructions

---
 .../lib/Transforms/Utils/DemoteRegToStack.cpp | 18 +++++++++--
 llvm/test/Transforms/Reg2Mem/callbr-crash.ll  | 32 +++++++++++++++++++
 2 files changed, 48 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/Transforms/Reg2Mem/callbr-crash.ll

diff --git a/llvm/lib/Transforms/Utils/DemoteRegToStack.cpp b/llvm/lib/Transforms/Utils/DemoteRegToStack.cpp
index b2a88eadd3dee8..f03de2f25a4163 100644
--- a/llvm/lib/Transforms/Utils/DemoteRegToStack.cpp
+++ b/llvm/lib/Transforms/Utils/DemoteRegToStack.cpp
@@ -50,6 +50,15 @@ AllocaInst *llvm::DemoteRegToStack(Instruction &I, bool VolatileLoads,
       assert(BB && "Unable to split critical edge.");
       (void)BB;
     }
+  } else if (CallBrInst *CBI = dyn_cast<CallBrInst>(&I)) {
+    for (int i = 0; i < CBI->getNumSuccessors(); i++) {
+      auto *Succ = CBI->getSuccessor(i);
+      if (!Succ->getSinglePredecessor()) {
+        assert(isCriticalEdge(II, i) && "Expected a critical edge!");
+        BasicBlock *BB = SplitCriticalEdge(II, i);
+        assert(BB && "Unable to split critical edge.");
+      }
+    }
   }
 
   // Change all of the users of the instruction to read from the stack slot.
@@ -102,9 +111,14 @@ AllocaInst *llvm::DemoteRegToStack(Instruction &I, bool VolatileLoads,
         new StoreInst(&I, Slot, Handler->getFirstInsertionPt());
       return Slot;
     }
+  } else if (InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
+    InsertPt = II->getNormalDest()->getFirstInsertionPt();
+  } else if (CallBrInst *CBI = dyn_cast<CallBrInst>(&I)) {
+    for (BasicBlock *Succ : successors(CBI))
+      new StoreInst(CBI, Slot, Succ->getFirstInsertionPt());
+    return Slot;
   } else {
-    InvokeInst &II = cast<InvokeInst>(I);
-    InsertPt = II.getNormalDest()->getFirstInsertionPt();
+    llvm_unreachable("Unsupported terminator for Reg2Mem");
   }
 
   new StoreInst(&I, Slot, InsertPt);
diff --git a/llvm/test/Transforms/Reg2Mem/callbr-crash.ll b/llvm/test/Transforms/Reg2Mem/callbr-crash.ll
new file mode 100644
index 00000000000000..2abb01b14b0e19
--- /dev/null
+++ b/llvm/test/Transforms/Reg2Mem/callbr-crash.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes=reg2mem -S < %s | FileCheck %s
+
+define void @crash() {
+; CHECK-LABEL: @crash(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[A_REG2MEM:%.*]] = alloca i64, align 8
+; CHECK-NEXT:    %"reg2mem alloca point" = bitcast i32 0 to i32
+; CHECK-NEXT:    [[A:%.*]] = callbr i64 asm "", "=r,r,!i"(i64 0)
+; CHECK-NEXT:            to label [[THEN:%.*]] [label %entry.else_crit_edge]
+; CHECK:       entry.else_crit_edge:
+; CHECK-NEXT:    store i64 [[A]], ptr [[A_REG2MEM]], align 4
+; CHECK-NEXT:    br label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    store i64 [[A]], ptr [[A_REG2MEM]], align 4
+; CHECK-NEXT:    [[A_RELOAD:%.*]] = load i64, ptr [[A_REG2MEM]], align 4
+; CHECK-NEXT:    [[B:%.*]] = inttoptr i64 [[A_RELOAD]] to ptr
+; CHECK-NEXT:    br label [[ELSE]]
+; CHECK:       else:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %a = callbr i64 asm "", "=r,r,!i"(i64 0)
+  to label %then [label %else]
+
+then:
+  %b = inttoptr i64 %a to ptr
+  br label %else
+
+else:
+  ret void
+}



More information about the llvm-commits mailing list