diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h
index 854eea60..c1f94c34 100644
--- a/source/Lib/CommonLib/CommonDef.h
+++ b/source/Lib/CommonLib/CommonDef.h
@@ -223,6 +223,9 @@ static const int IBC_MRG_MAX_NUM_CANDS_MEM =                        28;   ///< I
 static const int IBC_MRG_MAX_NUM_CANDS_MEM =                        20;   ///< IBC MERGE- max number of candidates
 #endif
 #endif
+#if IBC_TBVP
+static const int NUM_TBVP_CANDS =                                   3; ///< TBVP
+#endif
 #if JVET_X0083_BM_AMVP_MERGE_MODE
 #if JVET_Y0129_MVD_SIGNAL_AMVP_MERGE_MODE
 static const int MAX_NUM_AMVP_CANDS_MAX_REF =                       MAX_NUM_REF * AMVP_MAX_NUM_CANDS_MEM;
@@ -856,6 +859,9 @@ static const int    NUM_MRG_SATD_CAND =                             4;
 #if JVET_AA0061_IBC_MBVD
 static const int    NUM_IBC_MRG_SATD_CAND =                         3;
 #endif
+#if IBC_OVERLAP
+static const int    IBC_OVERLAP_TM_COST_FACTOR =                    2;
+#endif
 static const double MRG_FAST_RATIO    =                             1.25;
 static const int    NUM_AFF_MRG_SATD_CAND =                         2;
 #if AFFINE_MMVD
@@ -1216,11 +1222,23 @@ static const int IBC_FAST_METHOD_BUFFERBV = 0X02;
 static const int IBC_FAST_METHOD_ADAPTIVE_SEARCHRANGE = 0X04;
 #if JVET_AA0061_IBC_MBVD
 static const int IBC_MBVD_BASE_NUM =                                 5;
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+#if EE2_TEST_3_2_A
+static const int IBC_MBVD_STEP_NUM =                                 128; // number of distance offset
+#endif
+#if EE2_TEST_3_2_B
+static const int IBC_MBVD_STEP_NUM =                                 256; // number of distance offset
+#endif
+#else
 static const int IBC_MBVD_STEP_NUM =                                 20; // number of distance offset
+#endif
 static const int IBC_MBVD_OFFSET_DIR =                               4; // (+, 0); (-, 0); (0, +); (0, -);
 static const int IBC_MBVD_MAX_REFINE_NUM = IBC_MBVD_STEP_NUM * IBC_MBVD_OFFSET_DIR; ///< max number of candidate from a base candidate
 static const int IBC_MBVD_NUM = IBC_MBVD_BASE_NUM * IBC_MBVD_MAX_REFINE_NUM;        ///< total number of IBC mmvd candidate
 static const int IBC_MBVD_SIZE_ENC =                                 8;
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+static const int IBC_MBVD_ENC_NUM = IBC_MBVD_BASE_NUM * IBC_MBVD_SIZE_ENC;        ///< total number of IBC mmvd candidate for encoder
+#endif
 static const int ADAPTIVE_SUB_GROUP_SIZE_IBC_MBVD = IBC_MBVD_MAX_REFINE_NUM;
 #endif
 #if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_GPM
diff --git a/source/Lib/CommonLib/ContextModelling.cpp b/source/Lib/CommonLib/ContextModelling.cpp
index cb1da4d1..653c7309 100644
--- a/source/Lib/CommonLib/ContextModelling.cpp
+++ b/source/Lib/CommonLib/ContextModelling.cpp
@@ -1455,9 +1455,11 @@ bool AffineMergeCtx::xCheckSimilarMotion(int mergeCandIndex, uint32_t mvdSimilar
 #if JVET_AA0061_IBC_MBVD
 bool MergeCtx::setIbcMbvdMergeCandiInfo(PredictionUnit& pu, int candIdx, int candIdxMaped)
 {
+#if !JVET_AC0159_IBC_MBVD_LIST_DERIVATION
   const int mvShift = MV_FRACTIONAL_BITS_DIFF + 2;
   const int refMvdCands[IBC_MBVD_STEP_NUM] = { 1 << mvShift , 2 << mvShift , 4 << mvShift , 8 << mvShift , 12 << mvShift , 16 << mvShift , 24 << mvShift , 32 << mvShift , 40 << mvShift , 48 << mvShift , 56 << mvShift ,
     64 << mvShift , 72 << mvShift , 80 << mvShift , 88 << mvShift , 96 << mvShift , 104 << mvShift , 112 << mvShift , 120 << mvShift , 128 << mvShift };
+#endif
   int fPosGroup = 0;
   int fPosBaseIdx = 0;
   int fPosStep = 0;
@@ -1477,7 +1479,11 @@ bool MergeCtx::setIbcMbvdMergeCandiInfo(PredictionUnit& pu, int candIdx, int can
   tempIdx = tempIdx - fPosBaseIdx * (IBC_MBVD_MAX_REFINE_NUM);
   fPosStep = tempIdx / IBC_MBVD_OFFSET_DIR;
   fPosPosition = tempIdx - fPosStep * (IBC_MBVD_OFFSET_DIR);
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  int offset = g_ibcMbvdCands[fPosStep];
+#else
   int offset = refMvdCands[fPosStep];
+#endif
 
   const int refList0 = ibcMbvdBaseBv[fPosBaseIdx][0].refIdx;
   const int xDir[] = {1, -1,  0,  0,  1, -1,  1, -1, 2, -2,  2, -2, 1,  1, -1, -1};
diff --git a/source/Lib/CommonLib/IbcHashMap.cpp b/source/Lib/CommonLib/IbcHashMap.cpp
index 0d82f84b..734f4e4b 100644
--- a/source/Lib/CommonLib/IbcHashMap.cpp
+++ b/source/Lib/CommonLib/IbcHashMap.cpp
@@ -397,7 +397,15 @@ bool IbcHashMap::ibcHashMatch(const Area& lumaArea, std::vector<Position>& cand,
       bool wholeBlockMatch = true;
       if (lumaArea.width > MIN_PU_SIZE || lumaArea.height > MIN_PU_SIZE)
       {
+#if IBC_OVERLAP
+#if JVET_AA0070_RRIBC
+        if ((!cs.isDecomp(bottomRight, CHANNEL_TYPE_LUMA) && rribcFlipType) || bottomRight.x >= m_picWidth || bottomRight.y >= m_picHeight || topLeft.x < 0 || topLeft.y < 0)
+#else
+        if (bottomRight.x >= m_picWidth || bottomRight.y >= m_picHeight || topLeft.x < 0 || topLeft.y < 0)
+#endif
+#else
         if (!cs.isDecomp(bottomRight, CHANNEL_TYPE_LUMA) || bottomRight.x >= m_picWidth || bottomRight.y >= m_picHeight || topLeft.x < 0 || topLeft.y < 0)
+#endif
         {
           continue;
         }
@@ -420,7 +428,15 @@ bool IbcHashMap::ibcHashMatch(const Area& lumaArea, std::vector<Position>& cand,
       else
       {
         CHECK(topLeft != *refBlockPos, "4x4 target block should not have offset!");
+#if IBC_OVERLAP
+#if JVET_AA0070_RRIBC
+        if (abs(topLeft.x - lumaArea.x) > searchRange4SmallBlk || abs(topLeft.y - lumaArea.y) > searchRange4SmallBlk || (!cs.isDecomp(bottomRight, CHANNEL_TYPE_LUMA)&&rribcFlipType))
+#else
+        if (abs(topLeft.x - lumaArea.x) > searchRange4SmallBlk || abs(topLeft.y - lumaArea.y) > searchRange4SmallBlk)
+#endif
+#else
         if (abs(topLeft.x - lumaArea.x) > searchRange4SmallBlk || abs(topLeft.y - lumaArea.y) > searchRange4SmallBlk || !cs.isDecomp(bottomRight, CHANNEL_TYPE_LUMA))
+#endif
         {
           continue;
         }
diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp
index dfd76225..36fdffde 100644
--- a/source/Lib/CommonLib/InterPrediction.cpp
+++ b/source/Lib/CommonLib/InterPrediction.cpp
@@ -272,6 +272,11 @@ InterPrediction::InterPrediction()
     }
   }
 #endif
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  mbvdCandCostList = nullptr;
+  mbvdSearchCandsList = nullptr;
+  mbvdTestedCandsList = nullptr;
+#endif
 }
 
 InterPrediction::~InterPrediction()
@@ -420,6 +425,14 @@ void InterPrediction::destroy()
     }
   }
 #endif
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  xFree(mbvdCandCostList);
+  xFree(mbvdSearchCandsList);
+  xFree(mbvdTestedCandsList);
+  mbvdCandCostList = nullptr;
+  mbvdSearchCandsList = nullptr;
+  mbvdTestedCandsList = nullptr;
+#endif
 }
 
 #if INTER_LIC || (TM_AMVP || TM_MRG || JVET_Z0084_IBC_TM) || JVET_W0090_ARMC_TM || JVET_Z0056_GPM_SPLIT_MODE_REORDERING || JVET_Z0061_TM_OBMC
@@ -673,6 +686,11 @@ void InterPrediction::init( RdCost* pcRdCost, ChromaFormat chromaFormatIDC, cons
 #endif
   }
 #endif
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  mbvdCandCostList = new Distortion[IBC_MBVD_ENC_NUM];
+  mbvdSearchCandsList = new int[IBC_MBVD_NUM];
+  mbvdTestedCandsList = new bool[IBC_MBVD_NUM];
+#endif
 }
 
 // ====================================================================================================================
@@ -2298,6 +2316,32 @@ void InterPrediction::xPredInterBlk ( const ComponentID& compID, const Predictio
 #if RPR_ENABLE
   }
 #endif
+#if IBC_OVERLAP
+#if JVET_AA0070_RRIBC
+  if (isIBC&&(pu.cu->rribcFlipType == 0))
+#else
+  if(isIBC)
+#endif
+  {
+    int xPred = mv.getHor() >> shiftHor;
+    int yPred = mv.getVer() >> shiftVer;
+    int width = pu.blocks[compID].width;
+    int height = pu.blocks[compID].height;
+    if(((xPred+width)>=1)&&((yPred+height)>=1))
+    {
+      PelBuf & dstBuf = dstPic.bufs[compID];
+      //pad the unavailable samples
+      Pel* piPredTmp = dstBuf.buf;
+      for (unsigned y = abs(yPred); y < pu.blocks[compID].height; y++)
+      {
+        for (unsigned x = abs(xPred); x < pu.blocks[compID].width; x++)
+        {
+          piPredTmp[dstBuf.stride*y+x] = piPredTmp[dstBuf.stride*(y+yPred)+(x+xPred)];
+        }
+      }
+    }
+  }
+#endif
 #if INTER_LIC
 #if RPR_ENABLE
   PelBuf& dstBuf = dstPic.bufs[compID];
