Index: include/polly/ScopInfo.h
===================================================================
--- include/polly/ScopInfo.h
+++ include/polly/ScopInfo.h
@@ -244,7 +244,10 @@
   ReductionType RedType = RT_NONE;
 
   /// @brief The access instruction of this memory access.
-  Instruction *Inst;
+  Instruction *AccessInstruction;
+
+  /// @brief The value associated with this memory access.
+  Value *AccessValue;
 
   /// Updated access relation read from JSCOP file.
   isl_map *newAccessRelation;
@@ -377,8 +380,11 @@
 
   const std::string &getBaseName() const { return BaseName; }
 
+  /// @brief Return the access value of this memory access.
+  Value *getAccessValue() const { return AccessValue; }
+
   /// @brief Return the access instruction of this memory access.
-  Instruction *getAccessInstruction() const { return Inst; }
+  Instruction *getAccessInstruction() const { return AccessInstruction; }
 
   /// Get the stride of this memory access in the specified Schedule. Schedule
   /// is a map from the statement to a schedule where the innermost dimension is
Index: include/polly/TempScopInfo.h
===================================================================
--- include/polly/TempScopInfo.h
+++ include/polly/TempScopInfo.h
@@ -33,6 +33,7 @@
 class IRAccess {
 public:
   Value *BaseAddress;
+  Value *AccessValue;
 
   const SCEV *Offset;
 
@@ -58,22 +59,25 @@
   ///
   /// @param IsPHI Are we modeling special PHI node accesses?
   explicit IRAccess(TypeKind Type, Value *BaseAddress, const SCEV *Offset,
-                    unsigned elemBytes, bool Affine, bool IsPHI = false)
-      : BaseAddress(BaseAddress), Offset(Offset), ElemBytes(elemBytes),
-        Type(Type), IsAffine(Affine), IsPHI(IsPHI) {}
+                    unsigned elemBytes, bool Affine, Value *AccessValue,
+                    bool IsPHI = false)
+      : BaseAddress(BaseAddress), AccessValue(AccessValue), Offset(Offset),
+        ElemBytes(elemBytes), Type(Type), IsAffine(Affine), IsPHI(IsPHI) {}
 
   explicit IRAccess(TypeKind Type, Value *BaseAddress, const SCEV *Offset,
                     unsigned elemBytes, bool Affine,
                     SmallVector<const SCEV *, 4> Subscripts,
-                    SmallVector<const SCEV *, 4> Sizes)
-      : BaseAddress(BaseAddress), Offset(Offset), ElemBytes(elemBytes),
-        Type(Type), IsAffine(Affine), IsPHI(false), Subscripts(Subscripts),
-        Sizes(Sizes) {}
+                    SmallVector<const SCEV *, 4> Sizes, Value *AccessValue)
+      : BaseAddress(BaseAddress), AccessValue(AccessValue), Offset(Offset),
+        ElemBytes(elemBytes), Type(Type), IsAffine(Affine), IsPHI(false),
+        Subscripts(Subscripts), Sizes(Sizes) {}
 
   enum TypeKind getType() const { return Type; }
 
   Value *getBase() const { return BaseAddress; }
 
+  Value *getAccessValue() const { return AccessValue; }
+
   const SCEV *getOffset() const { return Offset; }
 
   unsigned getElemSizeInBytes() const { return ElemBytes; }
Index: lib/Analysis/ScopInfo.cpp
===================================================================
--- lib/Analysis/ScopInfo.cpp
+++ lib/Analysis/ScopInfo.cpp
@@ -447,7 +447,8 @@
 MemoryAccess::MemoryAccess(const IRAccess &Access, Instruction *AccInst,
                            ScopStmt *Statement, const ScopArrayInfo *SAI,
                            int Identifier)
-    : AccType(getMemoryAccessType(Access)), Statement(Statement), Inst(AccInst),
+    : AccType(getMemoryAccessType(Access)), Statement(Statement),
+      AccessInstruction(AccInst), AccessValue(Access.getAccessValue()),
       newAccessRelation(nullptr) {
 
   isl_ctx *Ctx = Statement->getIslCtx();
@@ -669,18 +670,6 @@
   Domain = NewDomain;
 }
 
