Index: lib/Transforms/Scalar/LoopInterchange.cpp =================================================================== --- lib/Transforms/Scalar/LoopInterchange.cpp +++ lib/Transforms/Scalar/LoopInterchange.cpp @@ -958,6 +958,18 @@ return false; } + // Check if outer and inner loop contain legal instructions only. + for (auto *BB : OuterLoop->blocks()) + for (Instruction &I : *BB) + if (CallInst *CI = dyn_cast(&I)) { + // readnone functions do not prevent interchanging. + if (CI->doesNotReadMemory()) + continue; + DEBUG(dbgs() << "Loops with call instructions cannot be interchanged " + << "safely."); + return false; + } + // Create unique Preheaders if we already do not have one. BasicBlock *OuterLoopPreHeader = OuterLoop->getLoopPreheader(); BasicBlock *InnerLoopPreHeader = InnerLoop->getLoopPreheader(); Index: test/Transforms/LoopInterchange/call-instructions.ll =================================================================== --- /dev/null +++ test/Transforms/LoopInterchange/call-instructions.ll @@ -0,0 +1,158 @@ +; RUN: opt < %s -basicaa -loop-interchange -S | FileCheck %s +;; We test the complete .ll for adjustment in outer loop header/latch and inner loop header/latch. + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@A = common global [100 x [100 x i32]] zeroinitializer + +declare void @foo(i64 %a) +declare void @bar(i64 %a) readnone + +;;--------------------------------------Test case 01------------------------------------ +;; Not safe to interchange, because the called function `foo` is not marked as +;; readnone, so it could introduce dependences. +;; +;; for(int i=0;i