Skip to content
  1. Feb 10, 2022
    • Greg Clayton's avatar
      Fix a double debug info size counting in top level stats for "statistics dump". · 3db7cc1b
      Greg Clayton authored
      This mainly affects Darwin targets (macOS, iOS, tvOS and watchOS) when these targets don't use dSYM files and the debug info was in the .o files. All modules, including the .o files that are loaded by the debug maps, were in the global module list. This was great because it allows us to see each .o file and how much it contributes. There were virtual functions on the SymbolFile class to fetch the symtab/debug info parse and index times, and also the total debug info size. So the main executable would add all of the .o file's stats together and report them as its own data. Then the "totalDebugInfoSize" and many other "totalXXX" top level totals were all being added together. This stems from the fact that my original patch only emitted the modules for a target at the start of the patch, but as comments from the reviews came in, we switched to emitting all of the modules from the global module list.
      
      So this patch fixes it so when we have a SymbolFileDWARFDebugMap that loads .o files, the main executable will have no debug info size or symtab/debug info parse/index times, but each .o file will have its own data as a separate module. Also, to be able to tell when/if we have a dSYM file I have added a "symbolFilePath" if the SymbolFile for the main modules path doesn't match that of the main executable. We also include a "symbolFileModuleIdentifiers" key in each module if the module does have multiple lldb_private::Module objects that contain debug info so that you can track down the information for a module and add up the contributions of all of the .o files.
      
      Tests were added that are labeled with @skipUnlessDarwin and @no_debug_info_test that test all of this functionality so it doesn't regress.
      
      For a module with a dSYM file, we can see the "symbolFilePath" is included:
      ```
        "modules": [
          {
            "debugInfoByteSize": 1070,
            "debugInfoIndexLoadedFromCache": false,
            "debugInfoIndexSavedToCache": false,
            "debugInfoIndexTime": 0,
            "debugInfoParseTime": 0,
            "identifier": 4873280600,
            "path": "/Users/gclayton/Documents/src/lldb/main/Debug/lldb-test-build.noindex/commands/statistics/basic/TestStats.test_dsym_binary_has_symfile_in_stats/a.out",
            "symbolFilePath": "/Users/gclayton/Documents/src/lldb/main/Debug/lldb-test-build.noindex/commands/statistics/basic/TestStats.test_dsym_binary_has_symfile_in_stats/a.out.dSYM/Contents/Resources/DWARF/a.out",
            "symbolTableIndexTime": 7.9999999999999996e-06,
            "symbolTableLoadedFromCache": false,
            "symbolTableParseTime": 7.8999999999999996e-05,
            "symbolTableSavedToCache": false,
            "triple": "arm64-apple-macosx12.0.0",
            "uuid": "E1F7D85B-3A42-321E-BF0D-29B103F5F2E3"
          },
      ```
      And for the DWARF in .o file case we can see the "symbolFileModuleIdentifiers" in the executable's module stats:
      ```
        "modules": [
          {
            "debugInfoByteSize": 0,
            "debugInfoIndexLoadedFromCache": false,
            "debugInfoIndexSavedToCache": false,
            "debugInfoIndexTime": 0,
            "debugInfoParseTime": 0,
            "identifier": 4603526968,
            "path": "/Users/gclayton/Documents/src/lldb/main/Debug/lldb-test-build.noindex/commands/statistics/basic/TestStats.test_no_dsym_binary_has_symfile_identifiers_in_stats/a.out",
            "symbolFileModuleIdentifiers": [
              4604429832
            ],
            "symbolTableIndexTime": 7.9999999999999996e-06,
            "symbolTableLoadedFromCache": false,
            "symbolTableParseTime": 0.000112,
            "symbolTableSavedToCache": false,
            "triple": "arm64-apple-macosx12.0.0",
            "uuid": "57008BF5-A726-3DE9-B1BF-3A9AD3EE8569"
          },
      ```
      And the .o file for 4604429832 looks like:
      ```
          {
            "debugInfoByteSize": 1028,
            "debugInfoIndexLoadedFromCache": false,
            "debugInfoIndexSavedToCache": false,
            "debugInfoIndexTime": 0,
            "debugInfoParseTime": 6.0999999999999999e-05,
            "identifier": 4604429832,
            "path": "/Users/gclayton/Documents/src/lldb/main/Debug/lldb-test-build.noindex/commands/statistics/basic/TestStats.test_no_dsym_binary_has_symfile_identifiers_in_stats/main.o",
            "symbolTableIndexTime": 0,
            "symbolTableLoadedFromCache": false,
            "symbolTableParseTime": 0,
            "symbolTableSavedToCache": false,
            "triple": "arm64-apple-macosx"
          }
      ```
      
      Differential Revision: https://reviews.llvm.org/D119400
      3db7cc1b
    • Renato Golin's avatar
      Wild guess to fix LLDB bot · 695b629e
      Renato Golin authored
      695b629e
    • LLVM GN Syncbot's avatar
      [gn build] Port bd3a1de6 · 8df4766e
      LLVM GN Syncbot authored
      8df4766e
    • Krzysztof Drewniak's avatar
      [MLIR][GPU] Add now-required include to SerializeToHsaco · c37b3e41
      Krzysztof Drewniak authored
      Reviewed By: whchung
      
      Differential Revision: https://reviews.llvm.org/D119455
      c37b3e41
    • Peter Klausler's avatar
      [flang] Handle "type(foo) function f" when foo is defined in f · 93b0638e
      Peter Klausler authored
      Fortran allows forward references to derived types, including
      function results that are typed in a prefix of a FUNCTION statement.
      If a type is defined in the body of the function, a reference to
      that type from a prefix on the FUNCTION statement must resolve to
      the local symbol, even and especially when that type shadows one
      from the host scope.
      
      The solution is to defer the processing of that type until the
      end of the function's specification part.  But the language doesn't
      allow for forward references to other names in the prefix, so defer
      the processing of the type only when it is not an intrinsic type.
      The data structures in name resolution that track this information
      for functions needed to become a stack in order to make this work,
      since functions can contain interfaces that are functions.
      
      Differential Revision: https://reviews.llvm.org/D119448
      93b0638e
    • Yuanfang Chen's avatar
      [clang-cl] Support the /JMC flag · bd3a1de6
      Yuanfang Chen authored
      The introduction and some examples are on this page:
      https://devblogs.microsoft.com/cppblog/announcing-jmc-stepping-in-visual-studio/
      
      The `/JMC` flag enables these instrumentations:
      - Insert at the beginning of every function immediately after the prologue with
        a call to `void __fastcall __CheckForDebuggerJustMyCode(unsigned char *JMC_flag)`.
        The argument for `__CheckForDebuggerJustMyCode` is the address of a boolean
        global variable (the global variable is initialized to 1) with the name
        convention `__<hash>_<filename>`. All such global variables are placed in
        the `.msvcjmc` section.
      - The `<hash>` part of `__<hash>_<filename>` has a one-to-one mapping
        with a directory path. MSVC uses some unknown hashing function. Here I
        used DJB.
      - Add a dummy/empty COMDAT function `__JustMyCode_Default`.
      - Add `/alternatename:__CheckForDebuggerJustMyCode=__JustMyCode_Default` link
        option via ".drectve" section. This is to prevent failure in
        case `__CheckForDebuggerJustMyCode` is not provided during linking.
      
      Implementation:
      All the instrumentations are implemented in an IR codegen pass. The pass is placed immediately before CodeGenPrepare pass. This is to not interfere with mid-end optimizations and make the instrumentation target-independent (I'm still working on an ELF port in a separate patch).
      
      Reviewed By: hans
      
      Differential Revision: https://reviews.llvm.org/D118428
      bd3a1de6
    • Yuanfang Chen's avatar
      [AArch64][ARM] add -Wunaligned-access only for clang · b96106af
      Yuanfang Chen authored
      Reviewed By: lenary
      
      Differential Revision: https://reviews.llvm.org/D119301
      b96106af
    • Huihui Zhang's avatar
      [AArch64][LoadStoreOptimizer] Ignore undef registers when checking rename... · 1d74b531
      Huihui Zhang authored
       [AArch64][LoadStoreOptimizer] Ignore undef registers when checking rename register used between paired instructions.
      
      The content of undef registers are not used in meaningful ways, when checking
      if a rename register is used between paired instructions we should ignore
      undef registers.
      
      Reviewed By: efriedma
      
      Differential Revision: https://reviews.llvm.org/D119305
      1d74b531
    • Marek Kurdej's avatar
    • Nirvedh's avatar
      [mlir][vector] Add pattern to drop lead unit dim for Contraction Op · ad9b5a4b
      Nirvedh authored
      If the result operand has a unit leading dim it is removed from all operands.
      
      Reviewed By: ThomasRaoux
      
      Differential Revision: https://reviews.llvm.org/D119206
      ad9b5a4b
    • Simon Pilgrim's avatar
      5565b38a
    • Ivan Murashko's avatar
      [clangd] Crash in __memcmp_avx2_movbe · 71d7c8d8
      Ivan Murashko authored
      There is a clangd crash at `__memcmp_avx2_movbe`. Short problem description is below.
      
      The method `HeaderIncludes::addExistingInclude` stores `Include` objects by reference at 2 places: `ExistingIncludes` (primary storage) and `IncludesByPriority` (pointer to the object's location at ExistingIncludes). `ExistingIncludes` is a map where value is a `SmallVector`. A new element is inserted by `push_back`. The operation might do resize. As result pointers stored at `IncludesByPriority` might become invalid.
      
      Typical stack trace
      ```
          frame #0: 0x00007f11460dcd94 libc.so.6`__memcmp_avx2_movbe + 308
          frame #1: 0x00000000004782b8 clangd`llvm::StringRef::compareMemory(Lhs="
      \"t2.h\"", Rhs="", Length=6) at StringRef.h:76:22
          frame #2: 0x0000000000701253 clangd`llvm::StringRef::compare(this=0x0000
      7f10de7d8610, RHS=(Data = "", Length = 7166742329480737377)) const at String
      Ref.h:206:34
        * frame #3: 0x00000000007603ab clangd`llvm::operator<(llvm::StringRef, llv
      m::StringRef)(LHS=(Data = "\"t2.h\"", Length = 6), RHS=(Data = "", Length =
      7166742329480737377)) at StringRef.h:907:23
          frame #4: 0x0000000002d0ad9f clangd`clang::tooling::HeaderIncludes::inse
      rt(this=0x00007f10de7fb1a0, IncludeName=(Data = "t2.h\"", Length = 4), IsAng
      led=false) const at HeaderIncludes.cpp:365:22
          frame #5: 0x00000000012ebfdd clangd`clang::clangd::IncludeInserter::inse
      rt(this=0x00007f10de7fb148, VerbatimHeader=(Data = "\"t2.h\"", Length = 6))
      const at Headers.cpp:262:70
      ```
      
      A unit test test for the crash was created (`HeaderIncludesTest.RepeatedIncludes`). The proposed solution is to use std::list instead of llvm::SmallVector
      
      Test Plan
      ```
      ./tools/clang/unittests/Tooling/ToolingTests --gtest_filter=HeaderIncludesTest.RepeatedIncludes
      ```
      
      Reviewed By: sammccall
      
      Differential Revision: https://reviews.llvm.org/D118755
      71d7c8d8
    • Craig Topper's avatar
      [RISCV] Lower the shufflevector equivalent of vector.splice · b0e77d5e
      Craig Topper authored
      We can lower a vector splice to a vslidedown and a vslideup.
      
      The majority of the matching code here came from X86's code for matching
      PALIGNR and VPALIGND/Q.
      
      The slidedown and slideup lowering don't really require it to be concatenation,
      but it happened to be an interesting pattern with existing analysis code I
      could use.
      
      This helps with cases where the scalar loop optimizer forwarded a load
      result from a previous loop iteration. For example, this happens if the
      loop uses x[i] and x[i+1] on the same iteration. The scalar optimizer
      will forward x[i+1] load from the previous loop to satisfy x[i] on this
      loop. When this get vectorized it results in one element of a vector
      being forwarded from the previous loop to be concatenated with elements
      loaded on this iteration.
      
      Whether that's more efficient than doing a shifted loaded or reloading
      the single scalar and using vslide1up is an interesting question.
      But that's not something the backend can help with.
      
      Reviewed By: khchen
      
      Differential Revision: https://reviews.llvm.org/D119039
      b0e77d5e
    • Valentin Clement's avatar
      [flang] Lower simple RETURN statement · 85b89ed2
      Valentin Clement authored
      This patch adds the lowering for the RETURN statement
      without alternate returns in the main program or in subroutine
      and functions.
      
      This patch is part of the upstreaming effort from fir-dev branch.
      
      Reviewed By: kiranchandramohan
      
      Differential Revision: https://reviews.llvm.org/D119429
      
      
      
      Co-authored-by: default avatarV Donaldson <vdonaldson@nvidia.com>
      Co-authored-by: default avatarEric Schweitz <eschweitz@nvidia.com>
      Co-authored-by: default avatarJean Perier <jperier@nvidia.com>
      85b89ed2
    • Valentin Clement's avatar
      [flang][NFC] Replace hardcoded attribute name · 2d4dc1cb
      Valentin Clement authored
      Replace the hardcoded attribute name with the constexpr StringRef
      defined in the FIROps.td file.
      
      Reviewed By: kiranchandramohan
      
      Differential Revision: https://reviews.llvm.org/D119422
      2d4dc1cb
    • Craig Topper's avatar
      [RISCV] Move the creation of VLMaxSentinel to isel. Use X0 during lowering. · b861ddf3
      Craig Topper authored
      The VLMaxSentinel is represented as TargetConstant, but that's included
      in isa<ConstantSDNode>. To keep constant VLs and VLMax separate as long
      as possible, use the X0 register during lowering and only convert to
      VLMaxSentinel during isel.
      
      Reviewed By: frasercrmck
      
      Differential Revision: https://reviews.llvm.org/D118845
      b861ddf3
    • Hans Wennborg's avatar
      [clang-cl] Accept the "legacy" -target flag spelling · 8baa076d
      Hans Wennborg authored
      we already accept "--target=". No reason to not accept "-target" too
      (that's the one I typically use for some reason).
      
      Differential revision: https://reviews.llvm.org/D119446
      8baa076d
    • Paul Walker's avatar
      [SVE] Remove AArch64ISD::ADD_PRED and AArch64ISD::SUB_PRED. · 02e0d50e
      Paul Walker authored
      These nodes provide an indirection that is not necessary because
      SVE has unpredicated add/sub instructions and there's no downside
      to using them for partial register operations. In fact, the test
      changes show that unifying how fixed-length and scalable vector
      add/sub are lowered enables better use of existing isel patterns.
      
      Differential Revision: https://reviews.llvm.org/D119355
      02e0d50e
    • Simon Pilgrim's avatar
      [X86] Add tests showing failure to use LEA to avoid spoiling EFLAGS from smulo · 039a88be
      Simon Pilgrim authored
      Add smulo and umulo test coverage
      039a88be
    • Simon Pilgrim's avatar
      [X86] getFMA3OpcodeToCommuteOperands - use unreachable to detect fma3 format mismatch · e95fc20f
      Simon Pilgrim authored
      Matches what we do in getThreeSrcCommuteCase.
      
      Fixes static analyzer out of bounds array access warning.
      e95fc20f
    • Arthur Eubanks's avatar
      [hwasan][test] Rework memaccess-clobber.ll · be2227b6
      Arthur Eubanks authored
      Previously memaccess-clobber.ll relied on both legacy PM-specific things
      like `-analyze` and MemoryDependenceAnalysis, which are both deprecated.
      
      This uses MemorySSA, which is the cool new thing that a bunch of passes
      have migrated to.
      
      Differential Revision: https://reviews.llvm.org/D119393
      be2227b6
    • Craig Topper's avatar
      [RISCV] Remove stale comment. NFC · 727cd520
      Craig Topper authored
      Now that we pre-process SPLAT_VECTOR to VFMV_V_F_VL, these patterns
      handled scalable vectors and vectors converted from fixed. These
      are also used by vp.fma lowering.
      727cd520
    • Jordan Rupprecht's avatar
      [libc++] Remove usage of `_LIBCPP_DEBUG` in `__comp_ref_type` and replace with... · d6b14488
      Jordan Rupprecht authored
      [libc++] Remove usage of `_LIBCPP_DEBUG` in `__comp_ref_type` and replace with `_LIBCPP_DEBUG_LEVEL`
      
      In libc++, checking specific `_LIBCPP_DEBUG_LEVEL` levels is used everywhere except in `comp_ref_type.h`. `_LIBCPP_DEBUG` is meant as a user-facing option, and internally libc++ should be checking the value of `_LIBCPP_DEBUG_LEVEL`.
      
      The definition of `std::__debug_less` doesn't need to be hidden behind the macro, we can unconditionally expose it. It will be unused by `__comp_ref_type` unless debug mode is enabled.
      
      This was suggested in D118940.
      
      Reviewed By: #libc, philnik, Quuxplusone, ldionne
      
      Differential Revision: https://reviews.llvm.org/D118950
      d6b14488
    • Jordan Rupprecht's avatar
      [libc++] Fix std::__debug_less in c++17. · 99e5c525
      Jordan Rupprecht authored
      b07b5bd7 adds a use of `__comp_ref_type.h` to `std::min`. When libc++ is built with `-D_LIBCPP_DEBUG=0`, this enables `std::__debug_less`, which is only marked constexpr after c++17.
      
      `std::min` itself is marked as being `constexpr` as of c++14, so by extension, `std::__debug_less` should also be marked `constexpr` for the same versions so that `std::min` can use it. This change lowers the guard from `> 17` to `> 11`.
      
      Reproducer in godbolt: https://godbolt.org/z/ans3TGsj8
      
      ```
      
      constexpr int x() { return std::min<int>({1, 2, 3, 4}); }
      
      static_assert(x() == 1);
      ```
      
      Reviewed By: #libc, philnik, Quuxplusone, ldionne
      
      Differential Revision: https://reviews.llvm.org/D118940
      99e5c525
    • Mark de Wever's avatar
      [libc++][nfc] Add TEST_HAS_NO_LOCALIZATION. · fedbd264
      Mark de Wever authored
      This avoids using an libc++ internal macro in our tests.
      
      Reviewed By: #libc, ldionne
      
      Differential Revision: https://reviews.llvm.org/D119352
      fedbd264
    • Jeremy Morse's avatar
      [DebugInfo][InstrRef] Avoid duplicate instruction numbers in x86-lea-fixup · 662799c8
      Jeremy Morse authored
      This new-ish LEA-fixup code path creates two substitutions for an
      instruction number -- this is incorrect because each Value should be
      replaced by a single replacement Value. Fix by deleting the duplicate
      substitution. Add some test coverage for this path with debug-info
      attached.
      
      Differential Revision: https://reviews.llvm.org/D119232
      662799c8
    • alex-t's avatar
      [AMDGPU] Missed sign/zero extend patterns for divergence-driven instruction selection · d88a146f
      alex-t authored
      This change includes tablegen patterns that were missed by https://reviews.llvm.org/D110950 and https://reviews.llvm.org/D76230
      
      Reviewed By: foad
      
      Differential Revision: https://reviews.llvm.org/D119302
      d88a146f
    • Simon Pilgrim's avatar
      [AMDGPU] Pull out repeated getVecSize() calls. NFC. · 8de72973
      Simon Pilgrim authored
      This is guaranteed to be evaluated so we can avoid repeated calls.
      
      Helps the static analyzer as it couldn't recognise that each getVecSize() would return the same value.
      8de72973
    • David Sherwood's avatar
      [AArch64] Improve codegen for get.active.lane.mask when SVE is available · 8b58494c
      David Sherwood authored
      When lowering the get.active.lane.mask intrinsic with a fixed-width
      predicate vector result, we can actually make use of the SVE whilelo
      instruction when SVE is enabled. We do this by carefully choosing
      a sensible VT for the whilelo instruction, then promoting it to an
      integer vector, i.e. nxv16i1 -> nx16i8. We can then extract a v16i8
      subvector and truncate back to the original return type, i.e. v16i1.
      This leads to a significant improvement in code quality.
      
      Differential Revision: https://reviews.llvm.org/D116664
      8b58494c
    • Nikolas Klauser's avatar
      [libc++] Prepare string.{contains, ends_with, iterators, require, starts_with} tests for constexpr · c515b652
      Nikolas Klauser authored
      Reviewed By: ldionne, #libc
      
      Spies: libcxx-commits
      
      Differential Revision: https://reviews.llvm.org/D119304
      c515b652
    • Florian Hahn's avatar
      f9779512
    • Aart Bik's avatar
      [mlir][sparse][pytaco] migrate to sparse compiler pipeline · 8189a2b8
      Aart Bik authored
      Reviewed By: bixia
      
      Differential Revision: https://reviews.llvm.org/D119395
      8189a2b8
    • dreachem's avatar
    • Rainer Orth's avatar
      [fir] Fix FlangOptimizerTests link on Solaris · c2b9e967
      Rainer Orth authored
      As reported in Issue #53690,
      `tools/flang/unittests/Optimizer/FlangOptimizerTests` `FAIL`s to link on
      Solaris:
      
        Undefined                       first referenced
         symbol                             in file
        _ZN3fir7runtimeL8getModelIcEEPFN4mlir4TypeEPNS2_11MLIRContextEEv lib/libFIRBuilder.a(Reduction.cpp.o)
      
      which is `mlir::Type (*fir::runtime::getModel<char>())(mlir::MLIRContext*)`.
      
      `clang++` warn's
      
        In file included from /var/llvm/llvm-14.0.0-rc1/rc1/llvm-project/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp:14:
        /var/llvm/llvm-14.0.0-rc1/rc1/llvm-project/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h:60:34: warning: function 'fir::runtime::getModel<char>' has internal linkage but is not defined [-Wundefined-internal]
        static constexpr TypeBuilderFunc getModel();
                                         ^
        /var/llvm/llvm-14.0.0-rc1/rc1/llvm-project/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h:289:29: note: used here
              TypeBuilderFunc ret = getModel<RT>();
                                    ^
      
      Fixed by adding an explicit template instantiation for `getModel<char>`.  I
      suppose this is necessary because on Solaris `char` is `signed`.
      
      Tested on `sparcv9-sun-solaris2.11`.
      
      Differential Revision: https://reviews.llvm.org/D119438
      c2b9e967
    • LLVM GN Syncbot's avatar
      [gn build] Port 9d905319 · 1e421108
      LLVM GN Syncbot authored
      1e421108
    • Nikita Popov's avatar
      [InstSimplify] Remove zero-index opaque pointer GEP · 87a0b1bd
      Nikita Popov authored
      With opaque pointers, a zero-index GEP is a no-op. It does not
      need to be retained for the pointer element type change it may
      perform.
      87a0b1bd
    • Nikolas Klauser's avatar
      [libc++][ranges] Implement std::ranges::swap_ranges() · 9d905319
      Nikolas Klauser authored
      Implement `std::ranges::swap_ranges()`
      
      Reviewed By: Quuxplusone, #libc, ldionne
      
      Spies: ldionne, mgorny, jloser, libcxx-commits
      
      Differential Revision: https://reviews.llvm.org/D116303
      9d905319
    • Christian Kandeler's avatar
      clangd: Set a diagnostic on a code action resulting from a tweak · bd6c6974
      Christian Kandeler authored
      ... if there is a match.
      This is needed to that clients can can make a connection between a
      diagnostic and an associated quickfix-tweak.
      Ideally, quickfix-kind tweak code actions would be provided inline along
      with the non-tweak fixes, but this doesn't seem easily achievable.
      
      Reviewed By: sammccall
      
      Differential Revision: https://reviews.llvm.org/D118976
      bd6c6974
    • Jay Foad's avatar
      [AMDGPU] Rename DSAtomicCmpXChg to DSAtomicCmpXChgSwapped. NFC. · e34623b1
      Jay Foad authored
      This is just a reminder that the operands are swapped compared with all
      the other CmpXChg instructions.
      
      Differential Revision: https://reviews.llvm.org/D119421
      e34623b1
    • Paul Walker's avatar
      [SVE] Remove redundant hasBF16 calls from lowering code. · 9cc7eb0e
      Paul Walker authored
      The are several places where hasBF16 is used to protect code that
      has no requirement for the +bf16 feature.  The lowering code uses
      stock SVE instructions for things like loads and stores and so is
      safe even when +bf16 is not available.
      
      NOTE: Currently the nxvbf16 type is not legal unless the +bf16
      feature is available, but that isn't an issue because the affected
      code is post type legalisation.
      
      NOTE: This patch mirrors previous work that removed the same
      redundant protection from isel patterns where the resulting
      selection emitted stock SVE instructions.
      
      Differential Revision: https://reviews.llvm.org/D119328
      9cc7eb0e
Loading