-// @brief Get the data-type of the elements accessed
-static Type *getAccessType(IRAccess &Access, Instruction *AccessInst) {
-  if (Access.isPHI())
-    return Access.getBase()->getType();
-
-  if (StoreInst *Store = dyn_cast<StoreInst>(AccessInst))
-    return Store->getValueOperand()->getType();
-  if (BranchInst *Branch = dyn_cast<BranchInst>(AccessInst))
-    return Branch->getCondition()->getType();
-  return AccessInst->getType();
-}
-
 void ScopStmt::buildAccesses(TempScop &tempScop, BasicBlock *Block,
                              bool isApproximated) {
   AccFuncSetType *AFS = tempScop.getAccessFunctions(Block);
@@ -690,7 +679,7 @@
   for (auto &AccessPair : *AFS) {
     IRAccess &Access = AccessPair.first;
     Instruction *AccessInst = AccessPair.second;
-    Type *ElementType = getAccessType(Access, AccessInst);
+    Type *ElementType = Access.getAccessValue()->getType();
 
     const ScopArrayInfo *SAI = getParent()->getOrCreateScopArrayInfo(
         Access.getBase(), ElementType, Access.Sizes, Access.isPHI());
Index: lib/Analysis/TempScopInfo.cpp
===================================================================
--- lib/Analysis/TempScopInfo.cpp
+++ lib/Analysis/TempScopInfo.cpp
@@ -135,9 +135,10 @@
       // we have to insert a scalar dependence from the definition of OpI to
       // OpBB if the definition is not in OpBB.
       if (OpIBB != OpBB) {
-        IRAccess ScalarRead(IRAccess::READ, OpI, ZeroOffset, 1, true);
+        IRAccess ScalarRead(IRAccess::READ, OpI, ZeroOffset, 1, true, OpI);
         AccFuncMap[OpBB].push_back(std::make_pair(ScalarRead, PHI));
-        IRAccess ScalarWrite(IRAccess::MUST_WRITE, OpI, ZeroOffset, 1, true);
+        IRAccess ScalarWrite(IRAccess::MUST_WRITE, OpI, ZeroOffset, 1, true,
+                             OpI);
         AccFuncMap[OpIBB].push_back(std::make_pair(ScalarWrite, OpI));
       }
     }
@@ -147,13 +148,13 @@
     if (!OpI)
       OpI = OpBB->getTerminator();
 
-    IRAccess ScalarAccess(IRAccess::MUST_WRITE, PHI, ZeroOffset, 1, true,
+    IRAccess ScalarAccess(IRAccess::MUST_WRITE, PHI, ZeroOffset, 1, true, Op,
                           /* IsPHI */ true);
     AccFuncMap[OpBB].push_back(std::make_pair(ScalarAccess, OpI));
   }
 
   if (!OnlyNonAffineSubRegionOperands) {
-    IRAccess ScalarAccess(IRAccess::READ, PHI, ZeroOffset, 1, true,
+    IRAccess ScalarAccess(IRAccess::READ, PHI, ZeroOffset, 1, true, PHI,
                           /* IsPHI */ true);
     Functions.push_back(std::make_pair(ScalarAccess, PHI));
   }
@@ -211,7 +212,7 @@
     // Do not build a read access that is not in the current SCoP
     // Use the def instruction as base address of the IRAccess, so that it will
     // become the name of the scalar access in the polyhedral form.
-    IRAccess ScalarAccess(IRAccess::READ, Inst, ZeroOffset, 1, true);
+    IRAccess ScalarAccess(IRAccess::READ, Inst, ZeroOffset, 1, true, Inst);
     AccFuncMap[UseParent].push_back(std::make_pair(ScalarAccess, UI));
   }
 
@@ -224,7 +225,7 @@
         if (R->contains(OpInst))
           continue;
 
-      IRAccess ScalarAccess(IRAccess::READ, Op, ZeroOffset, 1, true);
+      IRAccess ScalarAccess(IRAccess::READ, Op, ZeroOffset, 1, true, Op);
       AccFuncMap[Inst->getParent()].push_back(
           std::make_pair(ScalarAccess, Inst));
     }
