[llvm-commits] [llvm] r66808 - in /llvm/branches/Apple/Dib: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/i64-mem-copy.ll test/CodeGen/X86/mmx-copy-gprs.ll

Bill Wendling isanbard at gmail.com
Thu Mar 12 11:24:26 PDT 2009


Author: void
Date: Thu Mar 12 13:24:26 2009
New Revision: 66808

URL: http://llvm.org/viewvc/llvm-project?rev=66808&view=rev
Log:
--- Merging (from foreign repository) r66776 into '.':
A    test/CodeGen/X86/i64-mem-copy.ll
U    test/CodeGen/X86/mmx-copy-gprs.ll
Conflict discovered in 'lib/Target/X86/X86ISelLowering.cpp'.
Select: (p) postpone, (df) diff-full, (e) edit,
        (h) help for more options: e
Select: (p) postpone, (df) diff-full, (e) edit, (r) resolved,
        (h) help for more options: r
U    lib/Target/X86/X86ISelLowering.cpp

On x86, if the only use of a i64 load is a i64 store, generate a pair of double
load and store instead.

Added:
    llvm/branches/Apple/Dib/test/CodeGen/X86/i64-mem-copy.ll
Modified:
    llvm/branches/Apple/Dib/lib/Target/X86/X86ISelLowering.cpp
    llvm/branches/Apple/Dib/test/CodeGen/X86/mmx-copy-gprs.ll

Modified: llvm/branches/Apple/Dib/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Target/X86/X86ISelLowering.cpp?rev=66808&r1=66807&r2=66808&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Target/X86/X86ISelLowering.cpp Thu Mar 12 13:24:26 2009
@@ -8271,14 +8271,21 @@
 
 /// PerformSTORECombine - Do target-specific dag combines on STORE nodes.
 static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG,
-                                     const X86Subtarget *Subtarget) {
+                                   const X86Subtarget *Subtarget) {
   // Turn load->store of MMX types into GPR load/stores.  This avoids clobbering
   // the FP state in cases where an emms may be missing.
   // A preferable solution to the general problem is to figure out the right
   // places to insert EMMS.  This qualifies as a quick hack.
+
+  // Similarly, turn load->store of i64 into double load/stores in 32-bit mode.
   StoreSDNode *St = cast<StoreSDNode>(N);
-  if (St->getValue().getValueType().isVector() &&
-      St->getValue().getValueType().getSizeInBits() == 64 &&
+  MVT VT = St->getValue().getValueType();
+  if (VT.getSizeInBits() != 64)
+    return SDValue();
+
+  bool F64IsLegal = !UseSoftFloat && !NoImplicitFloat && Subtarget->hasSSE2();
+  if ((VT.isVector() ||
+       (VT == MVT::i64 && F64IsLegal && !Subtarget->is64Bit())) &&
       isa<LoadSDNode>(St->getValue()) &&
       !cast<LoadSDNode>(St->getValue())->isVolatile() &&
       St->getChain().hasOneUse() && !St->isVolatile()) {
@@ -8302,60 +8309,72 @@
           Ops.push_back(ChainVal->getOperand(i));
       }
     }
-    if (Ld) {
-      DebugLoc dl = N->getDebugLoc();
-      // If we are a 64-bit capable x86, lower to a single movq load/store pair.
-      if (Subtarget->is64Bit()) {
-        SDValue NewLd = DAG.getLoad(MVT::i64, dl, Ld->getChain(), 
-                                      Ld->getBasePtr(), Ld->getSrcValue(), 
-                                      Ld->getSrcValueOffset(), Ld->isVolatile(),
-                                      Ld->getAlignment());
-        SDValue NewChain = NewLd.getValue(1);
-        if (TokenFactorIndex != -1) {
-          Ops.push_back(NewChain);
-          NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Ops[0], 
-                                 Ops.size());
-        }
-        return DAG.getStore(NewChain, dl, NewLd, St->getBasePtr(),
-                            St->getSrcValue(), St->getSrcValueOffset(),
-                            St->isVolatile(), St->getAlignment());
-      }
-
-      // Otherwise, lower to two 32-bit copies.
-      SDValue LoAddr = Ld->getBasePtr();
-      SDValue HiAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, LoAddr,
-                                     DAG.getConstant(4, MVT::i32));
-
-      SDValue LoLd = DAG.getLoad(MVT::i32, dl, Ld->getChain(), LoAddr,
-                                   Ld->getSrcValue(), Ld->getSrcValueOffset(),
-                                   Ld->isVolatile(), Ld->getAlignment());
-      SDValue HiLd = DAG.getLoad(MVT::i32, dl, Ld->getChain(), HiAddr,
-                                   Ld->getSrcValue(), Ld->getSrcValueOffset()+4,
-                                   Ld->isVolatile(), 
-                                   MinAlign(Ld->getAlignment(), 4));
 