@@ -6606,9 +6650,33 @@ void InterPrediction::xProcessDMVR(PredictionUnit& pu, PelUnitBuf &pcYuvDst, con
 void  InterPrediction::sortIbcMergeMbvdCandidates(PredictionUnit &pu, MergeCtx& mrgCtx, uint32_t * ibcMbvdLUT,uint32_t * ibcMbvdValidNum, int ibcMbvdIdx)
 {
 
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  memset(ibcMbvdValidNum, 0, sizeof(uint32_t)     * IBC_MBVD_BASE_NUM);
+  int nWidth = pu.lumaSize().width;
+  int nHeight = pu.lumaSize().height;
+  if (!xAMLIBCGetCurBlkTemplate(pu, nWidth, nHeight))
+  {
+    return;
+  }
+#endif
   const int tempNum = (const int) (std::min<int>(IBC_MBVD_BASE_NUM, mrgCtx.numValidMergeCand) * IBC_MBVD_MAX_REFINE_NUM);
   const int groupSize = std::min<int>(tempNum, ADAPTIVE_SUB_GROUP_SIZE_IBC_MBVD);
 
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  memset(mbvdCandCostList,    -1,         sizeof(uint64_t) * IBC_MBVD_ENC_NUM);
+  memset(mbvdTestedCandsList, false,      sizeof(bool)     * IBC_MBVD_NUM);
+  int startMMVDIdx = 0;
+  int endMMVDIdx = tempNum;
+  if(ibcMbvdIdx!= -1)
+  {
+    uint32_t gpId = ibcMbvdIdx / IBC_MBVD_SIZE_ENC;
+    startMMVDIdx = gpId * groupSize;
+    endMMVDIdx = (gpId+1) * groupSize;
+  }
+  int startBvpIdx = startMMVDIdx / groupSize;
+  int endBvpIdx = endMMVDIdx / groupSize;
+  memset(ibcMbvdLUT,     -1, sizeof(uint32_t)     * IBC_MBVD_ENC_NUM);
+#else
   Distortion candCostList[IBC_MBVD_BASE_NUM* IBC_MBVD_MAX_REFINE_NUM];
 
   for (uint32_t i = 0; i < tempNum; i++)
@@ -6616,9 +6684,11 @@ void  InterPrediction::sortIbcMergeMbvdCandidates(PredictionUnit &pu, MergeCtx&
     ibcMbvdLUT[i] = i;
     candCostList[i] = MAX_UINT;
   }
+#endif
   Distortion uiCost;
   DistParam cDistParam;
   cDistParam.applyWeight = false;
+#if !JVET_AC0159_IBC_MBVD_LIST_DERIVATION
   int nWidth = pu.lumaSize().width;
   int nHeight = pu.lumaSize().height;
   if (!xAMLIBCGetCurBlkTemplate(pu, nWidth, nHeight))
@@ -6637,29 +6707,176 @@ void  InterPrediction::sortIbcMergeMbvdCandidates(PredictionUnit &pu, MergeCtx&
 
   int encGrpSize = IBC_MBVD_SIZE_ENC;
   int baseIdx = 0;
+#endif
   const int cuPelX = pu.Y().x;
   const int cuPelY = pu.Y().y;
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  int zzBvHorOffset[IBC_MBVD_BASE_NUM], zzBvVerOffset[IBC_MBVD_BASE_NUM];
+  for (int zzBvpIdx = startBvpIdx; zzBvpIdx < endBvpIdx; zzBvpIdx++)
+  {
+#if JVET_AA0070_RRIBC
+    zzBvHorOffset[zzBvpIdx] = 0;
+    zzBvVerOffset[zzBvpIdx] = 0;
+    int startBvdIdx = zzBvpIdx * groupSize;
+    if (mrgCtx.setIbcMbvdMergeCandiInfo(pu, startBvdIdx, startBvdIdx) == true)
+    {
+      bool zzMbvdCandMisAlign = mrgCtx.setIbcMbvdMergeCandiInfo(pu, startBvdIdx + 2, startBvdIdx + 2);
+      CHECK(zzMbvdCandMisAlign == true, "this is not possible");
+    }
+    if (m_bAMLTemplateAvailabe[0] == true && m_bAMLTemplateAvailabe[1] == true)
+    {
+      if (pu.cu->rribcFlipType == 0)
+      {
+        zzBvHorOffset[zzBvpIdx] -= AML_MERGE_TEMPLATE_SIZE;
+        zzBvVerOffset[zzBvpIdx] -= AML_MERGE_TEMPLATE_SIZE;
+      }
+      else if (pu.cu->rribcFlipType == 1)
+      {
+        zzBvVerOffset[zzBvpIdx] -= AML_MERGE_TEMPLATE_SIZE;
+      }
+      else
+      {
+        zzBvHorOffset[zzBvpIdx] -= AML_MERGE_TEMPLATE_SIZE;
+      }
+    }
+    else if (m_bAMLTemplateAvailabe[0] == true)
+    {
+      if (pu.cu->rribcFlipType != 2)
+      {
+        zzBvVerOffset[zzBvpIdx] -= AML_MERGE_TEMPLATE_SIZE;
+      }
+    }
+    else
+    {
+      if (pu.cu->rribcFlipType != 1)
+      {
+        zzBvHorOffset[zzBvpIdx] -= AML_MERGE_TEMPLATE_SIZE;
+      }
+    }
+#else
+    zzBvHorOffset[zzBvpIdx] -= AML_MERGE_TEMPLATE_SIZE;
+    zzBvVerOffset[zzBvpIdx] -= AML_MERGE_TEMPLATE_SIZE;
+#endif
+  }
+  const int roiWidth = pu.lwidth()   + ((m_bAMLTemplateAvailabe[1] == true) ? AML_MERGE_TEMPLATE_SIZE : 0);
+  const int roiHeight = pu.lheight() + ((m_bAMLTemplateAvailabe[0] == true) ? AML_MERGE_TEMPLATE_SIZE : 0);
+#else
   int roiWidth = pu.lwidth();
   int roiHeight = pu.lheight();
+#endif
   const int picWidth = pu.cs->slice->getPPS()->getPicWidthInLumaSamples();
   const int picHeight = pu.cs->slice->getPPS()->getPicHeightInLumaSamples();
   const unsigned int  lcuWidth = pu.cs->slice->getSPS()->getMaxCUWidth();
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  // 32 Pel-> 16 Pel -> 8 Pel -> 4 Pel -> 2 Pel -> 1 Pel
+  for (int bvdSearchLoopIdx = JVET_AC0159_CFG_START_N_PEL; bvdSearchLoopIdx >= 0; bvdSearchLoopIdx--)
+  {
+    // buildup search candidate list
+    int curInterval = (1 << bvdSearchLoopIdx);
+    int curIntervalShift = curInterval * IBC_MBVD_OFFSET_DIR;
+    int totalNumberBvdCandToSearch = 0;
+    int bvdSearchCandListIdx = 0;
+    for (int zzBvpIdx = startBvpIdx; zzBvpIdx < endBvpIdx; zzBvpIdx++)
+    {
+      int startBvdIdx = zzBvpIdx * groupSize;
+      int startBvdEncIdx = zzBvpIdx * IBC_MBVD_SIZE_ENC;
+      // this is early terminate
+      if (mbvdCandCostList[startBvdEncIdx + IBC_MBVD_SIZE_ENC - 1] < 1)
+      {
+        continue;
+      }
+      int endBvdIdx = startBvdIdx + groupSize;
+      // build up search candidate list
+      if (mbvdCandCostList[startBvdEncIdx + IBC_MBVD_SIZE_ENC - 1] == MAX_UINT64)
+      {
+        std::memcpy(mbvdSearchCandsList + bvdSearchCandListIdx,
+            g_ibcMbvdSearchStartPelNCandsList[bvdSearchLoopIdx] + zzBvpIdx * g_ibcMbvdSearchStartPelNCandsNumber[bvdSearchLoopIdx],
+            sizeof(int) * g_ibcMbvdSearchStartPelNCandsNumber[bvdSearchLoopIdx]);
+        totalNumberBvdCandToSearch += g_ibcMbvdSearchStartPelNCandsNumber[bvdSearchLoopIdx];
+        bvdSearchCandListIdx += g_ibcMbvdSearchStartPelNCandsNumber[bvdSearchLoopIdx];
+      }
+      else  // the rest of the steps
+      {
+        int nrNeighbourToTest = 2;
+        totalNumberBvdCandToSearch += ibcMbvdValidNum[zzBvpIdx] * nrNeighbourToTest;  // todo ??? how many neighbour want to test ??
+        for (int zzBestMvdIdx = 0; zzBestMvdIdx < ibcMbvdValidNum[zzBvpIdx]; zzBestMvdIdx++)
+        {
+          int tmpBestMvd = ibcMbvdLUT[startBvdEncIdx + zzBestMvdIdx];
+          // maybe need to add more for test ?
+          if (tmpBestMvd - curIntervalShift >= startBvdIdx && mbvdTestedCandsList[tmpBestMvd - curIntervalShift] == false)
+          {
+            *(mbvdSearchCandsList + bvdSearchCandListIdx) = tmpBestMvd - curIntervalShift;
+            bvdSearchCandListIdx++;
+            mbvdTestedCandsList[tmpBestMvd - curIntervalShift] = true;
+          }
+          else
+          {
+            totalNumberBvdCandToSearch--;
+          }
+          if (tmpBestMvd + curIntervalShift < endBvdIdx && mbvdTestedCandsList[tmpBestMvd + curIntervalShift] == false)
+          {
+            *(mbvdSearchCandsList + bvdSearchCandListIdx) = tmpBestMvd + curIntervalShift;
+            bvdSearchCandListIdx++;
+            mbvdTestedCandsList[tmpBestMvd + curIntervalShift] = true;
+          }
+          else
+          {
+            totalNumberBvdCandToSearch--;
+          }
+        }
+      }
+    }
+  for (int bvdSearchCandIdx = 0; bvdSearchCandIdx < totalNumberBvdCandToSearch; bvdSearchCandIdx++)
+  {
+    int mmvdMergeCand = mbvdSearchCandsList[bvdSearchCandIdx];
+    uint32_t gpIdx = mmvdMergeCand/groupSize;
+    uint32_t endEncIdx = (gpIdx + 1) * IBC_MBVD_SIZE_ENC;
+    mbvdTestedCandsList[mmvdMergeCand] = true;
+    if (mbvdCandCostList[endEncIdx - 1] < 1)
+    {
+      continue;
+    }
+#else
   for (int mmvdMergeCand = startMMVDIdx; mmvdMergeCand < endMMVDIdx; mmvdMergeCand++)
   {
+#endif
     bool mbvdCandMisAlign = mrgCtx.setIbcMbvdMergeCandiInfo(pu, mmvdMergeCand, mmvdMergeCand);
     if (mbvdCandMisAlign)
     {
       continue;
     }
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+    int xPred = pu.bv.getHor() + zzBvHorOffset[gpIdx];
+    int yPred = pu.bv.getVer() + zzBvVerOffset[gpIdx];
+#else
     int xPred = pu.bv.getHor();
     int yPred = pu.bv.getVer();
+#endif
 
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+    if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth,pu.cu->rribcFlipType)) // not valid bv derived
+#else
     if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth)) // not valid bv derived
+#endif
+    {
+      continue;
+    }
+#if IBC_OVERLAP
+    xPred = pu.bv.getHor();
+    yPred = pu.bv.getVer();
+#if JVET_AA0070_RRIBC
+    if (!PU::searchBv(pu, cuPelX, cuPelY, pu.lwidth(), pu.lheight(), picWidth, picHeight, xPred, yPred, lcuWidth,pu.cu->rribcFlipType)) // not valid bv derived
+#else
+    if (!PU::searchBv(pu, cuPelX, cuPelY, pu.lwidth(), pu.lheight(), picWidth, picHeight, xPred, yPred, lcuWidth)) // not valid bv derived
+#endif
     {
       continue;
     }
+#endif
+#if !JVET_AC0159_IBC_MBVD_LIST_DERIVATION
     baseIdx = mmvdMergeCand / IBC_MBVD_MAX_REFINE_NUM;
     ibcMbvdValidNum[baseIdx]++;
+#endif
     uiCost = 0;
 
     PelUnitBuf pcBufPredRefTop = (PelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvRefAMLTemplate[0][0], nWidth, AML_MERGE_TEMPLATE_SIZE)));
@@ -6667,7 +6884,11 @@ void  InterPrediction::sortIbcMergeMbvdCandidates(PredictionUnit &pu, MergeCtx&
     PelUnitBuf pcBufPredRefLeft = (PelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvRefAMLTemplate[1][0], AML_MERGE_TEMPLATE_SIZE, nHeight)));
     PelUnitBuf pcBufPredCurLeft = (PelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvCurAMLTemplate[1][0], AML_MERGE_TEMPLATE_SIZE, nHeight)));
 
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+    getIBCAMLRefTemplate(pu, nWidth, nHeight, false/*doIbcLic*/, false/*checkTmlBvValidaion*/);
+#else
     getIBCAMLRefTemplate(pu, nWidth, nHeight);
+#endif
 
     if (m_bAMLTemplateAvailabe[0])
     {
@@ -6676,18 +6897,39 @@ void  InterPrediction::sortIbcMergeMbvdCandidates(PredictionUnit &pu, MergeCtx&
       uiCost += cDistParam.distFunc(cDistParam);
     }
 
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+    if (uiCost < mbvdCandCostList[endEncIdx - 1] && m_bAMLTemplateAvailabe[1])
+#else
     if (m_bAMLTemplateAvailabe[1])
+#endif
     {
       m_pcRdCost->setDistParam(cDistParam, pcBufPredCurLeft.Y(), pcBufPredRefLeft.Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, false);
 
       uiCost += cDistParam.distFunc(cDistParam);
     }
+#if IBC_OVERLAP
+#if JVET_AA0070_RRIBC
+    if (pu.cu->rribcFlipType == 0)
+#endif
+    {
+      int xBv = pu.bv.hor;
+      int yBv = pu.bv.ver;
+      if (((xBv + nWidth) >= 1) && ((yBv + nHeight) >= 1))
+      {
+        uiCost = (uint64_t)(uiCost * IBC_OVERLAP_TM_COST_FACTOR + (uiCost >> 1));
+      }
+    }
+#endif
     // update part
     uint32_t i;
     uint32_t shift = 0;
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+    while (shift < IBC_MBVD_SIZE_ENC && uiCost < mbvdCandCostList[endEncIdx - 1 - shift])
+#else
     uint32_t gpIdx = mmvdMergeCand/groupSize;
     uint32_t endIdx = gpIdx * groupSize + encGrpSize;
     while (shift < encGrpSize && uiCost < candCostList[endIdx - 1 - shift])
+#endif
     {
       shift++;
     }
@@ -6695,13 +6937,36 @@ void  InterPrediction::sortIbcMergeMbvdCandidates(PredictionUnit &pu, MergeCtx&
     {
       for (i = 1; i < shift; i++)
       {
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+        ibcMbvdLUT[endEncIdx - i] = ibcMbvdLUT[endEncIdx - 1 - i];
+        mbvdCandCostList[endEncIdx - i] = mbvdCandCostList[endEncIdx - 1 - i];
+#else
         ibcMbvdLUT[endIdx - i] = ibcMbvdLUT[endIdx - 1 - i];
         candCostList[endIdx - i] = candCostList[endIdx - 1 - i];
+#endif
       }
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+      ibcMbvdLUT[endEncIdx - shift] = mmvdMergeCand;
+      mbvdCandCostList[endEncIdx - shift] = uiCost;
+#else
       ibcMbvdLUT[endIdx - shift] = mmvdMergeCand;
       candCostList[endIdx - shift] = uiCost;
+#endif
+    }
+  }
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+    for (int zzBackLoopBvpIdx = startBvpIdx; zzBackLoopBvpIdx < endBvpIdx; zzBackLoopBvpIdx++)
+    {
+      int startBackLoopBvdIdx = zzBackLoopBvpIdx * IBC_MBVD_SIZE_ENC;
+      int zzBackLoopIdx = IBC_MBVD_SIZE_ENC - 1;
+      while (mbvdCandCostList[startBackLoopBvdIdx + zzBackLoopIdx] == MAX_UINT64 && zzBackLoopIdx >= 0)
+      {
+        zzBackLoopIdx--;
+      }
+      ibcMbvdValidNum[zzBackLoopBvpIdx] = zzBackLoopIdx + 1;
     }
   }
+#endif
 }
 #endif
 
@@ -6754,7 +7019,11 @@ bool InterPrediction::xAMLIBCGetCurBlkTemplate(PredictionUnit& pu, int nCurBlkWi
 }
 
 #if JVET_AC0112_IBC_LIC
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+void InterPrediction::getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth, int nCurBlkHeight, bool doIbcLic, bool checkTmlBvValidaion)
+#else
 void InterPrediction::getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth, int nCurBlkHeight, bool doIbcLic)
+#endif
 #else
 void InterPrediction::getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth, int nCurBlkHeight)
 #endif
