do not share old induction variables when this would result in invalid
instructions (that would have to be split later)


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35227 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index dc023c8..e0d6740 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -875,6 +875,16 @@
   /// scale of the target addressing mode for load / store of the given type.
   virtual bool isLegalAddressScale(int64_t S, const Type *Ty) const;
 
+  /// isLegalAddressScaleAndImm - Return true if S works for IsLegalAddressScale
+  /// and V works for isLegalAddressImmediate _and_ both can be applied
+  /// simultaneously to the same instruction.
+  virtual bool isLegalAddressScaleAndImm(int64_t S, int64_t V, 
+                                                    const Type* Ty) const;
+  /// isLegalAddressScaleAndImm - Return true if S works for IsLegalAddressScale
+  /// and GV works for isLegalAddressImmediate _and_ both can be applied
+  /// simultaneously to the same instruction.
+  virtual bool isLegalAddressScaleAndImm(int64_t S, GlobalValue *GV) const;
+
   //===--------------------------------------------------------------------===//
   // Div utility functions
   //
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 8df7d8d..83bca75 100644
--- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -1958,6 +1958,22 @@
   return false;
 }
 
+/// isLegalAddressScaleAndImm - Return true if S works for IsLegalAddressScale
+/// and V works for isLegalAddressImmediate _and_ both can be applied
+/// simultaneously to the same instruction.
+bool TargetLowering::isLegalAddressScaleAndImm(int64_t S, int64_t V, 
+                                               const Type* Ty) const {
+  return false;
+}
+
+/// isLegalAddressScaleAndImm - Return true if S works for IsLegalAddressScale
+/// and GV works for isLegalAddressImmediate _and_ both can be applied
+/// simultaneously to the same instruction.
+bool TargetLowering::isLegalAddressScaleAndImm(int64_t S, 
+                                               GlobalValue *GV) const {
+
+  return false;
+}
 
 // Magic for divide replacement
 
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index bd7fa5c..17a41c5 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -1379,6 +1379,24 @@
   }
 }
 
+/// isLegalAddressScaleAndImm - Return true if S works for IsLegalAddressScale
+/// and V works for isLegalAddressImmediate _and_ both can be applied
+/// simultaneously to the same instruction.
+bool ARMTargetLowering::isLegalAddressScaleAndImm(int64_t S, int64_t V, 
+                                               const Type* Ty) const {
+  if (V == 0)
+    return isLegalAddressScale(S, Ty);
+  return false;
+}
+
+/// isLegalAddressScaleAndImm - Return true if S works for IsLegalAddressScale
+/// and GV works for isLegalAddressImmediate _and_ both can be applied
+/// simultaneously to the same instruction.
+bool ARMTargetLowering::isLegalAddressScaleAndImm(int64_t S, 
+                                               GlobalValue *GV) const {
+  return false;
+}
+
 static bool getIndexedAddressParts(SDNode *Ptr, MVT::ValueType VT,
                                    bool isSEXTLoad, SDOperand &Base,
                                    SDOperand &Offset, bool &isInc,
diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h
index dc146ba..1675e9c 100644
--- a/lib/Target/ARM/ARMISelLowering.h
+++ b/lib/Target/ARM/ARMISelLowering.h
@@ -100,6 +100,17 @@
     /// type.
     virtual bool isLegalAddressScale(int64_t S, const Type *Ty) const;
 
+    /// isLegalAddressScaleAndImm - Return true if S works for 
+    /// IsLegalAddressScale and V works for isLegalAddressImmediate _and_ 
+    /// both can be applied simultaneously to the same instruction.
+    virtual bool isLegalAddressScaleAndImm(int64_t S, int64_t V, 
+                                           const Type *Ty) const;
+
+    /// isLegalAddressScaleAndImm - Return true if S works for 
+    /// IsLegalAddressScale and GV works for isLegalAddressImmediate _and_
+    /// both can be applied simultaneously to the same instruction.
+    virtual bool isLegalAddressScaleAndImm(int64_t S, GlobalValue *GV) const;
+
     /// getPreIndexedAddressParts - returns true by value, base pointer and
     /// offset pointer and addressing mode by reference if the node's address
     /// can be legally represented as pre-indexed load / store address.
diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index 4353134..4ace17f 100644
--- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -883,9 +883,16 @@
 ///
 bool LoopStrengthReduce::ValidStride(int64_t Scale, 
                                const std::vector<BasedUser>& UsersToProcess) {
-  for (unsigned i=0, e = UsersToProcess.size(); i!=e; ++i)
-    if (!TLI->isLegalAddressScale(Scale, UsersToProcess[i].Inst->getType()))
+  int64_t Imm;
+  for (unsigned i=0, e = UsersToProcess.size(); i!=e; ++i) {
+    if (SCEVConstant *SC = dyn_cast<SCEVConstant>(UsersToProcess[i].Imm))
+      Imm = SC->getValue()->getSExtValue();
+    else
+      Imm = 0;
+    if (!TLI->isLegalAddressScaleAndImm(Scale, Imm, 
+                                  UsersToProcess[i].Inst->getType()))
       return false;
+  }
   return true;
 }
 
@@ -968,22 +975,6 @@
   SCEVHandle CommonExprs =
     RemoveCommonExpressionsFromUseBases(UsersToProcess);
   
-  // Check if it is possible to reuse a IV with stride that is factor of this
-  // stride. And the multiple is a number that can be encoded in the scale
-  // field of the target addressing mode.
-  PHINode *NewPHI = NULL;
-  Value   *IncV   = NULL;
-  IVExpr   ReuseIV;
-  unsigned RewriteFactor = CheckForIVReuse(Stride, ReuseIV,
-                                           CommonExprs->getType(),
-                                           UsersToProcess);
-  if (RewriteFactor != 0) {
-    DOUT << "BASED ON IV of STRIDE " << *ReuseIV.Stride
-         << " and BASE " << *ReuseIV.Base << " :\n";
-    NewPHI = ReuseIV.PHI;
-    IncV   = ReuseIV.IncV;
-  }
-
   // Next, figure out what we can represent in the immediate fields of
   // instructions.  If we can represent anything there, move it to the imm
   // fields of the BasedUsers.  We do this so that it increases the commonality
@@ -1011,6 +1002,23 @@
     }
   }
 
+  // Check if it is possible to reuse a IV with stride that is factor of this
+  // stride. And the multiple is a number that can be encoded in the scale
+  // field of the target addressing mode.  And we will have a valid
+  // instruction after this substition, including the immediate field, if any.
+  PHINode *NewPHI = NULL;
+  Value   *IncV   = NULL;
+  IVExpr   ReuseIV;
+  unsigned RewriteFactor = CheckForIVReuse(Stride, ReuseIV,
+                                           CommonExprs->getType(),
+                                           UsersToProcess);
+  if (RewriteFactor != 0) {
+    DOUT << "BASED ON IV of STRIDE " << *ReuseIV.Stride
+         << " and BASE " << *ReuseIV.Base << " :\n";
+    NewPHI = ReuseIV.PHI;
+    IncV   = ReuseIV.IncV;
+  }
+
   // Now that we know what we need to do, insert the PHI node itself.
   //
   DOUT << "INSERTING IV of STRIDE " << *Stride << " and BASE "