diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -353,6 +353,11 @@ JustMyCode feature. Note, you may need to manually add ``/JMC`` as additional compile options in the Visual Studio since it currently assumes clang-cl does not support ``/JMC``. +- Implemented generation of SEH unwind information on ARM. (C++ exception + handling in MSVC mode is still unimplemented though.) + +- Switched MinGW mode on ARM to use SEH instead of DWARF for unwind information. + AIX Support ----------- diff --git a/clang/test/Driver/sanitizer-ld.c b/clang/test/Driver/sanitizer-ld.c --- a/clang/test/Driver/sanitizer-ld.c +++ b/clang/test/Driver/sanitizer-ld.c @@ -15,6 +15,7 @@ // CHECK-ASAN-LINUX: "-lpthread" // CHECK-ASAN-LINUX: "-lrt" // CHECK-ASAN-LINUX: "-ldl" +// CHECK-ASAN-LINUX: "-lresolv" // RUN: %clang -fsanitize=address -fno-sanitize-link-runtime -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld \ @@ -69,6 +70,7 @@ // CHECK-SHARED-ASAN-LINUX-NOT: "-lpthread" // CHECK-SHARED-ASAN-LINUX-NOT: "-lrt" // CHECK-SHARED-ASAN-LINUX-NOT: "-ldl" +// CHECK-SHARED-ASAN-LINUX-NOT: "-lresolv" // CHECK-SHARED-ASAN-LINUX-NOT: "--export-dynamic" // CHECK-SHARED-ASAN-LINUX-NOT: "--dynamic-list" @@ -86,6 +88,7 @@ // CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-lpthread" // CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-lrt" // CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-ldl" +// CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-lresolv" // CHECK-DSO-SHARED-ASAN-LINUX-NOT: "--export-dynamic" // CHECK-DSO-SHARED-ASAN-LINUX-NOT: "--dynamic-list" @@ -104,6 +107,7 @@ // CHECK-ASAN-FREEBSD: "--export-dynamic" // CHECK-ASAN-FREEBSD: "-lpthread" // CHECK-ASAN-FREEBSD: "-lrt" +// CHECK-ASAN-FREEBSD: "-lresolv" // RUN: %clang -### %s 2>&1 \ // RUN: --target=i386-unknown-freebsd -fuse-ld=ld -fsanitize=address \ @@ -130,6 +134,7 @@ // CHECK-ASAN-LINUX-CXX: "-lpthread" // CHECK-ASAN-LINUX-CXX: "-lrt" // CHECK-ASAN-LINUX-CXX: "-ldl" +// CHECK-ASAN-LINUX-CXX: "-lresolv" // RUN: %clang -### %s -o /dev/null -fsanitize=address \ // RUN: --target=i386-unknown-linux -fuse-ld=ld -stdlib=platform \ @@ -169,8 +174,10 @@ // CHECK-ASAN-ANDROID: "-pie" // CHECK-ASAN-ANDROID-NOT: "-lc" // CHECK-ASAN-ANDROID-NOT: "-lpthread" +// CHECK-ASAN-ANDROID-NOT: "-lresolv" // CHECK-ASAN-ANDROID: libclang_rt.asan-arm-android.so" // CHECK-ASAN-ANDROID-NOT: "-lpthread" +// CHECK-ASAN-ANDROID-NOT: "-lresolv" // RUN: %clang -### %s 2>&1 \ // RUN: --target=arm-linux-androideabi -fuse-ld=ld -fsanitize=address \ @@ -182,6 +189,7 @@ // CHECK-ASAN-ANDROID-STATICLIBASAN: libclang_rt.asan-arm-android.a" // CHECK-ASAN-ANDROID-STATICLIBASAN-NOT: "-lpthread" // CHECK-ASAN-ANDROID-STATICLIBASAN-NOT: "-lrt" +// CHECK-ASAN-ANDROID-STATICLIBASAN-NOT: "-lresolv" // RUN: %clang -### %s 2>&1 \ // RUN: --target=arm-linux-androideabi -fuse-ld=ld -fsanitize=undefined \ @@ -192,8 +200,10 @@ // CHECK-UBSAN-ANDROID: "-pie" // CHECK-UBSAN-ANDROID-NOT: "-lc" // CHECK-UBSAN-ANDROID-NOT: "-lpthread" +// CHECK-UBSAN-ANDROID-NOT: "-lresolv" // CHECK-UBSAN-ANDROID: libclang_rt.ubsan_standalone-arm-android.so" // CHECK-UBSAN-ANDROID-NOT: "-lpthread" +// CHECK-UBSAN-ANDROID-NOT: "-lresolv" // RUN: %clang -### %s 2>&1 \ // RUN: --target=arm-linux-androideabi -fuse-ld=ld -fsanitize=undefined \ @@ -205,6 +215,7 @@ // CHECK-UBSAN-ANDROID-STATICLIBASAN: libclang_rt.ubsan_standalone-arm-android.a" // CHECK-UBSAN-ANDROID-STATICLIBASAN-NOT: "-lpthread" // CHECK-UBSAN-ANDROID-STATICLIBASAN-NOT: "-lrt" +// CHECK-UBSAN-ANDROID-STATICLIBASAN-NOT: "-lresolv" // // RUN: %clang -### %s 2>&1 \ @@ -216,8 +227,10 @@ // CHECK-ASAN-ANDROID-X86: "-pie" // CHECK-ASAN-ANDROID-X86-NOT: "-lc" // CHECK-ASAN-ANDROID-X86-NOT: "-lpthread" +// CHECK-ASAN-ANDROID-X86-NOT: "-lresolv" // CHECK-ASAN-ANDROID-X86: libclang_rt.asan-i686-android.so" // CHECK-ASAN-ANDROID-X86-NOT: "-lpthread" +// CHECK-ASAN-ANDROID-X86-NOT: "-lresolv" // // RUN: %clang -### %s 2>&1 \ // RUN: --target=arm-linux-androideabi -fsanitize=address \ @@ -237,6 +250,7 @@ // CHECK-ASAN-ANDROID-SHARED-NOT: "-lc" // CHECK-ASAN-ANDROID-SHARED: libclang_rt.asan-arm-android.so" // CHECK-ASAN-ANDROID-SHARED-NOT: "-lpthread" +// CHECK-ASAN-ANDROID-SHARED-NOT: "-lresolv" // RUN: %clang -### %s 2>&1 \ // RUN: --target=sparcel-myriad-rtems-elf -fuse-ld=ld -fsanitize=address \ @@ -265,6 +279,7 @@ // CHECK-TSAN-LINUX-CXX: "-lpthread" // CHECK-TSAN-LINUX-CXX: "-lrt" // CHECK-TSAN-LINUX-CXX: "-ldl" +// CHECK-TSAN-LINUX-CXX: "-lresolv" // RUN: %clang -fsanitize=thread -fno-sanitize-link-runtime -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld \ @@ -292,6 +307,7 @@ // CHECK-MSAN-LINUX-CXX: "-lpthread" // CHECK-MSAN-LINUX-CXX: "-lrt" // CHECK-MSAN-LINUX-CXX: "-ldl" +// CHECK-MSAN-LINUX-CXX: "-lresolv" // RUN: %clang -fsanitize=memory -fno-sanitize-link-runtime -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld \ @@ -328,6 +344,7 @@ // CHECK-UBSAN-LINUX-NOT: libclang_rt.ubsan_standalone_cxx // CHECK-UBSAN-LINUX-NOT: "-lstdc++" // CHECK-UBSAN-LINUX: "-lpthread" +// CHECK-UBSAN-LINUX: "-lresolv" // RUN: %clang -fsanitize=undefined -fno-sanitize-link-runtime -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld \ @@ -384,6 +401,7 @@ // CHECK-UBSAN-LINUX-CXX: "-lstdc++" // CHECK-UBSAN-LINUX-CXX-NOT: libclang_rt.asan // CHECK-UBSAN-LINUX-CXX: "-lpthread" +// CHECK-UBSAN-LINUX-CXX: "-lresolv" // RUN: %clang -fsanitize=undefined -fsanitize-minimal-runtime -### %s 2>&1 \ // RUN: --target=i386-unknown-linux -fuse-ld=ld \ @@ -393,6 +411,7 @@ // CHECK-UBSAN-MINIMAL-LINUX: "{{.*}}ld{{(.exe)?}}" // CHECK-UBSAN-MINIMAL-LINUX: "--whole-archive" "{{.*}}libclang_rt.ubsan_minimal-i386.a" "--no-whole-archive" // CHECK-UBSAN-MINIMAL-LINUX: "-lpthread" +// CHECK-UBSAN-MINIMAL-LINUX: "-lresolv" // RUN: %clang -fsanitize=undefined -fsanitize-minimal-runtime -### %s 2>&1 \ // RUN: --target=x86_64-apple-darwin -fuse-ld=ld \ @@ -418,6 +437,7 @@ // CHECK-ASAN-UBSAN-LINUX-NOT: libclang_rt.ubsan // CHECK-ASAN-UBSAN-LINUX-NOT: "-lstdc++" // CHECK-ASAN-UBSAN-LINUX: "-lpthread" +// CHECK-ASAN-UBSAN-LINUX: "-lresolv" // RUN: %clangxx -fsanitize=address,undefined -### %s 2>&1 \ // RUN: --target=i386-unknown-linux -fuse-ld=ld -stdlib=platform \ @@ -430,6 +450,7 @@ // CHECK-ASAN-UBSAN-LINUX-CXX-NOT: libclang_rt.ubsan // CHECK-ASAN-UBSAN-LINUX-CXX: "-lstdc++" // CHECK-ASAN-UBSAN-LINUX-CXX: "-lpthread" +// CHECK-ASAN-UBSAN-LINUX-CXX: "-lresolv" // RUN: %clangxx -fsanitize=memory,undefined -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld \ @@ -472,6 +493,7 @@ // CHECK-LSAN-LINUX: libclang_rt.lsan-x86_64.a" // CHECK-LSAN-LINUX: "-lpthread" // CHECK-LSAN-LINUX: "-ldl" +// CHECK-LSAN-LINUX: "-lresolv" // RUN: %clang -fsanitize=leak -fno-sanitize-link-runtime -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld \ @@ -494,6 +516,7 @@ // CHECK-LSAN-COV-LINUX-NOT: libclang_rt.ubsan // CHECK-LSAN-COV-LINUX: "-lpthread" // CHECK-LSAN-COV-LINUX: "-ldl" +// CHECK-LSAN-COV-LINUX: "-lresolv" // RUN: %clang -fsanitize=leak,address -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld \ @@ -515,6 +538,7 @@ // CHECK-ASAN-COV-LINUX-NOT: libclang_rt.ubsan // CHECK-ASAN-COV-LINUX-NOT: "-lstdc++" // CHECK-ASAN-COV-LINUX: "-lpthread" +// CHECK-ASAN-COV-LINUX: "-lresolv" // RUN: %clang -fsanitize=memory -fsanitize-coverage=func -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld \ @@ -526,6 +550,7 @@ // CHECK-MSAN-COV-LINUX-NOT: libclang_rt.ubsan // CHECK-MSAN-COV-LINUX-NOT: "-lstdc++" // CHECK-MSAN-COV-LINUX: "-lpthread" +// CHECK-MSAN-COV-LINUX: "-lresolv" // RUN: %clang -fsanitize=dataflow -fsanitize-coverage=func -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld \ @@ -537,6 +562,7 @@ // CHECK-DFSAN-COV-LINUX-NOT: libclang_rt.ubsan // CHECK-DFSAN-COV-LINUX-NOT: "-lstdc++" // CHECK-DFSAN-COV-LINUX: "-lpthread" +// CHECK-DFSAN-COV-LINUX: "-lresolv" // RUN: %clang -fsanitize=undefined -fsanitize-coverage=func -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld \ @@ -547,6 +573,7 @@ // CHECK-UBSAN-COV-LINUX: "--whole-archive" "{{.*}}libclang_rt.ubsan_standalone-x86_64.a" "--no-whole-archive" // CHECK-UBSAN-COV-LINUX-NOT: "-lstdc++" // CHECK-UBSAN-COV-LINUX: "-lpthread" +// CHECK-UBSAN-COV-LINUX: "-lresolv" // RUN: %clang -fsanitize-coverage=func -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld \ @@ -557,6 +584,7 @@ // CHECK-COV-LINUX: "--whole-archive" "{{.*}}libclang_rt.ubsan_standalone-x86_64.a" "--no-whole-archive" // CHECK-COV-LINUX-NOT: "-lstdc++" // CHECK-COV-LINUX: "-lpthread" +// CHECK-COV-LINUX: "-lresolv" // CFI by itself does not link runtime libraries. // RUN: %clang -fsanitize=cfi -### %s 2>&1 \ @@ -651,6 +679,7 @@ // CHECK-SAFESTACK-LINUX: "-u" "__safestack_init" // CHECK-SAFESTACK-LINUX: "-lpthread" // CHECK-SAFESTACK-LINUX: "-ldl" +// CHECK-SAFESTACK-LINUX: "-lresolv" // RUN: %clang -fsanitize=shadow-call-stack -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld \ @@ -828,6 +857,7 @@ // CHECK-SCUDO-LINUX-NOT: "-lstdc++" // CHECK-SCUDO-LINUX: "-lpthread" // CHECK-SCUDO-LINUX: "-ldl" +// CHECK-SCUDO-LINUX: "-lresolv" // RUN: %clang -fsanitize=scudo -fsanitize-minimal-runtime -### %s 2>&1 \ // RUN: --target=i386-unknown-linux -fuse-ld=ld \ @@ -838,6 +868,7 @@ // CHECK-SCUDO-MINIMAL-LINUX: "-pie" // CHECK-SCUDO-MINIMAL-LINUX: "--whole-archive" "{{.*}}libclang_rt.scudo_minimal-i386.a" "--no-whole-archive" // CHECK-SCUDO-MINIMAL-LINUX: "-lpthread" +// CHECK-SCUDO-MINIMAL-LINUX: "-lresolv" // RUN: %clang -### %s -o %t.so -shared 2>&1 \ // RUN: --target=i386-unknown-linux -fuse-ld=ld -fsanitize=scudo -shared-libsan \ @@ -852,6 +883,7 @@ // CHECK-SCUDO-SHARED-LINUX-NOT: "-lpthread" // CHECK-SCUDO-SHARED-LINUX-NOT: "-lrt" // CHECK-SCUDO-SHARED-LINUX-NOT: "-ldl" +// CHECK-SCUDO-SHARED-LINUX-NOT: "-lresolv" // CHECK-SCUDO-SHARED-LINUX-NOT: "--export-dynamic" // CHECK-SCUDO-SHARED-LINUX-NOT: "--dynamic-list" @@ -864,8 +896,10 @@ // CHECK-SCUDO-ANDROID-NOT: "-lc" // CHECK-SCUDO-ANDROID: "-pie" // CHECK-SCUDO-ANDROID-NOT: "-lpthread" +// CHECK-SCUDO-ANDROID-NOT: "-lresolv" // CHECK-SCUDO-ANDROID: libclang_rt.scudo-arm-android.so" // CHECK-SCUDO-ANDROID-NOT: "-lpthread" +// CHECK-SCUDO-ANDROID-NOT: "-lresolv" // RUN: %clang -### %s 2>&1 \ // RUN: --target=arm-linux-androideabi -fuse-ld=ld -fsanitize=scudo \ @@ -878,6 +912,7 @@ // CHECK-SCUDO-ANDROID-STATIC-NOT: "-lstdc++" // CHECK-SCUDO-ANDROID-STATIC-NOT: "-lpthread" // CHECK-SCUDO-ANDROID-STATIC-NOT: "-lrt" +// CHECK-SCUDO-ANDROID-STATIC-NOT: "-lresolv" // RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress \ @@ -895,6 +930,7 @@ // CHECK-HWASAN-X86-64-LINUX: "-lpthread" // CHECK-HWASAN-X86-64-LINUX: "-lrt" // CHECK-HWASAN-X86-64-LINUX: "-ldl" +// CHECK-HWASAN-X86-64-LINUX: "-lresolv" // RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress \ @@ -909,6 +945,7 @@ // CHECK-SHARED-HWASAN-X86-64-LINUX-NOT: "-lpthread" // CHECK-SHARED-HWASAN-X86-64-LINUX-NOT: "-lrt" // CHECK-SHARED-HWASAN-X86-64-LINUX-NOT: "-ldl" +// CHECK-SHARED-HWASAN-X86-64-LINUX-NOT: "-lresolv" // CHECK-SHARED-HWASAN-X86-64-LINUX-NOT: "--export-dynamic" // CHECK-SHARED-HWASAN-X86-64-LINUX-NOT: "--dynamic-list" @@ -925,6 +962,7 @@ // CHECK-DSO-SHARED-HWASAN-X86-64-LINUX-NOT: "-lpthread" // CHECK-DSO-SHARED-HWASAN-X86-64-LINUX-NOT: "-lrt" // CHECK-DSO-SHARED-HWASAN-X86-64-LINUX-NOT: "-ldl" +// CHECK-DSO-SHARED-HWASAN-X86-64-LINUX-NOT: "-lresolv" // CHECK-DSO-SHARED-HWASAN-X86-64-LINUX-NOT: "--export-dynamic" // CHECK-DSO-SHARED-HWASAN-X86-64-LINUX-NOT: "--dynamic-list" @@ -944,6 +982,7 @@ // CHECK-HWASAN-AARCH64-LINUX: "-lpthread" // CHECK-HWASAN-AARCH64-LINUX: "-lrt" // CHECK-HWASAN-AARCH64-LINUX: "-ldl" +// CHECK-HWASAN-AARCH64-LINUX: "-lresolv" // RUN: %clang -### %s 2>&1 \ // RUN: --target=aarch64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress \ @@ -959,6 +998,7 @@ // CHECK-SHARED-HWASAN-AARCH64-LINUX-NOT: "-lpthread" // CHECK-SHARED-HWASAN-AARCH64-LINUX-NOT: "-lrt" // CHECK-SHARED-HWASAN-AARCH64-LINUX-NOT: "-ldl" +// CHECK-SHARED-HWASAN-AARCH64-LINUX-NOT: "-lresolv" // CHECK-SHARED-HWASAN-AARCH64-LINUX-NOT: "--export-dynamic" // CHECK-SHARED-HWASAN-AARCH64-LINUX-NOT: "--dynamic-list" @@ -975,5 +1015,6 @@ // CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX-NOT: "-lpthread" // CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX-NOT: "-lrt" // CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX-NOT: "-ldl" +// CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX-NOT: "-lresolv" // CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX-NOT: "--export-dynamic" // CHECK-DSO-SHARED-HWASAN-AARCH64-LINUX-NOT: "--dynamic-list" diff --git a/compiler-rt/lib/asan/asan_allocator.h b/compiler-rt/lib/asan/asan_allocator.h --- a/compiler-rt/lib/asan/asan_allocator.h +++ b/compiler-rt/lib/asan/asan_allocator.h @@ -17,6 +17,7 @@ #include "asan_flags.h" #include "asan_interceptors.h" #include "asan_internal.h" +#include "lsan/lsan_allocator.h" #include "sanitizer_common/sanitizer_allocator.h" #include "sanitizer_common/sanitizer_list.h" #include "sanitizer_common/sanitizer_platform.h" @@ -118,12 +119,9 @@ }; #if SANITIZER_CAN_USE_ALLOCATOR64 -# if SANITIZER_FUCHSIA -const uptr kAllocatorSpace = ~(uptr)0; -const uptr kAllocatorSize = 0x40000000000ULL; // 4T. -typedef DefaultSizeClassMap SizeClassMap; -# elif defined(__powerpc64__) +# if defined(__powerpc64__) const uptr kAllocatorSpace = ~(uptr)0; +// NOTE: This differs slightly from the LSan allocator size which is 4T. const uptr kAllocatorSize = 0x20000000000ULL; // 2T. typedef DefaultSizeClassMap SizeClassMap; # elif defined(__aarch64__) && SANITIZER_ANDROID @@ -150,8 +148,9 @@ const uptr kAllocatorSize = 0x8000000000ULL; // 500G typedef DefaultSizeClassMap SizeClassMap; # else -const uptr kAllocatorSpace = 0x600000000000ULL; -const uptr kAllocatorSize = 0x40000000000ULL; // 4T. +// Use LSan's allocator configs. +const uptr kAllocatorSpace = __lsan::kAllocatorSpace; +const uptr kAllocatorSize = __lsan::kAllocatorSize; typedef DefaultSizeClassMap SizeClassMap; # endif template diff --git a/compiler-rt/lib/asan/asan_errors.cpp b/compiler-rt/lib/asan/asan_errors.cpp --- a/compiler-rt/lib/asan/asan_errors.cpp +++ b/compiler-rt/lib/asan/asan_errors.cpp @@ -279,9 +279,7 @@ void ErrorOutOfMemory::Print() { Decorator d; Printf("%s", d.Error()); - Report( - "ERROR: AddressSanitizer: allocator is out of memory trying to allocate " - "0x%zx bytes\n", requested_size); + ERROR_OOM("allocator is trying to allocate 0x%zx bytes\n", requested_size); Printf("%s", d.Default()); stack->Print(); PrintHintAllocatorCannotReturnNull(); diff --git a/compiler-rt/lib/lsan/lsan_allocator.h b/compiler-rt/lib/lsan/lsan_allocator.h --- a/compiler-rt/lib/lsan/lsan_allocator.h +++ b/compiler-rt/lib/lsan/lsan_allocator.h @@ -49,8 +49,7 @@ u32 stack_trace_id; }; -#if defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \ - defined(__arm__) || SANITIZER_RISCV64 || defined(__hexagon__) +#if !SANITIZER_CAN_USE_ALLOCATOR64 template struct AP32 { static const uptr kSpaceBeg = 0; @@ -65,7 +64,7 @@ template using PrimaryAllocatorASVT = SizeClassAllocator32>; using PrimaryAllocator = PrimaryAllocatorASVT; -#elif defined(__x86_64__) || defined(__powerpc64__) || defined(__s390x__) +#else # if SANITIZER_FUCHSIA || defined(__powerpc64__) const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x40000000000ULL; // 4T. diff --git a/compiler-rt/lib/orc/c_api.h b/compiler-rt/lib/orc/c_api.h --- a/compiler-rt/lib/orc/c_api.h +++ b/compiler-rt/lib/orc/c_api.h @@ -9,9 +9,6 @@ |* *| |* This file defines the C API for the ORC runtime *| |* *| -|* NOTE: The OrtRTWrapperFunctionResult type must be kept in sync with the *| -|* definition in llvm/include/llvm-c/OrcShared.h. *| -|* *| \*===----------------------------------------------------------------------===*/ #ifndef ORC_RT_C_API_H diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_report.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_report.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_report.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_report.cpp @@ -128,8 +128,7 @@ void NORETURN ReportOutOfMemory(uptr requested_size, const StackTrace *stack) { { ScopedAllocatorErrorReport report("out-of-memory", stack); - Report("ERROR: %s: allocator is out of memory trying to allocate 0x%zx " - "bytes\n", SanitizerToolName, requested_size); + ERROR_OOM("allocator is trying to allocate 0x%zx bytes\n", requested_size); } Die(); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -311,6 +311,18 @@ const char *mmap_type, error_t err, bool raw_report = false); +// Returns true if the platform-specific error reported is an OOM error. +bool ErrorIsOOM(error_t err); + +// This reports an error in the form: +// +// `ERROR: {{SanitizerToolName}}: out of memory: {{err_msg}}` +// +// Downstream tools that read sanitizer output will know that errors starting +// in this format are specifically OOM errors. +#define ERROR_OOM(err_msg, ...) \ + Report("ERROR: %s: out of memory: " err_msg, SanitizerToolName, __VA_ARGS__) + // Specific tools may override behavior of "Die" function to do tool-specific // job. typedef void (*DieCallbackType)(void); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp @@ -46,9 +46,15 @@ Die(); } recursion_count++; - Report("ERROR: %s failed to " - "%s 0x%zx (%zd) bytes of %s (error code: %d)\n", - SanitizerToolName, mmap_type, size, size, mem_type, err); + if (ErrorIsOOM(err)) { + ERROR_OOM("failed to %s 0x%zx (%zd) bytes of %s (error code: %d)\n", + mmap_type, size, size, mem_type, err); + } else { + Report( + "ERROR: %s failed to " + "%s 0x%zx (%zd) bytes of %s (error code: %d)\n", + SanitizerToolName, mmap_type, size, size, mem_type, err); + } #if !SANITIZER_GO DumpProcessMap(); #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -4963,6 +4963,27 @@ #define INIT_PTHREAD_ATTR_GETAFFINITY_NP #endif +#if SANITIZER_INTERCEPT_PTHREAD_GETAFFINITY_NP +INTERCEPTOR(int, pthread_getaffinity_np, void *attr, SIZE_T cpusetsize, + void *cpuset) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, pthread_getaffinity_np, attr, cpusetsize, + cpuset); + // FIXME: under ASan the call below may write to freed memory and corrupt + // its metadata. See + // https://github.com/google/sanitizers/issues/321. + int res = REAL(pthread_getaffinity_np)(attr, cpusetsize, cpuset); + if (!res && cpusetsize && cpuset) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize); + return res; +} + +#define INIT_PTHREAD_GETAFFINITY_NP \ + COMMON_INTERCEPT_FUNCTION(pthread_getaffinity_np); +#else +#define INIT_PTHREAD_GETAFFINITY_NP +#endif + #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED INTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int)) #define INIT_PTHREAD_MUTEXATTR_GETPSHARED \ @@ -10328,6 +10349,42 @@ #define INIT_SIGALTSTACK #endif +#if SANITIZER_INTERCEPT_PROCCTL +INTERCEPTOR(int, procctl, int idtype, u64 id, int cmd, uptr data) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, procctl, idtype, id, cmd, data); + static const int PROC_REAP_ACQUIRE = 2; + static const int PROC_REAP_RELEASE = 3; + static const int PROC_REAP_STATUS = 4; + static const int PROC_REAP_GETPIDS = 5; + static const int PROC_REAP_KILL = 6; + if (cmd < PROC_REAP_ACQUIRE || cmd > PROC_REAP_KILL) { + COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)data, sizeof(int)); + } else { + // reap_acquire/reap_release bears no arguments. + if (cmd > PROC_REAP_RELEASE) { + unsigned int reapsz; + switch (cmd) { + case PROC_REAP_STATUS: + reapsz = struct_procctl_reaper_status_sz; + break; + case PROC_REAP_GETPIDS: + reapsz = struct_procctl_reaper_pids_sz; + break; + case PROC_REAP_KILL: + reapsz = struct_procctl_reaper_kill_sz; + break; + } + COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)data, reapsz); + } + } + return REAL(procctl)(idtype, id, cmd, data); +} +#define INIT_PROCCTL COMMON_INTERCEPT_FUNCTION(procctl) +#else +#define INIT_PROCCTL +#endif + #if SANITIZER_INTERCEPT_UNAME INTERCEPTOR(int, uname, struct utsname *utsname) { #if SANITIZER_LINUX @@ -10535,6 +10592,7 @@ INIT_PTHREAD_ATTR_GET_SCHED; INIT_PTHREAD_ATTR_GETINHERITSCHED; INIT_PTHREAD_ATTR_GETAFFINITY_NP; + INIT_PTHREAD_GETAFFINITY_NP; INIT_PTHREAD_MUTEXATTR_GETPSHARED; INIT_PTHREAD_MUTEXATTR_GETTYPE; INIT_PTHREAD_MUTEXATTR_GETPROTOCOL; @@ -10686,6 +10744,7 @@ INIT_QSORT_R; INIT_BSEARCH; INIT_SIGALTSTACK; + INIT_PROCCTL INIT_UNAME; INIT___XUNAME; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp @@ -128,6 +128,8 @@ uptr GetMaxVirtualAddress() { return GetMaxUserVirtualAddress(); } +bool ErrorIsOOM(error_t err) { return err == ZX_ERR_NO_MEMORY; } + static void *DoAnonymousMmapOrDie(uptr size, const char *mem_type, bool raw_report, bool die_for_nomem) { size = RoundUpTo(size, GetPageSize()); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -82,6 +82,7 @@ #endif int internal_uname(struct utsname *buf); #elif SANITIZER_FREEBSD +uptr internal_procctl(int type, int id, int cmd, void *data); void internal_sigdelset(__sanitizer_sigset_t *set, int signum); #elif SANITIZER_NETBSD void internal_sigdelset(__sanitizer_sigset_t *set, int signum); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -901,6 +901,10 @@ return k_set->sig[idx] & ((uptr)1 << bit); } #elif SANITIZER_FREEBSD +uptr internal_procctl(int type, int id, int cmd, void *data) { + return internal_syscall(SYSCALL(procctl), type, id, cmd, data); +} + void internal_sigdelset(__sanitizer_sigset_t *set, int signum) { sigset_t *rset = reinterpret_cast(set); sigdelset(rset, signum); @@ -2186,7 +2190,8 @@ } #elif SANITIZER_FREEBSD int aslr_status; - if (UNLIKELY(procctl(P_PID, 0, PROC_ASLR_STATUS, &aslr_status) == -1)) { + int r = internal_procctl(P_PID, 0, PROC_ASLR_STATUS, &aslr_status); + if (UNLIKELY(r == -1)) { // We're making things less 'dramatic' here since // the cmd is not necessarily guaranteed to be here // just yet regarding FreeBSD release diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h @@ -285,7 +285,8 @@ #ifndef SANITIZER_CAN_USE_ALLOCATOR64 # if (SANITIZER_ANDROID && defined(__aarch64__)) || SANITIZER_FUCHSIA # define SANITIZER_CAN_USE_ALLOCATOR64 1 -# elif defined(__mips64) || defined(__aarch64__) +# elif defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \ + defined(__arm__) || SANITIZER_RISCV64 || defined(__hexagon__) # define SANITIZER_CAN_USE_ALLOCATOR64 0 # else # define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -348,6 +348,7 @@ #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED \ (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP SI_GLIBC +#define SANITIZER_INTERCEPT_PTHREAD_GETAFFINITY_NP SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED SI_POSIX #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED \ (SI_POSIX && !SI_NETBSD) @@ -592,6 +593,7 @@ #define SANITIZER_INTERCEPT_UNAME (SI_POSIX && !SI_FREEBSD) #define SANITIZER_INTERCEPT___XUNAME SI_FREEBSD #define SANITIZER_INTERCEPT_FLOPEN SI_FREEBSD +#define SANITIZER_INTERCEPT_PROCCTL SI_FREEBSD // This macro gives a way for downstream users to override the above // interceptor macros irrespective of the platform they are on. They have diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h @@ -424,6 +424,38 @@ char *ty_group; }; +// procctl reaper data for PROCCTL_REAPER flags +struct __sanitizer_procctl_reaper_status { + unsigned int rs_flags; + unsigned int rs_children; + unsigned int rs_descendants; + pid_t rs_reaper; + pid_t rs_pid; + unsigned int rs_pad0[15]; +}; + +struct __sanitizer_procctl_reaper_pidinfo { + pid_t pi_pid; + pid_t pi_subtree; + unsigned int pi_flags; + unsigned int pi_pad0[15]; +}; + +struct __sanitizer_procctl_reaper_pids { + unsigned int rp_count; + unsigned int rp_pad0[15]; + struct __sanitize_procctl_reapper_pidinfo *rp_pids; +}; + +struct __sanitizer_procctl_reaper_kill { + int rk_sig; + unsigned int rk_flags; + pid_t rk_subtree; + unsigned int rk_killed; + pid_t rk_fpid; + unsigned int rk_pad[15]; +}; + # define IOC_NRBITS 8 # define IOC_TYPEBITS 8 # if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__) @@ -480,6 +512,11 @@ extern unsigned struct_sioc_sg_req_sz; extern unsigned struct_sioc_vif_req_sz; +extern unsigned struct_procctl_reaper_status_sz; +extern unsigned struct_procctl_reaper_pidinfo_sz; +extern unsigned struct_procctl_reaper_pids_sz; +extern unsigned struct_procctl_reaper_kill_sz; + // ioctl request identifiers // A special value to mark ioctls that are not present on the target platform, diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp @@ -205,6 +205,10 @@ unsigned struct_ppp_stats_sz = sizeof(struct ppp_stats); unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req); unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req); +unsigned struct_procctl_reaper_status_sz = sizeof(struct __sanitizer_procctl_reaper_status); +unsigned struct_procctl_reaper_pidinfo_sz = sizeof(struct __sanitizer_procctl_reaper_pidinfo); +unsigned struct_procctl_reaper_pids_sz = sizeof(struct __sanitizer_procctl_reaper_pids); +unsigned struct_procctl_reaper_kill_sz = sizeof(struct __sanitizer_procctl_reaper_kill); const unsigned long __sanitizer_bufsiz = BUFSIZ; const unsigned IOCTL_NOT_PRESENT = 0; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp @@ -41,6 +41,8 @@ return GetPageSize(); } +bool ErrorIsOOM(error_t err) { return err == ENOMEM; } + void *MmapOrDie(uptr size, const char *mem_type, bool raw_report) { size = RoundUpTo(size, GetPageSizeCached()); uptr res = MmapNamed(nullptr, size, PROT_READ | PROT_WRITE, diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp @@ -131,6 +131,11 @@ } #endif // #if !SANITIZER_GO +bool ErrorIsOOM(error_t err) { + // TODO: This should check which `err`s correspond to OOM. + return false; +} + void *MmapOrDie(uptr size, const char *mem_type, bool raw_report) { void *rv = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (rv == 0) diff --git a/compiler-rt/test/hwasan/TestCases/sizes.cpp b/compiler-rt/test/hwasan/TestCases/sizes.cpp --- a/compiler-rt/test/hwasan/TestCases/sizes.cpp +++ b/compiler-rt/test/hwasan/TestCases/sizes.cpp @@ -84,6 +84,6 @@ } // CHECK-max: {{ERROR: HWAddressSanitizer: requested allocation size .* exceeds maximum supported size}} -// CHECK-oom: ERROR: HWAddressSanitizer: allocator is out of memory +// CHECK-oom: ERROR: HWAddressSanitizer: out of memory: allocator is trying to allocate // CHECK-calloc: ERROR: HWAddressSanitizer: calloc parameters overflow // CHECK-reallocarray: ERROR: HWAddressSanitizer: reallocarray parameters overflow diff --git a/compiler-rt/test/msan/Linux/pthread_getaffinity_np.cpp b/compiler-rt/test/msan/Linux/pthread_getaffinity_np.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/msan/Linux/pthread_getaffinity_np.cpp @@ -0,0 +1,15 @@ +// RUN: %clangxx_msan -O0 %s -o %t && %run %t + +#include +#include + +#include + +int main() { + cpu_set_t set_x; + int res = pthread_getaffinity_np(pthread_self(), sizeof(set_x), &set_x); + assert(res == 0); + __msan_check_mem_is_initialized(&set_x, sizeof(set_x)); + + return 0; +} diff --git a/compiler-rt/test/sanitizer_common/TestCases/FreeBSD/procctl.cpp b/compiler-rt/test/sanitizer_common/TestCases/FreeBSD/procctl.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/FreeBSD/procctl.cpp @@ -0,0 +1,28 @@ +// RUN: %clangxx %s -o %t && %run %t %p + +#include +#include +#include +#include + +int main() { + struct procctl_reaper_status status = {0}; + int res, aslr; + res = procctl(P_PID, getpid(), PROC_REAP_STATUS, &status); + if (res < 0) { + assert(errno == EPERM); + return 0; + } + + assert(status.rs_flags >= REAPER_STATUS_OWNED); + + res = procctl(P_PID, getpid(), PROC_ASLR_STATUS, &aslr); + if (res < 0) { + assert(errno == EPERM); + return 0; + } + + assert(aslr >= PROC_ASLR_FORCE_ENABLE); + + return 0; +} diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_getaffinity_np.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_getaffinity_np.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_getaffinity_np.cpp @@ -0,0 +1,18 @@ +// RUN: %clangxx -O0 %s -o %t && %run %t + +// UNSUPPORTED: android + +#include +#include +#include + +#include + +int main() { + cpu_set_t set_x; + int res = pthread_getaffinity_np(pthread_self(), sizeof(set_x), &set_x); + assert(res == 0); + assert(CPU_COUNT_S(sizeof(set_x), &set_x) == get_nprocs()); + + return 0; +} diff --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst --- a/libcxx/docs/ReleaseNotes.rst +++ b/libcxx/docs/ReleaseNotes.rst @@ -46,6 +46,8 @@ - Implemented P0980R1 (Making ``std::string`` constexpr) +- Implemented P0618R0 (Deprecating ) + - Marked the following papers as "Complete" (note that some of those might have been implemented in a previous release but not marked as such): @@ -144,6 +146,10 @@ as a return type instead of relying on the type of ``valarray``-expressions, which is not guaranteed by the Standard anyway. +- The contents of ````, ``wstring_convert`` and ``wbuffer_convert`` have been marked as deprecated. + To disable deprecation warnings you have to define ``_LIBCPP_DISABLE_DEPRECATION_WARNINGS``. Note that this + disables all deprecation warnings. + Build System Changes -------------------- diff --git a/libcxx/docs/Status/Cxx17Papers.csv b/libcxx/docs/Status/Cxx17Papers.csv --- a/libcxx/docs/Status/Cxx17Papers.csv +++ b/libcxx/docs/Status/Cxx17Papers.csv @@ -106,7 +106,7 @@ "`P0599R1 `__","LWG","noexcept for hash functions","Kona","|Complete|","5.0" "`P0604R0 `__","LWG","Resolving GB 55, US 84, US 85, US 86","Kona","|Complete|","" "`P0607R0 `__","LWG","Inline Variables for the Standard Library","Kona","|In Progress| [#note-P0607]_","6.0" -"`P0618R0 `__","LWG","Deprecating ","Kona","","" +"`P0618R0 `__","LWG","Deprecating ","Kona","|Complete|","15.0" "`P0623R0 `__","LWG","Final C++17 Parallel Algorithms Fixes","Kona","","" "","","","","","" "`P0682R1 `__","LWG","Repairing elementary string conversions","Toronto","","" diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -66,6 +66,7 @@ __algorithm/pop_heap.h __algorithm/prev_permutation.h __algorithm/push_heap.h + __algorithm/ranges_adjacent_find.h __algorithm/ranges_all_of.h __algorithm/ranges_any_of.h __algorithm/ranges_binary_search.h diff --git a/libcxx/include/__algorithm/ranges_adjacent_find.h b/libcxx/include/__algorithm/ranges_adjacent_find.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__algorithm/ranges_adjacent_find.h @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H +#define _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __adjacent_find { +struct __fn { + + template + _LIBCPP_HIDE_FROM_ABI constexpr static + _Iter __adjacent_find_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + if (__first == __last) + return __first; + + auto __i = __first; + while (++__i != __last) { + if (std::invoke(__pred, std::invoke(__proj, *__first), std::invoke(__proj, *__i))) + return __first; + __first = __i; + } + return __i; + } + + template _Sent, + class _Proj = identity, + indirect_binary_predicate, projected<_Iter, _Proj>> _Pred = ranges::equal_to> + _LIBCPP_HIDE_FROM_ABI constexpr + _Iter operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { + return __adjacent_find_impl(std::move(__first), std::move(__last), __pred, __proj); + } + + template , _Proj>, + projected, _Proj>> _Pred = ranges::equal_to> + _LIBCPP_HIDE_FROM_ABI constexpr + borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const { + return __adjacent_find_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + } +}; +} // namespace __adjacent_find + +inline namespace __cpo { + inline constexpr auto adjacent_find = __adjacent_find::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) + +#endif // _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm --- a/libcxx/include/algorithm +++ b/libcxx/include/algorithm @@ -391,6 +391,16 @@ Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 + template S, class Proj = identity, + indirect_binary_predicate, + projected> Pred = ranges::equal_to> + constexpr I ranges::adjacent_find(I first, S last, Pred pred = {}, Proj proj = {}); // since C+20 + + template, Proj>, + projected, Proj>> Pred = ranges::equal_to> + constexpr borrowed_iterator_t ranges::adjacent_find(R&& r, Pred pred = {}, Proj proj = {}); // since C++20 + } constexpr bool // constexpr in C++20 @@ -1107,6 +1117,7 @@ #include <__algorithm/pop_heap.h> #include <__algorithm/prev_permutation.h> #include <__algorithm/push_heap.h> +#include <__algorithm/ranges_adjacent_find.h> #include <__algorithm/ranges_all_of.h> #include <__algorithm/ranges_any_of.h> #include <__algorithm/ranges_binary_search.h> diff --git a/libcxx/include/codecvt b/libcxx/include/codecvt --- a/libcxx/include/codecvt +++ b/libcxx/include/codecvt @@ -65,7 +65,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -enum codecvt_mode +enum _LIBCPP_DEPRECATED_IN_CXX17 codecvt_mode { consume_header = 4, generate_header = 2, @@ -82,17 +82,23 @@ : public codecvt { unsigned long _Maxcode_; +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") codecvt_mode _Mode_; +_LIBCPP_DIAGNOSTIC_POP public: typedef wchar_t intern_type; typedef char extern_type; typedef mbstate_t state_type; +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") _LIBCPP_INLINE_VISIBILITY explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt(__refs), _Maxcode_(_Maxcode), _Mode_(_Mode) {} +_LIBCPP_DIAGNOSTIC_POP protected: virtual result do_out(state_type& __st, @@ -189,9 +195,11 @@ virtual int do_max_length() const _NOEXCEPT; }; +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") template -class _LIBCPP_TEMPLATE_VIS codecvt_utf8 +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 codecvt_utf8 : public __codecvt_utf8<_Elem> { public: @@ -202,6 +210,7 @@ _LIBCPP_INLINE_VISIBILITY ~codecvt_utf8() {} }; +_LIBCPP_DIAGNOSTIC_POP // codecvt_utf16 @@ -213,17 +222,23 @@ : public codecvt { unsigned long _Maxcode_; +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") codecvt_mode _Mode_; +_LIBCPP_DIAGNOSTIC_POP public: typedef wchar_t intern_type; typedef char extern_type; typedef mbstate_t state_type; +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") _LIBCPP_INLINE_VISIBILITY explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt(__refs), _Maxcode_(_Maxcode), _Mode_(_Mode) {} +_LIBCPP_DIAGNOSTIC_POP protected: virtual result do_out(state_type& __st, @@ -248,17 +263,23 @@ : public codecvt { unsigned long _Maxcode_; +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") codecvt_mode _Mode_; +_LIBCPP_DIAGNOSTIC_POP public: typedef wchar_t intern_type; typedef char extern_type; typedef mbstate_t state_type; +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") _LIBCPP_INLINE_VISIBILITY explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt(__refs), _Maxcode_(_Maxcode), _Mode_(_Mode) {} +_LIBCPP_DIAGNOSTIC_POP protected: virtual result do_out(state_type& __st, @@ -431,9 +452,11 @@ virtual int do_max_length() const _NOEXCEPT; }; +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") template -class _LIBCPP_TEMPLATE_VIS codecvt_utf16 +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 codecvt_utf16 : public __codecvt_utf16<_Elem, _Mode & little_endian> { public: @@ -444,6 +467,7 @@ _LIBCPP_INLINE_VISIBILITY ~codecvt_utf16() {} }; +_LIBCPP_DIAGNOSTIC_POP // codecvt_utf8_utf16 @@ -455,17 +479,23 @@ : public codecvt { unsigned long _Maxcode_; +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") codecvt_mode _Mode_; +_LIBCPP_DIAGNOSTIC_POP public: typedef wchar_t intern_type; typedef char extern_type; typedef mbstate_t state_type; +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") _LIBCPP_INLINE_VISIBILITY explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt(__refs), _Maxcode_(_Maxcode), _Mode_(_Mode) {} +_LIBCPP_DIAGNOSTIC_POP protected: virtual result do_out(state_type& __st, @@ -562,9 +592,11 @@ virtual int do_max_length() const _NOEXCEPT; }; +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") template -class _LIBCPP_TEMPLATE_VIS codecvt_utf8_utf16 +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 codecvt_utf8_utf16 : public __codecvt_utf8_utf16<_Elem> { public: @@ -575,6 +607,7 @@ _LIBCPP_INLINE_VISIBILITY ~codecvt_utf8_utf16() {} }; +_LIBCPP_DIAGNOSTIC_POP _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/locale b/libcxx/include/locale --- a/libcxx/include/locale +++ b/libcxx/include/locale @@ -3612,7 +3612,7 @@ template, class _Byte_alloc = allocator > -class _LIBCPP_TEMPLATE_VIS wstring_convert +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 wstring_convert { public: typedef basic_string, _Byte_alloc> byte_string; @@ -3877,7 +3877,7 @@ } template > -class _LIBCPP_TEMPLATE_VIS wbuffer_convert +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 wbuffer_convert : public basic_streambuf<_Elem, _Tr> { public: diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -298,6 +298,7 @@ module pop_heap { private header "__algorithm/pop_heap.h" } module prev_permutation { private header "__algorithm/prev_permutation.h" } module push_heap { private header "__algorithm/push_heap.h" } + module ranges_adjacent_find { private header "__algorithm/ranges_adjacent_find.h" } module ranges_all_of { private header "__algorithm/ranges_all_of.h" } module ranges_any_of { private header "__algorithm/ranges_any_of.h" } module ranges_binary_search { private header "__algorithm/ranges_binary_search.h" } diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp --- a/libcxx/src/locale.cpp +++ b/libcxx/src/locale.cpp @@ -1831,6 +1831,8 @@ // 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432 // 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536 +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") static codecvt_base::result utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt, @@ -3204,6 +3206,8 @@ return static_cast(frm_nxt - frm); } +_LIBCPP_DIAGNOSTIC_POP + // template <> class codecvt locale::id codecvt::id; @@ -3611,6 +3615,8 @@ #endif } +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-declarations") int __codecvt_utf8::do_max_length() const noexcept { @@ -4524,6 +4530,7 @@ return 7; return 4; } +_LIBCPP_DIAGNOSTIC_POP // __narrow_to_utf8<16> diff --git a/libcxx/test/libcxx/algorithms/ranges_robust_against_copying_comparators.pass.cpp b/libcxx/test/libcxx/algorithms/ranges_robust_against_copying_comparators.pass.cpp --- a/libcxx/test/libcxx/algorithms/ranges_robust_against_copying_comparators.pass.cpp +++ b/libcxx/test/libcxx/algorithms/ranges_robust_against_copying_comparators.pass.cpp @@ -90,8 +90,8 @@ int count = 1; int copies = 0; - //(void)std::ranges::adjacent_find(first, last, Equal(&copies)); assert(copies == 0); - //(void)std::ranges::adjacent_find(a, Equal(&copies)); assert(copies == 0); + (void)std::ranges::adjacent_find(first, last, Equal(&copies)); assert(copies == 0); + (void)std::ranges::adjacent_find(a, Equal(&copies)); assert(copies == 0); (void)std::ranges::all_of(first, last, UnaryTrue(&copies)); assert(copies == 0); (void)std::ranges::all_of(a, UnaryTrue(&copies)); assert(copies == 0); (void)std::ranges::any_of(first, last, UnaryTrue(&copies)); assert(copies == 0); diff --git a/libcxx/test/libcxx/algorithms/ranges_robust_against_copying_projections.pass.cpp b/libcxx/test/libcxx/algorithms/ranges_robust_against_copying_projections.pass.cpp --- a/libcxx/test/libcxx/algorithms/ranges_robust_against_copying_projections.pass.cpp +++ b/libcxx/test/libcxx/algorithms/ranges_robust_against_copying_projections.pass.cpp @@ -72,8 +72,8 @@ int count = 1; int copies = 0; - //(void)std::ranges::adjacent_find(first, last, Equal(), Proj(&copies)); assert(copies == 0); - //(void)std::ranges::adjacent_find(a, Equal(), Proj(&copies)); assert(copies == 0); + (void)std::ranges::adjacent_find(first, last, Equal(), Proj(&copies)); assert(copies == 0); + (void)std::ranges::adjacent_find(a, Equal(), Proj(&copies)); assert(copies == 0); (void)std::ranges::all_of(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0); (void)std::ranges::all_of(a, UnaryTrue(), Proj(&copies)); assert(copies == 0); (void)std::ranges::any_of(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0); diff --git a/libcxx/test/libcxx/localization/locales/locale.convenience/conversions/conversions.string/ctor_move.pass.cpp b/libcxx/test/libcxx/localization/locales/locale.convenience/conversions/conversions.string/ctor_move.pass.cpp --- a/libcxx/test/libcxx/localization/locales/locale.convenience/conversions/conversions.string/ctor_move.pass.cpp +++ b/libcxx/test/libcxx/localization/locales/locale.convenience/conversions/conversions.string/ctor_move.pass.cpp @@ -10,6 +10,8 @@ // UNSUPPORTED: c++03 +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // // wstring_convert diff --git a/libcxx/test/libcxx/private_headers.verify.cpp b/libcxx/test/libcxx/private_headers.verify.cpp --- a/libcxx/test/libcxx/private_headers.verify.cpp +++ b/libcxx/test/libcxx/private_headers.verify.cpp @@ -103,6 +103,7 @@ #include <__algorithm/pop_heap.h> // expected-error@*:* {{use of private header from outside its module: '__algorithm/pop_heap.h'}} #include <__algorithm/prev_permutation.h> // expected-error@*:* {{use of private header from outside its module: '__algorithm/prev_permutation.h'}} #include <__algorithm/push_heap.h> // expected-error@*:* {{use of private header from outside its module: '__algorithm/push_heap.h'}} +#include <__algorithm/ranges_adjacent_find.h> // expected-error@*:* {{use of private header from outside its module: '__algorithm/ranges_adjacent_find.h'}} #include <__algorithm/ranges_all_of.h> // expected-error@*:* {{use of private header from outside its module: '__algorithm/ranges_all_of.h'}} #include <__algorithm/ranges_any_of.h> // expected-error@*:* {{use of private header from outside its module: '__algorithm/ranges_any_of.h'}} #include <__algorithm/ranges_binary_search.h> // expected-error@*:* {{use of private header from outside its module: '__algorithm/ranges_binary_search.h'}} diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.transform/ranges.transform.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.transform/ranges.transform.pass.cpp --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.transform/ranges.transform.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.transform/ranges.transform.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17 // UNSUPPORTED: libcpp-has-no-incomplete-ranges -// On AIX the test takes a long time, leading to frequent CI timeouts. -// UNSUPPORTED: LIBCXX-AIX-FIXME // diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.adjacent.find/ranges.adjacent_find.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.adjacent.find/ranges.adjacent_find.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.adjacent.find/ranges.adjacent_find.pass.cpp @@ -0,0 +1,197 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-has-no-incomplete-ranges + +// template S, class Proj = identity, +// indirect_binary_predicate, +// projected> Pred = ranges::equal_to> +// constexpr I ranges::adjacent_find(I first, S last, Pred pred = {}, Proj proj = {}); +// template, Proj>, +// projected, Proj>> Pred = ranges::equal_to> +// constexpr borrowed_iterator_t ranges::adjacent_find(R&& r, Pred pred = {}, Proj proj = {}); + +#include +#include +#include +#include +#include + +#include "almost_satisfies_types.h" +#include "boolean_testable.h" +#include "test_iterators.h" + +template +concept HasAdjacentFindIt = requires (Iter iter, Sent sent) { std::ranges::adjacent_find(iter, sent); }; + +struct NotComparable {}; + +static_assert(HasAdjacentFindIt); +static_assert(!HasAdjacentFindIt); +static_assert(!HasAdjacentFindIt); +static_assert(!HasAdjacentFindIt); +static_assert(!HasAdjacentFindIt); +static_assert(!HasAdjacentFindIt); + +template +concept HasAdjacentFindR = requires (Range range) { std::ranges::adjacent_find(range); }; + +static_assert(HasAdjacentFindR>); +static_assert(!HasAdjacentFindR); +static_assert(!HasAdjacentFindR); +static_assert(!HasAdjacentFindR); +static_assert(!HasAdjacentFindR); +static_assert(!HasAdjacentFindR>); + +template +struct Data { + std::array input; + int expected; +}; + +template +constexpr void test(Data d) { + { + std::same_as decltype(auto) ret = + std::ranges::adjacent_find(Iter(d.input.data()), Sent(Iter(d.input.data() + d.input.size()))); + assert(base(ret) == d.input.data() + d.expected); + } + { + auto range = std::ranges::subrange(Iter(d.input.data()), Sent(Iter(d.input.data() + d.input.size()))); + std::same_as decltype(auto) ret = std::ranges::adjacent_find(range); + assert(base(ret) == d.input.data() + d.expected); + } +} + +template +constexpr void test_iterators() { + // simple test + test({.input = {1, 2, 2, 4}, .expected = 1}); + // last is returned with no match + test({.input = {1, 2, 3, 4}, .expected = 4}); + // first elements match + test({.input = {1, 1, 3, 4}, .expected = 0}); + // the first match is returned + test({.input = {1, 1, 3, 4, 4, 4, 4}, .expected = 0}); + // two element range works + test({.input = {3, 3}, .expected = 0}); + // single element range works + test({.input = {1}, .expected = 1}); + // empty range works + test({.input = {}, .expected = 0}); +} + +constexpr bool test() { + test_iterators, sentinel_wrapper>>(); + test_iterators>(); + test_iterators>(); + test_iterators>(); + test_iterators>(); + test_iterators(); + test_iterators(); + + { // check that ranges::dangling is returned + [[maybe_unused]] std::same_as decltype(auto) ret = + std::ranges::adjacent_find(std::array{1, 2, 3, 4}); + } + + { // check that the complexity requirements are met with no match + { + int predicateCount = 0; + auto pred = [&](int, int) { ++predicateCount; return false; }; + auto projectionCount = 0; + auto proj = [&](int i) { ++projectionCount; return i; }; + int a[] = {1, 2, 3, 4, 5}; + auto ret = std::ranges::adjacent_find(a, a + 5, pred, proj); + assert(ret == a + 5); + assert(predicateCount == 4); + assert(projectionCount == 8); + } + { + int predicateCount = 0; + auto pred = [&](int, int) { ++predicateCount; return false; }; + auto projectionCount = 0; + auto proj = [&](int i) { ++projectionCount; return i; }; + int a[] = {1, 2, 3, 4, 5}; + auto ret = std::ranges::adjacent_find(a, pred, proj); + assert(ret == a + 5); + assert(predicateCount == 4); + assert(projectionCount == 8); + } + } + + { // check that the complexity requirements are met with a match + { + int predicateCount = 0; + auto pred = [&](int i, int j) { ++predicateCount; return i == j; }; + auto projectionCount = 0; + auto proj = [&](int i) { ++projectionCount; return i; }; + int a[] = {1, 2, 4, 4, 5}; + auto ret = std::ranges::adjacent_find(a, a + 5, pred, proj); + assert(ret == a + 2); + assert(predicateCount == 3); + assert(projectionCount == 6); + } + { + int predicateCount = 0; + auto pred = [&](int i, int j) { ++predicateCount; return i == j; }; + auto projectionCount = 0; + auto proj = [&](int i) { ++projectionCount; return i; }; + int a[] = {1, 2, 4, 4, 5}; + auto ret = std::ranges::adjacent_find(a, pred, proj); + assert(ret == a + 2); + assert(predicateCount == 3); + assert(projectionCount == 6); + } + } + + { // check that std::invoke is used + struct S { + constexpr S(int i_) : i(i_) {} + constexpr bool compare(const S& j) const { return j.i == i; } + constexpr const S& identity() const { return *this; } + int i; + }; + { + S a[] = {1, 2, 3, 4}; + auto ret = std::ranges::adjacent_find(std::begin(a), std::end(a), &S::compare, &S::identity); + assert(ret == a + 4); + } + { + S a[] = {1, 2, 3, 4}; + auto ret = std::ranges::adjacent_find(a, &S::compare, &S::identity); + assert(ret == a + 4); + } + } + + { // check that the implicit conversion to bool works + { + int a[] = {1, 2, 2, 4}; + auto ret = std::ranges::adjacent_find(a, a + 4, [](int i, int j) { return BooleanTestable{i == j}; }); + assert(ret == a + 1); + } + { + int a[] = {1, 2, 2, 4}; + auto ret = std::ranges::adjacent_find(a, [](int i, int j) { return BooleanTestable{i == j}; }); + assert(ret == a + 1); + } + } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/library/description/conventions/customization.point.object/niebloid.compile.pass.cpp b/libcxx/test/std/library/description/conventions/customization.point.object/niebloid.compile.pass.cpp --- a/libcxx/test/std/library/description/conventions/customization.point.object/niebloid.compile.pass.cpp +++ b/libcxx/test/std/library/description/conventions/customization.point.object/niebloid.compile.pass.cpp @@ -60,7 +60,7 @@ // [algorithm.syn] -//static_assert(test(std::ranges::adjacent_find, a)); +static_assert(test(std::ranges::adjacent_find, a)); static_assert(test(std::ranges::all_of, a, odd)); static_assert(test(std::ranges::any_of, a, odd)); static_assert(test(std::ranges::binary_search, a, 42)); diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_mode.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_mode.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_mode.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_mode.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // enum codecvt_mode // { // consume_header = 4, diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf16 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_always_noconv.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_always_noconv.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_always_noconv.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_always_noconv.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf16 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_encoding.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_encoding.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_encoding.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_encoding.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf16 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_in.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_in.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_in.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_in.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf16 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_length.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_length.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_length.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_length.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf16 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_max_length.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_max_length.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_max_length.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_max_length.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf16 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_out.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_out.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_out.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_out.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf16 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_unshift.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_unshift.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_unshift.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf16_unshift.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf16 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf8 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_always_noconv.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_always_noconv.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_always_noconv.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_always_noconv.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf8 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_encoding.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_encoding.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_encoding.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_encoding.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf8 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_in.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_in.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_in.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_in.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf8 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_length.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_length.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_length.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_length.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf8 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_max_length.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_max_length.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_max_length.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_max_length.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf8 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_out.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_out.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_out.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_out.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf8 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_unshift.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_unshift.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_unshift.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_unshift.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf8 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_always_noconv.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_always_noconv.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_always_noconv.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_always_noconv.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf8_utf16 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_encoding.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_encoding.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_encoding.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_encoding.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf8_utf16 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_in.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_in.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_in.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_in.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf8_utf16 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_length.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_length.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_length.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_length.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf8_utf16 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_max_length.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_max_length.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_max_length.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_max_length.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf8_utf16 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_out.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_out.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_out.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_out.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf8_utf16 diff --git a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_unshift.pass.cpp b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_unshift.pass.cpp --- a/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_unshift.pass.cpp +++ b/libcxx/test/std/localization/locale.stdcvt/codecvt_utf8_utf16_unshift.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // class codecvt_utf8_utf16 diff --git a/libcxx/test/std/localization/locale.stdcvt/depr.verify.cpp b/libcxx/test/std/localization/locale.stdcvt/depr.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/localization/locale.stdcvt/depr.verify.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +// + +// ensure that codecvt content is marked as deprecated + +#include + +std::codecvt_mode c1; // expected-warning {{'codecvt_mode' is deprecated}} +std::codecvt_utf8 c2; // expected-warning {{'codecvt_utf8' is deprecated}} +std::codecvt_utf16 c3; // expected-warning {{'codecvt_utf16' is deprecated}} +std::codecvt_utf8_utf16 c4; // expected-warning {{'codecvt_utf8_utf16' is deprecated}} diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // wbuffer_convert // wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt, diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/state.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/depr.verify.cpp copy from libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/state.pass.cpp copy to libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/depr.verify.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/state.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/depr.verify.cpp @@ -6,29 +6,14 @@ // //===----------------------------------------------------------------------===// -// +// UNSUPPORTED: c++03, c++11, c++14 -// wbuffer_convert +// -// state_type state() const; +// ensure that wbuffer_convert is marked as deprecated -// XFAIL: no-wide-characters - -#include #include -#include -#include - -#include "test_macros.h" - -int main(int, char**) -{ - typedef std::wbuffer_convert > B; - { - B b; - std::mbstate_t s = b.state(); - ((void)s); - } +#include - return 0; -} +std::wbuffer_convert> c1; // expected-warning {{'wbuffer_convert>' is deprecated}} +// expected-warning@-1 {{'codecvt_utf8' is deprecated}} diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/overflow.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/overflow.pass.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/overflow.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/overflow.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // wbuffer_convert // int_type overflow(int_type c = traits::eof()); diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/pbackfail.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/pbackfail.pass.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/pbackfail.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/pbackfail.pass.cpp @@ -10,6 +10,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // wbuffer_convert // int_type pbackfail(int_type c = traits::eof()); diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/rdbuf.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/rdbuf.pass.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/rdbuf.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/rdbuf.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // wbuffer_convert // streambuf *rdbuf(streambuf *bytebuf); diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/seekoff.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/seekoff.pass.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/seekoff.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/seekoff.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // wbuffer_convert // pos_type seekoff(off_type off, ios_base::seekdir way, diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/state.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/state.pass.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/state.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/state.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // wbuffer_convert // state_type state() const; diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/test.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/test.pass.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/test.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/test.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // wbuffer_convert // XFAIL: no-wide-characters diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/underflow.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/underflow.pass.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/underflow.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/underflow.pass.cpp @@ -10,6 +10,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // wbuffer_convert // int_type underflow(); diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/converted.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/converted.pass.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/converted.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/converted.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // wstring_convert // size_t converted() const; diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_codecvt.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_codecvt.pass.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_codecvt.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_codecvt.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // wstring_convert // wstring_convert(Codecvt* pcvt = new Codecvt); // before C++14 diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_codecvt_state.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_codecvt_state.pass.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_codecvt_state.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_codecvt_state.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // wstring_convert // wstring_convert(Codecvt* pcvt, state_type state); diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_copy.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_copy.pass.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_copy.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_copy.pass.cpp @@ -12,6 +12,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // wstring_convert // wstring_convert(wstring_convert const&) = delete; diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_err_string.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_err_string.pass.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_err_string.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_err_string.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // wstring_convert // wstring_convert(const byte_string& byte_err, diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/state.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/depr.verify.cpp copy from libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/state.pass.cpp copy to libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/depr.verify.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/state.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/depr.verify.cpp @@ -6,29 +6,14 @@ // //===----------------------------------------------------------------------===// -// +// UNSUPPORTED: c++03, c++11, c++14 -// wbuffer_convert +// -// state_type state() const; +// ensure that wstring_convert is marked as deprecated -// XFAIL: no-wide-characters - -#include #include -#include -#include - -#include "test_macros.h" - -int main(int, char**) -{ - typedef std::wbuffer_convert > B; - { - B b; - std::mbstate_t s = b.state(); - ((void)s); - } +#include - return 0; -} +std::wstring_convert> c1; // expected-warning {{'wstring_convert>' is deprecated}} +// expected-warning@-1 {{'codecvt_utf8' is deprecated}} diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/from_bytes.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/from_bytes.pass.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/from_bytes.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/from_bytes.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // wstring_convert // wide_string from_bytes(char byte); diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/state.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/state.pass.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/state.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/state.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // wstring_convert // state_type state() const; diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/to_bytes.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/to_bytes.pass.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/to_bytes.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/to_bytes.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // wstring_convert // byte_string to_bytes(Elem wchar); diff --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/types.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/types.pass.cpp --- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/types.pass.cpp +++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/types.pass.cpp @@ -8,6 +8,8 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template, // class Byte_alloc = allocator> diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -746,7 +746,12 @@ set(LLVM_TARGET_TRIPLE_ENV CACHE STRING "The name of environment variable to override default target. Disabled by blank.") mark_as_advanced(LLVM_TARGET_TRIPLE_ENV) -set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR OFF CACHE BOOL +if(CMAKE_SYSTEM_NAME MATCHES "Linux") + set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_default ON) +else() + set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_default OFF) +endif() +set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ${LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_default} CACHE BOOL "Enable per-target runtimes directory") set(LLVM_PROFDATA_FILE "" CACHE FILEPATH diff --git a/llvm/docs/OpaquePointers.rst b/llvm/docs/OpaquePointers.rst --- a/llvm/docs/OpaquePointers.rst +++ b/llvm/docs/OpaquePointers.rst @@ -222,3 +222,12 @@ * Migrate Clang/LLVM tests to use opaque pointers. * Remove support for typed pointers after the LLVM 15 branch has been created. + +Version Support +=============== + +**LLVM 14:** Supports all necessary APIs for migrating to opaque pointers and deprecates/removes incompatible APIs. However, using opaque pointers in the optimization pipeline is **not** fully supported. This release can be used to make out-of-tree code compatible with opaque pointers, but opaque pointers should **not** be enabled in production. + +**LLVM 15:** Opaque pointers are enabled by default. Typed pointers are still available, but only supported on a best-effort basis and may be untested. + +**LLVM 16:** Only opaque pointers will be supported. Typed pointers will not be supported. diff --git a/llvm/docs/ProgrammersManual.rst b/llvm/docs/ProgrammersManual.rst --- a/llvm/docs/ProgrammersManual.rst +++ b/llvm/docs/ProgrammersManual.rst @@ -1705,6 +1705,9 @@ list, and ``ilist``\ s are guaranteed to support a constant-time splice operation. +An ``ilist`` and an ``iplist`` are ``using`` aliases to one another and the +latter only currently exists for historical purposes. + These properties are exactly what we want for things like ``Instruction``\ s and basic blocks, which is why these are implemented with ``ilist``\ s. @@ -1712,8 +1715,6 @@ * :ref:`ilist_traits ` -* :ref:`iplist ` - * :ref:`llvm/ADT/ilist_node.h ` * :ref:`Sentinels ` @@ -1754,19 +1755,8 @@ ilist_traits ^^^^^^^^^^^^ -``ilist_traits`` is ``ilist``'s customization mechanism. ``iplist`` -(and consequently ``ilist``) publicly derive from this traits class. - -.. _dss_iplist: - -iplist -^^^^^^ - -``iplist`` is ``ilist``'s base and as such supports a slightly narrower -interface. Notably, inserters from ``T&`` are absent. - -``ilist_traits`` is a public base of this class and can be used for a wide -variety of customizations. +``ilist_traits`` is ``ilist``'s customization mechanism. ``ilist`` +publicly derives from this traits class. .. _dss_ilist_node: diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -102,6 +102,8 @@ versions. * Added a pass to workaround Cortex-A57 Erratum 1742098 and Cortex-A72 Erratum 1655431. This is enabled by default when targeting either CPU. +* Implemented generation of Windows SEH unwind information. +* Switched the MinGW target to use SEH instead of DWARF for unwind information. Changes to the AVR Backend -------------------------- diff --git a/llvm/include/llvm/ADT/edit_distance.h b/llvm/include/llvm/ADT/edit_distance.h --- a/llvm/include/llvm/ADT/edit_distance.h +++ b/llvm/include/llvm/ADT/edit_distance.h @@ -61,6 +61,15 @@ typename ArrayRef::size_type m = FromArray.size(); typename ArrayRef::size_type n = ToArray.size(); + if (MaxEditDistance) { + // If the difference in size between the 2 arrays is larger than the max + // distance allowed, we can bail out as we will always need at least + // MaxEditDistance insertions or removals. + typename ArrayRef::size_type AbsDiff = m > n ? m - n : n - m; + if (AbsDiff > MaxEditDistance) + return MaxEditDistance + 1; + } + const unsigned SmallBufferSize = 64; unsigned SmallBuffer[SmallBufferSize]; std::unique_ptr Allocated; diff --git a/llvm/include/llvm/Support/TypeSize.h b/llvm/include/llvm/Support/TypeSize.h --- a/llvm/include/llvm/Support/TypeSize.h +++ b/llvm/include/llvm/Support/TypeSize.h @@ -373,6 +373,20 @@ isScalable())); } + /// Returns true if there exists a value X where RHS.multiplyCoefficientBy(X) + /// will result in a value whose size matches our own. + bool hasKnownScalarFactor(const LinearPolySize &RHS) const { + return isScalable() == RHS.isScalable() && + getKnownMinValue() % RHS.getKnownMinValue() == 0; + } + + /// Returns a value X where RHS.multiplyCoefficientBy(X) will result in a + /// value whose size matches our own. + ScalarTy getKnownScalarFactor(const LinearPolySize &RHS) const { + assert(hasKnownScalarFactor(RHS) && "Expected RHS to be a known factor!"); + return getKnownMinValue() / RHS.getKnownMinValue(); + } + /// Printing function. void print(raw_ostream &OS) const { if (isScalable()) diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp --- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -734,8 +734,6 @@ llvm::sort(Cache); ++NumCacheDirtyNonLocal; - // cerr << "CACHED CASE: " << DirtyBlocks.size() << " dirty: " - // << Cache.size() << " cached: " << *QueryInst; } else { // Seed DirtyBlocks with each of the preds of QueryInst's block. BasicBlock *QueryBB = QueryCall->getParent(); diff --git a/llvm/lib/Analysis/PHITransAddr.cpp b/llvm/lib/Analysis/PHITransAddr.cpp --- a/llvm/lib/Analysis/PHITransAddr.cpp +++ b/llvm/lib/Analysis/PHITransAddr.cpp @@ -34,9 +34,6 @@ isa(Inst->getOperand(1))) return true; - // cerr << "MEMDEP: Could not PHI translate: " << *Pointer; - // if (isa(PtrInst) || isa(PtrInst)) - // cerr << "OP:\t\t\t\t" << *PtrInst->getOperand(0); return false; } diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -4806,7 +4806,6 @@ } // It isn't profitable to do this, roll back. - //cerr << "NOT FOLDING: " << *I; AddrMode = BackupAddrMode; AddrModeInsts.resize(OldSize); TPT.rollback(LastKnownGood); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -1731,16 +1731,14 @@ SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp, EVT SlotVT, EVT DestVT, const SDLoc &dl, SDValue Chain) { - unsigned SrcSize = SrcOp.getValueSizeInBits(); - unsigned SlotSize = SlotVT.getSizeInBits(); - unsigned DestSize = DestVT.getSizeInBits(); + EVT SrcVT = SrcOp.getValueType(); Type *DestType = DestVT.getTypeForEVT(*DAG.getContext()); Align DestAlign = DAG.getDataLayout().getPrefTypeAlign(DestType); // Don't convert with stack if the load/store is expensive. - if ((SrcSize > SlotSize && + if ((SrcVT.bitsGT(SlotVT) && !TLI.isTruncStoreLegalOrCustom(SrcOp.getValueType(), SlotVT)) || - (SlotSize < DestSize && + (SlotVT.bitsLT(DestVT) && !TLI.isLoadExtLegalOrCustom(ISD::EXTLOAD, DestVT, SlotVT))) return SDValue(); @@ -1758,20 +1756,19 @@ // later than DestVT. SDValue Store; - if (SrcSize > SlotSize) + if (SrcVT.bitsGT(SlotVT)) Store = DAG.getTruncStore(Chain, dl, SrcOp, FIPtr, PtrInfo, SlotVT, SrcAlign); else { - assert(SrcSize == SlotSize && "Invalid store"); - Store = - DAG.getStore(Chain, dl, SrcOp, FIPtr, PtrInfo, SrcAlign); + assert(SrcVT.bitsEq(SlotVT) && "Invalid store"); + Store = DAG.getStore(Chain, dl, SrcOp, FIPtr, PtrInfo, SrcAlign); } // Result is a load from the stack slot. - if (SlotSize == DestSize) + if (SlotVT.bitsEq(DestVT)) return DAG.getLoad(DestVT, dl, Store, FIPtr, PtrInfo, DestAlign); - assert(SlotSize < DestSize && "Unknown extension!"); + assert(SlotVT.bitsLT(DestVT) && "Unknown extension!"); return DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, Store, FIPtr, PtrInfo, SlotVT, DestAlign); } diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -453,13 +453,13 @@ // as the widened input type would be a legal type, we can widen the bitcast // and handle the promotion after. if (NOutVT.isVector()) { - unsigned WidenInSize = NInVT.getSizeInBits(); - unsigned OutSize = OutVT.getSizeInBits(); - if (WidenInSize % OutSize == 0) { - unsigned Scale = WidenInSize / OutSize; - EVT WideOutVT = EVT::getVectorVT(*DAG.getContext(), - OutVT.getVectorElementType(), - OutVT.getVectorNumElements() * Scale); + TypeSize WidenInSize = NInVT.getSizeInBits(); + TypeSize OutSize = OutVT.getSizeInBits(); + if (WidenInSize.hasKnownScalarFactor(OutSize)) { + unsigned Scale = WidenInSize.getKnownScalarFactor(OutSize); + EVT WideOutVT = + EVT::getVectorVT(*DAG.getContext(), OutVT.getVectorElementType(), + OutVT.getVectorElementCount() * Scale); if (isTypeLegal(WideOutVT)) { InOp = DAG.getBitcast(WideOutVT, GetWidenedVector(InOp)); InOp = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, OutVT, InOp, diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp --- a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp @@ -16,8 +16,11 @@ #include "llvm/BinaryFormat/ELF.h" #include "llvm/ExecutionEngine/JITLink/aarch64.h" #include "llvm/Object/ELFObjectFile.h" +#include "llvm/Support/Endian.h" #include "llvm/Support/MathExtras.h" +#include "PerGraphGOTAndPLTStubsBuilder.h" + #define DEBUG_TYPE "jitlink" using namespace llvm; @@ -45,7 +48,17 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder { private: enum ELFAArch64RelocationKind : Edge::Kind { - ELFBranch26 = Edge::FirstRelocation, + ELFCall26 = Edge::FirstRelocation, + ELFAdrPage21, + ELFAddAbs12, + ELFLdSt8Abs12, + ELFLdSt16Abs12, + ELFLdSt32Abs12, + ELFLdSt64Abs12, + ELFLdSt128Abs12, + ELFAbs64, + ELFAdrGOTPage21, + ELFLd64GOTLo12, }; static Expected @@ -53,7 +66,27 @@ using namespace aarch64; switch (Type) { case ELF::R_AARCH64_CALL26: - return ELFBranch26; + return ELFCall26; + case ELF::R_AARCH64_ADR_PREL_PG_HI21: + return ELFAdrPage21; + case ELF::R_AARCH64_ADD_ABS_LO12_NC: + return ELFAddAbs12; + case ELF::R_AARCH64_LDST8_ABS_LO12_NC: + return ELFLdSt8Abs12; + case ELF::R_AARCH64_LDST16_ABS_LO12_NC: + return ELFLdSt16Abs12; + case ELF::R_AARCH64_LDST32_ABS_LO12_NC: + return ELFLdSt32Abs12; + case ELF::R_AARCH64_LDST64_ABS_LO12_NC: + return ELFLdSt64Abs12; + case ELF::R_AARCH64_LDST128_ABS_LO12_NC: + return ELFLdSt128Abs12; + case ELF::R_AARCH64_ABS64: + return ELFAbs64; + case ELF::R_AARCH64_ADR_GOT_PAGE: + return ELFAdrGOTPage21; + case ELF::R_AARCH64_LD64_GOT_LO12_NC: + return ELFLd64GOTLo12; } return make_error("Unsupported aarch64 relocation:" + @@ -76,6 +109,7 @@ Error addSingleRelocation(const typename ELFT::Rela &Rel, const typename ELFT::Shdr &FixupSect, Block &BlockToFix) { + using support::ulittle32_t; using Base = ELFLinkGraphBuilder; uint32_t SymbolIndex = Rel.getSymbol(false); @@ -102,13 +136,92 @@ orc::ExecutorAddr(FixupSect.sh_addr) + Rel.r_offset; Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress(); + // Get a pointer to the fixup content. + const void *FixupContent = BlockToFix.getContent().data() + + (FixupAddress - BlockToFix.getAddress()); + Edge::Kind Kind = Edge::Invalid; switch (*RelocKind) { - case ELFBranch26: { + case ELFCall26: { Kind = aarch64::Branch26; break; } + case ELFAdrPage21: { + Kind = aarch64::Page21; + break; + } + case ELFAddAbs12: { + Kind = aarch64::PageOffset12; + break; + } + case ELFLdSt8Abs12: { + uint32_t Instr = *(const ulittle32_t *)FixupContent; + if (!aarch64::isLoadStoreImm12(Instr) || + aarch64::getPageOffset12Shift(Instr) != 0) + return make_error( + "R_AARCH64_LDST8_ABS_LO12_NC target is not a " + "LDRB/STRB (imm12) instruction"); + + Kind = aarch64::PageOffset12; + break; + } + case ELFLdSt16Abs12: { + uint32_t Instr = *(const ulittle32_t *)FixupContent; + if (!aarch64::isLoadStoreImm12(Instr) || + aarch64::getPageOffset12Shift(Instr) != 1) + return make_error( + "R_AARCH64_LDST16_ABS_LO12_NC target is not a " + "LDRH/STRH (imm12) instruction"); + + Kind = aarch64::PageOffset12; + break; + } + case ELFLdSt32Abs12: { + uint32_t Instr = *(const ulittle32_t *)FixupContent; + if (!aarch64::isLoadStoreImm12(Instr) || + aarch64::getPageOffset12Shift(Instr) != 2) + return make_error( + "R_AARCH64_LDST32_ABS_LO12_NC target is not a " + "LDR/STR (imm12, 32 bit) instruction"); + + Kind = aarch64::PageOffset12; + break; + } + case ELFLdSt64Abs12: { + uint32_t Instr = *(const ulittle32_t *)FixupContent; + if (!aarch64::isLoadStoreImm12(Instr) || + aarch64::getPageOffset12Shift(Instr) != 3) + return make_error( + "R_AARCH64_LDST64_ABS_LO12_NC target is not a " + "LDR/STR (imm12, 64 bit) instruction"); + + Kind = aarch64::PageOffset12; + break; + } + case ELFLdSt128Abs12: { + uint32_t Instr = *(const ulittle32_t *)FixupContent; + if (!aarch64::isLoadStoreImm12(Instr) || + aarch64::getPageOffset12Shift(Instr) != 4) + return make_error( + "R_AARCH64_LDST128_ABS_LO12_NC target is not a " + "LDR/STR (imm12, 128 bit) instruction"); + + Kind = aarch64::PageOffset12; + break; + } + case ELFAbs64: { + Kind = aarch64::Pointer64; + break; + } + case ELFAdrGOTPage21: { + Kind = aarch64::GOTPage21; + break; + } + case ELFLd64GOTLo12: { + Kind = aarch64::GOTPageOffset12; + break; + } }; Edge GE(Kind, Offset, *GraphSymbol, Addend); @@ -125,8 +238,28 @@ /// Return the string name of the given ELF aarch64 edge kind. const char *getELFAArch64RelocationKindName(Edge::Kind R) { switch (R) { - case ELFBranch26: - return "ELFBranch26"; + case ELFCall26: + return "ELFCall26"; + case ELFAdrPage21: + return "ELFAdrPage21"; + case ELFAddAbs12: + return "ELFAddAbs12"; + case ELFLdSt8Abs12: + return "ELFLdSt8Abs12"; + case ELFLdSt16Abs12: + return "ELFLdSt16Abs12"; + case ELFLdSt32Abs12: + return "ELFLdSt32Abs12"; + case ELFLdSt64Abs12: + return "ELFLdSt64Abs12"; + case ELFLdSt128Abs12: + return "ELFLdSt128Abs12"; + case ELFAbs64: + return "ELFAbs64"; + case ELFAdrGOTPage21: + return "ELFAdrGOTPage21"; + case ELFLd64GOTLo12: + return "ELFLd64GOTLo12"; default: return getGenericEdgeKindName(static_cast(R)); } @@ -139,6 +272,64 @@ aarch64::getEdgeKindName) {} }; +class PerGraphGOTAndPLTStubsBuilder_ELF_arm64 + : public PerGraphGOTAndPLTStubsBuilder< + PerGraphGOTAndPLTStubsBuilder_ELF_arm64> { +public: + using PerGraphGOTAndPLTStubsBuilder< + PerGraphGOTAndPLTStubsBuilder_ELF_arm64>::PerGraphGOTAndPLTStubsBuilder; + + bool isGOTEdgeToFix(Edge &E) const { + return E.getKind() == aarch64::GOTPage21 || + E.getKind() == aarch64::GOTPageOffset12; + } + + Symbol &createGOTEntry(Symbol &Target) { + auto &GOTEntryBlock = G.createContentBlock( + getGOTSection(), getGOTEntryBlockContent(), orc::ExecutorAddr(), 8, 0); + GOTEntryBlock.addEdge(aarch64::Pointer64, 0, Target, 0); + return G.addAnonymousSymbol(GOTEntryBlock, 0, 8, false, false); + } + + void fixGOTEdge(Edge &E, Symbol &GOTEntry) { + if (E.getKind() == aarch64::GOTPage21) { + E.setKind(aarch64::Page21); + E.setTarget(GOTEntry); + } else if (E.getKind() == aarch64::GOTPageOffset12) { + E.setKind(aarch64::PageOffset12); + E.setTarget(GOTEntry); + } else + llvm_unreachable("Not a GOT edge?"); + } + + bool isExternalBranchEdge(Edge &E) { return false; } + + Symbol &createPLTStub(Symbol &Target) { + assert(false && "unimplemetned"); + return Target; + } + + void fixPLTEdge(Edge &E, Symbol &Stub) { assert(false && "unimplemetned"); } + +private: + Section &getGOTSection() { + if (!GOTSection) + GOTSection = &G.createSection("$__GOT", MemProt::Read | MemProt::Exec); + return *GOTSection; + } + + ArrayRef getGOTEntryBlockContent() { + return {reinterpret_cast(NullGOTEntryContent), + sizeof(NullGOTEntryContent)}; + } + + static const uint8_t NullGOTEntryContent[8]; + Section *GOTSection = nullptr; +}; + +const uint8_t PerGraphGOTAndPLTStubsBuilder_ELF_arm64::NullGOTEntryContent[8] = + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + Expected> createLinkGraphFromELFObject_aarch64(MemoryBufferRef ObjectBuffer) { LLVM_DEBUG({ @@ -170,6 +361,10 @@ else Config.PrePrunePasses.push_back(markAllSymbolsLive); } + + Config.PostPrunePasses.push_back( + PerGraphGOTAndPLTStubsBuilder_ELF_arm64::asPass); + if (auto Err = Ctx->modifyPassConfig(*G, Config)) return Ctx->notifyFailed(std::move(Err)); diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -3817,6 +3817,14 @@ return LowerFixedLengthBitcastToSVE(Op, DAG); if (OpVT.isScalableVector()) { + // Bitcasting between unpacked vector types of different element counts is + // not a NOP because the live elements are laid out differently. + // 01234567 + // e.g. nxv2i32 = XX??XX?? + // nxv4f16 = X?X?X?X? + if (OpVT.getVectorElementCount() != ArgVT.getVectorElementCount()) + return SDValue(); + if (isTypeLegal(OpVT) && !isTypeLegal(ArgVT)) { assert(OpVT.isFloatingPoint() && !ArgVT.isFloatingPoint() && "Expected int->fp bitcast!"); @@ -19282,6 +19290,15 @@ if (VT.isScalableVector() && !isTypeLegal(VT) && isTypeLegal(SrcVT)) { assert(!VT.isFloatingPoint() && SrcVT.isFloatingPoint() && "Expected fp->int bitcast!"); + + // Bitcasting between unpacked vector types of different element counts is + // not a NOP because the live elements are laid out differently. + // 01234567 + // e.g. nxv2i32 = XX??XX?? + // nxv4f16 = X?X?X?X? + if (VT.getVectorElementCount() != SrcVT.getVectorElementCount()) + return; + SDValue CastResult = getSVESafeBitCast(getSVEContainerType(VT), Op, DAG); Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, CastResult)); return; @@ -21137,6 +21154,17 @@ EVT PackedVT = getPackedSVEVectorVT(VT.getVectorElementType()); EVT PackedInVT = getPackedSVEVectorVT(InVT.getVectorElementType()); + // Safe bitcasting between unpacked vector types of different element counts + // is currently unsupported because the following is missing the necessary + // work to ensure the result's elements live where they're supposed to within + // an SVE register. + // 01234567 + // e.g. nxv2i32 = XX??XX?? + // nxv4f16 = X?X?X?X? + assert((VT.getVectorElementCount() == InVT.getVectorElementCount() || + VT == PackedVT || InVT == PackedInVT) && + "Unexpected bitcast!"); + // Pack input if required. if (InVT != PackedInVT) Op = DAG.getNode(AArch64ISD::REINTERPRET_CAST, DL, PackedInVT, Op); diff --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp --- a/llvm/lib/Target/DirectX/DXILPrepare.cpp +++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp @@ -127,7 +127,7 @@ continue; } // Only insert bitcasts if the IR is using opaque pointers. - if (!M.getContext().hasSetOpaquePointersValue()) + if (M.getContext().supportsTypedPointers()) continue; // Emtting NoOp bitcast instructions allows the ValueEnumerator to be diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -2564,6 +2564,7 @@ bool SkipOutermostLoad = !isa(DVI); Value *Storage = DVI->getVariableLocationOp(0); Value *OriginalStorage = Storage; + while (auto *Inst = dyn_cast_or_null(Storage)) { if (auto *LdInst = dyn_cast(Inst)) { Storage = LdInst->getOperand(0); @@ -2619,8 +2620,7 @@ // expression, we need to add a DW_OP_deref at the *start* of the // expression to first load the contents of the alloca before // adjusting it with the expression. - if (Expr && Expr->isComplex()) - Expr = DIExpression::prepend(Expr, DIExpression::DerefBefore); + Expr = DIExpression::prepend(Expr, DIExpression::DerefBefore); } DVI->replaceVariableLocationOp(OriginalStorage, Storage); diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -608,17 +608,14 @@ // Will trap. } else if (const StoreInst *SI = dyn_cast(U)) { if (SI->getOperand(0) == V) { - //cerr << "NONTRAPPING USE: " << *U; return false; // Storing the value. } } else if (const CallInst *CI = dyn_cast(U)) { if (CI->getCalledOperand() != V) { - //cerr << "NONTRAPPING USE: " << *U; return false; // Not calling the ptr } } else if (const InvokeInst *II = dyn_cast(U)) { if (II->getCalledOperand() != V) { - //cerr << "NONTRAPPING USE: " << *U; return false; // Not calling the ptr } } else if (const BitCastInst *CI = dyn_cast(U)) { @@ -642,7 +639,6 @@ // the comparing of the value of the created global init bool later in // optimizeGlobalAddressOfAllocation for the global variable. } else { - //cerr << "NONTRAPPING USE: " << *U; return false; } } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -36,8 +36,10 @@ if (BinaryOperator *I = dyn_cast(Val)) { // Cannot look past anything that might overflow. + // We specifically require nuw because we store the Scale in an unsigned + // and perform an unsigned divide on it. OverflowingBinaryOperator *OBI = dyn_cast(Val); - if (OBI && !OBI->hasNoUnsignedWrap() && !OBI->hasNoSignedWrap()) { + if (OBI && !OBI->hasNoUnsignedWrap()) { Scale = 1; Offset = 0; return Val; diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp --- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp @@ -1632,7 +1632,6 @@ NewS = Ext; const SCEV *V = cast(NewS)->evaluateAtIteration(IH, SE); - //cerr << "Evaluated: " << *this << "\n to: " << *V << "\n"; // Truncate the result down to the original type, if needed. const SCEV *T = SE.getTruncateOrNoop(V, Ty); diff --git a/llvm/test/Bitcode/compatibility.ll b/llvm/test/Bitcode/compatibility.ll --- a/llvm/test/Bitcode/compatibility.ll +++ b/llvm/test/Bitcode/compatibility.ll @@ -6,7 +6,7 @@ ; http://llvm.org/docs/DeveloperPolicy.html#ir-backwards-compatibility ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s -; RUN-PR24755: verify-uselistorder < %s +; RUN: verify-uselistorder < %s target datalayout = "E" ; CHECK: target datalayout = "E" diff --git a/llvm/test/CodeGen/AArch64/sve-bitcast.ll b/llvm/test/CodeGen/AArch64/sve-bitcast.ll --- a/llvm/test/CodeGen/AArch64/sve-bitcast.ll +++ b/llvm/test/CodeGen/AArch64/sve-bitcast.ll @@ -518,6 +518,15 @@ ret %bc } +define @bitcast_nxv1i64_to_nxv8i8( %v) #0 { +; CHECK-LABEL: bitcast_nxv1i64_to_nxv8i8: +; CHECK: // %bb.0: +; CHECK-NEXT: uunpklo z0.h, z0.b +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + define @bitcast_nxv4f16_to_nxv8i8( %v) #0 { ; CHECK-LABEL: bitcast_nxv4f16_to_nxv8i8: ; CHECK: // %bb.0: @@ -550,6 +559,15 @@ ret %bc } +define @bitcast_nxv1f64_to_nxv8i8( %v) #0 { +; CHECK-LABEL: bitcast_nxv1f64_to_nxv8i8: +; CHECK: // %bb.0: +; CHECK-NEXT: uunpklo z0.h, z0.b +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + define @bitcast_nxv4bf16_to_nxv8i8( %v) #0 { ; CHECK-LABEL: bitcast_nxv4bf16_to_nxv8i8: ; CHECK: // %bb.0: @@ -602,6 +620,15 @@ ret %bc } +define @bitcast_nxv1i64_to_nxv4i16( %v) #0 { +; CHECK-LABEL: bitcast_nxv1i64_to_nxv4i16: +; CHECK: // %bb.0: +; CHECK-NEXT: uunpklo z0.s, z0.h +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + define @bitcast_nxv4f16_to_nxv4i16( %v) #0 { ; CHECK-LABEL: bitcast_nxv4f16_to_nxv4i16: ; CHECK: // %bb.0: @@ -610,16 +637,31 @@ ret %bc } -; TODO: Invalid code generation because the bitcast must change the in-register -; layout when casting between unpacked scalable vector types. define @bitcast_nxv2f32_to_nxv4i16( %v) #0 { ; CHECK-LABEL: bitcast_nxv2f32_to_nxv4i16: ; CHECK: // %bb.0: +; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: addvl sp, sp, #-1 +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: st1w { z0.d }, p0, [sp, #1, mul vl] +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: ld1h { z0.s }, p0/z, [sp, #1, mul vl] +; CHECK-NEXT: addvl sp, sp, #1 +; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret %bc = bitcast %v to ret %bc } +define @bitcast_nxv1f64_to_nxv4i16( %v) #0 { +; CHECK-LABEL: bitcast_nxv1f64_to_nxv4i16: +; CHECK: // %bb.0: +; CHECK-NEXT: uunpklo z0.s, z0.h +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + define @bitcast_nxv4bf16_to_nxv4i16( %v) #0 { ; CHECK-LABEL: bitcast_nxv4bf16_to_nxv4i16: ; CHECK: // %bb.0: @@ -664,11 +706,26 @@ ret %bc } -; TODO: Invalid code generation because the bitcast must change the in-register -; layout when casting between unpacked scalable vector types. +define @bitcast_nxv1i64_to_nxv2i32( %v) #0 { +; CHECK-LABEL: bitcast_nxv1i64_to_nxv2i32: +; CHECK: // %bb.0: +; CHECK-NEXT: uunpklo z0.d, z0.s +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + define @bitcast_nxv4f16_to_nxv2i32( %v) #0 { ; CHECK-LABEL: bitcast_nxv4f16_to_nxv2i32: ; CHECK: // %bb.0: +; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: addvl sp, sp, #-1 +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: st1h { z0.s }, p0, [sp, #1, mul vl] +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: ld1w { z0.d }, p0/z, [sp, #1, mul vl] +; CHECK-NEXT: addvl sp, sp, #1 +; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret %bc = bitcast %v to ret %bc @@ -682,16 +739,97 @@ ret %bc } -; TODO: Invalid code generation because the bitcast must change the in-register -; layout when casting between unpacked scalable vector types. +define @bitcast_nxv1f64_to_nxv2i32( %v) #0 { +; CHECK-LABEL: bitcast_nxv1f64_to_nxv2i32: +; CHECK: // %bb.0: +; CHECK-NEXT: uunpklo z0.d, z0.s +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + define @bitcast_nxv4bf16_to_nxv2i32( %v) #0 { ; CHECK-LABEL: bitcast_nxv4bf16_to_nxv2i32: ; CHECK: // %bb.0: +; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: addvl sp, sp, #-1 +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: st1h { z0.s }, p0, [sp, #1, mul vl] +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: ld1w { z0.d }, p0/z, [sp, #1, mul vl] +; CHECK-NEXT: addvl sp, sp, #1 +; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret %bc = bitcast %v to ret %bc } +; +; bitcast to nxv1i64 +; + +define @bitcast_nxv8i8_to_nxv1i64( %v) #0 { +; CHECK-LABEL: bitcast_nxv8i8_to_nxv1i64: +; CHECK: // %bb.0: +; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + +define @bitcast_nxv4i16_to_nxv1i64( %v) #0 { +; CHECK-LABEL: bitcast_nxv4i16_to_nxv1i64: +; CHECK: // %bb.0: +; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + +define @bitcast_nxv2i32_to_nxv1i64( %v) #0 { +; CHECK-LABEL: bitcast_nxv2i32_to_nxv1i64: +; CHECK: // %bb.0: +; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + +define @bitcast_nxv4f16_to_nxv1i64( %v) #0 { +; CHECK-LABEL: bitcast_nxv4f16_to_nxv1i64: +; CHECK: // %bb.0: +; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + +define @bitcast_nxv2f32_to_nxv1i64( %v) #0 { +; CHECK-LABEL: bitcast_nxv2f32_to_nxv1i64: +; CHECK: // %bb.0: +; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + +define @bitcast_nxv1f64_to_nxv1i64( %v) #0 { +; CHECK-LABEL: bitcast_nxv1f64_to_nxv1i64: +; CHECK: // %bb.0: +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + +define @bitcast_nxv4bf16_to_nxv1i64( %v) #0 { +; CHECK-LABEL: bitcast_nxv4bf16_to_nxv1i64: +; CHECK: // %bb.0: +; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + ; ; bitcast to nxv4f16 ; @@ -720,26 +858,42 @@ ret %bc } -; TODO: Invalid code generation because the bitcast must change the in-register -; layout when casting between unpacked scalable vector types. define @bitcast_nxv2i32_to_nxv4f16( %v) #0 { ; CHECK-LABEL: bitcast_nxv2i32_to_nxv4f16: ; CHECK: // %bb.0: +; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: addvl sp, sp, #-1 +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: st1w { z0.d }, p0, [sp, #1, mul vl] +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: ld1h { z0.s }, p0/z, [sp, #1, mul vl] +; CHECK-NEXT: addvl sp, sp, #1 +; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret %bc = bitcast %v to ret %bc } -; TODO: Invalid code generation because the bitcast must change the in-register -; layout when casting between unpacked scalable vector types. +; @bitcast_nxv1i64_to_nxv4f16 is missing + define @bitcast_nxv2f32_to_nxv4f16( %v) #0 { ; CHECK-LABEL: bitcast_nxv2f32_to_nxv4f16: ; CHECK: // %bb.0: +; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: addvl sp, sp, #-1 +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: st1w { z0.d }, p0, [sp, #1, mul vl] +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: ld1h { z0.s }, p0/z, [sp, #1, mul vl] +; CHECK-NEXT: addvl sp, sp, #1 +; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret %bc = bitcast %v to ret %bc } +; @bitcast_nxv1f64_to_nxv4f16 is missing + define @bitcast_nxv4bf16_to_nxv4f16( %v) #0 { ; CHECK-LABEL: bitcast_nxv4bf16_to_nxv4f16: ; CHECK: // %bb.0: @@ -768,11 +922,17 @@ ret %bc } -; TODO: Invalid code generation because the bitcast must change the in-register -; layout when casting between unpacked scalable vector types. define @bitcast_nxv4i16_to_nxv2f32( %v) #0 { ; CHECK-LABEL: bitcast_nxv4i16_to_nxv2f32: ; CHECK: // %bb.0: +; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: addvl sp, sp, #-1 +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: st1h { z0.s }, p0, [sp, #1, mul vl] +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: ld1w { z0.d }, p0/z, [sp, #1, mul vl] +; CHECK-NEXT: addvl sp, sp, #1 +; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret %bc = bitcast %v to ret %bc @@ -786,26 +946,54 @@ ret %bc } -; TODO: Invalid code generation because the bitcast must change the in-register -; layout when casting between unpacked scalable vector types. +; @bitcast_nxv1i64_to_nxv2f32 is missing + define @bitcast_nxv4f16_to_nxv2f32( %v) #0 { ; CHECK-LABEL: bitcast_nxv4f16_to_nxv2f32: ; CHECK: // %bb.0: +; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: addvl sp, sp, #-1 +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: st1h { z0.s }, p0, [sp, #1, mul vl] +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: ld1w { z0.d }, p0/z, [sp, #1, mul vl] +; CHECK-NEXT: addvl sp, sp, #1 +; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret %bc = bitcast %v to ret %bc } -; TODO: Invalid code generation because the bitcast must change the in-register -; layout when casting between unpacked scalable vector types. +; @bitcast_nxv1f64_to_nxv2f32 is missing + define @bitcast_nxv4bf16_to_nxv2f32( %v) #0 { ; CHECK-LABEL: bitcast_nxv4bf16_to_nxv2f32: ; CHECK: // %bb.0: +; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: addvl sp, sp, #-1 +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: st1h { z0.s }, p0, [sp, #1, mul vl] +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: ld1w { z0.d }, p0/z, [sp, #1, mul vl] +; CHECK-NEXT: addvl sp, sp, #1 +; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret %bc = bitcast %v to ret %bc } +; +; bitcast to nxv1f64 +; + +; @bitcast_nxv8i8_to_nxv1f64 is missing +; @bitcast_nxv4i16_to_nxv1f64 is missing +; @bitcast_nxv2i32_to_nxv1f64 is missing +; @bitcast_nxv1i64_to_nxv1f64 is missing +; @bitcast_nxv4f16_to_nxv1f64 is missing +; @bitcast_nxv2f32_to_nxv1f64 is missing +; @bitcast_nxv4bf16_to_nxv1f64 is missing + ; ; bitcast to nxv4bf16 ; @@ -834,16 +1022,24 @@ ret %bc } -; TODO: Invalid code generation because the bitcast must change the in-register -; layout when casting between unpacked scalable vector types. define @bitcast_nxv2i32_to_nxv4bf16( %v) #0 { ; CHECK-LABEL: bitcast_nxv2i32_to_nxv4bf16: ; CHECK: // %bb.0: +; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: addvl sp, sp, #-1 +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: st1w { z0.d }, p0, [sp, #1, mul vl] +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: ld1h { z0.s }, p0/z, [sp, #1, mul vl] +; CHECK-NEXT: addvl sp, sp, #1 +; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret %bc = bitcast %v to ret %bc } +; @bitcast_nxv1i64_to_nxv4bf16 is missing + define @bitcast_nxv4f16_to_nxv4bf16( %v) #0 { ; CHECK-LABEL: bitcast_nxv4f16_to_nxv4bf16: ; CHECK: // %bb.0: @@ -852,16 +1048,24 @@ ret %bc } -; TODO: Invalid code generation because the bitcast must change the in-register -; layout when casting between unpacked scalable vector types. define @bitcast_nxv2f32_to_nxv4bf16( %v) #0 { ; CHECK-LABEL: bitcast_nxv2f32_to_nxv4bf16: ; CHECK: // %bb.0: +; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: addvl sp, sp, #-1 +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: st1w { z0.d }, p0, [sp, #1, mul vl] +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: ld1h { z0.s }, p0/z, [sp, #1, mul vl] +; CHECK-NEXT: addvl sp, sp, #1 +; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret %bc = bitcast %v to ret %bc } +; @bitcast_nxv1f64_to_nxv4bf16 is missing + ; ; bitcast to nxv4i8 ; @@ -882,6 +1086,16 @@ ret %bc } +define @bitcast_nxv1i32_to_nxv4i8( %v) #0 { +; CHECK-LABEL: bitcast_nxv1i32_to_nxv4i8: +; CHECK: // %bb.0: +; CHECK-NEXT: uunpklo z0.h, z0.b +; CHECK-NEXT: uunpklo z0.s, z0.h +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + define @bitcast_nxv2f16_to_nxv4i8( %v) #0 { ; CHECK-LABEL: bitcast_nxv2f16_to_nxv4i8: ; CHECK: // %bb.0: @@ -898,6 +1112,8 @@ ret %bc } +; @bitcast_nxv1f32_to_nxv4i8 is missing + define @bitcast_nxv2bf16_to_nxv4i8( %v) #0 { ; CHECK-LABEL: bitcast_nxv2bf16_to_nxv4i8: ; CHECK: // %bb.0: @@ -934,6 +1150,16 @@ ret %bc } +define @bitcast_nxv1i32_to_nxv2i16( %v) #0 { +; CHECK-LABEL: bitcast_nxv1i32_to_nxv2i16: +; CHECK: // %bb.0: +; CHECK-NEXT: uunpklo z0.s, z0.h +; CHECK-NEXT: uunpklo z0.d, z0.s +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + define @bitcast_nxv2f16_to_nxv2i16( %v) #0 { ; CHECK-LABEL: bitcast_nxv2f16_to_nxv2i16: ; CHECK: // %bb.0: @@ -942,6 +1168,8 @@ ret %bc } +; @bitcast_nxv1f32_to_nxv2i16 is missing + define @bitcast_nxv2bf16_to_nxv2i16( %v) #0 { ; CHECK-LABEL: bitcast_nxv2bf16_to_nxv2i16: ; CHECK: // %bb.0: @@ -950,6 +1178,64 @@ ret %bc } +; +; bitcast to nxv1i32 +; + +define @bitcast_nxv4i8_to_nxv1i32( %v) #0 { +; CHECK-LABEL: bitcast_nxv4i8_to_nxv1i32: +; CHECK: // %bb.0: +; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h +; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + +define @bitcast_nxv2i16_to_nxv1i32( %v) #0 { +; CHECK-LABEL: bitcast_nxv2i16_to_nxv1i32: +; CHECK: // %bb.0: +; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s +; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + +define @bitcast_nxv2f16_to_nxv1i32( %v) #0 { +; CHECK-LABEL: bitcast_nxv2f16_to_nxv1i32: +; CHECK: // %bb.0: +; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: addvl sp, sp, #-1 +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: st1h { z0.d }, p0, [sp] +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: ld1w { z0.s }, p0/z, [sp] +; CHECK-NEXT: addvl sp, sp, #1 +; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + +; @bitcast_nxv1f32_to_nxv1i32 is missing + +define @bitcast_nxv2bf16_to_nxv1i32( %v) #0 { +; CHECK-LABEL: bitcast_nxv2bf16_to_nxv1i32: +; CHECK: // %bb.0: +; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: addvl sp, sp, #-1 +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: st1h { z0.d }, p0, [sp] +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: ld1w { z0.s }, p0/z, [sp] +; CHECK-NEXT: addvl sp, sp, #1 +; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + ; ; bitcast to nxv2f16 ; @@ -978,6 +1264,9 @@ ret %bc } +; @bitcast_nxv1i32_to_nxv2f16 is missing +; @bitcast_nxv1f32_to_nxv2f16 is missing + define @bitcast_nxv2bf16_to_nxv2f16( %v) #0 { ; CHECK-LABEL: bitcast_nxv2bf16_to_nxv2f16: ; CHECK: // %bb.0: @@ -1014,6 +1303,8 @@ ret %bc } +; @bitcast_nxv1i32_to_nxv2bf16 is missing + define @bitcast_nxv2f16_to_nxv2bf16( %v) #0 { ; CHECK-LABEL: bitcast_nxv2f16_to_nxv2bf16: ; CHECK: // %bb.0: @@ -1022,6 +1313,44 @@ ret %bc } +; @bitcast_nxv1f32_to_nxv2bf16 is missing + +; +; bitcast to nxv2i8 +; + +define @bitcast_nxv1i16_to_nxv2i8( %v) #0 { +; CHECK-LABEL: bitcast_nxv1i16_to_nxv2i8: +; CHECK: // %bb.0: +; CHECK-NEXT: uunpklo z0.h, z0.b +; CHECK-NEXT: uunpklo z0.s, z0.h +; CHECK-NEXT: uunpklo z0.d, z0.s +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + +; @bitcast_nxv1f16_to_nxv2i8 is missing +; @bitcast_nxv1bf16_to_nxv2i8 is missing + +; +; bitcast to nxv1i16 +; + +define @bitcast_nxv2i8_to_nxv1i16( %v) #0 { +; CHECK-LABEL: bitcast_nxv2i8_to_nxv1i16: +; CHECK: // %bb.0: +; CHECK-NEXT: uzp1 z0.s, z0.s, z0.s +; CHECK-NEXT: uzp1 z0.h, z0.h, z0.h +; CHECK-NEXT: uzp1 z0.b, z0.b, z0.b +; CHECK-NEXT: ret + %bc = bitcast %v to + ret %bc +} + +; @bitcast_nxv1f16_to_nxv1i16 is missing +; @bitcast_nxv1bf16_to_nxv1i16 is missing + ; ; Other ; @@ -1049,13 +1378,18 @@ ret %extended } -; TODO: Invalid code generation because the bitcast must change the in-register -; layout when casting between unpacked scalable vector types. define @bitcast_short_half_to_float( %v) #0 { ; CHECK-LABEL: bitcast_short_half_to_float: ; CHECK: // %bb.0: +; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: addvl sp, sp, #-1 ; CHECK-NEXT: ptrue p0.s ; CHECK-NEXT: fadd z0.h, p0/m, z0.h, z0.h +; CHECK-NEXT: st1h { z0.s }, p0, [sp, #1, mul vl] +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: ld1w { z0.d }, p0/z, [sp, #1, mul vl] +; CHECK-NEXT: addvl sp, sp, #1 +; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret %add = fadd %v, %v %bitcast = bitcast %add to diff --git a/llvm/test/CodeGen/DirectX/typed_ptr.ll b/llvm/test/CodeGen/DirectX/typed_ptr.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/typed_ptr.ll @@ -0,0 +1,10 @@ +; RUN: opt -S -dxil-prepare < %s | FileCheck %s +target triple = "dxil-unknown-unknown" + +; Make sure not crash when has typed ptr. +; CHECK:@test + +define i64 @test(i64* %p) { + %v = load i64, i64* %p + ret i64 %v +} diff --git a/llvm/test/CodeGen/RISCV/early-clobber-tied-def-subreg-liveness.ll b/llvm/test/CodeGen/RISCV/early-clobber-tied-def-subreg-liveness.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/early-clobber-tied-def-subreg-liveness.ll @@ -0,0 +1,117 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -O2 -mtriple riscv64 -mattr=+v,+m,+zbb -riscv-enable-subreg-liveness < %s \ +; RUN: | FileCheck %s + +@var_47 = dso_local global [2 x i16] [i16 -32732, i16 19439], align 2 +@__const._Z3foov.var_49 = private unnamed_addr constant [2 x i16] [i16 157, i16 24062], align 2 +@__const._Z3foov.var_48 = private unnamed_addr constant [2 x i8] c"\AEN", align 1 +@__const._Z3foov.var_46 = private unnamed_addr constant [2 x i16] [i16 729, i16 -32215], align 2 +@__const._Z3foov.var_45 = private unnamed_addr constant [2 x i16] [i16 -27462, i16 -1435], align 2 +@__const._Z3foov.var_44 = private unnamed_addr constant [2 x i16] [i16 22611, i16 -18435], align 2 +@__const._Z3foov.var_40 = private unnamed_addr constant [2 x i16] [i16 -19932, i16 -26252], align 2 + +define void @_Z3foov() { +; CHECK-LABEL: _Z3foov: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addi sp, sp, -16 +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: csrr a0, vlenb +; CHECK-NEXT: li a1, 10 +; CHECK-NEXT: mul a0, a0, a1 +; CHECK-NEXT: sub sp, sp, a0 +; CHECK-NEXT: lui a0, %hi(.L__const._Z3foov.var_49) +; CHECK-NEXT: addi a0, a0, %lo(.L__const._Z3foov.var_49) +; CHECK-NEXT: vsetivli zero, 2, e16, m2, ta, mu +; CHECK-NEXT: vle16.v v8, (a0) +; CHECK-NEXT: lui a0, %hi(.L__const._Z3foov.var_48) +; CHECK-NEXT: addi a0, a0, %lo(.L__const._Z3foov.var_48) +; CHECK-NEXT: vle8.v v10, (a0) +; CHECK-NEXT: csrr a0, vlenb +; CHECK-NEXT: slli a0, a0, 3 +; CHECK-NEXT: add a0, sp, a0 +; CHECK-NEXT: addi a0, a0, 16 +; CHECK-NEXT: vs1r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-NEXT: lui a0, %hi(.L__const._Z3foov.var_46) +; CHECK-NEXT: addi a0, a0, %lo(.L__const._Z3foov.var_46) +; CHECK-NEXT: vle16.v v10, (a0) +; CHECK-NEXT: lui a0, %hi(.L__const._Z3foov.var_45) +; CHECK-NEXT: addi a0, a0, %lo(.L__const._Z3foov.var_45) +; CHECK-NEXT: vle16.v v12, (a0) +; CHECK-NEXT: addi a0, sp, 16 +; CHECK-NEXT: csrr a1, vlenb +; CHECK-NEXT: slli a1, a1, 1 +; CHECK-NEXT: vs2r.v v8, (a0) # Unknown-size Folded Spill +; CHECK-NEXT: add a0, a0, a1 +; CHECK-NEXT: vs2r.v v10, (a0) # Unknown-size Folded Spill +; CHECK-NEXT: add a0, a0, a1 +; CHECK-NEXT: vs2r.v v12, (a0) # Unknown-size Folded Spill +; CHECK-NEXT: add a0, a0, a1 +; CHECK-NEXT: vs2r.v v14, (a0) # Unknown-size Folded Spill +; CHECK-NEXT: #APP +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: lui a0, %hi(.L__const._Z3foov.var_44) +; CHECK-NEXT: addi a0, a0, %lo(.L__const._Z3foov.var_44) +; CHECK-NEXT: vsetivli zero, 2, e16, m2, ta, mu +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: csrr a2, vlenb +; CHECK-NEXT: slli a2, a2, 1 +; CHECK-NEXT: vl2r.v v8, (a1) # Unknown-size Folded Reload +; CHECK-NEXT: add a1, a1, a2 +; CHECK-NEXT: vl2r.v v10, (a1) # Unknown-size Folded Reload +; CHECK-NEXT: add a1, a1, a2 +; CHECK-NEXT: vl2r.v v12, (a1) # Unknown-size Folded Reload +; CHECK-NEXT: add a1, a1, a2 +; CHECK-NEXT: vl2r.v v14, (a1) # Unknown-size Folded Reload +; CHECK-NEXT: vle16.v v14, (a0) +; CHECK-NEXT: vsetivli zero, 2, e16, m2, ta, mu +; CHECK-NEXT: lui a0, %hi(.L__const._Z3foov.var_40) +; CHECK-NEXT: addi a0, a0, %lo(.L__const._Z3foov.var_40) +; CHECK-NEXT: vle16.v v8, (a0) +; CHECK-NEXT: vsetivli zero, 2, e16, m2, ta, mu +; CHECK-NEXT: lui a0, 1048572 +; CHECK-NEXT: addiw a0, a0, 928 +; CHECK-NEXT: vmsbc.vx v0, v8, a0 +; CHECK-NEXT: vsetivli zero, 2, e16, m2, tu, mu +; CHECK-NEXT: csrr a0, vlenb +; CHECK-NEXT: slli a0, a0, 3 +; CHECK-NEXT: add a0, sp, a0 +; CHECK-NEXT: addi a0, a0, 16 +; CHECK-NEXT: vl1r.v v16, (a0) # Unknown-size Folded Reload +; CHECK-NEXT: vsext.vf2 v8, v16, v0.t +; CHECK-NEXT: lui a0, %hi(var_47) +; CHECK-NEXT: addi a0, a0, %lo(var_47) +; CHECK-NEXT: vsseg4e16.v v8, (a0) +; CHECK-NEXT: csrr a0, vlenb +; CHECK-NEXT: li a1, 10 +; CHECK-NEXT: mul a0, a0, a1 +; CHECK-NEXT: add sp, sp, a0 +; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: ret +entry: + %0 = tail call @llvm.riscv.vle.nxv8i16.i64( undef, ptr nonnull @__const._Z3foov.var_49, i64 2) + %1 = tail call @llvm.riscv.vle.nxv8i8.i64( undef, ptr nonnull @__const._Z3foov.var_48, i64 2) + %2 = tail call @llvm.riscv.vle.nxv8i16.i64( undef, ptr nonnull @__const._Z3foov.var_46, i64 2) + %3 = tail call @llvm.riscv.vle.nxv8i16.i64( undef, ptr nonnull @__const._Z3foov.var_45, i64 2) + tail call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31}"() #2 + %4 = tail call @llvm.riscv.vle.nxv8i16.i64( undef, ptr nonnull @__const._Z3foov.var_44, i64 2) + %5 = tail call i64 @llvm.riscv.vsetvli.i64(i64 2, i64 1, i64 1) + %6 = tail call @llvm.riscv.vle.nxv8i16.i64( undef, ptr nonnull @__const._Z3foov.var_40, i64 2) + %7 = tail call i64 @llvm.riscv.vsetvli.i64(i64 2, i64 1, i64 1) + %8 = tail call @llvm.riscv.vmsbc.nxv8i16.i16.i64( %6, i16 -15456, i64 2) + %9 = tail call i64 @llvm.riscv.vsetvli.i64(i64 2, i64 1, i64 1) + %10 = tail call @llvm.riscv.vsext.mask.nxv8i16.nxv8i8.i64( %0, %1, %8, i64 2, i64 0) + tail call void @llvm.riscv.vsseg4.nxv8i16.i64( %10, %2, %3, %4, ptr nonnull @var_47, i64 2) + ret void +} + +declare @llvm.riscv.vle.nxv8i16.i64(, ptr nocapture, i64) + +declare @llvm.riscv.vle.nxv8i8.i64(, ptr nocapture, i64) + +declare i64 @llvm.riscv.vsetvli.i64(i64, i64 immarg, i64 immarg) + +declare @llvm.riscv.vmsbc.nxv8i16.i16.i64(, i16, i64) + +declare @llvm.riscv.vsext.mask.nxv8i16.nxv8i8.i64(, , , i64, i64 immarg) + +declare void @llvm.riscv.vsseg4.nxv8i16.i64(, , , , ptr nocapture, i64) diff --git a/llvm/test/CodeGen/RISCV/early-clobber-tied-def-subreg-liveness.mir b/llvm/test/CodeGen/RISCV/early-clobber-tied-def-subreg-liveness.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/early-clobber-tied-def-subreg-liveness.mir @@ -0,0 +1,225 @@ +# REQUIRES: asserts +# RUN: llc %s -run-pass=greedy -debug -riscv-enable-subreg-liveness -o - 2>&1 \ +# RUN: | FileCheck %s +--- | + ; ModuleID = 'early-clobber-tied-def-subreg-liveness.ll' + source_filename = "early-clobber-tied-def-subreg-liveness.ll" + target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128" + target triple = "riscv64" + + @var_47 = dso_local global [2 x i16] [i16 -32732, i16 19439], align 2 + @__const._Z3foov.var_49 = private unnamed_addr constant [2 x i16] [i16 157, i16 24062], align 2 + @__const._Z3foov.var_48 = private unnamed_addr constant [2 x i8] c"\AEN", align 1 + @__const._Z3foov.var_46 = private unnamed_addr constant [2 x i16] [i16 729, i16 -32215], align 2 + @__const._Z3foov.var_45 = private unnamed_addr constant [2 x i16] [i16 -27462, i16 -1435], align 2 + @__const._Z3foov.var_44 = private unnamed_addr constant [2 x i16] [i16 22611, i16 -18435], align 2 + @__const._Z3foov.var_40 = private unnamed_addr constant [2 x i16] [i16 -19932, i16 -26252], align 2 + + define void @_Z3foov() #0 { + entry: + %0 = tail call @llvm.riscv.vle.nxv8i16.i64( undef, ptr nonnull @__const._Z3foov.var_49, i64 2) + %1 = tail call @llvm.riscv.vle.nxv8i8.i64( undef, ptr nonnull @__const._Z3foov.var_48, i64 2) + %2 = tail call @llvm.riscv.vle.nxv8i16.i64( undef, ptr nonnull @__const._Z3foov.var_46, i64 2) + %3 = tail call @llvm.riscv.vle.nxv8i16.i64( undef, ptr nonnull @__const._Z3foov.var_45, i64 2) + tail call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31}"() + %4 = tail call @llvm.riscv.vle.nxv8i16.i64( undef, ptr nonnull @__const._Z3foov.var_44, i64 2) + %5 = tail call i64 @llvm.riscv.vsetvli.i64(i64 2, i64 1, i64 1) + %6 = tail call @llvm.riscv.vle.nxv8i16.i64( undef, ptr nonnull @__const._Z3foov.var_40, i64 2) + %7 = tail call i64 @llvm.riscv.vsetvli.i64(i64 2, i64 1, i64 1) + %8 = tail call @llvm.riscv.vmsbc.nxv8i16.i16.i64( %6, i16 -15456, i64 2) + %9 = tail call i64 @llvm.riscv.vsetvli.i64(i64 2, i64 1, i64 1) + %10 = tail call @llvm.riscv.vsext.mask.nxv8i16.nxv8i8.i64( %0, %1, %8, i64 2, i64 0) + tail call void @llvm.riscv.vsseg4.nxv8i16.i64( %10, %2, %3, %4, ptr nonnull @var_47, i64 2) + ret void + } + + ; Function Attrs: nounwind readonly + declare @llvm.riscv.vle.nxv8i16.i64(, ptr nocapture, i64) #1 + + ; Function Attrs: nounwind readonly + declare @llvm.riscv.vle.nxv8i8.i64(, ptr nocapture, i64) #1 + + ; Function Attrs: nounwind + declare i64 @llvm.riscv.vsetvli.i64(i64, i64 immarg, i64 immarg) #2 + + ; Function Attrs: nounwind readnone + declare @llvm.riscv.vmsbc.nxv8i16.i16.i64(, i16, i64) #3 + + ; Function Attrs: nounwind readnone + declare @llvm.riscv.vsext.mask.nxv8i16.nxv8i8.i64(, , , i64, i64 immarg) #3 + + ; Function Attrs: nounwind writeonly + declare void @llvm.riscv.vsseg4.nxv8i16.i64(, , , , ptr nocapture, i64) #4 + + attributes #0 = { "target-features"="+v,+m,+zbb" } + attributes #1 = { nounwind readonly "target-features"="+v,+m,+zbb" } + attributes #2 = { nounwind "target-features"="+v,+m,+zbb" } + attributes #3 = { nounwind readnone "target-features"="+v,+m,+zbb" } + attributes #4 = { nounwind writeonly "target-features"="+v,+m,+zbb" } + +... +--- +name: _Z3foov +alignment: 4 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: false +tracksRegLiveness: true +hasWinCFI: false +callsEHReturn: false +callsUnwindInit: false +hasEHCatchret: false +hasEHScopes: false +hasEHFunclets: false +failsVerification: false +tracksDebugUserValues: false +registers: + - { id: 0, class: gpr, preferred-register: '' } + - { id: 1, class: gpr, preferred-register: '' } + - { id: 2, class: vrm2nov0, preferred-register: '' } + - { id: 3, class: gpr, preferred-register: '' } + - { id: 4, class: gpr, preferred-register: '' } + - { id: 5, class: vr, preferred-register: '' } + - { id: 6, class: gpr, preferred-register: '' } + - { id: 7, class: gpr, preferred-register: '' } + - { id: 8, class: vrm2, preferred-register: '' } + - { id: 9, class: gpr, preferred-register: '' } + - { id: 10, class: gpr, preferred-register: '' } + - { id: 11, class: vrm2, preferred-register: '' } + - { id: 12, class: gpr, preferred-register: '' } + - { id: 13, class: gpr, preferred-register: '' } + - { id: 14, class: vrm2, preferred-register: '' } + - { id: 15, class: gpr, preferred-register: '' } + - { id: 16, class: gpr, preferred-register: '' } + - { id: 17, class: gpr, preferred-register: '' } + - { id: 18, class: vrm2, preferred-register: '' } + - { id: 19, class: gpr, preferred-register: '' } + - { id: 20, class: gpr, preferred-register: '' } + - { id: 21, class: gpr, preferred-register: '' } + - { id: 22, class: vr, preferred-register: '' } + - { id: 23, class: gpr, preferred-register: '' } + - { id: 24, class: vrm2nov0, preferred-register: '' } + - { id: 25, class: vrn4m2nov0, preferred-register: '' } + - { id: 26, class: gpr, preferred-register: '' } + - { id: 27, class: gpr, preferred-register: '' } +liveins: [] +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 1 + adjustsStack: false + hasCalls: false + stackProtector: '' + functionContext: '' + maxCallFrameSize: 4294967295 + cvBytesOfCalleeSavedRegisters: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + hasTailCall: false + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: [] +stack: [] +callSites: [] +debugValueSubstitutions: [] +constants: [] +machineFunctionInfo: + varArgsFrameIndex: 0 + varArgsSaveSize: 0 +body: | + bb.0.entry: + ; CHECK: 0B bb.0.entry: + ; CHECK-NEXT: 16B %0:gpr = LUI target-flags(riscv-hi) @__const._Z3foov.var_49 + ; CHECK-NEXT: 32B %1:gpr = ADDI %0:gpr, target-flags(riscv-lo) @__const._Z3foov.var_49 + ; CHECK-NEXT: 48B dead $x0 = PseudoVSETIVLI 2, 73, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: 64B undef %25.sub_vrm2_0:vrn4m2nov0 = PseudoVLE16_V_M2 %1:gpr, 2, 4, implicit $vl, implicit $vtype + ; CHECK-NEXT: 80B %3:gpr = LUI target-flags(riscv-hi) @__const._Z3foov.var_48 + ; CHECK-NEXT: 96B %4:gpr = ADDI %3:gpr, target-flags(riscv-lo) @__const._Z3foov.var_48 + ; CHECK-NEXT: 112B %5:vr = PseudoVLE8_V_M1 %4:gpr, 2, 3, implicit $vl, implicit $vtype + ; CHECK-NEXT: 128B %6:gpr = LUI target-flags(riscv-hi) @__const._Z3foov.var_46 + ; CHECK-NEXT: 144B %7:gpr = ADDI %6:gpr, target-flags(riscv-lo) @__const._Z3foov.var_46 + ; CHECK-NEXT: 160B %25.sub_vrm2_1:vrn4m2nov0 = PseudoVLE16_V_M2 %7:gpr, 2, 4, implicit $vl, implicit $vtype + ; CHECK-NEXT: 176B %9:gpr = LUI target-flags(riscv-hi) @__const._Z3foov.var_45 + ; CHECK-NEXT: 192B %10:gpr = ADDI %9:gpr, target-flags(riscv-lo) @__const._Z3foov.var_45 + ; CHECK-NEXT: 208B %25.sub_vrm2_2:vrn4m2nov0 = PseudoVLE16_V_M2 %10:gpr, 2, 4, implicit $vl, implicit $vtype + ; CHECK-NEXT: 224B INLINEASM &"" [sideeffect] [attdialect], $0:[clobber], implicit-def dead early-clobber $v0, $1:[clobber], implicit-def dead early-clobber $v1, $2:[clobber], implicit-def dead early-clobber $v2, $3:[clobber], implicit-def dead early-clobber $v3, $4:[clobber], implicit-def dead early-clobber $v4, $5:[clobber], implicit-def dead early-clobber $v5, $6:[clobber], implicit-def dead early-clobber $v6, $7:[clobber], implicit-def dead early-clobber $v7, $8:[clobber], implicit-def dead early-clobber $v8, $9:[clobber], implicit-def dead early-clobber $v9, $10:[clobber], implicit-def dead early-clobber $v10, $11:[clobber], implicit-def dead early-clobber $v11, $12:[clobber], implicit-def dead early-clobber $v12, $13:[clobber], implicit-def dead early-clobber $v13, $14:[clobber], implicit-def dead early-clobber $v14, $15:[clobber], implicit-def dead early-clobber $v15, $16:[clobber], implicit-def dead early-clobber $v16, $17:[clobber], implicit-def dead early-clobber $v17, $18:[clobber], implicit-def dead early-clobber $v18, $19:[clobber], implicit-def dead early-clobber $v19, $20:[clobber], implicit-def dead early-clobber $v20, $21:[clobber], implicit-def dead early-clobber $v21, $22:[clobber], implicit-def dead early-clobber $v22, $23:[clobber], implicit-def dead early-clobber $v23, $24:[clobber], implicit-def dead early-clobber $v24, $25:[clobber], implicit-def dead early-clobber $v25, $26:[clobber], implicit-def dead early-clobber $v26, $27:[clobber], implicit-def dead early-clobber $v27, $28:[clobber], implicit-def dead early-clobber $v28, $29:[clobber], implicit-def dead early-clobber $v29, $30:[clobber], implicit-def dead early-clobber $v30, $31:[clobber], implicit-def dead early-clobber $v31 + ; CHECK-NEXT: 240B %12:gpr = LUI target-flags(riscv-hi) @__const._Z3foov.var_44 + ; CHECK-NEXT: 256B %13:gpr = ADDI %12:gpr, target-flags(riscv-lo) @__const._Z3foov.var_44 + ; CHECK-NEXT: 272B dead $x0 = PseudoVSETIVLI 2, 73, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: 288B %25.sub_vrm2_3:vrn4m2nov0 = PseudoVLE16_V_M2 %13:gpr, 2, 4, implicit $vl, implicit $vtype + ; CHECK-NEXT: 304B $x0 = PseudoVSETIVLI 2, 73, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: 320B %16:gpr = LUI target-flags(riscv-hi) @__const._Z3foov.var_40 + ; CHECK-NEXT: 336B %17:gpr = ADDI %16:gpr, target-flags(riscv-lo) @__const._Z3foov.var_40 + ; CHECK-NEXT: 352B %18:vrm2 = PseudoVLE16_V_M2 %17:gpr, 2, 4, implicit $vl, implicit $vtype + ; CHECK-NEXT: 368B $x0 = PseudoVSETIVLI 2, 73, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: 384B %20:gpr = LUI 1048572 + ; CHECK-NEXT: 400B %21:gpr = ADDIW %20:gpr, 928 + ; CHECK-NEXT: 416B early-clobber %22:vr = PseudoVMSBC_VX_M2 %18:vrm2, %21:gpr, 2, 4, implicit $vl, implicit $vtype + ; CHECK-NEXT: 432B $x0 = PseudoVSETIVLI 2, 9, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: 448B $v0 = COPY %22:vr + ; CHECK-NEXT: 464B early-clobber %25.sub_vrm2_0:vrn4m2nov0 = PseudoVSEXT_VF2_M2_MASK %25.sub_vrm2_0:vrn4m2nov0(tied-def 0), %5:vr, killed $v0, 2, 4, 0, implicit $vl, implicit $vtype + ; CHECK-NEXT: 480B %26:gpr = LUI target-flags(riscv-hi) @var_47 + ; CHECK-NEXT: 496B %27:gpr = ADDI %26:gpr, target-flags(riscv-lo) @var_47 + ; CHECK-NEXT: 512B PseudoVSSEG4E16_V_M2 %25:vrn4m2nov0, %27:gpr, 2, 4, implicit $vl, implicit $vtype + ; CHECK-NEXT: 528B PseudoRET + %0:gpr = LUI target-flags(riscv-hi) @__const._Z3foov.var_49 + %1:gpr = ADDI %0, target-flags(riscv-lo) @__const._Z3foov.var_49 + dead $x0 = PseudoVSETIVLI 2, 73 /* e16, m2, ta, mu */, implicit-def $vl, implicit-def $vtype + undef %25.sub_vrm2_0:vrn4m2nov0 = PseudoVLE16_V_M2 %1, 2, 4 /* e16 */, implicit $vl, implicit $vtype + %3:gpr = LUI target-flags(riscv-hi) @__const._Z3foov.var_48 + %4:gpr = ADDI %3, target-flags(riscv-lo) @__const._Z3foov.var_48 + %5:vr = PseudoVLE8_V_M1 %4, 2, 3 /* e8 */, implicit $vl, implicit $vtype + %6:gpr = LUI target-flags(riscv-hi) @__const._Z3foov.var_46 + %7:gpr = ADDI %6, target-flags(riscv-lo) @__const._Z3foov.var_46 + %25.sub_vrm2_1:vrn4m2nov0 = PseudoVLE16_V_M2 %7, 2, 4 /* e16 */, implicit $vl, implicit $vtype + %9:gpr = LUI target-flags(riscv-hi) @__const._Z3foov.var_45 + %10:gpr = ADDI %9, target-flags(riscv-lo) @__const._Z3foov.var_45 + %25.sub_vrm2_2:vrn4m2nov0 = PseudoVLE16_V_M2 %10, 2, 4 /* e16 */, implicit $vl, implicit $vtype + INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $v0, 12 /* clobber */, implicit-def dead early-clobber $v1, 12 /* clobber */, implicit-def dead early-clobber $v2, 12 /* clobber */, implicit-def dead early-clobber $v3, 12 /* clobber */, implicit-def dead early-clobber $v4, 12 /* clobber */, implicit-def dead early-clobber $v5, 12 /* clobber */, implicit-def dead early-clobber $v6, 12 /* clobber */, implicit-def dead early-clobber $v7, 12 /* clobber */, implicit-def dead early-clobber $v8, 12 /* clobber */, implicit-def dead early-clobber $v9, 12 /* clobber */, implicit-def dead early-clobber $v10, 12 /* clobber */, implicit-def dead early-clobber $v11, 12 /* clobber */, implicit-def dead early-clobber $v12, 12 /* clobber */, implicit-def dead early-clobber $v13, 12 /* clobber */, implicit-def dead early-clobber $v14, 12 /* clobber */, implicit-def dead early-clobber $v15, 12 /* clobber */, implicit-def dead early-clobber $v16, 12 /* clobber */, implicit-def dead early-clobber $v17, 12 /* clobber */, implicit-def dead early-clobber $v18, 12 /* clobber */, implicit-def dead early-clobber $v19, 12 /* clobber */, implicit-def dead early-clobber $v20, 12 /* clobber */, implicit-def dead early-clobber $v21, 12 /* clobber */, implicit-def dead early-clobber $v22, 12 /* clobber */, implicit-def dead early-clobber $v23, 12 /* clobber */, implicit-def dead early-clobber $v24, 12 /* clobber */, implicit-def dead early-clobber $v25, 12 /* clobber */, implicit-def dead early-clobber $v26, 12 /* clobber */, implicit-def dead early-clobber $v27, 12 /* clobber */, implicit-def dead early-clobber $v28, 12 /* clobber */, implicit-def dead early-clobber $v29, 12 /* clobber */, implicit-def dead early-clobber $v30, 12 /* clobber */, implicit-def dead early-clobber $v31 + %12:gpr = LUI target-flags(riscv-hi) @__const._Z3foov.var_44 + %13:gpr = ADDI %12, target-flags(riscv-lo) @__const._Z3foov.var_44 + dead $x0 = PseudoVSETIVLI 2, 73 /* e16, m2, ta, mu */, implicit-def $vl, implicit-def $vtype + %25.sub_vrm2_3:vrn4m2nov0 = PseudoVLE16_V_M2 %13, 2, 4 /* e16 */, implicit $vl, implicit $vtype + $x0 = PseudoVSETIVLI 2, 73 /* e16, m2, ta, mu */, implicit-def $vl, implicit-def $vtype + %16:gpr = LUI target-flags(riscv-hi) @__const._Z3foov.var_40 + %17:gpr = ADDI %16, target-flags(riscv-lo) @__const._Z3foov.var_40 + %18:vrm2 = PseudoVLE16_V_M2 %17, 2, 4 /* e16 */, implicit $vl, implicit $vtype + $x0 = PseudoVSETIVLI 2, 73 /* e16, m2, ta, mu */, implicit-def $vl, implicit-def $vtype + %20:gpr = LUI 1048572 + %21:gpr = ADDIW %20, 928 + early-clobber %22:vr = PseudoVMSBC_VX_M2 %18, %21, 2, 4 /* e16 */, implicit $vl, implicit $vtype + $x0 = PseudoVSETIVLI 2, 9 /* e16, m2, tu, mu */, implicit-def $vl, implicit-def $vtype + $v0 = COPY %22 + early-clobber %25.sub_vrm2_0:vrn4m2nov0 = PseudoVSEXT_VF2_M2_MASK %25.sub_vrm2_0, %5, killed $v0, 2, 4 /* e16 */, 0, implicit $vl, implicit $vtype + ; CHECK: Best local split range: 64r-208r, 6.999861e-03, 3 instrs + ; CHECK-NEXT: enterIntvBefore 64r: not live + ; CHECK-NEXT: leaveIntvAfter 208r: valno 1 + ; CHECK-NEXT: useIntv [64B;216r): [64B;216r):1 + ; CHECK-NEXT: blit [64r,160r:4): [64r;160r)=1(%29)(recalc) + ; CHECK-NEXT: blit [160r,208r:0): [160r;208r)=1(%29)(recalc) + ; CHECK-NEXT: blit [208r,288r:1): [208r;216r)=1(%29)(recalc) [216r;288r)=0(%28)(recalc) + ; CHECK-NEXT: blit [288r,464e:2): [288r;464e)=0(%28)(recalc) + ; CHECK-NEXT: blit [464e,512r:3): [464e;512r)=0(%28)(recalc) + ; CHECK-NEXT: rewr %bb.0 464e:0 early-clobber %28.sub_vrm2_0:vrn4m2nov0 = PseudoVSEXT_VF2_M2_MASK %25.sub_vrm2_0:vrn4m2nov0(tied-def 0), %5:vr, $v0, 2, 4, 0, implicit $vl, implicit $vtype + ; CHECK-NEXT: rewr %bb.0 288r:0 %28.sub_vrm2_3:vrn4m2nov0 = PseudoVLE16_V_M2 %13:gpr, 2, 4, implicit $vl, implicit $vtype + ; CHECK-NEXT: rewr %bb.0 208r:1 %29.sub_vrm2_2:vrn4m2nov0 = PseudoVLE16_V_M2 %10:gpr, 2, 4, implicit $vl, implicit $vtype + ; CHECK-NEXT: rewr %bb.0 160r:1 %29.sub_vrm2_1:vrn4m2nov0 = PseudoVLE16_V_M2 %7:gpr, 2, 4, implicit $vl, implicit $vtype + ; CHECK-NEXT: rewr %bb.0 64r:1 undef %29.sub_vrm2_0:vrn4m2nov0 = PseudoVLE16_V_M2 %1:gpr, 2, 4, implicit $vl, implicit $vtype + ; CHECK-NEXT: rewr %bb.0 464B:0 early-clobber %28.sub_vrm2_0:vrn4m2nov0 = PseudoVSEXT_VF2_M2_MASK %28.sub_vrm2_0:vrn4m2nov0(tied-def 0), %5:vr, $v0, 2, 4, 0, implicit $vl, implicit $vtype + ; CHECK-NEXT: rewr %bb.0 512B:0 PseudoVSSEG4E16_V_M2 %28:vrn4m2nov0, %27:gpr, 2, 4, implicit $vl, implicit $vtype + ; CHECK-NEXT: rewr %bb.0 216B:1 undef %28.sub_vrm1_0_sub_vrm1_1_sub_vrm1_2_sub_vrm1_3_sub_vrm1_4_sub_vrm1_5:vrn4m2nov0 = COPY %29.sub_vrm1_0_sub_vrm1_1_sub_vrm1_2_sub_vrm1_3_sub_vrm1_4_sub_vrm1_5:vrn4m2nov0 + ; CHECK-NEXT: queuing new interval: %28 [216r,288r:0)[288r,464e:1)[464e,512r:2) 0@216r 1@288r 2@464e L000000000000000C [216r,216d:0)[464e,512r:1) 0@216r 1@464e L0000000000000300 [288r,512r:0) 0@288r L00000000000000C0 [216r,512r:0) 0@216r L0000000000000030 [216r,512r:0) 0@216r weight:8.706897e-03 + %26:gpr = LUI target-flags(riscv-hi) @var_47 + %27:gpr = ADDI %26, target-flags(riscv-lo) @var_47 + PseudoVSSEG4E16_V_M2 %25, %27, 2, 4 /* e16 */, implicit $vl, implicit $vtype + PseudoRET + +... diff --git a/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_relocations.s b/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_relocations.s new file mode 100644 --- /dev/null +++ b/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_relocations.s @@ -0,0 +1,169 @@ +# RUN: rm -rf %t && mkdir -p %t +# RUN: llvm-mc -triple=aarch64-unknown-linux-gnu -relax-relocations=false \ +# RUN: -position-independent -filetype=obj -o %t/elf_reloc.o %s +# RUN: llvm-jitlink -noexec \ +# RUN: -abs external_data=0xdeadbeef \ +# RUN: -check %s %t/elf_reloc.o + + .text + + .globl main + .p2align 2 + .type main,@function +main: + ret + + .size main, .-main + +# Check R_AARCH64_CALL26 relocation of a local function call +# +# jitlink-check: decode_operand(local_func_call26, 0)[25:0] = (local_func - local_func_call26)[27:2] + .globl local_func + .p2align 2 + .type local_func,@function +local_func: + ret + .size local_func, .-local_func + + .globl local_func_call26 + .p2align 2 +local_func_call26: + bl local_func + .size local_func_call26, .-local_func_call26 + + +# Check R_AARCH64_ADR_PREL_PG_HI21 / R_AARCH64_ADD_ABS_LO12_NC relocation of a local symbol +# +# For the ADR_PREL_PG_HI21/ADRP instruction we have the 21-bit delta to the 4k page +# containing the global. +# +# jitlink-check: decode_operand(test_adr_prel, 1) = (named_data - test_adr_prel)[32:12] +# jitlink-check: decode_operand(test_add_abs_lo12, 2) = (named_data + 0)[11:0] + .globl test_adr_prel + .p2align 2 +test_adr_prel: + adrp x0, named_data + .size test_adr_prel, .-test_adr_prel + + .globl test_add_abs_lo12 + .p2align 2 +test_add_abs_lo12: + add x0, x0, :lo12:named_data + .size test_add_abs_lo12, .-test_add_abs_lo12 + +# Check R_AARCH64_LDST*_ABS_LO12_NC relocation of a local symbol +# +# The immediate value should be the symbol address right shifted according to its instruction bitwidth. +# +# jitlink-check: decode_operand(test_ldrb, 2) = named_data[11:0] +# jitlink-check: decode_operand(test_ldrsb, 2) = (named_data + 0)[11:0] +# jitlink-check: decode_operand(test_ldrh, 2) = (named_data + 0)[11:1] +# jitlink-check: decode_operand(test_ldrsh, 2) = (named_data + 0)[11:1] +# jitlink-check: decode_operand(test_ldr_32bit, 2) = (named_data + 0)[11:2] +# jitlink-check: decode_operand(test_ldr_64bit, 2) = (named_data + 0)[11:3] +# jitlink-check: decode_operand(test_strb, 2) = named_data[11:0] +# jitlink-check: decode_operand(test_strh, 2) = (named_data + 0)[11:1] +# jitlink-check: decode_operand(test_str_32bit, 2) = (named_data + 0)[11:2] +# jitlink-check: decode_operand(test_str_64bit, 2) = (named_data + 0)[11:3] + + .globl test_ldrb +test_ldrb: + ldrb w0, [x1, :lo12:named_data] + .size test_ldrb, .-test_ldrb + + .globl test_ldrsb +test_ldrsb: + ldrsb w0, [x1, :lo12:named_data] + .size test_ldrsb, .-test_ldrsb + + .globl test_ldrh +test_ldrh: + ldrh w0, [x1, :lo12:named_data] + .size test_ldrh, .-test_ldrh + + .globl test_ldrsh +test_ldrsh: + ldrsh w0, [x1, :lo12:named_data] + .size test_ldrsh, .-test_ldrsh + + .globl test_ldr_32bit +test_ldr_32bit: + ldr w0, [x1, :lo12:named_data] + .size test_ldr_32bit, .-test_ldr_32bit + + .globl test_ldr_64bit +test_ldr_64bit: + ldr x0, [x1, :lo12:named_data] + .size test_ldr_64bit, .-test_ldr_64bit + + .globl test_strb +test_strb: + strb w0, [x1, :lo12:named_data] + .size test_strb, .-test_strb + + .globl test_strh +test_strh: + strh w0, [x1, :lo12:named_data] + .size test_strh, .-test_strh + + .globl test_str_32bit +test_str_32bit: + str w0, [x1, :lo12:named_data] + .size test_str_32bit, .-test_str_32bit + + .globl test_str_64bit +test_str_64bit: + str x0, [x1, :lo12:named_data] + .size test_str_64bit, .-test_str_64bit + +# Check R_AARCH64_ABS64 relocation of a function pointer to local symbol +# +# jitlink-check: *{8}local_func_addr_quad = named_func + .globl local_func_addr_quad + .p2align 3 +local_func_addr_quad: + .xword named_func + .size local_func_addr_quad, 8 + +# Check R_AARCH64_ADR_GOT_PAGE / R_AARCH64_LD64_GOT_LO12_NC handling with a +# reference to an external symbol. Validate both the reference to the GOT entry, +# and also the content of the GOT entry. +# +# For the ADRP :got: instruction we have the 21-bit delta to the 4k page +# containing the GOT entry for external_data. +# +# For the LDR :got_lo12: instruction we have the 12-bit offset of the entry +# within the page. +# +# jitlink-check: *{8}(got_addr(elf_reloc.o, external_data)) = external_data +# jitlink-check: decode_operand(test_adr_gotpage_external, 1) = \ +# jitlink-check: (got_addr(elf_reloc.o, external_data)[32:12] - \ +# jitlink-check: test_adr_gotpage_external[32:12]) +# jitlink-check: decode_operand(test_ld64_gotlo12_external, 2) = \ +# jitlink-check: got_addr(elf_reloc.o, external_data)[11:3] + .globl test_adr_gotpage_external + .p2align 2 +test_adr_gotpage_external: + adrp x0, :got:external_data + .size test_adr_gotpage_external, .-test_adr_gotpage_external + + .globl test_ld64_gotlo12_external + .p2align 2 +test_ld64_gotlo12_external: + ldr x0, [x0, :got_lo12:external_data] + .size test_ld64_gotlo12_external, .-test_ld64_gotlo12_external + + .globl named_data + .p2align 4 + .type named_data,@object +named_data: + .quad 0x2222222222222222 + .quad 0x3333333333333333 + .size named_data, .-named_data + + .globl named_func + .p2align 2 + .type named_func,@function +named_func: + ret + .size named_func, .-named_func diff --git a/llvm/test/Transforms/Coroutines/coro-debug-coro-frame.ll b/llvm/test/Transforms/Coroutines/coro-debug-coro-frame.ll --- a/llvm/test/Transforms/Coroutines/coro-debug-coro-frame.ll +++ b/llvm/test/Transforms/Coroutines/coro-debug-coro-frame.ll @@ -10,7 +10,8 @@ ; ; CHECK: define internal fastcc void @f.resume( ; CHECK: entry.resume: -; CHECK: call void @llvm.dbg.declare(metadata %f.Frame** %[[FramePtr_RESUME:.*]], metadata ![[CORO_FRAME_IN_RESUME:[0-9]+]], metadata !DIExpression() +; CHECK: %[[FramePtr_RESUME:.*]] = alloca %f.Frame* +; CHECK: call void @llvm.dbg.declare(metadata %f.Frame** %[[FramePtr_RESUME]], metadata ![[CORO_FRAME_IN_RESUME:[0-9]+]], metadata !DIExpression(DW_OP_deref) ; ; CHECK-DAG: ![[FILE:[0-9]+]] = !DIFile(filename: "coro-debug.cpp" ; CHECK-DAG: ![[RAMP:[0-9]+]] = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", diff --git a/llvm/test/Transforms/IndVarSimplify/pr55689.ll b/llvm/test/Transforms/IndVarSimplify/pr55689.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/IndVarSimplify/pr55689.ll @@ -0,0 +1,47 @@ +; RUN: opt -S -passes='loop(indvars)' -verify-scev < %s | FileCheck %s + +; REQUIRES: asserts +; XFAIL: * + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2" +target triple = "x86_64-unknown-linux-gnu" + +define void @test_01(i1 %b) { +; CHECK-LABEL: test_01 +entry: + %b.ext = zext i1 %b to i32 + %zero = and i32 %b.ext, 2 + %precond = icmp ne i32 %zero, 0 + call void @llvm.assume(i1 %precond) + br label %loop + +loop: + %iv = phi i16 [ 0, %entry ], [ %iv.next, %loop ] + %iv.next = add i16 %iv, 1 + %cond = icmp slt i16 %iv, 1 + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @test_02() { +; CHECK-LABEL: test_02 +entry: + %tmp = and i1 false, undef + br i1 %tmp, label %preheader, label %unreached + +preheader: ; preds = %entry + br label %loop + +loop: ; preds = %loop, %preheader + %tmp3 = phi i32 [ 2, %preheader ], [ %tmp4, %loop ] + %tmp4 = add nuw nsw i32 %tmp3, 1 + %tmp5 = icmp ugt i32 %tmp3, 74 + br i1 %tmp5, label %unreached, label %loop + +unreached: ; preds = %loop + unreachable +} + +declare void @llvm.assume(i1) diff --git a/llvm/test/Transforms/InstCombine/2011-06-13-nsw-alloca.ll b/llvm/test/Transforms/InstCombine/2011-06-13-nsw-alloca.ll --- a/llvm/test/Transforms/InstCombine/2011-06-13-nsw-alloca.ll +++ b/llvm/test/Transforms/InstCombine/2011-06-13-nsw-alloca.ll @@ -15,9 +15,9 @@ ;