@@ -6792,11 +7061,24 @@ void InterPrediction::getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth,
     MotionInfo miTop;
     miTop.mv[0] = Mv(mvTop.hor <<horShift , mvTop.ver<< verShift);
     miTop.refIdx[0] = MAX_NUM_REF;
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+    miTop.rribcFlipType = pu.cu->rribcFlipType;
+#endif
     Mv mvTop2(0, -1);
     mvTop2 += mvTop;
     MotionInfo miTop2;
     miTop2.mv[0] = Mv(mvTop2.hor <<horShift , mvTop2.ver<< verShift);
     miTop2.refIdx[0] = MAX_NUM_REF;
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+    miTop2.rribcFlipType = pu.cu->rribcFlipType;
+#endif
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+    if (checkTmlBvValidaion == false)
+    {
+      // do nothing
+    }
+    else
+#endif
 #if JVET_AA0070_RRIBC
     if (pu.cu->rribcFlipType == 2)
     {
@@ -6844,11 +7126,24 @@ void InterPrediction::getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth,
     MotionInfo miLeft;
     miLeft.mv[0] = Mv(mvLeft.hor <<horShift , mvLeft.ver<< verShift);
     miLeft.refIdx[0] = MAX_NUM_REF;
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+    miLeft.rribcFlipType = pu.cu->rribcFlipType;
+#endif
     Mv mvLeft2(-1, 0);
     mvLeft2 += mvLeft;
     MotionInfo miLeft2;
     miLeft2.mv[0] = Mv(mvLeft2.hor <<horShift , mvLeft2.ver<< verShift);
     miLeft2.refIdx[0] = MAX_NUM_REF;
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+    miLeft2.rribcFlipType = pu.cu->rribcFlipType;
+#endif
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+    if (checkTmlBvValidaion == false)
+    {
+      // do nothing
+    }
+    else
+#endif
 #if JVET_AA0070_RRIBC
     if (pu.cu->rribcFlipType == 1)
     {
@@ -7022,6 +7317,9 @@ void InterPrediction::getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth,
     MotionInfo miTop;
     miTop.mv[0] = Mv(mvTop.hor <<horShift , mvTop.ver<< verShift);
     miTop.refIdx[0] = MAX_NUM_REF;
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+    miTop.rribcFlipType = pu.cu->rribcFlipType;
+#endif
 #if JVET_AA0070_RRIBC
     if (pu.cu->rribcFlipType == 2)
     {
@@ -7079,6 +7377,9 @@ void InterPrediction::getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth,
     MotionInfo miLeft;
     miLeft.mv[0] = Mv(mvLeft.hor <<horShift , mvLeft.ver<< verShift);
     miLeft.refIdx[0] = MAX_NUM_REF;
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+    miLeft.rribcFlipType = pu.cu->rribcFlipType;
+#endif
 #if JVET_AA0070_RRIBC
     if (pu.cu->rribcFlipType == 1)
     {
@@ -10460,6 +10761,19 @@ void  InterPrediction::adjustIBCMergeCandidates(PredictionUnit &pu, MergeCtx& mr
 
       uiCost += cDistParam.distFunc(cDistParam);
     }
+#if IBC_OVERLAP
+#if JVET_AA0070_RRIBC
+    if (pu.cu->rribcFlipType == 0)
+#endif
+    {
+      int xBv = pu.bv.hor;
+      int yBv = pu.bv.ver;
+      if (((xBv + nWidth) >= 1) && ((yBv + nHeight) >= 1))
+      {
+        uiCost = (uint64_t)(uiCost * IBC_OVERLAP_TM_COST_FACTOR + (uiCost >> 1));
+      }
+    }
+#endif
     updateCandList(uiMergeCand, uiCost, ADAPTIVE_IBC_SUB_GROUP_SIZE, rdCandList[uiMergeCand / ADAPTIVE_IBC_SUB_GROUP_SIZE], candCostList[uiMergeCand / ADAPTIVE_IBC_SUB_GROUP_SIZE]);
   }
 
@@ -10621,6 +10935,19 @@ void  InterPrediction::adjustIBCMergeCandidates(PredictionUnit &pu, MergeCtx& mr
       uiCost += cDistParam.distFunc(cDistParam);
     }
 
+#if IBC_OVERLAP
+#if JVET_AA0070_RRIBC
+    if (pu.cu->rribcFlipType == 0)
+#endif
+    {
+      int xBv = pu.bv.hor;
+      int yBv = pu.bv.ver;
+      if (((xBv + nWidth) >= 1) && ((yBv + nHeight) >= 1))
+      {
+        uiCost = (uint64_t)(uiCost * IBC_OVERLAP_TM_COST_FACTOR + (uiCost >> 1));
+      }
+    }
+#endif
     updateCandList(uiMergeCand, uiCost, IBC_MRG_MAX_NUM_CANDS_MEM, rdCandList, candCostList);
   }
 
@@ -11752,6 +12079,30 @@ void InterPrediction::xIntraBlockCopy(PredictionUnit &pu, PelUnitBuf &predBuf, c
 #endif    
 #endif
   }
+#if IBC_OVERLAP
+#if JVET_AA0070_RRIBC
+  if (pu.cu->rribcFlipType == 0)
+#endif
+  {
+    int xPred = (pu.bv.hor >> shiftSampleHor);
+    int yPred = (pu.bv.ver >> shiftSampleVer);
+    int width = pu.blocks[compID].width;
+    int height = pu.blocks[compID].height;
+    if(((xPred+width)>=1)&&((yPred+height)>=1))
+    {
+      PelBuf & dstBuf = predBuf.bufs[compID];
+      //pad the unavailable samples
+      Pel* piPredTmp = dstBuf.buf;
+      for (unsigned y = abs(yPred); y < pu.blocks[compID].height; y++)
+      {
+        for (unsigned x = abs(xPred); x < pu.blocks[compID].width; x++)
+        {
+          piPredTmp[dstBuf.stride*y+x] = piPredTmp[dstBuf.stride*(y+yPred)+(x+xPred)];
+        }
+      }
+    }
+  }
+#endif
 }
 
 void InterPrediction::resetIBCBuffer(const ChromaFormat chromaFormatIDC, const int ctuSize)
@@ -11838,7 +12189,11 @@ void InterPrediction::resetVPDUforIBC(const ChromaFormat chromaFormatIDC, const
 #endif
 }
 
+#if IBC_OVERLAP
+bool InterPrediction::isLumaBvValid(const int ctuSize, const int xCb, const int yCb, const int width, const int height, const int xBv, const int yBv, int rribcFlipType)
+#else
 bool InterPrediction::isLumaBvValid(const int ctuSize, const int xCb, const int yCb, const int width, const int height, const int xBv, const int yBv)
+#endif
 {
 #if JVET_Z0153_IBC_EXT_REF
   int refTLx = xCb + xBv;
@@ -11858,6 +12213,10 @@ bool InterPrediction::isLumaBvValid(const int ctuSize, const int xCb, const int
   PelBuf buf = m_ibcBuffer.Y();
 #endif
 
+#if IBC_OVERLAP
+  if (rribcFlipType)
+  {
+#endif
   for(int x = 0; x < width; x += 4)
   {
     for(int y = 0; y < height; y += 4)
@@ -11887,6 +12246,20 @@ bool InterPrediction::isLumaBvValid(const int ctuSize, const int xCb, const int
 #endif
     }
   }
+#if IBC_OVERLAP
+  }
+  else
+  {
+#if JVET_Z0153_IBC_EXT_REF
+    if(buf.at((refTLx) % m_ibcBufferWidth, (refTLy) % m_ibcBufferHeight) == -1)
+    {
+      return false;
+    }
+#else
+    if(buf.at((refTLx) & (m_ibcBufferWidth - 1), refTLy) == -1) return false;
+#endif
+  }
+#endif
 
   return true;
 }
@@ -12441,6 +12814,9 @@ void InterPrediction::xGetSublkTemplate(const CodingUnit& cu,
     MotionInfo miTop;
     miTop.mv[0] = Mv(mvTop.hor << lumaShift, mvTop.ver << lumaShift);
     miTop.refIdx[0] = MAX_NUM_REF;
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+    miTop.rribcFlipType = cu.rribcFlipType;
+#endif
     bool refBvValid = false;
     if (PU::checkIsIBCCandidateValid(*cu.firstPU, miTop, true, true))
     {
@@ -12474,6 +12850,9 @@ void InterPrediction::xGetSublkTemplate(const CodingUnit& cu,
     MotionInfo miLeft;
     miLeft.mv[0] = Mv(mvLeft.hor << lumaShift, mvLeft.ver << lumaShift);
     miLeft.refIdx[0] = MAX_NUM_REF;
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+    miLeft.rribcFlipType = cu.rribcFlipType;
+#endif
     bool refBvValid = false;
     if (PU::checkIsIBCCandidateValid(*cu.firstPU, miLeft, true, false))
     {
@@ -13357,6 +13736,26 @@ void TplMatchingCtrl::xRefineMvSearch(int maxSearchRounds, int searchStepShift)
       }
 
       cost = xGetTempMatchError<tplSize>(mvCand);
+#if JVET_Z0084_IBC_TM && IBC_OVERLAP
+      if (CU::isIBC(m_cu))
+      {
+#if JVET_AA0070_RRIBC
+        if (m_cu.rribcFlipType == 0)
+#endif
+        {
+          Mv tempBv = mvCand;
+          tempBv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT);
+          int xBv = tempBv.getHor();
+          int yBv = tempBv.getVer();
+          int nWidth = m_pu.lwidth();
+          int nHeight = m_pu.lheight();
+          if (((xBv + nWidth) >= 1) && ((yBv + nHeight) >= 1))
+          {
+            cost = (uint64_t)(cost * IBC_OVERLAP_TM_COST_FACTOR + (cost >> 1));
+          }
+        }
+      }
+#endif
 #if MULTI_PASS_DMVR
       costArray[nDirect] = cost;
 #endif
@@ -19290,7 +19689,11 @@ void InterPrediction::deriveMVDcandAffine(const PredictionUnit& pu, RefPicList e
 
       if (doBoundaryCheck)
       {
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+        res = PU::searchBv(pu, pu.lumaPos().x, pu.lumaPos().y, pu.lwidth(), pu.lheight(), picWidth, picHeight, xPred, yPred, lcuWidth,pu.cu->rribcFlipType);
+#else
         res = PU::searchBv(pu, pu.lumaPos().x, pu.lumaPos().y, pu.lwidth(), pu.lheight(), picWidth, picHeight, xPred, yPred, lcuWidth);
+#endif
       }
       bool& useTop = tplCtrl.getCurTopRefAvailFlag();
       bool& useLeft = tplCtrl.getCurLeftRefAvailFlag();
@@ -19298,6 +19701,22 @@ void InterPrediction::deriveMVDcandAffine(const PredictionUnit& pu, RefPicList e
       if (res && doBoundaryCheck)
       {
 #if JVET_AA0070_RRIBC
+#if IBC_OVERLAP
+        if (1 == pu.cu->rribcFlipType)
+        {
+          useTop = PU::searchBv(pu, pu.lumaPos().x, pu.lumaPos().y, pu.lwidth(), 1, picWidth, picHeight, xPred, yPred, lcuWidth,pu.cu->rribcFlipType);
+          xPred += pu.lwidth(); //at least, template size of 1 should be available
+          useLeft = PU::searchBv(pu, pu.lumaPos().x, pu.lumaPos().y, 1, pu.lheight(), picWidth, picHeight, xPred, yPred, lcuWidth,pu.cu->rribcFlipType);
+        }
+        else
+        {
+          if( 2 == pu.cu->rribcFlipType )
+          {
+            useLeft = PU::searchBv( pu, pu.lumaPos().x, pu.lumaPos().y, 1, pu.lheight(), picWidth, picHeight, xPred, yPred, lcuWidth,pu.cu->rribcFlipType);
+            yPred += pu.lheight(); //at least, template size of 1 should be available
+            useTop = PU::searchBv( pu, pu.lumaPos().x, pu.lumaPos().y, pu.lwidth(), 1, picWidth, picHeight, xPred, yPred, lcuWidth,pu.cu->rribcFlipType);
+          }
+#else
         if (1 == pu.cu->rribcFlipType)
         {
           useTop = PU::searchBv(pu, pu.lumaPos().x, pu.lumaPos().y, pu.lwidth(), 1, picWidth, picHeight, xPred, yPred, lcuWidth);
@@ -19312,6 +19731,7 @@ void InterPrediction::deriveMVDcandAffine(const PredictionUnit& pu, RefPicList e
             yPred += pu.lheight(); //at least, template size of 1 should be available
             useTop = PU::searchBv(pu, pu.lumaPos().x, pu.lumaPos().y, pu.lwidth(), 1, picWidth, picHeight, xPred, yPred, lcuWidth);
           }
+#endif
           else
           {
             useLeft = PU::searchBv(pu, pu.lumaPos().x, pu.lumaPos().y, 1, pu.lheight(), picWidth, picHeight, xPred - 1, yPred, lcuWidth);
@@ -19338,6 +19758,21 @@ void InterPrediction::deriveMVDcandAffine(const PredictionUnit& pu, RefPicList e
         CHECK(!(res && (useTop || useLeft)), "candidate is invalid, but check is skipped");
       }
 
+#if IBC_OVERLAP
+#if JVET_AA0070_RRIBC
+      if (pu.cu->rribcFlipType == 0)
+#endif
+      {
+        int xBv = xPred;
+        int yBv = yPred;
+        int nWidth = pu.lumaSize().width;
+        int nHeight = pu.lumaSize().height;
+        if (((xBv + nWidth) >= 1) && ((yBv + nHeight) >= 1))
+        {
+          uiCost = (uint64_t)(uiCost + (uiCost >> 1));
+        }
+      }
+#endif
       aMvCostVec[n] = { cMvdTest, uiCost };
 
       return res && useTop && useLeft;
diff --git a/source/Lib/CommonLib/InterPrediction.h b/source/Lib/CommonLib/InterPrediction.h
index a97382d2..6caa5fe3 100644
--- a/source/Lib/CommonLib/InterPrediction.h
+++ b/source/Lib/CommonLib/InterPrediction.h
@@ -402,6 +402,11 @@ protected:
   Pel    (*m_tplColWeightTbl)[GEO_MAX_CU_SIZE * GEO_MODE_SEL_TM_SIZE];
 #endif
 
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  Distortion*   mbvdCandCostList;
+  int*          mbvdSearchCandsList;
+  bool*         mbvdTestedCandsList;
+#endif
 #if JVET_J0090_MEMORY_BANDWITH_MEASURE
   CacheModel      *m_cacheModel;
 #endif
@@ -566,7 +571,11 @@ public:
 #if JVET_AA0061_IBC_MBVD || (JVET_W0090_ARMC_TM && JVET_Y0058_IBC_LIST_MODIFY)
   bool xAMLIBCGetCurBlkTemplate(PredictionUnit& pu, int nCurBlkWidth, int nCurBlkHeight);
 #if JVET_AC0112_IBC_LIC
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  void getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth, int nCurBlkHeight, bool doIbcLic = false, bool checkTmlBvValidaion = true);
+#else
   void getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth, int nCurBlkHeight, bool doIbcLic = false);
+#endif
 #else
   void getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth, int nCurBlkHeight);
 #endif
@@ -932,7 +941,11 @@ public:
   void resetIBCBuffer(const ChromaFormat chromaFormatIDC, const int ctuSize);
   void resetVPDUforIBC(const ChromaFormat chromaFormatIDC, const int ctuSize, const int vSize, const int xPos, const int yPos);
 
+#if IBC_OVERLAP
+  bool isLumaBvValid(const int ctuSize, const int xCb, const int yCb, const int width, const int height, const int xBv, const int yBv,int rribcFlipType = 0);
+#else
   bool isLumaBvValid(const int ctuSize, const int xCb, const int yCb, const int width, const int height, const int xBv, const int yBv);
+#endif
 
   bool xPredInterBlkRPR( const std::pair<int, int>& scalingRatio, const PPS& pps, const CompArea &blk, const Picture* refPic, const Mv& mv, Pel* dst, const int dstStride, const bool bi, const bool wrapRef, const ClpRng& clpRng, const int filterIndex, const bool useAltHpelIf = false);
 #if JVET_Z0118_GDR
diff --git a/source/Lib/CommonLib/Rom.cpp b/source/Lib/CommonLib/Rom.cpp
index 0cc1b2a5..d450d6a3 100644
--- a/source/Lib/CommonLib/Rom.cpp
+++ b/source/Lib/CommonLib/Rom.cpp
@@ -4707,6 +4707,45 @@ void initROM()
     g_rmvfMultApproxTbl[k] = ((1 << 15) + (k >> 1)) / k;
   }
 #endif
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  int searchCandIdx[JVET_AC0159_CFG_START_N_PEL + 1] = { 0, };
+  for (int bvpIdx = 0; bvpIdx < IBC_MBVD_BASE_NUM; bvpIdx++)
+  {
+    int startBvdIdx = bvpIdx * IBC_MBVD_MAX_REFINE_NUM;
+    int endBvdIdx = (bvpIdx + 1) * IBC_MBVD_MAX_REFINE_NUM;
+    int curInterval = (1 << JVET_AC0159_CFG_START_N_PEL);
+    int incInterval = curInterval * IBC_MBVD_OFFSET_DIR;
+    int startStepOffset = (curInterval - 1) * IBC_MBVD_OFFSET_DIR;
+    for (int zzBvdIdx = startBvdIdx + startStepOffset; zzBvdIdx < endBvdIdx; zzBvdIdx += incInterval)
+    {
+      for (int zzDir = 0; zzDir < IBC_MBVD_OFFSET_DIR; zzDir++)
+      {
+        g_ibcMbvdSearchStartPelNCandsList[JVET_AC0159_CFG_START_N_PEL][searchCandIdx[JVET_AC0159_CFG_START_N_PEL]] = zzBvdIdx + zzDir;
+        searchCandIdx[JVET_AC0159_CFG_START_N_PEL]++;
+      }
+    }
+    int startPelN = JVET_AC0159_CFG_START_N_PEL - 1;
+    while (startPelN >= 0)
+    {
+      curInterval >>= 1;
+      startStepOffset = (curInterval - 1) * IBC_MBVD_OFFSET_DIR;
+      incInterval = (curInterval << 1) * IBC_MBVD_OFFSET_DIR;
+      for (int zzBvdIdx = startBvdIdx + startStepOffset; zzBvdIdx < endBvdIdx; zzBvdIdx += incInterval)
+      {
+        for (int zzDir = 0; zzDir < IBC_MBVD_OFFSET_DIR; zzDir++)
+        {
+          g_ibcMbvdSearchStartPelNCandsList[startPelN][searchCandIdx[startPelN]] = zzBvdIdx + zzDir;
+          searchCandIdx[startPelN]++;
+        }
+      }
+      startPelN--;
+    }
+  }
+  for (int zz = 0; zz < IBC_MBVD_STEP_NUM; zz++)
+  {
+    g_ibcMbvdCands[zz] = ((zz + 1) << MV_FRACTIONAL_BITS_INTERNAL);
+  }
+#endif
 }
 
 void destroyROM()
@@ -4871,6 +4910,25 @@ const uint8_t g_chroma422IntraAngleMappingTable[NUM_INTRA_MODE] =
 { 0, 1, 61, 62, 63, 64, 65, 66, 2, 3,  5,  6,  8, 10, 12, 13, 14, 16, 18, 20, 22, 23, 24, 26, 28, 30, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 41, 42, 43, 43, 44, 44, 45, 45, 46, 47, 48, 48, 49, 49, 50, 51, 51, 52, 52, 53, 54, 55, 55, 56, 56, 57, 57, 58, 59, 59, 60, DM_CHROMA_IDX };
 
 
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+int g_ibcMbvdCands[IBC_MBVD_STEP_NUM];
+int g_ibcMbvdSearchStartPelNCandsList[JVET_AC0159_CFG_START_N_PEL + 1][(IBC_MBVD_MAX_REFINE_NUM >> 1) * IBC_MBVD_BASE_NUM];
+const int g_ibcMbvdSearchStartPelNCandsNumber[JVET_AC0159_CFG_START_N_PEL + 1] = {
+#if JVET_AC0159_CFG_START_N_PEL == 5
+    (IBC_MBVD_MAX_REFINE_NUM >> 1), (IBC_MBVD_MAX_REFINE_NUM >> 2), (IBC_MBVD_MAX_REFINE_NUM >> 3), (IBC_MBVD_MAX_REFINE_NUM >> 4), (IBC_MBVD_MAX_REFINE_NUM >> 5), (IBC_MBVD_MAX_REFINE_NUM >> 5)
+#elif JVET_AC0159_CFG_START_N_PEL == 4
+    (IBC_MBVD_MAX_REFINE_NUM >> 1), (IBC_MBVD_MAX_REFINE_NUM >> 2), (IBC_MBVD_MAX_REFINE_NUM >> 3), (IBC_MBVD_MAX_REFINE_NUM >> 4), (IBC_MBVD_MAX_REFINE_NUM >> 4)
+#elif JVET_AC0159_CFG_START_N_PEL == 3
+    (IBC_MBVD_MAX_REFINE_NUM >> 1), (IBC_MBVD_MAX_REFINE_NUM >> 2), (IBC_MBVD_MAX_REFINE_NUM >> 3), (IBC_MBVD_MAX_REFINE_NUM >> 3)
+#elif JVET_AC0159_CFG_START_N_PEL == 2
+    (IBC_MBVD_MAX_REFINE_NUM >> 1), (IBC_MBVD_MAX_REFINE_NUM >> 2), (IBC_MBVD_MAX_REFINE_NUM >> 2)
+#elif JVET_AC0159_CFG_START_N_PEL == 1
+    (IBC_MBVD_MAX_REFINE_NUM >> 1), (IBC_MBVD_MAX_REFINE_NUM >> 1)
+#else
+    IBC_MBVD_MAX_REFINE_NUM
+#endif
+};
+#endif
 
 // ====================================================================================================================
 // Misc.
diff --git a/source/Lib/CommonLib/Rom.h b/source/Lib/CommonLib/Rom.h
index f8b89ec5..2d929564 100644
--- a/source/Lib/CommonLib/Rom.h
+++ b/source/Lib/CommonLib/Rom.h
@@ -416,5 +416,10 @@ extern const int8_t g_ibcGpmFirstSetSplitDirToIdx[GEO_NUM_PARTITION_MODE];
 extern const int8_t g_ibcGpmFirstSetSplitDir[IBC_GPM_MAX_SPLIT_DIR_FIRST_SET_NUM];
 extern const int8_t g_ibcGpmSecondSetSplitDir[GEO_NUM_PARTITION_MODE];
 #endif
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+extern int g_ibcMbvdCands[IBC_MBVD_STEP_NUM];
+extern int g_ibcMbvdSearchStartPelNCandsList[JVET_AC0159_CFG_START_N_PEL + 1][(IBC_MBVD_MAX_REFINE_NUM >> 1) * IBC_MBVD_BASE_NUM];
+extern const int g_ibcMbvdSearchStartPelNCandsNumber[JVET_AC0159_CFG_START_N_PEL + 1];
+#endif
 #endif  //__TCOMROM__
 
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 6a53b54c..f812c0c5 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -50,6 +50,56 @@
 #include <assert.h>
 #include <cassert>
 
+#define ANCHOR_FIX_MR_380                                 0
+
+#define EE2_TEST_3_2_A_CFG_1                              1
+#define EE2_TEST_3_2_A_CFG_2                              0
+#define EE2_TEST_3_2_A_CFG_3                              0
+#define EE2_TEST_3_2_B_CFG_1                              0
+#define EE2_TEST_3_2_B_CFG_2                              0
+#define EE2_TEST_3_2_B_CFG_3                              0
+
+#if EE2_TEST_3_2_A_CFG_1
+#define JVET_AC0159_IBC_MBVD_LIST_DERIVATION              1
+#define EE2_TEST_3_2_A                                    1
+#define JVET_AC0159_CFG_START_N_PEL                       3   // 1 << 5 = 32-pel, 1 << 4 = 16-pel, 1 << 3 = 8-pel, 1 << 2 = 4-pel, 1 << 1 = 2-pel, 1 << 0 = 1-pel
+#define JVET_AC0159_CFG_BV_DIFF_TH                        160 // 1/16 precision MV
+#endif
+
+#if EE2_TEST_3_2_A_CFG_2
+#define JVET_AC0159_IBC_MBVD_LIST_DERIVATION              1
+#define EE2_TEST_3_2_A                                    1
+#define JVET_AC0159_CFG_START_N_PEL                       2   // 1 << 5 = 32-pel, 1 << 4 = 16-pel, 1 << 3 = 8-pel, 1 << 2 = 4-pel, 1 << 1 = 2-pel, 1 << 0 = 1-pel
+#define JVET_AC0159_CFG_BV_DIFF_TH                        96  // 1/16 precision MV
+#endif
+
+#if EE2_TEST_3_2_A_CFG_3
+#define JVET_AC0159_IBC_MBVD_LIST_DERIVATION              1
+#define EE2_TEST_3_2_A                                    1
+#define JVET_AC0159_CFG_START_N_PEL                       1   // 1 << 5 = 32-pel, 1 << 4 = 16-pel, 1 << 3 = 8-pel, 1 << 2 = 4-pel, 1 << 1 = 2-pel, 1 << 0 = 1-pel
+#define JVET_AC0159_CFG_BV_DIFF_TH                        512 // 1/16 precision MV
+#endif
+
+#if EE2_TEST_3_2_B_CFG_1
+#define JVET_AC0159_IBC_MBVD_LIST_DERIVATION              1
+#define EE2_TEST_3_2_B                                    1
+#define JVET_AC0159_CFG_START_N_PEL                       3   // 1 << 5 = 32-pel, 1 << 4 = 16-pel, 1 << 3 = 8-pel, 1 << 2 = 4-pel, 1 << 1 = 2-pel, 1 << 0 = 1-pel
+#define JVET_AC0159_CFG_BV_DIFF_TH                        128 // 1/16 precision MV
+#endif
+
+#if EE2_TEST_3_2_B_CFG_2
+#define JVET_AC0159_IBC_MBVD_LIST_DERIVATION              1
+#define EE2_TEST_3_2_B                                    1
+#define JVET_AC0159_CFG_START_N_PEL                       2   // 1 << 5 = 32-pel, 1 << 4 = 16-pel, 1 << 3 = 8-pel, 1 << 2 = 4-pel, 1 << 1 = 2-pel, 1 << 0 = 1-pel
+#define JVET_AC0159_CFG_BV_DIFF_TH                        512 // 1/16 precision MV
+#endif
+
+#if EE2_TEST_3_2_B_CFG_3
+#define JVET_AC0159_IBC_MBVD_LIST_DERIVATION              1
+#define EE2_TEST_3_2_B                                    1
+#define JVET_AC0159_CFG_START_N_PEL                       1    // 1 << 5 = 32-pel, 1 << 4 = 16-pel, 1 << 3 = 8-pel, 1 << 2 = 4-pel, 1 << 1 = 2-pel, 1 << 0 = 1-pel
+#define JVET_AC0159_CFG_BV_DIFF_TH                        1024 // 1/16 precision MV
+#endif
 
 #define BASE_ENCODER                                      1
 #define BASE_NORMATIVE                                    1
@@ -192,6 +242,8 @@
 #define JVET_AC0104_IBC_BVD_PREDICTION                    1 // JVET-AC0104: IBC block vector difference prediction (part of JVET-AC0113 Test 3.5a) 
 #define JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV  1 // JVET-AC0060: IBC BVP candidates clustering and BVD sign derivation for BV with one zero component (part of JVET-AC0113 Test 3.5a) 
 #define JVET_AC0071_DBV                                   1 // JVET-AC0071: Direct block vector mode for chroma prediction
+#define IBC_OVERLAP                                       1
+#define IBC_TBVP                                          1
 
 
 // Inter
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index bf665670..f990e3cc 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -3137,6 +3137,9 @@ inline void PU::getTemplateRefTop(const PredictionUnit &pu, CPelBuf pRecY, PelBu
   MotionInfo templateMv;
   int        offset = -AML_MERGE_TEMPLATE_SIZE;
   templateMv.mv[0]  = CandMv + Mv(0, offset << (MV_PRECISION_INTERNAL - MV_PRECISION_INT));
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+  templateMv.rribcFlipType = pu.cu->rribcFlipType;
+#endif
   if (!PU::checkIsIBCCandidateValid(pu, templateMv))
   {
     offset = 0;
@@ -3151,6 +3154,9 @@ inline void PU::getTemplateRefLeft(const PredictionUnit &pu, CPelBuf pRecY, PelB
   MotionInfo templateMv;
   int        offset = -AML_MERGE_TEMPLATE_SIZE;
   templateMv.mv[0]  = CandMv + Mv(offset << (MV_PRECISION_INTERNAL - MV_PRECISION_INT), 0);
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+  templateMv.rribcFlipType = pu.cu->rribcFlipType;
+#endif
   if (!PU::checkIsIBCCandidateValid(pu, templateMv))
   {
     offset = 0;
@@ -3176,6 +3182,23 @@ inline Distortion PU::getTMCost(const PredictionUnit &pu, CPelBuf pRecY, Mv Cand
                            pu.cs->m_pcBufPredCurLeft.height);
     uiCost += pcInter->getTempCost(pu, pu.cs->m_pcBufPredCurLeft, pu.cs->m_pcBufPredRefLeft);
   }
+#if IBC_OVERLAP
+#if JVET_AA0070_RRIBC
+  if (pu.cu->rribcFlipType == 0)
+#endif
+  {
+    Mv tempBv = CandMv;
+    tempBv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT);
+    int xBv = tempBv.getHor();
+    int yBv = tempBv.getVer();
+    int nWidth = pu.lwidth();
+    int nHeight = pu.lheight();
+    if (((xBv + nWidth) >= 1) && ((yBv + nHeight) >= 1))
+    {
+      uiCost = (uint64_t)(uiCost * IBC_OVERLAP_TM_COST_FACTOR + (uiCost >> 1));
+    }
+  }
+#endif
   return uiCost;
 }
 #endif
@@ -3799,6 +3822,164 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const
   }
 #endif
 
+#if IBC_TBVP
+#if INTER_RM_SIZE_CONSTRAINTS
+  if (pu.cs->slice->getPicHeader()->getEnableTMVPFlag())
+#else
+  if (pu.cs->slice->getPicHeader()->getEnableTMVPFlag() && (pu.lumaSize().width + pu.lumaSize().height > 12))
+#endif
+  {
+    //>> MTK colocated-RightBottom
+    // offset the pos to be sure to "point" to the same position the uiAbsPartIdx would've pointed to
+    const PreCalcValues& pcv = *cs.pcv;
+    bool C0Avail;
+    bool C1Avail;
+    bool boundaryCond;
+    const SubPic& curSubPic = pu.cs->slice->getPPS()->getSubPicFromPos(pu.lumaPos());
+    Position posRB = pu.Y().bottomRight().offset(-3, -3);
+    Position posCenter = pu.Y().center();
+    Position posC0;
+    Position posC1;
+
+    int offsetX0 = 0, offsetX1 = 0, offsetX2 = 0, offsetX3 = pu.Y().width >> 1;
+    int offsetY0 = 0, offsetY1 = 0, offsetY2 = 0, offsetY3 = pu.Y().height >> 1;
+
+    const int iNACANDIDATE_NUM[5] = { 2, 2, 2, 2, 2 };
+    const int idxMap[5][2] = { { 0, 1 },{ 0, 2 },{ 0, 2 },{ 0, 2 },{ 0, 2 } };
+    int cntTBVP = 0;
+    uint32_t maxNumTBVPCand = NUM_TBVP_CANDS;
+    if (pu.cu->slice->getCheckLDC())
+    {
+      maxNumTBVPCand -= 1;
+    }
+    for (int iDistanceIndex = 0; iDistanceIndex < TMVP_DISTANCE_LEVEL && cntTBVP < maxNumTBVPCand; iDistanceIndex++)
+    {
+      const int iNADistanceHor = pu.Y().width * iDistanceIndex;
+      const int iNADistanceVer = pu.Y().height * iDistanceIndex;
+
+      for (int NASPIdx = 0; NASPIdx < iNACANDIDATE_NUM[iDistanceIndex] && cntTBVP < maxNumTBVPCand; NASPIdx++)
+      {
+        switch (idxMap[iDistanceIndex][NASPIdx])
+        {
+        case 0: offsetX0 = offsetX2 = 4 + iNADistanceHor; offsetY0 = offsetY2 = 4 + iNADistanceVer; offsetX1 = iNADistanceHor; offsetY1 = iNADistanceVer; break;
+        case 1: offsetX0 = 4; offsetY0 = 0; offsetX1 = 0; offsetY1 = 4; break;
+        case 2: offsetX0 = offsetX2; offsetY0 = 4 - offsetY3; offsetX1 = 4 - offsetX3; offsetY1 = offsetY2; break;
+        default: printf("error!"); exit(0); break;
+        }
+        C0Avail = false;
+        if (curSubPic.getTreatedAsPicFlag())
+        {
+          boundaryCond = ((posRB.x + offsetX0) <= curSubPic.getSubPicRight() && (posRB.y + offsetY0) <= curSubPic.getSubPicBottom());
+        }
+        else
+        {
+          boundaryCond = ((posRB.x + offsetX0) < pcv.lumaWidth) && ((posRB.y + offsetY0) < pcv.lumaHeight);
+        }
+        if (boundaryCond)
+        {
+          int posYInCtu = posRB.y & pcv.maxCUHeightMask;
+          if (posYInCtu + offsetY0 < pcv.maxCUHeight)
+          {
+            posC0 = posRB.offset(offsetX0, offsetY0);
+            C0Avail = true;
+          }
+        }
+
+        if (idxMap[iDistanceIndex][NASPIdx] == 0)
+        {
+          C1Avail = false;
+          if (curSubPic.getTreatedAsPicFlag())
+          {
+            boundaryCond = ((posCenter.x + offsetX1) <= curSubPic.getSubPicRight() && (posCenter.y + offsetY1) <= curSubPic.getSubPicBottom());
+          }
+          else
+          {
+            boundaryCond = ((posCenter.x + offsetX1) < pcv.lumaWidth) && ((posCenter.y + offsetY1) < pcv.lumaHeight);
+          }
+          if (boundaryCond)
+          {
+            int posYInCtu = posCenter.y & pcv.maxCUHeightMask;
+            if (posYInCtu + offsetY1 < pcv.maxCUHeight)
+            {
+              posC1 = posCenter.offset(offsetX1, offsetY1);
+              C1Avail = true;
+            }
+          }
+        }
+        else
+        {
+          C1Avail = false;
+          if (curSubPic.getTreatedAsPicFlag())
+          {
+            boundaryCond = ((posRB.x + offsetX1) <= curSubPic.getSubPicRight() && (posRB.y + offsetY1) <= curSubPic.getSubPicBottom());
+          }
+          else
+          {
+            boundaryCond = ((posRB.x + offsetX1) < pcv.lumaWidth) && ((posRB.y + offsetY1) < pcv.lumaHeight);
+          }
+          if (boundaryCond)
+          {
+            int posYInCtu = posRB.y & pcv.maxCUHeightMask;
+            if (posYInCtu + offsetY1 < pcv.maxCUHeight)
+            {
+              posC1 = posRB.offset(offsetX1, offsetY1);
+              C1Avail = true;
+            }
+          }
+        }
+
+        Mv        cColMv;
+        bool      bExistMV = (C0Avail && getColocatedBVP(pu, posC0, cColMv)) || (C1Avail && getColocatedBVP(pu, posC1, cColMv));
+        if (bExistMV)
+        {
+          MotionInfo miTemp;
+          miTemp.mv[0] = cColMv;
+          miTemp.refIdx[0] = MAX_NUM_REF;
+#if JVET_AA0070_RRIBC
+          miTemp.rribcFlipType = 0;
+#endif
+          if (checkIsIBCCandidateValid(pu, miTemp))
+          {
+            mrgCtx.mvFieldNeighbours[cnt * 2].setMvField(cColMv, MAX_NUM_REF);
+            mrgCtx.interDirNeighbours[cnt] = 1;
+#if JVET_AA0070_RRIBC
+            mrgCtx.rribcFlipTypes[cnt] = 0;
+#endif
+#if JVET_AC0112_IBC_LIC
+            mrgCtx.ibcLicFlags[cnt] = false;
+#endif
+#if JVET_Z0084_IBC_TM
+            if (!mrgCtx.xCheckSimilarIBCMotion(cnt, mvdSimilarityThresh))
+#else
+            if (!mrgCtx.xCheckSimilarMotion(cnt))
+#endif
+            {
+              if (mrgCandIdx == cnt)
+              {
+#if JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV
+                mrgCtx.numAMVPMergeCand = cnt;
+#endif
+                return;
+              }
+              cnt++;
+              cntTBVP++;
+
+              // early termination
+              if (cnt == maxNumMergeCand)
+              {
+#if JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV
+                mrgCtx.numAMVPMergeCand = cnt;
+#endif
+                return;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+#endif
+
   if (cnt != maxNumMergeCand)
   {
 #if JVET_Z0075_IBC_HMVP_ENLARGE
@@ -3869,10 +4050,16 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const
     MotionInfo miAvg;
     miAvg.mv[0] = avgMv;
     miAvg.refIdx[0] = MAX_NUM_REF;
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+    miAvg.rribcFlipType = 0;
+#endif
     if (checkIsIBCCandidateValid(pu, miAvg))
     {
       mrgCtx.mvFieldNeighbours[cnt * 2].setMvField(avgMv, MAX_NUM_REF);
       mrgCtx.interDirNeighbours[cnt] = 1;
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+      mrgCtx.rribcFlipTypes[cnt] = 0;
+#endif
 #if JVET_Z0084_IBC_TM
       if( !mrgCtx.xCheckSimilarIBCMotion(cnt, mvdSimilarityThresh) )
 #else
@@ -3980,6 +4167,9 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const
 #endif
     MotionInfo miCand;
     miCand.mv[0] = mvp;
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+    miCand.rribcFlipType = 0;
+#endif
     mrgCtx.mvFieldNeighbours[cnt * 2].setMvField(mvp, MAX_NUM_REF);
     mrgCtx.interDirNeighbours[cnt] = 1;
 #if JVET_AC0112_IBC_LIC
@@ -3989,10 +4179,18 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const
     mrgCtx.rribcFlipTypes[cnt] = 0;
 #endif
 
+#if JVET_Y0058_IBC_LIST_MODIFY
 #if JVET_Z0084_IBC_TM
     if (!mrgCtx.xCheckSimilarIBCMotion(cnt, mvdSimilarityThresh) && checkIsIBCCandidateValid(pu, miCand))
 #else
     if (!duplicateBVP && checkIsIBCCandidateValid(pu, miCand))
+#endif
+#else
+#if JVET_Z0084_IBC_TM
+    if (!mrgCtx.xCheckSimilarIBCMotion(cnt, mvdSimilarityThresh))
+#else
+    if (!duplicateBVP)
+#endif
 #endif
     {
       if (mrgCandIdx == cnt)
@@ -4060,7 +4258,16 @@ bool PU::checkIsIBCCandidateValid(const PredictionUnit& pu, const MotionInfo miN
   int xPred = bv.getHor();
   int yPred = bv.getVer();
 
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+#if IBC_TM_MRG
+  int rribcFlipType = (!pu.tmMergeFlag) ? miNeighbor.rribcFlipType : 0;
+#else
+  int rribcFlipType = miNeighbor.rribcFlipType;
+#endif
+  if (searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth,rribcFlipType))
+#else
   if (searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth)) // not valid bv derived
+#endif
   {
     return true;
   }
@@ -4072,7 +4279,11 @@ bool PU::checkIsIBCCandidateValid(const PredictionUnit& pu, const MotionInfo miN
 #endif
 
 #if JVET_Y0058_IBC_LIST_MODIFY || JVET_Z0084_IBC_TM
+#if IBC_OVERLAP
+bool PU::searchBv(const PredictionUnit& pu, int xPos, int yPos, int width, int height, int picWidth, int picHeight, int xBv, int yBv, int ctuSize,int rribcFlipType)
+#else
 bool PU::searchBv(const PredictionUnit& pu, int xPos, int yPos, int width, int height, int picWidth, int picHeight, int xBv, int yBv, int ctuSize)
+#endif
 {
   const int ctuSizeLog2 = floorLog2(ctuSize);
 
@@ -4099,10 +4310,24 @@ bool PU::searchBv(const PredictionUnit& pu, int xPos, int yPos, int width, int h
   {
     return false;
   }
-  if ((xBv + width) > 0 && (yBv + height) > 0)
+#if IBC_OVERLAP
+  if (rribcFlipType)
   {
-    return false;
+#endif
+    if ((xBv + width) > 0 && (yBv + height) > 0)
+    {
+      return false;
+    }
+#if IBC_OVERLAP
+  }
+  else
+  {
+    if ((xBv + width) > 0 && (yBv + height) > 0 && ((xBv > 0) || (yBv > 0)))
+    {
+      return false;
+    }
   }
+#endif
 
 #if !JVET_Z0153_IBC_EXT_REF
   // Don't search the above CTU row
@@ -4242,10 +4467,24 @@ bool PU::searchBv(const PredictionUnit& pu, int xPos, int yPos, int width, int h
   const Position refPosBR = pu.Y().bottomRight().offset(xBv, yBv);
 #endif
   const ChannelType      chType = toChannelType(COMPONENT_Y);
-  if (!pu.cs->isDecomp(refPosBR, chType))
+#if IBC_OVERLAP
+  if (rribcFlipType)
   {
-    return false;
+#endif
+    if (!pu.cs->isDecomp(refPosBR, chType))
+    {
+      return false;
+    }
+#if IBC_OVERLAP
   }
+  else
+  {
+    if (!pu.cs->isDecomp(refPosBR, chType) && ((xBv > 0) || (yBv > 0)))
+    {
+      return false;
+    }
+  }
+#endif
   if (!pu.cs->isDecomp(refPosLT, chType))
   {
     return false;
@@ -4254,6 +4493,81 @@ bool PU::searchBv(const PredictionUnit& pu, int xPos, int yPos, int width, int h
 }
 #endif
 
+#if IBC_OVERLAP
+void PU::updateDistParam(const PredictionUnit &pu, const Pel* piRefSrch, int refStride, int xPred, int yPred,DistParam &distParam,PelBuf &tmpRefLuma)
+{
+  //copy the available rows.
+  Pel* piPredTmp = tmpRefLuma.buf;
+  const Pel* piRecoPic = piRefSrch + refStride * yPred + xPred;
+  for (unsigned y = 0; y < abs(yPred); y++)
+  {
+    for (unsigned x = 0; x < pu.lwidth(); x++)
+    {
+      piPredTmp[x] = piRecoPic[x];
+    }
+    piPredTmp += tmpRefLuma.stride;
+    piRecoPic += refStride;
+  }
+  //copy the availbale columns
+  piPredTmp = tmpRefLuma.buf;
+  piRecoPic = piRefSrch + refStride * yPred + xPred;
+  for (unsigned y = abs(yPred); y < pu.lheight(); y++)
+  {
+    for (unsigned x = 0; x < abs(xPred); x++)
+    {
+      piPredTmp[tmpRefLuma.stride*y+x] = piRecoPic[refStride*y+x];
+    }
+  }
+  //pad the unavailable samples
+  piPredTmp = tmpRefLuma.buf;
+  for (unsigned y = abs(yPred); y < pu.lheight(); y++)
+  {
+    for (unsigned x = abs(xPred); x < pu.lwidth(); x++)
+    {
+      piPredTmp[tmpRefLuma.stride*y+x] = piPredTmp[tmpRefLuma.stride*(y+yPred)+(x+xPred)];
+    }
+  }
+  distParam.cur = (const CPelBuf)tmpRefLuma;
+}
+#if JVET_AC0112_IBC_LIC
+void PU::updateDistParam(const PredictionUnit &pu, PelBuf predBuf, int xPred, int yPred,DistParam &distParam,PelBuf &tmpRefLuma)
+{
+  //copy the available rows.
+  Pel* piPredTmp = tmpRefLuma.buf;
+  const Pel* piRecoPic = predBuf.buf;
+  for (unsigned y = 0; y < abs(yPred); y++)
+  {
+    for (unsigned x = 0; x < pu.lwidth(); x++)
+    {
+      piPredTmp[x] = piRecoPic[x];
+    }
+    piPredTmp += tmpRefLuma.stride;
+    piRecoPic += predBuf.stride;
+  }
+  //copy the availbale columns
+  piPredTmp = tmpRefLuma.buf;
+  piRecoPic = predBuf.buf;
+  for (unsigned y = abs(yPred); y < pu.lheight(); y++)
+  {
+    for (unsigned x = 0; x < abs(xPred); x++)
+    {
+      piPredTmp[tmpRefLuma.stride*y+x] = piRecoPic[predBuf.stride*y+x];
+    }
+  }
+  //pad the unavailable samples
+  piPredTmp = tmpRefLuma.buf;
+  for (unsigned y = abs(yPred); y < pu.lheight(); y++)
+  {
+    for (unsigned x = abs(xPred); x < pu.lwidth(); x++)
+    {
+      piPredTmp[tmpRefLuma.stride*y+x] = piPredTmp[tmpRefLuma.stride*(y+yPred)+(x+xPred)];
+    }
+  }
+  distParam.cur = (const CPelBuf)tmpRefLuma;
+}
+#endif
+#endif
+
 #if JVET_AA0061_IBC_MBVD
 void PU::getIbcMbvdMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, int numValidBv)
 {
@@ -4261,6 +4575,36 @@ void PU::getIbcMbvdMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, i
   int k;
   int currBaseNum = 0;
 
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  for( k = 0; k < mrgCtx.numValidMergeCand; k++ )
+  {
+    refIdxList0 = mrgCtx.mvFieldNeighbours[( k << 1 )].refIdx;
+    if( refIdxList0 >= 0 )
+    {
+      mrgCtx.ibcMbvdBaseBv[currBaseNum][0] = mrgCtx.mvFieldNeighbours[( k << 1 )];
+      mrgCtx.ibcMbvdBaseBv[currBaseNum][1] = MvField( Mv( 0, 0 ), -1 );
+      bool findSimilarBaseBv = false;
+      for (int zz = 0; zz < currBaseNum; zz++)
+      {
+        if (((mrgCtx.ibcMbvdBaseBv[zz][0].mv.hor == mrgCtx.ibcMbvdBaseBv[currBaseNum][0].mv.hor)
+            && (std::abs(mrgCtx.ibcMbvdBaseBv[zz][0].mv.ver - mrgCtx.ibcMbvdBaseBv[currBaseNum][0].mv.ver) < JVET_AC0159_CFG_BV_DIFF_TH))
+          || ((mrgCtx.ibcMbvdBaseBv[zz][0].mv.ver == mrgCtx.ibcMbvdBaseBv[currBaseNum][0].mv.ver)
+              && (std::abs(mrgCtx.ibcMbvdBaseBv[zz][0].mv.hor - mrgCtx.ibcMbvdBaseBv[currBaseNum][0].mv.hor) < JVET_AC0159_CFG_BV_DIFF_TH)))
+        {
+          findSimilarBaseBv = true;
+          break;
+        }
+      }
+      currBaseNum += (findSimilarBaseBv == false);
+    }
+    if (currBaseNum == numValidBv)
+    {
+      mrgCtx.numValidMergeCand = currBaseNum;
+      return;
+    }
+  }
+  mrgCtx.numValidMergeCand = currBaseNum;
+#else
   for( k = 0; k < numValidBv; k++ )
   {
     refIdxList0 = mrgCtx.mvFieldNeighbours[( k << 1 )].refIdx;
@@ -4278,14 +4622,23 @@ void PU::getIbcMbvdMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, i
       break;
     }
   }
+#endif
 }
 int32_t PU::getIbcMbvdEstBits(const PredictionUnit &pu,unsigned int mmvdMergeCand)
 {
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  int baseIdx = mmvdMergeCand / IBC_MBVD_SIZE_ENC;
+#else
   int baseIdx = mmvdMergeCand / IBC_MBVD_MAX_REFINE_NUM;
+#endif
   int baseBits = (IBC_MBVD_BASE_NUM == 1 ? 0 : baseIdx + (baseIdx == IBC_MBVD_BASE_NUM - 1 ? 0: 1));
   int ricePar = 1;
   unsigned int mvpIdx = mmvdMergeCand;
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  mvpIdx -= baseIdx * IBC_MBVD_SIZE_ENC;
+#else
   mvpIdx -= baseIdx * IBC_MBVD_MAX_REFINE_NUM;
+#endif
   mvpIdx >>= ricePar;
   int numCandStepMinus1 = (IBC_MBVD_SIZE_ENC >> ricePar) - 1;
   int mmvdUnaryBits = mvpIdx + (mvpIdx == numCandStepMinus1 ? 0 : 1);
@@ -9672,6 +10025,49 @@ bool PU::getColocatedMVP(const PredictionUnit &pu, const RefPicList &eRefPicList
 #endif
 }
 
+#if IBC_TBVP
+bool PU::getColocatedBVP(const PredictionUnit &pu, const Position &_pos, Mv& rcMv)
+{
+  // don't perform MV compression when generally disabled or subPuMvp is used
+  const unsigned scale = 4 * std::max<int>(1, 4 * AMVP_DECIMATION_FACTOR / 4);
+  const unsigned mask  = ~( scale - 1 );
+
+  const Position pos = Position{ PosType( _pos.x & mask ), PosType( _pos.y & mask ) };
+
+  const Slice &slice = *pu.cs->slice;
+
+  // use coldir.
+  const Picture* const pColPic = slice.getRefPic(RefPicList(slice.isInterB() ? 1 - slice.getColFromL0Flag() : 0), slice.getColRefIdx());
+
+  if( !pColPic )
+  {
+    return false;
+  }
+
+  // Check the position of colocated block is within a subpicture
+  const SubPic &curSubPic = pu.cs->slice->getPPS()->getSubPicFromPos(pu.lumaPos());
+  if (curSubPic.getTreatedAsPicFlag())
+  {
+    if (!curSubPic.isContainingPos(pos))
+    {
+      return false;
+    }
+  }
+
+  const MotionInfo& mi = pColPic->cs->getMotionInfo( pos );
+
+  if (CU::isIBC(*pu.cu) && mi.isIBCmot)
+  {
+    rcMv = mi.mv[0];
+    return true;
+  }
+  else
+  {
+    return false;
+  }
+}
+#endif
+
 bool PU::isDiffMER(const Position &pos1, const Position &pos2, const unsigned plevel)
 {
   const unsigned xN = pos1.x;
diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h
index 2c52985c..13b58dd1 100644
--- a/source/Lib/CommonLib/UnitTools.h
+++ b/source/Lib/CommonLib/UnitTools.h
@@ -261,8 +261,18 @@ namespace PU
   bool checkIsIBCCandidateValid(const PredictionUnit &pu, const MotionInfo miNeighbor, bool isRefTemplate = false, bool isRefAbove = false);
 #endif
 #if JVET_Y0058_IBC_LIST_MODIFY || JVET_Z0084_IBC_TM || JVET_AA0061_IBC_MBVD
+#if IBC_OVERLAP
+  bool searchBv(const PredictionUnit& pu, int xPos, int yPos, int width, int height, int picWidth, int picHeight, int xBv, int yBv, int ctuSize,int rribcFlipType = 0);
+#else
   bool searchBv(const PredictionUnit& pu, int xPos, int yPos, int width, int height, int picWidth, int picHeight, int xBv, int yBv, int ctuSize);
 #endif
+#endif
+#if IBC_OVERLAP
+  void updateDistParam(const PredictionUnit &pu, const Pel* piRefSrch, int refStride, int xPred, int yPred,DistParam &distParam,PelBuf &tmpRefLuma);
+#if JVET_AC0112_IBC_LIC
+  void updateDistParam(const PredictionUnit &pu, PelBuf predBuf, int xPred, int yPred,DistParam &distParam,PelBuf &tmpRefLuma);
+#endif
+#endif
 #if JVET_AA0061_IBC_MBVD
   void getIbcMbvdMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, int numValidBv);
   int32_t getIbcMbvdEstBits      (const PredictionUnit &pu, unsigned int mmvdMergeCand);
@@ -291,6 +301,9 @@ namespace PU
                               bool availableTmLeft, InterPrediction *pcInter);
   inline void       getRribcBvpCand(PredictionUnit &pu, AMVPInfo *amvpInfo);
   inline void       clusterBvpCand(const int cbWidth, const int cbHeight, AMVPInfo *pInfo);
+#endif
+#if IBC_TBVP
+  bool getColocatedBVP                (const PredictionUnit &pu, const Position &pos, Mv& rcMv);
 #endif
   void fillMvpCand                    (      PredictionUnit &pu, const RefPicList &eRefPicList, const int &refIdx, AMVPInfo &amvpInfo 
 #if TM_AMVP || JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV
diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp
index c1514fea..7503e06a 100644
--- a/source/Lib/DecoderLib/CABACReader.cpp
+++ b/source/Lib/DecoderLib/CABACReader.cpp
@@ -3916,7 +3916,11 @@ void CABACReader::ibcMbvdData(PredictionUnit& pu)
   }
   uiUnaryIdx <<= ricePar;
   uiUnaryIdx += temp;
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  pu.ibcMbvdMergeIdx = var0 * IBC_MBVD_SIZE_ENC + uiUnaryIdx;
+#else
   pu.ibcMbvdMergeIdx = var0 * IBC_MBVD_MAX_REFINE_NUM  +uiUnaryIdx;
+#endif
   DTRACE(g_trace_ctx, D_SYNTAX, "IBC_mbvd_merge_idx() IBC_mbvd_merge_idx=%d\n", pu.ibcMbvdMergeIdx);
 }
 #endif
diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp
index 47087951..a8939a1e 100644
--- a/source/Lib/DecoderLib/DecCu.cpp
+++ b/source/Lib/DecoderLib/DecCu.cpp
@@ -2266,7 +2266,11 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
 #if JVET_AA0061_IBC_MBVD
             if (pu.ibcMbvdMergeFlag)
             {
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+              int fPosIBCBaseIdx = pu.ibcMbvdMergeIdx / IBC_MBVD_SIZE_ENC;
+#else
               int fPosIBCBaseIdx = pu.ibcMbvdMergeIdx / IBC_MBVD_MAX_REFINE_NUM;
+#endif
 #if JVET_Y0058_IBC_LIST_MODIFY && JVET_W0090_ARMC_TM
               if (pu.cs->sps->getUseAML())
               {
@@ -2294,7 +2298,11 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
 
               PU::getIbcMbvdMergeCandidates(pu, mrgCtx, fPosIBCBaseIdx + 1);
 
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+              uint32_t ibcMbvdLUT[IBC_MBVD_ENC_NUM];
+#else
               uint32_t ibcMbvdLUT[IBC_MBVD_NUM];
+#endif
               uint32_t ibcMbvdValidNum[IBC_MBVD_BASE_NUM] = { 0 };
               int      ibcMbvdIdx= pu.ibcMbvdMergeIdx;
               m_pcInterPred->sortIbcMergeMbvdCandidates(pu, mrgCtx, ibcMbvdLUT, ibcMbvdValidNum, ibcMbvdIdx);
@@ -3469,6 +3477,23 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
       const unsigned int  lcuWidth = pu.cs->slice->getSPS()->getMaxCUWidth();
       int xPred = pu.mv[0].getHor() >> MV_FRACTIONAL_BITS_INTERNAL;
       int yPred = pu.mv[0].getVer() >> MV_FRACTIONAL_BITS_INTERNAL;
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+#if JVET_Z0118_GDR
+      if (cu.cs->isGdrEnabled())
+      {
+        if (cu.cs->isClean(cu)) 
+        {
+          CHECK(!m_pcInterPred->isLumaBvValid(lcuWidth, cuPelX, cuPelY, roiWidth, roiHeight, xPred, yPred,pu.cu->rribcFlipType), "invalid block vector for IBC detected.");
+        }
+      }
+      else 
+      {
+        CHECK(!m_pcInterPred->isLumaBvValid(lcuWidth, cuPelX, cuPelY, roiWidth, roiHeight, xPred, yPred,pu.cu->rribcFlipType), "invalid block vector for IBC detected.");
+      }
+#else
+      CHECK(!m_pcInterPred->isLumaBvValid(lcuWidth, cuPelX, cuPelY, roiWidth, roiHeight, xPred, yPred,pu.cu->rribcFlipType), "invalid block vector for IBC detected.");
+#endif
+#else
 #if JVET_Z0118_GDR
       if (cu.cs->isGdrEnabled())
       {
@@ -3483,6 +3508,7 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
       }
 #else
       CHECK(!m_pcInterPred->isLumaBvValid(lcuWidth, cuPelX, cuPelY, roiWidth, roiHeight, xPred, yPred), "invalid block vector for IBC detected.");
+#endif
 #endif
     }
 #if MULTI_HYP_PRED
diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp
index ea6a716b..45e35b53 100644
--- a/source/Lib/EncoderLib/CABACWriter.cpp
+++ b/source/Lib/EncoderLib/CABACWriter.cpp
@@ -3471,8 +3471,13 @@ void CABACWriter::ibcMbvdData(const PredictionUnit& pu)
   }
   int mvpIdx = pu.ibcMbvdMergeIdx;
   uint8_t var0;
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  var0 = mvpIdx / IBC_MBVD_SIZE_ENC;
+  mvpIdx -= var0 * IBC_MBVD_SIZE_ENC;
+#else
   var0 = mvpIdx / IBC_MBVD_MAX_REFINE_NUM;
   mvpIdx -= var0 * IBC_MBVD_MAX_REFINE_NUM;
+#endif
 
   // Base affine merge candidate idx
 
diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp
index 0e66d915..f713c1f2 100644
--- a/source/Lib/EncoderLib/EncCu.cpp
+++ b/source/Lib/EncoderLib/EncCu.cpp
@@ -11098,7 +11098,11 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
 #endif
 #if JVET_AA0061_IBC_MBVD
   MergeCtx mergeCtxTmp;
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  uint32_t ibcMbvdLUT[IBC_MBVD_ENC_NUM];
+#else
   uint32_t ibcMbvdLUT[IBC_MBVD_NUM];
+#endif
   uint32_t ibcMbvdValidNum[IBC_MBVD_BASE_NUM] = { 0 };
 #endif
 
@@ -11231,7 +11235,11 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
 
 #if JVET_Z0084_IBC_TM && IBC_TM_MRG
 #if JVET_AA0061_IBC_MBVD
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+  const int numCandidates = ( IBC_MRG_MAX_NUM_CANDS << 1 ) + IBC_MBVD_ENC_NUM;
+#else
   const int numCandidates = ( IBC_MRG_MAX_NUM_CANDS << 1 ) + IBC_MBVD_NUM;
+#endif
 #else
   const int numCandidates = IBC_MRG_MAX_NUM_CANDS << 1;
 #endif
@@ -11490,6 +11498,23 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
 #endif
 
       int refStride = refBuf.stride;
+#if IBC_OVERLAP
+#if !JVET_AA0070_RRIBC
+      const CompArea &area = cu.blocks[COMPONENT_Y];
+      CompArea    tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
+#endif
+      PelStorage m_tmpStorageCUPad;
+      m_tmpStorageCUPad.create(UnitArea(pu.chromaFormat, Area(0, 0, MAX_CU_SIZE, MAX_CU_SIZE)));
+      PelBuf tmpRefLuma = m_tmpStorageCUPad.getBuf(tmpArea);
+#if JVET_AC0112_IBC_LIC
+      PelStorage m_tmpStorageCUPadLIC;
+      m_tmpStorageCUPadLIC.create(UnitArea(pu.chromaFormat, Area(0, 0, MAX_CU_SIZE, MAX_CU_SIZE)));
+      PelBuf tmpRefLumaLIC = m_tmpStorageCUPadLIC.getBuf(tmpArea);
+#endif
+#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_GPM
+      bool ibcOverlapCand = false;
+#endif
+#endif
 #if !JVET_Y0058_IBC_LIST_MODIFY
       const UnitArea localUnitArea(tempCS->area.chromaFormat, Area(0, 0, tempCS->area.Y().width, tempCS->area.Y().height));
       const int cuPelX = pu.Y().x;
@@ -11512,6 +11537,9 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
       for (unsigned int mergeCand = 0; mergeCand < mergeCtx.numValidMergeCand; mergeCand++)
       {
         mergeCtx.setMergeInfo(pu, mergeCand); // set bv info in merge mode
+#if IBC_OVERLAP && (JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_GPM)
+        ibcOverlapCand = false;
+#endif
 #if JVET_AC0112_IBC_GPM
         int mergeCandIbcGpm = mergeCand - skipCandNum[mergeCand > 0 ? mergeCand - 1 : 0];
 #endif
@@ -11519,11 +11547,19 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
         int xPred = pu.bv.getHor();
         int yPred = pu.bv.getVer();
 #if !JVET_Y0058_IBC_LIST_MODIFY  //should have already been checked at merge list construction
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+#if JVET_Z0084_IBC_TM
+        if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth, pu.cu->rribcFlipType)) // not valid bv derived
+#else
+        if (!m_pcInterSearch->searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth, pu.cu->rribcFlipType)) // not valid bv derived
+#endif
+#else
 #if JVET_Z0084_IBC_TM
         if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth)) // not valid bv derived
 #else
         if (!m_pcInterSearch->searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth)) // not valid bv derived
 #endif
+#endif
 #else
         if (pu.bv == Mv(0, 0))
 #endif
@@ -11588,7 +11624,36 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
         }
         else
 #endif
+#if IBC_OVERLAP
+        {
+          distParam.cur.buf = piRefSrch + refStride * yPred + xPred;
+          distParam.cur.stride = refStride;
+        }
+#else
         distParam.cur.buf = piRefSrch + refStride * yPred + xPred;
+#endif
+#if IBC_OVERLAP
+#if JVET_AA0070_RRIBC
+        if (pu.cu->rribcFlipType == 0)
+#endif
+        {
+          int width = pu.lwidth();
+          int height = pu.lheight();
+          if(((xPred+width)>=1)&&((yPred+height)>=1))
+          {
+#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_GPM
+            ibcOverlapCand = true;
+#endif
+            PU::updateDistParam(pu, piRefSrch, refStride, xPred, yPred, distParam,tmpRefLuma);
+#if JVET_AC0112_IBC_LIC
+            if (pu.cu->ibcLicFlag)
+            {
+              PU::updateDistParam(pu, predBuf, xPred, yPred, distParam,tmpRefLumaLIC);
+            }
+#endif
+          }
+        }
+#endif
 
         Distortion sad = distParam.distFunc(distParam);
         unsigned int bitsCand = mergeCand + 1;
@@ -11638,7 +11703,18 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
             int dstStride = ibcCiipBuf.stride;
             Pel *pPredIntra = intraPredBuf[ibcCiipIntraList[dirIdx]].Y().buf;
             int intraStride = intraPredBuf[ibcCiipIntraList[dirIdx]].Y().stride;
-            m_pcIntraSearch->m_ibcCiipBlending(pPredDst, dstStride, pPredIbc, refStride, pPredIntra, intraStride, wIbc, wIntra, shift, width, height);
+#if IBC_OVERLAP
+            if (ibcOverlapCand)
+            {
+              m_pcIntraSearch->m_ibcCiipBlending(pPredDst, dstStride, tmpRefLuma.buf, tmpRefLuma.stride, pPredIntra, intraStride, wIbc, wIntra, shift, width, height);
+            }
+            else
+            {
+#endif
+              m_pcIntraSearch->m_ibcCiipBlending(pPredDst, dstStride, pPredIbc, refStride, pPredIntra, intraStride, wIbc, wIntra, shift, width, height);
+#if IBC_OVERLAP
+            }
+#endif
 
             distParam.cur.buf = ibcCiipBuf.buf;
             distParam.cur.stride = ibcCiipBuf.stride;
@@ -11678,8 +11754,20 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
 #endif
         {
           ibcGpmCandNumValid++;
-          distParamSad.cur.buf = piRefSrch + refStride * yPred + xPred;
-          distParamSad.cur.stride = refBuf.stride;
+#if IBC_OVERLAP
+          if (ibcOverlapCand)
+          {
+            distParamSad.cur.buf = tmpRefLuma.buf;
+            distParamSad.cur.stride = tmpRefLuma.stride;
+          }
+          else
+          {
+#endif
+            distParamSad.cur.buf = piRefSrch + refStride * yPred + xPred;
+            distParamSad.cur.stride = refBuf.stride;
+#if IBC_OVERLAP
+          }
+#endif
           ibcPredBuf[mergeCandIbcGpm] = m_acMergeBuffer[mergeCandIbcGpm].getBuf(localUnitArea);
           ibcPredBuf[mergeCandIbcGpm].bufs[COMPONENT_Y].copyFrom(distParamSad.cur);
           sadWholeBlk[mergeCandIbcGpm] = distParamSad.distFunc(distParamSad);
@@ -11724,6 +11812,9 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
     for (unsigned int mergeCand = 0; mergeCand < mergeCtxTm.numValidMergeCand; mergeCand++)
     {
       mergeCtxTm.setMergeInfo(pu, mergeCand); // set bv info in merge mode
+#if IBC_OVERLAP && (JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_GPM)
+      ibcOverlapCand = false;
+#endif
 #if JVET_AC0112_IBC_GPM
       int mergeCandIbcGpm = mergeCand - skipCandNumTm[mergeCtx.numValidMergeCand + (mergeCand  > 0 ? mergeCand - 1 : 0)];
 #endif
@@ -11751,7 +11842,11 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
       int xPred = pu.bv.getHor();
       int yPred = pu.bv.getVer();
 #if !JVET_Y0058_IBC_LIST_MODIFY  //should have already been checked at merge list construction and during refinement
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+      if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth,pu.cu->rribcFlipType)) // not valid bv derived
+#else
       if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth)) // not valid bv derived
+#endif
 #else
       if (pu.bv == Mv(0, 0))
 #endif
@@ -11816,7 +11911,36 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
       }
       else
 #endif
+#if IBC_OVERLAP
+      {
+        distParam.cur.buf = piRefSrch + refStride * yPred + xPred;
+        distParam.cur.stride = refStride;
+      }
+#else
       distParam.cur.buf = piRefSrch + refStride * yPred + xPred;
+#endif
+#if IBC_OVERLAP
+#if JVET_AA0070_RRIBC
+      if (pu.cu->rribcFlipType == 0)
+#endif
+      {
+        int width = pu.lwidth();
+        int height = pu.lheight();
+        if(((xPred+width)>=1)&&((yPred+height)>=1))
+        {
+#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_GPM
+          ibcOverlapCand = true;
+#endif
+          PU::updateDistParam(pu, piRefSrch, refStride, xPred, yPred, distParam,tmpRefLuma);
+#if JVET_AC0112_IBC_LIC
+          if (pu.cu->ibcLicFlag)
+          {
+            PU::updateDistParam(pu, predBuf, xPred, yPred, distParam,tmpRefLumaLIC);
+          }
+#endif
+        }
+      }
+#endif
 
       Distortion sad = distParam.distFunc(distParam);
       unsigned int bitsCand = mergeCand + 1;
@@ -11862,7 +11986,18 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
           int dstStride = ibcCiipBuf.stride;
           Pel *pPredIntra = intraPredBuf[ibcCiipIntraList[dirIdx]].Y().buf;
           int intraStride = intraPredBuf[ibcCiipIntraList[dirIdx]].Y().stride;
-          m_pcIntraSearch->m_ibcCiipBlending(pPredDst, dstStride, pPredIbc, refStride, pPredIntra, intraStride, wIbc, wIntra, shift, width, height);
+#if IBC_OVERLAP
+          if (ibcOverlapCand)
+          {
+            m_pcIntraSearch->m_ibcCiipBlending(pPredDst, dstStride, tmpRefLuma.buf, tmpRefLuma.stride, pPredIntra, intraStride, wIbc, wIntra, shift, width, height);
+          }
+          else
+          {
+#endif
+            m_pcIntraSearch->m_ibcCiipBlending(pPredDst, dstStride, pPredIbc, refStride, pPredIntra, intraStride, wIbc, wIntra, shift, width, height);
+#if IBC_OVERLAP
+          }
+#endif
 
           distParam.cur.buf = ibcCiipBuf.buf;
           distParam.cur.stride = ibcCiipBuf.stride;
@@ -11902,8 +12037,20 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
 #endif
       {
         ibcGpmCandNumValid++;
-        distParamSad.cur.buf = piRefSrch + refStride * yPred + xPred;
-        distParamSad.cur.stride = refBuf.stride;
+#if IBC_OVERLAP
+        if (ibcOverlapCand)
+        {
+          distParamSad.cur.buf = tmpRefLuma.buf;
+          distParamSad.cur.stride = tmpRefLuma.stride;
+        }
+        else
+        {
+#endif
+          distParamSad.cur.buf = piRefSrch + refStride * yPred + xPred;
+          distParamSad.cur.stride = refBuf.stride;
+#if IBC_OVERLAP
+        }
+#endif
         ibcPredBuf[mergeCtx.numValidMergeCand + mergeCandIbcGpm] = m_acMergeBuffer[mergeCtx.numValidMergeCand + mergeCandIbcGpm].getBuf(localUnitArea);
         ibcPredBuf[mergeCtx.numValidMergeCand + mergeCandIbcGpm].bufs[COMPONENT_Y].copyFrom(distParamSad.cur);
         sadWholeBlk[mergeCtx.numValidMergeCand + mergeCandIbcGpm] = distParamSad.distFunc(distParamSad);
@@ -11947,17 +12094,28 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
     {
       if (pu.cs->sps->getUseIbcMbvd())
       {
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+        PU::getIbcMbvdMergeCandidates(pu, mergeCtxTmp, std::min(numValidBvIBC, IBC_MBVD_BASE_NUM));
+#else
 #if JVET_AA0070_RRIBC
         for (unsigned int mergeCand = 0; mergeCand < mergeCtxTmp.numValidMergeCand; mergeCand++)
         {
           mergeCtxTmp.setMergeInfo(pu, mergeCand); // set bv info in merge mode
 
 #if !JVET_Y0058_IBC_LIST_MODIFY  //should have already been checked at merge list construction
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+#if JVET_Z0084_IBC_TM
+          if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth,pu.cu->rribcFlipType)) // not valid bv derived
+#else
+          if (!m_pcInterSearch->searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth,pu.cu->rribcFlipType)) // not valid bv derived
+#endif
+#else
 #if JVET_Z0084_IBC_TM
           if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth)) // not valid bv derived
 #else
           if (!m_pcInterSearch->searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth)) // not valid bv derived
 #endif
+#endif
 #else
           if (pu.bv == Mv(0, 0))
 #endif
@@ -11973,12 +12131,24 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
 #endif
 
         PU::getIbcMbvdMergeCandidates(pu, mergeCtxTmp, baseNum);
+#endif
 
         bool flag = pu.ibcMbvdMergeFlag;
         pu.ibcMbvdMergeFlag = true;
         m_pcInterSearch->sortIbcMergeMbvdCandidates(pu, mergeCtxTmp, ibcMbvdLUT, ibcMbvdValidNum);
         pu.ibcMbvdMergeFlag = flag;
 
+#if JVET_AC0159_IBC_MBVD_LIST_DERIVATION
+        for (unsigned int mmvdMergeCandtemp = 0; mmvdMergeCandtemp < IBC_MBVD_ENC_NUM; mmvdMergeCandtemp++)
+        {
+          int zzBaseIdx = mmvdMergeCandtemp / IBC_MBVD_SIZE_ENC;
+          if (mmvdMergeCandtemp - zzBaseIdx * IBC_MBVD_SIZE_ENC >= ibcMbvdValidNum[zzBaseIdx])
+          {
+            continue;
+          }
+          unsigned int mbvdMergeCand = ibcMbvdLUT[mmvdMergeCandtemp];
+          bool mbvdCandMisAlign = mergeCtxTmp.setIbcMbvdMergeCandiInfo(pu, mmvdMergeCandtemp, mbvdMergeCand);
+#else
         const int tempNum = baseNum * IBC_MBVD_MAX_REFINE_NUM;
         int baseIdx = 0;
         for (unsigned int mmvdMergeCandtemp = 0; mmvdMergeCandtemp < tempNum; mmvdMergeCandtemp++)
@@ -11994,7 +12164,11 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
           }
           unsigned int mmvdMergeCand = ibcMbvdLUT[mmvdMergeCandtemp];
           bool mbvdCandMisAlign = mergeCtxTmp.setIbcMbvdMergeCandiInfo(pu, mmvdMergeCandtemp, mmvdMergeCand);
+#endif
           CHECK(mbvdCandMisAlign, "MBVD candidate is invalid");
+#if IBC_OVERLAP && (JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_GPM)
+          ibcOverlapCand = false;
+#endif
 
           int xPred = pu.bv.getHor();
           int yPred = pu.bv.getVer();
@@ -12032,7 +12206,36 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
           }
           else
 #endif
+#if IBC_OVERLAP
+          {
+            distParam.cur.buf = piRefSrch + refStride * yPred + xPred;
+            distParam.cur.stride = refStride;
+          }
+#else
           distParam.cur.buf = piRefSrch + refStride * yPred + xPred;
+#endif
+#if IBC_OVERLAP
+#if JVET_AA0070_RRIBC
+          if (pu.cu->rribcFlipType == 0)
+#endif
+          {
+            int width = pu.lwidth();
+            int height = pu.lheight();
+            if(((xPred+width)>=1)&&((yPred+height)>=1))
+            {
+#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_GPM
+              ibcOverlapCand = true;
+#endif
+              PU::updateDistParam(pu, piRefSrch, refStride, xPred, yPred, distParam,tmpRefLuma);
+#if JVET_AC0112_IBC_LIC
+              if (pu.cu->ibcLicFlag)
+              {
+                PU::updateDistParam(pu, predBuf, xPred, yPred, distParam,tmpRefLumaLIC);
+              }
+#endif
+            }
+          }
+#endif
 
           Distortion sad = distParam.distFunc(distParam);
           uint32_t bitsCand = PU::getIbcMbvdEstBits(pu, mmvdMergeCandtemp);
@@ -12075,7 +12278,18 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
               int dstStride = ibcCiipBuf.stride;
               Pel *pPredIntra = intraPredBuf[ibcCiipIntraList[dirIdx]].Y().buf;
               int intraStride = intraPredBuf[ibcCiipIntraList[dirIdx]].Y().stride;
-              m_pcIntraSearch->m_ibcCiipBlending(pPredDst, dstStride, pPredIbc, refStride, pPredIntra, intraStride, wIbc, wIntra, shift, width, height);
+#if IBC_OVERLAP
+              if (ibcOverlapCand)
+              {
+                m_pcIntraSearch->m_ibcCiipBlending(pPredDst, dstStride, tmpRefLuma.buf, tmpRefLuma.stride, pPredIntra, intraStride, wIbc, wIntra, shift, width, height);
+              }
+              else
+              {
+#endif
+                m_pcIntraSearch->m_ibcCiipBlending(pPredDst, dstStride, pPredIbc, refStride, pPredIntra, intraStride, wIbc, wIntra, shift, width, height);
+#if IBC_OVERLAP
+              }
+#endif
 
               distParam.cur.buf = ibcCiipBuf.buf;
               distParam.cur.stride = ibcCiipBuf.stride;
@@ -12131,6 +12345,12 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
     m_tmpStorageCUflipH.destroy();
     m_tmpStorageCUflipV.destroy();
 #endif
+#if IBC_OVERLAP
+    m_tmpStorageCUPad.destroy();
+#if JVET_AC0112_IBC_LIC
+    m_tmpStorageCUPadLIC.destroy();
+#endif
+#endif
 
 #if JVET_AC0112_IBC_GPM
       static_vector<int, IBC_GPM_MAX_TRY_WEIGHTED_SATD> geoSplitDirList;
diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp
index 49f24f67..29c61a3b 100644
--- a/source/Lib/EncoderLib/EncSlice.cpp
+++ b/source/Lib/EncoderLib/EncSlice.cpp
@@ -1807,7 +1807,11 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
     if (cs.slice->getPOC() == 0 || cs.slice->getSliceType() == I_SLICE) // ensure sequential and parallel simulation generate same output
     {
       SPS* spsTmp = const_cast<SPS*>(cs.sps);
+#if ANCHOR_FIX_MR_380
+      hashBlkHitPerc = (hashBlkHitPerc == -1) ? m_pcCuEncoder->getIbcHashMap().calHashBlkMatchPerc(cs.area.Y()) : hashBlkHitPerc;
+#else
       hashBlkHitPerc == -1 ? m_pcCuEncoder->getIbcHashMap().calHashBlkMatchPerc(cs.area.Y()) : hashBlkHitPerc;
+#endif
       bool hashScc = hashBlkHitPerc < 57;
       spsTmp->setUseOBMC(hashScc);
 #if JVET_Z0061_TM_OBMC
diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp
index b4587978..39684b41 100644
--- a/source/Lib/EncoderLib/InterSearch.cpp
+++ b/source/Lib/EncoderLib/InterSearch.cpp
@@ -1106,8 +1106,10 @@ void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cSt
   const int   srchRngVerBottom = pcMvSrchRngRB->getVer();
 
   const unsigned int  lcuWidth = pu.cs->slice->getSPS()->getMaxCUWidth();
+#if JVET_AA0070_RRIBC || !IBC_OVERLAP
   const int   puPelOffsetX = 0;
   const int   puPelOffsetY = 0;
+#endif
   const int   cuPelX = pu.Y().x;
   const int   cuPelY = pu.Y().y;
 
@@ -1125,6 +1127,13 @@ void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cSt
 
   Distortion  sadBestCand[CHROMA_REFINEMENT_CANDIDATES];
   Mv      cMVCand[CHROMA_REFINEMENT_CANDIDATES];
+#if IBC_OVERLAP
+  const CompArea &area = pu.cu->blocks[COMPONENT_Y];
+  CompArea        tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
+  PelStorage m_tmpStorageCUPad;
+  m_tmpStorageCUPad.create(UnitArea(pu.chromaFormat, Area(0, 0, MAX_CU_SIZE, MAX_CU_SIZE)));
+  PelBuf tmpRefLuma = m_tmpStorageCUPad.getBuf(tmpArea);
+  #endif
 
 
   for (int cand = 0; cand < CHROMA_REFINEMENT_CANDIDATES; cand++)
@@ -1170,10 +1179,18 @@ void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cSt
         && !((yPred < srTop) || (yPred > srBottom))
         && !((xPred < srLeft) || (xPred > srRight)))
       {
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+#if JVET_Z0084_IBC_TM
+        bool validCand = PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth,rribcFlipType);
+#else
+        bool validCand = searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth,rribcFlipType);
+#endif
+#else
 #if JVET_Z0084_IBC_TM
         bool validCand = PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth);
 #else
         bool validCand = searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth);
+#endif
 #endif
 
         if (validCand)
@@ -1184,6 +1201,20 @@ void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cSt
           sad = m_pcRdCost->getBvCostMultiplePreds(xPred, yPred, pu.cs->sps->getAMVREnabledFlag());
 #endif
           m_cDistParam.cur.buf = piRefSrch + cStruct.iRefStride * yPred + xPred;
+#if IBC_OVERLAP
+          m_cDistParam.cur.stride = cStruct.iRefStride;
+#if JVET_AA0070_RRIBC
+          if (rribcFlipType == 0)
+#endif
+          {
+            int width = pu.lwidth();
+            int height = pu.lheight();
+            if(((xPred+width)>=1)&&((yPred+height)>=1))
+            {
+              PU::updateDistParam(pu, piRefSrch, cStruct.iRefStride, xPred, yPred, m_cDistParam,tmpRefLuma);
+            }
+          }
+#endif
           sad += m_cDistParam.distFunc(m_cDistParam);
 
           xIBCSearchMVCandUpdate(sad, xPred, yPred, sadBestCand, cMVCand);
@@ -1196,7 +1227,15 @@ void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cSt
     rcMv.set(bestX, bestY);
     sadBest = sadBestCand[0];
 
+#if IBC_OVERLAP
+#if JVET_AA0070_RRIBC
+    const int boundY = rribcFlipType ? (0 - roiHeight - puPelOffsetY) : -1;
+#else
+    const int boundY = -1;
+#endif
+#else
     const int boundY = (0 - roiHeight - puPelOffsetY);
+#endif
     for (int y = std::max(srchRngVerTop, 0 - cuPelY); y <= boundY; ++y)
     {
 #if JVET_AA0070_RRIBC
@@ -1205,10 +1244,18 @@ void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cSt
         continue;
       }
 #endif
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+#if JVET_Z0084_IBC_TM
+      if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, 0, y, lcuWidth,rribcFlipType))
+#else
+      if (!searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, 0, y, lcuWidth,rribcFlipType))
+#endif
+#else
 #if JVET_Z0084_IBC_TM
       if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, 0, y, lcuWidth))
 #else
       if (!searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, 0, y, lcuWidth))
+#endif
 #endif
       {
         continue;
@@ -1220,6 +1267,20 @@ void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cSt
       sad = m_pcRdCost->getBvCostMultiplePreds(0, y, pu.cs->sps->getAMVREnabledFlag());
 #endif
       m_cDistParam.cur.buf = piRefSrch + cStruct.iRefStride * y;
+#if IBC_OVERLAP
+      m_cDistParam.cur.stride = cStruct.iRefStride;
+#if JVET_AA0070_RRIBC
+      if (rribcFlipType == 0)
+#endif
+      {
+        int width = pu.lwidth();
+        int height = pu.lheight();
+        if(((0+width)>=1)&&((y+height)>=1))
+        {
+          PU::updateDistParam(pu, piRefSrch, cStruct.iRefStride, 0, y, m_cDistParam, tmpRefLuma);
+        }
+      }
+#endif
       sad += m_cDistParam.distFunc(m_cDistParam);
 
       xIBCSearchMVCandUpdate(sad, 0, y, sadBestCand, cMVCand);
@@ -1236,7 +1297,16 @@ void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cSt
     }
 
     const int boundX = std::max(srchRngHorLeft, -cuPelX);
+#if IBC_OVERLAP
+#if JVET_AA0070_RRIBC
+    const int startX = rribcFlipType ? (0 - roiWidth - puPelOffsetX) : -1;
+#else
+    const int startX = -1;
+#endif
+    for (int x = startX; x >= boundX; --x)
+#else
     for (int x = 0 - roiWidth - puPelOffsetX; x >= boundX; --x)
