Fix the SVOffset values for loads and stores produced by
authorDan Gohman <gohman@apple.com>
Mon, 28 Apr 2008 17:15:20 +0000 (17:15 +0000)
committerDan Gohman <gohman@apple.com>
Mon, 28 Apr 2008 17:15:20 +0000 (17:15 +0000)
memcpy/memset expansion. It was a bug for the SVOffset value
to be used in the actual address calculations.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50359 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/SelectionDAG.h
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMISelLowering.h
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86ISelLowering.h

index 0d0e4d374cb1826d6c664805077f69c034e9a67c..e17e32eaf14310185df213703b43ac38c75e9bb4 100644 (file)
@@ -326,17 +326,17 @@ public:
   SDOperand getMemcpy(SDOperand Chain, SDOperand Dst, SDOperand Src,
                       SDOperand Size, unsigned Align,
                       bool AlwaysInline,
-                      const Value *DstSV, uint64_t DstOff,
-                      const Value *SrcSV, uint64_t SrcOff);
+                      const Value *DstSV, uint64_t DstSVOff,
+                      const Value *SrcSV, uint64_t SrcSVOff);
 
   SDOperand getMemmove(SDOperand Chain, SDOperand Dst, SDOperand Src,
                        SDOperand Size, unsigned Align,
-                       const Value *DstSV, uint64_t DstOff,
-                       const Value *SrcSV, uint64_t SrcOff);
+                       const Value *DstSV, uint64_t DstOSVff,
+                       const Value *SrcSV, uint64_t SrcSVOff);
 
   SDOperand getMemset(SDOperand Chain, SDOperand Dst, SDOperand Src,
                       SDOperand Size, unsigned Align,
-                      const Value *DstSV, uint64_t DstOff);
+                      const Value *DstSV, uint64_t DstSVOff);
 
   /// getSetCC - Helper function to make it easier to build SetCC's if you just
   /// have an ISD::CondCode instead of an SDOperand.
index bfc350689940efc14210bbab2136f7b39d6a36b5..dfd422a4a931d93af4cf64f167926fbc3c3199c1 100644 (file)
@@ -2590,8 +2590,8 @@ static SDOperand getMemcpyLoadsAndStores(SelectionDAG &DAG,
                                          SDOperand Src, uint64_t Size,
                                          unsigned Align,
                                          bool AlwaysInline,
-                                         const Value *DstSV, uint64_t DstOff,
-                                         const Value *SrcSV, uint64_t SrcOff) {
+                                         const Value *DstSV, uint64_t DstSVOff,
+                                         const Value *SrcSV, uint64_t SrcSVOff){
   const TargetLowering &TLI = DAG.getTargetLoweringInfo();
 
   // Expand memcpy to a series of store ops if the size operand falls below
@@ -2610,6 +2610,7 @@ static SDOperand getMemcpyLoadsAndStores(SelectionDAG &DAG,
   GlobalAddressSDNode *G = NULL;
   std::string Str;
   bool CopyFromStr = false;
+  uint64_t SrcOff = 0, DstOff = 0;
 
   if (Src.getOpcode() == ISD::GlobalAddress)
     G = cast<GlobalAddressSDNode>(Src);
@@ -2640,15 +2641,15 @@ static SDOperand getMemcpyLoadsAndStores(SelectionDAG &DAG,
       Store =
         DAG.getStore(Chain, Value,
                      getMemBasePlusOffset(Dst, DstOff, DAG),
-                     DstSV, DstOff);
+                     DstSV, DstSVOff + DstOff);
     } else {
       Value = DAG.getLoad(VT, Chain,
                           getMemBasePlusOffset(Src, SrcOff, DAG),
-                          SrcSV, SrcOff, false, Align);
+                          SrcSV, SrcSVOff + SrcOff, false, Align);
       Store =
         DAG.getStore(Chain, Value,
                      getMemBasePlusOffset(Dst, DstOff, DAG),
-                     DstSV, DstOff, false, Align);
+                     DstSV, DstSVOff + DstOff, false, Align);
     }
     OutChains.push_back(Store);
     SrcOff += VTSize;
