diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
--- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -1876,8 +1876,31 @@
           // We are searching for the definition of the store's destination.
           // So, if that is the same definition as the load, then this is a
           // noop. Otherwise, fail.
-          if (LoadAccess != Current)
+          if (LoadAccess != Current) {
+            auto *CurrentDef = cast<MemoryDef>(Current);
+            if (auto *CurrentStoreI =
+                    dyn_cast_or_null<StoreInst>(CurrentDef->getMemoryInst()))
+              // Check alignment to ensure load or store does not access at an
+              // offset.
+              if (CurrentStoreI->getValueOperand() == LoadI) {
+                // This is a potentially clobbering store, but it writes the
+                // same value, so we can safely ignore it if alignment is as
+                // expected.
+
+                TypeSize StoreSize = DL.getTypeStoreSize(LoadI->getType());
+                // Check alignment to ensure load or store does not access at
+                // an offset.
+                if (!StoreSize.isScalable() &&
+                    std::min(CurrentStoreI->getAlign(), LoadI->getAlign()) >=
+                        StoreSize) {
+                  ToCheck.insert(MSSA.getWalker()->getClobberingMemoryAccess(
+                      CurrentDef->getDefiningAccess(),
+                      MemoryLocation::get(Store)));
+                  continue;
+                }
+              }
             return false;
+          }
         }
         return true;
       }
diff --git a/llvm/test/Transforms/DeadStoreElimination/noop-stores.ll b/llvm/test/Transforms/DeadStoreElimination/noop-stores.ll
--- a/llvm/test/Transforms/DeadStoreElimination/noop-stores.ll
+++ b/llvm/test/Transforms/DeadStoreElimination/noop-stores.ll
@@ -672,7 +672,6 @@
 ; CHECK-LABEL: @store_same_i32_to_mayalias_loc(
 ; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P:%.*]], align 4
 ; CHECK-NEXT:    store i32 [[V]], ptr [[Q:%.*]], align 4
-; CHECK-NEXT:    store i32 [[V]], ptr [[P]], align 4
 ; CHECK-NEXT:    ret void
 ;
   %v = load i32, ptr %p, align 4
@@ -698,7 +697,6 @@
 ; CHECK-LABEL: @store_same_i12_to_mayalias_loc(
 ; CHECK-NEXT:    [[V:%.*]] = load i12, ptr [[P:%.*]], align 2
 ; CHECK-NEXT:    store i12 [[V]], ptr [[Q:%.*]], align 2
-; CHECK-NEXT:    store i12 [[V]], ptr [[P]], align 2
 ; CHECK-NEXT:    ret void
 ;
   %v = load i12, ptr %p, align 2
@@ -724,7 +722,6 @@
 ; CHECK-LABEL: @store_same_ptr_to_mayalias_loc(
 ; CHECK-NEXT:    [[V:%.*]] = load ptr, ptr [[P:%.*]], align 8
 ; CHECK-NEXT:    store ptr [[V]], ptr [[Q:%.*]], align 8
-; CHECK-NEXT:    store ptr [[V]], ptr [[P]], align 8
 ; CHECK-NEXT:    ret void
 ;
   %v = load ptr, ptr %p, align 8
@@ -785,3 +782,63 @@
   store i8 %v, ptr %q, align 1
   ret void
 }
+
+define void @multiple_defs_between_noop_store_and_load(ptr %arg, ptr %arg1, i1 %arg2) {
+; CHECK-LABEL: @multiple_defs_between_noop_store_and_load(
+; CHECK-NEXT:  bb:
+; CHECK-NEXT:    [[TMP:%.*]] = load i32, ptr [[ARG:%.*]], align 8
+; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARG1:%.*]], align 8
+; CHECK-NEXT:    store i32 [[TMP3]], ptr [[ARG]], align 8
+; CHECK-NEXT:    store i32 [[TMP]], ptr [[ARG1]], align 8
+; CHECK-NEXT:    br i1 [[ARG2:%.*]], label [[BB5:%.*]], label [[BB6:%.*]]
+; CHECK:       bb5:
+; CHECK-NEXT:    store i32 [[TMP]], ptr [[ARG]], align 8
+; CHECK-NEXT:    store i32 [[TMP3]], ptr [[ARG1]], align 8
+; CHECK-NEXT:    ret void
+; CHECK:       bb6:
+; CHECK-NEXT:    ret void
+;
+bb:
+  %tmp = load i32, ptr %arg, align 8
+  %tmp3 = load i32, ptr %arg1, align 8
+  store i32 %tmp3, ptr %arg, align 8
+  store i32 %tmp, ptr %arg1, align 8
+  br i1 %arg2, label %bb5, label %bb6
+
+bb5:
+  store i32 %tmp, ptr %arg, align 8
+  store i32 %tmp3, ptr %arg1, align 8
+  ret void
+
+bb6:
+  ret void
+}
+
+define void @cross_noalias_store(i32 %v2, ptr %p, ptr %p2, i1 %c) {
+; CHECK-LABEL: @cross_noalias_store(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P2:%.*]], align 4
+; CHECK-NEXT:    store i32 [[V2:%.*]], ptr [[P2]], align 4, !alias.scope !0
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    store i32 [[V]], ptr [[P:%.*]], align 4, !noalias !0
+; CHECK-NEXT:    store i32 [[V]], ptr [[P2]], align 4
+; CHECK-NEXT:    br label [[ELSE]]
+; CHECK:       else:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %v = load i32, ptr %p2
+  store i32 %v2, ptr %p2, !alias.scope !0
+  br i1 %c, label %if.then, label %else
+if.then:
+  store i32 %v, ptr %p, !noalias !0
+  store i32 %v, ptr %p2
+  br label %else
+else:
+  ret void
+}
+
+!0 = !{!1}
+!1 = !{!1, !2, !"scope"}
+!2 = !{!2, !"domain"}
diff --git a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll
--- a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll
+++ b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll
@@ -594,7 +594,6 @@
 ; CHECK-LABEL: @pr49927(
 ; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P:%.*]], align 4
 ; CHECK-NEXT:    store i32 [[V]], ptr [[Q:%.*]], align 4
-; CHECK-NEXT:    store i32 [[V]], ptr [[P]], align 4
 ; CHECK-NEXT:    ret void
 ;
   %v = load i32, ptr %p, align 4