Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#73662 introduces a strict weak ordering violation in a comparator #108618

Closed
alexfh opened this issue Sep 13, 2024 · 2 comments · Fixed by #108947
Closed

#73662 introduces a strict weak ordering violation in a comparator #108618

alexfh opened this issue Sep 13, 2024 · 2 comments · Fixed by #108947

Comments

@alexfh
Copy link
Contributor

alexfh commented Sep 13, 2024

#73662 / d77067d introduces an assertion failure when Clang is compiled with the strict weak ordering check for comparators enabled in libc++ check (-D_LIBCPP_DEBUG_STRICT_WEAK_ORDERING_CHECK):

$ clang -O1 -c -o /dev/null -x ir -
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: cold noreturn nounwind
declare void @llvm.ubsantrap(i8 immarg) #0

define void @f(ptr %cpi, ptr %x, i32 %i.0, i1 %cmp125.not) {
entry:
  br label %for.cond

trap3:                                            ; preds = %if.end147, %if.else141, %for.body
  call void @llvm.ubsantrap(i8 0)
  unreachable

for.cond:                                         ; preds = %cont93, %entry
  %i.01 = phi i32 [ 0, %entry ], [ %inc, %cont93 ]
  %cmp91 = icmp ult i32 %i.01, 20
  br i1 %cmp91, label %for.body, label %for.cond116

for.body:                                         ; preds = %for.cond
  %0 = icmp eq ptr %x, null
  br i1 %0, label %cont93, label %trap3

cont93:                                           ; preds = %for.body
  %inc = or i32 %i.0, 1
  br label %for.cond

for.cond116:                                      ; preds = %cont148, %for.cond
  %i.1 = phi i32 [ %inc158, %cont148 ], [ 0, %for.cond ]
  %cmp117 = icmp ult i32 %i.1, 20
  br i1 %cmp117, label %cont120, label %cont213

cont120:                                          ; preds = %for.cond116
  br i1 %cmp125.not, label %if.else141, label %if.end147

if.else141:                                       ; preds = %cont120
  %1 = ptrtoint ptr %x to i64
  %2 = and i64 %1, 1
  %3 = icmp eq i64 %2, 0
  br i1 %3, label %cont146, label %trap3

cont146:                                          ; preds = %if.else141
  store i32 0, ptr %cpi, align 4
  br label %if.end147

if.end147:                                        ; preds = %cont146, %cont120
  %4 = ptrtoint ptr %x to i64
  %5 = and i64 %4, 1
  %6 = icmp eq i64 %5, 0
  br i1 %6, label %cont148, label %trap3

cont148:                                          ; preds = %if.end147
  %inc158 = or i32 %i.0, 1
  br label %for.cond116

cont213:                                          ; preds = %for.cond116
  ret void
}

attributes #0 = { cold noreturn nounwind }
include/c++/v1/__debug_utils/strict_weak_ordering_check.h:59: assertion __comp(*(__first + __a), *(__first + __b)) failed: Your comparator is not a valid strict-weak ordering
PLEASE submit a bug report to ... and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: blaze-bin/third_party/llvm/llvm-project/clang/clang -O1 -c -o /dev/null -x ir -
1.      Optimizer
@nikic
Copy link
Contributor

nikic commented Sep 13, 2024

Can you please provide a backtrace?

@alexfh
Copy link
Contributor Author

alexfh commented Sep 14, 2024