@@ -240,17 +241,20 @@
                             const ScopDetection::BoxedLoopsSetTy *BoxedLoops) {
   unsigned Size;
   Type *SizeType;
+  Value *Val;
   enum IRAccess::TypeKind Type;
 
   if (LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
     SizeType = Load->getType();
     Size = TD->getTypeStoreSize(SizeType);
     Type = IRAccess::READ;
+    Val = Load;
   } else {
     StoreInst *Store = cast<StoreInst>(Inst);
     SizeType = Store->getValueOperand()->getType();
     Size = TD->getTypeStoreSize(SizeType);
     Type = IRAccess::MUST_WRITE;
+    Val = Store->getValueOperand();
   }
 
   const SCEV *AccessFunction = SE->getSCEVAtScope(getPointerOperand(*Inst), L);
@@ -264,7 +268,7 @@
   if (PollyDelinearize && AccItr != InsnToMemAcc.end())
     return IRAccess(Type, BasePointer->getValue(), AccessFunction, Size, true,
                     AccItr->second.DelinearizedSubscripts,
-                    AccItr->second.Shape->DelinearizedSizes);
+                    AccItr->second.Shape->DelinearizedSizes, Val);
 
   // Check if the access depends on a loop contained in a non-affine subregion.
   bool isVariantInNonAffineLoop = false;
@@ -287,7 +291,7 @@
     Type = IRAccess::MAY_WRITE;
 
   return IRAccess(Type, BasePointer->getValue(), AccessFunction, Size, IsAffine,
-                  Subscripts, Sizes);
+                  Subscripts, Sizes, Val);
 }
 
 void TempScopInfo::buildAccessFunctions(Region &R, Region &SR) {
@@ -326,7 +330,8 @@
         buildScalarDependences(Inst, &R, NonAffineSubRegion)) {
       // If the Instruction is used outside the statement, we need to build the
       // write access.
-      IRAccess ScalarAccess(IRAccess::MUST_WRITE, Inst, ZeroOffset, 1, true);
+      IRAccess ScalarAccess(IRAccess::MUST_WRITE, Inst, ZeroOffset, 1, true,
+                            Inst);
       Functions.push_back(std::make_pair(ScalarAccess, Inst));
     }
   }
Index: lib/CodeGen/BlockGenerators.cpp
===================================================================
--- lib/CodeGen/BlockGenerators.cpp
+++ lib/CodeGen/BlockGenerators.cpp
@@ -495,21 +495,14 @@
       continue;
 
     Instruction *Base = cast<Instruction>(MA->getBaseAddr());
-    Instruction *Inst = MA->getAccessInstruction();
+    Value *Val = MA->getAccessValue();
 
-    Value *Val = nullptr;
     AllocaInst *Address = nullptr;
-
-    if (MA->getScopArrayInfo()->isPHI()) {
-      PHINode *BasePHI = dyn_cast<PHINode>(Base);
-      int PHIIdx = BasePHI->getBasicBlockIndex(BB);
-      assert(PHIIdx >= 0);
+    if (MA->getScopArrayInfo()->isPHI())
       Address = getOrCreateAlloca(Base, PHIOpMap, ".phiops");
-      Val = BasePHI->getIncomingValue(PHIIdx);
-    } else {
+    else
       Address = getOrCreateAlloca(Base, ScalarMap, ".s2a");
-      Val = Inst;
-    }
+
     Val = getNewScalarValue(Val, R, ScalarMap, BBMap, GlobalMap);
     Builder.CreateStore(Val, Address);
   }
@@ -1124,23 +1117,18 @@
 
     Instruction *ScalarBase = cast<Instruction>(MA->getBaseAddr());
     Instruction *ScalarInst = MA->getAccessInstruction();
-    PHINode *ScalarBasePHI = dyn_cast<PHINode>(ScalarBase);
 
     // Only generate accesses that belong to this basic block.
     if (ScalarInst->getParent() != BB)
       continue;
 
-    Value *Val = nullptr;
+    Value *Val = MA->getAccessValue();
     AllocaInst *ScalarAddr = nullptr;
 
-    if (MA->getScopArrayInfo()->isPHI()) {
-      int PHIIdx = ScalarBasePHI->getBasicBlockIndex(BB);
+    if (MA->getScopArrayInfo()->isPHI())
       ScalarAddr = getOrCreateAlloca(ScalarBase, PHIOpMap, ".phiops");
-      Val = ScalarBasePHI->getIncomingValue(PHIIdx);
-    } else {
+    else
       ScalarAddr = getOrCreateAlloca(ScalarBase, ScalarMap, ".s2a");
-      Val = ScalarInst;
-    }
 
     Val = getNewScalarValue(Val, R, ScalarMap, BBMap, GlobalMap);
     Builder.CreateStore(Val, ScalarAddr);