-      SDValue NewChain = LoLd.getValue(1);
+    if (!Ld || !ISD::isNormalLoad(Ld))
+      return SDValue();
+
+    // If this is not the MMX case, i.e. we are just turning i64 load/store
+    // into f64 load/store, avoid the transformation if there are multiple
+    // uses of the loaded value.
+    if (!VT.isVector() && !Ld->hasNUsesOfValue(1, 0))
+      return SDValue();
+
+    DebugLoc LdDL = Ld->getDebugLoc();
+    DebugLoc StDL = N->getDebugLoc();
+    // If we are a 64-bit capable x86, lower to a single movq load/store pair.
+    // Otherwise, if it's legal to use f64 SSE instructions, use f64 load/store
+    // pair instead.
+    if (Subtarget->is64Bit() || F64IsLegal) {
+      MVT LdVT = Subtarget->is64Bit() ? MVT::i64 : MVT::f64;
+      SDValue NewLd = DAG.getLoad(LdVT, LdDL, Ld->getChain(),
+                                  Ld->getBasePtr(), Ld->getSrcValue(),
+                                  Ld->getSrcValueOffset(), Ld->isVolatile(),
+                                  Ld->getAlignment());
+      SDValue NewChain = NewLd.getValue(1);
       if (TokenFactorIndex != -1) {
-        Ops.push_back(LoLd);
-        Ops.push_back(HiLd);
-        NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Ops[0], 
+        Ops.push_back(NewChain);
+        NewChain = DAG.getNode(ISD::TokenFactor, LdDL, MVT::Other, &Ops[0],
                                Ops.size());
       }
-
-      LoAddr = St->getBasePtr();
-      HiAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, LoAddr,
-                           DAG.getConstant(4, MVT::i32));
-
-      SDValue LoSt = DAG.getStore(NewChain, dl, LoLd, LoAddr,
+      return DAG.getStore(NewChain, StDL, NewLd, St->getBasePtr(),
                           St->getSrcValue(), St->getSrcValueOffset(),
                           St->isVolatile(), St->getAlignment());
-      SDValue HiSt = DAG.getStore(NewChain, dl, HiLd, HiAddr,
-                                    St->getSrcValue(),
-                                    St->getSrcValueOffset() + 4,
-                                    St->isVolatile(), 
-                                    MinAlign(St->getAlignment(), 4));
-      return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, LoSt, HiSt);
     }
