<div dir="ltr">Hi Andrew,<div><br></div><div>(Let me know if someone else is more appropriate to review this).  This patch removes setPreservesCFG() from the instcombine pass.  The reason is that InstCombine can modify terminator instructions (branches) specifically the predicate.  Instcombine clears out dead blocks and replaces all the dead instruction uses with undef:</div><div><br></div><div><a href="http://llvm.org/docs/doxygen/html/InstructionCombining_8cpp_source.html#l02792">http://llvm.org/docs/doxygen/html/InstructionCombining_8cpp_source.html#l02792</a><br></div><div><br></div><div>These new undefs can be predicates of branches, and from the comment of setPreservesCFG():</div><div><div><br></div><div>// setPreservesCFG - This function should be called to by the pass, iff they do</div><div>// not:</div><div>//</div><div>//  1. Add or remove basic blocks from the function</div><div>//  2. Modify terminator instructions in any way.</div></div><div><br></div><div>Clearly instcombine is modifying terminator instructions so should not be calling setPreservesCFG().  The specific issue I ran into was a dead loop not being deleted because of stale analysis data.  Repro:</div><div><br></div><div><div>void foo(int *a, int start_x, int end_x, int start_y, int end_y, int k) {</div><div>  for (int y = start_y; y < end_y; y++) {</div><div>    for (int x = start_x; x < end_x; x++) {</div><div>      for (int i = 0; i < 1000; i++) {</div><div>        a[x + y + k*i] = 0;</div><div>      }</div><div>    }</div><div>  }</div><div>}</div></div><div><br></div><div># Dead loop left after loop deletion:</div><div>clang -S -emit-llvm foo.c -o - | opt -O1 -loop-rotate -loop-unswitch -instcombine -loop-deletion -S > bad.ll<br></div><div><br></div><div># Dead loop removed by splitting out loop-deletion into separate opt invocation:</div><div>clang -S -emit-llvm foo.c -o - | opt -O1 -loop-rotate -loop-unswitch -instcombine | opt -loop-deletion -S > good.ll<br></div><div><br></div><div>This patch fixes this discrepancy.</div><div><br></div><div>Mark</div></div>