Sure, here it is:

    frame #1: 0x00007ffff7cefdf7 libc.so.6`abort + 247
    frame #2: 0x000055556070c5f7 clang`std::__u::__libcpp_verbose_abort(char const*, ...) + 151
    frame #3: 0x000055555f3ea483 clang`(anonymous namespace)::IndVarSimplify::run(llvm::Loop*) + 22867
    frame #4: 0x000055555f3e49d9 clang`llvm::IndVarSimplifyPass::run(llvm::Loop&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) + 361
    frame #5: 0x000055555e5399f2 clang`llvm::detail::PassModel<llvm::Loop, llvm::IndVarSimplifyPass, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::run(llvm::Loop&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) + 18
    frame #6: 0x000055555f471dd6 clang`std::__u::optional<llvm::PreservedAnalyses> llvm::PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::runSinglePass<llvm::Loop, std::__u::unique_ptr<llvm::detail::PassConcept<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>, std::__u::default_delete<llvm::detail::PassConcept<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>>>>(llvm::Loop&, std::__u::unique_ptr<llvm::detail::PassConcept<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>, std::__u::default_delete<llvm::detail::PassConcept<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>>>&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&, llvm::PassInstrumentation&) + 102
    frame #7: 0x000055555f470bab clang`llvm::PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::runWithoutLoopNestPasses(llvm::Loop&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) + 267
    frame #8: 0x000055555f470357 clang`llvm::PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::run(llvm::Loop&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) + 23
    frame #9: 0x000055555e50f762 clang`llvm::detail::PassModel<llvm::Loop, llvm::PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::run(llvm::Loop&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) + 18
    frame #10: 0x000055555f471467 clang`llvm::FunctionToLoopPassAdaptor::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) + 1207
    frame #11: 0x000055555e539632 clang`llvm::detail::PassModel<llvm::Function, llvm::FunctionToLoopPassAdaptor, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) + 18
    frame #12: 0x00005555601f5737 clang`llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) + 263
    frame #13: 0x000055555ad78792 clang`llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) + 18
    frame #14: 0x000055555faa6132 clang`llvm::CGSCCToFunctionPassAdaptor::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) + 962
    frame #15: 0x000055555d8d0132 clang`llvm::detail::PassModel<llvm::LazyCallGraph::SCC, llvm::CGSCCToFunctionPassAdaptor, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) + 18
    frame #16: 0x000055555faa34dd clang`llvm::PassManager<llvm::LazyCallGraph::SCC, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) + 349
    frame #17: 0x000055555e51b442 clang`llvm::detail::PassModel<llvm::LazyCallGraph::SCC, llvm::PassManager<llvm::LazyCallGraph::SCC, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) + 18
    frame #18: 0x000055555faa4b10 clang`llvm::DevirtSCCRepeatedPass::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) + 336
    frame #19: 0x000055555e53b4b2 clang`llvm::detail::PassModel<llvm::LazyCallGraph::SCC, llvm::DevirtSCCRepeatedPass, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager<llvm::LazyCallGraph::SCC, llvm::LazyCallGraph&>&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) + 18
    frame #20: 0x000055555faa4186 clang`llvm::ModuleToPostOrderCGSCCPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) + 2454
    frame #21: 0x000055555e51b622 clang`llvm::detail::PassModel<llvm::Module, llvm::ModuleToPostOrderCGSCCPassAdaptor, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) + 18
    frame #22: 0x00005555601f4bf7 clang`llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) + 391
    frame #23: 0x000055555f0d6b19 clang`llvm::ModuleInlinerWrapperPass::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) + 729
    frame #24: 0x000055555e522032 clang`llvm::detail::PassModel<llvm::Module, llvm::ModuleInlinerWrapperPass, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) + 18
    frame #25: 0x00005555601f4bf7 clang`llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) + 391
    frame #26: 0x000055555ad6daf4 clang`(anonymous namespace)::EmitAssemblyHelper::RunOptimizationPipeline(clang::BackendAction, std::__u::unique_ptr<llvm::raw_pwrite_stream, std::__u::default_delete<llvm::raw_pwrite_stream>>&, std::__u::unique_ptr<llvm::ToolOutputFile, std::__u::default_delete<llvm::ToolOutputFile>>&, clang::BackendConsumer*) + 14356
    frame #27: 0x000055555ad671df clang`clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::__u::unique_ptr<llvm::raw_pwrite_stream, std::__u::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) + 3375
    frame #28: 0x000055555a9836f6 clang`clang::CodeGenAction::ExecuteAction() + 2326
    frame #29: 0x000055555b75c0f4 clang`clang::FrontendAction::Execute() + 84
    frame #30: 0x000055555b6d29a6 clang`clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 886
    frame #31: 0x000055555a52aaca clang`clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 650
    frame #32: 0x000055555a527a70 clang`cc1_main(llvm::ArrayRef<char const*>, char const*, void*) + 3104
    frame #33: 0x000055555a51b2a4 clang`ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) + 916
    frame #34: 0x000055555b88f9d8 clang`void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::__u::optional<llvm::StringRef>>, std::__u::basic_string<char, std::__u::char_traits<char>, std::__u::allocator<char>>*, bool*) const::$_0>(long) + 40
    frame #35: 0x00005555603aa795 clang`llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) + 149
    frame #36: 0x000055555b88f81e clang`clang::driver::CC1Command::Execute(llvm::ArrayRef<std::__u::optional<llvm::StringRef>>, std::__u::basic_string<char, std::__u::char_traits<char>, std::__u::allocator<char>>*, bool*) const + 334
    frame #37: 0x000055555b85554f clang`clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const + 687
    frame #38: 0x000055555b8557ec clang`clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::__u::pair<int, clang::driver::Command const*>>&, bool) const + 156
    frame #39: 0x000055555b86d772 clang`clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::__u::pair<int, clang::driver::Command const*>>&) + 386
    frame #40: 0x000055555a51a9d6 clang`clang_main(int, char**, llvm::ToolContext const&) + 11798
    frame #41: 0x000055555a517a00 clang`main + 48
    frame #42: 0x00007ffff7cda3d4 libc.so.6`__libc_start_main + 244
    frame #43: 0x000055555a5177ea clang`_start + 42

@nikic nikic closed this as completed in 34e16b6 Sep 17, 2024
tmsri pushed a commit to tmsri/llvm-project that referenced this issue Sep 19, 2024
The sort used the block name as a tie-breaker, which will not work for
unnamed blocks and can result in a strict weak ordering violation.

Fix this by checking that all exiting blocks dominate the latch first,
which means that we have a total dominance order. This makes the code
structure here align with what optimizeLoopExits() does.

Fixes llvm#108618.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants