Index: include/llvm/Analysis/ScalarEvolution.h =================================================================== --- include/llvm/Analysis/ScalarEvolution.h +++ include/llvm/Analysis/ScalarEvolution.h @@ -1509,6 +1509,9 @@ ScalarEvolution *getSE() const { return &SE; } /// We need to explicitly define the copy constructor because of FlagsMap. PredicatedScalarEvolution(const PredicatedScalarEvolution&); + /// Print the SCEV mappings done by the Predicated Scalar Evolution. + /// The printed text is indented by \p Depth. + void print(raw_ostream &OS, unsigned Depth) const; private: /// \brief Increments the version number of the predicate. /// This needs to be called every time the SCEV predicate changes. Index: lib/Analysis/LoopAccessAnalysis.cpp =================================================================== --- lib/Analysis/LoopAccessAnalysis.cpp +++ lib/Analysis/LoopAccessAnalysis.cpp @@ -1904,6 +1904,11 @@ OS.indent(Depth) << "SCEV assumptions:\n"; PSE.getUnionPredicate().print(OS, Depth); + + OS << "\n"; + + OS.indent(Depth) << "Expressions re-written:\n"; + PSE.print(OS, Depth); } const LoopAccessInfo & Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp +++ lib/Analysis/ScalarEvolution.cpp @@ -10221,3 +10221,30 @@ for (auto I = Init.FlagsMap.begin(), E = Init.FlagsMap.end(); I != E; ++I) FlagsMap.insert(*I); } + +void PredicatedScalarEvolution::print(raw_ostream &OS, unsigned Depth) const { + // For each block. + for (Loop::block_iterator bb = L.block_begin(), + be = L.block_end(); bb != be; ++bb) + + for (BasicBlock::iterator it = (*bb)->begin(), e = (*bb)->end(); + it != e; ++it) { + Instruction *I = &*it; + if (!SE.isSCEVable(I->getType())) + continue; + + auto *Expr = SE.getSCEV(I); + auto II = RewriteMap.find(Expr); + + if (II == RewriteMap.end()) + continue; + + // Don't print things that are not interesting. + if (II->second.second == Expr) + continue; + + OS.indent(Depth) << "[PSE]" << *I << ":\n"; + OS.indent(Depth + 2) << *Expr << "\n"; + OS.indent(Depth + 2) << "--> " << *II->second.second << "\n"; + } +} Index: test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll =================================================================== --- test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll +++ test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll @@ -31,6 +31,11 @@ ; We have added the nusw flag to turn this expression into the SCEV expression: ; i64 {0,+,2}<%for.body> +; LAA: [PSE] %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext: +; LAA-NEXT: ((2 * (zext i32 {0,+,2}<%for.body> to i64)) + %a) +; LAA-NEXT: --> {%a,+,4}<%for.body> + + ; LV-LABEL: f1 ; LV-LABEL: for.body.lver.check ; LV: [[PredCheck0:%[^ ]*]] = icmp ne i128 @@ -100,6 +105,10 @@ ; We have added the nusw flag to turn this expression into the following SCEV: ; i64 {zext i32 (2 * (trunc i64 %N to i32)) to i64,+,-2}<%for.body> +; LAA: [PSE] %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext: +; LAA-NEXT: ((2 * (zext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64)) + %a) +; LAA-NEXT: --> {((2 * (zext i32 (2 * (trunc i64 %N to i32)) to i64)) + %a),+,-4}<%for.body> + ; LV-LABEL: f2 ; LV-LABEL: for.body.lver.check ; LV: [[PredCheck0:%[^ ]*]] = icmp ne i128 @@ -154,6 +163,10 @@ ; We have added the nssw flag to turn this expression into the following SCEV: ; i64 {0,+,2}<%for.body> +; LAA: [PSE] %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext: +; LAA-NEXT: ((2 * (sext i32 {0,+,2}<%for.body> to i64)) + %a) +; LAA-NEXT: --> {%a,+,4}<%for.body> + ; LV-LABEL: f3 ; LV-LABEL: for.body.lver.check ; LV: [[PredCheck0:%[^ ]*]] = icmp ne i128 @@ -204,6 +217,10 @@ ; We have added the nssw flag to turn this expression into the following SCEV: ; i64 {sext i32 (2 * (trunc i64 %N to i32)) to i64,+,-2}<%for.body> +; LAA: [PSE] %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext: +; LAA-NEXT: ((2 * (sext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64)) + %a) +; LAA-NEXT: --> {((2 * (sext i32 (2 * (trunc i64 %N to i32)) to i64)) + %a),+,-4}<%for.body> + ; LV-LABEL: f4 ; LV-LABEL: for.body.lver.check ; LV: [[PredCheck0:%[^ ]*]] = icmp ne i128 @@ -257,6 +274,10 @@ ; LAA-NEXT: {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> Added Flags: ; LAA-NEXT: {((2 * (sext i32 (2 * (trunc i64 %N to i32)) to i64)) + %a),+,-4}<%for.body> Added Flags: +; LAA: [PSE] %arrayidxA = getelementptr inbounds i16, i16* %a, i32 %mul: +; LAA-NEXT: ((2 * (sext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64)) + %a) +; LAA-NEXT: --> {((2 * (sext i32 (2 * (trunc i64 %N to i32)) to i64)) + %a),+,-4}<%for.body> + ; LV-LABEL: f5 ; LV-LABEL: for.body.lver.check define void @f5(i16* noalias %a,