+#endif
     {
 #if JVET_AA0070_RRIBC
       if (rribcFlipType == 2 && x != 0)
@@ -1244,10 +1314,18 @@ void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cSt
         continue;
       }
 #endif
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+#if JVET_Z0084_IBC_TM
+      if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, 0, lcuWidth,rribcFlipType))
+#else
+      if (!searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, 0, lcuWidth,rribcFlipType))
+#endif
+#else
 #if JVET_Z0084_IBC_TM
       if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, 0, lcuWidth))
 #else
       if (!searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, 0, lcuWidth))
+#endif
 #endif
       {
         continue;
@@ -1259,6 +1337,20 @@ void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cSt
       sad = m_pcRdCost->getBvCostMultiplePreds(x, 0, pu.cs->sps->getAMVREnabledFlag());
 #endif
       m_cDistParam.cur.buf = piRefSrch + x;
+#if IBC_OVERLAP
+      m_cDistParam.cur.stride = cStruct.iRefStride;
+#if JVET_AA0070_RRIBC
+      if (rribcFlipType == 0)
+#endif
+      {
+        int width = pu.lwidth();
+        int height = pu.lheight();
+        if(((x+width)>=1)&&((0+height)>=1))
+        {
+          PU::updateDistParam(pu, piRefSrch, cStruct.iRefStride, x, 0, m_cDistParam,tmpRefLuma);
+        }
+      }
+#endif
       sad += m_cDistParam.distFunc(m_cDistParam);
 
 
@@ -1350,10 +1442,18 @@ void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cSt
           if ((x == 0) || ((int)(cuPelX + x + roiWidth) >= picWidth))
             continue;
 
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+#if JVET_Z0084_IBC_TM
+          if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, y, lcuWidth,rribcFlipType))
+#else
+          if (!searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, y, lcuWidth,rribcFlipType))
+#endif
+#else
 #if JVET_Z0084_IBC_TM
           if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, y, lcuWidth))
 #else
           if (!searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, y, lcuWidth))
