This is an archive of the discontinued LLVM Phabricator instance.

[SCEV] Fix and validate ValueExprMap/ExprValueMap consistency
ClosedPublic

Authored by nikic on Nov 6 2021, 12:50 PM.

Details

Summary

This adds validation for consistency of ValueExprMap and ExprValueMap, and fixes identified issues:

  • Addrec construction directly wrote to ValueExprMap in a few places, without updating ExprValueMap. Add a helper to ensures they stay consistent. The adjustment in forgetSymbolicName() explicitly drops the old value from the map, so that we don't rely on it being overwritten.
  • forgetMemoizedResultsImpl() was dropping the SCEV from ExprValueMap, but not dropping the corresponding entries from ValueExprMap.

Diff Detail

Event Timeline

nikic created this revision.Nov 6 2021, 12:50 PM
nikic requested review of this revision.Nov 6 2021, 12:50 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 6 2021, 12:50 PM
nikic added inline comments.Nov 6 2021, 12:52 PM
llvm/test/CodeGen/PowerPC/more-dq-form-prepare.ll
1

This test changes because more instructions get reused by SCEV expander.

Can we split out refactoring + verifier changes (that expose some failues) and fixes for those failures? I'd like to see the tests and situations where they fail to make sure these functional fixes really address the problems. If those failures aren't too numerous or disrupting, please do.

nikic added a comment.Nov 8 2021, 12:16 AM

Can we split out refactoring + verifier changes (that expose some failues) and fixes for those failures? I'd like to see the tests and situations where they fail to make sure these functional fixes really address the problems. If those failures aren't too numerous or disrupting, please do.

