Index: lib/Transforms/Scalar/LoopInterchange.cpp =================================================================== --- lib/Transforms/Scalar/LoopInterchange.cpp +++ lib/Transforms/Scalar/LoopInterchange.cpp @@ -963,6 +963,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/interchange-call-instructions-readnone.ll =================================================================== --- /dev/null +++ test/Transforms/LoopInterchange/interchange-call-instructions-readnone.ll @@ -0,0 +1,59 @@ +; 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 +@B = common global [100 x i32] zeroinitializer +@C = common global [100 x [100 x i32]] zeroinitializer +@D = common global [100 x [100 x [100 x i32]]] zeroinitializer + +declare void @foo(i64 %a) readnone + +;;--------------------------------------Test case 01------------------------------------ +;; for(int i=0;i