+#endif
 #endif
           {
             continue;
@@ -1365,6 +1465,20 @@ void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cSt
           sad = m_pcRdCost->getBvCostMultiplePreds(x, y, pu.cs->sps->getAMVREnabledFlag());
 #endif
           m_cDistParam.cur.buf = piRefSrch + cStruct.iRefStride * y + x;
+#if IBC_OVERLAP
+          m_cDistParam.cur.stride = cStruct.iRefStride;
+#if JVET_AA0070_RRIBC
+          if (rribcFlipType == 0)
+#endif
+          {
+            int width = pu.lwidth();
+            int height = pu.lheight();
+            if(((x+width)>=1)&&((y+height)>=1))
+            {
+              PU::updateDistParam(pu, piRefSrch, cStruct.iRefStride, x, y, m_cDistParam,tmpRefLuma);
+            }
+          }
+#endif
           sad += m_cDistParam.distFunc(m_cDistParam);
 
           xIBCSearchMVCandUpdate(sad, x, y, sadBestCand, cMVCand);
@@ -1431,10 +1545,18 @@ void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cSt
           if ((x == 0) || ((int)(cuPelX + x + roiWidth) >= picWidth))
             continue;
 
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+#if JVET_Z0084_IBC_TM
+          if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, y, lcuWidth,rribcFlipType))
+#else
+          if (!searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, y, lcuWidth,rribcFlipType))
+#endif
+#else
 #if JVET_Z0084_IBC_TM
           if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, y, lcuWidth))
 #else
           if (!searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, y, lcuWidth))
+#endif
 #endif
           {
             continue;
@@ -1447,6 +1569,20 @@ void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cSt
 #endif
 
           m_cDistParam.cur.buf = piRefSrch + cStruct.iRefStride * y + x;
+#if IBC_OVERLAP
+          m_cDistParam.cur.stride = cStruct.iRefStride;
+#if JVET_AA0070_RRIBC
+          if (rribcFlipType == 0)
+#endif
+          {
+            int width = pu.lwidth();
+            int height = pu.lheight();
+            if(((x+width)>=1)&&((y+height)>=1))
+            {
+              PU::updateDistParam(pu, piRefSrch, cStruct.iRefStride, x, y, m_cDistParam,tmpRefLuma);
+            }
+          }
+#endif
           sad += m_cDistParam.distFunc(m_cDistParam);
 
 
@@ -1533,10 +1669,18 @@ void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cSt
           if ((x == 0) || ((int)(cuPelX + x + roiWidth) >= picWidth))
             continue;
 
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+#if JVET_Z0084_IBC_TM
+          if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, y, lcuWidth,rribcFlipType))
+#else
+          if (!searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, y, lcuWidth,rribcFlipType))
+#endif
+#else
 #if JVET_Z0084_IBC_TM
           if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, y, lcuWidth))
 #else
           if (!searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, y, lcuWidth))
+#endif
 #endif
           {
             continue;
@@ -1548,6 +1692,20 @@ void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cSt
           sad = m_pcRdCost->getBvCostMultiplePreds(x, y, pu.cs->sps->getAMVREnabledFlag());
 #endif
           m_cDistParam.cur.buf = piRefSrch + cStruct.iRefStride * y + x;
+#if IBC_OVERLAP
+          m_cDistParam.cur.stride = cStruct.iRefStride;
+#if JVET_AA0070_RRIBC
+          if (rribcFlipType == 0)
+#endif
+          {
+            int width = pu.lwidth();
+            int height = pu.lheight();
+            if(((x+width)>=1)&&((y+height)>=1))
+            {
+              PU::updateDistParam(pu, piRefSrch, cStruct.iRefStride, x, y, m_cDistParam,tmpRefLuma);
+            }
+          }
+#endif
           sad += m_cDistParam.distFunc(m_cDistParam);
 
 
@@ -1619,6 +1777,10 @@ end:
     m_ctuRecord[pu.lumaPos()][pu.lumaSize()].bvRecord[cMVCand[cand]] = sadBestCand[cand];
   }
 
+#if IBC_OVERLAP
+  m_tmpStorageCUPad.destroy();
+#endif
+
   return;
 }
 
@@ -1724,6 +1886,16 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Mv *pc
   }
 #endif
 
+#if IBC_OVERLAP
+#if !JVET_AA0070_RRIBC
+  const CompArea &area = pu.blocks[COMPONENT_Y];
+  CompArea    tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
+#endif
+  PelStorage m_tmpStorageCUPad;
+  m_tmpStorageCUPad.create(UnitArea(pu.chromaFormat, Area(0, 0, MAX_CU_SIZE, MAX_CU_SIZE)));
+  PelBuf tmpRefLuma = m_tmpStorageCUPad.getBuf(tmpArea);
+#endif
+
   m_lumaClpRng = pu.cs->slice->clpRng(COMPONENT_Y);
   Picture* refPic = pu.cu->slice->getPic();
   const CPelBuf refBuf = refPic->getRecoBuf(pu.blocks[COMPONENT_Y]);
@@ -1807,10 +1979,18 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Mv *pc
           {
             continue;
           }
+#if IBC_OVERLAP
+#if JVET_Z0084_IBC_TM
+          if (PU::searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xBv, yBv, lcuWidth,rribcFlipType))
+#else
+          if (searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xBv, yBv, lcuWidth,rribcFlipType))
+#endif
+#else
 #if JVET_Z0084_IBC_TM
           if (PU::searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xBv, yBv, lcuWidth))
 #else
           if (searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xBv, yBv, lcuWidth))
+#endif
 #endif
           {
             buffered = true;
@@ -1818,6 +1998,20 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Mv *pc
             cStruct.pcPatternKey = (rribcFlipType == 0) ? pcPatternKey : ((rribcFlipType == 1) ? pcPatternKeyFlipH : pcPatternKeyFlipV);
             m_pcRdCost->setDistParam(m_cDistParam, *cStruct.pcPatternKey, cStruct.piRefY, cStruct.iRefStride, m_lumaClpRng.bd, COMPONENT_Y, cStruct.subShiftMode);
             m_cDistParam.cur.buf = cStruct.piRefY + cStruct.iRefStride * yBv + xBv;
+#if IBC_OVERLAP
+            m_cDistParam.cur.stride = cStruct.iRefStride;
+#if JVET_AA0070_RRIBC
+            if (rribcFlipType == 0)
+#endif
+            {
+              int width = pu.lwidth();
+              int height = pu.lheight();
+              if(((xBv+width)>=1)&&((yBv+height)>=1))
+              {
+                PU::updateDistParam(pu, cStruct.piRefY, cStruct.iRefStride, xBv, yBv, m_cDistParam,tmpRefLuma);
+              }
+            }
+#endif
             sad += m_cDistParam.distFunc(m_cDistParam);
             if (!isCalc[rribcFlipType])
             {
@@ -1865,16 +2059,38 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Mv *pc
             {
               continue;
             }
+#if IBC_OVERLAP
+#if JVET_Z0084_IBC_TM
+            if (PU::searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xPred, yPred, lcuWidth,rribcFlipType))
+#else
+            if (searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xPred, yPred, lcuWidth,rribcFlipType))
+#endif
+#else
 #if JVET_Z0084_IBC_TM
             if (PU::searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xPred, yPred, lcuWidth))
 #else
             if (searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xPred, yPred, lcuWidth))
+#endif
 #endif
             {
               Distortion sad = m_pcRdCost->getBvCostMultiplePreds(xPred, yPred, pu.cs->sps->getAMVREnabledFlag(), rribcFlipType);
               cStruct.pcPatternKey = (rribcFlipType == 0) ? pcPatternKey : ((rribcFlipType == 1) ? pcPatternKeyFlipH : pcPatternKeyFlipV);
               m_pcRdCost->setDistParam(m_cDistParam, *cStruct.pcPatternKey, cStruct.piRefY, cStruct.iRefStride, m_lumaClpRng.bd, COMPONENT_Y, cStruct.subShiftMode);
               m_cDistParam.cur.buf = cStruct.piRefY + cStruct.iRefStride * yPred + xPred;
+#if IBC_OVERLAP
+              m_cDistParam.cur.stride = cStruct.iRefStride;
+#if JVET_AA0070_RRIBC
+              if (rribcFlipType == 0)
+#endif
+              {
+                int width = pu.lwidth();
+                int height = pu.lheight();
+                if(((xPred+width)>=1)&&((yPred+height)>=1))
+                {
+                  PU::updateDistParam(pu, cStruct.piRefY, cStruct.iRefStride, xPred, yPred, m_cDistParam,tmpRefLuma);
+                }
+              }
+#endif
               sad += m_cDistParam.distFunc(m_cDistParam);
               if (sad >= minCostProj)
               {
@@ -1946,6 +2162,19 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Mv *pc
           {
             continue;
           }
+#if IBC_OVERLAP
+          if (rribcFlipType)
+          {
+#if JVET_Z0084_IBC_TM
+            if (!PU::searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xBv, yBv, lcuWidth,rribcFlipType))
+#else
+            if (!searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xBv, yBv, lcuWidth,rribcFlipType))
+#endif
+            {
+              continue;
+            }
+          }
+#endif
           buffered = true;
           Distortion sad = m_pcRdCost->getBvCostMultiplePreds(xBv, yBv, pu.cs->sps->getAMVREnabledFlag(), rribcFlipType);
           cStruct.pcPatternKey = (rribcFlipType == 0) ? pcPatternKey : ((rribcFlipType == 1) ? pcPatternKeyFlipH : pcPatternKeyFlipV);
@@ -1955,6 +2184,20 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Mv *pc
         Distortion sad = m_pcRdCost->getBvCostMultiplePreds(xBv, yBv, pu.cs->sps->getAMVREnabledFlag());
 #endif
         m_cDistParam.cur.buf = cStruct.piRefY + cStruct.iRefStride * yBv + xBv;
+#if IBC_OVERLAP
+        m_cDistParam.cur.stride = cStruct.iRefStride;
+#if JVET_AA0070_RRIBC
+        if (rribcFlipType == 0)
+#endif
+        {
+          int width = pu.lwidth();
+          int height = pu.lheight();
+          if(((xBv+width)>=1)&&((yBv+height)>=1))
+          {
+            PU::updateDistParam(pu, cStruct.piRefY, cStruct.iRefStride, xBv, yBv, m_cDistParam,tmpRefLuma);
+          }
+        }
+#endif
         sad += m_cDistParam.distFunc(m_cDistParam);
         if (sad < ruiCost)
         {
@@ -2012,6 +2255,19 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Mv *pc
             {
               continue;
             }
+#if IBC_OVERLAP
+            if (rribcFlipType)
+            {
+#if JVET_Z0084_IBC_TM
+              if (!PU::searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xPred, yPred, lcuWidth,rribcFlipType))
+#else
+              if (!searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xPred, yPred, lcuWidth,rribcFlipType))
+#endif
+              {
+                continue;
+              }
+            }
+#endif
             Distortion sad = m_pcRdCost->getBvCostMultiplePreds(xPred, yPred, pu.cs->sps->getAMVREnabledFlag(), rribcFlipType);
             cStruct.pcPatternKey = (rribcFlipType == 0) ? pcPatternKey : ((rribcFlipType == 1) ? pcPatternKeyFlipH : pcPatternKeyFlipV);
             m_pcRdCost->setDistParam(m_cDistParam, *cStruct.pcPatternKey, cStruct.piRefY, cStruct.iRefStride, m_lumaClpRng.bd, COMPONENT_Y, cStruct.subShiftMode);
@@ -2019,6 +2275,20 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Mv *pc
           Distortion sad = m_pcRdCost->getBvCostMultiplePreds(xPred, yPred, pu.cs->sps->getAMVREnabledFlag());
 #endif
           m_cDistParam.cur.buf = cStruct.piRefY + cStruct.iRefStride * yPred + xPred;
+#if IBC_OVERLAP
+          m_cDistParam.cur.stride = cStruct.iRefStride;
+#if JVET_AA0070_RRIBC
+          if (rribcFlipType == 0)
+#endif
+          {
+            int width = pu.lwidth();
+            int height = pu.lheight();
+            if(((xPred+width)>=1)&&((yPred+height)>=1))
+            {
+              PU::updateDistParam(pu, cStruct.piRefY, cStruct.iRefStride, xPred, yPred, m_cDistParam,tmpRefLuma);
+            }
+          }
+#endif
           sad += m_cDistParam.distFunc(m_cDistParam);
           if (sad < ruiCost)
           {
@@ -2085,6 +2355,9 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Mv *pc
     xIntraPatternSearch(pu, cStruct, rcMv, ruiCost, &cMvSrchRngLT, &cMvSrchRngRB, pcMvPred);
   }
 #endif
+#if IBC_OVERLAP
+  m_tmpStorageCUPad.destroy();
+#endif
 }
 
 // based on xSetSearchRange
@@ -2785,17 +3058,35 @@ void InterSearch::xxIBCHashSearch(PredictionUnit &pu, Mv *mvPred, int numMvPred,
     for (std::vector<Position>::iterator pos = candPos.begin(); pos != candPos.end(); pos++)
     {
 #endif
+#if JVET_AA0070_RRIBC || !IBC_OVERLAP
       Position bottomRight = pos->offset(pu.Y().width - 1, pu.Y().height - 1);
+#endif
+#if IBC_OVERLAP
+#if JVET_AA0070_RRIBC
+      if (pu.cs->isDecomp(*pos, CHANNEL_TYPE_LUMA) && (!rribcFlipType || pu.cs->isDecomp(bottomRight, CHANNEL_TYPE_LUMA)))
+#else
+      if (pu.cs->isDecomp(*pos, CHANNEL_TYPE_LUMA))
+#endif
+#else
       if (pu.cs->isDecomp(*pos, CHANNEL_TYPE_LUMA) && pu.cs->isDecomp(bottomRight, CHANNEL_TYPE_LUMA))
+#endif
       {
         Position tmp = *pos - pu.Y().pos();
         Mv candMv;
         candMv.set(tmp.x, tmp.y);
 
+#if IBC_OVERLAP && JVET_AA0070_RRIBC
+#if JVET_Z0084_IBC_TM
+        if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, candMv.getHor(), candMv.getVer(), lcuWidth,rribcFlipType))
+#else
+        if (!searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, candMv.getHor(), candMv.getVer(), lcuWidth,rribcFlipType))
+#endif
+#else
 #if JVET_Z0084_IBC_TM
         if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, candMv.getHor(), candMv.getVer(), lcuWidth))
 #else
         if (!searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, candMv.getHor(), candMv.getVer(), lcuWidth))
+#endif
 #endif
         {
           continue;
@@ -11926,7 +12217,11 @@ uint64_t InterSearch::xCalcPuMeBits(PredictionUnit& pu)
 }
 
 #if !JVET_Z0084_IBC_TM
+#if IBC_OVERLAP
+bool InterSearch::searchBv(PredictionUnit& pu, int xPos, int yPos, int width, int height, int picWidth, int picHeight, int xBv, int yBv, int ctuSize, int rribcFlipType)
+#else
 bool InterSearch::searchBv(PredictionUnit& pu, int xPos, int yPos, int width, int height, int picWidth, int picHeight, int xBv, int yBv, int ctuSize)
+#endif
 {
   const int ctuSizeLog2 = floorLog2(ctuSize);
 
@@ -11953,10 +12248,24 @@ bool InterSearch::searchBv(PredictionUnit& pu, int xPos, int yPos, int width, in
   {
     return false;
   }
-  if ((xBv + width) > 0 && (yBv + height) > 0)
+#if IBC_OVERLAP
+  if (rribcFlipType)
   {
-    return false;
+#endif
+    if ((xBv + width) > 0 && (yBv + height) > 0)
+    {
+      return false;
+    }
+#if IBC_OVERLAP
+  }
+  else
+  {
+    if ((xBv + width) > 0 && (yBv + height) > 0 && ((xBv > 0) || (yBv > 0)))
+    {
+      return false;
+    }
   }
+#endif
 
 #if !JVET_Z0153_IBC_EXT_REF
   // Don't search the above CTU row
@@ -12042,8 +12351,22 @@ bool InterSearch::searchBv(PredictionUnit& pu, int xPos, int yPos, int width, in
   const Position refPosLT = pu.Y().topLeft().offset(xBv, yBv);
   const Position refPosBR = pu.Y().bottomRight().offset(xBv, yBv);
   const ChannelType      chType = toChannelType(COMPONENT_Y);
-  if (!pu.cs->isDecomp(refPosBR, chType))
-    return false;
+#if IBC_OVERLAP
+  if (rribcFlipType)
+  {
+#endif
+    if (!pu.cs->isDecomp(refPosBR, chType))
+      return false;
+#if IBC_OVERLAP
+  }
+  else
+  {
+    if (!pu.cs->isDecomp(refPosBR, chType) && ((xBv > 0) || (yBv > 0)))
+    {
+      return false;
+    }
+  }
+#endif
   if (!pu.cs->isDecomp(refPosLT, chType))
     return false;
   return true;
diff --git a/source/Lib/EncoderLib/InterSearch.h b/source/Lib/EncoderLib/InterSearch.h
index 561930e9..8a085d1e 100644
--- a/source/Lib/EncoderLib/InterSearch.h
+++ b/source/Lib/EncoderLib/InterSearch.h
@@ -702,7 +702,11 @@ public:
   void resetSavedAffineMotion();
   void storeAffineMotion( Mv acAffineMv[2][3], int8_t affineRefIdx[2], EAffineModel affineType, int bcwIdx );
 #if !JVET_Z0084_IBC_TM
+#if IBC_OVERLAP
+  bool searchBv(PredictionUnit& pu, int xPos, int yPos, int width, int height, int picWidth, int picHeight, int xBv, int yBv, int ctuSize,int rribcFlipType = 0);
+#else
   bool searchBv(PredictionUnit& pu, int xPos, int yPos, int width, int height, int picWidth, int picHeight, int xBv, int yBv, int ctuSize);
+#endif
 #endif
   void setClipMvInSubPic(bool flag) { m_clipMvInSubPic = flag; }
 protected:
