Perform address optimization of sub-vector load/store.

Change-Id: I3459f9a5472aba37e1b7016b27403094e17bb9f7
Reviewed-on: https://chromium-review.googlesource.com/433372
Reviewed-by: Jim Stichnoth <stichnot@chromium.org>
diff --git a/src/IceTargetLowering.cpp b/src/IceTargetLowering.cpp
index 2ec2f75..3d8537d 100644
--- a/src/IceTargetLowering.cpp
+++ b/src/IceTargetLowering.cpp
@@ -364,6 +364,13 @@
     doAddressOptLoad();
   else if (llvm::isa<InstStore>(*Context.getCur()))
     doAddressOptStore();
+  else if (auto *Intrinsic =
+               llvm::dyn_cast<InstIntrinsicCall>(&*Context.getCur())) {
+    if (Intrinsic->getIntrinsicInfo().ID == Intrinsics::LoadSubVector)
+      doAddressOptLoadSubVector();
+    else if (Intrinsic->getIntrinsicInfo().ID == Intrinsics::StoreSubVector)
+      doAddressOptStoreSubVector();
+  }
   Context.advanceCur();
   Context.advanceNext();
 }
diff --git a/src/IceTargetLowering.h b/src/IceTargetLowering.h
index bfe0a0e..5cb42e6 100644
--- a/src/IceTargetLowering.h
+++ b/src/IceTargetLowering.h
@@ -426,6 +426,8 @@
   virtual void doAddressOptOther() {}
   virtual void doAddressOptLoad() {}
   virtual void doAddressOptStore() {}
+  virtual void doAddressOptLoadSubVector() {}
+  virtual void doAddressOptStoreSubVector() {}
   virtual void doMockBoundsCheck(Operand *) {}
   virtual void randomlyInsertNop(float Probability,
                                  RandomNumberGenerator &RNG) = 0;
diff --git a/src/IceTargetLoweringX86Base.h b/src/IceTargetLoweringX86Base.h
index 19e745f..2eac3f4 100644
--- a/src/IceTargetLoweringX86Base.h
+++ b/src/IceTargetLoweringX86Base.h
@@ -313,6 +313,8 @@
   void doAddressOptOther() override;
   void doAddressOptLoad() override;
   void doAddressOptStore() override;
+  void doAddressOptLoadSubVector() override;
+  void doAddressOptStoreSubVector() override;
   void doMockBoundsCheck(Operand *Opnd) override;
   void randomlyInsertNop(float Probability,
                          RandomNumberGenerator &RNG) override;
diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h
index 65041e8..c2bce04 100644
--- a/src/IceTargetLoweringX86BaseImpl.h
+++ b/src/IceTargetLoweringX86BaseImpl.h
@@ -6014,6 +6014,23 @@
 }
 
 template <typename TraitsType>
+void TargetX86Base<TraitsType>::doAddressOptLoadSubVector() {
+  auto *Intrinsic = llvm::cast<InstIntrinsicCall>(Context.getCur());
+  Operand *Addr = Intrinsic->getArg(0);
+  Variable *Dest = Intrinsic->getDest();
+  if (auto *OptAddr = computeAddressOpt(Intrinsic, Dest->getType(), Addr)) {
+    Intrinsic->setDeleted();
+    const Ice::Intrinsics::IntrinsicInfo Info = {
+        Ice::Intrinsics::LoadSubVector, Ice::Intrinsics::SideEffects_F,
+        Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
+    auto Target = Ctx->getConstantUndef(Ice::IceType_i32);
+    auto *NewLoad = Context.insert<InstIntrinsicCall>(2, Dest, Target, Info);
+    NewLoad->addArg(OptAddr);
+    NewLoad->addArg(Intrinsic->getArg(1));
+  }
+}
+
+template <typename TraitsType>
 void TargetX86Base<TraitsType>::randomlyInsertNop(float Probability,
                                                   RandomNumberGenerator &RNG) {
   RandomNumberGeneratorWrapper RNGW(RNG);
@@ -6858,6 +6875,25 @@
 }
 
 template <typename TraitsType>
+void TargetX86Base<TraitsType>::doAddressOptStoreSubVector() {
+  auto *Intrinsic = llvm::cast<InstIntrinsicCall>(Context.getCur());
+  Operand *Addr = Intrinsic->getArg(1);
+  Operand *Data = Intrinsic->getArg(0);
+  if (auto *OptAddr = computeAddressOpt(Intrinsic, Data->getType(), Addr)) {
+    Intrinsic->setDeleted();
+    const Ice::Intrinsics::IntrinsicInfo Info = {
+        Ice::Intrinsics::StoreSubVector, Ice::Intrinsics::SideEffects_T,
+        Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_T};
+    auto Target = Ctx->getConstantUndef(Ice::IceType_i32);
+    auto *NewStore =
+        Context.insert<InstIntrinsicCall>(3, nullptr, Target, Info);
+    NewStore->addArg(Data);
+    NewStore->addArg(OptAddr);
+    NewStore->addArg(Intrinsic->getArg(2));
+  }
+}
+
+template <typename TraitsType>
 Operand *TargetX86Base<TraitsType>::lowerCmpRange(Operand *Comparison,
                                                   uint64_t Min, uint64_t Max) {
   // TODO(ascull): 64-bit should not reach here but only because it is not