+
+    // Otherwise, lower to two pairs of 32-bit loads / stores.
+    SDValue LoAddr = Ld->getBasePtr();
+    SDValue HiAddr = DAG.getNode(ISD::ADD, LdDL, MVT::i32, LoAddr,
+                                 DAG.getConstant(4, MVT::i32));
+
+    SDValue LoLd = DAG.getLoad(MVT::i32, LdDL, Ld->getChain(), LoAddr,
+                               Ld->getSrcValue(), Ld->getSrcValueOffset(),
+                               Ld->isVolatile(), Ld->getAlignment());
+    SDValue HiLd = DAG.getLoad(MVT::i32, LdDL, Ld->getChain(), HiAddr,
+                               Ld->getSrcValue(), Ld->getSrcValueOffset()+4,
+                               Ld->isVolatile(),
+                               MinAlign(Ld->getAlignment(), 4));
+
+    SDValue NewChain = LoLd.getValue(1);
+    if (TokenFactorIndex != -1) {
+      Ops.push_back(LoLd);
+      Ops.push_back(HiLd);
+      NewChain = DAG.getNode(ISD::TokenFactor, LdDL, MVT::Other, &Ops[0],
+                             Ops.size());
+    }
+
+    LoAddr = St->getBasePtr();
+    HiAddr = DAG.getNode(ISD::ADD, StDL, MVT::i32, LoAddr,
+                         DAG.getConstant(4, MVT::i32));
+
+    SDValue LoSt = DAG.getStore(NewChain, StDL, LoLd, LoAddr,
+                                St->getSrcValue(), St->getSrcValueOffset(),
+                                St->isVolatile(), St->getAlignment());
+    SDValue HiSt = DAG.getStore(NewChain, StDL, HiLd, HiAddr,
+                                St->getSrcValue(),
+                                St->getSrcValueOffset() + 4,
+                                St->isVolatile(),
+                                MinAlign(St->getAlignment(), 4));
+    return DAG.getNode(ISD::TokenFactor, StDL, MVT::Other, LoSt, HiSt);
   }
   return SDValue();
 }

Added: llvm/branches/Apple/Dib/test/CodeGen/X86/i64-mem-copy.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/test/CodeGen/X86/i64-mem-copy.ll?rev=66808&view=auto

==============================================================================
--- llvm/branches/Apple/Dib/test/CodeGen/X86/i64-mem-copy.ll (added)
+++ llvm/branches/Apple/Dib/test/CodeGen/X86/i64-mem-copy.ll Thu Mar 12 13:24:26 2009
@@ -0,0 +1,13 @@
+; RUN: llvm-as < %s | llc -march=x86-64           | grep {movq.*(%rsi), %rax}
+; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep {movsd.*(%eax),}
+
+; Uses movsd to load / store i64 values in sse2 is available.
+
+; rdar://6659858
+
+define void @foo(i64* %x, i64* %y) nounwind  {
+entry:
+	%tmp1 = load i64* %y, align 8		; <i64> [#uses=1]
+	store i64 %tmp1, i64* %x, align 8
+	ret void
+}

Modified: llvm/branches/Apple/Dib/test/CodeGen/X86/mmx-copy-gprs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/test/CodeGen/X86/mmx-copy-gprs.ll?rev=66808&r1=66807&r2=66808&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/test/CodeGen/X86/mmx-copy-gprs.ll (original)
+++ llvm/branches/Apple/Dib/test/CodeGen/X86/mmx-copy-gprs.ll Thu Mar 12 13:24:26 2009
@@ -1,11 +1,11 @@
-; RUN: llvm-as < %s | llc -march=x86-64 | grep {movq.*(%rsi), %rax}
-; RUN: llvm-as < %s | llc -march=x86 | grep {movl.*4(%eax),}
+; RUN: llvm-as < %s | llc -march=x86-64           | grep {movq.*(%rsi), %rax}
+; RUN: llvm-as < %s | llc -march=x86 -mattr=-sse2 | grep {movl.*4(%eax),}
+; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep {movsd.(%eax),}
 
 ; This test should use GPRs to copy the mmx value, not MMX regs.  Using mmx regs,
 ; increases the places that need to use emms.
 
 ; rdar://5741668
-target triple = "x86_64-apple-darwin8"
 
 define void @foo(<1 x i64>* %x, <1 x i64>* %y) nounwind  {
 entry:





More information about the llvm-commits mailing list