@@ -2663,7 +2664,7 @@ static SDOperand getMemsetStores(SelectionDAG &DAG,
                                  SDOperand Chain, SDOperand Dst,
                                  SDOperand Src, uint64_t Size,
                                  unsigned Align,
-                                 const Value *DstSV, uint64_t DstOff) {
+                                 const Value *DstSV, uint64_t DstSVOff) {
   const TargetLowering &TLI = DAG.getTargetLoweringInfo();
 
   // Expand memset to a series of load/store ops if the size operand
@@ -2674,6 +2675,7 @@ static SDOperand getMemsetStores(SelectionDAG &DAG,
     return SDOperand();
 
   SmallVector<SDOperand, 8> OutChains;
+  uint64_t DstOff = 0;
 
   unsigned NumMemOps = MemOps.size();
   for (unsigned i = 0; i < NumMemOps; i++) {
@@ -2682,7 +2684,7 @@ static SDOperand getMemsetStores(SelectionDAG &DAG,
     SDOperand Value = getMemsetValue(Src, VT, DAG);
     SDOperand Store = DAG.getStore(Chain, Value,
                                    getMemBasePlusOffset(Dst, DstOff, DAG),
-                                   DstSV, DstOff);
+                                   DstSV, DstSVOff + DstOff);
     OutChains.push_back(Store);
     DstOff += VTSize;
   }
@@ -2694,8 +2696,8 @@ static SDOperand getMemsetStores(SelectionDAG &DAG,
 SDOperand SelectionDAG::getMemcpy(SDOperand Chain, SDOperand Dst,
                                   SDOperand Src, SDOperand Size,
                                   unsigned Align, bool AlwaysInline,
-                                  const Value *DstSV, uint64_t DstOff,
-                                  const Value *SrcSV, uint64_t SrcOff) {
+                                  const Value *DstSV, uint64_t DstSVOff,
+                                  const Value *SrcSV, uint64_t SrcSVOff) {
 
   // Check to see if we should lower the memcpy to loads and stores first.
   // For cases within the target-specified limits, this is the best choice.
@@ -2707,7 +2709,7 @@ SDOperand SelectionDAG::getMemcpy(SDOperand Chain, SDOperand Dst,
 
     SDOperand Result =
       getMemcpyLoadsAndStores(*this, Chain, Dst, Src, ConstantSize->getValue(),
-                              Align, false, DstSV, DstOff, SrcSV, SrcOff);
+                              Align, false, DstSV, DstSVOff, SrcSV, SrcSVOff);
     if (Result.Val)
       return Result;
   }
@@ -2717,7 +2719,7 @@ SDOperand SelectionDAG::getMemcpy(SDOperand Chain, SDOperand Dst,
   SDOperand Result =
     TLI.EmitTargetCodeForMemcpy(*this, Chain, Dst, Src, Size, Align,
                                 AlwaysInline,
-                                DstSV, DstOff, SrcSV, SrcOff);
+                                DstSV, DstSVOff, SrcSV, SrcSVOff);
   if (Result.Val)
     return Result;
 
@@ -2727,7 +2729,7 @@ SDOperand SelectionDAG::getMemcpy(SDOperand Chain, SDOperand Dst,
     assert(ConstantSize && "AlwaysInline requires a constant size!");
     return getMemcpyLoadsAndStores(*this, Chain, Dst, Src,
                                    ConstantSize->getValue(), Align, true,
-                                   DstSV, DstOff, SrcSV, SrcOff);
+                                   DstSV, DstSVOff, SrcSV, SrcSVOff);
   }
 
   // Emit a library call.
@@ -2748,8 +2750,8 @@ SDOperand SelectionDAG::getMemcpy(SDOperand Chain, SDOperand Dst,
 SDOperand SelectionDAG::getMemmove(SDOperand Chain, SDOperand Dst,
                                    SDOperand Src, SDOperand Size,
                                    unsigned Align,
-                                   const Value *DstSV, uint64_t DstOff,
-                                   const Value *SrcSV, uint64_t SrcOff) {
+                                   const Value *DstSV, uint64_t DstSVOff,
+                                   const Value *SrcSV, uint64_t SrcSVOff) {
 
   // TODO: Optimize small memmove cases with simple loads and stores,
   // ensuring that all loads precede all stores. This can cause severe
@@ -2759,7 +2761,7 @@ SDOperand SelectionDAG::getMemmove(SDOperand Chain, SDOperand Dst,
   // code. If the target chooses to do this, this is the next best.
   SDOperand Result =
     TLI.EmitTargetCodeForMemmove(*this, Chain, Dst, Src, Size, Align,
-                                 DstSV, DstOff, SrcSV, SrcOff);
+                                 DstSV, DstSVOff, SrcSV, SrcSVOff);
   if (Result.Val)
     return Result;
 
@@ -2781,7 +2783,7 @@ SDOperand SelectionDAG::getMemmove(SDOperand Chain, SDOperand Dst,
 SDOperand SelectionDAG::getMemset(SDOperand Chain, SDOperand Dst,
                                   SDOperand Src, SDOperand Size,
                                   unsigned Align,
-                                  const Value *DstSV, uint64_t DstOff) {
+                                  const Value *DstSV, uint64_t DstSVOff) {
 
   // Check to see if we should lower the memset to stores first.
   // For cases within the target-specified limits, this is the best choice.
@@ -2793,7 +2795,7 @@ SDOperand SelectionDAG::getMemset(SDOperand Chain, SDOperand Dst,
 
     SDOperand Result =
       getMemsetStores(*this, Chain, Dst, Src, ConstantSize->getValue(), Align,
-                      DstSV, DstOff);
+                      DstSV, DstSVOff);
     if (Result.Val)
       return Result;
   }
@@ -2802,7 +2804,7 @@ SDOperand SelectionDAG::getMemset(SDOperand Chain, SDOperand Dst,
   // code. If the target chooses to do this, this is the next best.
   SDOperand Result =
     TLI.EmitTargetCodeForMemset(*this, Chain, Dst, Src, Size, Align,
-                                DstSV, DstOff);
+                                DstSV, DstSVOff);
   if (Result.Val)
     return Result;
 
index 6a581f715fd7d62bba3298868747474e237bbb1c..dc76b7b333fc4523c68e622d527cfb34f18f0517 100644 (file)
@@ -1247,8 +1247,8 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG,
                                            SDOperand Dst, SDOperand Src,
                                            SDOperand Size, unsigned Align,
                                            bool AlwaysInline,
-                                           const Value *DstSV, uint64_t DstOff,
-                                           const Value *SrcSV, uint64_t SrcOff){
+                                         const Value *DstSV, uint64_t DstSVOff,
+                                         const Value *SrcSV, uint64_t SrcSVOff){
   // Do repeated 4-byte loads and stores. To be improved.
   // This requires 4-byte alignment.
   if ((Align & 3) != 0)
@@ -1271,6 +1271,7 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG,
   const unsigned MAX_LOADS_IN_LDM = 6;
   SDOperand TFOps[MAX_LOADS_IN_LDM];
   SDOperand Loads[MAX_LOADS_IN_LDM];
+  uint64_t SrcOff = 0, DstOff = 0;
 
   // Emit up to MAX_LOADS_IN_LDM loads, then a TokenFactor barrier, then the
   // same number of stores.  The loads and stores will get combined into
@@ -1281,7 +1282,7 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG,
       Loads[i] = DAG.getLoad(VT, Chain,
                              DAG.getNode(ISD::ADD, MVT::i32, Src,
                                          DAG.getConstant(SrcOff, MVT::i32)),
-                             SrcSV, SrcOff);
+                             SrcSV, SrcSVOff + SrcOff);
       TFOps[i] = Loads[i].getValue(1);
       SrcOff += VTSize;
     }
@@ -1292,7 +1293,7 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG,
       TFOps[i] = DAG.getStore(Chain, Loads[i],
                            DAG.getNode(ISD::ADD, MVT::i32, Dst, 
                                        DAG.getConstant(DstOff, MVT::i32)),
-                           DstSV, DstOff);
+                           DstSV, DstSVOff + DstOff);
       DstOff += VTSize;
     }
     Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &TFOps[0], i);
@@ -1318,7 +1319,7 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG,
     Loads[i] = DAG.getLoad(VT, Chain,
                            DAG.getNode(ISD::ADD, MVT::i32, Src,
                                        DAG.getConstant(SrcOff, MVT::i32)),
-                           SrcSV, SrcOff);
+                           SrcSV, SrcSVOff + SrcOff);
     TFOps[i] = Loads[i].getValue(1);
     ++i;
     SrcOff += VTSize;
@@ -1340,7 +1341,7 @@ ARMTargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG,
     TFOps[i] = DAG.getStore(Chain, Loads[i],
                             DAG.getNode(ISD::ADD, MVT::i32, Dst, 
                                         DAG.getConstant(DstOff, MVT::i32)),
-                            DstSV, DstOff);
+                            DstSV, DstSVOff + DstOff);
     ++i;
     DstOff += VTSize;
     BytesLeft -= VTSize;
index 13f5c08375364c88ed2d37d60aa7c561e6b313b0..ce6d5fe449ab22395d3889c1da54b4077979283f 100644 (file)
@@ -149,8 +149,8 @@ namespace llvm {
                                       SDOperand Dst, SDOperand Src,
                                       SDOperand Size, unsigned Align,
                                       bool AlwaysInline,
-                                      const Value *DstSV, uint64_t DstOff,
-                                      const Value *SrcSV, uint64_t SrcOff);
+                                      const Value *DstSV, uint64_t DstSVOff,
+                                      const Value *SrcSV, uint64_t SrcSVOff);
   };
 }
 
