[XRay] Fix assertion failure on empty machine basic blocks (PR 31424)
authorDean Michael Berris <dberris@google.com>
Mon, 19 Dec 2016 09:20:38 +0000 (09:20 +0000)
committerDean Michael Berris <dberris@google.com>
Mon, 19 Dec 2016 09:20:38 +0000 (09:20 +0000)
The original version of the code in XRayInstrumentation.cpp assumed that
functions may not have empty machine basic blocks (or that the first one
couldn't be). This change addresses that by special-casing that specific
situation.

We provide two .mir test-cases to make sure we're handling this
appropriately.

Fixes llvm.org/PR31424.

Reviewers: chandlerc

Subscribers: varno, llvm-commits

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

llvm-svn: 290091

llvm/lib/CodeGen/XRayInstrumentation.cpp
llvm/test/CodeGen/X86/xray-empty-firstmbb.mir [new file with mode: 0644]
llvm/test/CodeGen/X86/xray-empty-function.mir [new file with mode: 0644]

index 570b2ed..63bd762 100644 (file)
@@ -129,7 +129,15 @@ bool XRayInstrumentation::runOnMachineFunction(MachineFunction &MF) {
       return false; // Function is too small.
   }
 
-  auto &FirstMBB = *MF.begin();
+  // We look for the first non-empty MachineBasicBlock, so that we can insert
+  // the function instrumentation in the appropriate place.
+  auto MBI =
+      find_if(MF, [&](const MachineBasicBlock &MBB) { return !MBB.empty(); });
+  if (MBI == MF.end())
+    return false; // The function is empty.
+
+  auto *TII = MF.getSubtarget().getInstrInfo();
+  auto &FirstMBB = *MBI;
   auto &FirstMI = *FirstMBB.begin();
 
   if (!MF.getSubtarget().isXRaySupported()) {
@@ -142,7 +150,6 @@ bool XRayInstrumentation::runOnMachineFunction(MachineFunction &MF) {
 
   // First, insert an PATCHABLE_FUNCTION_ENTER as the first instruction of the
   // MachineFunction.
-  auto *TII = MF.getSubtarget().getInstrInfo();
   BuildMI(FirstMBB, FirstMI, FirstMI.getDebugLoc(),
           TII->get(TargetOpcode::PATCHABLE_FUNCTION_ENTER));
 
diff --git a/llvm/test/CodeGen/X86/xray-empty-firstmbb.mir b/llvm/test/CodeGen/X86/xray-empty-firstmbb.mir
new file mode 100644 (file)
index 0000000..746ee15
--- /dev/null
@@ -0,0 +1,23 @@
+# RUN: llc -run-pass xray-instrumentation -mtriple=x86_64-unknown-linux-gnu -o - %s | FileCheck %s
+#
+# Make sure we can handle empty first basic blocks.
+
+--- |
+
+  define i32 @foo() noinline uwtable "xray-instruction-threshold"="1" {
+  entry:
+    unreachable
+  }
+
+...
+
+---
+name: foo
+tracksRegLiveness: true
+liveins:
+  - { reg: '%edi'}
+body:            |
+  bb.0.entry:
+    liveins: %edi
+    ; CHECK-NOT: PATCHABLE_FUNCTION_ENTER
+...
diff --git a/llvm/test/CodeGen/X86/xray-empty-function.mir b/llvm/test/CodeGen/X86/xray-empty-function.mir
new file mode 100644 (file)
index 0000000..3229c93
--- /dev/null
@@ -0,0 +1,13 @@
+# RUN: llc -run-pass xray-instrumentation -mtriple=x86_64-unknown-linux-gnu -o - %s | FileCheck %s
+#
+# Make sure we can handle empty functions.
+---
+name: empty
+tracksRegLiveness: true
+liveins:
+  - { reg: '%edi'}
+body:            |
+  bb.0:
+    ; CHECK-NOT: PATCHABLE_FUNCTION_ENTER
+...
+