[llvm-commits] [llvm] r82815 - in /llvm/trunk: lib/CodeGen/MachineSink.cpp test/CodeGen/X86/sink.ll

Dan Gohman gohman at apple.com
Fri Sep 25 15:53:30 PDT 2009


Author: djg
Date: Fri Sep 25 17:53:29 2009
New Revision: 82815

URL: http://llvm.org/viewvc/llvm-project?rev=82815&view=rev
Log:
Fix MachineSink to be able to sink instructions that use physical registers
which have no defs anywhere in the function. In particular, this fixes sinking
of instructions that reference RIP on x86-64, which is currently being modeled
as a register.

Added:
    llvm/trunk/test/CodeGen/X86/sink.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=82815&r1=82814&r2=82815&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/MachineSink.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineSink.cpp Fri Sep 25 17:53:29 2009
@@ -35,6 +35,7 @@
   class VISIBILITY_HIDDEN MachineSinking : public MachineFunctionPass {
     const TargetMachine   *TM;
     const TargetInstrInfo *TII;
+    const TargetRegisterInfo *TRI;
     MachineFunction       *CurMF; // Current MachineFunction
     MachineRegisterInfo  *RegInfo; // Machine register information
     MachineDominatorTree *DT;   // Machine dominator tree
@@ -95,6 +96,7 @@
   CurMF = &MF;
   TM = &CurMF->getTarget();
   TII = TM->getInstrInfo();
+  TRI = TM->getRegisterInfo();
   RegInfo = &CurMF->getRegInfo();
   DT = &getAnalysis<MachineDominatorTree>();
 
@@ -176,8 +178,19 @@
     if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
       // If this is a physical register use, we can't move it.  If it is a def,
       // we can move it, but only if the def is dead.
-      if (MO.isUse() || !MO.isDead())
+      if (MO.isUse()) {
+        // If the physreg has no defs anywhere, it's just an ambient register
+        // and we can freely move its uses.
+        if (!RegInfo->def_empty(Reg))
+          return false;
+        // Check for a def among the register's aliases too.
+        for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias)
+          if (!RegInfo->def_empty(*Alias))
+            return false;
+      } else if (!MO.isDead()) {
+        // A def that isn't dead. We can't move it.
         return false;
+      }
     } else {
       // Virtual register uses are always safe to sink.
       if (MO.isUse()) continue;

Added: llvm/trunk/test/CodeGen/X86/sink.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sink.ll?rev=82815&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/X86/sink.ll (added)
+++ llvm/trunk/test/CodeGen/X86/sink.ll Fri Sep 25 17:53:29 2009
@@ -0,0 +1,18 @@
+; RUN: llc < %s -march=x86-64 -asm-verbose=false | FileCheck %s
+
+; Currently, floating-point selects are lowered to CFG triangles.
+; This means that one side of the select is always unconditionally
+; evaluated, however with MachineSink we can sink the other side so
+; that it's conditionally evaluated.
+
+; CHECK: foo:
+; CHECK-NEXT: divsd
+; CHECK-NEXT: testb $1, %dil
+; CHECK-NEXT: jne
+
+define double @foo(double %x, double %y, i1 %c) nounwind {
+  %a = fdiv double %x, 3.2
+  %b = fdiv double %y, 3.3
+  %z = select i1 %c, double %a, double %b
+  ret double %z
+}





More information about the llvm-commits mailing list