I'm still not sure about the correctness of this. It seems like only setting the BeginCaseVal and EndCaseVal to the appropriate values is enough to handle overflowing switch cases. Test transformations themselves look correct!
Please use GitHub pull requests for new patches. Phabricator shutdown timeline
- Queries
- All Stories
- Search
- Advanced Search
- Transactions
- Transaction Logs
Advanced Search
Tue, Sep 19
Mon, Sep 18
rebase for main and the parent revision change
Thu, Sep 14
Wed, Sep 13
@vitalybuka Thank you a lot! I'll try to land this in a day!
- update lifetime-missing.ll
- drop TODO comment.
Mon, Sep 11
@vitalybuka Ah, sorry, I was confused and not sure what you said. Did you mean just stripping the src lifetime work?
strip the src lifetime if the transform suceed
@vitalybuka @bgraur @joanahalili
Thank you for reporting this!
Sun, Sep 10
@uabelho Thank you for catching this! As you see, attaching NSW to this example you gave seems unreasonable!
Wed, Sep 6
Thank you for the review!
- use BitMaskEnum
- pass by-ref for mistakenly passed by-val
- unwrap optional on CheckModRefConflict
Wed, Aug 30
Thank you for the review!
- return early
- remove .getFixedValue for optional TypeSize comparison
- add comments
Tue, Aug 29
Rebase for test fix
Update comments and debug macros
remove test noises
Mon, Aug 28
rebase for the test
If I used the backward approach like this, I couldn't handle cleanly some cases that we could merge in the multi-BB case (for example, src and dest are read-only together; I believe it's a sufficiently familiar case for Rust). Still, I now noticed extending the ModRef analysis in a more forward flow-sensitive way could cover the use after def cases as complex as this patch is. So a change is planned.
Is it necessary to handle this for the PDT case, or can it not happen there? (Maybe all blocks get connected to the virtual exit block there?)
@nikic Thanks! It sounds like a good point! I couldn't follow completely, but I do believe so; DT's entry is PDT's leaves, so I guess we can calculate PDom if it's unreachable from entry, but I'll add the test for the case that contains a cycle unreachable from entry.
Sun, Aug 27
@nikic Thanks! fixed.
Aug 26 2023
Hmm, seems like the assertion failed somehow. (Is this due to the DominatorTree update being forgotten somewhere?)
https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/Support/GenericDomTree.h#L500
tweak comment
Aug 24 2023
It looks like this is a diff against some intermediate version, rather than the full patch.
@nikic Thanks! I fixed and updated the description, although still WIP!
fix wrong diff
implement and use findNearestCommonDominator for InsertionPt
@nikic Thanks! I'll reduce the descriptions!
Aug 22 2023
Aug 21 2023
rebased for test update
add a case for branched dest mod before copy
Is there a negative test where %dest is written before the memcpy (with some control flow)? Maybe I missed it, but it seems like most of the tests here work on %src.
Aug 20 2023
apply feedbacks
- refine comments
- use getFirstInsertionPt
add phi node test
Aug 18 2023
Thanks!
- modify description, fix typo
- fix post-dominator
- rebase for tests
add
- a test for BB, Instruction mixed post-dominator finding
Aug 17 2023
Use UnionPointer for post-dominator finding and erase ModRefCheck after that.
Thank you for the review!
Aug 16 2023
- remove unrelated clang-format things
- handle post dominator for each case 1) invoke, 2) user of SrcAlloca, 3) other.
It looks like a clang-format of the whole file snuck in.
Ah, ... sorry for the noise.
rebase for https://reviews.llvm.org/D153453 and https://reviews.llvm.org/D157979
Aug 15 2023
Sorry, I forgot to tie https://reviews.llvm.org/rGca68a7f956f24aa3882134c5d8e72659355292dc with this revision, so manually closed.
- Use getDefiningAccess on the second arg of createMemoryAccessAfter.
- Rebased for an added test. https://reviews.llvm.org/rG0b4f8c9fc40afaa300fe4248bb5fb70dfb2cf1b4
@nikic Thanks! I was wondering readonly call isn't MemoryUse(Currently seems not so, that can probably be patched);)
%src = alloca %struct.Foo, align 4 %dest = alloca %struct.Foo, align 4 store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false) %_v = call i32 @use_readonly(ptr nocapture readonly %dest) %_v2 = call i32 @use_readonly(ptr nocapture readonly %src) ret void
Aug 13 2023
@vitalybuka Thank you!
seems like MemoryAccess Creation is broken... (only stage2 build?)
FAILED: tools/clang/unittests/Analysis/FlowSensitive/CMakeFiles/ClangAnalysisFlowSensitiveTests.dir/MultiVarConstantPropagationTest.cpp.o CCACHE_CPP2=yes CCACHE_HASHDIR=yes /usr/bin/ccache /b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm_build0/bin/clang++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GNU_SOURCE -D_LIBCPP_ENABLE_HARDENED_MODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm_build_ubsan/tools/clang/unittests/Analysis/FlowSensitive -I/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm-project/clang/unittests/Analysis/FlowSensitive -I/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm-project/clang/include -I/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm_build_ubsan/tools/clang/include -I/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm_build_ubsan/include -I/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm-project/llvm/include -I/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm-project/third-party/unittest/googletest/include -I/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm-project/third-party/unittest/googlemock/include -nostdinc++ -isystem /b/sanitizer-x86_64-linux-bootstrap-ubsan/build/libcxx_build_ubsan/include -isystem /b/sanitizer-x86_64-linux-bootstrap-ubsan/build/libcxx_build_ubsan/include/c++/v1 -fsanitize=undefined -Wl,--rpath=/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/libcxx_build_ubsan/lib -L/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/libcxx_build_ubsan/lib -w -stdlib=libc++ -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-class-memaccess -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fno-omit-frame-pointer -gline-tables-only -fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all -fsanitize-blacklist=/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/sanitizers/ubsan_ignorelist.txt -fdiagnostics-color -ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual -Wno-nested-anon-types -O3 -DNDEBUG -Wno-variadic-macros -Wno-gnu-zero-variadic-macro-arguments -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -Wno-suggest-override -std=c++17 -MD -MT tools/clang/unittests/Analysis/FlowSensitive/CMakeFiles/ClangAnalysisFlowSensitiveTests.dir/MultiVarConstantPropagationTest.cpp.o -MF tools/clang/unittests/Analysis/FlowSensitive/CMakeFiles/ClangAnalysisFlowSensitiveTests.dir/MultiVarConstantPropagationTest.cpp.o.d -o tools/clang/unittests/Analysis/FlowSensitive/CMakeFiles/ClangAnalysisFlowSensitiveTests.dir/MultiVarConstantPropagationTest.cpp.o -c /b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm-project/clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp clang++: /b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm-project/llvm/lib/Analysis/MemorySSA.cpp:1693: llvm::MemoryUseOrDef *llvm::MemorySSA::createDefinedAccess(llvm::Instruction *, llvm::MemoryAccess *, const llvm::MemoryUseOrDef *, bool): Assertion `(!Definition || !isa<MemoryUse>(Definition)) && "A use cannot be a defining access"' failed. PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script. Stack dump: 0. Program arguments: /b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm_build0/bin/clang++ -fsanitize=undefined -L/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/libcxx_build_ubsan/lib -w -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-class-memaccess -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fno-omit-frame-pointer -gline-tables-only -fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all -fsanitize-blacklist=/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm-project/llvm/utils/sanitizers/ubsan_ignorelist.txt -ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual -Wno-nested-anon-types -O3 -Wno-variadic-macros -Wno-gnu-zero-variadic-macro-arguments -fno-exceptions -funwind-tables -fno-rtti -Wno-suggest-override -std=c++17 -fdiagnostics-color -Wl,--rpath=/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/libcxx_build_ubsan/lib -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GNU_SOURCE -D_LIBCPP_ENABLE_HARDENED_MODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm_build_ubsan/tools/clang/unittests/Analysis/FlowSensitive -I/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm-project/clang/unittests/Analysis/FlowSensitive -I/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm-project/clang/include -I/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm_build_ubsan/tools/clang/include -I/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm_build_ubsan/include -I/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm-project/llvm/include -I/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm-project/third-party/unittest/googletest/include -I/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm-project/third-party/unittest/googlemock/include -nostdinc++ -isystem /b/sanitizer-x86_64-linux-bootstrap-ubsan/build/libcxx_build_ubsan/include -isystem /b/sanitizer-x86_64-linux-bootstrap-ubsan/build/libcxx_build_ubsan/include/c++/v1 -stdlib=libc++ -DNDEBUG -UNDEBUG -c -MD -MT tools/clang/unittests/Analysis/FlowSensitive/CMakeFiles/ClangAnalysisFlowSensitiveTests.dir/MultiVarConstantPropagationTest.cpp.o -MF tools/clang/unittests/Analysis/FlowSensitive/CMakeFiles/ClangAnalysisFlowSensitiveTests.dir/MultiVarConstantPropagationTest.cpp.o.d -fcolor-diagnostics -o tools/clang/unittests/Analysis/FlowSensitive/CMakeFiles/ClangAnalysisFlowSensitiveTests.dir/MultiVarConstantPropagationTest.cpp.o /b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm-project/clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp 1. <eof> parser at end of file 2. Optimizer #0 0x00005638879950f7 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm_build0/bin/clang+++0x7b4f0f7) #1 0x0000563887992fee llvm::sys::RunSignalHandlers() (/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm_build0/bin/clang+++0x7b4cfee) #2 0x0000563887900248 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0 #3 0x00007fb9f783bcf0 (/lib/x86_64-linux-gnu/libc.so.6+0x3bcf0) #4 0x00007fb9f789226b pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x9226b) #5 0x00007fb9f783bc46 raise (/lib/x86_64-linux-gnu/libc.so.6+0x3bc46) #6 0x00007fb9f78227fc abort (/lib/x86_64-linux-gnu/libc.so.6+0x227fc) #7 0x00007fb9f782271b (/lib/x86_64-linux-gnu/libc.so.6+0x2271b) #8 0x00007fb9f7833596 (/lib/x86_64-linux-gnu/libc.so.6+0x33596) #9 0x0000563886bee00b llvm::MemorySSA::createDefinedAccess(llvm::Instruction*, llvm::MemoryAccess*, llvm::MemoryUseOrDef const*, bool) (/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm_build0/bin/clang+++0x6da800b) #10 0x0000563886c0c585 llvm::MemorySSAUpdater::createMemoryAccessAfter(llvm::Instruction*, llvm::MemoryAccess*, llvm::MemoryAccess*) (/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm_build0/bin/clang+++0x6dc6585) #11 0x0000563889005416 llvm::MemCpyOptPass::performStackMoveOptzn(llvm::Instruction*, llvm::Instruction*, llvm::AllocaInst*, llvm::AllocaInst*, unsigned long, llvm::BatchAAResults&) (/b/sanitizer-x86_64-linux-bootstrap-ubsan/build/llvm_build0/bin/clang+++0x91bf416)
apply feedback
- Remove LoopInfo
- fix comments
Looks strange that we add lifetime markers on alloca which has no markers before.
Can't create counterexample, precondition blocks transformation.
Apply clang-format, update comments.
@vitalybuka Thank you for the review!
Aug 8 2023
rebase and a bailout for MemoryAccess creation on lifetime.end inserting for non-user post dominator.
@vitalybuka What do you think about this change? Especially the lifetime part is unchanged because it would be safe.
use LastMA(MemoryAccess) directly rather than LastMA->getDefiningAccess() for MemorySSAUpdater::createMemoryAccessAfter
rebased for test fix
I slightly modified the tests by https://github.com/llvm/llvm-project/commit/90ecb9d5b082e331a569f8c06f85289faa2a5c5f
- add -verify-memoryssa to the opt flag
- make memcpy defined on lifetime-missing test
use createMemoryAccessBefore instead of createMemoryAccessAfter and use Definitions
Aug 7 2023
I looked into this a bit, and I believe the problem here is that we're not adding MSSA MemoryAccesses for the newly inserted lifetime intrinsics. The actual intrinsic placement transform itself is correct, it's just that following MSSA queries fail to see them and perform incorrect transforms as a result.
@nikic
Thanks! You are right. I created MemoryAccess for newly created lifetime markers.
If we limit to alloca with at most one pair of start/end we just need to pick which start/end out of up 4 markers to keep using Domination.
e.g, if either src or dst has no markers, we strip markers from src
if src.start dominates dst.start then keep src.start
if dst.start dominates src.start then keep dst.start
if neither, don't perform transformationsimilar with ends and postdominate.
create MemoryAccess for newly inserted lifetime intrinsics.