Index: include/llvm/Analysis/AliasSetTracker.h =================================================================== --- include/llvm/Analysis/AliasSetTracker.h +++ include/llvm/Analysis/AliasSetTracker.h @@ -468,6 +468,7 @@ /// pointer. AliasSet &mergeAllAliasSets(); +public: // HACK: fixme AliasSet *findAliasSetForUnknownInst(Instruction *Inst); }; Index: lib/Transforms/Scalar/LICM.cpp =================================================================== --- lib/Transforms/Scalar/LICM.cpp +++ lib/Transforms/Scalar/LICM.cpp @@ -658,6 +658,7 @@ if (CI->mayThrow()) return false; +#if 0 if (Function *F = CI->getCalledFunction()) switch (F->getIntrinsicID()) { default: break; @@ -666,7 +667,7 @@ // Assumes don't actually alias anything or throw return true; }; - + // Handle simple cases by querying alias analysis. FunctionModRefBehavior Behavior = AA->getModRefBehavior(CI); if (Behavior == FMRB_DoesNotAccessMemory) @@ -683,17 +684,38 @@ return false; return true; } + // If this call only reads from memory and there are no writes to memory // in the loop, we can hoist or sink the call as appropriate. if (isReadOnly(CurAST)) return true; } +#endif - // FIXME: This should use mod/ref information to see if we can hoist or - // sink the call. + AliasSet *AS = CurAST->findAliasSetForUnknownInst(CI); + if (!AS) + // Was considered by AST not to alias any possible memory location + return true; + if (!AS->isMod()) + // The call (which must be readonly per AST) does read memory clobbered + // in the loop. + return true; +#if 1 + // May contain a clobber, give up! return false; +#else + // Now check for a uniquely writing instruction within the loop. In this + // case, the value written can't be overwritten or read within the loop. + // NOTE: Drop in first patch. + auto *UniqueI = AS->getUniqueInstruction(); + if (!UniqueI) + // other memory op, give up + return false; + assert(UniqueI == CI && "AS must contain FI"); + return true; +#endif } else if (auto *FI = dyn_cast(&I)) { // Fences alias (most) everything to provide ordering. For the moment, // just give up if there are any other memory operations in the loop.