42574.patch 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. From 3757213db371dcea53cae357cf9c56d1b0604f98 Mon Sep 17 00:00:00 2001
  2. From: Alina Sbirlea <asbirlea@google.com>
  3. Date: Fri, 12 Jul 2019 22:30:30 +0000
  4. Subject: [PATCH] [MemorySSA] Use SetVector to avoid nondeterminism.
  5. Summary:
  6. Use a SetVector for DeadBlockSet.
  7. Resolves PR42574.
  8. Reviewers: george.burgess.iv, uabelho, dblaikie
  9. Subscribers: jlebar, Prazek, mgrang, llvm-commits
  10. Tags: #llvm
  11. Differential Revision: https://reviews.llvm.org/D64601
  12. llvm-svn: 365970
  13. diff --git a/llvm/include/llvm/Analysis/MemorySSAUpdater.h b/llvm/include/llvm/Analysis/MemorySSAUpdater.h
  14. index 169d5bd9fa8..276620bd445 100644
  15. --- a/llvm/include/llvm/Analysis/MemorySSAUpdater.h
  16. +++ b/llvm/include/llvm/Analysis/MemorySSAUpdater.h
  17. @@ -32,6 +32,7 @@
  18. #ifndef LLVM_ANALYSIS_MEMORYSSAUPDATER_H
  19. #define LLVM_ANALYSIS_MEMORYSSAUPDATER_H
  20. +#include "llvm/ADT/SetVector.h"
  21. #include "llvm/ADT/SmallPtrSet.h"
  22. #include "llvm/ADT/SmallSet.h"
  23. #include "llvm/ADT/SmallVector.h"
  24. @@ -239,7 +240,7 @@ public:
  25. /// Deleted blocks still have successor info, but their predecessor edges and
  26. /// Phi nodes may already be updated. Instructions in DeadBlocks should be
  27. /// deleted after this call.
  28. - void removeBlocks(const SmallPtrSetImpl<BasicBlock *> &DeadBlocks);
  29. + void removeBlocks(const SmallSetVector<BasicBlock *, 8> &DeadBlocks);
  30. /// Get handle on MemorySSA.
  31. MemorySSA* getMemorySSA() const { return MSSA; }
  32. diff --git a/llvm/lib/Analysis/MemorySSAUpdater.cpp b/llvm/lib/Analysis/MemorySSAUpdater.cpp
  33. index 6c817d20368..a6c7142a697 100644
  34. --- a/llvm/lib/Analysis/MemorySSAUpdater.cpp
  35. +++ b/llvm/lib/Analysis/MemorySSAUpdater.cpp
  36. @@ -1101,7 +1101,7 @@ void MemorySSAUpdater::removeMemoryAccess(MemoryAccess *MA) {
  37. }
  38. void MemorySSAUpdater::removeBlocks(
  39. - const SmallPtrSetImpl<BasicBlock *> &DeadBlocks) {
  40. + const SmallSetVector<BasicBlock *, 8> &DeadBlocks) {
  41. // First delete all uses of BB in MemoryPhis.
  42. for (BasicBlock *BB : DeadBlocks) {
  43. Instruction *TI = BB->getTerminator();
  44. diff --git a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
  45. index 2e5927f9a06..f464df26a02 100644
  46. --- a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
  47. +++ b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
  48. @@ -388,8 +388,8 @@ private:
  49. void deleteDeadLoopBlocks() {
  50. DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
  51. if (MSSAU) {
  52. - SmallPtrSet<BasicBlock *, 8> DeadLoopBlocksSet(DeadLoopBlocks.begin(),
  53. - DeadLoopBlocks.end());
  54. + SmallSetVector<BasicBlock *, 8> DeadLoopBlocksSet(DeadLoopBlocks.begin(),
  55. + DeadLoopBlocks.end());
  56. MSSAU->removeBlocks(DeadLoopBlocksSet);
  57. }
  58. for (auto *BB : DeadLoopBlocks) {
  59. diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
  60. index 5a67178cef3..814cf814989 100644
  61. --- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
  62. +++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
  63. @@ -1436,8 +1436,8 @@ deleteDeadClonedBlocks(Loop &L, ArrayRef<BasicBlock *> ExitBlocks,
  64. // Remove all MemorySSA in the dead blocks
  65. if (MSSAU) {
  66. - SmallPtrSet<BasicBlock *, 16> DeadBlockSet(DeadBlocks.begin(),
  67. - DeadBlocks.end());
  68. + SmallSetVector<BasicBlock *, 8> DeadBlockSet(DeadBlocks.begin(),
  69. + DeadBlocks.end());
  70. MSSAU->removeBlocks(DeadBlockSet);
  71. }
  72. @@ -1455,7 +1455,7 @@ static void deleteDeadBlocksFromLoop(Loop &L,
  73. MemorySSAUpdater *MSSAU) {
  74. // Find all the dead blocks tied to this loop, and remove them from their
  75. // successors.
  76. - SmallPtrSet<BasicBlock *, 16> DeadBlockSet;
  77. + SmallSetVector<BasicBlock *, 8> DeadBlockSet;
  78. // Start with loop/exit blocks and get a transitive closure of reachable dead
  79. // blocks.
  80. diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
  81. index 499e611acb5..83dabcd7952 100644
  82. --- a/llvm/lib/Transforms/Utils/Local.cpp
  83. +++ b/llvm/lib/Transforms/Utils/Local.cpp
  84. @@ -2211,7 +2211,7 @@ bool llvm::removeUnreachableBlocks(Function &F, LazyValueInfo *LVI,
  85. assert(Reachable.size() < F.size());
  86. NumRemoved += F.size()-Reachable.size();
  87. - SmallPtrSet<BasicBlock *, 16> DeadBlockSet;
  88. + SmallSetVector<BasicBlock *, 8> DeadBlockSet;
  89. for (Function::iterator I = ++F.begin(), E = F.end(); I != E; ++I) {
  90. auto *BB = &*I;
  91. if (Reachable.count(BB))
  92. diff --git a/llvm/test/Analysis/MemorySSA/nondeterminism.ll b/llvm/test/Analysis/MemorySSA/nondeterminism.ll
  93. new file mode 100644
  94. index 00000000000..0bb3df30b58
  95. --- /dev/null
  96. +++ b/llvm/test/Analysis/MemorySSA/nondeterminism.ll
  97. @@ -0,0 +1,122 @@
  98. +; RUN: opt -simplifycfg -enable-mssa-loop-dependency -S --preserve-ll-uselistorder %s | FileCheck %s
  99. +; REQUIRES: x86-registered-target
  100. +; CHECK-LABEL: @n
  101. +; CHECK: uselistorder i16 0, { 3, 2, 4, 1, 5, 0, 6 }
  102. +
  103. +; Note: test was added in an effort to ensure determinism when updating memoryssa. See PR42574.
  104. +; If the uselistorder check becomes no longer relevant, the test can be disabled or removed.
  105. +
  106. +%rec9 = type { i16, i32, i32 }
  107. +
  108. +@a = global [1 x [1 x %rec9]] zeroinitializer
  109. +
  110. +define i16 @n() {
  111. + br label %..split_crit_edge
  112. +
  113. +..split_crit_edge: ; preds = %0
  114. + br label %.split
  115. +
  116. +bb4.us4: ; preds = %bb2.split.us32, %bb6.us28
  117. + %i.4.01.us5 = phi i16 [ %_tmp49.us30, %bb6.us28 ]
  118. + br label %g.exit4.us21
  119. +
  120. +bb1.i.us14: ; preds = %bb4.us4
  121. + br label %g.exit4.us21
  122. +
  123. +g.exit4.us21: ; preds = %bb1.i.us14, %g.exit4.critedge.us9
  124. + %i.4.02.us22 = phi i16 [ %i.4.01.us5, %bb4.us4 ], [ %i.4.01.us5, %bb1.i.us14 ]
  125. + br label %bb6.us28
  126. +
  127. +bb5.us26: ; preds = %g.exit4.us21
  128. + br label %bb6.us28
  129. +
  130. +bb6.us28: ; preds = %bb5.us26, %g.exit4.us21
  131. + %i.4.03.us29 = phi i16 [ %i.4.02.us22, %bb5.us26 ], [ %i.4.02.us22, %g.exit4.us21 ]
  132. + %_tmp49.us30 = add nuw nsw i16 %i.4.03.us29, 1
  133. + br label %bb4.us4
  134. +
  135. +bb4.us.us: ; preds = %bb2.split.us.us, %bb6.us.us
  136. + %i.4.01.us.us = phi i16 [ %_tmp49.us.us, %bb6.us.us ]
  137. + br label %bb1.i.us.us
  138. +
  139. +bb1.i.us.us: ; preds = %bb4.us.us
  140. + br label %g.exit4.us.us
  141. +
  142. +g.exit4.us.us: ; preds = %bb1.i.us.us, %g.exit4.critedge.us.us
  143. + %i.4.02.us.us = phi i16 [ %i.4.01.us.us, %bb1.i.us.us ]
  144. + br label %bb5.us.us
  145. +
  146. +bb5.us.us: ; preds = %g.exit4.us.us
  147. + br label %bb6.us.us
  148. +
  149. +bb6.us.us: ; preds = %bb5.us.us, %g.exit4.us.us
  150. + %i.4.03.us.us = phi i16 [ %i.4.02.us.us, %bb5.us.us ]
  151. + %_tmp49.us.us = add nuw nsw i16 %i.4.03.us.us, 1
  152. + br label %bb4.us.us
  153. +
  154. +
  155. +.split: ; preds = %..split_crit_edge
  156. + br label %bb2
  157. +
  158. +bb2: ; preds = %.split, %bb7
  159. + %h.3.0 = phi i16 [ undef, %.split ], [ %_tmp53, %bb7 ]
  160. + br label %bb2.bb2.split_crit_edge
  161. +
  162. +bb2.bb2.split_crit_edge: ; preds = %bb2
  163. + br label %bb2.split
  164. +
  165. +bb2.split.us: ; preds = %bb2
  166. + br label %bb4.us
  167. +
  168. +bb4.us: ; preds = %bb6.us, %bb2.split.us
  169. + %i.4.01.us = phi i16 [ 0, %bb2.split.us ]
  170. + br label %bb1.i.us
  171. +
  172. +g.exit4.critedge.us: ; preds = %bb4.us
  173. + br label %g.exit4.us
  174. +
  175. +bb1.i.us: ; preds = %bb4.us
  176. + br label %g.exit4.us
  177. +
  178. +g.exit4.us: ; preds = %bb1.i.us, %g.exit4.critedge.us
  179. + %i.4.02.us = phi i16 [ %i.4.01.us, %g.exit4.critedge.us ], [ %i.4.01.us, %bb1.i.us ]
  180. + br label %bb5.us
  181. +
  182. +bb5.us: ; preds = %g.exit4.us
  183. + br label %bb7
  184. +
  185. +bb2.split: ; preds = %bb2.bb2.split_crit_edge
  186. + br label %bb4
  187. +
  188. +bb4: ; preds = %bb2.split, %bb6
  189. + %i.4.01 = phi i16 [ 0, %bb2.split ]
  190. + %_tmp16 = getelementptr [1 x [1 x %rec9]], [1 x [1 x %rec9]]* @a, i16 0, i16 %h.3.0, i16 %i.4.01, i32 0
  191. + %_tmp17 = load i16, i16* %_tmp16, align 1
  192. + br label %g.exit4.critedge
  193. +
  194. +bb1.i: ; preds = %bb4
  195. + br label %g.exit4
  196. +
  197. +g.exit4.critedge: ; preds = %bb4
  198. + %_tmp28.c = getelementptr [1 x [1 x %rec9]], [1 x [1 x %rec9]]* @a, i16 0, i16 %h.3.0, i16 %i.4.01, i32 1
  199. + %_tmp29.c = load i32, i32* %_tmp28.c, align 1
  200. + %_tmp30.c = trunc i32 %_tmp29.c to i16
  201. + br label %g.exit4
  202. +
  203. +g.exit4: ; preds = %g.exit4.critedge, %bb1.i
  204. + %i.4.02 = phi i16 [ %i.4.01, %g.exit4.critedge ], [ %i.4.01, %bb1.i ]
  205. + %_tmp41 = getelementptr [1 x [1 x %rec9]], [1 x [1 x %rec9]]* @a, i16 0, i16 %h.3.0, i16 %i.4.02, i32 2
  206. + br label %bb6
  207. +
  208. +bb5: ; preds = %g.exit4
  209. + br label %bb6
  210. +
  211. +bb6: ; preds = %bb5, %g.exit4
  212. + %i.4.03 = phi i16 [ %i.4.02, %bb5 ], [ %i.4.02, %g.exit4 ]
  213. + %_tmp49 = add nuw nsw i16 %i.4.03, 1
  214. + br label %bb7
  215. +
  216. +bb7: ; preds = %bb7.us-lcssa.us, %bb7.us-lcssa
  217. + %_tmp53 = add nsw i16 %h.3.0, 1
  218. + br label %bb2
  219. +}
  220. --
  221. 2.24.0