Index: llvm/lib/Transforms/Scalar/LoopFlatten.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopFlatten.cpp +++ llvm/lib/Transforms/Scalar/LoopFlatten.cpp @@ -679,7 +679,18 @@ auto *AC = &AM.getResult(F); auto *TTI = &AM.getResult(F); - if (!Flatten(DT, LI, SE, AC, TTI)) + bool Changed = false; + + // The loop flattening pass requires loops to be in simplified form. + // Running this pass will simplify all loops, + // regardless of whether anything ends up being flattened. + for (auto &L : *LI) + Changed |= + simplifyLoop(L, DT, LI, SE, AC, nullptr, false /* PreserveLCSSA */); + + Changed |= Flatten(DT, LI, SE, AC, TTI); + + if (!Changed) return PreservedAnalyses::all(); return PreservedAnalyses::none(); Index: llvm/test/Transforms/LoopFlatten/loop-flatten-simplify-cfg.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/LoopFlatten/loop-flatten-simplify-cfg.ll @@ -0,0 +1,82 @@ +;; This test was created to ensure that the LoopFlatten pass can +;; operate on loops that are not in simplified form before applying the pass. +;; +;; It was generated by running following command: +;; clang test.c -target aarch64-arm-none-eabi -Ofast -mllvm -enable-loop-flatten -fno-vectorize -fno-unroll-loops -S -emit-llvm -mllvm -opt-bisect-limit=50 -S -emit-llvm +;; Where test.c: +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;void add(unsigned N, int *A, short val) { +;; int i,j; +;; for (i=0; i