index c0ba4d1b9aca4856d90a88131598f4161556cf43..799ba007fa19614611005b114a96c53a83c7224c 100644 (file)
@@ -4763,7 +4763,7 @@ X86TargetLowering::EmitTargetCodeForMemset(SelectionDAG &DAG,
                                            SDOperand Chain,
                                            SDOperand Dst, SDOperand Src,
                                            SDOperand Size, unsigned Align,
-                                           const Value *DstSV, uint64_t DstOff) {
+                                        const Value *DstSV, uint64_t DstSVOff) {
   ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
 
   /// If not DWORD aligned or size is more than the threshold, call the library.
@@ -4890,7 +4890,7 @@ X86TargetLowering::EmitTargetCodeForMemset(SelectionDAG &DAG,
                                       DAG.getConstant(Offset, AddrVT)),
                           Src,
                           DAG.getConstant(BytesLeft, SizeVT),
-                          Align, DstSV, 0);
+                          Align, DstSV, DstSVOff + Offset);
   }
 
   // TODO: Use a Tokenfactor, as in memcpy, instead of a single chain.
@@ -4903,8 +4903,8 @@ X86TargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG,
                                            SDOperand Dst, SDOperand Src,
                                            SDOperand Size, unsigned Align,
                                            bool AlwaysInline,
-                                           const Value *DstSV, uint64_t DstOff,
-                                           const Value *SrcSV, uint64_t SrcOff){
+                                           const Value *DstSV, uint64_t DstSVOff,
+                                           const Value *SrcSV, uint64_t SrcSVOff){
   
   // This requires the copy size to be a constant, preferrably
   // within a subtarget-specific limit.
@@ -4964,7 +4964,8 @@ X86TargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG,
                                                 DAG.getConstant(Offset, SrcVT)),
                                     DAG.getConstant(BytesLeft, SizeVT),
                                     Align, AlwaysInline,
-                                    DstSV, 0, SrcSV, 0));
+                                    DstSV, DstSVOff + Offset,
+                                    SrcSV, SrcSVOff + Offset));
   }
 
   return DAG.getNode(ISD::TokenFactor, MVT::Other, &Results[0], Results.size());
index 6b02f33aadc611220d067f74d92401cd58486cc6..987cf73102f3e0bb5e37e7c17c8741adc421652c 100644 (file)
@@ -538,14 +538,14 @@ namespace llvm {
                                       SDOperand Chain,
                                       SDOperand Dst, SDOperand Src,
                                       SDOperand Size, unsigned Align,
-                                      const Value *DstSV, uint64_t DstOff);
+                                      const Value *DstSV, uint64_t DstSVOff);
     SDOperand EmitTargetCodeForMemcpy(SelectionDAG &DAG,
                                       SDOperand Chain,
                                       SDOperand Dst, SDOperand Src,
                                       SDOperand Size, unsigned Align,
                                       bool AlwaysInline,
-                                      const Value *DstSV, uint64_t DstOff,
-                                      const Value *SrcSV, uint64_t SrcOff);
+                                      const Value *DstSV, uint64_t DstSVOff,
+                                      const Value *SrcSV, uint64_t SrcSVOff);
   };
 }