[llvm] r258254 - [MachineSink] Don't break ImplicitNulls

Sanjoy Das via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 19 16:06:14 PST 2016


Author: sanjoy
Date: Tue Jan 19 18:06:14 2016
New Revision: 258254

URL: http://llvm.org/viewvc/llvm-project?rev=258254&view=rev
Log:
[MachineSink] Don't break ImplicitNulls

Summary:
This teaches MachineSink to not sink instructions that might break the
implicit null check optimization that runs later.  This should not
affect frontends that do not use implicit null checks.

Reviewers: aadg, reames, hfinkel, atrick

Subscribers: majnemer, llvm-commits

Differential Revision: http://reviews.llvm.org/D14632

Added:
    llvm/trunk/test/CodeGen/X86/machine-sink-and-implicit-null-checks.ll
Modified:
    llvm/trunk/lib/CodeGen/MachineSink.cpp

Modified: llvm/trunk/lib/CodeGen/MachineSink.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineSink.cpp?rev=258254&r1=258253&r2=258254&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineSink.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineSink.cpp Tue Jan 19 18:06:14 2016
@@ -27,6 +27,7 @@
 #include "llvm/CodeGen/MachineLoopInfo.h"
 #include "llvm/CodeGen/MachinePostDominators.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/IR/LLVMContext.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
@@ -673,6 +674,49 @@ MachineBasicBlock *MachineSinking::FindS
   return SuccToSinkTo;
 }
 
+/// \brief Return true if MI is likely to be usable as a memory operation by the
+/// implicit null check optimization.
+///
+/// This is a "best effort" heuristic, and should not be relied upon for
+/// correctness.  This returning true does not guarantee that the implicit null
+/// check optimization is legal over MI, and this returning false does not
+/// guarantee MI cannot possibly be used to do a null check.
+static bool SinkingPreventsImplicitNullCheck(MachineInstr *MI,
+                                             const TargetInstrInfo *TII,
+                                             const TargetRegisterInfo *TRI) {
+  typedef TargetInstrInfo::MachineBranchPredicate MachineBranchPredicate;
+
+  auto *MBB = MI->getParent();
+  if (MBB->pred_size() != 1)
+    return false;
+
+  auto *PredMBB = *MBB->pred_begin();
+  auto *PredBB = PredMBB->getBasicBlock();
+
+  // Frontends that don't use implicit null checks have no reason to emit
+  // branches with make.implicit metadata, and this function should always
+  // return false for them.
+  if (!PredBB ||
+      !PredBB->getTerminator()->getMetadata(LLVMContext::MD_make_implicit))
+    return false;
+
+  unsigned BaseReg, Offset;
+  if (!TII->getMemOpBaseRegImmOfs(MI, BaseReg, Offset, TRI))
+    return false;
+
+  if (!(MI->mayLoad() && !MI->isPredicable()))
+    return false;
+
+  MachineBranchPredicate MBP;
+  if (TII->AnalyzeBranchPredicate(*PredMBB, MBP, false))
+    return false;
+
+  return MBP.LHS.isReg() && MBP.RHS.isImm() && MBP.RHS.getImm() == 0 &&
+         (MBP.Predicate == MachineBranchPredicate::PRED_NE ||
+          MBP.Predicate == MachineBranchPredicate::PRED_EQ) &&
+         MBP.LHS.getReg() == BaseReg;
+}
+
 /// SinkInstruction - Determine whether it is safe to sink the specified machine
 /// instruction out of its current block into a successor.
 bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore,
@@ -691,6 +735,11 @@ bool MachineSinking::SinkInstruction(Mac
   if (MI->isConvergent())
     return false;
 
+  // Don't break implicit null checks.  This is a performance heuristic, and not
+  // required for correctness.
+  if (SinkingPreventsImplicitNullCheck(MI, TII, TRI))
+    return false;
+
   // FIXME: This should include support for sinking instructions within the
   // block they are currently in to shorten the live ranges.  We often get
   // instructions sunk into the top of a large block, but it would be better to

Added: llvm/trunk/test/CodeGen/X86/machine-sink-and-implicit-null-checks.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/machine-sink-and-implicit-null-checks.ll?rev=258254&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/machine-sink-and-implicit-null-checks.ll (added)
+++ llvm/trunk/test/CodeGen/X86/machine-sink-and-implicit-null-checks.ll Tue Jan 19 18:06:14 2016
@@ -0,0 +1,49 @@
+; RUN: llc -mtriple=x86_64-apple-macosx -O3 -enable-implicit-null-checks -o - < %s 2>&1 | FileCheck %s
+
+declare void @throw0()
+declare void @throw1()
+
+define i1 @f(i8* %p0, i8* %p1) {
+ entry:
+  %c0 = icmp eq i8* %p0, null
+  br i1 %c0, label %throw0, label %continue0, !make.implicit !0
+
+ continue0:
+  %v0 = load i8, i8* %p0
+  %c1 = icmp eq i8* %p1, null
+  br i1 %c1, label %throw1, label %continue1, !make.implicit !0
+
+ continue1:
+  %v1 = load i8, i8* %p1
+  %v = icmp eq i8 %v0, %v1
+  ret i1 %v
+
+ throw0:
+  call void @throw0()
+  unreachable
+
+ throw1:
+  call void @throw1()
+  unreachable
+}
+
+; Check that we have two implicit null checks in @f
+
+; CHECK: __LLVM_FaultMaps:
+; CHECK-NEXT:        .byte   1
+; CHECK-NEXT:        .byte   0
+; CHECK-NEXT:        .short  0
+; CHECK-NEXT:        .long   1
+
+; FunctionInfo[0] =
+
+; FunctionAddress =
+; CHECK-NEXT:        .quad   _f
+
+; NumFaultingPCs =
+; CHECK-NEXT:        .long   2
+
+; Reserved =
+; CHECK-NEXT:        .long   0
+
+!0 = !{}




More information about the llvm-commits mailing list