The new verification makes pretty much all tests that verify SCEV fail. (This is a surprisingly low number, basically only LCSSA, LoopFuse and LoopUnrollAndJam tests, which use either verify<scalar-evolution> or explicitly call SE.verify(). Apparently the -verify-scev option doesn't do anything under the new pass manager...)

nikic added a comment.Nov 10 2021, 2:33 AM

It may be worth mentioning that currently mismatches in these maps aren't a correctness problem -- worst that will happen is that SCEVExpander misses a CSE opportunity. However, I want to use these maps in a way where correctness is important in the future, thus the validation now.

This revision is now accepted and ready to land.Nov 21 2021, 8:16 PM
This revision was landed with ongoing or failed builds.Nov 22 2021, 6:27 AM
This revision was automatically updated to reflect the committed changes.
nikic added a comment.Nov 22 2021, 9:50 AM

Reduction from asan bootstrap for the assertion failure (opt -loop-reduce):

define void @test() {
entry:
  br label %loop.header

loop.header:
  %ptr = phi i64* [ %ptr.next, %loop.latch ], [ null, %entry ]
  br i1 true, label %loop.exit, label %loop2.preheader

loop.exit:
  ret void

loop2.preheader:
  br label %loop2.header

loop2.header:
  %ptr2 = phi i64* [ %ptr, %loop2.preheader ], [ %ptr2.next, %loop2.header ]
  %ptr2.next = getelementptr inbounds i64, i64* %ptr2, i64 1
  br i1 false, label %loop2.header, label %loop2.cont

loop2.cont:
  %ptr2.i8 = bitcast i64* %ptr2 to i8*
  %v = load i8, i8* %ptr2.i8
  %c = icmp ne i8 %v, 0
  br i1 %c, label %loop.exit, label %loop.latch

loop.latch:
  %ptr.next = getelementptr inbounds i64, i64* %ptr, i64 1
  br label %loop.header
}
sberg added a subscriber: sberg.Nov 29 2021, 6:42 AM

I commented inline at https://reviews.llvm.org/rG2b160e95c89f28a30e2481e6131073659d866a8c#1040993 "Reland [SCEV] Fix and validate ValueExprMap/ExprValueMap consistency":

I see this assert [in ScalarEvolution::insertValueToMap at llvm/lib/Analysis/ScalarEvolution.cpp:4105] trigger for

$ cat test.cc
struct S {
    virtual void f1();
    void f2(int *);
    int * a1;
    int n1;
};
void S::f2(int * a2) {
    int n2 = 0;
    for (int i = 0; i != 2; ++i) {
        int n3 = n2;
        for (; n2 < n1; ++n2) {
            if (a1[n2]) {
                break;
            }
        }
        *a2 = 0;
        for (; n2 < n1; ++n2) {
            a1[n2];
        }
    }
}
$ clang++ -fsanitize=undefined -O -c test.cc
# Driver args: "--driver-mode=g++" "-fsanitize=undefined" "-O" "-c" "test.cc"
# Original command:  "~/llvm/inst/bin/clang-14" "-cc1" "-triple" "x86_64-unknown-linux-gnu" "-emit-obj" "--mrelax-relocations" "-disable-free" "-clear-ast-before-backend" "-main-file-name" "test.cc" "-mrelocation-model" "static" "-mframe-pointer=none" "-fmath-errno" "-ffp-contract=on" "-fno-rounding-math" "-mconstructor-aliases" "-funwind-tables=2" "-target-cpu" "x86-64" "-tune-cpu" "generic" "-debugger-tuning=gdb" "-fcoverage-compilation-dir=~/lo/core" "-resource-dir" "~/llvm/inst/lib/clang/14.0.0" "-internal-isystem" "/usr/lib/gcc/x86_64-redhat-linux/11/../../../../include/c++/11" "-internal-isystem" "/usr/lib/gcc/x86_64-redhat-linux/11/../../../../include/c++/11/x86_64-redhat-linux" "-internal-isystem" "/usr/lib/gcc/x86_64-redhat-linux/11/../../../../include/c++/11/backward" "-internal-isystem" "~/llvm/inst/lib/clang/14.0.0/include" "-internal-isystem" "/usr/local/include" "-internal-isystem" "/usr/lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include" "-internal-externc-isystem" "/include" "-internal-externc-isystem" "/usr/include" "-O1" "-fdeprecated-macro" "-fdebug-compilation-dir=~/lo/core" "-ferror-limit" "19" "-fsanitize=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,function,integer-divide-by-zero,nonnull-attribute,null,object-size,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,unreachable,vla-bound,vptr" "-fsanitize-recover=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,function,integer-divide-by-zero,nonnull-attribute,null,object-size,pointer-overflow,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,vla-bound,vptr" "-fgnuc-version=4.2.1" "-fcxx-exceptions" "-fexceptions" "-fcolor-diagnostics" "-faddrsig" "-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-o" "test.o" "-x" "c++" "test.cc"
 "~/llvm/inst/bin/clang-14" "-cc1" "-triple" "x86_64-unknown-linux-gnu" "-emit-obj" "--mrelax-relocations" "-disable-free" "-clear-ast-before-backend" "-main-file-name" "test.cc" "-mrelocation-model" "static" "-mframe-pointer=none" "-fmath-errno" "-ffp-contract=on" "-fno-rounding-math" "-mconstructor-aliases" "-funwind-tables=2" "-target-cpu" "x86-64" "-tune-cpu" "generic" "-debugger-tuning=gdb" "-fcoverage-compilation-dir=~/lo/core" "-O1" "-fdeprecated-macro" "-fdebug-compilation-dir=~/lo/core" "-ferror-limit" "19" "-fsanitize=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,function,integer-divide-by-zero,nonnull-attribute,null,object-size,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,unreachable,vla-bound,vptr" "-fsanitize-recover=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,function,integer-divide-by-zero,nonnull-attribute,null,object-size,pointer-overflow,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,vla-bound,vptr" "-fgnuc-version=4.2.1" "-fcxx-exceptions" "-fexceptions" "-fcolor-diagnostics" "-faddrsig" "-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-x" "c++" "test-580877.cpp"
test.cc:18:18: warning: expression result unused [-Wunused-value]
            a1[n2];
            ~~ ~~^
clang++: ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:4105: void llvm::ScalarEvolution::insertValueToMap(llvm::Value *, const llvm::SCEV *): Assertion `It->second == S' failed.
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: ~/llvm/inst/bin/clang++ -fsanitize=undefined -O -c test.cc
1.	<eof> parser at end of file
2.	Code generation
3.	Running pass 'Function Pass Manager' on module 'test.cc'.
4.	Running pass 'Loop Pass Manager' on function '@_ZN1S2f2EPi'
5.	Running pass 'Canonicalize Freeze Instructions in Loops' on basic block '%cont4'
 #0 0x00000000029923a3 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) ~/github.com/llvm/llvm-project/llvm/lib/Support/Unix/Signals.inc:565:13
 #1 0x0000000002990580 llvm::sys::RunSignalHandlers() ~/github.com/llvm/llvm-project/llvm/lib/Support/Signals.cpp:98:18
 #2 0x000000000290cc33 (anonymous namespace)::CrashRecoveryContextImpl::HandleCrash(int, unsigned long) ~/github.com/llvm/llvm-project/llvm/lib/Support/CrashRecoveryContext.cpp:76:5
 #3 0x000000000290cdf8 CrashRecoverySignalHandler(int) ~/github.com/llvm/llvm-project/llvm/lib/Support/CrashRecoveryContext.cpp:390:1
 #4 0x00007f71e2b50760 __restore_rt (/lib64/libc.so.6+0x42760)
 #5 0x00007f71e2b9d85c __pthread_kill_implementation (/lib64/libc.so.6+0x8f85c)
 #6 0x00007f71e2b506b6 gsignal (/lib64/libc.so.6+0x426b6)
 #7 0x00007f71e2b3a7d3 abort (/lib64/libc.so.6+0x2c7d3)
 #8 0x00007f71e2b3a6fb _nl_load_domain.cold (/lib64/libc.so.6+0x2c6fb)
 #9 0x00007f71e2b493a6 (/lib64/libc.so.6+0x3b3a6)
#10 0x0000000001c0ad70 llvm::CallbackVH::CallbackVH(llvm::Value*) ~/github.com/llvm/llvm-project/llvm/include/llvm/IR/ValueHandle.h:396:55
#11 0x0000000001c0ad70 llvm::ScalarEvolution::SCEVCallbackVH::SCEVCallbackVH(llvm::Value*, llvm::ScalarEvolution*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:12428:5
#12 0x0000000001c0ad70 llvm::ScalarEvolution::insertValueToMap(llvm::Value*, llvm::SCEV const*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:4100:26
#13 0x0000000001c0f1ed llvm::ScalarEvolution::createSimpleAffineAddRec(llvm::PHINode*, llvm::Value*, llvm::Value*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:0:3
#14 0x0000000001c10040 llvm::ScalarEvolution::createAddRecFromPHI(llvm::PHINode*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:0:17
#15 0x0000000001c11614 llvm::ScalarEvolution::createNodeForPHI(llvm::PHINode*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:5638:19
#16 0x0000000001c0c472 llvm::ScalarEvolution::createSCEV(llvm::Value*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:0:12
#17 0x0000000001c04b78 llvm::ScalarEvolution::getSCEV(llvm::Value*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:4116:9
#18 0x0000000001c0c4d7 llvm::Value::getType() const ~/github.com/llvm/llvm-project/llvm/include/llvm/IR/Value.h:255:34
#19 0x0000000001c0c4d7 llvm::ScalarEvolution::createSCEV(llvm::Value*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:7105:58
#20 0x0000000001c04b78 llvm::ScalarEvolution::getSCEV(llvm::Value*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:4116:9
#21 0x0000000001c1007a llvm::isa_impl_cl<llvm::SCEVAddExpr, llvm::SCEV const*>::doit(llvm::SCEV const*) ~/github.com/llvm/llvm-project/llvm/include/llvm/Support/Casting.h:104:5
#22 0x0000000001c1007a llvm::isa_impl_wrap<llvm::SCEVAddExpr, llvm::SCEV const*, llvm::SCEV const*>::doit(llvm::SCEV const* const&) ~/github.com/llvm/llvm-project/llvm/include/llvm/Support/Casting.h:131:12
#23 0x0000000001c1007a llvm::isa_impl_wrap<llvm::SCEVAddExpr, llvm::SCEV const* const, llvm::SCEV const*>::doit(llvm::SCEV const* const&) ~/github.com/llvm/llvm-project/llvm/include/llvm/Support/Casting.h:121:12
#24 0x0000000001c1007a bool llvm::isa<llvm::SCEVAddExpr, llvm::SCEV const*>(llvm::SCEV const* const&) ~/github.com/llvm/llvm-project/llvm/include/llvm/Support/Casting.h:142:10
#25 0x0000000001c1007a llvm::cast_retty<llvm::SCEVAddExpr, llvm::SCEV const*>::ret_type llvm::dyn_cast<llvm::SCEVAddExpr, llvm::SCEV const>(llvm::SCEV const*) ~/github.com/llvm/llvm-project/llvm/include/llvm/Support/Casting.h:345:10
#26 0x0000000001c1007a llvm::ScalarEvolution::createAddRecFromPHI(llvm::PHINode*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:5375:32
#27 0x0000000001c11614 llvm::ScalarEvolution::createNodeForPHI(llvm::PHINode*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:5638:19
#28 0x0000000001c0c472 llvm::ScalarEvolution::createSCEV(llvm::Value*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:0:12
#29 0x0000000001c04b78 llvm::ScalarEvolution::getSCEV(llvm::Value*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:4116:9
#30 0x0000000001c0f1b8 llvm::ScalarEvolution::createSimpleAffineAddRec(llvm::PHINode*, llvm::Value*, llvm::Value*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:0:26
#31 0x0000000001c10040 llvm::ScalarEvolution::createAddRecFromPHI(llvm::PHINode*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:0:17
#32 0x0000000001c11614 llvm::ScalarEvolution::createNodeForPHI(llvm::PHINode*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:5638:19
#33 0x0000000001c0c472 llvm::ScalarEvolution::createSCEV(llvm::Value*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:0:12
#34 0x0000000001c04b78 llvm::ScalarEvolution::getSCEV(llvm::Value*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:4116:9
#35 0x0000000001cca7d4 llvm::InductionDescriptor::isInductionPHI(llvm::PHINode*, llvm::Loop const*, llvm::ScalarEvolution*, llvm::InductionDescriptor&, llvm::SCEV const*, llvm::SmallVectorImpl<llvm::Instruction*>*) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/IVDescriptors.cpp:0:43
#36 0x00000000029bdb90 (anonymous namespace)::CanonicalizeFreezeInLoopsImpl::run() ~/github.com/llvm/llvm-project/llvm/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp:133:9
#37 0x00000000029bee0d (anonymous namespace)::CanonicalizeFreezeInLoops::runOnLoop(llvm::Loop*, llvm::LPPassManager&) ~/github.com/llvm/llvm-project/llvm/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp:225:1
#38 0x0000000001b8431b llvm::LPPassManager::runOnFunction(llvm::Function&) ~/github.com/llvm/llvm-project/llvm/lib/Analysis/LoopPass.cpp:209:13
#39 0x00000000021f37e8 llvm::FPPassManager::runOnFunction(llvm::Function&) ~/github.com/llvm/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1439:27
#40 0x00000000021f9c91 llvm::FPPassManager::runOnModule(llvm::Module&) ~/github.com/llvm/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1485:13
#41 0x00000000021f3e78 (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&) ~/github.com/llvm/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:0:27
#42 0x00000000021f3e78 llvm::legacy::PassManagerImpl::run(llvm::Module&) ~/github.com/llvm/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:542:44
#43 0x0000000002c0e6a7 (anonymous namespace)::EmitAssemblyHelper::RunCodegenPipeline(clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream> >&, std::unique_ptr<llvm::ToolOutputFile, std::default_delete<llvm::ToolOutputFile> >&) ~/github.com/llvm/llvm-project/clang/lib/CodeGen/BackendUtil.cpp:1520:1
#44 0x0000000002c0e6a7 (anonymous namespace)::EmitAssemblyHelper::EmitAssembly(clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream> >) ~/github.com/llvm/llvm-project/clang/lib/CodeGen/BackendUtil.cpp:1548:3
#45 0x0000000002c0e6a7 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream> >) ~/github.com/llvm/llvm-project/clang/lib/CodeGen/BackendUtil.cpp:1710:15
#46 0x000000000384bd1e std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream> >::~unique_ptr() /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../include/c++/11/bits/unique_ptr.h:360:6
#47 0x000000000384bd1e clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) ~/github.com/llvm/llvm-project/clang/lib/CodeGen/CodeGenAction.cpp:370:7
#48 0x00000000042c80a4 __gnu_cxx::__normal_iterator<std::unique_ptr<clang::TemplateInstantiationCallback, std::default_delete<clang::TemplateInstantiationCallback> >*, std::vector<std::unique_ptr<clang::TemplateInstantiationCallback, std::default_delete<clang::TemplateInstantiationCallback> >, std::allocator<std::unique_ptr<clang::TemplateInstantiationCallback, std::default_delete<clang::TemplateInstantiationCallback> > > > >::__normal_iterator(std::unique_ptr<clang::TemplateInstantiationCallback, std::default_delete<clang::TemplateInstantiationCallback> >* const&) /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../include/c++/11/bits/stl_iterator.h:1011:20
#49 0x00000000042c80a4 std::vector<std::unique_ptr<clang::TemplateInstantiationCallback, std::default_delete<clang::TemplateInstantiationCallback> >, std::allocator<std::unique_ptr<clang::TemplateInstantiationCallback, std::default_delete<clang::TemplateInstantiationCallback> > > >::begin() /usr/bin/../lib/gcc/x86_64-redhat-linux/11/../../../../include/c++/11/bits/stl_vector.h:812:16
#50 0x00000000042c80a4 void clang::finalize<std::vector<std::unique_ptr<clang::TemplateInstantiationCallback, std::default_delete<clang::TemplateInstantiationCallback> >, std::allocator<std::unique_ptr<clang::TemplateInstantiationCallback, std::default_delete<clang::TemplateInstantiationCallback> > > > >(std::vector<std::unique_ptr<clang::TemplateInstantiationCallback, std::default_delete<clang::TemplateInstantiationCallback> >, std::allocator<std::unique_ptr<clang::TemplateInstantiationCallback, std::default_delete<clang::TemplateInstantiationCallback> > > >&, clang::Sema const&) ~/github.com/llvm/llvm-project/clang/include/clang/Sema/TemplateInstCallback.h:54:16
#51 0x00000000042c80a4 clang::ParseAST(clang::Sema&, bool, bool) ~/github.com/llvm/llvm-project/clang/lib/Parse/ParseAST.cpp:178:3
#52 0x000000000320ac61 clang::FrontendAction::Execute() ~/github.com/llvm/llvm-project/clang/lib/Frontend/FrontendAction.cpp:971:10
#53 0x0000000003191d5f llvm::Error::getPtr() const ~/github.com/llvm/llvm-project/llvm/include/llvm/Support/Error.h:273:42
#54 0x0000000003191d5f llvm::Error::operator bool() ~/github.com/llvm/llvm-project/llvm/include/llvm/Support/Error.h:236:16
#55 0x0000000003191d5f clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) ~/github.com/llvm/llvm-project/clang/lib/Frontend/CompilerInstance.cpp:1030:23
#56 0x00000000032c7fa9 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) ~/github.com/llvm/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:261:25
#57 0x00000000009dfecb cc1_main(llvm::ArrayRef<char const*>, char const*, void*) ~/github.com/llvm/llvm-project/clang/tools/driver/cc1_main.cpp:246:15
#58 0x00000000009dd9ca ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) ~/github.com/llvm/llvm-project/clang/tools/driver/driver.cpp:317:12
#59 0x000000000306bc62 clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, bool*) const::$_1::operator()() const ~/github.com/llvm/llvm-project/clang/lib/Driver/Job.cpp:405:30
#60 0x000000000306bc62 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, bool*) const::$_1>(long) ~/github.com/llvm/llvm-project/llvm/include/llvm/ADT/STLExtras.h:177:12
#61 0x000000000290cb47 llvm::function_ref<void ()>::operator()() const ~/github.com/llvm/llvm-project/llvm/include/llvm/ADT/STLExtras.h:0:12
#62 0x000000000290cb47 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) ~/github.com/llvm/llvm-project/llvm/lib/Support/CrashRecoveryContext.cpp:425:3
#63 0x000000000306b517 clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, bool*) const ~/github.com/llvm/llvm-project/clang/lib/Driver/Job.cpp:405:7
#64 0x000000000303f763 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&) const ~/github.com/llvm/llvm-project/clang/lib/Driver/Compilation.cpp:196:15
#65 0x000000000303fae7 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) const ~/github.com/llvm/llvm-project/clang/lib/Driver/Compilation.cpp:249:13
#66 0x0000000003053f9e llvm::SmallVectorBase<unsigned int>::empty() const ~/github.com/llvm/llvm-project/llvm/include/llvm/ADT/SmallVector.h:73:47
#67 0x0000000003053f9e clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) ~/github.com/llvm/llvm-project/clang/lib/Driver/Driver.cpp:1555:23
#68 0x00000000009dd22d main ~/github.com/llvm/llvm-project/clang/tools/driver/driver.cpp:489:21
#69 0x00007f71e2b3b560 __libc_start_call_main (/lib64/libc.so.6+0x2d560)
#70 0x00007f71e2b3b60c __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x2d60c)
#71 0x00000000009da9a5 _start (~/llvm/inst/bin/clang+++0x9da9a5)

with It->second->dump() being

{(sext i32 {%n2.067,+,1}<nsw><%cont4> to i64),+,1}<nsw><%cont24>

and S->dump() being

{{(sext i32 %n2.067 to i64),+,1}<nsw><%cont4>,+,1}<nsw><%cont24>

(There may be an easier reproducer not needing -fsanitize=undefined; I only noticed that I still had it on the command line late into coming up with a minimal reproducer.)

nikic added a comment.Nov 29 2021, 7:44 AM

@sberg Thanks for the report! Here's a reduction for opt -passes='print<scalar-evolution>':

define void @test(i32* %p) {
entry:
  br label %loop.header

loop.header:
  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
  br label %loop2

loop2:
  %iv2 = phi i32 [ %iv, %loop.header ], [ %iv2.next, %loop2 ]
  %iv2.next = add i32 %iv2, 1
  %v = load i32, i32* %p
  %cmp = icmp slt i32 %iv2, %v
  br i1 %cmp, label %loop2, label %loop2.end

loop2.end:
  %iv2.ext = sext i32 %iv2 to i64
  br label %loop3

loop3:
  %iv3 = phi i64 [ %iv2.ext, %loop2.end ], [ %iv3.next, %loop3 ]
  %iv3.next = add nsw i64 %iv3, 1
  br i1 false, label %loop3, label %loop.latch

loop.latch:
  %iv.next = trunc i64 %iv3 to i32
  br label %loop.header
}

I'll probably just drop the assert -- while it should be the same in an ideal world, lazy nowrap flag updates mean that it can be a different (but equivalent) SCEV expression, as is the case here.

I wrote
https://github.com/llvm/llvm-project/issues/53905
that started happening with this patch.