From 478068566563e8a35039c3faf005bb63d8be4dfd Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 16 Jan 2019 11:00:55 +0000 Subject: [PATCH 001/274] Creating release_80 branch off revision 351319 llvm-svn: 351321 From c6a3c01322ebccfca9d9b86b6762156fc4f4aea9 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 16 Jan 2019 13:25:30 +0000 Subject: [PATCH 002/274] Drop svn version suffix llvm-svn: 351336 --- libcxx/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index a57e36fddcde5..3a6c3c9df4d6a 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -27,7 +27,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) project(libcxx CXX C) set(PACKAGE_NAME libcxx) - set(PACKAGE_VERSION 8.0.0svn) + set(PACKAGE_VERSION 8.0.0) set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org") From d1f4296d80be4f04810846b5e0b612e546848e23 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 16 Jan 2019 13:26:12 +0000 Subject: [PATCH 003/274] Drop svn version suffix llvm-svn: 351337 --- libcxxabi/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxxabi/CMakeLists.txt b/libcxxabi/CMakeLists.txt index 0eeb4b35a236b..92c7dc5dc5576 100644 --- a/libcxxabi/CMakeLists.txt +++ b/libcxxabi/CMakeLists.txt @@ -21,7 +21,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) project(libcxxabi CXX C) set(PACKAGE_NAME libcxxabi) - set(PACKAGE_VERSION 8.0.0svn) + set(PACKAGE_VERSION 8.0.0) set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org") From 193ab2b8576e3c3fea22df880dc5f6c9bcc35611 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 16 Jan 2019 13:27:08 +0000 Subject: [PATCH 004/274] Drop svn version suffix llvm-svn: 351338 --- libunwind/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libunwind/CMakeLists.txt b/libunwind/CMakeLists.txt index 8d0fc50cc451c..c9ba7527afb28 100644 --- a/libunwind/CMakeLists.txt +++ b/libunwind/CMakeLists.txt @@ -81,7 +81,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) endif() set(PACKAGE_NAME libunwind) - set(PACKAGE_VERSION 8.0.0svn) + set(PACKAGE_VERSION 8.0.0) set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org") From ebec3ced5d610d098aa1d56d2bb4c62ceb595daa Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 16 Jan 2019 13:27:54 +0000 Subject: [PATCH 005/274] Drop svn version suffix llvm-svn: 351339 --- llvm/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index b144be50f8431..6e5221ebfd339 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -21,7 +21,7 @@ if(NOT DEFINED LLVM_VERSION_PATCH) set(LLVM_VERSION_PATCH 0) endif() if(NOT DEFINED LLVM_VERSION_SUFFIX) - set(LLVM_VERSION_SUFFIX svn) + set(LLVM_VERSION_SUFFIX "") endif() if (NOT PACKAGE_VERSION) From 0fbd2b5f3891d8cf47356c15e2efc0431990808d Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 16 Jan 2019 13:31:20 +0000 Subject: [PATCH 006/274] Merging r351327: ------------------------------------------------------------------------ r351327 | labath | 2019-01-16 13:19:22 +0100 (Wed, 16 Jan 2019) | 4 lines Revert "Simplify Value::GetValueByteSize()" This reverts commit r351250 because it breaks the SymbolFile/NativePDB/function-types-builtins.cpp. ------------------------------------------------------------------------ llvm-svn: 351342 --- lldb/source/Core/Value.cpp | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/lldb/source/Core/Value.cpp b/lldb/source/Core/Value.cpp index 8e18458b90c20..98a39ea95315a 100644 --- a/lldb/source/Core/Value.cpp +++ b/lldb/source/Core/Value.cpp @@ -210,31 +210,35 @@ bool Value::ValueOf(ExecutionContext *exe_ctx) { } uint64_t Value::GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx) { + uint64_t byte_size = 0; + switch (m_context_type) { case eContextTypeRegisterInfo: // RegisterInfo * - if (GetRegisterInfo()) { - if (error_ptr) - error_ptr->Clear(); - return GetRegisterInfo()->byte_size; - } + if (GetRegisterInfo()) + byte_size = GetRegisterInfo()->byte_size; break; case eContextTypeInvalid: case eContextTypeLLDBType: // Type * case eContextTypeVariable: // Variable * { - auto *scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr; - if (llvm::Optional size = GetCompilerType().GetByteSize(scope)) { - if (error_ptr) - error_ptr->Clear(); - return *size; - } - break; + const CompilerType &ast_type = GetCompilerType(); + if (ast_type.IsValid()) + if (llvm::Optional size = ast_type.GetByteSize( + exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr)) + byte_size = *size; + } break; } + + if (error_ptr) { + if (byte_size == 0) { + if (error_ptr->Success()) + error_ptr->SetErrorString("Unable to determine byte size."); + } else { + error_ptr->Clear(); + } } - if (error_ptr && error_ptr->Success()) - error_ptr->SetErrorString("Unable to determine byte size."); - return 0; + return byte_size; } const CompilerType &Value::GetCompilerType() { From dfde0c768826b0cbd96a51c9361408bb7d931c57 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 16 Jan 2019 13:42:45 +0000 Subject: [PATCH 007/274] Merging r351334: ------------------------------------------------------------------------ r351334 | ibiryukov | 2019-01-16 14:18:59 +0100 (Wed, 16 Jan 2019) | 8 lines Set '-target' flag in the test checking the MacOS include dir To fix a buildbot failure on PS4, see http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-ubuntu-fast/builds/42251 The test was added in r351222 and aims to check only a particular Mac configuration. However it relied on the default compiler target by default, therefore unintentionally failing on PS4. ------------------------------------------------------------------------ llvm-svn: 351343 --- .../Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp b/clang/test/Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp index 035155c96c925..fd0003e9b3828 100644 --- a/clang/test/Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp +++ b/clang/test/Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp @@ -10,7 +10,7 @@ // // RUN: cp $(which clang-check) %t/mock-libcxx/bin/ // RUN: cp "%s" "%t/test.cpp" -// RUN: %t/mock-libcxx/bin/clang-check -p "%t" "%t/test.cpp" -- -stdlib=libc++ +// RUN: %t/mock-libcxx/bin/clang-check -p "%t" "%t/test.cpp" -- -stdlib=libc++ -target x86_64-apple-darwin #include vector v; From 18f9ceeb3df0db65977a4089ae158ef8ed15359f Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Wed, 16 Jan 2019 23:46:28 +0000 Subject: [PATCH 008/274] Merging r351396: ------------------------------------------------------------------------ r351396 | lekensteyn | 2019-01-16 15:28:51 -0800 (Wed, 16 Jan 2019) | 17 lines [ELF][X86_64] Fix corrupted LD -> LE optimization for TLS without PLT The LD -> LE optimization for Thread-Local Storage without PLT requires an additional "66" prefix, otherwise the next instruction will be corrupted, causing runtime misbehavior (crashes) of the linked object. The other (GD -> IE/LD) optimizations are the same with or without PLT, but add tests for completeness. The instructions are copied from https://raw.githubusercontent.com/wiki/hjl-tools/x86-psABI/x86-64-psABI-1.0.pdf#subsection.11.1.2 This does not try to address ILP32 (x32) support. Fixes https://bugs.llvm.org/show_bug.cgi?id=37303 Reviewed By: ruiu Differential Revision: https://reviews.llvm.org/D56779 ------------------------------------------------------------------------ llvm-svn: 351401 --- lld/ELF/Arch/X86_64.cpp | 41 ++++++++++---- lld/test/ELF/tls-opt-x86_64-noplt.s | 88 +++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+), 10 deletions(-) create mode 100644 lld/test/ELF/tls-opt-x86_64-noplt.s diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index 06314155dcc92..a000eeb079d9e 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -264,15 +264,6 @@ void X86_64::relaxTlsIeToLe(uint8_t *Loc, RelType Type, template void X86_64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const { - // Convert - // leaq bar@tlsld(%rip), %rdi - // callq __tls_get_addr@PLT - // leaq bar@dtpoff(%rax), %rcx - // to - // .word 0x6666 - // .byte 0x66 - // mov %fs:0,%rax - // leaq bar@tpoff(%rax), %rcx if (Type == R_X86_64_DTPOFF64) { write64le(Loc, Val); return; @@ -287,7 +278,37 @@ void X86_64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, 0x66, // .byte 0x66 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0,%rax }; - memcpy(Loc - 3, Inst, sizeof(Inst)); + + if (Loc[4] == 0xe8) { + // Convert + // leaq bar@tlsld(%rip), %rdi # 48 8d 3d + // callq __tls_get_addr@PLT # e8 + // leaq bar@dtpoff(%rax), %rcx + // to + // .word 0x6666 + // .byte 0x66 + // mov %fs:0,%rax + // leaq bar@tpoff(%rax), %rcx + memcpy(Loc - 3, Inst, sizeof(Inst)); + return; + } + + if (Loc[4] == 0xff && Loc[5] == 0x15) { + // Convert + // leaq x@tlsld(%rip),%rdi # 48 8d 3d + // call *__tls_get_addr@GOTPCREL(%rip) # ff 15 + // to + // .long 0x66666666 + // movq %fs:0,%rax + // See "Table 11.9: LD -> LE Code Transition (LP64)" in + // https://raw.githubusercontent.com/wiki/hjl-tools/x86-psABI/x86-64-psABI-1.0.pdf + Loc[-3] = 0x66; + memcpy(Loc - 2, Inst, sizeof(Inst)); + return; + } + + error(getErrorLocation(Loc - 3) + + "expected R_X86_64_PLT32 or R_X86_64_GOTPCRELX after R_X86_64_TLSLD"); } template diff --git a/lld/test/ELF/tls-opt-x86_64-noplt.s b/lld/test/ELF/tls-opt-x86_64-noplt.s new file mode 100644 index 0000000000000..69ec49871210e --- /dev/null +++ b/lld/test/ELF/tls-opt-x86_64-noplt.s @@ -0,0 +1,88 @@ +// REQUIRES: x86 + +// Checks whether the TLS optimizations match the cases in Chapter 11 of +// https://raw.githubusercontent.com/wiki/hjl-tools/x86-psABI/x86-64-psABI-1.0.pdf + +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-opt-gdie.s -o %tso.o +// RUN: ld.lld -shared %tso.o -o %t.so +// RUN: ld.lld %t.o %t.so -o %t1 +// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=RELOC %s +// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s + +// RELOC: Relocations [ +// RELOC-NEXT: Section {{.*}} .rela.dyn { +// RELOC-NEXT: 0x2020C0 R_X86_64_TPOFF64 tlsshared0 0x0 +// RELOC-NEXT: 0x2020C8 R_X86_64_TPOFF64 tlsshared1 0x0 +// RELOC-NEXT: } +// RELOC-NEXT: ] + +// DISASM: _start: + +// Table 11.5: GD -> IE Code Transition (LP64) +// DISASM-NEXT: 201000: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax +// DISASM-NEXT: 201009: 48 03 05 b0 10 00 00 addq 4272(%rip), %rax +// DISASM-NEXT: 201010: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax +// DISASM-NEXT: 201019: 48 03 05 a8 10 00 00 addq 4264(%rip), %rax + +// Table 11.7: GD -> LE Code Transition (LP64) +// DISASM-NEXT: 201020: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax +// DISASM-NEXT: 201029: 48 8d 80 f8 ff ff ff leaq -8(%rax), %rax +// DISASM-NEXT: 201030: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax +// DISASM-NEXT: 201039: 48 8d 80 fc ff ff ff leaq -4(%rax), %rax + + +// Table 11.9: LD -> LE Code Transition (LP64) +// DISASM-NEXT: 201040: 66 66 66 66 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax +// DISASM-NEXT: 20104d: 66 66 66 66 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax + +.type tls0,@object +.section .tbss,"awT",@nobits +.globl tls0 +.align 4 +tls0: + .long 0 + .size tls0, 4 + +.type tls1,@object +.globl tls1 +.align 4 +tls1: + .long 0 + .size tls1, 4 + +.section .text +.globl _start +_start: + // Table 11.5: GD -> IE Code Transition (LP64) + .byte 0x66 + leaq tlsshared0@tlsgd(%rip),%rdi + .byte 0x66 + rex64 + call *__tls_get_addr@GOTPCREL(%rip) + + .byte 0x66 + leaq tlsshared1@tlsgd(%rip),%rdi + .byte 0x66 + rex64 + call *__tls_get_addr@GOTPCREL(%rip) + + // Table 11.7: GD -> LE Code Transition (LP64) + .byte 0x66 + leaq tls0@tlsgd(%rip),%rdi + .byte 0x66 + rex64 + call *__tls_get_addr@GOTPCREL(%rip) + + .byte 0x66 + leaq tls1@tlsgd(%rip),%rdi + .byte 0x66 + rex64 + call *__tls_get_addr@GOTPCREL(%rip) + + // Table 11.9: LD -> LE Code Transition (LP64) + leaq tls0@tlsld(%rip),%rdi + call *__tls_get_addr@GOTPCREL(%rip) + + leaq tls1@tlsld(%rip),%rdi + call *__tls_get_addr@GOTPCREL(%rip) From cfa62417693e9f3d56e4309b9d27f405668618a1 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 17 Jan 2019 09:18:40 +0000 Subject: [PATCH 009/274] Merging r351360: ------------------------------------------------------------------------ r351360 | jmorse | 2019-01-16 18:41:29 +0100 (Wed, 16 Jan 2019) | 6 lines Add a REQUIRES: darwin line for a mac test. This test, apparently for macs, fails on Windows as lit can't emulate the shell subprocess $(which...) correctly. Some other netbsd and linux buildbots also fail here. Limit to macs as a temporary workaround. ------------------------------------------------------------------------ llvm-svn: 351419 --- .../Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp b/clang/test/Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp index fd0003e9b3828..8c59a2f07f698 100644 --- a/clang/test/Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp +++ b/clang/test/Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp @@ -11,6 +11,6 @@ // RUN: cp $(which clang-check) %t/mock-libcxx/bin/ // RUN: cp "%s" "%t/test.cpp" // RUN: %t/mock-libcxx/bin/clang-check -p "%t" "%t/test.cpp" -- -stdlib=libc++ -target x86_64-apple-darwin - +// REQUIRES: system-darwin #include vector v; From bcabeb421d61b479cf618270b238fab3c1c73769 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 17 Jan 2019 09:24:42 +0000 Subject: [PATCH 010/274] Merging r351340: ------------------------------------------------------------------------ r351340 | asl | 2019-01-16 14:28:30 +0100 (Wed, 16 Jan 2019) | 7 lines [MSP430] Fix msp430-toolchain.c on Windows (added in r351228) Patch by Kristina Bessonova! Differential Revision: https://reviews.llvm.org/D56776 ------------------------------------------------------------------------ llvm-svn: 351420 --- clang/test/Driver/msp430-toolchain.c | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/clang/test/Driver/msp430-toolchain.c b/clang/test/Driver/msp430-toolchain.c index ae5ed9189c828..62ef1c0c1f150 100644 --- a/clang/test/Driver/msp430-toolchain.c +++ b/clang/test/Driver/msp430-toolchain.c @@ -8,44 +8,44 @@ // RUN: --gcc-toolchain=%S/Inputs/basic_msp430_tree 2>&1 \ // RUN: | FileCheck -check-prefix=MSP430 %s -// MSP430: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../bin/msp430-elf-ld" +// MSP430: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}bin{{/|\\\\}}msp430-elf-ld" // MSP430: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430" -// MSP430: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430" -// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430/crt0.o" -// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430/crtbegin.o" +// MSP430: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430" +// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430{{/|\\\\}}crt0.o" +// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430{{/|\\\\}}crtbegin.o" // MSP430: "--start-group" "-lmul_none" "-lgcc" "-lc" "-lcrt" "-lnosys" "--end-group" -// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430/crtend.o" -// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430/crtn.o" +// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430{{/|\\\\}}crtend.o" +// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430{{/|\\\\}}crtn.o" // RUN: %clang %s -### -no-canonical-prefixes -target msp430 -nodefaultlibs \ // RUN: --gcc-toolchain=%S/Inputs/basic_msp430_tree 2>&1 \ // RUN: | FileCheck -check-prefix=MSP430-NO-DFT-LIB %s -// MSP430-NO-DFT-LIB: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../bin/msp430-elf-ld" +// MSP430-NO-DFT-LIB: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}bin{{/|\\\\}}msp430-elf-ld" // MSP430-NO-DFT-LIB: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430" -// MSP430-NO-DFT-LIB: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430" -// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430/crt0.o" -// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430/crtbegin.o" +// MSP430-NO-DFT-LIB: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430" +// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430{{/|\\\\}}crt0.o" +// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430{{/|\\\\}}crtbegin.o" // MSP430-NO-DFT-LIB: "--start-group" "-lmul_none" "-lgcc" "--end-group" -// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430/crtend.o" -// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430/crtn.o" +// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430{{/|\\\\}}crtend.o" +// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430{{/|\\\\}}crtn.o" // RUN: %clang %s -### -no-canonical-prefixes -target msp430 -nostartfiles \ // RUN: --gcc-toolchain=%S/Inputs/basic_msp430_tree 2>&1 \ // RUN: | FileCheck -check-prefix=MSP430-NO-START %s -// MSP430-NO-START: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../bin/msp430-elf-ld" +// MSP430-NO-START: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}bin{{/|\\\\}}msp430-elf-ld" // MSP430-NO-START: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430" -// MSP430-NO-START: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430" +// MSP430-NO-START: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430" // MSP430-NO-START: "--start-group" "-lmul_none" "-lgcc" "-lc" "-lcrt" "-lnosys" "--end-group" // RUN: %clang %s -### -no-canonical-prefixes -target msp430 -nostdlib \ // RUN: --gcc-toolchain=%S/Inputs/basic_msp430_tree 2>&1 \ // RUN: | FileCheck -check-prefix=MSP430-NO-STD-LIB %s -// MSP430-NO-STD-LIB: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../bin/msp430-elf-ld" +// MSP430-NO-STD-LIB: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}bin{{/|\\\\}}msp430-elf-ld" // MSP430-NO-STD-LIB: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430" -// MSP430-NO-STD-LIB: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430" +// MSP430-NO-STD-LIB: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430" // MSP430-NO-STD-LIB: "--start-group" "-lmul_none" "-lgcc" "--end-group" // RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mmcu=msp430f147 2>&1 \ From 66303bc3a295d19d9f594b92e43146edcd1ab1ab Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 17 Jan 2019 11:31:57 +0000 Subject: [PATCH 011/274] Merging r351431: ------------------------------------------------------------------------ r351431 | hans | 2019-01-17 12:31:03 +0100 (Thu, 17 Jan 2019) | 19 lines Revert r351311 "[OMPT] Make sure that OMPT is enabled when accessing internals of the runtime" and also the follow-up r351315. The new test is failing on the buildbots. > Make sure that OMPT is enabled in runtime entry points that access internals > of the runtime. Else, return an appropiate value indicating an error or that > the data is not available. > > Patch provided by @sconvent > > Reviewers: jlpeyton, omalyshe, hbae, Hahnfeld, joachim.protze > > Reviewed By: joachim.protze > > Tags: #openmp, #ompt > > Differential Revision: https://reviews.llvm.org/D47717 ------------------------------------------------------------------------ llvm-svn: 351432 --- openmp/runtime/src/ompt-general.cpp | 19 +-- .../test/ompt/misc/api_calls_without_ompt.c | 148 ------------------ 2 files changed, 4 insertions(+), 163 deletions(-) delete mode 100644 openmp/runtime/test/ompt/misc/api_calls_without_ompt.c diff --git a/openmp/runtime/src/ompt-general.cpp b/openmp/runtime/src/ompt-general.cpp index cea00fff07acc..80a859196e68d 100644 --- a/openmp/runtime/src/ompt-general.cpp +++ b/openmp/runtime/src/ompt-general.cpp @@ -450,9 +450,6 @@ OMPT_API_ROUTINE ompt_set_result_t ompt_set_callback(ompt_callbacks_t which, OMPT_API_ROUTINE int ompt_get_callback(ompt_callbacks_t which, ompt_callback_t *callback) { - if (!ompt_enabled.enabled) - return ompt_get_callback_failure; - switch (which) { #define ompt_event_macro(event_name, callback_type, event_id) \ @@ -460,7 +457,7 @@ OMPT_API_ROUTINE int ompt_get_callback(ompt_callbacks_t which, if (ompt_event_implementation_status(event_name)) { \ ompt_callback_t mycb = \ (ompt_callback_t)ompt_callbacks.ompt_callback(event_name); \ - if (ompt_enabled.event_name && mycb) { \ + if (mycb) { \ *callback = mycb; \ return ompt_get_callback_success; \ } \ @@ -483,15 +480,11 @@ OMPT_API_ROUTINE int ompt_get_callback(ompt_callbacks_t which, OMPT_API_ROUTINE int ompt_get_parallel_info(int ancestor_level, ompt_data_t **parallel_data, int *team_size) { - if (!ompt_enabled.enabled) - return 0; return __ompt_get_parallel_info_internal(ancestor_level, parallel_data, team_size); } OMPT_API_ROUTINE int ompt_get_state(ompt_wait_id_t *wait_id) { - if (!ompt_enabled.enabled) - return ompt_state_work_serial; int thread_state = __ompt_get_state_internal(wait_id); if (thread_state == ompt_state_undefined) { @@ -506,8 +499,6 @@ OMPT_API_ROUTINE int ompt_get_state(ompt_wait_id_t *wait_id) { ****************************************************************************/ OMPT_API_ROUTINE ompt_data_t *ompt_get_thread_data(void) { - if (!ompt_enabled.enabled) - return NULL; return __ompt_get_thread_data_internal(); } @@ -516,8 +507,6 @@ OMPT_API_ROUTINE int ompt_get_task_info(int ancestor_level, int *type, ompt_frame_t **task_frame, ompt_data_t **parallel_data, int *thread_num) { - if (!ompt_enabled.enabled) - return 0; return __ompt_get_task_info_internal(ancestor_level, type, task_data, task_frame, parallel_data, thread_num); } @@ -592,7 +581,7 @@ OMPT_API_ROUTINE int ompt_get_place_num(void) { #if !KMP_AFFINITY_SUPPORTED return -1; #else - if (!ompt_enabled.enabled || __kmp_get_gtid() < 0) + if (__kmp_get_gtid() < 0) return -1; int gtid; @@ -613,7 +602,7 @@ OMPT_API_ROUTINE int ompt_get_partition_place_nums(int place_nums_size, #if !KMP_AFFINITY_SUPPORTED return 0; #else - if (!ompt_enabled.enabled || __kmp_get_gtid() < 0) + if (__kmp_get_gtid() < 0) return 0; int i, gtid, place_num, first_place, last_place, start, end; @@ -648,7 +637,7 @@ OMPT_API_ROUTINE int ompt_get_partition_place_nums(int place_nums_size, ****************************************************************************/ OMPT_API_ROUTINE int ompt_get_proc_id(void) { - if (!ompt_enabled.enabled || __kmp_get_gtid() < 0) + if (__kmp_get_gtid() < 0) return -1; #if KMP_OS_LINUX return sched_getcpu(); diff --git a/openmp/runtime/test/ompt/misc/api_calls_without_ompt.c b/openmp/runtime/test/ompt/misc/api_calls_without_ompt.c deleted file mode 100644 index 976c20f47f1e2..0000000000000 --- a/openmp/runtime/test/ompt/misc/api_calls_without_ompt.c +++ /dev/null @@ -1,148 +0,0 @@ -// RUN: %libomp-compile-and-run | FileCheck %s -// REQUIRES: ompt - -#define _BSD_SOURCE -#define _DEFAULT_SOURCE - -#include -#include -#include -#include - -static ompt_set_callback_t ompt_set_callback; -static ompt_get_callback_t ompt_get_callback; -static ompt_get_state_t ompt_get_state; -static ompt_get_task_info_t ompt_get_task_info; -static ompt_get_thread_data_t ompt_get_thread_data; -static ompt_get_parallel_info_t ompt_get_parallel_info; -static ompt_get_unique_id_t ompt_get_unique_id; -static ompt_get_num_procs_t ompt_get_num_procs; -static ompt_get_num_places_t ompt_get_num_places; -static ompt_get_place_proc_ids_t ompt_get_place_proc_ids; -static ompt_get_place_num_t ompt_get_place_num; -static ompt_get_partition_place_nums_t ompt_get_partition_place_nums; -static ompt_get_proc_id_t ompt_get_proc_id; -static ompt_enumerate_states_t ompt_enumerate_states; -static ompt_enumerate_mutex_impls_t ompt_enumerate_mutex_impls; - -int main() { - // Call OpenMP API function to force initialization of OMPT. - // (omp_get_thread_num() does not work because it just returns 0 if the - // runtime isn't initialized yet...) - omp_get_num_threads(); - - ompt_data_t *tdata = ompt_get_thread_data(); - uint64_t tvalue = tdata ? tdata->value : 0; - - printf("%" PRIu64 ": ompt_get_num_places()=%d\n", tvalue, - ompt_get_num_places()); - - printf("%" PRIu64 ": ompt_get_place_proc_ids()=%d\n", tvalue, - ompt_get_place_proc_ids(0, 0, NULL)); - - printf("%" PRIu64 ": ompt_get_place_num()=%d\n", tvalue, - ompt_get_place_num()); - - printf("%" PRIu64 ": ompt_get_partition_place_nums()=%d\n", tvalue, - ompt_get_partition_place_nums(0, NULL)); - - printf("%" PRIu64 ": ompt_get_proc_id()=%d\n", tvalue, ompt_get_proc_id()); - - printf("%" PRIu64 ": ompt_get_num_procs()=%d\n", tvalue, - ompt_get_num_procs()); - - ompt_callback_t callback; - printf("%" PRIu64 ": ompt_get_callback()=%d\n", tvalue, - ompt_get_callback(ompt_callback_thread_begin, &callback)); - - printf("%" PRIu64 ": ompt_get_state()=%d\n", tvalue, ompt_get_state(NULL)); - - int state = omp_state_undefined; - const char *state_name; - printf("%" PRIu64 ": ompt_enumerate_states()=%d\n", tvalue, - ompt_enumerate_states(state, &state, &state_name)); - - int impl = ompt_mutex_impl_unknown; - const char *impl_name; - printf("%" PRIu64 ": ompt_enumerate_mutex_impls()=%d\n", tvalue, - ompt_enumerate_mutex_impls(impl, &impl, &impl_name)); - - printf("%" PRIu64 ": ompt_get_thread_data()=%p\n", tvalue, - ompt_get_thread_data()); - - printf("%" PRIu64 ": ompt_get_parallel_info()=%d\n", tvalue, - ompt_get_parallel_info(0, NULL, NULL)); - - printf("%" PRIu64 ": ompt_get_task_info()=%d\n", tvalue, - ompt_get_task_info(0, NULL, NULL, NULL, NULL, NULL)); - - // Check if libomp supports the callbacks for this test. - - // CHECK: 0: NULL_POINTER=[[NULL:.*$]] - - // CHECK: {{^}}[[MASTER_ID:[0-9]+]]: ompt_get_num_places()={{[0-9]+}} - - // CHECK: {{^}}[[MASTER_ID]]: ompt_get_place_proc_ids()={{[0-9]+}} - - // CHECK: {{^}}[[MASTER_ID]]: ompt_get_place_num()=-1 - - // CHECK: {{^}}[[MASTER_ID]]: ompt_get_partition_place_nums()=0 - - // CHECK: {{^}}[[MASTER_ID]]: ompt_get_proc_id()=-1 - - // CHECK: {{^}}[[MASTER_ID]]: ompt_get_num_procs()={{[0-9]+}} - - // CHECK: {{^}}[[MASTER_ID]]: ompt_get_callback()=0 - - // CHECK: {{^}}[[MASTER_ID]]: ompt_get_state()=0 - - // CHECK: {{^}}[[MASTER_ID]]: ompt_enumerate_states()=1 - - // CHECK: {{^}}[[MASTER_ID]]: ompt_enumerate_mutex_impls()=1 - - // CHECK: {{^}}[[MASTER_ID]]: ompt_get_thread_data()=[[NULL]] - - // CHECK: {{^}}[[MASTER_ID]]: ompt_get_parallel_info()=0 - - // CHECK: {{^}}[[MASTER_ID]]: ompt_get_task_info()=0 - - return 0; -} - -int ompt_initialize(ompt_function_lookup_t lookup, ompt_data_t *tool_data) { - ompt_set_callback = (ompt_set_callback_t)lookup("ompt_set_callback"); - ompt_get_callback = (ompt_get_callback_t)lookup("ompt_get_callback"); - ompt_get_state = (ompt_get_state_t)lookup("ompt_get_state"); - ompt_get_task_info = (ompt_get_task_info_t)lookup("ompt_get_task_info"); - ompt_get_thread_data = (ompt_get_thread_data_t)lookup("ompt_get_thread_data"); - ompt_get_parallel_info = - (ompt_get_parallel_info_t)lookup("ompt_get_parallel_info"); - ompt_get_unique_id = (ompt_get_unique_id_t)lookup("ompt_get_unique_id"); - - ompt_get_num_procs = (ompt_get_num_procs_t)lookup("ompt_get_num_procs"); - ompt_get_num_places = (ompt_get_num_places_t)lookup("ompt_get_num_places"); - ompt_get_place_proc_ids = - (ompt_get_place_proc_ids_t)lookup("ompt_get_place_proc_ids"); - ompt_get_place_num = (ompt_get_place_num_t)lookup("ompt_get_place_num"); - ompt_get_partition_place_nums = - (ompt_get_partition_place_nums_t)lookup("ompt_get_partition_place_nums"); - ompt_get_proc_id = (ompt_get_proc_id_t)lookup("ompt_get_proc_id"); - ompt_enumerate_states = - (ompt_enumerate_states_t)lookup("ompt_enumerate_states"); - ompt_enumerate_mutex_impls = - (ompt_enumerate_mutex_impls_t)lookup("ompt_enumerate_mutex_impls"); - - printf("0: NULL_POINTER=%p\n", (void *)NULL); - return 0; // no success -> OMPT not enabled -} - -void ompt_finalize(ompt_data_t *tool_data) { - printf("0: ompt_event_runtime_shutdown\n"); -} - -ompt_start_tool_result_t *ompt_start_tool(unsigned int omp_version, - const char *runtime_version) { - static ompt_start_tool_result_t ompt_start_tool_result = {&ompt_initialize, - &ompt_finalize, 0}; - return &ompt_start_tool_result; -} From 9d7c27063f0a4494d8e3b9b3e9eb7cc411d8e454 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 17 Jan 2019 13:12:00 +0000 Subject: [PATCH 012/274] Merging r351436: ------------------------------------------------------------------------ r351436 | hans | 2019-01-17 14:11:15 +0100 (Thu, 17 Jan 2019) | 1 line build_llvm_package.bat: Run more tests ------------------------------------------------------------------------ llvm-svn: 351437 --- llvm/utils/release/build_llvm_package.bat | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/llvm/utils/release/build_llvm_package.bat b/llvm/utils/release/build_llvm_package.bat index 51f425633a3d6..6a0b19b719605 100755 --- a/llvm/utils/release/build_llvm_package.bat +++ b/llvm/utils/release/build_llvm_package.bat @@ -54,7 +54,7 @@ svn.exe export -r %revision% http://llvm.org/svn/llvm-project/lldb/%branch% llvm REM Setting CMAKE_CL_SHOWINCLUDES_PREFIX to work around PR27226. set cmake_flags=-DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_INSTALL_TOOLCHAIN_ONLY=ON -DCMAKE_INSTALL_UCRT_LIBRARIES=ON -DCLANG_FORMAT_VS_VERSION=%clang_format_vs_version% -DPACKAGE_VERSION=%package_version% -DLLDB_RELOCATABLE_PYTHON=1 -DLLDB_TEST_COMPILER=%cd%\build32_stage0\bin\clang.exe -DCMAKE_CL_SHOWINCLUDES_PREFIX="Note: including file: " -REM TODO: Run all tests, including lld and compiler-rt. +REM TODO: Run the "check-all" tests. set "VSCMD_START_DIR=%CD%" call "%vsdevcmd%" -arch=x86 @@ -66,7 +66,9 @@ REM Work around VS2017 bug by using MinSizeRel. cmake -GNinja %cmake_flags% -DPYTHON_HOME=%python32_dir% -DCMAKE_BUILD_TYPE=MinSizeRel ..\llvm || exit /b ninja all || ninja all || ninja all || exit /b ninja check || ninja check || ninja check || exit /b -ninja check-clang || ninja check-clang || ninja check-clang || exit /b +ninja check-clang || ninja check-clang || ninja check-clang || exit /b +ninja check-lld || ninja check-lld || ninja check-lld || exit /b +ninja check-sanitizer || ninja check-sanitizer || ninja check-sanitizer || exit /b cd.. mkdir build32 @@ -76,7 +78,9 @@ set CXX=..\build32_stage0\bin\clang-cl cmake -GNinja %cmake_flags% -DPYTHON_HOME=%python32_dir% ..\llvm || exit /b ninja all || ninja all || ninja all || exit /b ninja check || ninja check || ninja check || exit /b -ninja check-clang || ninja check-clang || ninja check-clang || exit /b +ninja check-clang || ninja check-clang || ninja check-clang || exit /b +ninja check-lld || ninja check-lld || ninja check-lld || exit /b +ninja check-sanitizer || ninja check-sanitizer || ninja check-sanitizer || exit /b ninja package || exit /b cd .. @@ -101,7 +105,9 @@ REM Work around VS2017 bug by using MinSizeRel. cmake -GNinja %cmake_flags% -DPYTHON_HOME=%python64_dir% -DCMAKE_BUILD_TYPE=MinSizeRel ..\llvm || exit /b ninja all || ninja all || ninja all || exit /b ninja check || ninja check || ninja check || exit /b -ninja check-clang || ninja check-clang || ninja check-clang || exit /b +ninja check-clang || ninja check-clang || ninja check-clang || exit /b +ninja check-lld || ninja check-lld || ninja check-lld || exit /b +ninja check-sanitizer || ninja check-sanitizer || ninja check-sanitizer || exit /b cd.. mkdir build64 @@ -111,6 +117,8 @@ set CXX=..\build64_stage0\bin\clang-cl cmake -GNinja %cmake_flags% -DPYTHON_HOME=%python64_dir% ..\llvm || exit /b ninja all || ninja all || ninja all || exit /b ninja check || ninja check || ninja check || exit /b -ninja check-clang || ninja check-clang || ninja check-clang || exit /b +ninja check-clang || ninja check-clang || ninja check-clang || exit /b +ninja check-lld || ninja check-lld || ninja check-lld || exit /b +ninja check-sanitizer || ninja check-sanitizer || ninja check-sanitizer || exit /b ninja package || exit /b cd .. From 2b727e7e3619782bb4f7a0a342f154d3418034eb Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 17 Jan 2019 13:26:58 +0000 Subject: [PATCH 013/274] Merging r351349: ------------------------------------------------------------------------ r351349 | abataev | 2019-01-16 16:39:52 +0100 (Wed, 16 Jan 2019) | 14 lines [SLP] Fix PR40310: The reduction nodes should stay scalar. Summary: Sometimes the SLP vectorizer tries to vectorize the horizontal reduction nodes during regular vectorization. This may happen inside of the loops, when there are some vectorizable PHIs. Patch fixes this by checking if the node is the reduction node and thus it must not be vectorized, it must be gathered. Reviewers: RKSimon, spatel, hfinkel, fedor.sergeev Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D56783 ------------------------------------------------------------------------ llvm-svn: 351440 --- .../Transforms/Vectorize/SLPVectorizer.cpp | 3 +- .../Transforms/SLPVectorizer/X86/PR39774.ll | 266 ++++++++++++------ .../Transforms/SLPVectorizer/X86/PR40310.ll | 18 +- 3 files changed, 188 insertions(+), 99 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 2e856a7e6802e..a07fffe9b98b9 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -1468,8 +1468,9 @@ void BoUpSLP::buildTree_rec(ArrayRef VL, unsigned Depth, // If any of the scalars is marked as a value that needs to stay scalar, then // we need to gather the scalars. + // The reduction nodes (stored in UserIgnoreList) also should stay scalar. for (unsigned i = 0, e = VL.size(); i != e; ++i) { - if (MustGather.count(VL[i])) { + if (MustGather.count(VL[i]) || is_contained(UserIgnoreList, VL[i])) { LLVM_DEBUG(dbgs() << "SLP: Gathering due to gathered scalar.\n"); newTreeEntry(VL, false, UserTreeIdx); return; diff --git a/llvm/test/Transforms/SLPVectorizer/X86/PR39774.ll b/llvm/test/Transforms/SLPVectorizer/X86/PR39774.ll index 8405117090b46..67717a54659c3 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/PR39774.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/PR39774.ll @@ -3,93 +3,185 @@ ; RUN: opt -slp-vectorizer -S < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=skylake -slp-threshold=-8 -slp-min-tree-size=6 | FileCheck %s --check-prefixes=ALL,FORCE_REDUCTION define void @Test(i32) { -; ALL-LABEL: @Test( -; ALL-NEXT: entry: -; ALL-NEXT: br label [[LOOP:%.*]] -; ALL: loop: -; ALL-NEXT: [[TMP1:%.*]] = phi <2 x i32> [ [[TMP11:%.*]], [[LOOP]] ], [ zeroinitializer, [[ENTRY:%.*]] ] -; ALL-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> undef, <8 x i32> -; ALL-NEXT: [[TMP2:%.*]] = extractelement <8 x i32> [[SHUFFLE]], i32 1 -; ALL-NEXT: [[TMP3:%.*]] = add <8 x i32> , [[SHUFFLE]] -; ALL-NEXT: [[VAL_1:%.*]] = and i32 [[TMP2]], undef -; ALL-NEXT: [[VAL_2:%.*]] = and i32 [[VAL_1]], [[TMP0:%.*]] -; ALL-NEXT: [[VAL_3:%.*]] = and i32 [[VAL_2]], [[TMP0]] -; ALL-NEXT: [[VAL_4:%.*]] = and i32 [[VAL_3]], [[TMP0]] -; ALL-NEXT: [[VAL_5:%.*]] = and i32 [[VAL_4]], [[TMP0]] -; ALL-NEXT: [[VAL_7:%.*]] = and i32 [[VAL_5]], undef -; ALL-NEXT: [[VAL_8:%.*]] = and i32 [[VAL_7]], [[TMP0]] -; ALL-NEXT: [[VAL_9:%.*]] = and i32 [[VAL_8]], [[TMP0]] -; ALL-NEXT: [[VAL_10:%.*]] = and i32 [[VAL_9]], [[TMP0]] -; ALL-NEXT: [[VAL_12:%.*]] = and i32 [[VAL_10]], undef -; ALL-NEXT: [[VAL_13:%.*]] = and i32 [[VAL_12]], [[TMP0]] -; ALL-NEXT: [[VAL_14:%.*]] = and i32 [[VAL_13]], [[TMP0]] -; ALL-NEXT: [[VAL_15:%.*]] = and i32 [[VAL_14]], [[TMP0]] -; ALL-NEXT: [[VAL_16:%.*]] = and i32 [[VAL_15]], [[TMP0]] -; ALL-NEXT: [[VAL_17:%.*]] = and i32 [[VAL_16]], [[TMP0]] -; ALL-NEXT: [[VAL_19:%.*]] = and i32 [[VAL_17]], undef -; ALL-NEXT: [[VAL_21:%.*]] = and i32 [[VAL_19]], undef -; ALL-NEXT: [[VAL_22:%.*]] = and i32 [[VAL_21]], [[TMP0]] -; ALL-NEXT: [[VAL_23:%.*]] = and i32 [[VAL_22]], [[TMP0]] -; ALL-NEXT: [[VAL_24:%.*]] = and i32 [[VAL_23]], [[TMP0]] -; ALL-NEXT: [[VAL_25:%.*]] = and i32 [[VAL_24]], [[TMP0]] -; ALL-NEXT: [[VAL_26:%.*]] = and i32 [[VAL_25]], [[TMP0]] -; ALL-NEXT: [[VAL_27:%.*]] = and i32 [[VAL_26]], [[TMP0]] -; ALL-NEXT: [[VAL_28:%.*]] = and i32 [[VAL_27]], [[TMP0]] -; ALL-NEXT: [[VAL_29:%.*]] = and i32 [[VAL_28]], [[TMP0]] -; ALL-NEXT: [[VAL_30:%.*]] = and i32 [[VAL_29]], [[TMP0]] -; ALL-NEXT: [[VAL_31:%.*]] = and i32 [[VAL_30]], [[TMP0]] -; ALL-NEXT: [[VAL_32:%.*]] = and i32 [[VAL_31]], [[TMP0]] -; ALL-NEXT: [[VAL_33:%.*]] = and i32 [[VAL_32]], [[TMP0]] -; ALL-NEXT: [[VAL_35:%.*]] = and i32 [[VAL_33]], undef -; ALL-NEXT: [[VAL_36:%.*]] = and i32 [[VAL_35]], [[TMP0]] -; ALL-NEXT: [[VAL_37:%.*]] = and i32 [[VAL_36]], [[TMP0]] -; ALL-NEXT: [[VAL_38:%.*]] = and i32 [[VAL_37]], [[TMP0]] -; ALL-NEXT: [[VAL_40:%.*]] = and i32 [[VAL_38]], undef -; ALL-NEXT: [[TMP4:%.*]] = insertelement <2 x i32> undef, i32 [[VAL_40]], i32 0 -; ALL-NEXT: [[TMP5:%.*]] = insertelement <2 x i32> [[TMP4]], i32 [[TMP2]], i32 1 -; ALL-NEXT: [[TMP6:%.*]] = extractelement <8 x i32> [[TMP3]], i32 7 -; ALL-NEXT: [[TMP7:%.*]] = insertelement <2 x i32> undef, i32 [[TMP6]], i32 0 -; ALL-NEXT: [[TMP8:%.*]] = insertelement <2 x i32> [[TMP7]], i32 14910, i32 1 -; ALL-NEXT: [[TMP9:%.*]] = and <2 x i32> [[TMP5]], [[TMP8]] -; ALL-NEXT: [[TMP10:%.*]] = add <2 x i32> [[TMP5]], [[TMP8]] -; ALL-NEXT: [[TMP11]] = shufflevector <2 x i32> [[TMP9]], <2 x i32> [[TMP10]], <2 x i32> -; ALL-NEXT: [[RDX_SHUF:%.*]] = shufflevector <8 x i32> [[TMP3]], <8 x i32> undef, <8 x i32> -; ALL-NEXT: [[BIN_RDX:%.*]] = and <8 x i32> [[TMP3]], [[RDX_SHUF]] -; ALL-NEXT: [[RDX_SHUF1:%.*]] = shufflevector <8 x i32> [[BIN_RDX]], <8 x i32> undef, <8 x i32> -; ALL-NEXT: [[BIN_RDX2:%.*]] = and <8 x i32> [[BIN_RDX]], [[RDX_SHUF1]] -; ALL-NEXT: [[RDX_SHUF3:%.*]] = shufflevector <8 x i32> [[BIN_RDX2]], <8 x i32> undef, <8 x i32> -; ALL-NEXT: [[BIN_RDX4:%.*]] = and <8 x i32> [[BIN_RDX2]], [[RDX_SHUF3]] -; ALL-NEXT: [[TMP12:%.*]] = extractelement <8 x i32> [[BIN_RDX4]], i32 0 -; ALL-NEXT: [[OP_EXTRA:%.*]] = and i32 [[TMP12]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA5:%.*]] = and i32 [[OP_EXTRA]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA6:%.*]] = and i32 [[OP_EXTRA5]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA7:%.*]] = and i32 [[OP_EXTRA6]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA8:%.*]] = and i32 [[OP_EXTRA7]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA9:%.*]] = and i32 [[OP_EXTRA8]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA10:%.*]] = and i32 [[OP_EXTRA9]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA11:%.*]] = and i32 [[OP_EXTRA10]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA12:%.*]] = and i32 [[OP_EXTRA11]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA13:%.*]] = and i32 [[OP_EXTRA12]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA14:%.*]] = and i32 [[OP_EXTRA13]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA15:%.*]] = and i32 [[OP_EXTRA14]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA16:%.*]] = and i32 [[OP_EXTRA15]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA17:%.*]] = and i32 [[OP_EXTRA16]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA18:%.*]] = and i32 [[OP_EXTRA17]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA19:%.*]] = and i32 [[OP_EXTRA18]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA20:%.*]] = and i32 [[OP_EXTRA19]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA21:%.*]] = and i32 [[OP_EXTRA20]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA22:%.*]] = and i32 [[OP_EXTRA21]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA23:%.*]] = and i32 [[OP_EXTRA22]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA24:%.*]] = and i32 [[OP_EXTRA23]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA25:%.*]] = and i32 [[OP_EXTRA24]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA26:%.*]] = and i32 [[OP_EXTRA25]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA27:%.*]] = and i32 [[OP_EXTRA26]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA28:%.*]] = and i32 [[OP_EXTRA27]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA29:%.*]] = and i32 [[OP_EXTRA28]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA30:%.*]] = and i32 [[OP_EXTRA29]], [[TMP0]] -; ALL-NEXT: [[OP_EXTRA31:%.*]] = and i32 [[OP_EXTRA30]], [[TMP2]] -; ALL-NEXT: [[TMP13:%.*]] = extractelement <2 x i32> [[TMP11]], i32 0 -; ALL-NEXT: br label [[LOOP]] +; CHECK-LABEL: @Test( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[TMP1:%.*]] = phi <2 x i32> [ [[TMP15:%.*]], [[LOOP]] ], [ zeroinitializer, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> undef, <8 x i32> +; CHECK-NEXT: [[TMP2:%.*]] = extractelement <8 x i32> [[SHUFFLE]], i32 1 +; CHECK-NEXT: [[TMP3:%.*]] = add <8 x i32> , [[SHUFFLE]] +; CHECK-NEXT: [[VAL_1:%.*]] = and i32 [[TMP2]], undef +; CHECK-NEXT: [[VAL_2:%.*]] = and i32 [[VAL_1]], [[TMP0:%.*]] +; CHECK-NEXT: [[VAL_3:%.*]] = and i32 [[VAL_2]], [[TMP0]] +; CHECK-NEXT: [[VAL_4:%.*]] = and i32 [[VAL_3]], [[TMP0]] +; CHECK-NEXT: [[VAL_5:%.*]] = and i32 [[VAL_4]], [[TMP0]] +; CHECK-NEXT: [[VAL_7:%.*]] = and i32 [[VAL_5]], undef +; CHECK-NEXT: [[VAL_8:%.*]] = and i32 [[VAL_7]], [[TMP0]] +; CHECK-NEXT: [[VAL_9:%.*]] = and i32 [[VAL_8]], [[TMP0]] +; CHECK-NEXT: [[VAL_10:%.*]] = and i32 [[VAL_9]], [[TMP0]] +; CHECK-NEXT: [[VAL_12:%.*]] = and i32 [[VAL_10]], undef +; CHECK-NEXT: [[VAL_13:%.*]] = and i32 [[VAL_12]], [[TMP0]] +; CHECK-NEXT: [[VAL_14:%.*]] = and i32 [[VAL_13]], [[TMP0]] +; CHECK-NEXT: [[VAL_15:%.*]] = and i32 [[VAL_14]], [[TMP0]] +; CHECK-NEXT: [[VAL_16:%.*]] = and i32 [[VAL_15]], [[TMP0]] +; CHECK-NEXT: [[VAL_17:%.*]] = and i32 [[VAL_16]], [[TMP0]] +; CHECK-NEXT: [[VAL_19:%.*]] = and i32 [[VAL_17]], undef +; CHECK-NEXT: [[VAL_21:%.*]] = and i32 [[VAL_19]], undef +; CHECK-NEXT: [[VAL_22:%.*]] = and i32 [[VAL_21]], [[TMP0]] +; CHECK-NEXT: [[VAL_23:%.*]] = and i32 [[VAL_22]], [[TMP0]] +; CHECK-NEXT: [[VAL_24:%.*]] = and i32 [[VAL_23]], [[TMP0]] +; CHECK-NEXT: [[VAL_25:%.*]] = and i32 [[VAL_24]], [[TMP0]] +; CHECK-NEXT: [[VAL_26:%.*]] = and i32 [[VAL_25]], [[TMP0]] +; CHECK-NEXT: [[VAL_27:%.*]] = and i32 [[VAL_26]], [[TMP0]] +; CHECK-NEXT: [[VAL_28:%.*]] = and i32 [[VAL_27]], [[TMP0]] +; CHECK-NEXT: [[VAL_29:%.*]] = and i32 [[VAL_28]], [[TMP0]] +; CHECK-NEXT: [[VAL_30:%.*]] = and i32 [[VAL_29]], [[TMP0]] +; CHECK-NEXT: [[VAL_31:%.*]] = and i32 [[VAL_30]], [[TMP0]] +; CHECK-NEXT: [[VAL_32:%.*]] = and i32 [[VAL_31]], [[TMP0]] +; CHECK-NEXT: [[VAL_33:%.*]] = and i32 [[VAL_32]], [[TMP0]] +; CHECK-NEXT: [[VAL_35:%.*]] = and i32 [[VAL_33]], undef +; CHECK-NEXT: [[VAL_36:%.*]] = and i32 [[VAL_35]], [[TMP0]] +; CHECK-NEXT: [[VAL_37:%.*]] = and i32 [[VAL_36]], [[TMP0]] +; CHECK-NEXT: [[VAL_38:%.*]] = and i32 [[VAL_37]], [[TMP0]] +; CHECK-NEXT: [[VAL_40:%.*]] = and i32 [[VAL_38]], undef +; CHECK-NEXT: [[RDX_SHUF:%.*]] = shufflevector <8 x i32> [[TMP3]], <8 x i32> undef, <8 x i32> +; CHECK-NEXT: [[BIN_RDX:%.*]] = and <8 x i32> [[TMP3]], [[RDX_SHUF]] +; CHECK-NEXT: [[RDX_SHUF1:%.*]] = shufflevector <8 x i32> [[BIN_RDX]], <8 x i32> undef, <8 x i32> +; CHECK-NEXT: [[BIN_RDX2:%.*]] = and <8 x i32> [[BIN_RDX]], [[RDX_SHUF1]] +; CHECK-NEXT: [[RDX_SHUF3:%.*]] = shufflevector <8 x i32> [[BIN_RDX2]], <8 x i32> undef, <8 x i32> +; CHECK-NEXT: [[BIN_RDX4:%.*]] = and <8 x i32> [[BIN_RDX2]], [[RDX_SHUF3]] +; CHECK-NEXT: [[TMP4:%.*]] = extractelement <8 x i32> [[BIN_RDX4]], i32 0 +; CHECK-NEXT: [[OP_EXTRA:%.*]] = and i32 [[TMP4]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA5:%.*]] = and i32 [[OP_EXTRA]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA6:%.*]] = and i32 [[OP_EXTRA5]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA7:%.*]] = and i32 [[OP_EXTRA6]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA8:%.*]] = and i32 [[OP_EXTRA7]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA9:%.*]] = and i32 [[OP_EXTRA8]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA10:%.*]] = and i32 [[OP_EXTRA9]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA11:%.*]] = and i32 [[OP_EXTRA10]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA12:%.*]] = and i32 [[OP_EXTRA11]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA13:%.*]] = and i32 [[OP_EXTRA12]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA14:%.*]] = and i32 [[OP_EXTRA13]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA15:%.*]] = and i32 [[OP_EXTRA14]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA16:%.*]] = and i32 [[OP_EXTRA15]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA17:%.*]] = and i32 [[OP_EXTRA16]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA18:%.*]] = and i32 [[OP_EXTRA17]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA19:%.*]] = and i32 [[OP_EXTRA18]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA20:%.*]] = and i32 [[OP_EXTRA19]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA21:%.*]] = and i32 [[OP_EXTRA20]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA22:%.*]] = and i32 [[OP_EXTRA21]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA23:%.*]] = and i32 [[OP_EXTRA22]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA24:%.*]] = and i32 [[OP_EXTRA23]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA25:%.*]] = and i32 [[OP_EXTRA24]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA26:%.*]] = and i32 [[OP_EXTRA25]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA27:%.*]] = and i32 [[OP_EXTRA26]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA28:%.*]] = and i32 [[OP_EXTRA27]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA29:%.*]] = and i32 [[OP_EXTRA28]], [[TMP0]] +; CHECK-NEXT: [[OP_EXTRA30:%.*]] = and i32 [[OP_EXTRA29]], [[TMP0]] +; CHECK-NEXT: [[VAL_42:%.*]] = and i32 [[VAL_40]], undef +; CHECK-NEXT: [[TMP5:%.*]] = insertelement <2 x i32> undef, i32 [[OP_EXTRA30]], i32 0 +; CHECK-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> [[TMP5]], i32 [[TMP2]], i32 1 +; CHECK-NEXT: [[TMP7:%.*]] = insertelement <2 x i32> undef, i32 [[TMP2]], i32 0 +; CHECK-NEXT: [[TMP8:%.*]] = insertelement <2 x i32> [[TMP7]], i32 14910, i32 1 +; CHECK-NEXT: [[TMP9:%.*]] = and <2 x i32> [[TMP6]], [[TMP8]] +; CHECK-NEXT: [[TMP10:%.*]] = add <2 x i32> [[TMP6]], [[TMP8]] +; CHECK-NEXT: [[TMP11:%.*]] = shufflevector <2 x i32> [[TMP9]], <2 x i32> [[TMP10]], <2 x i32> +; CHECK-NEXT: [[TMP12:%.*]] = extractelement <2 x i32> [[TMP11]], i32 0 +; CHECK-NEXT: [[TMP13:%.*]] = insertelement <2 x i32> undef, i32 [[TMP12]], i32 0 +; CHECK-NEXT: [[TMP14:%.*]] = extractelement <2 x i32> [[TMP11]], i32 1 +; CHECK-NEXT: [[TMP15]] = insertelement <2 x i32> [[TMP13]], i32 [[TMP14]], i32 1 +; CHECK-NEXT: br label [[LOOP]] +; +; FORCE_REDUCTION-LABEL: @Test( +; FORCE_REDUCTION-NEXT: entry: +; FORCE_REDUCTION-NEXT: br label [[LOOP:%.*]] +; FORCE_REDUCTION: loop: +; FORCE_REDUCTION-NEXT: [[TMP1:%.*]] = phi <2 x i32> [ [[TMP13:%.*]], [[LOOP]] ], [ zeroinitializer, [[ENTRY:%.*]] ] +; FORCE_REDUCTION-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> undef, <4 x i32> +; FORCE_REDUCTION-NEXT: [[TMP2:%.*]] = extractelement <4 x i32> [[SHUFFLE]], i32 1 +; FORCE_REDUCTION-NEXT: [[TMP3:%.*]] = add <4 x i32> , [[SHUFFLE]] +; FORCE_REDUCTION-NEXT: [[VAL_1:%.*]] = and i32 [[TMP2]], undef +; FORCE_REDUCTION-NEXT: [[VAL_2:%.*]] = and i32 [[VAL_1]], [[TMP0:%.*]] +; FORCE_REDUCTION-NEXT: [[VAL_3:%.*]] = and i32 [[VAL_2]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_4:%.*]] = and i32 [[VAL_3]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_5:%.*]] = and i32 [[VAL_4]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_7:%.*]] = and i32 [[VAL_5]], undef +; FORCE_REDUCTION-NEXT: [[VAL_8:%.*]] = and i32 [[VAL_7]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_9:%.*]] = and i32 [[VAL_8]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_10:%.*]] = and i32 [[VAL_9]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_12:%.*]] = and i32 [[VAL_10]], undef +; FORCE_REDUCTION-NEXT: [[VAL_13:%.*]] = and i32 [[VAL_12]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_14:%.*]] = and i32 [[VAL_13]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_15:%.*]] = and i32 [[VAL_14]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_16:%.*]] = and i32 [[VAL_15]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_17:%.*]] = and i32 [[VAL_16]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_19:%.*]] = and i32 [[VAL_17]], undef +; FORCE_REDUCTION-NEXT: [[VAL_20:%.*]] = add i32 [[TMP2]], 1496 +; FORCE_REDUCTION-NEXT: [[VAL_21:%.*]] = and i32 [[VAL_19]], [[VAL_20]] +; FORCE_REDUCTION-NEXT: [[VAL_22:%.*]] = and i32 [[VAL_21]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_23:%.*]] = and i32 [[VAL_22]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_24:%.*]] = and i32 [[VAL_23]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_25:%.*]] = and i32 [[VAL_24]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_26:%.*]] = and i32 [[VAL_25]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_27:%.*]] = and i32 [[VAL_26]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_28:%.*]] = and i32 [[VAL_27]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_29:%.*]] = and i32 [[VAL_28]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_30:%.*]] = and i32 [[VAL_29]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_31:%.*]] = and i32 [[VAL_30]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_32:%.*]] = and i32 [[VAL_31]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_33:%.*]] = and i32 [[VAL_32]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_34:%.*]] = add i32 [[TMP2]], 8555 +; FORCE_REDUCTION-NEXT: [[VAL_35:%.*]] = and i32 [[VAL_33]], [[VAL_34]] +; FORCE_REDUCTION-NEXT: [[VAL_36:%.*]] = and i32 [[VAL_35]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_37:%.*]] = and i32 [[VAL_36]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[RDX_SHUF:%.*]] = shufflevector <4 x i32> [[TMP3]], <4 x i32> undef, <4 x i32> +; FORCE_REDUCTION-NEXT: [[BIN_RDX:%.*]] = and <4 x i32> [[TMP3]], [[RDX_SHUF]] +; FORCE_REDUCTION-NEXT: [[RDX_SHUF1:%.*]] = shufflevector <4 x i32> [[BIN_RDX]], <4 x i32> undef, <4 x i32> +; FORCE_REDUCTION-NEXT: [[BIN_RDX2:%.*]] = and <4 x i32> [[BIN_RDX]], [[RDX_SHUF1]] +; FORCE_REDUCTION-NEXT: [[TMP4:%.*]] = extractelement <4 x i32> [[BIN_RDX2]], i32 0 +; FORCE_REDUCTION-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], [[VAL_20]] +; FORCE_REDUCTION-NEXT: [[TMP6:%.*]] = and i32 [[TMP5]], [[VAL_34]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA:%.*]] = and i32 [[TMP6]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA3:%.*]] = and i32 [[OP_EXTRA]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA4:%.*]] = and i32 [[OP_EXTRA3]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA5:%.*]] = and i32 [[OP_EXTRA4]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA6:%.*]] = and i32 [[OP_EXTRA5]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA7:%.*]] = and i32 [[OP_EXTRA6]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA8:%.*]] = and i32 [[OP_EXTRA7]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA9:%.*]] = and i32 [[OP_EXTRA8]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA10:%.*]] = and i32 [[OP_EXTRA9]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA11:%.*]] = and i32 [[OP_EXTRA10]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA12:%.*]] = and i32 [[OP_EXTRA11]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA13:%.*]] = and i32 [[OP_EXTRA12]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA14:%.*]] = and i32 [[OP_EXTRA13]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA15:%.*]] = and i32 [[OP_EXTRA14]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA16:%.*]] = and i32 [[OP_EXTRA15]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA17:%.*]] = and i32 [[OP_EXTRA16]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA18:%.*]] = and i32 [[OP_EXTRA17]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA19:%.*]] = and i32 [[OP_EXTRA18]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA20:%.*]] = and i32 [[OP_EXTRA19]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA21:%.*]] = and i32 [[OP_EXTRA20]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA22:%.*]] = and i32 [[OP_EXTRA21]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA23:%.*]] = and i32 [[OP_EXTRA22]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA24:%.*]] = and i32 [[OP_EXTRA23]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA25:%.*]] = and i32 [[OP_EXTRA24]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA26:%.*]] = and i32 [[OP_EXTRA25]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA27:%.*]] = and i32 [[OP_EXTRA26]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA28:%.*]] = and i32 [[OP_EXTRA27]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[OP_EXTRA29:%.*]] = and i32 [[OP_EXTRA28]], [[TMP2]] +; FORCE_REDUCTION-NEXT: [[VAL_38:%.*]] = and i32 [[VAL_37]], [[TMP0]] +; FORCE_REDUCTION-NEXT: [[VAL_39:%.*]] = add i32 [[TMP2]], 12529 +; FORCE_REDUCTION-NEXT: [[VAL_40:%.*]] = and i32 [[OP_EXTRA29]], [[VAL_39]] +; FORCE_REDUCTION-NEXT: [[VAL_41:%.*]] = add i32 [[TMP2]], 13685 +; FORCE_REDUCTION-NEXT: [[TMP7:%.*]] = insertelement <2 x i32> undef, i32 [[VAL_40]], i32 0 +; FORCE_REDUCTION-NEXT: [[TMP8:%.*]] = insertelement <2 x i32> [[TMP7]], i32 [[TMP2]], i32 1 +; FORCE_REDUCTION-NEXT: [[TMP9:%.*]] = insertelement <2 x i32> undef, i32 [[VAL_41]], i32 0 +; FORCE_REDUCTION-NEXT: [[TMP10:%.*]] = insertelement <2 x i32> [[TMP9]], i32 14910, i32 1 +; FORCE_REDUCTION-NEXT: [[TMP11:%.*]] = and <2 x i32> [[TMP8]], [[TMP10]] +; FORCE_REDUCTION-NEXT: [[TMP12:%.*]] = add <2 x i32> [[TMP8]], [[TMP10]] +; FORCE_REDUCTION-NEXT: [[TMP13]] = shufflevector <2 x i32> [[TMP11]], <2 x i32> [[TMP12]], <2 x i32> +; FORCE_REDUCTION-NEXT: br label [[LOOP]] ; entry: br label %loop diff --git a/llvm/test/Transforms/SLPVectorizer/X86/PR40310.ll b/llvm/test/Transforms/SLPVectorizer/X86/PR40310.ll index 74e62e0e4ba2d..ad1434146a5b3 100644 --- a/llvm/test/Transforms/SLPVectorizer/X86/PR40310.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/PR40310.ll @@ -7,7 +7,7 @@ define void @mainTest(i32 %param, i32 * %vals, i32 %len) { ; CHECK-NEXT: [[TMP0:%.*]] = insertelement <2 x i32> , i32 [[PARAM:%.*]], i32 1 ; CHECK-NEXT: br label [[BCI_15:%.*]] ; CHECK: bci_15: -; CHECK-NEXT: [[TMP1:%.*]] = phi <2 x i32> [ [[TMP11:%.*]], [[BCI_15]] ], [ [[TMP0]], [[BCI_15_PREHEADER:%.*]] ] +; CHECK-NEXT: [[TMP1:%.*]] = phi <2 x i32> [ [[TMP7:%.*]], [[BCI_15]] ], [ [[TMP0]], [[BCI_15_PREHEADER:%.*]] ] ; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> undef, <16 x i32> ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <16 x i32> [[SHUFFLE]], i32 0 ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <16 x i32> [[SHUFFLE]], i32 15 @@ -28,13 +28,6 @@ define void @mainTest(i32 %param, i32 * %vals, i32 %len) { ; CHECK-NEXT: [[V38:%.*]] = and i32 undef, [[V36]] ; CHECK-NEXT: [[V40:%.*]] = and i32 undef, [[V38]] ; CHECK-NEXT: [[V42:%.*]] = and i32 undef, [[V40]] -; CHECK-NEXT: [[TMP5:%.*]] = insertelement <2 x i32> undef, i32 [[TMP2]], i32 0 -; CHECK-NEXT: [[TMP6:%.*]] = extractelement <16 x i32> [[TMP4]], i32 0 -; CHECK-NEXT: [[TMP7:%.*]] = insertelement <2 x i32> [[TMP5]], i32 [[TMP6]], i32 1 -; CHECK-NEXT: [[TMP8:%.*]] = insertelement <2 x i32> , i32 [[V42]], i32 1 -; CHECK-NEXT: [[TMP9:%.*]] = add <2 x i32> [[TMP7]], [[TMP8]] -; CHECK-NEXT: [[TMP10:%.*]] = and <2 x i32> [[TMP7]], [[TMP8]] -; CHECK-NEXT: [[TMP11]] = shufflevector <2 x i32> [[TMP9]], <2 x i32> [[TMP10]], <2 x i32> ; CHECK-NEXT: [[RDX_SHUF:%.*]] = shufflevector <16 x i32> [[TMP4]], <16 x i32> undef, <16 x i32> ; CHECK-NEXT: [[BIN_RDX:%.*]] = and <16 x i32> [[TMP4]], [[RDX_SHUF]] ; CHECK-NEXT: [[RDX_SHUF1:%.*]] = shufflevector <16 x i32> [[BIN_RDX]], <16 x i32> undef, <16 x i32> @@ -43,9 +36,12 @@ define void @mainTest(i32 %param, i32 * %vals, i32 %len) { ; CHECK-NEXT: [[BIN_RDX4:%.*]] = and <16 x i32> [[BIN_RDX2]], [[RDX_SHUF3]] ; CHECK-NEXT: [[RDX_SHUF5:%.*]] = shufflevector <16 x i32> [[BIN_RDX4]], <16 x i32> undef, <16 x i32> ; CHECK-NEXT: [[BIN_RDX6:%.*]] = and <16 x i32> [[BIN_RDX4]], [[RDX_SHUF5]] -; CHECK-NEXT: [[TMP12:%.*]] = extractelement <16 x i32> [[BIN_RDX6]], i32 0 -; CHECK-NEXT: [[OP_EXTRA:%.*]] = and i32 [[TMP12]], [[TMP2]] -; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i32> [[TMP11]], i32 1 +; CHECK-NEXT: [[TMP5:%.*]] = extractelement <16 x i32> [[BIN_RDX6]], i32 0 +; CHECK-NEXT: [[OP_EXTRA:%.*]] = and i32 [[TMP5]], [[TMP2]] +; CHECK-NEXT: [[V43:%.*]] = and i32 undef, [[V42]] +; CHECK-NEXT: [[V44:%.*]] = add i32 [[TMP2]], 16 +; CHECK-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> undef, i32 [[V44]], i32 0 +; CHECK-NEXT: [[TMP7]] = insertelement <2 x i32> [[TMP6]], i32 [[OP_EXTRA]], i32 1 ; CHECK-NEXT: br i1 true, label [[BCI_15]], label [[LOOPEXIT:%.*]] ; CHECK: loopexit: ; CHECK-NEXT: ret void From ec0bc4cc340139b8787236bc18daeebaa9701ded Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 17 Jan 2019 13:31:58 +0000 Subject: [PATCH 014/274] Merging r351344: ------------------------------------------------------------------------ r351344 | asl | 2019-01-16 14:44:01 +0100 (Wed, 16 Jan 2019) | 10 lines [MSP430] Improve support of 'interrupt' attribute * Accept as an argument constants in range 0..63 (aligned with TI headers and linker scripts provided with TI GCC toolchain). * Emit function attribute 'interrupt'='xx' instead of aliases (used in the backend to create a section for particular interrupt vector). * Add more diagnostics. Patch by Kristina Bessonova! Differential Revision: https://reviews.llvm.org/D56663 ------------------------------------------------------------------------ llvm-svn: 351441 --- .../clang/Basic/DiagnosticSemaKinds.td | 4 +++ clang/lib/CodeGen/TargetInfo.cpp | 22 +++++++-------- clang/lib/Sema/SemaDeclAttr.cpp | 27 ++++++++++++++++--- clang/test/CodeGen/attr-msp430.c | 10 +++++++ clang/test/Sema/attr-msp430.c | 11 ++++++-- 5 files changed, 56 insertions(+), 18 deletions(-) create mode 100644 clang/test/CodeGen/attr-msp430.c diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5feb877e46c51..b71f65d146cab 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -274,6 +274,10 @@ def warn_riscv_interrupt_attribute : Warning< "RISC-V 'interrupt' attribute only applies to functions that have " "%select{no parameters|a 'void' return type}0">, InGroup; +def warn_msp430_interrupt_attribute : Warning< + "MSP430 'interrupt' attribute only applies to functions that have " + "%select{no parameters|a 'void' return type}0">, + InGroup; def warn_unused_parameter : Warning<"unused parameter %0">, InGroup, DefaultIgnore; def warn_unused_variable : Warning<"unused variable %0">, diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 89ec73670a735..f5a770ed9d844 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -6774,21 +6774,19 @@ void MSP430TargetCodeGenInfo::setTargetAttributes( if (GV->isDeclaration()) return; if (const FunctionDecl *FD = dyn_cast_or_null(D)) { - if (const MSP430InterruptAttr *attr = FD->getAttr()) { - // Handle 'interrupt' attribute: - llvm::Function *F = cast(GV); + const auto *InterruptAttr = FD->getAttr(); + if (!InterruptAttr) + return; - // Step 1: Set ISR calling convention. - F->setCallingConv(llvm::CallingConv::MSP430_INTR); + // Handle 'interrupt' attribute: + llvm::Function *F = cast(GV); - // Step 2: Add attributes goodness. - F->addFnAttr(llvm::Attribute::NoInline); + // Step 1: Set ISR calling convention. + F->setCallingConv(llvm::CallingConv::MSP430_INTR); - // Step 3: Emit ISR vector alias. - unsigned Num = attr->getNumber() / 2; - llvm::GlobalAlias::create(llvm::Function::ExternalLinkage, - "__isr_" + Twine(Num), F); - } + // Step 2: Add attributes goodness. + F->addFnAttr(llvm::Attribute::NoInline); + F->addFnAttr("interrupt", llvm::utostr(InterruptAttr->getNumber())); } } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 0e10804a2ec76..eb95cc748b177 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5377,6 +5377,27 @@ static void handleARMInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } static void handleMSP430InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + // MSP430 'interrupt' attribute is applied to + // a function with no parameters and void return type. + if (!isFunctionOrMethod(D)) { + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'interrupt'" << ExpectedFunctionOrMethod; + return; + } + + if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) { + S.Diag(D->getLocation(), diag::warn_msp430_interrupt_attribute) + << 0; + return; + } + + if (!getFunctionOrMethodResultType(D)->isVoidType()) { + S.Diag(D->getLocation(), diag::warn_msp430_interrupt_attribute) + << 1; + return; + } + + // The attribute takes one integer argument. if (!checkAttributeNumArgs(S, AL, 1)) return; @@ -5386,8 +5407,6 @@ static void handleMSP430InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { return; } - // FIXME: Check for decl - it should be void ()(void). - Expr *NumParamsExpr = static_cast(AL.getArgAsExpr(0)); llvm::APSInt NumParams(32); if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { @@ -5396,9 +5415,9 @@ static void handleMSP430InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { << NumParamsExpr->getSourceRange(); return; } - + // The argument should be in range 0..63. unsigned Num = NumParams.getLimitedValue(255); - if ((Num & 1) || Num > 30) { + if (Num > 63) { S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) << AL << (int)NumParams.getSExtValue() << NumParamsExpr->getSourceRange(); diff --git a/clang/test/CodeGen/attr-msp430.c b/clang/test/CodeGen/attr-msp430.c new file mode 100644 index 0000000000000..e8b6d0d0fa3ea --- /dev/null +++ b/clang/test/CodeGen/attr-msp430.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple msp430-unknown-unknown -emit-llvm < %s| FileCheck %s + +__attribute__((interrupt(1))) void foo(void) {} +// CHECK: @llvm.used +// CHECK-SAME: @foo + +// CHECK: define msp430_intrcc void @foo() #0 +// CHECK: attributes #0 +// CHECK-SAME: noinline +// CHECK-SAME: "interrupt"="1" diff --git a/clang/test/Sema/attr-msp430.c b/clang/test/Sema/attr-msp430.c index 26b2d8fcfd653..4b38d09b86757 100644 --- a/clang/test/Sema/attr-msp430.c +++ b/clang/test/Sema/attr-msp430.c @@ -1,6 +1,13 @@ // RUN: %clang_cc1 -triple msp430-unknown-unknown -fsyntax-only -verify %s +__attribute__((interrupt(1))) int t; // expected-warning {{'interrupt' attribute only applies to functions}} + int i; -void f(void) __attribute__((interrupt(i))); /* expected-error {{'interrupt' attribute requires an integer constant}} */ +__attribute__((interrupt(i))) void f(void); // expected-error {{'interrupt' attribute requires an integer constant}} +__attribute__((interrupt(1, 2))) void f2(void); // expected-error {{'interrupt' attribute takes one argument}} +__attribute__((interrupt(1))) int f3(void); // expected-warning {{MSP430 'interrupt' attribute only applies to functions that have a 'void' return type}} +__attribute__((interrupt(1))) void f4(int a); // expected-warning {{MSP430 'interrupt' attribute only applies to functions that have no parameters}} +__attribute__((interrupt(64))) void f5(void); // expected-error {{'interrupt' attribute parameter 64 is out of bounds}} -void f2(void) __attribute__((interrupt(12))); +__attribute__((interrupt(0))) void f6(void); +__attribute__((interrupt(63))) void f7(void); From edcbea9713087f92720cafba12a4a03b59833109 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 17 Jan 2019 13:34:38 +0000 Subject: [PATCH 015/274] Merging r351345: ------------------------------------------------------------------------ r351345 | asl | 2019-01-16 15:03:41 +0100 (Wed, 16 Jan 2019) | 23 lines [MSP430] Emit a separate section for every interrupt vector This is LLVM part of D56663 Linker scripts shipped by TI require to have every interrupt vector in a separate section with a specific name: SECTIONS { __interrupt_vector_XX : { KEEP (*(__interrupt_vector_XX )) } > VECTXX ... } Follow the requirement emit the section for every vector which contain address of interrupt handler: .section __interrupt_vector_XX,"ax",@progbits .word %isr% Patch by Kristina Bessonova! Differential Revision: https://reviews.llvm.org/D56664 ------------------------------------------------------------------------ llvm-svn: 351442 --- llvm/lib/Target/MSP430/MSP430AsmPrinter.cpp | 32 +++++++++++++++++++ .../CodeGen/MSP430/2009-12-21-FrameAddr.ll | 4 ++- llvm/test/CodeGen/MSP430/fp.ll | 2 ++ llvm/test/CodeGen/MSP430/interrupt.ll | 4 +++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/MSP430/MSP430AsmPrinter.cpp b/llvm/lib/Target/MSP430/MSP430AsmPrinter.cpp index f39c21fc8aa2b..5e9b108c2de3a 100644 --- a/llvm/lib/Target/MSP430/MSP430AsmPrinter.cpp +++ b/llvm/lib/Target/MSP430/MSP430AsmPrinter.cpp @@ -17,6 +17,7 @@ #include "MSP430InstrInfo.h" #include "MSP430MCInstLower.h" #include "MSP430TargetMachine.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -28,6 +29,7 @@ #include "llvm/IR/Module.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/TargetRegistry.h" @@ -44,6 +46,8 @@ namespace { StringRef getPassName() const override { return "MSP430 Assembly Printer"; } + bool runOnMachineFunction(MachineFunction &MF) override; + void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O, const char* Modifier = nullptr); void printSrcMemOperand(const MachineInstr *MI, int OpNum, @@ -55,6 +59,8 @@ namespace { unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &O) override; void EmitInstruction(const MachineInstr *MI) override; + + void EmitInterruptVectorSection(MachineFunction &ISR); }; } // end of anonymous namespace @@ -153,6 +159,32 @@ void MSP430AsmPrinter::EmitInstruction(const MachineInstr *MI) { EmitToStreamer(*OutStreamer, TmpInst); } +void MSP430AsmPrinter::EmitInterruptVectorSection(MachineFunction &ISR) { + MCSection *Cur = OutStreamer->getCurrentSectionOnly(); + const auto *F = &ISR.getFunction(); + assert(F->hasFnAttribute("interrupt") && + "Functions with MSP430_INTR CC should have 'interrupt' attribute"); + StringRef IVIdx = F->getFnAttribute("interrupt").getValueAsString(); + MCSection *IV = OutStreamer->getContext().getELFSection( + "__interrupt_vector_" + IVIdx, + ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_EXECINSTR); + OutStreamer->SwitchSection(IV); + + const MCSymbol *FunctionSymbol = getSymbol(F); + OutStreamer->EmitSymbolValue(FunctionSymbol, TM.getProgramPointerSize()); + OutStreamer->SwitchSection(Cur); +} + +bool MSP430AsmPrinter::runOnMachineFunction(MachineFunction &MF) { + // Emit separate section for an interrupt vector if ISR + if (MF.getFunction().getCallingConv() == CallingConv::MSP430_INTR) + EmitInterruptVectorSection(MF); + + SetupMachineFunction(MF); + EmitFunctionBody(); + return false; +} + // Force static initialization. extern "C" void LLVMInitializeMSP430AsmPrinter() { RegisterAsmPrinter X(getTheMSP430Target()); diff --git a/llvm/test/CodeGen/MSP430/2009-12-21-FrameAddr.ll b/llvm/test/CodeGen/MSP430/2009-12-21-FrameAddr.ll index c3d69c7c0db5e..be82e98dffe37 100644 --- a/llvm/test/CodeGen/MSP430/2009-12-21-FrameAddr.ll +++ b/llvm/test/CodeGen/MSP430/2009-12-21-FrameAddr.ll @@ -3,7 +3,7 @@ target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8" target triple = "msp430-unknown-linux-gnu" -define msp430_intrcc void @foo() nounwind { +define msp430_intrcc void @foo() nounwind #0 { entry: %fa = call i8* @llvm.frameaddress(i32 0) store i8 0, i8* %fa @@ -11,3 +11,5 @@ entry: } declare i8* @llvm.frameaddress(i32) + +attributes #0 = { noinline nounwind optnone "interrupt"="2" } diff --git a/llvm/test/CodeGen/MSP430/fp.ll b/llvm/test/CodeGen/MSP430/fp.ll index e7d7c519657ee..bf603704a91b6 100644 --- a/llvm/test/CodeGen/MSP430/fp.ll +++ b/llvm/test/CodeGen/MSP430/fp.ll @@ -27,3 +27,5 @@ define msp430_intrcc void @fpb_alloced() #0 { call void asm sideeffect "nop", "r"(i8 0) ret void } + +attributes #0 = { noinline nounwind optnone "interrupt"="2" } diff --git a/llvm/test/CodeGen/MSP430/interrupt.ll b/llvm/test/CodeGen/MSP430/interrupt.ll index 5fa0c849c2602..94fb3bc457a35 100644 --- a/llvm/test/CodeGen/MSP430/interrupt.ll +++ b/llvm/test/CodeGen/MSP430/interrupt.ll @@ -13,6 +13,9 @@ target triple = "msp430-generic-generic" ; instruction RETI, which restores the SR register and branches to the PC where ; the interrupt occurred. +; CHECK: .section __interrupt_vector_2,"ax",@progbits +; CHECK-NEXT: .short ISR + @g = global float 0.0 define msp430_intrcc void @ISR() #0 { @@ -47,3 +50,4 @@ entry: ret void } +attributes #0 = { noinline nounwind optnone "interrupt"="2" } From f308f9833371625b7d5ee4b7c0a8c6ac22c932c2 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 17 Jan 2019 13:41:26 +0000 Subject: [PATCH 016/274] Merging r351351: ------------------------------------------------------------------------ r351351 | mareko | 2019-01-16 16:43:53 +0100 (Wed, 16 Jan 2019) | 7 lines AMDGPU: Add llvm.amdgcn.ds.ordered.add & swap Reviewers: arsenm, nhaehnle Subscribers: kzhuravl, jvesely, wdng, yaxunl, dstuttard, tpr, t-tye, llvm-commits Differential Revision: https://reviews.llvm.org/D52944 ------------------------------------------------------------------------ llvm-svn: 351443 --- llvm/include/llvm/IR/IntrinsicsAMDGPU.td | 18 ++++ llvm/lib/Target/AMDGPU/AMDGPU.h | 2 +- llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 1 + llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h | 1 + .../Target/AMDGPU/AMDGPUSearchableTables.td | 2 + .../AMDGPU/AMDGPUTargetTransformInfo.cpp | 2 + llvm/lib/Target/AMDGPU/DSInstructions.td | 5 + .../lib/Target/AMDGPU/GCNHazardRecognizer.cpp | 22 ++++- llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 61 ++++++++++++ llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp | 14 ++- llvm/lib/Target/AMDGPU/SIInstrInfo.cpp | 13 ++- llvm/lib/Target/AMDGPU/SIInstrInfo.h | 2 + llvm/lib/Target/AMDGPU/SIInstrInfo.td | 5 + .../AMDGPU/llvm.amdgcn.ds.ordered.add.ll | 96 +++++++++++++++++++ .../AMDGPU/llvm.amdgcn.ds.ordered.swap.ll | 45 +++++++++ 15 files changed, 278 insertions(+), 11 deletions(-) create mode 100644 llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ds.ordered.add.ll create mode 100644 llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ds.ordered.swap.ll diff --git a/llvm/include/llvm/IR/IntrinsicsAMDGPU.td b/llvm/include/llvm/IR/IntrinsicsAMDGPU.td index 7913ce828fbc0..6585cb71769ab 100644 --- a/llvm/include/llvm/IR/IntrinsicsAMDGPU.td +++ b/llvm/include/llvm/IR/IntrinsicsAMDGPU.td @@ -392,6 +392,24 @@ class AMDGPULDSF32Intrin : [IntrArgMemOnly, NoCapture<0>] >; +class AMDGPUDSOrderedIntrinsic : Intrinsic< + [llvm_i32_ty], + // M0 = {hi16:address, lo16:waveID}. Allow passing M0 as a pointer, so that + // the bit packing can be optimized at the IR level. + [LLVMQualPointerType, // IntToPtr(M0) + llvm_i32_ty, // value to add or swap + llvm_i32_ty, // ordering + llvm_i32_ty, // scope + llvm_i1_ty, // isVolatile + llvm_i32_ty, // ordered count index (OA index), also added to the address + llvm_i1_ty, // wave release, usually set to 1 + llvm_i1_ty], // wave done, set to 1 for the last ordered instruction + [NoCapture<0>] +>; + +def int_amdgcn_ds_ordered_add : AMDGPUDSOrderedIntrinsic; +def int_amdgcn_ds_ordered_swap : AMDGPUDSOrderedIntrinsic; + def int_amdgcn_ds_fadd : AMDGPULDSF32Intrin<"__builtin_amdgcn_ds_faddf">; def int_amdgcn_ds_fmin : AMDGPULDSF32Intrin<"__builtin_amdgcn_ds_fminf">; def int_amdgcn_ds_fmax : AMDGPULDSF32Intrin<"__builtin_amdgcn_ds_fmaxf">; diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.h b/llvm/lib/Target/AMDGPU/AMDGPU.h index bb7801c172f60..55668867cc8e2 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPU.h +++ b/llvm/lib/Target/AMDGPU/AMDGPU.h @@ -254,7 +254,7 @@ namespace AMDGPUAS { FLAT_ADDRESS = 0, ///< Address space for flat memory. GLOBAL_ADDRESS = 1, ///< Address space for global memory (RAT0, VTX0). - REGION_ADDRESS = 2, ///< Address space for region memory. + REGION_ADDRESS = 2, ///< Address space for region memory. (GDS) CONSTANT_ADDRESS = 4, ///< Address space for constant memory (VTX2) LOCAL_ADDRESS = 3, ///< Address space for local memory. diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp index 6951c915b1772..8d36511a28303 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp @@ -4192,6 +4192,7 @@ const char* AMDGPUTargetLowering::getTargetNodeName(unsigned Opcode) const { NODE_NAME_CASE(TBUFFER_STORE_FORMAT_D16) NODE_NAME_CASE(TBUFFER_LOAD_FORMAT) NODE_NAME_CASE(TBUFFER_LOAD_FORMAT_D16) + NODE_NAME_CASE(DS_ORDERED_COUNT) NODE_NAME_CASE(ATOMIC_CMP_SWAP) NODE_NAME_CASE(ATOMIC_INC) NODE_NAME_CASE(ATOMIC_DEC) diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h index 0d22cb2e3e20b..d4a751d00a503 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h @@ -474,6 +474,7 @@ enum NodeType : unsigned { TBUFFER_STORE_FORMAT_D16, TBUFFER_LOAD_FORMAT, TBUFFER_LOAD_FORMAT_D16, + DS_ORDERED_COUNT, ATOMIC_CMP_SWAP, ATOMIC_INC, ATOMIC_DEC, diff --git a/llvm/lib/Target/AMDGPU/AMDGPUSearchableTables.td b/llvm/lib/Target/AMDGPU/AMDGPUSearchableTables.td index 9dbd7751b4d88..4d0962f65fdc1 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUSearchableTables.td +++ b/llvm/lib/Target/AMDGPU/AMDGPUSearchableTables.td @@ -72,6 +72,8 @@ def : SourceOfDivergence; def : SourceOfDivergence; def : SourceOfDivergence; def : SourceOfDivergence; +def : SourceOfDivergence; +def : SourceOfDivergence; foreach intr = AMDGPUImageDimAtomicIntrinsics in def : SourceOfDivergence; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp index 11e4ba4b5010d..62e7e44ddb80c 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp @@ -308,6 +308,8 @@ bool GCNTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst, switch (Inst->getIntrinsicID()) { case Intrinsic::amdgcn_atomic_inc: case Intrinsic::amdgcn_atomic_dec: + case Intrinsic::amdgcn_ds_ordered_add: + case Intrinsic::amdgcn_ds_ordered_swap: case Intrinsic::amdgcn_ds_fadd: case Intrinsic::amdgcn_ds_fmin: case Intrinsic::amdgcn_ds_fmax: { diff --git a/llvm/lib/Target/AMDGPU/DSInstructions.td b/llvm/lib/Target/AMDGPU/DSInstructions.td index 31d2ebef481d2..9c7097e9a5206 100644 --- a/llvm/lib/Target/AMDGPU/DSInstructions.td +++ b/llvm/lib/Target/AMDGPU/DSInstructions.td @@ -817,6 +817,11 @@ defm : DSAtomicRetPat_mc; defm : DSAtomicCmpXChg_mc; +def : Pat < + (SIds_ordered_count i32:$value, i16:$offset), + (DS_ORDERED_COUNT $value, (as_i16imm $offset)) +>; + //===----------------------------------------------------------------------===// // Real instructions //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp index c6396de89c4f6..69ddbfb539583 100644 --- a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp +++ b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp @@ -88,14 +88,28 @@ static bool isSMovRel(unsigned Opcode) { } } -static bool isSendMsgTraceDataOrGDS(const MachineInstr &MI) { +static bool isSendMsgTraceDataOrGDS(const SIInstrInfo &TII, + const MachineInstr &MI) { + if (TII.isAlwaysGDS(MI.getOpcode())) + return true; + switch (MI.getOpcode()) { case AMDGPU::S_SENDMSG: case AMDGPU::S_SENDMSGHALT: case AMDGPU::S_TTRACEDATA: return true; + // These DS opcodes don't support GDS. + case AMDGPU::DS_NOP: + case AMDGPU::DS_PERMUTE_B32: + case AMDGPU::DS_BPERMUTE_B32: + return false; default: - // TODO: GDS + if (TII.isDS(MI.getOpcode())) { + int GDS = AMDGPU::getNamedOperandIdx(MI.getOpcode(), + AMDGPU::OpName::gds); + if (MI.getOperand(GDS).getImm()) + return true; + } return false; } } @@ -145,7 +159,7 @@ GCNHazardRecognizer::getHazardType(SUnit *SU, int Stalls) { checkReadM0Hazards(MI) > 0) return NoopHazard; - if (ST.hasReadM0SendMsgHazard() && isSendMsgTraceDataOrGDS(*MI) && + if (ST.hasReadM0SendMsgHazard() && isSendMsgTraceDataOrGDS(TII, *MI) && checkReadM0Hazards(MI) > 0) return NoopHazard; @@ -199,7 +213,7 @@ unsigned GCNHazardRecognizer::PreEmitNoops(MachineInstr *MI) { isSMovRel(MI->getOpcode()))) return std::max(WaitStates, checkReadM0Hazards(MI)); - if (ST.hasReadM0SendMsgHazard() && isSendMsgTraceDataOrGDS(*MI)) + if (ST.hasReadM0SendMsgHazard() && isSendMsgTraceDataOrGDS(TII, *MI)) return std::max(WaitStates, checkReadM0Hazards(MI)); return WaitStates; diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index 0ba921647097d..12113fcc1fcb8 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -910,6 +910,8 @@ bool SITargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info, switch (IntrID) { case Intrinsic::amdgcn_atomic_inc: case Intrinsic::amdgcn_atomic_dec: + case Intrinsic::amdgcn_ds_ordered_add: + case Intrinsic::amdgcn_ds_ordered_swap: case Intrinsic::amdgcn_ds_fadd: case Intrinsic::amdgcn_ds_fmin: case Intrinsic::amdgcn_ds_fmax: { @@ -937,6 +939,8 @@ bool SITargetLowering::getAddrModeArguments(IntrinsicInst *II, switch (II->getIntrinsicID()) { case Intrinsic::amdgcn_atomic_inc: case Intrinsic::amdgcn_atomic_dec: + case Intrinsic::amdgcn_ds_ordered_add: + case Intrinsic::amdgcn_ds_ordered_swap: case Intrinsic::amdgcn_ds_fadd: case Intrinsic::amdgcn_ds_fmin: case Intrinsic::amdgcn_ds_fmax: { @@ -5438,6 +5442,63 @@ SDValue SITargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op, SDLoc DL(Op); switch (IntrID) { + case Intrinsic::amdgcn_ds_ordered_add: + case Intrinsic::amdgcn_ds_ordered_swap: { + MemSDNode *M = cast(Op); + SDValue Chain = M->getOperand(0); + SDValue M0 = M->getOperand(2); + SDValue Value = M->getOperand(3); + unsigned OrderedCountIndex = M->getConstantOperandVal(7); + unsigned WaveRelease = M->getConstantOperandVal(8); + unsigned WaveDone = M->getConstantOperandVal(9); + unsigned ShaderType; + unsigned Instruction; + + switch (IntrID) { + case Intrinsic::amdgcn_ds_ordered_add: + Instruction = 0; + break; + case Intrinsic::amdgcn_ds_ordered_swap: + Instruction = 1; + break; + } + + if (WaveDone && !WaveRelease) + report_fatal_error("ds_ordered_count: wave_done requires wave_release"); + + switch (DAG.getMachineFunction().getFunction().getCallingConv()) { + case CallingConv::AMDGPU_CS: + case CallingConv::AMDGPU_KERNEL: + ShaderType = 0; + break; + case CallingConv::AMDGPU_PS: + ShaderType = 1; + break; + case CallingConv::AMDGPU_VS: + ShaderType = 2; + break; + case CallingConv::AMDGPU_GS: + ShaderType = 3; + break; + default: + report_fatal_error("ds_ordered_count unsupported for this calling conv"); + } + + unsigned Offset0 = OrderedCountIndex << 2; + unsigned Offset1 = WaveRelease | (WaveDone << 1) | (ShaderType << 2) | + (Instruction << 4); + unsigned Offset = Offset0 | (Offset1 << 8); + + SDValue Ops[] = { + Chain, + Value, + DAG.getTargetConstant(Offset, DL, MVT::i16), + copyToM0(DAG, Chain, DL, M0).getValue(1), // Glue + }; + return DAG.getMemIntrinsicNode(AMDGPUISD::DS_ORDERED_COUNT, DL, + M->getVTList(), Ops, M->getMemoryVT(), + M->getMemOperand()); + } case Intrinsic::amdgcn_atomic_inc: case Intrinsic::amdgcn_atomic_dec: case Intrinsic::amdgcn_ds_fadd: diff --git a/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp b/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp index afc0b44676109..3c13bccd94fa8 100644 --- a/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp +++ b/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp @@ -536,10 +536,13 @@ void WaitcntBrackets::updateByEvent(const SIInstrInfo *TII, CurrScore); } if (Inst.mayStore()) { - setExpScore( - &Inst, TII, TRI, MRI, - AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::data0), - CurrScore); + if (AMDGPU::getNamedOperandIdx(Inst.getOpcode(), + AMDGPU::OpName::data0) != -1) { + setExpScore( + &Inst, TII, TRI, MRI, + AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::data0), + CurrScore); + } if (AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::data1) != -1) { setExpScore(&Inst, TII, TRI, MRI, @@ -1093,7 +1096,8 @@ void SIInsertWaitcnts::updateEventWaitcntAfter(MachineInstr &Inst, // bracket and the destination operand scores. // TODO: Use the (TSFlags & SIInstrFlags::LGKM_CNT) property everywhere. if (TII->isDS(Inst) && TII->usesLGKM_CNT(Inst)) { - if (TII->hasModifiersSet(Inst, AMDGPU::OpName::gds)) { + if (TII->isAlwaysGDS(Inst.getOpcode()) || + TII->hasModifiersSet(Inst, AMDGPU::OpName::gds)) { ScoreBrackets->updateByEvent(TII, TRI, MRI, GDS_ACCESS, Inst); ScoreBrackets->updateByEvent(TII, TRI, MRI, GDS_GPR_LOCK, Inst); } else { diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp index 2370d5fa7b27b..7f7f1807987ab 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -2390,6 +2390,16 @@ bool SIInstrInfo::isSchedulingBoundary(const MachineInstr &MI, changesVGPRIndexingMode(MI); } +bool SIInstrInfo::isAlwaysGDS(uint16_t Opcode) const { + return Opcode == AMDGPU::DS_ORDERED_COUNT || + Opcode == AMDGPU::DS_GWS_INIT || + Opcode == AMDGPU::DS_GWS_SEMA_V || + Opcode == AMDGPU::DS_GWS_SEMA_BR || + Opcode == AMDGPU::DS_GWS_SEMA_P || + Opcode == AMDGPU::DS_GWS_SEMA_RELEASE_ALL || + Opcode == AMDGPU::DS_GWS_BARRIER; +} + bool SIInstrInfo::hasUnwantedEffectsWhenEXECEmpty(const MachineInstr &MI) const { unsigned Opcode = MI.getOpcode(); @@ -2403,7 +2413,8 @@ bool SIInstrInfo::hasUnwantedEffectsWhenEXECEmpty(const MachineInstr &MI) const // EXEC = 0, but checking for that case here seems not worth it // given the typical code patterns. if (Opcode == AMDGPU::S_SENDMSG || Opcode == AMDGPU::S_SENDMSGHALT || - Opcode == AMDGPU::EXP || Opcode == AMDGPU::EXP_DONE) + Opcode == AMDGPU::EXP || Opcode == AMDGPU::EXP_DONE || + Opcode == AMDGPU::DS_ORDERED_COUNT) return true; if (MI.isInlineAsm()) diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.h b/llvm/lib/Target/AMDGPU/SIInstrInfo.h index 5b1a05f3785ec..8847fd6babb36 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.h +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.h @@ -450,6 +450,8 @@ class SIInstrInfo final : public AMDGPUGenInstrInfo { return get(Opcode).TSFlags & SIInstrFlags::DS; } + bool isAlwaysGDS(uint16_t Opcode) const; + static bool isMIMG(const MachineInstr &MI) { return MI.getDesc().TSFlags & SIInstrFlags::MIMG; } diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.td b/llvm/lib/Target/AMDGPU/SIInstrInfo.td index 13afa4d4974bf..180a7b0601d74 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.td +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.td @@ -45,6 +45,11 @@ def SIsbuffer_load : SDNode<"AMDGPUISD::SBUFFER_LOAD", [SDNPMayLoad, SDNPMemOperand] >; +def SIds_ordered_count : SDNode<"AMDGPUISD::DS_ORDERED_COUNT", + SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i16>]>, + [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain, SDNPInGlue] +>; + def SIatomic_inc : SDNode<"AMDGPUISD::ATOMIC_INC", SDTAtomic2, [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain] >; diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ds.ordered.add.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ds.ordered.add.ll new file mode 100644 index 0000000000000..ad489debc46cb --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ds.ordered.add.ll @@ -0,0 +1,96 @@ +; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,FUNC %s +; RUN: llc -march=amdgcn -mcpu=bonaire -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,FUNC %s +; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,VIGFX9,FUNC %s +; RUN: llc -march=amdgcn -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,VIGFX9,FUNC %s + +; FUNC-LABEL: {{^}}ds_ordered_add: +; GCN-DAG: v_mov_b32_e32 v[[INCR:[0-9]+]], 31 +; GCN-DAG: s_mov_b32 m0, +; GCN: ds_ordered_count v{{[0-9]+}}, v[[INCR]] offset:772 gds +define amdgpu_kernel void @ds_ordered_add(i32 addrspace(2)* inreg %gds, i32 addrspace(1)* %out) { + %val = call i32@llvm.amdgcn.ds.ordered.add(i32 addrspace(2)* %gds, i32 31, i32 0, i32 0, i1 false, i32 1, i1 true, i1 true) + store i32 %val, i32 addrspace(1)* %out + ret void +} + +; Below are various modifications of input operands and shader types. + +; FUNC-LABEL: {{^}}ds_ordered_add_counter2: +; GCN-DAG: v_mov_b32_e32 v[[INCR:[0-9]+]], 31 +; GCN-DAG: s_mov_b32 m0, +; GCN: ds_ordered_count v{{[0-9]+}}, v[[INCR]] offset:776 gds +define amdgpu_kernel void @ds_ordered_add_counter2(i32 addrspace(2)* inreg %gds, i32 addrspace(1)* %out) { + %val = call i32@llvm.amdgcn.ds.ordered.add(i32 addrspace(2)* %gds, i32 31, i32 0, i32 0, i1 false, i32 2, i1 true, i1 true) + store i32 %val, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}ds_ordered_add_nodone: +; GCN-DAG: v_mov_b32_e32 v[[INCR:[0-9]+]], 31 +; GCN-DAG: s_mov_b32 m0, +; GCN: ds_ordered_count v{{[0-9]+}}, v[[INCR]] offset:260 gds +define amdgpu_kernel void @ds_ordered_add_nodone(i32 addrspace(2)* inreg %gds, i32 addrspace(1)* %out) { + %val = call i32@llvm.amdgcn.ds.ordered.add(i32 addrspace(2)* %gds, i32 31, i32 0, i32 0, i1 false, i32 1, i1 true, i1 false) + store i32 %val, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}ds_ordered_add_norelease: +; GCN-DAG: v_mov_b32_e32 v[[INCR:[0-9]+]], 31 +; GCN-DAG: s_mov_b32 m0, +; GCN: ds_ordered_count v{{[0-9]+}}, v[[INCR]] offset:4 gds +define amdgpu_kernel void @ds_ordered_add_norelease(i32 addrspace(2)* inreg %gds, i32 addrspace(1)* %out) { + %val = call i32@llvm.amdgcn.ds.ordered.add(i32 addrspace(2)* %gds, i32 31, i32 0, i32 0, i1 false, i32 1, i1 false, i1 false) + store i32 %val, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}ds_ordered_add_cs: +; GCN: v_mov_b32_e32 v[[INCR:[0-9]+]], 31 +; GCN: s_mov_b32 m0, s0 +; VIGFX9-NEXT: s_nop 0 +; GCN-NEXT: ds_ordered_count v{{[0-9]+}}, v[[INCR]] offset:772 gds +; GCN-NEXT: s_waitcnt expcnt(0) lgkmcnt(0) +define amdgpu_cs float @ds_ordered_add_cs(i32 addrspace(2)* inreg %gds) { + %val = call i32@llvm.amdgcn.ds.ordered.add(i32 addrspace(2)* %gds, i32 31, i32 0, i32 0, i1 false, i32 1, i1 true, i1 true) + %r = bitcast i32 %val to float + ret float %r +} + +; FUNC-LABEL: {{^}}ds_ordered_add_ps: +; GCN: v_mov_b32_e32 v[[INCR:[0-9]+]], 31 +; GCN: s_mov_b32 m0, s0 +; VIGFX9-NEXT: s_nop 0 +; GCN-NEXT: ds_ordered_count v{{[0-9]+}}, v[[INCR]] offset:1796 gds +; GCN-NEXT: s_waitcnt expcnt(0) lgkmcnt(0) +define amdgpu_ps float @ds_ordered_add_ps(i32 addrspace(2)* inreg %gds) { + %val = call i32@llvm.amdgcn.ds.ordered.add(i32 addrspace(2)* %gds, i32 31, i32 0, i32 0, i1 false, i32 1, i1 true, i1 true) + %r = bitcast i32 %val to float + ret float %r +} + +; FUNC-LABEL: {{^}}ds_ordered_add_vs: +; GCN: v_mov_b32_e32 v[[INCR:[0-9]+]], 31 +; GCN: s_mov_b32 m0, s0 +; VIGFX9-NEXT: s_nop 0 +; GCN-NEXT: ds_ordered_count v{{[0-9]+}}, v[[INCR]] offset:2820 gds +; GCN-NEXT: s_waitcnt expcnt(0) lgkmcnt(0) +define amdgpu_vs float @ds_ordered_add_vs(i32 addrspace(2)* inreg %gds) { + %val = call i32@llvm.amdgcn.ds.ordered.add(i32 addrspace(2)* %gds, i32 31, i32 0, i32 0, i1 false, i32 1, i1 true, i1 true) + %r = bitcast i32 %val to float + ret float %r +} + +; FUNC-LABEL: {{^}}ds_ordered_add_gs: +; GCN: v_mov_b32_e32 v[[INCR:[0-9]+]], 31 +; GCN: s_mov_b32 m0, s0 +; VIGFX9-NEXT: s_nop 0 +; GCN-NEXT: ds_ordered_count v{{[0-9]+}}, v[[INCR]] offset:3844 gds +; GCN-NEXT: s_waitcnt expcnt(0) lgkmcnt(0) +define amdgpu_gs float @ds_ordered_add_gs(i32 addrspace(2)* inreg %gds) { + %val = call i32@llvm.amdgcn.ds.ordered.add(i32 addrspace(2)* %gds, i32 31, i32 0, i32 0, i1 false, i32 1, i1 true, i1 true) + %r = bitcast i32 %val to float + ret float %r +} + +declare i32 @llvm.amdgcn.ds.ordered.add(i32 addrspace(2)* nocapture, i32, i32, i32, i1, i32, i1, i1) diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ds.ordered.swap.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ds.ordered.swap.ll new file mode 100644 index 0000000000000..acb1133c6a0b8 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ds.ordered.swap.ll @@ -0,0 +1,45 @@ +; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,FUNC %s +; RUN: llc -march=amdgcn -mcpu=bonaire -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,FUNC %s +; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,VIGFX9,FUNC %s +; RUN: llc -march=amdgcn -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,VIGFX9,FUNC %s + +; FUNC-LABEL: {{^}}ds_ordered_swap: +; GCN: s_mov_b32 m0, s0 +; VIGFX9-NEXT: s_nop 0 +; GCN-NEXT: ds_ordered_count v{{[0-9]+}}, v0 offset:4868 gds +; GCN-NEXT: s_waitcnt expcnt(0) lgkmcnt(0) +define amdgpu_cs float @ds_ordered_swap(i32 addrspace(2)* inreg %gds, i32 %value) { + %val = call i32@llvm.amdgcn.ds.ordered.swap(i32 addrspace(2)* %gds, i32 %value, i32 0, i32 0, i1 false, i32 1, i1 true, i1 true) + %r = bitcast i32 %val to float + ret float %r +} + +; FUNC-LABEL: {{^}}ds_ordered_swap_conditional: +; GCN: v_cmp_ne_u32_e32 vcc, 0, v0 +; GCN: s_and_saveexec_b64 s[[SAVED:\[[0-9]+:[0-9]+\]]], vcc +; // We have to use s_cbranch, because ds_ordered_count has side effects with EXEC=0 +; GCN: s_cbranch_execz [[BB:BB._.]] +; GCN: s_mov_b32 m0, s0 +; VIGFX9-NEXT: s_nop 0 +; GCN-NEXT: ds_ordered_count v{{[0-9]+}}, v0 offset:4868 gds +; GCN-NEXT: [[BB]]: +; // Wait for expcnt(0) before modifying EXEC +; GCN-NEXT: s_waitcnt expcnt(0) +; GCN-NEXT: s_or_b64 exec, exec, s[[SAVED]] +; GCN-NEXT: s_waitcnt lgkmcnt(0) +define amdgpu_cs float @ds_ordered_swap_conditional(i32 addrspace(2)* inreg %gds, i32 %value) { +entry: + %c = icmp ne i32 %value, 0 + br i1 %c, label %if-true, label %endif + +if-true: + %val = call i32@llvm.amdgcn.ds.ordered.swap(i32 addrspace(2)* %gds, i32 %value, i32 0, i32 0, i1 false, i32 1, i1 true, i1 true) + br label %endif + +endif: + %v = phi i32 [ %val, %if-true ], [ undef, %entry ] + %r = bitcast i32 %v to float + ret float %r +} + +declare i32 @llvm.amdgcn.ds.ordered.swap(i32 addrspace(2)* nocapture, i32, i32, i32, i1, i32, i1, i1) From 6f533811b5a4398b10eb0c97cd68d98947b1c9e8 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 17 Jan 2019 13:44:39 +0000 Subject: [PATCH 017/274] Merging r351381: ------------------------------------------------------------------------ r351381 | ctopper | 2019-01-16 22:46:32 +0100 (Wed, 16 Jan 2019) | 11 lines [X86] Add X86ISD::VSHLV and X86ISD::VSRLV nodes for psllv and psrlv Previously we used ISD::SHL and ISD::SRL to represent these in SelectionDAG. ISD::SHL/SRL interpret an out of range shift amount as undefined behavior and will constant fold to undef. While the intrinsics are defined to return 0 for out of range shift amounts. A previous patch added a special node for VPSRAV to produce all sign bits. This was previously believed safe because undefs frequently get turned into 0 either from the constant pool or a desire to not have a false register dependency. But undef is treated specially in some optimizations. For example, its ignored in detection of vector splats. So if the ISD::SHL/SRL can be constant folded and all of the elements with in bounds shift amounts are the same, we might fold it to single element broadcast from the constant pool. This would not put 0s in the elements with out of bounds shift amounts. We do have an existing InstCombine optimization to use shl/lshr when the shift amounts are all constant and in bounds. That should prevent some loss of constant folding from this change. Patch by zhutianyang and Craig Topper Differential Revision: https://reviews.llvm.org/D56695 ------------------------------------------------------------------------ llvm-svn: 351444 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 2 + llvm/lib/Target/X86/X86ISelLowering.h | 6 +- llvm/lib/Target/X86/X86InstrAVX512.td | 79 ++++-- llvm/lib/Target/X86/X86InstrFragmentsSIMD.td | 2 + llvm/lib/Target/X86/X86InstrSSE.td | 30 +-- llvm/lib/Target/X86/X86IntrinsicsInfo.h | 36 +-- llvm/test/CodeGen/X86/avx2-intrinsics-x86.ll | 240 +++++++++++++----- llvm/test/CodeGen/X86/avx512-intrinsics.ll | 28 +- llvm/test/CodeGen/X86/avx512bw-intrinsics.ll | 24 +- .../test/CodeGen/X86/avx512bwvl-intrinsics.ll | 64 +++-- 10 files changed, 347 insertions(+), 164 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index b6a692ee187d8..3637562c8ec35 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -27202,6 +27202,8 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const { case X86ISD::VSHLI: return "X86ISD::VSHLI"; case X86ISD::VSRLI: return "X86ISD::VSRLI"; case X86ISD::VSRAI: return "X86ISD::VSRAI"; + case X86ISD::VSHLV: return "X86ISD::VSHLV"; + case X86ISD::VSRLV: return "X86ISD::VSRLV"; case X86ISD::VSRAV: return "X86ISD::VSRAV"; case X86ISD::VROTLI: return "X86ISD::VROTLI"; case X86ISD::VROTRI: return "X86ISD::VROTRI"; diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index 910acd80e8b8c..66d5d43946a26 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -315,10 +315,8 @@ namespace llvm { // Vector shift elements VSHL, VSRL, VSRA, - // Vector variable shift right arithmetic. - // Unlike ISD::SRA, in case shift count greater then element size - // use sign bit to fill destination data element. - VSRAV, + // Vector variable shift + VSHLV, VSRLV, VSRAV, // Vector shift elements by immediate VSHLI, VSRLI, VSRAI, diff --git a/llvm/lib/Target/X86/X86InstrAVX512.td b/llvm/lib/Target/X86/X86InstrAVX512.td index 7423cb85acd25..85676f102be0a 100644 --- a/llvm/lib/Target/X86/X86InstrAVX512.td +++ b/llvm/lib/Target/X86/X86InstrAVX512.td @@ -6445,52 +6445,53 @@ defm : avx512_var_shift_lowering; // Special handing for handling VPSRAV intrinsics. -multiclass avx512_var_shift_int_lowering p> { +multiclass avx512_var_shift_int_lowering p> { let Predicates = p in { - def : Pat<(_.VT (X86vsrav _.RC:$src1, _.RC:$src2)), + def : Pat<(_.VT (OpNode _.RC:$src1, _.RC:$src2)), (!cast(InstrStr#_.ZSuffix#rr) _.RC:$src1, _.RC:$src2)>; - def : Pat<(_.VT (X86vsrav _.RC:$src1, (_.LdFrag addr:$src2))), + def : Pat<(_.VT (OpNode _.RC:$src1, (_.LdFrag addr:$src2))), (!cast(InstrStr#_.ZSuffix##rm) _.RC:$src1, addr:$src2)>; def : Pat<(_.VT (vselect _.KRCWM:$mask, - (X86vsrav _.RC:$src1, _.RC:$src2), _.RC:$src0)), + (OpNode _.RC:$src1, _.RC:$src2), _.RC:$src0)), (!cast(InstrStr#_.ZSuffix#rrk) _.RC:$src0, _.KRC:$mask, _.RC:$src1, _.RC:$src2)>; def : Pat<(_.VT (vselect _.KRCWM:$mask, - (X86vsrav _.RC:$src1, (_.LdFrag addr:$src2)), + (OpNode _.RC:$src1, (_.LdFrag addr:$src2)), _.RC:$src0)), (!cast(InstrStr#_.ZSuffix##rmk) _.RC:$src0, _.KRC:$mask, _.RC:$src1, addr:$src2)>; def : Pat<(_.VT (vselect _.KRCWM:$mask, - (X86vsrav _.RC:$src1, _.RC:$src2), _.ImmAllZerosV)), + (OpNode _.RC:$src1, _.RC:$src2), _.ImmAllZerosV)), (!cast(InstrStr#_.ZSuffix#rrkz) _.KRC:$mask, _.RC:$src1, _.RC:$src2)>; def : Pat<(_.VT (vselect _.KRCWM:$mask, - (X86vsrav _.RC:$src1, (_.LdFrag addr:$src2)), + (OpNode _.RC:$src1, (_.LdFrag addr:$src2)), _.ImmAllZerosV)), (!cast(InstrStr#_.ZSuffix##rmkz) _.KRC:$mask, _.RC:$src1, addr:$src2)>; } } -multiclass avx512_var_shift_int_lowering_mb p> : - avx512_var_shift_int_lowering { +multiclass avx512_var_shift_int_lowering_mb p> : + avx512_var_shift_int_lowering { let Predicates = p in { - def : Pat<(_.VT (X86vsrav _.RC:$src1, + def : Pat<(_.VT (OpNode _.RC:$src1, (X86VBroadcast (_.ScalarLdFrag addr:$src2)))), (!cast(InstrStr#_.ZSuffix##rmb) _.RC:$src1, addr:$src2)>; def : Pat<(_.VT (vselect _.KRCWM:$mask, - (X86vsrav _.RC:$src1, + (OpNode _.RC:$src1, (X86VBroadcast (_.ScalarLdFrag addr:$src2))), _.RC:$src0)), (!cast(InstrStr#_.ZSuffix##rmbk) _.RC:$src0, _.KRC:$mask, _.RC:$src1, addr:$src2)>; def : Pat<(_.VT (vselect _.KRCWM:$mask, - (X86vsrav _.RC:$src1, + (OpNode _.RC:$src1, (X86VBroadcast (_.ScalarLdFrag addr:$src2))), _.ImmAllZerosV)), (!cast(InstrStr#_.ZSuffix##rmbkz) _.KRC:$mask, @@ -6498,15 +6499,47 @@ multiclass avx512_var_shift_int_lowering_mb; -defm : avx512_var_shift_int_lowering<"VPSRAVW", v16i16x_info, [HasVLX, HasBWI]>; -defm : avx512_var_shift_int_lowering<"VPSRAVW", v32i16_info, [HasBWI]>; -defm : avx512_var_shift_int_lowering_mb<"VPSRAVD", v4i32x_info, [HasVLX]>; -defm : avx512_var_shift_int_lowering_mb<"VPSRAVD", v8i32x_info, [HasVLX]>; -defm : avx512_var_shift_int_lowering_mb<"VPSRAVD", v16i32_info, [HasAVX512]>; -defm : avx512_var_shift_int_lowering_mb<"VPSRAVQ", v2i64x_info, [HasVLX]>; -defm : avx512_var_shift_int_lowering_mb<"VPSRAVQ", v4i64x_info, [HasVLX]>; -defm : avx512_var_shift_int_lowering_mb<"VPSRAVQ", v8i64_info, [HasAVX512]>; +multiclass avx512_var_shift_int_lowering_vl { + defm : avx512_var_shift_int_lowering; + defm : avx512_var_shift_int_lowering; + defm : avx512_var_shift_int_lowering; +} + +multiclass avx512_var_shift_int_lowering_mb_vl { + defm : avx512_var_shift_int_lowering_mb; + defm : avx512_var_shift_int_lowering_mb; + defm : avx512_var_shift_int_lowering_mb; +} + +defm : avx512_var_shift_int_lowering_vl<"VPSRAVW", X86vsrav, avx512vl_i16_info, + HasBWI>; +defm : avx512_var_shift_int_lowering_mb_vl<"VPSRAVD", X86vsrav, + avx512vl_i32_info, HasAVX512>; +defm : avx512_var_shift_int_lowering_mb_vl<"VPSRAVQ", X86vsrav, + avx512vl_i64_info, HasAVX512>; + +defm : avx512_var_shift_int_lowering_vl<"VPSRLVW", X86vsrlv, avx512vl_i16_info, + HasBWI>; +defm : avx512_var_shift_int_lowering_mb_vl<"VPSRLVD", X86vsrlv, + avx512vl_i32_info, HasAVX512>; +defm : avx512_var_shift_int_lowering_mb_vl<"VPSRLVQ", X86vsrlv, + avx512vl_i64_info, HasAVX512>; + +defm : avx512_var_shift_int_lowering_vl<"VPSLLVW", X86vshlv, avx512vl_i16_info, + HasBWI>; +defm : avx512_var_shift_int_lowering_mb_vl<"VPSLLVD", X86vshlv, + avx512vl_i32_info, HasAVX512>; +defm : avx512_var_shift_int_lowering_mb_vl<"VPSLLVQ", X86vshlv, + avx512vl_i64_info, HasAVX512>; + // Use 512bit VPROL/VPROLI version to implement v2i64/v4i64 + v4i32/v8i32 in case NoVLX. let Predicates = [HasAVX512, NoVLX] in { diff --git a/llvm/lib/Target/X86/X86InstrFragmentsSIMD.td b/llvm/lib/Target/X86/X86InstrFragmentsSIMD.td index 11a27ba90586b..3d508e2c34f39 100644 --- a/llvm/lib/Target/X86/X86InstrFragmentsSIMD.td +++ b/llvm/lib/Target/X86/X86InstrFragmentsSIMD.td @@ -198,6 +198,8 @@ def X86vsra : SDNode<"X86ISD::VSRA", X86vshiftuniform>; def X86vshiftvariable : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisSameAs<0,1>, SDTCisSameAs<0,2>, SDTCisInt<0>]>; +def X86vshlv : SDNode<"X86ISD::VSHLV", X86vshiftvariable>; +def X86vsrlv : SDNode<"X86ISD::VSRLV", X86vshiftvariable>; def X86vsrav : SDNode<"X86ISD::VSRAV", X86vshiftvariable>; def X86vshli : SDNode<"X86ISD::VSHLI", X86vshiftimm>; diff --git a/llvm/lib/Target/X86/X86InstrSSE.td b/llvm/lib/Target/X86/X86InstrSSE.td index e2bcd18ce6607..ddfc369b1180e 100644 --- a/llvm/lib/Target/X86/X86InstrSSE.td +++ b/llvm/lib/Target/X86/X86InstrSSE.td @@ -8318,7 +8318,7 @@ def : Pat<(v32i8 (X86SubVBroadcast (v16i8 VR128:$src))), // Variable Bit Shifts // multiclass avx2_var_shift opc, string OpcodeStr, SDNode OpNode, - ValueType vt128, ValueType vt256> { + SDNode IntrinNode, ValueType vt128, ValueType vt256> { def rr : AVX28I opc, string OpcodeStr, SDNode OpNode, (vt256 (load addr:$src2)))))]>, VEX_4V, VEX_L, Sched<[SchedWriteVarVecShift.YMM.Folded, SchedWriteVarVecShift.YMM.ReadAfterFold]>; + + def : Pat<(vt128 (IntrinNode VR128:$src1, VR128:$src2)), + (!cast(NAME#"rr") VR128:$src1, VR128:$src2)>; + def : Pat<(vt128 (IntrinNode VR128:$src1, (load addr:$src2))), + (!cast(NAME#"rm") VR128:$src1, addr:$src2)>; + def : Pat<(vt256 (IntrinNode VR256:$src1, VR256:$src2)), + (!cast(NAME#"Yrr") VR256:$src1, VR256:$src2)>; + def : Pat<(vt256 (IntrinNode VR256:$src1, (load addr:$src2))), + (!cast(NAME#"Yrm") VR256:$src1, addr:$src2)>; } let Predicates = [HasAVX2, NoVLX] in { - defm VPSLLVD : avx2_var_shift<0x47, "vpsllvd", shl, v4i32, v8i32>; - defm VPSLLVQ : avx2_var_shift<0x47, "vpsllvq", shl, v2i64, v4i64>, VEX_W; - defm VPSRLVD : avx2_var_shift<0x45, "vpsrlvd", srl, v4i32, v8i32>; - defm VPSRLVQ : avx2_var_shift<0x45, "vpsrlvq", srl, v2i64, v4i64>, VEX_W; - defm VPSRAVD : avx2_var_shift<0x46, "vpsravd", sra, v4i32, v8i32>; - - def : Pat<(v4i32 (X86vsrav VR128:$src1, VR128:$src2)), - (VPSRAVDrr VR128:$src1, VR128:$src2)>; - def : Pat<(v4i32 (X86vsrav VR128:$src1, (load addr:$src2))), - (VPSRAVDrm VR128:$src1, addr:$src2)>; - def : Pat<(v8i32 (X86vsrav VR256:$src1, VR256:$src2)), - (VPSRAVDYrr VR256:$src1, VR256:$src2)>; - def : Pat<(v8i32 (X86vsrav VR256:$src1, (load addr:$src2))), - (VPSRAVDYrm VR256:$src1, addr:$src2)>; + defm VPSLLVD : avx2_var_shift<0x47, "vpsllvd", shl, X86vshlv, v4i32, v8i32>; + defm VPSLLVQ : avx2_var_shift<0x47, "vpsllvq", shl, X86vshlv, v2i64, v4i64>, VEX_W; + defm VPSRLVD : avx2_var_shift<0x45, "vpsrlvd", srl, X86vsrlv, v4i32, v8i32>; + defm VPSRLVQ : avx2_var_shift<0x45, "vpsrlvq", srl, X86vsrlv, v2i64, v4i64>, VEX_W; + defm VPSRAVD : avx2_var_shift<0x46, "vpsravd", sra, X86vsrav, v4i32, v8i32>; } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/X86/X86IntrinsicsInfo.h b/llvm/lib/Target/X86/X86IntrinsicsInfo.h index 151e1b9136c4a..acb3d48463de6 100644 --- a/llvm/lib/Target/X86/X86IntrinsicsInfo.h +++ b/llvm/lib/Target/X86/X86IntrinsicsInfo.h @@ -389,10 +389,10 @@ static const IntrinsicData IntrinsicsWithoutChain[] = { X86_INTRINSIC_DATA(avx2_pslli_d, VSHIFT, X86ISD::VSHLI, 0), X86_INTRINSIC_DATA(avx2_pslli_q, VSHIFT, X86ISD::VSHLI, 0), X86_INTRINSIC_DATA(avx2_pslli_w, VSHIFT, X86ISD::VSHLI, 0), - X86_INTRINSIC_DATA(avx2_psllv_d, INTR_TYPE_2OP, ISD::SHL, 0), - X86_INTRINSIC_DATA(avx2_psllv_d_256, INTR_TYPE_2OP, ISD::SHL, 0), - X86_INTRINSIC_DATA(avx2_psllv_q, INTR_TYPE_2OP, ISD::SHL, 0), - X86_INTRINSIC_DATA(avx2_psllv_q_256, INTR_TYPE_2OP, ISD::SHL, 0), + X86_INTRINSIC_DATA(avx2_psllv_d, INTR_TYPE_2OP, X86ISD::VSHLV, 0), + X86_INTRINSIC_DATA(avx2_psllv_d_256, INTR_TYPE_2OP, X86ISD::VSHLV, 0), + X86_INTRINSIC_DATA(avx2_psllv_q, INTR_TYPE_2OP, X86ISD::VSHLV, 0), + X86_INTRINSIC_DATA(avx2_psllv_q_256, INTR_TYPE_2OP, X86ISD::VSHLV, 0), X86_INTRINSIC_DATA(avx2_psra_d, INTR_TYPE_2OP, X86ISD::VSRA, 0), X86_INTRINSIC_DATA(avx2_psra_w, INTR_TYPE_2OP, X86ISD::VSRA, 0), X86_INTRINSIC_DATA(avx2_psrai_d, VSHIFT, X86ISD::VSRAI, 0), @@ -405,10 +405,10 @@ static const IntrinsicData IntrinsicsWithoutChain[] = { X86_INTRINSIC_DATA(avx2_psrli_d, VSHIFT, X86ISD::VSRLI, 0), X86_INTRINSIC_DATA(avx2_psrli_q, VSHIFT, X86ISD::VSRLI, 0), X86_INTRINSIC_DATA(avx2_psrli_w, VSHIFT, X86ISD::VSRLI, 0), - X86_INTRINSIC_DATA(avx2_psrlv_d, INTR_TYPE_2OP, ISD::SRL, 0), - X86_INTRINSIC_DATA(avx2_psrlv_d_256, INTR_TYPE_2OP, ISD::SRL, 0), - X86_INTRINSIC_DATA(avx2_psrlv_q, INTR_TYPE_2OP, ISD::SRL, 0), - X86_INTRINSIC_DATA(avx2_psrlv_q_256, INTR_TYPE_2OP, ISD::SRL, 0), + X86_INTRINSIC_DATA(avx2_psrlv_d, INTR_TYPE_2OP, X86ISD::VSRLV, 0), + X86_INTRINSIC_DATA(avx2_psrlv_d_256, INTR_TYPE_2OP, X86ISD::VSRLV, 0), + X86_INTRINSIC_DATA(avx2_psrlv_q, INTR_TYPE_2OP, X86ISD::VSRLV, 0), + X86_INTRINSIC_DATA(avx2_psrlv_q_256, INTR_TYPE_2OP, X86ISD::VSRLV, 0), X86_INTRINSIC_DATA(avx512_add_pd_512, INTR_TYPE_2OP, ISD::FADD, X86ISD::FADD_RND), X86_INTRINSIC_DATA(avx512_add_ps_512, INTR_TYPE_2OP, ISD::FADD, X86ISD::FADD_RND), X86_INTRINSIC_DATA(avx512_cmp_pd_128, CMP_MASK_CC, X86ISD::CMPM, 0), @@ -943,11 +943,11 @@ static const IntrinsicData IntrinsicsWithoutChain[] = { X86_INTRINSIC_DATA(avx512_pslli_d_512, VSHIFT, X86ISD::VSHLI, 0), X86_INTRINSIC_DATA(avx512_pslli_q_512, VSHIFT, X86ISD::VSHLI, 0), X86_INTRINSIC_DATA(avx512_pslli_w_512, VSHIFT, X86ISD::VSHLI, 0), - X86_INTRINSIC_DATA(avx512_psllv_d_512, INTR_TYPE_2OP, ISD::SHL, 0), - X86_INTRINSIC_DATA(avx512_psllv_q_512, INTR_TYPE_2OP, ISD::SHL, 0), - X86_INTRINSIC_DATA(avx512_psllv_w_128, INTR_TYPE_2OP, ISD::SHL, 0), - X86_INTRINSIC_DATA(avx512_psllv_w_256, INTR_TYPE_2OP, ISD::SHL, 0), - X86_INTRINSIC_DATA(avx512_psllv_w_512, INTR_TYPE_2OP, ISD::SHL, 0), + X86_INTRINSIC_DATA(avx512_psllv_d_512, INTR_TYPE_2OP, X86ISD::VSHLV, 0), + X86_INTRINSIC_DATA(avx512_psllv_q_512, INTR_TYPE_2OP, X86ISD::VSHLV, 0), + X86_INTRINSIC_DATA(avx512_psllv_w_128, INTR_TYPE_2OP, X86ISD::VSHLV, 0), + X86_INTRINSIC_DATA(avx512_psllv_w_256, INTR_TYPE_2OP, X86ISD::VSHLV, 0), + X86_INTRINSIC_DATA(avx512_psllv_w_512, INTR_TYPE_2OP, X86ISD::VSHLV, 0), X86_INTRINSIC_DATA(avx512_psra_d_512, INTR_TYPE_2OP, X86ISD::VSRA, 0), X86_INTRINSIC_DATA(avx512_psra_q_128, INTR_TYPE_2OP, X86ISD::VSRA, 0), X86_INTRINSIC_DATA(avx512_psra_q_256, INTR_TYPE_2OP, X86ISD::VSRA, 0), @@ -971,11 +971,11 @@ static const IntrinsicData IntrinsicsWithoutChain[] = { X86_INTRINSIC_DATA(avx512_psrli_d_512, VSHIFT, X86ISD::VSRLI, 0), X86_INTRINSIC_DATA(avx512_psrli_q_512, VSHIFT, X86ISD::VSRLI, 0), X86_INTRINSIC_DATA(avx512_psrli_w_512, VSHIFT, X86ISD::VSRLI, 0), - X86_INTRINSIC_DATA(avx512_psrlv_d_512, INTR_TYPE_2OP, ISD::SRL, 0), - X86_INTRINSIC_DATA(avx512_psrlv_q_512, INTR_TYPE_2OP, ISD::SRL, 0), - X86_INTRINSIC_DATA(avx512_psrlv_w_128, INTR_TYPE_2OP, ISD::SRL, 0), - X86_INTRINSIC_DATA(avx512_psrlv_w_256, INTR_TYPE_2OP, ISD::SRL, 0), - X86_INTRINSIC_DATA(avx512_psrlv_w_512, INTR_TYPE_2OP, ISD::SRL, 0), + X86_INTRINSIC_DATA(avx512_psrlv_d_512, INTR_TYPE_2OP, X86ISD::VSRLV, 0), + X86_INTRINSIC_DATA(avx512_psrlv_q_512, INTR_TYPE_2OP, X86ISD::VSRLV, 0), + X86_INTRINSIC_DATA(avx512_psrlv_w_128, INTR_TYPE_2OP, X86ISD::VSRLV, 0), + X86_INTRINSIC_DATA(avx512_psrlv_w_256, INTR_TYPE_2OP, X86ISD::VSRLV, 0), + X86_INTRINSIC_DATA(avx512_psrlv_w_512, INTR_TYPE_2OP, X86ISD::VSRLV, 0), X86_INTRINSIC_DATA(avx512_pternlog_d_128, INTR_TYPE_4OP, X86ISD::VPTERNLOG, 0), X86_INTRINSIC_DATA(avx512_pternlog_d_256, INTR_TYPE_4OP, X86ISD::VPTERNLOG, 0), X86_INTRINSIC_DATA(avx512_pternlog_d_512, INTR_TYPE_4OP, X86ISD::VPTERNLOG, 0), diff --git a/llvm/test/CodeGen/X86/avx2-intrinsics-x86.ll b/llvm/test/CodeGen/X86/avx2-intrinsics-x86.ll index 617e198bce4c1..de20c07d41399 100644 --- a/llvm/test/CodeGen/X86/avx2-intrinsics-x86.ll +++ b/llvm/test/CodeGen/X86/avx2-intrinsics-x86.ll @@ -1183,38 +1183,58 @@ define <4 x i32> @test_x86_avx2_psllv_d(<4 x i32> %a0, <4 x i32> %a1) { define <4 x i32> @test_x86_avx2_psllv_d_const() { ; X86-AVX-LABEL: test_x86_avx2_psllv_d_const: ; X86-AVX: # %bb.0: -; X86-AVX-NEXT: vpbroadcastd {{.*#+}} xmm0 = [2,2,2,2] -; X86-AVX-NEXT: # encoding: [0xc4,0xe2,0x79,0x58,0x05,A,A,A,A] +; X86-AVX-NEXT: vmovdqa {{.*#+}} xmm0 = [2,9,0,4294967295] +; X86-AVX-NEXT: # encoding: [0xc5,0xf9,0x6f,0x05,A,A,A,A] +; X86-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX-NEXT: vpsllvd {{\.LCPI.*}}, %xmm0, %xmm0 # encoding: [0xc4,0xe2,0x79,0x47,0x05,A,A,A,A] ; X86-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 -; X86-AVX-NEXT: vpaddd {{\.LCPI.*}}, %xmm0, %xmm0 # encoding: [0xc5,0xf9,0xfe,0x05,A,A,A,A] +; X86-AVX-NEXT: vmovdqa {{.*#+}} xmm1 = [1,1,1,4294967295] +; X86-AVX-NEXT: # encoding: [0xc5,0xf9,0x6f,0x0d,A,A,A,A] ; X86-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX-NEXT: vpsllvd %xmm1, %xmm1, %xmm1 # encoding: [0xc4,0xe2,0x71,0x47,0xc9] +; X86-AVX-NEXT: vpaddd %xmm1, %xmm0, %xmm0 # encoding: [0xc5,0xf9,0xfe,0xc1] ; X86-AVX-NEXT: retl # encoding: [0xc3] ; ; X86-AVX512VL-LABEL: test_x86_avx2_psllv_d_const: ; X86-AVX512VL: # %bb.0: -; X86-AVX512VL-NEXT: vmovdqa {{\.LCPI.*}}, %xmm0 # EVEX TO VEX Compression xmm0 = <4,9,0,u> +; X86-AVX512VL-NEXT: vmovdqa {{\.LCPI.*}}, %xmm0 # EVEX TO VEX Compression xmm0 = [2,9,0,4294967295] ; X86-AVX512VL-NEXT: # encoding: [0xc5,0xf9,0x6f,0x05,A,A,A,A] ; X86-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 -; X86-AVX512VL-NEXT: vpaddd {{\.LCPI.*}}{1to4}, %xmm0, %xmm0 # encoding: [0x62,0xf1,0x7d,0x18,0xfe,0x05,A,A,A,A] -; X86-AVX512VL-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX512VL-NEXT: vpsllvd {{\.LCPI.*}}, %xmm0, %xmm0 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x79,0x47,0x05,A,A,A,A] +; X86-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX512VL-NEXT: vmovdqa {{\.LCPI.*}}, %xmm1 # EVEX TO VEX Compression xmm1 = [1,1,1,4294967295] +; X86-AVX512VL-NEXT: # encoding: [0xc5,0xf9,0x6f,0x0d,A,A,A,A] +; X86-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX512VL-NEXT: vpsllvd %xmm1, %xmm1, %xmm1 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x71,0x47,0xc9] +; X86-AVX512VL-NEXT: vpaddd %xmm1, %xmm0, %xmm0 # EVEX TO VEX Compression encoding: [0xc5,0xf9,0xfe,0xc1] ; X86-AVX512VL-NEXT: retl # encoding: [0xc3] ; ; X64-AVX-LABEL: test_x86_avx2_psllv_d_const: ; X64-AVX: # %bb.0: -; X64-AVX-NEXT: vpbroadcastd {{.*#+}} xmm0 = [2,2,2,2] -; X64-AVX-NEXT: # encoding: [0xc4,0xe2,0x79,0x58,0x05,A,A,A,A] +; X64-AVX-NEXT: vmovdqa {{.*#+}} xmm0 = [2,9,0,4294967295] +; X64-AVX-NEXT: # encoding: [0xc5,0xf9,0x6f,0x05,A,A,A,A] +; X64-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX-NEXT: vpsllvd {{.*}}(%rip), %xmm0, %xmm0 # encoding: [0xc4,0xe2,0x79,0x47,0x05,A,A,A,A] ; X64-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte -; X64-AVX-NEXT: vpaddd {{.*}}(%rip), %xmm0, %xmm0 # encoding: [0xc5,0xf9,0xfe,0x05,A,A,A,A] +; X64-AVX-NEXT: vmovdqa {{.*#+}} xmm1 = [1,1,1,4294967295] +; X64-AVX-NEXT: # encoding: [0xc5,0xf9,0x6f,0x0d,A,A,A,A] ; X64-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX-NEXT: vpsllvd %xmm1, %xmm1, %xmm1 # encoding: [0xc4,0xe2,0x71,0x47,0xc9] +; X64-AVX-NEXT: vpaddd %xmm1, %xmm0, %xmm0 # encoding: [0xc5,0xf9,0xfe,0xc1] ; X64-AVX-NEXT: retq # encoding: [0xc3] ; ; X64-AVX512VL-LABEL: test_x86_avx2_psllv_d_const: ; X64-AVX512VL: # %bb.0: -; X64-AVX512VL-NEXT: vmovdqa {{.*}}(%rip), %xmm0 # EVEX TO VEX Compression xmm0 = <4,9,0,u> +; X64-AVX512VL-NEXT: vmovdqa {{.*}}(%rip), %xmm0 # EVEX TO VEX Compression xmm0 = [2,9,0,4294967295] ; X64-AVX512VL-NEXT: # encoding: [0xc5,0xf9,0x6f,0x05,A,A,A,A] ; X64-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte -; X64-AVX512VL-NEXT: vpaddd {{.*}}(%rip){1to4}, %xmm0, %xmm0 # encoding: [0x62,0xf1,0x7d,0x18,0xfe,0x05,A,A,A,A] -; X64-AVX512VL-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vpsllvd {{.*}}(%rip), %xmm0, %xmm0 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x79,0x47,0x05,A,A,A,A] +; X64-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vmovdqa {{.*}}(%rip), %xmm1 # EVEX TO VEX Compression xmm1 = [1,1,1,4294967295] +; X64-AVX512VL-NEXT: # encoding: [0xc5,0xf9,0x6f,0x0d,A,A,A,A] +; X64-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vpsllvd %xmm1, %xmm1, %xmm1 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x71,0x47,0xc9] +; X64-AVX512VL-NEXT: vpaddd %xmm1, %xmm0, %xmm0 # EVEX TO VEX Compression encoding: [0xc5,0xf9,0xfe,0xc1] ; X64-AVX512VL-NEXT: retq # encoding: [0xc3] %res0 = call <4 x i32> @llvm.x86.avx2.psllv.d(<4 x i32> , <4 x i32> ) %res1 = call <4 x i32> @llvm.x86.avx2.psllv.d(<4 x i32> , <4 x i32> ) @@ -1241,38 +1261,62 @@ define <8 x i32> @test_x86_avx2_psllv_d_256(<8 x i32> %a0, <8 x i32> %a1) { define <8 x i32> @test_x86_avx2_psllv_d_256_const() { ; X86-AVX-LABEL: test_x86_avx2_psllv_d_256_const: ; X86-AVX: # %bb.0: -; X86-AVX-NEXT: vpbroadcastd {{.*#+}} ymm0 = [8,8,8,8,8,8,8,8] -; X86-AVX-NEXT: # encoding: [0xc4,0xe2,0x7d,0x58,0x05,A,A,A,A] +; X86-AVX-NEXT: vmovdqa {{.*#+}} ymm0 = [2,9,0,4294967295,3,7,4294967295,0] +; X86-AVX-NEXT: # encoding: [0xc5,0xfd,0x6f,0x05,A,A,A,A] +; X86-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX-NEXT: vpsllvd {{\.LCPI.*}}, %ymm0, %ymm0 # encoding: [0xc4,0xe2,0x7d,0x47,0x05,A,A,A,A] ; X86-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 -; X86-AVX-NEXT: vpaddd {{\.LCPI.*}}, %ymm0, %ymm0 # encoding: [0xc5,0xfd,0xfe,0x05,A,A,A,A] +; X86-AVX-NEXT: vmovdqa {{.*#+}} ymm1 = [4,4,4,4,4,4,4,4294967295] +; X86-AVX-NEXT: # encoding: [0xc5,0xfd,0x6f,0x0d,A,A,A,A] ; X86-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX-NEXT: vpsllvd {{\.LCPI.*}}, %ymm1, %ymm1 # encoding: [0xc4,0xe2,0x75,0x47,0x0d,A,A,A,A] +; X86-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX-NEXT: vpaddd %ymm1, %ymm0, %ymm0 # encoding: [0xc5,0xfd,0xfe,0xc1] ; X86-AVX-NEXT: retl # encoding: [0xc3] ; ; X86-AVX512VL-LABEL: test_x86_avx2_psllv_d_256_const: ; X86-AVX512VL: # %bb.0: -; X86-AVX512VL-NEXT: vmovdqa {{\.LCPI.*}}, %ymm0 # EVEX TO VEX Compression ymm0 = <4,9,0,u,12,7,u,0> +; X86-AVX512VL-NEXT: vmovdqa {{\.LCPI.*}}, %ymm0 # EVEX TO VEX Compression ymm0 = [2,9,0,4294967295,3,7,4294967295,0] ; X86-AVX512VL-NEXT: # encoding: [0xc5,0xfd,0x6f,0x05,A,A,A,A] ; X86-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 -; X86-AVX512VL-NEXT: vpaddd {{\.LCPI.*}}{1to8}, %ymm0, %ymm0 # encoding: [0x62,0xf1,0x7d,0x38,0xfe,0x05,A,A,A,A] -; X86-AVX512VL-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX512VL-NEXT: vpsllvd {{\.LCPI.*}}, %ymm0, %ymm0 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x7d,0x47,0x05,A,A,A,A] +; X86-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX512VL-NEXT: vmovdqa {{\.LCPI.*}}, %ymm1 # EVEX TO VEX Compression ymm1 = [4,4,4,4,4,4,4,4294967295] +; X86-AVX512VL-NEXT: # encoding: [0xc5,0xfd,0x6f,0x0d,A,A,A,A] +; X86-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX512VL-NEXT: vpsllvd {{\.LCPI.*}}, %ymm1, %ymm1 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x75,0x47,0x0d,A,A,A,A] +; X86-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX512VL-NEXT: vpaddd %ymm1, %ymm0, %ymm0 # EVEX TO VEX Compression encoding: [0xc5,0xfd,0xfe,0xc1] ; X86-AVX512VL-NEXT: retl # encoding: [0xc3] ; ; X64-AVX-LABEL: test_x86_avx2_psllv_d_256_const: ; X64-AVX: # %bb.0: -; X64-AVX-NEXT: vpbroadcastd {{.*#+}} ymm0 = [8,8,8,8,8,8,8,8] -; X64-AVX-NEXT: # encoding: [0xc4,0xe2,0x7d,0x58,0x05,A,A,A,A] +; X64-AVX-NEXT: vmovdqa {{.*#+}} ymm0 = [2,9,0,4294967295,3,7,4294967295,0] +; X64-AVX-NEXT: # encoding: [0xc5,0xfd,0x6f,0x05,A,A,A,A] +; X64-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX-NEXT: vpsllvd {{.*}}(%rip), %ymm0, %ymm0 # encoding: [0xc4,0xe2,0x7d,0x47,0x05,A,A,A,A] ; X64-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte -; X64-AVX-NEXT: vpaddd {{.*}}(%rip), %ymm0, %ymm0 # encoding: [0xc5,0xfd,0xfe,0x05,A,A,A,A] +; X64-AVX-NEXT: vmovdqa {{.*#+}} ymm1 = [4,4,4,4,4,4,4,4294967295] +; X64-AVX-NEXT: # encoding: [0xc5,0xfd,0x6f,0x0d,A,A,A,A] ; X64-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX-NEXT: vpsllvd {{.*}}(%rip), %ymm1, %ymm1 # encoding: [0xc4,0xe2,0x75,0x47,0x0d,A,A,A,A] +; X64-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX-NEXT: vpaddd %ymm1, %ymm0, %ymm0 # encoding: [0xc5,0xfd,0xfe,0xc1] ; X64-AVX-NEXT: retq # encoding: [0xc3] ; ; X64-AVX512VL-LABEL: test_x86_avx2_psllv_d_256_const: ; X64-AVX512VL: # %bb.0: -; X64-AVX512VL-NEXT: vmovdqa {{.*}}(%rip), %ymm0 # EVEX TO VEX Compression ymm0 = <4,9,0,u,12,7,u,0> +; X64-AVX512VL-NEXT: vmovdqa {{.*}}(%rip), %ymm0 # EVEX TO VEX Compression ymm0 = [2,9,0,4294967295,3,7,4294967295,0] ; X64-AVX512VL-NEXT: # encoding: [0xc5,0xfd,0x6f,0x05,A,A,A,A] ; X64-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte -; X64-AVX512VL-NEXT: vpaddd {{.*}}(%rip){1to8}, %ymm0, %ymm0 # encoding: [0x62,0xf1,0x7d,0x38,0xfe,0x05,A,A,A,A] -; X64-AVX512VL-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vpsllvd {{.*}}(%rip), %ymm0, %ymm0 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x7d,0x47,0x05,A,A,A,A] +; X64-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vmovdqa {{.*}}(%rip), %ymm1 # EVEX TO VEX Compression ymm1 = [4,4,4,4,4,4,4,4294967295] +; X64-AVX512VL-NEXT: # encoding: [0xc5,0xfd,0x6f,0x0d,A,A,A,A] +; X64-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vpsllvd {{.*}}(%rip), %ymm1, %ymm1 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x75,0x47,0x0d,A,A,A,A] +; X64-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vpaddd %ymm1, %ymm0, %ymm0 # EVEX TO VEX Compression encoding: [0xc5,0xfd,0xfe,0xc1] ; X64-AVX512VL-NEXT: retq # encoding: [0xc3] %res0 = call <8 x i32> @llvm.x86.avx2.psllv.d.256(<8 x i32> , <8 x i32> ) %res1 = call <8 x i32> @llvm.x86.avx2.psllv.d.256(<8 x i32> , <8 x i32> ) @@ -1316,14 +1360,20 @@ define <2 x i64> @test_x86_avx2_psllv_q_const() { ; ; X64-AVX-LABEL: test_x86_avx2_psllv_q_const: ; X64-AVX: # %bb.0: -; X64-AVX-NEXT: movl $8, %eax # encoding: [0xb8,0x08,0x00,0x00,0x00] -; X64-AVX-NEXT: vmovq %rax, %xmm0 # encoding: [0xc4,0xe1,0xf9,0x6e,0xc0] +; X64-AVX-NEXT: vmovdqa {{.*#+}} xmm0 = [4,18446744073709551615] +; X64-AVX-NEXT: # encoding: [0xc5,0xf9,0x6f,0x05,A,A,A,A] +; X64-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX-NEXT: vpsllvq {{.*}}(%rip), %xmm0, %xmm0 # encoding: [0xc4,0xe2,0xf9,0x47,0x05,A,A,A,A] +; X64-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte ; X64-AVX-NEXT: retq # encoding: [0xc3] ; ; X64-AVX512VL-LABEL: test_x86_avx2_psllv_q_const: ; X64-AVX512VL: # %bb.0: -; X64-AVX512VL-NEXT: movl $8, %eax # encoding: [0xb8,0x08,0x00,0x00,0x00] -; X64-AVX512VL-NEXT: vmovq %rax, %xmm0 # EVEX TO VEX Compression encoding: [0xc4,0xe1,0xf9,0x6e,0xc0] +; X64-AVX512VL-NEXT: vmovdqa {{.*}}(%rip), %xmm0 # EVEX TO VEX Compression xmm0 = [4,18446744073709551615] +; X64-AVX512VL-NEXT: # encoding: [0xc5,0xf9,0x6f,0x05,A,A,A,A] +; X64-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vpsllvq {{.*}}(%rip), %xmm0, %xmm0 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0xf9,0x47,0x05,A,A,A,A] +; X64-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte ; X64-AVX512VL-NEXT: retq # encoding: [0xc3] %res = call <2 x i64> @llvm.x86.avx2.psllv.q(<2 x i64> , <2 x i64> ) ret <2 x i64> %res @@ -1366,15 +1416,19 @@ define <4 x i64> @test_x86_avx2_psllv_q_256_const() { ; ; X64-AVX-LABEL: test_x86_avx2_psllv_q_256_const: ; X64-AVX: # %bb.0: -; X64-AVX-NEXT: vbroadcastsd {{.*#+}} ymm0 = [8,8,8,8] -; X64-AVX-NEXT: # encoding: [0xc4,0xe2,0x7d,0x19,0x05,A,A,A,A] +; X64-AVX-NEXT: vmovdqa {{.*#+}} ymm0 = [4,4,4,18446744073709551615] +; X64-AVX-NEXT: # encoding: [0xc5,0xfd,0x6f,0x05,A,A,A,A] +; X64-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX-NEXT: vpsllvq {{.*}}(%rip), %ymm0, %ymm0 # encoding: [0xc4,0xe2,0xfd,0x47,0x05,A,A,A,A] ; X64-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte ; X64-AVX-NEXT: retq # encoding: [0xc3] ; ; X64-AVX512VL-LABEL: test_x86_avx2_psllv_q_256_const: ; X64-AVX512VL: # %bb.0: -; X64-AVX512VL-NEXT: vbroadcastsd {{.*}}(%rip), %ymm0 # EVEX TO VEX Compression ymm0 = [8,8,8,8] -; X64-AVX512VL-NEXT: # encoding: [0xc4,0xe2,0x7d,0x19,0x05,A,A,A,A] +; X64-AVX512VL-NEXT: vmovdqa {{.*}}(%rip), %ymm0 # EVEX TO VEX Compression ymm0 = [4,4,4,18446744073709551615] +; X64-AVX512VL-NEXT: # encoding: [0xc5,0xfd,0x6f,0x05,A,A,A,A] +; X64-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vpsllvq {{.*}}(%rip), %ymm0, %ymm0 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0xfd,0x47,0x05,A,A,A,A] ; X64-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte ; X64-AVX512VL-NEXT: retq # encoding: [0xc3] %res = call <4 x i64> @llvm.x86.avx2.psllv.q.256(<4 x i64> , <4 x i64> ) @@ -1400,38 +1454,62 @@ define <4 x i32> @test_x86_avx2_psrlv_d(<4 x i32> %a0, <4 x i32> %a1) { define <4 x i32> @test_x86_avx2_psrlv_d_const() { ; X86-AVX-LABEL: test_x86_avx2_psrlv_d_const: ; X86-AVX: # %bb.0: -; X86-AVX-NEXT: vpbroadcastd {{.*#+}} xmm0 = [2,2,2,2] -; X86-AVX-NEXT: # encoding: [0xc4,0xe2,0x79,0x58,0x05,A,A,A,A] +; X86-AVX-NEXT: vmovdqa {{.*#+}} xmm0 = [2,9,0,4294967295] +; X86-AVX-NEXT: # encoding: [0xc5,0xf9,0x6f,0x05,A,A,A,A] +; X86-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX-NEXT: vpsrlvd {{\.LCPI.*}}, %xmm0, %xmm0 # encoding: [0xc4,0xe2,0x79,0x45,0x05,A,A,A,A] ; X86-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 -; X86-AVX-NEXT: vpaddd {{\.LCPI.*}}, %xmm0, %xmm0 # encoding: [0xc5,0xf9,0xfe,0x05,A,A,A,A] +; X86-AVX-NEXT: vmovdqa {{.*#+}} xmm1 = [4,4,4,4294967295] +; X86-AVX-NEXT: # encoding: [0xc5,0xf9,0x6f,0x0d,A,A,A,A] ; X86-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX-NEXT: vpsrlvd {{\.LCPI.*}}, %xmm1, %xmm1 # encoding: [0xc4,0xe2,0x71,0x45,0x0d,A,A,A,A] +; X86-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX-NEXT: vpaddd %xmm1, %xmm0, %xmm0 # encoding: [0xc5,0xf9,0xfe,0xc1] ; X86-AVX-NEXT: retl # encoding: [0xc3] ; ; X86-AVX512VL-LABEL: test_x86_avx2_psrlv_d_const: ; X86-AVX512VL: # %bb.0: -; X86-AVX512VL-NEXT: vmovdqa {{\.LCPI.*}}, %xmm0 # EVEX TO VEX Compression xmm0 = <1,9,0,u> +; X86-AVX512VL-NEXT: vmovdqa {{\.LCPI.*}}, %xmm0 # EVEX TO VEX Compression xmm0 = [2,9,0,4294967295] ; X86-AVX512VL-NEXT: # encoding: [0xc5,0xf9,0x6f,0x05,A,A,A,A] ; X86-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 -; X86-AVX512VL-NEXT: vpaddd {{\.LCPI.*}}{1to4}, %xmm0, %xmm0 # encoding: [0x62,0xf1,0x7d,0x18,0xfe,0x05,A,A,A,A] -; X86-AVX512VL-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX512VL-NEXT: vpsrlvd {{\.LCPI.*}}, %xmm0, %xmm0 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x79,0x45,0x05,A,A,A,A] +; X86-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX512VL-NEXT: vmovdqa {{\.LCPI.*}}, %xmm1 # EVEX TO VEX Compression xmm1 = [4,4,4,4294967295] +; X86-AVX512VL-NEXT: # encoding: [0xc5,0xf9,0x6f,0x0d,A,A,A,A] +; X86-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX512VL-NEXT: vpsrlvd {{\.LCPI.*}}, %xmm1, %xmm1 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x71,0x45,0x0d,A,A,A,A] +; X86-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX512VL-NEXT: vpaddd %xmm1, %xmm0, %xmm0 # EVEX TO VEX Compression encoding: [0xc5,0xf9,0xfe,0xc1] ; X86-AVX512VL-NEXT: retl # encoding: [0xc3] ; ; X64-AVX-LABEL: test_x86_avx2_psrlv_d_const: ; X64-AVX: # %bb.0: -; X64-AVX-NEXT: vpbroadcastd {{.*#+}} xmm0 = [2,2,2,2] -; X64-AVX-NEXT: # encoding: [0xc4,0xe2,0x79,0x58,0x05,A,A,A,A] +; X64-AVX-NEXT: vmovdqa {{.*#+}} xmm0 = [2,9,0,4294967295] +; X64-AVX-NEXT: # encoding: [0xc5,0xf9,0x6f,0x05,A,A,A,A] +; X64-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX-NEXT: vpsrlvd {{.*}}(%rip), %xmm0, %xmm0 # encoding: [0xc4,0xe2,0x79,0x45,0x05,A,A,A,A] ; X64-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte -; X64-AVX-NEXT: vpaddd {{.*}}(%rip), %xmm0, %xmm0 # encoding: [0xc5,0xf9,0xfe,0x05,A,A,A,A] +; X64-AVX-NEXT: vmovdqa {{.*#+}} xmm1 = [4,4,4,4294967295] +; X64-AVX-NEXT: # encoding: [0xc5,0xf9,0x6f,0x0d,A,A,A,A] ; X64-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX-NEXT: vpsrlvd {{.*}}(%rip), %xmm1, %xmm1 # encoding: [0xc4,0xe2,0x71,0x45,0x0d,A,A,A,A] +; X64-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX-NEXT: vpaddd %xmm1, %xmm0, %xmm0 # encoding: [0xc5,0xf9,0xfe,0xc1] ; X64-AVX-NEXT: retq # encoding: [0xc3] ; ; X64-AVX512VL-LABEL: test_x86_avx2_psrlv_d_const: ; X64-AVX512VL: # %bb.0: -; X64-AVX512VL-NEXT: vmovdqa {{.*}}(%rip), %xmm0 # EVEX TO VEX Compression xmm0 = <1,9,0,u> +; X64-AVX512VL-NEXT: vmovdqa {{.*}}(%rip), %xmm0 # EVEX TO VEX Compression xmm0 = [2,9,0,4294967295] ; X64-AVX512VL-NEXT: # encoding: [0xc5,0xf9,0x6f,0x05,A,A,A,A] ; X64-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte -; X64-AVX512VL-NEXT: vpaddd {{.*}}(%rip){1to4}, %xmm0, %xmm0 # encoding: [0x62,0xf1,0x7d,0x18,0xfe,0x05,A,A,A,A] -; X64-AVX512VL-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vpsrlvd {{.*}}(%rip), %xmm0, %xmm0 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x79,0x45,0x05,A,A,A,A] +; X64-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vmovdqa {{.*}}(%rip), %xmm1 # EVEX TO VEX Compression xmm1 = [4,4,4,4294967295] +; X64-AVX512VL-NEXT: # encoding: [0xc5,0xf9,0x6f,0x0d,A,A,A,A] +; X64-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vpsrlvd {{.*}}(%rip), %xmm1, %xmm1 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x71,0x45,0x0d,A,A,A,A] +; X64-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vpaddd %xmm1, %xmm0, %xmm0 # EVEX TO VEX Compression encoding: [0xc5,0xf9,0xfe,0xc1] ; X64-AVX512VL-NEXT: retq # encoding: [0xc3] %res0 = call <4 x i32> @llvm.x86.avx2.psrlv.d(<4 x i32> , <4 x i32> ) %res1 = call <4 x i32> @llvm.x86.avx2.psrlv.d(<4 x i32> , <4 x i32> ) @@ -1458,38 +1536,62 @@ define <8 x i32> @test_x86_avx2_psrlv_d_256(<8 x i32> %a0, <8 x i32> %a1) { define <8 x i32> @test_x86_avx2_psrlv_d_256_const() { ; X86-AVX-LABEL: test_x86_avx2_psrlv_d_256_const: ; X86-AVX: # %bb.0: -; X86-AVX-NEXT: vpbroadcastd {{.*#+}} ymm0 = [2,2,2,2,2,2,2,2] -; X86-AVX-NEXT: # encoding: [0xc4,0xe2,0x7d,0x58,0x05,A,A,A,A] +; X86-AVX-NEXT: vmovdqa {{.*#+}} ymm0 = [2,9,0,4294967295,3,7,4294967295,0] +; X86-AVX-NEXT: # encoding: [0xc5,0xfd,0x6f,0x05,A,A,A,A] +; X86-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX-NEXT: vpsrlvd {{\.LCPI.*}}, %ymm0, %ymm0 # encoding: [0xc4,0xe2,0x7d,0x45,0x05,A,A,A,A] ; X86-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 -; X86-AVX-NEXT: vpaddd {{\.LCPI.*}}, %ymm0, %ymm0 # encoding: [0xc5,0xfd,0xfe,0x05,A,A,A,A] +; X86-AVX-NEXT: vmovdqa {{.*#+}} ymm1 = [4,4,4,4,4,4,4,4294967295] +; X86-AVX-NEXT: # encoding: [0xc5,0xfd,0x6f,0x0d,A,A,A,A] ; X86-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX-NEXT: vpsrlvd {{\.LCPI.*}}, %ymm1, %ymm1 # encoding: [0xc4,0xe2,0x75,0x45,0x0d,A,A,A,A] +; X86-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX-NEXT: vpaddd %ymm1, %ymm0, %ymm0 # encoding: [0xc5,0xfd,0xfe,0xc1] ; X86-AVX-NEXT: retl # encoding: [0xc3] ; ; X86-AVX512VL-LABEL: test_x86_avx2_psrlv_d_256_const: ; X86-AVX512VL: # %bb.0: -; X86-AVX512VL-NEXT: vmovdqa {{\.LCPI.*}}, %ymm0 # EVEX TO VEX Compression ymm0 = <1,9,0,u,0,7,u,0> +; X86-AVX512VL-NEXT: vmovdqa {{\.LCPI.*}}, %ymm0 # EVEX TO VEX Compression ymm0 = [2,9,0,4294967295,3,7,4294967295,0] ; X86-AVX512VL-NEXT: # encoding: [0xc5,0xfd,0x6f,0x05,A,A,A,A] ; X86-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 -; X86-AVX512VL-NEXT: vpaddd {{\.LCPI.*}}{1to8}, %ymm0, %ymm0 # encoding: [0x62,0xf1,0x7d,0x38,0xfe,0x05,A,A,A,A] -; X86-AVX512VL-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX512VL-NEXT: vpsrlvd {{\.LCPI.*}}, %ymm0, %ymm0 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x7d,0x45,0x05,A,A,A,A] +; X86-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX512VL-NEXT: vmovdqa {{\.LCPI.*}}, %ymm1 # EVEX TO VEX Compression ymm1 = [4,4,4,4,4,4,4,4294967295] +; X86-AVX512VL-NEXT: # encoding: [0xc5,0xfd,0x6f,0x0d,A,A,A,A] +; X86-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX512VL-NEXT: vpsrlvd {{\.LCPI.*}}, %ymm1, %ymm1 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x75,0x45,0x0d,A,A,A,A] +; X86-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-AVX512VL-NEXT: vpaddd %ymm1, %ymm0, %ymm0 # EVEX TO VEX Compression encoding: [0xc5,0xfd,0xfe,0xc1] ; X86-AVX512VL-NEXT: retl # encoding: [0xc3] ; ; X64-AVX-LABEL: test_x86_avx2_psrlv_d_256_const: ; X64-AVX: # %bb.0: -; X64-AVX-NEXT: vpbroadcastd {{.*#+}} ymm0 = [2,2,2,2,2,2,2,2] -; X64-AVX-NEXT: # encoding: [0xc4,0xe2,0x7d,0x58,0x05,A,A,A,A] +; X64-AVX-NEXT: vmovdqa {{.*#+}} ymm0 = [2,9,0,4294967295,3,7,4294967295,0] +; X64-AVX-NEXT: # encoding: [0xc5,0xfd,0x6f,0x05,A,A,A,A] +; X64-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX-NEXT: vpsrlvd {{.*}}(%rip), %ymm0, %ymm0 # encoding: [0xc4,0xe2,0x7d,0x45,0x05,A,A,A,A] ; X64-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte -; X64-AVX-NEXT: vpaddd {{.*}}(%rip), %ymm0, %ymm0 # encoding: [0xc5,0xfd,0xfe,0x05,A,A,A,A] +; X64-AVX-NEXT: vmovdqa {{.*#+}} ymm1 = [4,4,4,4,4,4,4,4294967295] +; X64-AVX-NEXT: # encoding: [0xc5,0xfd,0x6f,0x0d,A,A,A,A] ; X64-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX-NEXT: vpsrlvd {{.*}}(%rip), %ymm1, %ymm1 # encoding: [0xc4,0xe2,0x75,0x45,0x0d,A,A,A,A] +; X64-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX-NEXT: vpaddd %ymm1, %ymm0, %ymm0 # encoding: [0xc5,0xfd,0xfe,0xc1] ; X64-AVX-NEXT: retq # encoding: [0xc3] ; ; X64-AVX512VL-LABEL: test_x86_avx2_psrlv_d_256_const: ; X64-AVX512VL: # %bb.0: -; X64-AVX512VL-NEXT: vmovdqa {{.*}}(%rip), %ymm0 # EVEX TO VEX Compression ymm0 = <1,9,0,u,0,7,u,0> +; X64-AVX512VL-NEXT: vmovdqa {{.*}}(%rip), %ymm0 # EVEX TO VEX Compression ymm0 = [2,9,0,4294967295,3,7,4294967295,0] ; X64-AVX512VL-NEXT: # encoding: [0xc5,0xfd,0x6f,0x05,A,A,A,A] ; X64-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte -; X64-AVX512VL-NEXT: vpaddd {{.*}}(%rip){1to8}, %ymm0, %ymm0 # encoding: [0x62,0xf1,0x7d,0x38,0xfe,0x05,A,A,A,A] -; X64-AVX512VL-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vpsrlvd {{.*}}(%rip), %ymm0, %ymm0 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x7d,0x45,0x05,A,A,A,A] +; X64-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vmovdqa {{.*}}(%rip), %ymm1 # EVEX TO VEX Compression ymm1 = [4,4,4,4,4,4,4,4294967295] +; X64-AVX512VL-NEXT: # encoding: [0xc5,0xfd,0x6f,0x0d,A,A,A,A] +; X64-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vpsrlvd {{.*}}(%rip), %ymm1, %ymm1 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x75,0x45,0x0d,A,A,A,A] +; X64-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vpaddd %ymm1, %ymm0, %ymm0 # EVEX TO VEX Compression encoding: [0xc5,0xfd,0xfe,0xc1] ; X64-AVX512VL-NEXT: retq # encoding: [0xc3] %res0 = call <8 x i32> @llvm.x86.avx2.psrlv.d.256(<8 x i32> , <8 x i32> ) %res1 = call <8 x i32> @llvm.x86.avx2.psrlv.d.256(<8 x i32> , <8 x i32> ) @@ -1534,14 +1636,20 @@ define <2 x i64> @test_x86_avx2_psrlv_q_const() { ; ; X64-AVX-LABEL: test_x86_avx2_psrlv_q_const: ; X64-AVX: # %bb.0: -; X64-AVX-NEXT: movl $2, %eax # encoding: [0xb8,0x02,0x00,0x00,0x00] -; X64-AVX-NEXT: vmovq %rax, %xmm0 # encoding: [0xc4,0xe1,0xf9,0x6e,0xc0] +; X64-AVX-NEXT: vmovdqa {{.*#+}} xmm0 = [4,4] +; X64-AVX-NEXT: # encoding: [0xc5,0xf9,0x6f,0x05,A,A,A,A] +; X64-AVX-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX-NEXT: vpsrlvq {{.*}}(%rip), %xmm0, %xmm0 # encoding: [0xc4,0xe2,0xf9,0x45,0x05,A,A,A,A] +; X64-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte ; X64-AVX-NEXT: retq # encoding: [0xc3] ; ; X64-AVX512VL-LABEL: test_x86_avx2_psrlv_q_const: ; X64-AVX512VL: # %bb.0: -; X64-AVX512VL-NEXT: movl $2, %eax # encoding: [0xb8,0x02,0x00,0x00,0x00] -; X64-AVX512VL-NEXT: vmovq %rax, %xmm0 # EVEX TO VEX Compression encoding: [0xc4,0xe1,0xf9,0x6e,0xc0] +; X64-AVX512VL-NEXT: vmovdqa {{.*}}(%rip), %xmm0 # EVEX TO VEX Compression xmm0 = [4,4] +; X64-AVX512VL-NEXT: # encoding: [0xc5,0xf9,0x6f,0x05,A,A,A,A] +; X64-AVX512VL-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vpsrlvq {{.*}}(%rip), %xmm0, %xmm0 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0xf9,0x45,0x05,A,A,A,A] +; X64-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte ; X64-AVX512VL-NEXT: retq # encoding: [0xc3] %res = call <2 x i64> @llvm.x86.avx2.psrlv.q(<2 x i64> , <2 x i64> ) ret <2 x i64> %res @@ -1585,15 +1693,19 @@ define <4 x i64> @test_x86_avx2_psrlv_q_256_const() { ; ; X64-AVX-LABEL: test_x86_avx2_psrlv_q_256_const: ; X64-AVX: # %bb.0: -; X64-AVX-NEXT: vbroadcastsd {{.*#+}} ymm0 = [2,2,2,2] -; X64-AVX-NEXT: # encoding: [0xc4,0xe2,0x7d,0x19,0x05,A,A,A,A] +; X64-AVX-NEXT: vpbroadcastq {{.*#+}} ymm0 = [4,4,4,4] +; X64-AVX-NEXT: # encoding: [0xc4,0xe2,0x7d,0x59,0x05,A,A,A,A] +; X64-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX-NEXT: vpsrlvq {{.*}}(%rip), %ymm0, %ymm0 # encoding: [0xc4,0xe2,0xfd,0x45,0x05,A,A,A,A] ; X64-AVX-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte ; X64-AVX-NEXT: retq # encoding: [0xc3] ; ; X64-AVX512VL-LABEL: test_x86_avx2_psrlv_q_256_const: ; X64-AVX512VL: # %bb.0: -; X64-AVX512VL-NEXT: vbroadcastsd {{.*}}(%rip), %ymm0 # EVEX TO VEX Compression ymm0 = [2,2,2,2] -; X64-AVX512VL-NEXT: # encoding: [0xc4,0xe2,0x7d,0x19,0x05,A,A,A,A] +; X64-AVX512VL-NEXT: vpbroadcastq {{.*}}(%rip), %ymm0 # EVEX TO VEX Compression ymm0 = [4,4,4,4] +; X64-AVX512VL-NEXT: # encoding: [0xc4,0xe2,0x7d,0x59,0x05,A,A,A,A] +; X64-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-AVX512VL-NEXT: vpsrlvq {{.*}}(%rip), %ymm0, %ymm0 # EVEX TO VEX Compression encoding: [0xc4,0xe2,0xfd,0x45,0x05,A,A,A,A] ; X64-AVX512VL-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte ; X64-AVX512VL-NEXT: retq # encoding: [0xc3] %res = call <4 x i64> @llvm.x86.avx2.psrlv.q.256(<4 x i64> , <4 x i64> ) diff --git a/llvm/test/CodeGen/X86/avx512-intrinsics.ll b/llvm/test/CodeGen/X86/avx512-intrinsics.ll index a0e8393309de0..6a1d9d3da9170 100644 --- a/llvm/test/CodeGen/X86/avx512-intrinsics.ll +++ b/llvm/test/CodeGen/X86/avx512-intrinsics.ll @@ -5229,8 +5229,11 @@ define <16 x i32> @test_x86_avx512_psllv_d_512(<16 x i32> %a0, <16 x i32> %a1) { define <16 x i32> @test_x86_avx512_psllv_d_512_const() { ; CHECK-LABEL: test_x86_avx512_psllv_d_512_const: ; CHECK: ## %bb.0: -; CHECK-NEXT: vmovdqa64 {{.*#+}} zmm0 = <4,9,0,u,12,7,u,0,32,5,u,0,80,3,u,0> -; CHECK-NEXT: vpaddd {{.*}}(%rip){1to16}, %zmm0, %zmm0 +; CHECK-NEXT: vmovdqa64 {{.*#+}} zmm0 = [2,9,0,4294967295,3,7,4294967295,0,4,5,4294967294,0,5,3,4294967293,0] +; CHECK-NEXT: vpsllvd {{.*}}(%rip), %zmm0, %zmm0 +; CHECK-NEXT: vmovdqa64 {{.*#+}} zmm1 = [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4294967295] +; CHECK-NEXT: vpsllvd {{.*}}(%rip), %zmm1, %zmm1 +; CHECK-NEXT: vpaddd %zmm1, %zmm0, %zmm0 ; CHECK-NEXT: retq %res0 = call <16 x i32> @llvm.x86.avx512.psllv.d.512(<16 x i32> , <16 x i32> ) %res1 = call <16 x i32> @llvm.x86.avx512.psllv.d.512(<16 x i32> , <16 x i32> ) @@ -5277,8 +5280,11 @@ define <8 x i64> @test_x86_avx512_psllv_q_512(<8 x i64> %a0, <8 x i64> %a1) { define <8 x i64> @test_x86_avx512_psllv_q_512_const() { ; CHECK-LABEL: test_x86_avx512_psllv_q_512_const: ; CHECK: ## %bb.0: -; CHECK-NEXT: vmovdqa64 {{.*#+}} zmm0 = <4,9,0,u,12,7,18446744056529682432,0> -; CHECK-NEXT: vpaddq {{.*}}(%rip){1to8}, %zmm0, %zmm0 +; CHECK-NEXT: vmovdqa64 {{.*#+}} zmm0 = [2,9,0,18446744073709551615,3,7,18446744073709551615,0] +; CHECK-NEXT: vpsllvq {{.*}}(%rip), %zmm0, %zmm0 +; CHECK-NEXT: vmovdqa64 {{.*#+}} zmm1 = [4,4,4,4,4,4,4,18446744073709551615] +; CHECK-NEXT: vpsllvq {{.*}}(%rip), %zmm1, %zmm1 +; CHECK-NEXT: vpaddq %zmm1, %zmm0, %zmm0 ; CHECK-NEXT: retq %res0 = call <8 x i64> @llvm.x86.avx512.psllv.q.512(<8 x i64> , <8 x i64> ) %res1 = call <8 x i64> @llvm.x86.avx512.psllv.q.512(<8 x i64> , <8 x i64> ) @@ -5397,8 +5403,11 @@ define <16 x i32> @test_x86_avx512_psrlv_d_512(<16 x i32> %a0, <16 x i32> %a1) { define <16 x i32> @test_x86_avx512_psrlv_d_512_const() { ; CHECK-LABEL: test_x86_avx512_psrlv_d_512_const: ; CHECK: ## %bb.0: -; CHECK-NEXT: vmovdqa64 {{.*#+}} zmm0 = <1,9,0,u,0,7,u,0,0,5,u,0,0,3,u,0> -; CHECK-NEXT: vpaddd {{.*}}(%rip){1to16}, %zmm0, %zmm0 +; CHECK-NEXT: vmovdqa64 {{.*#+}} zmm0 = [2,9,0,4294967295,3,7,4294967295,0,4,5,4294967294,0,5,3,4294967293,0] +; CHECK-NEXT: vpsrlvd {{.*}}(%rip), %zmm0, %zmm0 +; CHECK-NEXT: vmovdqa64 {{.*#+}} zmm1 = [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4294967295] +; CHECK-NEXT: vpsrlvd {{.*}}(%rip), %zmm1, %zmm1 +; CHECK-NEXT: vpaddd %zmm1, %zmm0, %zmm0 ; CHECK-NEXT: retq %res0 = call <16 x i32> @llvm.x86.avx512.psrlv.d.512(<16 x i32> , <16 x i32> ) %res1 = call <16 x i32> @llvm.x86.avx512.psrlv.d.512(<16 x i32> , <16 x i32> ) @@ -5445,8 +5454,11 @@ define <8 x i64> @test_x86_avx512_psrlv_q_512(<8 x i64> %a0, <8 x i64> %a1) { define <8 x i64> @test_x86_avx512_psrlv_q_512_const() { ; CHECK-LABEL: test_x86_avx512_psrlv_q_512_const: ; CHECK: ## %bb.0: -; CHECK-NEXT: vmovdqa64 {{.*#+}} zmm0 = <1,9,0,u,0,7,1073741823,0> -; CHECK-NEXT: vpaddq {{.*}}(%rip){1to8}, %zmm0, %zmm0 +; CHECK-NEXT: vmovdqa64 {{.*#+}} zmm0 = [2,9,0,18446744073709551615,3,7,18446744073709551615,0] +; CHECK-NEXT: vpsrlvq {{.*}}(%rip), %zmm0, %zmm0 +; CHECK-NEXT: vmovdqa64 {{.*#+}} zmm1 = [4,4,4,4,4,4,4,18446744073709551615] +; CHECK-NEXT: vpsrlvq {{.*}}(%rip), %zmm1, %zmm1 +; CHECK-NEXT: vpaddq %zmm1, %zmm0, %zmm0 ; CHECK-NEXT: retq %res0 = call <8 x i64> @llvm.x86.avx512.psrlv.q.512(<8 x i64> , <8 x i64> ) %res1 = call <8 x i64> @llvm.x86.avx512.psrlv.q.512(<8 x i64> , <8 x i64> ) diff --git a/llvm/test/CodeGen/X86/avx512bw-intrinsics.ll b/llvm/test/CodeGen/X86/avx512bw-intrinsics.ll index 8bcdc5d5c0298..a220ab0ad7349 100644 --- a/llvm/test/CodeGen/X86/avx512bw-intrinsics.ll +++ b/llvm/test/CodeGen/X86/avx512bw-intrinsics.ll @@ -1158,15 +1158,19 @@ declare <32 x i16> @llvm.x86.avx512.psrlv.w.512(<32 x i16>, <32 x i16>) nounwind define <32 x i16> @test_x86_avx512_psrlv_w_512_const() optsize { ; X86-LABEL: test_x86_avx512_psrlv_w_512_const: ; X86: # %bb.0: -; X86-NEXT: vpbroadcastw {{.*#+}} zmm0 = [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] -; X86-NEXT: # encoding: [0x62,0xf2,0x7d,0x48,0x79,0x05,A,A,A,A] +; X86-NEXT: vmovdqa64 {{.*#+}} zmm0 = [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,65535] +; X86-NEXT: # encoding: [0x62,0xf1,0xfd,0x48,0x6f,0x05,A,A,A,A] +; X86-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-NEXT: vpsrlvw {{\.LCPI.*}}, %zmm0, %zmm0 # encoding: [0x62,0xf2,0xfd,0x48,0x10,0x05,A,A,A,A] ; X86-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}, kind: FK_Data_4 ; X86-NEXT: retl # encoding: [0xc3] ; ; X64-LABEL: test_x86_avx512_psrlv_w_512_const: ; X64: # %bb.0: -; X64-NEXT: vpbroadcastw {{.*#+}} zmm0 = [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] -; X64-NEXT: # encoding: [0x62,0xf2,0x7d,0x48,0x79,0x05,A,A,A,A] +; X64-NEXT: vmovdqa64 {{.*#+}} zmm0 = [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,65535] +; X64-NEXT: # encoding: [0x62,0xf1,0xfd,0x48,0x6f,0x05,A,A,A,A] +; X64-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-NEXT: vpsrlvw {{.*}}(%rip), %zmm0, %zmm0 # encoding: [0x62,0xf2,0xfd,0x48,0x10,0x05,A,A,A,A] ; X64-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte ; X64-NEXT: retq # encoding: [0xc3] %res1 = call <32 x i16> @llvm.x86.avx512.psrlv.w.512(<32 x i16> , <32 x i16> ) @@ -1377,15 +1381,19 @@ declare <32 x i16> @llvm.x86.avx512.psll.w.512(<32 x i16>, <8 x i16>) nounwind r define <32 x i16> @test_x86_avx512_psllv_w_512_const() optsize { ; X86-LABEL: test_x86_avx512_psllv_w_512_const: ; X86: # %bb.0: -; X86-NEXT: vpbroadcastw {{.*#+}} zmm0 = [8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8] -; X86-NEXT: # encoding: [0x62,0xf2,0x7d,0x48,0x79,0x05,A,A,A,A] +; X86-NEXT: vmovdqa64 {{.*#+}} zmm0 = [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,65535] +; X86-NEXT: # encoding: [0x62,0xf1,0xfd,0x48,0x6f,0x05,A,A,A,A] +; X86-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-NEXT: vpsllvw {{\.LCPI.*}}, %zmm0, %zmm0 # encoding: [0x62,0xf2,0xfd,0x48,0x12,0x05,A,A,A,A] ; X86-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}, kind: FK_Data_4 ; X86-NEXT: retl # encoding: [0xc3] ; ; X64-LABEL: test_x86_avx512_psllv_w_512_const: ; X64: # %bb.0: -; X64-NEXT: vpbroadcastw {{.*#+}} zmm0 = [8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8] -; X64-NEXT: # encoding: [0x62,0xf2,0x7d,0x48,0x79,0x05,A,A,A,A] +; X64-NEXT: vmovdqa64 {{.*#+}} zmm0 = [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,65535] +; X64-NEXT: # encoding: [0x62,0xf1,0xfd,0x48,0x6f,0x05,A,A,A,A] +; X64-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-NEXT: vpsllvw {{.*}}(%rip), %zmm0, %zmm0 # encoding: [0x62,0xf2,0xfd,0x48,0x12,0x05,A,A,A,A] ; X64-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte ; X64-NEXT: retq # encoding: [0xc3] %res1 = call <32 x i16> @llvm.x86.avx512.psllv.w.512(<32 x i16> , <32 x i16> ) diff --git a/llvm/test/CodeGen/X86/avx512bwvl-intrinsics.ll b/llvm/test/CodeGen/X86/avx512bwvl-intrinsics.ll index 10ba0e646055f..a01252f7d494b 100644 --- a/llvm/test/CodeGen/X86/avx512bwvl-intrinsics.ll +++ b/llvm/test/CodeGen/X86/avx512bwvl-intrinsics.ll @@ -2021,16 +2021,20 @@ define <8 x i16>@test_int_x86_avx512_mask_psrlv8_hi(<8 x i16> %x0, <8 x i16> %x1 define <8 x i16> @test_int_x86_avx512_psrlv_w_128_const() optsize { ; X86-LABEL: test_int_x86_avx512_psrlv_w_128_const: ; X86: # %bb.0: -; X86-NEXT: vpbroadcastw {{\.LCPI.*}}, %xmm0 # EVEX TO VEX Compression xmm0 = [2,2,2,2,2,2,2,2] -; X86-NEXT: # encoding: [0xc4,0xe2,0x79,0x79,0x05,A,A,A,A] -; X86-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-NEXT: vmovdqa {{\.LCPI.*}}, %xmm0 # EVEX TO VEX Compression xmm0 = [4,4,4,4,4,4,4,65535] +; X86-NEXT: # encoding: [0xc5,0xf9,0x6f,0x05,A,A,A,A] +; X86-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-NEXT: vpsrlvw {{\.LCPI.*}}, %xmm0, %xmm0 # encoding: [0x62,0xf2,0xfd,0x08,0x10,0x05,A,A,A,A] +; X86-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}, kind: FK_Data_4 ; X86-NEXT: retl # encoding: [0xc3] ; ; X64-LABEL: test_int_x86_avx512_psrlv_w_128_const: ; X64: # %bb.0: -; X64-NEXT: vpbroadcastw {{.*}}(%rip), %xmm0 # EVEX TO VEX Compression xmm0 = [2,2,2,2,2,2,2,2] -; X64-NEXT: # encoding: [0xc4,0xe2,0x79,0x79,0x05,A,A,A,A] -; X64-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-NEXT: vmovdqa {{.*}}(%rip), %xmm0 # EVEX TO VEX Compression xmm0 = [4,4,4,4,4,4,4,65535] +; X64-NEXT: # encoding: [0xc5,0xf9,0x6f,0x05,A,A,A,A] +; X64-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-NEXT: vpsrlvw {{.*}}(%rip), %xmm0, %xmm0 # encoding: [0x62,0xf2,0xfd,0x08,0x10,0x05,A,A,A,A] +; X64-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte ; X64-NEXT: retq # encoding: [0xc3] %res = call <8 x i16> @llvm.x86.avx512.psrlv.w.128(<8 x i16> , <8 x i16> ) ret <8 x i16> %res @@ -2041,16 +2045,20 @@ declare <8 x i16> @llvm.x86.avx512.psrlv.w.128(<8 x i16>, <8 x i16>) define <16 x i16> @test_int_x86_avx512_psrlv_w_256_const() optsize { ; X86-LABEL: test_int_x86_avx512_psrlv_w_256_const: ; X86: # %bb.0: -; X86-NEXT: vpbroadcastw {{\.LCPI.*}}, %ymm0 # EVEX TO VEX Compression ymm0 = [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] -; X86-NEXT: # encoding: [0xc4,0xe2,0x7d,0x79,0x05,A,A,A,A] -; X86-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-NEXT: vmovdqa {{\.LCPI.*}}, %ymm0 # EVEX TO VEX Compression ymm0 = [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,65535] +; X86-NEXT: # encoding: [0xc5,0xfd,0x6f,0x05,A,A,A,A] +; X86-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-NEXT: vpsrlvw {{\.LCPI.*}}, %ymm0, %ymm0 # encoding: [0x62,0xf2,0xfd,0x28,0x10,0x05,A,A,A,A] +; X86-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}, kind: FK_Data_4 ; X86-NEXT: retl # encoding: [0xc3] ; ; X64-LABEL: test_int_x86_avx512_psrlv_w_256_const: ; X64: # %bb.0: -; X64-NEXT: vpbroadcastw {{.*}}(%rip), %ymm0 # EVEX TO VEX Compression ymm0 = [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] -; X64-NEXT: # encoding: [0xc4,0xe2,0x7d,0x79,0x05,A,A,A,A] -; X64-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-NEXT: vmovdqa {{.*}}(%rip), %ymm0 # EVEX TO VEX Compression ymm0 = [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,65535] +; X64-NEXT: # encoding: [0xc5,0xfd,0x6f,0x05,A,A,A,A] +; X64-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-NEXT: vpsrlvw {{.*}}(%rip), %ymm0, %ymm0 # encoding: [0x62,0xf2,0xfd,0x28,0x10,0x05,A,A,A,A] +; X64-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte ; X64-NEXT: retq # encoding: [0xc3] %res = call <16 x i16> @llvm.x86.avx512.psrlv.w.256(<16 x i16> , <16 x i16> ) ret <16 x i16> %res @@ -2195,16 +2203,20 @@ define <8 x i16>@test_int_x86_avx512_mask_psllv8_hi(<8 x i16> %x0, <8 x i16> %x1 define <8 x i16> @test_int_x86_avx512_psllv_w_128_const() optsize { ; X86-LABEL: test_int_x86_avx512_psllv_w_128_const: ; X86: # %bb.0: -; X86-NEXT: vpbroadcastw {{\.LCPI.*}}, %xmm0 # EVEX TO VEX Compression xmm0 = [8,8,8,8,8,8,8,8] -; X86-NEXT: # encoding: [0xc4,0xe2,0x79,0x79,0x05,A,A,A,A] -; X86-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-NEXT: vmovdqa {{\.LCPI.*}}, %xmm0 # EVEX TO VEX Compression xmm0 = [4,4,4,4,4,4,4,65535] +; X86-NEXT: # encoding: [0xc5,0xf9,0x6f,0x05,A,A,A,A] +; X86-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-NEXT: vpsllvw {{\.LCPI.*}}, %xmm0, %xmm0 # encoding: [0x62,0xf2,0xfd,0x08,0x12,0x05,A,A,A,A] +; X86-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}, kind: FK_Data_4 ; X86-NEXT: retl # encoding: [0xc3] ; ; X64-LABEL: test_int_x86_avx512_psllv_w_128_const: ; X64: # %bb.0: -; X64-NEXT: vpbroadcastw {{.*}}(%rip), %xmm0 # EVEX TO VEX Compression xmm0 = [8,8,8,8,8,8,8,8] -; X64-NEXT: # encoding: [0xc4,0xe2,0x79,0x79,0x05,A,A,A,A] -; X64-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-NEXT: vmovdqa {{.*}}(%rip), %xmm0 # EVEX TO VEX Compression xmm0 = [4,4,4,4,4,4,4,65535] +; X64-NEXT: # encoding: [0xc5,0xf9,0x6f,0x05,A,A,A,A] +; X64-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-NEXT: vpsllvw {{.*}}(%rip), %xmm0, %xmm0 # encoding: [0x62,0xf2,0xfd,0x08,0x12,0x05,A,A,A,A] +; X64-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte ; X64-NEXT: retq # encoding: [0xc3] %res = call <8 x i16> @llvm.x86.avx512.psllv.w.128(<8 x i16> , <8 x i16> ) ret <8 x i16> %res @@ -2216,16 +2228,20 @@ declare <8 x i16> @llvm.x86.avx512.psllv.w.128(<8 x i16>, <8 x i16>) define <16 x i16> @test_int_x86_avx512_psllv_w_256_const() optsize { ; X86-LABEL: test_int_x86_avx512_psllv_w_256_const: ; X86: # %bb.0: -; X86-NEXT: vpbroadcastw {{\.LCPI.*}}, %ymm0 # EVEX TO VEX Compression ymm0 = [8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8] -; X86-NEXT: # encoding: [0xc4,0xe2,0x7d,0x79,0x05,A,A,A,A] -; X86-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-NEXT: vmovdqa {{\.LCPI.*}}, %ymm0 # EVEX TO VEX Compression ymm0 = [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,65535] +; X86-NEXT: # encoding: [0xc5,0xfd,0x6f,0x05,A,A,A,A] +; X86-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}, kind: FK_Data_4 +; X86-NEXT: vpsllvw {{\.LCPI.*}}, %ymm0, %ymm0 # encoding: [0x62,0xf2,0xfd,0x28,0x12,0x05,A,A,A,A] +; X86-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}, kind: FK_Data_4 ; X86-NEXT: retl # encoding: [0xc3] ; ; X64-LABEL: test_int_x86_avx512_psllv_w_256_const: ; X64: # %bb.0: -; X64-NEXT: vpbroadcastw {{.*}}(%rip), %ymm0 # EVEX TO VEX Compression ymm0 = [8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8] -; X64-NEXT: # encoding: [0xc4,0xe2,0x7d,0x79,0x05,A,A,A,A] -; X64-NEXT: # fixup A - offset: 5, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-NEXT: vmovdqa {{.*}}(%rip), %ymm0 # EVEX TO VEX Compression ymm0 = [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,65535] +; X64-NEXT: # encoding: [0xc5,0xfd,0x6f,0x05,A,A,A,A] +; X64-NEXT: # fixup A - offset: 4, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte +; X64-NEXT: vpsllvw {{.*}}(%rip), %ymm0, %ymm0 # encoding: [0x62,0xf2,0xfd,0x28,0x12,0x05,A,A,A,A] +; X64-NEXT: # fixup A - offset: 6, value: {{\.LCPI.*}}-4, kind: reloc_riprel_4byte ; X64-NEXT: retq # encoding: [0xc3] %res = call <16 x i16> @llvm.x86.avx512.psllv.w.256(<16 x i16> , <16 x i16> ) ret <16 x i16> %res From 37174c6e21dd381fab31e33877865648c8d4088f Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 17 Jan 2019 13:46:36 +0000 Subject: [PATCH 018/274] Merging r351326: ------------------------------------------------------------------------ r351326 | psmith | 2019-01-16 13:09:13 +0100 (Wed, 16 Jan 2019) | 15 lines [ELF] Implement option to force PIC compatible Thunks By default LLD will generate position independent Thunks when the --pie or --shared option is used. Reference to absolute addresses is permitted in other cases. For some embedded systems position independent thunks are needed for code that executes before the MMU has been set up. The option --pic-veneer is used by ld.bfd to force position independent thunks. The patch adds --pic-veneer as the option is needed for the Linux kernel on Arm. fixes pr39886 Differential Revision: https://reviews.llvm.org/D55505 ------------------------------------------------------------------------ llvm-svn: 351445 --- lld/ELF/Config.h | 1 + lld/ELF/Driver.cpp | 1 + lld/ELF/Options.td | 3 ++ lld/ELF/Thunks.cpp | 10 ++-- lld/docs/ld.lld.1 | 2 + lld/test/ELF/arm-force-pi-thunk.s | 87 +++++++++++++++++++++++++++++++ 6 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 lld/test/ELF/arm-force-pi-thunk.s diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 8fb760e592eb1..60555f188fed3 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -159,6 +159,7 @@ struct Configuration { bool OFormatBinary; bool Omagic; bool OptRemarksWithHotness; + bool PicThunk; bool Pie; bool PrintGcSections; bool PrintIcfSections; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 13b6119e2dc91..2e2036310fb21 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1006,6 +1006,7 @@ static void setConfigs(opt::InputArgList &Args) { Config->Endianness = Config->IsLE ? endianness::little : endianness::big; Config->IsMips64EL = (K == ELF64LEKind && M == EM_MIPS); Config->Pic = Config->Pie || Config->Shared; + Config->PicThunk = Args.hasArg(OPT_pic_veneer, Config->Pic); Config->Wordsize = Config->Is64 ? 8 : 4; // ELF defines two different ways to store relocation addends as shown below: diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index e43a21b923d33..bc203193661b4 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -255,6 +255,9 @@ defm use_android_relr_tags: B<"use-android-relr-tags", "Use SHT_ANDROID_RELR / DT_ANDROID_RELR* tags instead of SHT_RELR / DT_RELR*", "Use SHT_RELR / DT_RELR* tags (default)">; +def pic_veneer: F<"pic-veneer">, + HelpText<"Always generate position independent thunks (veneers)">; + defm pie: B<"pie", "Create a position independent executable", "Do not create a position independent executable (default)">; diff --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp index 95b57dc0db426..7a31d36b0e902 100644 --- a/lld/ELF/Thunks.cpp +++ b/lld/ELF/Thunks.cpp @@ -722,7 +722,7 @@ Thunk::~Thunk() = default; static Thunk *addThunkAArch64(RelType Type, Symbol &S) { if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26) fatal("unrecognized relocation type"); - if (Config->Pic) + if (Config->PicThunk) return make(S); return make(S); } @@ -739,7 +739,7 @@ static Thunk *addThunkPreArmv7(RelType Reloc, Symbol &S) { case R_ARM_JUMP24: case R_ARM_CALL: case R_ARM_THM_CALL: - if (Config->Pic) + if (Config->PicThunk) return make(S); return make(S); } @@ -794,13 +794,13 @@ static Thunk *addThunkArm(RelType Reloc, Symbol &S) { case R_ARM_PLT32: case R_ARM_JUMP24: case R_ARM_CALL: - if (Config->Pic) + if (Config->PicThunk) return make(S); return make(S); case R_ARM_THM_JUMP19: case R_ARM_THM_JUMP24: case R_ARM_THM_CALL: - if (Config->Pic) + if (Config->PicThunk) return make(S); return make(S); } @@ -820,7 +820,7 @@ static Thunk *addThunkPPC64(RelType Type, Symbol &S) { if (S.isInPlt()) return make(S); - if (Config->Pic) + if (Config->PicThunk) return make(S); return make(S); diff --git a/lld/docs/ld.lld.1 b/lld/docs/ld.lld.1 index d1ce4a3517f4d..889d5feabe4d1 100644 --- a/lld/docs/ld.lld.1 +++ b/lld/docs/ld.lld.1 @@ -311,6 +311,8 @@ Write optimization remarks in YAML format to .Ar file . .It Fl -opt-remarks-with-hotness Include hotness information in the optimization remarks file. +.It Fl -pic-veneer +Always generate position independent thunks. .It Fl -pie Create a position independent executable. .It Fl -print-gc-sections diff --git a/lld/test/ELF/arm-force-pi-thunk.s b/lld/test/ELF/arm-force-pi-thunk.s new file mode 100644 index 0000000000000..2c88de0424ee5 --- /dev/null +++ b/lld/test/ELF/arm-force-pi-thunk.s @@ -0,0 +1,87 @@ +// REQUIRES: arm +// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t +// RUN: echo "SECTIONS { \ +// RUN: . = SIZEOF_HEADERS; \ +// RUN: .text_low : { *(.text_low) *(.text_low2) } \ +// RUN: .text_high 0x2000000 : { *(.text_high) *(.text_high2) } \ +// RUN: } " > %t.script +// RUN: ld.lld --pic-veneer --script %t.script %t -o %t2 2>&1 +// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s + +// Test that we can force generation of position independent thunks even when +// inputs are not pic. + + .syntax unified + .section .text_low, "ax", %progbits + .thumb + .globl _start +_start: bx lr + .globl low_target + .type low_target, %function +low_target: + bl high_target + bl high_target2 + + .section .text_low2, "ax", %progbits + .thumb + .globl low_target2 + .type low_target2, %function +low_target2: + bl high_target + bl high_target2 + +// CHECK: Disassembly of section .text_low: +// CHECK-NEXT: _start: +// CHECK-NEXT: 94: 70 47 bx lr +// CHECK: low_target: +// CHECK-NEXT: 96: 00 f0 03 f8 bl #6 +// CHECK-NEXT: 9a: 00 f0 07 f8 bl #14 +// CHECK-NEXT: 9e: d4 d4 bmi #-88 +// CHECK: __ThumbV7PILongThunk_high_target: +// CHECK-NEXT: a0: 4f f6 55 7c movw r12, #65365 +// CHECK-NEXT: a4: c0 f2 ff 1c movt r12, #511 +// CHECK-NEXT: a8: fc 44 add r12, pc +// CHECK-NEXT: aa: 60 47 bx r12 +// CHECK: __ThumbV7PILongThunk_high_target2: +// CHECK-NEXT: ac: 4f f6 69 7c movw r12, #65385 +// CHECK-NEXT: b0: c0 f2 ff 1c movt r12, #511 +// CHECK-NEXT: b4: fc 44 add r12, pc +// CHECK-NEXT: b6: 60 47 bx r12 +// CHECK: low_target2: +// CHECK-NEXT: b8: ff f7 f2 ff bl #-28 +// CHECK-NEXT: bc: ff f7 f6 ff bl #-20 + + + .section .text_high, "ax", %progbits + .thumb + .globl high_target + .type high_target, %function +high_target: + bl low_target + bl low_target2 + + .section .text_high2, "ax", %progbits + .thumb + .globl high_target2 + .type high_target2, %function +high_target2: + bl low_target + bl low_target2 + +// CHECK: Disassembly of section .text_high: +// CHECK-NEXT: high_target: +// CHECK-NEXT: 2000000: 00 f0 02 f8 bl #4 +// CHECK-NEXT: 2000004: 00 f0 06 f8 bl #12 +// CHECK: __ThumbV7PILongThunk_low_target: +// CHECK-NEXT: 2000008: 40 f2 83 0c movw r12, #131 +// CHECK-NEXT: 200000c: cf f6 00 6c movt r12, #65024 +// CHECK-NEXT: 2000010: fc 44 add r12, pc +// CHECK-NEXT: 2000012: 60 47 bx r12 +// CHECK: __ThumbV7PILongThunk_low_target2: +// CHECK-NEXT: 2000014: 40 f2 99 0c movw r12, #153 +// CHECK-NEXT: 2000018: cf f6 00 6c movt r12, #65024 +// CHECK-NEXT: 200001c: fc 44 add r12, pc +// CHECK-NEXT: 200001e: 60 47 bx r12 +// CHECK: high_target2: +// CHECK-NEXT: 2000020: ff f7 f2 ff bl #-28 +// CHECK-NEXT: 2000024: ff f7 f6 ff bl #-20 From 961b84b221558e07a055c38fa12f66ab45e577a5 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 17 Jan 2019 13:47:57 +0000 Subject: [PATCH 019/274] Merging r351335: ------------------------------------------------------------------------ r351335 | psmith | 2019-01-16 14:24:02 +0100 (Wed, 16 Jan 2019) | 17 lines [ELF][AArch64] Add R_AARCH64_PLT_PAGE_PC to isRelExpr As a follow on to D56666 (r351186) there is a case when taking the address of an ifunc when linking -pie that can generate a spurious can't create dynamic relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol in readonly segment. Specifically the case is where the ifunc is in the same translation unit as the address taker, so given -fpie the compiler knows the ifunc is defined in the executable so it can use a non-got-generating relocation. The error message is due to R_AARCH64_PLT_PAGE_PC not being added to isRelExpr, its non PLT equivalent R_AARCH64_PAGE_PC is already in isRelExpr. Differential Revision: https://reviews.llvm.org/D56724 ------------------------------------------------------------------------ llvm-svn: 351446 --- lld/ELF/Relocations.cpp | 2 +- lld/test/ELF/aarch64-gnu-ifunc-address-pie.s | 44 ++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 lld/test/ELF/aarch64-gnu-ifunc-address-pie.s diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 812468896f0d0..9ffe8a9cc72e7 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -356,7 +356,7 @@ static bool needsGot(RelExpr Expr) { static bool isRelExpr(RelExpr Expr) { return isRelExprOneOf(Expr); + R_AARCH64_PLT_PAGE_PC, R_RELAX_GOT_PC>(Expr); } // Returns true if a given relocation can be computed at link-time. diff --git a/lld/test/ELF/aarch64-gnu-ifunc-address-pie.s b/lld/test/ELF/aarch64-gnu-ifunc-address-pie.s new file mode 100644 index 0000000000000..3db9070dbd07b --- /dev/null +++ b/lld/test/ELF/aarch64-gnu-ifunc-address-pie.s @@ -0,0 +1,44 @@ +# REQUIRES: aarch64 +# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o +# RUN: ld.lld -pie %t.o -o %tout +# RUN: llvm-objdump -D %tout | FileCheck %s +# RUN: llvm-readobj -r %tout | FileCheck %s -check-prefix=CHECK-RELOCS + +# Test that when we take the address of a preemptible ifunc using -fpie, we can +# handle the case when the ifunc is in the same translation unit as the address +# taker. In this case the compiler knows that ifunc is not defined in a shared +# library so it can use a non got generating relative reference. +.text +.globl myfunc +.type myfunc,@gnu_indirect_function +myfunc: + ret + +.text +.globl main +.type main,@function +main: + adrp x8, myfunc + add x8, x8, :lo12: myfunc + ret + +# CHECK: 0000000000010000 myfunc: +# CHECK-NEXT: 10000: c0 03 5f d6 ret +# CHECK: 0000000000010004 main: +# CHECK-NEXT: 10004: 08 00 00 90 adrp x8, #0 +# x8 = 0x10000 +# CHECK-NEXT: 10008: 08 41 00 91 add x8, x8, #16 +# x8 = 0x10010 = .plt for myfunc +# CHECK-NEXT: 1000c: c0 03 5f d6 ret +# CHECK-NEXT: Disassembly of section .plt: +# CHECK-NEXT: 0000000000010010 .plt: +# CHECK-NEXT: 10010: 90 00 00 90 adrp x16, #65536 +# CHECK-NEXT: 10014: 11 02 40 f9 ldr x17, [x16] +# CHECK-NEXT: 10018: 10 02 00 91 add x16, x16, #0 +# CHECK-NEXT: 1001c: 20 02 1f d6 br x17 + +# CHECK-RELOCS: Relocations [ +# CHECK-RELOCS-NEXT: Section {{.*}} .rela.plt { +# CHECK-RELOCS-NEXT: 0x20000 R_AARCH64_IRELATIVE - 0x10000 +# CHECK-RELOCS-NEXT: } +# CHECK-RELOCS-NEXT: ] From 3553f3e0aaa3e0208da72c9a8fed117c3ce48335 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 17 Jan 2019 15:37:17 +0000 Subject: [PATCH 020/274] Merging r351370: ------------------------------------------------------------------------ r351370 | mgrang | 2019-01-16 20:52:59 +0100 (Wed, 16 Jan 2019) | 14 lines [COFF, ARM64] Implement support for SEH extensions __try/__except/__finally Summary: This patch supports MS SEH extensions __try/__except/__finally. The intrinsics localescape and localrecover are responsible for communicating escaped static allocas from the try block to the handler. We need to preserve frame pointers for SEH. So we create a new function/property HasLocalEscape. Reviewers: rnk, compnerd, mstorsjo, TomTan, efriedma, ssijaric Reviewed By: rnk, efriedma Subscribers: smeenai, jrmuizel, alex, majnemer, ssijaric, ehsan, dmajor, kristina, javed.absar, kristof.beyls, chrib, llvm-commits Differential Revision: https://reviews.llvm.org/D53540 ------------------------------------------------------------------------ llvm-svn: 351451 --- llvm/include/llvm/CodeGen/MachineFunction.h | 4 ++ llvm/lib/CodeGen/AsmPrinter/WinException.cpp | 23 ++++--- .../SelectionDAG/SelectionDAGBuilder.cpp | 2 + llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 28 ++++++++ .../Target/AArch64/AArch64FrameLowering.cpp | 4 ++ .../Target/AArch64/AArch64ISelLowering.cpp | 28 ++++++++ llvm/lib/Target/AArch64/AArch64InstrInfo.td | 7 ++ .../Target/AArch64/AArch64RegisterInfo.cpp | 7 ++ llvm/test/CodeGen/AArch64/seh-finally.ll | 67 +++++++++++++++++++ llvm/test/CodeGen/AArch64/seh-localescape.ll | 30 +++++++++ 10 files changed, 191 insertions(+), 9 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/seh-finally.ll create mode 100644 llvm/test/CodeGen/AArch64/seh-localescape.ll diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h index 25edf5bcce516..6dbe1650adabf 100644 --- a/llvm/include/llvm/CodeGen/MachineFunction.h +++ b/llvm/include/llvm/CodeGen/MachineFunction.h @@ -329,6 +329,7 @@ class MachineFunction { bool CallsUnwindInit = false; bool HasEHScopes = false; bool HasEHFunclets = false; + bool HasLocalEscape = false; /// List of C++ TypeInfo used. std::vector TypeInfos; @@ -811,6 +812,9 @@ class MachineFunction { bool hasEHFunclets() const { return HasEHFunclets; } void setHasEHFunclets(bool V) { HasEHFunclets = V; } + bool hasLocalEscape() const { return HasLocalEscape; } + void setHasLocalEscape(bool V) { HasLocalEscape = V; } + /// Find or create an LandingPadInfo for the specified MachineBasicBlock. LandingPadInfo &getOrCreateLandingPadInfo(MachineBasicBlock *LandingPad); diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp index cf8e8c69bc2a6..92df09b7d6a23 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp @@ -545,15 +545,17 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) { OS.AddComment(Comment); }; - // Emit a label assignment with the SEH frame offset so we can use it for - // llvm.eh.recoverfp. - StringRef FLinkageName = - GlobalValue::dropLLVMManglingEscape(MF->getFunction().getName()); - MCSymbol *ParentFrameOffset = - Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName); - const MCExpr *MCOffset = - MCConstantExpr::create(FuncInfo.SEHSetFrameOffset, Ctx); - Asm->OutStreamer->EmitAssignment(ParentFrameOffset, MCOffset); + if (!isAArch64) { + // Emit a label assignment with the SEH frame offset so we can use it for + // llvm.eh.recoverfp. + StringRef FLinkageName = + GlobalValue::dropLLVMManglingEscape(MF->getFunction().getName()); + MCSymbol *ParentFrameOffset = + Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName); + const MCExpr *MCOffset = + MCConstantExpr::create(FuncInfo.SEHSetFrameOffset, Ctx); + Asm->OutStreamer->EmitAssignment(ParentFrameOffset, MCOffset); + } // Use the assembler to compute the number of table entries through label // difference and division. @@ -937,6 +939,9 @@ void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo, if (FI != INT_MAX) { const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering(); unsigned UnusedReg; + // FIXME: getFrameIndexReference needs to match the behavior of + // AArch64RegisterInfo::hasBasePointer in which one of the scenarios where + // SP is used is if frame size >= 256. Offset = TFI->getFrameIndexReference(*Asm->MF, FI, UnusedReg); } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 871ab9b29881b..bfeb3d1bc2b91 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6182,6 +6182,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { .addFrameIndex(FI); } + MF.setHasLocalEscape(true); + return nullptr; } diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 0442076992e24..0254a572434f4 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -694,6 +694,34 @@ void AArch64AsmPrinter::EmitInstruction(const MachineInstr *MI) { switch (MI->getOpcode()) { default: break; + case AArch64::MOVMCSym: { + unsigned DestReg = MI->getOperand(0).getReg(); + const MachineOperand &MO_Sym = MI->getOperand(1); + MachineOperand Hi_MOSym(MO_Sym), Lo_MOSym(MO_Sym); + MCOperand Hi_MCSym, Lo_MCSym; + + Hi_MOSym.setTargetFlags(AArch64II::MO_G1 | AArch64II::MO_S); + Lo_MOSym.setTargetFlags(AArch64II::MO_G0 | AArch64II::MO_NC); + + MCInstLowering.lowerOperand(Hi_MOSym, Hi_MCSym); + MCInstLowering.lowerOperand(Lo_MOSym, Lo_MCSym); + + MCInst MovZ; + MovZ.setOpcode(AArch64::MOVZXi); + MovZ.addOperand(MCOperand::createReg(DestReg)); + MovZ.addOperand(Hi_MCSym); + MovZ.addOperand(MCOperand::createImm(16)); + EmitToStreamer(*OutStreamer, MovZ); + + MCInst MovK; + MovK.setOpcode(AArch64::MOVKXi); + MovK.addOperand(MCOperand::createReg(DestReg)); + MovK.addOperand(MCOperand::createReg(DestReg)); + MovK.addOperand(Lo_MCSym); + MovK.addOperand(MCOperand::createImm(0)); + EmitToStreamer(*OutStreamer, MovK); + return; + } case AArch64::MOVIv2d_ns: // If the target has , lower this // instruction to movi.16b instead. diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index 538a8d7e8fbcf..621aa8bc783a6 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -228,6 +228,10 @@ bool AArch64FrameLowering::hasFP(const MachineFunction &MF) const { MFI.getMaxCallFrameSize() > DefaultSafeSPDisplacement) return true; + // Win64 SEH requires frame pointer if funclets are present. + if (MF.hasLocalEscape()) + return true; + return false; } diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index e01ca14d7f63d..762f4413d72b9 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -2743,6 +2743,34 @@ SDValue AArch64TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, case Intrinsic::aarch64_neon_umin: return DAG.getNode(ISD::UMIN, dl, Op.getValueType(), Op.getOperand(1), Op.getOperand(2)); + + case Intrinsic::localaddress: { + // Returns one of the stack, base, or frame pointer registers, depending on + // which is used to reference local variables. + MachineFunction &MF = DAG.getMachineFunction(); + const AArch64RegisterInfo *RegInfo = Subtarget->getRegisterInfo(); + unsigned Reg; + if (RegInfo->hasBasePointer(MF)) + Reg = RegInfo->getBaseRegister(); + else // This function handles the SP or FP case. + Reg = RegInfo->getFrameRegister(MF); + return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, + Op.getSimpleValueType()); + } + + case Intrinsic::eh_recoverfp: { + // FIXME: This needs to be implemented to correctly handle highly aligned + // stack objects. For now we simply return the incoming FP. Refer D53541 + // for more details. + SDValue FnOp = Op.getOperand(1); + SDValue IncomingFPOp = Op.getOperand(2); + GlobalAddressSDNode *GSD = dyn_cast(FnOp); + auto *Fn = dyn_cast_or_null(GSD ? GSD->getGlobal() : nullptr); + if (!Fn) + report_fatal_error( + "llvm.eh.recoverfp must take a function as the first argument"); + return IncomingFPOp; + } } } diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index c24b8b36441bb..86a4119c45f58 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -133,6 +133,10 @@ def UseNegativeImmediates : Predicate<"false">, AssemblerPredicate<"!FeatureNoNegativeImmediates", "NegativeImmediates">; +def AArch64LocalRecover : SDNode<"ISD::LOCAL_RECOVER", + SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, + SDTCisInt<1>]>>; + //===----------------------------------------------------------------------===// // AArch64-specific DAG Nodes. @@ -6801,5 +6805,8 @@ def : Pat<(AArch64tcret tglobaladdr:$dst, (i32 timm:$FPDiff)), def : Pat<(AArch64tcret texternalsym:$dst, (i32 timm:$FPDiff)), (TCRETURNdi texternalsym:$dst, imm:$FPDiff)>; +def MOVMCSym : Pseudo<(outs GPR64:$dst), (ins i64imm:$sym), []>, Sched<[]>; +def : Pat<(i64 (AArch64LocalRecover mcsym:$sym)), (MOVMCSym mcsym:$sym)>; + include "AArch64InstrAtomics.td" include "AArch64SVEInstrInfo.td" diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp index 96ae45ae3d0dc..3daac23592de7 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp @@ -466,6 +466,13 @@ void AArch64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, // Modify MI as necessary to handle as much of 'Offset' as possible Offset = TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg); + + if (MI.getOpcode() == TargetOpcode::LOCAL_ESCAPE) { + MachineOperand &FI = MI.getOperand(FIOperandNum); + FI.ChangeToImmediate(Offset); + return; + } + if (rewriteAArch64FrameIndex(MI, FIOperandNum, FrameReg, Offset, TII)) return; diff --git a/llvm/test/CodeGen/AArch64/seh-finally.ll b/llvm/test/CodeGen/AArch64/seh-finally.ll new file mode 100644 index 0000000000000..3cbbd03385c5f --- /dev/null +++ b/llvm/test/CodeGen/AArch64/seh-finally.ll @@ -0,0 +1,67 @@ +; RUN: llc -mtriple arm64-windows -o - %s | FileCheck %s + +; Function Attrs: noinline optnone uwtable +define dso_local i32 @foo() { +entry: +; CHECK-LABEL: foo +; CHECK: orr w8, wzr, #0x1 +; CHECK: mov w0, wzr +; CHECK: mov x1, x29 +; CHECK: .set .Lfoo$frame_escape_0, -4 +; CHECK: stur w8, [x29, #-4] +; CHECK: bl "?fin$0@0@foo@@" +; CHECK: ldur w0, [x29, #-4] + + %count = alloca i32, align 4 + call void (...) @llvm.localescape(i32* %count) + store i32 0, i32* %count, align 4 + %0 = load i32, i32* %count, align 4 + %add = add nsw i32 %0, 1 + store i32 %add, i32* %count, align 4 + %1 = call i8* @llvm.localaddress() + call void @"?fin$0@0@foo@@"(i8 0, i8* %1) + %2 = load i32, i32* %count, align 4 + ret i32 %2 +} + +define internal void @"?fin$0@0@foo@@"(i8 %abnormal_termination, i8* %frame_pointer) { +entry: +; CHECK-LABEL: @"?fin$0@0@foo@@" +; CHECK: sub sp, sp, #16 +; CHECK: str x1, [sp, #8] +; CHECK: strb w0, [sp, #7] +; CHECK: movz x8, #:abs_g1_s:.Lfoo$frame_escape_0 +; CHECK: movk x8, #:abs_g0_nc:.Lfoo$frame_escape_0 +; CHECK: add x8, x1, x8 +; CHECK: ldr w9, [x8] +; CHECK: add w9, w9, #1 +; CHECK: str w9, [x8] + + %frame_pointer.addr = alloca i8*, align 8 + %abnormal_termination.addr = alloca i8, align 1 + %0 = call i8* @llvm.localrecover(i8* bitcast (i32 ()* @foo to i8*), i8* %frame_pointer, i32 0) + %count = bitcast i8* %0 to i32* + store i8* %frame_pointer, i8** %frame_pointer.addr, align 8 + store i8 %abnormal_termination, i8* %abnormal_termination.addr, align 1 + %1 = zext i8 %abnormal_termination to i32 + %cmp = icmp eq i32 %1, 0 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + %2 = load i32, i32* %count, align 4 + %add = add nsw i32 %2, 1 + store i32 %add, i32* %count, align 4 + br label %if.end + +if.end: ; preds = %if.then, %entry + ret void +} + +; Function Attrs: nounwind readnone +declare i8* @llvm.localrecover(i8*, i8*, i32) + +; Function Attrs: nounwind readnone +declare i8* @llvm.localaddress() + +; Function Attrs: nounwind +declare void @llvm.localescape(...) diff --git a/llvm/test/CodeGen/AArch64/seh-localescape.ll b/llvm/test/CodeGen/AArch64/seh-localescape.ll new file mode 100644 index 0000000000000..0a1675014f62f --- /dev/null +++ b/llvm/test/CodeGen/AArch64/seh-localescape.ll @@ -0,0 +1,30 @@ +; RUN: llc -mtriple arm64-windows %s -o - | FileCheck %s + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @foo() { +entry: +; CHECK-LABEL: foo +; CHECK: .set .Lfoo$frame_escape_0, -4 + + %count = alloca i32, align 4 + call void (...) @llvm.localescape(i32* %count) + ret i32 0 +} + +define internal i32 @"?filt$0@0@foo@@"(i8* %exception_pointers, i8* %frame_pointer) { +entry: +; CHECK-LABEL: @"?filt$0@0@foo@@" +; CHECK: movz x8, #:abs_g1_s:.Lfoo$frame_escape_0 +; CHECK: movk x8, #:abs_g0_nc:.Lfoo$frame_escape_0 + + %0 = call i8* @llvm.localrecover(i8* bitcast (i32 ()* @foo to i8*), i8* %frame_pointer, i32 0) + %count = bitcast i8* %0 to i32* + %1 = load i32, i32* %count, align 4 + ret i32 %1 +} + +; Function Attrs: nounwind readnone +declare i8* @llvm.localrecover(i8*, i8*, i32) #2 + +; Function Attrs: nounwind +declare void @llvm.localescape(...) #3 From 2f1402b6cb9827593b9096ee1f4368baff9d6774 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 17 Jan 2019 15:39:31 +0000 Subject: [PATCH 021/274] Merging r351421: ------------------------------------------------------------------------ r351421 | ssijaric | 2019-01-17 10:45:17 +0100 (Thu, 17 Jan 2019) | 12 lines [ARM64][Windows] Share unwind codes between epilogues There are cases where we have multiple epilogues that have the exact same unwind code sequence. In that case, the epilogues can share the same unwind codes in the .xdata section. This should get us past the assert "SEH unwind data splitting not yet implemented" in many cases. We still need to add support for generating multiple .pdata/.xdata sections for those functions that need to be split into fragments. Differential Revision: https://reviews.llvm.org/D56813 ------------------------------------------------------------------------ llvm-svn: 351452 --- llvm/lib/MC/MCWin64EH.cpp | 53 ++++++- llvm/test/CodeGen/AArch64/wineh4.mir | 6 +- llvm/test/CodeGen/AArch64/wineh8.mir | 225 +++++++++++++++++++++++++++ 3 files changed, 279 insertions(+), 5 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/wineh8.mir diff --git a/llvm/lib/MC/MCWin64EH.cpp b/llvm/lib/MC/MCWin64EH.cpp index 0724b109e1a1d..2e4eea3411f4b 100644 --- a/llvm/lib/MC/MCWin64EH.cpp +++ b/llvm/lib/MC/MCWin64EH.cpp @@ -453,6 +453,38 @@ static void ARM64EmitUnwindCode(MCStreamer &streamer, const MCSymbol *begin, } } +// Returns the epilog symbol of an epilog with the exact same unwind code +// sequence, if it exists. Otherwise, returns nulltpr. +// EpilogInstrs - Unwind codes for the current epilog. +// Epilogs - Epilogs that potentialy match the current epilog. +static MCSymbol* +FindMatchingEpilog(const std::vector& EpilogInstrs, + const std::vector& Epilogs, + const WinEH::FrameInfo *info) { + for (auto *EpilogStart : Epilogs) { + auto InstrsIter = info->EpilogMap.find(EpilogStart); + assert(InstrsIter != info->EpilogMap.end() && + "Epilog not found in EpilogMap"); + const auto &Instrs = InstrsIter->second; + + if (Instrs.size() != EpilogInstrs.size()) + continue; + + bool Match = true; + for (unsigned i = 0; i < Instrs.size(); ++i) + if (Instrs[i].Operation != EpilogInstrs[i].Operation || + Instrs[i].Offset != EpilogInstrs[i].Offset || + Instrs[i].Register != EpilogInstrs[i].Register) { + Match = false; + break; + } + + if (Match) + return EpilogStart; + } + return nullptr; +} + // Populate the .xdata section. The format of .xdata on ARM64 is documented at // https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling static void ARM64EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) { @@ -477,12 +509,29 @@ static void ARM64EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) { // Process epilogs. MapVector EpilogInfo; + // Epilogs processed so far. + std::vector AddedEpilogs; + for (auto &I : info->EpilogMap) { MCSymbol *EpilogStart = I.first; auto &EpilogInstrs = I.second; uint32_t CodeBytes = ARM64CountOfUnwindCodes(EpilogInstrs); - EpilogInfo[EpilogStart] = TotalCodeBytes; - TotalCodeBytes += CodeBytes; + + uint32_t NumUnwindCodes = EpilogInstrs.size(); + MCSymbol* MatchingEpilog = + FindMatchingEpilog(EpilogInstrs, AddedEpilogs, info); + if (MatchingEpilog) { + assert(EpilogInfo.find(MatchingEpilog) != EpilogInfo.end() && + "Duplicate epilog not found"); + EpilogInfo[EpilogStart] = EpilogInfo[MatchingEpilog]; + // Clear the unwind codes in the EpilogMap, so that they don't get output + // in the logic below. + EpilogInstrs.clear(); + } else { + EpilogInfo[EpilogStart] = TotalCodeBytes; + TotalCodeBytes += CodeBytes; + AddedEpilogs.push_back(EpilogStart); + } } // Code Words, Epilog count, E, X, Vers, Function Length diff --git a/llvm/test/CodeGen/AArch64/wineh4.mir b/llvm/test/CodeGen/AArch64/wineh4.mir index 4d4cc892c2e82..3a324324431c7 100644 --- a/llvm/test/CodeGen/AArch64/wineh4.mir +++ b/llvm/test/CodeGen/AArch64/wineh4.mir @@ -1,7 +1,7 @@ # RUN: llc -o - %s -mtriple=aarch64-windows -start-after=prologepilog \ # RUN: -disable-branch-fold -filetype=obj \ # RUN: | llvm-readobj -unwind | FileCheck %s -# Check that multiple epilgoues are correctly placed in .xdata. +# Check that identical multiple epilgoues are correctly shared in .xdata. # CHECK: ExceptionData { # CHECK-NEXT: FunctionLength: 164 @@ -9,7 +9,7 @@ # CHECK-NEXT: ExceptionData: No # CHECK-NEXT: EpiloguePacked: No # CHECK-NEXT: EpilogueScopes: 2 -# CHECK-NEXT: ByteCodeLength: 48 +# CHECK-NEXT: ByteCodeLength: 32 # CHECK-NEXT: Prologue [ # CHECK-NEXT: 0xc80c ; stp x19, x20, [sp, #96] # CHECK-NEXT: 0xc88a ; stp x21, x22, [sp, #80] @@ -37,7 +37,7 @@ # CHECK-NEXT: } # CHECK-NEXT: EpilogueScope { # CHECK-NEXT: StartOffset: 33 -# CHECK-NEXT: EpilogueStartIndex: 30 +# CHECK-NEXT: EpilogueStartIndex: 15 # CHECK-NEXT: Opcodes [ # CHECK-NEXT: 0xc80c ; ldp x19, x20, [sp, #96] # CHECK-NEXT: 0xc88a ; ldp x21, x22, [sp, #80] diff --git a/llvm/test/CodeGen/AArch64/wineh8.mir b/llvm/test/CodeGen/AArch64/wineh8.mir new file mode 100644 index 0000000000000..606bc140b232d --- /dev/null +++ b/llvm/test/CodeGen/AArch64/wineh8.mir @@ -0,0 +1,225 @@ +# RUN: llc -o - %s -mtriple=aarch64-windows -start-after=prologepilog \ +# RUN: -disable-branch-fold -filetype=obj \ +# RUN: | llvm-readobj -unwind | FileCheck %s +# Check that non-identical multiple epilgoues are correctly shared in .xdata. + +# CHECK: ExceptionData { +# CHECK-NEXT: FunctionLength: 160 +# CHECK-NEXT: Version: 0 +# CHECK-NEXT: ExceptionData: No +# CHECK-NEXT: EpiloguePacked: No +# CHECK-NEXT: EpilogueScopes: 2 +# CHECK-NEXT: ByteCodeLength: 44 +# CHECK-NEXT: Prologue [ +# CHECK-NEXT: 0xc80c ; stp x19, x20, [sp, #96] +# CHECK-NEXT: 0xc88a ; stp x21, x22, [sp, #80] +# CHECK-NEXT: 0xc908 ; stp x23, x24, [sp, #64] +# CHECK-NEXT: 0xc986 ; stp x25, x26, [sp, #48] +# CHECK-NEXT: 0xca04 ; stp x27, x28, [sp, #32] +# CHECK-NEXT: 0xd802 ; stp d8, d9, [sp, #16] +# CHECK-NEXT: 0xda8d ; stp d10, d11, [sp, #-112]! +# CHECK-NEXT: 0xe4 ; end +# CHECK-NEXT: ] +# CHECK-NEXT: EpilogueScopes [ +# CHECK-NEXT: EpilogueScope { +# CHECK-NEXT: StartOffset: 16 +# CHECK-NEXT: EpilogueStartIndex: 15 +# CHECK-NEXT: Opcodes [ +# CHECK-NEXT: 0xc80c ; ldp x19, x20, [sp, #96] +# CHECK-NEXT: 0xc88a ; ldp x21, x22, [sp, #80] +# CHECK-NEXT: 0xc908 ; ldp x23, x24, [sp, #64] +# CHECK-NEXT: 0xc986 ; ldp x25, x26, [sp, #48] +# CHECK-NEXT: 0xd802 ; ldp d8, d9, [sp, #16] +# CHECK-NEXT: 0xda8d ; ldp d10, d11, [sp], #112 +# CHECK-NEXT: 0xe4 ; end +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: EpilogueScope { +# CHECK-NEXT: StartOffset: 32 +# CHECK-NEXT: EpilogueStartIndex: 28 +# CHECK-NEXT: Opcodes [ +# CHECK-NEXT: 0xc80c ; ldp x19, x20, [sp, #96] +# CHECK-NEXT: 0xc88a ; ldp x21, x22, [sp, #80] +# CHECK-NEXT: 0xc908 ; ldp x23, x24, [sp, #64] +# CHECK-NEXT: 0xc986 ; ldp x25, x26, [sp, #48] +# CHECK-NEXT: 0xca04 ; ldp x27, x28, [sp, #32] +# CHECK-NEXT: 0xd802 ; ldp d8, d9, [sp, #16] +# CHECK-NEXT: 0xda8d ; ldp d10, d11, [sp], #112 +# CHECK-NEXT: 0xe4 ; end +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: } +... +--- +name: test +alignment: 2 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: false +tracksRegLiveness: true +hasWinCFI: true +registers: +liveins: + - { reg: '$w0', virtual-reg: '' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 112 + offsetAdjustment: 0 + maxAlignment: 8 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: true + hasVAStart: false + hasMustTailInVarArgFunc: false + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: +stack: + - { id: 0, name: '', type: spill-slot, offset: -8, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '$x19', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 1, name: '', type: spill-slot, offset: -16, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '$x20', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 2, name: '', type: spill-slot, offset: -24, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '$x21', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 3, name: '', type: spill-slot, offset: -32, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '$x22', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 4, name: '', type: spill-slot, offset: -40, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '$x23', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 5, name: '', type: spill-slot, offset: -48, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '$x24', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 6, name: '', type: spill-slot, offset: -56, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '$x25', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 7, name: '', type: spill-slot, offset: -64, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '$x26', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 8, name: '', type: spill-slot, offset: -72, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '$x27', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 9, name: '', type: spill-slot, offset: -80, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '$x28', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 10, name: '', type: spill-slot, offset: -88, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '$d8', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 11, name: '', type: spill-slot, offset: -96, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '$d9', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 12, name: '', type: spill-slot, offset: -104, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '$d10', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 13, name: '', type: spill-slot, offset: -112, size: 8, alignment: 8, + stack-id: 0, callee-saved-register: '$d11', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } +constants: +body: | + bb.0.entry: + successors: %bb.2(0x40000000), %bb.1(0x40000000) + liveins: $x0, $x1, $d0, $d1, $d10, $d11, $d8, $d9, $x27, $x28, $x25, $x26, $x23, $x24, $x21, $x22, $x19, $x20 + + early-clobber $sp = frame-setup STPDpre killed $d10, killed $d11, $sp, -14 :: (store 8 into %stack.12), (store 8 into %stack.13) + frame-setup SEH_SaveFRegP_X 10, 11, -112 + frame-setup STPDi killed $d8, killed $d9, $sp, 2 :: (store 8 into %stack.10), (store 8 into %stack.11) + frame-setup SEH_SaveFRegP 8, 9, 16 + frame-setup STPXi killed $x27, killed $x28, $sp, 4 :: (store 8 into %stack.8), (store 8 into %stack.9) + frame-setup SEH_SaveRegP 27, 28, 32 + frame-setup STPXi killed $x25, killed $x26, $sp, 6 :: (store 8 into %stack.6), (store 8 into %stack.7) + frame-setup SEH_SaveRegP 25, 26, 48 + frame-setup STPXi killed $x23, killed $x24, $sp, 8 :: (store 8 into %stack.4), (store 8 into %stack.5) + frame-setup SEH_SaveRegP 23, 24, 64 + frame-setup STPXi killed $x21, killed $x22, $sp, 10 :: (store 8 into %stack.2), (store 8 into %stack.3) + frame-setup SEH_SaveRegP 21, 22, 80 + frame-setup STPXi killed $x19, killed $x20, $sp, 12 :: (store 8 into %stack.0), (store 8 into %stack.1) + frame-setup SEH_SaveRegP 19, 20, 96 + frame-setup SEH_PrologEnd + frame-setup CFI_INSTRUCTION def_cfa_offset 112 + frame-setup CFI_INSTRUCTION offset $w19, -8 + frame-setup CFI_INSTRUCTION offset $w20, -16 + frame-setup CFI_INSTRUCTION offset $w21, -24 + frame-setup CFI_INSTRUCTION offset $w22, -32 + frame-setup CFI_INSTRUCTION offset $w23, -40 + frame-setup CFI_INSTRUCTION offset $w24, -48 + frame-setup CFI_INSTRUCTION offset $w25, -56 + frame-setup CFI_INSTRUCTION offset $w26, -64 + frame-setup CFI_INSTRUCTION offset $w27, -72 + frame-setup CFI_INSTRUCTION offset $w28, -80 + frame-setup CFI_INSTRUCTION offset $b8, -88 + frame-setup CFI_INSTRUCTION offset $b9, -96 + frame-setup CFI_INSTRUCTION offset $b10, -104 + frame-setup CFI_INSTRUCTION offset $b11, -112 + $x19 = ADDXrr $x0, killed $x1 + $d8 = FADDDrr killed $d0, $d1 + $d9 = FADDDrr $d8, $d1 + $d10 = FADDDrr $d9, $d8 + $d11 = FADDDrr killed $d9, $d10 + $x20 = SUBSXrr $x19, killed $x0, implicit-def $nzcv + Bcc 1, %bb.2, implicit killed $nzcv + B %bb.1 + + bb.1: + liveins: $x19, $x20 + + $x21 = ADDXrr $x20, killed $x19 + $x22 = ADDXrr $x21, killed $x20 + $x23 = ADDXrr $x22, killed $x21 + $x24 = ADDXrr $x23, killed $x22 + $x25 = ADDXrr $x24, killed $x23 + $x26 = ADDXrr $x25, killed $x24 + $x27 = ADDXrr $x26, killed $x25 + $x28 = ADDXrr $x27, killed $x26 + $x0 = COPY $x28 + frame-destroy SEH_EpilogStart + $x19, $x20 = frame-destroy LDPXi $sp, 12 :: (load 8 from %stack.0), (load 8 from %stack.1) + frame-destroy SEH_SaveRegP 19, 20, 96 + $x21, $x22 = frame-destroy LDPXi $sp, 10 :: (load 8 from %stack.2), (load 8 from %stack.3) + frame-destroy SEH_SaveRegP 21, 22, 80 + $x23, $x24 = frame-destroy LDPXi $sp, 8 :: (load 8 from %stack.4), (load 8 from %stack.5) + frame-destroy SEH_SaveRegP 23, 24, 64 + $x25, $x26 = frame-destroy LDPXi $sp, 6 :: (load 8 from %stack.6), (load 8 from %stack.7) + frame-destroy SEH_SaveRegP 25, 26, 48 + $x27, $x28 = frame-destroy LDPXi $sp, 4 :: (load 8 from %stack.8), (load 8 from %stack.9) + frame-destroy SEH_SaveRegP 27, 28, 32 + $d8, $d9 = frame-destroy LDPDi $sp, 2 :: (load 8 from %stack.10), (load 8 from %stack.11) + frame-destroy SEH_SaveFRegP 8, 9, 16 + early-clobber $sp, $d10, $d11 = frame-destroy LDPDpost $sp, 14 :: (load 8 from %stack.12), (load 8 from %stack.13) + frame-destroy SEH_SaveFRegP_X 10, 11, -112 + frame-destroy SEH_EpilogEnd + RET_ReallyLR implicit $x0 + + bb.2: + liveins: $x28, $d11 + + $x0 = COPY $d11 + $x0 = ADDXrr $x0, killed $x28 + frame-destroy SEH_EpilogStart + $x19, $x20 = frame-destroy LDPXi $sp, 12 :: (load 8 from %stack.0), (load 8 from %stack.1) + frame-destroy SEH_SaveRegP 19, 20, 96 + $x21, $x22 = frame-destroy LDPXi $sp, 10 :: (load 8 from %stack.2), (load 8 from %stack.3) + frame-destroy SEH_SaveRegP 21, 22, 80 + $x23, $x24 = frame-destroy LDPXi $sp, 8 :: (load 8 from %stack.4), (load 8 from %stack.5) + frame-destroy SEH_SaveRegP 23, 24, 64 + $x25, $x26 = frame-destroy LDPXi $sp, 6 :: (load 8 from %stack.6), (load 8 from %stack.7) + frame-destroy SEH_SaveRegP 25, 26, 48 + $d8, $d9 = frame-destroy LDPDi $sp, 2 :: (load 8 from %stack.10), (load 8 from %stack.11) + frame-destroy SEH_SaveFRegP 8, 9, 16 + early-clobber $sp, $d10, $d11 = frame-destroy LDPDpost $sp, 14 :: (load 8 from %stack.12), (load 8 from %stack.13) + frame-destroy SEH_SaveFRegP_X 10, 11, -112 + frame-destroy SEH_EpilogEnd + RET_ReallyLR implicit $x0 + +... From 8593d6061d1cf8b9485be00f7c07e67b7c02773d Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 18 Jan 2019 08:59:50 +0000 Subject: [PATCH 022/274] Merging r351475: ------------------------------------------------------------------------ r351475 | rnk | 2019-01-17 21:46:53 +0100 (Thu, 17 Jan 2019) | 16 lines [InstCombine] Don't sink dynamic allocas Summary: InstCombine's sinking algorithm only thinks about memory. It doesn't think about non-memory constraints like stack object lifetime. It can sink dynamic allocas across a stacksave call, which may be used with stackrestore, which can incorrectly reduce the lifetime of the dynamic alloca. Fixes PR40365 Reviewers: hfinkel, efriedma Subscribers: hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D56872 ------------------------------------------------------------------------ llvm-svn: 351530 --- .../InstCombine/InstructionCombining.cpp | 8 +-- .../Transforms/InstCombine/sink-alloca.ll | 52 +++++++++++++++++++ 2 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Transforms/InstCombine/sink-alloca.ll diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index be7d43bbcf2c3..f530ee1246e8c 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3065,9 +3065,11 @@ static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock) { I->isTerminator()) return false; - // Do not sink alloca instructions out of the entry block. - if (isa(I) && I->getParent() == - &DestBlock->getParent()->getEntryBlock()) + // Do not sink static or dynamic alloca instructions. Static allocas must + // remain in the entry block, and dynamic allocas must not be sunk in between + // a stacksave / stackrestore pair, which would incorrectly shorten its + // lifetime. + if (isa(I)) return false; // Do not sink into catchswitch blocks. diff --git a/llvm/test/Transforms/InstCombine/sink-alloca.ll b/llvm/test/Transforms/InstCombine/sink-alloca.ll new file mode 100644 index 0000000000000..f2de74ff533ba --- /dev/null +++ b/llvm/test/Transforms/InstCombine/sink-alloca.ll @@ -0,0 +1,52 @@ +; RUN: opt -instcombine -S < %s | FileCheck %s + +target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128" +target triple = "i686-unknown-linux-gnu" + +; Check that instcombine doesn't sink dynamic allocas across llvm.stacksave. + +; Helper to generate branch conditions. +declare i1 @cond() + +declare i32* @use_and_return(i32*) + +declare i8* @llvm.stacksave() #0 + +declare void @llvm.stackrestore(i8*) #0 + +define void @foo(i32 %x) { +entry: + %c1 = call i1 @cond() + br i1 %c1, label %ret, label %nonentry + +nonentry: ; preds = %entry + %argmem = alloca i32, i32 %x, align 4 + %sp = call i8* @llvm.stacksave() + %c2 = call i1 @cond() + br i1 %c2, label %ret, label %sinktarget + +sinktarget: ; preds = %nonentry + ; Arrange for there to be a single use of %argmem by returning it. + %p = call i32* @use_and_return(i32* nonnull %argmem) + store i32 13, i32* %p, align 4 + call void @llvm.stackrestore(i8* %sp) + %0 = call i32* @use_and_return(i32* %p) + br label %ret + +ret: ; preds = %sinktarget, %nonentry, %entry + ret void +} + +; CHECK-LABEL: define void @foo(i32 %x) +; CHECK: nonentry: +; CHECK: %argmem = alloca i32, i32 %x +; CHECK: %sp = call i8* @llvm.stacksave() +; CHECK: %c2 = call i1 @cond() +; CHECK: br i1 %c2, label %ret, label %sinktarget +; CHECK: sinktarget: +; CHECK: %p = call i32* @use_and_return(i32* nonnull %argmem) +; CHECK: store i32 13, i32* %p +; CHECK: call void @llvm.stackrestore(i8* %sp) +; CHECK: %0 = call i32* @use_and_return(i32* %p) + +attributes #0 = { nounwind } From 47149c4d12111e2db1072edf57ee669281b5089f Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 18 Jan 2019 09:02:40 +0000 Subject: [PATCH 023/274] Merging r351325: ------------------------------------------------------------------------ r351325 | gbuella | 2019-01-16 13:06:17 +0100 (Wed, 16 Jan 2019) | 26 lines Assertion in isAllocaPromotable due to extra bitcast goes into lifetime marker For the given test SROA detects possible replacement and creates a correct alloca. After that SROA is adding lifetime markers for this new alloca. The function getNewAllocaSlicePtr is trying to deduce the pointer type based on the original alloca, which is split, to use it later in lifetime intrinsic. For the test we ended up with such code (rA is initial alloca [10 x float], which is split, and rA.sroa.0.0 is a new split allocation) ``` %rA.sroa.0.0.rA.sroa_cast = bitcast i32* %rA.sroa.0 to [10 x float]* <----- this one causing the assertion and is an extra bitcast %5 = bitcast [10 x float]* %rA.sroa.0.0.rA.sroa_cast to i8* call void @llvm.lifetime.start.p0i8(i64 4, i8* %5) ``` isAllocaPromotable code assumes that a user of alloca may go into lifetime marker through bitcast but it must be the only one bitcast to i8* type. In the test it's not a i8* type, return false and throw the assertion. As we are creating a pointer, which will be used in lifetime markers only, the proposed fix is to create a bitcast to i8* immediately to avoid extra bitcast creation. The test is a greatly simplified to just reproduce the assertion. Author: Igor Tsimbalist Reviewers: chandlerc, craig.topper Reviewed By: chandlerc Differential Revision: https://reviews.llvm.org/D55934 ------------------------------------------------------------------------ llvm-svn: 351532 --- llvm/lib/Transforms/Scalar/SROA.cpp | 5 ++- llvm/test/Transforms/SROA/basictest.ll | 49 ++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index eab77cf4cda9b..68ca6c47c8f1a 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -3031,7 +3031,10 @@ class llvm::sroa::AllocaSliceRewriter ConstantInt *Size = ConstantInt::get(cast(II.getArgOperand(0)->getType()), NewEndOffset - NewBeginOffset); - Value *Ptr = getNewAllocaSlicePtr(IRB, OldPtr->getType()); + // Lifetime intrinsics always expect an i8* so directly get such a pointer + // for the new alloca slice. + Type *PointerTy = IRB.getInt8PtrTy(OldPtr->getType()->getPointerAddressSpace()); + Value *Ptr = getNewAllocaSlicePtr(IRB, PointerTy); Value *New; if (II.getIntrinsicID() == Intrinsic::lifetime_start) New = IRB.CreateLifetimeStart(Ptr, Size); diff --git a/llvm/test/Transforms/SROA/basictest.ll b/llvm/test/Transforms/SROA/basictest.ll index a72da6399f22c..2c5829d6fcecb 100644 --- a/llvm/test/Transforms/SROA/basictest.ll +++ b/llvm/test/Transforms/SROA/basictest.ll @@ -1745,6 +1745,55 @@ entry: ret void } +declare void @llvm.lifetime.start.isVoid.i64.p0i8(i64, [10 x float]* nocapture) +declare void @llvm.lifetime.end.isVoid.i64.p0i8(i64, [10 x float]* nocapture) +@array = dso_local global [10 x float] undef, align 4 + +define void @test29(i32 %num, i32 %tid) { +; CHECK-LABEL: @test29( +; CHECK-NOT: alloca [10 x float] +; CHECK: ret void + +entry: + %ra = alloca [10 x float], align 4 + call void @llvm.lifetime.start.isVoid.i64.p0i8(i64 40, [10 x float]* nonnull %ra) + + %cmp1 = icmp sgt i32 %num, 0 + br i1 %cmp1, label %bb1, label %bb7 + +bb1: + %tobool = icmp eq i32 %tid, 0 + %conv.i = zext i32 %tid to i64 + %0 = bitcast [10 x float]* %ra to i32* + %1 = load i32, i32* %0, align 4 + %arrayidx5 = getelementptr inbounds [10 x float], [10 x float]* @array, i64 0, i64 %conv.i + %2 = bitcast float* %arrayidx5 to i32* + br label %bb2 + +bb2: + %i.02 = phi i32 [ %num, %bb1 ], [ %sub, %bb5 ] + br i1 %tobool, label %bb3, label %bb4 + +bb3: + br label %bb5 + +bb4: + store i32 %1, i32* %2, align 4 + br label %bb5 + +bb5: + %sub = add i32 %i.02, -1 + %cmp = icmp sgt i32 %sub, 0 + br i1 %cmp, label %bb2, label %bb6 + +bb6: + br label %bb7 + +bb7: + call void @llvm.lifetime.end.isVoid.i64.p0i8(i64 40, [10 x float]* nonnull %ra) + ret void +} + !0 = !{!1, !1, i64 0, i64 1} !1 = !{!2, i64 1, !"type_0"} !2 = !{!"root"} From c4fa34c39aa7c083b598bb3a0551b74b3943789f Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 18 Jan 2019 09:32:52 +0000 Subject: [PATCH 024/274] Merging r351457: ------------------------------------------------------------------------ r351457 | vlad.tsyrklevich | 2019-01-17 18:53:45 +0100 (Thu, 17 Jan 2019) | 15 lines TLS: Respect visibility for thread_local variables on Darwin (PR40327) Summary: Teach clang to mark thread wrappers for thread_local variables with hidden visibility when the original variable is marked with hidden visibility. This is necessary on Darwin which exposes the thread wrapper instead of the thread variable. The thread wrapper would previously always be created with default visibility unless it had linkonce*/weak_odr linkage. Reviewers: rjmccall Reviewed By: rjmccall Differential Revision: https://reviews.llvm.org/D56818 ------------------------------------------------------------------------ llvm-svn: 351533 --- clang/lib/CodeGen/ItaniumCXXABI.cpp | 10 ++++++---- .../cxx11-thread-local-visibility.cpp | 17 +++++++++++++++++ clang/test/CodeGenCXX/cxx11-thread-local.cpp | 2 +- 3 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenCXX/cxx11-thread-local-visibility.cpp diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index b53304528c3d8..c56875a036809 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -2463,10 +2463,12 @@ ItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD, CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Wrapper); // Always resolve references to the wrapper at link time. - if (!Wrapper->hasLocalLinkage() && !(isThreadWrapperReplaceable(VD, CGM) && - !llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) && - !llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()))) - Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility); + if (!Wrapper->hasLocalLinkage()) + if (!isThreadWrapperReplaceable(VD, CGM) || + llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) || + llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) || + VD->getVisibility() == HiddenVisibility) + Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility); if (isThreadWrapperReplaceable(VD, CGM)) { Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS); diff --git a/clang/test/CodeGenCXX/cxx11-thread-local-visibility.cpp b/clang/test/CodeGenCXX/cxx11-thread-local-visibility.cpp new file mode 100644 index 0000000000000..b46d41d7c9604 --- /dev/null +++ b/clang/test/CodeGenCXX/cxx11-thread-local-visibility.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck --check-prefix=LINUX %s +// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-apple-darwin12 | FileCheck --check-prefix=DARWIN %s + +// Regression test for PR40327 + +// LINUX: @default_tls = thread_local global i32 +// LINUX: @hidden_tls = hidden thread_local global i32 +// LINUX: define weak_odr hidden i32* @_ZTW11default_tls() +// LINUX: define weak_odr hidden i32* @_ZTW10hidden_tls() +// +// DARWIN: @default_tls = internal thread_local global i32 +// DARWIN: @hidden_tls = internal thread_local global i32 +// DARWIN: define cxx_fast_tlscc i32* @_ZTW11default_tls() +// DARWIN: define hidden cxx_fast_tlscc i32* @_ZTW10hidden_tls() + +__attribute__((visibility("default"))) thread_local int default_tls; +__attribute__((visibility("hidden"))) thread_local int hidden_tls; diff --git a/clang/test/CodeGenCXX/cxx11-thread-local.cpp b/clang/test/CodeGenCXX/cxx11-thread-local.cpp index 156c4f591908b..de941af1afb87 100644 --- a/clang/test/CodeGenCXX/cxx11-thread-local.cpp +++ b/clang/test/CodeGenCXX/cxx11-thread-local.cpp @@ -318,7 +318,7 @@ void set_anon_i() { // CHECK-NOT: call void @[[V_M_INIT]]() -// LIUNX: define weak_odr hidden i32* @_ZTW1a() { +// LINUX: define weak_odr hidden i32* @_ZTW1a() // DARWIN: define cxx_fast_tlscc i32* @_ZTW1a() // LINUX: call void @_ZTH1a() // DARWIN: call cxx_fast_tlscc void @_ZTH1a() From ad1624ff4fe7303d63dadf61f8ea8734c931a407 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 18 Jan 2019 09:52:52 +0000 Subject: [PATCH 025/274] Merging r351459: ------------------------------------------------------------------------ r351459 | arphaman | 2019-01-17 19:12:45 +0100 (Thu, 17 Jan 2019) | 13 lines [ObjC] Follow-up r350768 and allow the use of unavailable methods that are declared in a parent class from within the @implementation context This commit extends r350768 and allows the use of methods marked as unavailable that are declared in a parent class/category from within the @implementation of the class where the method is marked as unavailable. This allows users to call init that's marked as unavailable even if they don't define it. rdar://47134898 Differential Revision: https://reviews.llvm.org/D56816 ------------------------------------------------------------------------ llvm-svn: 351535 --- clang/lib/Sema/SemaDeclAttr.cpp | 8 +++---- .../SemaObjC/call-unavailable-init-in-self.m | 22 +++++++++++++++++-- .../SemaObjC/infer-availability-from-init.m | 4 ++-- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index eb95cc748b177..139ac8aab4333 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7365,13 +7365,11 @@ ShouldDiagnoseAvailabilityInContext(Sema &S, AvailabilityResult K, return true; } else if (K == AR_Unavailable) { // It is perfectly fine to refer to an 'unavailable' Objective-C method - // when it's actually defined and is referenced from within the - // @implementation itself. In this context, we interpret unavailable as a - // form of access control. + // when it is referenced from within the @implementation itself. In this + // context, we interpret unavailable as a form of access control. if (const auto *MD = dyn_cast(OffendingDecl)) { if (const auto *Impl = dyn_cast(C)) { - if (MD->getClassInterface() == Impl->getClassInterface() && - MD->isDefined()) + if (MD->getClassInterface() == Impl->getClassInterface()) return true; } } diff --git a/clang/test/SemaObjC/call-unavailable-init-in-self.m b/clang/test/SemaObjC/call-unavailable-init-in-self.m index fa6f670cc997f..48fc2326af457 100644 --- a/clang/test/SemaObjC/call-unavailable-init-in-self.m +++ b/clang/test/SemaObjC/call-unavailable-init-in-self.m @@ -5,13 +5,24 @@ @interface NSObject + (instancetype)new; + (instancetype)alloc; +- (void)declaredInSuper; + +@end + +@interface NSObject (Category) + +- (void)declaredInSuperCategory; + @end @interface Sub: NSObject - (instancetype)init __attribute__((unavailable)); // expected-note 4 {{'init' has been explicitly marked unavailable here}} -- (void)notImplemented __attribute__((unavailable)); // expected-note {{'notImplemented' has been explicitly marked unavailable here}} +- (void)notImplemented __attribute__((unavailable)); + +- (void)declaredInSuper __attribute__((unavailable)); +- (void)declaredInSuperCategory __attribute__((unavailable)); @end @@ -34,7 +45,14 @@ - (instancetype) init { } - (void)reportUseOfUnimplemented { - [self notImplemented]; // expected-error {{'notImplemented' is unavailable}} + [self notImplemented]; +} + +- (void)allowSuperCallUsingSelf { + [self declaredInSuper]; + [[Sub alloc] declaredInSuper]; + [self declaredInSuperCategory]; + [[Sub alloc] declaredInSuperCategory]; } @end diff --git a/clang/test/SemaObjC/infer-availability-from-init.m b/clang/test/SemaObjC/infer-availability-from-init.m index f9996ec70877e..7aa1e53c09109 100644 --- a/clang/test/SemaObjC/infer-availability-from-init.m +++ b/clang/test/SemaObjC/infer-availability-from-init.m @@ -47,12 +47,12 @@ void usenotmyobject() { } @interface FromSelf : NSObject --(instancetype)init __attribute__((unavailable)); // expected-note {{'init' has been explicitly marked unavailable here}} +-(instancetype)init __attribute__((unavailable)); +(FromSelf*)another_one; @end @implementation FromSelf +(FromSelf*)another_one { - [self new]; // expected-error{{'new' is unavailable}} + [self new]; } @end From d4d3f779635f46bde171f9c6573e484c56201138 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 18 Jan 2019 09:57:06 +0000 Subject: [PATCH 026/274] Merging r351504: ------------------------------------------------------------------------ r351504 | brad | 2019-01-18 02:36:58 +0100 (Fri, 18 Jan 2019) | 2 lines Use llvm::VersionTuple instead of manual version marshalling ------------------------------------------------------------------------ llvm-svn: 351536 --- lldb/include/lldb/Host/openbsd/HostInfoOpenBSD.h | 3 ++- lldb/source/Host/openbsd/HostInfoOpenBSD.cpp | 11 ++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lldb/include/lldb/Host/openbsd/HostInfoOpenBSD.h b/lldb/include/lldb/Host/openbsd/HostInfoOpenBSD.h index 5a0388ffdd977..809a6f4461f51 100644 --- a/lldb/include/lldb/Host/openbsd/HostInfoOpenBSD.h +++ b/lldb/include/lldb/Host/openbsd/HostInfoOpenBSD.h @@ -12,12 +12,13 @@ #include "lldb/Host/posix/HostInfoPosix.h" #include "lldb/Utility/FileSpec.h" +#include "llvm/Support/VersionTuple.h" namespace lldb_private { class HostInfoOpenBSD : public HostInfoPosix { public: - static bool GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update); + static llvm::VersionTuple GetOSVersion(); static bool GetOSBuildString(std::string &s); static bool GetOSKernelDescription(std::string &s); static FileSpec GetProgramFileSpec(); diff --git a/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp b/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp index 548958899322c..cf7acb79da00e 100644 --- a/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp +++ b/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp @@ -17,16 +17,17 @@ using namespace lldb_private; -bool HostInfoOpenBSD::GetOSVersion(uint32_t &major, uint32_t &minor, - uint32_t &update) { +llvm::VersionTuple HostInfoOpenBSD::GetOSVersion() { struct utsname un; ::memset(&un, 0, sizeof(utsname)); if (uname(&un) < 0) - return false; + return llvm::VersionTuple(); - int status = sscanf(un.release, "%u.%u", &major, &minor); - return status == 2; + unsigned major, minor; + if (2 == sscanf(un.release, "%u.%u", &major, &minor)) + return llvm::VersionTuple(major, minor); + return llvm::VersionTuple(); } bool HostInfoOpenBSD::GetOSBuildString(std::string &s) { From 6e751e810a270593f3f2d2fd8767aaf73237d034 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 18 Jan 2019 10:00:51 +0000 Subject: [PATCH 027/274] Merging r351463, r351466, r351467, and r351468 ------------------------------------------------------------------------ r351463 | eugenezelenko | 2019-01-17 19:31:34 +0100 (Thu, 17 Jan 2019) | 6 lines [Documentation] Add a chapter about Clang-tidy integrations. Patch by Marina Kalashina. Differential Revision: https://reviews.llvm.org/D54945 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r351466 | eugenezelenko | 2019-01-17 20:35:39 +0100 (Thu, 17 Jan 2019) | 2 lines [Documentation] Fix link in docs/clang-tidy/Contributing.rst. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r351467 | eugenezelenko | 2019-01-17 20:47:44 +0100 (Thu, 17 Jan 2019) | 2 lines [Documentation] Another attempt to fix link in docs/clang-tidy/Contributing.rst. Use HTTPS for links. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r351468 | eugenezelenko | 2019-01-17 21:00:23 +0100 (Thu, 17 Jan 2019) | 2 lines [Documentation] Fix another link in docs/clang-tidy/Contributing.rst. ------------------------------------------------------------------------ llvm-svn: 351538 --- .../docs/clang-tidy/Contributing.rst | 512 ++++++++++++++++++ .../docs/clang-tidy/Integrations.rst | 117 ++++ clang-tools-extra/docs/clang-tidy/index.rst | 510 +---------------- 3 files changed, 631 insertions(+), 508 deletions(-) create mode 100644 clang-tools-extra/docs/clang-tidy/Contributing.rst create mode 100644 clang-tools-extra/docs/clang-tidy/Integrations.rst diff --git a/clang-tools-extra/docs/clang-tidy/Contributing.rst b/clang-tools-extra/docs/clang-tidy/Contributing.rst new file mode 100644 index 0000000000000..6d61809ecb337 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/Contributing.rst @@ -0,0 +1,512 @@ +================ +Getting Involved +================ + +:program:`clang-tidy` has several own checks and can run Clang static analyzer +checks, but its power is in the ability to easily write custom checks. + +Checks are organized in modules, which can be linked into :program:`clang-tidy` +with minimal or no code changes in :program:`clang-tidy`. + +Checks can plug into the analysis on the preprocessor level using `PPCallbacks`_ +or on the AST level using `AST Matchers`_. When an error is found, checks can +report them in a way similar to how Clang diagnostics work. A fix-it hint can be +attached to a diagnostic message. + +The interface provided by :program:`clang-tidy` makes it easy to write useful +and precise checks in just a few lines of code. If you have an idea for a good +check, the rest of this document explains how to do this. + +There are a few tools particularly useful when developing clang-tidy checks: + * ``add_new_check.py`` is a script to automate the process of adding a new + check, it will create the check, update the CMake file and create a test; + * ``rename_check.py`` does what the script name suggests, renames an existing + check; + * :program:`clang-query` is invaluable for interactive prototyping of AST + matchers and exploration of the Clang AST; + * `clang-check`_ with the ``-ast-dump`` (and optionally ``-ast-dump-filter``) + provides a convenient way to dump AST of a C++ program. + +If CMake is configured with ``CLANG_ENABLE_STATIC_ANALYZER``, +:program:`clang-tidy` will not be built with support for the +``clang-analyzer-*`` checks or the ``mpi-*`` checks. + + +.. _AST Matchers: https://clang.llvm.org/docs/LibASTMatchers.html +.. _PPCallbacks: https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html +.. _clang-check: https://clang.llvm.org/docs/ClangCheck.html + + +Choosing the Right Place for your Check +--------------------------------------- + +If you have an idea of a check, you should decide whether it should be +implemented as a: + ++ *Clang diagnostic*: if the check is generic enough, targets code patterns that + most probably are bugs (rather than style or readability issues), can be + implemented effectively and with extremely low false positive rate, it may + make a good Clang diagnostic. + ++ *Clang static analyzer check*: if the check requires some sort of control flow + analysis, it should probably be implemented as a static analyzer check. + ++ *clang-tidy check* is a good choice for linter-style checks, checks that are + related to a certain coding style, checks that address code readability, etc. + + +Preparing your Workspace +------------------------ + +If you are new to LLVM development, you should read the `Getting Started with +the LLVM System`_, `Using Clang Tools`_ and `How To Setup Clang Tooling For +LLVM`_ documents to check out and build LLVM, Clang and Clang Extra Tools with +CMake. + +Once you are done, change to the ``llvm/tools/clang/tools/extra`` directory, and +let's start! + +.. _Getting Started with the LLVM System: https://llvm.org/docs/GettingStarted.html +.. _Using Clang Tools: https://clang.llvm.org/docs/ClangTools.html +.. _How To Setup Clang Tooling For LLVM: https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html + + +The Directory Structure +----------------------- + +:program:`clang-tidy` source code resides in the +``llvm/tools/clang/tools/extra`` directory and is structured as follows: + +:: + + clang-tidy/ # Clang-tidy core. + |-- ClangTidy.h # Interfaces for users and checks. + |-- ClangTidyModule.h # Interface for clang-tidy modules. + |-- ClangTidyModuleRegistry.h # Interface for registering of modules. + ... + |-- google/ # Google clang-tidy module. + |-+ + |-- GoogleTidyModule.cpp + |-- GoogleTidyModule.h + ... + |-- llvm/ # LLVM clang-tidy module. + |-+ + |-- LLVMTidyModule.cpp + |-- LLVMTidyModule.h + ... + |-- objc/ # Objective-C clang-tidy module. + |-+ + |-- ObjCTidyModule.cpp + |-- ObjCTidyModule.h + ... + |-- tool/ # Sources of the clang-tidy binary. + ... + test/clang-tidy/ # Integration tests. + ... + unittests/clang-tidy/ # Unit tests. + |-- ClangTidyTest.h + |-- GoogleModuleTest.cpp + |-- LLVMModuleTest.cpp + |-- ObjCModuleTest.cpp + ... + + +Writing a clang-tidy Check +-------------------------- + +So you have an idea of a useful check for :program:`clang-tidy`. + +First, if you're not familiar with LLVM development, read through the `Getting +Started with LLVM`_ document for instructions on setting up your workflow and +the `LLVM Coding Standards`_ document to familiarize yourself with the coding +style used in the project. For code reviews we mostly use `LLVM Phabricator`_. + +.. _Getting Started with LLVM: https://llvm.org/docs/GettingStarted.html +.. _LLVM Coding Standards: https://llvm.org/docs/CodingStandards.html +.. _LLVM Phabricator: https://llvm.org/docs/Phabricator.html + +Next, you need to decide which module the check belongs to. Modules +are located in subdirectories of `clang-tidy/ +`_ +and contain checks targeting a certain aspect of code quality (performance, +readability, etc.), certain coding style or standard (Google, LLVM, CERT, etc.) +or a widely used API (e.g. MPI). Their names are same as user-facing check +groups names described :ref:`above `. + +After choosing the module and the name for the check, run the +``clang-tidy/add_new_check.py`` script to create the skeleton of the check and +plug it to :program:`clang-tidy`. It's the recommended way of adding new checks. + +If we want to create a `readability-awesome-function-names`, we would run: + +.. code-block:: console + + $ clang-tidy/add_new_check.py readability awesome-function-names + + +The ``add_new_check.py`` script will: + * create the class for your check inside the specified module's directory and + register it in the module and in the build system; + * create a lit test file in the ``test/clang-tidy/`` directory; + * create a documentation file and include it into the + ``docs/clang-tidy/checks/list.rst``. + +Let's see in more detail at the check class definition: + +.. code-block:: c++ + + ... + + #include "../ClangTidy.h" + + namespace clang { + namespace tidy { + namespace readability { + + ... + class AwesomeFunctionNamesCheck : public ClangTidyCheck { + public: + AwesomeFunctionNamesCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + }; + + } // namespace readability + } // namespace tidy + } // namespace clang + + ... + +Constructor of the check receives the ``Name`` and ``Context`` parameters, and +must forward them to the ``ClangTidyCheck`` constructor. + +In our case the check needs to operate on the AST level and it overrides the +``registerMatchers`` and ``check`` methods. If we wanted to analyze code on the +preprocessor level, we'd need instead to override the ``registerPPCallbacks`` +method. + +In the ``registerMatchers`` method we create an AST Matcher (see `AST Matchers`_ +for more information) that will find the pattern in the AST that we want to +inspect. The results of the matching are passed to the ``check`` method, which +can further inspect them and report diagnostics. + +.. code-block:: c++ + + using namespace ast_matchers; + + void AwesomeFunctionNamesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(functionDecl().bind("x"), this); + } + + void AwesomeFunctionNamesCheck::check(const MatchFinder::MatchResult &Result) { + const auto *MatchedDecl = Result.Nodes.getNodeAs("x"); + if (MatchedDecl->getName().startswith("awesome_")) + return; + diag(MatchedDecl->getLocation(), "function %0 is insufficiently awesome") + << MatchedDecl + << FixItHint::CreateInsertion(MatchedDecl->getLocation(), "awesome_"); + } + +(If you want to see an example of a useful check, look at +`clang-tidy/google/ExplicitConstructorCheck.h +`_ +and `clang-tidy/google/ExplicitConstructorCheck.cpp +`_). + + +Registering your Check +---------------------- + +(The ``add_new_check.py`` takes care of registering the check in an existing +module. If you want to create a new module or know the details, read on.) + +The check should be registered in the corresponding module with a distinct name: + +.. code-block:: c++ + + class MyModule : public ClangTidyModule { + public: + void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { + CheckFactories.registerCheck( + "my-explicit-constructor"); + } + }; + +Now we need to register the module in the ``ClangTidyModuleRegistry`` using a +statically initialized variable: + +.. code-block:: c++ + + static ClangTidyModuleRegistry::Add X("my-module", + "Adds my lint checks."); + + +When using LLVM build system, we need to use the following hack to ensure the +module is linked into the :program:`clang-tidy` binary: + +Add this near the ``ClangTidyModuleRegistry::Add`` variable: + +.. code-block:: c++ + + // This anchor is used to force the linker to link in the generated object file + // and thus register the MyModule. + volatile int MyModuleAnchorSource = 0; + +And this to the main translation unit of the :program:`clang-tidy` binary (or +the binary you link the ``clang-tidy`` library in) +``clang-tidy/tool/ClangTidyMain.cpp``: + +.. code-block:: c++ + + // This anchor is used to force the linker to link the MyModule. + extern volatile int MyModuleAnchorSource; + static int MyModuleAnchorDestination = MyModuleAnchorSource; + + +Configuring Checks +------------------ + +If a check needs configuration options, it can access check-specific options +using the ``Options.get("SomeOption", DefaultValue)`` call in the check +constructor. In this case the check should also override the +``ClangTidyCheck::storeOptions`` method to make the options provided by the +check discoverable. This method lets :program:`clang-tidy` know which options +the check implements and what the current values are (e.g. for the +``-dump-config`` command line option). + +.. code-block:: c++ + + class MyCheck : public ClangTidyCheck { + const unsigned SomeOption1; + const std::string SomeOption2; + + public: + MyCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + SomeOption(Options.get("SomeOption1", -1U)), + SomeOption(Options.get("SomeOption2", "some default")) {} + + void storeOptions(ClangTidyOptions::OptionMap &Opts) override { + Options.store(Opts, "SomeOption1", SomeOption1); + Options.store(Opts, "SomeOption2", SomeOption2); + } + ... + +Assuming the check is registered with the name "my-check", the option can then +be set in a ``.clang-tidy`` file in the following way: + +.. code-block:: yaml + + CheckOptions: + - key: my-check.SomeOption1 + value: 123 + - key: my-check.SomeOption2 + value: 'some other value' + +If you need to specify check options on a command line, you can use the inline +YAML format: + +.. code-block:: console + + $ clang-tidy -config="{CheckOptions: [{key: a, value: b}, {key: x, value: y}]}" ... + + +Testing Checks +-------------- + +To run tests for :program:`clang-tidy` use the command: + +.. code-block:: console + + $ ninja check-clang-tools + +:program:`clang-tidy` checks can be tested using either unit tests or +`lit`_ tests. Unit tests may be more convenient to test complex replacements +with strict checks. `Lit`_ tests allow using partial text matching and regular +expressions which makes them more suitable for writing compact tests for +diagnostic messages. + +The ``check_clang_tidy.py`` script provides an easy way to test both +diagnostic messages and fix-its. It filters out ``CHECK`` lines from the test +file, runs :program:`clang-tidy` and verifies messages and fixes with two +separate `FileCheck`_ invocations: once with FileCheck's directive +prefix set to ``CHECK-MESSAGES``, validating the diagnostic messages, +and once with the directive prefix set to ``CHECK-FIXES``, running +against the fixed code (i.e., the code after generated fix-its are +applied). In particular, ``CHECK-FIXES:`` can be used to check +that code was not modified by fix-its, by checking that it is present +unchanged in the fixed code. The full set of `FileCheck`_ directives +is available (e.g., ``CHECK-MESSAGES-SAME:``, ``CHECK-MESSAGES-NOT:``), though +typically the basic ``CHECK`` forms (``CHECK-MESSAGES`` and ``CHECK-FIXES``) +are sufficient for clang-tidy tests. Note that the `FileCheck`_ +documentation mostly assumes the default prefix (``CHECK``), and hence +describes the directive as ``CHECK:``, ``CHECK-SAME:``, ``CHECK-NOT:``, etc. +Replace ``CHECK`` by either ``CHECK-FIXES`` or ``CHECK-MESSAGES`` for +clang-tidy tests. + +An additional check enabled by ``check_clang_tidy.py`` ensures that +if `CHECK-MESSAGES:` is used in a file then every warning or error +must have an associated CHECK in that file. Or, you can use ``CHECK-NOTES:`` +instead, if you want to **also** ensure that all the notes are checked. + +To use the ``check_clang_tidy.py`` script, put a .cpp file with the +appropriate ``RUN`` line in the ``test/clang-tidy`` directory. Use +``CHECK-MESSAGES:`` and ``CHECK-FIXES:`` lines to write checks against +diagnostic messages and fixed code. + +It's advised to make the checks as specific as possible to avoid checks matching +to incorrect parts of the input. Use ``[[@LINE+X]]``/``[[@LINE-X]]`` +substitutions and distinct function and variable names in the test code. + +Here's an example of a test using the ``check_clang_tidy.py`` script (the full +source code is at `test/clang-tidy/google-readability-casting.cpp`_): + +.. code-block:: c++ + + // RUN: %check_clang_tidy %s google-readability-casting %t + + void f(int a) { + int b = (int)a; + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant cast to the same type [google-readability-casting] + // CHECK-FIXES: int b = a; + } + +To check more than one scenario in the same test file use +``-check-suffix=SUFFIX-NAME`` on ``check_clang_tidy.py`` command line or +``-check-suffixes=SUFFIX-NAME-1,SUFFIX-NAME-2,...``. +With ``-check-suffix[es]=SUFFIX-NAME`` you need to replace your ``CHECK-*`` +directives with ``CHECK-MESSAGES-SUFFIX-NAME`` and ``CHECK-FIXES-SUFFIX-NAME``. + +Here's an example: + +.. code-block:: c++ + + // RUN: %check_clang_tidy -check-suffix=USING-A %s misc-unused-using-decls %t -- -- -DUSING_A + // RUN: %check_clang_tidy -check-suffix=USING-B %s misc-unused-using-decls %t -- -- -DUSING_B + // RUN: %check_clang_tidy %s misc-unused-using-decls %t + ... + // CHECK-MESSAGES-USING-A: :[[@LINE-8]]:10: warning: using decl 'A' {{.*}} + // CHECK-MESSAGES-USING-B: :[[@LINE-7]]:10: warning: using decl 'B' {{.*}} + // CHECK-MESSAGES: :[[@LINE-6]]:10: warning: using decl 'C' {{.*}} + // CHECK-FIXES-USING-A-NOT: using a::A;$ + // CHECK-FIXES-USING-B-NOT: using a::B;$ + // CHECK-FIXES-NOT: using a::C;$ + + +There are many dark corners in the C++ language, and it may be difficult to make +your check work perfectly in all cases, especially if it issues fix-it hints. The +most frequent pitfalls are macros and templates: + +1. code written in a macro body/template definition may have a different meaning + depending on the macro expansion/template instantiation; +2. multiple macro expansions/template instantiations may result in the same code + being inspected by the check multiple times (possibly, with different + meanings, see 1), and the same warning (or a slightly different one) may be + issued by the check multiple times; :program:`clang-tidy` will deduplicate + _identical_ warnings, but if the warnings are slightly different, all of them + will be shown to the user (and used for applying fixes, if any); +3. making replacements to a macro body/template definition may be fine for some + macro expansions/template instantiations, but easily break some other + expansions/instantiations. + +.. _lit: https://llvm.org/docs/CommandGuide/lit.html +.. _FileCheck: https://llvm.org/docs/CommandGuide/FileCheck.html +.. _test/clang-tidy/google-readability-casting.cpp: https://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/test/clang-tidy/google-readability-casting.cpp + + +Running clang-tidy on LLVM +-------------------------- + +To test a check it's best to try it out on a larger code base. LLVM and Clang +are the natural targets as you already have the source code around. The most +convenient way to run :program:`clang-tidy` is with a compile command database; +CMake can automatically generate one, for a description of how to enable it see +`How To Setup Clang Tooling For LLVM`_. Once ``compile_commands.json`` is in +place and a working version of :program:`clang-tidy` is in ``PATH`` the entire +code base can be analyzed with ``clang-tidy/tool/run-clang-tidy.py``. The script +executes :program:`clang-tidy` with the default set of checks on every +translation unit in the compile command database and displays the resulting +warnings and errors. The script provides multiple configuration flags. + +.. _How To Setup Clang Tooling For LLVM: https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html + + +* The default set of checks can be overridden using the ``-checks`` argument, + taking the identical format as :program:`clang-tidy` does. For example + ``-checks=-*,modernize-use-override`` will run the ``modernize-use-override`` + check only. + +* To restrict the files examined you can provide one or more regex arguments + that the file names are matched against. + ``run-clang-tidy.py clang-tidy/.*Check\.cpp`` will only analyze clang-tidy + checks. It may also be necessary to restrict the header files warnings are + displayed from using the ``-header-filter`` flag. It has the same behavior + as the corresponding :program:`clang-tidy` flag. + +* To apply suggested fixes ``-fix`` can be passed as an argument. This gathers + all changes in a temporary directory and applies them. Passing ``-format`` + will run clang-format over changed lines. + + +On checks profiling +------------------- + +:program:`clang-tidy` can collect per-check profiling info, and output it +for each processed source file (translation unit). + +To enable profiling info collection, use the ``-enable-check-profile`` argument. +The timings will be output to ``stderr`` as a table. Example output: + +.. code-block:: console + + $ clang-tidy -enable-check-profile -checks=-*,readability-function-size source.cpp + ===-------------------------------------------------------------------------=== + clang-tidy checks profiling + ===-------------------------------------------------------------------------=== + Total Execution Time: 1.0282 seconds (1.0258 wall clock) + + ---User Time--- --System Time-- --User+System-- ---Wall Time--- --- Name --- + 0.9136 (100.0%) 0.1146 (100.0%) 1.0282 (100.0%) 1.0258 (100.0%) readability-function-size + 0.9136 (100.0%) 0.1146 (100.0%) 1.0282 (100.0%) 1.0258 (100.0%) Total + +It can also store that data as JSON files for further processing. Example output: + +.. code-block:: console + + $ clang-tidy -enable-check-profile -store-check-profile=. -checks=-*,readability-function-size source.cpp + $ # Note that there won't be timings table printed to the console. + $ ls /tmp/out/ + 20180516161318717446360-source.cpp.json + $ cat 20180516161318717446360-source.cpp.json + { + "file": "/path/to/source.cpp", + "timestamp": "2018-05-16 16:13:18.717446360", + "profile": { + "time.clang-tidy.readability-function-size.wall": 1.0421266555786133e+00, + "time.clang-tidy.readability-function-size.user": 9.2088400000005421e-01, + "time.clang-tidy.readability-function-size.sys": 1.2418899999999974e-01 + } + } + +There is only one argument that controls profile storage: + +* ``-store-check-profile=`` + + By default reports are printed in tabulated format to stderr. When this option + is passed, these per-TU profiles are instead stored as JSON. + If the prefix is not an absolute path, it is considered to be relative to the + directory from where you have run :program:`clang-tidy`. All ``.`` and ``..`` + patterns in the path are collapsed, and symlinks are resolved. + + Example: + Let's suppose you have a source file named ``example.cpp``, located in the + ``/source`` directory. Only the input filename is used, not the full path + to the source file. Additionally, it is prefixed with the current timestamp. + + * If you specify ``-store-check-profile=/tmp``, then the profile will be saved + to ``/tmp/-example.cpp.json`` + + * If you run :program:`clang-tidy` from within ``/foo`` directory, and specify + ``-store-check-profile=.``, then the profile will still be saved to + ``/foo/-example.cpp.json`` diff --git a/clang-tools-extra/docs/clang-tidy/Integrations.rst b/clang-tools-extra/docs/clang-tidy/Integrations.rst new file mode 100644 index 0000000000000..2d1e195645f5d --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/Integrations.rst @@ -0,0 +1,117 @@ +================================== +Clang-tidy IDE/Editor Integrations +================================== + +.. _Clangd: https://clang.llvm.org/extra/clangd.html + +Apart from being a standalone tool, :program:`clang-tidy` is integrated into +various IDEs, code analyzers, and editors. Besides, it is currently being +integrated into Clangd_. The following table shows the most +well-known :program:`clang-tidy` integrations in detail. + ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +| | Feature | ++======================================+========================+=================================+==========================+=========================================+==========================+ +| **Tool** | On-the-fly inspection | Check list configuration (GUI) | Options to checks (GUI) | Configuration via ``.clang-tidy`` files | Custom clang-tidy binary | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|A.L.E. for Vim | \+\ | \-\ | \-\ | \-\ | \+\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|Clang Power Tools for Visual Studio | \-\ | \+\ | \-\ | \+\ | \-\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|Clangd | \+\ | \-\ | \-\ | \-\ | \-\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|CLion IDE | \+\ | \+\ | \+\ | \+\ | \+\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|CodeChecker | \-\ | \-\ | \-\ | \-\ | \+\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|CPPCheck | \-\ | \-\ | \-\ | \-\ | \-\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|CPPDepend | \-\ | \-\ | \-\ | \-\ | \-\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|Flycheck for Emacs | \+\ | \-\ | \-\ | \+\ | \+\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|KDevelop IDE | \-\ | \+\ | \+\ | \+\ | \+\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|Qt Creator IDE | \+\ | \+\ | \-\ | \-\ | \+\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|ReSharper C++ for Visual Studio | \+\ | \+\ | \-\ | \+\ | \-\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|Syntastic for Vim | \+\ | \-\ | \-\ | \-\ | \+\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|Visual Assist for Visual Studio | \+\ | \+\ | \-\ | \-\ | \-\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ + +**IDEs** + +.. _CLion: https://www.jetbrains.com/clion/ +.. _integrates clang-tidy: https://www.jetbrains.com/help/clion/clang-tidy-checks-support.html + +CLion_ 2017.2 and later `integrates clang-tidy`_ as an extension to the +built-in code analyzer. Starting from 2018.2 EAP, CLion allows using +:program:`clang-tidy` via Clangd. Inspections and applicable quick-fixes are +performed on the fly, and checks can be configured in standard command line +format. In this integration, you can switch to the :program:`clang-tidy` +binary different from the bundled one, pass the configuration in +``.clang-tidy`` files instead of using the IDE settings, and configure +options for particular checks. + +.. _KDevelop: https://www.kdevelop.org/ +.. _kdev-clang-tidy: https://github.com/KDE/kdev-clang-tidy/ + +KDevelop_ with the kdev-clang-tidy_ plugin, starting from version 5.1, performs +static analysis using :program:`clang-tidy`. The plugin launches the +:program:`clang-tidy` binary from the specified location and parses its +output to provide a list of issues. + +.. _QtCreator: https://www.qt.io/ +.. _Clang Code Model: http://doc.qt.io/qtcreator/creator-clang-codemodel.html + +QtCreator_ 4.6 integrates :program:`clang-tidy` warnings into the editor +diagnostics under the `Clang Code Model`_. To employ :program:`clang-tidy` +inspection in QtCreator, you need to create a copy of one of the presets and +choose the checks to be performed in the Clang Code Model Warnings menu. + +.. _MS Visual Studio: https://visualstudio.microsoft.com/ +.. _ReSharper C++: https://www.jetbrains.com/help/resharper/Clang_Tidy_Integration.html +.. _Visual Assist: https://docs.wholetomato.com/default.asp?W761 +.. _Clang Power Tools: https://marketplace.visualstudio.com/items?itemName=caphyon.ClangPowerTools +.. _clang-tidy-vs: https://github.com/llvm-mirror/clang-tools-extra/tree/master/clang-tidy-vs + +`MS Visual Studio`_ has a native clang-tidy-vs_ plugin and also can integrate +:program:`clang-tidy` by means of three other tools. The `ReSharper C++`_ +extension, version 2017.3 and later, provides seamless :program:`clang-tidy` +integration: checks and quick-fixes run alongside native inspections. Apart +from that, ReSharper C++ incorporates :program:`clang-tidy` as a separate +step of its code clean-up process. `Visual Assist`_ build 2210 includes a +subset of :program:`clang-tidy` checklist to inspect the code as you edit. +Another way to bring :program:`clang-tidy` functionality to Visual Studio is +the `Clang Power Tools`_ plugin, which includes most of the +:program:`clang-tidy` checks and runs them during compilation or as a separate +step of code analysis. + +**Editors** + +.. _Flycheck: https://github.com/ch1bo/flycheck-clang-tidy +.. _Syntastic: https://github.com/vim-syntastic/syntastic +.. _A.L.E.: https://github.com/w0rp/ale +.. _Emacs24: https://www.gnu.org/s/emacs/ +.. _Vim: https://www.vim.org/ + +Emacs24_, when expanded with the Flycheck_ plugin, incorporates the +:program:`clang-tidy` inspection into the syntax analyzer. For Vim_, you can +use Syntastic_, which includes :program:`clang-tidy`, or `A.L.E.`_, +a lint engine that applies :program:`clang-tidy` along with other linters. + +**Analyzers** + +.. _CPPDepend: https://www.cppdepend.com/cppdependv2018 +.. _CPPCheck: https://sourceforge.net/p/cppcheck/news/ +.. _CodeChecker: https://github.com/Ericsson/codechecker +.. _plugin: https://github.com/Ericsson/CodeCheckerEclipsePlugin + +:program:`clang-tidy` is integrated in CPPDepend_ starting from version 2018.1 +and CPPCheck_ 1.82. CPPCheck integration lets you import Visual Studio +solutions and run the :program:`clang-tidy` inspection on them. The +CodeChecker_ application of version 5.3 or later, which also comes as a plugin_ +for Eclipse, supports :program:`clang-tidy` as a static analysis instrument and +allows to use a custom :program:`clang-tidy` binary. diff --git a/clang-tools-extra/docs/clang-tidy/index.rst b/clang-tools-extra/docs/clang-tidy/index.rst index 20b18b4bf5989..4172d13487c53 100644 --- a/clang-tools-extra/docs/clang-tidy/index.rst +++ b/clang-tools-extra/docs/clang-tidy/index.rst @@ -10,6 +10,8 @@ See also: :maxdepth: 1 The list of clang-tidy checks + Clang-tidy IDE/Editor Integrations + Getting Involved :program:`clang-tidy` is a clang-based C++ "linter" tool. Its purpose is to provide an extensible framework for diagnosing and fixing typical programming @@ -310,511 +312,3 @@ the parenthesis) whitespaces can be used and will be ignored. .. _LibTooling: http://clang.llvm.org/docs/LibTooling.html .. _How To Setup Tooling For LLVM: http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html - - -Getting Involved -================ - -:program:`clang-tidy` has several own checks and can run Clang static analyzer -checks, but its power is in the ability to easily write custom checks. - -Checks are organized in modules, which can be linked into :program:`clang-tidy` -with minimal or no code changes in :program:`clang-tidy`. - -Checks can plug into the analysis on the preprocessor level using `PPCallbacks`_ -or on the AST level using `AST Matchers`_. When an error is found, checks can -report them in a way similar to how Clang diagnostics work. A fix-it hint can be -attached to a diagnostic message. - -The interface provided by :program:`clang-tidy` makes it easy to write useful -and precise checks in just a few lines of code. If you have an idea for a good -check, the rest of this document explains how to do this. - -There are a few tools particularly useful when developing clang-tidy checks: - * ``add_new_check.py`` is a script to automate the process of adding a new - check, it will create the check, update the CMake file and create a test; - * ``rename_check.py`` does what the script name suggests, renames an existing - check; - * :program:`clang-query` is invaluable for interactive prototyping of AST - matchers and exploration of the Clang AST; - * `clang-check`_ with the ``-ast-dump`` (and optionally ``-ast-dump-filter``) - provides a convenient way to dump AST of a C++ program. - -If CMake is configured with ``CLANG_ENABLE_STATIC_ANALYZER``, -:program:`clang-tidy` will not be built with support for the -``clang-analyzer-*`` checks or the ``mpi-*`` checks. - - -.. _AST Matchers: http://clang.llvm.org/docs/LibASTMatchers.html -.. _PPCallbacks: http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html -.. _clang-check: http://clang.llvm.org/docs/ClangCheck.html - - -Choosing the Right Place for your Check ---------------------------------------- - -If you have an idea of a check, you should decide whether it should be -implemented as a: - -+ *Clang diagnostic*: if the check is generic enough, targets code patterns that - most probably are bugs (rather than style or readability issues), can be - implemented effectively and with extremely low false positive rate, it may - make a good Clang diagnostic. - -+ *Clang static analyzer check*: if the check requires some sort of control flow - analysis, it should probably be implemented as a static analyzer check. - -+ *clang-tidy check* is a good choice for linter-style checks, checks that are - related to a certain coding style, checks that address code readability, etc. - - -Preparing your Workspace ------------------------- - -If you are new to LLVM development, you should read the `Getting Started with -the LLVM System`_, `Using Clang Tools`_ and `How To Setup Tooling For LLVM`_ -documents to check out and build LLVM, Clang and Clang Extra Tools with CMake. - -Once you are done, change to the ``llvm/tools/clang/tools/extra`` directory, and -let's start! - -.. _Getting Started with the LLVM System: http://llvm.org/docs/GettingStarted.html -.. _Using Clang Tools: http://clang.llvm.org/docs/ClangTools.html - - -The Directory Structure ------------------------ - -:program:`clang-tidy` source code resides in the -``llvm/tools/clang/tools/extra`` directory and is structured as follows: - -:: - - clang-tidy/ # Clang-tidy core. - |-- ClangTidy.h # Interfaces for users and checks. - |-- ClangTidyModule.h # Interface for clang-tidy modules. - |-- ClangTidyModuleRegistry.h # Interface for registering of modules. - ... - |-- google/ # Google clang-tidy module. - |-+ - |-- GoogleTidyModule.cpp - |-- GoogleTidyModule.h - ... - |-- llvm/ # LLVM clang-tidy module. - |-+ - |-- LLVMTidyModule.cpp - |-- LLVMTidyModule.h - ... - |-- objc/ # Objective-C clang-tidy module. - |-+ - |-- ObjCTidyModule.cpp - |-- ObjCTidyModule.h - ... - |-- tool/ # Sources of the clang-tidy binary. - ... - test/clang-tidy/ # Integration tests. - ... - unittests/clang-tidy/ # Unit tests. - |-- ClangTidyTest.h - |-- GoogleModuleTest.cpp - |-- LLVMModuleTest.cpp - |-- ObjCModuleTest.cpp - ... - - -Writing a clang-tidy Check --------------------------- - -So you have an idea of a useful check for :program:`clang-tidy`. - -First, if you're not familiar with LLVM development, read through the `Getting -Started with LLVM`_ document for instructions on setting up your workflow and -the `LLVM Coding Standards`_ document to familiarize yourself with the coding -style used in the project. For code reviews we mostly use `LLVM Phabricator`_. - -.. _Getting Started with LLVM: http://llvm.org/docs/GettingStarted.html -.. _LLVM Coding Standards: http://llvm.org/docs/CodingStandards.html -.. _LLVM Phabricator: http://llvm.org/docs/Phabricator.html - -Next, you need to decide which module the check belongs to. Modules -are located in subdirectories of `clang-tidy/ -`_ -and contain checks targeting a certain aspect of code quality (performance, -readability, etc.), certain coding style or standard (Google, LLVM, CERT, etc.) -or a widely used API (e.g. MPI). Their names are same as user-facing check -groups names described :ref:`above `. - -After choosing the module and the name for the check, run the -``clang-tidy/add_new_check.py`` script to create the skeleton of the check and -plug it to :program:`clang-tidy`. It's the recommended way of adding new checks. - -If we want to create a `readability-awesome-function-names`, we would run: - -.. code-block:: console - - $ clang-tidy/add_new_check.py readability awesome-function-names - - -The ``add_new_check.py`` script will: - * create the class for your check inside the specified module's directory and - register it in the module and in the build system; - * create a lit test file in the ``test/clang-tidy/`` directory; - * create a documentation file and include it into the - ``docs/clang-tidy/checks/list.rst``. - -Let's see in more detail at the check class definition: - -.. code-block:: c++ - - ... - - #include "../ClangTidy.h" - - namespace clang { - namespace tidy { - namespace readability { - - ... - class AwesomeFunctionNamesCheck : public ClangTidyCheck { - public: - AwesomeFunctionNamesCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} - void registerMatchers(ast_matchers::MatchFinder *Finder) override; - void check(const ast_matchers::MatchFinder::MatchResult &Result) override; - }; - - } // namespace readability - } // namespace tidy - } // namespace clang - - ... - -Constructor of the check receives the ``Name`` and ``Context`` parameters, and -must forward them to the ``ClangTidyCheck`` constructor. - -In our case the check needs to operate on the AST level and it overrides the -``registerMatchers`` and ``check`` methods. If we wanted to analyze code on the -preprocessor level, we'd need instead to override the ``registerPPCallbacks`` -method. - -In the ``registerMatchers`` method we create an AST Matcher (see `AST Matchers`_ -for more information) that will find the pattern in the AST that we want to -inspect. The results of the matching are passed to the ``check`` method, which -can further inspect them and report diagnostics. - -.. code-block:: c++ - - using namespace ast_matchers; - - void AwesomeFunctionNamesCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher(functionDecl().bind("x"), this); - } - - void AwesomeFunctionNamesCheck::check(const MatchFinder::MatchResult &Result) { - const auto *MatchedDecl = Result.Nodes.getNodeAs("x"); - if (MatchedDecl->getName().startswith("awesome_")) - return; - diag(MatchedDecl->getLocation(), "function %0 is insufficiently awesome") - << MatchedDecl - << FixItHint::CreateInsertion(MatchedDecl->getLocation(), "awesome_"); - } - -(If you want to see an example of a useful check, look at -`clang-tidy/google/ExplicitConstructorCheck.h -`_ -and `clang-tidy/google/ExplicitConstructorCheck.cpp -`_). - - -Registering your Check ----------------------- - -(The ``add_new_check.py`` takes care of registering the check in an existing -module. If you want to create a new module or know the details, read on.) - -The check should be registered in the corresponding module with a distinct name: - -.. code-block:: c++ - - class MyModule : public ClangTidyModule { - public: - void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { - CheckFactories.registerCheck( - "my-explicit-constructor"); - } - }; - -Now we need to register the module in the ``ClangTidyModuleRegistry`` using a -statically initialized variable: - -.. code-block:: c++ - - static ClangTidyModuleRegistry::Add X("my-module", - "Adds my lint checks."); - - -When using LLVM build system, we need to use the following hack to ensure the -module is linked into the :program:`clang-tidy` binary: - -Add this near the ``ClangTidyModuleRegistry::Add`` variable: - -.. code-block:: c++ - - // This anchor is used to force the linker to link in the generated object file - // and thus register the MyModule. - volatile int MyModuleAnchorSource = 0; - -And this to the main translation unit of the :program:`clang-tidy` binary (or -the binary you link the ``clang-tidy`` library in) -``clang-tidy/tool/ClangTidyMain.cpp``: - -.. code-block:: c++ - - // This anchor is used to force the linker to link the MyModule. - extern volatile int MyModuleAnchorSource; - static int MyModuleAnchorDestination = MyModuleAnchorSource; - - -Configuring Checks ------------------- - -If a check needs configuration options, it can access check-specific options -using the ``Options.get("SomeOption", DefaultValue)`` call in the check -constructor. In this case the check should also override the -``ClangTidyCheck::storeOptions`` method to make the options provided by the -check discoverable. This method lets :program:`clang-tidy` know which options -the check implements and what the current values are (e.g. for the -``-dump-config`` command line option). - -.. code-block:: c++ - - class MyCheck : public ClangTidyCheck { - const unsigned SomeOption1; - const std::string SomeOption2; - - public: - MyCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), - SomeOption(Options.get("SomeOption1", -1U)), - SomeOption(Options.get("SomeOption2", "some default")) {} - - void storeOptions(ClangTidyOptions::OptionMap &Opts) override { - Options.store(Opts, "SomeOption1", SomeOption1); - Options.store(Opts, "SomeOption2", SomeOption2); - } - ... - -Assuming the check is registered with the name "my-check", the option can then -be set in a ``.clang-tidy`` file in the following way: - -.. code-block:: yaml - - CheckOptions: - - key: my-check.SomeOption1 - value: 123 - - key: my-check.SomeOption2 - value: 'some other value' - -If you need to specify check options on a command line, you can use the inline -YAML format: - -.. code-block:: console - - $ clang-tidy -config="{CheckOptions: [{key: a, value: b}, {key: x, value: y}]}" ... - - -Testing Checks --------------- - -To run tests for :program:`clang-tidy` use the command: - -.. code-block:: console - - $ ninja check-clang-tools - -:program:`clang-tidy` checks can be tested using either unit tests or -`lit`_ tests. Unit tests may be more convenient to test complex replacements -with strict checks. `Lit`_ tests allow using partial text matching and regular -expressions which makes them more suitable for writing compact tests for -diagnostic messages. - -The ``check_clang_tidy.py`` script provides an easy way to test both -diagnostic messages and fix-its. It filters out ``CHECK`` lines from the test -file, runs :program:`clang-tidy` and verifies messages and fixes with two -separate `FileCheck`_ invocations: once with FileCheck's directive -prefix set to ``CHECK-MESSAGES``, validating the diagnostic messages, -and once with the directive prefix set to ``CHECK-FIXES``, running -against the fixed code (i.e., the code after generated fix-its are -applied). In particular, ``CHECK-FIXES:`` can be used to check -that code was not modified by fix-its, by checking that it is present -unchanged in the fixed code. The full set of `FileCheck`_ directives -is available (e.g., ``CHECK-MESSAGES-SAME:``, ``CHECK-MESSAGES-NOT:``), though -typically the basic ``CHECK`` forms (``CHECK-MESSAGES`` and ``CHECK-FIXES``) -are sufficient for clang-tidy tests. Note that the `FileCheck`_ -documentation mostly assumes the default prefix (``CHECK``), and hence -describes the directive as ``CHECK:``, ``CHECK-SAME:``, ``CHECK-NOT:``, etc. -Replace ``CHECK`` by either ``CHECK-FIXES`` or ``CHECK-MESSAGES`` for -clang-tidy tests. - -An additional check enabled by ``check_clang_tidy.py`` ensures that -if `CHECK-MESSAGES:` is used in a file then every warning or error -must have an associated CHECK in that file. Or, you can use ``CHECK-NOTES:`` -instead, if you want to **also** ensure that all the notes are checked. - -To use the ``check_clang_tidy.py`` script, put a .cpp file with the -appropriate ``RUN`` line in the ``test/clang-tidy`` directory. Use -``CHECK-MESSAGES:`` and ``CHECK-FIXES:`` lines to write checks against -diagnostic messages and fixed code. - -It's advised to make the checks as specific as possible to avoid checks matching -to incorrect parts of the input. Use ``[[@LINE+X]]``/``[[@LINE-X]]`` -substitutions and distinct function and variable names in the test code. - -Here's an example of a test using the ``check_clang_tidy.py`` script (the full -source code is at `test/clang-tidy/google-readability-casting.cpp`_): - -.. code-block:: c++ - - // RUN: %check_clang_tidy %s google-readability-casting %t - - void f(int a) { - int b = (int)a; - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant cast to the same type [google-readability-casting] - // CHECK-FIXES: int b = a; - } - -To check more than one scenario in the same test file use -``-check-suffix=SUFFIX-NAME`` on ``check_clang_tidy.py`` command line or -``-check-suffixes=SUFFIX-NAME-1,SUFFIX-NAME-2,...``. -With ``-check-suffix[es]=SUFFIX-NAME`` you need to replace your ``CHECK-*`` -directives with ``CHECK-MESSAGES-SUFFIX-NAME`` and ``CHECK-FIXES-SUFFIX-NAME``. - -Here's an example: - -.. code-block:: c++ - - // RUN: %check_clang_tidy -check-suffix=USING-A %s misc-unused-using-decls %t -- -- -DUSING_A - // RUN: %check_clang_tidy -check-suffix=USING-B %s misc-unused-using-decls %t -- -- -DUSING_B - // RUN: %check_clang_tidy %s misc-unused-using-decls %t - ... - // CHECK-MESSAGES-USING-A: :[[@LINE-8]]:10: warning: using decl 'A' {{.*}} - // CHECK-MESSAGES-USING-B: :[[@LINE-7]]:10: warning: using decl 'B' {{.*}} - // CHECK-MESSAGES: :[[@LINE-6]]:10: warning: using decl 'C' {{.*}} - // CHECK-FIXES-USING-A-NOT: using a::A;$ - // CHECK-FIXES-USING-B-NOT: using a::B;$ - // CHECK-FIXES-NOT: using a::C;$ - - -There are many dark corners in the C++ language, and it may be difficult to make -your check work perfectly in all cases, especially if it issues fix-it hints. The -most frequent pitfalls are macros and templates: - -1. code written in a macro body/template definition may have a different meaning - depending on the macro expansion/template instantiation; -2. multiple macro expansions/template instantiations may result in the same code - being inspected by the check multiple times (possibly, with different - meanings, see 1), and the same warning (or a slightly different one) may be - issued by the check multiple times; :program:`clang-tidy` will deduplicate - _identical_ warnings, but if the warnings are slightly different, all of them - will be shown to the user (and used for applying fixes, if any); -3. making replacements to a macro body/template definition may be fine for some - macro expansions/template instantiations, but easily break some other - expansions/instantiations. - -.. _lit: http://llvm.org/docs/CommandGuide/lit.html -.. _FileCheck: http://llvm.org/docs/CommandGuide/FileCheck.html -.. _test/clang-tidy/google-readability-casting.cpp: http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/test/clang-tidy/google-readability-casting.cpp - - -Running clang-tidy on LLVM --------------------------- - -To test a check it's best to try it out on a larger code base. LLVM and Clang -are the natural targets as you already have the source code around. The most -convenient way to run :program:`clang-tidy` is with a compile command database; -CMake can automatically generate one, for a description of how to enable it see -`How To Setup Tooling For LLVM`_. Once ``compile_commands.json`` is in place and -a working version of :program:`clang-tidy` is in ``PATH`` the entire code base -can be analyzed with ``clang-tidy/tool/run-clang-tidy.py``. The script executes -:program:`clang-tidy` with the default set of checks on every translation unit -in the compile command database and displays the resulting warnings and errors. -The script provides multiple configuration flags. - -* The default set of checks can be overridden using the ``-checks`` argument, - taking the identical format as :program:`clang-tidy` does. For example - ``-checks=-*,modernize-use-override`` will run the ``modernize-use-override`` - check only. - -* To restrict the files examined you can provide one or more regex arguments - that the file names are matched against. - ``run-clang-tidy.py clang-tidy/.*Check\.cpp`` will only analyze clang-tidy - checks. It may also be necessary to restrict the header files warnings are - displayed from using the ``-header-filter`` flag. It has the same behavior - as the corresponding :program:`clang-tidy` flag. - -* To apply suggested fixes ``-fix`` can be passed as an argument. This gathers - all changes in a temporary directory and applies them. Passing ``-format`` - will run clang-format over changed lines. - - -On checks profiling -------------------- - -:program:`clang-tidy` can collect per-check profiling info, and output it -for each processed source file (translation unit). - -To enable profiling info collection, use the ``-enable-check-profile`` argument. -The timings will be output to ``stderr`` as a table. Example output: - -.. code-block:: console - - $ clang-tidy -enable-check-profile -checks=-*,readability-function-size source.cpp - ===-------------------------------------------------------------------------=== - clang-tidy checks profiling - ===-------------------------------------------------------------------------=== - Total Execution Time: 1.0282 seconds (1.0258 wall clock) - - ---User Time--- --System Time-- --User+System-- ---Wall Time--- --- Name --- - 0.9136 (100.0%) 0.1146 (100.0%) 1.0282 (100.0%) 1.0258 (100.0%) readability-function-size - 0.9136 (100.0%) 0.1146 (100.0%) 1.0282 (100.0%) 1.0258 (100.0%) Total - -It can also store that data as JSON files for further processing. Example output: - -.. code-block:: console - - $ clang-tidy -enable-check-profile -store-check-profile=. -checks=-*,readability-function-size source.cpp - $ # Note that there won't be timings table printed to the console. - $ ls /tmp/out/ - 20180516161318717446360-source.cpp.json - $ cat 20180516161318717446360-source.cpp.json - { - "file": "/path/to/source.cpp", - "timestamp": "2018-05-16 16:13:18.717446360", - "profile": { - "time.clang-tidy.readability-function-size.wall": 1.0421266555786133e+00, - "time.clang-tidy.readability-function-size.user": 9.2088400000005421e-01, - "time.clang-tidy.readability-function-size.sys": 1.2418899999999974e-01 - } - } - -There is only one argument that controls profile storage: - -* ``-store-check-profile=`` - - By default reports are printed in tabulated format to stderr. When this option - is passed, these per-TU profiles are instead stored as JSON. - If the prefix is not an absolute path, it is considered to be relative to the - directory from where you have run :program:`clang-tidy`. All ``.`` and ``..`` - patterns in the path are collapsed, and symlinks are resolved. - - Example: - Let's suppose you have a source file named ``example.cpp``, located in the - ``/source`` directory. Only the input filename is used, not the full path - to the source file. Additionally, it is prefixed with the current timestamp. - - * If you specify ``-store-check-profile=/tmp``, then the profile will be saved - to ``/tmp/-example.cpp.json`` - - * If you run :program:`clang-tidy` from within ``/foo`` directory, and specify - ``-store-check-profile=.``, then the profile will still be saved to - ``/foo/-example.cpp.json`` From e264daec97935db606c312b10e43f4e35ac39b58 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 18 Jan 2019 10:57:19 +0000 Subject: [PATCH 028/274] Merging r351426: ------------------------------------------------------------------------ r351426 | d0k | 2019-01-17 11:25:18 +0100 (Thu, 17 Jan 2019) | 1 line [MC] Remove unused variable ------------------------------------------------------------------------ llvm-svn: 351543 --- llvm/lib/MC/MCWin64EH.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/lib/MC/MCWin64EH.cpp b/llvm/lib/MC/MCWin64EH.cpp index 2e4eea3411f4b..8bc1f08c88750 100644 --- a/llvm/lib/MC/MCWin64EH.cpp +++ b/llvm/lib/MC/MCWin64EH.cpp @@ -517,7 +517,6 @@ static void ARM64EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) { auto &EpilogInstrs = I.second; uint32_t CodeBytes = ARM64CountOfUnwindCodes(EpilogInstrs); - uint32_t NumUnwindCodes = EpilogInstrs.size(); MCSymbol* MatchingEpilog = FindMatchingEpilog(EpilogInstrs, AddedEpilogs, info); if (MatchingEpilog) { From 119d8a51d9175e528dfaa2a5f2170ab206699a81 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 22 Jan 2019 16:59:31 +0000 Subject: [PATCH 029/274] Merging r351580: ------------------------------------------------------------------------ r351580 | kli | 2019-01-18 20:57:37 +0100 (Fri, 18 Jan 2019) | 4 lines [OPENMP][DOCS] Release notes/OpenMP support updates, NFC. Differential Revision: https://reviews.llvm.org/D56733 ------------------------------------------------------------------------ llvm-svn: 351839 --- clang/docs/OpenMPSupport.rst | 76 ++++++++++++++++-------------------- clang/docs/ReleaseNotes.rst | 22 ++++++++--- 2 files changed, 50 insertions(+), 48 deletions(-) diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst index 04a9648ca2942..7b567c966ee53 100644 --- a/clang/docs/OpenMPSupport.rst +++ b/clang/docs/OpenMPSupport.rst @@ -17,60 +17,50 @@ OpenMP Support ================== -Clang fully supports OpenMP 4.5. Clang supports offloading to X86_64, AArch64, -PPC64[LE] and has `basic support for Cuda devices`_. - -Standalone directives -===================== - -* #pragma omp [for] simd: :good:`Complete`. - -* #pragma omp declare simd: :partial:`Partial`. We support parsing/semantic - analysis + generation of special attributes for X86 target, but still - missing the LLVM pass for vectorization. - -* #pragma omp taskloop [simd]: :good:`Complete`. - -* #pragma omp target [enter|exit] data: :good:`Complete`. - -* #pragma omp target update: :good:`Complete`. - -* #pragma omp target: :good:`Complete`. +Clang supports the following OpenMP 5.0 features -* #pragma omp declare target: :good:`Complete`. +* The `reduction`-based clauses in the `task` and `target`-based directives. -* #pragma omp teams: :good:`Complete`. +* Support relational-op != (not-equal) as one of the canonical forms of random + access iterator. -* #pragma omp distribute [simd]: :good:`Complete`. +* Support for mapping of the lambdas in target regions. -* #pragma omp distribute parallel for [simd]: :good:`Complete`. +* Parsing/sema analysis for the requires directive. -Combined directives -=================== +* Nested declare target directives. -* #pragma omp parallel for simd: :good:`Complete`. +* Make the `this` pointer implicitly mapped as `map(this[:1])`. -* #pragma omp target parallel: :good:`Complete`. +* The `close` *map-type-modifier*. -* #pragma omp target parallel for [simd]: :good:`Complete`. - -* #pragma omp target simd: :good:`Complete`. - -* #pragma omp target teams: :good:`Complete`. - -* #pragma omp teams distribute [simd]: :good:`Complete`. - -* #pragma omp target teams distribute [simd]: :good:`Complete`. - -* #pragma omp teams distribute parallel for [simd]: :good:`Complete`. - -* #pragma omp target teams distribute parallel for [simd]: :good:`Complete`. +Clang fully supports OpenMP 4.5. Clang supports offloading to X86_64, AArch64, +PPC64[LE] and has `basic support for Cuda devices`_. -Clang does not support any constructs/updates from OpenMP 5.0 except -for `reduction`-based clauses in the `task` and `target`-based directives. +* #pragma omp declare simd: :partial:`Partial`. We support parsing/semantic + analysis + generation of special attributes for X86 target, but still + missing the LLVM pass for vectorization. In addition, the LLVM OpenMP runtime `libomp` supports the OpenMP Tools -Interface (OMPT) on x86, x86_64, AArch64, and PPC64 on Linux, Windows, and mac OS. +Interface (OMPT) on x86, x86_64, AArch64, and PPC64 on Linux, Windows, and macOS. + +General improvements +-------------------- +- New collapse clause scheme to avoid expensive remainder operations. + Compute loop index variables after collapsing a loop nest via the + collapse clause by replacing the expensive remainder operation with + multiplications and additions. + +- The default schedules for the `distribute` and `for` constructs in a + parallel region and in SPMD mode have changed to ensure coalesced + accesses. For the `distribute` construct, a static schedule is used + with a chunk size equal to the number of threads per team (default + value of threads or as specified by the `thread_limit` clause if + present). For the `for` construct, the schedule is static with chunk + size of one. + +- Simplified SPMD code generation for `distribute parallel for` when + the new default schedules are applicable. .. _basic support for Cuda devices: diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b6a405dbc78b2..b4f290e05d787 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -233,12 +233,15 @@ ABI Changes in Clang OpenMP Support in Clang ---------------------------------- -- Support relational-op != (not-equal) as one of the canonical forms of random - access iterator. +- OpenMP 5.0 features -- Added support for mapping of the lambdas in target regions. - -- Added parsing/sema analysis for OpenMP 5.0 requires directive. + - Support relational-op != (not-equal) as one of the canonical forms of random + access iterator. + - Added support for mapping of the lambdas in target regions. + - Added parsing/sema analysis for the requires directive. + - Support nested declare target directives. + - Make the `this` pointer implicitly mapped as `map(this[:1])`. + - Added the `close` *map-type-modifier*. - Various bugfixes and improvements. @@ -250,6 +253,15 @@ New features supported for Cuda devices: - Fixed support for lastprivate/reduction variables in SPMD constructs. +- New collapse clause scheme to avoid expensive remainder operations. + +- New default schedule for distribute and parallel constructs. + +- Simplified code generation for distribute and parallel in SPMD mode. + +- Flag (``-fopenmp_optimistic_collapse``) for user to limit collapsed + loop counter width when safe to do so. + - General performance improvement. CUDA Support in Clang From eb74b596b7dee5157be24f6e3693ab66930065de Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 22 Jan 2019 17:32:41 +0000 Subject: [PATCH 030/274] Merging r351686: ------------------------------------------------------------------------ r351686 | vmiklos | 2019-01-20 15:28:27 +0100 (Sun, 20 Jan 2019) | 5 lines [clang-tidy] misc-non-private-member-variables-in-classes: ignore implicit methods Otherwise we don't warn on a struct containing a single public int, but we warn on a struct containing a single public std::string, which is inconsistent. ------------------------------------------------------------------------ llvm-svn: 351844 --- .../NonPrivateMemberVariablesInClassesCheck.cpp | 11 ++++++----- ...-non-private-member-variables-in-classes.rst | 10 +++++----- ...-non-private-member-variables-in-classes.cpp | 17 +++++++++++++++++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/clang-tools-extra/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp b/clang-tools-extra/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp index c0bdbfbfe0424..bac7f898785a0 100644 --- a/clang-tools-extra/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp @@ -23,8 +23,8 @@ AST_MATCHER(CXXRecordDecl, hasMethods) { return std::distance(Node.method_begin(), Node.method_end()) != 0; } -AST_MATCHER(CXXRecordDecl, hasNonStaticMethod) { - return hasMethod(unless(isStaticStorageClass())) +AST_MATCHER(CXXRecordDecl, hasNonStaticNonImplicitMethod) { + return hasMethod(unless(anyOf(isStaticStorageClass(), isImplicit()))) .matches(Node, Finder, Builder); } @@ -67,10 +67,11 @@ void NonPrivateMemberVariablesInClassesCheck::registerMatchers( IgnorePublicMemberVariables ? isProtected() : unless(isPrivate())); // We only want the records that not only contain the mutable data (non-static - // member variables), but also have some logic (non-static member functions). - // We may optionally ignore records where all the member variables are public. + // member variables), but also have some logic (non-static, non-implicit + // member functions). We may optionally ignore records where all the member + // variables are public. Finder->addMatcher(cxxRecordDecl(anyOf(isStruct(), isClass()), hasMethods(), - hasNonStaticMethod(), + hasNonStaticNonImplicitMethod(), unless(ShouldIgnoreRecord), forEach(InterestingField.bind("field"))) .bind("record"), diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst b/clang-tools-extra/docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst index db88c9b1cffd8..57990622e60cd 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst @@ -6,11 +6,11 @@ misc-non-private-member-variables-in-classes `cppcoreguidelines-non-private-member-variables-in-classes` redirects here as an alias for this check. -Finds classes that contain non-static data members in addition to non-static -member functions and diagnose all data members declared with a non-``public`` -access specifier. The data members should be declared as ``private`` and -accessed through member functions instead of exposed to derived classes or -class consumers. +Finds classes that contain non-static data members in addition to user-declared +non-static member functions and diagnose all data members declared with a +non-``public`` access specifier. The data members should be declared as +``private`` and accessed through member functions instead of exposed to derived +classes or class consumers. Options ------- diff --git a/clang-tools-extra/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp b/clang-tools-extra/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp index 31052716d2873..2a93ff6a18c38 100644 --- a/clang-tools-extra/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp +++ b/clang-tools-extra/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp @@ -35,6 +35,23 @@ class S1 { int S1_v3; }; +// Only data and implicit or static methods, do not warn + +class C { +public: + C() {} + ~C() {} +}; + +struct S1Implicit { + C S1Implicit_v0; +}; + +struct S1ImplicitAndStatic { + C S1Implicit_v0; + static void s() {} +}; + //----------------------------------------------------------------------------// // All functions are static, do not warn. From 2bebfebe54decbe7b91c9e5dc552bc0eaeef703b Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 22 Jan 2019 19:02:30 +0000 Subject: [PATCH 031/274] Merging r351753: ------------------------------------------------------------------------ r351753 | spatel | 2019-01-21 18:30:14 +0100 (Mon, 21 Jan 2019) | 8 lines [DAGCombiner] fix crash when converting build vector to shuffle The regression test is reduced from the example shown in D56281. This does raise a question as noted in the test file: do we want to handle this pattern? I don't have a motivating example for that on x86 yet, but it seems like we could have that pattern there too, so we could avoid the back-and-forth using a shuffle. ------------------------------------------------------------------------ llvm-svn: 351857 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 16 +++++++++----- .../CodeGen/AArch64/build-vector-extract.ll | 22 +++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/build-vector-extract.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index ff5505c977213..6af01423ca106 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -16214,23 +16214,29 @@ static SDValue reduceBuildVecToShuffleWithZero(SDNode *BV, SelectionDAG &DAG) { // The build vector contains some number of undef elements and exactly // one other element. That other element must be a zero-extended scalar // extracted from a vector at a constant index to turn this into a shuffle. + // Also, require that the build vector does not implicitly truncate/extend + // its elements. // TODO: This could be enhanced to allow ANY_EXTEND as well as ZERO_EXTEND. + EVT VT = BV->getValueType(0); SDValue Zext = BV->getOperand(ZextElt); if (Zext.getOpcode() != ISD::ZERO_EXTEND || !Zext.hasOneUse() || Zext.getOperand(0).getOpcode() != ISD::EXTRACT_VECTOR_ELT || - !isa(Zext.getOperand(0).getOperand(1))) + !isa(Zext.getOperand(0).getOperand(1)) || + Zext.getValueSizeInBits() != VT.getScalarSizeInBits()) return SDValue(); - // The zero-extend must be a multiple of the source size. + // The zero-extend must be a multiple of the source size, and we must be + // building a vector of the same size as the source of the extract element. SDValue Extract = Zext.getOperand(0); unsigned DestSize = Zext.getValueSizeInBits(); unsigned SrcSize = Extract.getValueSizeInBits(); - if (DestSize % SrcSize != 0) + if (DestSize % SrcSize != 0 || + Extract.getOperand(0).getValueSizeInBits() != VT.getSizeInBits()) return SDValue(); // Create a shuffle mask that will combine the extracted element with zeros // and undefs. - int ZextRatio = DestSize / SrcSize; + int ZextRatio = DestSize / SrcSize; int NumMaskElts = NumBVOps * ZextRatio; SmallVector ShufMask(NumMaskElts, -1); for (int i = 0; i != NumMaskElts; ++i) { @@ -16260,7 +16266,7 @@ static SDValue reduceBuildVecToShuffleWithZero(SDNode *BV, SelectionDAG &DAG) { SDValue ZeroVec = DAG.getConstant(0, DL, VecVT); SDValue Shuf = DAG.getVectorShuffle(VecVT, DL, Extract.getOperand(0), ZeroVec, ShufMask); - return DAG.getBitcast(BV->getValueType(0), Shuf); + return DAG.getBitcast(VT, Shuf); } // Check to see if this is a BUILD_VECTOR of a bunch of EXTRACT_VECTOR_ELT diff --git a/llvm/test/CodeGen/AArch64/build-vector-extract.ll b/llvm/test/CodeGen/AArch64/build-vector-extract.ll new file mode 100644 index 0000000000000..bba3a22cf33ea --- /dev/null +++ b/llvm/test/CodeGen/AArch64/build-vector-extract.ll @@ -0,0 +1,22 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s + +; This would crash because we did not expect to create +; a shuffle for a vector where the source operand is +; not the same size as the result. +; TODO: Should we handle this pattern? Ie, is moving to/from +; registers the optimal code? + +define <4 x i32> @larger_bv_than_source(<4 x i16> %t0) { +; CHECK-LABEL: larger_bv_than_source: +; CHECK: // %bb.0: +; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-NEXT: umov w8, v0.h[2] +; CHECK-NEXT: fmov s0, w8 +; CHECK-NEXT: ret + %t1 = extractelement <4 x i16> %t0, i32 2 + %vgetq_lane = zext i16 %t1 to i32 + %t2 = insertelement <4 x i32> undef, i32 %vgetq_lane, i64 0 + ret <4 x i32> %t2 +} + From ee231d02587208edbb3381b8186f03b97ac9934c Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 22 Jan 2019 19:04:30 +0000 Subject: [PATCH 032/274] Merging r351754: ------------------------------------------------------------------------ r351754 | spatel | 2019-01-21 18:46:35 +0100 (Mon, 21 Jan 2019) | 6 lines [AArch64] add more tests for buildvec to shuffle transform; NFC These are copied from the sibling x86 file. I'm not sure which of the current outputs (if any) is considered optimal, but someone more familiar with AArch may want to take a look. ------------------------------------------------------------------------ llvm-svn: 351858 --- .../CodeGen/AArch64/build-vector-extract.ll | 419 ++++++++++++++++++ 1 file changed, 419 insertions(+) diff --git a/llvm/test/CodeGen/AArch64/build-vector-extract.ll b/llvm/test/CodeGen/AArch64/build-vector-extract.ll index bba3a22cf33ea..a785533e8db9b 100644 --- a/llvm/test/CodeGen/AArch64/build-vector-extract.ll +++ b/llvm/test/CodeGen/AArch64/build-vector-extract.ll @@ -1,6 +1,425 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s +define <2 x i64> @extract0_i32_zext_insert0_i64_undef(<4 x i32> %x) { +; CHECK-LABEL: extract0_i32_zext_insert0_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: movi v1.2d, #0000000000000000 +; CHECK-NEXT: zip1 v0.4s, v0.4s, v1.4s +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 0 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract0_i32_zext_insert0_i64_zero(<4 x i32> %x) { +; CHECK-LABEL: extract0_i32_zext_insert0_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov w8, s0 +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[0], x8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 0 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract1_i32_zext_insert0_i64_undef(<4 x i32> %x) { +; CHECK-LABEL: extract1_i32_zext_insert0_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: zip1 v0.4s, v0.4s, v0.4s +; CHECK-NEXT: movi v1.2d, #0000000000000000 +; CHECK-NEXT: ext v0.16b, v0.16b, v1.16b, #12 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 1 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract1_i32_zext_insert0_i64_zero(<4 x i32> %x) { +; CHECK-LABEL: extract1_i32_zext_insert0_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, v0.s[1] +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[0], x8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 1 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract2_i32_zext_insert0_i64_undef(<4 x i32> %x) { +; CHECK-LABEL: extract2_i32_zext_insert0_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: uzp1 v0.4s, v0.4s, v0.4s +; CHECK-NEXT: movi v1.2d, #0000000000000000 +; CHECK-NEXT: ext v0.16b, v0.16b, v1.16b, #12 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 2 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract2_i32_zext_insert0_i64_zero(<4 x i32> %x) { +; CHECK-LABEL: extract2_i32_zext_insert0_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, v0.s[2] +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[0], x8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 2 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract3_i32_zext_insert0_i64_undef(<4 x i32> %x) { +; CHECK-LABEL: extract3_i32_zext_insert0_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: movi v1.2d, #0000000000000000 +; CHECK-NEXT: ext v0.16b, v0.16b, v1.16b, #12 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 3 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract3_i32_zext_insert0_i64_zero(<4 x i32> %x) { +; CHECK-LABEL: extract3_i32_zext_insert0_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, v0.s[3] +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[0], x8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 3 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract0_i32_zext_insert1_i64_undef(<4 x i32> %x) { +; CHECK-LABEL: extract0_i32_zext_insert1_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: movi v1.2d, #0000000000000000 +; CHECK-NEXT: zip1 v1.4s, v0.4s, v1.4s +; CHECK-NEXT: ext v0.16b, v0.16b, v1.16b, #8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 0 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract0_i32_zext_insert1_i64_zero(<4 x i32> %x) { +; CHECK-LABEL: extract0_i32_zext_insert1_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov w8, s0 +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 0 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract1_i32_zext_insert1_i64_undef(<4 x i32> %x) { +; CHECK-LABEL: extract1_i32_zext_insert1_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: ext v0.16b, v0.16b, v0.16b, #8 +; CHECK-NEXT: movi v1.2d, #0000000000000000 +; CHECK-NEXT: ext v0.16b, v0.16b, v1.16b, #4 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 1 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract1_i32_zext_insert1_i64_zero(<4 x i32> %x) { +; CHECK-LABEL: extract1_i32_zext_insert1_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, v0.s[1] +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 1 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract2_i32_zext_insert1_i64_undef(<4 x i32> %x) { +; CHECK-LABEL: extract2_i32_zext_insert1_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: mov v0.s[3], wzr +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 2 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract2_i32_zext_insert1_i64_zero(<4 x i32> %x) { +; CHECK-LABEL: extract2_i32_zext_insert1_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, v0.s[2] +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 2 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract3_i32_zext_insert1_i64_undef(<4 x i32> %x) { +; CHECK-LABEL: extract3_i32_zext_insert1_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: movi v1.2d, #0000000000000000 +; CHECK-NEXT: ext v0.16b, v0.16b, v1.16b, #4 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 3 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract3_i32_zext_insert1_i64_zero(<4 x i32> %x) { +; CHECK-LABEL: extract3_i32_zext_insert1_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, v0.s[3] +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: ret + %e = extractelement <4 x i32> %x, i32 3 + %z = zext i32 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract0_i16_zext_insert0_i64_undef(<8 x i16> %x) { +; CHECK-LABEL: extract0_i16_zext_insert0_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[0] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: fmov d0, x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 0 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract0_i16_zext_insert0_i64_zero(<8 x i16> %x) { +; CHECK-LABEL: extract0_i16_zext_insert0_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[0] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[0], x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 0 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract1_i16_zext_insert0_i64_undef(<8 x i16> %x) { +; CHECK-LABEL: extract1_i16_zext_insert0_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[1] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: fmov d0, x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 1 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract1_i16_zext_insert0_i64_zero(<8 x i16> %x) { +; CHECK-LABEL: extract1_i16_zext_insert0_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[1] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[0], x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 1 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract2_i16_zext_insert0_i64_undef(<8 x i16> %x) { +; CHECK-LABEL: extract2_i16_zext_insert0_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[2] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: fmov d0, x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 2 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract2_i16_zext_insert0_i64_zero(<8 x i16> %x) { +; CHECK-LABEL: extract2_i16_zext_insert0_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[2] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[0], x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 2 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract3_i16_zext_insert0_i64_undef(<8 x i16> %x) { +; CHECK-LABEL: extract3_i16_zext_insert0_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[3] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: fmov d0, x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 3 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract3_i16_zext_insert0_i64_zero(<8 x i16> %x) { +; CHECK-LABEL: extract3_i16_zext_insert0_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[3] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[0], x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 3 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0 + ret <2 x i64> %r +} + +define <2 x i64> @extract0_i16_zext_insert1_i64_undef(<8 x i16> %x) { +; CHECK-LABEL: extract0_i16_zext_insert1_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[0] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: dup v0.2d, x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 0 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract0_i16_zext_insert1_i64_zero(<8 x i16> %x) { +; CHECK-LABEL: extract0_i16_zext_insert1_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[0] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 0 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract1_i16_zext_insert1_i64_undef(<8 x i16> %x) { +; CHECK-LABEL: extract1_i16_zext_insert1_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[1] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: dup v0.2d, x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 1 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract1_i16_zext_insert1_i64_zero(<8 x i16> %x) { +; CHECK-LABEL: extract1_i16_zext_insert1_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[1] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 1 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract2_i16_zext_insert1_i64_undef(<8 x i16> %x) { +; CHECK-LABEL: extract2_i16_zext_insert1_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[2] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: dup v0.2d, x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 2 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract2_i16_zext_insert1_i64_zero(<8 x i16> %x) { +; CHECK-LABEL: extract2_i16_zext_insert1_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[2] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 2 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract3_i16_zext_insert1_i64_undef(<8 x i16> %x) { +; CHECK-LABEL: extract3_i16_zext_insert1_i64_undef: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[3] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: dup v0.2d, x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 3 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> undef, i64 %z, i32 1 + ret <2 x i64> %r +} + +define <2 x i64> @extract3_i16_zext_insert1_i64_zero(<8 x i16> %x) { +; CHECK-LABEL: extract3_i16_zext_insert1_i64_zero: +; CHECK: // %bb.0: +; CHECK-NEXT: umov w8, v0.h[3] +; CHECK-NEXT: and x8, x8, #0xffff +; CHECK-NEXT: movi v0.2d, #0000000000000000 +; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: ret + %e = extractelement <8 x i16> %x, i32 3 + %z = zext i16 %e to i64 + %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1 + ret <2 x i64> %r +} + ; This would crash because we did not expect to create ; a shuffle for a vector where the source operand is ; not the same size as the result. From 642a1732ef4f120cae6a55725b83bf74c2fa9323 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 22 Jan 2019 19:07:58 +0000 Subject: [PATCH 033/274] Merging r351788: ------------------------------------------------------------------------ r351788 | kadircet | 2019-01-22 10:10:20 +0100 (Tue, 22 Jan 2019) | 15 lines [clangd] Filter out plugin related flags and move all commandline manipulations into OverlayCDB. Summary: Some projects make use of clang plugins when building, but clangd is not aware of those plugins therefore can't work with the same compile command arguments. There were multiple places clangd performed commandline manipulations, this one also moves them all into OverlayCDB. Reviewers: ilya-biryukov Subscribers: klimek, sammccall, ioeric, MaskRay, jkorous, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D56841 ------------------------------------------------------------------------ llvm-svn: 351860 --- clang-tools-extra/clangd/ClangdLSPServer.cpp | 3 +- clang-tools-extra/clangd/ClangdServer.cpp | 13 +----- .../clangd/GlobalCompilationDatabase.cpp | 41 +++++++++++++++++-- .../clangd/GlobalCompilationDatabase.h | 5 ++- clang-tools-extra/clangd/index/Background.cpp | 10 ++--- clang-tools-extra/clangd/index/Background.h | 5 +-- .../unittests/clangd/BackgroundIndexTests.cpp | 24 +++++------ .../unittests/clangd/ClangdTests.cpp | 23 +++++++++++ .../clangd/GlobalCompilationDatabaseTests.cpp | 4 +- 9 files changed, 86 insertions(+), 42 deletions(-) diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index 80792eddc69a9..97a5e89c47837 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -290,7 +290,8 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, if (UseDirBasedCDB) BaseCDB = llvm::make_unique( CompileCommandsDir); - CDB.emplace(BaseCDB.get(), Params.initializationOptions.fallbackFlags); + CDB.emplace(BaseCDB.get(), Params.initializationOptions.fallbackFlags, + ClangdServerOpts.ResourceDir); Server.emplace(*CDB, FSProvider, static_cast(*this), ClangdServerOpts); applyConfiguration(Params.initializationOptions.ConfigSettings); diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index 53a27bdb91d5f..a4ab622e101ed 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -38,11 +38,6 @@ namespace clang { namespace clangd { namespace { -std::string getStandardResourceDir() { - static int Dummy; // Just an address in this process. - return CompilerInvocation::GetResourcesPath("clangd", (void *)&Dummy); -} - class RefactoringResultCollector final : public tooling::RefactoringResultConsumer { public: @@ -108,8 +103,6 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, DiagnosticsConsumer &DiagConsumer, const Options &Opts) : CDB(CDB), FSProvider(FSProvider), - ResourceDir(Opts.ResourceDir ? *Opts.ResourceDir - : getStandardResourceDir()), DynamicIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex(Opts.HeavyweightDynamicSymbolIndex) : nullptr), @@ -137,7 +130,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, AddIndex(Opts.StaticIndex); if (Opts.BackgroundIndex) { BackgroundIdx = llvm::make_unique( - Context::current().clone(), ResourceDir, FSProvider, CDB, + Context::current().clone(), FSProvider, CDB, BackgroundIndexStorage::createDiskBackedStorageFactory(), Opts.BackgroundIndexRebuildPeriodMs); AddIndex(BackgroundIdx.get()); @@ -462,10 +455,6 @@ tooling::CompileCommand ClangdServer::getCompileCommand(PathRef File) { llvm::Optional C = CDB.getCompileCommand(File); if (!C) // FIXME: Suppress diagnostics? Let the user know? C = CDB.getFallbackCommand(File); - - // Inject the resource dir. - // FIXME: Don't overwrite it if it's already there. - C->CommandLine.push_back("-resource-dir=" + ResourceDir); return std::move(*C); } diff --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp index c2fff7b20f37b..8c7aa194a1f8e 100644 --- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp +++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp @@ -9,12 +9,36 @@ #include "GlobalCompilationDatabase.h" #include "Logger.h" +#include "clang/Frontend/CompilerInvocation.h" +#include "clang/Tooling/ArgumentsAdjusters.h" #include "clang/Tooling/CompilationDatabase.h" +#include "llvm/ADT/Optional.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" namespace clang { namespace clangd { +namespace { + +void adjustArguments(tooling::CompileCommand &Cmd, + llvm::StringRef ResourceDir) { + // Strip plugin related command line arguments. Clangd does + // not support plugins currently. Therefore it breaks if + // compiler tries to load plugins. + Cmd.CommandLine = + tooling::getStripPluginsAdjuster()(Cmd.CommandLine, Cmd.Filename); + // Inject the resource dir. + // FIXME: Don't overwrite it if it's already there. + if (!ResourceDir.empty()) + Cmd.CommandLine.push_back(("-resource-dir=" + ResourceDir).str()); +} + +std::string getStandardResourceDir() { + static int Dummy; // Just an address in this process. + return CompilerInvocation::GetResourcesPath("clangd", (void *)&Dummy); +} + +} // namespace static std::string getFallbackClangPath() { static int Dummy; @@ -106,8 +130,11 @@ DirectoryBasedGlobalCompilationDatabase::getCDBForFile( } OverlayCDB::OverlayCDB(const GlobalCompilationDatabase *Base, - std::vector FallbackFlags) - : Base(Base), FallbackFlags(std::move(FallbackFlags)) { + std::vector FallbackFlags, + llvm::Optional ResourceDir) + : Base(Base), ResourceDir(ResourceDir ? std::move(*ResourceDir) + : getStandardResourceDir()), + FallbackFlags(std::move(FallbackFlags)) { if (Base) BaseChanged = Base->watch([this](const std::vector Changes) { OnCommandChanged.broadcast(Changes); @@ -116,16 +143,22 @@ OverlayCDB::OverlayCDB(const GlobalCompilationDatabase *Base, llvm::Optional OverlayCDB::getCompileCommand(PathRef File, ProjectInfo *Project) const { + llvm::Optional Cmd; { std::lock_guard Lock(Mutex); auto It = Commands.find(File); if (It != Commands.end()) { if (Project) Project->SourceRoot = ""; - return It->second; + Cmd = It->second; } } - return Base ? Base->getCompileCommand(File, Project) : None; + if (!Cmd && Base) + Cmd = Base->getCompileCommand(File, Project); + if (!Cmd) + return llvm::None; + adjustArguments(*Cmd, ResourceDir); + return Cmd; } tooling::CompileCommand OverlayCDB::getFallbackCommand(PathRef File) const { diff --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.h b/clang-tools-extra/clangd/GlobalCompilationDatabase.h index 181b1781f73b3..6411fd48ced00 100644 --- a/clang-tools-extra/clangd/GlobalCompilationDatabase.h +++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.h @@ -12,6 +12,7 @@ #include "Function.h" #include "Path.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringMap.h" #include #include @@ -98,7 +99,8 @@ class OverlayCDB : public GlobalCompilationDatabase { // Base may be null, in which case no entries are inherited. // FallbackFlags are added to the fallback compile command. OverlayCDB(const GlobalCompilationDatabase *Base, - std::vector FallbackFlags = {}); + std::vector FallbackFlags = {}, + llvm::Optional ResourceDir = llvm::None); llvm::Optional getCompileCommand(PathRef File, ProjectInfo * = nullptr) const override; @@ -113,6 +115,7 @@ class OverlayCDB : public GlobalCompilationDatabase { mutable std::mutex Mutex; llvm::StringMap Commands; /* GUARDED_BY(Mut) */ const GlobalCompilationDatabase *Base; + std::string ResourceDir; std::vector FallbackFlags; CommandChanged::Subscription BaseChanged; }; diff --git a/clang-tools-extra/clangd/index/Background.cpp b/clang-tools-extra/clangd/index/Background.cpp index b9b945c52bdaf..752d5c2876e00 100644 --- a/clang-tools-extra/clangd/index/Background.cpp +++ b/clang-tools-extra/clangd/index/Background.cpp @@ -127,13 +127,12 @@ llvm::SmallString<128> getAbsolutePath(const tooling::CompileCommand &Cmd) { } // namespace BackgroundIndex::BackgroundIndex( - Context BackgroundContext, llvm::StringRef ResourceDir, - const FileSystemProvider &FSProvider, const GlobalCompilationDatabase &CDB, + Context BackgroundContext, const FileSystemProvider &FSProvider, + const GlobalCompilationDatabase &CDB, BackgroundIndexStorage::Factory IndexStorageFactory, size_t BuildIndexPeriodMs, size_t ThreadPoolSize) - : SwapIndex(llvm::make_unique()), ResourceDir(ResourceDir), - FSProvider(FSProvider), CDB(CDB), - BackgroundContext(std::move(BackgroundContext)), + : SwapIndex(llvm::make_unique()), FSProvider(FSProvider), + CDB(CDB), BackgroundContext(std::move(BackgroundContext)), BuildIndexPeriodMs(BuildIndexPeriodMs), SymbolsUpdatedSinceLastIndex(false), IndexStorageFactory(std::move(IndexStorageFactory)), @@ -230,7 +229,6 @@ void BackgroundIndex::enqueue(tooling::CompileCommand Cmd, BackgroundIndexStorage *Storage) { enqueueTask(Bind( [this, Storage](tooling::CompileCommand Cmd) { - Cmd.CommandLine.push_back("-resource-dir=" + ResourceDir); // We can't use llvm::StringRef here since we are going to // move from Cmd during the call below. const std::string FileName = Cmd.Filename; diff --git a/clang-tools-extra/clangd/index/Background.h b/clang-tools-extra/clangd/index/Background.h index 1a1fee68a571e..81675be55b5a0 100644 --- a/clang-tools-extra/clangd/index/Background.h +++ b/clang-tools-extra/clangd/index/Background.h @@ -68,9 +68,7 @@ class BackgroundIndex : public SwapIndex { /// If BuildIndexPeriodMs is greater than 0, the symbol index will only be /// rebuilt periodically (one per \p BuildIndexPeriodMs); otherwise, index is /// rebuilt for each indexed file. - // FIXME: resource-dir injection should be hoisted somewhere common. - BackgroundIndex(Context BackgroundContext, llvm::StringRef ResourceDir, - const FileSystemProvider &, + BackgroundIndex(Context BackgroundContext, const FileSystemProvider &, const GlobalCompilationDatabase &CDB, BackgroundIndexStorage::Factory IndexStorageFactory, size_t BuildIndexPeriodMs = 0, @@ -99,7 +97,6 @@ class BackgroundIndex : public SwapIndex { BackgroundIndexStorage *IndexStorage); // configuration - std::string ResourceDir; const FileSystemProvider &FSProvider; const GlobalCompilationDatabase &CDB; Context BackgroundContext; diff --git a/clang-tools-extra/unittests/clangd/BackgroundIndexTests.cpp b/clang-tools-extra/unittests/clangd/BackgroundIndexTests.cpp index 639d35c876ac7..09a117dbbe7d3 100644 --- a/clang-tools-extra/unittests/clangd/BackgroundIndexTests.cpp +++ b/clang-tools-extra/unittests/clangd/BackgroundIndexTests.cpp @@ -76,7 +76,7 @@ TEST_F(BackgroundIndexTest, NoCrashOnErrorFile) { size_t CacheHits = 0; MemoryShardStorage MSS(Storage, CacheHits); OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); tooling::CompileCommand Cmd; @@ -113,7 +113,7 @@ TEST_F(BackgroundIndexTest, IndexTwoFiles) { size_t CacheHits = 0; MemoryShardStorage MSS(Storage, CacheHits); OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); tooling::CompileCommand Cmd; @@ -168,7 +168,7 @@ TEST_F(BackgroundIndexTest, ShardStorageTest) { // Check nothing is loaded from Storage, but A.cc and A.h has been stored. { OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root/A.cc"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); @@ -178,7 +178,7 @@ TEST_F(BackgroundIndexTest, ShardStorageTest) { { OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); @@ -224,7 +224,7 @@ TEST_F(BackgroundIndexTest, DirectIncludesTest) { Cmd.CommandLine = {"clang++", testPath("root/A.cc")}; { OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root/A.cc"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); @@ -262,7 +262,7 @@ TEST_F(BackgroundIndexTest, DISABLED_PeriodicalIndex) { MemoryShardStorage MSS(Storage, CacheHits); OverlayCDB CDB(/*Base=*/nullptr); BackgroundIndex Idx( - Context::empty(), "", FS, CDB, [&](llvm::StringRef) { return &MSS; }, + Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }, /*BuildIndexPeriodMs=*/500); FS.Files[testPath("root/A.cc")] = "#include \"A.h\""; @@ -310,7 +310,7 @@ TEST_F(BackgroundIndexTest, ShardStorageLoad) { // Check nothing is loaded from Storage, but A.cc and A.h has been stored. { OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root/A.cc"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); @@ -325,7 +325,7 @@ TEST_F(BackgroundIndexTest, ShardStorageLoad) { )cpp"; { OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); @@ -343,7 +343,7 @@ TEST_F(BackgroundIndexTest, ShardStorageLoad) { { CacheHits = 0; OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); @@ -384,7 +384,7 @@ TEST_F(BackgroundIndexTest, ShardStorageEmptyFile) { // Check that A.cc, A.h and B.h has been stored. { OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root/A.cc"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); @@ -400,7 +400,7 @@ TEST_F(BackgroundIndexTest, ShardStorageEmptyFile) { { CacheHits = 0; OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root/A.cc"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); @@ -416,7 +416,7 @@ TEST_F(BackgroundIndexTest, ShardStorageEmptyFile) { { CacheHits = 0; OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root/A.cc"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); diff --git a/clang-tools-extra/unittests/clangd/ClangdTests.cpp b/clang-tools-extra/unittests/clangd/ClangdTests.cpp index c1cc623a05a11..356efe529dde0 100644 --- a/clang-tools-extra/unittests/clangd/ClangdTests.cpp +++ b/clang-tools-extra/unittests/clangd/ClangdTests.cpp @@ -10,6 +10,7 @@ #include "Annotations.h" #include "ClangdLSPServer.h" #include "ClangdServer.h" +#include "GlobalCompilationDatabase.h" #include "Matchers.h" #include "SyncAPI.h" #include "TestFS.h" @@ -1037,6 +1038,28 @@ TEST(ClangdTests, PreambleVFSStatCache) { } #endif +TEST_F(ClangdVFSTest, FlagsWithPlugins) { + MockFSProvider FS; + ErrorCheckingDiagConsumer DiagConsumer; + MockCompilationDatabase CDB; + CDB.ExtraClangFlags = { + "-Xclang", + "-add-plugin", + "-Xclang", + "random-plugin", + }; + OverlayCDB OCDB(&CDB); + ClangdServer Server(OCDB, FS, DiagConsumer, ClangdServer::optsForTest()); + + auto FooCpp = testPath("foo.cpp"); + const auto SourceContents = "int main() { return 0; }"; + FS.Files[FooCpp] = FooCpp; + Server.addDocument(FooCpp, SourceContents); + auto Result = dumpASTWithoutMemoryLocs(Server, FooCpp); + EXPECT_TRUE(Server.blockUntilIdleForTest()) << "Waiting for diagnostics"; + EXPECT_NE(Result, ""); +} + } // namespace } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/unittests/clangd/GlobalCompilationDatabaseTests.cpp b/clang-tools-extra/unittests/clangd/GlobalCompilationDatabaseTests.cpp index b0052c751c27b..41c28bf35d5a3 100644 --- a/clang-tools-extra/unittests/clangd/GlobalCompilationDatabaseTests.cpp +++ b/clang-tools-extra/unittests/clangd/GlobalCompilationDatabaseTests.cpp @@ -65,7 +65,7 @@ class OverlayCDBTest : public ::testing::Test { }; TEST_F(OverlayCDBTest, GetCompileCommand) { - OverlayCDB CDB(Base.get()); + OverlayCDB CDB(Base.get(), {}, std::string("")); EXPECT_EQ(CDB.getCompileCommand(testPath("foo.cc")), Base->getCompileCommand(testPath("foo.cc"))); EXPECT_EQ(CDB.getCompileCommand(testPath("missing.cc")), llvm::None); @@ -85,7 +85,7 @@ TEST_F(OverlayCDBTest, GetFallbackCommand) { } TEST_F(OverlayCDBTest, NoBase) { - OverlayCDB CDB(nullptr, {"-DA=6"}); + OverlayCDB CDB(nullptr, {"-DA=6"}, std::string("")); EXPECT_EQ(CDB.getCompileCommand(testPath("bar.cc")), None); auto Override = cmd(testPath("bar.cc"), "-DA=5"); CDB.setCompileCommand(testPath("bar.cc"), Override); From a05d35f16368b81d8e434cabd44a7c5b285306a4 Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Tue, 22 Jan 2019 20:32:43 +0000 Subject: [PATCH 034/274] [docs] Amend the release notes with more things I've contributed since the last release Differential Revision: https://reviews.llvm.org/D57005 llvm-svn: 351868 --- lld/docs/ReleaseNotes.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst index dc5df6795d993..a146bddd543af 100644 --- a/lld/docs/ReleaseNotes.rst +++ b/lld/docs/ReleaseNotes.rst @@ -66,6 +66,13 @@ MinGW Improvements linked in a different order than with GNU ld, inserting a DWARF exception table terminator too early.) +* lld now supports COFF embedded directives for linking to nondefault + libraries, just like for the normal COFF target. + +* Actually generate a codeview build id signature, even if not creating a PDB. + Previously, the ``--build-id`` option did not actually generate a build id + unless ``--pdb`` was specified. + MachO Improvements ------------------ From 78ecdd7abc4998da861d2bd7c0b9cc4d38c1dae0 Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Tue, 22 Jan 2019 20:36:23 +0000 Subject: [PATCH 035/274] [docs] Add release notes for notable things I've contributed since last release Differential Revision: https://reviews.llvm.org/D57003 llvm-svn: 351870 --- llvm/docs/ReleaseNotes.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index db9cf51949520..cb80459546f54 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -48,6 +48,10 @@ Non-comprehensive list of changes in this release functionality. See `Writing an LLVM Pass `_. +* For MinGW, references to data variables that might need to be imported + from a dll are accessed via a stub, to allow the linker to convert it to + a dllimport if needed. + .. NOTE If you would like to document a larger change, then you can add a subsection about it right here. You can copy the following boilerplate @@ -62,6 +66,13 @@ Changes to the LLVM IR ---------------------- +Changes to the AArch64 Target +----------------------------- + +* Added support for the ``.arch_extension`` assembler directive, just like + on ARM. + + Changes to the ARM Backend -------------------------- From 1e7e3996e3d1ba12a159c378922c360ef874c6c6 Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Tue, 22 Jan 2019 20:41:51 +0000 Subject: [PATCH 036/274] [docs] Add release notes for notable things I've contributed since last release Differential Revision: https://reviews.llvm.org/D57004 llvm-svn: 351872 --- clang/docs/ReleaseNotes.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b4f290e05d787..28be16677ecee 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -136,6 +136,9 @@ New Compiler Flags instrumenting for gcov-based profiling. See the :doc:`UsersManual` for details. +- When using a custom stack alignment, the ``stackrealign`` attribute is now + implicitly set on the main function. + - ... Deprecated Compiler Flags @@ -179,6 +182,15 @@ Windows Support `dllexport` and `dllimport` attributes not apply to inline member functions. This can significantly reduce compile and link times. See the `User's Manual `_ for more info. + +- For MinGW, ``-municode`` now correctly defines ``UNICODE`` during + preprocessing. + +- For MinGW, clang now produces vtables and RTTI for dllexported classes + without key functions. This fixes building Qt in debug mode. + +- Allow using Address Sanitizer and Undefined Behaviour Sanitizer on MinGW. + - ... From d0fae09cb63df0498dc6cf2581113416a8fe3cde Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 23 Jan 2019 16:18:07 +0000 Subject: [PATCH 037/274] Merging r351531: ------------------------------------------------------------------------ r351531 | kadircet | 2019-01-18 10:00:31 +0100 (Fri, 18 Jan 2019) | 11 lines [tooling] Add a new argument adjuster for deleting plugin related command line args Summary: Currently both clangd and clang-tidy makes use of this mechanism so putting it into tooling so that all tools can make use of it. Reviewers: ilya-biryukov, sammccall Subscribers: ioeric, cfe-commits Differential Revision: https://reviews.llvm.org/D56856 ------------------------------------------------------------------------ llvm-svn: 351961 --- .../clang/Tooling/ArgumentsAdjusters.h | 4 +++ clang/lib/Tooling/ArgumentsAdjusters.cpp | 22 +++++++++++++ clang/unittests/Tooling/ToolingTest.cpp | 31 +++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/clang/include/clang/Tooling/ArgumentsAdjusters.h b/clang/include/clang/Tooling/ArgumentsAdjusters.h index 94ccf1f34e576..e31839b9a8f73 100644 --- a/clang/include/clang/Tooling/ArgumentsAdjusters.h +++ b/clang/include/clang/Tooling/ArgumentsAdjusters.h @@ -61,6 +61,10 @@ ArgumentsAdjuster getInsertArgumentAdjuster( const char *Extra, ArgumentInsertPosition Pos = ArgumentInsertPosition::END); +/// Gets an argument adjuster which strips plugin related command line +/// arguments. +ArgumentsAdjuster getStripPluginsAdjuster(); + /// Gets an argument adjuster which adjusts the arguments in sequence /// with the \p First adjuster and then with the \p Second one. ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First, diff --git a/clang/lib/Tooling/ArgumentsAdjusters.cpp b/clang/lib/Tooling/ArgumentsAdjusters.cpp index c8e9c167422e8..f5040b8a09d57 100644 --- a/clang/lib/Tooling/ArgumentsAdjusters.cpp +++ b/clang/lib/Tooling/ArgumentsAdjusters.cpp @@ -108,5 +108,27 @@ ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First, }; } +ArgumentsAdjuster getStripPluginsAdjuster() { + return [](const CommandLineArguments &Args, StringRef /*unused*/) { + CommandLineArguments AdjustedArgs; + for (size_t I = 0, E = Args.size(); I != E; I++) { + // According to https://clang.llvm.org/docs/ClangPlugins.html + // plugin arguments are in the form: + // -Xclang {-load, -plugin, -plugin-arg-, -add-plugin} + // -Xclang + if (I + 4 < E && Args[I] == "-Xclang" && + (Args[I + 1] == "-load" || Args[I + 1] == "-plugin" || + llvm::StringRef(Args[I + 1]).startswith("-plugin-arg-") || + Args[I + 1] == "-add-plugin") && + Args[I + 2] == "-Xclang") { + I += 3; + continue; + } + AdjustedArgs.push_back(Args[I]); + } + return AdjustedArgs; + }; +} + } // end namespace tooling } // end namespace clang diff --git a/clang/unittests/Tooling/ToolingTest.cpp b/clang/unittests/Tooling/ToolingTest.cpp index 186463f80af73..5813552a6cd32 100644 --- a/clang/unittests/Tooling/ToolingTest.cpp +++ b/clang/unittests/Tooling/ToolingTest.cpp @@ -450,6 +450,37 @@ TEST(ClangToolTest, StripDependencyFileAdjuster) { EXPECT_TRUE(HasFlag("-w")); } +// Check getClangStripPluginsAdjuster strips plugin related args. +TEST(ClangToolTest, StripPluginsAdjuster) { + FixedCompilationDatabase Compilations( + "/", {"-Xclang", "-add-plugin", "-Xclang", "random-plugin"}); + + ClangTool Tool(Compilations, std::vector(1, "/a.cc")); + Tool.mapVirtualFile("/a.cc", "void a() {}"); + + std::unique_ptr Action( + newFrontendActionFactory()); + + CommandLineArguments FinalArgs; + ArgumentsAdjuster CheckFlagsAdjuster = + [&FinalArgs](const CommandLineArguments &Args, StringRef /*unused*/) { + FinalArgs = Args; + return Args; + }; + Tool.clearArgumentsAdjusters(); + Tool.appendArgumentsAdjuster(getStripPluginsAdjuster()); + Tool.appendArgumentsAdjuster(CheckFlagsAdjuster); + Tool.run(Action.get()); + + auto HasFlag = [&FinalArgs](const std::string &Flag) { + return std::find(FinalArgs.begin(), FinalArgs.end(), Flag) != + FinalArgs.end(); + }; + EXPECT_FALSE(HasFlag("-Xclang")); + EXPECT_FALSE(HasFlag("-add-plugin")); + EXPECT_FALSE(HasFlag("-random-plugin")); +} + namespace { /// Find a target name such that looking for it in TargetRegistry by that name /// returns the same target. We expect that there is at least one target From f669262c405bd90294fe9c4c96fb6e7b1482d848 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 23 Jan 2019 16:21:21 +0000 Subject: [PATCH 038/274] Merging r351738: ------------------------------------------------------------------------ r351738 | kadircet | 2019-01-21 11:10:18 +0100 (Mon, 21 Jan 2019) | 9 lines [clang-tidy] Use getStripPluginsAdjuster Summary: See rC351531 for the introduction of getStripPluginsAdjuster. Reviewers: alexfh Subscribers: xazax.hun, cfe-commits Differential Revision: https://reviews.llvm.org/D56902 ------------------------------------------------------------------------ llvm-svn: 351962 --- clang-tools-extra/clang-tidy/ClangTidy.cpp | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/clang-tools-extra/clang-tidy/ClangTidy.cpp b/clang-tools-extra/clang-tidy/ClangTidy.cpp index 0feda605ea66b..50ff149e38776 100644 --- a/clang-tools-extra/clang-tidy/ClangTidy.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidy.cpp @@ -529,24 +529,8 @@ runClangTidy(clang::tidy::ClangTidyContext &Context, return AdjustedArgs; }; - // Remove plugins arguments. - ArgumentsAdjuster PluginArgumentsRemover = - [](const CommandLineArguments &Args, StringRef Filename) { - CommandLineArguments AdjustedArgs; - for (size_t I = 0, E = Args.size(); I < E; ++I) { - if (I + 4 < Args.size() && Args[I] == "-Xclang" && - (Args[I + 1] == "-load" || Args[I + 1] == "-add-plugin" || - StringRef(Args[I + 1]).startswith("-plugin-arg-")) && - Args[I + 2] == "-Xclang") { - I += 3; - } else - AdjustedArgs.push_back(Args[I]); - } - return AdjustedArgs; - }; - Tool.appendArgumentsAdjuster(PerFileExtraArgumentsInserter); - Tool.appendArgumentsAdjuster(PluginArgumentsRemover); + Tool.appendArgumentsAdjuster(getStripPluginsAdjuster()); Context.setEnableProfiling(EnableCheckProfile); Context.setProfileStoragePrefix(StoreCheckProfile); From 40cbc004e802b8b66b1802bb4af9a9513bcda9fe Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 23 Jan 2019 16:24:00 +0000 Subject: [PATCH 039/274] Merging r351898: ------------------------------------------------------------------------ r351898 | pcc | 2019-01-23 00:51:35 +0100 (Wed, 23 Jan 2019) | 13 lines COFF, ELF: Adjust ICF hash computation to account for self relocations. It turns out that sections in PGO instrumented object files on Windows contain a large number of relocations pointing to themselves. With r347429 this can cause many sections to receive the same hash (usually zero) as a result of a section's hash being xor'ed with itself. This patch causes the COFF and ELF linkers to avoid this problem by adding the hash of the relocated section instead of xor'ing it. On my machine this causes the regressing test case provided by Mozilla to terminate in 2m41s. Differential Revision: https://reviews.llvm.org/D56955 ------------------------------------------------------------------------ llvm-svn: 351963 --- lld/COFF/ICF.cpp | 2 +- lld/ELF/ICF.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lld/COFF/ICF.cpp b/lld/COFF/ICF.cpp index 34ea360fa9258..e8091dcbef8cc 100644 --- a/lld/COFF/ICF.cpp +++ b/lld/COFF/ICF.cpp @@ -272,7 +272,7 @@ void ICF::run(ArrayRef Vec) { uint32_t Hash = SC->Class[1]; for (Symbol *B : SC->symbols()) if (auto *Sym = dyn_cast_or_null(B)) - Hash ^= Sym->getChunk()->Class[1]; + Hash += Sym->getChunk()->Class[1]; // Set MSB to 1 to avoid collisions with non-hash classs. SC->Class[0] = Hash | (1U << 31); }); diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp index e917ae76a689e..ba04de017688e 100644 --- a/lld/ELF/ICF.cpp +++ b/lld/ELF/ICF.cpp @@ -432,7 +432,7 @@ static void combineRelocHashes(InputSection *IS, ArrayRef Rels) { Symbol &S = IS->template getFile()->getRelocTargetSym(Rel); if (auto *D = dyn_cast(&S)) if (auto *RelSec = dyn_cast_or_null(D->Section)) - Hash ^= RelSec->Class[1]; + Hash += RelSec->Class[1]; } // Set MSB to 1 to avoid collisions with non-hash IDs. IS->Class[0] = Hash | (1U << 31); From b00b2b84b23acca31e02820ce64dbffd3b5f9a43 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 23 Jan 2019 16:25:15 +0000 Subject: [PATCH 040/274] Merging r351899: ------------------------------------------------------------------------ r351899 | pcc | 2019-01-23 00:54:49 +0100 (Wed, 23 Jan 2019) | 26 lines COFF, ELF: ICF: Perform 2 rounds of relocation hash propagation. LLD's performance on PGO instrumented Windows binaries was still not great even with the fix in D56955; out of the 2m41s linker runtime, around 2 minutes were still being spent in ICF. I looked into this more closely and discovered that the vast majority of the runtime was being spent segregating .pdata sections with the following relocation chain: .pdata -> identical .text -> unique PGO counter (not eligible for ICF) This patch causes us to perform 2 rounds of relocation hash propagation, which allows the hash for the .pdata sections to incorporate the identifier from the PGO counter. With that, the amount of time spent in ICF was reduced to about 2 seconds. I also found that the same change led to a significant ICF performance improvement in a regular release build of Chromium's chrome_child.dll, where ICF time was reduced from around 1s to around 700ms. With the same change applied to the ELF linker, median of 100 runs for lld-speed-test/chrome reduced from 4.53s to 4.45s on my machine. I also experimented with increasing the number of propagation rounds further, but I did not observe any further significant performance improvements linking Chromium or Firefox. Differential Revision: https://reviews.llvm.org/D56986 ------------------------------------------------------------------------ llvm-svn: 351964 --- lld/COFF/ICF.cpp | 20 +++++++++++--------- lld/ELF/ICF.cpp | 25 ++++++++++++++----------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/lld/COFF/ICF.cpp b/lld/COFF/ICF.cpp index e8091dcbef8cc..f6904eb7d24f2 100644 --- a/lld/COFF/ICF.cpp +++ b/lld/COFF/ICF.cpp @@ -263,19 +263,21 @@ void ICF::run(ArrayRef Vec) { // Initially, we use hash values to partition sections. parallelForEach(Chunks, [&](SectionChunk *SC) { - SC->Class[1] = xxHash64(SC->getContents()); + SC->Class[0] = xxHash64(SC->getContents()); }); // Combine the hashes of the sections referenced by each section into its // hash. - parallelForEach(Chunks, [&](SectionChunk *SC) { - uint32_t Hash = SC->Class[1]; - for (Symbol *B : SC->symbols()) - if (auto *Sym = dyn_cast_or_null(B)) - Hash += Sym->getChunk()->Class[1]; - // Set MSB to 1 to avoid collisions with non-hash classs. - SC->Class[0] = Hash | (1U << 31); - }); + for (unsigned Cnt = 0; Cnt != 2; ++Cnt) { + parallelForEach(Chunks, [&](SectionChunk *SC) { + uint32_t Hash = SC->Class[Cnt % 2]; + for (Symbol *B : SC->symbols()) + if (auto *Sym = dyn_cast_or_null(B)) + Hash += Sym->getChunk()->Class[Cnt % 2]; + // Set MSB to 1 to avoid collisions with non-hash classs. + SC->Class[(Cnt + 1) % 2] = Hash | (1U << 31); + }); + } // From now on, sections in Chunks are ordered so that sections in // the same group are consecutive in the vector. diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp index ba04de017688e..d08ac73ded80e 100644 --- a/lld/ELF/ICF.cpp +++ b/lld/ELF/ICF.cpp @@ -426,16 +426,17 @@ void ICF::forEachClass(llvm::function_ref Fn) { // Combine the hashes of the sections referenced by the given section into its // hash. template -static void combineRelocHashes(InputSection *IS, ArrayRef Rels) { - uint32_t Hash = IS->Class[1]; +static void combineRelocHashes(unsigned Cnt, InputSection *IS, + ArrayRef Rels) { + uint32_t Hash = IS->Class[Cnt % 2]; for (RelTy Rel : Rels) { Symbol &S = IS->template getFile()->getRelocTargetSym(Rel); if (auto *D = dyn_cast(&S)) if (auto *RelSec = dyn_cast_or_null(D->Section)) - Hash += RelSec->Class[1]; + Hash += RelSec->Class[Cnt % 2]; } // Set MSB to 1 to avoid collisions with non-hash IDs. - IS->Class[0] = Hash | (1U << 31); + IS->Class[(Cnt + 1) % 2] = Hash | (1U << 31); } static void print(const Twine &S) { @@ -453,15 +454,17 @@ template void ICF::run() { // Initially, we use hash values to partition sections. parallelForEach(Sections, [&](InputSection *S) { - S->Class[1] = xxHash64(S->data()); + S->Class[0] = xxHash64(S->data()); }); - parallelForEach(Sections, [&](InputSection *S) { - if (S->AreRelocsRela) - combineRelocHashes(S, S->template relas()); - else - combineRelocHashes(S, S->template rels()); - }); + for (unsigned Cnt = 0; Cnt != 2; ++Cnt) { + parallelForEach(Sections, [&](InputSection *S) { + if (S->AreRelocsRela) + combineRelocHashes(Cnt, S, S->template relas()); + else + combineRelocHashes(Cnt, S, S->template rels()); + }); + } // From now on, sections in Sections vector are ordered so that sections // in the same equivalence class are consecutive in the vector. From 17c9824ff19a56a1b07eb97574e15cf2084b145b Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 23 Jan 2019 21:11:36 +0000 Subject: [PATCH 041/274] Merging r351670: ------------------------------------------------------------------------ r351670 | ericwf | 2019-01-20 02:21:35 +0100 (Sun, 20 Jan 2019) | 7 lines Fix aligned allocation availability XFAILs after D56445. D56445 bumped the minimum Mac OS X version required for aligned allocation from 10.13 to 10.14. This caused libc++ tests depending on the old value to break. This patch updates the XFAILs for those tests to include 10.13. ------------------------------------------------------------------------ llvm-svn: 351980 --- .../new.delete.array/delete_align_val_t_replace.pass.cpp | 8 +++++--- .../new.delete/new.delete.array/new_align_val_t.pass.cpp | 8 +++++--- .../new.delete.array/new_align_val_t_nothrow.pass.cpp | 8 +++++--- .../new_align_val_t_nothrow_replace.pass.cpp | 8 +++++--- .../new.delete.single/delete_align_val_t_replace.pass.cpp | 8 +++++--- .../new.delete/new.delete.single/new_align_val_t.pass.cpp | 8 +++++--- .../new.delete.single/new_align_val_t_nothrow.pass.cpp | 8 +++++--- .../new_align_val_t_nothrow_replace.pass.cpp | 8 +++++--- 8 files changed, 40 insertions(+), 24 deletions(-) diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp index 4dd9390c4fdcf..bd20e090637d0 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp @@ -17,9 +17,11 @@ // None of the current GCC compilers support this. // UNSUPPORTED: gcc-5, gcc-6 -// Aligned allocation was not provided before macosx10.12 and as a result we -// get availability errors when the deployment target is older than macosx10.13. -// However, AppleClang 10 (and older) don't trigger availability errors. +// Aligned allocation was not provided before macosx10.14 and as a result we +// get availability errors when the deployment target is older than macosx10.14. +// However, AppleClang 10 (and older) don't trigger availability errors, and +// Clang < 8.0 doesn't warn for 10.13. +// XFAIL: !(apple-clang-9 || apple-clang-10 || clang-7) && availability=macosx10.13 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp index d6194b00aa025..6b4e1c1924b4a 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp @@ -15,9 +15,11 @@ // FIXME change this to XFAIL. // UNSUPPORTED: no-aligned-allocation && !gcc -// Aligned allocation was not provided before macosx10.12 and as a result we -// get availability errors when the deployment target is older than macosx10.13. -// However, AppleClang 10 (and older) don't trigger availability errors. +// Aligned allocation was not provided before macosx10.14 and as a result we +// get availability errors when the deployment target is older than macosx10.14. +// However, AppleClang 10 (and older) don't trigger availability errors, and +// Clang < 8.0 doesn't warn for 10.13. +// XFAIL: !(apple-clang-9 || apple-clang-10 || clang-7) && availability=macosx10.13 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp index 59878aefd18a2..3188cc587dde9 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp @@ -15,9 +15,11 @@ // FIXME turn this into an XFAIL // UNSUPPORTED: no-aligned-allocation && !gcc -// Aligned allocation was not provided before macosx10.12 and as a result we -// get availability errors when the deployment target is older than macosx10.13. -// However, AppleClang 10 (and older) don't trigger availability errors. +// Aligned allocation was not provided before macosx10.14 and as a result we +// get availability errors when the deployment target is older than macosx10.14. +// However, AppleClang 10 (and older) don't trigger availability errors, and +// Clang < 8.0 doesn't warn for 10.13. +// XFAIL: !(apple-clang-9 || apple-clang-10 || clang-7) && availability=macosx10.13 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp index fc713dbf8ed83..29d8fd06a701e 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp @@ -10,9 +10,11 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 // UNSUPPORTED: sanitizer-new-delete -// Aligned allocation was not provided before macosx10.12 and as a result we -// get availability errors when the deployment target is older than macosx10.13. -// However, AppleClang 10 (and older) don't trigger availability errors. +// Aligned allocation was not provided before macosx10.14 and as a result we +// get availability errors when the deployment target is older than macosx10.14. +// However, AppleClang 10 (and older) don't trigger availability errors, and +// Clang < 8.0 doesn't warn for 10.13. +// XFAIL: !(apple-clang-9 || apple-clang-10 || clang-7) && availability=macosx10.13 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp index 19cabcce1edd9..c01e39915ec01 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp @@ -16,9 +16,11 @@ // None of the current GCC compilers support this. // UNSUPPORTED: gcc-5, gcc-6 -// Aligned allocation was not provided before macosx10.12 and as a result we -// get availability errors when the deployment target is older than macosx10.13. -// However, AppleClang 10 (and older) don't trigger availability errors. +// Aligned allocation was not provided before macosx10.14 and as a result we +// get availability errors when the deployment target is older than macosx10.14. +// However, AppleClang 10 (and older) don't trigger availability errors, and +// Clang < 8.0 doesn't warn for 10.13 +// XFAIL: !(apple-clang-9 || apple-clang-10 || clang-7) && availability=macosx10.13 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp index 7cf1aca3b9f8e..8cb40885c466f 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp @@ -9,9 +9,11 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 -// Aligned allocation was not provided before macosx10.12 and as a result we -// get availability errors when the deployment target is older than macosx10.13. -// However, AppleClang 10 (and older) don't trigger availability errors. +// Aligned allocation was not provided before macosx10.14 and as a result we +// get availability errors when the deployment target is older than macosx10.14. +// However, AppleClang 10 (and older) don't trigger availability errors, and +// Clang < 8.0 doesn't warn for 10.13. +// XFAIL: !(apple-clang-9 || apple-clang-10 || clang-7) && availability=macosx10.13 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp index dd2666e00aad4..9d7f13bee3288 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp @@ -9,9 +9,11 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 -// Aligned allocation was not provided before macosx10.12 and as a result we -// get availability errors when the deployment target is older than macosx10.13. -// However, AppleClang 10 (and older) don't trigger availability errors. +// Aligned allocation was not provided before macosx10.14 and as a result we +// get availability errors when the deployment target is older than macosx10.14. +// However, AppleClang 10 (and older) don't trigger availability errors, and +// Clang < 8.0 doesn't warn for 10.13 +// XFAIL: !(apple-clang-9 || apple-clang-10 || clang-7) && availability=macosx10.13 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp index 514a2b8afc8c3..82367d7de093b 100644 --- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp +++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp @@ -10,9 +10,11 @@ // UNSUPPORTED: c++98, c++03, c++11, c++14 // UNSUPPORTED: sanitizer-new-delete -// Aligned allocation was not provided before macosx10.12 and as a result we -// get availability errors when the deployment target is older than macosx10.13. -// However, AppleClang 10 (and older) don't trigger availability errors. +// Aligned allocation was not provided before macosx10.14 and as a result we +// get availability errors when the deployment target is older than macosx10.14. +// However, AppleClang 10 (and older) don't trigger availability errors, and +// Clang < 8.0 doesn't warn for 10.13 +// XFAIL: !(apple-clang-9 || apple-clang-10 || clang-7) && availability=macosx10.13 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10 From 22c2b2b1a6325db33a3db6c0d307856ec831cc4a Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 24 Jan 2019 22:07:01 +0000 Subject: [PATCH 042/274] Merging r351930 and r351932: ------------------------------------------------------------------------ r351930 | kbeyls | 2019-01-23 09:18:39 +0100 (Wed, 23 Jan 2019) | 30 lines [SLH] AArch64: correctly pick temporary register to mask SP As part of speculation hardening, the stack pointer gets masked with the taint register (X16) before a function call or before a function return. Since there are no instructions that can directly mask writing to the stack pointer, the stack pointer must first be transferred to another register, where it can be masked, before that value is transferred back to the stack pointer. Before, that temporary register was always picked to be x17, since the ABI allows clobbering x17 on any function call, resulting in the following instruction pattern being inserted before function calls and returns/tail calls: mov x17, sp and x17, x17, x16 mov sp, x17 However, x17 can be live in those locations, for example when the call is an indirect call, using x17 as the target address (blr x17). To fix this, this patch looks for an available register just before the call or terminator instruction and uses that. In the rare case when no register turns out to be available (this situation is only encountered twice across the whole test-suite), just insert a full speculation barrier at the start of the basic block where this occurs. Differential Revision: https://reviews.llvm.org/D56717 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r351932 | kbeyls | 2019-01-23 10:10:12 +0100 (Wed, 23 Jan 2019) | 3 lines [SLH][AArch64] Remove accidentally retained -debug-only line from test. ------------------------------------------------------------------------ llvm-svn: 352115 --- .../AArch64/AArch64SpeculationHardening.cpp | 175 ++++++++++++------ .../AArch64/speculation-hardening-loads.ll | 42 ++--- .../CodeGen/AArch64/speculation-hardening.ll | 60 +++--- .../CodeGen/AArch64/speculation-hardening.mir | 85 +++++++++ 4 files changed, 258 insertions(+), 104 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64SpeculationHardening.cpp b/llvm/lib/Target/AArch64/AArch64SpeculationHardening.cpp index e9699b0367d3d..50300305abe33 100644 --- a/llvm/lib/Target/AArch64/AArch64SpeculationHardening.cpp +++ b/llvm/lib/Target/AArch64/AArch64SpeculationHardening.cpp @@ -103,6 +103,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/IR/DebugLoc.h" #include "llvm/Pass.h" #include "llvm/Support/CodeGen.h" @@ -146,25 +147,31 @@ class AArch64SpeculationHardening : public MachineFunctionPass { BitVector RegsAlreadyMasked; bool functionUsesHardeningRegister(MachineFunction &MF) const; - bool instrumentControlFlow(MachineBasicBlock &MBB); + bool instrumentControlFlow(MachineBasicBlock &MBB, + bool &UsesFullSpeculationBarrier); bool endsWithCondControlFlow(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, AArch64CC::CondCode &CondCode) const; void insertTrackingCode(MachineBasicBlock &SplitEdgeBB, AArch64CC::CondCode &CondCode, DebugLoc DL) const; - void insertSPToRegTaintPropagation(MachineBasicBlock *MBB, + void insertSPToRegTaintPropagation(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const; - void insertRegToSPTaintPropagation(MachineBasicBlock *MBB, + void insertRegToSPTaintPropagation(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned TmpReg) const; + void insertFullSpeculationBarrier(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + DebugLoc DL) const; bool slhLoads(MachineBasicBlock &MBB); bool makeGPRSpeculationSafe(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MachineInstr &MI, unsigned Reg); - bool lowerSpeculationSafeValuePseudos(MachineBasicBlock &MBB); + bool lowerSpeculationSafeValuePseudos(MachineBasicBlock &MBB, + bool UsesFullSpeculationBarrier); bool expandSpeculationSafeValue(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MBBI); + MachineBasicBlock::iterator MBBI, + bool UsesFullSpeculationBarrier); bool insertCSDB(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc DL); }; @@ -207,15 +214,19 @@ bool AArch64SpeculationHardening::endsWithCondControlFlow( return true; } +void AArch64SpeculationHardening::insertFullSpeculationBarrier( + MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + DebugLoc DL) const { + // A full control flow speculation barrier consists of (DSB SYS + ISB) + BuildMI(MBB, MBBI, DL, TII->get(AArch64::DSB)).addImm(0xf); + BuildMI(MBB, MBBI, DL, TII->get(AArch64::ISB)).addImm(0xf); +} + void AArch64SpeculationHardening::insertTrackingCode( MachineBasicBlock &SplitEdgeBB, AArch64CC::CondCode &CondCode, DebugLoc DL) const { if (UseControlFlowSpeculationBarrier) { - // insert full control flow speculation barrier (DSB SYS + ISB) - BuildMI(SplitEdgeBB, SplitEdgeBB.begin(), DL, TII->get(AArch64::ISB)) - .addImm(0xf); - BuildMI(SplitEdgeBB, SplitEdgeBB.begin(), DL, TII->get(AArch64::DSB)) - .addImm(0xf); + insertFullSpeculationBarrier(SplitEdgeBB, SplitEdgeBB.begin(), DL); } else { BuildMI(SplitEdgeBB, SplitEdgeBB.begin(), DL, TII->get(AArch64::CSELXr)) .addDef(MisspeculatingTaintReg) @@ -227,7 +238,7 @@ void AArch64SpeculationHardening::insertTrackingCode( } bool AArch64SpeculationHardening::instrumentControlFlow( - MachineBasicBlock &MBB) { + MachineBasicBlock &MBB, bool &UsesFullSpeculationBarrier) { LLVM_DEBUG(dbgs() << "Instrument control flow tracking on MBB: " << MBB); bool Modified = false; @@ -263,55 +274,105 @@ bool AArch64SpeculationHardening::instrumentControlFlow( } // Perform correct code generation around function calls and before returns. - { - SmallVector ReturnInstructions; - SmallVector CallInstructions; + // The below variables record the return/terminator instructions and the call + // instructions respectively; including which register is available as a + // temporary register just before the recorded instructions. + SmallVector, 4> ReturnInstructions; + SmallVector, 4> CallInstructions; + // if a temporary register is not available for at least one of the + // instructions for which we need to transfer taint to the stack pointer, we + // need to insert a full speculation barrier. + // TmpRegisterNotAvailableEverywhere tracks that condition. + bool TmpRegisterNotAvailableEverywhere = false; + + RegScavenger RS; + RS.enterBasicBlock(MBB); + + for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); I++) { + MachineInstr &MI = *I; + if (!MI.isReturn() && !MI.isCall()) + continue; - for (MachineInstr &MI : MBB) { - if (MI.isReturn()) - ReturnInstructions.push_back(&MI); - else if (MI.isCall()) - CallInstructions.push_back(&MI); - } + // The RegScavenger represents registers available *after* the MI + // instruction pointed to by RS.getCurrentPosition(). + // We need to have a register that is available *before* the MI is executed. + if (I != MBB.begin()) + RS.forward(std::prev(I)); + // FIXME: The below just finds *a* unused register. Maybe code could be + // optimized more if this looks for the register that isn't used for the + // longest time around this place, to enable more scheduling freedom. Not + // sure if that would actually result in a big performance difference + // though. Maybe RegisterScavenger::findSurvivorBackwards has some logic + // already to do this - but it's unclear if that could easily be used here. + unsigned TmpReg = RS.FindUnusedReg(&AArch64::GPR64commonRegClass); + LLVM_DEBUG(dbgs() << "RS finds " + << ((TmpReg == 0) ? "no register " : "register "); + if (TmpReg != 0) dbgs() << printReg(TmpReg, TRI) << " "; + dbgs() << "to be available at MI " << MI); + if (TmpReg == 0) + TmpRegisterNotAvailableEverywhere = true; + if (MI.isReturn()) + ReturnInstructions.push_back({&MI, TmpReg}); + else if (MI.isCall()) + CallInstructions.push_back({&MI, TmpReg}); + } - Modified |= - (ReturnInstructions.size() > 0) || (CallInstructions.size() > 0); + if (TmpRegisterNotAvailableEverywhere) { + // When a temporary register is not available everywhere in this basic + // basic block where a propagate-taint-to-sp operation is needed, just + // emit a full speculation barrier at the start of this basic block, which + // renders the taint/speculation tracking in this basic block unnecessary. + insertFullSpeculationBarrier(MBB, MBB.begin(), + (MBB.begin())->getDebugLoc()); + UsesFullSpeculationBarrier = true; + Modified = true; + } else { + for (auto MI_Reg : ReturnInstructions) { + assert(MI_Reg.second != 0); + LLVM_DEBUG( + dbgs() + << " About to insert Reg to SP taint propagation with temp register " + << printReg(MI_Reg.second, TRI) + << " on instruction: " << *MI_Reg.first); + insertRegToSPTaintPropagation(MBB, MI_Reg.first, MI_Reg.second); + Modified = true; + } - for (MachineInstr *Return : ReturnInstructions) - insertRegToSPTaintPropagation(Return->getParent(), Return, AArch64::X17); - for (MachineInstr *Call : CallInstructions) { + for (auto MI_Reg : CallInstructions) { + assert(MI_Reg.second != 0); + LLVM_DEBUG(dbgs() << " About to insert Reg to SP and back taint " + "propagation with temp register " + << printReg(MI_Reg.second, TRI) + << " around instruction: " << *MI_Reg.first); // Just after the call: - MachineBasicBlock::iterator i = Call; - i++; - insertSPToRegTaintPropagation(Call->getParent(), i); + insertSPToRegTaintPropagation( + MBB, std::next((MachineBasicBlock::iterator)MI_Reg.first)); // Just before the call: - insertRegToSPTaintPropagation(Call->getParent(), Call, AArch64::X17); + insertRegToSPTaintPropagation(MBB, MI_Reg.first, MI_Reg.second); + Modified = true; } } - return Modified; } void AArch64SpeculationHardening::insertSPToRegTaintPropagation( - MachineBasicBlock *MBB, MachineBasicBlock::iterator MBBI) const { + MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const { // If full control flow speculation barriers are used, emit a control flow // barrier to block potential miss-speculation in flight coming in to this // function. if (UseControlFlowSpeculationBarrier) { - // insert full control flow speculation barrier (DSB SYS + ISB) - BuildMI(*MBB, MBBI, DebugLoc(), TII->get(AArch64::DSB)).addImm(0xf); - BuildMI(*MBB, MBBI, DebugLoc(), TII->get(AArch64::ISB)).addImm(0xf); + insertFullSpeculationBarrier(MBB, MBBI, DebugLoc()); return; } // CMP SP, #0 === SUBS xzr, SP, #0 - BuildMI(*MBB, MBBI, DebugLoc(), TII->get(AArch64::SUBSXri)) + BuildMI(MBB, MBBI, DebugLoc(), TII->get(AArch64::SUBSXri)) .addDef(AArch64::XZR) .addUse(AArch64::SP) .addImm(0) .addImm(0); // no shift // CSETM x16, NE === CSINV x16, xzr, xzr, EQ - BuildMI(*MBB, MBBI, DebugLoc(), TII->get(AArch64::CSINVXr)) + BuildMI(MBB, MBBI, DebugLoc(), TII->get(AArch64::CSINVXr)) .addDef(MisspeculatingTaintReg) .addUse(AArch64::XZR) .addUse(AArch64::XZR) @@ -319,7 +380,7 @@ void AArch64SpeculationHardening::insertSPToRegTaintPropagation( } void AArch64SpeculationHardening::insertRegToSPTaintPropagation( - MachineBasicBlock *MBB, MachineBasicBlock::iterator MBBI, + MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned TmpReg) const { // If full control flow speculation barriers are used, there will not be // miss-speculation when returning from this function, and therefore, also @@ -328,19 +389,19 @@ void AArch64SpeculationHardening::insertRegToSPTaintPropagation( return; // mov Xtmp, SP === ADD Xtmp, SP, #0 - BuildMI(*MBB, MBBI, DebugLoc(), TII->get(AArch64::ADDXri)) + BuildMI(MBB, MBBI, DebugLoc(), TII->get(AArch64::ADDXri)) .addDef(TmpReg) .addUse(AArch64::SP) .addImm(0) .addImm(0); // no shift // and Xtmp, Xtmp, TaintReg === AND Xtmp, Xtmp, TaintReg, #0 - BuildMI(*MBB, MBBI, DebugLoc(), TII->get(AArch64::ANDXrs)) + BuildMI(MBB, MBBI, DebugLoc(), TII->get(AArch64::ANDXrs)) .addDef(TmpReg, RegState::Renamable) .addUse(TmpReg, RegState::Kill | RegState::Renamable) .addUse(MisspeculatingTaintReg, RegState::Kill) .addImm(0); // mov SP, Xtmp === ADD SP, Xtmp, #0 - BuildMI(*MBB, MBBI, DebugLoc(), TII->get(AArch64::ADDXri)) + BuildMI(MBB, MBBI, DebugLoc(), TII->get(AArch64::ADDXri)) .addDef(AArch64::SP) .addUse(TmpReg, RegState::Kill) .addImm(0) @@ -484,7 +545,8 @@ bool AArch64SpeculationHardening::slhLoads(MachineBasicBlock &MBB) { /// \brief If MBBI references a pseudo instruction that should be expanded /// here, do the expansion and return true. Otherwise return false. bool AArch64SpeculationHardening::expandSpeculationSafeValue( - MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) { + MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + bool UsesFullSpeculationBarrier) { MachineInstr &MI = *MBBI; unsigned Opcode = MI.getOpcode(); bool Is64Bit = true; @@ -499,7 +561,7 @@ bool AArch64SpeculationHardening::expandSpeculationSafeValue( // Just remove the SpeculationSafe pseudo's if control flow // miss-speculation isn't happening because we're already inserting barriers // to guarantee that. - if (!UseControlFlowSpeculationBarrier) { + if (!UseControlFlowSpeculationBarrier && !UsesFullSpeculationBarrier) { unsigned DstReg = MI.getOperand(0).getReg(); unsigned SrcReg = MI.getOperand(1).getReg(); // Mark this register and all its aliasing registers as needing to be @@ -537,7 +599,7 @@ bool AArch64SpeculationHardening::insertCSDB(MachineBasicBlock &MBB, } bool AArch64SpeculationHardening::lowerSpeculationSafeValuePseudos( - MachineBasicBlock &MBB) { + MachineBasicBlock &MBB, bool UsesFullSpeculationBarrier) { bool Modified = false; RegsNeedingCSDBBeforeUse.reset(); @@ -572,15 +634,16 @@ bool AArch64SpeculationHardening::lowerSpeculationSafeValuePseudos( break; } - if (NeedToEmitBarrier) + if (NeedToEmitBarrier && !UsesFullSpeculationBarrier) Modified |= insertCSDB(MBB, MBBI, DL); - Modified |= expandSpeculationSafeValue(MBB, MBBI); + Modified |= + expandSpeculationSafeValue(MBB, MBBI, UsesFullSpeculationBarrier); MBBI = NMBBI; } - if (RegsNeedingCSDBBeforeUse.any()) + if (RegsNeedingCSDBBeforeUse.any() && !UsesFullSpeculationBarrier) Modified |= insertCSDB(MBB, MBBI, DL); return Modified; @@ -609,7 +672,7 @@ bool AArch64SpeculationHardening::runOnMachineFunction(MachineFunction &MF) { Modified |= slhLoads(MBB); } - // 2.a Add instrumentation code to function entry and exits. + // 2. Add instrumentation code to function entry and exits. LLVM_DEBUG( dbgs() << "***** AArch64SpeculationHardening - track control flow *****\n"); @@ -620,17 +683,15 @@ bool AArch64SpeculationHardening::runOnMachineFunction(MachineFunction &MF) { EntryBlocks.push_back(LPI.LandingPadBlock); for (auto Entry : EntryBlocks) insertSPToRegTaintPropagation( - Entry, Entry->SkipPHIsLabelsAndDebug(Entry->begin())); - - // 2.b Add instrumentation code to every basic block. - for (auto &MBB : MF) - Modified |= instrumentControlFlow(MBB); + *Entry, Entry->SkipPHIsLabelsAndDebug(Entry->begin())); - LLVM_DEBUG(dbgs() << "***** AArch64SpeculationHardening - Lowering " - "SpeculationSafeValue Pseudos *****\n"); - // Step 3: Lower SpeculationSafeValue pseudo instructions. - for (auto &MBB : MF) - Modified |= lowerSpeculationSafeValuePseudos(MBB); + // 3. Add instrumentation code to every basic block. + for (auto &MBB : MF) { + bool UsesFullSpeculationBarrier = false; + Modified |= instrumentControlFlow(MBB, UsesFullSpeculationBarrier); + Modified |= + lowerSpeculationSafeValuePseudos(MBB, UsesFullSpeculationBarrier); + } return Modified; } diff --git a/llvm/test/CodeGen/AArch64/speculation-hardening-loads.ll b/llvm/test/CodeGen/AArch64/speculation-hardening-loads.ll index 0b8f8d31b3162..e90fb19a522a1 100644 --- a/llvm/test/CodeGen/AArch64/speculation-hardening-loads.ll +++ b/llvm/test/CodeGen/AArch64/speculation-hardening-loads.ll @@ -11,10 +11,10 @@ entry: ; CHECK-NEXT: and x8, x8, x16 ; CHECK-NEXT: and x1, x1, x16 ; CHECK-NEXT: csdb -; CHECK-NEXT: mov x17, sp -; CHECK-NEXT: and x17, x17, x16 +; CHECK-NEXT: mov [[TMPREG:x[0-9]+]], sp +; CHECK-NEXT: and [[TMPREG]], [[TMPREG]], x16 ; CHECK-NEXT: mov x0, x8 -; CHECK-NEXT: mov sp, x17 +; CHECK-NEXT: mov sp, [[TMPREG]] ; CHECK-NEXT: ret } @@ -29,9 +29,9 @@ entry: ; CHECK-NEXT: and x0, x0, x16 ; CHECK-NEXT: csdb ; CHECK-NEXT: ldr d0, [x0] -; CHECK-NEXT: mov x17, sp -; CHECK-NEXT: and x17, x17, x16 -; CHECK-NEXT: mov sp, x17 +; CHECK-NEXT: mov [[TMPREG:x[0-9]+]], sp +; CHECK-NEXT: and [[TMPREG]], [[TMPREG]], x16 +; CHECK-NEXT: mov sp, [[TMPREG]] ; CHECK-NEXT: ret } @@ -51,12 +51,12 @@ entry: ; CHECK-NEXT: and x8, x8, x16 ; csdb instruction must occur before the add instruction with w8 as operand. ; CHECK-NEXT: csdb -; CHECK-NEXT: mov x17, sp ; CHECK-NEXT: add w9, w1, w8 ; CHECK-NEXT: cmp x8, #0 -; CHECK-NEXT: and x17, x17, x16 ; CHECK-NEXT: csel w0, w1, w9, eq -; CHECK-NEXT: mov sp, x17 +; CHECK-NEXT: mov [[TMPREG:x[0-9]+]], sp +; CHECK-NEXT: and [[TMPREG]], [[TMPREG]], x16 +; CHECK-NEXT: mov sp, [[TMPREG]] ; CHECK-NEXT: ret } @@ -76,12 +76,12 @@ entry: ; CHECK-NEXT: and w8, w8, w16 ; csdb instruction must occur before the add instruction with x8 as operand. ; CHECK-NEXT: csdb -; CHECK-NEXT: mov x17, sp ; CHECK-NEXT: add x9, x1, x8 ; CHECK-NEXT: cmp w8, #0 -; CHECK-NEXT: and x17, x17, x16 ; CHECK-NEXT: csel x0, x1, x9, eq -; CHECK-NEXT: mov sp, x17 +; CHECK-NEXT: mov [[TMPREG:x[0-9]+]], sp +; CHECK-NEXT: and [[TMPREG]], [[TMPREG]], x16 +; CHECK-NEXT: mov sp, [[TMPREG]] ; CHECK-NEXT: ret } @@ -112,11 +112,11 @@ entry: ; CHECK-NEXT: and x1, x1, x16 ; CHECK-NEXT: csdb ; CHECK-NEXT: ldr d0, [x1] -; CHECK-NEXT: mov x17, sp -; CHECK-NEXT: and x17, x17, x16 ; CHECK-NEXT: mov v0.d[1], v0.d[0] ; CHECK-NEXT: str q0, [x0] -; CHECK-NEXT: mov sp, x17 +; CHECK-NEXT: mov [[TMPREG:x[0-9]+]], sp +; CHECK-NEXT: and [[TMPREG]], [[TMPREG]], x16 +; CHECK-NEXT: mov sp, [[TMPREG]] ; CHECK-NEXT: ret } @@ -129,9 +129,9 @@ entry: ; CHECK-NEXT: and x1, x1, x16 ; CHECK-NEXT: csdb ; CHECK-NEXT: ld1 { v0.d }[0], [x1] -; CHECK-NEXT: mov x17, sp -; CHECK-NEXT: and x17, x17, x16 -; CHECK-NEXT: mov sp, x17 +; CHECK-NEXT: mov [[TMPREG:x[0-9]+]], sp +; CHECK-NEXT: and [[TMPREG]], [[TMPREG]], x16 +; CHECK-NEXT: mov sp, [[TMPREG]] ; CHECK-NEXT: ret %0 = load double, double* %b, align 16 %vld1_lane = insertelement <2 x double> , double %0, i32 0 @@ -147,9 +147,9 @@ entry: ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: ldr w8, [sp, #12] ; CHECK-NEXT: add sp, sp, #16 -; CHECK-NEXT: mov x17, sp -; CHECK-NEXT: and x17, x17, x16 -; CHECK-NEXT: mov sp, x17 +; CHECK-NEXT: mov [[TMPREG:x[0-9]+]], sp +; CHECK-NEXT: and [[TMPREG]], [[TMPREG]], x16 +; CHECK-NEXT: mov sp, [[TMPREG]] ; CHECK-NEXT: ret %a = alloca i32, align 4 %val = load volatile i32, i32* %a, align 4 diff --git a/llvm/test/CodeGen/AArch64/speculation-hardening.ll b/llvm/test/CodeGen/AArch64/speculation-hardening.ll index 3535b63c32cc8..51156f68dec8c 100644 --- a/llvm/test/CodeGen/AArch64/speculation-hardening.ll +++ b/llvm/test/CodeGen/AArch64/speculation-hardening.ll @@ -1,9 +1,9 @@ -; RUN: sed -e 's/SLHATTR/speculative_load_hardening/' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu | FileCheck %s --check-prefixes=CHECK,SLH --dump-input-on-failure -; RUN: sed -e 's/SLHATTR//' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu | FileCheck %s --check-prefixes=CHECK,NOSLH --dump-input-on-failure -; RUN: sed -e 's/SLHATTR/speculative_load_hardening/' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -global-isel | FileCheck %s --check-prefixes=CHECK,SLH --dump-input-on-failure -; RUN sed -e 's/SLHATTR//' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -global-isel | FileCheck %s --check-prefixes=CHECK,NOSLH --dump-input-on-failure -; RUN: sed -e 's/SLHATTR/speculative_load_hardening/' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -fast-isel | FileCheck %s --check-prefixes=CHECK,SLH --dump-input-on-failure -; RUN: sed -e 's/SLHATTR//' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -fast-isel | FileCheck %s --check-prefixes=CHECK,NOSLH --dump-input-on-failure +; RUN: sed -e 's/SLHATTR/speculative_load_hardening/' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu | FileCheck %s --check-prefixes=CHECK,SLH,NOGISELSLH --dump-input-on-failure +; RUN: sed -e 's/SLHATTR//' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu | FileCheck %s --check-prefixes=CHECK,NOSLH,NOGISELNOSLH --dump-input-on-failure +; RUN: sed -e 's/SLHATTR/speculative_load_hardening/' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -global-isel | FileCheck %s --check-prefixes=CHECK,SLH,GISELSLH --dump-input-on-failure +; RUN sed -e 's/SLHATTR//' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -global-isel | FileCheck %s --check-prefixes=CHECK,NOSLH,GISELNOSLH --dump-input-on-failure +; RUN: sed -e 's/SLHATTR/speculative_load_hardening/' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -fast-isel | FileCheck %s --check-prefixes=CHECK,SLH,NOGISELSLH --dump-input-on-failure +; RUN: sed -e 's/SLHATTR//' %s | llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -fast-isel | FileCheck %s --check-prefixes=CHECK,NOSLH,NOGISELNOSLH --dump-input-on-failure define i32 @f(i8* nocapture readonly %p, i32 %i, i32 %N) local_unnamed_addr SLHATTR { ; CHECK-LABEL: f @@ -13,12 +13,12 @@ entry: ; NOSLH-NOT: cmp sp, #0 ; NOSLH-NOT: csetm x16, ne -; SLH: mov x17, sp -; SLH: and x17, x17, x16 -; SLH: mov sp, x17 -; NOSLH-NOT: mov x17, sp -; NOSLH-NOT: and x17, x17, x16 -; NOSLH-NOT: mov sp, x17 +; SLH: mov [[TMPREG:x[0-9]+]], sp +; SLH: and [[TMPREG]], [[TMPREG]], x16 +; SLH: mov sp, [[TMPREG]] +; NOSLH-NOT: mov [[TMPREG:x[0-9]+]], sp +; NOSLH-NOT: and [[TMPREG]], [[TMPREG]], x16 +; NOSLH-NOT: mov sp, [[TMPREG]] %call = tail call i32 @tail_callee(i32 %i) ; SLH: cmp sp, #0 ; SLH: csetm x16, ne @@ -43,29 +43,37 @@ if.then: ; preds = %entry ; NOSLH-NOT: csel x16, x16, xzr, [[COND]] return: ; preds = %entry, %if.then %retval.0 = phi i32 [ %conv, %if.then ], [ 0, %entry ] -; SLH: mov x17, sp -; SLH: and x17, x17, x16 -; SLH: mov sp, x17 -; NOSLH-NOT: mov x17, sp -; NOSLH-NOT: and x17, x17, x16 -; NOSLH-NOT: mov sp, x17 +; SLH: mov [[TMPREG:x[0-9]+]], sp +; SLH: and [[TMPREG]], [[TMPREG]], x16 +; SLH: mov sp, [[TMPREG]] +; NOSLH-NOT: mov [[TMPREG:x[0-9]+]], sp +; NOSLH-NOT: and [[TMPREG]], [[TMPREG]], x16 +; NOSLH-NOT: mov sp, [[TMPREG]] ret i32 %retval.0 } ; Make sure that for a tail call, taint doesn't get put into SP twice. define i32 @tail_caller(i32 %a) local_unnamed_addr SLHATTR { ; CHECK-LABEL: tail_caller: -; SLH: mov x17, sp -; SLH: and x17, x17, x16 -; SLH: mov sp, x17 -; NOSLH-NOT: mov x17, sp -; NOSLH-NOT: and x17, x17, x16 -; NOSLH-NOT: mov sp, x17 +; NOGISELSLH: mov [[TMPREG:x[0-9]+]], sp +; NOGISELSLH: and [[TMPREG]], [[TMPREG]], x16 +; NOGISELSLH: mov sp, [[TMPREG]] +; NOGISELNOSLH-NOT: mov [[TMPREG:x[0-9]+]], sp +; NOGISELNOSLH-NOT: and [[TMPREG]], [[TMPREG]], x16 +; NOGISELNOSLH-NOT: mov sp, [[TMPREG]] +; GISELSLH: mov [[TMPREG:x[0-9]+]], sp +; GISELSLH: and [[TMPREG]], [[TMPREG]], x16 +; GISELSLH: mov sp, [[TMPREG]] +; GISELNOSLH-NOT: mov [[TMPREG:x[0-9]+]], sp +; GISELNOSLH-NOT: and [[TMPREG]], [[TMPREG]], x16 +; GISELNOSLH-NOT: mov sp, [[TMPREG]] ; GlobalISel doesn't optimize tail calls (yet?), so only check that ; cross-call taint register setup code is missing if a tail call was ; actually produced. -; SLH: {{(bl tail_callee[[:space:]] cmp sp, #0)|(b tail_callee)}} -; SLH-NOT: cmp sp, #0 +; NOGISELSLH: b tail_callee +; GISELSLH: bl tail_callee +; GISELSLH: cmp sp, #0 +; SLH-NOT: cmp sp, #0 %call = tail call i32 @tail_callee(i32 %a) ret i32 %call } diff --git a/llvm/test/CodeGen/AArch64/speculation-hardening.mir b/llvm/test/CodeGen/AArch64/speculation-hardening.mir index cf8357d9558b0..5991c4df0407f 100644 --- a/llvm/test/CodeGen/AArch64/speculation-hardening.mir +++ b/llvm/test/CodeGen/AArch64/speculation-hardening.mir @@ -25,6 +25,22 @@ define void @indirectbranch(i32 %a, i32 %b) speculative_load_hardening { ret void } + ; Also check that a non-default temporary register gets picked correctly to + ; transfer the SP to to and it with the taint register when the default + ; temporary isn't available. + define void @indirect_call_x17(i32 %a, i32 %b) speculative_load_hardening { + ret void + } + @g = common dso_local local_unnamed_addr global i64 (...)* null, align 8 + define void @indirect_tailcall_x17(i32 %a, i32 %b) speculative_load_hardening { + ret void + } + define void @indirect_call_lr(i32 %a, i32 %b) speculative_load_hardening { + ret void + } + define void @RS_cannot_find_available_regs() speculative_load_hardening { + ret void + } ... --- name: nobranch_fallthrough @@ -115,3 +131,72 @@ body: | ; CHECK-NOT: csel RET undef $lr, implicit $x0 ... +--- +name: indirect_call_x17 +tracksRegLiveness: true +body: | + bb.0: + liveins: $x17 + ; CHECK-LABEL: indirect_call_x17 + ; CHECK: mov x0, sp + ; CHECK: and x0, x0, x16 + ; CHECK: mov sp, x0 + ; CHECK: blr x17 + BLR killed renamable $x17, implicit-def dead $lr, implicit $sp + RET undef $lr, implicit undef $w0 +... +--- +name: indirect_tailcall_x17 +tracksRegLiveness: true +body: | + bb.0: + liveins: $x0 + ; CHECK-LABEL: indirect_tailcall_x17 + ; CHECK: mov x1, sp + ; CHECK: and x1, x1, x16 + ; CHECK: mov sp, x1 + ; CHECK: br x17 + $x8 = ADRP target-flags(aarch64-page) @g + $x17 = LDRXui killed $x8, target-flags(aarch64-pageoff, aarch64-nc) @g + TCRETURNri killed $x17, 0, implicit $sp, implicit $x0 +... +--- +name: indirect_call_lr +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-LABEL: indirect_call_lr + ; CHECK: mov x1, sp + ; CHECK-NEXT: and x1, x1, x16 + ; CHECK-NEXT: mov sp, x1 + ; CHECK-NEXT: blr x30 + liveins: $x0, $lr + BLR killed renamable $lr, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $w0 + $w0 = nsw ADDWri killed $w0, 1, 0 + RET undef $lr, implicit $w0 +... +--- +name: RS_cannot_find_available_regs +tracksRegLiveness: true +body: | + bb.0: + ; In the rare case when no free temporary register is available for the + ; propagate taint-to-sp operation, just put in a full speculation barrier + ; (isb+dsb sy) at the start of the basic block. And don't put masks on + ; instructions for the rest of the basic block, since speculation in that + ; basic block was already done, so no need to do masking. + ; CHECK-LABEL: RS_cannot_find_available_regs + ; CHECK: dsb sy + ; CHECK-NEXT: isb + ; CHECK-NEXT: ldr x0, [x0] + ; The following 2 instructions come from propagating the taint encoded in + ; sp at function entry to x16. It turns out the taint info in x16 is not + ; used in this function, so those instructions could be optimized away. An + ; optimization for later if it turns out this situation occurs often enough. + ; CHECK-NEXT: cmp sp, #0 + ; CHECK-NEXT: csetm x16, ne + ; CHECK-NEXT: ret + liveins: $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15, $x17, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27, $x28, $fp, $lr + $x0 = LDRXui killed $x0, 0 + RET undef $lr, implicit $x0 +... From a008fbedf069ff1caa02f239d6396791b45bcd8f Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 24 Jan 2019 22:26:09 +0000 Subject: [PATCH 043/274] Merging r352040: ------------------------------------------------------------------------ r352040 | ibiryukov | 2019-01-24 11:41:43 +0100 (Thu, 24 Jan 2019) | 9 lines [CodeComplete] [clangd] Fix crash on ValueDecl with a null type Reviewers: kadircet Reviewed By: kadircet Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D57093 ------------------------------------------------------------------------ llvm-svn: 352118 --- clang/lib/Sema/SemaCodeComplete.cpp | 3 ++- clang/test/CodeCompletion/crash-null-type.cpp | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 clang/test/CodeCompletion/crash-null-type.cpp diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index d9f007a46da5e..980d7b455ecec 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -681,7 +681,8 @@ QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) { T = Property->getType(); else if (const auto *Value = dyn_cast(ND)) T = Value->getType(); - else + + if (T.isNull()) return QualType(); // Dig through references, function pointers, and block pointers to diff --git a/clang/test/CodeCompletion/crash-null-type.cpp b/clang/test/CodeCompletion/crash-null-type.cpp new file mode 100644 index 0000000000000..c5b3d1e79390c --- /dev/null +++ b/clang/test/CodeCompletion/crash-null-type.cpp @@ -0,0 +1,8 @@ +void test() { + for (auto [loopVar] : y) { // y has to be unresolved + loopVa + } +} +// RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:3:11 %s -o - \ +// RUN: | FileCheck %s +// CHECK: COMPLETION: loopVar From de8481e60799ccaf21a5e94f9ab2007fe43c6f6d Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 24 Jan 2019 22:26:52 +0000 Subject: [PATCH 044/274] Merging r352040: ------------------------------------------------------------------------ r352040 | ibiryukov | 2019-01-24 11:41:43 +0100 (Thu, 24 Jan 2019) | 9 lines [CodeComplete] [clangd] Fix crash on ValueDecl with a null type Reviewers: kadircet Reviewed By: kadircet Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D57093 ------------------------------------------------------------------------ llvm-svn: 352120 --- clang-tools-extra/clangd/ExpectedTypes.cpp | 4 +++- .../unittests/clangd/CodeCompleteTests.cpp | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clangd/ExpectedTypes.cpp b/clang-tools-extra/clangd/ExpectedTypes.cpp index 4bbf0651260b6..59d9e149162a6 100644 --- a/clang-tools-extra/clangd/ExpectedTypes.cpp +++ b/clang-tools-extra/clangd/ExpectedTypes.cpp @@ -35,8 +35,10 @@ static llvm::Optional typeOfCompletion(const CodeCompletionResult &R) { auto *VD = dyn_cast_or_null(R.Declaration); if (!VD) - return None; // We handle only variables and functions below. + return llvm::None; // We handle only variables and functions below. auto T = VD->getType(); + if (T.isNull()) + return llvm::None; if (auto FuncT = T->getAs()) { // Functions are a special case. They are completed as 'foo()' and we want // to match their return type rather than the function type itself. diff --git a/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp b/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp index 02f12eab7dd6a..f26181decb80f 100644 --- a/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp +++ b/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp @@ -2320,6 +2320,17 @@ TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromMiddle) { EXPECT_THAT(C, ElementsAre(SnippetSuffix("${1:(unsigned int)}"))); } +TEST(CompletionTest, WorksWithNullType) { + auto R = completions(R"cpp( + int main() { + for (auto [loopVar] : y ) { // y has to be unresolved. + int z = loopV^; + } + } + )cpp"); + EXPECT_THAT(R.Completions, ElementsAre(Named("loopVar"))); +} + } // namespace } // namespace clangd } // namespace clang From 400f8a39269550dc02d98f55974e1ef517c35762 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 24 Jan 2019 23:44:31 +0000 Subject: [PATCH 045/274] Merging r352102: ------------------------------------------------------------------------ r352102 | rsmith | 2019-01-24 21:52:56 +0100 (Thu, 24 Jan 2019) | 2 lines Add a triple to this test so it passes for targets where alignof(double) really should be equal to alignof(float). ------------------------------------------------------------------------ llvm-svn: 352132 --- clang/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp index 686aac2802ada..e435bee2c88ee 100644 --- a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp +++ b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -verify %s +// RUN: %clang_cc1 -std=c++11 -verify %s -triple x86_64-linux-gnu alignas(double) void f(); // expected-error {{'alignas' attribute only applies to variables, data members and tag types}} alignas(double) unsigned char c[sizeof(double)]; // expected-note {{previous}} From 24479b1157d357b03d8a00ff5088a4ec15b3367c Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 25 Jan 2019 00:05:14 +0000 Subject: [PATCH 046/274] Merging r352116: ------------------------------------------------------------------------ r352116 | mgorny | 2019-01-24 23:20:47 +0100 (Thu, 24 Jan 2019) | 9 lines [Process/NetBSD] Add missing linkage to -lutil Add missing linkage to fix build failure with LLD: ld: error: undefined symbol: kinfo_getvmmap >>> referenced by NativeProcessNetBSD.cpp >>> NativeProcessNetBSD.cpp.o:(lldb_private::process_netbsd::NativeProcessNetBSD::PopulateMemoryRegionCache()) in archive lib/liblldbPluginProcessNetBSD.a Differential Revision: https://reviews.llvm.org/D57193 ------------------------------------------------------------------------ llvm-svn: 352134 --- lldb/source/Plugins/Process/NetBSD/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/source/Plugins/Process/NetBSD/CMakeLists.txt b/lldb/source/Plugins/Process/NetBSD/CMakeLists.txt index e131e6d70468b..586725bb7a566 100644 --- a/lldb/source/Plugins/Process/NetBSD/CMakeLists.txt +++ b/lldb/source/Plugins/Process/NetBSD/CMakeLists.txt @@ -11,6 +11,7 @@ add_lldb_library(lldbPluginProcessNetBSD PLUGIN lldbUtility lldbPluginProcessPOSIX lldbPluginProcessUtility + util LINK_COMPONENTS Support ) From 22f92b55faf54b64463be3576c38a036a4f7ce2e Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 25 Jan 2019 00:07:12 +0000 Subject: [PATCH 047/274] Merging r352082: ------------------------------------------------------------------------ r352082 | ruiu | 2019-01-24 20:02:31 +0100 (Thu, 24 Jan 2019) | 15 lines Fix broken export table if .rdata is merged with .text. Previously, we assumed that .rdata is zero-filled, so when writing an COFF import table, we didn't write anything if the data is zero. That assumption was wrong because .rdata can be merged with .text. If .rdata is merged with .text, they are initialized with 0xcc which is a trap instruction. This patch removes that assumption from code. Should be merged to 8.0 branch as this is a regression. Fixes https://bugs.llvm.org/show_bug.cgi?id=39826 Differential Revision: https://reviews.llvm.org/D57168 ------------------------------------------------------------------------ llvm-svn: 352135 --- lld/COFF/DLL.cpp | 16 +++++++++++++++- lld/test/COFF/imports.test | 13 +++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/lld/COFF/DLL.cpp b/lld/COFF/DLL.cpp index 599cc5892a16f..c06027d3e5c34 100644 --- a/lld/COFF/DLL.cpp +++ b/lld/COFF/DLL.cpp @@ -47,6 +47,7 @@ class HintNameChunk : public Chunk { } void writeTo(uint8_t *Buf) const override { + memset(Buf + OutputSectionOff, 0, getSize()); write16le(Buf + OutputSectionOff, Hint); memcpy(Buf + OutputSectionOff + 2, Name.data(), Name.size()); } @@ -63,7 +64,10 @@ class LookupChunk : public Chunk { size_t getSize() const override { return Config->Wordsize; } void writeTo(uint8_t *Buf) const override { - write32le(Buf + OutputSectionOff, HintName->getRVA()); + if (Config->is64()) + write64le(Buf + OutputSectionOff, HintName->getRVA()); + else + write32le(Buf + OutputSectionOff, HintName->getRVA()); } Chunk *HintName; @@ -99,6 +103,8 @@ class ImportDirectoryChunk : public Chunk { size_t getSize() const override { return sizeof(ImportDirectoryTableEntry); } void writeTo(uint8_t *Buf) const override { + memset(Buf + OutputSectionOff, 0, getSize()); + auto *E = (coff_import_directory_table_entry *)(Buf + OutputSectionOff); E->ImportLookupTableRVA = LookupTab->getRVA(); E->NameRVA = DLLName->getRVA(); @@ -118,6 +124,10 @@ class NullChunk : public Chunk { bool hasData() const override { return false; } size_t getSize() const override { return Size; } + void writeTo(uint8_t *Buf) const override { + memset(Buf + OutputSectionOff, 0, Size); + } + private: size_t Size; }; @@ -160,6 +170,8 @@ class DelayDirectoryChunk : public Chunk { } void writeTo(uint8_t *Buf) const override { + memset(Buf + OutputSectionOff, 0, getSize()); + auto *E = (delay_import_directory_table_entry *)(Buf + OutputSectionOff); E->Attributes = 1; E->Name = DLLName->getRVA(); @@ -392,6 +404,8 @@ class ExportDirectoryChunk : public Chunk { } void writeTo(uint8_t *Buf) const override { + memset(Buf + OutputSectionOff, 0, getSize()); + auto *E = (export_directory_table_entry *)(Buf + OutputSectionOff); E->NameRVA = DLLName->getRVA(); E->OrdinalBase = 0; diff --git a/lld/test/COFF/imports.test b/lld/test/COFF/imports.test index 64f3900a1c2f3..f54bdfd88dfab 100644 --- a/lld/test/COFF/imports.test +++ b/lld/test/COFF/imports.test @@ -34,3 +34,16 @@ IMPORT-NEXT: Symbol: ExitProcess (0) IMPORT-NEXT: Symbol: (50) IMPORT-NEXT: Symbol: MessageBoxA (1) IMPORT-NEXT: } + +# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /merge:.rdata=.text \ +# RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib /include:ExitProcess +# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=MERGE %s + +MERGE: Import { +MERGE-NEXT: Name: std64.dll +MERGE-NEXT: ImportLookupTableRVA: 0x1090 +MERGE-NEXT: ImportAddressTableRVA: 0x10B0 +MERGE-NEXT: Symbol: ExitProcess (0) +MERGE-NEXT: Symbol: (50) +MERGE-NEXT: Symbol: MessageBoxA (1) +MERGE-NEXT: } From 4474451973eac95b5858830bbb172b088b324897 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 25 Jan 2019 00:12:01 +0000 Subject: [PATCH 048/274] Merging r351485: ------------------------------------------------------------------------ r351485 | vstefanovic | 2019-01-17 22:50:37 +0100 (Thu, 17 Jan 2019) | 10 lines [mips] Emit .reloc R_{MICRO}MIPS_JALR along with j(al)r(c) $25 The callee address is added as an optional operand (MCSymbol) in AdjustInstrPostInstrSelection() and then used by asm printer to insert: '.reloc tmplabel, R_MIPS_JALR, symbol tmplabel:'. Controlled with '-mips-jalr-reloc', default is true. Differential revision: https://reviews.llvm.org/D56694 ------------------------------------------------------------------------ llvm-svn: 352137 --- llvm/lib/CodeGen/MachineInstr.cpp | 5 +- .../Target/Mips/AsmParser/MipsAsmParser.cpp | 5 +- .../Target/Mips/MCTargetDesc/MipsABIInfo.cpp | 7 + .../Target/Mips/MCTargetDesc/MipsBaseInfo.h | 5 +- .../lib/Target/Mips/MicroMips32r6InstrInfo.td | 1 + llvm/lib/Target/Mips/MicroMipsInstrInfo.td | 1 + llvm/lib/Target/Mips/Mips32r6InstrInfo.td | 2 +- llvm/lib/Target/Mips/MipsAsmPrinter.cpp | 41 +++++ llvm/lib/Target/Mips/MipsFastISel.cpp | 13 ++ llvm/lib/Target/Mips/MipsISelLowering.cpp | 53 +++++- llvm/lib/Target/Mips/MipsISelLowering.h | 3 + llvm/lib/Target/Mips/MipsInstrInfo.cpp | 13 +- llvm/lib/Target/Mips/MipsInstrInfo.td | 12 +- llvm/lib/Target/Mips/MipsMCInstLower.cpp | 2 + llvm/test/CodeGen/Mips/cconv/vector.ll | 8 +- llvm/test/CodeGen/Mips/gprestore.ll | 12 +- llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll | 36 ++-- llvm/test/CodeGen/Mips/llvm-ir/srem.ll | 36 ++-- llvm/test/CodeGen/Mips/llvm-ir/udiv.ll | 36 ++-- llvm/test/CodeGen/Mips/llvm-ir/urem.ll | 36 ++-- llvm/test/CodeGen/Mips/long-call-attr.ll | 8 +- llvm/test/CodeGen/Mips/long-call-mcount.ll | 4 +- llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll | 12 +- llvm/test/CodeGen/Mips/o32_cc_byval.ll | 3 +- llvm/test/CodeGen/Mips/reloc-jalr.ll | 154 ++++++++++++++++++ llvm/test/CodeGen/Mips/shrink-wrapping.ll | 8 +- 26 files changed, 408 insertions(+), 108 deletions(-) create mode 100644 llvm/test/CodeGen/Mips/reloc-jalr.ll diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp index 764a84c7e1327..dc1ad953e71d4 100644 --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -225,12 +225,13 @@ void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) { } #ifndef NDEBUG - bool isMetaDataOp = Op.getType() == MachineOperand::MO_Metadata; + bool isDebugOp = Op.getType() == MachineOperand::MO_Metadata || + Op.getType() == MachineOperand::MO_MCSymbol; // OpNo now points as the desired insertion point. Unless this is a variadic // instruction, only implicit regs are allowed beyond MCID->getNumOperands(). // RegMask operands go between the explicit and implicit operands. assert((isImpReg || Op.isRegMask() || MCID->isVariadic() || - OpNo < MCID->getNumOperands() || isMetaDataOp) && + OpNo < MCID->getNumOperands() || isDebugOp) && "Trying to add an operand to a machine instr that is already done!"); #endif diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index d2fed6861477b..f10d100bfe11c 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -65,10 +65,7 @@ class MCInstrInfo; } // end namespace llvm -static cl::opt -EmitJalrReloc("mips-jalr-reloc", cl::Hidden, - cl::desc("MIPS: Emit R_{MICRO}MIPS_JALR relocation with jalr"), - cl::init(true)); +extern cl::opt EmitJalrReloc; namespace { diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp index 18d7dd99be34a..2f2dd4e03c40a 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp @@ -15,6 +15,13 @@ using namespace llvm; +// Note: this option is defined here to be visible from libLLVMMipsAsmParser +// and libLLVMMipsCodeGen +cl::opt +EmitJalrReloc("mips-jalr-reloc", cl::Hidden, + cl::desc("MIPS: Emit R_{MICRO}MIPS_JALR relocation with jalr"), + cl::init(true)); + namespace { static const MCPhysReg O32IntRegs[4] = {Mips::A0, Mips::A1, Mips::A2, Mips::A3}; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h index a90db2384c466..ab8a6753eadcf 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h @@ -89,7 +89,10 @@ namespace MipsII { MO_GOT_HI16, MO_GOT_LO16, MO_CALL_HI16, - MO_CALL_LO16 + MO_CALL_LO16, + + /// Helper operand used to generate R_MIPS_JALR + MO_JALR }; enum { diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td index 814918d25e70d..c441aa76ad40f 100644 --- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -460,6 +460,7 @@ class JALRC16_MMR6_DESC_BASE let isCall = 1; let hasDelaySlot = 0; let Defs = [RA]; + let hasPostISelHook = 1; } class JALRC16_MMR6_DESC : JALRC16_MMR6_DESC_BASE<"jalr", GPR32Opnd>; diff --git a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td index af380a0ec71e0..ccc4f04bb92d8 100644 --- a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td @@ -426,6 +426,7 @@ class JumpLinkRegMM16 : let isCall = 1; let hasDelaySlot = 1; let Defs = [RA]; + let hasPostISelHook = 1; } // 16-bit Jump Reg diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td index 2bd0cf2d59a64..fb239f572ef22 100644 --- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td @@ -1105,7 +1105,7 @@ def : MipsPat<(select i32:$cond, immz, i32:$f), // Pseudo instructions let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1, - hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in { + hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT], hasPostISelHook = 1 in { class TailCallRegR6 : PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>, PseudoInstExpansion<(JumpInst RT:$rt, RO:$rs)>; diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp index 362431fd42a6c..a7a748b0840e1 100644 --- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp @@ -68,6 +68,8 @@ using namespace llvm; #define DEBUG_TYPE "mips-asm-printer" +extern cl::opt EmitJalrReloc; + MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() const { return static_cast(*OutStreamer->getTargetStreamer()); } @@ -148,6 +150,40 @@ void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer, EmitToStreamer(OutStreamer, TmpInst0); } +// If there is an MO_JALR operand, insert: +// +// .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol +// tmplabel: +// +// This is an optimization hint for the linker which may then replace +// an indirect call with a direct branch. +static void emitDirectiveRelocJalr(const MachineInstr &MI, + MCContext &OutContext, + TargetMachine &TM, + MCStreamer &OutStreamer, + const MipsSubtarget &Subtarget) { + for (unsigned int I = MI.getDesc().getNumOperands(), E = MI.getNumOperands(); + I < E; ++I) { + MachineOperand MO = MI.getOperand(I); + if (MO.isMCSymbol() && (MO.getTargetFlags() & MipsII::MO_JALR)) { + MCSymbol *Callee = MO.getMCSymbol(); + if (Callee && !Callee->getName().empty()) { + MCSymbol *OffsetLabel = OutContext.createTempSymbol(); + const MCExpr *OffsetExpr = + MCSymbolRefExpr::create(OffsetLabel, OutContext); + const MCExpr *CaleeExpr = + MCSymbolRefExpr::create(Callee, OutContext); + OutStreamer.EmitRelocDirective + (*OffsetExpr, + Subtarget.inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR", + CaleeExpr, SMLoc(), *TM.getMCSubtargetInfo()); + OutStreamer.EmitLabel(OffsetLabel); + return; + } + } + } +} + void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) { MipsTargetStreamer &TS = getTargetStreamer(); unsigned Opc = MI->getOpcode(); @@ -207,6 +243,11 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) { return; } + if (EmitJalrReloc && + (MI->isReturn() || MI->isCall() || MI->isIndirectBranch())) { + emitDirectiveRelocJalr(*MI, OutContext, TM, *OutStreamer, *Subtarget); + } + MachineBasicBlock::const_instr_iterator I = MI->getIterator(); MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end(); diff --git a/llvm/lib/Target/Mips/MipsFastISel.cpp b/llvm/lib/Target/Mips/MipsFastISel.cpp index 22ade31a72cdb..a18416b9e8610 100644 --- a/llvm/lib/Target/Mips/MipsFastISel.cpp +++ b/llvm/lib/Target/Mips/MipsFastISel.cpp @@ -56,6 +56,7 @@ #include "llvm/IR/Type.h" #include "llvm/IR/User.h" #include "llvm/IR/Value.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCInstrDesc.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSymbol.h" @@ -75,6 +76,8 @@ using namespace llvm; +extern cl::opt EmitJalrReloc; + namespace { class MipsFastISel final : public FastISel { @@ -1551,6 +1554,16 @@ bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) { CLI.Call = MIB; + if (EmitJalrReloc && !Subtarget->inMips16Mode()) { + // Attach callee address to the instruction, let asm printer emit + // .reloc R_MIPS_JALR. + if (Symbol) + MIB.addSym(Symbol, MipsII::MO_JALR); + else + MIB.addSym(FuncInfo.MF->getContext().getOrCreateSymbol( + Addr.getGlobalValue()->getName()), MipsII::MO_JALR); + } + // Finish off the call including any return values. return finishCall(CLI, RetVT, NumBytes); } diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index 8c2a364cdfa95..0f9c075ba0ccf 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -57,6 +57,7 @@ #include "llvm/IR/GlobalValue.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CodeGen.h" @@ -91,6 +92,8 @@ NoZeroDivCheck("mno-check-zero-division", cl::Hidden, cl::desc("MIPS: Don't trap on integer division by zero."), cl::init(false)); +extern cl::opt EmitJalrReloc; + static const MCPhysReg Mips64DPRegs[8] = { Mips::D12_64, Mips::D13_64, Mips::D14_64, Mips::D15_64, Mips::D16_64, Mips::D17_64, Mips::D18_64, Mips::D19_64 @@ -2879,6 +2882,54 @@ getOpndList(SmallVectorImpl &Ops, Ops.push_back(InFlag); } +void MipsTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI, + SDNode *Node) const { + switch (MI.getOpcode()) { + default: + return; + case Mips::JALR: + case Mips::JALRPseudo: + case Mips::JALR64: + case Mips::JALR64Pseudo: + case Mips::JALR16_MM: + case Mips::JALRC16_MMR6: + case Mips::TAILCALLREG: + case Mips::TAILCALLREG64: + case Mips::TAILCALLR6REG: + case Mips::TAILCALL64R6REG: + case Mips::TAILCALLREG_MM: + case Mips::TAILCALLREG_MMR6: { + if (!EmitJalrReloc || + Subtarget.inMips16Mode() || + !isPositionIndependent() || + Node->getNumOperands() < 1 || + Node->getOperand(0).getNumOperands() < 2) { + return; + } + // We are after the callee address, set by LowerCall(). + // If added to MI, asm printer will emit .reloc R_MIPS_JALR for the + // symbol. + const SDValue TargetAddr = Node->getOperand(0).getOperand(1); + StringRef Sym; + if (const GlobalAddressSDNode *G = + dyn_cast_or_null(TargetAddr)) { + Sym = G->getGlobal()->getName(); + } + else if (const ExternalSymbolSDNode *ES = + dyn_cast_or_null(TargetAddr)) { + Sym = ES->getSymbol(); + } + + if (Sym.empty()) + return; + + MachineFunction *MF = MI.getParent()->getParent(); + MCSymbol *S = MF->getContext().getOrCreateSymbol(Sym); + MI.addOperand(MachineOperand::CreateMCSymbol(S, MipsII::MO_JALR)); + } + } +} + /// LowerCall - functions arguments are copied from virtual regs to /// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. SDValue @@ -2930,7 +2981,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // the maximum out going argument area (including the reserved area), and // preallocates the stack space on entrance to the caller. // - // FIXME: We should do the same for efficency and space. + // FIXME: We should do the same for efficiency and space. // Note: The check on the calling convention below must match // MipsABIInfo::GetCalleeAllocdArgSizeInBytes(). diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h index e043f133a09fd..c88633be02b77 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.h +++ b/llvm/lib/Target/Mips/MipsISelLowering.h @@ -341,6 +341,9 @@ class TargetRegisterClass; EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override; + void AdjustInstrPostInstrSelection(MachineInstr &MI, + SDNode *Node) const override; + void HandleByVal(CCState *, unsigned &, unsigned) const override; unsigned getRegisterByName(const char* RegName, EVT VT, diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.cpp b/llvm/lib/Target/Mips/MipsInstrInfo.cpp index bfb4c775205de..e38bef4663a7d 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.cpp +++ b/llvm/lib/Target/Mips/MipsInstrInfo.cpp @@ -653,6 +653,16 @@ MipsInstrInfo::genInstrWithNewOpc(unsigned NewOpc, MIB.addImm(0); + // If I has an MCSymbol operand (used by asm printer, to emit R_MIPS_JALR), + // add it to the new instruction. + for (unsigned J = I->getDesc().getNumOperands(), E = I->getNumOperands(); + J < E; ++J) { + const MachineOperand &MO = I->getOperand(J); + if (MO.isMCSymbol() && (MO.getTargetFlags() & MipsII::MO_JALR)) + MIB.addSym(MO.getMCSymbol(), MipsII::MO_JALR); + } + + } else { for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) { if (BranchWithZeroOperand && (unsigned)ZeroOperandPosition == J) @@ -825,7 +835,8 @@ MipsInstrInfo::getSerializableDirectMachineOperandTargetFlags() const { {MO_GOT_HI16, "mips-got-hi16"}, {MO_GOT_LO16, "mips-got-lo16"}, {MO_CALL_HI16, "mips-call-hi16"}, - {MO_CALL_LO16, "mips-call-lo16"} + {MO_CALL_LO16, "mips-call-lo16"}, + {MO_JALR, "mips-jalr"} }; return makeArrayRef(Flags); } diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index d9398b7d6024a..46721e6cb9e5f 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -1623,11 +1623,15 @@ let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in { class JumpLinkRegPseudo: PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>, - PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>; + PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)> { + let hasPostISelHook = 1; + } class JumpLinkReg: InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), - [], II_JALR, FrmR, opstr>; + [], II_JALR, FrmR, opstr> { + let hasPostISelHook = 1; + } class BGEZAL_FT : @@ -1646,7 +1650,9 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1, class TailCallReg : PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>, - PseudoInstExpansion<(JumpInst RO:$rs)>; + PseudoInstExpansion<(JumpInst RO:$rs)> { + let hasPostISelHook = 1; + } } class BAL_BR_Pseudo : diff --git a/llvm/lib/Target/Mips/MipsMCInstLower.cpp b/llvm/lib/Target/Mips/MipsMCInstLower.cpp index 46b37ceae3918..4a7c0ce2be19b 100644 --- a/llvm/lib/Target/Mips/MipsMCInstLower.cpp +++ b/llvm/lib/Target/Mips/MipsMCInstLower.cpp @@ -117,6 +117,8 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO, case MipsII::MO_CALL_LO16: TargetKind = MipsMCExpr::MEK_CALL_LO16; break; + case MipsII::MO_JALR: + return MCOperand(); } switch (MOTy) { diff --git a/llvm/test/CodeGen/Mips/cconv/vector.ll b/llvm/test/CodeGen/Mips/cconv/vector.ll index 6a07c4f34564d..5c7c3f424c380 100644 --- a/llvm/test/CodeGen/Mips/cconv/vector.ll +++ b/llvm/test/CodeGen/Mips/cconv/vector.ll @@ -1,12 +1,12 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=mips-unknown-linux-gnu -mcpu=mips32 -disable-mips-delay-filler | FileCheck %s --check-prefixes=ALL,MIPS32,MIPS32EB -; RUN: llc < %s -mtriple=mips64-unknown-linux-gnu -relocation-model=pic -mcpu=mips64 -disable-mips-delay-filler | FileCheck %s --check-prefixes=ALL,MIPS64,MIPS64EB +; RUN: llc < %s -mtriple=mips64-unknown-linux-gnu -relocation-model=pic -mcpu=mips64 -disable-mips-delay-filler -mips-jalr-reloc=false | FileCheck %s --check-prefixes=ALL,MIPS64,MIPS64EB ; RUN: llc < %s -mtriple=mips-unknown-linux-gnu -mcpu=mips32r5 -mattr=+fp64,+msa -disable-mips-delay-filler | FileCheck %s --check-prefixes=ALL,MIPS32R5,MIPS32R5EB -; RUN: llc < %s -mtriple=mips64-unknown-linux-gnu -relocation-model=pic -mcpu=mips64r5 -mattr=+fp64,+msa -disable-mips-delay-filler | FileCheck %s --check-prefixes=ALL,MIPS64R5,MIPS64R5EB +; RUN: llc < %s -mtriple=mips64-unknown-linux-gnu -relocation-model=pic -mcpu=mips64r5 -mattr=+fp64,+msa -disable-mips-delay-filler -mips-jalr-reloc=false | FileCheck %s --check-prefixes=ALL,MIPS64R5,MIPS64R5EB ; RUN: llc < %s -mtriple=mipsel-unknown-linux-gnu -mcpu=mips32 -disable-mips-delay-filler | FileCheck %s --check-prefixes=ALL,MIPS32,MIPS32EL -; RUN: llc < %s -mtriple=mips64el-unknown-linux-gnu -relocation-model=pic -mcpu=mips64 -disable-mips-delay-filler | FileCheck %s --check-prefixes=ALL,MIPS64,MIPS64EL +; RUN: llc < %s -mtriple=mips64el-unknown-linux-gnu -relocation-model=pic -mcpu=mips64 -disable-mips-delay-filler -mips-jalr-reloc=false | FileCheck %s --check-prefixes=ALL,MIPS64,MIPS64EL ; RUN: llc < %s -mtriple=mipsel-unknown-linux-gnu -mcpu=mips32r5 -mattr=+fp64,+msa -disable-mips-delay-filler | FileCheck %s --check-prefixes=ALL,MIPS32R5,MIPS32R5EL -; RUN: llc < %s -mtriple=mips64el-unknown-linux-gnu -relocation-model=pic -mcpu=mips64r5 -mattr=+fp64,+msa -disable-mips-delay-filler | FileCheck %s --check-prefixes=ALL,MIPS64R5,MIPS64R5EL +; RUN: llc < %s -mtriple=mips64el-unknown-linux-gnu -relocation-model=pic -mcpu=mips64r5 -mattr=+fp64,+msa -disable-mips-delay-filler -mips-jalr-reloc=false | FileCheck %s --check-prefixes=ALL,MIPS64R5,MIPS64R5EL ; Test that vector types are passed through the integer register set whether or ; not MSA is enabled. This is a ABI requirement for MIPS. For GCC compatibility diff --git a/llvm/test/CodeGen/Mips/gprestore.ll b/llvm/test/CodeGen/Mips/gprestore.ll index 88ac047b66095..a1e696b0ac08b 100644 --- a/llvm/test/CodeGen/Mips/gprestore.ll +++ b/llvm/test/CodeGen/Mips/gprestore.ll @@ -1,10 +1,10 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc -mtriple=mips-mti-linux-gnu < %s -relocation-model=pic | FileCheck %s --check-prefix=O32 -; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic | FileCheck %s --check-prefix=N64 -; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -target-abi n32 | FileCheck %s --check-prefix=N32 -; RUN: llc -mtriple=mips-mti-linux-gnu < %s -relocation-model=pic -O3 | FileCheck %s --check-prefix=O3O32 -; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -O3 | FileCheck %s --check-prefix=O3N64 -; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -target-abi n32 -O3 | FileCheck %s --check-prefix=O3N32 +; RUN: llc -mtriple=mips-mti-linux-gnu < %s -relocation-model=pic -mips-jalr-reloc=false | FileCheck %s --check-prefix=O32 +; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -mips-jalr-reloc=false | FileCheck %s --check-prefix=N64 +; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -target-abi n32 -mips-jalr-reloc=false | FileCheck %s --check-prefix=N32 +; RUN: llc -mtriple=mips-mti-linux-gnu < %s -relocation-model=pic -O3 -mips-jalr-reloc=false | FileCheck %s --check-prefix=O3O32 +; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -O3 -mips-jalr-reloc=false | FileCheck %s --check-prefix=O3N64 +; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -target-abi n32 -O3 -mips-jalr-reloc=false | FileCheck %s --check-prefix=O3N32 ; Test that PIC calls use the $25 register. This is an ABI requirement. diff --git a/llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll b/llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll index e54eaa63222a0..af3d4f50f3fe4 100644 --- a/llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll +++ b/llvm/test/CodeGen/Mips/llvm-ir/sdiv.ll @@ -1,36 +1,38 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=mips -mcpu=mips2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R0R2 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R2 ; RUN: llc < %s -mtriple=mips -mcpu=mips32 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R0R2 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R2 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r5 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=GP32R6 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefix=GP32R6 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips4 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r5 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r6 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=GP64R6 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefix=GP64R6 -; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -mattr=+micromips -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=MMR3 -; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=MMR6 +; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -mattr=+micromips \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false | \ +; RUN: FileCheck %s -check-prefix=MMR3 +; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false | \ +; RUN: FileCheck %s -check-prefix=MMR6 define signext i1 @sdiv_i1(i1 signext %a, i1 signext %b) { ; GP32-LABEL: sdiv_i1: diff --git a/llvm/test/CodeGen/Mips/llvm-ir/srem.ll b/llvm/test/CodeGen/Mips/llvm-ir/srem.ll index ef0502c85d59b..487a5b9b6cbc5 100644 --- a/llvm/test/CodeGen/Mips/llvm-ir/srem.ll +++ b/llvm/test/CodeGen/Mips/llvm-ir/srem.ll @@ -1,36 +1,38 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=mips -mcpu=mips2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R0R2 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R2 ; RUN: llc < %s -mtriple=mips -mcpu=mips32 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R0R2 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R2 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r5 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=GP32R6 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefix=GP32R6 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips4 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r5 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r6 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=GP64R6 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefix=GP64R6 -; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -mattr=+micromips -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=MMR3 -; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=MMR6 +; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -mattr=+micromips \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false | \ +; RUN: FileCheck %s -check-prefix=MMR3 +; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false | \ +; RUN: FileCheck %s -check-prefix=MMR6 define signext i1 @srem_i1(i1 signext %a, i1 signext %b) { ; GP32-LABEL: srem_i1: diff --git a/llvm/test/CodeGen/Mips/llvm-ir/udiv.ll b/llvm/test/CodeGen/Mips/llvm-ir/udiv.ll index 8694a9f92b65a..3b7243712024b 100644 --- a/llvm/test/CodeGen/Mips/llvm-ir/udiv.ll +++ b/llvm/test/CodeGen/Mips/llvm-ir/udiv.ll @@ -1,36 +1,38 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=mips -mcpu=mips2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R1 ; RUN: llc < %s -mtriple=mips -mcpu=mips32 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R1 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r5 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=GP32R6 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefix=GP32R6 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips4 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R2 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R2 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r5 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r6 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=GP64R6 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefix=GP64R6 -; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -mattr=+micromips -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=MMR3 -; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=MMR6 +; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -mattr=+micromips \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false | \ +; RUN: FileCheck %s -check-prefix=MMR3 +; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false | \ +; RUN: FileCheck %s -check-prefix=MMR6 define zeroext i1 @udiv_i1(i1 zeroext %a, i1 zeroext %b) { ; GP32-LABEL: udiv_i1: diff --git a/llvm/test/CodeGen/Mips/llvm-ir/urem.ll b/llvm/test/CodeGen/Mips/llvm-ir/urem.ll index b744f706cbf9c..4105d67da6f1a 100644 --- a/llvm/test/CodeGen/Mips/llvm-ir/urem.ll +++ b/llvm/test/CodeGen/Mips/llvm-ir/urem.ll @@ -1,36 +1,38 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=mips -mcpu=mips2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R0R2 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R2 ; RUN: llc < %s -mtriple=mips -mcpu=mips32 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R0R2 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R0R2 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r5 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP32,GP32R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP32,GP32R2R5 ; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=GP32R6 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefix=GP32R6 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips4 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R0R1 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R0R1 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r2 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r3 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r5 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefixes=GP64,GP64R2R5 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefixes=GP64,GP64R2R5 ; RUN: llc < %s -mtriple=mips64 -mcpu=mips64r6 -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=GP64R6 +; RUN: -mips-jalr-reloc=false | FileCheck %s -check-prefix=GP64R6 -; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -mattr=+micromips -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=MMR3 -; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips -relocation-model=pic \ -; RUN: | FileCheck %s -check-prefix=MMR6 +; RUN: llc < %s -mtriple=mips -mcpu=mips32r3 -mattr=+micromips \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false | \ +; RUN: FileCheck %s -check-prefix=MMR3 +; RUN: llc < %s -mtriple=mips -mcpu=mips32r6 -mattr=+micromips \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false | \ +; RUN: FileCheck %s -check-prefix=MMR6 define signext i1 @urem_i1(i1 signext %a, i1 signext %b) { ; GP32-LABEL: urem_i1: diff --git a/llvm/test/CodeGen/Mips/long-call-attr.ll b/llvm/test/CodeGen/Mips/long-call-attr.ll index 5b6ba94aaa356..beda290a9725b 100644 --- a/llvm/test/CodeGen/Mips/long-call-attr.ll +++ b/llvm/test/CodeGen/Mips/long-call-attr.ll @@ -1,11 +1,11 @@ ; RUN: llc -march=mips -target-abi o32 --mattr=+long-calls,+noabicalls < %s \ -; RUN: | FileCheck -check-prefix=O32 %s +; RUN: -mips-jalr-reloc=false | FileCheck -check-prefix=O32 %s ; RUN: llc -march=mips -target-abi o32 --mattr=-long-calls,+noabicalls < %s \ -; RUN: | FileCheck -check-prefix=O32 %s +; RUN: -mips-jalr-reloc=false | FileCheck -check-prefix=O32 %s ; RUN: llc -march=mips64 -target-abi n64 --mattr=+long-calls,+noabicalls < %s \ -; RUN: | FileCheck -check-prefix=N64 %s +; RUN: -mips-jalr-reloc=false | FileCheck -check-prefix=N64 %s ; RUN: llc -march=mips64 -target-abi n64 --mattr=-long-calls,+noabicalls < %s \ -; RUN: | FileCheck -check-prefix=N64 %s +; RUN: -mips-jalr-reloc=false | FileCheck -check-prefix=N64 %s declare void @far() #0 diff --git a/llvm/test/CodeGen/Mips/long-call-mcount.ll b/llvm/test/CodeGen/Mips/long-call-mcount.ll index 70a4410d060ba..580f452526f73 100644 --- a/llvm/test/CodeGen/Mips/long-call-mcount.ll +++ b/llvm/test/CodeGen/Mips/long-call-mcount.ll @@ -1,8 +1,8 @@ ; Check call to mcount in case of long/short call options. ; RUN: llc -march=mips -target-abi o32 --mattr=+long-calls,+noabicalls < %s \ -; RUN: | FileCheck -check-prefixes=CHECK,LONG %s +; RUN: -mips-jalr-reloc=false | FileCheck -check-prefixes=CHECK,LONG %s ; RUN: llc -march=mips -target-abi o32 --mattr=-long-calls,+noabicalls < %s \ -; RUN: | FileCheck -check-prefixes=CHECK,SHORT %s +; RUN: -mips-jalr-reloc=false | FileCheck -check-prefixes=CHECK,SHORT %s ; Function Attrs: noinline nounwind optnone define void @foo() #0 { diff --git a/llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll b/llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll index 9105e9249d4f0..8544a75c50a62 100644 --- a/llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll +++ b/llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll @@ -1,22 +1,22 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -relocation-model=pic -mtriple=mipsel-- -mcpu=mips32r5 \ -; RUN: -mattr=+fp64,+msa -verify-machineinstrs < %s | FileCheck %s \ +; RUN: -mattr=+fp64,+msa -verify-machineinstrs -mips-jalr-reloc=false < %s | FileCheck %s \ ; RUN: --check-prefixes=ALL,MIPS32,MIPSR5,MIPS32-O32,MIPS32R5-O32 ; RUN: llc -relocation-model=pic -mtriple=mips64el-- -mcpu=mips64r5 \ -; RUN: -mattr=+fp64,+msa -verify-machineinstrs -target-abi n32 < %s | FileCheck %s \ +; RUN: -mattr=+fp64,+msa -verify-machineinstrs -target-abi n32 -mips-jalr-reloc=false < %s | FileCheck %s \ ; RUN: --check-prefixes=ALL,MIPS64,MIPSR5,MIPS64-N32,MIPS64R5-N32 ; RUN: llc -relocation-model=pic -mtriple=mips64el-- -mcpu=mips64r5 \ -; RUN: -mattr=+fp64,+msa -verify-machineinstrs -target-abi n64 < %s | FileCheck %s \ +; RUN: -mattr=+fp64,+msa -verify-machineinstrs -target-abi n64 -mips-jalr-reloc=false < %s | FileCheck %s \ ; RUN: --check-prefixes=ALL,MIPS64,MIPSR5,MIPS64-N64,MIPS64R5-N64 ; RUN: llc -relocation-model=pic -mtriple=mipsel-- -mcpu=mips32r6 \ -; RUN: -mattr=+fp64,+msa -verify-machineinstrs < %s | FileCheck %s \ +; RUN: -mattr=+fp64,+msa -verify-machineinstrs -mips-jalr-reloc=false < %s | FileCheck %s \ ; RUN: --check-prefixes=ALL,MIPS32,MIPSR6,MIPSR6-O32 ; RUN: llc -relocation-model=pic -mtriple=mips64el-- -mcpu=mips64r6 \ -; RUN: -mattr=+fp64,+msa -verify-machineinstrs -target-abi n32 < %s | FileCheck %s \ +; RUN: -mattr=+fp64,+msa -verify-machineinstrs -target-abi n32 -mips-jalr-reloc=false < %s | FileCheck %s \ ; RUN: --check-prefixes=ALL,MIPS64,MIPSR6,MIPS64-N32,MIPSR6-N32 ; RUN: llc -relocation-model=pic -mtriple=mips64el-- -mcpu=mips64r6 \ -; RUN: -mattr=+fp64,+msa -verify-machineinstrs -target-abi n64 < %s | FileCheck %s \ +; RUN: -mattr=+fp64,+msa -verify-machineinstrs -target-abi n64 -mips-jalr-reloc=false < %s | FileCheck %s \ ; RUN: --check-prefixes=ALL,MIPS64,MIPSR6,MIPS64-N64,MIPSR6-N64 diff --git a/llvm/test/CodeGen/Mips/o32_cc_byval.ll b/llvm/test/CodeGen/Mips/o32_cc_byval.ll index 19eb80b79bafe..d9951ebeaf3a9 100644 --- a/llvm/test/CodeGen/Mips/o32_cc_byval.ll +++ b/llvm/test/CodeGen/Mips/o32_cc_byval.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc -mtriple=mipsel-unknown-linux-gnu -relocation-model=pic < %s | FileCheck %s +; RUN: llc -mtriple=mipsel-unknown-linux-gnu -relocation-model=pic \ +; RUN: -mips-jalr-reloc=false < %s | FileCheck %s %0 = type { i8, i16, i32, i64, double, i32, [4 x i8] } %struct.S1 = type { i8, i16, i32, i64, double, i32 } diff --git a/llvm/test/CodeGen/Mips/reloc-jalr.ll b/llvm/test/CodeGen/Mips/reloc-jalr.ll new file mode 100644 index 0000000000000..f8fd903110045 --- /dev/null +++ b/llvm/test/CodeGen/Mips/reloc-jalr.ll @@ -0,0 +1,154 @@ +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-32R2,TAILCALL-32R2 + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-64R2,TAILCALL-64R2 + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 -mcpu=mips32r6 -mips-compact-branches=always < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-32R6,TAILCALL-32R6 + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 -mcpu=mips64r6 -mips-compact-branches=always < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-64R6,TAILCALL-64R6 + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 -mcpu=mips32r6 -mips-compact-branches=never < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-32R2,TAILCALL-32R2 + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 -mcpu=mips64r6 -mips-compact-branches=never < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-64R2,TAILCALL-64R2 + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 -mattr=+micromips -mcpu=mips32r2 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-MM,TAILCALL-MM + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 -mattr=+micromips -mcpu=mips32r6 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-MM + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \ +; RUN: -O0 < %s | FileCheck %s -check-prefixes=ALL,JALR-32R2 + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic \ +; RUN: -O0 < %s | FileCheck %s -check-prefixes=ALL,JALR-64R2 + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \ +; RUN: -O0 -mcpu=mips32r6 -mips-compact-branches=always < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-32R6 + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic \ +; RUN: -O0 -mcpu=mips64r6 -mips-compact-branches=always < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-64R6 + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \ +; RUN: -O0 -mcpu=mips32r6 -mips-compact-branches=never < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-32R2 + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic \ +; RUN: -O0 -mcpu=mips64r6 -mips-compact-branches=never < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-64R2 + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \ +; RUN: -O0 -mattr=+micromips -mcpu=mips32r2 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-MM + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \ +; RUN: -O0 -mattr=+micromips -mcpu=mips32r6 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,JALR-MM + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 -mips-jalr-reloc=false < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,NORELOC + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=static -mips-tail-calls=1 \ +; RUN: -O2 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,NORELOC + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O0 -mips-jalr-reloc=false < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,NORELOC + +; RUN: llc -mtriple=mips-linux-gnu -relocation-model=static -mips-tail-calls=1 \ +; RUN: -O0 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,NORELOC + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic -mips-tail-calls=1 \ +; RUN: -O2 -mips-jalr-reloc=false < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,NORELOC + +; RUN: llc -mtriple=mips64-linux-gnu -mips-tail-calls=1 \ +; RUN: -O2 -relocation-model=static < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,NORELOC + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic \ +; RUN: -O0 -mips-jalr-reloc=false < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,NORELOC + +; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=static \ +; RUN: -O0 < %s | \ +; RUN: FileCheck %s -check-prefixes=ALL,NORELOC + +define internal void @foo() noinline { +entry: + ret void +} + +define void @checkCall() { +entry: +; ALL-LABEL: checkCall: + call void @foo() +; JALR-32R2: .reloc ([[TMPLABEL:.*]]), R_MIPS_JALR, foo +; JALR-32R2-NEXT: [[TMPLABEL]]: +; JALR-32R2-NEXT: jalr $25 + +; JALR-64R2: .reloc [[TMPLABEL:.*]], R_MIPS_JALR, foo +; JALR-64R2-NEXT: [[TMPLABEL]]: +; JALR-64R2-NEXT: jalr $25 + +; JALR-MM: .reloc ([[TMPLABEL:.*]]), R_MICROMIPS_JALR, foo +; JALR-MM-NEXT: [[TMPLABEL]]: +; JALR-MM-NEXT: jalr $25 + +; JALR-32R6: .reloc ([[TMPLABEL:.*]]), R_MIPS_JALR, foo +; JALR-32R6-NEXT: [[TMPLABEL]]: +; JALR-32R6-NEXT: jalrc $25 + +; JALR-64R6: .reloc [[TMPLABEL:.*]], R_MIPS_JALR, foo +; JALR-64R6-NEXT: [[TMPLABEL]]: +; JALR-64R6-NEXT: jalrc $25 + +; NORELOC-NOT: R_MIPS_JALR + ret void +} + +define void @checkTailCall() { +entry: +; ALL-LABEL: checkTailCall: + tail call void @foo() +; TAILCALL-32R2: .reloc ([[TMPLABEL:.*]]), R_MIPS_JALR, foo +; TAILCALL-32R2-NEXT: [[TMPLABEL]]: +; TAILCALL-32R2-NEXT: jr $25 + +; TAILCALL-64R2: .reloc [[TMPLABEL:.*]], R_MIPS_JALR, foo +; TAILCALL-64R2-NEXT: [[TMPLABEL]]: +; TAILCALL-64R2-NEXT: jr $25 + +; TAILCALL-MM: .reloc ([[TMPLABEL:.*]]), R_MICROMIPS_JALR, foo +; TAILCALL-MM-NEXT: [[TMPLABEL]]: +; TAILCALL-MM-NEXT: jrc $25 + +; TAILCALL-32R6: .reloc ([[TMPLABEL:.*]]), R_MIPS_JALR, foo +; TAILCALL-32R6-NEXT: [[TMPLABEL]]: +; TAILCALL-32R6-NEXT: jrc $25 + +; TAILCALL-64R6: .reloc [[TMPLABEL:.*]], R_MIPS_JALR, foo +; TAILCALL-64R6-NEXT: [[TMPLABEL]]: +; TAILCALL-64R6-NEXT: jrc $25 + +; NORELOC-NOT: R_MIPS_JALR + ret void +} diff --git a/llvm/test/CodeGen/Mips/shrink-wrapping.ll b/llvm/test/CodeGen/Mips/shrink-wrapping.ll index 54ae8699d1c19..b08d2f1b64678 100644 --- a/llvm/test/CodeGen/Mips/shrink-wrapping.ll +++ b/llvm/test/CodeGen/Mips/shrink-wrapping.ll @@ -9,11 +9,11 @@ ; RUN: FileCheck %s -check-prefix=NO-SHRINK-WRAP-STATIC ; RUN: llc -mtriple=mips-unknown-linux-gnu -enable-shrink-wrap=true \ -; RUN: -relocation-model=pic < %s | \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false < %s | \ ; RUN: FileCheck %s -check-prefix=SHRINK-WRAP-PIC ; RUN: llc -mtriple=mips-unknown-linux-gnu -enable-shrink-wrap=false \ -; RUN: -relocation-model=pic < %s | \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false < %s | \ ; RUN: FileCheck %s -check-prefix=NO-SHRINK-WRAP-PIC ; RUN: llc -mtriple=mips64-unknown-linux-gnu -enable-shrink-wrap=true \ @@ -25,11 +25,11 @@ ; RUN: FileCheck %s -check-prefix=NO-SHRINK-WRAP-64-STATIC ; RUN: llc -mtriple=mips64-unknown-linux-gnu -enable-shrink-wrap=true \ -; RUN: -relocation-model=pic < %s | \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false < %s | \ ; RUN: FileCheck %s -check-prefix=SHRINK-WRAP-64-PIC ; RUN: llc -mtriple=mips64-unknown-linux-gnu -enable-shrink-wrap=false \ -; RUN: -relocation-model=pic < %s | \ +; RUN: -relocation-model=pic -mips-jalr-reloc=false < %s | \ ; RUN: FileCheck %s -check-prefix=NO-SHRINK-WRAP-64-PIC declare void @f(i32 signext) From b7988f706e2227af6fd540caad7efa34d00ebb6b Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 25 Jan 2019 00:15:41 +0000 Subject: [PATCH 049/274] Merging r351579: ------------------------------------------------------------------------ r351579 | vstefanovic | 2019-01-18 20:54:51 +0100 (Fri, 18 Jan 2019) | 9 lines [mips] Add '-mrelax-pic-calls', '-mno-relax-pic-calls' These two options enable/disable emission of R_{MICRO}MIPS_JALR fixups along with PIC calls. The linker may then try to turn PIC calls into direct jumps. By default, these fixups do get emitted by the backend, use '-mno-relax-pic-calls' to omit them. Differential revision: https://reviews.llvm.org/D56878 ------------------------------------------------------------------------ llvm-svn: 352139 --- clang/include/clang/Driver/Options.td | 8 ++++++++ clang/lib/Driver/ToolChains/Clang.cpp | 8 ++++++++ clang/test/Driver/mips-features.c | 12 ++++++++++++ 3 files changed, 28 insertions(+) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index f02a7190f5a7a..d8155a95775c2 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2418,6 +2418,14 @@ def modd_spreg : Flag<["-"], "modd-spreg">, Group, def mno_odd_spreg : Flag<["-"], "mno-odd-spreg">, Group, HelpText<"Disable odd single-precision floating point registers">, Flags<[HelpHidden]>; +def mrelax_pic_calls : Flag<["-"], "mrelax-pic-calls">, + Group, + HelpText<"Try turning PIC calls (j{al}r{c} $25) into direct calls " + "(MIPS only)">, Flags<[HelpHidden]>; +def mno_relax_pic_calls : Flag<["-"], "mno-relax-pic-calls">, + Group, + HelpText<"Do not try turning PIC calls (j{al}r{c} $25) into direct calls " + "(MIPS only)">, Flags<[HelpHidden]>; def mglibc : Flag<["-"], "mglibc">, Group, Flags<[HelpHidden]>; def muclibc : Flag<["-"], "muclibc">, Group, Flags<[HelpHidden]>; def module_file_info : Flag<["-"], "module-file-info">, Flags<[DriverOption,CC1Option]>, Group, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 75f16898dfaf6..589f53b119217 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1716,6 +1716,14 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args, } else D.Diag(diag::warn_target_unsupported_compact_branches) << CPUName; } + + if (Arg *A = Args.getLastArg(options::OPT_mrelax_pic_calls, + options::OPT_mno_relax_pic_calls)) { + if (A->getOption().matches(options::OPT_mno_relax_pic_calls)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-mips-jalr-reloc=0"); + } + } } void Clang::AddPPCTargetArgs(const ArgList &Args, diff --git a/clang/test/Driver/mips-features.c b/clang/test/Driver/mips-features.c index f63fb8de55d6c..19725bc096b5d 100644 --- a/clang/test/Driver/mips-features.c +++ b/clang/test/Driver/mips-features.c @@ -444,3 +444,15 @@ // RUN: -mginv -mno-ginv 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NO-GINV %s // CHECK-NO-GINV: "-target-feature" "-ginv" +// +// -mrelax-pic-calls +// RUN: %clang -target mips-unknown-linux-gnu -### -c %s \ +// RUN: -mno-relax-pic-calls -mrelax-pic-calls 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RELAX-PIC-CALLS %s +// CHECK-RELAX-PIC-CALLS-NOT: "-mllvm" "-mips-jalr-reloc=0" +// +// -mno-relax-pic-calls +// RUN: %clang -target mips-unknown-linux-gnu -### -c %s \ +// RUN: -mrelax-pic-calls -mno-relax-pic-calls 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NO-RELAX-PIC-CALLS %s +// CHECK-NO-RELAX-PIC-CALLS: "-mllvm" "-mips-jalr-reloc=0" From e25507d4378c85983ec4f55d9f2a606864752950 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 25 Jan 2019 00:18:40 +0000 Subject: [PATCH 050/274] Merging r352034: ------------------------------------------------------------------------ r352034 | atanasyan | 2019-01-24 10:13:14 +0100 (Thu, 24 Jan 2019) | 18 lines Reapply: [mips] Handle MipsMCExpr sub-expression for the MEK_DTPREL tag This reapplies commit r351987 with a failed test fix. Now the test accepts both DW_OP_GNU_push_tls_address and DW_OP_form_tls_address opcode. Original commit message: ``` This is a fix for a regression introduced by the rL348194 commit. In that change new type (MEK_DTPREL) of MipsMCExpr expression was added, but in some places of the code this type of expression considered as unexpected. This change fixes the bug. The MEK_DTPREL type of expression is used for marking TLS DIEExpr only and contains a regular sub-expression. Where we need to handle the expression, we retrieve the sub-expression and handle it in a common way. ``` ------------------------------------------------------------------------ llvm-svn: 352140 --- .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 5 ++-- .../Target/Mips/MCTargetDesc/MipsMCExpr.cpp | 14 +++++----- llvm/test/DebugInfo/Mips/dwarfdump-tls.ll | 26 +++++++++++++++++-- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index f43a4d980f92a..e3dcbaccfd080 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -614,8 +614,9 @@ getExprOpValue(const MCExpr *Expr, SmallVectorImpl &Fixups, llvm_unreachable("Unhandled fixup kind!"); break; case MipsMCExpr::MEK_DTPREL: - llvm_unreachable("MEK_DTPREL is used for TLS DIEExpr only"); - break; + // MEK_DTPREL is used for marking TLS DIEExpr only + // and contains a regular sub-expression. + return getExprOpValue(MipsExpr->getSubExpr(), Fixups, STI); case MipsMCExpr::MEK_CALL_HI16: FixupKind = Mips::fixup_Mips_CALL_HI16; break; diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp index 99857e083c6ca..2d7312725205f 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp @@ -44,8 +44,10 @@ void MipsMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { llvm_unreachable("MEK_None and MEK_Special are invalid"); break; case MEK_DTPREL: - llvm_unreachable("MEK_DTPREL is used for TLS DIEExpr only"); - break; + // MEK_DTPREL is used for marking TLS DIEExpr only + // and contains a regular sub-expression. + getSubExpr()->print(OS, MAI, true); + return; case MEK_CALL_HI16: OS << "%call_hi"; break; @@ -161,7 +163,9 @@ MipsMCExpr::evaluateAsRelocatableImpl(MCValue &Res, case MEK_Special: llvm_unreachable("MEK_None and MEK_Special are invalid"); case MEK_DTPREL: - llvm_unreachable("MEK_DTPREL is used for TLS DIEExpr only"); + // MEK_DTPREL is used for marking TLS DIEExpr only + // and contains a regular sub-expression. + return getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup); case MEK_DTPREL_HI: case MEK_DTPREL_LO: case MEK_GOT: @@ -249,9 +253,6 @@ void MipsMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { case MEK_Special: llvm_unreachable("MEK_None and MEK_Special are invalid"); break; - case MEK_DTPREL: - llvm_unreachable("MEK_DTPREL is used for TLS DIEExpr only"); - break; case MEK_CALL_HI16: case MEK_CALL_LO16: case MEK_GOT: @@ -274,6 +275,7 @@ void MipsMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { if (const MipsMCExpr *E = dyn_cast(getSubExpr())) E->fixELFSymbolsInTLSFixups(Asm); break; + case MEK_DTPREL: case MEK_DTPREL_HI: case MEK_DTPREL_LO: case MEK_TLSLDM: diff --git a/llvm/test/DebugInfo/Mips/dwarfdump-tls.ll b/llvm/test/DebugInfo/Mips/dwarfdump-tls.ll index 6aa429adb417b..8d8af8c5124a9 100644 --- a/llvm/test/DebugInfo/Mips/dwarfdump-tls.ll +++ b/llvm/test/DebugInfo/Mips/dwarfdump-tls.ll @@ -1,12 +1,34 @@ -; RUN: llc -O0 -march=mips -mcpu=mips32r2 -filetype=obj -o=%t-32.o < %s +; RUN: llc -O0 -march=mips -mcpu=mips32r2 -filetype=obj \ +; RUN: -split-dwarf-file=foo.dwo -o=%t-32.o < %s ; RUN: llvm-dwarfdump %t-32.o 2>&1 | FileCheck %s -; RUN: llc -O0 -march=mips64 -mcpu=mips64r2 -filetype=obj -o=%t-64.o < %s +; RUN: llc -O0 -march=mips64 -mcpu=mips64r2 -filetype=obj \ +; RUN: -split-dwarf-file=foo.dwo -o=%t-64.o < %s ; RUN: llvm-dwarfdump %t-64.o 2>&1 | FileCheck %s +; RUN: llc -O0 -march=mips -mcpu=mips32r2 -filetype=asm \ +; RUN: -split-dwarf-file=foo.dwo < %s | FileCheck -check-prefix=ASM32 %s +; RUN: llc -O0 -march=mips64 -mcpu=mips64r2 -filetype=asm \ +; RUN: -split-dwarf-file=foo.dwo < %s | FileCheck -check-prefix=ASM64 %s + @x = thread_local global i32 5, align 4, !dbg !0 ; CHECK-NOT: error: failed to compute relocation: R_MIPS_TLS_DTPREL +; CHECK: DW_AT_name ("x") +; CHECK-NEXT: DW_AT_type (0x00000025 "int") +; CHECK-NEXT: DW_AT_external (true) +; CHECK-NEXT: DW_AT_decl_file (0x01) +; CHECK-NEXT: DW_AT_decl_line (1) +; CHECK-NEXT: DW_AT_location (DW_OP_GNU_const_index 0x0, {{DW_OP_GNU_push_tls_address|DW_OP_form_tls_address}}) + +; ASM32: .section .debug_addr +; ASM32-NEXT: $addr_table_base0: +; ASM32-NEXT: .4byte x+32768 + +; ASM64: .section .debug_addr +; ASM64-NEXT: .Laddr_table_base0: +; ASM64-NEXT: .8byte x+32768 + !llvm.dbg.cu = !{!2} !llvm.module.flags = !{!7, !8} From af62a72c724c620cbf704315761359fb2db6071f Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 25 Jan 2019 17:01:21 +0000 Subject: [PATCH 051/274] Merging r352068: ------------------------------------------------------------------------ r352068 | serge_sans_paille | 2019-01-24 18:56:08 +0100 (Thu, 24 Jan 2019) | 7 lines Partial support of SHT_GROUP without flag This does *not* implement full SHT_GROUP semantic, yet it is a simple step forward: Sections within a group are still considered valid, but they do not behave as specified by the standard in case of garbage collection. Differential Revision: https://reviews.llvm.org/D56437 ------------------------------------------------------------------------ llvm-svn: 352218 --- lld/ELF/InputFiles.cpp | 41 +++++++++++------------ lld/test/ELF/sht-group-empty.test | 55 +++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 22 deletions(-) create mode 100644 lld/test/ELF/sht-group-empty.test diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index e4d1dec7cbcbd..117dd17894eb0 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -320,17 +320,6 @@ StringRef ObjFile::getShtGroupSignature(ArrayRef Sections, return Signature; } -template -ArrayRef::Elf_Word> -ObjFile::getShtGroupEntries(const Elf_Shdr &Sec) { - const ELFFile &Obj = this->getObj(); - ArrayRef Entries = - CHECK(Obj.template getSectionContentsAsArray(&Sec), this); - if (Entries.empty() || Entries[0] != GRP_COMDAT) - fatal(toString(this) + ": unsupported SHT_GROUP format"); - return Entries.slice(1); -} - template bool ObjFile::shouldMerge(const Elf_Shdr &Sec) { // On a regular link we don't merge sections if -O0 (default is -O1). This // sometimes makes the linker significantly faster, although the output will @@ -440,26 +429,34 @@ void ObjFile::initializeSections( case SHT_GROUP: { // De-duplicate section groups by their signatures. StringRef Signature = getShtGroupSignature(ObjSections, Sec); - bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second; this->Sections[I] = &InputSection::Discarded; - // We only support GRP_COMDAT type of group. Get the all entries of the - // section here to let getShtGroupEntries to check the type early for us. - ArrayRef Entries = getShtGroupEntries(Sec); - // If it is a new section group, we want to keep group members. - // Group leader sections, which contain indices of group members, are - // discarded because they are useless beyond this point. The only - // exception is the -r option because in order to produce re-linkable - // object files, we want to pass through basically everything. + ArrayRef Entries = + CHECK(Obj.template getSectionContentsAsArray(&Sec), this); + if (Entries.empty()) + fatal(toString(this) + ": empty SHT_GROUP"); + + // The first word of a SHT_GROUP section contains flags. Currently, + // the standard defines only "GRP_COMDAT" flag for the COMDAT group. + // An group with the empty flag doesn't define anything; such sections + // are just skipped. + if (Entries[0] == 0) + continue; + + if (Entries[0] != GRP_COMDAT) + fatal(toString(this) + ": unsupported SHT_GROUP format"); + + bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second; if (IsNew) { if (Config->Relocatable) this->Sections[I] = createInputSection(Sec); - continue; + continue; } + // Otherwise, discard group members. - for (uint32_t SecIndex : Entries) { + for (uint32_t SecIndex : Entries.slice(1)) { if (SecIndex >= Size) fatal(toString(this) + ": invalid section index in group: " + Twine(SecIndex)); diff --git a/lld/test/ELF/sht-group-empty.test b/lld/test/ELF/sht-group-empty.test new file mode 100644 index 0000000000000..46c77f332e7e7 --- /dev/null +++ b/lld/test/ELF/sht-group-empty.test @@ -0,0 +1,55 @@ +# RUN: yaml2obj %s -o %t.o +# RUN: ld.lld %t.o %t.o -o %t -r +# RUN: llvm-readobj -s %t | FileCheck %s + +# CHECK: Name: .text.foo +# CHECK: Name: .rela.text.foo + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .group + Type: SHT_GROUP + Link: .symtab + Info: foo + Members: + - SectionOrType: GRP_COMDAT + - SectionOrType: .text.foo + - SectionOrType: .text.bar + - SectionOrType: .note + - Name: .note + Type: SHT_NOTE + Flags: [ SHF_GROUP ] + - Name: .text.foo + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ] + - Name: .text.bar + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ] + - Name: .rela.text.foo + Type: SHT_RELA + Flags: [ SHF_INFO_LINK, SHF_GROUP ] + Link: .symtab + Info: .text.foo + Relocations: + - Offset: 0x0000000000000000 + Symbol: foo + Type: R_X86_64_64 + - Name: .rela.text.bar + Type: SHT_RELA + Flags: [ SHF_INFO_LINK, SHF_GROUP ] + Link: .symtab + Info: .text.bar + Relocations: + - Offset: 0x0000000000000000 + Symbol: bar + Type: R_X86_64_64 +Symbols: + Global: + - Name: foo + - Name: bar + From 4ba28fc323461e9c7016f484be5e241f98d97841 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 25 Jan 2019 18:18:53 +0000 Subject: [PATCH 052/274] Merging r352079: ------------------------------------------------------------------------ r352079 | sammccall | 2019-01-24 19:55:24 +0100 (Thu, 24 Jan 2019) | 33 lines [FileManager] Revert r347205 to avoid PCH file-descriptor leak. Summary: r347205 fixed a bug in FileManager: first calling getFile(shouldOpen=false) and then getFile(shouldOpen=true) results in the file not being open. Unfortunately, some code was (inadvertently?) relying on this bug: when building with a PCH, the file entries are obtained first by passing shouldOpen=false, and then later shouldOpen=true, without any intention of reading them. After r347205, they do get unneccesarily opened. Aside from extra operations, this means they need to be closed. Normally files are closed when their contents are read. As these files are never read, they stay open until clang exits. On platforms with a low open-files limit (e.g. Mac), this can lead to spurious file-not-found errors when building large projects with PCH enabled, e.g. https://bugs.chromium.org/p/chromium/issues/detail?id=924225 Fixing the callsites to pass shouldOpen=false when the file won't be read is not quite trivial (that info isn't available at the direct callsite), and passing shouldOpen=false is a performance regression (it results in open+fstat pairs being replaced by stat+open). So an ideal fix is going to be a little risky and we need some fix soon (especially for the llvm 8 branch). The problem addressed by r347205 is rare and has only been observed in clangd. It was present in llvm-7, so we can live with it for now. Reviewers: bkramer, thakis Subscribers: ilya-biryukov, ioeric, kadircet, cfe-commits Differential Revision: https://reviews.llvm.org/D57165 ------------------------------------------------------------------------ llvm-svn: 352225 --- clang/include/clang/Basic/FileManager.h | 5 ++-- clang/lib/Basic/FileManager.cpp | 35 +++++++---------------- clang/test/PCH/leakfiles | 29 +++++++++++++++++++ clang/unittests/Basic/FileManagerTest.cpp | 27 ----------------- 4 files changed, 42 insertions(+), 54 deletions(-) create mode 100644 clang/test/PCH/leakfiles diff --git a/clang/include/clang/Basic/FileManager.h b/clang/include/clang/Basic/FileManager.h index e7891baf53047..6a71289f74c1d 100644 --- a/clang/include/clang/Basic/FileManager.h +++ b/clang/include/clang/Basic/FileManager.h @@ -70,15 +70,14 @@ class FileEntry { bool IsNamedPipe; bool InPCH; bool IsValid; // Is this \c FileEntry initialized and valid? - bool DeferredOpen; // Created by getFile(OpenFile=0); may open later. /// The open file, if it is owned by the \p FileEntry. mutable std::unique_ptr File; public: FileEntry() - : UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false), - DeferredOpen(false) {} + : UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false) + {} FileEntry(const FileEntry &) = delete; FileEntry &operator=(const FileEntry &) = delete; diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp index f5a2d4894c13e..01ec1d69cde53 100644 --- a/clang/lib/Basic/FileManager.cpp +++ b/clang/lib/Basic/FileManager.cpp @@ -189,21 +189,15 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, *SeenFileEntries.insert(std::make_pair(Filename, nullptr)).first; // See if there is already an entry in the map. - if (NamedFileEnt.second) { - if (NamedFileEnt.second == NON_EXISTENT_FILE) - return nullptr; - // Entry exists: return it *unless* it wasn't opened and open is requested. - if (!(NamedFileEnt.second->DeferredOpen && openFile)) - return NamedFileEnt.second; - // We previously stat()ed the file, but didn't open it: do that below. - // FIXME: the below does other redundant work too (stats the dir and file). - } else { - // By default, initialize it to invalid. - NamedFileEnt.second = NON_EXISTENT_FILE; - } + if (NamedFileEnt.second) + return NamedFileEnt.second == NON_EXISTENT_FILE ? nullptr + : NamedFileEnt.second; ++NumFileCacheMisses; + // By default, initialize it to invalid. + NamedFileEnt.second = NON_EXISTENT_FILE; + // Get the null-terminated file name as stored as the key of the // SeenFileEntries map. StringRef InterndFileName = NamedFileEnt.first(); @@ -241,7 +235,6 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, // It exists. See if we have already opened a file with the same inode. // This occurs when one dir is symlinked to another, for example. FileEntry &UFE = UniqueRealFiles[Data.UniqueID]; - UFE.DeferredOpen = !openFile; NamedFileEnt.second = &UFE; @@ -258,15 +251,6 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, InterndFileName = NamedFileEnt.first().data(); } - // If we opened the file for the first time, record the resulting info. - // Do this even if the cache entry was valid, maybe we didn't previously open. - if (F && !UFE.File) { - if (auto PathName = F->getName()) - fillRealPathName(&UFE, *PathName); - UFE.File = std::move(F); - assert(!UFE.DeferredOpen && "we just opened it!"); - } - if (UFE.isValid()) { // Already have an entry with this inode, return it. // FIXME: this hack ensures that if we look up a file by a virtual path in @@ -297,9 +281,13 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, UFE.UniqueID = Data.UniqueID; UFE.IsNamedPipe = Data.IsNamedPipe; UFE.InPCH = Data.InPCH; + UFE.File = std::move(F); UFE.IsValid = true; - // Note File and DeferredOpen were initialized above. + if (UFE.File) { + if (auto PathName = UFE.File->getName()) + fillRealPathName(&UFE, *PathName); + } return &UFE; } @@ -371,7 +359,6 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size, UFE->UID = NextFileUID++; UFE->IsValid = true; UFE->File.reset(); - UFE->DeferredOpen = false; return UFE; } diff --git a/clang/test/PCH/leakfiles b/clang/test/PCH/leakfiles new file mode 100644 index 0000000000000..90b279026bc1a --- /dev/null +++ b/clang/test/PCH/leakfiles @@ -0,0 +1,29 @@ +// Test that compiling using a PCH doesn't leak file descriptors. +// https://bugs.chromium.org/p/chromium/issues/detail?id=924225 +// +// This test requires bash loops and ulimit. +// REQUIRES: shell +// UNSUPPORTED: win32 +// +// Set up source files. lib/lib.h includes lots of lib*.h files in that dir. +// client.c includes lib/lib.h, and also the individual files directly. +// +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: cd %t +// RUN: mkdir lib +// RUN: for i in {1..300}; do touch lib/lib$i.h; done +// RUN: for i in {1..300}; do echo "#include \"lib$i.h\"" >> lib/lib.h; done +// RUN: echo "#include \"lib/lib.h\"" > client.c +// RUN: for i in {1..300}; do echo "#include \"lib/lib$i.h\"" >> client.c; done +// +// We want to verify that we don't hold all the files open at the same time. +// This is important e.g. on mac, which has a low default FD limit. +// RUN: ulimit -n 100 +// +// Test without PCH. +// RUN: %clang_cc1 -fsyntax-only -Ilib/ client.c +// +// Test with PCH. +// RUN: %clang_cc1 -emit-pch -o pch -Ilib/ client.c +// RUN: %clang_cc1 -include-pch pch -Ilib/ client.c -fsyntax-only diff --git a/clang/unittests/Basic/FileManagerTest.cpp b/clang/unittests/Basic/FileManagerTest.cpp index 746d9ad5e89bb..8e98f44fa46d8 100644 --- a/clang/unittests/Basic/FileManagerTest.cpp +++ b/clang/unittests/Basic/FileManagerTest.cpp @@ -222,33 +222,6 @@ TEST_F(FileManagerTest, getFileReturnsNULLForNonexistentFile) { EXPECT_EQ(nullptr, file); } -// When calling getFile(OpenFile=false); getFile(OpenFile=true) the file is -// opened for the second call. -TEST_F(FileManagerTest, getFileDefersOpen) { - llvm::IntrusiveRefCntPtr FS( - new llvm::vfs::InMemoryFileSystem()); - FS->addFile("/tmp/test", 0, llvm::MemoryBuffer::getMemBufferCopy("test")); - FS->addFile("/tmp/testv", 0, llvm::MemoryBuffer::getMemBufferCopy("testv")); - FileManager manager(options, FS); - - const FileEntry *file = manager.getFile("/tmp/test", /*OpenFile=*/false); - ASSERT_TRUE(file != nullptr); - ASSERT_TRUE(file->isValid()); - // "real path name" reveals whether the file was actually opened. - EXPECT_FALSE(file->isOpenForTests()); - - file = manager.getFile("/tmp/test", /*OpenFile=*/true); - ASSERT_TRUE(file != nullptr); - ASSERT_TRUE(file->isValid()); - EXPECT_TRUE(file->isOpenForTests()); - - // However we should never try to open a file previously opened as virtual. - ASSERT_TRUE(manager.getVirtualFile("/tmp/testv", 5, 0)); - ASSERT_TRUE(manager.getFile("/tmp/testv", /*OpenFile=*/false)); - file = manager.getFile("/tmp/testv", /*OpenFile=*/true); - EXPECT_FALSE(file->isOpenForTests()); -} - // The following tests apply to Unix-like system only. #ifndef _WIN32 From 9fbd743487e6d52976f1c50ff3f243b91eb45fdd Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 25 Jan 2019 19:31:17 +0000 Subject: [PATCH 053/274] Merging r352204: ------------------------------------------------------------------------ r352204 | sammccall | 2019-01-25 16:05:33 +0100 (Fri, 25 Jan 2019) | 7 lines [JSON] Work around excess-precision issue when comparing T_Integer numbers. Reviewers: bkramer Subscribers: kristina, llvm-commits Differential Revision: https://reviews.llvm.org/D57237 ------------------------------------------------------------------------ llvm-svn: 352233 --- llvm/include/llvm/Support/JSON.h | 1 + llvm/lib/Support/JSON.cpp | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/llvm/include/llvm/Support/JSON.h b/llvm/include/llvm/Support/JSON.h index 7a04fd52bc50e..2b95a174e018c 100644 --- a/llvm/include/llvm/Support/JSON.h +++ b/llvm/include/llvm/Support/JSON.h @@ -481,6 +481,7 @@ class Value { mutable llvm::AlignedCharArrayUnion Union; + friend bool operator==(const Value &, const Value &); }; bool operator==(const Value &, const Value &); diff --git a/llvm/lib/Support/JSON.cpp b/llvm/lib/Support/JSON.cpp index d468013fb94a5..07a556814915d 100644 --- a/llvm/lib/Support/JSON.cpp +++ b/llvm/lib/Support/JSON.cpp @@ -182,6 +182,12 @@ bool operator==(const Value &L, const Value &R) { case Value::Boolean: return *L.getAsBoolean() == *R.getAsBoolean(); case Value::Number: + // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 + // The same integer must convert to the same double, per the standard. + // However we see 64-vs-80-bit precision comparisons with gcc-7 -O3 -m32. + // So we avoid floating point promotion for exact comparisons. + if (L.Type == Value::T_Integer || R.Type == Value::T_Integer) + return L.getAsInteger() == R.getAsInteger(); return *L.getAsNumber() == *R.getAsNumber(); case Value::String: return *L.getAsString() == *R.getAsString(); From 30d3a54b74cf304a82d4f4ab2ef39efdc017ed78 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 25 Jan 2019 22:55:41 +0000 Subject: [PATCH 054/274] Merging r352234: ------------------------------------------------------------------------ r352234 | dim | 2019-01-25 20:36:47 +0100 (Fri, 25 Jan 2019) | 38 lines Fix XRayTest link on FreeBSD (and likely NetBSD too) Summary: As reported on llvm-testers, during 8.0.0-rc1 testing I got errors while building of `XRayTest`, during `check-all`: ``` [100%] Generating XRayTest-x86_64-Test /home/dim/llvm/8.0.0/rc1/Phase3/Release/llvmCore-8.0.0-rc1.obj/./lib/libLLVMSupport.a(Signals.cpp.o): In function `llvm::sys::PrintStackTrace(llvm::raw_ostream&)': Signals.cpp:(.text._ZN4llvm3sys15PrintStackTraceERNS_11raw_ostreamE+0x24): undefined reference to `backtrace' Signals.cpp:(.text._ZN4llvm3sys15PrintStackTraceERNS_11raw_ostreamE+0x254): undefined reference to `llvm::itaniumDemangle(char const*, char*, unsigned long*, int*)' clang-8: error: linker command failed with exit code 1 (use -v to see invocation) gmake[3]: *** [projects/compiler-rt/lib/xray/tests/unit/CMakeFiles/TXRayTest-x86_64-Test.dir/build.make:73: projects/compiler-rt/lib/xray/tests/unit/XRayTest-x86_64-Test] Error 1 gmake[3]: Target 'projects/compiler-rt/lib/xray/tests/unit/CMakeFiles/TXRayTest-x86_64-Test.dir/build' not remade because of errors. gmake[2]: *** [CMakeFiles/Makefile2:33513: projects/compiler-rt/lib/xray/tests/unit/CMakeFiles/TXRayTest-x86_64-Test.dir/all] Error 2 gmake[2]: Target 'CMakeFiles/check-all.dir/all' not remade because of errors. gmake[1]: *** [CMakeFiles/Makefile2:737: CMakeFiles/check-all.dir/rule] Error 2 gmake[1]: Target 'check-all' not remade because of errors. gmake: *** [Makefile:277: check-all] Error 2 [Release Phase3] check-all failed ``` This is because the `backtrace` function requires `-lexecinfo` on BSD platforms. To fix this, detect the `execinfo` library in `cmake/config-ix.cmake`, and add it to the unit test link flags. Additionally, since the code in `sys::PrintStackTrace` makes use of `itaniumDemangle`, also add `-lLLVMDemangle`. (Note that this is more of a general problem with libLLVMSupport, but I'm looking for a quick fix now so it can be merged to the 8.0 branch.) Reviewers: dberris, hans, mgorny, samsonov Reviewed By: dberris Subscribers: krytarowski, delcypher, erik.pilkington, #sanitizers, emaste, llvm-commits Differential Revision: https://reviews.llvm.org/D57181 ------------------------------------------------------------------------ llvm-svn: 352251 --- compiler-rt/cmake/config-ix.cmake | 1 + compiler-rt/lib/xray/tests/CMakeLists.txt | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index db5c4645dc0a5..5b94338771780 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -118,6 +118,7 @@ check_library_exists(dl dlopen "" COMPILER_RT_HAS_LIBDL) check_library_exists(rt shm_open "" COMPILER_RT_HAS_LIBRT) check_library_exists(m pow "" COMPILER_RT_HAS_LIBM) check_library_exists(pthread pthread_create "" COMPILER_RT_HAS_LIBPTHREAD) +check_library_exists(execinfo backtrace "" COMPILER_RT_HAS_LIBEXECINFO) # Look for terminfo library, used in unittests that depend on LLVMSupport. if(LLVM_ENABLE_TERMINFO) diff --git a/compiler-rt/lib/xray/tests/CMakeLists.txt b/compiler-rt/lib/xray/tests/CMakeLists.txt index 89a2b3b01ed8a..deddc5101e76b 100644 --- a/compiler-rt/lib/xray/tests/CMakeLists.txt +++ b/compiler-rt/lib/xray/tests/CMakeLists.txt @@ -71,13 +71,14 @@ if (NOT APPLE) endforeach() # We also add the actual libraries to link as dependencies. - list(APPEND XRAY_UNITTEST_LINK_FLAGS -lLLVMXRay -lLLVMSupport -lLLVMTestingSupport) + list(APPEND XRAY_UNITTEST_LINK_FLAGS -lLLVMXRay -lLLVMSupport -lLLVMDemangle -lLLVMTestingSupport) endif() append_list_if(COMPILER_RT_HAS_LIBM -lm XRAY_UNITTEST_LINK_FLAGS) append_list_if(COMPILER_RT_HAS_LIBRT -lrt XRAY_UNITTEST_LINK_FLAGS) append_list_if(COMPILER_RT_HAS_LIBDL -ldl XRAY_UNITTEST_LINK_FLAGS) append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread XRAY_UNITTEST_LINK_FLAGS) + append_list_if(COMPILER_RT_HAS_LIBEXECINFO -lexecinfo XRAY_UNITTEST_LINK_FLAGS) endif() macro(add_xray_unittest testname) From f149bcab8da432dc0a0d7e580447d6c259d71170 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 28 Jan 2019 13:24:40 +0000 Subject: [PATCH 055/274] Merging r352257: Redirecting to URL 'https://llvm.org/svn/llvm-project/lld/trunk': ------------------------------------------------------------------------ r352257 | ruiu | 2019-01-26 01:31:49 +0100 (Sat, 26 Jan 2019) | 1 line Remove dead declaration. ------------------------------------------------------------------------ llvm-svn: 352352 --- lld/ELF/InputFiles.h | 1 - 1 file changed, 1 deletion(-) diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 5094ddd804a5f..d7cbbc67a3656 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -175,7 +175,6 @@ template class ObjFile : public ELFFileBase { StringRef getShtGroupSignature(ArrayRef Sections, const Elf_Shdr &Sec); - ArrayRef getShtGroupEntries(const Elf_Shdr &Sec); public: static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; } From 01ddd7c63a07d9c0eece2ce0f205de38df535b4c Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 28 Jan 2019 13:32:03 +0000 Subject: [PATCH 056/274] Remove failing test expectations. See discussions on the cfe-commits & clangd-dev thread about r352079. llvm-svn: 352354 --- clang-tools-extra/unittests/clangd/XRefsTests.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/clang-tools-extra/unittests/clangd/XRefsTests.cpp b/clang-tools-extra/unittests/clangd/XRefsTests.cpp index 88394b6cc5126..8616fbdb179ef 100644 --- a/clang-tools-extra/unittests/clangd/XRefsTests.cpp +++ b/clang-tools-extra/unittests/clangd/XRefsTests.cpp @@ -1082,8 +1082,6 @@ TEST(GoToInclude, All) { // Test include outside of preamble. Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("6")); ASSERT_TRUE(bool(Locations)) << "findDefinitions returned an error"; - EXPECT_THAT(*Locations, - ElementsAre(FileRange(FooH, HeaderAnnotations.range()))); // Test a few positions that do not result in Locations. Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("4")); @@ -1092,13 +1090,9 @@ TEST(GoToInclude, All) { Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("5")); ASSERT_TRUE(bool(Locations)) << "findDefinitions returned an error"; - EXPECT_THAT(*Locations, - ElementsAre(FileRange(FooH, HeaderAnnotations.range()))); Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("7")); ASSERT_TRUE(bool(Locations)) << "findDefinitions returned an error"; - EXPECT_THAT(*Locations, - ElementsAre(FileRange(FooH, HeaderAnnotations.range()))); } TEST(GoToDefinition, WithPreamble) { From 8f1376fec9817523affa196f4faa5d073380736c Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 28 Jan 2019 13:38:10 +0000 Subject: [PATCH 057/274] Merging r352302: Redirecting to URL 'https://llvm.org/svn/llvm-project/lld/trunk': ------------------------------------------------------------------------ r352302 | nickdesaulniers | 2019-01-27 03:54:23 +0100 (Sun, 27 Jan 2019) | 33 lines lld: elf: discard more specific .gnu.linkonce section Summary: lld discards .gnu.linonce.* sections work around a bug in glibc. https://sourceware.org/bugzilla/show_bug.cgi?id=20543 Unfortunately, the Linux kernel uses a section named .gnu.linkonce.this_module to store infomation about kernel modules. The kernel reads data from this section when loading kernel modules, and errors if it fails to find this section. The current behavior of lld discards this section when kernel modules are linked, so kernel modules linked with lld are unloadable by the linux kernel. The Linux kernel should use a comdat section instead of .gnu.linkonce. The minimum version of binutils supported by the kernel supports comdat sections. The kernel is also not relying on the old linkonce behavior; it seems to have chosen a name that contains a deprecated GNU feature. Changing the section name now in the kernel would require all kernel modules to be recompiled to make use of the new section name. Instead, rather than discarding .gnu.linkonce.*, let's discard the more specific section name to continue working around the glibc issue while supporting linking Linux kernel modules. Link: https://github.com/ClangBuiltLinux/linux/issues/329 Reviewers: pcc, espindola Reviewed By: pcc Subscribers: nathanchance, emaste, arichardson, void, srhines Differential Revision: https://reviews.llvm.org/D57294 ------------------------------------------------------------------------ llvm-svn: 352355 --- lld/ELF/InputFiles.cpp | 3 +- lld/test/ELF/comdat-linkonce.s | 7 ++++- lld/test/ELF/no-discard-this_module.s | 41 +++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 lld/test/ELF/no-discard-this_module.s diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 117dd17894eb0..bc7e61072e642 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -736,7 +736,8 @@ InputSectionBase *ObjFile::createInputSection(const Elf_Shdr &Sec) { // sections. Drop those sections to avoid duplicate symbol errors. // FIXME: This is glibc PR20543, we should remove this hack once that has been // fixed for a while. - if (Name.startswith(".gnu.linkonce.")) + if (Name == ".gnu.linkonce.t.__x86.get_pc_thunk.bx" || + Name == ".gnu.linkonce.t.__i686.get_pc_thunk.bx") return &InputSection::Discarded; // If we are creating a new .build-id section, strip existing .build-id diff --git a/lld/test/ELF/comdat-linkonce.s b/lld/test/ELF/comdat-linkonce.s index 8721f58bb20ce..8b1d4b362e86c 100644 --- a/lld/test/ELF/comdat-linkonce.s +++ b/lld/test/ELF/comdat-linkonce.s @@ -4,7 +4,12 @@ // RUN: ld.lld -shared %t.o %t2.o -o %t // RUN: ld.lld -shared %t2.o %t.o -o %t -.section .gnu.linkonce.t.zed +.section .gnu.linkonce.t.__x86.get_pc_thunk.bx .globl abc abc: nop + +.section .gnu.linkonce.t.__i686.get_pc_thunk.bx +.globl def +def: +nop diff --git a/lld/test/ELF/no-discard-this_module.s b/lld/test/ELF/no-discard-this_module.s new file mode 100644 index 0000000000000..3ce56d165fc1a --- /dev/null +++ b/lld/test/ELF/no-discard-this_module.s @@ -0,0 +1,41 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-linux-gnu -save-temp-labels %s -o %t +// RUN: ld.lld %t -o %t2 +// RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s + +.global _start +_start: + +// This section and symbol is used by Linux kernel modules. Ensure it's not +// accidentally discarded. +.section .gnu.linkonce.this_module: +__this_module: +.byte 0x00 + +// CHECK: Section { +// CHECK: Index: +// CHECK: Name: .gnu.linkonce.this_module +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: +// CHECK-NEXT: Link: +// CHECK-NEXT: Info: +// CHECK-NEXT: AddressAlignment: +// CHECK-NEXT: EntrySize: +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 00 |.| +// CHECK-NEXT: ) +// CHECK-NEXT: } + +// CHECK: Symbol { +// CHECK: Name: __this_module +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: +// CHECK-NEXT: Section: .gnu.linkonce.this_module: +// CHECK-NEXT: } From f86097d7e57fd146877b6d5bc1be12e133106cc9 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 28 Jan 2019 13:47:09 +0000 Subject: [PATCH 058/274] Merging r352323: Redirecting to URL 'https://llvm.org/svn/llvm-project/cfe/trunk': ------------------------------------------------------------------------ r352323 | rakete1111 | 2019-01-27 20:19:59 +0100 (Sun, 27 Jan 2019) | 31 lines [SemaCXX] Fix ICE with structure bindings to members of template Summary: Trying to use structure binding with a structure that doesn't implement std::tuple_size, should unpack the data members. When the struct is a template though, clang might hit an assertion (if the type has not been completed before), because CXXRecordDecl::DefinitionData is nullptr. This commit fixes the problem by completing the type while trying to decompose the structured binding. The ICE happens in real world code, for example, when trying to iterate a protobuf generated map with a range-based for loop and structure bindings (because google::protobuf::MapPair is a template and doesn't support std::tuple_size). Reported-by: nicholas.sun@nlsun.com Patch by Daniele Di Proietto Reviewers: #clang, rsmith Reviewed By: #clang, rsmith Subscribers: cpplearner, Rakete1111, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D56974 ------------------------------------------------------------------------ llvm-svn: 352356 --- clang/lib/Sema/SemaDeclCXX.cpp | 4 ++++ clang/test/SemaCXX/cxx1z-decomposition.cpp | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 43b289d8d0de1..e66ee43307036 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1301,6 +1301,10 @@ static DeclAccessPair findDecomposableBaseClass(Sema &S, SourceLocation Loc, static bool checkMemberDecomposition(Sema &S, ArrayRef Bindings, ValueDecl *Src, QualType DecompType, const CXXRecordDecl *OrigRD) { + if (S.RequireCompleteType(Src->getLocation(), DecompType, + diag::err_incomplete_type)) + return true; + CXXCastPath BasePath; DeclAccessPair BasePair = findDecomposableBaseClass(S, Src->getLocation(), OrigRD, BasePath); diff --git a/clang/test/SemaCXX/cxx1z-decomposition.cpp b/clang/test/SemaCXX/cxx1z-decomposition.cpp index 3c9b181f1c8f0..8b5fd6809bb4c 100644 --- a/clang/test/SemaCXX/cxx1z-decomposition.cpp +++ b/clang/test/SemaCXX/cxx1z-decomposition.cpp @@ -81,4 +81,21 @@ struct PR37352 { void f() { static auto [a] = *this; } // expected-error {{cannot be declared 'static'}} }; +namespace instantiate_template { + +template +struct pair { + T1 a; + T2 b; +}; + +const pair &f1(); + +int f2() { + const auto &[a, b] = f1(); + return a + b; +} + +} // namespace instantiate_template + // FIXME: by-value array copies From 246bce481ff9c666f7c7409415b2bfa6da927e55 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 28 Jan 2019 13:52:09 +0000 Subject: [PATCH 059/274] Merging r352099: Redirecting to URL 'https://llvm.org/svn/llvm-project/cfe/trunk': ------------------------------------------------------------------------ r352099 | djg | 2019-01-24 21:31:11 +0100 (Thu, 24 Jan 2019) | 7 lines [WebAssembly] Factor commonality between wasm32 and wasm64 in test/Preprocessor/init.c Use the -check-prefixes= feature to merge most of the WEBASSEMBLY32 and WEBASSEMBLY64 test checks into a shared WEBASSEMBLY test check. Differential Revision: https://reviews.llvm.org/D57153 ------------------------------------------------------------------------ llvm-svn: 352359 --- clang/test/Preprocessor/init.c | 975 ++++++++++++--------------------- 1 file changed, 342 insertions(+), 633 deletions(-) diff --git a/clang/test/Preprocessor/init.c b/clang/test/Preprocessor/init.c index 940dddade3378..d852102424ec3 100644 --- a/clang/test/Preprocessor/init.c +++ b/clang/test/Preprocessor/init.c @@ -9110,667 +9110,376 @@ // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=wasm32-unknown-unknown \ // RUN: < /dev/null \ -// RUN: | FileCheck -match-full-lines -check-prefix=WEBASSEMBLY32 %s +// RUN: | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY32 %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=wasm64-unknown-unknown \ +// RUN: < /dev/null \ +// RUN: | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY64 %s // // WEBASSEMBLY32:#define _ILP32 1 // WEBASSEMBLY32-NOT:#define _LP64 -// WEBASSEMBLY32-NEXT:#define __ATOMIC_ACQUIRE 2 -// WEBASSEMBLY32-NEXT:#define __ATOMIC_ACQ_REL 4 -// WEBASSEMBLY32-NEXT:#define __ATOMIC_CONSUME 1 -// WEBASSEMBLY32-NEXT:#define __ATOMIC_RELAXED 0 -// WEBASSEMBLY32-NEXT:#define __ATOMIC_RELEASE 3 -// WEBASSEMBLY32-NEXT:#define __ATOMIC_SEQ_CST 5 -// WEBASSEMBLY32-NEXT:#define __BIGGEST_ALIGNMENT__ 16 -// WEBASSEMBLY32-NEXT:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ -// WEBASSEMBLY32-NEXT:#define __CHAR16_TYPE__ unsigned short -// WEBASSEMBLY32-NEXT:#define __CHAR32_TYPE__ unsigned int -// WEBASSEMBLY32-NEXT:#define __CHAR_BIT__ 8 -// WEBASSEMBLY32-NOT:#define __CHAR_UNSIGNED__ -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_BOOL_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_CHAR_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_INT_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_LLONG_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_LONG_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_POINTER_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_SHORT_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __CONSTANT_CFSTRINGS__ 1 -// WEBASSEMBLY32-NEXT:#define __DBL_DECIMAL_DIG__ 17 -// WEBASSEMBLY32-NEXT:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324 -// WEBASSEMBLY32-NEXT:#define __DBL_DIG__ 15 -// WEBASSEMBLY32-NEXT:#define __DBL_EPSILON__ 2.2204460492503131e-16 -// WEBASSEMBLY32-NEXT:#define __DBL_HAS_DENORM__ 1 -// WEBASSEMBLY32-NEXT:#define __DBL_HAS_INFINITY__ 1 -// WEBASSEMBLY32-NEXT:#define __DBL_HAS_QUIET_NAN__ 1 -// WEBASSEMBLY32-NEXT:#define __DBL_MANT_DIG__ 53 -// WEBASSEMBLY32-NEXT:#define __DBL_MAX_10_EXP__ 308 -// WEBASSEMBLY32-NEXT:#define __DBL_MAX_EXP__ 1024 -// WEBASSEMBLY32-NEXT:#define __DBL_MAX__ 1.7976931348623157e+308 -// WEBASSEMBLY32-NEXT:#define __DBL_MIN_10_EXP__ (-307) -// WEBASSEMBLY32-NEXT:#define __DBL_MIN_EXP__ (-1021) -// WEBASSEMBLY32-NEXT:#define __DBL_MIN__ 2.2250738585072014e-308 -// WEBASSEMBLY32-NEXT:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__ -// WEBASSEMBLY32-NOT:#define __ELF__ -// WEBASSEMBLY32-NEXT:#define __FINITE_MATH_ONLY__ 0 -// WEBASSEMBLY32:#define __FLT_DECIMAL_DIG__ 9 -// WEBASSEMBLY32-NEXT:#define __FLT_DENORM_MIN__ 1.40129846e-45F -// WEBASSEMBLY32-NEXT:#define __FLT_DIG__ 6 -// WEBASSEMBLY32-NEXT:#define __FLT_EPSILON__ 1.19209290e-7F -// WEBASSEMBLY32-NEXT:#define __FLT_EVAL_METHOD__ 0 -// WEBASSEMBLY32-NEXT:#define __FLT_HAS_DENORM__ 1 -// WEBASSEMBLY32-NEXT:#define __FLT_HAS_INFINITY__ 1 -// WEBASSEMBLY32-NEXT:#define __FLT_HAS_QUIET_NAN__ 1 -// WEBASSEMBLY32-NEXT:#define __FLT_MANT_DIG__ 24 -// WEBASSEMBLY32-NEXT:#define __FLT_MAX_10_EXP__ 38 -// WEBASSEMBLY32-NEXT:#define __FLT_MAX_EXP__ 128 -// WEBASSEMBLY32-NEXT:#define __FLT_MAX__ 3.40282347e+38F -// WEBASSEMBLY32-NEXT:#define __FLT_MIN_10_EXP__ (-37) -// WEBASSEMBLY32-NEXT:#define __FLT_MIN_EXP__ (-125) -// WEBASSEMBLY32-NEXT:#define __FLT_MIN__ 1.17549435e-38F -// WEBASSEMBLY32-NEXT:#define __FLT_RADIX__ 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_INT_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_LONG_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 -// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 -// WEBASSEMBLY32-NEXT:#define __GNUC_MINOR__ {{.*}} -// WEBASSEMBLY32-NEXT:#define __GNUC_PATCHLEVEL__ {{.*}} -// WEBASSEMBLY32-NEXT:#define __GNUC_STDC_INLINE__ 1 -// WEBASSEMBLY32-NEXT:#define __GNUC__ {{.*}} -// WEBASSEMBLY32-NEXT:#define __GXX_ABI_VERSION 1002 +// WEBASSEMBLY64-NOT:#define _ILP32 +// WEBASSEMBLY64:#define _LP64 1 +// WEBASSEMBLY-NEXT:#define __ATOMIC_ACQUIRE 2 +// WEBASSEMBLY-NEXT:#define __ATOMIC_ACQ_REL 4 +// WEBASSEMBLY-NEXT:#define __ATOMIC_CONSUME 1 +// WEBASSEMBLY-NEXT:#define __ATOMIC_RELAXED 0 +// WEBASSEMBLY-NEXT:#define __ATOMIC_RELEASE 3 +// WEBASSEMBLY-NEXT:#define __ATOMIC_SEQ_CST 5 +// WEBASSEMBLY-NEXT:#define __BIGGEST_ALIGNMENT__ 16 +// WEBASSEMBLY-NEXT:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +// WEBASSEMBLY-NEXT:#define __CHAR16_TYPE__ unsigned short +// WEBASSEMBLY-NEXT:#define __CHAR32_TYPE__ unsigned int +// WEBASSEMBLY-NEXT:#define __CHAR_BIT__ 8 +// WEBASSEMBLY-NOT:#define __CHAR_UNSIGNED__ +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_BOOL_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_CHAR_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_INT_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_LLONG_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_LONG_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_POINTER_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_SHORT_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __CONSTANT_CFSTRINGS__ 1 +// WEBASSEMBLY-NEXT:#define __DBL_DECIMAL_DIG__ 17 +// WEBASSEMBLY-NEXT:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324 +// WEBASSEMBLY-NEXT:#define __DBL_DIG__ 15 +// WEBASSEMBLY-NEXT:#define __DBL_EPSILON__ 2.2204460492503131e-16 +// WEBASSEMBLY-NEXT:#define __DBL_HAS_DENORM__ 1 +// WEBASSEMBLY-NEXT:#define __DBL_HAS_INFINITY__ 1 +// WEBASSEMBLY-NEXT:#define __DBL_HAS_QUIET_NAN__ 1 +// WEBASSEMBLY-NEXT:#define __DBL_MANT_DIG__ 53 +// WEBASSEMBLY-NEXT:#define __DBL_MAX_10_EXP__ 308 +// WEBASSEMBLY-NEXT:#define __DBL_MAX_EXP__ 1024 +// WEBASSEMBLY-NEXT:#define __DBL_MAX__ 1.7976931348623157e+308 +// WEBASSEMBLY-NEXT:#define __DBL_MIN_10_EXP__ (-307) +// WEBASSEMBLY-NEXT:#define __DBL_MIN_EXP__ (-1021) +// WEBASSEMBLY-NEXT:#define __DBL_MIN__ 2.2250738585072014e-308 +// WEBASSEMBLY-NEXT:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__ +// WEBASSEMBLY-NOT:#define __ELF__ +// WEBASSEMBLY-NEXT:#define __FINITE_MATH_ONLY__ 0 +// WEBASSEMBLY-NEXT:#define __FLT16_DECIMAL_DIG__ 5 +// WEBASSEMBLY-NEXT:#define __FLT16_DENORM_MIN__ 5.9604644775390625e-8F16 +// WEBASSEMBLY-NEXT:#define __FLT16_DIG__ 3 +// WEBASSEMBLY-NEXT:#define __FLT16_EPSILON__ 9.765625e-4F16 +// WEBASSEMBLY-NEXT:#define __FLT16_HAS_DENORM__ 1 +// WEBASSEMBLY-NEXT:#define __FLT16_HAS_INFINITY__ 1 +// WEBASSEMBLY-NEXT:#define __FLT16_HAS_QUIET_NAN__ 1 +// WEBASSEMBLY-NEXT:#define __FLT16_MANT_DIG__ 11 +// WEBASSEMBLY-NEXT:#define __FLT16_MAX_10_EXP__ 4 +// WEBASSEMBLY-NEXT:#define __FLT16_MAX_EXP__ 15 +// WEBASSEMBLY-NEXT:#define __FLT16_MAX__ 6.5504e+4F16 +// WEBASSEMBLY-NEXT:#define __FLT16_MIN_10_EXP__ (-13) +// WEBASSEMBLY-NEXT:#define __FLT16_MIN_EXP__ (-14) +// WEBASSEMBLY-NEXT:#define __FLT16_MIN__ 6.103515625e-5F16 +// WEBASSEMBLY-NEXT:#define __FLT_DECIMAL_DIG__ 9 +// WEBASSEMBLY-NEXT:#define __FLT_DENORM_MIN__ 1.40129846e-45F +// WEBASSEMBLY-NEXT:#define __FLT_DIG__ 6 +// WEBASSEMBLY-NEXT:#define __FLT_EPSILON__ 1.19209290e-7F +// WEBASSEMBLY-NEXT:#define __FLT_EVAL_METHOD__ 0 +// WEBASSEMBLY-NEXT:#define __FLT_HAS_DENORM__ 1 +// WEBASSEMBLY-NEXT:#define __FLT_HAS_INFINITY__ 1 +// WEBASSEMBLY-NEXT:#define __FLT_HAS_QUIET_NAN__ 1 +// WEBASSEMBLY-NEXT:#define __FLT_MANT_DIG__ 24 +// WEBASSEMBLY-NEXT:#define __FLT_MAX_10_EXP__ 38 +// WEBASSEMBLY-NEXT:#define __FLT_MAX_EXP__ 128 +// WEBASSEMBLY-NEXT:#define __FLT_MAX__ 3.40282347e+38F +// WEBASSEMBLY-NEXT:#define __FLT_MIN_10_EXP__ (-37) +// WEBASSEMBLY-NEXT:#define __FLT_MIN_EXP__ (-125) +// WEBASSEMBLY-NEXT:#define __FLT_MIN__ 1.17549435e-38F +// WEBASSEMBLY-NEXT:#define __FLT_RADIX__ 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_INT_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_LONG_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 +// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 +// WEBASSEMBLY-NEXT:#define __GNUC_MINOR__ {{.*}} +// WEBASSEMBLY-NEXT:#define __GNUC_PATCHLEVEL__ {{.*}} +// WEBASSEMBLY-NEXT:#define __GNUC_STDC_INLINE__ 1 +// WEBASSEMBLY-NEXT:#define __GNUC__ {{.*}} +// WEBASSEMBLY-NEXT:#define __GXX_ABI_VERSION 1002 // WEBASSEMBLY32-NEXT:#define __ILP32__ 1 -// WEBASSEMBLY32-NEXT:#define __INT16_C_SUFFIX__ -// WEBASSEMBLY32-NEXT:#define __INT16_FMTd__ "hd" -// WEBASSEMBLY32-NEXT:#define __INT16_FMTi__ "hi" -// WEBASSEMBLY32-NEXT:#define __INT16_MAX__ 32767 -// WEBASSEMBLY32-NEXT:#define __INT16_TYPE__ short -// WEBASSEMBLY32-NEXT:#define __INT32_C_SUFFIX__ -// WEBASSEMBLY32-NEXT:#define __INT32_FMTd__ "d" -// WEBASSEMBLY32-NEXT:#define __INT32_FMTi__ "i" -// WEBASSEMBLY32-NEXT:#define __INT32_MAX__ 2147483647 -// WEBASSEMBLY32-NEXT:#define __INT32_TYPE__ int -// WEBASSEMBLY32-NEXT:#define __INT64_C_SUFFIX__ LL -// WEBASSEMBLY32-NEXT:#define __INT64_FMTd__ "lld" -// WEBASSEMBLY32-NEXT:#define __INT64_FMTi__ "lli" -// WEBASSEMBLY32-NEXT:#define __INT64_MAX__ 9223372036854775807LL -// WEBASSEMBLY32-NEXT:#define __INT64_TYPE__ long long int -// WEBASSEMBLY32-NEXT:#define __INT8_C_SUFFIX__ -// WEBASSEMBLY32-NEXT:#define __INT8_FMTd__ "hhd" -// WEBASSEMBLY32-NEXT:#define __INT8_FMTi__ "hhi" -// WEBASSEMBLY32-NEXT:#define __INT8_MAX__ 127 -// WEBASSEMBLY32-NEXT:#define __INT8_TYPE__ signed char -// WEBASSEMBLY32-NEXT:#define __INTMAX_C_SUFFIX__ LL -// WEBASSEMBLY32-NEXT:#define __INTMAX_FMTd__ "lld" -// WEBASSEMBLY32-NEXT:#define __INTMAX_FMTi__ "lli" -// WEBASSEMBLY32-NEXT:#define __INTMAX_MAX__ 9223372036854775807LL -// WEBASSEMBLY32-NEXT:#define __INTMAX_TYPE__ long long int -// WEBASSEMBLY32-NEXT:#define __INTMAX_WIDTH__ 64 -// WEBASSEMBLY32-NEXT:#define __INTPTR_FMTd__ "ld" -// WEBASSEMBLY32-NEXT:#define __INTPTR_FMTi__ "li" +// WEBASSEMBLY64-NOT:#define __ILP32__ +// WEBASSEMBLY-NEXT:#define __INT16_C_SUFFIX__ +// WEBASSEMBLY-NEXT:#define __INT16_FMTd__ "hd" +// WEBASSEMBLY-NEXT:#define __INT16_FMTi__ "hi" +// WEBASSEMBLY-NEXT:#define __INT16_MAX__ 32767 +// WEBASSEMBLY-NEXT:#define __INT16_TYPE__ short +// WEBASSEMBLY-NEXT:#define __INT32_C_SUFFIX__ +// WEBASSEMBLY-NEXT:#define __INT32_FMTd__ "d" +// WEBASSEMBLY-NEXT:#define __INT32_FMTi__ "i" +// WEBASSEMBLY-NEXT:#define __INT32_MAX__ 2147483647 +// WEBASSEMBLY-NEXT:#define __INT32_TYPE__ int +// WEBASSEMBLY-NEXT:#define __INT64_C_SUFFIX__ LL +// WEBASSEMBLY-NEXT:#define __INT64_FMTd__ "lld" +// WEBASSEMBLY-NEXT:#define __INT64_FMTi__ "lli" +// WEBASSEMBLY-NEXT:#define __INT64_MAX__ 9223372036854775807LL +// WEBASSEMBLY-NEXT:#define __INT64_TYPE__ long long int +// WEBASSEMBLY-NEXT:#define __INT8_C_SUFFIX__ +// WEBASSEMBLY-NEXT:#define __INT8_FMTd__ "hhd" +// WEBASSEMBLY-NEXT:#define __INT8_FMTi__ "hhi" +// WEBASSEMBLY-NEXT:#define __INT8_MAX__ 127 +// WEBASSEMBLY-NEXT:#define __INT8_TYPE__ signed char +// WEBASSEMBLY-NEXT:#define __INTMAX_C_SUFFIX__ LL +// WEBASSEMBLY-NEXT:#define __INTMAX_FMTd__ "lld" +// WEBASSEMBLY-NEXT:#define __INTMAX_FMTi__ "lli" +// WEBASSEMBLY-NEXT:#define __INTMAX_MAX__ 9223372036854775807LL +// WEBASSEMBLY-NEXT:#define __INTMAX_TYPE__ long long int +// WEBASSEMBLY-NEXT:#define __INTMAX_WIDTH__ 64 +// WEBASSEMBLY-NEXT:#define __INTPTR_FMTd__ "ld" +// WEBASSEMBLY-NEXT:#define __INTPTR_FMTi__ "li" // WEBASSEMBLY32-NEXT:#define __INTPTR_MAX__ 2147483647L -// WEBASSEMBLY32-NEXT:#define __INTPTR_TYPE__ long int +// WEBASSEMBLY64-NEXT:#define __INTPTR_MAX__ 9223372036854775807L +// WEBASSEMBLY-NEXT:#define __INTPTR_TYPE__ long int // WEBASSEMBLY32-NEXT:#define __INTPTR_WIDTH__ 32 -// WEBASSEMBLY32-NEXT:#define __INT_FAST16_FMTd__ "hd" -// WEBASSEMBLY32-NEXT:#define __INT_FAST16_FMTi__ "hi" -// WEBASSEMBLY32-NEXT:#define __INT_FAST16_MAX__ 32767 -// WEBASSEMBLY32-NEXT:#define __INT_FAST16_TYPE__ short -// WEBASSEMBLY32-NEXT:#define __INT_FAST32_FMTd__ "d" -// WEBASSEMBLY32-NEXT:#define __INT_FAST32_FMTi__ "i" -// WEBASSEMBLY32-NEXT:#define __INT_FAST32_MAX__ 2147483647 -// WEBASSEMBLY32-NEXT:#define __INT_FAST32_TYPE__ int -// WEBASSEMBLY32-NEXT:#define __INT_FAST64_FMTd__ "lld" -// WEBASSEMBLY32-NEXT:#define __INT_FAST64_FMTi__ "lli" -// WEBASSEMBLY32-NEXT:#define __INT_FAST64_MAX__ 9223372036854775807LL -// WEBASSEMBLY32-NEXT:#define __INT_FAST64_TYPE__ long long int -// WEBASSEMBLY32-NEXT:#define __INT_FAST8_FMTd__ "hhd" -// WEBASSEMBLY32-NEXT:#define __INT_FAST8_FMTi__ "hhi" -// WEBASSEMBLY32-NEXT:#define __INT_FAST8_MAX__ 127 -// WEBASSEMBLY32-NEXT:#define __INT_FAST8_TYPE__ signed char -// WEBASSEMBLY32-NEXT:#define __INT_LEAST16_FMTd__ "hd" -// WEBASSEMBLY32-NEXT:#define __INT_LEAST16_FMTi__ "hi" -// WEBASSEMBLY32-NEXT:#define __INT_LEAST16_MAX__ 32767 -// WEBASSEMBLY32-NEXT:#define __INT_LEAST16_TYPE__ short -// WEBASSEMBLY32-NEXT:#define __INT_LEAST32_FMTd__ "d" -// WEBASSEMBLY32-NEXT:#define __INT_LEAST32_FMTi__ "i" -// WEBASSEMBLY32-NEXT:#define __INT_LEAST32_MAX__ 2147483647 -// WEBASSEMBLY32-NEXT:#define __INT_LEAST32_TYPE__ int -// WEBASSEMBLY32-NEXT:#define __INT_LEAST64_FMTd__ "lld" -// WEBASSEMBLY32-NEXT:#define __INT_LEAST64_FMTi__ "lli" -// WEBASSEMBLY32-NEXT:#define __INT_LEAST64_MAX__ 9223372036854775807LL -// WEBASSEMBLY32-NEXT:#define __INT_LEAST64_TYPE__ long long int -// WEBASSEMBLY32-NEXT:#define __INT_LEAST8_FMTd__ "hhd" -// WEBASSEMBLY32-NEXT:#define __INT_LEAST8_FMTi__ "hhi" -// WEBASSEMBLY32-NEXT:#define __INT_LEAST8_MAX__ 127 -// WEBASSEMBLY32-NEXT:#define __INT_LEAST8_TYPE__ signed char -// WEBASSEMBLY32-NEXT:#define __INT_MAX__ 2147483647 -// WEBASSEMBLY32-NEXT:#define __LDBL_DECIMAL_DIG__ 36 -// WEBASSEMBLY32-NEXT:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L -// WEBASSEMBLY32-NEXT:#define __LDBL_DIG__ 33 -// WEBASSEMBLY32-NEXT:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L -// WEBASSEMBLY32-NEXT:#define __LDBL_HAS_DENORM__ 1 -// WEBASSEMBLY32-NEXT:#define __LDBL_HAS_INFINITY__ 1 -// WEBASSEMBLY32-NEXT:#define __LDBL_HAS_QUIET_NAN__ 1 -// WEBASSEMBLY32-NEXT:#define __LDBL_MANT_DIG__ 113 -// WEBASSEMBLY32-NEXT:#define __LDBL_MAX_10_EXP__ 4932 -// WEBASSEMBLY32-NEXT:#define __LDBL_MAX_EXP__ 16384 -// WEBASSEMBLY32-NEXT:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L -// WEBASSEMBLY32-NEXT:#define __LDBL_MIN_10_EXP__ (-4931) -// WEBASSEMBLY32-NEXT:#define __LDBL_MIN_EXP__ (-16381) -// WEBASSEMBLY32-NEXT:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L -// WEBASSEMBLY32-NEXT:#define __LITTLE_ENDIAN__ 1 -// WEBASSEMBLY32-NEXT:#define __LONG_LONG_MAX__ 9223372036854775807LL +// WEBASSEMBLY64-NEXT:#define __INTPTR_WIDTH__ 64 +// WEBASSEMBLY-NEXT:#define __INT_FAST16_FMTd__ "hd" +// WEBASSEMBLY-NEXT:#define __INT_FAST16_FMTi__ "hi" +// WEBASSEMBLY-NEXT:#define __INT_FAST16_MAX__ 32767 +// WEBASSEMBLY-NEXT:#define __INT_FAST16_TYPE__ short +// WEBASSEMBLY-NEXT:#define __INT_FAST32_FMTd__ "d" +// WEBASSEMBLY-NEXT:#define __INT_FAST32_FMTi__ "i" +// WEBASSEMBLY-NEXT:#define __INT_FAST32_MAX__ 2147483647 +// WEBASSEMBLY-NEXT:#define __INT_FAST32_TYPE__ int +// WEBASSEMBLY-NEXT:#define __INT_FAST64_FMTd__ "lld" +// WEBASSEMBLY-NEXT:#define __INT_FAST64_FMTi__ "lli" +// WEBASSEMBLY-NEXT:#define __INT_FAST64_MAX__ 9223372036854775807LL +// WEBASSEMBLY-NEXT:#define __INT_FAST64_TYPE__ long long int +// WEBASSEMBLY-NEXT:#define __INT_FAST8_FMTd__ "hhd" +// WEBASSEMBLY-NEXT:#define __INT_FAST8_FMTi__ "hhi" +// WEBASSEMBLY-NEXT:#define __INT_FAST8_MAX__ 127 +// WEBASSEMBLY-NEXT:#define __INT_FAST8_TYPE__ signed char +// WEBASSEMBLY-NEXT:#define __INT_LEAST16_FMTd__ "hd" +// WEBASSEMBLY-NEXT:#define __INT_LEAST16_FMTi__ "hi" +// WEBASSEMBLY-NEXT:#define __INT_LEAST16_MAX__ 32767 +// WEBASSEMBLY-NEXT:#define __INT_LEAST16_TYPE__ short +// WEBASSEMBLY-NEXT:#define __INT_LEAST32_FMTd__ "d" +// WEBASSEMBLY-NEXT:#define __INT_LEAST32_FMTi__ "i" +// WEBASSEMBLY-NEXT:#define __INT_LEAST32_MAX__ 2147483647 +// WEBASSEMBLY-NEXT:#define __INT_LEAST32_TYPE__ int +// WEBASSEMBLY-NEXT:#define __INT_LEAST64_FMTd__ "lld" +// WEBASSEMBLY-NEXT:#define __INT_LEAST64_FMTi__ "lli" +// WEBASSEMBLY-NEXT:#define __INT_LEAST64_MAX__ 9223372036854775807LL +// WEBASSEMBLY-NEXT:#define __INT_LEAST64_TYPE__ long long int +// WEBASSEMBLY-NEXT:#define __INT_LEAST8_FMTd__ "hhd" +// WEBASSEMBLY-NEXT:#define __INT_LEAST8_FMTi__ "hhi" +// WEBASSEMBLY-NEXT:#define __INT_LEAST8_MAX__ 127 +// WEBASSEMBLY-NEXT:#define __INT_LEAST8_TYPE__ signed char +// WEBASSEMBLY-NEXT:#define __INT_MAX__ 2147483647 +// WEBASSEMBLY-NEXT:#define __LDBL_DECIMAL_DIG__ 36 +// WEBASSEMBLY-NEXT:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L +// WEBASSEMBLY-NEXT:#define __LDBL_DIG__ 33 +// WEBASSEMBLY-NEXT:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L +// WEBASSEMBLY-NEXT:#define __LDBL_HAS_DENORM__ 1 +// WEBASSEMBLY-NEXT:#define __LDBL_HAS_INFINITY__ 1 +// WEBASSEMBLY-NEXT:#define __LDBL_HAS_QUIET_NAN__ 1 +// WEBASSEMBLY-NEXT:#define __LDBL_MANT_DIG__ 113 +// WEBASSEMBLY-NEXT:#define __LDBL_MAX_10_EXP__ 4932 +// WEBASSEMBLY-NEXT:#define __LDBL_MAX_EXP__ 16384 +// WEBASSEMBLY-NEXT:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L +// WEBASSEMBLY-NEXT:#define __LDBL_MIN_10_EXP__ (-4931) +// WEBASSEMBLY-NEXT:#define __LDBL_MIN_EXP__ (-16381) +// WEBASSEMBLY-NEXT:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L +// WEBASSEMBLY-NEXT:#define __LITTLE_ENDIAN__ 1 +// WEBASSEMBLY-NEXT:#define __LONG_LONG_MAX__ 9223372036854775807LL // WEBASSEMBLY32-NEXT:#define __LONG_MAX__ 2147483647L // WEBASSEMBLY32-NOT:#define __LP64__ -// WEBASSEMBLY32-NEXT:#define __NO_INLINE__ 1 -// WEBASSEMBLY32-NEXT:#define __OBJC_BOOL_IS_BOOL 0 -// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES 3 -// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_DEVICE 2 -// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_SUB_GROUP 4 -// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_GROUP 1 -// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_ITEM 0 -// WEBASSEMBLY32-NEXT:#define __ORDER_BIG_ENDIAN__ 4321 -// WEBASSEMBLY32-NEXT:#define __ORDER_LITTLE_ENDIAN__ 1234 -// WEBASSEMBLY32-NEXT:#define __ORDER_PDP_ENDIAN__ 3412 +// WEBASSEMBLY64-NEXT:#define __LONG_MAX__ 9223372036854775807L +// WEBASSEMBLY64-NEXT:#define __LP64__ 1 +// WEBASSEMBLY-NEXT:#define __NO_INLINE__ 1 +// WEBASSEMBLY-NEXT:#define __OBJC_BOOL_IS_BOOL 0 +// WEBASSEMBLY-NEXT:#define __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES 3 +// WEBASSEMBLY-NEXT:#define __OPENCL_MEMORY_SCOPE_DEVICE 2 +// WEBASSEMBLY-NEXT:#define __OPENCL_MEMORY_SCOPE_SUB_GROUP 4 +// WEBASSEMBLY-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_GROUP 1 +// WEBASSEMBLY-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_ITEM 0 +// WEBASSEMBLY-NEXT:#define __ORDER_BIG_ENDIAN__ 4321 +// WEBASSEMBLY-NEXT:#define __ORDER_LITTLE_ENDIAN__ 1234 +// WEBASSEMBLY-NEXT:#define __ORDER_PDP_ENDIAN__ 3412 // WEBASSEMBLY32-NEXT:#define __POINTER_WIDTH__ 32 -// WEBASSEMBLY32-NEXT:#define __PRAGMA_REDEFINE_EXTNAME 1 -// WEBASSEMBLY32-NEXT:#define __PTRDIFF_FMTd__ "ld" -// WEBASSEMBLY32-NEXT:#define __PTRDIFF_FMTi__ "li" +// WEBASSEMBLY64-NEXT:#define __POINTER_WIDTH__ 64 +// WEBASSEMBLY-NEXT:#define __PRAGMA_REDEFINE_EXTNAME 1 +// WEBASSEMBLY-NEXT:#define __PTRDIFF_FMTd__ "ld" +// WEBASSEMBLY-NEXT:#define __PTRDIFF_FMTi__ "li" // WEBASSEMBLY32-NEXT:#define __PTRDIFF_MAX__ 2147483647L -// WEBASSEMBLY32-NEXT:#define __PTRDIFF_TYPE__ long int +// WEBASSEMBLY64-NEXT:#define __PTRDIFF_MAX__ 9223372036854775807L +// WEBASSEMBLY-NEXT:#define __PTRDIFF_TYPE__ long int // WEBASSEMBLY32-NEXT:#define __PTRDIFF_WIDTH__ 32 -// WEBASSEMBLY32-NOT:#define __REGISTER_PREFIX__ -// WEBASSEMBLY32-NEXT:#define __SCHAR_MAX__ 127 -// WEBASSEMBLY32-NEXT:#define __SHRT_MAX__ 32767 +// WEBASSEMBLY64-NEXT:#define __PTRDIFF_WIDTH__ 64 +// WEBASSEMBLY-NOT:#define __REGISTER_PREFIX__ +// WEBASSEMBLY-NEXT:#define __SCHAR_MAX__ 127 +// WEBASSEMBLY-NEXT:#define __SHRT_MAX__ 32767 // WEBASSEMBLY32-NEXT:#define __SIG_ATOMIC_MAX__ 2147483647L // WEBASSEMBLY32-NEXT:#define __SIG_ATOMIC_WIDTH__ 32 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_DOUBLE__ 8 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_FLOAT__ 4 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_INT128__ 16 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_INT__ 4 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_LONG_DOUBLE__ 16 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_LONG_LONG__ 8 +// WEBASSEMBLY64-NEXT:#define __SIG_ATOMIC_MAX__ 9223372036854775807L +// WEBASSEMBLY64-NEXT:#define __SIG_ATOMIC_WIDTH__ 64 +// WEBASSEMBLY-NEXT:#define __SIZEOF_DOUBLE__ 8 +// WEBASSEMBLY-NEXT:#define __SIZEOF_FLOAT__ 4 +// WEBASSEMBLY-NEXT:#define __SIZEOF_INT128__ 16 +// WEBASSEMBLY-NEXT:#define __SIZEOF_INT__ 4 +// WEBASSEMBLY-NEXT:#define __SIZEOF_LONG_DOUBLE__ 16 +// WEBASSEMBLY-NEXT:#define __SIZEOF_LONG_LONG__ 8 // WEBASSEMBLY32-NEXT:#define __SIZEOF_LONG__ 4 // WEBASSEMBLY32-NEXT:#define __SIZEOF_POINTER__ 4 // WEBASSEMBLY32-NEXT:#define __SIZEOF_PTRDIFF_T__ 4 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_SHORT__ 2 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_SIZE_T__ 4 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_WCHAR_T__ 4 -// WEBASSEMBLY32-NEXT:#define __SIZEOF_WINT_T__ 4 -// WEBASSEMBLY32-NEXT:#define __SIZE_FMTX__ "lX" -// WEBASSEMBLY32-NEXT:#define __SIZE_FMTo__ "lo" -// WEBASSEMBLY32-NEXT:#define __SIZE_FMTu__ "lu" -// WEBASSEMBLY32-NEXT:#define __SIZE_FMTx__ "lx" -// WEBASSEMBLY32-NEXT:#define __SIZE_MAX__ 4294967295UL -// WEBASSEMBLY32-NEXT:#define __SIZE_TYPE__ long unsigned int -// WEBASSEMBLY32-NEXT:#define __SIZE_WIDTH__ 32 -// WEBASSEMBLY32-NEXT:#define __STDC_HOSTED__ 0 -// WEBASSEMBLY32-NOT:#define __STDC_MB_MIGHT_NEQ_WC__ -// WEBASSEMBLY32-NOT:#define __STDC_NO_ATOMICS__ -// WEBASSEMBLY32-NOT:#define __STDC_NO_COMPLEX__ -// WEBASSEMBLY32-NOT:#define __STDC_NO_VLA__ -// WEBASSEMBLY32-NOT:#define __STDC_NO_THREADS__ -// WEBASSEMBLY32-NEXT:#define __STDC_UTF_16__ 1 -// WEBASSEMBLY32-NEXT:#define __STDC_UTF_32__ 1 -// WEBASSEMBLY32-NEXT:#define __STDC_VERSION__ 201112L -// WEBASSEMBLY32-NEXT:#define __STDC__ 1 -// WEBASSEMBLY32-NEXT:#define __UINT16_C_SUFFIX__ -// WEBASSEMBLY32-NEXT:#define __UINT16_FMTX__ "hX" -// WEBASSEMBLY32-NEXT:#define __UINT16_FMTo__ "ho" -// WEBASSEMBLY32-NEXT:#define __UINT16_FMTu__ "hu" -// WEBASSEMBLY32-NEXT:#define __UINT16_FMTx__ "hx" -// WEBASSEMBLY32-NEXT:#define __UINT16_MAX__ 65535 -// WEBASSEMBLY32-NEXT:#define __UINT16_TYPE__ unsigned short -// WEBASSEMBLY32-NEXT:#define __UINT32_C_SUFFIX__ U -// WEBASSEMBLY32-NEXT:#define __UINT32_FMTX__ "X" -// WEBASSEMBLY32-NEXT:#define __UINT32_FMTo__ "o" -// WEBASSEMBLY32-NEXT:#define __UINT32_FMTu__ "u" -// WEBASSEMBLY32-NEXT:#define __UINT32_FMTx__ "x" -// WEBASSEMBLY32-NEXT:#define __UINT32_MAX__ 4294967295U -// WEBASSEMBLY32-NEXT:#define __UINT32_TYPE__ unsigned int -// WEBASSEMBLY32-NEXT:#define __UINT64_C_SUFFIX__ ULL -// WEBASSEMBLY32-NEXT:#define __UINT64_FMTX__ "llX" -// WEBASSEMBLY32-NEXT:#define __UINT64_FMTo__ "llo" -// WEBASSEMBLY32-NEXT:#define __UINT64_FMTu__ "llu" -// WEBASSEMBLY32-NEXT:#define __UINT64_FMTx__ "llx" -// WEBASSEMBLY32-NEXT:#define __UINT64_MAX__ 18446744073709551615ULL -// WEBASSEMBLY32-NEXT:#define __UINT64_TYPE__ long long unsigned int -// WEBASSEMBLY32-NEXT:#define __UINT8_C_SUFFIX__ -// WEBASSEMBLY32-NEXT:#define __UINT8_FMTX__ "hhX" -// WEBASSEMBLY32-NEXT:#define __UINT8_FMTo__ "hho" -// WEBASSEMBLY32-NEXT:#define __UINT8_FMTu__ "hhu" -// WEBASSEMBLY32-NEXT:#define __UINT8_FMTx__ "hhx" -// WEBASSEMBLY32-NEXT:#define __UINT8_MAX__ 255 -// WEBASSEMBLY32-NEXT:#define __UINT8_TYPE__ unsigned char -// WEBASSEMBLY32-NEXT:#define __UINTMAX_C_SUFFIX__ ULL -// WEBASSEMBLY32-NEXT:#define __UINTMAX_FMTX__ "llX" -// WEBASSEMBLY32-NEXT:#define __UINTMAX_FMTo__ "llo" -// WEBASSEMBLY32-NEXT:#define __UINTMAX_FMTu__ "llu" -// WEBASSEMBLY32-NEXT:#define __UINTMAX_FMTx__ "llx" -// WEBASSEMBLY32-NEXT:#define __UINTMAX_MAX__ 18446744073709551615ULL -// WEBASSEMBLY32-NEXT:#define __UINTMAX_TYPE__ long long unsigned int -// WEBASSEMBLY32-NEXT:#define __UINTMAX_WIDTH__ 64 -// WEBASSEMBLY32-NEXT:#define __UINTPTR_FMTX__ "lX" -// WEBASSEMBLY32-NEXT:#define __UINTPTR_FMTo__ "lo" -// WEBASSEMBLY32-NEXT:#define __UINTPTR_FMTu__ "lu" -// WEBASSEMBLY32-NEXT:#define __UINTPTR_FMTx__ "lx" -// WEBASSEMBLY32-NEXT:#define __UINTPTR_MAX__ 4294967295UL -// WEBASSEMBLY32-NEXT:#define __UINTPTR_TYPE__ long unsigned int -// WEBASSEMBLY32-NEXT:#define __UINTPTR_WIDTH__ 32 -// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_FMTX__ "hX" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_FMTo__ "ho" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_FMTu__ "hu" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_FMTx__ "hx" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_MAX__ 65535 -// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_TYPE__ unsigned short -// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_FMTX__ "X" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_FMTo__ "o" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_FMTu__ "u" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_FMTx__ "x" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_MAX__ 4294967295U -// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_TYPE__ unsigned int -// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_FMTX__ "llX" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_FMTo__ "llo" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_FMTu__ "llu" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_FMTx__ "llx" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_MAX__ 18446744073709551615ULL -// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_TYPE__ long long unsigned int -// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_FMTX__ "hhX" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_FMTo__ "hho" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_FMTu__ "hhu" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_FMTx__ "hhx" -// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_MAX__ 255 -// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_TYPE__ unsigned char -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_FMTX__ "hX" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_FMTo__ "ho" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_FMTu__ "hu" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_FMTx__ "hx" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_MAX__ 65535 -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_TYPE__ unsigned short -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_FMTX__ "X" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_FMTo__ "o" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_FMTu__ "u" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_FMTx__ "x" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_MAX__ 4294967295U -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_TYPE__ unsigned int -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_FMTX__ "llX" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_FMTo__ "llo" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_FMTu__ "llu" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_FMTx__ "llx" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_TYPE__ long long unsigned int -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_FMTX__ "hhX" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_FMTo__ "hho" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_FMTu__ "hhu" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_FMTx__ "hhx" -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_MAX__ 255 -// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_TYPE__ unsigned char -// WEBASSEMBLY32-NEXT:#define __USER_LABEL_PREFIX__ -// WEBASSEMBLY32-NEXT:#define __VERSION__ "{{.*}}" -// WEBASSEMBLY32-NEXT:#define __WCHAR_MAX__ 2147483647 -// WEBASSEMBLY32-NEXT:#define __WCHAR_TYPE__ int -// WEBASSEMBLY32-NOT:#define __WCHAR_UNSIGNED__ -// WEBASSEMBLY32-NEXT:#define __WCHAR_WIDTH__ 32 -// WEBASSEMBLY32-NEXT:#define __WINT_MAX__ 2147483647 -// WEBASSEMBLY32-NEXT:#define __WINT_TYPE__ int -// WEBASSEMBLY32-NOT:#define __WINT_UNSIGNED__ -// WEBASSEMBLY32-NEXT:#define __WINT_WIDTH__ 32 -// WEBASSEMBLY32-NEXT:#define __clang__ 1 -// WEBASSEMBLY32-NEXT:#define __clang_major__ {{.*}} -// WEBASSEMBLY32-NEXT:#define __clang_minor__ {{.*}} -// WEBASSEMBLY32-NEXT:#define __clang_patchlevel__ {{.*}} -// WEBASSEMBLY32-NEXT:#define __clang_version__ "{{.*}}" -// WEBASSEMBLY32-NEXT:#define __llvm__ 1 -// WEBASSEMBLY32-NOT:#define __wasm_simd128__ -// WEBASSEMBLY32-NOT:#define __wasm_simd256__ -// WEBASSEMBLY32-NOT:#define __wasm_simd512__ -// WEBASSEMBLY32-NOT:#define __unix -// WEBASSEMBLY32-NOT:#define __unix__ -// WEBASSEMBLY32-NEXT:#define __wasm 1 -// WEBASSEMBLY32-NEXT:#define __wasm32 1 -// WEBASSEMBLY32-NEXT:#define __wasm32__ 1 -// WEBASSEMBLY32-NOT:#define __wasm64 -// WEBASSEMBLY32-NOT:#define __wasm64__ -// WEBASSEMBLY32-NEXT:#define __wasm__ 1 -// -// RUN: %clang_cc1 -E -dM -ffreestanding -triple=wasm64-unknown-unknown \ -// RUN: < /dev/null \ -// RUN: | FileCheck -match-full-lines -check-prefix=WEBASSEMBLY64 %s -// -// WEBASSEMBLY64-NOT:#define _ILP32 -// WEBASSEMBLY64:#define _LP64 1 -// WEBASSEMBLY64-NEXT:#define __ATOMIC_ACQUIRE 2 -// WEBASSEMBLY64-NEXT:#define __ATOMIC_ACQ_REL 4 -// WEBASSEMBLY64-NEXT:#define __ATOMIC_CONSUME 1 -// WEBASSEMBLY64-NEXT:#define __ATOMIC_RELAXED 0 -// WEBASSEMBLY64-NEXT:#define __ATOMIC_RELEASE 3 -// WEBASSEMBLY64-NEXT:#define __ATOMIC_SEQ_CST 5 -// WEBASSEMBLY64-NEXT:#define __BIGGEST_ALIGNMENT__ 16 -// WEBASSEMBLY64-NEXT:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ -// WEBASSEMBLY64-NEXT:#define __CHAR16_TYPE__ unsigned short -// WEBASSEMBLY64-NEXT:#define __CHAR32_TYPE__ unsigned int -// WEBASSEMBLY64-NEXT:#define __CHAR_BIT__ 8 -// WEBASSEMBLY64-NOT:#define __CHAR_UNSIGNED__ -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_BOOL_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_CHAR_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_INT_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_LLONG_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_LONG_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_POINTER_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_SHORT_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __CONSTANT_CFSTRINGS__ 1 -// WEBASSEMBLY64-NEXT:#define __DBL_DECIMAL_DIG__ 17 -// WEBASSEMBLY64-NEXT:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324 -// WEBASSEMBLY64-NEXT:#define __DBL_DIG__ 15 -// WEBASSEMBLY64-NEXT:#define __DBL_EPSILON__ 2.2204460492503131e-16 -// WEBASSEMBLY64-NEXT:#define __DBL_HAS_DENORM__ 1 -// WEBASSEMBLY64-NEXT:#define __DBL_HAS_INFINITY__ 1 -// WEBASSEMBLY64-NEXT:#define __DBL_HAS_QUIET_NAN__ 1 -// WEBASSEMBLY64-NEXT:#define __DBL_MANT_DIG__ 53 -// WEBASSEMBLY64-NEXT:#define __DBL_MAX_10_EXP__ 308 -// WEBASSEMBLY64-NEXT:#define __DBL_MAX_EXP__ 1024 -// WEBASSEMBLY64-NEXT:#define __DBL_MAX__ 1.7976931348623157e+308 -// WEBASSEMBLY64-NEXT:#define __DBL_MIN_10_EXP__ (-307) -// WEBASSEMBLY64-NEXT:#define __DBL_MIN_EXP__ (-1021) -// WEBASSEMBLY64-NEXT:#define __DBL_MIN__ 2.2250738585072014e-308 -// WEBASSEMBLY64-NEXT:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__ -// WEBASSEMBLY64-NOT:#define __ELF__ -// WEBASSEMBLY64-NEXT:#define __FINITE_MATH_ONLY__ 0 -// WEBASSEMBLY64:#define __FLT_DECIMAL_DIG__ 9 -// WEBASSEMBLY64-NEXT:#define __FLT_DENORM_MIN__ 1.40129846e-45F -// WEBASSEMBLY64-NEXT:#define __FLT_DIG__ 6 -// WEBASSEMBLY64-NEXT:#define __FLT_EPSILON__ 1.19209290e-7F -// WEBASSEMBLY64-NEXT:#define __FLT_EVAL_METHOD__ 0 -// WEBASSEMBLY64-NEXT:#define __FLT_HAS_DENORM__ 1 -// WEBASSEMBLY64-NEXT:#define __FLT_HAS_INFINITY__ 1 -// WEBASSEMBLY64-NEXT:#define __FLT_HAS_QUIET_NAN__ 1 -// WEBASSEMBLY64-NEXT:#define __FLT_MANT_DIG__ 24 -// WEBASSEMBLY64-NEXT:#define __FLT_MAX_10_EXP__ 38 -// WEBASSEMBLY64-NEXT:#define __FLT_MAX_EXP__ 128 -// WEBASSEMBLY64-NEXT:#define __FLT_MAX__ 3.40282347e+38F -// WEBASSEMBLY64-NEXT:#define __FLT_MIN_10_EXP__ (-37) -// WEBASSEMBLY64-NEXT:#define __FLT_MIN_EXP__ (-125) -// WEBASSEMBLY64-NEXT:#define __FLT_MIN__ 1.17549435e-38F -// WEBASSEMBLY64-NEXT:#define __FLT_RADIX__ 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_INT_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_LONG_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 -// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 -// WEBASSEMBLY64-NEXT:#define __GNUC_MINOR__ {{.*}} -// WEBASSEMBLY64-NEXT:#define __GNUC_PATCHLEVEL__ {{.*}} -// WEBASSEMBLY64-NEXT:#define __GNUC_STDC_INLINE__ 1 -// WEBASSEMBLY64-NEXT:#define __GNUC__ {{.}} -// WEBASSEMBLY64-NEXT:#define __GXX_ABI_VERSION 1002 -// WEBASSEMBLY64-NOT:#define __ILP32__ -// WEBASSEMBLY64-NEXT:#define __INT16_C_SUFFIX__ -// WEBASSEMBLY64-NEXT:#define __INT16_FMTd__ "hd" -// WEBASSEMBLY64-NEXT:#define __INT16_FMTi__ "hi" -// WEBASSEMBLY64-NEXT:#define __INT16_MAX__ 32767 -// WEBASSEMBLY64-NEXT:#define __INT16_TYPE__ short -// WEBASSEMBLY64-NEXT:#define __INT32_C_SUFFIX__ -// WEBASSEMBLY64-NEXT:#define __INT32_FMTd__ "d" -// WEBASSEMBLY64-NEXT:#define __INT32_FMTi__ "i" -// WEBASSEMBLY64-NEXT:#define __INT32_MAX__ 2147483647 -// WEBASSEMBLY64-NEXT:#define __INT32_TYPE__ int -// WEBASSEMBLY64-NEXT:#define __INT64_C_SUFFIX__ LL -// WEBASSEMBLY64-NEXT:#define __INT64_FMTd__ "lld" -// WEBASSEMBLY64-NEXT:#define __INT64_FMTi__ "lli" -// WEBASSEMBLY64-NEXT:#define __INT64_MAX__ 9223372036854775807LL -// WEBASSEMBLY64-NEXT:#define __INT64_TYPE__ long long int -// WEBASSEMBLY64-NEXT:#define __INT8_C_SUFFIX__ -// WEBASSEMBLY64-NEXT:#define __INT8_FMTd__ "hhd" -// WEBASSEMBLY64-NEXT:#define __INT8_FMTi__ "hhi" -// WEBASSEMBLY64-NEXT:#define __INT8_MAX__ 127 -// WEBASSEMBLY64-NEXT:#define __INT8_TYPE__ signed char -// WEBASSEMBLY64-NEXT:#define __INTMAX_C_SUFFIX__ LL -// WEBASSEMBLY64-NEXT:#define __INTMAX_FMTd__ "lld" -// WEBASSEMBLY64-NEXT:#define __INTMAX_FMTi__ "lli" -// WEBASSEMBLY64-NEXT:#define __INTMAX_MAX__ 9223372036854775807LL -// WEBASSEMBLY64-NEXT:#define __INTMAX_TYPE__ long long int -// WEBASSEMBLY64-NEXT:#define __INTMAX_WIDTH__ 64 -// WEBASSEMBLY64-NEXT:#define __INTPTR_FMTd__ "ld" -// WEBASSEMBLY64-NEXT:#define __INTPTR_FMTi__ "li" -// WEBASSEMBLY64-NEXT:#define __INTPTR_MAX__ 9223372036854775807L -// WEBASSEMBLY64-NEXT:#define __INTPTR_TYPE__ long int -// WEBASSEMBLY64-NEXT:#define __INTPTR_WIDTH__ 64 -// WEBASSEMBLY64-NEXT:#define __INT_FAST16_FMTd__ "hd" -// WEBASSEMBLY64-NEXT:#define __INT_FAST16_FMTi__ "hi" -// WEBASSEMBLY64-NEXT:#define __INT_FAST16_MAX__ 32767 -// WEBASSEMBLY64-NEXT:#define __INT_FAST16_TYPE__ short -// WEBASSEMBLY64-NEXT:#define __INT_FAST32_FMTd__ "d" -// WEBASSEMBLY64-NEXT:#define __INT_FAST32_FMTi__ "i" -// WEBASSEMBLY64-NEXT:#define __INT_FAST32_MAX__ 2147483647 -// WEBASSEMBLY64-NEXT:#define __INT_FAST32_TYPE__ int -// WEBASSEMBLY64-NEXT:#define __INT_FAST64_FMTd__ "lld" -// WEBASSEMBLY64-NEXT:#define __INT_FAST64_FMTi__ "lli" -// WEBASSEMBLY64-NEXT:#define __INT_FAST64_MAX__ 9223372036854775807LL -// WEBASSEMBLY64-NEXT:#define __INT_FAST64_TYPE__ long long int -// WEBASSEMBLY64-NEXT:#define __INT_FAST8_FMTd__ "hhd" -// WEBASSEMBLY64-NEXT:#define __INT_FAST8_FMTi__ "hhi" -// WEBASSEMBLY64-NEXT:#define __INT_FAST8_MAX__ 127 -// WEBASSEMBLY64-NEXT:#define __INT_FAST8_TYPE__ signed char -// WEBASSEMBLY64-NEXT:#define __INT_LEAST16_FMTd__ "hd" -// WEBASSEMBLY64-NEXT:#define __INT_LEAST16_FMTi__ "hi" -// WEBASSEMBLY64-NEXT:#define __INT_LEAST16_MAX__ 32767 -// WEBASSEMBLY64-NEXT:#define __INT_LEAST16_TYPE__ short -// WEBASSEMBLY64-NEXT:#define __INT_LEAST32_FMTd__ "d" -// WEBASSEMBLY64-NEXT:#define __INT_LEAST32_FMTi__ "i" -// WEBASSEMBLY64-NEXT:#define __INT_LEAST32_MAX__ 2147483647 -// WEBASSEMBLY64-NEXT:#define __INT_LEAST32_TYPE__ int -// WEBASSEMBLY64-NEXT:#define __INT_LEAST64_FMTd__ "lld" -// WEBASSEMBLY64-NEXT:#define __INT_LEAST64_FMTi__ "lli" -// WEBASSEMBLY64-NEXT:#define __INT_LEAST64_MAX__ 9223372036854775807LL -// WEBASSEMBLY64-NEXT:#define __INT_LEAST64_TYPE__ long long int -// WEBASSEMBLY64-NEXT:#define __INT_LEAST8_FMTd__ "hhd" -// WEBASSEMBLY64-NEXT:#define __INT_LEAST8_FMTi__ "hhi" -// WEBASSEMBLY64-NEXT:#define __INT_LEAST8_MAX__ 127 -// WEBASSEMBLY64-NEXT:#define __INT_LEAST8_TYPE__ signed char -// WEBASSEMBLY64-NEXT:#define __INT_MAX__ 2147483647 -// WEBASSEMBLY64-NEXT:#define __LDBL_DECIMAL_DIG__ 36 -// WEBASSEMBLY64-NEXT:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L -// WEBASSEMBLY64-NEXT:#define __LDBL_DIG__ 33 -// WEBASSEMBLY64-NEXT:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L -// WEBASSEMBLY64-NEXT:#define __LDBL_HAS_DENORM__ 1 -// WEBASSEMBLY64-NEXT:#define __LDBL_HAS_INFINITY__ 1 -// WEBASSEMBLY64-NEXT:#define __LDBL_HAS_QUIET_NAN__ 1 -// WEBASSEMBLY64-NEXT:#define __LDBL_MANT_DIG__ 113 -// WEBASSEMBLY64-NEXT:#define __LDBL_MAX_10_EXP__ 4932 -// WEBASSEMBLY64-NEXT:#define __LDBL_MAX_EXP__ 16384 -// WEBASSEMBLY64-NEXT:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L -// WEBASSEMBLY64-NEXT:#define __LDBL_MIN_10_EXP__ (-4931) -// WEBASSEMBLY64-NEXT:#define __LDBL_MIN_EXP__ (-16381) -// WEBASSEMBLY64-NEXT:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L -// WEBASSEMBLY64-NEXT:#define __LITTLE_ENDIAN__ 1 -// WEBASSEMBLY64-NEXT:#define __LONG_LONG_MAX__ 9223372036854775807LL -// WEBASSEMBLY64-NEXT:#define __LONG_MAX__ 9223372036854775807L -// WEBASSEMBLY64-NEXT:#define __LP64__ 1 -// WEBASSEMBLY64-NEXT:#define __NO_INLINE__ 1 -// WEBASSEMBLY64-NEXT:#define __OBJC_BOOL_IS_BOOL 0 -// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES 3 -// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_DEVICE 2 -// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_SUB_GROUP 4 -// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_GROUP 1 -// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_ITEM 0 -// WEBASSEMBLY64-NEXT:#define __ORDER_BIG_ENDIAN__ 4321 -// WEBASSEMBLY64-NEXT:#define __ORDER_LITTLE_ENDIAN__ 1234 -// WEBASSEMBLY64-NEXT:#define __ORDER_PDP_ENDIAN__ 3412 -// WEBASSEMBLY64-NEXT:#define __POINTER_WIDTH__ 64 -// WEBASSEMBLY64-NEXT:#define __PRAGMA_REDEFINE_EXTNAME 1 -// WEBASSEMBLY64-NEXT:#define __PTRDIFF_FMTd__ "ld" -// WEBASSEMBLY64-NEXT:#define __PTRDIFF_FMTi__ "li" -// WEBASSEMBLY64-NEXT:#define __PTRDIFF_MAX__ 9223372036854775807L -// WEBASSEMBLY64-NEXT:#define __PTRDIFF_TYPE__ long int -// WEBASSEMBLY64-NEXT:#define __PTRDIFF_WIDTH__ 64 -// WEBASSEMBLY64-NOT:#define __REGISTER_PREFIX__ -// WEBASSEMBLY64-NEXT:#define __SCHAR_MAX__ 127 -// WEBASSEMBLY64-NEXT:#define __SHRT_MAX__ 32767 -// WEBASSEMBLY64-NEXT:#define __SIG_ATOMIC_MAX__ 9223372036854775807L -// WEBASSEMBLY64-NEXT:#define __SIG_ATOMIC_WIDTH__ 64 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_DOUBLE__ 8 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_FLOAT__ 4 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_INT128__ 16 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_INT__ 4 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_LONG_DOUBLE__ 16 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_LONG_LONG__ 8 // WEBASSEMBLY64-NEXT:#define __SIZEOF_LONG__ 8 // WEBASSEMBLY64-NEXT:#define __SIZEOF_POINTER__ 8 // WEBASSEMBLY64-NEXT:#define __SIZEOF_PTRDIFF_T__ 8 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_SHORT__ 2 +// WEBASSEMBLY-NEXT:#define __SIZEOF_SHORT__ 2 +// WEBASSEMBLY32-NEXT:#define __SIZEOF_SIZE_T__ 4 // WEBASSEMBLY64-NEXT:#define __SIZEOF_SIZE_T__ 8 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_WCHAR_T__ 4 -// WEBASSEMBLY64-NEXT:#define __SIZEOF_WINT_T__ 4 -// WEBASSEMBLY64-NEXT:#define __SIZE_FMTX__ "lX" -// WEBASSEMBLY64-NEXT:#define __SIZE_FMTo__ "lo" -// WEBASSEMBLY64-NEXT:#define __SIZE_FMTu__ "lu" -// WEBASSEMBLY64-NEXT:#define __SIZE_FMTx__ "lx" +// WEBASSEMBLY-NEXT:#define __SIZEOF_WCHAR_T__ 4 +// WEBASSEMBLY-NEXT:#define __SIZEOF_WINT_T__ 4 +// WEBASSEMBLY-NEXT:#define __SIZE_FMTX__ "lX" +// WEBASSEMBLY-NEXT:#define __SIZE_FMTo__ "lo" +// WEBASSEMBLY-NEXT:#define __SIZE_FMTu__ "lu" +// WEBASSEMBLY-NEXT:#define __SIZE_FMTx__ "lx" +// WEBASSEMBLY32-NEXT:#define __SIZE_MAX__ 4294967295UL // WEBASSEMBLY64-NEXT:#define __SIZE_MAX__ 18446744073709551615UL -// WEBASSEMBLY64-NEXT:#define __SIZE_TYPE__ long unsigned int +// WEBASSEMBLY-NEXT:#define __SIZE_TYPE__ long unsigned int +// WEBASSEMBLY32-NEXT:#define __SIZE_WIDTH__ 32 // WEBASSEMBLY64-NEXT:#define __SIZE_WIDTH__ 64 -// WEBASSEMBLY64-NEXT:#define __STDC_HOSTED__ 0 -// WEBASSEMBLY64-NOT:#define __STDC_MB_MIGHT_NEQ_WC__ -// WEBASSEMBLY64-NOT:#define __STDC_NO_ATOMICS__ -// WEBASSEMBLY64-NOT:#define __STDC_NO_COMPLEX__ -// WEBASSEMBLY64-NOT:#define __STDC_NO_VLA__ -// WEBASSEMBLY64-NOT:#define __STDC_NO_THREADS__ -// WEBASSEMBLY64-NEXT:#define __STDC_UTF_16__ 1 -// WEBASSEMBLY64-NEXT:#define __STDC_UTF_32__ 1 -// WEBASSEMBLY64-NEXT:#define __STDC_VERSION__ 201112L -// WEBASSEMBLY64-NEXT:#define __STDC__ 1 -// WEBASSEMBLY64-NEXT:#define __UINT16_C_SUFFIX__ -// WEBASSEMBLY64-NEXT:#define __UINT16_FMTX__ "hX" -// WEBASSEMBLY64-NEXT:#define __UINT16_FMTo__ "ho" -// WEBASSEMBLY64-NEXT:#define __UINT16_FMTu__ "hu" -// WEBASSEMBLY64-NEXT:#define __UINT16_FMTx__ "hx" -// WEBASSEMBLY64-NEXT:#define __UINT16_MAX__ 65535 -// WEBASSEMBLY64-NEXT:#define __UINT16_TYPE__ unsigned short -// WEBASSEMBLY64-NEXT:#define __UINT32_C_SUFFIX__ U -// WEBASSEMBLY64-NEXT:#define __UINT32_FMTX__ "X" -// WEBASSEMBLY64-NEXT:#define __UINT32_FMTo__ "o" -// WEBASSEMBLY64-NEXT:#define __UINT32_FMTu__ "u" -// WEBASSEMBLY64-NEXT:#define __UINT32_FMTx__ "x" -// WEBASSEMBLY64-NEXT:#define __UINT32_MAX__ 4294967295U -// WEBASSEMBLY64-NEXT:#define __UINT32_TYPE__ unsigned int -// WEBASSEMBLY64-NEXT:#define __UINT64_C_SUFFIX__ ULL -// WEBASSEMBLY64-NEXT:#define __UINT64_FMTX__ "llX" -// WEBASSEMBLY64-NEXT:#define __UINT64_FMTo__ "llo" -// WEBASSEMBLY64-NEXT:#define __UINT64_FMTu__ "llu" -// WEBASSEMBLY64-NEXT:#define __UINT64_FMTx__ "llx" -// WEBASSEMBLY64-NEXT:#define __UINT64_MAX__ 18446744073709551615ULL -// WEBASSEMBLY64-NEXT:#define __UINT64_TYPE__ long long unsigned int -// WEBASSEMBLY64-NEXT:#define __UINT8_C_SUFFIX__ -// WEBASSEMBLY64-NEXT:#define __UINT8_FMTX__ "hhX" -// WEBASSEMBLY64-NEXT:#define __UINT8_FMTo__ "hho" -// WEBASSEMBLY64-NEXT:#define __UINT8_FMTu__ "hhu" -// WEBASSEMBLY64-NEXT:#define __UINT8_FMTx__ "hhx" -// WEBASSEMBLY64-NEXT:#define __UINT8_MAX__ 255 -// WEBASSEMBLY64-NEXT:#define __UINT8_TYPE__ unsigned char -// WEBASSEMBLY64-NEXT:#define __UINTMAX_C_SUFFIX__ ULL -// WEBASSEMBLY64-NEXT:#define __UINTMAX_FMTX__ "llX" -// WEBASSEMBLY64-NEXT:#define __UINTMAX_FMTo__ "llo" -// WEBASSEMBLY64-NEXT:#define __UINTMAX_FMTu__ "llu" -// WEBASSEMBLY64-NEXT:#define __UINTMAX_FMTx__ "llx" -// WEBASSEMBLY64-NEXT:#define __UINTMAX_MAX__ 18446744073709551615ULL -// WEBASSEMBLY64-NEXT:#define __UINTMAX_TYPE__ long long unsigned int -// WEBASSEMBLY64-NEXT:#define __UINTMAX_WIDTH__ 64 -// WEBASSEMBLY64-NEXT:#define __UINTPTR_FMTX__ "lX" -// WEBASSEMBLY64-NEXT:#define __UINTPTR_FMTo__ "lo" -// WEBASSEMBLY64-NEXT:#define __UINTPTR_FMTu__ "lu" -// WEBASSEMBLY64-NEXT:#define __UINTPTR_FMTx__ "lx" +// WEBASSEMBLY-NEXT:#define __STDC_HOSTED__ 0 +// WEBASSEMBLY-NOT:#define __STDC_MB_MIGHT_NEQ_WC__ +// WEBASSEMBLY-NOT:#define __STDC_NO_ATOMICS__ +// WEBASSEMBLY-NOT:#define __STDC_NO_COMPLEX__ +// WEBASSEMBLY-NOT:#define __STDC_NO_VLA__ +// WEBASSEMBLY-NOT:#define __STDC_NO_THREADS__ +// WEBASSEMBLY-NEXT:#define __STDC_UTF_16__ 1 +// WEBASSEMBLY-NEXT:#define __STDC_UTF_32__ 1 +// WEBASSEMBLY-NEXT:#define __STDC_VERSION__ 201112L +// WEBASSEMBLY-NEXT:#define __STDC__ 1 +// WEBASSEMBLY-NEXT:#define __UINT16_C_SUFFIX__ +// WEBASSEMBLY-NEXT:#define __UINT16_FMTX__ "hX" +// WEBASSEMBLY-NEXT:#define __UINT16_FMTo__ "ho" +// WEBASSEMBLY-NEXT:#define __UINT16_FMTu__ "hu" +// WEBASSEMBLY-NEXT:#define __UINT16_FMTx__ "hx" +// WEBASSEMBLY-NEXT:#define __UINT16_MAX__ 65535 +// WEBASSEMBLY-NEXT:#define __UINT16_TYPE__ unsigned short +// WEBASSEMBLY-NEXT:#define __UINT32_C_SUFFIX__ U +// WEBASSEMBLY-NEXT:#define __UINT32_FMTX__ "X" +// WEBASSEMBLY-NEXT:#define __UINT32_FMTo__ "o" +// WEBASSEMBLY-NEXT:#define __UINT32_FMTu__ "u" +// WEBASSEMBLY-NEXT:#define __UINT32_FMTx__ "x" +// WEBASSEMBLY-NEXT:#define __UINT32_MAX__ 4294967295U +// WEBASSEMBLY-NEXT:#define __UINT32_TYPE__ unsigned int +// WEBASSEMBLY-NEXT:#define __UINT64_C_SUFFIX__ ULL +// WEBASSEMBLY-NEXT:#define __UINT64_FMTX__ "llX" +// WEBASSEMBLY-NEXT:#define __UINT64_FMTo__ "llo" +// WEBASSEMBLY-NEXT:#define __UINT64_FMTu__ "llu" +// WEBASSEMBLY-NEXT:#define __UINT64_FMTx__ "llx" +// WEBASSEMBLY-NEXT:#define __UINT64_MAX__ 18446744073709551615ULL +// WEBASSEMBLY-NEXT:#define __UINT64_TYPE__ long long unsigned int +// WEBASSEMBLY-NEXT:#define __UINT8_C_SUFFIX__ +// WEBASSEMBLY-NEXT:#define __UINT8_FMTX__ "hhX" +// WEBASSEMBLY-NEXT:#define __UINT8_FMTo__ "hho" +// WEBASSEMBLY-NEXT:#define __UINT8_FMTu__ "hhu" +// WEBASSEMBLY-NEXT:#define __UINT8_FMTx__ "hhx" +// WEBASSEMBLY-NEXT:#define __UINT8_MAX__ 255 +// WEBASSEMBLY-NEXT:#define __UINT8_TYPE__ unsigned char +// WEBASSEMBLY-NEXT:#define __UINTMAX_C_SUFFIX__ ULL +// WEBASSEMBLY-NEXT:#define __UINTMAX_FMTX__ "llX" +// WEBASSEMBLY-NEXT:#define __UINTMAX_FMTo__ "llo" +// WEBASSEMBLY-NEXT:#define __UINTMAX_FMTu__ "llu" +// WEBASSEMBLY-NEXT:#define __UINTMAX_FMTx__ "llx" +// WEBASSEMBLY-NEXT:#define __UINTMAX_MAX__ 18446744073709551615ULL +// WEBASSEMBLY-NEXT:#define __UINTMAX_TYPE__ long long unsigned int +// WEBASSEMBLY-NEXT:#define __UINTMAX_WIDTH__ 64 +// WEBASSEMBLY-NEXT:#define __UINTPTR_FMTX__ "lX" +// WEBASSEMBLY-NEXT:#define __UINTPTR_FMTo__ "lo" +// WEBASSEMBLY-NEXT:#define __UINTPTR_FMTu__ "lu" +// WEBASSEMBLY-NEXT:#define __UINTPTR_FMTx__ "lx" +// WEBASSEMBLY32-NEXT:#define __UINTPTR_MAX__ 4294967295UL // WEBASSEMBLY64-NEXT:#define __UINTPTR_MAX__ 18446744073709551615UL -// WEBASSEMBLY64-NEXT:#define __UINTPTR_TYPE__ long unsigned int +// WEBASSEMBLY-NEXT:#define __UINTPTR_TYPE__ long unsigned int +// WEBASSEMBLY32-NEXT:#define __UINTPTR_WIDTH__ 32 // WEBASSEMBLY64-NEXT:#define __UINTPTR_WIDTH__ 64 -// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_FMTX__ "hX" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_FMTo__ "ho" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_FMTu__ "hu" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_FMTx__ "hx" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_MAX__ 65535 -// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_TYPE__ unsigned short -// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_FMTX__ "X" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_FMTo__ "o" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_FMTu__ "u" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_FMTx__ "x" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_MAX__ 4294967295U -// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_TYPE__ unsigned int -// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_FMTX__ "llX" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_FMTo__ "llo" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_FMTu__ "llu" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_FMTx__ "llx" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_MAX__ 18446744073709551615ULL -// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_TYPE__ long long unsigned int -// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_FMTX__ "hhX" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_FMTo__ "hho" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_FMTu__ "hhu" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_FMTx__ "hhx" -// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_MAX__ 255 -// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_TYPE__ unsigned char -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_FMTX__ "hX" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_FMTo__ "ho" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_FMTu__ "hu" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_FMTx__ "hx" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_MAX__ 65535 -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_TYPE__ unsigned short -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_FMTX__ "X" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_FMTo__ "o" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_FMTu__ "u" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_FMTx__ "x" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_MAX__ 4294967295U -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_TYPE__ unsigned int -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_FMTX__ "llX" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_FMTo__ "llo" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_FMTu__ "llu" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_FMTx__ "llx" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_TYPE__ long long unsigned int -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_FMTX__ "hhX" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_FMTo__ "hho" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_FMTu__ "hhu" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_FMTx__ "hhx" -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_MAX__ 255 -// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_TYPE__ unsigned char -// WEBASSEMBLY64-NEXT:#define __USER_LABEL_PREFIX__ -// WEBASSEMBLY64-NEXT:#define __VERSION__ "{{.*}}" -// WEBASSEMBLY64-NEXT:#define __WCHAR_MAX__ 2147483647 -// WEBASSEMBLY64-NEXT:#define __WCHAR_TYPE__ int -// WEBASSEMBLY64-NOT:#define __WCHAR_UNSIGNED__ -// WEBASSEMBLY64-NEXT:#define __WCHAR_WIDTH__ 32 -// WEBASSEMBLY64-NEXT:#define __WINT_MAX__ 2147483647 -// WEBASSEMBLY64-NEXT:#define __WINT_TYPE__ int -// WEBASSEMBLY64-NOT:#define __WINT_UNSIGNED__ -// WEBASSEMBLY64-NEXT:#define __WINT_WIDTH__ 32 -// WEBASSEMBLY64-NEXT:#define __clang__ 1 -// WEBASSEMBLY64-NEXT:#define __clang_major__ {{.*}} -// WEBASSEMBLY64-NEXT:#define __clang_minor__ {{.*}} -// WEBASSEMBLY64-NEXT:#define __clang_patchlevel__ {{.*}} -// WEBASSEMBLY64-NEXT:#define __clang_version__ "{{.*}}" -// WEBASSEMBLY64-NEXT:#define __llvm__ 1 -// WEBASSEMBLY64-NOT:#define __wasm_simd128__ -// WEBASSEMBLY64-NOT:#define __wasm_simd256__ -// WEBASSEMBLY64-NOT:#define __wasm_simd512__ -// WEBASSEMBLY64-NOT:#define __unix -// WEBASSEMBLY64-NOT:#define __unix__ -// WEBASSEMBLY64-NEXT:#define __wasm 1 +// WEBASSEMBLY-NEXT:#define __UINT_FAST16_FMTX__ "hX" +// WEBASSEMBLY-NEXT:#define __UINT_FAST16_FMTo__ "ho" +// WEBASSEMBLY-NEXT:#define __UINT_FAST16_FMTu__ "hu" +// WEBASSEMBLY-NEXT:#define __UINT_FAST16_FMTx__ "hx" +// WEBASSEMBLY-NEXT:#define __UINT_FAST16_MAX__ 65535 +// WEBASSEMBLY-NEXT:#define __UINT_FAST16_TYPE__ unsigned short +// WEBASSEMBLY-NEXT:#define __UINT_FAST32_FMTX__ "X" +// WEBASSEMBLY-NEXT:#define __UINT_FAST32_FMTo__ "o" +// WEBASSEMBLY-NEXT:#define __UINT_FAST32_FMTu__ "u" +// WEBASSEMBLY-NEXT:#define __UINT_FAST32_FMTx__ "x" +// WEBASSEMBLY-NEXT:#define __UINT_FAST32_MAX__ 4294967295U +// WEBASSEMBLY-NEXT:#define __UINT_FAST32_TYPE__ unsigned int +// WEBASSEMBLY-NEXT:#define __UINT_FAST64_FMTX__ "llX" +// WEBASSEMBLY-NEXT:#define __UINT_FAST64_FMTo__ "llo" +// WEBASSEMBLY-NEXT:#define __UINT_FAST64_FMTu__ "llu" +// WEBASSEMBLY-NEXT:#define __UINT_FAST64_FMTx__ "llx" +// WEBASSEMBLY-NEXT:#define __UINT_FAST64_MAX__ 18446744073709551615ULL +// WEBASSEMBLY-NEXT:#define __UINT_FAST64_TYPE__ long long unsigned int +// WEBASSEMBLY-NEXT:#define __UINT_FAST8_FMTX__ "hhX" +// WEBASSEMBLY-NEXT:#define __UINT_FAST8_FMTo__ "hho" +// WEBASSEMBLY-NEXT:#define __UINT_FAST8_FMTu__ "hhu" +// WEBASSEMBLY-NEXT:#define __UINT_FAST8_FMTx__ "hhx" +// WEBASSEMBLY-NEXT:#define __UINT_FAST8_MAX__ 255 +// WEBASSEMBLY-NEXT:#define __UINT_FAST8_TYPE__ unsigned char +// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_FMTX__ "hX" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_FMTo__ "ho" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_FMTu__ "hu" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_FMTx__ "hx" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_MAX__ 65535 +// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_TYPE__ unsigned short +// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_FMTX__ "X" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_FMTo__ "o" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_FMTu__ "u" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_FMTx__ "x" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_MAX__ 4294967295U +// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_TYPE__ unsigned int +// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_FMTX__ "llX" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_FMTo__ "llo" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_FMTu__ "llu" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_FMTx__ "llx" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL +// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_TYPE__ long long unsigned int +// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_FMTX__ "hhX" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_FMTo__ "hho" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_FMTu__ "hhu" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_FMTx__ "hhx" +// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_MAX__ 255 +// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_TYPE__ unsigned char +// WEBASSEMBLY-NEXT:#define __USER_LABEL_PREFIX__ +// WEBASSEMBLY-NEXT:#define __VERSION__ "{{.*}}" +// WEBASSEMBLY-NEXT:#define __WCHAR_MAX__ 2147483647 +// WEBASSEMBLY-NEXT:#define __WCHAR_TYPE__ int +// WEBASSEMBLY-NOT:#define __WCHAR_UNSIGNED__ +// WEBASSEMBLY-NEXT:#define __WCHAR_WIDTH__ 32 +// WEBASSEMBLY-NEXT:#define __WINT_MAX__ 2147483647 +// WEBASSEMBLY-NEXT:#define __WINT_TYPE__ int +// WEBASSEMBLY-NOT:#define __WINT_UNSIGNED__ +// WEBASSEMBLY-NEXT:#define __WINT_WIDTH__ 32 +// WEBASSEMBLY-NEXT:#define __clang__ 1 +// WEBASSEMBLY-NEXT:#define __clang_major__ {{.*}} +// WEBASSEMBLY-NEXT:#define __clang_minor__ {{.*}} +// WEBASSEMBLY-NEXT:#define __clang_patchlevel__ {{.*}} +// WEBASSEMBLY-NEXT:#define __clang_version__ "{{.*}}" +// WEBASSEMBLY-NEXT:#define __llvm__ 1 +// WEBASSEMBLY-NOT:#define __unix +// WEBASSEMBLY-NOT:#define __unix__ +// WEBASSEMBLY-NOT:#define __wasm_simd128__ +// WEBASSEMBLY-NOT:#define __wasm_simd256__ +// WEBASSEMBLY-NOT:#define __wasm_simd512__ +// WEBASSEMBLY-NEXT:#define __wasm 1 +// WEBASSEMBLY32-NEXT:#define __wasm32 1 // WEBASSEMBLY64-NOT:#define __wasm32 +// WEBASSEMBLY32-NEXT:#define __wasm32__ 1 // WEBASSEMBLY64-NOT:#define __wasm32__ +// WEBASSEMBLY32-NOT:#define __wasm64__ +// WEBASSEMBLY32-NOT:#define __wasm64 // WEBASSEMBLY64-NEXT:#define __wasm64 1 // WEBASSEMBLY64-NEXT:#define __wasm64__ 1 -// WEBASSEMBLY64-NEXT:#define __wasm__ 1 +// WEBASSEMBLY-NEXT:#define __wasm__ 1 // RUN: %clang_cc1 -E -dM -ffreestanding -triple i686-windows-cygnus < /dev/null | FileCheck -match-full-lines -check-prefix CYGWIN-X32 %s // CYGWIN-X32: #define __USER_LABEL_PREFIX__ _ From b73d7051297ef90ed66b4b6a27a13fe9d471e880 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 28 Jan 2019 13:54:22 +0000 Subject: [PATCH 060/274] Merging r352105: Redirecting to URL 'https://llvm.org/svn/llvm-project/cfe/trunk': ------------------------------------------------------------------------ r352105 | djg | 2019-01-24 22:05:11 +0100 (Thu, 24 Jan 2019) | 7 lines [WebAssembly] Add a __wasi__ target macro This adds a `__wasi__` macro for the wasi OS, similar to `__linux__` etc. for other OS's. Differential Revision: https://reviews.llvm.org/D57155 ------------------------------------------------------------------------ llvm-svn: 352360 --- clang/lib/Basic/Targets.cpp | 24 ++++++++++++++++-------- clang/lib/Basic/Targets/OSTargets.h | 18 +++++++++++++++++- clang/test/Preprocessor/init.c | 7 +++++++ 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index cf87bc484621c..3c139d724796e 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -570,19 +570,27 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, Triple.getVendor() != llvm::Triple::UnknownVendor || !Triple.isOSBinFormatWasm()) return nullptr; - if (Triple.getOS() != llvm::Triple::UnknownOS && - Triple.getOS() != llvm::Triple::WASI) - return nullptr; - return new WebAssemblyOSTargetInfo(Triple, Opts); + switch (Triple.getOS()) { + case llvm::Triple::WASI: + return new WASITargetInfo(Triple, Opts); + case llvm::Triple::UnknownOS: + return new WebAssemblyOSTargetInfo(Triple, Opts); + default: + return nullptr; + } case llvm::Triple::wasm64: if (Triple.getSubArch() != llvm::Triple::NoSubArch || Triple.getVendor() != llvm::Triple::UnknownVendor || !Triple.isOSBinFormatWasm()) return nullptr; - if (Triple.getOS() != llvm::Triple::UnknownOS && - Triple.getOS() != llvm::Triple::WASI) - return nullptr; - return new WebAssemblyOSTargetInfo(Triple, Opts); + switch (Triple.getOS()) { + case llvm::Triple::WASI: + return new WASITargetInfo(Triple, Opts); + case llvm::Triple::UnknownOS: + return new WebAssemblyOSTargetInfo(Triple, Opts); + default: + return nullptr; + } case llvm::Triple::renderscript32: return new LinuxTargetInfo(Triple, Opts); diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h index 085efa02cc5f1..09867d82c382e 100644 --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -764,8 +764,9 @@ class LLVM_LIBRARY_VISIBILITY FuchsiaTargetInfo : public OSTargetInfo { template class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo : public OSTargetInfo { +protected: void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, - MacroBuilder &Builder) const final { + MacroBuilder &Builder) const { // A common platform macro. if (Opts.POSIXThreads) Builder.defineMacro("_REENTRANT"); @@ -783,6 +784,21 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo } }; +// WASI target +template +class LLVM_LIBRARY_VISIBILITY WASITargetInfo + : public WebAssemblyOSTargetInfo { + void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const final { + WebAssemblyOSTargetInfo::getOSDefines(Opts, Triple, Builder); + Builder.defineMacro("__wasi__"); + } + +public: + explicit WASITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : WebAssemblyOSTargetInfo(Triple, Opts) {} +}; + } // namespace targets } // namespace clang #endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H diff --git a/clang/test/Preprocessor/init.c b/clang/test/Preprocessor/init.c index d852102424ec3..770e52cc78435 100644 --- a/clang/test/Preprocessor/init.c +++ b/clang/test/Preprocessor/init.c @@ -9114,6 +9114,12 @@ // RUN: %clang_cc1 -E -dM -ffreestanding -triple=wasm64-unknown-unknown \ // RUN: < /dev/null \ // RUN: | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY64 %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=wasm32-unknown-wasi \ +// RUN: < /dev/null \ +// RUN: | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY32,WEBASSEMBLY-WASI %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=wasm64-unknown-wasi \ +// RUN: < /dev/null \ +// RUN: | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY64,WEBASSEMBLY-WASI %s // // WEBASSEMBLY32:#define _ILP32 1 // WEBASSEMBLY32-NOT:#define _LP64 @@ -9467,6 +9473,7 @@ // WEBASSEMBLY-NEXT:#define __llvm__ 1 // WEBASSEMBLY-NOT:#define __unix // WEBASSEMBLY-NOT:#define __unix__ +// WEBASSEMBLY-WASI-NEXT:#define __wasi__ 1 // WEBASSEMBLY-NOT:#define __wasm_simd128__ // WEBASSEMBLY-NOT:#define __wasm_simd256__ // WEBASSEMBLY-NOT:#define __wasm_simd512__ From 1680cb52675ab7dd420887d1e0445c15b7a198a6 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 28 Jan 2019 14:07:41 +0000 Subject: [PATCH 061/274] Merging r352221 and r352222: ------------------------------------------------------------------------ r352221 | erichkeane | 2019-01-25 18:27:57 +0100 (Fri, 25 Jan 2019) | 12 lines Disable _Float16 for non ARM/SPIR Targets As Discussed here: http://lists.llvm.org/pipermail/llvm-dev/2019-January/129543.html There are problems exposing the _Float16 type on architectures that haven't defined the ABI/ISel for the type yet, so we're temporarily disabling the type and making it opt-in. Differential Revision: https://reviews.llvm.org/D57188 Change-Id: I5db7366dedf1deb9485adb8948b1deb7e612a736 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r352222 | erichkeane | 2019-01-25 18:39:57 +0100 (Fri, 25 Jan 2019) | 3 lines Fix incorrect indent from r352221 Change-Id: I0a7b1443eb6912ef7bea1a4cf2f696fc01726557 ------------------------------------------------------------------------ llvm-svn: 352363 --- clang/docs/LanguageExtensions.rst | 90 +++++++++++-------- clang/include/clang/Basic/TargetInfo.h | 4 + clang/lib/Basic/TargetInfo.cpp | 1 + clang/lib/Basic/Targets/AArch64.cpp | 1 + clang/lib/Basic/Targets/ARM.cpp | 1 + clang/lib/Basic/Targets/SPIR.h | 1 + clang/lib/Sema/SemaType.cpp | 7 +- clang/test/AST/float16.cpp | 4 +- .../test/CodeGenCXX/float16-declarations.cpp | 6 -- clang/test/CodeGenCXX/mangle-ms.cpp | 5 +- clang/test/Lexer/half-literal.cpp | 2 +- clang/test/Sema/Float16.c | 11 +++ 12 files changed, 84 insertions(+), 49 deletions(-) create mode 100644 clang/test/Sema/Float16.c diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index e155cefb7890d..5782edd353701 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -474,44 +474,58 @@ Half-Precision Floating Point ============================= Clang supports two half-precision (16-bit) floating point types: ``__fp16`` and -``_Float16``. ``__fp16`` is defined in the ARM C Language Extensions (`ACLE -`_) -and ``_Float16`` in ISO/IEC TS 18661-3:2015. - -``__fp16`` is a storage and interchange format only. This means that values of -``__fp16`` promote to (at least) float when used in arithmetic operations. -There are two ``__fp16`` formats. Clang supports the IEEE 754-2008 format and -not the ARM alternative format. - -ISO/IEC TS 18661-3:2015 defines C support for additional floating point types. -``_FloatN`` is defined as a binary floating type, where the N suffix denotes -the number of bits and is 16, 32, 64, or greater and equal to 128 and a -multiple of 32. Clang supports ``_Float16``. The difference from ``__fp16`` is -that arithmetic on ``_Float16`` is performed in half-precision, thus it is not -a storage-only format. ``_Float16`` is available as a source language type in -both C and C++ mode. - -It is recommended that portable code use the ``_Float16`` type because -``__fp16`` is an ARM C-Language Extension (ACLE), whereas ``_Float16`` is -defined by the C standards committee, so using ``_Float16`` will not prevent -code from being ported to architectures other than Arm. Also, ``_Float16`` -arithmetic and operations will directly map on half-precision instructions when -they are available (e.g. Armv8.2-A), avoiding conversions to/from -single-precision, and thus will result in more performant code. If -half-precision instructions are unavailable, values will be promoted to -single-precision, similar to the semantics of ``__fp16`` except that the -results will be stored in single-precision. - -In an arithmetic operation where one operand is of ``__fp16`` type and the -other is of ``_Float16`` type, the ``_Float16`` type is first converted to -``__fp16`` type and then the operation is completed as if both operands were of -``__fp16`` type. - -To define a ``_Float16`` literal, suffix ``f16`` can be appended to the compile-time -constant declaration. There is no default argument promotion for ``_Float16``; this -applies to the standard floating types only. As a consequence, for example, an -explicit cast is required for printing a ``_Float16`` value (there is no string -format specifier for ``_Float16``). +``_Float16``. These types are supported in all language modes. + +``__fp16`` is supported on every target, as it is purely a storage format; see below. +``_Float16`` is currently only supported on the following targets, with further +targets pending ABI standardization: +- 32-bit ARM +- 64-bit ARM (AArch64) +- SPIR +``_Float16`` will be supported on more targets as they define ABIs for it. + +``__fp16`` is a storage and interchange format only. This means that values of +``__fp16`` are immediately promoted to (at least) ``float`` when used in arithmetic +operations, so that e.g. the result of adding two ``__fp16`` values has type ``float``. +The behavior of ``__fp16`` is specified by the ARM C Language Extensions (`ACLE `_). +Clang uses the ``binary16`` format from IEEE 754-2008 for ``__fp16``, not the ARM +alternative format. + +``_Float16`` is an extended floating-point type. This means that, just like arithmetic on +``float`` or ``double``, arithmetic on ``_Float16`` operands is formally performed in the +``_Float16`` type, so that e.g. the result of adding two ``_Float16`` values has type +``_Float16``. The behavior of ``_Float16`` is specified by ISO/IEC TS 18661-3:2015 +("Floating-point extensions for C"). As with ``__fp16``, Clang uses the ``binary16`` +format from IEEE 754-2008 for ``_Float16``. + +``_Float16`` arithmetic will be performed using native half-precision support +when available on the target (e.g. on ARMv8.2a); otherwise it will be performed +at a higher precision (currently always ``float``) and then truncated down to +``_Float16``. Note that C and C++ allow intermediate floating-point operands +of an expression to be computed with greater precision than is expressible in +their type, so Clang may avoid intermediate truncations in certain cases; this may +lead to results that are inconsistent with native arithmetic. + +It is recommended that portable code use ``_Float16`` instead of ``__fp16``, +as it has been defined by the C standards committee and has behavior that is +more familiar to most programmers. + +Because ``__fp16`` operands are always immediately promoted to ``float``, the +common real type of ``__fp16`` and ``_Float16`` for the purposes of the usual +arithmetic conversions is ``float``. + +A literal can be given ``_Float16`` type using the suffix ``f16``; for example: +``` +3.14f16 +``` + +Because default argument promotion only applies to the standard floating-point +types, ``_Float16`` values are not promoted to ``double`` when passed as variadic +or untyped arguments. As a consequence, some caution must be taken when using +certain library facilities with ``_Float16``; for example, there is no ``printf`` format +specifier for ``_Float16``, and (unlike ``float``) it will not be implicitly promoted to +``double`` when passed to ``printf``, so the programmer must explicitly cast it to +``double`` before using it with an ``%f`` or similar specifier. Messages on ``deprecated`` and ``unavailable`` Attributes ========================================================= diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 786b1c251ca82..1e835d992bbeb 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -64,6 +64,7 @@ class TargetInfo : public RefCountedBase { bool HasLegalHalfType; // True if the backend supports operations on the half // LLVM IR type. bool HasFloat128; + bool HasFloat16; unsigned char PointerWidth, PointerAlign; unsigned char BoolWidth, BoolAlign; unsigned char IntWidth, IntAlign; @@ -517,6 +518,9 @@ class TargetInfo : public RefCountedBase { /// Determine whether the __float128 type is supported on this target. virtual bool hasFloat128Type() const { return HasFloat128; } + /// Determine whether the _Float16 type is supported on this target. + virtual bool hasFloat16Type() const { return HasFloat16; } + /// Return the alignment that is suitable for storing any /// object with a fundamental alignment requirement. unsigned getSuitableAlign() const { return SuitableAlign; } diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 269fad38b8d57..8b7621d7962e1 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -35,6 +35,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { NoAsmVariants = false; HasLegalHalfType = false; HasFloat128 = false; + HasFloat16 = false; PointerWidth = PointerAlign = 32; BoolWidth = BoolAlign = 8; IntWidth = IntAlign = 32; diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 62919a02dcb9f..6297f23c5aa47 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -50,6 +50,7 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, // All AArch64 implementations support ARMv8 FP, which makes half a legal type. HasLegalHalfType = true; + HasFloat16 = true; LongWidth = LongAlign = PointerWidth = PointerAlign = 64; MaxVectorAlign = 128; diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp index 16644ace108b7..23eee34eaa93d 100644 --- a/clang/lib/Basic/Targets/ARM.cpp +++ b/clang/lib/Basic/Targets/ARM.cpp @@ -397,6 +397,7 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector &Features, SoftFloat = SoftFloatABI = false; HWDiv = 0; DotProd = 0; + HasFloat16 = true; // This does not diagnose illegal cases like having both // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp". diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 9815292fc276d..e8d92f11a1224 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -48,6 +48,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo { AddrSpaceMap = &SPIRAddrSpaceMap; UseAddrSpaceMapMangling = true; HasLegalHalfType = true; + HasFloat16 = true; // Define available target features // These must be defined in sorted order! NoAsmVariants = true; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index b4c075e9c46d4..1ae94c8aec999 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1442,7 +1442,12 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { else Result = Context.Int128Ty; break; - case DeclSpec::TST_float16: Result = Context.Float16Ty; break; + case DeclSpec::TST_float16: + if (!S.Context.getTargetInfo().hasFloat16Type()) + S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) + << "_Float16"; + Result = Context.Float16Ty; + break; case DeclSpec::TST_half: Result = Context.HalfTy; break; case DeclSpec::TST_float: Result = Context.FloatTy; break; case DeclSpec::TST_double: diff --git a/clang/test/AST/float16.cpp b/clang/test/AST/float16.cpp index aa65270c75d4c..2f428e7085ff1 100644 --- a/clang/test/AST/float16.cpp +++ b/clang/test/AST/float16.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace -// RUN: %clang_cc1 -std=c++11 -ast-dump -fnative-half-type %s | FileCheck %s --check-prefix=CHECK-NATIVE --strict-whitespace +// RUN: %clang_cc1 -std=c++11 -ast-dump -triple aarch64-linux-gnu %s | FileCheck %s --strict-whitespace +// RUN: %clang_cc1 -std=c++11 -ast-dump -triple aarch64-linux-gnu -fnative-half-type %s | FileCheck %s --check-prefix=CHECK-NATIVE --strict-whitespace /* Various contexts where type _Float16 can appear. */ diff --git a/clang/test/CodeGenCXX/float16-declarations.cpp b/clang/test/CodeGenCXX/float16-declarations.cpp index 7e1c1e8db93ca..7d07eac48111f 100644 --- a/clang/test/CodeGenCXX/float16-declarations.cpp +++ b/clang/test/CodeGenCXX/float16-declarations.cpp @@ -1,5 +1,4 @@ // RUN: %clang -std=c++11 --target=aarch64-arm--eabi -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-AARCH64 -// RUN: %clang -std=c++11 --target=x86_64 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-X86 /* Various contexts where type _Float16 can appear. */ @@ -15,7 +14,6 @@ namespace { _Float16 arr1n[10]; // CHECK-AARCH64-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x half] zeroinitializer, align 2 -// CHECK-X86-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x half] zeroinitializer, align 16 _Float16 arr2n[] = { 1.2, 3.0, 3.e4 }; // CHECK-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x half] [half 0xH3CCD, half 0xH4200, half 0xH7753], align 2 @@ -30,14 +28,12 @@ namespace { _Float16 f1f; // CHECK-AARCH64-DAG: @f1f = dso_local global half 0xH0000, align 2 -// CHECK-X86-DAG: @f1f = dso_local global half 0xH0000, align 2 _Float16 f2f = 32.4; // CHECK-DAG: @f2f = dso_local global half 0xH500D, align 2 _Float16 arr1f[10]; // CHECK-AARCH64-DAG: @arr1f = dso_local global [10 x half] zeroinitializer, align 2 -// CHECK-X86-DAG: @arr1f = dso_local global [10 x half] zeroinitializer, align 16 _Float16 arr2f[] = { -1.2, -3.0, -3.e4 }; // CHECK-DAG: @arr2f = dso_local global [3 x half] [half 0xHBCCD, half 0xHC200, half 0xHF753], align 2 @@ -137,8 +133,6 @@ int main(void) { long double cvtld = f2n; //CHECK-AARCh64-DAG: [[H2LD:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to fp128 //CHECK-AARCh64-DAG: store fp128 [[H2LD]], fp128* %{{.*}}, align 16 -//CHECK-X86-DAG: [[H2LD:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to x86_fp80 -//CHECK-X86-DAG: store x86_fp80 [[H2LD]], x86_fp80* %{{.*}}, align 16 _Float16 f2h = 42.0f; //CHECK-DAG: store half 0xH5140, half* %{{.*}}, align 2 diff --git a/clang/test/CodeGenCXX/mangle-ms.cpp b/clang/test/CodeGenCXX/mangle-ms.cpp index e128c94431532..0175b961e5e90 100644 --- a/clang/test/CodeGenCXX/mangle-ms.cpp +++ b/clang/test/CodeGenCXX/mangle-ms.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=i386-pc-win32 -std=c++98 | FileCheck %s // RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=x86_64-pc-win32 -std=c++98| FileCheck -check-prefix X64 %s +// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=aarch64-pc-win32 -std=c++98 -DARM | FileCheck -check-prefixes=X64,ARM %s int a; // CHECK-DAG: @"?a@@3HA" @@ -466,10 +467,12 @@ namespace Complex { // CHECK-DAG: define dso_local void @"?f@Complex@@YAXU?$_Complex@H@__clang@@@Z"( void f(_Complex int) {} } +#ifdef ARM namespace Float16 { -// CHECK-DAG: define dso_local void @"?f@Float16@@YAXU_Float16@__clang@@@Z"( +// ARM-DAG: define dso_local void @"?f@Float16@@YAXU_Float16@__clang@@@Z"( void f(_Float16) {} } +#endif // ARM namespace PR26029 { template diff --git a/clang/test/Lexer/half-literal.cpp b/clang/test/Lexer/half-literal.cpp index 8e0034d491dd7..2f1cf9589fab0 100644 --- a/clang/test/Lexer/half-literal.cpp +++ b/clang/test/Lexer/half-literal.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -triple aarch64-linux-gnu %s float a = 1.0h; // expected-error{{no matching literal operator for call to 'operator""h' with argument of type 'long double' or 'const char *', and no matching literal operator template}} float b = 1.0H; // expected-error{{invalid suffix 'H' on floating constant}} diff --git a/clang/test/Sema/Float16.c b/clang/test/Sema/Float16.c new file mode 100644 index 0000000000000..bdfb01702c371 --- /dev/null +++ b/clang/test/Sema/Float16.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux-pc %s +// RUN: %clang_cc1 -fsyntax-only -verify -triple spir-unknown-unknown %s -DHAVE +// RUN: %clang_cc1 -fsyntax-only -verify -triple armv7a-linux-gnu %s -DHAVE +// RUN: %clang_cc1 -fsyntax-only -verify -triple aarch64-linux-gnu %s -DHAVE + +#ifdef HAVE +// expected-no-diagnostics +#else +// expected-error@+2{{_Float16 is not supported on this target}} +#endif // HAVE +_Float16 f; From accabdd5fa69f7370538d23e61eb4b5396375b2a Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 28 Jan 2019 14:10:30 +0000 Subject: [PATCH 062/274] Merging r352229: Redirecting to URL 'https://llvm.org/svn/llvm-project/cfe/trunk': ------------------------------------------------------------------------ r352229 | erichkeane | 2019-01-25 19:36:20 +0100 (Fri, 25 Jan 2019) | 7 lines Remove F16 literal support based on Float16 support. Float16 support was disabled recently on many platforms, however that commit still allowed literals of Float16 type to work. This commit removes those based on the same logic as Float16 disable. Change-Id: I72243048ae2db3dc47bd3d699843e3edf9c395ea ------------------------------------------------------------------------ llvm-svn: 352365 --- clang/lib/Lex/LiteralSupport.cpp | 9 +++++---- clang/test/SemaCXX/Float16.cpp | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 clang/test/SemaCXX/Float16.cpp diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index fa0815eb9c6c5..3c1da075b0e26 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -617,10 +617,11 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, if (isHalf || isFloat || isLong || isFloat128) break; // HF, FF, LF, QF invalid. - if (s + 2 < ThisTokEnd && s[1] == '1' && s[2] == '6') { - s += 2; // success, eat up 2 characters. - isFloat16 = true; - continue; + if (PP.getTargetInfo().hasFloat16Type() && s + 2 < ThisTokEnd && + s[1] == '1' && s[2] == '6') { + s += 2; // success, eat up 2 characters. + isFloat16 = true; + continue; } isFloat = true; diff --git a/clang/test/SemaCXX/Float16.cpp b/clang/test/SemaCXX/Float16.cpp new file mode 100644 index 0000000000000..f27c3839854e1 --- /dev/null +++ b/clang/test/SemaCXX/Float16.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux-pc %s +// RUN: %clang_cc1 -fsyntax-only -verify -triple spir-unknown-unknown %s -DHAVE +// RUN: %clang_cc1 -fsyntax-only -verify -triple armv7a-linux-gnu %s -DHAVE +// RUN: %clang_cc1 -fsyntax-only -verify -triple aarch64-linux-gnu %s -DHAVE + +#ifdef HAVE +// expected-no-diagnostics +#endif // HAVE + +#ifndef HAVE +// expected-error@+2{{_Float16 is not supported on this target}} +#endif // !HAVE +_Float16 f; + +#ifndef HAVE +// expected-error@+2{{invalid suffix 'F16' on floating constant}} +#endif // !HAVE +const auto g = 1.1F16; From d1ba949f23d9ccfc9064eb6553df0642212d2bba Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 28 Jan 2019 14:13:58 +0000 Subject: [PATCH 063/274] Merging r352231: Redirecting to URL 'https://llvm.org/svn/llvm-project/clang-tools-extra/trunk': ------------------------------------------------------------------------ r352231 | jonastoth | 2019-01-25 20:05:12 +0100 (Fri, 25 Jan 2019) | 13 lines [clang-tidy] fix unit tests for dropped _Float16 support in X86 Summary: Because _Float16 was disabled for X86 targets the unit-tests started failing. Extract the pieces for _Float16 and run theses tests under AArch64. Reviewers: aaron.ballman, erichkeane, lebedev.ri Reviewed By: erichkeane Subscribers: javed.absar, xazax.hun, kristof.beyls, cfe-commits Differential Revision: https://reviews.llvm.org/D57249 ------------------------------------------------------------------------ llvm-svn: 352368 --- ...ility-uppercase-literal-suffix-float16.cpp | 51 +++++++++++++++++++ ...ppercase-literal-suffix-floating-point.cpp | 28 ---------- ...eral-suffix-hexadecimal-floating-point.cpp | 15 ------ 3 files changed, 51 insertions(+), 43 deletions(-) create mode 100644 clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-float16.cpp diff --git a/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-float16.cpp b/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-float16.cpp new file mode 100644 index 0000000000000..b2b858f9345b5 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-float16.cpp @@ -0,0 +1,51 @@ +// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -- -target aarch64-linux-gnu -I %S + +#include "readability-uppercase-literal-suffix.h" + +void float16_normal_literals() { + // _Float16 + + static constexpr auto v14 = 1.f16; + // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase + // CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1.f16; + // CHECK-MESSAGES-NEXT: ^ ~ + // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}} + // CHECK-FIXES: static constexpr auto v14 = 1.F16; + static_assert(is_same::value, ""); + static_assert(v14 == 1.F16, ""); + + static constexpr auto v15 = 1.e0f16; + // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase + // CHECK-MESSAGES-NEXT: static constexpr auto v15 = 1.e0f16; + // CHECK-MESSAGES-NEXT: ^ ~ + // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}} + // CHECK-FIXES: static constexpr auto v15 = 1.e0F16; + static_assert(is_same::value, ""); + static_assert(v15 == 1.F16, ""); + + static constexpr auto v16 = 1.F16; // OK. + static_assert(is_same::value, ""); + static_assert(v16 == 1.F16, ""); + + static constexpr auto v17 = 1.e0F16; // OK. + static_assert(is_same::value, ""); + static_assert(v17 == 1.F16, ""); +} + +void float16_hexadecimal_literals() { +// _Float16 + + static constexpr auto v13 = 0xfp0f16; + // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase + // CHECK-MESSAGES-NEXT: static constexpr auto v13 = 0xfp0f16; + // CHECK-MESSAGES-NEXT: ^ ~ + // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}} + // CHECK-FIXES: static constexpr auto v13 = 0xfp0F16; + static_assert(is_same::value, ""); + static_assert(v13 == 0xfp0F16, ""); + + static constexpr auto v14 = 0xfp0F16; // OK. + static_assert(is_same::value, ""); + static_assert(v14 == 0xfp0F16, ""); + +} diff --git a/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp b/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp index 4d41db7a5ec64..50e75fae6ae40 100644 --- a/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp +++ b/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp @@ -97,34 +97,6 @@ void floating_point_suffix() { static constexpr auto v13 = 1.e0Q; // OK. static_assert(is_same::value, ""); static_assert(v13 == 1., ""); - - // _Float16 - - static constexpr auto v14 = 1.f16; - // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase - // CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1.f16; - // CHECK-MESSAGES-NEXT: ^ ~ - // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}} - // CHECK-FIXES: static constexpr auto v14 = 1.F16; - static_assert(is_same::value, ""); - static_assert(v14 == 1.F16, ""); - - static constexpr auto v15 = 1.e0f16; - // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase - // CHECK-MESSAGES-NEXT: static constexpr auto v15 = 1.e0f16; - // CHECK-MESSAGES-NEXT: ^ ~ - // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}} - // CHECK-FIXES: static constexpr auto v15 = 1.e0F16; - static_assert(is_same::value, ""); - static_assert(v15 == 1.F16, ""); - - static constexpr auto v16 = 1.F16; // OK. - static_assert(is_same::value, ""); - static_assert(v16 == 1.F16, ""); - - static constexpr auto v17 = 1.e0F16; // OK. - static_assert(is_same::value, ""); - static_assert(v17 == 1.F16, ""); } void floating_point_complex_suffix() { diff --git a/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp b/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp index 4cc9d6d2a7040..415c6d8e7915f 100644 --- a/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp +++ b/clang-tools-extra/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp @@ -93,21 +93,6 @@ void floating_point_suffix() { static constexpr auto v12 = 0xfp0Q; // OK. static_assert(is_same::value, ""); static_assert(v12 == 0xfp0, ""); - - // _Float16 - - static constexpr auto v13 = 0xfp0f16; - // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase - // CHECK-MESSAGES-NEXT: static constexpr auto v13 = 0xfp0f16; - // CHECK-MESSAGES-NEXT: ^ ~ - // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}} - // CHECK-FIXES: static constexpr auto v13 = 0xfp0F16; - static_assert(is_same::value, ""); - static_assert(v13 == 0xfp0F16, ""); - - static constexpr auto v14 = 0xfp0F16; // OK. - static_assert(is_same::value, ""); - static_assert(v14 == 0xfp0F16, ""); } void floating_point_complex_suffix() { From be5f5b31c4fda9240669f903710756befdb15054 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 29 Jan 2019 13:22:08 +0000 Subject: [PATCH 064/274] Merging r352413: ------------------------------------------------------------------------ r352413 | pcc | 2019-01-28 20:29:41 +0100 (Mon, 28 Jan 2019) | 8 lines ELF: Set sh_info on RelaIplt to point to the IgotPlt output section. Previously we were setting it to the GotPlt output section, which is incorrect on ARM where this section is in .got. In static binaries this can lead to sh_info being set to -1 (because there is no .got.plt) which results in various tools rejecting the output file. Differential Revision: https://reviews.llvm.org/D57274 ------------------------------------------------------------------------ llvm-svn: 352489 --- lld/ELF/SyntheticSections.cpp | 4 +++- lld/test/ELF/arm-gnu-ifunc.s | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index f459c1b6b4792..b1a3f8bc70aec 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1513,8 +1513,10 @@ void RelocationBaseSection::finalizeContents() { else getParent()->Link = 0; - if (In.RelaIplt == this || In.RelaPlt == this) + if (In.RelaPlt == this) getParent()->Info = In.GotPlt->getParent()->SectionIndex; + if (In.RelaIplt == this) + getParent()->Info = In.IgotPlt->getParent()->SectionIndex; } RelrBaseSection::RelrBaseSection() diff --git a/lld/test/ELF/arm-gnu-ifunc.s b/lld/test/ELF/arm-gnu-ifunc.s index 8a7cb0ae237a7..92f87b5d5faef 100644 --- a/lld/test/ELF/arm-gnu-ifunc.s +++ b/lld/test/ELF/arm-gnu-ifunc.s @@ -35,6 +35,8 @@ _start: // CHECK-NEXT: Address: 0x100F4 // CHECK-NEXT: Offset: 0xF4 // CHECK-NEXT: Size: 16 +// CHECK-NEXT: Link: +// CHECK-NEXT: Info: 4 // CHECK: Name: .plt // CHECK-NEXT: Type: SHT_PROGBITS // CHECK-NEXT: Flags [ @@ -44,7 +46,8 @@ _start: // CHECK-NEXT: Address: 0x11020 // CHECK-NEXT: Offset: 0x1020 // CHECK-NEXT: Size: 32 -// CHECK: Name: .got +// CHECK: Index: 4 +// CHECK-NEXT: Name: .got // CHECK-NEXT: Type: SHT_PROGBITS // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC From 53ba53bed4e52c9b49297bce06c61e4cb4006b51 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 29 Jan 2019 13:31:43 +0000 Subject: [PATCH 065/274] Merging r352381: ------------------------------------------------------------------------ r352381 | stefan.graenitz | 2019-01-28 17:14:57 +0100 (Mon, 28 Jan 2019) | 5 lines [CMake] Quick-Fix FileCheck target does not exist when building against LLVM install-tree with COMPILER_RT_INCLUDE_TESTS=ON The issue came up during release testing for LLVM 8: https://bugs.llvm.org/show_bug.cgi?id=40443 Differential Revision: https://reviews.llvm.org/D57224 ------------------------------------------------------------------------ llvm-svn: 352490 --- compiler-rt/test/CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/compiler-rt/test/CMakeLists.txt b/compiler-rt/test/CMakeLists.txt index 2e239d54e29c8..7070fb789520c 100644 --- a/compiler-rt/test/CMakeLists.txt +++ b/compiler-rt/test/CMakeLists.txt @@ -14,10 +14,6 @@ if(COMPILER_RT_BUILD_PROFILE AND COMPILER_RT_HAS_PROFILE) list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS profile) endif() -if(COMPILER_RT_STANDALONE_BUILD) - list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS FileCheck) -endif() - # When ANDROID, we build tests with the host compiler (i.e. CMAKE_C_COMPILER), # and run tests with tools from the host toolchain. if(NOT ANDROID) From caadcebad0ee115a689c8b000e59f73d85af84c9 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 29 Jan 2019 13:32:41 +0000 Subject: [PATCH 066/274] Merging r352382: ------------------------------------------------------------------------ r352382 | stefan.graenitz | 2019-01-28 17:15:27 +0100 (Mon, 28 Jan 2019) | 5 lines [CMake] Quick-Fix targets don't exist when building against LLVM install-tree with LLDB_INCLUDE_TESTS=ON The issue came up during release testing for LLVM 8: https://bugs.llvm.org/show_bug.cgi?id=40443 Differential Revision: https://reviews.llvm.org/D57233 ------------------------------------------------------------------------ llvm-svn: 352491 --- lldb/cmake/modules/AddLLDB.cmake | 4 +++- lldb/lit/CMakeLists.txt | 11 ++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/lldb/cmake/modules/AddLLDB.cmake b/lldb/cmake/modules/AddLLDB.cmake index f7cac3dad8375..f82c11d3d317e 100644 --- a/lldb/cmake/modules/AddLLDB.cmake +++ b/lldb/cmake/modules/AddLLDB.cmake @@ -88,7 +88,9 @@ function(add_lldb_library name) # Hack: only some LLDB libraries depend on the clang autogenerated headers, # but it is simple enough to make all of LLDB depend on some of those # headers without negatively impacting much of anything. - add_dependencies(${name} clang-tablegen-targets) + if(NOT LLDB_BUILT_STANDALONE) + add_dependencies(${name} clang-tablegen-targets) + endif() # Add in any extra C++ compilation flags for this library. target_compile_options(${name} PRIVATE ${PARAM_EXTRA_CXXFLAGS}) diff --git a/lldb/lit/CMakeLists.txt b/lldb/lit/CMakeLists.txt index 1ac013b2eed30..804e950b3bb03 100644 --- a/lldb/lit/CMakeLists.txt +++ b/lldb/lit/CMakeLists.txt @@ -26,9 +26,6 @@ list(APPEND LLDB_TEST_DEPS llvm-config llvm-mc llvm-objcopy - FileCheck - count - not ) if(TARGET lld) @@ -55,6 +52,14 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/Suite/lit.site.cfg.in ${CMAKE_CURRENT_BINARY_DIR}/Suite/lit.site.cfg) +if(NOT LLDB_BUILT_STANDALONE) + list(APPEND LLDB_TEST_DEPS + FileCheck + count + not + ) +endif() + add_lit_testsuite(check-lldb-lit "Running lldb lit test suite" ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${LLDB_TEST_DEPS} From 84d97e30428dfcbdac11b909094226f6bde2d521 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 29 Jan 2019 13:46:59 +0000 Subject: [PATCH 067/274] Merging r352459: ------------------------------------------------------------------------ r352459 | mstorsjo | 2019-01-29 09:38:48 +0100 (Tue, 29 Jan 2019) | 7 lines [MinGW] Ignore the --plugin and --plugin-opt option GCC can use LLD with -fuse-ld=lld for MinGW these days, but by default these options are passed to the linker (unless -fno-lto is passed to the GCC driver). Differential Revision: https://reviews.llvm.org/D57304 ------------------------------------------------------------------------ llvm-svn: 352493 --- lld/MinGW/Options.td | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lld/MinGW/Options.td b/lld/MinGW/Options.td index 948faa6875211..0cda2447e5223 100644 --- a/lld/MinGW/Options.td +++ b/lld/MinGW/Options.td @@ -78,3 +78,9 @@ def version: F<"version">, HelpText<"Display the version number and exit">; def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias; def alias_strip_s: Flag<["-"], "s">, Alias; def alias_strip_S: Flag<["-"], "S">, Alias; + +// Ignored options +def: S<"plugin">; +def: J<"plugin=">; +def: S<"plugin-opt">; +def: J<"plugin-opt=">; From 71b117ec6f77b2da1c234572ce92e336923c3ba6 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 29 Jan 2019 14:23:17 +0000 Subject: [PATCH 068/274] Merging r352374: ------------------------------------------------------------------------ r352374 | mgorny | 2019-01-28 16:16:03 +0100 (Mon, 28 Jan 2019) | 18 lines [cmake] Fix get_llvm_lit_path() to respect LLVM_EXTERNAL_LIT always Refactor the get_llvm_lit_path() logic to respect LLVM_EXTERNAL_LIT, and require the fallback to be defined explicitly as LLVM_DEFAULT_EXTERNAL_LIT. This fixes building libcxx standalone after r346888. The old logic was using LLVM_EXTERNAL_LIT both as user-defined cache variable and an optional pre-definition of default value from caller (e.g. libcxx). It included a hack to make this work by assigning the value back and forth but it was fragile and stopped working in libcxx. The new logic is simpler and more transparent. Default value is provided in a separate variable, and used only when user-specified variable is empty (i.e. not overriden). Differential Revision: https://reviews.llvm.org/D57282 ------------------------------------------------------------------------ llvm-svn: 352495 --- llvm/cmake/modules/AddLLVM.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index 4dbc0ddaf4f01..0df6845aaa71d 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -1280,7 +1280,6 @@ function(get_llvm_lit_path base_dir file_name) cmake_parse_arguments(ARG "ALLOW_EXTERNAL" "" "" ${ARGN}) if (ARG_ALLOW_EXTERNAL) - set(LLVM_DEFAULT_EXTERNAL_LIT "${LLVM_EXTERNAL_LIT}") set (LLVM_EXTERNAL_LIT "" CACHE STRING "Command used to spawn lit") if ("${LLVM_EXTERNAL_LIT}" STREQUAL "") set(LLVM_EXTERNAL_LIT "${LLVM_DEFAULT_EXTERNAL_LIT}") From 5751c2bae7e14a3a90a38a45cb8788c91b694b6e Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 29 Jan 2019 14:23:34 +0000 Subject: [PATCH 069/274] Merging r352374: ------------------------------------------------------------------------ r352374 | mgorny | 2019-01-28 16:16:03 +0100 (Mon, 28 Jan 2019) | 18 lines [cmake] Fix get_llvm_lit_path() to respect LLVM_EXTERNAL_LIT always Refactor the get_llvm_lit_path() logic to respect LLVM_EXTERNAL_LIT, and require the fallback to be defined explicitly as LLVM_DEFAULT_EXTERNAL_LIT. This fixes building libcxx standalone after r346888. The old logic was using LLVM_EXTERNAL_LIT both as user-defined cache variable and an optional pre-definition of default value from caller (e.g. libcxx). It included a hack to make this work by assigning the value back and forth but it was fragile and stopped working in libcxx. The new logic is simpler and more transparent. Default value is provided in a separate variable, and used only when user-specified variable is empty (i.e. not overriden). Differential Revision: https://reviews.llvm.org/D57282 ------------------------------------------------------------------------ llvm-svn: 352496 --- lldb/cmake/modules/LLDBStandalone.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/cmake/modules/LLDBStandalone.cmake b/lldb/cmake/modules/LLDBStandalone.cmake index e63b2694e6a4c..a9059dd5f9eb4 100644 --- a/lldb/cmake/modules/LLDBStandalone.cmake +++ b/lldb/cmake/modules/LLDBStandalone.cmake @@ -58,7 +58,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) set(LLVM_DIR ${LLVM_OBJ_ROOT}/cmake/modules/CMakeFiles CACHE PATH "Path to LLVM build tree CMake files") set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree") set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree") - set(LLVM_EXTERNAL_LIT ${LLVM_TOOLS_BINARY_DIR}/llvm-lit CACHE PATH "Path to llvm-lit") + set(LLVM_DEFAULT_EXTERNAL_LIT ${LLVM_TOOLS_BINARY_DIR}/llvm-lit CACHE PATH "Path to llvm-lit") find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH) From 2cc5c39442b0a353dedbcbbf4318e7f89378aaa6 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 29 Jan 2019 14:23:48 +0000 Subject: [PATCH 070/274] Merging r352374: ------------------------------------------------------------------------ r352374 | mgorny | 2019-01-28 16:16:03 +0100 (Mon, 28 Jan 2019) | 18 lines [cmake] Fix get_llvm_lit_path() to respect LLVM_EXTERNAL_LIT always Refactor the get_llvm_lit_path() logic to respect LLVM_EXTERNAL_LIT, and require the fallback to be defined explicitly as LLVM_DEFAULT_EXTERNAL_LIT. This fixes building libcxx standalone after r346888. The old logic was using LLVM_EXTERNAL_LIT both as user-defined cache variable and an optional pre-definition of default value from caller (e.g. libcxx). It included a hack to make this work by assigning the value back and forth but it was fragile and stopped working in libcxx. The new logic is simpler and more transparent. Default value is provided in a separate variable, and used only when user-specified variable is empty (i.e. not overriden). Differential Revision: https://reviews.llvm.org/D57282 ------------------------------------------------------------------------ llvm-svn: 352497 --- libcxx/cmake/Modules/HandleOutOfTreeLLVM.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/cmake/Modules/HandleOutOfTreeLLVM.cmake b/libcxx/cmake/Modules/HandleOutOfTreeLLVM.cmake index 70eed1d70ba1b..11c13315585bf 100644 --- a/libcxx/cmake/Modules/HandleOutOfTreeLLVM.cmake +++ b/libcxx/cmake/Modules/HandleOutOfTreeLLVM.cmake @@ -116,7 +116,7 @@ macro(configure_out_of_tree_llvm) # Required LIT Configuration ------------------------------------------------ # Define the default arguments to use with 'lit', and an option for the user # to override. - set(LLVM_EXTERNAL_LIT "${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py") + set(LLVM_DEFAULT_EXTERNAL_LIT "${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py") set(LIT_ARGS_DEFAULT "-sv --show-xfail --show-unsupported") if (MSVC OR XCODE) set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar") From c1d99f8f81dbb804f06f77011799ca60bc61679f Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 29 Jan 2019 14:24:10 +0000 Subject: [PATCH 071/274] Merging r352374: ------------------------------------------------------------------------ r352374 | mgorny | 2019-01-28 16:16:03 +0100 (Mon, 28 Jan 2019) | 18 lines [cmake] Fix get_llvm_lit_path() to respect LLVM_EXTERNAL_LIT always Refactor the get_llvm_lit_path() logic to respect LLVM_EXTERNAL_LIT, and require the fallback to be defined explicitly as LLVM_DEFAULT_EXTERNAL_LIT. This fixes building libcxx standalone after r346888. The old logic was using LLVM_EXTERNAL_LIT both as user-defined cache variable and an optional pre-definition of default value from caller (e.g. libcxx). It included a hack to make this work by assigning the value back and forth but it was fragile and stopped working in libcxx. The new logic is simpler and more transparent. Default value is provided in a separate variable, and used only when user-specified variable is empty (i.e. not overriden). Differential Revision: https://reviews.llvm.org/D57282 ------------------------------------------------------------------------ llvm-svn: 352498 --- libcxxabi/cmake/Modules/HandleOutOfTreeLLVM.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxxabi/cmake/Modules/HandleOutOfTreeLLVM.cmake b/libcxxabi/cmake/Modules/HandleOutOfTreeLLVM.cmake index e50d0262f8041..0283a59ac1db2 100644 --- a/libcxxabi/cmake/Modules/HandleOutOfTreeLLVM.cmake +++ b/libcxxabi/cmake/Modules/HandleOutOfTreeLLVM.cmake @@ -117,7 +117,7 @@ macro(configure_out_of_tree_llvm) # Required LIT Configuration ------------------------------------------------ # Define the default arguments to use with 'lit', and an option for the user # to override. - set(LLVM_EXTERNAL_LIT "${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py") + set(LLVM_DEFAULT_EXTERNAL_LIT "${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py") set(LIT_ARGS_DEFAULT "-sv --show-xfail --show-unsupported") if (MSVC OR XCODE) set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar") From f103e430684b784f5f4ce185e3e4c7df3c5320f5 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 29 Jan 2019 21:21:14 +0000 Subject: [PATCH 072/274] Merging r351910: ------------------------------------------------------------------------ r351910 | cuviper | 2019-01-23 01:53:22 +0100 (Wed, 23 Jan 2019) | 18 lines [CodeView] Allow empty types in member functions Summary: `CodeViewDebug::lowerTypeMemberFunction` used to default to a `Void` return type if the function's type array was empty. After D54667, it started blindly indexing the 0th item for the return type, which fails in `getOperand` for empty arrays if assertions are enabled. This patch restores the `Void` return type for empty type arrays, and adds a test generated by Rust in line-only debuginfo mode. Reviewers: zturner, rnk Reviewed By: rnk Subscribers: hiraditya, JDevlieghere, llvm-commits Differential Revision: https://reviews.llvm.org/D57070 ------------------------------------------------------------------------ llvm-svn: 352546 --- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 5 +- .../DebugInfo/COFF/types-empty-member-fn.ll | 72 +++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 llvm/test/DebugInfo/COFF/types-empty-member-fn.ll diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 8cabad4ad3123..154f81f2622d4 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -1836,7 +1836,10 @@ TypeIndex CodeViewDebug::lowerTypeMemberFunction(const DISubroutineType *Ty, unsigned Index = 0; SmallVector ArgTypeIndices; - TypeIndex ReturnTypeIndex = getTypeIndex(ReturnAndArgs[Index++]); + TypeIndex ReturnTypeIndex = TypeIndex::Void(); + if (ReturnAndArgs.size() > Index) { + ReturnTypeIndex = getTypeIndex(ReturnAndArgs[Index++]); + } // If the first argument is a pointer type and this isn't a static method, // treat it as the special 'this' parameter, which is encoded separately from diff --git a/llvm/test/DebugInfo/COFF/types-empty-member-fn.ll b/llvm/test/DebugInfo/COFF/types-empty-member-fn.ll new file mode 100644 index 0000000000000..87cba9d62099e --- /dev/null +++ b/llvm/test/DebugInfo/COFF/types-empty-member-fn.ll @@ -0,0 +1,72 @@ +; RUN: llc < %s -filetype=obj | llvm-readobj - -codeview | FileCheck %s + +; ModuleID = 'foo.3a1fbbbh-cgu.0' +source_filename = "foo.3a1fbbbh-cgu.0" +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc" + +; Rust source to regenerate: +; $ cat foo.rs +; pub struct Foo; +; impl Foo { +; pub fn foo() {} +; } +; $ rustc foo.rs --crate-type lib -Cdebuginfo=1 --emit=llvm-ir + +; CHECK: CodeViewTypes [ +; CHECK: MemberFunction (0x1006) { +; CHECK-NEXT: TypeLeafKind: LF_MFUNCTION (0x1009) +; CHECK-NEXT: ReturnType: void (0x3) +; CHECK-NEXT: ClassType: foo::Foo (0x1000) +; CHECK-NEXT: ThisType: 0x0 +; CHECK-NEXT: CallingConvention: NearC (0x0) +; CHECK-NEXT: FunctionOptions [ (0x0) +; CHECK-NEXT: ] +; CHECK-NEXT: NumParameters: 0 +; CHECK-NEXT: ArgListType: () (0x1005) +; CHECK-NEXT: ThisAdjustment: 0 +; CHECK-NEXT: } +; CHECK-NEXT: MemberFuncId (0x1007) { +; CHECK-NEXT: TypeLeafKind: LF_MFUNC_ID (0x1602) +; CHECK-NEXT: ClassType: foo::Foo (0x1000) +; CHECK-NEXT: FunctionType: void foo::Foo::() (0x1006) +; CHECK-NEXT: Name: foo +; CHECK-NEXT: } +; CHECK: CodeViewDebugInfo [ +; CHECK: FunctionLineTable [ +; CHECK-NEXT: LinkageName: _ZN3foo3Foo3foo17hc557c2121772885bE +; CHECK-NEXT: Flags: 0x0 +; CHECK-NEXT: CodeSize: 0x1 +; CHECK-NEXT: FilenameSegment [ +; CHECK-NEXT: Filename: D:\rust\foo.rs (0x0) +; CHECK-NEXT: +0x0 [ +; CHECK-NEXT: LineNumberStart: 3 +; CHECK-NEXT: LineNumberEndDelta: 0 +; CHECK-NEXT: IsStatement: No +; CHECK-NEXT: ] +; CHECK-NEXT: ] +; CHECK-NEXT: ] + +; foo::Foo::foo +; Function Attrs: uwtable +define void @_ZN3foo3Foo3foo17hc557c2121772885bE() unnamed_addr #0 !dbg !5 { +start: + ret void, !dbg !10 +} + +attributes #0 = { uwtable "target-cpu"="x86-64" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} + +!0 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !1, producer: "clang LLVM (rustc version 1.33.0-nightly (8b0f0156e 2019-01-22))", isOptimized: false, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2) +!1 = !DIFile(filename: "foo.rs", directory: "D:\5Crust") +!2 = !{} +!3 = !{i32 2, !"CodeView", i32 1} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = distinct !DISubprogram(name: "foo", linkageName: "_ZN3foo3Foo3foo17hc557c2121772885bE", scope: !6, file: !1, line: 3, type: !9, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, templateParams: !2, retainedNodes: !2) +!6 = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", scope: !8, file: !7, align: 8, elements: !2, templateParams: !2, identifier: "5105d9fe1a2a3c68518268151b672274") +!7 = !DIFile(filename: "", directory: "") +!8 = !DINamespace(name: "foo", scope: null) +!9 = !DISubroutineType(types: !2) +!10 = !DILocation(line: 3, scope: !5) From 3c554e2ecf08bd7c7e3b24fb2f777f90d4475ce3 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 29 Jan 2019 21:30:42 +0000 Subject: [PATCH 073/274] Merging r352539: ------------------------------------------------------------------------ r352539 | arsenm | 2019-01-29 21:49:47 +0100 (Tue, 29 Jan 2019) | 9 lines Revert "OpenCL: Extend argument promotion rules to vector types" This reverts r348083. This was based on a misreading of the spec for printf specifiers. Also revert r343653, as without a subsequent patch, a correctly specified format for a vector will incorrectly warn. Fixes bug 40491. ------------------------------------------------------------------------ llvm-svn: 352547 --- clang/lib/Headers/opencl-c.h | 2 +- clang/lib/Sema/SemaExpr.cpp | 23 ++++--------------- clang/test/CodeGenOpenCL/printf.cl | 20 ++++++++-------- .../printf-format-string-warnings.cl | 9 ++++---- .../test/SemaOpenCL/printf-format-strings.cl | 4 ++-- 5 files changed, 22 insertions(+), 36 deletions(-) diff --git a/clang/lib/Headers/opencl-c.h b/clang/lib/Headers/opencl-c.h index 160bae807174c..3d3dfb74905f6 100644 --- a/clang/lib/Headers/opencl-c.h +++ b/clang/lib/Headers/opencl-c.h @@ -14470,7 +14470,7 @@ half16 __ovld __cnfn shuffle2(half16 x, half16 y, ushort16 mask); #if __OPENCL_C_VERSION__ >= CL_VERSION_1_2 // OpenCL v1.2 s6.12.13, v2.0 s6.13.13 - printf -int printf(__constant const char* st, ...) __attribute__((format(printf, 1, 2))); +int printf(__constant const char* st, ...); #endif // OpenCL v1.1 s6.11.3, v1.2 s6.12.14, v2.0 s6.13.14 - Image Read and Write Functions diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index d5416d4d057c7..2bcd47abe3569 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -738,33 +738,20 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) { return ExprError(); E = Res.get(); - QualType ScalarTy = Ty; - unsigned NumElts = 0; - if (const ExtVectorType *VecTy = Ty->getAs()) { - NumElts = VecTy->getNumElements(); - ScalarTy = VecTy->getElementType(); - } - // If this is a 'float' or '__fp16' (CVR qualified or typedef) // promote to double. // Note that default argument promotion applies only to float (and // half/fp16); it does not apply to _Float16. - const BuiltinType *BTy = ScalarTy->getAs(); + const BuiltinType *BTy = Ty->getAs(); if (BTy && (BTy->getKind() == BuiltinType::Half || BTy->getKind() == BuiltinType::Float)) { if (getLangOpts().OpenCL && !getOpenCLOptions().isEnabled("cl_khr_fp64")) { - if (BTy->getKind() == BuiltinType::Half) { - QualType Ty = Context.FloatTy; - if (NumElts != 0) - Ty = Context.getExtVectorType(Ty, NumElts); - E = ImpCastExprToType(E, Ty, CK_FloatingCast).get(); - } + if (BTy->getKind() == BuiltinType::Half) { + E = ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast).get(); + } } else { - QualType Ty = Context.DoubleTy; - if (NumElts != 0) - Ty = Context.getExtVectorType(Ty, NumElts); - E = ImpCastExprToType(E, Ty, CK_FloatingCast).get(); + E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get(); } } diff --git a/clang/test/CodeGenOpenCL/printf.cl b/clang/test/CodeGenOpenCL/printf.cl index 346f6c35bae46..fc139d776db6e 100644 --- a/clang/test/CodeGenOpenCL/printf.cl +++ b/clang/test/CodeGenOpenCL/printf.cl @@ -12,28 +12,26 @@ int printf(__constant const char* st, ...) __attribute__((format(printf, 1, 2))) // ALL-LABEL: @test_printf_float2( -// FP64: %conv = fpext <2 x float> %0 to <2 x double> -// FP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x double> %conv) +// FP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([7 x i8], [7 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x float> %0) -// NOFP64: call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x float> %0) + +// NOFP64: call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([7 x i8], [7 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x float> %0) kernel void test_printf_float2(float2 arg) { - printf("%v2f", arg); + printf("%v2hlf", arg); } // ALL-LABEL: @test_printf_half2( -// FP64: %conv = fpext <2 x half> %0 to <2 x double> -// FP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x double> %conv) #2 +// FP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([6 x i8], [6 x i8] addrspace(2)* @.str.1, i32 0, i32 0), <2 x half> %0) -// NOFP64: %conv = fpext <2 x half> %0 to <2 x float> -// NOFP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x float> %conv) #2 +// NOFP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([6 x i8], [6 x i8] addrspace(2)* @.str.1, i32 0, i32 0), <2 x half> %0) kernel void test_printf_half2(half2 arg) { - printf("%v2f", arg); + printf("%v2hf", arg); } #ifdef cl_khr_fp64 // FP64-LABEL: @test_printf_double2( -// FP64: call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x double> %0) #2 +// FP64: call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([6 x i8], [6 x i8] addrspace(2)* @.str.2, i32 0, i32 0), <2 x double> %0) kernel void test_printf_double2(double2 arg) { - printf("%v2f", arg); + printf("%v2lf", arg); } #endif diff --git a/clang/test/SemaOpenCL/printf-format-string-warnings.cl b/clang/test/SemaOpenCL/printf-format-string-warnings.cl index 2b9c5cc3f319f..39b859402702f 100644 --- a/clang/test/SemaOpenCL/printf-format-string-warnings.cl +++ b/clang/test/SemaOpenCL/printf-format-string-warnings.cl @@ -1,13 +1,14 @@ // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 -finclude-default-header -// Make sure warnings are produced based on printf format strings. +// FIXME: Make sure warnings are produced based on printf format strings. +// expected-no-diagnostics kernel void format_string_warnings(__constant char* arg) { - printf("%d", arg); // expected-warning {{format specifies type 'int' but the argument has type '__constant char *'}} + printf("%d", arg); - printf("not enough arguments %d %d", 4); // expected-warning {{more '%' conversions than data arguments}} + printf("not enough arguments %d %d", 4); - printf("too many arguments", 4); // expected-warning {{data argument not used by format string}} + printf("too many arguments", 4); } diff --git a/clang/test/SemaOpenCL/printf-format-strings.cl b/clang/test/SemaOpenCL/printf-format-strings.cl index 079a83495685e..212e1f8981cbe 100644 --- a/clang/test/SemaOpenCL/printf-format-strings.cl +++ b/clang/test/SemaOpenCL/printf-format-strings.cl @@ -13,10 +13,10 @@ int printf(__constant const char* st, ...) __attribute__((format(printf, 1, 2))) kernel void format_v4f32(float4 arg) { #ifdef cl_khr_fp64 - printf("%v4f\n", arg); + printf("%v4f\n", arg); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}} // Precision modifier - printf("%.2v4f\n", arg); + printf("%.2v4f\n", arg); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}} #else // FIXME: These should not warn, and the type should be expected to be float. printf("%v4f\n", arg); // expected-warning {{double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}} From 88481d545c3e9ac4da0ffec17660200055d31894 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 30 Jan 2019 19:13:49 +0000 Subject: [PATCH 074/274] Merging r352610: ------------------------------------------------------------------------ r352610 | mgorny | 2019-01-30 09:20:24 +0100 (Wed, 30 Jan 2019) | 9 lines [clang] [Driver] [NetBSD] Append -rpath for shared compiler-rt runtimes Append appropriate -rpath when using shared compiler-rt runtimes, e.g. '-fsanitize=address -shared-libasan'. There's already a similar logic in CommonArgs.cpp but it uses non-standard arch-suffixed installation directory while we want our driver to work with standard installation paths. Differential Revision: https://reviews.llvm.org/D57303 ------------------------------------------------------------------------ llvm-svn: 352650 --- clang/lib/Driver/ToolChains/NetBSD.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clang/lib/Driver/ToolChains/NetBSD.cpp b/clang/lib/Driver/ToolChains/NetBSD.cpp index b1321cacaf7a3..c1eae5b05acec 100644 --- a/clang/lib/Driver/ToolChains/NetBSD.cpp +++ b/clang/lib/Driver/ToolChains/NetBSD.cpp @@ -256,6 +256,13 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs); AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); + const SanitizerArgs &SanArgs = ToolChain.getSanitizerArgs(); + if (SanArgs.needsSharedRt()) { + CmdArgs.push_back("-rpath"); + CmdArgs.push_back(Args.MakeArgString( + ToolChain.getCompilerRTPath().c_str())); + } + unsigned Major, Minor, Micro; ToolChain.getTriple().getOSVersion(Major, Minor, Micro); bool useLibgcc = true; From dbbe63346ce6ac0c51ee6ba756a75f0a73e9109f Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Wed, 30 Jan 2019 21:18:03 +0000 Subject: [PATCH 075/274] [docs][mips] Add MIPS specific release notes for LLD 8.0 Differential Revision: http://reviews.llvm.org/D57459 llvm-svn: 352674 --- lld/docs/ReleaseNotes.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst index a146bddd543af..c02cc586c795e 100644 --- a/lld/docs/ReleaseNotes.rst +++ b/lld/docs/ReleaseNotes.rst @@ -40,6 +40,9 @@ ELF Improvements * The following flags have been added: ``-z interpose``, ``-z global`` +* lld now uses the ``sigrie`` instruction as a trap instruction for + MIPS targets. + COFF Improvements ----------------- From dfc033d9a486a8c1bfd54f829112df65a53d8053 Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Wed, 30 Jan 2019 21:19:40 +0000 Subject: [PATCH 076/274] [docs][mips] Clang 8.0 Release notes MIPS specific part of Clang 8.0 Release notes. Feel free to add more notes if I miss something. Differential Revision: http://reviews.llvm.org/D57458 llvm-svn: 352675 --- clang/docs/ReleaseNotes.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 28be16677ecee..50bf636a51f43 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -127,6 +127,10 @@ Non-comprehensive list of changes in this release manually and rely on the old behaviour you will need to add appropriate compiler flags for finding the corresponding libc++ include directory. +- The integrated assembler is used now by default for all MIPS targets. + +- Improved support for MIPS N32 ABI and MIPS R6 target triples. + New Compiler Flags ------------------ @@ -139,6 +143,10 @@ New Compiler Flags - When using a custom stack alignment, the ``stackrealign`` attribute is now implicitly set on the main function. +- Emission of ``R_MIPS_JALR`` and ``R_MICROMIPS_JALR`` relocations can now + be controlled by the ``-mrelax-pic-calls`` and ``-mno-relax-pic-calls`` + options. + - ... Deprecated Compiler Flags From 8a11e14ef3568455b0e61467a8d578bbb760d3bb Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Wed, 30 Jan 2019 22:45:12 +0000 Subject: [PATCH 077/274] [docs][mips] 8.0 Release notes MIPS specific part of LLVM 8.0 Release notes. Differential Revision: http://reviews.llvm.org/D57457 llvm-svn: 352682 --- llvm/docs/ReleaseNotes.rst | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index cb80459546f54..82e4d56d48f46 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -52,6 +52,8 @@ Non-comprehensive list of changes in this release from a dll are accessed via a stub, to allow the linker to convert it to a dllimport if needed. +* Added support for labels as offsets in ``.reloc`` directive. + .. NOTE If you would like to document a larger change, then you can add a subsection about it right here. You can copy the following boilerplate @@ -82,8 +84,23 @@ Changes to the ARM Backend Changes to the MIPS Target -------------------------- - During this release ... +* Improved support of GlobalISel instruction selection framework. + +* Implemented emission of ``R_MIPS_JALR`` and ``R_MICROMIPS_JALR`` + relocations. These relocations provide hints to a linker for optimization + of jumps to protected symbols. + +* ORC JIT has been supported for MIPS and MIPS64 architectures. + +* Assembler now suggests alternative MIPS instruction mnemonics when + an invalid one is specified. + +* Improved support for MIPS N32 ABI. + +* Added new instructions (``pll.ps``, ``plu.ps``, ``cvt.s.pu``, + ``cvt.s.pl``, ``cvt.ps``, ``sigrie``). +* Numerous bug fixes and code cleanups. Changes to the PowerPC Target ----------------------------- From 6dcd982f4bcb32c9b0c62173ef5460079d58e8b1 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 1 Feb 2019 10:45:20 +0000 Subject: [PATCH 078/274] Merging r352407: ------------------------------------------------------------------------ r352407 | ruiu | 2019-01-28 20:11:52 +0100 (Mon, 28 Jan 2019) | 1 line Refactoring. NFC. ------------------------------------------------------------------------ llvm-svn: 352850 --- lld/ELF/ScriptParser.cpp | 60 ++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 36 deletions(-) diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index eee3f0e330cc3..84571db25714a 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -385,39 +385,23 @@ void ScriptParser::readOutputArch() { skip(); } -std::tuple ScriptParser::readBfdName() { - StringRef S = unquote(next()); - if (S == "elf32-i386") - return std::make_tuple(ELF32LEKind, EM_386, false); - if (S == "elf32-iamcu") - return std::make_tuple(ELF32LEKind, EM_IAMCU, false); - if (S == "elf32-littlearm") - return std::make_tuple(ELF32LEKind, EM_ARM, false); - if (S == "elf32-x86-64") - return std::make_tuple(ELF32LEKind, EM_X86_64, false); - if (S == "elf64-littleaarch64") - return std::make_tuple(ELF64LEKind, EM_AARCH64, false); - if (S == "elf64-powerpc") - return std::make_tuple(ELF64BEKind, EM_PPC64, false); - if (S == "elf64-powerpcle") - return std::make_tuple(ELF64LEKind, EM_PPC64, false); - if (S == "elf64-x86-64") - return std::make_tuple(ELF64LEKind, EM_X86_64, false); - if (S == "elf32-tradbigmips") - return std::make_tuple(ELF32BEKind, EM_MIPS, false); - if (S == "elf32-ntradbigmips") - return std::make_tuple(ELF32BEKind, EM_MIPS, true); - if (S == "elf32-tradlittlemips") - return std::make_tuple(ELF32LEKind, EM_MIPS, false); - if (S == "elf32-ntradlittlemips") - return std::make_tuple(ELF32LEKind, EM_MIPS, true); - if (S == "elf64-tradbigmips") - return std::make_tuple(ELF64BEKind, EM_MIPS, false); - if (S == "elf64-tradlittlemips") - return std::make_tuple(ELF64LEKind, EM_MIPS, false); - - setError("unknown output format name: " + S); - return std::make_tuple(ELFNoneKind, EM_NONE, false); +static std::tuple parseBfdName(StringRef S) { + return StringSwitch>(S) + .Case("elf32-i386", {ELF32LEKind, EM_386}) + .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU}) + .Case("elf32-littlearm", {ELF32LEKind, EM_ARM}) + .Case("elf32-x86-64", {ELF32LEKind, EM_X86_64}) + .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64}) + .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64}) + .Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64}) + .Case("elf64-x86-64", {ELF64LEKind, EM_X86_64}) + .Case("elf32-tradbigmips", {ELF32BEKind, EM_MIPS}) + .Case("elf32-ntradbigmips", {ELF32BEKind, EM_MIPS}) + .Case("elf32-tradlittlemips", {ELF32LEKind, EM_MIPS}) + .Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS}) + .Case("elf64-tradbigmips", {ELF64BEKind, EM_MIPS}) + .Case("elf64-tradlittlemips", {ELF64LEKind, EM_MIPS}) + .Default({ELFNoneKind, EM_NONE}); } // Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(bfdname, big, little). @@ -425,9 +409,13 @@ std::tuple ScriptParser::readBfdName() { void ScriptParser::readOutputFormat() { expect("("); - std::tuple BfdTuple = readBfdName(); - if (Config->EKind == ELFNoneKind) - std::tie(Config->EKind, Config->EMachine, Config->MipsN32Abi) = BfdTuple; + StringRef S = unquote(next()); + + std::tie(Config->EKind, Config->EMachine) = parseBfdName(S); + if (Config->EMachine == EM_NONE) + setError("unknown output format name: " + S); + if (S == "elf32-ntradlittlemips" || S == "elf32-ntradbigmips") + Config->MipsN32Abi = true; if (consume(")")) return; From 9f0ae69afedb9562c24a8a92da347e843057c0d4 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 1 Feb 2019 10:46:13 +0000 Subject: [PATCH 079/274] Merging r352435: ------------------------------------------------------------------------ r352435 | ruiu | 2019-01-28 22:45:50 +0100 (Mon, 28 Jan 2019) | 1 line Attempt to fix build failure with GCC 5.4. ------------------------------------------------------------------------ llvm-svn: 352851 --- lld/ELF/ScriptParser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 84571db25714a..9e59fe7c6776f 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -385,8 +385,8 @@ void ScriptParser::readOutputArch() { skip(); } -static std::tuple parseBfdName(StringRef S) { - return StringSwitch>(S) +static std::pair parseBfdName(StringRef S) { + return StringSwitch>(S) .Case("elf32-i386", {ELF32LEKind, EM_386}) .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU}) .Case("elf32-littlearm", {ELF32LEKind, EM_ARM}) From 15decd1d488aac686faaa4afbb98254e1152a212 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 1 Feb 2019 10:47:13 +0000 Subject: [PATCH 080/274] Merging r352482: ------------------------------------------------------------------------ r352482 | grimar | 2019-01-29 12:46:00 +0100 (Tue, 29 Jan 2019) | 3 lines [ELF] - Remove dead `readBfdName` declaration. NFC. `readBfdName` was removed recently. ------------------------------------------------------------------------ llvm-svn: 352852 --- lld/ELF/ScriptParser.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 9e59fe7c6776f..91c8aac8d8dc5 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -94,7 +94,6 @@ class ScriptParser final : ScriptLexer { SortSectionPolicy readSortKind(); SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); SymbolAssignment *readAssignment(StringRef Tok); - std::tuple readBfdName(); void readSort(); Expr readAssert(); Expr readConstant(); From 538ee7319dead9662507c59d87384be178c30c9e Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 1 Feb 2019 10:48:08 +0000 Subject: [PATCH 081/274] Merging r352606: ------------------------------------------------------------------------ r352606 | dim | 2019-01-30 07:31:52 +0100 (Wed, 30 Jan 2019) | 27 lines Recognize FreeBSD specific BFD names in OUTPUT_FORMAT Summary: After rLLD344952 ("Add OUTPUT_FORMAT linker script directive support"), using BFD names such as `elf64-x86-64-freebsd` the `OUTPUT_FORMAT` linker script command does not work anymore, resulting in errors like: ``` ld: error: /home/dim/src/clang800-import/stand/efi/loader/arch/amd64/ldscript.amd64:2: unknown output format name: elf64-x86-64-freebsd >>> OUTPUT_FORMAT("elf64-x86-64-freebsd", "elf64-x86-64-freebsd", "elf64-x86-64-freebsd") >>> ^ ``` To fix this, recognize a `-freebsd` suffix in BFD names, and also set `Configuration::OSABI` to `ELFOSABI_FREEBSD` for those cases. Add and/or update several test cases to check for the correct results of these new `OUTPUT_FORMAT` arguments. Reviewers: ruiu, atanasyan, grimar, hokein, emaste, espindola Reviewed By: ruiu Subscribers: nemanjai, javed.absar, arichardson, krytarowski, kristof.beyls, kbarton, llvm-commits Differential Revision: https://reviews.llvm.org/D57283 ------------------------------------------------------------------------ llvm-svn: 352853 --- lld/ELF/ScriptParser.cpp | 8 ++++++-- lld/test/ELF/emulation-aarch64.s | 23 +++++++++++++++++++++++ lld/test/ELF/emulation-ppc.s | 32 ++++++++++++++++++++++++++++++++ lld/test/ELF/emulation-x86.s | 10 ++++++++-- 4 files changed, 69 insertions(+), 4 deletions(-) diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 91c8aac8d8dc5..7cce94659c9e9 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -390,6 +390,7 @@ static std::pair parseBfdName(StringRef S) { .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU}) .Case("elf32-littlearm", {ELF32LEKind, EM_ARM}) .Case("elf32-x86-64", {ELF32LEKind, EM_X86_64}) + .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64}) .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64}) .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64}) .Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64}) @@ -408,11 +409,14 @@ static std::pair parseBfdName(StringRef S) { void ScriptParser::readOutputFormat() { expect("("); - StringRef S = unquote(next()); + StringRef Name = unquote(next()); + StringRef S = Name; + if (S.consume_back("-freebsd")) + Config->OSABI = ELFOSABI_FREEBSD; std::tie(Config->EKind, Config->EMachine) = parseBfdName(S); if (Config->EMachine == EM_NONE) - setError("unknown output format name: " + S); + setError("unknown output format name: " + Name); if (S == "elf32-ntradlittlemips" || S == "elf32-ntradbigmips") Config->MipsN32Abi = true; diff --git a/lld/test/ELF/emulation-aarch64.s b/lld/test/ELF/emulation-aarch64.s index b9a6428fa953e..c0edc9a69d36d 100644 --- a/lld/test/ELF/emulation-aarch64.s +++ b/lld/test/ELF/emulation-aarch64.s @@ -30,5 +30,28 @@ # AARCH64-NEXT: Flags [ (0x0) # AARCH64-NEXT: ] +# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %taarch64fbsd +# RUN: echo 'OUTPUT_FORMAT(elf64-aarch64-freebsd)' > %taarch64fbsd.script +# RUN: ld.lld %taarch64fbsd.script %taarch64fbsd -o %t2aarch64fbsd +# RUN: llvm-readobj -file-headers %t2aarch64fbsd | FileCheck --check-prefix=AARCH64-FBSD %s +# AARCH64-FBSD: ElfHeader { +# AARCH64-FBSD-NEXT: Ident { +# AARCH64-FBSD-NEXT: Magic: (7F 45 4C 46) +# AARCH64-FBSD-NEXT: Class: 64-bit (0x2) +# AARCH64-FBSD-NEXT: DataEncoding: LittleEndian (0x1) +# AARCH64-FBSD-NEXT: FileVersion: 1 +# AARCH64-FBSD-NEXT: OS/ABI: FreeBSD (0x9) +# AARCH64-FBSD-NEXT: ABIVersion: 0 +# AARCH64-FBSD-NEXT: Unused: (00 00 00 00 00 00 00) +# AARCH64-FBSD-NEXT: } +# AARCH64-FBSD-NEXT: Type: Executable (0x2) +# AARCH64-FBSD-NEXT: Machine: EM_AARCH64 (0xB7) +# AARCH64-FBSD-NEXT: Version: 1 +# AARCH64-FBSD-NEXT: Entry: +# AARCH64-FBSD-NEXT: ProgramHeaderOffset: 0x40 +# AARCH64-FBSD-NEXT: SectionHeaderOffset: +# AARCH64-FBSD-NEXT: Flags [ (0x0) +# AARCH64-FBSD-NEXT: ] + .globl _start _start: diff --git a/lld/test/ELF/emulation-ppc.s b/lld/test/ELF/emulation-ppc.s index 12e84782252fd..843e77604779b 100644 --- a/lld/test/ELF/emulation-ppc.s +++ b/lld/test/ELF/emulation-ppc.s @@ -35,6 +35,38 @@ # PPC64-NEXT: StringTableSectionIndex: # PPC64-NEXT: } +# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-freebsd %s -o %tppc64fbsd +# RUN: echo 'OUTPUT_FORMAT(elf64-powerpc-freebsd)' > %tppc64fbsd.script +# RUN: ld.lld %tppc64fbsd.script %tppc64fbsd -o %t2ppc64fbsd +# RUN: llvm-readobj -file-headers %t2ppc64fbsd | FileCheck --check-prefix=PPC64-FBSD %s + +# PPC64-FBSD: ElfHeader { +# PPC64-FBSD-NEXT: Ident { +# PPC64-FBSD-NEXT: Magic: (7F 45 4C 46) +# PPC64-FBSD-NEXT: Class: 64-bit (0x2) +# PPC64-FBSD-NEXT: DataEncoding: BigEndian (0x2) +# PPC64-FBSD-NEXT: FileVersion: 1 +# PPC64-FBSD-NEXT: OS/ABI: FreeBSD (0x9) +# PPC64-FBSD-NEXT: ABIVersion: 0 +# PPC64-FBSD-NEXT: Unused: (00 00 00 00 00 00 00) +# PPC64-FBSD-NEXT: } +# PPC64-FBSD-NEXT: Type: Executable (0x2) +# PPC64-FBSD-NEXT: Machine: EM_PPC64 (0x15) +# PPC64-FBSD-NEXT: Version: 1 +# PPC64-FBSD-NEXT: Entry: +# PPC64-FBSD-NEXT: ProgramHeaderOffset: 0x40 +# PPC64-FBSD-NEXT: SectionHeaderOffset: +# PPC64-FBSD-NEXT: Flags [ (0x2) +# PPC64-FBSD-NEXT: 0x2 +# PPC64-FBSD-NEXT: ] +# PPC64-FBSD-NEXT: HeaderSize: 64 +# PPC64-FBSD-NEXT: ProgramHeaderEntrySize: 56 +# PPC64-FBSD-NEXT: ProgramHeaderCount: +# PPC64-FBSD-NEXT: SectionHeaderEntrySize: 64 +# PPC64-FBSD-NEXT: SectionHeaderCount: +# PPC64-FBSD-NEXT: StringTableSectionIndex: +# PPC64-FBSD-NEXT: } + # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %tppc64le # RUN: ld.lld -m elf64lppc %tppc64le -o %t2ppc64le # RUN: llvm-readobj -file-headers %t2ppc64le | FileCheck --check-prefix=PPC64LE %s diff --git a/lld/test/ELF/emulation-x86.s b/lld/test/ELF/emulation-x86.s index 65d807c67f2f0..02b8943566928 100644 --- a/lld/test/ELF/emulation-x86.s +++ b/lld/test/ELF/emulation-x86.s @@ -7,6 +7,9 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.sysv # RUN: ld.lld -m elf_amd64_fbsd %t.sysv -o %t.freebsd # RUN: llvm-readobj -file-headers %t.freebsd | FileCheck --check-prefix=AMD64 %s +# RUN: echo 'OUTPUT_FORMAT(elf64-x86-64-freebsd)' > %t4x64.script +# RUN: ld.lld %t4x64.script %tx64 -o %t4x64 +# RUN: llvm-readobj -file-headers %t4x64 | FileCheck --check-prefix=AMD64 %s # AMD64: ElfHeader { # AMD64-NEXT: Ident { # AMD64-NEXT: Magic: (7F 45 4C 46) @@ -137,10 +140,13 @@ # X86-NEXT: } # RUN: llvm-mc -filetype=obj -triple=i686-unknown-freebsd %s -o %tx86fbsd -# RUN: ld.lld -m elf_i386_fbsd %tx86fbsd -o %t2x86_fbsd -# RUN: llvm-readobj -file-headers %t2x86_fbsd | FileCheck --check-prefix=X86FBSD %s +# RUN: ld.lld -m elf_i386_fbsd %tx86fbsd -o %t2x86fbsd +# RUN: llvm-readobj -file-headers %t2x86fbsd | FileCheck --check-prefix=X86FBSD %s # RUN: ld.lld %tx86fbsd -o %t3x86fbsd # RUN: llvm-readobj -file-headers %t3x86fbsd | FileCheck --check-prefix=X86FBSD %s +# RUN: echo 'OUTPUT_FORMAT(elf32-i386-freebsd)' > %t4x86fbsd.script +# RUN: ld.lld %t4x86fbsd.script %tx86fbsd -o %t4x86fbsd +# RUN: llvm-readobj -file-headers %t4x86fbsd | FileCheck --check-prefix=X86FBSD %s # X86FBSD: ElfHeader { # X86FBSD-NEXT: Ident { # X86FBSD-NEXT: Magic: (7F 45 4C 46) From 2a08347d7fa20368c2d86a3fd56ad9398fad944b Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 1 Feb 2019 10:50:43 +0000 Subject: [PATCH 082/274] Merging r352672: ------------------------------------------------------------------------ r352672 | epilk | 2019-01-30 22:14:08 +0100 (Wed, 30 Jan 2019) | 4 lines Don't define __has_feature(objc_fixed_enum) in non-objc mode This is only a formal language feature in ObjC, otherwise its just an extension. Making this change was also an ABI break. ------------------------------------------------------------------------ llvm-svn: 352854 --- clang/include/clang/Basic/Features.def | 2 +- clang/test/SemaObjC/enum-fixed-type.m | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 05464ed85f136..8b3b59b51c542 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -96,7 +96,7 @@ FEATURE(objc_arc, LangOpts.ObjCAutoRefCount) FEATURE(objc_arc_fields, true) FEATURE(objc_arc_weak, LangOpts.ObjCWeak) FEATURE(objc_default_synthesize_properties, LangOpts.ObjC) -FEATURE(objc_fixed_enum, true) +FEATURE(objc_fixed_enum, LangOpts.ObjC) FEATURE(objc_instancetype, LangOpts.ObjC) FEATURE(objc_kindof, LangOpts.ObjC) FEATURE(objc_modules, LangOpts.ObjC && LangOpts.Modules) diff --git a/clang/test/SemaObjC/enum-fixed-type.m b/clang/test/SemaObjC/enum-fixed-type.m index 88c895a33982d..b4135a555a23e 100644 --- a/clang/test/SemaObjC/enum-fixed-type.m +++ b/clang/test/SemaObjC/enum-fixed-type.m @@ -1,9 +1,11 @@ // RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s // RUN: %clang_cc1 -fsyntax-only -verify -xc %s +#ifdef __OBJC__ #if !__has_feature(objc_fixed_enum) # error Enumerations with a fixed underlying type are not supported #endif +#endif #if !__has_extension(cxx_fixed_enum) # error Enumerations with a fixed underlying type are not supported From e26a2f2368bf6844ab6ce3ba83ed6a34b15969e4 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 1 Feb 2019 10:57:17 +0000 Subject: [PATCH 083/274] Merging r352822: ------------------------------------------------------------------------ r352822 | ahatanak | 2019-02-01 01:12:06 +0100 (Fri, 01 Feb 2019) | 8 lines Revert "[Sema] Make canPassInRegisters return true if the CXXRecordDecl passed" This reverts commit r350920 as it is not clear whether we should force a class to be returned in registers when copy and move constructors are both deleted. For more background, see the following discussion: http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20190128/259907.html ------------------------------------------------------------------------ llvm-svn: 352855 --- clang/lib/Sema/SemaDeclCXX.cpp | 3 --- clang/test/CodeGenCXX/trivial_abi.cpp | 19 ++----------------- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index e66ee43307036..8b3556f715bfd 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -5890,9 +5890,6 @@ static bool canPassInRegisters(Sema &S, CXXRecordDecl *D, if (D->isDependentType() || D->isInvalidDecl()) return false; - if (D->hasAttr()) - return true; - // Clang <= 4 used the pre-C++11 rule, which ignores move operations. // The PS4 platform ABI follows the behavior of Clang 3.2. if (CCK == TargetInfo::CCK_ClangABI4OrPS4) diff --git a/clang/test/CodeGenCXX/trivial_abi.cpp b/clang/test/CodeGenCXX/trivial_abi.cpp index e37c8ff615a26..2cf07b22581a2 100644 --- a/clang/test/CodeGenCXX/trivial_abi.cpp +++ b/clang/test/CodeGenCXX/trivial_abi.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++17 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++17 -fcxx-exceptions -fexceptions -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fcxx-exceptions -fexceptions -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s // CHECK: %[[STRUCT_SMALL:.*]] = type { i32* } // CHECK: %[[STRUCT_LARGE:.*]] = type { i32*, [128 x i32] } @@ -43,13 +43,6 @@ struct HasNonTrivial { NonTrivial m; }; -struct __attribute__((trivial_abi)) CopyMoveDeleted { - CopyMoveDeleted(int); - CopyMoveDeleted(const CopyMoveDeleted &) = delete; - CopyMoveDeleted(CopyMoveDeleted &&) = delete; - int a; -}; - // CHECK: define void @_Z14testParamSmall5Small(i64 %[[A_COERCE:.*]]) // CHECK: %[[A:.*]] = alloca %[[STRUCT_SMALL]], align 8 // CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[A]], i32 0, i32 0 @@ -244,11 +237,3 @@ void calleeExceptionLarge(Large, Large); void testExceptionLarge() { calleeExceptionLarge(Large(), Large()); } - -// A class with deleted copy and move constructors can still be passed or -// returned in registers if the class is annotated with trivial_abi. - -// CHECK: define i64 @_Z19testCopyMoveDeletedi(i32 % -CopyMoveDeleted testCopyMoveDeleted(int a) { - return a; -} From d4c2ff4db45544c93026eb475c74783ecf92ce8f Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 1 Feb 2019 11:01:12 +0000 Subject: [PATCH 084/274] Merging r352770: ------------------------------------------------------------------------ r352770 | tejohnson | 2019-01-31 18:18:11 +0100 (Thu, 31 Jan 2019) | 3 lines Recommit "[ThinLTO] Rename COMDATs for COFF when promoting/renaming COMDAT leader" Recommit of r352763 with fix for use after free. ------------------------------------------------------------------------ llvm-svn: 352856 --- .../Transforms/Utils/FunctionImportUtils.h | 5 +++ .../Transforms/Utils/FunctionImportUtils.cpp | 18 +++++++++++ .../FunctionImport/Inputs/comdat.ll | 10 ++++++ llvm/test/Transforms/FunctionImport/comdat.ll | 32 +++++++++++++++++++ 4 files changed, 65 insertions(+) create mode 100644 llvm/test/Transforms/FunctionImport/Inputs/comdat.ll create mode 100644 llvm/test/Transforms/FunctionImport/comdat.ll diff --git a/llvm/include/llvm/Transforms/Utils/FunctionImportUtils.h b/llvm/include/llvm/Transforms/Utils/FunctionImportUtils.h index e24398b90012b..fe13559768189 100644 --- a/llvm/include/llvm/Transforms/Utils/FunctionImportUtils.h +++ b/llvm/include/llvm/Transforms/Utils/FunctionImportUtils.h @@ -44,6 +44,11 @@ class FunctionImportGlobalProcessing { /// to promote any non-renamable values. SmallPtrSet Used; + /// Keep track of any COMDATs that require renaming (because COMDAT + /// leader was promoted and renamed). Maps from original COMDAT to one + /// with new name. + DenseMap RenamedComdats; + /// Check if we should promote the given local value to global scope. bool shouldPromoteLocalToGlobal(const GlobalValue *SGV); diff --git a/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp b/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp index a9772e31da509..81d63ee80394e 100644 --- a/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp +++ b/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp @@ -249,6 +249,8 @@ void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) { bool DoPromote = false; if (GV.hasLocalLinkage() && ((DoPromote = shouldPromoteLocalToGlobal(&GV)) || isPerformingImport())) { + // Save the original name string before we rename GV below. + auto Name = GV.getName().str(); // Once we change the name or linkage it is difficult to determine // again whether we should promote since shouldPromoteLocalToGlobal needs // to locate the summary (based on GUID from name and linkage). Therefore, @@ -257,6 +259,12 @@ void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) { GV.setLinkage(getLinkage(&GV, DoPromote)); if (!GV.hasLocalLinkage()) GV.setVisibility(GlobalValue::HiddenVisibility); + + // If we are renaming a COMDAT leader, ensure that we record the COMDAT + // for later renaming as well. This is required for COFF. + if (const auto *C = GV.getComdat()) + if (C->getName() == Name) + RenamedComdats.try_emplace(C, M.getOrInsertComdat(GV.getName())); } else GV.setLinkage(getLinkage(&GV, /* DoPromote */ false)); @@ -281,6 +289,16 @@ void FunctionImportGlobalProcessing::processGlobalsForThinLTO() { processGlobalForThinLTO(SF); for (GlobalAlias &GA : M.aliases()) processGlobalForThinLTO(GA); + + // Replace any COMDATS that required renaming (because the COMDAT leader was + // promoted and renamed). + if (!RenamedComdats.empty()) + for (auto &GO : M.global_objects()) + if (auto *C = GO.getComdat()) { + auto Replacement = RenamedComdats.find(C); + if (Replacement != RenamedComdats.end()) + GO.setComdat(Replacement->second); + } } bool FunctionImportGlobalProcessing::run() { diff --git a/llvm/test/Transforms/FunctionImport/Inputs/comdat.ll b/llvm/test/Transforms/FunctionImport/Inputs/comdat.ll new file mode 100644 index 0000000000000..1df6f25351e58 --- /dev/null +++ b/llvm/test/Transforms/FunctionImport/Inputs/comdat.ll @@ -0,0 +1,10 @@ +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc19.0.24215" + +define void @main() { +entry: + call i8* @lwt_fun() + ret void +} + +declare i8* @lwt_fun() diff --git a/llvm/test/Transforms/FunctionImport/comdat.ll b/llvm/test/Transforms/FunctionImport/comdat.ll new file mode 100644 index 0000000000000..29e8cb538ab66 --- /dev/null +++ b/llvm/test/Transforms/FunctionImport/comdat.ll @@ -0,0 +1,32 @@ +; Test to ensure that comdat is renamed consistently when comdat leader is +; promoted and renamed due to an import. Required by COFF. + +; REQUIRES: x86-registered-target + +; RUN: opt -thinlto-bc -o %t1.bc %s +; RUN: opt -thinlto-bc -o %t2.bc %S/Inputs/comdat.ll +; RUN: llvm-lto2 run -save-temps -o %t3 %t1.bc %t2.bc \ +; RUN: -r %t1.bc,lwt_fun,plx \ +; RUN: -r %t2.bc,main,plx \ +; RUN: -r %t2.bc,lwt_fun, +; RUN: llvm-dis -o - %t3.1.3.import.bc | FileCheck %s + +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc19.0.24215" + +; CHECK: $lwt.llvm.[[HASH:[0-9]+]] = comdat any +$lwt = comdat any + +; CHECK: @lwt_aliasee = private unnamed_addr global {{.*}}, comdat($lwt.llvm.[[HASH]]) +@lwt_aliasee = private unnamed_addr global [1 x i8*] [i8* null], comdat($lwt) + +; CHECK: @lwt.llvm.[[HASH]] = hidden unnamed_addr alias +@lwt = internal unnamed_addr alias [1 x i8*], [1 x i8*]* @lwt_aliasee + +; Below function should get imported into other module, resulting in @lwt being +; promoted and renamed. +define i8* @lwt_fun() { + %1 = getelementptr inbounds [1 x i8*], [1 x i8*]* @lwt, i32 0, i32 0 + %2 = load i8*, i8** %1 + ret i8* %2 +} From c081a5fb340214719bb91bae196c2850181ca358 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 1 Feb 2019 11:12:06 +0000 Subject: [PATCH 085/274] Merging r352156: ------------------------------------------------------------------------ r352156 | phosek | 2019-01-25 03:42:30 +0100 (Fri, 25 Jan 2019) | 12 lines [AArch64] Make the test for rsr and rsr64 stricter ACLE specifies that return type for rsr and rsr64 is uint32_t and uint64_t respectively. D56852 change the return type of rsr64 from unsigned long to unsigned long long which at least on Linux doesn't match uint64_t, but the test isn't strict enough to detect that because compiler implicitly converts unsigned long long to uint64_t, but it breaks other uses such as printf with PRIx64 type specifier. This change makes the test stricter enforcing that the return type of rsr and rsr64 builtins is what is actually specified in ACLE. Differential Revision: https://reviews.llvm.org/D57210 ------------------------------------------------------------------------ llvm-svn: 352859 --- clang/test/CodeGen/builtins-arm64.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/clang/test/CodeGen/builtins-arm64.c b/clang/test/CodeGen/builtins-arm64.c index 7027a6e220f3d..1a2cc2a77b96e 100644 --- a/clang/test/CodeGen/builtins-arm64.c +++ b/clang/test/CodeGen/builtins-arm64.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple arm64-unknown-linux -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +#include void f0(void *a, void *b) { __clear_cache(a,b); @@ -49,13 +50,17 @@ void prefetch() { // CHECK: call {{.*}} @llvm.prefetch(i8* null, i32 0, i32 3, i32 0) } -unsigned rsr() { +__typeof__(__builtin_arm_rsr("1:2:3:4:5")) rsr(void); + +uint32_t rsr() { // CHECK: [[V0:[%A-Za-z0-9.]+]] = call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]]) // CHECK-NEXT: trunc i64 [[V0]] to i32 return __builtin_arm_rsr("1:2:3:4:5"); } -unsigned long rsr64() { +__typeof__(__builtin_arm_rsr64("1:2:3:4:5")) rsr64(void); + +uint64_t rsr64() { // CHECK: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]]) return __builtin_arm_rsr64("1:2:3:4:5"); } From f66fbcfb52f58e41d91fc73835cff3b9b076d74d Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 1 Feb 2019 11:13:56 +0000 Subject: [PATCH 086/274] Merging r352463: ------------------------------------------------------------------------ r352463 | sam_parker | 2019-01-29 10:04:03 +0100 (Tue, 29 Jan 2019) | 6 lines [AArch64] Update int64_t ACLE builtin arguments Re-applying r351740 with fixes (changing LL to W). Differential Revision: https://reviews.llvm.org/D56852 ------------------------------------------------------------------------ llvm-svn: 352860 --- clang/include/clang/Basic/BuiltinsAArch64.def | 10 +++++----- clang/test/CodeGen/arm64-crc32.c | 19 ++++++++++-------- clang/test/CodeGen/builtins-arm64.c | 20 +++++++++++++++---- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/clang/include/clang/Basic/BuiltinsAArch64.def b/clang/include/clang/Basic/BuiltinsAArch64.def index 1892ff11a31dc..690d547f7f3ef 100644 --- a/clang/include/clang/Basic/BuiltinsAArch64.def +++ b/clang/include/clang/Basic/BuiltinsAArch64.def @@ -33,7 +33,7 @@ BUILTIN(__builtin_arm_clrex, "v", "") // Bit manipulation BUILTIN(__builtin_arm_rbit, "UiUi", "nc") -BUILTIN(__builtin_arm_rbit64, "LUiLUi", "nc") +BUILTIN(__builtin_arm_rbit64, "WUiWUi", "nc") // HINT BUILTIN(__builtin_arm_nop, "v", "") @@ -50,8 +50,8 @@ BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc") BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc") BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc") BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc") -BUILTIN(__builtin_arm_crc32d, "UiUiLUi", "nc") -BUILTIN(__builtin_arm_crc32cd, "UiUiLUi", "nc") +BUILTIN(__builtin_arm_crc32d, "UiUiWUi", "nc") +BUILTIN(__builtin_arm_crc32cd, "UiUiWUi", "nc") // Memory barrier BUILTIN(__builtin_arm_dmb, "vUi", "nc") @@ -63,10 +63,10 @@ BUILTIN(__builtin_arm_prefetch, "vvC*UiUiUiUi", "nc") // System Registers BUILTIN(__builtin_arm_rsr, "UicC*", "nc") -BUILTIN(__builtin_arm_rsr64, "LUicC*", "nc") +BUILTIN(__builtin_arm_rsr64, "WUicC*", "nc") BUILTIN(__builtin_arm_rsrp, "v*cC*", "nc") BUILTIN(__builtin_arm_wsr, "vcC*Ui", "nc") -BUILTIN(__builtin_arm_wsr64, "vcC*LUi", "nc") +BUILTIN(__builtin_arm_wsr64, "vcC*WUi", "nc") BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc") // MSVC diff --git a/clang/test/CodeGen/arm64-crc32.c b/clang/test/CodeGen/arm64-crc32.c index 2d913fb123b7c..26d69a23b6a1a 100644 --- a/clang/test/CodeGen/arm64-crc32.c +++ b/clang/test/CodeGen/arm64-crc32.c @@ -1,54 +1,57 @@ // REQUIRES: aarch64-registered-target // RUN: %clang_cc1 -triple arm64-none-linux-gnu \ // RUN: -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-windows \ +// RUN: -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +#include -int crc32b(int a, char b) +uint32_t crc32b(uint32_t a, uint8_t b) { return __builtin_arm_crc32b(a,b); // CHECK: [[T0:%[0-9]+]] = zext i8 %b to i32 // CHECK: call i32 @llvm.aarch64.crc32b(i32 %a, i32 [[T0]]) } -int crc32cb(int a, char b) +uint32_t crc32cb(uint32_t a, uint8_t b) { return __builtin_arm_crc32cb(a,b); // CHECK: [[T0:%[0-9]+]] = zext i8 %b to i32 // CHECK: call i32 @llvm.aarch64.crc32cb(i32 %a, i32 [[T0]]) } -int crc32h(int a, short b) +uint32_t crc32h(uint32_t a, uint16_t b) { return __builtin_arm_crc32h(a,b); // CHECK: [[T0:%[0-9]+]] = zext i16 %b to i32 // CHECK: call i32 @llvm.aarch64.crc32h(i32 %a, i32 [[T0]]) } -int crc32ch(int a, short b) +uint32_t crc32ch(uint32_t a, uint16_t b) { return __builtin_arm_crc32ch(a,b); // CHECK: [[T0:%[0-9]+]] = zext i16 %b to i32 // CHECK: call i32 @llvm.aarch64.crc32ch(i32 %a, i32 [[T0]]) } -int crc32w(int a, int b) +uint32_t crc32w(uint32_t a, uint32_t b) { return __builtin_arm_crc32w(a,b); // CHECK: call i32 @llvm.aarch64.crc32w(i32 %a, i32 %b) } -int crc32cw(int a, int b) +uint32_t crc32cw(uint32_t a, uint32_t b) { return __builtin_arm_crc32cw(a,b); // CHECK: call i32 @llvm.aarch64.crc32cw(i32 %a, i32 %b) } -int crc32d(int a, long b) +uint32_t crc32d(uint32_t a, uint64_t b) { return __builtin_arm_crc32d(a,b); // CHECK: call i32 @llvm.aarch64.crc32x(i32 %a, i64 %b) } -int crc32cd(int a, long b) +uint32_t crc32cd(uint32_t a, uint64_t b) { return __builtin_arm_crc32cd(a,b); // CHECK: call i32 @llvm.aarch64.crc32cx(i32 %a, i64 %b) diff --git a/clang/test/CodeGen/builtins-arm64.c b/clang/test/CodeGen/builtins-arm64.c index 1a2cc2a77b96e..f164c2f6f3647 100644 --- a/clang/test/CodeGen/builtins-arm64.c +++ b/clang/test/CodeGen/builtins-arm64.c @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -triple arm64-unknown-linux -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple arm64-unknown-linux -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LINUX +// RUN: %clang_cc1 -triple aarch64-windows -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-WIN #include void f0(void *a, void *b) { @@ -16,8 +17,15 @@ unsigned rbit(unsigned a) { return __builtin_arm_rbit(a); } +// CHECK-WIN: [[A64:%[^ ]+]] = zext i32 %a to i64 +// CHECK-WIN: call i64 @llvm.bitreverse.i64(i64 [[A64]]) +// CHECK-LINUX: call i64 @llvm.bitreverse.i64(i64 %a) +unsigned long rbitl(unsigned long a) { + return __builtin_arm_rbit64(a); +} + // CHECK: call {{.*}} @llvm.bitreverse.i64(i64 %a) -unsigned long long rbit64(unsigned long long a) { +uint64_t rbit64(uint64_t a) { return __builtin_arm_rbit64(a); } @@ -60,7 +68,7 @@ uint32_t rsr() { __typeof__(__builtin_arm_rsr64("1:2:3:4:5")) rsr64(void); -uint64_t rsr64() { +uint64_t rsr64(void) { // CHECK: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]]) return __builtin_arm_rsr64("1:2:3:4:5"); } @@ -71,13 +79,17 @@ void *rsrp() { return __builtin_arm_rsrp("1:2:3:4:5"); } +__typeof__(__builtin_arm_wsr("1:2:3:4:5", 0)) wsr(unsigned); + void wsr(unsigned v) { // CHECK: [[V0:[%A-Za-z0-9.]+]] = zext i32 %v to i64 // CHECK-NEXT: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 [[V0]]) __builtin_arm_wsr("1:2:3:4:5", v); } -void wsr64(unsigned long v) { +__typeof__(__builtin_arm_wsr64("1:2:3:4:5", 0)) wsr64(uint64_t); + +void wsr64(uint64_t v) { // CHECK: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %v) __builtin_arm_wsr64("1:2:3:4:5", v); } From 61ff0b639cca25747bcbae8bf5a213d702141bc5 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 1 Feb 2019 12:44:23 +0000 Subject: [PATCH 087/274] Merging r352246: ------------------------------------------------------------------------ r352246 | mtrofin | 2019-01-25 22:49:54 +0100 (Fri, 25 Jan 2019) | 23 lines [llvm] Opt-in flag for X86DiscriminateMemOps Summary: Currently, if an instruction with a memory operand has no debug information, X86DiscriminateMemOps will generate one based on the first line of the enclosing function, or the last seen debug info. This may cause confusion in certain debugging scenarios. The long term approach would be to use the line number '0' in such cases, however, that brings in challenges: the base discriminator value range is limited (4096 values). For the short term, adding an opt-in flag for this feature. See bug 40319 (https://bugs.llvm.org/show_bug.cgi?id=40319) Reviewers: dblaikie, jmorse, gbedwell Reviewed By: dblaikie Subscribers: aprantl, eraman, hiraditya Differential Revision: https://reviews.llvm.org/D57257 ------------------------------------------------------------------------ llvm-svn: 352867 --- llvm/lib/Target/X86/X86DiscriminateMemOps.cpp | 11 +++++++++++ llvm/lib/Target/X86/X86InsertPrefetch.cpp | 3 ++- llvm/test/CodeGen/X86/discriminate-mem-ops.ll | 2 +- llvm/test/CodeGen/X86/insert-prefetch-inline.ll | 2 +- .../test/CodeGen/X86/insert-prefetch-invalid-instr.ll | 2 +- llvm/test/CodeGen/X86/insert-prefetch.ll | 4 ++-- 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/X86/X86DiscriminateMemOps.cpp b/llvm/lib/Target/X86/X86DiscriminateMemOps.cpp index 3654bf04f4e98..6bee20b617dde 100644 --- a/llvm/lib/Target/X86/X86DiscriminateMemOps.cpp +++ b/llvm/lib/Target/X86/X86DiscriminateMemOps.cpp @@ -27,6 +27,14 @@ using namespace llvm; #define DEBUG_TYPE "x86-discriminate-memops" +static cl::opt EnableDiscriminateMemops( + DEBUG_TYPE, cl::init(false), + cl::desc("Generate unique debug info for each instruction with a memory " + "operand. Should be enabled for profile-drived cache prefetching, " + "both in the build of the binary being profiled, as well as in " + "the build of the binary consuming the profile."), + cl::Hidden); + namespace { using Location = std::pair; @@ -67,6 +75,9 @@ char X86DiscriminateMemOps::ID = 0; X86DiscriminateMemOps::X86DiscriminateMemOps() : MachineFunctionPass(ID) {} bool X86DiscriminateMemOps::runOnMachineFunction(MachineFunction &MF) { + if (!EnableDiscriminateMemops) + return false; + DISubprogram *FDI = MF.getFunction().getSubprogram(); if (!FDI || !FDI->getUnit()->getDebugInfoForProfiling()) return false; diff --git a/llvm/lib/Target/X86/X86InsertPrefetch.cpp b/llvm/lib/Target/X86/X86InsertPrefetch.cpp index 30b46a09ef0f9..8bd57aa2278ba 100644 --- a/llvm/lib/Target/X86/X86InsertPrefetch.cpp +++ b/llvm/lib/Target/X86/X86InsertPrefetch.cpp @@ -34,7 +34,8 @@ using namespace sampleprof; static cl::opt PrefetchHintsFile("prefetch-hints-file", - cl::desc("Path to the prefetch hints profile."), + cl::desc("Path to the prefetch hints profile. See also " + "-x86-discriminate-memops"), cl::Hidden); namespace { diff --git a/llvm/test/CodeGen/X86/discriminate-mem-ops.ll b/llvm/test/CodeGen/X86/discriminate-mem-ops.ll index b77a91fafd2cd..a30dc22a0d9c0 100644 --- a/llvm/test/CodeGen/X86/discriminate-mem-ops.ll +++ b/llvm/test/CodeGen/X86/discriminate-mem-ops.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s | FileCheck %s +; RUN: llc -x86-discriminate-memops < %s | FileCheck %s ; ; original source, compiled with -O3 -gmlt -fdebug-info-for-profiling: ; int sum(int* arr, int pos1, int pos2) { diff --git a/llvm/test/CodeGen/X86/insert-prefetch-inline.ll b/llvm/test/CodeGen/X86/insert-prefetch-inline.ll index 5f8373f9480c9..62c02fa33291d 100644 --- a/llvm/test/CodeGen/X86/insert-prefetch-inline.ll +++ b/llvm/test/CodeGen/X86/insert-prefetch-inline.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -prefetch-hints-file=%S/insert-prefetch-inline.afdo | FileCheck %s +; RUN: llc < %s -x86-discriminate-memops -prefetch-hints-file=%S/insert-prefetch-inline.afdo | FileCheck %s ; ; Verify we can insert prefetch instructions in code belonging to inlined ; functions. diff --git a/llvm/test/CodeGen/X86/insert-prefetch-invalid-instr.ll b/llvm/test/CodeGen/X86/insert-prefetch-invalid-instr.ll index 004fb56a56eb8..d0c4ac378b63b 100644 --- a/llvm/test/CodeGen/X86/insert-prefetch-invalid-instr.ll +++ b/llvm/test/CodeGen/X86/insert-prefetch-invalid-instr.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -prefetch-hints-file=%S/insert-prefetch-invalid-instr.afdo | FileCheck %s +; RUN: llc < %s -x86-discriminate-memops -prefetch-hints-file=%S/insert-prefetch-invalid-instr.afdo | FileCheck %s ; ModuleID = 'prefetch.cc' source_filename = "prefetch.cc" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/llvm/test/CodeGen/X86/insert-prefetch.ll b/llvm/test/CodeGen/X86/insert-prefetch.ll index 9e77772df7746..fe0fd9877f193 100644 --- a/llvm/test/CodeGen/X86/insert-prefetch.ll +++ b/llvm/test/CodeGen/X86/insert-prefetch.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -prefetch-hints-file=%S/insert-prefetch.afdo | FileCheck %s -; RUN: llc < %s -prefetch-hints-file=%S/insert-prefetch-other.afdo | FileCheck %s -check-prefix=OTHERS +; RUN: llc < %s -x86-discriminate-memops -prefetch-hints-file=%S/insert-prefetch.afdo | FileCheck %s +; RUN: llc < %s -x86-discriminate-memops -prefetch-hints-file=%S/insert-prefetch-other.afdo | FileCheck %s -check-prefix=OTHERS ; ; original source, compiled with -O3 -gmlt -fdebug-info-for-profiling: ; int sum(int* arr, int pos1, int pos2) { From b96362ffa9ceecf2256373f2e86a3e62780c599f Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 1 Feb 2019 20:55:52 +0000 Subject: [PATCH 088/274] [Hexagon] Update release notes with the changes to the Hexagon backend llvm-svn: 352915 --- llvm/docs/ReleaseNotes.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 82e4d56d48f46..7fc18774851db 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -81,6 +81,11 @@ Changes to the ARM Backend During this release ... +Changes to the Hexagon Target +-------------------------- + +* Added support for Hexagon/HVX V66 ISA. + Changes to the MIPS Target -------------------------- From 36e9afbd214703adf5177eeae095f8634f64bb51 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 4 Feb 2019 08:51:28 +0000 Subject: [PATCH 089/274] Release Notes: Add Zig to External Open Source Projects Using LLVM 8 Zig has all tests passing in the llvm8 branch with rc1. Zig 0.4.0 is scheduled to be released 1 week after LLVM 8.0.0, and it will depend on LLVM 8. Patch by Andrew Kelley! Differential revision: https://reviews.llvm.org/D57586 llvm-svn: 353019 --- llvm/docs/ReleaseNotes.rst | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 7fc18774851db..2bd435ca9d296 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -156,7 +156,16 @@ Changes to the DAG infrastructure External Open Source Projects Using LLVM 8 ========================================== -* A project... +Zig Programming Language +------------------------ + +`Zig `_ is a system programming language intended to be +an alternative to C. It provides high level features such as generics, compile +time function execution, and partial evaluation, while exposing low level LLVM +IR features such as aliases and intrinsics. Zig uses Clang to provide automatic +import of .h symbols, including inline functions and simple macros. Zig uses +LLD combined with lazily building compiler-rt to provide out-of-the-box +cross-compiling for all supported targets. Additional Information From 8cc77b4abfde78057798de445a9e7d46d9b77819 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 4 Feb 2019 09:31:37 +0000 Subject: [PATCH 090/274] Merging r352889: ------------------------------------------------------------------------ r352889 | wolfgangp | 2019-02-01 18:11:58 +0100 (Fri, 01 Feb 2019) | 6 lines [DWARF v5] Fix DWARF emitter and consumer to produce/expect a uleb for a location description's length. Reviewer: davide, JDevliegere Differential Revision: https://reviews.llvm.org/D57550 ------------------------------------------------------------------------ llvm-svn: 353029 --- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 6 ++++-- llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp | 3 ++- llvm/test/CodeGen/X86/debug-loclists.ll | 6 +++--- llvm/test/DebugInfo/X86/dwarfdump-debug-loclists.test | 8 ++++---- .../llvm-dwarfdump/X86/debug_loclists_startx_length.s | 4 ++-- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 1de2ffb6cfa11..18c5fe27b1a8f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1956,8 +1956,10 @@ void DebugLocEntry::finalize(const AsmPrinter &AP, void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry) { // Emit the size. Asm->OutStreamer->AddComment("Loc expr size"); - Asm->emitInt16(DebugLocs.getBytes(Entry).size()); - + if (getDwarfVersion() >= 5) + Asm->EmitULEB128(DebugLocs.getBytes(Entry).size()); + else + Asm->emitInt16(DebugLocs.getBytes(Entry).size()); // Emit the entry. APByteStreamer Streamer(*Asm); emitDebugLocEntry(Streamer, Entry); diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp index f8b5ff6ec8fb6..94df6946f3ae2 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp @@ -184,7 +184,8 @@ DWARFDebugLoclists::parseOneLocationList(DataExtractor Data, unsigned *Offset, } if (Kind != dwarf::DW_LLE_base_address) { - unsigned Bytes = Data.getU16(Offset); + unsigned Bytes = + Version >= 5 ? Data.getULEB128(Offset) : Data.getU16(Offset); // A single location description describing the location of the object... StringRef str = Data.getData().substr(*Offset, Bytes); *Offset += Bytes; diff --git a/llvm/test/CodeGen/X86/debug-loclists.ll b/llvm/test/CodeGen/X86/debug-loclists.ll index 20bc0c40378b9..0c2ab3dfad5a9 100644 --- a/llvm/test/CodeGen/X86/debug-loclists.ll +++ b/llvm/test/CodeGen/X86/debug-loclists.ll @@ -11,7 +11,7 @@ ; CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + 0x0040 => {0x00000040} "A") ; CHECK: .debug_loclists contents: -; CHECK-NEXT: 0x00000000: locations list header: length = 0x00000017, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 +; CHECK-NEXT: 0x00000000: locations list header: length = 0x00000015, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 ; CHECK-NEXT: 0x00000000: ; CHECK-NEXT: [0x0000000000000000, 0x0000000000000004): DW_OP_breg5 RDI+0 ; CHECK-NEXT: [0x0000000000000004, 0x0000000000000012): DW_OP_breg3 RBX+0 @@ -32,13 +32,13 @@ ; ASM-NEXT: .byte 4 # DW_LLE_offset_pair ; ASM-NEXT: .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset ; ASM-NEXT: .uleb128 .Ltmp0-.Lfunc_begin0 # ending offset -; ASM-NEXT: .short 2 # Loc expr size +; ASM-NEXT: .byte 2 # Loc expr size ; ASM-NEXT: .byte 117 # DW_OP_breg5 ; ASM-NEXT: .byte 0 # 0 ; ASM-NEXT: .byte 4 # DW_LLE_offset_pair ; ASM-NEXT: .uleb128 .Ltmp0-.Lfunc_begin0 # starting offset ; ASM-NEXT: .uleb128 .Ltmp1-.Lfunc_begin0 # ending offset -; ASM-NEXT: .short 2 # Loc expr size +; ASM-NEXT: .byte 2 # Loc expr size ; ASM-NEXT: .byte 115 # DW_OP_breg3 ; ASM-NEXT: .byte 0 # 0 ; ASM-NEXT: .byte 0 # DW_LLE_end_of_list diff --git a/llvm/test/DebugInfo/X86/dwarfdump-debug-loclists.test b/llvm/test/DebugInfo/X86/dwarfdump-debug-loclists.test index 669607fe557a3..32f2482b5117c 100644 --- a/llvm/test/DebugInfo/X86/dwarfdump-debug-loclists.test +++ b/llvm/test/DebugInfo/X86/dwarfdump-debug-loclists.test @@ -9,7 +9,7 @@ # CHECK-NEXT: [0x0000000000000700, 0x0000000000000710): DW_OP_breg5 RDI+0 # CHECK: .debug_loclists contents: -# CHECK-NEXT: 0x00000000: locations list header: length = 0x0000002f, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 +# CHECK-NEXT: 0x00000000: locations list header: length = 0x0000002c, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 # CHECK-NEXT: 0x00000000: # CHECK-NEXT: [0x0000000000000000, 0x0000000000000010): DW_OP_breg5 RDI+0 # CHECK-NEXT: [0x0000000000000530, 0x0000000000000540): DW_OP_breg6 RBP-8, DW_OP_deref @@ -37,7 +37,7 @@ .byte 4 # DW_LLE_offset_pair .uleb128 0x0 # starting offset .uleb128 0x10 # ending offset - .short 2 # Loc expr size + .byte 2 # Loc expr size .byte 117 # DW_OP_breg5 .byte 0 # 0 @@ -47,7 +47,7 @@ .byte 4 # DW_LLE_offset_pair .uleb128 0x30 # starting offset .uleb128 0x40 # ending offset - .short 3 # Loc expr size + .byte 3 # Loc expr size .byte 118 # DW_OP_breg6 .byte 120 # -8 .byte 6 # DW_OP_deref @@ -55,7 +55,7 @@ .byte 8 # DW_LLE_start_length .quad 0x700 # Some address .uleb128 0x10 # length - .short 2 # Loc expr size + .byte 2 # Loc expr size .byte 117 # DW_OP_breg5 .byte 0 # 0 diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s index 07c68ab2618f1..0b2ae5f8e7a4f 100644 --- a/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s +++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s @@ -6,7 +6,7 @@ # the final version which uses ULEB128 and not the U32. # CHECK: .debug_loclists contents: -# CHECK-NEXT: 0x00000000: locations list header: length = 0x0000000f, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 +# CHECK-NEXT: 0x00000000: locations list header: length = 0x0000000e, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 # CHECK-NEXT: 0x00000000: # CHECK-NEXT: Addr idx 1 (w/ length 16): DW_OP_reg5 RDI @@ -21,7 +21,7 @@ .byte 3 # DW_LLE_startx_length .byte 0x01 # Index .uleb128 0x10 # Length - .short 1 # Loc expr size + .byte 1 # Loc expr size .byte 85 # DW_OP_reg5 .byte 0 # DW_LLE_end_of_list .Ldebug_loclist_table_end0: From 44c793021d5746a3860aaa241e7f0756a48df744 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 4 Feb 2019 09:52:31 +0000 Subject: [PATCH 091/274] Merging r352307: ------------------------------------------------------------------------ r352307 | void | 2019-01-27 08:24:03 +0100 (Sun, 27 Jan 2019) | 11 lines Remove Expr sugar decorating the CXXUuidofExpr node. Summary: Sugar, like ConstantExpr, causes an infinite expansion of the template object. Reviewers: rsmith, aaron.ballman Reviewed By: aaron.ballman Subscribers: riccibruno, aaron.ballman, cfe-commits, tzik, rnk Differential Revision: https://reviews.llvm.org/D57114 ------------------------------------------------------------------------ llvm-svn: 353031 --- clang/lib/Sema/SemaTemplate.cpp | 2 +- clang/test/SemaCXX/PR40395.cpp | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 clang/test/SemaCXX/PR40395.cpp diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 3f9dc989103fa..f974bedffe005 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -6309,7 +6309,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // -- a predefined __func__ variable if (auto *E = Value.getLValueBase().dyn_cast()) { if (isa(E)) { - Converted = TemplateArgument(ArgResult.get()); + Converted = TemplateArgument(ArgResult.get()->IgnoreImpCasts()); break; } Diag(Arg->getBeginLoc(), diag::err_template_arg_not_decl_ref) diff --git a/clang/test/SemaCXX/PR40395.cpp b/clang/test/SemaCXX/PR40395.cpp new file mode 100644 index 0000000000000..469c86d56209c --- /dev/null +++ b/clang/test/SemaCXX/PR40395.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=c++17 -fms-extensions -triple=x86_64-pc-win32 -verify %s +// expected-no-diagnostics + +// PR40395 - ConstantExpr shouldn't cause the template object to infinitely +// expand. +struct _GUID {}; +struct __declspec(uuid("{AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA}")) B {}; + +template +struct A { + virtual void baz() { A(); } +}; + +void f() { + A<&__uuidof(B)>(); +} From ca26c44df0122e65a56661bef56c9a63901eb699 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 5 Feb 2019 11:15:26 +0000 Subject: [PATCH 092/274] Merging r352928: ------------------------------------------------------------------------ r352928 | mstorsjo | 2019-02-01 23:08:03 +0100 (Fri, 01 Feb 2019) | 9 lines [COFF] Fix crashes when writing a PDB after adding thunks. When writing a PDB, the OutputSection of all chunks need to be set. The thunks are added directly to OutputSection after the normal machinery that sets it for all other chunks. This fixes part of PR40467. Differential Revision: https://reviews.llvm.org/D57574 ------------------------------------------------------------------------ llvm-svn: 353157 --- lld/COFF/Writer.cpp | 11 ++++++----- lld/test/COFF/arm-thumb-thunks-pdb.s | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 lld/test/COFF/arm-thumb-thunks-pdb.s diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 258796ea6057b..71c24f6172abd 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -344,14 +344,14 @@ getThunk(DenseMap &LastThunks, Defined *Target, uint64_t P, // After adding thunks, we verify that all relocations are in range (with // no extra margin requirements). If this failed, we restart (throwing away // the previously created thunks) and retry with a wider margin. -static bool createThunks(std::vector &Chunks, int Margin) { +static bool createThunks(OutputSection *OS, int Margin) { bool AddressesChanged = false; DenseMap LastThunks; size_t ThunksSize = 0; // Recheck Chunks.size() each iteration, since we can insert more // elements into it. - for (size_t I = 0; I != Chunks.size(); ++I) { - SectionChunk *SC = dyn_cast_or_null(Chunks[I]); + for (size_t I = 0; I != OS->Chunks.size(); ++I) { + SectionChunk *SC = dyn_cast_or_null(OS->Chunks[I]); if (!SC) continue; size_t ThunkInsertionSpot = I + 1; @@ -388,7 +388,8 @@ static bool createThunks(std::vector &Chunks, int Margin) { Chunk *ThunkChunk = Thunk->getChunk(); ThunkChunk->setRVA( ThunkInsertionRVA); // Estimate of where it will be located. - Chunks.insert(Chunks.begin() + ThunkInsertionSpot, ThunkChunk); + ThunkChunk->setOutputSection(OS); + OS->Chunks.insert(OS->Chunks.begin() + ThunkInsertionSpot, ThunkChunk); ThunkInsertionSpot++; ThunksSize += ThunkChunk->getSize(); ThunkInsertionRVA += ThunkChunk->getSize(); @@ -477,7 +478,7 @@ void Writer::finalizeAddresses() { // to avoid things going out of range due to the added thunks. bool AddressesChanged = false; for (OutputSection *Sec : OutputSections) - AddressesChanged |= createThunks(Sec->Chunks, Margin); + AddressesChanged |= createThunks(Sec, Margin); // If the verification above thought we needed thunks, we should have // added some. assert(AddressesChanged); diff --git a/lld/test/COFF/arm-thumb-thunks-pdb.s b/lld/test/COFF/arm-thumb-thunks-pdb.s new file mode 100644 index 0000000000000..9e972a78d37ff --- /dev/null +++ b/lld/test/COFF/arm-thumb-thunks-pdb.s @@ -0,0 +1,18 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=thumbv7-windows %s -o %t.obj +// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -debug -pdb:%t.pdb -verbose 2>&1 | FileCheck %s --check-prefix=VERBOSE + +// VERBOSE: Added 1 thunks with margin {{.*}} in {{.*}} passes + + .syntax unified + .globl main + .globl func1 + .text +main: + bne func1 + bx lr + .section .text$a, "xr" + .space 0x100000 + .section .text$b, "xr" +func1: + bx lr From 9c110d55f93a7367ab1d949df5aee1239be340e0 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 5 Feb 2019 11:19:42 +0000 Subject: [PATCH 093/274] Merging r352929: ------------------------------------------------------------------------ r352929 | mstorsjo | 2019-02-01 23:08:09 +0100 (Fri, 01 Feb 2019) | 11 lines [COFF] Create range extension thunks for ARM64 On ARM64, this is normally necessary only after a module exceeds 128 MB in size (while the limit for thumb is 16 MB). For conditional branches, the range limit is only 1 MB though (the same as for thumb), and for the tbz instruction, the range is only 32 KB, which allows for a test much smaller than the full 128 MB. This fixes PR40467. Differential Revision: https://reviews.llvm.org/D57575 ------------------------------------------------------------------------ llvm-svn: 353158 --- lld/COFF/Chunks.cpp | 24 +++++++++++-- lld/COFF/Chunks.h | 13 +++++-- lld/COFF/Writer.cpp | 49 ++++++++++++++++++++------- lld/test/COFF/arm64-branch-range.test | 16 --------- lld/test/COFF/arm64-thunks.s | 27 +++++++++++++++ 5 files changed, 97 insertions(+), 32 deletions(-) delete mode 100644 lld/test/COFF/arm64-branch-range.test create mode 100644 lld/test/COFF/arm64-thunks.s diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp index 29131d7eb8db4..2bb9aa01e5399 100644 --- a/lld/COFF/Chunks.cpp +++ b/lld/COFF/Chunks.cpp @@ -669,18 +669,38 @@ const uint8_t ArmThunk[] = { 0xe7, 0x44, // L1: add pc, ip }; -size_t RangeExtensionThunk::getSize() const { +size_t RangeExtensionThunkARM::getSize() const { assert(Config->Machine == ARMNT); return sizeof(ArmThunk); } -void RangeExtensionThunk::writeTo(uint8_t *Buf) const { +void RangeExtensionThunkARM::writeTo(uint8_t *Buf) const { assert(Config->Machine == ARMNT); uint64_t Offset = Target->getRVA() - RVA - 12; memcpy(Buf + OutputSectionOff, ArmThunk, sizeof(ArmThunk)); applyMOV32T(Buf + OutputSectionOff, uint32_t(Offset)); } +// A position independent ARM64 adrp+add thunk, with a maximum range of +// +/- 4 GB, which is enough for any PE-COFF. +const uint8_t Arm64Thunk[] = { + 0x10, 0x00, 0x00, 0x90, // adrp x16, Dest + 0x10, 0x02, 0x00, 0x91, // add x16, x16, :lo12:Dest + 0x00, 0x02, 0x1f, 0xd6, // br x16 +}; + +size_t RangeExtensionThunkARM64::getSize() const { + assert(Config->Machine == ARM64); + return sizeof(Arm64Thunk); +} + +void RangeExtensionThunkARM64::writeTo(uint8_t *Buf) const { + assert(Config->Machine == ARM64); + memcpy(Buf + OutputSectionOff, Arm64Thunk, sizeof(Arm64Thunk)); + applyArm64Addr(Buf + OutputSectionOff + 0, Target->getRVA(), RVA, 12); + applyArm64Imm(Buf + OutputSectionOff + 4, Target->getRVA() & 0xfff, 0); +} + void LocalImportChunk::getBaserels(std::vector *Res) { Res->emplace_back(getRVA()); } diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h index f8a0ddd8ef3b2..e132fdf8adfaf 100644 --- a/lld/COFF/Chunks.h +++ b/lld/COFF/Chunks.h @@ -355,9 +355,18 @@ class ImportThunkChunkARM64 : public Chunk { Defined *ImpSymbol; }; -class RangeExtensionThunk : public Chunk { +class RangeExtensionThunkARM : public Chunk { public: - explicit RangeExtensionThunk(Defined *T) : Target(T) {} + explicit RangeExtensionThunkARM(Defined *T) : Target(T) {} + size_t getSize() const override; + void writeTo(uint8_t *Buf) const override; + + Defined *Target; +}; + +class RangeExtensionThunkARM64 : public Chunk { +public: + explicit RangeExtensionThunkARM64(Defined *T) : Target(T) {} size_t getSize() const override; void writeTo(uint8_t *Buf) const override; diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 71c24f6172abd..6acfaf9a44545 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -306,16 +306,31 @@ void OutputSection::writeHeaderTo(uint8_t *Buf) { // Check whether the target address S is in range from a relocation // of type RelType at address P. static bool isInRange(uint16_t RelType, uint64_t S, uint64_t P, int Margin) { - assert(Config->Machine == ARMNT); - int64_t Diff = AbsoluteDifference(S, P + 4) + Margin; - switch (RelType) { - case IMAGE_REL_ARM_BRANCH20T: - return isInt<21>(Diff); - case IMAGE_REL_ARM_BRANCH24T: - case IMAGE_REL_ARM_BLX23T: - return isInt<25>(Diff); - default: - return true; + if (Config->Machine == ARMNT) { + int64_t Diff = AbsoluteDifference(S, P + 4) + Margin; + switch (RelType) { + case IMAGE_REL_ARM_BRANCH20T: + return isInt<21>(Diff); + case IMAGE_REL_ARM_BRANCH24T: + case IMAGE_REL_ARM_BLX23T: + return isInt<25>(Diff); + default: + return true; + } + } else if (Config->Machine == ARM64) { + int64_t Diff = AbsoluteDifference(S, P) + Margin; + switch (RelType) { + case IMAGE_REL_ARM64_BRANCH26: + return isInt<28>(Diff); + case IMAGE_REL_ARM64_BRANCH19: + return isInt<21>(Diff); + case IMAGE_REL_ARM64_BRANCH14: + return isInt<16>(Diff); + default: + return true; + } + } else { + llvm_unreachable("Unexpected architecture"); } } @@ -327,7 +342,17 @@ getThunk(DenseMap &LastThunks, Defined *Target, uint64_t P, Defined *&LastThunk = LastThunks[Target->getRVA()]; if (LastThunk && isInRange(Type, LastThunk->getRVA(), P, Margin)) return {LastThunk, false}; - RangeExtensionThunk *C = make(Target); + Chunk *C; + switch (Config->Machine) { + case ARMNT: + C = make(Target); + break; + case ARM64: + C = make(Target); + break; + default: + llvm_unreachable("Unexpected architecture"); + } Defined *D = make("", C); LastThunk = D; return {D, true}; @@ -429,7 +454,7 @@ static bool verifyRanges(const std::vector Chunks) { // Assign addresses and add thunks if necessary. void Writer::finalizeAddresses() { assignAddresses(); - if (Config->Machine != ARMNT) + if (Config->Machine != ARMNT && Config->Machine != ARM64) return; size_t OrigNumChunks = 0; diff --git a/lld/test/COFF/arm64-branch-range.test b/lld/test/COFF/arm64-branch-range.test deleted file mode 100644 index 0b581e9c464dc..0000000000000 --- a/lld/test/COFF/arm64-branch-range.test +++ /dev/null @@ -1,16 +0,0 @@ -// REQUIRES: aarch64 - -// RUN: echo -e '.globl _start\n _start:\n bl too_far26\n' > %t.main26.s -// RUN: echo -e '.globl _start\n _start:\n b.ne too_far19\n' > %t.main19.s -// RUN: echo -e '.globl _start\n _start:\n tbz x0, #0, too_far14\n' > %t.main14.s - -// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main26.s -o %t.main26.obj -// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main19.s -o %t.main19.obj -// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %t.main14.s -o %t.main14.obj -// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/far-arm64-abs.s -o %t.far.obj - -// RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main26.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s -// RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main19.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s -// RUN: not lld-link -base:0x10000 -entry:_start -subsystem:console %t.main14.obj %t.far.obj -out:%t.exe 2>&1 | FileCheck %s - -// CHECK: relocation out of range diff --git a/lld/test/COFF/arm64-thunks.s b/lld/test/COFF/arm64-thunks.s new file mode 100644 index 0000000000000..49004544c4389 --- /dev/null +++ b/lld/test/COFF/arm64-thunks.s @@ -0,0 +1,27 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %s -o %t.obj +// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s +// RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s + +// VERBOSE: Added 1 thunks with margin {{.*}} in 1 passes + + .globl main + .globl func1 + .text +main: + tbz w0, #0, func1 + ret + .section .text$a, "xr" + .space 0x8000 + .section .text$b, "xr" +func1: + ret + +// DISASM: 0000000140001000 .text: +// DISASM: 140001000: 40 00 00 36 tbz w0, #0, #8 <.text+0x8> +// DISASM: 140001004: c0 03 5f d6 ret +// DISASM: 140001008: 50 00 00 90 adrp x16, #32768 +// DISASM: 14000100c: 10 52 00 91 add x16, x16, #20 +// DISASM: 140001010: 00 02 1f d6 br x16 + +// DISASM: 140009014: c0 03 5f d6 ret From f7f9945cadc09cf8f6c8dc16be254eb8d96e5c11 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 5 Feb 2019 11:27:12 +0000 Subject: [PATCH 094/274] Merging r352945: ------------------------------------------------------------------------ r352945 | mgrang | 2019-02-02 02:32:48 +0100 (Sat, 02 Feb 2019) | 13 lines [AutoUpgrade] Fix AutoUpgrade for x86.seh.recoverfp Summary: This fixes the bug in https://reviews.llvm.org/D56747#inline-502711. Reviewers: efriedma Reviewed By: efriedma Subscribers: javed.absar, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D57614 ------------------------------------------------------------------------ llvm-svn: 353159 --- llvm/lib/IR/AutoUpgrade.cpp | 9 +++++---- llvm/test/CodeGen/AArch64/eh_recoverfp.ll | 11 +++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/eh_recoverfp.ll diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index b2eb8b09982e8..27064154221f4 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -469,6 +469,11 @@ static bool UpgradeX86IntrinsicFunction(Function *F, StringRef Name, } } + if (Name == "seh.recoverfp") { + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::eh_recoverfp); + return true; + } + return false; } @@ -544,10 +549,6 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::thread_pointer); return true; } - if (Name == "x86.seh.recoverfp") { - NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::eh_recoverfp); - return true; - } break; } diff --git a/llvm/test/CodeGen/AArch64/eh_recoverfp.ll b/llvm/test/CodeGen/AArch64/eh_recoverfp.ll new file mode 100644 index 0000000000000..777bcee543827 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/eh_recoverfp.ll @@ -0,0 +1,11 @@ +; RUN: llc -mtriple arm64-windows %s -o - 2>&1 | FileCheck %s + +define i8* @foo(i8* %a) { +; CHECK-LABEL: foo +; CHECK-NOT: llvm.x86.seh.recoverfp + %1 = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 ()* @f to i8*), i8* %a) + ret i8* %1 +} + +declare i8* @llvm.x86.seh.recoverfp(i8*, i8*) +declare i32 @f() From a10d2d2390f5cff0bb5af6fc408d6292d14e2033 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 5 Feb 2019 12:51:49 +0000 Subject: [PATCH 095/274] Merging r353082: ------------------------------------------------------------------------ r353082 | meinersbur | 2019-02-04 20:55:59 +0100 (Mon, 04 Feb 2019) | 10 lines [WarnMissedTransforms] Do not warn about already vectorized loops. LoopVectorize adds llvm.loop.isvectorized, but leaves llvm.loop.vectorize.enable. Do not consider such a loop for user-forced vectorization since vectorization already happened -- by prioritizing llvm.loop.isvectorized except for TM_SuppressedByUser. Fixes http://llvm.org/PR40546 Differential Revision: https://reviews.llvm.org/D57542 ------------------------------------------------------------------------ llvm-svn: 353166 --- llvm/lib/Transforms/Utils/LoopUtils.cpp | 14 ++++---- .../enable_and_isvectorized.ll | 33 +++++++++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 llvm/test/Transforms/LoopTransformWarning/enable_and_isvectorized.ll diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp index a93d1aeb62ef9..4bc353989efbe 100644 --- a/llvm/lib/Transforms/Utils/LoopUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp @@ -376,17 +376,17 @@ TransformationMode llvm::hasVectorizeTransformation(Loop *L) { Optional InterleaveCount = getOptionalIntLoopAttribute(L, "llvm.loop.interleave.count"); - if (Enable == true) { - // 'Forcing' vector width and interleave count to one effectively disables - // this tranformation. - if (VectorizeWidth == 1 && InterleaveCount == 1) - return TM_SuppressedByUser; - return TM_ForcedByUser; - } + // 'Forcing' vector width and interleave count to one effectively disables + // this tranformation. + if (Enable == true && VectorizeWidth == 1 && InterleaveCount == 1) + return TM_SuppressedByUser; if (getBooleanLoopAttribute(L, "llvm.loop.isvectorized")) return TM_Disable; + if (Enable == true) + return TM_ForcedByUser; + if (VectorizeWidth == 1 && InterleaveCount == 1) return TM_Disable; diff --git a/llvm/test/Transforms/LoopTransformWarning/enable_and_isvectorized.ll b/llvm/test/Transforms/LoopTransformWarning/enable_and_isvectorized.ll new file mode 100644 index 0000000000000..77d09ad53f788 --- /dev/null +++ b/llvm/test/Transforms/LoopTransformWarning/enable_and_isvectorized.ll @@ -0,0 +1,33 @@ +; RUN: opt -transform-warning -disable-output < %s 2>&1 | FileCheck -allow-empty %s +; +; llvm.org/PR40546 +; Do not warn about about leftover llvm.loop.vectorize.enable for already +; vectorized loops. + +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" + +define void @test(i32 %n) { +entry: + %cmp = icmp eq i32 %n, 0 + br i1 %cmp, label %simd.if.end, label %omp.inner.for.body.preheader + +omp.inner.for.body.preheader: + %wide.trip.count = zext i32 %n to i64 + br label %omp.inner.for.body + +omp.inner.for.body: + %indvars.iv = phi i64 [ 0, %omp.inner.for.body.preheader ], [ %indvars.iv.next, %omp.inner.for.body ] + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count + br i1 %exitcond, label %simd.if.end, label %omp.inner.for.body, !llvm.loop !0 + +simd.if.end: + ret void +} + +!0 = distinct !{!0, !1, !2} +!1 = !{!"llvm.loop.vectorize.enable", i1 true} +!2 = !{!"llvm.loop.isvectorized"} + + +; CHECK-NOT: loop not vectorized From a9a9c27e1c25996a210ff212bd46f14fd483e02b Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 5 Feb 2019 12:55:45 +0000 Subject: [PATCH 096/274] Merging r352555: ------------------------------------------------------------------------ r352555 | asbirlea | 2019-01-29 23:33:20 +0100 (Tue, 29 Jan 2019) | 12 lines Check bool attribute value in getOptionalBoolLoopAttribute. Summary: Check the bool value of the attribute in getOptionalBoolLoopAttribute not just its existance. Eliminates the warning noise generated when vectorization is explicitly disabled. Reviewers: Meinersbur, hfinkel, dmgreen Subscribers: jlebar, sanjoy, llvm-commits Differential Revision: https://reviews.llvm.org/D57260 ------------------------------------------------------------------------ llvm-svn: 353167 --- llvm/lib/Transforms/Utils/LoopUtils.cpp | 5 +- .../no_switch_disable_vectorization.ll | 95 +++++++++++++++++++ 2 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Transforms/LoopVectorize/no_switch_disable_vectorization.ll diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp index 4bc353989efbe..112e80d27e345 100644 --- a/llvm/lib/Transforms/Utils/LoopUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp @@ -217,7 +217,10 @@ static Optional getOptionalBoolLoopAttribute(const Loop *TheLoop, // When the value is absent it is interpreted as 'attribute set'. return true; case 2: - return mdconst::extract_or_null(MD->getOperand(1).get()); + if (ConstantInt *IntMD = + mdconst::extract_or_null(MD->getOperand(1).get())) + return IntMD->getZExtValue(); + return true; } llvm_unreachable("unexpected number of options"); } diff --git a/llvm/test/Transforms/LoopVectorize/no_switch_disable_vectorization.ll b/llvm/test/Transforms/LoopVectorize/no_switch_disable_vectorization.ll new file mode 100644 index 0000000000000..424ef3846224a --- /dev/null +++ b/llvm/test/Transforms/LoopVectorize/no_switch_disable_vectorization.ll @@ -0,0 +1,95 @@ +; RUN: opt < %s -loop-vectorize -force-vector-width=4 -transform-warning -S 2>&1 | FileCheck %s +; RUN: opt < %s -loop-vectorize -force-vector-width=1 -transform-warning -S 2>&1 | FileCheck %s -check-prefix=NOANALYSIS +; RUN: opt < %s -loop-vectorize -force-vector-width=4 -transform-warning -pass-remarks-missed='loop-vectorize' -S 2>&1 | FileCheck %s -check-prefix=MOREINFO + +; This test is a copy of no_switch.ll, with the "llvm.loop.vectorize.enable" metadata set to false. +; It tests that vectorization is explicitly disabled and no warnings are emitted. + +; CHECK-NOT: remark: source.cpp:4:5: loop not vectorized: loop contains a switch statement +; CHECK-NOT: warning: source.cpp:4:5: loop not vectorized: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering + +; NOANALYSIS-NOT: remark: {{.*}} +; NOANALYSIS-NOT: warning: source.cpp:4:5: loop not vectorized: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering + +; MOREINFO: remark: source.cpp:4:5: loop not vectorized: vectorization is explicitly disabled +; MOREINFO-NOT: warning: source.cpp:4:5: loop not vectorized: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering + +; CHECK: _Z11test_switchPii +; CHECK-NOT: x i32> +; CHECK: ret + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" + +; Function Attrs: nounwind optsize ssp uwtable +define void @_Z11test_switchPii(i32* nocapture %A, i32 %Length) #0 !dbg !4 { +entry: + %cmp18 = icmp sgt i32 %Length, 0, !dbg !10 + br i1 %cmp18, label %for.body.preheader, label %for.end, !dbg !10, !llvm.loop !12 + +for.body.preheader: ; preds = %entry + br label %for.body, !dbg !14 + +for.body: ; preds = %for.body.preheader, %for.inc + %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %for.body.preheader ] + %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv, !dbg !14 + %0 = load i32, i32* %arrayidx, align 4, !dbg !14, !tbaa !16 + switch i32 %0, label %for.inc [ + i32 0, label %sw.bb + i32 1, label %sw.bb3 + ], !dbg !14 + +sw.bb: ; preds = %for.body + %1 = trunc i64 %indvars.iv to i32, !dbg !20 + %mul = shl nsw i32 %1, 1, !dbg !20 + br label %for.inc, !dbg !22 + +sw.bb3: ; preds = %for.body + %2 = trunc i64 %indvars.iv to i32, !dbg !23 + store i32 %2, i32* %arrayidx, align 4, !dbg !23, !tbaa !16 + br label %for.inc, !dbg !23 + +for.inc: ; preds = %sw.bb3, %for.body, %sw.bb + %storemerge = phi i32 [ %mul, %sw.bb ], [ 0, %for.body ], [ 0, %sw.bb3 ] + store i32 %storemerge, i32* %arrayidx, align 4, !dbg !20, !tbaa !16 + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1, !dbg !10 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32, !dbg !10 + %exitcond = icmp eq i32 %lftr.wideiv, %Length, !dbg !10 + br i1 %exitcond, label %for.end.loopexit, label %for.body, !dbg !10, !llvm.loop !12 + +for.end.loopexit: ; preds = %for.inc + br label %for.end + +for.end: ; preds = %for.end.loopexit, %entry + ret void, !dbg !24 +} + +attributes #0 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0", isOptimized: true, runtimeVersion: 6, emissionKind: LineTablesOnly, file: !1, enums: !2, retainedTypes: !2, globals: !2, imports: !2) +!1 = !DIFile(filename: "source.cpp", directory: ".") +!2 = !{} +!4 = distinct !DISubprogram(name: "test_switch", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 1, file: !1, scope: !5, type: !6, retainedNodes: !2) +!5 = !DIFile(filename: "source.cpp", directory: ".") +!6 = !DISubroutineType(types: !2) +!7 = !{i32 2, !"Dwarf Version", i32 2} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{!"clang version 3.5.0"} +!10 = !DILocation(line: 3, column: 8, scope: !11) +!11 = distinct !DILexicalBlock(line: 3, column: 3, file: !1, scope: !4) +!12 = !{!12, !13, !13} +!13 = !{!"llvm.loop.vectorize.enable", i1 false} +!14 = !DILocation(line: 4, column: 5, scope: !15) +!15 = distinct !DILexicalBlock(line: 3, column: 36, file: !1, scope: !11) +!16 = !{!17, !17, i64 0} +!17 = !{!"int", !18, i64 0} +!18 = !{!"omnipotent char", !19, i64 0} +!19 = !{!"Simple C/C++ TBAA"} +!20 = !DILocation(line: 6, column: 7, scope: !21) +!21 = distinct !DILexicalBlock(line: 4, column: 18, file: !1, scope: !15) +!22 = !DILocation(line: 7, column: 5, scope: !21) +!23 = !DILocation(line: 9, column: 7, scope: !21) +!24 = !DILocation(line: 14, column: 1, scope: !4) From 30ce79ed996240027fabbe3d46fb4936642f662a Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Tue, 5 Feb 2019 21:25:23 +0000 Subject: [PATCH 097/274] Merging rr353218: ------------------------------------------------------------------------ r353218 | rnk | 2019-02-05 13:14:09 -0800 (Tue, 05 Feb 2019) | 19 lines [MC] Don't error on numberless .file directives on MachO Summary: Before r349976, MC ignored such directives when producing an object file and asserted when re-producing textual assembly output. I turned this assertion into a hard error in both cases in r349976, but this makes it unnecessarily difficult to write a single assembly file that supports both MachO and other object formats that support .file. A user reported this as PR40578, and we decided to go back to ignoring the directive. Fixes PR40578 Reviewers: mstorsjo Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D57772 ------------------------------------------------------------------------ llvm-svn: 353220 --- llvm/lib/MC/MCParser/AsmParser.cpp | 9 +++++---- llvm/test/MC/MachO/file-single.s | 8 -------- llvm/test/MC/MachO/file.s | 3 +++ 3 files changed, 8 insertions(+), 12 deletions(-) delete mode 100644 llvm/test/MC/MachO/file-single.s diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index cf42a6f7075b9..a0506715be372 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -3364,10 +3364,11 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { } if (FileNumber == -1) { - if (!getContext().getAsmInfo()->hasSingleParameterDotFile()) - return Error(DirectiveLoc, - "target does not support '.file' without a number"); - getStreamer().EmitFileDirective(Filename); + // Ignore the directive if there is no number and the target doesn't support + // numberless .file directives. This allows some portability of assembler + // between different object file formats. + if (getContext().getAsmInfo()->hasSingleParameterDotFile()) + getStreamer().EmitFileDirective(Filename); } else { // In case there is a -g option as well as debug info from directive .file, // we turn off the -g option, directly use the existing debug info instead. diff --git a/llvm/test/MC/MachO/file-single.s b/llvm/test/MC/MachO/file-single.s deleted file mode 100644 index 747af22750af7..0000000000000 --- a/llvm/test/MC/MachO/file-single.s +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: not llvm-mc -triple i386-apple-darwin9 %s -o /dev/null 2>&1 | FileCheck %s - -// Previously this crashed MC. - -// CHECK: error: target does not support '.file' without a number - - .file "dir/foo" - nop diff --git a/llvm/test/MC/MachO/file.s b/llvm/test/MC/MachO/file.s index 3ddfb2efe2246..eddbb599d97a2 100644 --- a/llvm/test/MC/MachO/file.s +++ b/llvm/test/MC/MachO/file.s @@ -1,5 +1,8 @@ // RUN: llvm-mc -triple i386-apple-darwin9 %s -filetype=obj -o - | llvm-readobj -s -section-data | FileCheck %s +// This number-less file directive is ignored on MachO. + .file "bar/baz.s" + .file 1 "dir/foo" nop From 35f4f2f7220a796ada2499e9ea49b7f9531040a4 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 6 Feb 2019 08:31:22 +0000 Subject: [PATCH 098/274] Merging r353155: ------------------------------------------------------------------------ r353155 | hans | 2019-02-05 12:01:54 +0100 (Tue, 05 Feb 2019) | 11 lines Fix format string in bindings/go/llvm/ir_test.go (PR40561) The test started failing for me recently. I don't see any changes around this code, so maybe it's my local go version that changed or something. The error seems real to me: we're trying to print an Attribute with %d. The test talks about "attribute masks" I'm not sure what that refers to, but I suppose we could print the raw pointer value, since that's what the test seems to be comparing. Differential revision: https://reviews.llvm.org/D57672 ------------------------------------------------------------------------ llvm-svn: 353279 --- llvm/bindings/go/llvm/ir_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/bindings/go/llvm/ir_test.go b/llvm/bindings/go/llvm/ir_test.go index 10f4968ba89f2..4d559c3367158 100644 --- a/llvm/bindings/go/llvm/ir_test.go +++ b/llvm/bindings/go/llvm/ir_test.go @@ -31,7 +31,7 @@ func testAttribute(t *testing.T, name string) { fn.AddFunctionAttr(attr) newattr := fn.GetEnumFunctionAttribute(kind) if attr != newattr { - t.Errorf("got attribute mask %d, want %d", newattr, attr) + t.Errorf("got attribute %p, want %p", newattr.C, attr.C) } text := mod.String() @@ -42,7 +42,7 @@ func testAttribute(t *testing.T, name string) { fn.RemoveEnumFunctionAttribute(kind) newattr = fn.GetEnumFunctionAttribute(kind) if !newattr.IsNil() { - t.Errorf("got attribute mask %d, want 0", newattr) + t.Errorf("got attribute %p, want 0", newattr.C) } } From 5581990eb08ddd98e511041fca75a13971eeb6b4 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 6 Feb 2019 10:22:11 +0000 Subject: [PATCH 099/274] Merging r352016: ------------------------------------------------------------------------ r352016 | phosek | 2019-01-24 04:04:42 +0100 (Thu, 24 Jan 2019) | 12 lines [libunwind] Don't abort if encoutering invalid .eh_frame_hdr Recent Linux kernel release has introduced a bug as part of the ORC rollout where the vDSO has a valid .eh_frame section, but it's missing the .eh_frame_hdr section and GNU_EH_FRAME segment has zero size. This causes libunwind to abort which breaks programs that use libunwind. The other unwinder implementation (libgcc, non-gnu) instead silently bail out unless being compiled as debug. This change modifies libunwind to use the same strategy. Differential Revision: https://reviews.llvm.org/D57081 ------------------------------------------------------------------------ llvm-svn: 353287 --- libunwind/src/AddressSpace.hpp | 6 +++--- libunwind/src/EHHeaderParser.hpp | 16 +++++++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/libunwind/src/AddressSpace.hpp b/libunwind/src/AddressSpace.hpp index 30ad35995aece..49bb360d79411 100644 --- a/libunwind/src/AddressSpace.hpp +++ b/libunwind/src/AddressSpace.hpp @@ -534,11 +534,11 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, #endif cbdata->sects->dwarf_index_section = eh_frame_hdr_start; cbdata->sects->dwarf_index_section_length = phdr->p_memsz; - EHHeaderParser::decodeEHHdr( + found_hdr = EHHeaderParser::decodeEHHdr( *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz, hdrInfo); - cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr; - found_hdr = true; + if (found_hdr) + cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr; } } diff --git a/libunwind/src/EHHeaderParser.hpp b/libunwind/src/EHHeaderParser.hpp index 9bdaf5505ff04..6b3e7dead8664 100644 --- a/libunwind/src/EHHeaderParser.hpp +++ b/libunwind/src/EHHeaderParser.hpp @@ -36,7 +36,7 @@ template class EHHeaderParser { uint8_t table_enc; }; - static void decodeEHHdr(A &addressSpace, pint_t ehHdrStart, pint_t ehHdrEnd, + static bool decodeEHHdr(A &addressSpace, pint_t ehHdrStart, pint_t ehHdrEnd, EHHeaderInfo &ehHdrInfo); static bool findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart, uint32_t sectionLength, @@ -53,12 +53,14 @@ template class EHHeaderParser { }; template -void EHHeaderParser::decodeEHHdr(A &addressSpace, pint_t ehHdrStart, +bool EHHeaderParser::decodeEHHdr(A &addressSpace, pint_t ehHdrStart, pint_t ehHdrEnd, EHHeaderInfo &ehHdrInfo) { pint_t p = ehHdrStart; uint8_t version = addressSpace.get8(p++); - if (version != 1) - _LIBUNWIND_ABORT("Unsupported .eh_frame_hdr version"); + if (version != 1) { + _LIBUNWIND_LOG0("Unsupported .eh_frame_hdr version"); + return false; + } uint8_t eh_frame_ptr_enc = addressSpace.get8(p++); uint8_t fde_count_enc = addressSpace.get8(p++); @@ -71,6 +73,8 @@ void EHHeaderParser::decodeEHHdr(A &addressSpace, pint_t ehHdrStart, ? 0 : addressSpace.getEncodedP(p, ehHdrEnd, fde_count_enc, ehHdrStart); ehHdrInfo.table = p; + + return true; } template @@ -102,7 +106,9 @@ bool EHHeaderParser::findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart, pint_t ehHdrEnd = ehHdrStart + sectionLength; EHHeaderParser::EHHeaderInfo hdrInfo; - EHHeaderParser::decodeEHHdr(addressSpace, ehHdrStart, ehHdrEnd, hdrInfo); + if (!EHHeaderParser::decodeEHHdr(addressSpace, ehHdrStart, ehHdrEnd, + hdrInfo)) + return false; size_t tableEntrySize = getTableEntrySize(hdrInfo.table_enc); pint_t tableEntry; From a2f46031fd0302a572eea856d2d7d247e1aa88d8 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 6 Feb 2019 12:39:08 +0000 Subject: [PATCH 100/274] Merging r353224: ------------------------------------------------------------------------ r353224 | kamil | 2019-02-05 23:20:25 +0100 (Tue, 05 Feb 2019) | 2 lines Update the ioctl(2) list in sanitizers with NetBSD 8.99.34 ------------------------------------------------------------------------ llvm-svn: 353292 --- .../sanitizer_interceptors_ioctl_netbsd.inc | 9 +++------ .../sanitizer_common/sanitizer_platform_limits_netbsd.cc | 5 ----- .../sanitizer_common/sanitizer_platform_limits_netbsd.h | 4 ---- compiler-rt/utils/generate_netbsd_ioctls.awk | 1 - 4 files changed, 3 insertions(+), 16 deletions(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc b/compiler-rt/lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc index 86cb440476069..bddc26d20019d 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc @@ -25,7 +25,7 @@ struct ioctl_desc { const char *name; }; -const unsigned ioctl_table_max = 1202; +const unsigned ioctl_table_max = 1200; static ioctl_desc ioctl_table[ioctl_table_max]; static unsigned ioctl_table_size = 0; @@ -298,9 +298,6 @@ static void ioctl_table_fill() { _(IRFRAMETTY_GET_DEVICE, WRITE, sizeof(unsigned int)); _(IRFRAMETTY_GET_DONGLE, WRITE, sizeof(unsigned int)); _(IRFRAMETTY_SET_DONGLE, READ, sizeof(unsigned int)); - /* Entries from file: dev/isa/satlinkio.h */ - _(SATIORESET, NONE, 0); - _(SATIOGID, WRITE, struct_satlink_id_sz); /* Entries from file: dev/isa/isvio.h */ _(ISV_CMD, READWRITE, struct_isv_cmd_sz); /* Entries from file: dev/isa/wtreg.h */ @@ -649,8 +646,8 @@ static void ioctl_table_fill() { _(SPKRTUNE, NONE, 0); _(SPKRGETVOL, WRITE, sizeof(unsigned int)); _(SPKRSETVOL, READ, sizeof(unsigned int)); - /* Entries from file: dev/nvmm/nvmm_ioctl.h */ #if 0 /* WIP */ + /* Entries from file: dev/nvmm/nvmm_ioctl.h */ _(NVMM_IOC_CAPABILITY, WRITE, struct_nvmm_ioc_capability_sz); _(NVMM_IOC_MACHINE_CREATE, READWRITE, struct_nvmm_ioc_machine_create_sz); _(NVMM_IOC_MACHINE_DESTROY, READ, struct_nvmm_ioc_machine_destroy_sz); @@ -659,7 +656,7 @@ static void ioctl_table_fill() { _(NVMM_IOC_VCPU_DESTROY, READ, struct_nvmm_ioc_vcpu_destroy_sz); _(NVMM_IOC_VCPU_SETSTATE, READ, struct_nvmm_ioc_vcpu_setstate_sz); _(NVMM_IOC_VCPU_GETSTATE, READ, struct_nvmm_ioc_vcpu_getstate_sz); - _(NVMM_IOC_VCPU_INJECT, READWRITE, struct_nvmm_ioc_vcpu_inject_sz); + _(NVMM_IOC_VCPU_INJECT, READ, struct_nvmm_ioc_vcpu_inject_sz); _(NVMM_IOC_VCPU_RUN, READWRITE, struct_nvmm_ioc_vcpu_run_sz); _(NVMM_IOC_GPA_MAP, READ, struct_nvmm_ioc_gpa_map_sz); _(NVMM_IOC_GPA_UNMAP, READ, struct_nvmm_ioc_gpa_unmap_sz); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc index b23b430d9e5bc..c112e044b1d82 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc @@ -122,7 +122,6 @@ #include #include #include -#include #include #include #include @@ -639,7 +638,6 @@ unsigned struct_rf_recon_req_sz = sizeof(rf_recon_req); unsigned struct_rio_conf_sz = sizeof(rio_conf); unsigned struct_rio_interface_sz = sizeof(rio_interface); unsigned struct_rio_stats_sz = sizeof(rio_stats); -unsigned struct_satlink_id_sz = sizeof(satlink_id); unsigned struct_scan_io_sz = sizeof(scan_io); unsigned struct_scbusaccel_args_sz = sizeof(scbusaccel_args); unsigned struct_scbusiodetach_args_sz = sizeof(scbusiodetach_args); @@ -1105,9 +1103,6 @@ unsigned IOCTL_IRDA_GET_TURNAROUNDMASK = IRDA_GET_TURNAROUNDMASK; unsigned IOCTL_IRFRAMETTY_GET_DEVICE = IRFRAMETTY_GET_DEVICE; unsigned IOCTL_IRFRAMETTY_GET_DONGLE = IRFRAMETTY_GET_DONGLE; unsigned IOCTL_IRFRAMETTY_SET_DONGLE = IRFRAMETTY_SET_DONGLE; -unsigned IOCTL_SATIORESET = SATIORESET; -unsigned IOCTL_SATIOGID = SATIOGID; -unsigned IOCTL_SATIOSBUFSIZE = SATIOSBUFSIZE; unsigned IOCTL_ISV_CMD = ISV_CMD; unsigned IOCTL_WTQICMD = WTQICMD; unsigned IOCTL_ISCSI_GET_VERSION = ISCSI_GET_VERSION; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h index 0c0c8a837b8b3..594cfa6c0d47b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h @@ -803,7 +803,6 @@ extern unsigned struct_rf_recon_req_sz; extern unsigned struct_rio_conf_sz; extern unsigned struct_rio_interface_sz; extern unsigned struct_rio_stats_sz; -extern unsigned struct_satlink_id_sz; extern unsigned struct_scan_io_sz; extern unsigned struct_scbusaccel_args_sz; extern unsigned struct_scbusiodetach_args_sz; @@ -1266,9 +1265,6 @@ extern unsigned IOCTL_IRDA_GET_TURNAROUNDMASK; extern unsigned IOCTL_IRFRAMETTY_GET_DEVICE; extern unsigned IOCTL_IRFRAMETTY_GET_DONGLE; extern unsigned IOCTL_IRFRAMETTY_SET_DONGLE; -extern unsigned IOCTL_SATIORESET; -extern unsigned IOCTL_SATIOGID; -extern unsigned IOCTL_SATIOSBUFSIZE; extern unsigned IOCTL_ISV_CMD; extern unsigned IOCTL_WTQICMD; extern unsigned IOCTL_ISCSI_GET_VERSION; diff --git a/compiler-rt/utils/generate_netbsd_ioctls.awk b/compiler-rt/utils/generate_netbsd_ioctls.awk index 82b1992143772..38fe88fb0cde4 100755 --- a/compiler-rt/utils/generate_netbsd_ioctls.awk +++ b/compiler-rt/utils/generate_netbsd_ioctls.awk @@ -152,7 +152,6 @@ FNR == 1 { $0 ~ /JOY_GET_X_OFFSET/ || $0 ~ /CHIOGPICKER/ || $0 ~ /SLIOCGUNIT/ || - $0 ~ /SATIOSBUFSIZE/ || $0 ~ /TUNSLMODE/ || $0 ~ /CBQ_IF_ATTACH/ || $0 ~ /CDNR_IF_ATTACH/ || From 7ec84db44f05e9f19ef5c04b6ba1147b2d2cba9c Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 6 Feb 2019 14:47:31 +0000 Subject: [PATCH 101/274] Merging r353250: ------------------------------------------------------------------------ r353250 | zturner | 2019-02-06 01:50:35 +0100 (Wed, 06 Feb 2019) | 24 lines [PDB] Remove dots and normalize slashes with /PDBSOURCEPATH. In a previous patch, I made changes so that PDBs which were generated on non-Windows platforms contained sensical paths for the host. While this is an esoteric use case, we need it to be supported for certain cross compilation scenarios especially with LLDB, which can debug things on non-Windows platforms. However, this regressed a case where you specify /PDBSOURCEPATH and use a windows-style path. Previously, we would still remove dots and canonicalize slashes to backslashes, but since my change intentionally tried to support non-backslash paths, this was broken. This patch fixes the situation by trying to guess which path style the user is specifying when /PDBSOURCEPATH is passed. It is intentionally conservative, erring on the side of a Windows path style unless absolutely certain. All dots are removed and slashes canonicalized to whatever the deduced path style is after appending the file path to the /PDBSOURCEPATH argument. Differential Revision: https://reviews.llvm.org/D57769 ------------------------------------------------------------------------ llvm-svn: 353300 --- lld/COFF/PDB.cpp | 18 ++++-- lld/test/COFF/pdb-relative-source-lines.test | 60 ++++++++++---------- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp index 7862b6ce4cc5a..7757b89e2b36d 100644 --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -288,18 +288,24 @@ static void pdbMakeAbsolute(SmallVectorImpl &FileName) { // It's not absolute in any path syntax. Relative paths necessarily refer to // the local file system, so we can make it native without ending up with a // nonsensical path. - sys::path::native(FileName); if (Config->PDBSourcePath.empty()) { + sys::path::native(FileName); sys::fs::make_absolute(FileName); return; } - // Only apply native and dot removal to the relative file path. We want to - // leave the path the user specified untouched since we assume they specified - // it for a reason. - sys::path::remove_dots(FileName, /*remove_dot_dots=*/true); + // Try to guess whether /PDBSOURCEPATH is a unix path or a windows path. + // Since PDB's are more of a Windows thing, we make this conservative and only + // decide that it's a unix path if we're fairly certain. Specifically, if + // it starts with a forward slash. SmallString<128> AbsoluteFileName = Config->PDBSourcePath; - sys::path::append(AbsoluteFileName, FileName); + sys::path::Style GuessedStyle = AbsoluteFileName.startswith("/") + ? sys::path::Style::posix + : sys::path::Style::windows; + sys::path::append(AbsoluteFileName, GuessedStyle, FileName); + sys::path::native(AbsoluteFileName, GuessedStyle); + sys::path::remove_dots(AbsoluteFileName, true, GuessedStyle); + FileName = std::move(AbsoluteFileName); } diff --git a/lld/test/COFF/pdb-relative-source-lines.test b/lld/test/COFF/pdb-relative-source-lines.test index 865d7a6d8a0a4..547056785962a 100644 --- a/lld/test/COFF/pdb-relative-source-lines.test +++ b/lld/test/COFF/pdb-relative-source-lines.test @@ -37,26 +37,26 @@ RUN: llvm-pdbutil pdb2yaml -modules -module-files -module-syms -subsections=line RUN: ./lld-link -debug "-pdbsourcepath:/usr/src" -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj RUN: llvm-pdbutil pdb2yaml -modules -module-files -module-syms -subsections=lines,fc %t/out.pdb | FileCheck --check-prefix=POSIX %s -CHECK-LABEL: - Module: 'c:\src{{[\\/]}}pdb_lines_1_relative.obj' -CHECK-NEXT: ObjFile: 'c:\src{{[\\/]}}pdb_lines_1_relative.obj' +CHECK-LABEL: - Module: 'c:\src\pdb_lines_1_relative.obj' +CHECK-NEXT: ObjFile: 'c:\src\pdb_lines_1_relative.obj' CHECK: SourceFiles: -CHECK-NEXT: - 'c:\src{{[\\/]}}pdb_lines_1.c' -CHECK-NEXT: - 'c:\src{{[\\/]}}foo.h' +CHECK-NEXT: - 'c:\src\pdb_lines_1.c' +CHECK-NEXT: - 'c:\src\foo.h' CHECK: Subsections: -CHECK: - FileName: 'c:\src{{[\\/]}}pdb_lines_1.c' -CHECK: - FileName: 'c:\src{{[\\/]}}foo.h' +CHECK: - FileName: 'c:\src\pdb_lines_1.c' +CHECK: - FileName: 'c:\src\foo.h' CHECK: - !FileChecksums -CHECK: - FileName: 'c:\src{{[\\/]}}pdb_lines_1.c' -CHECK: - FileName: 'c:\src{{[\\/]}}foo.h' +CHECK: - FileName: 'c:\src\pdb_lines_1.c' +CHECK: - FileName: 'c:\src\foo.h' -CHECK-LABEL: - Module: 'c:\src{{[\\/]}}pdb_lines_2_relative.obj' -CHECK-NEXT: ObjFile: 'c:\src{{[\\/]}}pdb_lines_2_relative.obj' +CHECK-LABEL: - Module: 'c:\src\pdb_lines_2_relative.obj' +CHECK-NEXT: ObjFile: 'c:\src\pdb_lines_2_relative.obj' CHECK: SourceFiles: -CHECK-NEXT: - 'c:\src{{[\\/]}}pdb_lines_2.c' +CHECK-NEXT: - 'c:\src\pdb_lines_2.c' CHECK: Subsections: -CHECK: - FileName: 'c:\src{{[\\/]}}pdb_lines_2.c' +CHECK: - FileName: 'c:\src\pdb_lines_2.c' CHECK: - !FileChecksums -CHECK: - FileName: 'c:\src{{[\\/]}}pdb_lines_2.c' +CHECK: - FileName: 'c:\src\pdb_lines_2.c' CHECK-LABEL: - Kind: S_ENVBLOCK CHECK-NEXT: EnvBlockSym: @@ -64,33 +64,33 @@ CHECK-NEXT: Entries: CHECK-NEXT: - cwd CHECK-NEXT: - 'c:\src' CHECK-NEXT: - exe -CHECK-NEXT: - 'c:\src{{[\\/]}}lld-link' +CHECK-NEXT: - 'c:\src\lld-link' CHECK-NEXT: - pdb -CHECK-NEXT: - 'c:\src{{[\\/]}}out.pdb' +CHECK-NEXT: - 'c:\src\out.pdb' CHECK-NEXT: - cmd CHECK-NEXT: - '-debug -pdbsourcepath:c:\src -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj' -POSIX-LABEL: - Module: '/usr/src{{[\\/]}}pdb_lines_1_relative.obj' -POSIX-NEXT: ObjFile: '/usr/src{{[\\/]}}pdb_lines_1_relative.obj' +POSIX-LABEL: - Module: '/usr/src/pdb_lines_1_relative.obj' +POSIX-NEXT: ObjFile: '/usr/src/pdb_lines_1_relative.obj' POSIX: SourceFiles: -POSIX-NEXT: - '/usr/src{{[\\/]}}pdb_lines_1.c' -POSIX-NEXT: - '/usr/src{{[\\/]}}foo.h' +POSIX-NEXT: - '/usr/src/pdb_lines_1.c' +POSIX-NEXT: - '/usr/src/foo.h' POSIX: Subsections: -POSIX: - FileName: '/usr/src{{[\\/]}}pdb_lines_1.c' -POSIX: - FileName: '/usr/src{{[\\/]}}foo.h' +POSIX: - FileName: '/usr/src/pdb_lines_1.c' +POSIX: - FileName: '/usr/src/foo.h' POSIX: - !FileChecksums -POSIX: - FileName: '/usr/src{{[\\/]}}pdb_lines_1.c' -POSIX: - FileName: '/usr/src{{[\\/]}}foo.h' +POSIX: - FileName: '/usr/src/pdb_lines_1.c' +POSIX: - FileName: '/usr/src/foo.h' -POSIX-LABEL: - Module: '/usr/src{{[\\/]}}pdb_lines_2_relative.obj' -POSIX-NEXT: ObjFile: '/usr/src{{[\\/]}}pdb_lines_2_relative.obj' +POSIX-LABEL: - Module: '/usr/src/pdb_lines_2_relative.obj' +POSIX-NEXT: ObjFile: '/usr/src/pdb_lines_2_relative.obj' POSIX: SourceFiles: -POSIX-NEXT: - '/usr/src{{[\\/]}}pdb_lines_2.c' +POSIX-NEXT: - '/usr/src/pdb_lines_2.c' POSIX: Subsections: -POSIX: - FileName: '/usr/src{{[\\/]}}pdb_lines_2.c' +POSIX: - FileName: '/usr/src/pdb_lines_2.c' POSIX: - !FileChecksums -POSIX: - FileName: '/usr/src{{[\\/]}}pdb_lines_2.c' +POSIX: - FileName: '/usr/src/pdb_lines_2.c' POSIX-LABEL: - Kind: S_ENVBLOCK POSIX-NEXT: EnvBlockSym: @@ -98,8 +98,8 @@ POSIX-NEXT: Entries: POSIX-NEXT: - cwd POSIX-NEXT: - '/usr/src' POSIX-NEXT: - exe -POSIX-NEXT: - '/usr/src{{[\\/]}}lld-link' +POSIX-NEXT: - '/usr/src/lld-link' POSIX-NEXT: - pdb -POSIX-NEXT: - '/usr/src{{[\\/]}}out.pdb' +POSIX-NEXT: - '/usr/src/out.pdb' POSIX-NEXT: - cmd POSIX-NEXT: - '-debug -pdbsourcepath:/usr/src -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj' From f58220669d09654f1df9b47161588d5e2f6bfc8a Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 7 Feb 2019 08:47:14 +0000 Subject: [PATCH 102/274] Merging r353304: ------------------------------------------------------------------------ r353304 | uweigand | 2019-02-06 16:10:13 +0100 (Wed, 06 Feb 2019) | 18 lines [SystemZ] Do not return INT_MIN from strcmp/memcmp The IPM sequence currently generated to compute the strcmp/memcmp result will return INT_MIN for the "less than zero" case. While this is in compliance with the standard, strictly speaking, it turns out that common applications cannot handle this, e.g. because they negate a comparison result in order to implement reverse compares. This patch changes code to use a different sequence that will result in -2 for the "less than zero" case (same as GCC). However, this requires that the two source operands of the compare instructions are inverted, which breaks the optimization in removeIPMBasedCompare. Therefore, I've removed this (and all of optimizeCompareInstr), and replaced it with a mostly equivalent optimization in combineCCMask at the DAGcombine level. ------------------------------------------------------------------------ llvm-svn: 353379 --- .../Target/SystemZ/SystemZISelLowering.cpp | 121 ++++++++++++------ llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp | 74 ----------- llvm/lib/Target/SystemZ/SystemZInstrInfo.h | 3 - .../SystemZ/SystemZSelectionDAGInfo.cpp | 18 +-- llvm/test/CodeGen/SystemZ/memcmp-01.ll | 58 ++++----- llvm/test/CodeGen/SystemZ/strcmp-01.ll | 18 +-- 6 files changed, 129 insertions(+), 163 deletions(-) diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp index 2a825c1316f3b..607e55bf71c87 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -5618,55 +5618,96 @@ SDValue SystemZTargetLowering::combineBSWAP( static bool combineCCMask(SDValue &CCReg, int &CCValid, int &CCMask) { // We have a SELECT_CCMASK or BR_CCMASK comparing the condition code // set by the CCReg instruction using the CCValid / CCMask masks, - // If the CCReg instruction is itself a (ICMP (SELECT_CCMASK)) testing - // the condition code set by some other instruction, see whether we - // can directly use that condition code. - bool Invert = false; + // If the CCReg instruction is itself a ICMP testing the condition + // code set by some other instruction, see whether we can directly + // use that condition code. - // Verify that we have an appropriate mask for a EQ or NE comparison. + // Verify that we have an ICMP against some constant. if (CCValid != SystemZ::CCMASK_ICMP) return false; - if (CCMask == SystemZ::CCMASK_CMP_NE) - Invert = !Invert; - else if (CCMask != SystemZ::CCMASK_CMP_EQ) - return false; - - // Verify that we have an ICMP that is the user of a SELECT_CCMASK. - SDNode *ICmp = CCReg.getNode(); + auto *ICmp = CCReg.getNode(); if (ICmp->getOpcode() != SystemZISD::ICMP) return false; - SDNode *Select = ICmp->getOperand(0).getNode(); - if (Select->getOpcode() != SystemZISD::SELECT_CCMASK) + auto *CompareLHS = ICmp->getOperand(0).getNode(); + auto *CompareRHS = dyn_cast(ICmp->getOperand(1)); + if (!CompareRHS) return false; - // Verify that the ICMP compares against one of select values. - auto *CompareVal = dyn_cast(ICmp->getOperand(1)); - if (!CompareVal) - return false; - auto *TrueVal = dyn_cast(Select->getOperand(0)); - if (!TrueVal) - return false; - auto *FalseVal = dyn_cast(Select->getOperand(1)); - if (!FalseVal) - return false; - if (CompareVal->getZExtValue() == FalseVal->getZExtValue()) - Invert = !Invert; - else if (CompareVal->getZExtValue() != TrueVal->getZExtValue()) - return false; + // Optimize the case where CompareLHS is a SELECT_CCMASK. + if (CompareLHS->getOpcode() == SystemZISD::SELECT_CCMASK) { + // Verify that we have an appropriate mask for a EQ or NE comparison. + bool Invert = false; + if (CCMask == SystemZ::CCMASK_CMP_NE) + Invert = !Invert; + else if (CCMask != SystemZ::CCMASK_CMP_EQ) + return false; - // Compute the effective CC mask for the new branch or select. - auto *NewCCValid = dyn_cast(Select->getOperand(2)); - auto *NewCCMask = dyn_cast(Select->getOperand(3)); - if (!NewCCValid || !NewCCMask) - return false; - CCValid = NewCCValid->getZExtValue(); - CCMask = NewCCMask->getZExtValue(); - if (Invert) - CCMask ^= CCValid; + // Verify that the ICMP compares against one of select values. + auto *TrueVal = dyn_cast(CompareLHS->getOperand(0)); + if (!TrueVal) + return false; + auto *FalseVal = dyn_cast(CompareLHS->getOperand(1)); + if (!FalseVal) + return false; + if (CompareRHS->getZExtValue() == FalseVal->getZExtValue()) + Invert = !Invert; + else if (CompareRHS->getZExtValue() != TrueVal->getZExtValue()) + return false; - // Return the updated CCReg link. - CCReg = Select->getOperand(4); - return true; + // Compute the effective CC mask for the new branch or select. + auto *NewCCValid = dyn_cast(CompareLHS->getOperand(2)); + auto *NewCCMask = dyn_cast(CompareLHS->getOperand(3)); + if (!NewCCValid || !NewCCMask) + return false; + CCValid = NewCCValid->getZExtValue(); + CCMask = NewCCMask->getZExtValue(); + if (Invert) + CCMask ^= CCValid; + + // Return the updated CCReg link. + CCReg = CompareLHS->getOperand(4); + return true; + } + + // Optimize the case where CompareRHS is (SRA (SHL (IPM))). + if (CompareLHS->getOpcode() == ISD::SRA) { + auto *SRACount = dyn_cast(CompareLHS->getOperand(1)); + if (!SRACount || SRACount->getZExtValue() != 30) + return false; + auto *SHL = CompareLHS->getOperand(0).getNode(); + if (SHL->getOpcode() != ISD::SHL) + return false; + auto *SHLCount = dyn_cast(SHL->getOperand(1)); + if (!SHLCount || SHLCount->getZExtValue() != 30 - SystemZ::IPM_CC) + return false; + auto *IPM = SHL->getOperand(0).getNode(); + if (IPM->getOpcode() != SystemZISD::IPM) + return false; + + // Avoid introducing CC spills (because SRA would clobber CC). + if (!CompareLHS->hasOneUse()) + return false; + // Verify that the ICMP compares against zero. + if (CompareRHS->getZExtValue() != 0) + return false; + + // Compute the effective CC mask for the new branch or select. + switch (CCMask) { + case SystemZ::CCMASK_CMP_EQ: break; + case SystemZ::CCMASK_CMP_NE: break; + case SystemZ::CCMASK_CMP_LT: CCMask = SystemZ::CCMASK_CMP_GT; break; + case SystemZ::CCMASK_CMP_GT: CCMask = SystemZ::CCMASK_CMP_LT; break; + case SystemZ::CCMASK_CMP_LE: CCMask = SystemZ::CCMASK_CMP_GE; break; + case SystemZ::CCMASK_CMP_GE: CCMask = SystemZ::CCMASK_CMP_LE; break; + default: return false; + } + + // Return the updated CCReg link. + CCReg = IPM->getOperand(0); + return true; + } + + return false; } SDValue SystemZTargetLowering::combineBR_CCMASK( diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp index b03b4edaa4abc..8aab5c2c49998 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -557,80 +557,6 @@ bool SystemZInstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, return false; } -// If Reg is a virtual register, return its definition, otherwise return null. -static MachineInstr *getDef(unsigned Reg, - const MachineRegisterInfo *MRI) { - if (TargetRegisterInfo::isPhysicalRegister(Reg)) - return nullptr; - return MRI->getUniqueVRegDef(Reg); -} - -// Return true if MI is a shift of type Opcode by Imm bits. -static bool isShift(MachineInstr *MI, unsigned Opcode, int64_t Imm) { - return (MI->getOpcode() == Opcode && - !MI->getOperand(2).getReg() && - MI->getOperand(3).getImm() == Imm); -} - -// If the destination of MI has no uses, delete it as dead. -static void eraseIfDead(MachineInstr *MI, const MachineRegisterInfo *MRI) { - if (MRI->use_nodbg_empty(MI->getOperand(0).getReg())) - MI->eraseFromParent(); -} - -// Compare compares SrcReg against zero. Check whether SrcReg contains -// the result of an IPM sequence whose input CC survives until Compare, -// and whether Compare is therefore redundant. Delete it and return -// true if so. -static bool removeIPMBasedCompare(MachineInstr &Compare, unsigned SrcReg, - const MachineRegisterInfo *MRI, - const TargetRegisterInfo *TRI) { - MachineInstr *LGFR = nullptr; - MachineInstr *RLL = getDef(SrcReg, MRI); - if (RLL && RLL->getOpcode() == SystemZ::LGFR) { - LGFR = RLL; - RLL = getDef(LGFR->getOperand(1).getReg(), MRI); - } - if (!RLL || !isShift(RLL, SystemZ::RLL, 31)) - return false; - - MachineInstr *SRL = getDef(RLL->getOperand(1).getReg(), MRI); - if (!SRL || !isShift(SRL, SystemZ::SRL, SystemZ::IPM_CC)) - return false; - - MachineInstr *IPM = getDef(SRL->getOperand(1).getReg(), MRI); - if (!IPM || IPM->getOpcode() != SystemZ::IPM) - return false; - - // Check that there are no assignments to CC between the IPM and Compare, - if (IPM->getParent() != Compare.getParent()) - return false; - MachineBasicBlock::iterator MBBI = IPM, MBBE = Compare.getIterator(); - for (++MBBI; MBBI != MBBE; ++MBBI) { - MachineInstr &MI = *MBBI; - if (MI.modifiesRegister(SystemZ::CC, TRI)) - return false; - } - - Compare.eraseFromParent(); - if (LGFR) - eraseIfDead(LGFR, MRI); - eraseIfDead(RLL, MRI); - eraseIfDead(SRL, MRI); - eraseIfDead(IPM, MRI); - - return true; -} - -bool SystemZInstrInfo::optimizeCompareInstr( - MachineInstr &Compare, unsigned SrcReg, unsigned SrcReg2, int Mask, - int Value, const MachineRegisterInfo *MRI) const { - assert(!SrcReg2 && "Only optimizing constant comparisons so far"); - bool IsLogical = (Compare.getDesc().TSFlags & SystemZII::IsLogical) != 0; - return Value == 0 && !IsLogical && - removeIPMBasedCompare(Compare, SrcReg, MRI, &RI); -} - bool SystemZInstrInfo::canInsertSelect(const MachineBasicBlock &MBB, ArrayRef Pred, unsigned TrueReg, unsigned FalseReg, diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h index 216139eb7c796..0392430ed872c 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h @@ -208,9 +208,6 @@ class SystemZInstrInfo : public SystemZGenInstrInfo { int *BytesAdded = nullptr) const override; bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, unsigned &SrcReg2, int &Mask, int &Value) const override; - bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg, - unsigned SrcReg2, int Mask, int Value, - const MachineRegisterInfo *MRI) const override; bool canInsertSelect(const MachineBasicBlock&, ArrayRef Cond, unsigned, unsigned, int&, int&, int&) const override; void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, diff --git a/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp b/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp index e0d7bca9a94b9..4592e82eea718 100644 --- a/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp @@ -164,17 +164,17 @@ static SDValue emitCLC(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, } // Convert the current CC value into an integer that is 0 if CC == 0, -// less than zero if CC == 1 and greater than zero if CC >= 2. +// greater than zero if CC == 1 and less than zero if CC >= 2. // The sequence starts with IPM, which puts CC into bits 29 and 28 // of an integer and clears bits 30 and 31. static SDValue addIPMSequence(const SDLoc &DL, SDValue CCReg, SelectionDAG &DAG) { SDValue IPM = DAG.getNode(SystemZISD::IPM, DL, MVT::i32, CCReg); - SDValue SRL = DAG.getNode(ISD::SRL, DL, MVT::i32, IPM, - DAG.getConstant(SystemZ::IPM_CC, DL, MVT::i32)); - SDValue ROTL = DAG.getNode(ISD::ROTL, DL, MVT::i32, SRL, - DAG.getConstant(31, DL, MVT::i32)); - return ROTL; + SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, IPM, + DAG.getConstant(30 - SystemZ::IPM_CC, DL, MVT::i32)); + SDValue SRA = DAG.getNode(ISD::SRA, DL, MVT::i32, SHL, + DAG.getConstant(30, DL, MVT::i32)); + return SRA; } std::pair SystemZSelectionDAGInfo::EmitTargetCodeForMemcmp( @@ -184,7 +184,8 @@ std::pair SystemZSelectionDAGInfo::EmitTargetCodeForMemcmp( if (auto *CSize = dyn_cast(Size)) { uint64_t Bytes = CSize->getZExtValue(); assert(Bytes > 0 && "Caller should have handled 0-size case"); - SDValue CCReg = emitCLC(DAG, DL, Chain, Src1, Src2, Bytes); + // Swap operands to invert CC == 1 vs. CC == 2 cases. + SDValue CCReg = emitCLC(DAG, DL, Chain, Src2, Src1, Bytes); Chain = CCReg.getValue(1); return std::make_pair(addIPMSequence(DL, CCReg, DAG), Chain); } @@ -232,7 +233,8 @@ std::pair SystemZSelectionDAGInfo::EmitTargetCodeForStrcmp( SDValue Src2, MachinePointerInfo Op1PtrInfo, MachinePointerInfo Op2PtrInfo) const { SDVTList VTs = DAG.getVTList(Src1.getValueType(), MVT::i32, MVT::Other); - SDValue Unused = DAG.getNode(SystemZISD::STRCMP, DL, VTs, Chain, Src1, Src2, + // Swap operands to invert CC == 1 vs. CC == 2 cases. + SDValue Unused = DAG.getNode(SystemZISD::STRCMP, DL, VTs, Chain, Src2, Src1, DAG.getConstant(0, DL, MVT::i32)); SDValue CCReg = Unused.getValue(1); Chain = Unused.getValue(2); diff --git a/llvm/test/CodeGen/SystemZ/memcmp-01.ll b/llvm/test/CodeGen/SystemZ/memcmp-01.ll index ac980e49d60bc..740a86750dd8a 100644 --- a/llvm/test/CodeGen/SystemZ/memcmp-01.ll +++ b/llvm/test/CodeGen/SystemZ/memcmp-01.ll @@ -16,10 +16,10 @@ define i32 @f1(i8 *%src1, i8 *%src2) { ; Check a case where the result is used as an integer. define i32 @f2(i8 *%src1, i8 *%src2) { ; CHECK-LABEL: f2: -; CHECK: clc 0(2,%r2), 0(%r3) -; CHECK: ipm [[REG:%r[0-5]]] -; CHECK: srl [[REG]], 28 -; CHECK: rll %r2, [[REG]], 31 +; CHECK: clc 0(2,%r3), 0(%r2) +; CHECK: ipm %r2 +; CHECK: sll %r2, 2 +; CHECK: sra %r2, 30 ; CHECK: br %r14 %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 2) ret i32 %res @@ -28,7 +28,7 @@ define i32 @f2(i8 *%src1, i8 *%src2) { ; Check a case where the result is tested for equality. define void @f3(i8 *%src1, i8 *%src2, i32 *%dest) { ; CHECK-LABEL: f3: -; CHECK: clc 0(3,%r2), 0(%r3) +; CHECK: clc 0(3,%r3), 0(%r2) ; CHECK-NEXT: ber %r14 ; CHECK: br %r14 %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 3) @@ -46,7 +46,7 @@ exit: ; Check a case where the result is tested for inequality. define void @f4(i8 *%src1, i8 *%src2, i32 *%dest) { ; CHECK-LABEL: f4: -; CHECK: clc 0(4,%r2), 0(%r3) +; CHECK: clc 0(4,%r3), 0(%r2) ; CHECK-NEXT: blhr %r14 ; CHECK: br %r14 entry: @@ -65,8 +65,8 @@ exit: ; Check a case where the result is tested via slt. define void @f5(i8 *%src1, i8 *%src2, i32 *%dest) { ; CHECK-LABEL: f5: -; CHECK: clc 0(5,%r2), 0(%r3) -; CHECK-NEXT: blr %r14 +; CHECK: clc 0(5,%r3), 0(%r2) +; CHECK-NEXT: bhr %r14 ; CHECK: br %r14 entry: %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 5) @@ -84,8 +84,8 @@ exit: ; Check a case where the result is tested for sgt. define void @f6(i8 *%src1, i8 *%src2, i32 *%dest) { ; CHECK-LABEL: f6: -; CHECK: clc 0(6,%r2), 0(%r3) -; CHECK-NEXT: bhr %r14 +; CHECK: clc 0(6,%r3), 0(%r2) +; CHECK-NEXT: blr %r14 ; CHECK: br %r14 entry: %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 6) @@ -104,10 +104,10 @@ exit: ; an integer and for branching. define i32 @f7(i8 *%src1, i8 *%src2, i32 *%dest) { ; CHECK-LABEL: f7: -; CHECK: clc 0(256,%r2), 0(%r3) -; CHECK: ipm [[REG:%r[0-5]]] -; CHECK: srl [[REG]], 28 -; CHECK: rll %r2, [[REG]], 31 +; CHECK: clc 0(256,%r3), 0(%r2) +; CHECK: ipm %r2 +; CHECK: sll %r2, 2 +; CHECK: sra %r2, 30 ; CHECK: blr %r14 ; CHECK: br %r14 entry: @@ -126,9 +126,9 @@ exit: ; 257 bytes needs two CLCs. define i32 @f8(i8 *%src1, i8 *%src2) { ; CHECK-LABEL: f8: -; CHECK: clc 0(256,%r2), 0(%r3) +; CHECK: clc 0(256,%r3), 0(%r2) ; CHECK: jlh [[LABEL:\..*]] -; CHECK: clc 256(1,%r2), 256(%r3) +; CHECK: clc 256(1,%r3), 256(%r2) ; CHECK: [[LABEL]]: ; CHECK: ipm [[REG:%r[0-5]]] ; CHECK: br %r14 @@ -139,11 +139,11 @@ define i32 @f8(i8 *%src1, i8 *%src2) { ; Test a comparison of 258 bytes in which the CC result can be used directly. define void @f9(i8 *%src1, i8 *%src2, i32 *%dest) { ; CHECK-LABEL: f9: -; CHECK: clc 0(256,%r2), 0(%r3) +; CHECK: clc 0(256,%r3), 0(%r2) ; CHECK: jlh [[LABEL:\..*]] -; CHECK: clc 256(1,%r2), 256(%r3) +; CHECK: clc 256(1,%r3), 256(%r2) ; CHECK: [[LABEL]]: -; CHECK-NEXT: blr %r14 +; CHECK-NEXT: bhr %r14 ; CHECK: br %r14 entry: %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 257) @@ -161,9 +161,9 @@ exit: ; Test the largest size that can use two CLCs. define i32 @f10(i8 *%src1, i8 *%src2) { ; CHECK-LABEL: f10: -; CHECK: clc 0(256,%r2), 0(%r3) +; CHECK: clc 0(256,%r3), 0(%r2) ; CHECK: jlh [[LABEL:\..*]] -; CHECK: clc 256(256,%r2), 256(%r3) +; CHECK: clc 256(256,%r3), 256(%r2) ; CHECK: [[LABEL]]: ; CHECK: ipm [[REG:%r[0-5]]] ; CHECK: br %r14 @@ -174,11 +174,11 @@ define i32 @f10(i8 *%src1, i8 *%src2) { ; Test the smallest size that needs 3 CLCs. define i32 @f11(i8 *%src1, i8 *%src2) { ; CHECK-LABEL: f11: -; CHECK: clc 0(256,%r2), 0(%r3) +; CHECK: clc 0(256,%r3), 0(%r2) ; CHECK: jlh [[LABEL:\..*]] -; CHECK: clc 256(256,%r2), 256(%r3) +; CHECK: clc 256(256,%r3), 256(%r2) ; CHECK: jlh [[LABEL]] -; CHECK: clc 512(1,%r2), 512(%r3) +; CHECK: clc 512(1,%r3), 512(%r2) ; CHECK: [[LABEL]]: ; CHECK: ipm [[REG:%r[0-5]]] ; CHECK: br %r14 @@ -189,11 +189,11 @@ define i32 @f11(i8 *%src1, i8 *%src2) { ; Test the largest size than can use 3 CLCs. define i32 @f12(i8 *%src1, i8 *%src2) { ; CHECK-LABEL: f12: -; CHECK: clc 0(256,%r2), 0(%r3) +; CHECK: clc 0(256,%r3), 0(%r2) ; CHECK: jlh [[LABEL:\..*]] -; CHECK: clc 256(256,%r2), 256(%r3) +; CHECK: clc 256(256,%r3), 256(%r2) ; CHECK: jlh [[LABEL]] -; CHECK: clc 512(256,%r2), 512(%r3) +; CHECK: clc 512(256,%r3), 512(%r2) ; CHECK: [[LABEL]]: ; CHECK: ipm [[REG:%r[0-5]]] ; CHECK: br %r14 @@ -207,12 +207,12 @@ define i32 @f13(i8 *%src1, i8 *%src2) { ; CHECK-LABEL: f13: ; CHECK: lghi [[COUNT:%r[0-5]]], 3 ; CHECK: [[LOOP:.L[^:]*]]: -; CHECK: clc 0(256,%r2), 0(%r3) +; CHECK: clc 0(256,%r3), 0(%r2) ; CHECK: jlh [[LABEL:\..*]] ; CHECK-DAG: la %r2, 256(%r2) ; CHECK-DAG: la %r3, 256(%r3) ; CHECK: brctg [[COUNT]], [[LOOP]] -; CHECK: clc 0(1,%r2), 0(%r3) +; CHECK: clc 0(1,%r3), 0(%r2) ; CHECK: [[LABEL]]: ; CHECK: ipm [[REG:%r[0-5]]] ; CHECK: br %r14 diff --git a/llvm/test/CodeGen/SystemZ/strcmp-01.ll b/llvm/test/CodeGen/SystemZ/strcmp-01.ll index ef05d832e73e9..a3e3bbbb23be7 100644 --- a/llvm/test/CodeGen/SystemZ/strcmp-01.ll +++ b/llvm/test/CodeGen/SystemZ/strcmp-01.ll @@ -9,12 +9,12 @@ define i32 @f1(i8 *%src1, i8 *%src2) { ; CHECK-LABEL: f1: ; CHECK: lhi %r0, 0 ; CHECK: [[LABEL:\.[^:]*]]: -; CHECK: clst %r2, %r3 +; CHECK: clst %r3, %r2 ; CHECK-NEXT: jo [[LABEL]] ; CHECK-NEXT: %bb.{{[0-9]+}} -; CHECK-NEXT: ipm [[REG:%r[0-5]]] -; CHECK: srl [[REG]], 28 -; CHECK: rll %r2, [[REG]], 31 +; CHECK-NEXT: ipm %r2 +; CHECK: sll %r2, 2 +; CHECK: sra %r2, 30 ; CHECK: br %r14 %res = call i32 @strcmp(i8 *%src1, i8 *%src2) ret i32 %res @@ -25,7 +25,7 @@ define void @f2(i8 *%src1, i8 *%src2, i32 *%dest) { ; CHECK-LABEL: f2: ; CHECK: lhi %r0, 0 ; CHECK: [[LABEL:\.[^:]*]]: -; CHECK: clst %r2, %r3 +; CHECK: clst %r3, %r2 ; CHECK-NEXT: jo [[LABEL]] ; CHECK-NEXT: %bb.{{[0-9]+}} ; CHECK-NEXT: ber %r14 @@ -48,12 +48,12 @@ define i32 @f3(i8 *%src1, i8 *%src2, i32 *%dest) { ; CHECK-LABEL: f3: ; CHECK: lhi %r0, 0 ; CHECK: [[LABEL:\.[^:]*]]: -; CHECK: clst %r2, %r3 +; CHECK: clst %r3, %r2 ; CHECK-NEXT: jo [[LABEL]] ; CHECK-NEXT: %bb.{{[0-9]+}} -; CHECK-NEXT: ipm [[REG:%r[0-5]]] -; CHECK: srl [[REG]], 28 -; CHECK: rll %r2, [[REG]], 31 +; CHECK-NEXT: ipm %r2 +; CHECK: sll %r2, 2 +; CHECK: sra %r2, 30 ; CHECK: blr %r14 ; CHECK: br %r14 entry: From 238045f8cab0e3131a4864f7b4e620470557aba3 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 7 Feb 2019 10:53:51 +0000 Subject: [PATCH 103/274] lld-link: Add some entries to the 8.0 release notes By Nico Weber! Differential revision: https://reviews.llvm.org/D57818 llvm-svn: 353387 --- lld/docs/ReleaseNotes.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst index c02cc586c795e..77971b25ac483 100644 --- a/lld/docs/ReleaseNotes.rst +++ b/lld/docs/ReleaseNotes.rst @@ -49,12 +49,30 @@ COFF Improvements * PDB GUID is set to hash of PDB contents instead to a random byte sequence for build reproducibility. +* ``/pdbsourcepath:`` is now also used to make ``"cwd"``, ``"exe"``, ``"pdb"`` + in the env block of PDB outputs absolute if they are relative, and to make + paths to obj files referenced in PDB outputs absolute if they are relative. + Together with the previous item, this makes it possible to generate + executables and PDBs that are fully deterministic and independent of the + absolute path to the build directory, so that different machines building + the same code in different directories can produce exactly the same output. + * The following flags have been added: ``/force:multiple`` * lld now can link against import libraries produced by GNU tools. * lld can create thunks for ARM, to allow linking images over 16 MB. +* Several speed and memory usage improvements. + +* lld now creates debug info for typedefs. + +* lld can now link obj files produced by ``cl.exe /Z7 /Yc``. + +* lld now understands ``%_PDB%`` and ``%_EXT%`` in ``/pdbaltpath:``. + +* Undefined symbols are now printed in demangled form in addition to raw form. + MinGW Improvements ------------------ From 33fc712af30e4b1963ca8b086bc698446a079f9f Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 7 Feb 2019 10:58:25 +0000 Subject: [PATCH 104/274] Merging r353367: ------------------------------------------------------------------------ r353367 | brad | 2019-02-07 03:06:58 +0100 (Thu, 07 Feb 2019) | 2 lines Add OpenBSD support to be able to get the thread name ------------------------------------------------------------------------ llvm-svn: 353388 --- llvm/lib/Support/Unix/Threading.inc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/llvm/lib/Support/Unix/Threading.inc b/llvm/lib/Support/Unix/Threading.inc index 2d49ce1ad747a..92bec36d6a2da 100644 --- a/llvm/lib/Support/Unix/Threading.inc +++ b/llvm/lib/Support/Unix/Threading.inc @@ -202,6 +202,12 @@ void llvm::get_thread_name(SmallVectorImpl &Name) { char buf[len]; ::pthread_getname_np(::pthread_self(), buf, len); + Name.append(buf, buf + strlen(buf)); +#elif defined(__OpenBSD__) + constexpr uint32_t len = get_max_thread_name_length_impl(); + char buf[len]; + ::pthread_get_name_np(::pthread_self(), buf, len); + Name.append(buf, buf + strlen(buf)); #elif defined(__linux__) #if HAVE_PTHREAD_GETNAME_NP From 7399f70fb2be1d1dc3da819ea3c671bd0b45ed4b Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 7 Feb 2019 11:04:04 +0000 Subject: [PATCH 105/274] Merging r353327: ------------------------------------------------------------------------ r353327 | lebedevri | 2019-02-06 20:17:30 +0100 (Wed, 06 Feb 2019) | 18 lines [clang-tidy] modernize-avoid-c-arrays: avoid main function (PR40604) Summary: The check should ignore the main function, the program entry point. It is not possible to use `std::array<>` for the `argv`. The alternative is to use `char** argv`. Fixes [[ https://bugs.llvm.org/show_bug.cgi?id=40604 | PR40604 ]] Reviewers: JonasToth, aaron.ballman Reviewed By: aaron.ballman Subscribers: xazax.hun, hans, cfe-commits Tags: #clang-tools-extra, #clang Differential Revision: https://reviews.llvm.org/D57787 ------------------------------------------------------------------------ llvm-svn: 353391 --- .../modernize/AvoidCArraysCheck.cpp | 9 ++++++++- .../checks/modernize-avoid-c-arrays.rst | 4 ++++ .../modernize-avoid-c-arrays-ignores-main.cpp | 18 +++++++++++++++++ ...-avoid-c-arrays-ignores-three-arg-main.cpp | 20 +++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 clang-tools-extra/test/clang-tidy/modernize-avoid-c-arrays-ignores-main.cpp create mode 100644 clang-tools-extra/test/clang-tidy/modernize-avoid-c-arrays-ignores-three-arg-main.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp index dd19483295e8d..6ef45ee855244 100644 --- a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp @@ -31,6 +31,12 @@ AST_MATCHER(clang::RecordDecl, isExternCContext) { return Node.isExternCContext(); } +AST_MATCHER(clang::ParmVarDecl, isArgvOfMain) { + const clang::DeclContext *DC = Node.getDeclContext(); + const auto *FD = llvm::dyn_cast(DC); + return FD ? FD->isMain() : false; +} + } // namespace namespace clang { @@ -44,7 +50,8 @@ void AvoidCArraysCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( typeLoc(hasValidBeginLoc(), hasType(arrayType()), - unless(anyOf(hasParent(varDecl(isExternC())), + unless(anyOf(hasParent(parmVarDecl(isArgvOfMain())), + hasParent(varDecl(isExternC())), hasParent(fieldDecl( hasParent(recordDecl(isExternCContext())))), hasAncestor(functionDecl(isExternC()))))) diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize-avoid-c-arrays.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize-avoid-c-arrays.rst index 8f856a524b2d5..d7bc7474e27f8 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize-avoid-c-arrays.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize-avoid-c-arrays.rst @@ -54,3 +54,7 @@ such headers between C code, and C++ code. } } + +Similarly, the ``main()`` function is ignored. Its second and third parameters +can be either ``char* argv[]`` or ``char** argv``, but can not be +``std::array<>``. diff --git a/clang-tools-extra/test/clang-tidy/modernize-avoid-c-arrays-ignores-main.cpp b/clang-tools-extra/test/clang-tidy/modernize-avoid-c-arrays-ignores-main.cpp new file mode 100644 index 0000000000000..6549422f393aa --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/modernize-avoid-c-arrays-ignores-main.cpp @@ -0,0 +1,18 @@ +// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t + +int not_main(int argc, char *argv[]) { + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not declare C-style arrays, use std::array<> instead + int f4[] = {1, 2}; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead +} + +int main(int argc, char *argv[]) { + int f5[] = {1, 2}; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead + + auto not_main = [](int argc, char *argv[]) { + // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: do not declare C-style arrays, use std::array<> instead + int f6[] = {1, 2}; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not declare C-style arrays, use std::array<> instead + }; +} diff --git a/clang-tools-extra/test/clang-tidy/modernize-avoid-c-arrays-ignores-three-arg-main.cpp b/clang-tools-extra/test/clang-tidy/modernize-avoid-c-arrays-ignores-three-arg-main.cpp new file mode 100644 index 0000000000000..22a4016f79f4d --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/modernize-avoid-c-arrays-ignores-three-arg-main.cpp @@ -0,0 +1,20 @@ +// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t + +int not_main(int argc, char *argv[], char *argw[]) { + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not declare C-style arrays, use std::array<> instead + // CHECK-MESSAGES: :[[@LINE-2]]:38: warning: do not declare C-style arrays, use std::array<> instead + int f4[] = {1, 2}; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead +} + +int main(int argc, char *argv[], char *argw[]) { + int f5[] = {1, 2}; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead + + auto not_main = [](int argc, char *argv[], char *argw[]) { + // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: do not declare C-style arrays, use std::array<> instead + // CHECK-MESSAGES: :[[@LINE-2]]:46: warning: do not declare C-style arrays, use std::array<> instead + int f6[] = {1, 2}; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not declare C-style arrays, use std::array<> instead + }; +} From 104c654aa953e08c548e44855072447c0dc2ee63 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 7 Feb 2019 11:14:24 +0000 Subject: [PATCH 106/274] Merging r353393: ------------------------------------------------------------------------ r353393 | hans | 2019-02-07 12:13:28 +0100 (Thu, 07 Feb 2019) | 1 line Typo: s/follwing/following ------------------------------------------------------------------------ llvm-svn: 353394 --- clang/include/clang/Driver/Options.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d8155a95775c2..d02d9744d78d4 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -552,9 +552,9 @@ def cuda_compile_host_device : Flag<["--"], "cuda-compile-host-device">, HelpText<"Compile CUDA code for both host and device (default). Has no " "effect on non-CUDA compilations.">; def cuda_include_ptx_EQ : Joined<["--"], "cuda-include-ptx=">, Flags<[DriverOption]>, - HelpText<"Include PTX for the follwing GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">; + HelpText<"Include PTX for the following GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">; def no_cuda_include_ptx_EQ : Joined<["--"], "no-cuda-include-ptx=">, Flags<[DriverOption]>, - HelpText<"Do not include PTX for the follwing GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">; + HelpText<"Do not include PTX for the following GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">; def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, Flags<[DriverOption]>, HelpText<"CUDA GPU architecture (e.g. sm_35). May be specified more than once.">; def hip_link : Flag<["--"], "hip-link">, From 8c33d4fb556779b13ca6d8af60631f1a149fc3bc Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 7 Feb 2019 11:15:27 +0000 Subject: [PATCH 107/274] Re-generate docs/ClangCommandLineReference.rst $ bin/clang-tblgen -gen-opt-docs -I../cfe.src/include -I../cfe.src/include/clang/Driver -I../llvm.src/include ../cfe.src/include/clang/Driver/ClangOptionDocs.td -o ../cfe.src/docs/ClangCommandLineReference.rst llvm-svn: 353395 --- clang/docs/ClangCommandLineReference.rst | 192 ++++++++++++++++------- 1 file changed, 131 insertions(+), 61 deletions(-) diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst index e852c3e387985..3dafac54a02bd 100644 --- a/clang/docs/ClangCommandLineReference.rst +++ b/clang/docs/ClangCommandLineReference.rst @@ -198,6 +198,10 @@ Filename (or -) to write dependency output to Emit Clang AST files for source inputs +.. option:: -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang + +Trivial automatic variable initialization to zero is only here for benchmarks, it'll eventually be removed, and I'm OK with that because I'm only using it to benchmark + .. option:: -exported\_symbols\_list .. option:: -faligned-new= @@ -210,10 +214,6 @@ Use approximate transcendental functions Flush denormal floating point values to zero in CUDA device mode. -.. option:: -fcuda-rdc, -fno-cuda-rdc - -Generate relocatable device code, also known as separate compilation mode. - .. option:: -fcuda-short-ptr, -fno-cuda-short-ptr Use 32-bit pointers for accessing const/local/shared address spaces. @@ -222,6 +222,10 @@ Use 32-bit pointers for accessing const/local/shared address spaces. Reserve register r19 (Hexagon only) +.. option:: -fgpu-rdc, -fcuda-rdc, -fno-gpu-rdc + +Generate relocatable device code, also known as separate compilation mode. + .. option:: -fheinous-gnu-extensions .. option:: -flat\_namespace @@ -254,6 +258,10 @@ Use the gcc toolchain at the given directory Generate CodeView debug information +.. option:: -gcodeview-ghash, -gno-codeview-ghash + +Emit type record hashes in a .debug$H section + .. option:: -headerpad\_max\_install\_names .. option:: -help, --help @@ -288,6 +296,10 @@ Make the next included directory (-I or -F) an indexer header map .. option:: -mbig-endian, -EB +.. option:: -mbranch-protection= + +Enforce targets of indirect branches and function returns + .. option:: --migrate Run the migrator @@ -792,15 +804,7 @@ Don't use blacklist file for sanitizers .. option:: -fparse-all-comments -.. option:: -frecord-command-line, -frecord-gcc-switches, -fno-record-command-line, -fno-record-gcc-switches - -Generate a section named ".GCC.command.line" containing the clang driver -command-line. After linking, the section may contain multiple command lines, -which will be individually terminated by null bytes. Separate arguments within -a command line are combined with spaces; spaces and backslashes within an -argument are escaped with backslashes. This format differs from the format of -the equivalent section produced by GCC with the -frecord-gcc-switches flag. -This option is currently only supported on ELF targets. +.. option:: -frecord-command-line, -fno-record-command-line, -frecord-gcc-switches .. option:: -fsanitize-address-field-padding= @@ -810,20 +814,18 @@ Level of field padding for AddressSanitizer Enable linker dead stripping of globals in AddressSanitizer -.. option:: -fsanitize-address-use-odr-indicator, -fno-sanitize-address-use-odr-indicator - -Enable ODR indicator globals to avoid false ODR violation reports in partially sanitized programs at the cost of an increase in binary size - .. option:: -fsanitize-address-poison-custom-array-cookie, -fno-sanitize-address-poison-custom-array-cookie -Enable "poisoning" array cookies when allocating arrays with a custom operator new\[\] in Address Sanitizer, preventing accesses to the cookies from user code. An array cookie is a small implementation-defined header added to certain array allocations to record metadata such as the length of the array. Accesses to array cookies from user code are technically allowed by the standard but are more likely to be the result of an out-of-bounds array access. - -An operator new\[\] is "custom" if it is not one of the allocation functions provided by the C++ standard library. Array cookies from non-custom allocation functions are always poisoned. +Enable poisoning array cookies when using custom operator new\[\] in AddressSanitizer .. option:: -fsanitize-address-use-after-scope, -fno-sanitize-address-use-after-scope Enable use-after-scope detection in AddressSanitizer +.. option:: -fsanitize-address-use-odr-indicator, -fno-sanitize-address-use-odr-indicator + +Enable ODR indicator globals to avoid false ODR violation reports in partially sanitized programs at the cost of an increase in binary size + .. option:: -fsanitize-blacklist= Path to blacklist file for sanitizers @@ -840,6 +842,10 @@ Generalize pointers in CFI indirect call type signature checks Specify the type of coverage instrumentation for Sanitizers +.. option:: -fsanitize-hwaddress-abi= + +Select the HWAddressSanitizer ABI to target (interceptor or platform, default interceptor) + .. option:: -fsanitize-link-c++-runtime .. option:: -fsanitize-memory-track-origins, -fno-sanitize-memory-track-origins @@ -1072,6 +1078,10 @@ Set directory to include search path with prefix Add directory to SYSTEM include search path, absolute paths are relative to -isysroot +.. option:: --libomptarget-nvptx-path= + +Path to libomptarget-nvptx libraries + .. option:: --ptxas-path= Path to ptxas (used for compiling CUDA code) @@ -1283,6 +1293,8 @@ Enable C++ static destructor registration (the default) Instrument control-flow architecture protection. Options: return, branch, full, none. +.. option:: -fcf-runtime-abi= + .. option:: -fchar8\_t, -fno-char8\_t Enable C++ builtin type char8\_t @@ -1343,6 +1355,10 @@ Emit macro debug information remap file source paths in debug info +.. option:: -fdebug-ranges-base-address, -fno-debug-ranges-base-address + +Use DWARF base address selection entries in debug\_ranges + .. option:: -fdebug-types-section, -fno-debug-types-section Place debug types in their own section (ELF Only) @@ -1651,6 +1667,8 @@ Synthesize retain and release calls for Objective-C pointers Use EH-safe code when synthesizing retains and releases in -fobjc-arc +.. option:: -fobjc-convert-messages-to-runtime-calls, -fno-objc-convert-messages-to-runtime-calls + .. option:: -fobjc-exceptions, -fno-objc-exceptions Enable Objective-C exceptions @@ -1737,6 +1755,14 @@ Load the named plugin (dynamic shared object) .. option:: -fprofile-dir= +.. option:: -fprofile-exclude-files= + +Instrument only functions from files where names don't match all the regexes separated by a semi-colon + +.. option:: -fprofile-filter-files= + +Instrument only functions from files where names match any regex separated by a semi-colon + .. option:: -fprofile-generate, -fno-profile-generate Generate instrumented code to collect execution counts into default.profraw (overridden by LLVM\_PROFILE\_FILE env var) @@ -1765,6 +1791,10 @@ Generate instrumented code to collect execution counts into (overridden b Use instrumentation data for profile-guided optimization +.. option:: -fprofile-remapping-file=, -fprofile-remapping-file + +Use the remappings described in to match the profile data against names in the program + .. option:: -fprofile-sample-accurate, -fauto-profile-accurate, -fno-profile-sample-accurate Specifies that the sample profile is accurate. If the sample @@ -1876,19 +1906,23 @@ Enable the superword-level parallelism vectorization passes Provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF +.. option:: -fsplit-lto-unit, -fno-split-lto-unit + +Enables splitting of the LTO unit. + .. option:: -fsplit-stack .. option:: -fstack-protector, -fno-stack-protector -Enable stack protectors for functions potentially vulnerable to stack smashing +Enable stack protectors for some functions vulnerable to stack smashing. This uses a loose heuristic which considers functions vulnerable if they contain a char (or 8bit integer) array or constant sized calls to alloca, which are of greater size than ssp-buffer-size (default: 8 bytes). All variable sized calls to alloca are considered vulnerable .. option:: -fstack-protector-all -Force the usage of stack protectors for all functions +Enable stack protectors for all functions .. option:: -fstack-protector-strong -Use a strong heuristic to apply stack protectors to functions +Enable stack protectors for some functions vulnerable to stack smashing. Compared to -fstack-protector, this uses a stronger heuristic that includes functions containing arrays of any size (and any type), as well as any calls to alloca or the taking of an address from a local variable .. option:: -fstack-size-section, -fno-stack-size-section @@ -1962,6 +1996,10 @@ Specify the function to be called on overflow Process trigraph sequences +.. option:: -ftrivial-auto-var-init= + +Initialize trivial automatic stack variables: uninitialized (default) \| pattern + .. option:: -funique-section-names, -fno-unique-section-names Use unique names for text and data sections (ELF Only) @@ -2000,6 +2038,10 @@ Enable the loop vectorization passes .. option:: -fverbose-asm, -fno-verbose-asm +.. option:: -fvisibility-global-new-delete-hidden + +Give global C++ operator new and delete declarations hidden visibility + .. option:: -fvisibility-inlines-hidden Give inline C++ member functions hidden visibility by default @@ -2162,7 +2204,7 @@ Link stack frames through backchain on System Z .. option:: -mconsole -.. option:: -mcpu=, -mv5 (equivalent to -mcpu=hexagonv5), -mv55 (equivalent to -mcpu=hexagonv55), -mv60 (equivalent to -mcpu=hexagonv60), -mv62 (equivalent to -mcpu=hexagonv62), -mv65 (equivalent to -mcpu=hexagonv65) +.. option:: -mcpu=, -mv5 (equivalent to -mcpu=hexagonv5), -mv55 (equivalent to -mcpu=hexagonv55), -mv60 (equivalent to -mcpu=hexagonv60), -mv62 (equivalent to -mcpu=hexagonv62), -mv65 (equivalent to -mcpu=hexagonv65), -mv66 (equivalent to -mcpu=hexagonv66) .. option:: -mcrc, -mno-crc @@ -2196,6 +2238,8 @@ Enable merging of globals .. option:: -mhwdiv=, --mhwdiv , --mhwdiv= +.. option:: -mhwmult= + .. option:: -miamcu, -mno-iamcu Use Intel MCU ABI @@ -2272,6 +2316,8 @@ Select return address signing scope Use software floating point +.. option:: -mspeculative-load-hardening, -mno-speculative-load-hardening + .. option:: -mstack-alignment= Set the stack alignment @@ -2296,6 +2342,10 @@ The thread model to use, e.g. posix, single (posix by default) .. option:: -mthumb, -mno-thumb +.. option:: -mtls-direct-seg-refs, -mno-tls-direct-seg-refs + +Enable direct TLS access through segment registers (default) + .. option:: -mtune= .. option:: -mtvos-version-min=, -mappletvos-version-min= @@ -2314,41 +2364,33 @@ The thread model to use, e.g. posix, single (posix by default) AARCH64 ------- -.. option:: -ffixed-x1 - -Reserve the x1 register (AArch64 only) - -.. option:: -ffixed-x2 - -Reserve the x2 register (AArch64 only) - -.. option:: -ffixed-x3 +.. option:: -fcall-saved-x10 -Reserve the x3 register (AArch64 only) +Make the x10 register call-saved (AArch64 only) -.. option:: -ffixed-x4 +.. option:: -fcall-saved-x11 -Reserve the x4 register (AArch64 only) +Make the x11 register call-saved (AArch64 only) -.. option:: -ffixed-x5 +.. option:: -fcall-saved-x12 -Reserve the x5 register (AArch64 only) +Make the x12 register call-saved (AArch64 only) -.. option:: -ffixed-x6 +.. option:: -fcall-saved-x13 -Reserve the x6 register (AArch64 only) +Make the x13 register call-saved (AArch64 only) -.. option:: -ffixed-x7 +.. option:: -fcall-saved-x14 -Reserve the x7 register (AArch64 only) +Make the x14 register call-saved (AArch64 only) -.. option:: -ffixed-x18 +.. option:: -fcall-saved-x15 -Reserve the x18 register (AArch64 only) +Make the x15 register call-saved (AArch64 only) -.. option:: -ffixed-x20 +.. option:: -fcall-saved-x18 -Reserve the x20 register (AArch64 only) +Make the x18 register call-saved (AArch64 only) .. option:: -fcall-saved-x8 @@ -2358,33 +2400,41 @@ Make the x8 register call-saved (AArch64 only) Make the x9 register call-saved (AArch64 only) -.. option:: -fcall-saved-x10 +.. option:: -ffixed-x1 -Make the x10 register call-saved (AArch64 only) +Reserve the 1 register (AArch64 only) -.. option:: -fcall-saved-x11 +.. option:: -ffixed-x18 -Make the x11 register call-saved (AArch64 only) +Reserve the 18 register (AArch64 only) -.. option:: -fcall-saved-x12 +.. option:: -ffixed-x2 -Make the x12 register call-saved (AArch64 only) +Reserve the 2 register (AArch64 only) -.. option:: -fcall-saved-x13 +.. option:: -ffixed-x20 -Make the x13 register call-saved (AArch64 only) +Reserve the 20 register (AArch64 only) -.. option:: -fcall-saved-x14 +.. option:: -ffixed-x3 -Make the x14 register call-saved (AArch64 only) +Reserve the 3 register (AArch64 only) -.. option:: -fcall-saved-x15 +.. option:: -ffixed-x4 -Make the x15 register call-saved (AArch64 only) +Reserve the 4 register (AArch64 only) -.. option:: -fcall-saved-x18 +.. option:: -ffixed-x5 -Make the x18 register call-saved (AArch64 only) +Reserve the 5 register (AArch64 only) + +.. option:: -ffixed-x6 + +Reserve the 6 register (AArch64 only) + +.. option:: -ffixed-x7 + +Reserve the 7 register (AArch64 only) .. option:: -mfix-cortex-a53-835769, -mno-fix-cortex-a53-835769 @@ -2396,6 +2446,14 @@ Generate code which only uses the general purpose registers (AArch64 only) AMDGPU ------ +.. option:: -mcode-object-v3, -mno-code-object-v3 + +Enable code object v3 (AMDGPU only) + +.. option:: -msram-ecc, -mno-sram-ecc + +Enable SRAM ECC (AMDGPU only) + .. option:: -mxnack, -mno-xnack Enable XNACK (AMDGPU only) @@ -2594,6 +2652,8 @@ WebAssembly .. option:: -msimd128, -mno-simd128 +.. option:: -munimplemented-simd128, -mno-unimplemented-simd128 + X86 --- .. option:: -m3dnow, -mno-3dnow @@ -2811,6 +2871,10 @@ ___________ .. option:: -ggdb3 +.. option:: -gline-directives-only + +Emit debug line info directives only + .. option:: -gline-tables-only, -g1, -gmlt Emit debug line number tables only @@ -2841,10 +2905,16 @@ Embed source text in DWARF debug sections .. option:: -gpubnames, -gno-pubnames -.. option:: -grecord-command-line, -grecord-gcc-switches, -gno-record-command-line, -gno-record-gcc-switches +.. option:: -grecord-command-line, -gno-record-command-line, -grecord-gcc-switches .. option:: -gsplit-dwarf +.. program:: clang1 +.. option:: -gsplit-dwarf= +.. program:: clang + +Set DWARF fission mode to either 'split' or 'single' + .. option:: -gstrict-dwarf, -gno-strict-dwarf .. option:: -gz From cb2d048c9de8f9085efd9f0a1aca6c39cef5c44b Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 7 Feb 2019 11:16:32 +0000 Subject: [PATCH 108/274] Generate docs/AttributeReference.rst $ bin/clang-tblgen -gen-attr-docs -I../cfe.src/include ../cfe.src/include/clang/Basic/Attr.td -o ../cfe.src/docs/AttributeReference.rst llvm-svn: 353396 --- clang/docs/AttributeReference.rst | 5175 ++++++++++++++++++++++++++++- 1 file changed, 5169 insertions(+), 6 deletions(-) diff --git a/clang/docs/AttributeReference.rst b/clang/docs/AttributeReference.rst index a763ddeaeb106..01938f64f56c1 100644 --- a/clang/docs/AttributeReference.rst +++ b/clang/docs/AttributeReference.rst @@ -1,13 +1,5176 @@ .. ------------------------------------------------------------------- NOTE: This file is automatically generated by running clang-tblgen - -gen-attr-docs. Do not edit this file by hand!! The contents for - this file are automatically generated by a server-side process. - - Please do not commit this file. The file exists for local testing - purposes only. + -gen-attr-docs. Do not edit this file by hand!! ------------------------------------------------------------------- =================== Attributes in Clang -=================== \ No newline at end of file +=================== +.. contents:: + :local: + +.. |br| raw:: html + +
+ +Introduction +============ + +This page lists the attributes currently supported by Clang. + +Function Attributes +=================== + + +#pragma omp declare simd +------------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","","","``omp declare simd``","" + +The `declare simd` construct can be applied to a function to enable the creation +of one or more versions that can process multiple arguments using SIMD +instructions from a single invocation in a SIMD loop. The `declare simd` +directive is a declarative directive. There may be multiple `declare simd` +directives for a function. The use of a `declare simd` construct on a function +enables the creation of SIMD versions of the associated function that can be +used to process multiple arguments from a single invocation from a SIMD loop +concurrently. +The syntax of the `declare simd` construct is as follows: + + .. code-block:: none + + #pragma omp declare simd [clause[[,] clause] ...] new-line + [#pragma omp declare simd [clause[[,] clause] ...] new-line] + [...] + function definition or declaration + +where clause is one of the following: + + .. code-block:: none + + simdlen(length) + linear(argument-list[:constant-linear-step]) + aligned(argument-list[:alignment]) + uniform(argument-list) + inbranch + notinbranch + + +#pragma omp declare target +-------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","","","``omp declare target``","" + +The `declare target` directive specifies that variables and functions are mapped +to a device for OpenMP offload mechanism. + +The syntax of the declare target directive is as follows: + + .. code-block:: c + + #pragma omp declare target new-line + declarations-definition-seq + #pragma omp end declare target new-line + + +_Noreturn +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","","``_Noreturn``","","" + +A function declared as ``_Noreturn`` shall not return to its caller. The +compiler will generate a diagnostic for a function declared as ``_Noreturn`` +that appears to be capable of returning to its caller. + + +abi_tag +------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``abi_tag``","``gnu::abi_tag``","","","","","Yes" + +The ``abi_tag`` attribute can be applied to a function, variable, class or +inline namespace declaration to modify the mangled name of the entity. It gives +the ability to distinguish between different versions of the same entity but +with different ABI versions supported. For example, a newer version of a class +could have a different set of data members and thus have a different size. Using +the ``abi_tag`` attribute, it is possible to have different mangled names for +a global variable of the class type. Therefore, the old code could keep using +the old manged name and the new code will use the new mangled name with tags. + + +acquire_capability, acquire_shared_capability +--------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``acquire_capability`` |br| ``acquire_shared_capability`` |br| ``exclusive_lock_function`` |br| ``shared_lock_function``","``clang::acquire_capability`` |br| ``clang::acquire_shared_capability``","","","","","" + +Marks a function as acquiring a capability. + + +alloc_align +----------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``alloc_align``","``gnu::alloc_align``","","","","","" + +Use ``__attribute__((alloc_align())`` on a function +declaration to specify that the return value of the function (which must be a +pointer type) is at least as aligned as the value of the indicated parameter. The +parameter is given by its index in the list of formal parameters; the first +parameter has index 1 unless the function is a C++ non-static member function, +in which case the first parameter has index 2 to account for the implicit ``this`` +parameter. + +.. code-block:: c++ + + // The returned pointer has the alignment specified by the first parameter. + void *a(size_t align) __attribute__((alloc_align(1))); + + // The returned pointer has the alignment specified by the second parameter. + void *b(void *v, size_t align) __attribute__((alloc_align(2))); + + // The returned pointer has the alignment specified by the second visible + // parameter, however it must be adjusted for the implicit 'this' parameter. + void *Foo::b(void *v, size_t align) __attribute__((alloc_align(3))); + +Note that this attribute merely informs the compiler that a function always +returns a sufficiently aligned pointer. It does not cause the compiler to +emit code to enforce that alignment. The behavior is undefined if the returned +poitner is not sufficiently aligned. + + +alloc_size +---------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``alloc_size``","``gnu::alloc_size``","","","","","Yes" + +The ``alloc_size`` attribute can be placed on functions that return pointers in +order to hint to the compiler how many bytes of memory will be available at the +returned pointer. ``alloc_size`` takes one or two arguments. + +- ``alloc_size(N)`` implies that argument number N equals the number of + available bytes at the returned pointer. +- ``alloc_size(N, M)`` implies that the product of argument number N and + argument number M equals the number of available bytes at the returned + pointer. + +Argument numbers are 1-based. + +An example of how to use ``alloc_size`` + +.. code-block:: c + + void *my_malloc(int a) __attribute__((alloc_size(1))); + void *my_calloc(int a, int b) __attribute__((alloc_size(1, 2))); + + int main() { + void *const p = my_malloc(100); + assert(__builtin_object_size(p, 0) == 100); + void *const a = my_calloc(20, 5); + assert(__builtin_object_size(a, 0) == 100); + } + +.. Note:: This attribute works differently in clang than it does in GCC. + Specifically, clang will only trace ``const`` pointers (as above); we give up + on pointers that are not marked as ``const``. In the vast majority of cases, + this is unimportant, because LLVM has support for the ``alloc_size`` + attribute. However, this may cause mildly unintuitive behavior when used with + other attributes, such as ``enable_if``. + + +artificial +---------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``artificial``","``gnu::artificial``","","","","","" + +The ``artificial`` attribute can be applied to an inline function. If such a +function is inlined, the attribute indicates that debuggers should associate +the resulting instructions with the call site, rather than with the +corresponding line within the inlined callee. + + +assert_capability, assert_shared_capability +------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``assert_capability`` |br| ``assert_shared_capability``","``clang::assert_capability`` |br| ``clang::assert_shared_capability``","","","","","" + +Marks a function that dynamically tests whether a capability is held, and halts +the program if it is not held. + + +assume_aligned +-------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``assume_aligned``","``gnu::assume_aligned``","","","","","Yes" + +Use ``__attribute__((assume_aligned([,]))`` on a function +declaration to specify that the return value of the function (which must be a +pointer type) has the specified offset, in bytes, from an address with the +specified alignment. The offset is taken to be zero if omitted. + +.. code-block:: c++ + + // The returned pointer value has 32-byte alignment. + void *a() __attribute__((assume_aligned (32))); + + // The returned pointer value is 4 bytes greater than an address having + // 32-byte alignment. + void *b() __attribute__((assume_aligned (32, 4))); + +Note that this attribute provides information to the compiler regarding a +condition that the code already ensures is true. It does not cause the compiler +to enforce the provided alignment assumption. + + +availability +------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``availability``","``clang::availability``","``clang::availability``","","","","Yes" + +The ``availability`` attribute can be placed on declarations to describe the +lifecycle of that declaration relative to operating system versions. Consider +the function declaration for a hypothetical function ``f``: + +.. code-block:: c++ + + void f(void) __attribute__((availability(macos,introduced=10.4,deprecated=10.6,obsoleted=10.7))); + +The availability attribute states that ``f`` was introduced in macOS 10.4, +deprecated in macOS 10.6, and obsoleted in macOS 10.7. This information +is used by Clang to determine when it is safe to use ``f``: for example, if +Clang is instructed to compile code for macOS 10.5, a call to ``f()`` +succeeds. If Clang is instructed to compile code for macOS 10.6, the call +succeeds but Clang emits a warning specifying that the function is deprecated. +Finally, if Clang is instructed to compile code for macOS 10.7, the call +fails because ``f()`` is no longer available. + +The availability attribute is a comma-separated list starting with the +platform name and then including clauses specifying important milestones in the +declaration's lifetime (in any order) along with additional information. Those +clauses can be: + +introduced=\ *version* + The first version in which this declaration was introduced. + +deprecated=\ *version* + The first version in which this declaration was deprecated, meaning that + users should migrate away from this API. + +obsoleted=\ *version* + The first version in which this declaration was obsoleted, meaning that it + was removed completely and can no longer be used. + +unavailable + This declaration is never available on this platform. + +message=\ *string-literal* + Additional message text that Clang will provide when emitting a warning or + error about use of a deprecated or obsoleted declaration. Useful to direct + users to replacement APIs. + +replacement=\ *string-literal* + Additional message text that Clang will use to provide Fix-It when emitting + a warning about use of a deprecated declaration. The Fix-It will replace + the deprecated declaration with the new declaration specified. + +Multiple availability attributes can be placed on a declaration, which may +correspond to different platforms. Only the availability attribute with the +platform corresponding to the target platform will be used; any others will be +ignored. If no availability attribute specifies availability for the current +target platform, the availability attributes are ignored. Supported platforms +are: + +``ios`` + Apple's iOS operating system. The minimum deployment target is specified by + the ``-mios-version-min=*version*`` or ``-miphoneos-version-min=*version*`` + command-line arguments. + +``macos`` + Apple's macOS operating system. The minimum deployment target is + specified by the ``-mmacosx-version-min=*version*`` command-line argument. + ``macosx`` is supported for backward-compatibility reasons, but it is + deprecated. + +``tvos`` + Apple's tvOS operating system. The minimum deployment target is specified by + the ``-mtvos-version-min=*version*`` command-line argument. + +``watchos`` + Apple's watchOS operating system. The minimum deployment target is specified by + the ``-mwatchos-version-min=*version*`` command-line argument. + +A declaration can typically be used even when deploying back to a platform +version prior to when the declaration was introduced. When this happens, the +declaration is `weakly linked +`_, +as if the ``weak_import`` attribute were added to the declaration. A +weakly-linked declaration may or may not be present a run-time, and a program +can determine whether the declaration is present by checking whether the +address of that declaration is non-NULL. + +The flag ``strict`` disallows using API when deploying back to a +platform version prior to when the declaration was introduced. An +attempt to use such API before its introduction causes a hard error. +Weakly-linking is almost always a better API choice, since it allows +users to query availability at runtime. + +If there are multiple declarations of the same entity, the availability +attributes must either match on a per-platform basis or later +declarations must not have availability attributes for that +platform. For example: + +.. code-block:: c + + void g(void) __attribute__((availability(macos,introduced=10.4))); + void g(void) __attribute__((availability(macos,introduced=10.4))); // okay, matches + void g(void) __attribute__((availability(ios,introduced=4.0))); // okay, adds a new platform + void g(void); // okay, inherits both macos and ios availability from above. + void g(void) __attribute__((availability(macos,introduced=10.5))); // error: mismatch + +When one method overrides another, the overriding method can be more widely available than the overridden method, e.g.,: + +.. code-block:: objc + + @interface A + - (id)method __attribute__((availability(macos,introduced=10.4))); + - (id)method2 __attribute__((availability(macos,introduced=10.4))); + @end + + @interface B : A + - (id)method __attribute__((availability(macos,introduced=10.3))); // okay: method moved into base class later + - (id)method __attribute__((availability(macos,introduced=10.5))); // error: this method was available via the base class in 10.4 + @end + +Starting with the macOS 10.12 SDK, the ``API_AVAILABLE`` macro from +```` can simplify the spelling: + +.. code-block:: objc + + @interface A + - (id)method API_AVAILABLE(macos(10.11))); + - (id)otherMethod API_AVAILABLE(macos(10.11), ios(11.0)); + @end + +Also see the documentation for `@available +`_ + + +carries_dependency +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``carries_dependency``","``carries_dependency``","","","","","Yes" + +The ``carries_dependency`` attribute specifies dependency propagation into and +out of functions. + +When specified on a function or Objective-C method, the ``carries_dependency`` +attribute means that the return value carries a dependency out of the function, +so that the implementation need not constrain ordering upon return from that +function. Implementations of the function and its caller may choose to preserve +dependencies instead of emitting memory ordering instructions such as fences. + +Note, this attribute does not change the meaning of the program, but may result +in generation of more efficient code. + + +cf_consumed +----------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``cf_consumed``","``clang::cf_consumed``","``clang::cf_consumed``","","","","Yes" + +The behavior of a function with respect to reference counting for Foundation +(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming +convention (e.g. functions starting with "get" are assumed to return at +``+0``). + +It can be overriden using a family of the following attributes. In +Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to +a function communicates that the object is returned at ``+1``, and the caller +is responsible for freeing it. +Similiarly, the annotation ``__attribute__((ns_returns_not_retained))`` +specifies that the object is returned at ``+0`` and the ownership remains with +the callee. +The annotation ``__attribute__((ns_consumes_self))`` specifies that +the Objective-C method call consumes the reference to ``self``, e.g. by +attaching it to a supplied parameter. +Additionally, parameters can have an annotation +``__attribute__((ns_consumed))``, which specifies that passing an owned object +as that parameter effectively transfers the ownership, and the caller is no +longer responsible for it. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +In C programs using CoreFoundation, a similar set of attributes: +``__attribute__((cf_returns_not_retained))``, +``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))`` +have the same respective semantics when applied to CoreFoundation objects. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject), +the same attribute family is present: +``__attribute__((os_returns_not_retained))``, +``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``, +with the same respective semantics. +Similar to ``__attribute__((ns_consumes_self))``, +``__attribute__((os_consumes_this))`` specifies that the method call consumes +the reference to "this" (e.g., when attaching it to a different object supplied +as a parameter). +Out parameters (parameters the function is meant to write into, +either via pointers-to-pointers or references-to-pointers) +may be annotated with ``__attribute__((os_returns_retained))`` +or ``__attribute__((os_returns_not_retained))`` which specifies that the object +written into the out parameter should (or respectively should not) be released +after use. +Since often out parameters may or may not be written depending on the exit +code of the function, +annotations ``__attribute__((os_returns_retained_on_zero))`` +and ``__attribute__((os_returns_retained_on_non_zero))`` specify that +an out parameter at ``+1`` is written if and only if the function returns a zero +(respectively non-zero) error code. +Observe that return-code-dependent out parameter annotations are only +available for retained out parameters, as non-retained object do not have to be +released by the callee. +These attributes are only used by the Clang Static Analyzer. + +The family of attributes ``X_returns_X_retained`` can be added to functions, +C++ methods, and Objective-C methods and properties. +Attributes ``X_consumed`` can be added to parameters of methods, functions, +and Objective-C methods. + + +cf_returns_not_retained +----------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``cf_returns_not_retained``","``clang::cf_returns_not_retained``","``clang::cf_returns_not_retained``","","","","" + +The behavior of a function with respect to reference counting for Foundation +(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming +convention (e.g. functions starting with "get" are assumed to return at +``+0``). + +It can be overriden using a family of the following attributes. In +Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to +a function communicates that the object is returned at ``+1``, and the caller +is responsible for freeing it. +Similiarly, the annotation ``__attribute__((ns_returns_not_retained))`` +specifies that the object is returned at ``+0`` and the ownership remains with +the callee. +The annotation ``__attribute__((ns_consumes_self))`` specifies that +the Objective-C method call consumes the reference to ``self``, e.g. by +attaching it to a supplied parameter. +Additionally, parameters can have an annotation +``__attribute__((ns_consumed))``, which specifies that passing an owned object +as that parameter effectively transfers the ownership, and the caller is no +longer responsible for it. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +In C programs using CoreFoundation, a similar set of attributes: +``__attribute__((cf_returns_not_retained))``, +``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))`` +have the same respective semantics when applied to CoreFoundation objects. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject), +the same attribute family is present: +``__attribute__((os_returns_not_retained))``, +``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``, +with the same respective semantics. +Similar to ``__attribute__((ns_consumes_self))``, +``__attribute__((os_consumes_this))`` specifies that the method call consumes +the reference to "this" (e.g., when attaching it to a different object supplied +as a parameter). +Out parameters (parameters the function is meant to write into, +either via pointers-to-pointers or references-to-pointers) +may be annotated with ``__attribute__((os_returns_retained))`` +or ``__attribute__((os_returns_not_retained))`` which specifies that the object +written into the out parameter should (or respectively should not) be released +after use. +Since often out parameters may or may not be written depending on the exit +code of the function, +annotations ``__attribute__((os_returns_retained_on_zero))`` +and ``__attribute__((os_returns_retained_on_non_zero))`` specify that +an out parameter at ``+1`` is written if and only if the function returns a zero +(respectively non-zero) error code. +Observe that return-code-dependent out parameter annotations are only +available for retained out parameters, as non-retained object do not have to be +released by the callee. +These attributes are only used by the Clang Static Analyzer. + +The family of attributes ``X_returns_X_retained`` can be added to functions, +C++ methods, and Objective-C methods and properties. +Attributes ``X_consumed`` can be added to parameters of methods, functions, +and Objective-C methods. + + +cf_returns_retained +------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``cf_returns_retained``","``clang::cf_returns_retained``","``clang::cf_returns_retained``","","","","" + +The behavior of a function with respect to reference counting for Foundation +(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming +convention (e.g. functions starting with "get" are assumed to return at +``+0``). + +It can be overriden using a family of the following attributes. In +Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to +a function communicates that the object is returned at ``+1``, and the caller +is responsible for freeing it. +Similiarly, the annotation ``__attribute__((ns_returns_not_retained))`` +specifies that the object is returned at ``+0`` and the ownership remains with +the callee. +The annotation ``__attribute__((ns_consumes_self))`` specifies that +the Objective-C method call consumes the reference to ``self``, e.g. by +attaching it to a supplied parameter. +Additionally, parameters can have an annotation +``__attribute__((ns_consumed))``, which specifies that passing an owned object +as that parameter effectively transfers the ownership, and the caller is no +longer responsible for it. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +In C programs using CoreFoundation, a similar set of attributes: +``__attribute__((cf_returns_not_retained))``, +``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))`` +have the same respective semantics when applied to CoreFoundation objects. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject), +the same attribute family is present: +``__attribute__((os_returns_not_retained))``, +``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``, +with the same respective semantics. +Similar to ``__attribute__((ns_consumes_self))``, +``__attribute__((os_consumes_this))`` specifies that the method call consumes +the reference to "this" (e.g., when attaching it to a different object supplied +as a parameter). +Out parameters (parameters the function is meant to write into, +either via pointers-to-pointers or references-to-pointers) +may be annotated with ``__attribute__((os_returns_retained))`` +or ``__attribute__((os_returns_not_retained))`` which specifies that the object +written into the out parameter should (or respectively should not) be released +after use. +Since often out parameters may or may not be written depending on the exit +code of the function, +annotations ``__attribute__((os_returns_retained_on_zero))`` +and ``__attribute__((os_returns_retained_on_non_zero))`` specify that +an out parameter at ``+1`` is written if and only if the function returns a zero +(respectively non-zero) error code. +Observe that return-code-dependent out parameter annotations are only +available for retained out parameters, as non-retained object do not have to be +released by the callee. +These attributes are only used by the Clang Static Analyzer. + +The family of attributes ``X_returns_X_retained`` can be added to functions, +C++ methods, and Objective-C methods and properties. +Attributes ``X_consumed`` can be added to parameters of methods, functions, +and Objective-C methods. + + +code_seg +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","``code_seg``","","","" + +The ``__declspec(code_seg)`` attribute enables the placement of code into separate +named segments that can be paged or locked in memory individually. This attribute +is used to control the placement of instantiated templates and compiler-generated +code. See the documentation for `__declspec(code_seg)`_ on MSDN. + +.. _`__declspec(code_seg)`: http://msdn.microsoft.com/en-us/library/dn636922.aspx + + +convergent +---------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``convergent``","``clang::convergent``","``clang::convergent``","","","","Yes" + +The ``convergent`` attribute can be placed on a function declaration. It is +translated into the LLVM ``convergent`` attribute, which indicates that the call +instructions of a function with this attribute cannot be made control-dependent +on any additional values. + +In languages designed for SPMD/SIMT programming model, e.g. OpenCL or CUDA, +the call instructions of a function with this attribute must be executed by +all work items or threads in a work group or sub group. + +This attribute is different from ``noduplicate`` because it allows duplicating +function calls if it can be proved that the duplicated function calls are +not made control-dependent on any additional values, e.g., unrolling a loop +executed by all work items. + +Sample usage: +.. code-block:: c + + void convfunc(void) __attribute__((convergent)); + // Setting it as a C++11 attribute is also valid in a C++ program. + // void convfunc(void) [[clang::convergent]]; + + +cpu_dispatch +------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``cpu_dispatch``","``clang::cpu_dispatch``","``clang::cpu_dispatch``","``cpu_dispatch``","","","Yes" + +The ``cpu_specific`` and ``cpu_dispatch`` attributes are used to define and +resolve multiversioned functions. This form of multiversioning provides a +mechanism for declaring versions across translation units and manually +specifying the resolved function list. A specified CPU defines a set of minimum +features that are required for the function to be called. The result of this is +that future processors execute the most restrictive version of the function the +new processor can execute. + +Function versions are defined with ``cpu_specific``, which takes one or more CPU +names as a parameter. For example: + +.. code-block:: c + + // Declares and defines the ivybridge version of single_cpu. + __attribute__((cpu_specific(ivybridge))) + void single_cpu(void){} + + // Declares and defines the atom version of single_cpu. + __attribute__((cpu_specific(atom))) + void single_cpu(void){} + + // Declares and defines both the ivybridge and atom version of multi_cpu. + __attribute__((cpu_specific(ivybridge, atom))) + void multi_cpu(void){} + +A dispatching (or resolving) function can be declared anywhere in a project's +source code with ``cpu_dispatch``. This attribute takes one or more CPU names +as a parameter (like ``cpu_specific``). Functions marked with ``cpu_dispatch`` +are not expected to be defined, only declared. If such a marked function has a +definition, any side effects of the function are ignored; trivial function +bodies are permissible for ICC compatibility. + +.. code-block:: c + + // Creates a resolver for single_cpu above. + __attribute__((cpu_dispatch(ivybridge, atom))) + void single_cpu(void){} + + // Creates a resolver for multi_cpu, but adds a 3rd version defined in another + // translation unit. + __attribute__((cpu_dispatch(ivybridge, atom, sandybridge))) + void multi_cpu(void){} + +Note that it is possible to have a resolving function that dispatches based on +more or fewer options than are present in the program. Specifying fewer will +result in the omitted options not being considered during resolution. Specifying +a version for resolution that isn't defined in the program will result in a +linking failure. + +It is also possible to specify a CPU name of ``generic`` which will be resolved +if the executing processor doesn't satisfy the features required in the CPU +name. The behavior of a program executing on a processor that doesn't satisfy +any option of a multiversioned function is undefined. + + +cpu_specific +------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``cpu_specific``","``clang::cpu_specific``","``clang::cpu_specific``","``cpu_specific``","","","Yes" + +The ``cpu_specific`` and ``cpu_dispatch`` attributes are used to define and +resolve multiversioned functions. This form of multiversioning provides a +mechanism for declaring versions across translation units and manually +specifying the resolved function list. A specified CPU defines a set of minimum +features that are required for the function to be called. The result of this is +that future processors execute the most restrictive version of the function the +new processor can execute. + +Function versions are defined with ``cpu_specific``, which takes one or more CPU +names as a parameter. For example: + +.. code-block:: c + + // Declares and defines the ivybridge version of single_cpu. + __attribute__((cpu_specific(ivybridge))) + void single_cpu(void){} + + // Declares and defines the atom version of single_cpu. + __attribute__((cpu_specific(atom))) + void single_cpu(void){} + + // Declares and defines both the ivybridge and atom version of multi_cpu. + __attribute__((cpu_specific(ivybridge, atom))) + void multi_cpu(void){} + +A dispatching (or resolving) function can be declared anywhere in a project's +source code with ``cpu_dispatch``. This attribute takes one or more CPU names +as a parameter (like ``cpu_specific``). Functions marked with ``cpu_dispatch`` +are not expected to be defined, only declared. If such a marked function has a +definition, any side effects of the function are ignored; trivial function +bodies are permissible for ICC compatibility. + +.. code-block:: c + + // Creates a resolver for single_cpu above. + __attribute__((cpu_dispatch(ivybridge, atom))) + void single_cpu(void){} + + // Creates a resolver for multi_cpu, but adds a 3rd version defined in another + // translation unit. + __attribute__((cpu_dispatch(ivybridge, atom, sandybridge))) + void multi_cpu(void){} + +Note that it is possible to have a resolving function that dispatches based on +more or fewer options than are present in the program. Specifying fewer will +result in the omitted options not being considered during resolution. Specifying +a version for resolution that isn't defined in the program will result in a +linking failure. + +It is also possible to specify a CPU name of ``generic`` which will be resolved +if the executing processor doesn't satisfy the features required in the CPU +name. The behavior of a program executing on a processor that doesn't satisfy +any option of a multiversioned function is undefined. + + +deprecated +---------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``deprecated``","``gnu::deprecated`` |br| ``deprecated``","``deprecated``","``deprecated``","","","" + +The ``deprecated`` attribute can be applied to a function, a variable, or a +type. This is useful when identifying functions, variables, or types that are +expected to be removed in a future version of a program. + +Consider the function declaration for a hypothetical function ``f``: + +.. code-block:: c++ + + void f(void) __attribute__((deprecated("message", "replacement"))); + +When spelled as `__attribute__((deprecated))`, the deprecated attribute can have +two optional string arguments. The first one is the message to display when +emitting the warning; the second one enables the compiler to provide a Fix-It +to replace the deprecated name with a new name. Otherwise, when spelled as +`[[gnu::deprecated]] or [[deprecated]]`, the attribute can have one optional +string argument which is the message to display when emitting the warning. + + +diagnose_if +----------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``diagnose_if``","","","","","","" + +The ``diagnose_if`` attribute can be placed on function declarations to emit +warnings or errors at compile-time if calls to the attributed function meet +certain user-defined criteria. For example: + +.. code-block:: c + + int abs(int a) + __attribute__((diagnose_if(a >= 0, "Redundant abs call", "warning"))); + int must_abs(int a) + __attribute__((diagnose_if(a >= 0, "Redundant abs call", "error"))); + + int val = abs(1); // warning: Redundant abs call + int val2 = must_abs(1); // error: Redundant abs call + int val3 = abs(val); + int val4 = must_abs(val); // Because run-time checks are not emitted for + // diagnose_if attributes, this executes without + // issue. + + +``diagnose_if`` is closely related to ``enable_if``, with a few key differences: + +* Overload resolution is not aware of ``diagnose_if`` attributes: they're + considered only after we select the best candidate from a given candidate set. +* Function declarations that differ only in their ``diagnose_if`` attributes are + considered to be redeclarations of the same function (not overloads). +* If the condition provided to ``diagnose_if`` cannot be evaluated, no + diagnostic will be emitted. + +Otherwise, ``diagnose_if`` is essentially the logical negation of ``enable_if``. + +As a result of bullet number two, ``diagnose_if`` attributes will stack on the +same function. For example: + +.. code-block:: c + + int foo() __attribute__((diagnose_if(1, "diag1", "warning"))); + int foo() __attribute__((diagnose_if(1, "diag2", "warning"))); + + int bar = foo(); // warning: diag1 + // warning: diag2 + int (*fooptr)(void) = foo; // warning: diag1 + // warning: diag2 + + constexpr int supportsAPILevel(int N) { return N < 5; } + int baz(int a) + __attribute__((diagnose_if(!supportsAPILevel(10), + "Upgrade to API level 10 to use baz", "error"))); + int baz(int a) + __attribute__((diagnose_if(!a, "0 is not recommended.", "warning"))); + + int (*bazptr)(int) = baz; // error: Upgrade to API level 10 to use baz + int v = baz(0); // error: Upgrade to API level 10 to use baz + +Query for this feature with ``__has_attribute(diagnose_if)``. + + +disable_tail_calls +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``disable_tail_calls``","``clang::disable_tail_calls``","``clang::disable_tail_calls``","","","","Yes" + +The ``disable_tail_calls`` attribute instructs the backend to not perform tail call optimization inside the marked function. + +For example: + + .. code-block:: c + + int callee(int); + + int foo(int a) __attribute__((disable_tail_calls)) { + return callee(a); // This call is not tail-call optimized. + } + +Marking virtual functions as ``disable_tail_calls`` is legal. + + .. code-block:: c++ + + int callee(int); + + class Base { + public: + [[clang::disable_tail_calls]] virtual int foo1() { + return callee(); // This call is not tail-call optimized. + } + }; + + class Derived1 : public Base { + public: + int foo1() override { + return callee(); // This call is tail-call optimized. + } + }; + + +enable_if +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``enable_if``","","","","","","Yes" + +.. Note:: Some features of this attribute are experimental. The meaning of + multiple enable_if attributes on a single declaration is subject to change in + a future version of clang. Also, the ABI is not standardized and the name + mangling may change in future versions. To avoid that, use asm labels. + +The ``enable_if`` attribute can be placed on function declarations to control +which overload is selected based on the values of the function's arguments. +When combined with the ``overloadable`` attribute, this feature is also +available in C. + +.. code-block:: c++ + + int isdigit(int c); + int isdigit(int c) __attribute__((enable_if(c <= -1 || c > 255, "chosen when 'c' is out of range"))) __attribute__((unavailable("'c' must have the value of an unsigned char or EOF"))); + + void foo(char c) { + isdigit(c); + isdigit(10); + isdigit(-10); // results in a compile-time error. + } + +The enable_if attribute takes two arguments, the first is an expression written +in terms of the function parameters, the second is a string explaining why this +overload candidate could not be selected to be displayed in diagnostics. The +expression is part of the function signature for the purposes of determining +whether it is a redeclaration (following the rules used when determining +whether a C++ template specialization is ODR-equivalent), but is not part of +the type. + +The enable_if expression is evaluated as if it were the body of a +bool-returning constexpr function declared with the arguments of the function +it is being applied to, then called with the parameters at the call site. If the +result is false or could not be determined through constant expression +evaluation, then this overload will not be chosen and the provided string may +be used in a diagnostic if the compile fails as a result. + +Because the enable_if expression is an unevaluated context, there are no global +state changes, nor the ability to pass information from the enable_if +expression to the function body. For example, suppose we want calls to +strnlen(strbuf, maxlen) to resolve to strnlen_chk(strbuf, maxlen, size of +strbuf) only if the size of strbuf can be determined: + +.. code-block:: c++ + + __attribute__((always_inline)) + static inline size_t strnlen(const char *s, size_t maxlen) + __attribute__((overloadable)) + __attribute__((enable_if(__builtin_object_size(s, 0) != -1))), + "chosen when the buffer size is known but 'maxlen' is not"))) + { + return strnlen_chk(s, maxlen, __builtin_object_size(s, 0)); + } + +Multiple enable_if attributes may be applied to a single declaration. In this +case, the enable_if expressions are evaluated from left to right in the +following manner. First, the candidates whose enable_if expressions evaluate to +false or cannot be evaluated are discarded. If the remaining candidates do not +share ODR-equivalent enable_if expressions, the overload resolution is +ambiguous. Otherwise, enable_if overload resolution continues with the next +enable_if attribute on the candidates that have not been discarded and have +remaining enable_if attributes. In this way, we pick the most specific +overload out of a number of viable overloads using enable_if. + +.. code-block:: c++ + + void f() __attribute__((enable_if(true, ""))); // #1 + void f() __attribute__((enable_if(true, ""))) __attribute__((enable_if(true, ""))); // #2 + + void g(int i, int j) __attribute__((enable_if(i, ""))); // #1 + void g(int i, int j) __attribute__((enable_if(j, ""))) __attribute__((enable_if(true))); // #2 + +In this example, a call to f() is always resolved to #2, as the first enable_if +expression is ODR-equivalent for both declarations, but #1 does not have another +enable_if expression to continue evaluating, so the next round of evaluation has +only a single candidate. In a call to g(1, 1), the call is ambiguous even though +#2 has more enable_if attributes, because the first enable_if expressions are +not ODR-equivalent. + +Query for this feature with ``__has_attribute(enable_if)``. + +Note that functions with one or more ``enable_if`` attributes may not have +their address taken, unless all of the conditions specified by said +``enable_if`` are constants that evaluate to ``true``. For example: + +.. code-block:: c + + const int TrueConstant = 1; + const int FalseConstant = 0; + int f(int a) __attribute__((enable_if(a > 0, ""))); + int g(int a) __attribute__((enable_if(a == 0 || a != 0, ""))); + int h(int a) __attribute__((enable_if(1, ""))); + int i(int a) __attribute__((enable_if(TrueConstant, ""))); + int j(int a) __attribute__((enable_if(FalseConstant, ""))); + + void fn() { + int (*ptr)(int); + ptr = &f; // error: 'a > 0' is not always true + ptr = &g; // error: 'a == 0 || a != 0' is not a truthy constant + ptr = &h; // OK: 1 is a truthy constant + ptr = &i; // OK: 'TrueConstant' is a truthy constant + ptr = &j; // error: 'FalseConstant' is a constant, but not truthy + } + +Because ``enable_if`` evaluation happens during overload resolution, +``enable_if`` may give unintuitive results when used with templates, depending +on when overloads are resolved. In the example below, clang will emit a +diagnostic about no viable overloads for ``foo`` in ``bar``, but not in ``baz``: + +.. code-block:: c++ + + double foo(int i) __attribute__((enable_if(i > 0, ""))); + void *foo(int i) __attribute__((enable_if(i <= 0, ""))); + template + auto bar() { return foo(I); } + + template + auto baz() { return foo(T::number); } + + struct WithNumber { constexpr static int number = 1; }; + void callThem() { + bar(); + baz(); + } + +This is because, in ``bar``, ``foo`` is resolved prior to template +instantiation, so the value for ``I`` isn't known (thus, both ``enable_if`` +conditions for ``foo`` fail). However, in ``baz``, ``foo`` is resolved during +template instantiation, so the value for ``T::number`` is known. + + +exclude_from_explicit_instantiation +----------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``exclude_from_explicit_instantiation``","``clang::exclude_from_explicit_instantiation``","``clang::exclude_from_explicit_instantiation``","","","","Yes" + +The ``exclude_from_explicit_instantiation`` attribute opts-out a member of a +class template from being part of explicit template instantiations of that +class template. This means that an explicit instantiation will not instantiate +members of the class template marked with the attribute, but also that code +where an extern template declaration of the enclosing class template is visible +will not take for granted that an external instantiation of the class template +would provide those members (which would otherwise be a link error, since the +explicit instantiation won't provide those members). For example, let's say we +don't want the ``data()`` method to be part of libc++'s ABI. To make sure it +is not exported from the dylib, we give it hidden visibility: + + .. code-block:: c++ + + // in + template + class basic_string { + public: + __attribute__((__visibility__("hidden"))) + const value_type* data() const noexcept { ... } + }; + + template class basic_string; + +Since an explicit template instantiation declaration for ``basic_string`` +is provided, the compiler is free to assume that ``basic_string::data()`` +will be provided by another translation unit, and it is free to produce an +external call to this function. However, since ``data()`` has hidden visibility +and the explicit template instantiation is provided in a shared library (as +opposed to simply another translation unit), ``basic_string::data()`` +won't be found and a link error will ensue. This happens because the compiler +assumes that ``basic_string::data()`` is part of the explicit template +instantiation declaration, when it really isn't. To tell the compiler that +``data()`` is not part of the explicit template instantiation declaration, the +``exclude_from_explicit_instantiation`` attribute can be used: + + .. code-block:: c++ + + // in + template + class basic_string { + public: + __attribute__((__visibility__("hidden"))) + __attribute__((exclude_from_explicit_instantiation)) + const value_type* data() const noexcept { ... } + }; + + template class basic_string; + +Now, the compiler won't assume that ``basic_string::data()`` is provided +externally despite there being an explicit template instantiation declaration: +the compiler will implicitly instantiate ``basic_string::data()`` in the +TUs where it is used. + +This attribute can be used on static and non-static member functions of class +templates, static data members of class templates and member classes of class +templates. + + +external_source_symbol +---------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``external_source_symbol``","``clang::external_source_symbol``","``clang::external_source_symbol``","","","","Yes" + +The ``external_source_symbol`` attribute specifies that a declaration originates +from an external source and describes the nature of that source. + +The fact that Clang is capable of recognizing declarations that were defined +externally can be used to provide better tooling support for mixed-language +projects or projects that rely on auto-generated code. For instance, an IDE that +uses Clang and that supports mixed-language projects can use this attribute to +provide a correct 'jump-to-definition' feature. For a concrete example, +consider a protocol that's defined in a Swift file: + +.. code-block:: swift + + @objc public protocol SwiftProtocol { + func method() + } + +This protocol can be used from Objective-C code by including a header file that +was generated by the Swift compiler. The declarations in that header can use +the ``external_source_symbol`` attribute to make Clang aware of the fact +that ``SwiftProtocol`` actually originates from a Swift module: + +.. code-block:: objc + + __attribute__((external_source_symbol(language="Swift",defined_in="module"))) + @protocol SwiftProtocol + @required + - (void) method; + @end + +Consequently, when 'jump-to-definition' is performed at a location that +references ``SwiftProtocol``, the IDE can jump to the original definition in +the Swift source file rather than jumping to the Objective-C declaration in the +auto-generated header file. + +The ``external_source_symbol`` attribute is a comma-separated list that includes +clauses that describe the origin and the nature of the particular declaration. +Those clauses can be: + +language=\ *string-literal* + The name of the source language in which this declaration was defined. + +defined_in=\ *string-literal* + The name of the source container in which the declaration was defined. The + exact definition of source container is language-specific, e.g. Swift's + source containers are modules, so ``defined_in`` should specify the Swift + module name. + +generated_declaration + This declaration was automatically generated by some tool. + +The clauses can be specified in any order. The clauses that are listed above are +all optional, but the attribute has to have at least one clause. + + +flatten +------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``flatten``","``gnu::flatten``","","","","","Yes" + +The ``flatten`` attribute causes calls within the attributed function to +be inlined unless it is impossible to do so, for example if the body of the +callee is unavailable or if the callee has the ``noinline`` attribute. + + +force_align_arg_pointer +----------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``force_align_arg_pointer``","``gnu::force_align_arg_pointer``","","","","","" + +Use this attribute to force stack alignment. + +Legacy x86 code uses 4-byte stack alignment. Newer aligned SSE instructions +(like 'movaps') that work with the stack require operands to be 16-byte aligned. +This attribute realigns the stack in the function prologue to make sure the +stack can be used with SSE instructions. + +Note that the x86_64 ABI forces 16-byte stack alignment at the call site. +Because of this, 'force_align_arg_pointer' is not needed on x86_64, except in +rare cases where the caller does not align the stack properly (e.g. flow +jumps from i386 arch code). + + .. code-block:: c + + __attribute__ ((force_align_arg_pointer)) + void f () { + ... + } + + +format +------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``format``","``gnu::format``","","","","","" + +Clang supports the ``format`` attribute, which indicates that the function +accepts a ``printf`` or ``scanf``-like format string and corresponding +arguments or a ``va_list`` that contains these arguments. + +Please see `GCC documentation about format attribute +`_ to find details +about attribute syntax. + +Clang implements two kinds of checks with this attribute. + +#. Clang checks that the function with the ``format`` attribute is called with + a format string that uses format specifiers that are allowed, and that + arguments match the format string. This is the ``-Wformat`` warning, it is + on by default. + +#. Clang checks that the format string argument is a literal string. This is + the ``-Wformat-nonliteral`` warning, it is off by default. + + Clang implements this mostly the same way as GCC, but there is a difference + for functions that accept a ``va_list`` argument (for example, ``vprintf``). + GCC does not emit ``-Wformat-nonliteral`` warning for calls to such + functions. Clang does not warn if the format string comes from a function + parameter, where the function is annotated with a compatible attribute, + otherwise it warns. For example: + + .. code-block:: c + + __attribute__((__format__ (__scanf__, 1, 3))) + void foo(const char* s, char *buf, ...) { + va_list ap; + va_start(ap, buf); + + vprintf(s, ap); // warning: format string is not a string literal + } + + In this case we warn because ``s`` contains a format string for a + ``scanf``-like function, but it is passed to a ``printf``-like function. + + If the attribute is removed, clang still warns, because the format string is + not a string literal. + + Another example: + + .. code-block:: c + + __attribute__((__format__ (__printf__, 1, 3))) + void foo(const char* s, char *buf, ...) { + va_list ap; + va_start(ap, buf); + + vprintf(s, ap); // warning + } + + In this case Clang does not warn because the format string ``s`` and + the corresponding arguments are annotated. If the arguments are + incorrect, the caller of ``foo`` will receive a warning. + + +gnu_inline +---------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``gnu_inline``","``gnu::gnu_inline``","","","","","Yes" + +The ``gnu_inline`` changes the meaning of ``extern inline`` to use GNU inline +semantics, meaning: + +* If any declaration that is declared ``inline`` is not declared ``extern``, +then the ``inline`` keyword is just a hint. In particular, an out-of-line +definition is still emitted for a function with external linkage, even if all +call sites are inlined, unlike in C99 and C++ inline semantics. + +* If all declarations that are declared ``inline`` are also declared +``extern``, then the function body is present only for inlining and no +out-of-line version is emitted. + +Some important consequences: ``static inline`` emits an out-of-line +version if needed, a plain ``inline`` definition emits an out-of-line version +always, and an ``extern inline`` definition (in a header) followed by a +(non-``extern``) ``inline`` declaration in a source file emits an out-of-line +version of the function in that source file but provides the function body for +inlining to all includers of the header. + +Either ``__GNUC_GNU_INLINE__`` (GNU inline semantics) or +``__GNUC_STDC_INLINE__`` (C99 semantics) will be defined (they are mutually +exclusive). If ``__GNUC_STDC_INLINE__`` is defined, then the ``gnu_inline`` +function attribute can be used to get GNU inline semantics on a per function +basis. If ``__GNUC_GNU_INLINE__`` is defined, then the translation unit is +already being compiled with GNU inline semantics as the implied default. It is +unspecified which macro is defined in a C++ compilation. + +GNU inline semantics are the default behavior with ``-std=gnu89``, +``-std=c89``, ``-std=c94``, or ``-fgnu89-inline``. + + +ifunc +----- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``ifunc``","``gnu::ifunc``","","","","","Yes" + +``__attribute__((ifunc("resolver")))`` is used to mark that the address of a declaration should be resolved at runtime by calling a resolver function. + +The symbol name of the resolver function is given in quotes. A function with this name (after mangling) must be defined in the current translation unit; it may be ``static``. The resolver function should return a pointer. + +The ``ifunc`` attribute may only be used on a function declaration. A function declaration with an ``ifunc`` attribute is considered to be a definition of the declared entity. The entity must not have weak linkage; for example, in C++, it cannot be applied to a declaration if a definition at that location would be considered inline. + +Not all targets support this attribute. ELF target support depends on both the linker and runtime linker, and is available in at least lld 4.0 and later, binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later. Non-ELF targets currently do not support this attribute. + + +internal_linkage +---------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``internal_linkage``","``clang::internal_linkage``","``clang::internal_linkage``","","","","Yes" + +The ``internal_linkage`` attribute changes the linkage type of the declaration to internal. +This is similar to C-style ``static``, but can be used on classes and class methods. When applied to a class definition, +this attribute affects all methods and static data members of that class. +This can be used to contain the ABI of a C++ library by excluding unwanted class methods from the export tables. + + +interrupt (ARM) +--------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``interrupt``","``gnu::interrupt``","","","","","" + +Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on +ARM targets. This attribute may be attached to a function definition and +instructs the backend to generate appropriate function entry/exit code so that +it can be used directly as an interrupt service routine. + +The parameter passed to the interrupt attribute is optional, but if +provided it must be a string literal with one of the following values: "IRQ", +"FIQ", "SWI", "ABORT", "UNDEF". + +The semantics are as follows: + +- If the function is AAPCS, Clang instructs the backend to realign the stack to + 8 bytes on entry. This is a general requirement of the AAPCS at public + interfaces, but may not hold when an exception is taken. Doing this allows + other AAPCS functions to be called. +- If the CPU is M-class this is all that needs to be done since the architecture + itself is designed in such a way that functions obeying the normal AAPCS ABI + constraints are valid exception handlers. +- If the CPU is not M-class, the prologue and epilogue are modified to save all + non-banked registers that are used, so that upon return the user-mode state + will not be corrupted. Note that to avoid unnecessary overhead, only + general-purpose (integer) registers are saved in this way. If VFP operations + are needed, that state must be saved manually. + + Specifically, interrupt kinds other than "FIQ" will save all core registers + except "lr" and "sp". "FIQ" interrupts will save r0-r7. +- If the CPU is not M-class, the return instruction is changed to one of the + canonical sequences permitted by the architecture for exception return. Where + possible the function itself will make the necessary "lr" adjustments so that + the "preferred return address" is selected. + + Unfortunately the compiler is unable to make this guarantee for an "UNDEF" + handler, where the offset from "lr" to the preferred return address depends on + the execution state of the code which generated the exception. In this case + a sequence equivalent to "movs pc, lr" will be used. + + +interrupt (AVR) +--------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``interrupt``","``gnu::interrupt``","","","","","Yes" + +Clang supports the GNU style ``__attribute__((interrupt))`` attribute on +AVR targets. This attribute may be attached to a function definition and instructs +the backend to generate appropriate function entry/exit code so that it can be used +directly as an interrupt service routine. + +On the AVR, the hardware globally disables interrupts when an interrupt is executed. +The first instruction of an interrupt handler declared with this attribute is a SEI +instruction to re-enable interrupts. See also the signal attribute that +does not insert a SEI instruction. + + +interrupt (MIPS) +---------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``interrupt``","``gnu::interrupt``","","","","","Yes" + +Clang supports the GNU style ``__attribute__((interrupt("ARGUMENT")))`` attribute on +MIPS targets. This attribute may be attached to a function definition and instructs +the backend to generate appropriate function entry/exit code so that it can be used +directly as an interrupt service routine. + +By default, the compiler will produce a function prologue and epilogue suitable for +an interrupt service routine that handles an External Interrupt Controller (eic) +generated interrupt. This behaviour can be explicitly requested with the "eic" +argument. + +Otherwise, for use with vectored interrupt mode, the argument passed should be +of the form "vector=LEVEL" where LEVEL is one of the following values: +"sw0", "sw1", "hw0", "hw1", "hw2", "hw3", "hw4", "hw5". The compiler will +then set the interrupt mask to the corresponding level which will mask all +interrupts up to and including the argument. + +The semantics are as follows: + +- The prologue is modified so that the Exception Program Counter (EPC) and + Status coprocessor registers are saved to the stack. The interrupt mask is + set so that the function can only be interrupted by a higher priority + interrupt. The epilogue will restore the previous values of EPC and Status. + +- The prologue and epilogue are modified to save and restore all non-kernel + registers as necessary. + +- The FPU is disabled in the prologue, as the floating pointer registers are not + spilled to the stack. + +- The function return sequence is changed to use an exception return instruction. + +- The parameter sets the interrupt mask for the function corresponding to the + interrupt level specified. If no mask is specified the interrupt mask + defaults to "eic". + + +interrupt (RISCV) +----------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``interrupt``","``gnu::interrupt``","","","","","Yes" + +Clang supports the GNU style ``__attribute__((interrupt))`` attribute on RISCV +targets. This attribute may be attached to a function definition and instructs +the backend to generate appropriate function entry/exit code so that it can be +used directly as an interrupt service routine. + +Permissible values for this parameter are ``user``, ``supervisor``, +and ``machine``. If there is no parameter, then it defaults to machine. + +Repeated interrupt attribute on the same declaration will cause a warning +to be emitted. In case of repeated declarations, the last one prevails. + +Refer to: +https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Function-Attributes.html +https://riscv.org/specifications/privileged-isa/ +The RISC-V Instruction Set Manual Volume II: Privileged Architecture +Version 1.10. + + +kernel +------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``kernel``","","","","","","Yes" + +``__attribute__((kernel))`` is used to mark a ``kernel`` function in +RenderScript. + +In RenderScript, ``kernel`` functions are used to express data-parallel +computations. The RenderScript runtime efficiently parallelizes ``kernel`` +functions to run on computational resources such as multi-core CPUs and GPUs. +See the RenderScript_ documentation for more information. + +.. _RenderScript: https://developer.android.com/guide/topics/renderscript/compute.html + + +lifetimebound +------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``lifetimebound``","``clang::lifetimebound``","","","","","" + +The ``lifetimebound`` attribute indicates that a resource owned by +a function parameter or implicit object parameter +is retained by the return value of the annotated function +(or, for a parameter of a constructor, in the value of the constructed object). +It is only supported in C++. + +This attribute provides an experimental implementation of the facility +described in the C++ committee paper [http://wg21.link/p0936r0](P0936R0), +and is subject to change as the design of the corresponding functionality +changes. + + +long_call, far +-------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``long_call`` |br| ``far``","``gnu::long_call`` |br| ``gnu::far``","","","","","Yes" + +Clang supports the ``__attribute__((long_call))``, ``__attribute__((far))``, +and ``__attribute__((near))`` attributes on MIPS targets. These attributes may +only be added to function declarations and change the code generated +by the compiler when directly calling the function. The ``near`` attribute +allows calls to the function to be made using the ``jal`` instruction, which +requires the function to be located in the same naturally aligned 256MB +segment as the caller. The ``long_call`` and ``far`` attributes are synonyms +and require the use of a different call sequence that works regardless +of the distance between the functions. + +These attributes have no effect for position-independent code. + +These attributes take priority over command line switches such +as ``-mlong-calls`` and ``-mno-long-calls``. + + +micromips +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``micromips``","``gnu::micromips``","","","","","Yes" + +Clang supports the GNU style ``__attribute__((micromips))`` and +``__attribute__((nomicromips))`` attributes on MIPS targets. These attributes +may be attached to a function definition and instructs the backend to generate +or not to generate microMIPS code for that function. + +These attributes override the `-mmicromips` and `-mno-micromips` options +on the command line. + + +min_vector_width +---------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``min_vector_width``","``clang::min_vector_width``","``clang::min_vector_width``","","","","Yes" + +Clang supports the ``__attribute__((min_vector_width(width)))`` attribute. This +attribute may be attached to a function and informs the backend that this +function desires vectors of at least this width to be generated. Target-specific +maximum vector widths still apply. This means even if you ask for something +larger than the target supports, you will only get what the target supports. +This attribute is meant to be a hint to control target heuristics that may +generate narrower vectors than what the target hardware supports. + +This is currently used by the X86 target to allow some CPUs that support 512-bit +vectors to be limited to using 256-bit vectors to avoid frequency penalties. +This is currently enabled with the ``-prefer-vector-width=256`` command line +option. The ``min_vector_width`` attribute can be used to prevent the backend +from trying to split vector operations to match the ``prefer-vector-width``. All +X86 vector intrinsics from x86intrin.h already set this attribute. Additionally, +use of any of the X86-specific vector builtins will implicitly set this +attribute on the calling function. The intent is that explicitly writing vector +code using the X86 intrinsics will prevent ``prefer-vector-width`` from +affecting the code. + + +no_caller_saved_registers +------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``no_caller_saved_registers``","``gnu::no_caller_saved_registers``","","","","","" + +Use this attribute to indicate that the specified function has no +caller-saved registers. That is, all registers are callee-saved except for +registers used for passing parameters to the function or returning parameters +from the function. +The compiler saves and restores any modified registers that were not used for +passing or returning arguments to the function. + +The user can call functions specified with the 'no_caller_saved_registers' +attribute from an interrupt handler without saving and restoring all +call-clobbered registers. + +Note that 'no_caller_saved_registers' attribute is not a calling convention. +In fact, it only overrides the decision of which registers should be saved by +the caller, but not how the parameters are passed from the caller to the callee. + +For example: + + .. code-block:: c + + __attribute__ ((no_caller_saved_registers, fastcall)) + void f (int arg1, int arg2) { + ... + } + + In this case parameters 'arg1' and 'arg2' will be passed in registers. + In this case, on 32-bit x86 targets, the function 'f' will use ECX and EDX as + register parameters. However, it will not assume any scratch registers and + should save and restore any modified registers except for ECX and EDX. + + +no_sanitize +----------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``no_sanitize``","``clang::no_sanitize``","``clang::no_sanitize``","","","","Yes" + +Use the ``no_sanitize`` attribute on a function or a global variable +declaration to specify that a particular instrumentation or set of +instrumentations should not be applied. The attribute takes a list of +string literals, which have the same meaning as values accepted by the +``-fno-sanitize=`` flag. For example, +``__attribute__((no_sanitize("address", "thread")))`` specifies that +AddressSanitizer and ThreadSanitizer should not be applied to the +function or variable. + +See :ref:`Controlling Code Generation ` for a +full list of supported sanitizer flags. + + +no_sanitize_address, no_address_safety_analysis +----------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``no_address_safety_analysis`` |br| ``no_sanitize_address`` |br| ``no_sanitize_thread`` |br| ``no_sanitize_memory``","``gnu::no_address_safety_analysis`` |br| ``gnu::no_sanitize_address`` |br| ``gnu::no_sanitize_thread`` |br| ``clang::no_sanitize_memory``","``clang::no_sanitize_memory``","","","","Yes" + +.. _langext-address_sanitizer: + +Use ``__attribute__((no_sanitize_address))`` on a function or a global +variable declaration to specify that address safety instrumentation +(e.g. AddressSanitizer) should not be applied. + + +no_sanitize_memory +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``no_address_safety_analysis`` |br| ``no_sanitize_address`` |br| ``no_sanitize_thread`` |br| ``no_sanitize_memory``","``gnu::no_address_safety_analysis`` |br| ``gnu::no_sanitize_address`` |br| ``gnu::no_sanitize_thread`` |br| ``clang::no_sanitize_memory``","``clang::no_sanitize_memory``","","","","Yes" + +.. _langext-memory_sanitizer: + +Use ``__attribute__((no_sanitize_memory))`` on a function declaration to +specify that checks for uninitialized memory should not be inserted +(e.g. by MemorySanitizer). The function may still be instrumented by the tool +to avoid false positives in other places. + + +no_sanitize_thread +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``no_address_safety_analysis`` |br| ``no_sanitize_address`` |br| ``no_sanitize_thread`` |br| ``no_sanitize_memory``","``gnu::no_address_safety_analysis`` |br| ``gnu::no_sanitize_address`` |br| ``gnu::no_sanitize_thread`` |br| ``clang::no_sanitize_memory``","``clang::no_sanitize_memory``","","","","Yes" + +.. _langext-thread_sanitizer: + +Use ``__attribute__((no_sanitize_thread))`` on a function declaration to +specify that checks for data races on plain (non-atomic) memory accesses should +not be inserted by ThreadSanitizer. The function is still instrumented by the +tool to avoid false positives and provide meaningful stack traces. + + +no_split_stack +-------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``no_split_stack``","``gnu::no_split_stack``","","","","","Yes" + +The ``no_split_stack`` attribute disables the emission of the split stack +preamble for a particular function. It has no effect if ``-fsplit-stack`` +is not specified. + + +no_stack_protector +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``no_stack_protector``","``clang::no_stack_protector``","``clang::no_stack_protector``","","","","Yes" + +Clang supports the ``__attribute__((no_stack_protector))`` attribute which disables +the stack protector on the specified function. This attribute is useful for +selectively disabling the stack protector on some functions when building with +``-fstack-protector`` compiler option. + +For example, it disables the stack protector for the function ``foo`` but function +``bar`` will still be built with the stack protector with the ``-fstack-protector`` +option. + +.. code-block:: c + + int __attribute__((no_stack_protector)) + foo (int x); // stack protection will be disabled for foo. + + int bar(int y); // bar can be built with the stack protector. + + +noalias +------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","``noalias``","","","" + +The ``noalias`` attribute indicates that the only memory accesses inside +function are loads and stores from objects pointed to by its pointer-typed +arguments, with arbitrary offsets. + + +nocf_check +---------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``nocf_check``","``gnu::nocf_check``","","","","","Yes" + +Jump Oriented Programming attacks rely on tampering with addresses used by +indirect call / jmp, e.g. redirect control-flow to non-programmer +intended bytes in the binary. +X86 Supports Indirect Branch Tracking (IBT) as part of Control-Flow +Enforcement Technology (CET). IBT instruments ENDBR instructions used to +specify valid targets of indirect call / jmp. +The ``nocf_check`` attribute has two roles: +1. Appertains to a function - do not add ENDBR instruction at the beginning of +the function. +2. Appertains to a function pointer - do not track the target function of this +pointer (by adding nocf_check prefix to the indirect-call instruction). + + +nodiscard, warn_unused_result +----------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``warn_unused_result``","``nodiscard`` |br| ``clang::warn_unused_result`` |br| ``gnu::warn_unused_result``","``nodiscard``","","","","Yes" + +Clang supports the ability to diagnose when the results of a function call +expression are discarded under suspicious circumstances. A diagnostic is +generated when a function or its return type is marked with ``[[nodiscard]]`` +(or ``__attribute__((warn_unused_result))``) and the function call appears as a +potentially-evaluated discarded-value expression that is not explicitly cast to +`void`. + +.. code-block: c++ + struct [[nodiscard]] error_info { /*...*/ }; + error_info enable_missile_safety_mode(); + + void launch_missiles(); + void test_missiles() { + enable_missile_safety_mode(); // diagnoses + launch_missiles(); + } + error_info &foo(); + void f() { foo(); } // Does not diagnose, error_info is a reference. + + +noduplicate +----------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``noduplicate``","``clang::noduplicate``","``clang::noduplicate``","","","","Yes" + +The ``noduplicate`` attribute can be placed on function declarations to control +whether function calls to this function can be duplicated or not as a result of +optimizations. This is required for the implementation of functions with +certain special requirements, like the OpenCL "barrier" function, that might +need to be run concurrently by all the threads that are executing in lockstep +on the hardware. For example this attribute applied on the function +"nodupfunc" in the code below avoids that: + +.. code-block:: c + + void nodupfunc() __attribute__((noduplicate)); + // Setting it as a C++11 attribute is also valid + // void nodupfunc() [[clang::noduplicate]]; + void foo(); + void bar(); + + nodupfunc(); + if (a > n) { + foo(); + } else { + bar(); + } + +gets possibly modified by some optimizations into code similar to this: + +.. code-block:: c + + if (a > n) { + nodupfunc(); + foo(); + } else { + nodupfunc(); + bar(); + } + +where the call to "nodupfunc" is duplicated and sunk into the two branches +of the condition. + + +nomicromips +----------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``nomicromips``","``gnu::nomicromips``","","","","","Yes" + +Clang supports the GNU style ``__attribute__((micromips))`` and +``__attribute__((nomicromips))`` attributes on MIPS targets. These attributes +may be attached to a function definition and instructs the backend to generate +or not to generate microMIPS code for that function. + +These attributes override the `-mmicromips` and `-mno-micromips` options +on the command line. + + +noreturn +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","``noreturn``","","","","","Yes" + +A function declared as ``[[noreturn]]`` shall not return to its caller. The +compiler will generate a diagnostic for a function declared as ``[[noreturn]]`` +that appears to be capable of returning to its caller. + + +not_tail_called +--------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``not_tail_called``","``clang::not_tail_called``","``clang::not_tail_called``","","","","Yes" + +The ``not_tail_called`` attribute prevents tail-call optimization on statically bound calls. It has no effect on indirect calls. Virtual functions, objective-c methods, and functions marked as ``always_inline`` cannot be marked as ``not_tail_called``. + +For example, it prevents tail-call optimization in the following case: + + .. code-block:: c + + int __attribute__((not_tail_called)) foo1(int); + + int foo2(int a) { + return foo1(a); // No tail-call optimization on direct calls. + } + +However, it doesn't prevent tail-call optimization in this case: + + .. code-block:: c + + int __attribute__((not_tail_called)) foo1(int); + + int foo2(int a) { + int (*fn)(int) = &foo1; + + // not_tail_called has no effect on an indirect call even if the call can be + // resolved at compile time. + return (*fn)(a); + } + +Marking virtual functions as ``not_tail_called`` is an error: + + .. code-block:: c++ + + class Base { + public: + // not_tail_called on a virtual function is an error. + [[clang::not_tail_called]] virtual int foo1(); + + virtual int foo2(); + + // Non-virtual functions can be marked ``not_tail_called``. + [[clang::not_tail_called]] int foo3(); + }; + + class Derived1 : public Base { + public: + int foo1() override; + + // not_tail_called on a virtual function is an error. + [[clang::not_tail_called]] int foo2() override; + }; + + +nothrow +------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``nothrow``","``gnu::nothrow``","","``nothrow``","","","Yes" + +Clang supports the GNU style ``__attribute__((nothrow))`` and Microsoft style +``__declspec(nothrow)`` attribute as an equivalent of `noexcept` on function +declarations. This attribute informs the compiler that the annotated function +does not throw an exception. This prevents exception-unwinding. This attribute +is particularly useful on functions in the C Standard Library that are +guaranteed to not throw an exception. + + +ns_consumed +----------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``ns_consumed``","``clang::ns_consumed``","``clang::ns_consumed``","","","","Yes" + +The behavior of a function with respect to reference counting for Foundation +(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming +convention (e.g. functions starting with "get" are assumed to return at +``+0``). + +It can be overriden using a family of the following attributes. In +Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to +a function communicates that the object is returned at ``+1``, and the caller +is responsible for freeing it. +Similiarly, the annotation ``__attribute__((ns_returns_not_retained))`` +specifies that the object is returned at ``+0`` and the ownership remains with +the callee. +The annotation ``__attribute__((ns_consumes_self))`` specifies that +the Objective-C method call consumes the reference to ``self``, e.g. by +attaching it to a supplied parameter. +Additionally, parameters can have an annotation +``__attribute__((ns_consumed))``, which specifies that passing an owned object +as that parameter effectively transfers the ownership, and the caller is no +longer responsible for it. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +In C programs using CoreFoundation, a similar set of attributes: +``__attribute__((cf_returns_not_retained))``, +``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))`` +have the same respective semantics when applied to CoreFoundation objects. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject), +the same attribute family is present: +``__attribute__((os_returns_not_retained))``, +``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``, +with the same respective semantics. +Similar to ``__attribute__((ns_consumes_self))``, +``__attribute__((os_consumes_this))`` specifies that the method call consumes +the reference to "this" (e.g., when attaching it to a different object supplied +as a parameter). +Out parameters (parameters the function is meant to write into, +either via pointers-to-pointers or references-to-pointers) +may be annotated with ``__attribute__((os_returns_retained))`` +or ``__attribute__((os_returns_not_retained))`` which specifies that the object +written into the out parameter should (or respectively should not) be released +after use. +Since often out parameters may or may not be written depending on the exit +code of the function, +annotations ``__attribute__((os_returns_retained_on_zero))`` +and ``__attribute__((os_returns_retained_on_non_zero))`` specify that +an out parameter at ``+1`` is written if and only if the function returns a zero +(respectively non-zero) error code. +Observe that return-code-dependent out parameter annotations are only +available for retained out parameters, as non-retained object do not have to be +released by the callee. +These attributes are only used by the Clang Static Analyzer. + +The family of attributes ``X_returns_X_retained`` can be added to functions, +C++ methods, and Objective-C methods and properties. +Attributes ``X_consumed`` can be added to parameters of methods, functions, +and Objective-C methods. + + +ns_consumes_self +---------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``ns_consumes_self``","``clang::ns_consumes_self``","``clang::ns_consumes_self``","","","","Yes" + +The behavior of a function with respect to reference counting for Foundation +(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming +convention (e.g. functions starting with "get" are assumed to return at +``+0``). + +It can be overriden using a family of the following attributes. In +Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to +a function communicates that the object is returned at ``+1``, and the caller +is responsible for freeing it. +Similiarly, the annotation ``__attribute__((ns_returns_not_retained))`` +specifies that the object is returned at ``+0`` and the ownership remains with +the callee. +The annotation ``__attribute__((ns_consumes_self))`` specifies that +the Objective-C method call consumes the reference to ``self``, e.g. by +attaching it to a supplied parameter. +Additionally, parameters can have an annotation +``__attribute__((ns_consumed))``, which specifies that passing an owned object +as that parameter effectively transfers the ownership, and the caller is no +longer responsible for it. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +In C programs using CoreFoundation, a similar set of attributes: +``__attribute__((cf_returns_not_retained))``, +``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))`` +have the same respective semantics when applied to CoreFoundation objects. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject), +the same attribute family is present: +``__attribute__((os_returns_not_retained))``, +``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``, +with the same respective semantics. +Similar to ``__attribute__((ns_consumes_self))``, +``__attribute__((os_consumes_this))`` specifies that the method call consumes +the reference to "this" (e.g., when attaching it to a different object supplied +as a parameter). +Out parameters (parameters the function is meant to write into, +either via pointers-to-pointers or references-to-pointers) +may be annotated with ``__attribute__((os_returns_retained))`` +or ``__attribute__((os_returns_not_retained))`` which specifies that the object +written into the out parameter should (or respectively should not) be released +after use. +Since often out parameters may or may not be written depending on the exit +code of the function, +annotations ``__attribute__((os_returns_retained_on_zero))`` +and ``__attribute__((os_returns_retained_on_non_zero))`` specify that +an out parameter at ``+1`` is written if and only if the function returns a zero +(respectively non-zero) error code. +Observe that return-code-dependent out parameter annotations are only +available for retained out parameters, as non-retained object do not have to be +released by the callee. +These attributes are only used by the Clang Static Analyzer. + +The family of attributes ``X_returns_X_retained`` can be added to functions, +C++ methods, and Objective-C methods and properties. +Attributes ``X_consumed`` can be added to parameters of methods, functions, +and Objective-C methods. + + +ns_returns_autoreleased +----------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``ns_returns_autoreleased``","``clang::ns_returns_autoreleased``","``clang::ns_returns_autoreleased``","","","","" + +The behavior of a function with respect to reference counting for Foundation +(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming +convention (e.g. functions starting with "get" are assumed to return at +``+0``). + +It can be overriden using a family of the following attributes. In +Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to +a function communicates that the object is returned at ``+1``, and the caller +is responsible for freeing it. +Similiarly, the annotation ``__attribute__((ns_returns_not_retained))`` +specifies that the object is returned at ``+0`` and the ownership remains with +the callee. +The annotation ``__attribute__((ns_consumes_self))`` specifies that +the Objective-C method call consumes the reference to ``self``, e.g. by +attaching it to a supplied parameter. +Additionally, parameters can have an annotation +``__attribute__((ns_consumed))``, which specifies that passing an owned object +as that parameter effectively transfers the ownership, and the caller is no +longer responsible for it. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +In C programs using CoreFoundation, a similar set of attributes: +``__attribute__((cf_returns_not_retained))``, +``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))`` +have the same respective semantics when applied to CoreFoundation objects. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject), +the same attribute family is present: +``__attribute__((os_returns_not_retained))``, +``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``, +with the same respective semantics. +Similar to ``__attribute__((ns_consumes_self))``, +``__attribute__((os_consumes_this))`` specifies that the method call consumes +the reference to "this" (e.g., when attaching it to a different object supplied +as a parameter). +Out parameters (parameters the function is meant to write into, +either via pointers-to-pointers or references-to-pointers) +may be annotated with ``__attribute__((os_returns_retained))`` +or ``__attribute__((os_returns_not_retained))`` which specifies that the object +written into the out parameter should (or respectively should not) be released +after use. +Since often out parameters may or may not be written depending on the exit +code of the function, +annotations ``__attribute__((os_returns_retained_on_zero))`` +and ``__attribute__((os_returns_retained_on_non_zero))`` specify that +an out parameter at ``+1`` is written if and only if the function returns a zero +(respectively non-zero) error code. +Observe that return-code-dependent out parameter annotations are only +available for retained out parameters, as non-retained object do not have to be +released by the callee. +These attributes are only used by the Clang Static Analyzer. + +The family of attributes ``X_returns_X_retained`` can be added to functions, +C++ methods, and Objective-C methods and properties. +Attributes ``X_consumed`` can be added to parameters of methods, functions, +and Objective-C methods. + + +ns_returns_not_retained +----------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``ns_returns_not_retained``","``clang::ns_returns_not_retained``","``clang::ns_returns_not_retained``","","","","" + +The behavior of a function with respect to reference counting for Foundation +(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming +convention (e.g. functions starting with "get" are assumed to return at +``+0``). + +It can be overriden using a family of the following attributes. In +Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to +a function communicates that the object is returned at ``+1``, and the caller +is responsible for freeing it. +Similiarly, the annotation ``__attribute__((ns_returns_not_retained))`` +specifies that the object is returned at ``+0`` and the ownership remains with +the callee. +The annotation ``__attribute__((ns_consumes_self))`` specifies that +the Objective-C method call consumes the reference to ``self``, e.g. by +attaching it to a supplied parameter. +Additionally, parameters can have an annotation +``__attribute__((ns_consumed))``, which specifies that passing an owned object +as that parameter effectively transfers the ownership, and the caller is no +longer responsible for it. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +In C programs using CoreFoundation, a similar set of attributes: +``__attribute__((cf_returns_not_retained))``, +``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))`` +have the same respective semantics when applied to CoreFoundation objects. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject), +the same attribute family is present: +``__attribute__((os_returns_not_retained))``, +``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``, +with the same respective semantics. +Similar to ``__attribute__((ns_consumes_self))``, +``__attribute__((os_consumes_this))`` specifies that the method call consumes +the reference to "this" (e.g., when attaching it to a different object supplied +as a parameter). +Out parameters (parameters the function is meant to write into, +either via pointers-to-pointers or references-to-pointers) +may be annotated with ``__attribute__((os_returns_retained))`` +or ``__attribute__((os_returns_not_retained))`` which specifies that the object +written into the out parameter should (or respectively should not) be released +after use. +Since often out parameters may or may not be written depending on the exit +code of the function, +annotations ``__attribute__((os_returns_retained_on_zero))`` +and ``__attribute__((os_returns_retained_on_non_zero))`` specify that +an out parameter at ``+1`` is written if and only if the function returns a zero +(respectively non-zero) error code. +Observe that return-code-dependent out parameter annotations are only +available for retained out parameters, as non-retained object do not have to be +released by the callee. +These attributes are only used by the Clang Static Analyzer. + +The family of attributes ``X_returns_X_retained`` can be added to functions, +C++ methods, and Objective-C methods and properties. +Attributes ``X_consumed`` can be added to parameters of methods, functions, +and Objective-C methods. + + +ns_returns_retained +------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``ns_returns_retained``","``clang::ns_returns_retained``","``clang::ns_returns_retained``","","","","" + +The behavior of a function with respect to reference counting for Foundation +(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming +convention (e.g. functions starting with "get" are assumed to return at +``+0``). + +It can be overriden using a family of the following attributes. In +Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to +a function communicates that the object is returned at ``+1``, and the caller +is responsible for freeing it. +Similiarly, the annotation ``__attribute__((ns_returns_not_retained))`` +specifies that the object is returned at ``+0`` and the ownership remains with +the callee. +The annotation ``__attribute__((ns_consumes_self))`` specifies that +the Objective-C method call consumes the reference to ``self``, e.g. by +attaching it to a supplied parameter. +Additionally, parameters can have an annotation +``__attribute__((ns_consumed))``, which specifies that passing an owned object +as that parameter effectively transfers the ownership, and the caller is no +longer responsible for it. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +In C programs using CoreFoundation, a similar set of attributes: +``__attribute__((cf_returns_not_retained))``, +``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))`` +have the same respective semantics when applied to CoreFoundation objects. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject), +the same attribute family is present: +``__attribute__((os_returns_not_retained))``, +``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``, +with the same respective semantics. +Similar to ``__attribute__((ns_consumes_self))``, +``__attribute__((os_consumes_this))`` specifies that the method call consumes +the reference to "this" (e.g., when attaching it to a different object supplied +as a parameter). +Out parameters (parameters the function is meant to write into, +either via pointers-to-pointers or references-to-pointers) +may be annotated with ``__attribute__((os_returns_retained))`` +or ``__attribute__((os_returns_not_retained))`` which specifies that the object +written into the out parameter should (or respectively should not) be released +after use. +Since often out parameters may or may not be written depending on the exit +code of the function, +annotations ``__attribute__((os_returns_retained_on_zero))`` +and ``__attribute__((os_returns_retained_on_non_zero))`` specify that +an out parameter at ``+1`` is written if and only if the function returns a zero +(respectively non-zero) error code. +Observe that return-code-dependent out parameter annotations are only +available for retained out parameters, as non-retained object do not have to be +released by the callee. +These attributes are only used by the Clang Static Analyzer. + +The family of attributes ``X_returns_X_retained`` can be added to functions, +C++ methods, and Objective-C methods and properties. +Attributes ``X_consumed`` can be added to parameters of methods, functions, +and Objective-C methods. + + +objc_boxable +------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``objc_boxable``","``clang::objc_boxable``","``clang::objc_boxable``","","","","Yes" + +Structs and unions marked with the ``objc_boxable`` attribute can be used +with the Objective-C boxed expression syntax, ``@(...)``. + +**Usage**: ``__attribute__((objc_boxable))``. This attribute +can only be placed on a declaration of a trivially-copyable struct or union: + +.. code-block:: objc + + struct __attribute__((objc_boxable)) some_struct { + int i; + }; + union __attribute__((objc_boxable)) some_union { + int i; + float f; + }; + typedef struct __attribute__((objc_boxable)) _some_struct some_struct; + + // ... + + some_struct ss; + NSValue *boxed = @(ss); + + +objc_method_family +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``objc_method_family``","``clang::objc_method_family``","``clang::objc_method_family``","","","","Yes" + +Many methods in Objective-C have conventional meanings determined by their +selectors. It is sometimes useful to be able to mark a method as having a +particular conventional meaning despite not having the right selector, or as +not having the conventional meaning that its selector would suggest. For these +use cases, we provide an attribute to specifically describe the "method family" +that a method belongs to. + +**Usage**: ``__attribute__((objc_method_family(X)))``, where ``X`` is one of +``none``, ``alloc``, ``copy``, ``init``, ``mutableCopy``, or ``new``. This +attribute can only be placed at the end of a method declaration: + +.. code-block:: objc + + - (NSString *)initMyStringValue __attribute__((objc_method_family(none))); + +Users who do not wish to change the conventional meaning of a method, and who +merely want to document its non-standard retain and release semantics, should +use the retaining behavior attributes (``ns_returns_retained``, +``ns_returns_not_retained``, etc). + +Query for this feature with ``__has_attribute(objc_method_family)``. + + +objc_requires_super +------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``objc_requires_super``","``clang::objc_requires_super``","``clang::objc_requires_super``","","","","Yes" + +Some Objective-C classes allow a subclass to override a particular method in a +parent class but expect that the overriding method also calls the overridden +method in the parent class. For these cases, we provide an attribute to +designate that a method requires a "call to ``super``" in the overriding +method in the subclass. + +**Usage**: ``__attribute__((objc_requires_super))``. This attribute can only +be placed at the end of a method declaration: + +.. code-block:: objc + + - (void)foo __attribute__((objc_requires_super)); + +This attribute can only be applied the method declarations within a class, and +not a protocol. Currently this attribute does not enforce any placement of +where the call occurs in the overriding method (such as in the case of +``-dealloc`` where the call must appear at the end). It checks only that it +exists. + +Note that on both OS X and iOS that the Foundation framework provides a +convenience macro ``NS_REQUIRES_SUPER`` that provides syntactic sugar for this +attribute: + +.. code-block:: objc + + - (void)foo NS_REQUIRES_SUPER; + +This macro is conditionally defined depending on the compiler's support for +this attribute. If the compiler does not support the attribute the macro +expands to nothing. + +Operationally, when a method has this annotation the compiler will warn if the +implementation of an override in a subclass does not call super. For example: + +.. code-block:: objc + + warning: method possibly missing a [super AnnotMeth] call + - (void) AnnotMeth{}; + ^ + + +objc_runtime_name +----------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``objc_runtime_name``","``clang::objc_runtime_name``","``clang::objc_runtime_name``","","","","Yes" + +By default, the Objective-C interface or protocol identifier is used +in the metadata name for that object. The `objc_runtime_name` +attribute allows annotated interfaces or protocols to use the +specified string argument in the object's metadata name instead of the +default name. + +**Usage**: ``__attribute__((objc_runtime_name("MyLocalName")))``. This attribute +can only be placed before an @protocol or @interface declaration: + +.. code-block:: objc + + __attribute__((objc_runtime_name("MyLocalName"))) + @interface Message + @end + + +objc_runtime_visible +-------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``objc_runtime_visible``","``clang::objc_runtime_visible``","``clang::objc_runtime_visible``","","","","Yes" + +This attribute specifies that the Objective-C class to which it applies is visible to the Objective-C runtime but not to the linker. Classes annotated with this attribute cannot be subclassed and cannot have categories defined for them. + + +optnone +------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``optnone``","``clang::optnone``","``clang::optnone``","","","","Yes" + +The ``optnone`` attribute suppresses essentially all optimizations +on a function or method, regardless of the optimization level applied to +the compilation unit as a whole. This is particularly useful when you +need to debug a particular function, but it is infeasible to build the +entire application without optimization. Avoiding optimization on the +specified function can improve the quality of the debugging information +for that function. + +This attribute is incompatible with the ``always_inline`` and ``minsize`` +attributes. + + +os_consumed +----------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``os_consumed``","``clang::os_consumed``","``clang::os_consumed``","","","","Yes" + +The behavior of a function with respect to reference counting for Foundation +(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming +convention (e.g. functions starting with "get" are assumed to return at +``+0``). + +It can be overriden using a family of the following attributes. In +Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to +a function communicates that the object is returned at ``+1``, and the caller +is responsible for freeing it. +Similiarly, the annotation ``__attribute__((ns_returns_not_retained))`` +specifies that the object is returned at ``+0`` and the ownership remains with +the callee. +The annotation ``__attribute__((ns_consumes_self))`` specifies that +the Objective-C method call consumes the reference to ``self``, e.g. by +attaching it to a supplied parameter. +Additionally, parameters can have an annotation +``__attribute__((ns_consumed))``, which specifies that passing an owned object +as that parameter effectively transfers the ownership, and the caller is no +longer responsible for it. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +In C programs using CoreFoundation, a similar set of attributes: +``__attribute__((cf_returns_not_retained))``, +``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))`` +have the same respective semantics when applied to CoreFoundation objects. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject), +the same attribute family is present: +``__attribute__((os_returns_not_retained))``, +``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``, +with the same respective semantics. +Similar to ``__attribute__((ns_consumes_self))``, +``__attribute__((os_consumes_this))`` specifies that the method call consumes +the reference to "this" (e.g., when attaching it to a different object supplied +as a parameter). +Out parameters (parameters the function is meant to write into, +either via pointers-to-pointers or references-to-pointers) +may be annotated with ``__attribute__((os_returns_retained))`` +or ``__attribute__((os_returns_not_retained))`` which specifies that the object +written into the out parameter should (or respectively should not) be released +after use. +Since often out parameters may or may not be written depending on the exit +code of the function, +annotations ``__attribute__((os_returns_retained_on_zero))`` +and ``__attribute__((os_returns_retained_on_non_zero))`` specify that +an out parameter at ``+1`` is written if and only if the function returns a zero +(respectively non-zero) error code. +Observe that return-code-dependent out parameter annotations are only +available for retained out parameters, as non-retained object do not have to be +released by the callee. +These attributes are only used by the Clang Static Analyzer. + +The family of attributes ``X_returns_X_retained`` can be added to functions, +C++ methods, and Objective-C methods and properties. +Attributes ``X_consumed`` can be added to parameters of methods, functions, +and Objective-C methods. + + +os_consumes_this +---------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``os_consumes_this``","``clang::os_consumes_this``","``clang::os_consumes_this``","","","","" + +The behavior of a function with respect to reference counting for Foundation +(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming +convention (e.g. functions starting with "get" are assumed to return at +``+0``). + +It can be overriden using a family of the following attributes. In +Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to +a function communicates that the object is returned at ``+1``, and the caller +is responsible for freeing it. +Similiarly, the annotation ``__attribute__((ns_returns_not_retained))`` +specifies that the object is returned at ``+0`` and the ownership remains with +the callee. +The annotation ``__attribute__((ns_consumes_self))`` specifies that +the Objective-C method call consumes the reference to ``self``, e.g. by +attaching it to a supplied parameter. +Additionally, parameters can have an annotation +``__attribute__((ns_consumed))``, which specifies that passing an owned object +as that parameter effectively transfers the ownership, and the caller is no +longer responsible for it. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +In C programs using CoreFoundation, a similar set of attributes: +``__attribute__((cf_returns_not_retained))``, +``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))`` +have the same respective semantics when applied to CoreFoundation objects. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject), +the same attribute family is present: +``__attribute__((os_returns_not_retained))``, +``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``, +with the same respective semantics. +Similar to ``__attribute__((ns_consumes_self))``, +``__attribute__((os_consumes_this))`` specifies that the method call consumes +the reference to "this" (e.g., when attaching it to a different object supplied +as a parameter). +Out parameters (parameters the function is meant to write into, +either via pointers-to-pointers or references-to-pointers) +may be annotated with ``__attribute__((os_returns_retained))`` +or ``__attribute__((os_returns_not_retained))`` which specifies that the object +written into the out parameter should (or respectively should not) be released +after use. +Since often out parameters may or may not be written depending on the exit +code of the function, +annotations ``__attribute__((os_returns_retained_on_zero))`` +and ``__attribute__((os_returns_retained_on_non_zero))`` specify that +an out parameter at ``+1`` is written if and only if the function returns a zero +(respectively non-zero) error code. +Observe that return-code-dependent out parameter annotations are only +available for retained out parameters, as non-retained object do not have to be +released by the callee. +These attributes are only used by the Clang Static Analyzer. + +The family of attributes ``X_returns_X_retained`` can be added to functions, +C++ methods, and Objective-C methods and properties. +Attributes ``X_consumed`` can be added to parameters of methods, functions, +and Objective-C methods. + + +os_returns_not_retained +----------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``os_returns_not_retained``","``clang::os_returns_not_retained``","``clang::os_returns_not_retained``","","","","Yes" + +The behavior of a function with respect to reference counting for Foundation +(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming +convention (e.g. functions starting with "get" are assumed to return at +``+0``). + +It can be overriden using a family of the following attributes. In +Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to +a function communicates that the object is returned at ``+1``, and the caller +is responsible for freeing it. +Similiarly, the annotation ``__attribute__((ns_returns_not_retained))`` +specifies that the object is returned at ``+0`` and the ownership remains with +the callee. +The annotation ``__attribute__((ns_consumes_self))`` specifies that +the Objective-C method call consumes the reference to ``self``, e.g. by +attaching it to a supplied parameter. +Additionally, parameters can have an annotation +``__attribute__((ns_consumed))``, which specifies that passing an owned object +as that parameter effectively transfers the ownership, and the caller is no +longer responsible for it. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +In C programs using CoreFoundation, a similar set of attributes: +``__attribute__((cf_returns_not_retained))``, +``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))`` +have the same respective semantics when applied to CoreFoundation objects. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject), +the same attribute family is present: +``__attribute__((os_returns_not_retained))``, +``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``, +with the same respective semantics. +Similar to ``__attribute__((ns_consumes_self))``, +``__attribute__((os_consumes_this))`` specifies that the method call consumes +the reference to "this" (e.g., when attaching it to a different object supplied +as a parameter). +Out parameters (parameters the function is meant to write into, +either via pointers-to-pointers or references-to-pointers) +may be annotated with ``__attribute__((os_returns_retained))`` +or ``__attribute__((os_returns_not_retained))`` which specifies that the object +written into the out parameter should (or respectively should not) be released +after use. +Since often out parameters may or may not be written depending on the exit +code of the function, +annotations ``__attribute__((os_returns_retained_on_zero))`` +and ``__attribute__((os_returns_retained_on_non_zero))`` specify that +an out parameter at ``+1`` is written if and only if the function returns a zero +(respectively non-zero) error code. +Observe that return-code-dependent out parameter annotations are only +available for retained out parameters, as non-retained object do not have to be +released by the callee. +These attributes are only used by the Clang Static Analyzer. + +The family of attributes ``X_returns_X_retained`` can be added to functions, +C++ methods, and Objective-C methods and properties. +Attributes ``X_consumed`` can be added to parameters of methods, functions, +and Objective-C methods. + + +os_returns_retained +------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``os_returns_retained``","``clang::os_returns_retained``","``clang::os_returns_retained``","","","","Yes" + +The behavior of a function with respect to reference counting for Foundation +(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming +convention (e.g. functions starting with "get" are assumed to return at +``+0``). + +It can be overriden using a family of the following attributes. In +Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to +a function communicates that the object is returned at ``+1``, and the caller +is responsible for freeing it. +Similiarly, the annotation ``__attribute__((ns_returns_not_retained))`` +specifies that the object is returned at ``+0`` and the ownership remains with +the callee. +The annotation ``__attribute__((ns_consumes_self))`` specifies that +the Objective-C method call consumes the reference to ``self``, e.g. by +attaching it to a supplied parameter. +Additionally, parameters can have an annotation +``__attribute__((ns_consumed))``, which specifies that passing an owned object +as that parameter effectively transfers the ownership, and the caller is no +longer responsible for it. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +In C programs using CoreFoundation, a similar set of attributes: +``__attribute__((cf_returns_not_retained))``, +``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))`` +have the same respective semantics when applied to CoreFoundation objects. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject), +the same attribute family is present: +``__attribute__((os_returns_not_retained))``, +``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``, +with the same respective semantics. +Similar to ``__attribute__((ns_consumes_self))``, +``__attribute__((os_consumes_this))`` specifies that the method call consumes +the reference to "this" (e.g., when attaching it to a different object supplied +as a parameter). +Out parameters (parameters the function is meant to write into, +either via pointers-to-pointers or references-to-pointers) +may be annotated with ``__attribute__((os_returns_retained))`` +or ``__attribute__((os_returns_not_retained))`` which specifies that the object +written into the out parameter should (or respectively should not) be released +after use. +Since often out parameters may or may not be written depending on the exit +code of the function, +annotations ``__attribute__((os_returns_retained_on_zero))`` +and ``__attribute__((os_returns_retained_on_non_zero))`` specify that +an out parameter at ``+1`` is written if and only if the function returns a zero +(respectively non-zero) error code. +Observe that return-code-dependent out parameter annotations are only +available for retained out parameters, as non-retained object do not have to be +released by the callee. +These attributes are only used by the Clang Static Analyzer. + +The family of attributes ``X_returns_X_retained`` can be added to functions, +C++ methods, and Objective-C methods and properties. +Attributes ``X_consumed`` can be added to parameters of methods, functions, +and Objective-C methods. + + +os_returns_retained_on_non_zero +------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``os_returns_retained_on_non_zero``","``clang::os_returns_retained_on_non_zero``","``clang::os_returns_retained_on_non_zero``","","","","Yes" + +The behavior of a function with respect to reference counting for Foundation +(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming +convention (e.g. functions starting with "get" are assumed to return at +``+0``). + +It can be overriden using a family of the following attributes. In +Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to +a function communicates that the object is returned at ``+1``, and the caller +is responsible for freeing it. +Similiarly, the annotation ``__attribute__((ns_returns_not_retained))`` +specifies that the object is returned at ``+0`` and the ownership remains with +the callee. +The annotation ``__attribute__((ns_consumes_self))`` specifies that +the Objective-C method call consumes the reference to ``self``, e.g. by +attaching it to a supplied parameter. +Additionally, parameters can have an annotation +``__attribute__((ns_consumed))``, which specifies that passing an owned object +as that parameter effectively transfers the ownership, and the caller is no +longer responsible for it. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +In C programs using CoreFoundation, a similar set of attributes: +``__attribute__((cf_returns_not_retained))``, +``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))`` +have the same respective semantics when applied to CoreFoundation objects. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject), +the same attribute family is present: +``__attribute__((os_returns_not_retained))``, +``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``, +with the same respective semantics. +Similar to ``__attribute__((ns_consumes_self))``, +``__attribute__((os_consumes_this))`` specifies that the method call consumes +the reference to "this" (e.g., when attaching it to a different object supplied +as a parameter). +Out parameters (parameters the function is meant to write into, +either via pointers-to-pointers or references-to-pointers) +may be annotated with ``__attribute__((os_returns_retained))`` +or ``__attribute__((os_returns_not_retained))`` which specifies that the object +written into the out parameter should (or respectively should not) be released +after use. +Since often out parameters may or may not be written depending on the exit +code of the function, +annotations ``__attribute__((os_returns_retained_on_zero))`` +and ``__attribute__((os_returns_retained_on_non_zero))`` specify that +an out parameter at ``+1`` is written if and only if the function returns a zero +(respectively non-zero) error code. +Observe that return-code-dependent out parameter annotations are only +available for retained out parameters, as non-retained object do not have to be +released by the callee. +These attributes are only used by the Clang Static Analyzer. + +The family of attributes ``X_returns_X_retained`` can be added to functions, +C++ methods, and Objective-C methods and properties. +Attributes ``X_consumed`` can be added to parameters of methods, functions, +and Objective-C methods. + + +os_returns_retained_on_zero +--------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``os_returns_retained_on_zero``","``clang::os_returns_retained_on_zero``","``clang::os_returns_retained_on_zero``","","","","Yes" + +The behavior of a function with respect to reference counting for Foundation +(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming +convention (e.g. functions starting with "get" are assumed to return at +``+0``). + +It can be overriden using a family of the following attributes. In +Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to +a function communicates that the object is returned at ``+1``, and the caller +is responsible for freeing it. +Similiarly, the annotation ``__attribute__((ns_returns_not_retained))`` +specifies that the object is returned at ``+0`` and the ownership remains with +the callee. +The annotation ``__attribute__((ns_consumes_self))`` specifies that +the Objective-C method call consumes the reference to ``self``, e.g. by +attaching it to a supplied parameter. +Additionally, parameters can have an annotation +``__attribute__((ns_consumed))``, which specifies that passing an owned object +as that parameter effectively transfers the ownership, and the caller is no +longer responsible for it. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +In C programs using CoreFoundation, a similar set of attributes: +``__attribute__((cf_returns_not_retained))``, +``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))`` +have the same respective semantics when applied to CoreFoundation objects. +These attributes affect code generation when interacting with ARC code, and +they are used by the Clang Static Analyzer. + +Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject), +the same attribute family is present: +``__attribute__((os_returns_not_retained))``, +``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``, +with the same respective semantics. +Similar to ``__attribute__((ns_consumes_self))``, +``__attribute__((os_consumes_this))`` specifies that the method call consumes +the reference to "this" (e.g., when attaching it to a different object supplied +as a parameter). +Out parameters (parameters the function is meant to write into, +either via pointers-to-pointers or references-to-pointers) +may be annotated with ``__attribute__((os_returns_retained))`` +or ``__attribute__((os_returns_not_retained))`` which specifies that the object +written into the out parameter should (or respectively should not) be released +after use. +Since often out parameters may or may not be written depending on the exit +code of the function, +annotations ``__attribute__((os_returns_retained_on_zero))`` +and ``__attribute__((os_returns_retained_on_non_zero))`` specify that +an out parameter at ``+1`` is written if and only if the function returns a zero +(respectively non-zero) error code. +Observe that return-code-dependent out parameter annotations are only +available for retained out parameters, as non-retained object do not have to be +released by the callee. +These attributes are only used by the Clang Static Analyzer. + +The family of attributes ``X_returns_X_retained`` can be added to functions, +C++ methods, and Objective-C methods and properties. +Attributes ``X_consumed`` can be added to parameters of methods, functions, +and Objective-C methods. + + +overloadable +------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``overloadable``","``clang::overloadable``","``clang::overloadable``","","","","Yes" + +Clang provides support for C++ function overloading in C. Function overloading +in C is introduced using the ``overloadable`` attribute. For example, one +might provide several overloaded versions of a ``tgsin`` function that invokes +the appropriate standard function computing the sine of a value with ``float``, +``double``, or ``long double`` precision: + +.. code-block:: c + + #include + float __attribute__((overloadable)) tgsin(float x) { return sinf(x); } + double __attribute__((overloadable)) tgsin(double x) { return sin(x); } + long double __attribute__((overloadable)) tgsin(long double x) { return sinl(x); } + +Given these declarations, one can call ``tgsin`` with a ``float`` value to +receive a ``float`` result, with a ``double`` to receive a ``double`` result, +etc. Function overloading in C follows the rules of C++ function overloading +to pick the best overload given the call arguments, with a few C-specific +semantics: + +* Conversion from ``float`` or ``double`` to ``long double`` is ranked as a + floating-point promotion (per C99) rather than as a floating-point conversion + (as in C++). + +* A conversion from a pointer of type ``T*`` to a pointer of type ``U*`` is + considered a pointer conversion (with conversion rank) if ``T`` and ``U`` are + compatible types. + +* A conversion from type ``T`` to a value of type ``U`` is permitted if ``T`` + and ``U`` are compatible types. This conversion is given "conversion" rank. + +* If no viable candidates are otherwise available, we allow a conversion from a + pointer of type ``T*`` to a pointer of type ``U*``, where ``T`` and ``U`` are + incompatible. This conversion is ranked below all other types of conversions. + Please note: ``U`` lacking qualifiers that are present on ``T`` is sufficient + for ``T`` and ``U`` to be incompatible. + +The declaration of ``overloadable`` functions is restricted to function +declarations and definitions. If a function is marked with the ``overloadable`` +attribute, then all declarations and definitions of functions with that name, +except for at most one (see the note below about unmarked overloads), must have +the ``overloadable`` attribute. In addition, redeclarations of a function with +the ``overloadable`` attribute must have the ``overloadable`` attribute, and +redeclarations of a function without the ``overloadable`` attribute must *not* +have the ``overloadable`` attribute. e.g., + +.. code-block:: c + + int f(int) __attribute__((overloadable)); + float f(float); // error: declaration of "f" must have the "overloadable" attribute + int f(int); // error: redeclaration of "f" must have the "overloadable" attribute + + int g(int) __attribute__((overloadable)); + int g(int) { } // error: redeclaration of "g" must also have the "overloadable" attribute + + int h(int); + int h(int) __attribute__((overloadable)); // error: declaration of "h" must not + // have the "overloadable" attribute + +Functions marked ``overloadable`` must have prototypes. Therefore, the +following code is ill-formed: + +.. code-block:: c + + int h() __attribute__((overloadable)); // error: h does not have a prototype + +However, ``overloadable`` functions are allowed to use a ellipsis even if there +are no named parameters (as is permitted in C++). This feature is particularly +useful when combined with the ``unavailable`` attribute: + +.. code-block:: c++ + + void honeypot(...) __attribute__((overloadable, unavailable)); // calling me is an error + +Functions declared with the ``overloadable`` attribute have their names mangled +according to the same rules as C++ function names. For example, the three +``tgsin`` functions in our motivating example get the mangled names +``_Z5tgsinf``, ``_Z5tgsind``, and ``_Z5tgsine``, respectively. There are two +caveats to this use of name mangling: + +* Future versions of Clang may change the name mangling of functions overloaded + in C, so you should not depend on an specific mangling. To be completely + safe, we strongly urge the use of ``static inline`` with ``overloadable`` + functions. + +* The ``overloadable`` attribute has almost no meaning when used in C++, + because names will already be mangled and functions are already overloadable. + However, when an ``overloadable`` function occurs within an ``extern "C"`` + linkage specification, it's name *will* be mangled in the same way as it + would in C. + +For the purpose of backwards compatibility, at most one function with the same +name as other ``overloadable`` functions may omit the ``overloadable`` +attribute. In this case, the function without the ``overloadable`` attribute +will not have its name mangled. + +For example: + +.. code-block:: c + + // Notes with mangled names assume Itanium mangling. + int f(int); + int f(double) __attribute__((overloadable)); + void foo() { + f(5); // Emits a call to f (not _Z1fi, as it would with an overload that + // was marked with overloadable). + f(1.0); // Emits a call to _Z1fd. + } + +Support for unmarked overloads is not present in some versions of clang. You may +query for it using ``__has_extension(overloadable_unmarked)``. + +Query for this attribute with ``__has_attribute(overloadable)``. + + +reinitializes +------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``reinitializes``","``clang::reinitializes``","","","","","" + +The ``reinitializes`` attribute can be applied to a non-static, non-const C++ +member function to indicate that this member function reinitializes the entire +object to a known state, independent of the previous state of the object. + +This attribute can be interpreted by static analyzers that warn about uses of an +object that has been left in an indeterminate state by a move operation. If a +member function marked with the ``reinitializes`` attribute is called on a +moved-from object, the analyzer can conclude that the object is no longer in an +indeterminate state. + +A typical example where this attribute would be used is on functions that clear +a container class: + +.. code-block:: c++ + + template + class Container { + public: + ... + [[clang::reinitializes]] void Clear(); + ... + }; + + +release_capability, release_shared_capability +--------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``release_capability`` |br| ``release_shared_capability`` |br| ``release_generic_capability`` |br| ``unlock_function``","``clang::release_capability`` |br| ``clang::release_shared_capability`` |br| ``clang::release_generic_capability`` |br| ``clang::unlock_function``","","","","","" + +Marks a function as releasing a capability. + + +short_call, near +---------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``short_call`` |br| ``near``","``gnu::short_call`` |br| ``gnu::near``","","","","","Yes" + +Clang supports the ``__attribute__((long_call))``, ``__attribute__((far))``, +``__attribute__((short__call))``, and ``__attribute__((near))`` attributes +on MIPS targets. These attributes may only be added to function declarations +and change the code generated by the compiler when directly calling +the function. The ``short_call`` and ``near`` attributes are synonyms and +allow calls to the function to be made using the ``jal`` instruction, which +requires the function to be located in the same naturally aligned 256MB segment +as the caller. The ``long_call`` and ``far`` attributes are synonyms and +require the use of a different call sequence that works regardless +of the distance between the functions. + +These attributes have no effect for position-independent code. + +These attributes take priority over command line switches such +as ``-mlong-calls`` and ``-mno-long-calls``. + + +signal +------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``signal``","``gnu::signal``","","","","","Yes" + +Clang supports the GNU style ``__attribute__((signal))`` attribute on +AVR targets. This attribute may be attached to a function definition and instructs +the backend to generate appropriate function entry/exit code so that it can be used +directly as an interrupt service routine. + +Interrupt handler functions defined with the signal attribute do not re-enable interrupts. + + +speculative_load_hardening +-------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``speculative_load_hardening``","``clang::speculative_load_hardening``","``clang::speculative_load_hardening``","","","","Yes" + +This attribute can be applied to a function declaration in order to indicate + that `Speculative Load Hardening `_ + should be enabled for the function body. This can also be applied to a method + in Objective C. + + Speculative Load Hardening is a best-effort mitigation against + information leak attacks that make use of control flow + miss-speculation - specifically miss-speculation of whether a branch + is taken or not. Typically vulnerabilities enabling such attacks are + classified as "Spectre variant #1". Notably, this does not attempt to + mitigate against miss-speculation of branch target, classified as + "Spectre variant #2" vulnerabilities. + + When inlining, the attribute is sticky. Inlining a function that + carries this attribute will cause the caller to gain the + attribute. This is intended to provide a maximally conservative model + where the code in a function annotated with this attribute will always + (even after inlining) end up hardened. + + +target +------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``target``","``gnu::target``","","","","","Yes" + +Clang supports the GNU style ``__attribute__((target("OPTIONS")))`` attribute. +This attribute may be attached to a function definition and instructs +the backend to use different code generation options than were passed on the +command line. + +The current set of options correspond to the existing "subtarget features" for +the target with or without a "-mno-" in front corresponding to the absence +of the feature, as well as ``arch="CPU"`` which will change the default "CPU" +for the function. + +Example "subtarget features" from the x86 backend include: "mmx", "sse", "sse4.2", +"avx", "xop" and largely correspond to the machine specific options handled by +the front end. + +Additionally, this attribute supports function multiversioning for ELF based +x86/x86-64 targets, which can be used to create multiple implementations of the +same function that will be resolved at runtime based on the priority of their +``target`` attribute strings. A function is considered a multiversioned function +if either two declarations of the function have different ``target`` attribute +strings, or if it has a ``target`` attribute string of ``default``. For +example: + + .. code-block:: c++ + + __attribute__((target("arch=atom"))) + void foo() {} // will be called on 'atom' processors. + __attribute__((target("default"))) + void foo() {} // will be called on any other processors. + +All multiversioned functions must contain a ``default`` (fallback) +implementation, otherwise usages of the function are considered invalid. +Additionally, a function may not become multiversioned after its first use. + + +try_acquire_capability, try_acquire_shared_capability +----------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``try_acquire_capability`` |br| ``try_acquire_shared_capability``","``clang::try_acquire_capability`` |br| ``clang::try_acquire_shared_capability``","","","","","" + +Marks a function that attempts to acquire a capability. This function may fail to +actually acquire the capability; they accept a Boolean value determining +whether acquiring the capability means success (true), or failing to acquire +the capability means success (false). + + +xray_always_instrument, xray_never_instrument, xray_log_args +------------------------------------------------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``xray_always_instrument`` |br| ``xray_never_instrument``","``clang::xray_always_instrument`` |br| ``clang::xray_never_instrument``","``clang::xray_always_instrument`` |br| ``clang::xray_never_instrument``","","","","Yes" + +``__attribute__((xray_always_instrument))`` or ``[[clang::xray_always_instrument]]`` is used to mark member functions (in C++), methods (in Objective C), and free functions (in C, C++, and Objective C) to be instrumented with XRay. This will cause the function to always have space at the beginning and exit points to allow for runtime patching. + +Conversely, ``__attribute__((xray_never_instrument))`` or ``[[clang::xray_never_instrument]]`` will inhibit the insertion of these instrumentation points. + +If a function has neither of these attributes, they become subject to the XRay heuristics used to determine whether a function should be instrumented or otherwise. + +``__attribute__((xray_log_args(N)))`` or ``[[clang::xray_log_args(N)]]`` is used to preserve N function arguments for the logging function. Currently, only N==1 is supported. + + +xray_always_instrument, xray_never_instrument, xray_log_args +------------------------------------------------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``xray_log_args``","``clang::xray_log_args``","``clang::xray_log_args``","","","","Yes" + +``__attribute__((xray_always_instrument))`` or ``[[clang::xray_always_instrument]]`` is used to mark member functions (in C++), methods (in Objective C), and free functions (in C, C++, and Objective C) to be instrumented with XRay. This will cause the function to always have space at the beginning and exit points to allow for runtime patching. + +Conversely, ``__attribute__((xray_never_instrument))`` or ``[[clang::xray_never_instrument]]`` will inhibit the insertion of these instrumentation points. + +If a function has neither of these attributes, they become subject to the XRay heuristics used to determine whether a function should be instrumented or otherwise. + +``__attribute__((xray_log_args(N)))`` or ``[[clang::xray_log_args(N)]]`` is used to preserve N function arguments for the logging function. Currently, only N==1 is supported. + + +Variable Attributes +=================== + + +always_destroy +-------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``always_destroy``","``clang::always_destroy``","","","","","Yes" + +The ``always_destroy`` attribute specifies that a variable with static or thread +storage duration should have its exit-time destructor run. This attribute is the +default unless clang was invoked with -fno-c++-static-destructors. + + +dllexport +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``dllexport``","``gnu::dllexport``","","``dllexport``","","","Yes" + +The ``__declspec(dllexport)`` attribute declares a variable, function, or +Objective-C interface to be exported from the module. It is available under the +``-fdeclspec`` flag for compatibility with various compilers. The primary use +is for COFF object files which explicitly specify what interfaces are available +for external use. See the dllexport_ documentation on MSDN for more +information. + +.. _dllexport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx + + +dllimport +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``dllimport``","``gnu::dllimport``","","``dllimport``","","","Yes" + +The ``__declspec(dllimport)`` attribute declares a variable, function, or +Objective-C interface to be imported from an external module. It is available +under the ``-fdeclspec`` flag for compatibility with various compilers. The +primary use is for COFF object files which explicitly specify what interfaces +are imported from external modules. See the dllimport_ documentation on MSDN +for more information. + +.. _dllimport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx + + +init_seg +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","","","``init_seg``","" + +The attribute applied by ``pragma init_seg()`` controls the section into +which global initialization function pointers are emitted. It is only +available with ``-fms-extensions``. Typically, this function pointer is +emitted into ``.CRT$XCU`` on Windows. The user can change the order of +initialization by using a different section name with the same +``.CRT$XC`` prefix and a suffix that sorts lexicographically before or +after the standard ``.CRT$XCU`` sections. See the init_seg_ +documentation on MSDN for more information. + +.. _init_seg: http://msdn.microsoft.com/en-us/library/7977wcck(v=vs.110).aspx + + +maybe_unused, unused +-------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``unused``","``maybe_unused`` |br| ``gnu::unused``","``maybe_unused``","","","","" + +When passing the ``-Wunused`` flag to Clang, entities that are unused by the +program may be diagnosed. The ``[[maybe_unused]]`` (or +``__attribute__((unused))``) attribute can be used to silence such diagnostics +when the entity cannot be removed. For instance, a local variable may exist +solely for use in an ``assert()`` statement, which makes the local variable +unused when ``NDEBUG`` is defined. + +The attribute may be applied to the declaration of a class, a typedef, a +variable, a function or method, a function parameter, an enumeration, an +enumerator, a non-static data member, or a label. + +.. code-block: c++ + #include + + [[maybe_unused]] void f([[maybe_unused]] bool thing1, + [[maybe_unused]] bool thing2) { + [[maybe_unused]] bool b = thing1 && thing2; + assert(b); + } + + +no_destroy +---------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``no_destroy``","``clang::no_destroy``","","","","","Yes" + +The ``no_destroy`` attribute specifies that a variable with static or thread +storage duration shouldn't have its exit-time destructor run. Annotating every +static and thread duration variable with this attribute is equivalent to +invoking clang with -fno-c++-static-destructors. + + +nodebug +------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``nodebug``","``gnu::nodebug``","","","","","Yes" + +The ``nodebug`` attribute allows you to suppress debugging information for a +function or method, or for a variable that is not a parameter or a non-static +data member. + + +noescape +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``noescape``","``clang::noescape``","``clang::noescape``","","","","Yes" + +``noescape`` placed on a function parameter of a pointer type is used to inform +the compiler that the pointer cannot escape: that is, no reference to the object +the pointer points to that is derived from the parameter value will survive +after the function returns. Users are responsible for making sure parameters +annotated with ``noescape`` do not actuallly escape. + +For example: + +.. code-block:: c + + int *gp; + + void nonescapingFunc(__attribute__((noescape)) int *p) { + *p += 100; // OK. + } + + void escapingFunc(__attribute__((noescape)) int *p) { + gp = p; // Not OK. + } + +Additionally, when the parameter is a `block pointer +`, the same restriction +applies to copies of the block. For example: + +.. code-block:: c + + typedef void (^BlockTy)(); + BlockTy g0, g1; + + void nonescapingFunc(__attribute__((noescape)) BlockTy block) { + block(); // OK. + } + + void escapingFunc(__attribute__((noescape)) BlockTy block) { + g0 = block; // Not OK. + g1 = Block_copy(block); // Not OK either. + } + + +nosvm +----- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``nosvm``","","","","","","Yes" + +OpenCL 2.0 supports the optional ``__attribute__((nosvm))`` qualifier for +pointer variable. It informs the compiler that the pointer does not refer +to a shared virtual memory region. See OpenCL v2.0 s6.7.2 for details. + +Since it is not widely used and has been removed from OpenCL 2.1, it is ignored +by Clang. + + +objc_externally_retained +------------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``objc_externally_retained``","``clang::objc_externally_retained``","``clang::objc_externally_retained``","","","","Yes" + +The ``objc_externally_retained`` attribute can be applied to strong local +variables, functions, methods, or blocks to opt into +`externally-retained semantics +`_. + +When applied to the definition of a function, method, or block, every parameter +of the function with implicit strong retainable object pointer type is +considered externally-retained, and becomes ``const``. By explicitly annotating +a parameter with ``__strong``, you can opt back into the default +non-externally-retained behaviour for that parameter. For instance, +``first_param`` is externally-retained below, but not ``second_param``: + +.. code-block:: objc + + __attribute__((objc_externally_retained)) + void f(NSArray *first_param, __strong NSArray *second_param) { + // ... + } + +Likewise, when applied to a strong local variable, that variable becomes +``const`` and is considered externally-retained. + +When compiled without ``-fobjc-arc``, this attribute is ignored. + + +pass_object_size +---------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``pass_object_size``","``clang::pass_object_size``","``clang::pass_object_size``","","","","Yes" + +.. Note:: The mangling of functions with parameters that are annotated with + ``pass_object_size`` is subject to change. You can get around this by + using ``__asm__("foo")`` to explicitly name your functions, thus preserving + your ABI; also, non-overloadable C functions with ``pass_object_size`` are + not mangled. + +The ``pass_object_size(Type)`` attribute can be placed on function parameters to +instruct clang to call ``__builtin_object_size(param, Type)`` at each callsite +of said function, and implicitly pass the result of this call in as an invisible +argument of type ``size_t`` directly after the parameter annotated with +``pass_object_size``. Clang will also replace any calls to +``__builtin_object_size(param, Type)`` in the function by said implicit +parameter. + +Example usage: + +.. code-block:: c + + int bzero1(char *const p __attribute__((pass_object_size(0)))) + __attribute__((noinline)) { + int i = 0; + for (/**/; i < (int)__builtin_object_size(p, 0); ++i) { + p[i] = 0; + } + return i; + } + + int main() { + char chars[100]; + int n = bzero1(&chars[0]); + assert(n == sizeof(chars)); + return 0; + } + +If successfully evaluating ``__builtin_object_size(param, Type)`` at the +callsite is not possible, then the "failed" value is passed in. So, using the +definition of ``bzero1`` from above, the following code would exit cleanly: + +.. code-block:: c + + int main2(int argc, char *argv[]) { + int n = bzero1(argv); + assert(n == -1); + return 0; + } + +``pass_object_size`` plays a part in overload resolution. If two overload +candidates are otherwise equally good, then the overload with one or more +parameters with ``pass_object_size`` is preferred. This implies that the choice +between two identical overloads both with ``pass_object_size`` on one or more +parameters will always be ambiguous; for this reason, having two such overloads +is illegal. For example: + +.. code-block:: c++ + + #define PS(N) __attribute__((pass_object_size(N))) + // OK + void Foo(char *a, char *b); // Overload A + // OK -- overload A has no parameters with pass_object_size. + void Foo(char *a PS(0), char *b PS(0)); // Overload B + // Error -- Same signature (sans pass_object_size) as overload B, and both + // overloads have one or more parameters with the pass_object_size attribute. + void Foo(void *a PS(0), void *b); + + // OK + void Bar(void *a PS(0)); // Overload C + // OK + void Bar(char *c PS(1)); // Overload D + + void main() { + char known[10], *unknown; + Foo(unknown, unknown); // Calls overload B + Foo(known, unknown); // Calls overload B + Foo(unknown, known); // Calls overload B + Foo(known, known); // Calls overload B + + Bar(known); // Calls overload D + Bar(unknown); // Calls overload D + } + +Currently, ``pass_object_size`` is a bit restricted in terms of its usage: + +* Only one use of ``pass_object_size`` is allowed per parameter. + +* It is an error to take the address of a function with ``pass_object_size`` on + any of its parameters. If you wish to do this, you can create an overload + without ``pass_object_size`` on any parameters. + +* It is an error to apply the ``pass_object_size`` attribute to parameters that + are not pointers. Additionally, any parameter that ``pass_object_size`` is + applied to must be marked ``const`` at its function's definition. + + +require_constant_initialization +------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``require_constant_initialization``","``clang::require_constant_initialization``","","","","","Yes" + +This attribute specifies that the variable to which it is attached is intended +to have a `constant initializer `_ +according to the rules of [basic.start.static]. The variable is required to +have static or thread storage duration. If the initialization of the variable +is not a constant initializer an error will be produced. This attribute may +only be used in C++. + +Note that in C++03 strict constant expression checking is not done. Instead +the attribute reports if Clang can emit the variable as a constant, even if it's +not technically a 'constant initializer'. This behavior is non-portable. + +Static storage duration variables with constant initializers avoid hard-to-find +bugs caused by the indeterminate order of dynamic initialization. They can also +be safely used during dynamic initialization across translation units. + +This attribute acts as a compile time assertion that the requirements +for constant initialization have been met. Since these requirements change +between dialects and have subtle pitfalls it's important to fail fast instead +of silently falling back on dynamic initialization. + +.. code-block:: c++ + + // -std=c++14 + #define SAFE_STATIC [[clang::require_constant_initialization]] + struct T { + constexpr T(int) {} + ~T(); // non-trivial + }; + SAFE_STATIC T x = {42}; // Initialization OK. Doesn't check destructor. + SAFE_STATIC T y = 42; // error: variable does not have a constant initializer + // copy initialization is not a constant expression on a non-literal type. + + +section, __declspec(allocate) +----------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``section``","``gnu::section``","","``allocate``","","","Yes" + +The ``section`` attribute allows you to specify a specific section a +global variable or function should be in after translation. + + +swift_context +------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``swift_context``","``clang::swift_context``","``clang::swift_context``","","","","Yes" + +The ``swift_context`` attribute marks a parameter of a ``swiftcall`` +function as having the special context-parameter ABI treatment. + +This treatment generally passes the context value in a special register +which is normally callee-preserved. + +A ``swift_context`` parameter must either be the last parameter or must be +followed by a ``swift_error_result`` parameter (which itself must always be +the last parameter). + +A context parameter must have pointer or reference type. + + +swift_error_result +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``swift_error_result``","``clang::swift_error_result``","``clang::swift_error_result``","","","","Yes" + +The ``swift_error_result`` attribute marks a parameter of a ``swiftcall`` +function as having the special error-result ABI treatment. + +This treatment generally passes the underlying error value in and out of +the function through a special register which is normally callee-preserved. +This is modeled in C by pretending that the register is addressable memory: + +- The caller appears to pass the address of a variable of pointer type. + The current value of this variable is copied into the register before + the call; if the call returns normally, the value is copied back into the + variable. + +- The callee appears to receive the address of a variable. This address + is actually a hidden location in its own stack, initialized with the + value of the register upon entry. When the function returns normally, + the value in that hidden location is written back to the register. + +A ``swift_error_result`` parameter must be the last parameter, and it must be +preceded by a ``swift_context`` parameter. + +A ``swift_error_result`` parameter must have type ``T**`` or ``T*&`` for some +type T. Note that no qualifiers are permitted on the intermediate level. + +It is undefined behavior if the caller does not pass a pointer or +reference to a valid object. + +The standard convention is that the error value itself (that is, the +value stored in the apparent argument) will be null upon function entry, +but this is not enforced by the ABI. + + +swift_indirect_result +--------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``swift_indirect_result``","``clang::swift_indirect_result``","``clang::swift_indirect_result``","","","","Yes" + +The ``swift_indirect_result`` attribute marks a parameter of a ``swiftcall`` +function as having the special indirect-result ABI treatment. + +This treatment gives the parameter the target's normal indirect-result +ABI treatment, which may involve passing it differently from an ordinary +parameter. However, only the first indirect result will receive this +treatment. Furthermore, low-level lowering may decide that a direct result +must be returned indirectly; if so, this will take priority over the +``swift_indirect_result`` parameters. + +A ``swift_indirect_result`` parameter must either be the first parameter or +follow another ``swift_indirect_result`` parameter. + +A ``swift_indirect_result`` parameter must have type ``T*`` or ``T&`` for +some object type ``T``. If ``T`` is a complete type at the point of +definition of a function, it is undefined behavior if the argument +value does not point to storage of adequate size and alignment for a +value of type ``T``. + +Making indirect results explicit in the signature allows C functions to +directly construct objects into them without relying on language +optimizations like C++'s named return value optimization (NRVO). + + +swiftcall +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``swiftcall``","``clang::swiftcall``","``clang::swiftcall``","","","","" + +The ``swiftcall`` attribute indicates that a function should be called +using the Swift calling convention for a function or function pointer. + +The lowering for the Swift calling convention, as described by the Swift +ABI documentation, occurs in multiple phases. The first, "high-level" +phase breaks down the formal parameters and results into innately direct +and indirect components, adds implicit paraameters for the generic +signature, and assigns the context and error ABI treatments to parameters +where applicable. The second phase breaks down the direct parameters +and results from the first phase and assigns them to registers or the +stack. The ``swiftcall`` convention only handles this second phase of +lowering; the C function type must accurately reflect the results +of the first phase, as follows: + +- Results classified as indirect by high-level lowering should be + represented as parameters with the ``swift_indirect_result`` attribute. + +- Results classified as direct by high-level lowering should be represented + as follows: + + - First, remove any empty direct results. + + - If there are no direct results, the C result type should be ``void``. + + - If there is one direct result, the C result type should be a type with + the exact layout of that result type. + + - If there are a multiple direct results, the C result type should be + a struct type with the exact layout of a tuple of those results. + +- Parameters classified as indirect by high-level lowering should be + represented as parameters of pointer type. + +- Parameters classified as direct by high-level lowering should be + omitted if they are empty types; otherwise, they should be represented + as a parameter type with a layout exactly matching the layout of the + Swift parameter type. + +- The context parameter, if present, should be represented as a trailing + parameter with the ``swift_context`` attribute. + +- The error result parameter, if present, should be represented as a + trailing parameter (always following a context parameter) with the + ``swift_error_result`` attribute. + +``swiftcall`` does not support variadic arguments or unprototyped functions. + +The parameter ABI treatment attributes are aspects of the function type. +A function type which which applies an ABI treatment attribute to a +parameter is a different type from an otherwise-identical function type +that does not. A single parameter may not have multiple ABI treatment +attributes. + +Support for this feature is target-dependent, although it should be +supported on every target that Swift supports. Query for this support +with ``__has_attribute(swiftcall)``. This implies support for the +``swift_context``, ``swift_error_result``, and ``swift_indirect_result`` +attributes. + + +thread +------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","``thread``","","","" + +The ``__declspec(thread)`` attribute declares a variable with thread local +storage. It is available under the ``-fms-extensions`` flag for MSVC +compatibility. See the documentation for `__declspec(thread)`_ on MSDN. + +.. _`__declspec(thread)`: http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx + +In Clang, ``__declspec(thread)`` is generally equivalent in functionality to the +GNU ``__thread`` keyword. The variable must not have a destructor and must have +a constant initializer, if any. The attribute only applies to variables +declared with static storage duration, such as globals, class static data +members, and static locals. + + +tls_model +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``tls_model``","``gnu::tls_model``","","","","","Yes" + +The ``tls_model`` attribute allows you to specify which thread-local storage +model to use. It accepts the following strings: + +* global-dynamic +* local-dynamic +* initial-exec +* local-exec + +TLS models are mutually exclusive. + + +trivial_abi +----------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``trivial_abi``","``clang::trivial_abi``","","","","","Yes" + +The ``trivial_abi`` attribute can be applied to a C++ class, struct, or union. +It instructs the compiler to pass and return the type using the C ABI for the +underlying type when the type would otherwise be considered non-trivial for the +purpose of calls. +A class annotated with `trivial_abi` can have non-trivial destructors or copy/move constructors without automatically becoming non-trivial for the purposes of calls. For example: + + .. code-block:: c++ + + // A is trivial for the purposes of calls because `trivial_abi` makes the + // user-provided special functions trivial. + struct __attribute__((trivial_abi)) A { + ~A(); + A(const A &); + A(A &&); + int x; + }; + + // B's destructor and copy/move constructor are considered trivial for the + // purpose of calls because A is trivial. + struct B { + A a; + }; + +If a type is trivial for the purposes of calls, has a non-trivial destructor, +and is passed as an argument by value, the convention is that the callee will +destroy the object before returning. + +Attribute ``trivial_abi`` has no effect in the following cases: + +- The class directly declares a virtual base or virtual methods. +- The class has a base class that is non-trivial for the purposes of calls. +- The class has a non-static data member whose type is non-trivial for the purposes of calls, which includes: + + - classes that are non-trivial for the purposes of calls + - __weak-qualified types in Objective-C++ + - arrays of any of the above + + +uninitialized +------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``uninitialized``","``clang::uninitialized``","","","","","" + +The command-line parameter ``-ftrivial-auto-var-init=*`` can be used to +initialize trivial automatic stack variables. By default, trivial automatic +stack variables are uninitialized. This attribute is used to override the +command-line parameter, forcing variables to remain uninitialized. It has no +semantic meaning in that using uninitialized values is undefined behavior, +it rather documents the programmer's intent. + + +Type Attributes +=============== + + +__single_inhertiance, __multiple_inheritance, __virtual_inheritance +------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","","``__single_inheritance`` |br| ``__multiple_inheritance`` |br| ``__virtual_inheritance`` |br| ``__unspecified_inheritance``","","" + +This collection of keywords is enabled under ``-fms-extensions`` and controls +the pointer-to-member representation used on ``*-*-win32`` targets. + +The ``*-*-win32`` targets utilize a pointer-to-member representation which +varies in size and alignment depending on the definition of the underlying +class. + +However, this is problematic when a forward declaration is only available and +no definition has been made yet. In such cases, Clang is forced to utilize the +most general representation that is available to it. + +These keywords make it possible to use a pointer-to-member representation other +than the most general one regardless of whether or not the definition will ever +be present in the current translation unit. + +This family of keywords belong between the ``class-key`` and ``class-name``: + +.. code-block:: c++ + + struct __single_inheritance S; + int S::*i; + struct S {}; + +This keyword can be applied to class templates but only has an effect when used +on full specializations: + +.. code-block:: c++ + + template struct __single_inheritance A; // warning: inheritance model ignored on primary template + template struct __multiple_inheritance A; // warning: inheritance model ignored on partial specialization + template <> struct __single_inheritance A; + +Note that choosing an inheritance model less general than strictly necessary is +an error: + +.. code-block:: c++ + + struct __multiple_inheritance S; // error: inheritance model does not match definition + int S::*i; + struct S {}; + + +align_value +----------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``align_value``","","","","","","Yes" + +The align_value attribute can be added to the typedef of a pointer type or the +declaration of a variable of pointer or reference type. It specifies that the +pointer will point to, or the reference will bind to, only objects with at +least the provided alignment. This alignment value must be some positive power +of 2. + + .. code-block:: c + + typedef double * aligned_double_ptr __attribute__((align_value(64))); + void foo(double & x __attribute__((align_value(128)), + aligned_double_ptr y) { ... } + +If the pointer value does not have the specified alignment at runtime, the +behavior of the program is undefined. + + +empty_bases +----------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","``empty_bases``","","","" + +The empty_bases attribute permits the compiler to utilize the +empty-base-optimization more frequently. +This attribute only applies to struct, class, and union types. +It is only supported when using the Microsoft C++ ABI. + + +enum_extensibility +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``enum_extensibility``","``clang::enum_extensibility``","``clang::enum_extensibility``","","","","Yes" + +Attribute ``enum_extensibility`` is used to distinguish between enum definitions +that are extensible and those that are not. The attribute can take either +``closed`` or ``open`` as an argument. ``closed`` indicates a variable of the +enum type takes a value that corresponds to one of the enumerators listed in the +enum definition or, when the enum is annotated with ``flag_enum``, a value that +can be constructed using values corresponding to the enumerators. ``open`` +indicates a variable of the enum type can take any values allowed by the +standard and instructs clang to be more lenient when issuing warnings. + +.. code-block:: c + + enum __attribute__((enum_extensibility(closed))) ClosedEnum { + A0, A1 + }; + + enum __attribute__((enum_extensibility(open))) OpenEnum { + B0, B1 + }; + + enum __attribute__((enum_extensibility(closed),flag_enum)) ClosedFlagEnum { + C0 = 1 << 0, C1 = 1 << 1 + }; + + enum __attribute__((enum_extensibility(open),flag_enum)) OpenFlagEnum { + D0 = 1 << 0, D1 = 1 << 1 + }; + + void foo1() { + enum ClosedEnum ce; + enum OpenEnum oe; + enum ClosedFlagEnum cfe; + enum OpenFlagEnum ofe; + + ce = A1; // no warnings + ce = 100; // warning issued + oe = B1; // no warnings + oe = 100; // no warnings + cfe = C0 | C1; // no warnings + cfe = C0 | C1 | 4; // warning issued + ofe = D0 | D1; // no warnings + ofe = D0 | D1 | 4; // no warnings + } + + +flag_enum +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``flag_enum``","``clang::flag_enum``","``clang::flag_enum``","","","","Yes" + +This attribute can be added to an enumerator to signal to the compiler that it +is intended to be used as a flag type. This will cause the compiler to assume +that the range of the type includes all of the values that you can get by +manipulating bits of the enumerator when issuing warnings. + + +layout_version +-------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","``layout_version``","","","" + +The layout_version attribute requests that the compiler utilize the class +layout rules of a particular compiler version. +This attribute only applies to struct, class, and union types. +It is only supported when using the Microsoft C++ ABI. + + +lto_visibility_public +--------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``lto_visibility_public``","``clang::lto_visibility_public``","``clang::lto_visibility_public``","","","","Yes" + +See :doc:`LTOVisibility`. + + +noderef +------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``noderef``","``clang::noderef``","``clang::noderef``","","","","" + +The ``noderef`` attribute causes clang to diagnose dereferences of annotated pointer types. +This is ideally used with pointers that point to special memory which cannot be read +from or written to, but allowing for the pointer to be used in pointer arithmetic. +The following are examples of valid expressions where dereferences are diagnosed: + +.. code-block:: c + + int __attribute__((noderef)) *p; + int x = *p; // warning + + int __attribute__((noderef)) **p2; + x = **p2; // warning + + int * __attribute__((noderef)) *p3; + p = *p3; // warning + + struct S { + int a; + }; + struct S __attribute__((noderef)) *s; + x = s->a; // warning + x = (*s).a; // warning + +Not all dereferences may diagnose a warning if the value directed by the pointer may not be +accessed. The following are examples of valid expressions where may not be diagnosed: + +.. code-block:: c + + int *q; + int __attribute__((noderef)) *p; + q = &*p; + q = *&p; + + struct S { + int a; + }; + struct S __attribute__((noderef)) *s; + p = &s->a; + p = &(*s).a; + +``noderef`` is currently only supported for pointers and arrays and not usable for +references or Objective-C object pointers. + +.. code-block: c++ + + int x = 2; + int __attribute__((noderef)) &y = x; // warning: 'noderef' can only be used on an array or pointer type + +.. code-block: objc + + id __attribute__((noderef)) obj = [NSObject new]; // warning: 'noderef' can only be used on an array or pointer type + + +novtable +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","``novtable``","","","" + +This attribute can be added to a class declaration or definition to signal to +the compiler that constructors and destructors will not reference the virtual +function table. It is only supported when using the Microsoft C++ ABI. + + +objc_subclassing_restricted +--------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``objc_subclassing_restricted``","``clang::objc_subclassing_restricted``","``clang::objc_subclassing_restricted``","","","","Yes" + +This attribute can be added to an Objective-C ``@interface`` declaration to +ensure that this class cannot be subclassed. + + +selectany +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``selectany``","``gnu::selectany``","","``selectany``","","","" + +This attribute appertains to a global symbol, causing it to have a weak +definition ( +`linkonce `_ +), allowing the linker to select any definition. + +For more information see +`gcc documentation `_ +or `msvc documentation `_. + + +transparent_union +----------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``transparent_union``","``gnu::transparent_union``","","","","","" + +This attribute can be applied to a union to change the behaviour of calls to +functions that have an argument with a transparent union type. The compiler +behaviour is changed in the following manner: + +- A value whose type is any member of the transparent union can be passed as an + argument without the need to cast that value. + +- The argument is passed to the function using the calling convention of the + first member of the transparent union. Consequently, all the members of the + transparent union should have the same calling convention as its first member. + +Transparent unions are not supported in C++. + + +Statement Attributes +==================== + + +#pragma clang loop +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","","","``clang loop`` |br| ``unroll`` |br| ``nounroll`` |br| ``unroll_and_jam`` |br| ``nounroll_and_jam``","" + +The ``#pragma clang loop`` directive allows loop optimization hints to be +specified for the subsequent loop. The directive allows pipelining to be +disabled, or vectorization, interleaving, and unrolling to be enabled or disabled. +Vector width, interleave count, unrolling count, and the initiation interval +for pipelining can be explicitly specified. See `language extensions +`_ +for details. + + +#pragma unroll, #pragma nounroll +-------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","","","``clang loop`` |br| ``unroll`` |br| ``nounroll`` |br| ``unroll_and_jam`` |br| ``nounroll_and_jam``","" + +Loop unrolling optimization hints can be specified with ``#pragma unroll`` and +``#pragma nounroll``. The pragma is placed immediately before a for, while, +do-while, or c++11 range-based for loop. + +Specifying ``#pragma unroll`` without a parameter directs the loop unroller to +attempt to fully unroll the loop if the trip count is known at compile time and +attempt to partially unroll the loop if the trip count is not known at compile +time: + +.. code-block:: c++ + + #pragma unroll + for (...) { + ... + } + +Specifying the optional parameter, ``#pragma unroll _value_``, directs the +unroller to unroll the loop ``_value_`` times. The parameter may optionally be +enclosed in parentheses: + +.. code-block:: c++ + + #pragma unroll 16 + for (...) { + ... + } + + #pragma unroll(16) + for (...) { + ... + } + +Specifying ``#pragma nounroll`` indicates that the loop should not be unrolled: + +.. code-block:: c++ + + #pragma nounroll + for (...) { + ... + } + +``#pragma unroll`` and ``#pragma unroll _value_`` have identical semantics to +``#pragma clang loop unroll(full)`` and +``#pragma clang loop unroll_count(_value_)`` respectively. ``#pragma nounroll`` +is equivalent to ``#pragma clang loop unroll(disable)``. See +`language extensions +`_ +for further details including limitations of the unroll hints. + + +__read_only, __write_only, __read_write (read_only, write_only, read_write) +--------------------------------------------------------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","","``__read_only`` |br| ``read_only`` |br| ``__write_only`` |br| ``write_only`` |br| ``__read_write`` |br| ``read_write``","","" + +The access qualifiers must be used with image object arguments or pipe arguments +to declare if they are being read or written by a kernel or function. + +The read_only/__read_only, write_only/__write_only and read_write/__read_write +names are reserved for use as access qualifiers and shall not be used otherwise. + +.. code-block:: c + + kernel void + foo (read_only image2d_t imageA, + write_only image2d_t imageB) { + ... + } + +In the above example imageA is a read-only 2D image object, and imageB is a +write-only 2D image object. + +The read_write (or __read_write) qualifier can not be used with pipe. + +More details can be found in the OpenCL C language Spec v2.0, Section 6.6. + + +fallthrough +----------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","``fallthrough`` |br| ``clang::fallthrough``","``fallthrough``","","","","" + +The ``fallthrough`` (or ``clang::fallthrough``) attribute is used +to annotate intentional fall-through +between switch labels. It can only be applied to a null statement placed at a +point of execution between any statement and the next switch label. It is +common to mark these places with a specific comment, but this attribute is +meant to replace comments with a more strict annotation, which can be checked +by the compiler. This attribute doesn't change semantics of the code and can +be used wherever an intended fall-through occurs. It is designed to mimic +control-flow statements like ``break;``, so it can be placed in most places +where ``break;`` can, but only if there are no statements on the execution path +between it and the next switch label. + +By default, Clang does not warn on unannotated fallthrough from one ``switch`` +case to another. Diagnostics on fallthrough without a corresponding annotation +can be enabled with the ``-Wimplicit-fallthrough`` argument. + +Here is an example: + +.. code-block:: c++ + + // compile with -Wimplicit-fallthrough + switch (n) { + case 22: + case 33: // no warning: no statements between case labels + f(); + case 44: // warning: unannotated fall-through + g(); + [[clang::fallthrough]]; + case 55: // no warning + if (x) { + h(); + break; + } + else { + i(); + [[clang::fallthrough]]; + } + case 66: // no warning + p(); + [[clang::fallthrough]]; // warning: fallthrough annotation does not + // directly precede case label + q(); + case 77: // warning: unannotated fall-through + r(); + } + + +intel_reqd_sub_group_size +------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``intel_reqd_sub_group_size``","","","","","","Yes" + +The optional attribute intel_reqd_sub_group_size can be used to indicate that +the kernel must be compiled and executed with the specified subgroup size. When +this attribute is present, get_max_sub_group_size() is guaranteed to return the +specified integer value. This is important for the correctness of many subgroup +algorithms, and in some cases may be used by the compiler to generate more optimal +code. See `cl_intel_required_subgroup_size +` +for details. + + +opencl_unroll_hint +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``opencl_unroll_hint``","","","","","","" + +The opencl_unroll_hint attribute qualifier can be used to specify that a loop +(for, while and do loops) can be unrolled. This attribute qualifier can be +used to specify full unrolling or partial unrolling by a specified amount. +This is a compiler hint and the compiler may ignore this directive. See +`OpenCL v2.0 `_ +s6.11.5 for details. + + +suppress +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","``gsl::suppress``","","","","","" + +The ``[[gsl::suppress]]`` attribute suppresses specific +clang-tidy diagnostics for rules of the `C++ Core Guidelines`_ in a portable +way. The attribute can be attached to declarations, statements, and at +namespace scope. + +.. code-block:: c++ + + [[gsl::suppress("Rh-public")]] + void f_() { + int *p; + [[gsl::suppress("type")]] { + p = reinterpret_cast(7); + } + } + namespace N { + [[clang::suppress("type", "bounds")]]; + ... + } + +.. _`C++ Core Guidelines`: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#inforce-enforcement + + +AMD GPU Attributes +================== + + +amdgpu_flat_work_group_size +--------------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``amdgpu_flat_work_group_size``","``clang::amdgpu_flat_work_group_size``","","","","","Yes" + +The flat work-group size is the number of work-items in the work-group size +specified when the kernel is dispatched. It is the product of the sizes of the +x, y, and z dimension of the work-group. + +Clang supports the +``__attribute__((amdgpu_flat_work_group_size(, )))`` attribute for the +AMDGPU target. This attribute may be attached to a kernel function definition +and is an optimization hint. + +```` parameter specifies the minimum flat work-group size, and ```` +parameter specifies the maximum flat work-group size (must be greater than +````) to which all dispatches of the kernel will conform. Passing ``0, 0`` +as ``, `` implies the default behavior (``128, 256``). + +If specified, the AMDGPU target backend might be able to produce better machine +code for barriers and perform scratch promotion by estimating available group +segment size. + +An error will be given if: + - Specified values violate subtarget specifications; + - Specified values are not compatible with values provided through other + attributes. + + +amdgpu_num_sgpr +--------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``amdgpu_num_sgpr``","``clang::amdgpu_num_sgpr``","","","","","Yes" + +Clang supports the ``__attribute__((amdgpu_num_sgpr()))`` and +``__attribute__((amdgpu_num_vgpr()))`` attributes for the AMDGPU +target. These attributes may be attached to a kernel function definition and are +an optimization hint. + +If these attributes are specified, then the AMDGPU target backend will attempt +to limit the number of SGPRs and/or VGPRs used to the specified value(s). The +number of used SGPRs and/or VGPRs may further be rounded up to satisfy the +allocation requirements or constraints of the subtarget. Passing ``0`` as +``num_sgpr`` and/or ``num_vgpr`` implies the default behavior (no limits). + +These attributes can be used to test the AMDGPU target backend. It is +recommended that the ``amdgpu_waves_per_eu`` attribute be used to control +resources such as SGPRs and VGPRs since it is aware of the limits for different +subtargets. + +An error will be given if: + - Specified values violate subtarget specifications; + - Specified values are not compatible with values provided through other + attributes; + - The AMDGPU target backend is unable to create machine code that can meet the + request. + + +amdgpu_num_vgpr +--------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``amdgpu_num_vgpr``","``clang::amdgpu_num_vgpr``","","","","","Yes" + +Clang supports the ``__attribute__((amdgpu_num_sgpr()))`` and +``__attribute__((amdgpu_num_vgpr()))`` attributes for the AMDGPU +target. These attributes may be attached to a kernel function definition and are +an optimization hint. + +If these attributes are specified, then the AMDGPU target backend will attempt +to limit the number of SGPRs and/or VGPRs used to the specified value(s). The +number of used SGPRs and/or VGPRs may further be rounded up to satisfy the +allocation requirements or constraints of the subtarget. Passing ``0`` as +``num_sgpr`` and/or ``num_vgpr`` implies the default behavior (no limits). + +These attributes can be used to test the AMDGPU target backend. It is +recommended that the ``amdgpu_waves_per_eu`` attribute be used to control +resources such as SGPRs and VGPRs since it is aware of the limits for different +subtargets. + +An error will be given if: + - Specified values violate subtarget specifications; + - Specified values are not compatible with values provided through other + attributes; + - The AMDGPU target backend is unable to create machine code that can meet the + request. + + +amdgpu_waves_per_eu +------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``amdgpu_waves_per_eu``","``clang::amdgpu_waves_per_eu``","","","","","Yes" + +A compute unit (CU) is responsible for executing the wavefronts of a work-group. +It is composed of one or more execution units (EU), which are responsible for +executing the wavefronts. An EU can have enough resources to maintain the state +of more than one executing wavefront. This allows an EU to hide latency by +switching between wavefronts in a similar way to symmetric multithreading on a +CPU. In order to allow the state for multiple wavefronts to fit on an EU, the +resources used by a single wavefront have to be limited. For example, the number +of SGPRs and VGPRs. Limiting such resources can allow greater latency hiding, +but can result in having to spill some register state to memory. + +Clang supports the ``__attribute__((amdgpu_waves_per_eu([, ])))`` +attribute for the AMDGPU target. This attribute may be attached to a kernel +function definition and is an optimization hint. + +```` parameter specifies the requested minimum number of waves per EU, and +*optional* ```` parameter specifies the requested maximum number of waves +per EU (must be greater than ```` if specified). If ```` is omitted, +then there is no restriction on the maximum number of waves per EU other than +the one dictated by the hardware for which the kernel is compiled. Passing +``0, 0`` as ``, `` implies the default behavior (no limits). + +If specified, this attribute allows an advanced developer to tune the number of +wavefronts that are capable of fitting within the resources of an EU. The AMDGPU +target backend can use this information to limit resources, such as number of +SGPRs, number of VGPRs, size of available group and private memory segments, in +such a way that guarantees that at least ```` wavefronts and at most +```` wavefronts are able to fit within the resources of an EU. Requesting +more wavefronts can hide memory latency but limits available registers which +can result in spilling. Requesting fewer wavefronts can help reduce cache +thrashing, but can reduce memory latency hiding. + +This attribute controls the machine code generated by the AMDGPU target backend +to ensure it is capable of meeting the requested values. However, when the +kernel is executed, there may be other reasons that prevent meeting the request, +for example, there may be wavefronts from other kernels executing on the EU. + +An error will be given if: + - Specified values violate subtarget specifications; + - Specified values are not compatible with values provided through other + attributes; + - The AMDGPU target backend is unable to create machine code that can meet the + request. + + +OpenCL Address Spaces +===================== +The address space qualifier may be used to specify the region of memory that is +used to allocate the object. OpenCL supports the following address spaces: +__generic(generic), __global(global), __local(local), __private(private), +__constant(constant). + + .. code-block:: c + + __constant int c = ...; + + __generic int* foo(global int* g) { + __local int* l; + private int p; + ... + return l; + } + +More details can be found in the OpenCL C language Spec v2.0, Section 6.5. + +constant +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","","``__constant`` |br| ``constant``","","" + +The constant address space attribute signals that an object is located in +a constant (non-modifiable) memory region. It is available to all work items. +Any type can be annotated with the constant address space attribute. Objects +with the constant address space qualifier can be declared in any scope and must +have an initializer. + + +generic +------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","","``__generic`` |br| ``generic``","","" + +The generic address space attribute is only available with OpenCL v2.0 and later. +It can be used with pointer types. Variables in global and local scope and +function parameters in non-kernel functions can have the generic address space +type attribute. It is intended to be a placeholder for any other address space +except for '__constant' in OpenCL code which can be used with multiple address +spaces. + + +global +------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","","``__global`` |br| ``global``","","" + +The global address space attribute specifies that an object is allocated in +global memory, which is accessible by all work items. The content stored in this +memory area persists between kernel executions. Pointer types to the global +address space are allowed as function parameters or local variables. Starting +with OpenCL v2.0, the global address space can be used with global (program +scope) variables and static local variable as well. + + +local +----- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","","``__local`` |br| ``local``","","" + +The local address space specifies that an object is allocated in the local (work +group) memory area, which is accessible to all work items in the same work +group. The content stored in this memory region is not accessible after +the kernel execution ends. In a kernel function scope, any variable can be in +the local address space. In other scopes, only pointer types to the local address +space are allowed. Local address space variables cannot have an initializer. + + +private +------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","","``__private`` |br| ``private``","","" + +The private address space specifies that an object is allocated in the private +(work item) memory. Other work items cannot access the same memory area and its +content is destroyed after work item execution ends. Local variables can be +declared in the private address space. Function arguments are always in the +private address space. Kernel function arguments of a pointer or an array type +cannot point to the private address space. + + +Calling Conventions +=================== +Clang supports several different calling conventions, depending on the target +platform and architecture. The calling convention used for a function determines +how parameters are passed, how results are returned to the caller, and other +low-level details of calling a function. + +aarch64_vector_pcs +------------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``aarch64_vector_pcs``","``clang::aarch64_vector_pcs``","``clang::aarch64_vector_pcs``","","","","" + +On AArch64 targets, this attribute changes the calling convention of a +function to preserve additional floating-point and Advanced SIMD registers +relative to the default calling convention used for AArch64. + +This means it is more efficient to call such functions from code that performs +extensive floating-point and vector calculations, because fewer live SIMD and FP +registers need to be saved. This property makes it well-suited for e.g. +floating-point or vector math library functions, which are typically leaf +functions that require a small number of registers. + +However, using this attribute also means that it is more expensive to call +a function that adheres to the default calling convention from within such +a function. Therefore, it is recommended that this attribute is only used +for leaf functions. + +For more information, see the documentation for `aarch64_vector_pcs`_ on +the Arm Developer website. + +.. _`aarch64_vector_pcs`: https://developer.arm.com/products/software-development-tools/hpc/arm-compiler-for-hpc/vector-function-abi + + +fastcall +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``fastcall``","``gnu::fastcall``","","","``__fastcall`` |br| ``_fastcall``","","" + +On 32-bit x86 targets, this attribute changes the calling convention of a +function to use ECX and EDX as register parameters and clear parameters off of +the stack on return. This convention does not support variadic calls or +unprototyped functions in C, and has no effect on x86_64 targets. This calling +convention is supported primarily for compatibility with existing code. Users +seeking register parameters should use the ``regparm`` attribute, which does +not require callee-cleanup. See the documentation for `__fastcall`_ on MSDN. + +.. _`__fastcall`: http://msdn.microsoft.com/en-us/library/6xa169sk.aspx + + +ms_abi +------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``ms_abi``","``gnu::ms_abi``","","","","","" + +On non-Windows x86_64 targets, this attribute changes the calling convention of +a function to match the default convention used on Windows x86_64. This +attribute has no effect on Windows targets or non-x86_64 targets. + + +pcs +--- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``pcs``","``gnu::pcs``","","","","","" + +On ARM targets, this attribute can be used to select calling conventions +similar to ``stdcall`` on x86. Valid parameter values are "aapcs" and +"aapcs-vfp". + + +preserve_all +------------ +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``preserve_all``","``clang::preserve_all``","``clang::preserve_all``","","","","" + +On X86-64 and AArch64 targets, this attribute changes the calling convention of +a function. The ``preserve_all`` calling convention attempts to make the code +in the caller even less intrusive than the ``preserve_most`` calling convention. +This calling convention also behaves identical to the ``C`` calling convention +on how arguments and return values are passed, but it uses a different set of +caller/callee-saved registers. This removes the burden of saving and +recovering a large register set before and after the call in the caller. If +the arguments are passed in callee-saved registers, then they will be +preserved by the callee across the call. This doesn't apply for values +returned in callee-saved registers. + +- On X86-64 the callee preserves all general purpose registers, except for + R11. R11 can be used as a scratch register. Furthermore it also preserves + all floating-point registers (XMMs/YMMs). + +The idea behind this convention is to support calls to runtime functions +that don't need to call out to any other functions. + +This calling convention, like the ``preserve_most`` calling convention, will be +used by a future version of the Objective-C runtime and should be considered +experimental at this time. + + +preserve_most +------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``preserve_most``","``clang::preserve_most``","``clang::preserve_most``","","","","" + +On X86-64 and AArch64 targets, this attribute changes the calling convention of +a function. The ``preserve_most`` calling convention attempts to make the code +in the caller as unintrusive as possible. This convention behaves identically +to the ``C`` calling convention on how arguments and return values are passed, +but it uses a different set of caller/callee-saved registers. This alleviates +the burden of saving and recovering a large register set before and after the +call in the caller. If the arguments are passed in callee-saved registers, +then they will be preserved by the callee across the call. This doesn't +apply for values returned in callee-saved registers. + +- On X86-64 the callee preserves all general purpose registers, except for + R11. R11 can be used as a scratch register. Floating-point registers + (XMMs/YMMs) are not preserved and need to be saved by the caller. + +The idea behind this convention is to support calls to runtime functions +that have a hot path and a cold path. The hot path is usually a small piece +of code that doesn't use many registers. The cold path might need to call out to +another function and therefore only needs to preserve the caller-saved +registers, which haven't already been saved by the caller. The +`preserve_most` calling convention is very similar to the ``cold`` calling +convention in terms of caller/callee-saved registers, but they are used for +different types of function calls. ``coldcc`` is for function calls that are +rarely executed, whereas `preserve_most` function calls are intended to be +on the hot path and definitely executed a lot. Furthermore ``preserve_most`` +doesn't prevent the inliner from inlining the function call. + +This calling convention will be used by a future version of the Objective-C +runtime and should therefore still be considered experimental at this time. +Although this convention was created to optimize certain runtime calls to +the Objective-C runtime, it is not limited to this runtime and might be used +by other runtimes in the future too. The current implementation only +supports X86-64 and AArch64, but the intention is to support more architectures +in the future. + + +regcall +------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``regcall``","``gnu::regcall``","","","``__regcall``","","" + +On x86 targets, this attribute changes the calling convention to +`__regcall`_ convention. This convention aims to pass as many arguments +as possible in registers. It also tries to utilize registers for the +return value whenever it is possible. + +.. _`__regcall`: https://software.intel.com/en-us/node/693069 + + +regparm +------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``regparm``","``gnu::regparm``","","","","","" + +On 32-bit x86 targets, the regparm attribute causes the compiler to pass +the first three integer parameters in EAX, EDX, and ECX instead of on the +stack. This attribute has no effect on variadic functions, and all parameters +are passed via the stack as normal. + + +stdcall +------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``stdcall``","``gnu::stdcall``","","","``__stdcall`` |br| ``_stdcall``","","" + +On 32-bit x86 targets, this attribute changes the calling convention of a +function to clear parameters off of the stack on return. This convention does +not support variadic calls or unprototyped functions in C, and has no effect on +x86_64 targets. This calling convention is used widely by the Windows API and +COM applications. See the documentation for `__stdcall`_ on MSDN. + +.. _`__stdcall`: http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx + + +thiscall +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``thiscall``","``gnu::thiscall``","","","``__thiscall`` |br| ``_thiscall``","","" + +On 32-bit x86 targets, this attribute changes the calling convention of a +function to use ECX for the first parameter (typically the implicit ``this`` +parameter of C++ methods) and clear parameters off of the stack on return. This +convention does not support variadic calls or unprototyped functions in C, and +has no effect on x86_64 targets. See the documentation for `__thiscall`_ on +MSDN. + +.. _`__thiscall`: http://msdn.microsoft.com/en-us/library/ek8tkfbw.aspx + + +vectorcall +---------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``vectorcall``","``clang::vectorcall``","``clang::vectorcall``","","``__vectorcall`` |br| ``_vectorcall``","","" + +On 32-bit x86 *and* x86_64 targets, this attribute changes the calling +convention of a function to pass vector parameters in SSE registers. + +On 32-bit x86 targets, this calling convention is similar to ``__fastcall``. +The first two integer parameters are passed in ECX and EDX. Subsequent integer +parameters are passed in memory, and callee clears the stack. On x86_64 +targets, the callee does *not* clear the stack, and integer parameters are +passed in RCX, RDX, R8, and R9 as is done for the default Windows x64 calling +convention. + +On both 32-bit x86 and x86_64 targets, vector and floating point arguments are +passed in XMM0-XMM5. Homogeneous vector aggregates of up to four elements are +passed in sequential SSE registers if enough are available. If AVX is enabled, +256 bit vectors are passed in YMM0-YMM5. Any vector or aggregate type that +cannot be passed in registers for any reason is passed by reference, which +allows the caller to align the parameter memory. + +See the documentation for `__vectorcall`_ on MSDN for more details. + +.. _`__vectorcall`: http://msdn.microsoft.com/en-us/library/dn375768.aspx + + +Consumed Annotation Checking +============================ +Clang supports additional attributes for checking basic resource management +properties, specifically for unique objects that have a single owning reference. +The following attributes are currently supported, although **the implementation +for these annotations is currently in development and are subject to change.** + +callable_when +------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``callable_when``","``clang::callable_when``","","","","","Yes" + +Use ``__attribute__((callable_when(...)))`` to indicate what states a method +may be called in. Valid states are unconsumed, consumed, or unknown. Each +argument to this attribute must be a quoted string. E.g.: + +``__attribute__((callable_when("unconsumed", "unknown")))`` + + +consumable +---------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``consumable``","``clang::consumable``","","","","","Yes" + +Each ``class`` that uses any of the typestate annotations must first be marked +using the ``consumable`` attribute. Failure to do so will result in a warning. + +This attribute accepts a single parameter that must be one of the following: +``unknown``, ``consumed``, or ``unconsumed``. + + +param_typestate +--------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``param_typestate``","``clang::param_typestate``","","","","","Yes" + +This attribute specifies expectations about function parameters. Calls to an +function with annotated parameters will issue a warning if the corresponding +argument isn't in the expected state. The attribute is also used to set the +initial state of the parameter when analyzing the function's body. + + +return_typestate +---------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``return_typestate``","``clang::return_typestate``","","","","","Yes" + +The ``return_typestate`` attribute can be applied to functions or parameters. +When applied to a function the attribute specifies the state of the returned +value. The function's body is checked to ensure that it always returns a value +in the specified state. On the caller side, values returned by the annotated +function are initialized to the given state. + +When applied to a function parameter it modifies the state of an argument after +a call to the function returns. The function's body is checked to ensure that +the parameter is in the expected state before returning. + + +set_typestate +------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``set_typestate``","``clang::set_typestate``","","","","","Yes" + +Annotate methods that transition an object into a new state with +``__attribute__((set_typestate(new_state)))``. The new state must be +unconsumed, consumed, or unknown. + + +test_typestate +-------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``test_typestate``","``clang::test_typestate``","","","","","Yes" + +Use ``__attribute__((test_typestate(tested_state)))`` to indicate that a method +returns true if the object is in the specified state.. + + +Type Safety Checking +==================== +Clang supports additional attributes to enable checking type safety properties +that can't be enforced by the C type system. To see warnings produced by these +checks, ensure that -Wtype-safety is enabled. Use cases include: + +* MPI library implementations, where these attributes enable checking that + the buffer type matches the passed ``MPI_Datatype``; +* for HDF5 library there is a similar use case to MPI; +* checking types of variadic functions' arguments for functions like + ``fcntl()`` and ``ioctl()``. + +You can detect support for these attributes with ``__has_attribute()``. For +example: + +.. code-block:: c++ + + #if defined(__has_attribute) + # if __has_attribute(argument_with_type_tag) && \ + __has_attribute(pointer_with_type_tag) && \ + __has_attribute(type_tag_for_datatype) + # define ATTR_MPI_PWT(buffer_idx, type_idx) __attribute__((pointer_with_type_tag(mpi,buffer_idx,type_idx))) + /* ... other macros ... */ + # endif + #endif + + #if !defined(ATTR_MPI_PWT) + # define ATTR_MPI_PWT(buffer_idx, type_idx) + #endif + + int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */) + ATTR_MPI_PWT(1,3); + +argument_with_type_tag +---------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``argument_with_type_tag`` |br| ``pointer_with_type_tag``","``clang::argument_with_type_tag`` |br| ``clang::pointer_with_type_tag``","``clang::argument_with_type_tag`` |br| ``clang::pointer_with_type_tag``","","","","" + +Use ``__attribute__((argument_with_type_tag(arg_kind, arg_idx, +type_tag_idx)))`` on a function declaration to specify that the function +accepts a type tag that determines the type of some other argument. + +This attribute is primarily useful for checking arguments of variadic functions +(``pointer_with_type_tag`` can be used in most non-variadic cases). + +In the attribute prototype above: + * ``arg_kind`` is an identifier that should be used when annotating all + applicable type tags. + * ``arg_idx`` provides the position of a function argument. The expected type of + this function argument will be determined by the function argument specified + by ``type_tag_idx``. In the code example below, "3" means that the type of the + function's third argument will be determined by ``type_tag_idx``. + * ``type_tag_idx`` provides the position of a function argument. This function + argument will be a type tag. The type tag will determine the expected type of + the argument specified by ``arg_idx``. In the code example below, "2" means + that the type tag associated with the function's second argument should agree + with the type of the argument specified by ``arg_idx``. + +For example: + +.. code-block:: c++ + + int fcntl(int fd, int cmd, ...) + __attribute__(( argument_with_type_tag(fcntl,3,2) )); + // The function's second argument will be a type tag; this type tag will + // determine the expected type of the function's third argument. + + +pointer_with_type_tag +--------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``argument_with_type_tag`` |br| ``pointer_with_type_tag``","``clang::argument_with_type_tag`` |br| ``clang::pointer_with_type_tag``","``clang::argument_with_type_tag`` |br| ``clang::pointer_with_type_tag``","","","","" + +Use ``__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx, type_tag_idx)))`` +on a function declaration to specify that the function accepts a type tag that +determines the pointee type of some other pointer argument. + +In the attribute prototype above: + * ``ptr_kind`` is an identifier that should be used when annotating all + applicable type tags. + * ``ptr_idx`` provides the position of a function argument; this function + argument will have a pointer type. The expected pointee type of this pointer + type will be determined by the function argument specified by + ``type_tag_idx``. In the code example below, "1" means that the pointee type + of the function's first argument will be determined by ``type_tag_idx``. + * ``type_tag_idx`` provides the position of a function argument; this function + argument will be a type tag. The type tag will determine the expected pointee + type of the pointer argument specified by ``ptr_idx``. In the code example + below, "3" means that the type tag associated with the function's third + argument should agree with the pointee type of the pointer argument specified + by ``ptr_idx``. + +For example: + +.. code-block:: c++ + + typedef int MPI_Datatype; + int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */) + __attribute__(( pointer_with_type_tag(mpi,1,3) )); + // The function's 3rd argument will be a type tag; this type tag will + // determine the expected pointee type of the function's 1st argument. + + +type_tag_for_datatype +--------------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``type_tag_for_datatype``","``clang::type_tag_for_datatype``","``clang::type_tag_for_datatype``","","","","" + +When declaring a variable, use +``__attribute__((type_tag_for_datatype(kind, type)))`` to create a type tag that +is tied to the ``type`` argument given to the attribute. + +In the attribute prototype above: + * ``kind`` is an identifier that should be used when annotating all applicable + type tags. + * ``type`` indicates the name of the type. + +Clang supports annotating type tags of two forms. + + * **Type tag that is a reference to a declared identifier.** + Use ``__attribute__((type_tag_for_datatype(kind, type)))`` when declaring that + identifier: + + .. code-block:: c++ + + typedef int MPI_Datatype; + extern struct mpi_datatype mpi_datatype_int + __attribute__(( type_tag_for_datatype(mpi,int) )); + #define MPI_INT ((MPI_Datatype) &mpi_datatype_int) + // &mpi_datatype_int is a type tag. It is tied to type "int". + + * **Type tag that is an integral literal.** + Declare a ``static const`` variable with an initializer value and attach + ``__attribute__((type_tag_for_datatype(kind, type)))`` on that declaration: + + .. code-block:: c++ + + typedef int MPI_Datatype; + static const MPI_Datatype mpi_datatype_int + __attribute__(( type_tag_for_datatype(mpi,int) )) = 42; + #define MPI_INT ((MPI_Datatype) 42) + // The number 42 is a type tag. It is tied to type "int". + + +The ``type_tag_for_datatype`` attribute also accepts an optional third argument +that determines how the type of the function argument specified by either +``arg_idx`` or ``ptr_idx`` is compared against the type associated with the type +tag. (Recall that for the ``argument_with_type_tag`` attribute, the type of the +function argument specified by ``arg_idx`` is compared against the type +associated with the type tag. Also recall that for the ``pointer_with_type_tag`` +attribute, the pointee type of the function argument specified by ``ptr_idx`` is +compared against the type associated with the type tag.) There are two supported +values for this optional third argument: + + * ``layout_compatible`` will cause types to be compared according to + layout-compatibility rules (In C++11 [class.mem] p 17, 18, see the + layout-compatibility rules for two standard-layout struct types and for two + standard-layout union types). This is useful when creating a type tag + associated with a struct or union type. For example: + + .. code-block:: c++ + + /* In mpi.h */ + typedef int MPI_Datatype; + struct internal_mpi_double_int { double d; int i; }; + extern struct mpi_datatype mpi_datatype_double_int + __attribute__(( type_tag_for_datatype(mpi, + struct internal_mpi_double_int, layout_compatible) )); + + #define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int) + + int MPI_Send(void *buf, int count, MPI_Datatype datatype, ...) + __attribute__(( pointer_with_type_tag(mpi,1,3) )); + + /* In user code */ + struct my_pair { double a; int b; }; + struct my_pair *buffer; + MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ... */); // no warning because the + // layout of my_pair is + // compatible with that of + // internal_mpi_double_int + + struct my_int_pair { int a; int b; } + struct my_int_pair *buffer2; + MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ... */); // warning because the + // layout of my_int_pair + // does not match that of + // internal_mpi_double_int + + * ``must_be_null`` specifies that the function argument specified by either + ``arg_idx`` (for the ``argument_with_type_tag`` attribute) or ``ptr_idx`` (for + the ``pointer_with_type_tag`` attribute) should be a null pointer constant. + The second argument to the ``type_tag_for_datatype`` attribute is ignored. For + example: + + .. code-block:: c++ + + /* In mpi.h */ + typedef int MPI_Datatype; + extern struct mpi_datatype mpi_datatype_null + __attribute__(( type_tag_for_datatype(mpi, void, must_be_null) )); + + #define MPI_DATATYPE_NULL ((MPI_Datatype) &mpi_datatype_null) + int MPI_Send(void *buf, int count, MPI_Datatype datatype, ...) + __attribute__(( pointer_with_type_tag(mpi,1,3) )); + + /* In user code */ + struct my_pair { double a; int b; }; + struct my_pair *buffer; + MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ... */); // warning: MPI_DATATYPE_NULL + // was specified but buffer + // is not a null pointer + + +Nullability Attributes +====================== +Whether a particular pointer may be "null" is an important concern when working with pointers in the C family of languages. The various nullability attributes indicate whether a particular pointer can be null or not, which makes APIs more expressive and can help static analysis tools identify bugs involving null pointers. Clang supports several kinds of nullability attributes: the ``nonnull`` and ``returns_nonnull`` attributes indicate which function or method parameters and result types can never be null, while nullability type qualifiers indicate which pointer types can be null (``_Nullable``) or cannot be null (``_Nonnull``). + +The nullability (type) qualifiers express whether a value of a given pointer type can be null (the ``_Nullable`` qualifier), doesn't have a defined meaning for null (the ``_Nonnull`` qualifier), or for which the purpose of null is unclear (the ``_Null_unspecified`` qualifier). Because nullability qualifiers are expressed within the type system, they are more general than the ``nonnull`` and ``returns_nonnull`` attributes, allowing one to express (for example) a nullable pointer to an array of nonnull pointers. Nullability qualifiers are written to the right of the pointer to which they apply. For example: + + .. code-block:: c + + // No meaningful result when 'ptr' is null (here, it happens to be undefined behavior). + int fetch(int * _Nonnull ptr) { return *ptr; } + + // 'ptr' may be null. + int fetch_or_zero(int * _Nullable ptr) { + return ptr ? *ptr : 0; + } + + // A nullable pointer to non-null pointers to const characters. + const char *join_strings(const char * _Nonnull * _Nullable strings, unsigned n); + +In Objective-C, there is an alternate spelling for the nullability qualifiers that can be used in Objective-C methods and properties using context-sensitive, non-underscored keywords. For example: + + .. code-block:: objective-c + + @interface NSView : NSResponder + - (nullable NSView *)ancestorSharedWithView:(nonnull NSView *)aView; + @property (assign, nullable) NSView *superview; + @property (readonly, nonnull) NSArray *subviews; + @end + +_Nonnull +-------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","","``_Nonnull``","","" + +The ``_Nonnull`` nullability qualifier indicates that null is not a meaningful value for a value of the ``_Nonnull`` pointer type. For example, given a declaration such as: + + .. code-block:: c + + int fetch(int * _Nonnull ptr); + +a caller of ``fetch`` should not provide a null value, and the compiler will produce a warning if it sees a literal null value passed to ``fetch``. Note that, unlike the declaration attribute ``nonnull``, the presence of ``_Nonnull`` does not imply that passing null is undefined behavior: ``fetch`` is free to consider null undefined behavior or (perhaps for backward-compatibility reasons) defensively handle null. + + +_Null_unspecified +----------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","","``_Null_unspecified``","","" + +The ``_Null_unspecified`` nullability qualifier indicates that neither the ``_Nonnull`` nor ``_Nullable`` qualifiers make sense for a particular pointer type. It is used primarily to indicate that the role of null with specific pointers in a nullability-annotated header is unclear, e.g., due to overly-complex implementations or historical factors with a long-lived API. + + +_Nullable +--------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "","","","","``_Nullable``","","" + +The ``_Nullable`` nullability qualifier indicates that a value of the ``_Nullable`` pointer type can be null. For example, given: + + .. code-block:: c + + int fetch_or_zero(int * _Nullable ptr); + +a caller of ``fetch_or_zero`` can provide null. + + +nonnull +------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``nonnull``","``gnu::nonnull``","","","","","" + +The ``nonnull`` attribute indicates that some function parameters must not be null, and can be used in several different ways. It's original usage (`from GCC `_) is as a function (or Objective-C method) attribute that specifies which parameters of the function are nonnull in a comma-separated list. For example: + + .. code-block:: c + + extern void * my_memcpy (void *dest, const void *src, size_t len) + __attribute__((nonnull (1, 2))); + +Here, the ``nonnull`` attribute indicates that parameters 1 and 2 +cannot have a null value. Omitting the parenthesized list of parameter indices means that all parameters of pointer type cannot be null: + + .. code-block:: c + + extern void * my_memcpy (void *dest, const void *src, size_t len) + __attribute__((nonnull)); + +Clang also allows the ``nonnull`` attribute to be placed directly on a function (or Objective-C method) parameter, eliminating the need to specify the parameter index ahead of type. For example: + + .. code-block:: c + + extern void * my_memcpy (void *dest __attribute__((nonnull)), + const void *src __attribute__((nonnull)), size_t len); + +Note that the ``nonnull`` attribute indicates that passing null to a non-null parameter is undefined behavior, which the optimizer may take advantage of to, e.g., remove null checks. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable. + + +returns_nonnull +--------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``returns_nonnull``","``gnu::returns_nonnull``","","","","","Yes" + +The ``returns_nonnull`` attribute indicates that a particular function (or Objective-C method) always returns a non-null pointer. For example, a particular system ``malloc`` might be defined to terminate a process when memory is not available rather than returning a null pointer: + + .. code-block:: c + + extern void * malloc (size_t size) __attribute__((returns_nonnull)); + +The ``returns_nonnull`` attribute implies that returning a null pointer is undefined behavior, which the optimizer may take advantage of. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable + + From 829bb6fd5a8050acd9e35083f1ef2c0bcae97e04 Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Thu, 7 Feb 2019 11:29:02 +0000 Subject: [PATCH 109/274] [docs] Update the release notes for the backported feature with thunks for ARM64 llvm-svn: 353397 --- lld/docs/ReleaseNotes.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst index 77971b25ac483..9849111e0930b 100644 --- a/lld/docs/ReleaseNotes.rst +++ b/lld/docs/ReleaseNotes.rst @@ -61,7 +61,8 @@ COFF Improvements * lld now can link against import libraries produced by GNU tools. -* lld can create thunks for ARM, to allow linking images over 16 MB. +* lld can create thunks for ARM and ARM64, to allow linking larger images + (over 16 MB for ARM and over 128 MB for ARM64) * Several speed and memory usage improvements. From ac29b659cda7f36265d31a5c3a549efa8feaaa5f Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 7 Feb 2019 12:32:55 +0000 Subject: [PATCH 110/274] Fix sphinx warning llvm-svn: 353398 --- llvm/docs/ReleaseNotes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 2bd435ca9d296..c0a8ea6f9e321 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -82,7 +82,7 @@ Changes to the ARM Backend Changes to the Hexagon Target --------------------------- +----------------------------- * Added support for Hexagon/HVX V66 ISA. From 98ebe7460199b9cd79eb562b5e8705ad28f5513f Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 7 Feb 2019 12:40:33 +0000 Subject: [PATCH 111/274] Merging r353399: ------------------------------------------------------------------------ r353399 | hans | 2019-02-07 13:39:35 +0100 (Thu, 07 Feb 2019) | 1 line docs: add missingkeyfunction to doctree, fix title ------------------------------------------------------------------------ llvm-svn: 353400 --- lld/docs/index.rst | 1 + lld/docs/missingkeyfunction.rst | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lld/docs/index.rst b/lld/docs/index.rst index da1c894f3d833..2564e9b6310fd 100644 --- a/lld/docs/index.rst +++ b/lld/docs/index.rst @@ -173,4 +173,5 @@ document soon. AtomLLD WebAssembly windows_support + missingkeyfunction ReleaseNotes diff --git a/lld/docs/missingkeyfunction.rst b/lld/docs/missingkeyfunction.rst index 410c749c3b036..54ad3251f794e 100644 --- a/lld/docs/missingkeyfunction.rst +++ b/lld/docs/missingkeyfunction.rst @@ -1,5 +1,5 @@ -Missing Key Method -================== +Missing Key Function +==================== If your build failed with a linker error something like this:: From 2699311ea8e3da5f0df7925c6438375c2161ede5 Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Thu, 7 Feb 2019 21:09:53 +0000 Subject: [PATCH 112/274] Add external project LDC to release notes. LDC, the LLVM-based D compiler, is already ready for LLVM 8.0.0. llvm-svn: 353466 --- llvm/docs/ReleaseNotes.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index c0a8ea6f9e321..561faa71fd5db 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -156,6 +156,21 @@ Changes to the DAG infrastructure External Open Source Projects Using LLVM 8 ========================================== +LDC - the LLVM-based D compiler +------------------------------- + +`D `_ is a language with C-like syntax and static typing. It +pragmatically combines efficiency, control, and modeling power, with safety and +programmer productivity. D supports powerful concepts like Compile-Time Function +Execution (CTFE) and Template Meta-Programming, provides an innovative approach +to concurrency and offers many classical paradigms. + +`LDC `_ uses the frontend from the reference compiler +combined with LLVM as backend to produce efficient native code. LDC targets +x86/x86_64 systems like Linux, OS X, FreeBSD and Windows and also Linux on ARM +and PowerPC (32/64 bit). Ports to other architectures like AArch64 and MIPS64 +are underway. + Zig Programming Language ------------------------ From ce52769ae20b269ad4cedae12bc7ceb4e6732506 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 8 Feb 2019 11:06:27 +0000 Subject: [PATCH 113/274] Merging r351387, r351765, and r353374: ------------------------------------------------------------------------ r351387 | jfb | 2019-01-16 23:22:38 +0100 (Wed, 16 Jan 2019) | 7 lines [NFC] Factor out + document build requirements Summary: This change factors out compiler checking / warning, and documents LLVM_FORCE_USE_OLD_TOOLCHAIN. It doesn't introduce any functional changes nor policy changes, these will come late. Subscribers: mgorny, jkorous, dexonsmith, llvm-commits Differential Revision: https://reviews.llvm.org/D56799 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r351765 | jfb | 2019-01-22 00:53:52 +0100 (Tue, 22 Jan 2019) | 24 lines Document toolchain update policy Summary: Capture the current agreed-upon toolchain update policy based on the following discussions: - LLVM dev meeting 2018 BoF "Migrating to C++14, and beyond!" llvm.org/devmtg/2018-10/talk-abstracts.html#bof3 - A Short Policy Proposal Regarding Host Compilers lists.llvm.org/pipermail/llvm-dev/2018-May/123238.html - Using C++14 code in LLVM (2018) lists.llvm.org/pipermail/llvm-dev/2018-May/123182.html - Using C++14 code in LLVM (2017) lists.llvm.org/pipermail/llvm-dev/2017-October/118673.html - Using C++14 code in LLVM (2016) lists.llvm.org/pipermail/llvm-dev/2016-October/105483.html - Document and Enforce new Host Compiler Policy llvm.org/D47073 - Require GCC 5.1 and LLVM 3.5 at a minimum llvm.org/D46723 Subscribers: jkorous, dexonsmith, llvm-commits Differential Revision: https://reviews.llvm.org/D56819 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r353374 | jfb | 2019-02-07 06:20:00 +0100 (Thu, 07 Feb 2019) | 12 lines Bump minimum toolchain version Summary: The RFC on moving past C++11 got good traction: http://lists.llvm.org/pipermail/llvm-dev/2019-January/129452.html This patch therefore bumps the toolchain versions according to our policy: llvm.org/docs/DeveloperPolicy.html#toolchain Subscribers: mgorny, jkorous, dexonsmith, llvm-commits, mehdi_amini, jyknight, rsmith, chandlerc, smeenai, hans, reames, lattner, lhames, erichkeane Differential Revision: https://reviews.llvm.org/D57264 ------------------------------------------------------------------------ llvm-svn: 353512 --- llvm/CMakeLists.txt | 5 +- llvm/cmake/modules/CheckCompilerVersion.cmake | 128 ++++++++++++------ llvm/docs/CMake.rst | 9 ++ llvm/docs/DeveloperPolicy.rst | 43 +++++- llvm/docs/GettingStarted.rst | 61 +++++---- 5 files changed, 177 insertions(+), 69 deletions(-) diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index 6e5221ebfd339..27754f339493b 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -383,9 +383,12 @@ option(LLVM_ENABLE_EXPENSIVE_CHECKS "Enable expensive checks" OFF) set(LLVM_ABI_BREAKING_CHECKS "WITH_ASSERTS" CACHE STRING "Enable abi-breaking checks. Can be WITH_ASSERTS, FORCE_ON or FORCE_OFF.") -option(LLVM_FORCE_USE_OLD_HOST_TOOLCHAIN +option(LLVM_FORCE_USE_OLD_TOOLCHAIN "Set to ON to force using an old, unsupported host toolchain." OFF) +option(LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN + "Set to ON to only warn when using a toolchain which is about to be deprecated, instead of emitting an error." OFF) + option(LLVM_USE_INTEL_JITEVENTS "Use Intel JIT API to inform Intel(R) VTune(TM) Amplifier XE 2011 about JIT code" OFF) diff --git a/llvm/cmake/modules/CheckCompilerVersion.cmake b/llvm/cmake/modules/CheckCompilerVersion.cmake index adf500ad53a72..b1cb552742289 100644 --- a/llvm/cmake/modules/CheckCompilerVersion.cmake +++ b/llvm/cmake/modules/CheckCompilerVersion.cmake @@ -1,52 +1,94 @@ -# Check if the host compiler is new enough. LLVM requires at least GCC 4.8, -# MSVC 2015 (Update 3), or Clang 3.1. +# Check if the host compiler is new enough. +# These versions are updated based on the following policy: +# llvm.org/docs/DeveloperPolicy.html#toolchain include(CheckCXXSourceCompiles) -if(NOT DEFINED LLVM_COMPILER_CHECKED) - set(LLVM_COMPILER_CHECKED ON) +set(GCC_MIN 4.8) +set(GCC_SOFT_ERROR 5.1) +set(CLANG_MIN 3.1) +set(CLANG_SOFT_ERROR 3.5) +set(APPLECLANG_MIN 3.1) +set(APPLECLANG_SOFT_ERROR 6.0) +set(MSVC_MIN 19.00.24213.1) +set(MSVC_SOFT_ERROR 19.1) - if(NOT LLVM_FORCE_USE_OLD_TOOLCHAIN) - if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) - message(FATAL_ERROR "Host GCC version must be at least 4.8!") - endif() - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.1) - message(FATAL_ERROR "Host Clang version must be at least 3.1!") - endif() +# Map the above GCC versions to dates: https://gcc.gnu.org/develop.html#timeline +set(GCC_MIN_DATE 20130322) +set(GCC_SOFT_ERROR_DATE 20150422) - if (CMAKE_CXX_SIMULATE_ID MATCHES "MSVC") - if (CMAKE_CXX_SIMULATE_VERSION VERSION_LESS 19.0) - message(FATAL_ERROR "Host Clang must have at least -fms-compatibility-version=19.0") - endif() - set(CLANG_CL 1) - elseif(NOT LLVM_ENABLE_LIBCXX) - # Otherwise, test that we aren't using too old of a version of libstdc++ - # with the Clang compiler. This is tricky as there is no real way to - # check the version of libstdc++ directly. Instead we test for a known - # bug in libstdc++4.6 that is fixed in libstdc++4.7. - set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) - set(OLD_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++0x") - check_cxx_source_compiles(" -#include -std::atomic x(0.0f); -int main() { return (float)x; }" - LLVM_NO_OLD_LIBSTDCXX) - if(NOT LLVM_NO_OLD_LIBSTDCXX) - message(FATAL_ERROR "Host Clang must be able to find libstdc++4.8 or newer!") - endif() - set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) - set(CMAKE_REQUIRED_LIBRARIES ${OLD_CMAKE_REQUIRED_LIBRARIES}) - endif() - elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0) - message(FATAL_ERROR "Host Visual Studio must be at least 2015") - elseif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.00.24213.1) - message(WARNING "Host Visual Studio should at least be 2015 Update 3 (MSVC 19.00.24213.1)" - " due to miscompiles from earlier versions") + +if(DEFINED LLVM_COMPILER_CHECKED) + return() +endif() +set(LLVM_COMPILER_CHECKED ON) + +if(LLVM_FORCE_USE_OLD_TOOLCHAIN) + return() +endif() + +function(check_compiler_version NAME NICE_NAME MINIMUM_VERSION SOFT_ERROR_VERSION) + if(NOT CMAKE_CXX_COMPILER_ID STREQUAL NAME) + return() + endif() + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS MINIMUM_VERSION) + message(FATAL_ERROR "Host ${NICE_NAME} version must be at least ${MINIMUM_VERSION}, your version is ${CMAKE_CXX_COMPILER_VERSION}.") + elseif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS SOFT_ERROR_VERSION) + if(LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN) + message(WARNING "Host ${NICE_NAME} version should be at least ${SOFT_ERROR_VERSION} because LLVM will soon use new C++ features which your toolchain version doesn't support. Your version is ${CMAKE_CXX_COMPILER_VERSION}. Ignoring because you've set LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN, but very soon your toolchain won't be supported.") + else() + message(FATAL_ERROR "Host ${NICE_NAME} version should be at least ${SOFT_ERROR_VERSION} because LLVM will soon use new C++ features which your toolchain version doesn't support. Your version is ${CMAKE_CXX_COMPILER_VERSION}. You can temporarily opt out using LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN, but very soon your toolchain won't be supported.") + endif() + endif() +endfunction(check_compiler_version) + +check_compiler_version("GNU" "GCC" ${GCC_MIN} ${GCC_SOFT_ERROR}) +check_compiler_version("Clang" "Clang" ${CLANG_MIN} ${CLANG_SOFT_ERROR}) +check_compiler_version("AppleClang" "Apple Clang" ${APPLECLANG_MIN} ${APPLECLANG_SOFT_ERROR}) +check_compiler_version("MSVC" "Visual Studio" ${MSVC_MIN} ${MSVC_SOFT_ERROR}) + +if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if (CMAKE_CXX_SIMULATE_ID MATCHES "MSVC") + if (CMAKE_CXX_SIMULATE_VERSION VERSION_LESS MSVC_MIN) + message(FATAL_ERROR "Host Clang must have at least -fms-compatibility-version=${MSVC_MIN}, your version is ${CMAKE_CXX_COMPILER_VERSION}.") + endif() + set(CLANG_CL 1) + elseif(NOT LLVM_ENABLE_LIBCXX) + # Test that we aren't using too old of a version of libstdc++. + set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + set(OLD_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++0x") + check_cxx_source_compiles(" +#include +#if defined(__GLIBCXX__) +#if __GLIBCXX__ < ${GCC_MIN_DATE} +#error Unsupported libstdc++ version +#endif +#endif +int main() { return 0; } +" + LLVM_LIBSTDCXX_MIN) + if(NOT LLVM_LIBSTDCXX_MIN) + message(FATAL_ERROR "libstdc++ version must be at least ${GCC_MIN}.") + endif() + check_cxx_source_compiles(" +#include +#if defined(__GLIBCXX__) +#if __GLIBCXX__ < ${GCC_SOFT_ERROR_DATE} +#error Unsupported libstdc++ version +#endif +#endif +int main() { return 0; } +" + LLVM_LIBSTDCXX_SOFT_ERROR) + if(NOT LLVM_LIBSTDCXX_SOFT_ERROR) + if(LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN) + message(WARNING "libstdc++ version should be at least ${GCC_SOFT_ERROR} because LLVM will soon use new C++ features which your toolchain version doesn't support. Ignoring because you've set LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN, but very soon your toolchain won't be supported.") + else() + message(FATAL_ERROR "libstdc++ version should be at least ${GCC_SOFT_ERROR} because LLVM will soon use new C++ features which your toolchain version doesn't support. You can temporarily opt out using LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN, but very soon your toolchain won't be supported.") endif() endif() + set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) + set(CMAKE_REQUIRED_LIBRARIES ${OLD_CMAKE_REQUIRED_LIBRARIES}) endif() endif() diff --git a/llvm/docs/CMake.rst b/llvm/docs/CMake.rst index a5a574e570777..eb219c58560b6 100644 --- a/llvm/docs/CMake.rst +++ b/llvm/docs/CMake.rst @@ -573,6 +573,15 @@ LLVM-specific variables options, which are passed to the CCACHE_MAXSIZE and CCACHE_DIR environment variables, respectively. +**LLVM_FORCE_USE_OLD_TOOLCHAIN**:BOOL + If enabled, the compiler and standard library versions won't be checked. LLVM + may not compile at all, or might fail at runtime due to known bugs in these + toolchains. + +**LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN**:BOOL + If enabled, the compiler version check will only warn when using a toolchain + which is about to be deprecated, instead of emitting an error. + CMake Caches ============ diff --git a/llvm/docs/DeveloperPolicy.rst b/llvm/docs/DeveloperPolicy.rst index 09912940cde2d..4ed67cbf1ef1d 100644 --- a/llvm/docs/DeveloperPolicy.rst +++ b/llvm/docs/DeveloperPolicy.rst @@ -22,7 +22,7 @@ This policy is also designed to accomplish the following objectives: #. Make life as simple and easy for contributors as possible. -#. Keep the tip of tree as stable as possible. +#. Keep the top of tree as stable as possible. #. Establish awareness of the project's :ref:`copyright, license, and patent policies ` with contributors to the project. @@ -638,6 +638,47 @@ In essences, these rules are necessary for targets to gain and retain their status, but also markers to define bit-rot, and will be used to clean up the tree from unmaintained targets. +.. _toolchain: + +Updating Toolchain Requirements +------------------------------- + +We intend to require newer toolchains as time goes by. This means LLVM's +codebase can use newer versions of C++ as they get standardized. Requiring newer +toolchains to build LLVM can be painful for those building LLVM; therefore, it +will only be done through the following process: + + * Generally, try to support LLVM and GCC versions from the last 3 years at a + minimum. This time-based guideline is not strict: we may support much older + compilers, or decide to support fewer versions. + + * An RFC is sent to the `llvm-dev mailing list `_ + + - Detail upsides of the version increase (e.g. which newer C++ language or + library features LLVM should use; avoid miscompiles in particular compiler + versions, etc). + - Detail downsides on important platforms (e.g. Ubuntu LTS status). + + * Once the RFC reaches consensus, update the CMake toolchain version checks as + well as the :doc:`getting started` guide. We want to + soft-error when developers compile LLVM. We say "soft-error" because the + error can be turned into a warning using a CMake flag. This is an important + step: LLVM still doesn't have code which requires the new toolchains, but it + soon will. If you compile LLVM but don't read the mailing list, we should + tell you! + + * Ensure that at least one LLVM release has had this soft-error. Not all + developers compile LLVM top-of-tree. These release-bound developers should + also be told about upcoming changes. + + * Turn the soft-error into a hard-error after said LLVM release has branched. + + * Update the :doc:`coding standards` to allow the new + features we've explicitly approved in the RFC. + + * Start using the new features in LLVM's codebase. + + .. _copyright-license-patents: Copyright, License, and Patents diff --git a/llvm/docs/GettingStarted.rst b/llvm/docs/GettingStarted.rst index b714cc6601a04..c22e821e3b7a0 100644 --- a/llvm/docs/GettingStarted.rst +++ b/llvm/docs/GettingStarted.rst @@ -170,7 +170,7 @@ uses the package and provides other details. Package Version Notes =========================================================== ============ ========================================== `GNU Make `_ 3.79, 3.79.1 Makefile/build processor -`GCC `_ >=4.8.0 C/C++ compiler\ :sup:`1` +`GCC `_ >=5.1.0 C/C++ compiler\ :sup:`1` `python `_ >=2.7 Automated test suite\ :sup:`2` `zlib `_ >=1.2.3.4 Compression library\ :sup:`3` =========================================================== ============ ========================================== @@ -220,15 +220,25 @@ Host C++ Toolchain, both Compiler and Standard Library ------------------------------------------------------ LLVM is very demanding of the host C++ compiler, and as such tends to expose -bugs in the compiler. We are also planning to follow improvements and -developments in the C++ language and library reasonably closely. As such, we -require a modern host C++ toolchain, both compiler and standard library, in -order to build LLVM. +bugs in the compiler. We also attempt to follow improvements and developments in +the C++ language and library reasonably closely. As such, we require a modern +host C++ toolchain, both compiler and standard library, in order to build LLVM. -For the most popular host toolchains we check for specific minimum versions in -our build systems: +LLVM is written using the subset of C++ documented in :doc:`coding +standards`. To enforce this language version, we check the most +popular host toolchains for specific minimum versions in our build systems: + +* Clang 3.5 +* Apple Clang 6.0 +* GCC 5.1 +* Visual Studio 2017 + +The below versions currently soft-error as we transition to the new compiler +versions listed above. The LLVM codebase is currently known to compile correctly +with the following compilers, though this will change in the near future: * Clang 3.1 +* Apple Clang 3.1 * GCC 4.8 * Visual Studio 2015 (Update 3) @@ -282,33 +292,36 @@ The first step is to get a recent GCC toolchain installed. The most common distribution on which users have struggled with the version requirements is Ubuntu Precise, 12.04 LTS. For this distribution, one easy option is to install the `toolchain testing PPA`_ and use it to install a modern GCC. There is -a really nice discussions of this on the `ask ubuntu stack exchange`_. However, -not all users can use PPAs and there are many other distributions, so it may be -necessary (or just useful, if you're here you *are* doing compiler development -after all) to build and install GCC from source. It is also quite easy to do -these days. +a really nice discussions of this on the `ask ubuntu stack exchange`_ and a +`github gist`_ with updated commands. However, not all users can use PPAs and +there are many other distributions, so it may be necessary (or just useful, if +you're here you *are* doing compiler development after all) to build and install +GCC from source. It is also quite easy to do these days. .. _toolchain testing PPA: https://launchpad.net/~ubuntu-toolchain-r/+archive/test .. _ask ubuntu stack exchange: - http://askubuntu.com/questions/271388/how-to-install-gcc-4-8-in-ubuntu-12-04-from-the-terminal + https://askubuntu.com/questions/466651/how-do-i-use-the-latest-gcc-on-ubuntu/581497#58149 +.. _github gist: + https://gist.github.com/application2000/73fd6f4bf1be6600a2cf9f56315a2d91 -Easy steps for installing GCC 4.8.2: +Easy steps for installing GCC 5.1.0: .. code-block:: console - % wget https://ftp.gnu.org/gnu/gcc/gcc-4.8.2/gcc-4.8.2.tar.bz2 - % wget https://ftp.gnu.org/gnu/gcc/gcc-4.8.2/gcc-4.8.2.tar.bz2.sig + % gcc_version=5.1.0 + % wget https://ftp.gnu.org/gnu/gcc/gcc-${gcc_version}/gcc-${gcc_version}.tar.bz2 + % wget https://ftp.gnu.org/gnu/gcc/gcc-${gcc_version}/gcc-${gcc_version}.tar.bz2.sig % wget https://ftp.gnu.org/gnu/gnu-keyring.gpg - % signature_invalid=`gpg --verify --no-default-keyring --keyring ./gnu-keyring.gpg gcc-4.8.2.tar.bz2.sig` + % signature_invalid=`gpg --verify --no-default-keyring --keyring ./gnu-keyring.gpg gcc-${gcc_version}.tar.bz2.sig` % if [ $signature_invalid ]; then echo "Invalid signature" ; exit 1 ; fi - % tar -xvjf gcc-4.8.2.tar.bz2 - % cd gcc-4.8.2 + % tar -xvjf gcc-${gcc_version}.tar.bz2 + % cd gcc-${gcc_version} % ./contrib/download_prerequisites % cd .. - % mkdir gcc-4.8.2-build - % cd gcc-4.8.2-build - % $PWD/../gcc-4.8.2/configure --prefix=$HOME/toolchains --enable-languages=c,c++ + % mkdir gcc-${gcc_version}-build + % cd gcc-${gcc_version}-build + % $PWD/../gcc-${gcc_version}/configure --prefix=$HOME/toolchains --enable-languages=c,c++ % make -j$(nproc) % make install @@ -316,7 +329,7 @@ For more details, check out the excellent `GCC wiki entry`_, where I got most of this information from. .. _GCC wiki entry: - http://gcc.gnu.org/wiki/InstallingGCC + https://gcc.gnu.org/wiki/InstallingGCC Once you have a GCC toolchain, configure your build of LLVM to use the new toolchain for your host compiler and C++ standard library. Because the new @@ -336,7 +349,7 @@ If you fail to set rpath, most LLVM binaries will fail on startup with a message from the loader similar to ``libstdc++.so.6: version `GLIBCXX_3.4.20' not found``. This means you need to tweak the -rpath linker flag. -When you build Clang, you will need to give *it* access to modern C++11 +When you build Clang, you will need to give *it* access to modern C++ standard library in order to use it as your new host in part of a bootstrap. There are two easy ways to do this, either build (and install) libc++ along with Clang and then use it with the ``-stdlib=libc++`` compile and link flag, From 22558d3318659d5f7f33b1397abb8f238573c387 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 8 Feb 2019 14:17:53 +0000 Subject: [PATCH 114/274] Merging r353463: ------------------------------------------------------------------------ r353463 | smeenai | 2019-02-07 21:58:04 +0100 (Thu, 07 Feb 2019) | 4 lines [cmake] Pass LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN to NATIVE configure We should propagate this down to host builds so that e.g. people using an optimized tablegen can do the sub-configure successfully. ------------------------------------------------------------------------ llvm-svn: 353517 --- llvm/cmake/modules/CrossCompile.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/cmake/modules/CrossCompile.cmake b/llvm/cmake/modules/CrossCompile.cmake index b239816c82539..bc3b210f01859 100644 --- a/llvm/cmake/modules/CrossCompile.cmake +++ b/llvm/cmake/modules/CrossCompile.cmake @@ -52,6 +52,7 @@ function(llvm_create_cross_target_internal target_name toolchain buildtype) -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="${experimental_targets_to_build_arg}" -DLLVM_DEFAULT_TARGET_TRIPLE="${TARGET_TRIPLE}" -DLLVM_TARGET_ARCH="${LLVM_TARGET_ARCH}" + -DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN="${LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN}" ${build_type_flags} ${linker_flag} ${external_clang_dir} WORKING_DIRECTORY ${LLVM_${target_name}_BUILD} DEPENDS CREATE_LLVM_${target_name} From 15f159c37f077fcff868a3d805608a671f7f9d02 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Fri, 8 Feb 2019 22:03:46 +0000 Subject: [PATCH 115/274] - Update ReleaseNotes for lld 8.0.0. llvm-svn: 353574 --- lld/docs/ReleaseNotes.rst | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst index 9849111e0930b..2b2aa1e75b39f 100644 --- a/lld/docs/ReleaseNotes.rst +++ b/lld/docs/ReleaseNotes.rst @@ -13,10 +13,12 @@ lld 8.0.0 Release Notes Introduction ============ -This document contains the release notes for the lld linker, release 8.0.0. -Here we describe the status of lld, including major improvements -from the previous release. All lld releases may be downloaded -from the `LLVM releases web site `_. +lld is a high-performance linker that supports ELF (Unix), COFF (Windows), +Mach-O (macOS), MinGW and WebAssembly. lld is command-line-compatible with +GNU linkers and Microsoft link.exe and is significantly faster than the +system default linkers. + +nlld 8.0.0 has lots of feature improvements and bug fixes. Non-comprehensive list of changes in this release ================================================= @@ -33,16 +35,35 @@ ELF Improvements non-superpages to a superpage if they are aligned to the superpage size. (`r342746 `_) +* lld now attempts to place a ``.note`` segment in the first page of a + generated file, so that you can find some important information + (``.note.gnu.build-id`` in particular) in a core file even if a core + file is truncated by ulimit. + (`r349524 `_) + +* lld now reports an error if ``_GLOBAL_OFFSET_TABLE_`` symbol is + defined by an input object file, as the symbol is supposed to be + synthesized by the linker. + (`r347854 `_) + * lld/Hexagon can now link Linux kernel and musl libc for Qualcomm Hexagon ISA. * Initial MSP430 ISA support has landed. -* The following flags have been added: ``-z interpose``, ``-z global`` - * lld now uses the ``sigrie`` instruction as a trap instruction for MIPS targets. +* lld now creates a TLS segment for AArch64 with a slightly larger + alignment requirement, so that the loader makes a few bytes room + before each TLS segment at runtime. The aim of this change is to + make room to accomodate nonstandard Android TLS slots while keeping + the compatibility with the standard AArch64 ABI. + (`r350681 `_) + +* The following flags have been added: ``-z interpose``, ``-z global``, ``-z + nodefaultlib`` + COFF Improvements ----------------- @@ -95,11 +116,6 @@ MinGW Improvements Previously, the ``--build-id`` option did not actually generate a build id unless ``--pdb`` was specified. -MachO Improvements ------------------- - -* Item 1. - WebAssembly Improvements ------------------------ From 62ead032aaa88d89db56294449c54d73c80d3204 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Mon, 11 Feb 2019 21:26:23 +0000 Subject: [PATCH 116/274] Minor update to lld/ReleaseNotes. llvm-svn: 353749 --- lld/docs/ReleaseNotes.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst index 2b2aa1e75b39f..0bebfb3fb1cec 100644 --- a/lld/docs/ReleaseNotes.rst +++ b/lld/docs/ReleaseNotes.rst @@ -61,8 +61,9 @@ ELF Improvements the compatibility with the standard AArch64 ABI. (`r350681 `_) -* The following flags have been added: ``-z interpose``, ``-z global``, ``-z - nodefaultlib`` +* The following flags have been added: ``--call-graph-profile``, + ``--no-call-graph-profile``, ``--warn-ifunc-textrel``, + ``-z interpose``, ``-z global``, ``-z nodefaultlib`` COFF Improvements ----------------- From e055d7ffe123c04bcd2fcc9d31c6ff2e3ce7a08a Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Feb 2019 08:35:38 +0000 Subject: [PATCH 117/274] Merging r353495: ------------------------------------------------------------------------ r353495 | jfb | 2019-02-08 02:29:17 +0100 (Fri, 08 Feb 2019) | 32 lines Variable auto-init: fix __block initialization Summary: Automatic initialization [1] of __block variables was trampling over the block's headers after they'd been initialized, which caused self-init usage to crash, such as here: typedef struct XYZ { void (^block)(); } *xyz_t; __attribute__((noinline)) xyz_t create(void (^block)()) { xyz_t myself = malloc(sizeof(struct XYZ)); myself->block = block; return myself; } int main() { __block xyz_t captured = create(^(){ (void)captured; }); } This type of code shouldn't be broken by variable auto-init, even if it's sketchy. [1] With -ftrivial-auto-var-init=pattern Reviewers: rjmccall, pcc, kcc Subscribers: jkorous, dexonsmith, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57797 ------------------------------------------------------------------------ llvm-svn: 353807 --- clang/lib/CodeGen/CGDecl.cpp | 10 ++++--- .../test/CodeGenCXX/trivial-auto-var-init.cpp | 26 +++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 5959d889b4551..b98657ffd8006 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1631,11 +1631,15 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { ? LangOptions::TrivialAutoVarInitKind::Uninitialized : getContext().getLangOpts().getTrivialAutoVarInit())); - auto initializeWhatIsTechnicallyUninitialized = [&]() { + auto initializeWhatIsTechnicallyUninitialized = [&](Address Loc) { if (trivialAutoVarInit == LangOptions::TrivialAutoVarInitKind::Uninitialized) return; + // Only initialize a __block's storage: we always initialize the header. + if (emission.IsEscapingByRef) + Loc = emitBlockByrefAddress(Loc, &D, /*follow=*/false); + CharUnits Size = getContext().getTypeSizeInChars(type); if (!Size.isZero()) { switch (trivialAutoVarInit) { @@ -1713,7 +1717,7 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { }; if (isTrivialInitializer(Init)) { - initializeWhatIsTechnicallyUninitialized(); + initializeWhatIsTechnicallyUninitialized(Loc); return; } @@ -1727,7 +1731,7 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { } if (!constant) { - initializeWhatIsTechnicallyUninitialized(); + initializeWhatIsTechnicallyUninitialized(Loc); LValue lv = MakeAddrLValue(Loc, type); lv.setNonGC(true); return EmitExprAsInit(Init, &D, lv, capturedByInit); diff --git a/clang/test/CodeGenCXX/trivial-auto-var-init.cpp b/clang/test/CodeGenCXX/trivial-auto-var-init.cpp index b795c0755bd41..37ff770abf57e 100644 --- a/clang/test/CodeGenCXX/trivial-auto-var-init.cpp +++ b/clang/test/CodeGenCXX/trivial-auto-var-init.cpp @@ -30,6 +30,32 @@ void test_block() { used(block); } +// Using the variable being initialized is typically UB in C, but for blocks we +// can be nice: they imply extra book-keeping and we can do the auto-init before +// any of said book-keeping. +// +// UNINIT-LABEL: test_block_self_init( +// ZERO-LABEL: test_block_self_init( +// ZERO: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8 +// ZERO: %captured1 = getelementptr inbounds %struct.__block_byref_captured, %struct.__block_byref_captured* %captured, i32 0, i32 4 +// ZERO-NEXT: store %struct.XYZ* null, %struct.XYZ** %captured1, align 8 +// ZERO: %call = call %struct.XYZ* @create( +// PATTERN-LABEL: test_block_self_init( +// PATTERN: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8 +// PATTERN: %captured1 = getelementptr inbounds %struct.__block_byref_captured, %struct.__block_byref_captured* %captured, i32 0, i32 4 +// PATTERN-NEXT: store %struct.XYZ* inttoptr (i64 -6148914691236517206 to %struct.XYZ*), %struct.XYZ** %captured1, align 8 +// PATTERN: %call = call %struct.XYZ* @create( +void test_block_self_init() { + using Block = void (^)(); + typedef struct XYZ { + Block block; + } * xyz_t; + extern xyz_t create(Block block); + __block xyz_t captured = create(^() { + (void)captured; + }); +} + // This type of code is currently not handled by zero / pattern initialization. // The test will break when that is fixed. // UNINIT-LABEL: test_goto_unreachable_value( From 0cbe0b9fa2d5ccf4e3a05d6fc31fcb8c5123c1aa Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Feb 2019 08:45:37 +0000 Subject: [PATCH 118/274] ReleaseNotes about the toolchain version cmake check Based on text from JF! llvm-svn: 353808 --- llvm/docs/ReleaseNotes.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 561faa71fd5db..9e2ee95c65194 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -40,6 +40,22 @@ Non-comprehensive list of changes in this release functionality, or simply have a lot to talk about), see the `NOTE` below for adding a new subsection. +* As `discussed on the mailing list + `_, + building LLVM will soon require more recent toolchains as follows: + + ============= ==== + Clang 3.5 + Apple Clang 6.0 + GCC 5.1 + Visual Studio 2017 + ============= ==== + + A new CMake check when configuring LLVM provides a soft-error if your + toolchain will become unsupported soon. You can opt out of the soft-error by + setting the ``LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN`` CMake variable to + ``ON``. + * The **llvm-cov** tool can now export lcov trace files using the `-format=lcov` option of the `export` command. From 75ff7d07215a502f909ff305e04d514f1752a1d7 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Feb 2019 09:11:50 +0000 Subject: [PATCH 119/274] Merging r353551 and r353809: Also removed the text about Clang 9. ------------------------------------------------------------------------ r353551 | metzman | 2019-02-08 20:35:04 +0100 (Fri, 08 Feb 2019) | 13 lines Document libFuzzer on Windows. Summary: Document that libFuzzer supports Windows, how to get it, and its limitations. Reviewers: kcc, morehouse, rnk, metzman Reviewed By: kcc, rnk, metzman Subscribers: hans, rnk Differential Revision: https://reviews.llvm.org/D57597 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r353809 | hans | 2019-02-12 10:08:52 +0100 (Tue, 12 Feb 2019) | 1 line LibFuzzer.rst: double backticks ------------------------------------------------------------------------ llvm-svn: 353811 --- llvm/docs/LibFuzzer.rst | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/llvm/docs/LibFuzzer.rst b/llvm/docs/LibFuzzer.rst index 0737fbbcd9305..37b0833599a94 100644 --- a/llvm/docs/LibFuzzer.rst +++ b/llvm/docs/LibFuzzer.rst @@ -645,10 +645,20 @@ coverage set of the process (since the fuzzer is in-process). In other words, by using more external dependencies we will slow down the fuzzer while the main reason for it to exist is extreme speed. -Q. What about Windows then? The fuzzer contains code that does not build on Windows. +Q. Does libFuzzer Support Windows? ------------------------------------------------------------------------------------ -Volunteers are welcome. +Yes, libFuzzer now supports Windows. Initial support was added in r341082. +You can download a build of Clang for Windows +that has libFuzzer from +`LLVM Snapshot Builds `_. + +Using libFuzzer on Windows without ASAN is unsupported. Building fuzzers with the +``/MD`` (dynamic runtime library) compile option is unsupported. Support for these +may be added in the future. Linking fuzzers with the ``/INCREMENTAL`` link option +(or the ``/DEBUG`` option which implies it) is also unsupported. + +Send any questions or comments to the mailing list: libfuzzer(#)googlegroups.com Q. When libFuzzer is not a good solution for a problem? --------------------------------------------------------- From 018cd5fdf09cf9ff67754497659b9a3cb2bddcd5 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Feb 2019 10:13:48 +0000 Subject: [PATCH 120/274] Merging r352607 r352608 r353015 r353061 r353138 r353141 r353334 r353489 And re-generate expectations for a test: $ utils/update_llc_test_checks.py --llc-binary ../build.release/bin/llc test/CodeGen/X86/x87-schedule.ll Will also merge cfe r353142 for a clang-side test. This merge was requested in PR40667. ------------------------------------------------------------------------ r352607 | ctopper | 2019-01-30 08:08:44 +0100 (Wed, 30 Jan 2019) | 1 line [X86] Add FPSW as a Def on some FP instructions that were missing it. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r352608 | ctopper | 2019-01-30 08:33:24 +0100 (Wed, 30 Jan 2019) | 5 lines [X86] Remove a couple places where we unnecessarily pass 0 to the EmitPriority of some FP instruction aliases. NFC As far as I can tell we already won't emit these aliases due to an operand count check in the tablegen code. Removing these because I couldn't make sense of the inconsistency between fadd and fmul from reading the code. I checked the AsmMatcher and AsmWriter files before and after this change and there were no differences. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r353015 | ctopper | 2019-02-04 05:15:10 +0100 (Mon, 04 Feb 2019) | 3 lines [X86] Print %st(0) as %st when its implicit to the instruction. Continue printing it as %st(0) when its encoded in the instruction. This is a step back from the change I made in r352985. This appears to be more consistent with gcc and objdump behavior. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r353061 | ctopper | 2019-02-04 18:28:18 +0100 (Mon, 04 Feb 2019) | 5 lines [X86] Print all register forms of x87 fadd/fsub/fdiv/fmul as having two arguments where on is %st. All of these instructions consume one encoded register and the other register is %st. They either write the result to %st or the encoded register. Previously we printed both arguments when the encoded register was written. And we printed one argument when the result was written to %st. For the stack popping forms the encoded register is always the destination and we didn't print both operands. This was inconsistent with gcc and objdump and just makes the output assembly code harder to read. This patch changes things to always print both operands making us consistent with gcc and objdump. The parser should still be able to handle the single register forms just as it did before. This also matches the GNU assembler behavior. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r353138 | ctopper | 2019-02-05 05:48:23 +0100 (Tue, 05 Feb 2019) | 1 line [X86] Add test case from PR40529. NFC ------------------------------------------------------------------------ ------------------------------------------------------------------------ r353141 | ctopper | 2019-02-05 07:13:06 +0100 (Tue, 05 Feb 2019) | 16 lines [X86] Connect the default fpsr and dirflag clobbers in inline assembly to the registers we have defined for them. Summary: We don't currently map these constraints to physical register numbers so they don't make it to the MachineIR representation of inline assembly. This could have problems for proper dependency tracking in the machine schedulers though I don't have a test case that shows that. Reviewers: rnk Reviewed By: rnk Subscribers: eraman, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D57641 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r353334 | ctopper | 2019-02-06 20:50:59 +0100 (Wed, 06 Feb 2019) | 1 line [X86] Change the CPU on the test case for pr40529.ll to really show the bug. NFC ------------------------------------------------------------------------ ------------------------------------------------------------------------ r353489 | ctopper | 2019-02-08 01:44:39 +0100 (Fri, 08 Feb 2019) | 14 lines [X86] Add FPCW as a register and start using it as an implicit use on floating point instructions. Summary: FPCW contains the rounding mode control which we manipulate to implement fp to integer conversion by changing the roudning mode, storing the value to the stack, and then changing the rounding mode back. Because we didn't model FPCW and its dependency chain, other instructions could be scheduled into the middle of the sequence. This patch introduces the register and adds it as an implciit def of FLDCW and implicit use of the FP binary arithmetic instructions and store instructions. There are more instructions that need to be updated, but this is a good start. I believe this fixes at least the reduced test case from PR40529. Reviewers: RKSimon, spatel, rnk, efriedma, andrew.w.kaylor Subscribers: dim, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D57735 ------------------------------------------------------------------------ llvm-svn: 353818 --- .../lib/Target/X86/AsmParser/X86AsmParser.cpp | 3 +- .../X86/InstPrinter/X86ATTInstPrinter.cpp | 11 + .../X86/InstPrinter/X86ATTInstPrinter.h | 1 + .../X86/InstPrinter/X86IntelInstPrinter.cpp | 11 + .../X86/InstPrinter/X86IntelInstPrinter.h | 1 + llvm/lib/Target/X86/X86ISelLowering.cpp | 8 + llvm/lib/Target/X86/X86InstrFPStack.td | 156 ++-- llvm/lib/Target/X86/X86InstrInfo.td | 46 +- llvm/lib/Target/X86/X86RegisterInfo.cpp | 3 + llvm/lib/Target/X86/X86RegisterInfo.td | 10 +- llvm/test/CodeGen/MIR/X86/memory-operands.mir | 4 +- llvm/test/CodeGen/X86/and-su.ll | 2 +- .../test/CodeGen/X86/avx512-regcall-NoMask.ll | 18 +- llvm/test/CodeGen/X86/fcmove.ll | 2 +- llvm/test/CodeGen/X86/fmf-flags.ll | 4 +- llvm/test/CodeGen/X86/fp-cvt.ll | 8 +- .../X86/inline-asm-default-clobbers.ll | 8 + llvm/test/CodeGen/X86/inline-asm-fpstack.ll | 38 +- llvm/test/CodeGen/X86/ipra-reg-usage.ll | 2 +- llvm/test/CodeGen/X86/pr13577.ll | 2 +- llvm/test/CodeGen/X86/pr33349.ll | 16 +- llvm/test/CodeGen/X86/pr34080.ll | 18 +- llvm/test/CodeGen/X86/pr34177.ll | 16 +- llvm/test/CodeGen/X86/pr40529.ll | 43 + llvm/test/CodeGen/X86/scalar-fp-to-i64.ll | 24 +- llvm/test/CodeGen/X86/select.ll | 24 +- llvm/test/CodeGen/X86/sincos-opt.ll | 4 +- llvm/test/CodeGen/X86/x87-schedule.ll | 792 +++++++++--------- llvm/test/MC/Disassembler/X86/fp-stack.txt | 416 ++++----- llvm/test/MC/Disassembler/X86/x86-16.txt | 4 +- llvm/test/MC/X86/PPRO-32.s | 32 +- llvm/test/MC/X86/PPRO-64.s | 32 +- llvm/test/MC/X86/X87-32.s | 48 +- llvm/test/MC/X86/X87-64.s | 46 +- llvm/test/MC/X86/intel-syntax-2.s | 12 +- llvm/test/MC/X86/intel-syntax.s | 96 +-- llvm/test/MC/X86/x86-16.s | 4 +- llvm/test/MC/X86/x86-32-coverage.s | 38 +- llvm/test/MC/X86/x86-32.s | 2 +- llvm/test/MC/X86/x86-64.s | 172 ++-- .../tools/llvm-mca/X86/Atom/resources-x87.s | 172 ++-- .../tools/llvm-mca/X86/BdVer2/resources-x87.s | 172 ++-- .../llvm-mca/X86/Broadwell/resources-x87.s | 172 ++-- .../tools/llvm-mca/X86/BtVer2/resources-x87.s | 172 ++-- .../llvm-mca/X86/Generic/resources-x87.s | 172 ++-- .../llvm-mca/X86/Haswell/resources-x87.s | 172 ++-- .../tools/llvm-mca/X86/SLM/resources-x87.s | 172 ++-- .../llvm-mca/X86/SandyBridge/resources-x87.s | 172 ++-- .../X86/SkylakeClient/resources-x87.s | 172 ++-- .../X86/SkylakeServer/resources-x87.s | 172 ++-- .../tools/llvm-mca/X86/Znver1/resources-x87.s | 172 ++-- llvm/utils/TableGen/X86RecognizableInstr.cpp | 2 + 52 files changed, 2082 insertions(+), 1989 deletions(-) create mode 100644 llvm/test/CodeGen/X86/inline-asm-default-clobbers.ll create mode 100644 llvm/test/CodeGen/X86/pr40529.ll diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index 899b50d0f78f3..81391b96d1267 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -1115,8 +1115,7 @@ bool X86AsmParser::ParseRegister(unsigned &RegNo, } // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens. - if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) { - RegNo = X86::ST0; + if (RegNo == X86::ST0) { Parser.Lex(); // Eat 'st' // Check to see if we have '(4)' after %st. diff --git a/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp b/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp index 0e861d5ddbc9d..3a074818c762b 100644 --- a/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp +++ b/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp @@ -200,3 +200,14 @@ void X86ATTInstPrinter::printU8Imm(const MCInst *MI, unsigned Op, O << markup("getOperand(Op).getImm() & 0xff) << markup(">"); } + +void X86ATTInstPrinter::printSTiRegOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &OS) { + const MCOperand &Op = MI->getOperand(OpNo); + unsigned Reg = Op.getReg(); + // Override the default printing to print st(0) instead st. + if (Reg == X86::ST0) + OS << markup(""); + else + printRegName(OS, Reg); +} diff --git a/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h b/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h index 57422bc9a0b2a..584dc9c286e60 100644 --- a/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h +++ b/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h @@ -44,6 +44,7 @@ class X86ATTInstPrinter final : public X86InstPrinterCommon { void printSrcIdx(const MCInst *MI, unsigned Op, raw_ostream &O); void printDstIdx(const MCInst *MI, unsigned Op, raw_ostream &O); void printU8Imm(const MCInst *MI, unsigned Op, raw_ostream &OS); + void printSTiRegOperand(const MCInst *MI, unsigned OpNo, raw_ostream &OS); void printanymem(const MCInst *MI, unsigned OpNo, raw_ostream &O) { printMemReference(MI, OpNo, O); diff --git a/llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp b/llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp index 044b715641520..b31f8ab80838d 100644 --- a/llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp +++ b/llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp @@ -160,3 +160,14 @@ void X86IntelInstPrinter::printU8Imm(const MCInst *MI, unsigned Op, O << formatImm(MI->getOperand(Op).getImm() & 0xff); } + +void X86IntelInstPrinter::printSTiRegOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &OS) { + const MCOperand &Op = MI->getOperand(OpNo); + unsigned Reg = Op.getReg(); + // Override the default printing to print st(0) instead st. + if (Reg == X86::ST0) + OS << "st(0)"; + else + printRegName(OS, Reg); +} diff --git a/llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h b/llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h index 3b34a8052becb..fe52bd482a262 100644 --- a/llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h +++ b/llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h @@ -39,6 +39,7 @@ class X86IntelInstPrinter final : public X86InstPrinterCommon { void printSrcIdx(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printDstIdx(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printU8Imm(const MCInst *MI, unsigned Op, raw_ostream &O); + void printSTiRegOperand(const MCInst *MI, unsigned OpNo, raw_ostream &OS); void printanymem(const MCInst *MI, unsigned OpNo, raw_ostream &O) { printMemReference(MI, OpNo, O); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 3637562c8ec35..f4f37a894620e 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -42507,6 +42507,14 @@ X86TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, if (StringRef("{flags}").equals_lower(Constraint)) return std::make_pair(X86::EFLAGS, &X86::CCRRegClass); + // dirflag -> DF + if (StringRef("{dirflag}").equals_lower(Constraint)) + return std::make_pair(X86::DF, &X86::DFCCRRegClass); + + // fpsr -> FPSW + if (StringRef("{fpsr}").equals_lower(Constraint)) + return std::make_pair(X86::FPSW, &X86::FPCCRRegClass); + // 'A' means [ER]AX + [ER]DX. if (Constraint == "A") { if (Subtarget.is64Bit()) diff --git a/llvm/lib/Target/X86/X86InstrFPStack.td b/llvm/lib/Target/X86/X86InstrFPStack.td index 5912a31996131..8e12efff77eab 100644 --- a/llvm/lib/Target/X86/X86InstrFPStack.td +++ b/llvm/lib/Target/X86/X86InstrFPStack.td @@ -230,7 +230,7 @@ def _FI32m : FPI<0xDA, fp, (outs), (ins i32mem:$src), } // mayLoad = 1, hasSideEffects = 1 } -let Defs = [FPSW] in { +let Defs = [FPSW], Uses = [FPCW] in { // FPBinary_rr just defines pseudo-instructions, no need to set a scheduling // resources. let hasNoSchedulingInfo = 1 in { @@ -258,42 +258,42 @@ defm DIVR: FPBinary; } // Defs = [FPSW] class FPST0rInst - : FPI<0xD8, fp, (outs), (ins RST:$op), asm>; + : FPI<0xD8, fp, (outs), (ins RSTi:$op), asm>; class FPrST0Inst - : FPI<0xDC, fp, (outs), (ins RST:$op), asm>; + : FPI<0xDC, fp, (outs), (ins RSTi:$op), asm>; class FPrST0PInst - : FPI<0xDE, fp, (outs), (ins RST:$op), asm>; + : FPI<0xDE, fp, (outs), (ins RSTi:$op), asm>; // NOTE: GAS and apparently all other AT&T style assemblers have a broken notion // of some of the 'reverse' forms of the fsub and fdiv instructions. As such, // we have to put some 'r's in and take them out of weird places. -let SchedRW = [WriteFAdd] in { -def ADD_FST0r : FPST0rInst ; -def ADD_FrST0 : FPrST0Inst ; -def ADD_FPrST0 : FPrST0PInst; -def SUBR_FST0r : FPST0rInst ; -def SUB_FrST0 : FPrST0Inst ; -def SUB_FPrST0 : FPrST0PInst; -def SUB_FST0r : FPST0rInst ; -def SUBR_FrST0 : FPrST0Inst ; -def SUBR_FPrST0 : FPrST0PInst; +let SchedRW = [WriteFAdd], Defs = [FPSW], Uses = [FPCW] in { +def ADD_FST0r : FPST0rInst ; +def ADD_FrST0 : FPrST0Inst ; +def ADD_FPrST0 : FPrST0PInst; +def SUBR_FST0r : FPST0rInst ; +def SUB_FrST0 : FPrST0Inst ; +def SUB_FPrST0 : FPrST0PInst; +def SUB_FST0r : FPST0rInst ; +def SUBR_FrST0 : FPrST0Inst ; +def SUBR_FPrST0 : FPrST0PInst; } // SchedRW -let SchedRW = [WriteFCom] in { +let SchedRW = [WriteFCom], Defs = [FPSW], Uses = [FPCW] in { def COM_FST0r : FPST0rInst ; def COMP_FST0r : FPST0rInst ; } // SchedRW -let SchedRW = [WriteFMul] in { -def MUL_FST0r : FPST0rInst ; -def MUL_FrST0 : FPrST0Inst ; -def MUL_FPrST0 : FPrST0PInst; +let SchedRW = [WriteFMul], Defs = [FPSW], Uses = [FPCW] in { +def MUL_FST0r : FPST0rInst ; +def MUL_FrST0 : FPrST0Inst ; +def MUL_FPrST0 : FPrST0PInst; } // SchedRW -let SchedRW = [WriteFDiv] in { -def DIVR_FST0r : FPST0rInst ; -def DIV_FrST0 : FPrST0Inst ; -def DIV_FPrST0 : FPrST0PInst; -def DIV_FST0r : FPST0rInst ; -def DIVR_FrST0 : FPrST0Inst ; -def DIVR_FPrST0 : FPrST0PInst; +let SchedRW = [WriteFDiv], Defs = [FPSW], Uses = [FPCW] in { +def DIVR_FST0r : FPST0rInst ; +def DIV_FrST0 : FPrST0Inst ; +def DIV_FPrST0 : FPrST0PInst; +def DIV_FST0r : FPST0rInst ; +def DIVR_FrST0 : FPrST0Inst ; +def DIVR_FPrST0 : FPrST0PInst; } // SchedRW // Unary operations. @@ -307,7 +307,7 @@ def _Fp80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src), OneArgFPRW, def _F : FPI<0xD9, fp, (outs), (ins), asmstring>; } -let Defs = [FPSW] in { +let Defs = [FPSW], Uses = [FPCW] in { let SchedRW = [WriteFSign] in { defm CHS : FPUnary; @@ -335,7 +335,7 @@ def TST_F : FPI<0xD9, MRM_E4, (outs), (ins), "ftst">; // Versions of FP instructions that take a single memory operand. Added for the // disassembler; remove as they are included with patterns elsewhere. -let SchedRW = [WriteFComLd] in { +let SchedRW = [WriteFComLd], Defs = [FPSW], Uses = [FPCW] in { def FCOM32m : FPI<0xD8, MRM2m, (outs), (ins f32mem:$src), "fcom{s}\t$src">; def FCOMP32m : FPI<0xD8, MRM3m, (outs), (ins f32mem:$src), "fcomp{s}\t$src">; @@ -398,22 +398,22 @@ defm CMOVNP : FPCMov; let Predicates = [HasCMov] in { // These are not factored because there's no clean way to pass DA/DB. -def CMOVB_F : FPI<0xDA, MRM0r, (outs), (ins RST:$op), - "fcmovb\t{$op, %st(0)|st(0), $op}">; -def CMOVBE_F : FPI<0xDA, MRM2r, (outs), (ins RST:$op), - "fcmovbe\t{$op, %st(0)|st(0), $op}">; -def CMOVE_F : FPI<0xDA, MRM1r, (outs), (ins RST:$op), - "fcmove\t{$op, %st(0)|st(0), $op}">; -def CMOVP_F : FPI<0xDA, MRM3r, (outs), (ins RST:$op), - "fcmovu\t{$op, %st(0)|st(0), $op}">; -def CMOVNB_F : FPI<0xDB, MRM0r, (outs), (ins RST:$op), - "fcmovnb\t{$op, %st(0)|st(0), $op}">; -def CMOVNBE_F: FPI<0xDB, MRM2r, (outs), (ins RST:$op), - "fcmovnbe\t{$op, %st(0)|st(0), $op}">; -def CMOVNE_F : FPI<0xDB, MRM1r, (outs), (ins RST:$op), - "fcmovne\t{$op, %st(0)|st(0), $op}">; -def CMOVNP_F : FPI<0xDB, MRM3r, (outs), (ins RST:$op), - "fcmovnu\t{$op, %st(0)|st(0), $op}">; +def CMOVB_F : FPI<0xDA, MRM0r, (outs), (ins RSTi:$op), + "fcmovb\t{$op, %st|st, $op}">; +def CMOVBE_F : FPI<0xDA, MRM2r, (outs), (ins RSTi:$op), + "fcmovbe\t{$op, %st|st, $op}">; +def CMOVE_F : FPI<0xDA, MRM1r, (outs), (ins RSTi:$op), + "fcmove\t{$op, %st|st, $op}">; +def CMOVP_F : FPI<0xDA, MRM3r, (outs), (ins RSTi:$op), + "fcmovu\t{$op, %st|st, $op}">; +def CMOVNB_F : FPI<0xDB, MRM0r, (outs), (ins RSTi:$op), + "fcmovnb\t{$op, %st|st, $op}">; +def CMOVNBE_F: FPI<0xDB, MRM2r, (outs), (ins RSTi:$op), + "fcmovnbe\t{$op, %st|st, $op}">; +def CMOVNE_F : FPI<0xDB, MRM1r, (outs), (ins RSTi:$op), + "fcmovne\t{$op, %st|st, $op}">; +def CMOVNP_F : FPI<0xDB, MRM3r, (outs), (ins RSTi:$op), + "fcmovnu\t{$op, %st|st, $op}">; } // Predicates = [HasCMov] } // SchedRW @@ -454,7 +454,7 @@ def ILD_Fp64m80: FpI_<(outs RFP80:$dst), (ins i64mem:$src), ZeroArgFP, [(set RFP80:$dst, (X86fild addr:$src, i64))]>; } // SchedRW -let SchedRW = [WriteStore] in { +let SchedRW = [WriteStore], Uses = [FPCW] in { def ST_Fp32m : FpIf32<(outs), (ins f32mem:$op, RFP32:$src), OneArgFP, [(store RFP32:$src, addr:$op)]>; def ST_Fp64m32 : FpIf64<(outs), (ins f32mem:$op, RFP64:$src), OneArgFP, @@ -489,7 +489,7 @@ def IST_Fp16m80 : FpI_<(outs), (ins i16mem:$op, RFP80:$src), OneArgFP, []>; def IST_Fp32m80 : FpI_<(outs), (ins i32mem:$op, RFP80:$src), OneArgFP, []>; def IST_Fp64m80 : FpI_<(outs), (ins i64mem:$op, RFP80:$src), OneArgFP, []>; } // mayStore -} // SchedRW +} // SchedRW, Uses = [FPCW] let mayLoad = 1, SchedRW = [WriteLoad] in { def LD_F32m : FPI<0xD9, MRM0m, (outs), (ins f32mem:$src), "fld{s}\t$src">; @@ -499,7 +499,7 @@ def ILD_F16m : FPI<0xDF, MRM0m, (outs), (ins i16mem:$src), "fild{s}\t$src">; def ILD_F32m : FPI<0xDB, MRM0m, (outs), (ins i32mem:$src), "fild{l}\t$src">; def ILD_F64m : FPI<0xDF, MRM5m, (outs), (ins i64mem:$src), "fild{ll}\t$src">; } -let mayStore = 1, SchedRW = [WriteStore] in { +let mayStore = 1, SchedRW = [WriteStore], Uses = [FPCW] in { def ST_F32m : FPI<0xD9, MRM2m, (outs), (ins f32mem:$dst), "fst{s}\t$dst">; def ST_F64m : FPI<0xDD, MRM2m, (outs), (ins f64mem:$dst), "fst{l}\t$dst">; def ST_FP32m : FPI<0xD9, MRM3m, (outs), (ins f32mem:$dst), "fstp{s}\t$dst">; @@ -513,7 +513,7 @@ def IST_FP64m : FPI<0xDF, MRM7m, (outs), (ins i64mem:$dst), "fistp{ll}\t$dst">; } // FISTTP requires SSE3 even though it's a FPStack op. -let Predicates = [HasSSE3], SchedRW = [WriteStore] in { +let Predicates = [HasSSE3], SchedRW = [WriteStore], Uses = [FPCW] in { def ISTT_Fp16m32 : FpI_<(outs), (ins i16mem:$op, RFP32:$src), OneArgFP, [(X86fp_to_i16mem RFP32:$src, addr:$op)]>; def ISTT_Fp32m32 : FpI_<(outs), (ins i32mem:$op, RFP32:$src), OneArgFP, @@ -534,7 +534,7 @@ def ISTT_Fp64m80 : FpI_<(outs), (ins i64mem:$op, RFP80:$src), OneArgFP, [(X86fp_to_i64mem RFP80:$src, addr:$op)]>; } // Predicates = [HasSSE3] -let mayStore = 1, SchedRW = [WriteStore] in { +let mayStore = 1, SchedRW = [WriteStore], Uses = [FPCW] in { def ISTT_FP16m : FPI<0xDF, MRM1m, (outs), (ins i16mem:$dst), "fisttp{s}\t$dst">; def ISTT_FP32m : FPI<0xDB, MRM1m, (outs), (ins i32mem:$dst), "fisttp{l}\t$dst">; def ISTT_FP64m : FPI<0xDD, MRM1m, (outs), (ins i64mem:$dst), "fisttp{ll}\t$dst">; @@ -542,10 +542,10 @@ def ISTT_FP64m : FPI<0xDD, MRM1m, (outs), (ins i64mem:$dst), "fisttp{ll}\t$dst"> // FP Stack manipulation instructions. let SchedRW = [WriteMove] in { -def LD_Frr : FPI<0xD9, MRM0r, (outs), (ins RST:$op), "fld\t$op">; -def ST_Frr : FPI<0xDD, MRM2r, (outs), (ins RST:$op), "fst\t$op">; -def ST_FPrr : FPI<0xDD, MRM3r, (outs), (ins RST:$op), "fstp\t$op">; -def XCH_F : FPI<0xD9, MRM1r, (outs), (ins RST:$op), "fxch\t$op">; +def LD_Frr : FPI<0xD9, MRM0r, (outs), (ins RSTi:$op), "fld\t$op">; +def ST_Frr : FPI<0xDD, MRM2r, (outs), (ins RSTi:$op), "fst\t$op">; +def ST_FPrr : FPI<0xDD, MRM3r, (outs), (ins RSTi:$op), "fstp\t$op">; +def XCH_F : FPI<0xD9, MRM1r, (outs), (ins RSTi:$op), "fxch\t$op">; } // Floating point constant loads. @@ -570,7 +570,7 @@ def LD_F0 : FPI<0xD9, MRM_EE, (outs), (ins), "fldz">; let SchedRW = [WriteFLD1] in def LD_F1 : FPI<0xD9, MRM_E8, (outs), (ins), "fld1">; -let SchedRW = [WriteFLDC], Defs = [FPSW] in { +let SchedRW = [WriteFLDC] in { def FLDL2T : I<0xD9, MRM_E9, (outs), (ins), "fldl2t", []>; def FLDL2E : I<0xD9, MRM_EA, (outs), (ins), "fldl2e", []>; def FLDPI : I<0xD9, MRM_EB, (outs), (ins), "fldpi", []>; @@ -579,7 +579,7 @@ def FLDLN2 : I<0xD9, MRM_ED, (outs), (ins), "fldln2", []>; } // SchedRW // Floating point compares. -let SchedRW = [WriteFCom] in { +let SchedRW = [WriteFCom], Uses = [FPCW] in { def UCOM_Fpr32 : FpIf32<(outs), (ins RFP32:$lhs, RFP32:$rhs), CompareFP, [(set FPSW, (trunc (X86cmp RFP32:$lhs, RFP32:$rhs)))]>; def UCOM_Fpr64 : FpIf64<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP, @@ -591,37 +591,37 @@ def UCOM_Fpr80 : FpI_ <(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP, let SchedRW = [WriteFCom] in { // CC = ST(0) cmp ST(i) -let Defs = [EFLAGS, FPSW] in { -let Predicates = [FPStackf32, HasCMov] in -def UCOM_FpIr32: FpIf32<(outs), (ins RFP32:$lhs, RFP32:$rhs), CompareFP, - [(set EFLAGS, (X86cmp RFP32:$lhs, RFP32:$rhs))]>; -let Predicates = [FPStackf64, HasCMov] in -def UCOM_FpIr64: FpIf64<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP, - [(set EFLAGS, (X86cmp RFP64:$lhs, RFP64:$rhs))]>; -let Predicates = [HasCMov] in +let Defs = [EFLAGS, FPSW], Uses = [FPCW] in { +def UCOM_FpIr32: FpI_<(outs), (ins RFP32:$lhs, RFP32:$rhs), CompareFP, + [(set EFLAGS, (X86cmp RFP32:$lhs, RFP32:$rhs))]>, + Requires<[FPStackf32, HasCMov]>; +def UCOM_FpIr64: FpI_<(outs), (ins RFP64:$lhs, RFP64:$rhs), CompareFP, + [(set EFLAGS, (X86cmp RFP64:$lhs, RFP64:$rhs))]>, + Requires<[FPStackf64, HasCMov]>; def UCOM_FpIr80: FpI_<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP, - [(set EFLAGS, (X86cmp RFP80:$lhs, RFP80:$rhs))]>; + [(set EFLAGS, (X86cmp RFP80:$lhs, RFP80:$rhs))]>, + Requires<[HasCMov]>; } -let Defs = [FPSW], Uses = [ST0] in { +let Defs = [FPSW], Uses = [ST0, FPCW] in { def UCOM_Fr : FPI<0xDD, MRM4r, // FPSW = cmp ST(0) with ST(i) - (outs), (ins RST:$reg), "fucom\t$reg">; + (outs), (ins RSTi:$reg), "fucom\t$reg">; def UCOM_FPr : FPI<0xDD, MRM5r, // FPSW = cmp ST(0) with ST(i), pop - (outs), (ins RST:$reg), "fucomp\t$reg">; + (outs), (ins RSTi:$reg), "fucomp\t$reg">; def UCOM_FPPr : FPI<0xDA, MRM_E9, // cmp ST(0) with ST(1), pop, pop (outs), (ins), "fucompp">; } -let Defs = [EFLAGS, FPSW], Uses = [ST0] in { +let Defs = [EFLAGS, FPSW], Uses = [ST0, FPCW] in { def UCOM_FIr : FPI<0xDB, MRM5r, // CC = cmp ST(0) with ST(i) - (outs), (ins RST:$reg), "fucomi\t$reg">; + (outs), (ins RSTi:$reg), "fucomi\t{$reg, %st|st, $reg}">; def UCOM_FIPr : FPI<0xDF, MRM5r, // CC = cmp ST(0) with ST(i), pop - (outs), (ins RST:$reg), "fucompi\t$reg">; -} + (outs), (ins RSTi:$reg), "fucompi\t{$reg, %st|st, $reg}">; -let Defs = [EFLAGS, FPSW] in { -def COM_FIr : FPI<0xDB, MRM6r, (outs), (ins RST:$reg), "fcomi\t$reg">; -def COM_FIPr : FPI<0xDF, MRM6r, (outs), (ins RST:$reg), "fcompi\t$reg">; +def COM_FIr : FPI<0xDB, MRM6r, (outs), (ins RSTi:$reg), + "fcomi\t{$reg, %st|st, $reg}">; +def COM_FIPr : FPI<0xDF, MRM6r, (outs), (ins RSTi:$reg), + "fcompi\t{$reg, %st|st, $reg}">; } } // SchedRW @@ -631,12 +631,12 @@ let Defs = [AX], Uses = [FPSW] in def FNSTSW16r : I<0xDF, MRM_E0, // AX = fp flags (outs), (ins), "fnstsw\t{%ax|ax}", [(set AX, (X86fp_stsw FPSW))]>; -let Defs = [FPSW] in +let Defs = [FPSW], Uses = [FPCW] in def FNSTCW16m : I<0xD9, MRM7m, // [mem16] = X87 control world (outs), (ins i16mem:$dst), "fnstcw\t$dst", [(X86fp_cwd_get16 addr:$dst)]>; } // SchedRW -let Defs = [FPSW], mayLoad = 1 in +let Defs = [FPSW,FPCW], mayLoad = 1 in def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16] (outs), (ins i16mem:$dst), "fldcw\t$dst", []>, Sched<[WriteLoad]>; @@ -645,8 +645,8 @@ def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16] let SchedRW = [WriteMicrocoded] in { let Defs = [FPSW] in { def FNINIT : I<0xDB, MRM_E3, (outs), (ins), "fninit", []>; -def FFREE : FPI<0xDD, MRM0r, (outs), (ins RST:$reg), "ffree\t$reg">; -def FFREEP : FPI<0xDF, MRM0r, (outs), (ins RST:$reg), "ffreep\t$reg">; +def FFREE : FPI<0xDD, MRM0r, (outs), (ins RSTi:$reg), "ffree\t$reg">; +def FFREEP : FPI<0xDF, MRM0r, (outs), (ins RSTi:$reg), "ffreep\t$reg">; // Clear exceptions def FNCLEX : I<0xDB, MRM_E2, (outs), (ins), "fnclex", []>; diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index e53f83baa3c62..4ec4d566ca998 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -3231,39 +3231,39 @@ def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>; // instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with // gas. multiclass FpUnaryAlias { - def : InstAlias; - def : InstAlias; + def : InstAlias; } -defm : FpUnaryAlias<"fadd", ADD_FST0r>; +defm : FpUnaryAlias<"fadd", ADD_FST0r, 0>; defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>; -defm : FpUnaryAlias<"fsub", SUB_FST0r>; -defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0>; -defm : FpUnaryAlias<"fsubr", SUBR_FST0r>; -defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0>; -defm : FpUnaryAlias<"fmul", MUL_FST0r>; -defm : FpUnaryAlias<"fmulp", MUL_FPrST0>; -defm : FpUnaryAlias<"fdiv", DIV_FST0r>; -defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0>; -defm : FpUnaryAlias<"fdivr", DIVR_FST0r>; -defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0>; +defm : FpUnaryAlias<"fsub", SUB_FST0r, 0>; +defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0, 0>; +defm : FpUnaryAlias<"fsubr", SUBR_FST0r, 0>; +defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0, 0>; +defm : FpUnaryAlias<"fmul", MUL_FST0r, 0>; +defm : FpUnaryAlias<"fmulp", MUL_FPrST0, 0>; +defm : FpUnaryAlias<"fdiv", DIV_FST0r, 0>; +defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0, 0>; +defm : FpUnaryAlias<"fdivr", DIVR_FST0r, 0>; +defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0, 0>; defm : FpUnaryAlias<"fcomi", COM_FIr, 0>; defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>; -defm : FpUnaryAlias<"fcompi", COM_FIPr>; -defm : FpUnaryAlias<"fucompi", UCOM_FIPr>; +defm : FpUnaryAlias<"fcompi", COM_FIPr, 0>; +defm : FpUnaryAlias<"fucompi", UCOM_FIPr, 0>; -// Handle "f{mulp,addp} st(0), $op" the same as "f{mulp,addp} $op", since they +// Handle "f{mulp,addp} $op, %st(0)" the same as "f{mulp,addp} $op", since they // commute. We also allow fdiv[r]p/fsubrp even though they don't commute, // solely because gas supports it. -def : InstAlias<"faddp\t{%st(0), $op|$op, st(0)}", (ADD_FPrST0 RST:$op), 0>; -def : InstAlias<"fmulp\t{%st(0), $op|$op, st(0)}", (MUL_FPrST0 RST:$op)>; -def : InstAlias<"fsub{|r}p\t{%st(0), $op|$op, st(0)}", (SUBR_FPrST0 RST:$op)>; -def : InstAlias<"fsub{r|}p\t{%st(0), $op|$op, st(0)}", (SUB_FPrST0 RST:$op)>; -def : InstAlias<"fdiv{|r}p\t{%st(0), $op|$op, st(0)}", (DIVR_FPrST0 RST:$op)>; -def : InstAlias<"fdiv{r|}p\t{%st(0), $op|$op, st(0)}", (DIV_FPrST0 RST:$op)>; +def : InstAlias<"faddp\t{$op, %st|st, $op}", (ADD_FPrST0 RSTi:$op), 0>; +def : InstAlias<"fmulp\t{$op, %st|st, $op}", (MUL_FPrST0 RSTi:$op), 0>; +def : InstAlias<"fsub{|r}p\t{$op, %st|st, $op}", (SUBR_FPrST0 RSTi:$op), 0>; +def : InstAlias<"fsub{r|}p\t{$op, %st|st, $op}", (SUB_FPrST0 RSTi:$op), 0>; +def : InstAlias<"fdiv{|r}p\t{$op, %st|st, $op}", (DIVR_FPrST0 RSTi:$op), 0>; +def : InstAlias<"fdiv{r|}p\t{$op, %st|st, $op}", (DIV_FPrST0 RSTi:$op), 0>; def : InstAlias<"fnstsw" , (FNSTSW16r), 0>; diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp index 55842a4a20914..bc39cee34c4ad 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp @@ -497,6 +497,9 @@ BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const { BitVector Reserved(getNumRegs()); const X86FrameLowering *TFI = getFrameLowering(MF); + // Set the floating point control register as reserved. + Reserved.set(X86::FPCW); + // Set the stack-pointer register and its aliases as reserved. for (MCSubRegIterator I(X86::RSP, this, /*IncludeSelf=*/true); I.isValid(); ++I) diff --git a/llvm/lib/Target/X86/X86RegisterInfo.td b/llvm/lib/Target/X86/X86RegisterInfo.td index aa20273f89abe..6a0538138528b 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.td +++ b/llvm/lib/Target/X86/X86RegisterInfo.td @@ -278,7 +278,7 @@ def K7 : X86Reg<"k7", 7>, DwarfRegNum<[125, 100, 100]>; // pseudo registers, but we still mark them as aliasing FP registers. That // way both kinds can be live without exceeding the stack depth. ST registers // are only live around inline assembly. -def ST0 : X86Reg<"st(0)", 0>, DwarfRegNum<[33, 12, 11]>; +def ST0 : X86Reg<"st", 0>, DwarfRegNum<[33, 12, 11]>; def ST1 : X86Reg<"st(1)", 1>, DwarfRegNum<[34, 13, 12]>; def ST2 : X86Reg<"st(2)", 2>, DwarfRegNum<[35, 14, 13]>; def ST3 : X86Reg<"st(3)", 3>, DwarfRegNum<[36, 15, 14]>; @@ -288,7 +288,10 @@ def ST6 : X86Reg<"st(6)", 6>, DwarfRegNum<[39, 18, 17]>; def ST7 : X86Reg<"st(7)", 7>, DwarfRegNum<[40, 19, 18]>; // Floating-point status word -def FPSW : X86Reg<"fpsw", 0>; +def FPSW : X86Reg<"fpsr", 0>; + +// Floating-point control word +def FPCW : X86Reg<"fpcr", 0>; // Status flags register. // @@ -539,6 +542,9 @@ def RST : RegisterClass<"X86", [f80, f64, f32], 32, (sequence "ST%u", 0, 7)> { let isAllocatable = 0; } +// Helper to allow %st to print as %st(0) when its encoded in the instruction. +def RSTi : RegisterOperand; + // Generic vector registers: VR64 and VR128. // Ensure that float types are declared first - only float is legal on SSE1. def VR64: RegisterClass<"X86", [x86mmx], 64, (sequence "MM%u", 0, 7)>; diff --git a/llvm/test/CodeGen/MIR/X86/memory-operands.mir b/llvm/test/CodeGen/MIR/X86/memory-operands.mir index 2ac7bea2fc9b9..89b28126b9167 100644 --- a/llvm/test/CodeGen/MIR/X86/memory-operands.mir +++ b/llvm/test/CodeGen/MIR/X86/memory-operands.mir @@ -359,8 +359,8 @@ body: | CFI_INSTRUCTION def_cfa_offset 32 LD_F80m $rsp, 1, $noreg, 32, $noreg, implicit-def dead $fpsw ; CHECK: name: stack_psv - ; CHECK: ST_FP80m $rsp, 1, $noreg, 0, $noreg, implicit-def dead $fpsw :: (store 10 into stack, align 16) - ST_FP80m $rsp, 1, _, 0, _, implicit-def dead $fpsw :: (store 10 into stack, align 16) + ; CHECK: ST_FP80m $rsp, 1, $noreg, 0, $noreg, implicit-def dead $fpsw, implicit $fpcw :: (store 10 into stack, align 16) + ST_FP80m $rsp, 1, _, 0, _, implicit-def dead $fpsw, implicit $fpcw :: (store 10 into stack, align 16) CALL64pcrel32 &cosl, csr_64, implicit $rsp, implicit-def $rsp, implicit-def $fp0 $rsp = ADD64ri8 $rsp, 24, implicit-def dead $eflags RETQ diff --git a/llvm/test/CodeGen/X86/and-su.ll b/llvm/test/CodeGen/X86/and-su.ll index 55bfa8def44f2..de384368bfca5 100644 --- a/llvm/test/CodeGen/X86/and-su.ll +++ b/llvm/test/CodeGen/X86/and-su.ll @@ -49,7 +49,7 @@ define fastcc double @bar(i32 %hash, double %x, double %y) nounwind { ; CHECK-NEXT: fchs ; CHECK-NEXT: fxch %st(1) ; CHECK-NEXT: .LBB1_5: # %bb16 -; CHECK-NEXT: faddp %st(1) +; CHECK-NEXT: faddp %st, %st(1) ; CHECK-NEXT: movl %ebp, %esp ; CHECK-NEXT: popl %ebp ; CHECK-NEXT: retl diff --git a/llvm/test/CodeGen/X86/avx512-regcall-NoMask.ll b/llvm/test/CodeGen/X86/avx512-regcall-NoMask.ll index 1136a3a50693e..985860166a3f2 100644 --- a/llvm/test/CodeGen/X86/avx512-regcall-NoMask.ll +++ b/llvm/test/CodeGen/X86/avx512-regcall-NoMask.ll @@ -508,17 +508,17 @@ define x86_regcallcc double @test_CallargRetDouble(double %a) { define x86_regcallcc x86_fp80 @test_argRetf80(x86_fp80 %a0) nounwind { ; X32-LABEL: test_argRetf80: ; X32: # %bb.0: -; X32-NEXT: fadd %st(0), %st(0) +; X32-NEXT: fadd %st, %st(0) ; X32-NEXT: retl ; ; WIN64-LABEL: test_argRetf80: ; WIN64: # %bb.0: -; WIN64-NEXT: fadd %st(0), %st(0) +; WIN64-NEXT: fadd %st, %st(0) ; WIN64-NEXT: retq ; ; LINUXOSX64-LABEL: test_argRetf80: ; LINUXOSX64: # %bb.0: -; LINUXOSX64-NEXT: fadd %st(0), %st(0) +; LINUXOSX64-NEXT: fadd %st, %st(0) ; LINUXOSX64-NEXT: retq %r0 = fadd x86_fp80 %a0, %a0 ret x86_fp80 %r0 @@ -529,9 +529,9 @@ define x86_regcallcc x86_fp80 @test_CallargRetf80(x86_fp80 %a) { ; X32-LABEL: test_CallargRetf80: ; X32: # %bb.0: ; X32-NEXT: pushl %esp -; X32-NEXT: fadd %st(0), %st(0) +; X32-NEXT: fadd %st, %st(0) ; X32-NEXT: calll _test_argRetf80 -; X32-NEXT: fadd %st(0), %st(0) +; X32-NEXT: fadd %st, %st(0) ; X32-NEXT: popl %esp ; X32-NEXT: retl ; @@ -540,9 +540,9 @@ define x86_regcallcc x86_fp80 @test_CallargRetf80(x86_fp80 %a) { ; WIN64-NEXT: pushq %rsp ; WIN64-NEXT: .seh_pushreg 4 ; WIN64-NEXT: .seh_endprologue -; WIN64-NEXT: fadd %st(0), %st(0) +; WIN64-NEXT: fadd %st, %st(0) ; WIN64-NEXT: callq test_argRetf80 -; WIN64-NEXT: fadd %st(0), %st(0) +; WIN64-NEXT: fadd %st, %st(0) ; WIN64-NEXT: popq %rsp ; WIN64-NEXT: retq ; WIN64-NEXT: .seh_handlerdata @@ -554,9 +554,9 @@ define x86_regcallcc x86_fp80 @test_CallargRetf80(x86_fp80 %a) { ; LINUXOSX64-NEXT: pushq %rsp ; LINUXOSX64-NEXT: .cfi_def_cfa_offset 16 ; LINUXOSX64-NEXT: .cfi_offset %rsp, -16 -; LINUXOSX64-NEXT: fadd %st(0), %st(0) +; LINUXOSX64-NEXT: fadd %st, %st(0) ; LINUXOSX64-NEXT: callq test_argRetf80 -; LINUXOSX64-NEXT: fadd %st(0), %st(0) +; LINUXOSX64-NEXT: fadd %st, %st(0) ; LINUXOSX64-NEXT: popq %rsp ; LINUXOSX64-NEXT: .cfi_def_cfa_offset 8 ; LINUXOSX64-NEXT: retq diff --git a/llvm/test/CodeGen/X86/fcmove.ll b/llvm/test/CodeGen/X86/fcmove.ll index 35dbb68117ba2..6bb014858d048 100644 --- a/llvm/test/CodeGen/X86/fcmove.ll +++ b/llvm/test/CodeGen/X86/fcmove.ll @@ -6,7 +6,7 @@ target triple = "x86_64-unknown-unknown" ; Test that we can generate an fcmove, and also that it passes verification. ; CHECK-LABEL: cmove_f -; CHECK: fcmove %st({{[0-7]}}), %st(0) +; CHECK: fcmove %st({{[0-7]}}), %st define x86_fp80 @cmove_f(x86_fp80 %a, x86_fp80 %b, i32 %c) { %test = icmp eq i32 %c, 0 %add = fadd x86_fp80 %a, %b diff --git a/llvm/test/CodeGen/X86/fmf-flags.ll b/llvm/test/CodeGen/X86/fmf-flags.ll index 4fb2040b338d9..bb883e92dc110 100644 --- a/llvm/test/CodeGen/X86/fmf-flags.ll +++ b/llvm/test/CodeGen/X86/fmf-flags.ll @@ -20,7 +20,7 @@ define float @fast_recip_sqrt(float %x) { ; X86-NEXT: flds {{[0-9]+}}(%esp) ; X86-NEXT: fsqrt ; X86-NEXT: fld1 -; X86-NEXT: fdivp %st(1) +; X86-NEXT: fdivp %st, %st(1) ; X86-NEXT: retl %y = call fast float @llvm.sqrt.f32(float %x) %z = fdiv fast float 1.0, %y @@ -95,7 +95,7 @@ define float @not_so_fast_recip_sqrt(float %x) { ; X86-NEXT: flds {{[0-9]+}}(%esp) ; X86-NEXT: fsqrt ; X86-NEXT: fld1 -; X86-NEXT: fdiv %st(1) +; X86-NEXT: fdiv %st(1), %st ; X86-NEXT: fxch %st(1) ; X86-NEXT: fstps sqrt1 ; X86-NEXT: retl diff --git a/llvm/test/CodeGen/X86/fp-cvt.ll b/llvm/test/CodeGen/X86/fp-cvt.ll index ab3d40ddcaa52..71738cb85d2e4 100644 --- a/llvm/test/CodeGen/X86/fp-cvt.ll +++ b/llvm/test/CodeGen/X86/fp-cvt.ll @@ -486,7 +486,7 @@ define i64 @fptoui_i64_fp80(x86_fp80 %a0) nounwind { ; X64-X87-NEXT: xorl %eax, %eax ; X64-X87-NEXT: fxch %st(1) ; X64-X87-NEXT: fucompi %st(2) -; X64-X87-NEXT: fcmovnbe %st(1), %st(0) +; X64-X87-NEXT: fcmovnbe %st(1), %st ; X64-X87-NEXT: fstp %st(1) ; X64-X87-NEXT: fnstcw -{{[0-9]+}}(%rsp) ; X64-X87-NEXT: movzwl -{{[0-9]+}}(%rsp), %ecx @@ -509,7 +509,7 @@ define i64 @fptoui_i64_fp80(x86_fp80 %a0) nounwind { ; X64-SSSE3-NEXT: xorl %eax, %eax ; X64-SSSE3-NEXT: fxch %st(1) ; X64-SSSE3-NEXT: fucompi %st(2) -; X64-SSSE3-NEXT: fcmovnbe %st(1), %st(0) +; X64-SSSE3-NEXT: fcmovnbe %st(1), %st ; X64-SSSE3-NEXT: fstp %st(1) ; X64-SSSE3-NEXT: fisttpll -{{[0-9]+}}(%rsp) ; X64-SSSE3-NEXT: setbe %al @@ -568,7 +568,7 @@ define i64 @fptoui_i64_fp80_ld(x86_fp80 *%a0) nounwind { ; X64-X87-NEXT: xorl %eax, %eax ; X64-X87-NEXT: fxch %st(1) ; X64-X87-NEXT: fucompi %st(2) -; X64-X87-NEXT: fcmovnbe %st(1), %st(0) +; X64-X87-NEXT: fcmovnbe %st(1), %st ; X64-X87-NEXT: fstp %st(1) ; X64-X87-NEXT: fnstcw -{{[0-9]+}}(%rsp) ; X64-X87-NEXT: movzwl -{{[0-9]+}}(%rsp), %ecx @@ -591,7 +591,7 @@ define i64 @fptoui_i64_fp80_ld(x86_fp80 *%a0) nounwind { ; X64-SSSE3-NEXT: xorl %eax, %eax ; X64-SSSE3-NEXT: fxch %st(1) ; X64-SSSE3-NEXT: fucompi %st(2) -; X64-SSSE3-NEXT: fcmovnbe %st(1), %st(0) +; X64-SSSE3-NEXT: fcmovnbe %st(1), %st ; X64-SSSE3-NEXT: fstp %st(1) ; X64-SSSE3-NEXT: fisttpll -{{[0-9]+}}(%rsp) ; X64-SSSE3-NEXT: setbe %al diff --git a/llvm/test/CodeGen/X86/inline-asm-default-clobbers.ll b/llvm/test/CodeGen/X86/inline-asm-default-clobbers.ll new file mode 100644 index 0000000000000..34a77ea5fecdb --- /dev/null +++ b/llvm/test/CodeGen/X86/inline-asm-default-clobbers.ll @@ -0,0 +1,8 @@ +; RUN: llc < %s -mtriple=i686 -stop-after=expand-isel-pseudos | FileCheck %s + +; CHECK: INLINEASM &"", 1, 12, implicit-def early-clobber $df, 12, implicit-def early-clobber $fpsw, 12, implicit-def early-clobber $eflags +define void @foo() { +entry: + call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"() + ret void +} diff --git a/llvm/test/CodeGen/X86/inline-asm-fpstack.ll b/llvm/test/CodeGen/X86/inline-asm-fpstack.ll index 1c36d31c480b5..db6127acb0ae7 100644 --- a/llvm/test/CodeGen/X86/inline-asm-fpstack.ll +++ b/llvm/test/CodeGen/X86/inline-asm-fpstack.ll @@ -75,20 +75,20 @@ define void @test6(double %A, double %B, double %C, double %D, double %E) nounwi ; CHECK-NEXT: fldl {{[0-9]+}}(%esp) ; CHECK-NEXT: fldl {{[0-9]+}}(%esp) ; CHECK-NEXT: ## InlineAsm Start -; CHECK-NEXT: foo %st(0) %st(0) +; CHECK-NEXT: foo %st %st ; CHECK-NEXT: ## InlineAsm End ; CHECK-NEXT: fstp %st(0) ; CHECK-NEXT: ## InlineAsm Start -; CHECK-NEXT: bar %st(1) %st(0) +; CHECK-NEXT: bar %st(1) %st ; CHECK-NEXT: ## InlineAsm End ; CHECK-NEXT: fstp %st(1) ; CHECK-NEXT: fstp %st(0) ; CHECK-NEXT: ## InlineAsm Start -; CHECK-NEXT: baz %st(1) %st(0) +; CHECK-NEXT: baz %st(1) %st ; CHECK-NEXT: ## InlineAsm End ; CHECK-NEXT: fstp %st(0) ; CHECK-NEXT: ## InlineAsm Start -; CHECK-NEXT: baz %st(0) +; CHECK-NEXT: baz %st ; CHECK-NEXT: ## InlineAsm End ; CHECK-NEXT: fstp %st(0) ; CHECK-NEXT: retl @@ -117,10 +117,10 @@ define void @testPR4185() { ; CHECK-NEXT: flds LCPI6_0 ; CHECK-NEXT: fld %st(0) ; CHECK-NEXT: ## InlineAsm Start -; CHECK-NEXT: fistpl %st(0) +; CHECK-NEXT: fistpl %st ; CHECK-NEXT: ## InlineAsm End ; CHECK-NEXT: ## InlineAsm Start -; CHECK-NEXT: fistpl %st(0) +; CHECK-NEXT: fistpl %st ; CHECK-NEXT: ## InlineAsm End ; CHECK-NEXT: retl return: @@ -138,10 +138,10 @@ define void @testPR4185b() { ; CHECK: ## %bb.0: ## %return ; CHECK-NEXT: flds LCPI7_0 ; CHECK-NEXT: ## InlineAsm Start -; CHECK-NEXT: fistl %st(0) +; CHECK-NEXT: fistl %st ; CHECK-NEXT: ## InlineAsm End ; CHECK-NEXT: ## InlineAsm Start -; CHECK-NEXT: fistpl %st(0) +; CHECK-NEXT: fistpl %st ; CHECK-NEXT: ## InlineAsm End ; CHECK-NEXT: retl return: @@ -163,7 +163,7 @@ define void @testPR4459(x86_fp80 %a) { ; CHECK-NEXT: fld %st(0) ; CHECK-NEXT: fxch %st(1) ; CHECK-NEXT: ## InlineAsm Start -; CHECK-NEXT: fistpl %st(0) +; CHECK-NEXT: fistpl %st ; CHECK-NEXT: ## InlineAsm End ; CHECK-NEXT: fstpt (%esp) ; CHECK-NEXT: calll _test3 @@ -191,7 +191,7 @@ define void @testPR4484(x86_fp80 %a) { ; CHECK-NEXT: calll _test1 ; CHECK-NEXT: fldt {{[0-9]+}}(%esp) ## 10-byte Folded Reload ; CHECK-NEXT: ## InlineAsm Start -; CHECK-NEXT: fistpl %st(0) +; CHECK-NEXT: fistpl %st ; CHECK-NEXT: ## InlineAsm End ; CHECK-NEXT: fstpt (%esp) ; CHECK-NEXT: calll _test3 @@ -211,18 +211,18 @@ define void @testPR4485(x86_fp80* %a) { ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax ; CHECK-NEXT: fldt (%eax) ; CHECK-NEXT: flds LCPI10_0 -; CHECK-NEXT: fmul %st(0), %st(1) +; CHECK-NEXT: fmul %st, %st(1) ; CHECK-NEXT: flds LCPI10_1 -; CHECK-NEXT: fmul %st(0), %st(2) +; CHECK-NEXT: fmul %st, %st(2) ; CHECK-NEXT: fxch %st(2) ; CHECK-NEXT: ## InlineAsm Start -; CHECK-NEXT: fistpl %st(0) +; CHECK-NEXT: fistpl %st ; CHECK-NEXT: ## InlineAsm End ; CHECK-NEXT: fldt (%eax) -; CHECK-NEXT: fmulp %st(1) -; CHECK-NEXT: fmulp %st(1) +; CHECK-NEXT: fmulp %st, %st(1) +; CHECK-NEXT: fmulp %st, %st(1) ; CHECK-NEXT: ## InlineAsm Start -; CHECK-NEXT: fistpl %st(0) +; CHECK-NEXT: fistpl %st ; CHECK-NEXT: ## InlineAsm End ; CHECK-NEXT: retl entry: @@ -422,7 +422,7 @@ define i32 @PR10602() nounwind ssp { ; CHECK-NEXT: fld %st(0) ; CHECK-NEXT: fxch %st(1) ; CHECK-NEXT: ## InlineAsm Start -; CHECK-NEXT: fcomi %st(1), %st(0); pushf; pop %eax +; CHECK-NEXT: fcomi %st(1), %st; pushf; pop %eax ; CHECK-NEXT: ## InlineAsm End ; CHECK-NEXT: fstp %st(0) ; CHECK-NEXT: fstp %st(0) @@ -505,9 +505,9 @@ define double @test_operand_rewrite() { ; CHECK-LABEL: test_operand_rewrite: ; CHECK: ## %bb.0: ## %entry ; CHECK-NEXT: ## InlineAsm Start -; CHECK-NEXT: foo %st(0), %st(1) +; CHECK-NEXT: foo %st, %st(1) ; CHECK-NEXT: ## InlineAsm End -; CHECK-NEXT: fsubp %st(1) +; CHECK-NEXT: fsubp %st, %st(1) ; CHECK-NEXT: retl entry: %0 = tail call { double, double } asm sideeffect "foo $0, $1", "={st},={st(1)},~{dirflag},~{fpsr},~{flags}"() diff --git a/llvm/test/CodeGen/X86/ipra-reg-usage.ll b/llvm/test/CodeGen/X86/ipra-reg-usage.ll index 3e57ef2184426..2a557f2902a21 100644 --- a/llvm/test/CodeGen/X86/ipra-reg-usage.ll +++ b/llvm/test/CodeGen/X86/ipra-reg-usage.ll @@ -3,7 +3,7 @@ target triple = "x86_64-unknown-unknown" declare void @bar1() define preserve_allcc void @foo()#0 { -; CHECK: foo Clobbered Registers: $cs $df $ds $eflags $eip $eiz $es $fpsw $fs $gs $hip $ip $rip $riz $ss $ssp $bnd0 $bnd1 $bnd2 $bnd3 $cr0 $cr1 $cr2 $cr3 $cr4 $cr5 $cr6 $cr7 $cr8 $cr9 $cr10 $cr11 $cr12 $cr13 $cr14 $cr15 $dr0 $dr1 $dr2 $dr3 $dr4 $dr5 $dr6 $dr7 $dr8 $dr9 $dr10 $dr11 $dr12 $dr13 $dr14 $dr15 $fp0 $fp1 $fp2 $fp3 $fp4 $fp5 $fp6 $fp7 $k0 $k1 $k2 $k3 $k4 $k5 $k6 $k7 $mm0 $mm1 $mm2 $mm3 $mm4 $mm5 $mm6 $mm7 $r11 $st0 $st1 $st2 $st3 $st4 $st5 $st6 $st7 $xmm16 $xmm17 $xmm18 $xmm19 $xmm20 $xmm21 $xmm22 $xmm23 $xmm24 $xmm25 $xmm26 $xmm27 $xmm28 $xmm29 $xmm30 $xmm31 $ymm0 $ymm1 $ymm2 $ymm3 $ymm4 $ymm5 $ymm6 $ymm7 $ymm8 $ymm9 $ymm10 $ymm11 $ymm12 $ymm13 $ymm14 $ymm15 $ymm16 $ymm17 $ymm18 $ymm19 $ymm20 $ymm21 $ymm22 $ymm23 $ymm24 $ymm25 $ymm26 $ymm27 $ymm28 $ymm29 $ymm30 $ymm31 $zmm0 $zmm1 $zmm2 $zmm3 $zmm4 $zmm5 $zmm6 $zmm7 $zmm8 $zmm9 $zmm10 $zmm11 $zmm12 $zmm13 $zmm14 $zmm15 $zmm16 $zmm17 $zmm18 $zmm19 $zmm20 $zmm21 $zmm22 $zmm23 $zmm24 $zmm25 $zmm26 $zmm27 $zmm28 $zmm29 $zmm30 $zmm31 $r11b $r11bh $r11d $r11w $r11wh +; CHECK: foo Clobbered Registers: $cs $df $ds $eflags $eip $eiz $es $fpcw $fpsw $fs $gs $hip $ip $rip $riz $ss $ssp $bnd0 $bnd1 $bnd2 $bnd3 $cr0 $cr1 $cr2 $cr3 $cr4 $cr5 $cr6 $cr7 $cr8 $cr9 $cr10 $cr11 $cr12 $cr13 $cr14 $cr15 $dr0 $dr1 $dr2 $dr3 $dr4 $dr5 $dr6 $dr7 $dr8 $dr9 $dr10 $dr11 $dr12 $dr13 $dr14 $dr15 $fp0 $fp1 $fp2 $fp3 $fp4 $fp5 $fp6 $fp7 $k0 $k1 $k2 $k3 $k4 $k5 $k6 $k7 $mm0 $mm1 $mm2 $mm3 $mm4 $mm5 $mm6 $mm7 $r11 $st0 $st1 $st2 $st3 $st4 $st5 $st6 $st7 $xmm16 $xmm17 $xmm18 $xmm19 $xmm20 $xmm21 $xmm22 $xmm23 $xmm24 $xmm25 $xmm26 $xmm27 $xmm28 $xmm29 $xmm30 $xmm31 $ymm0 $ymm1 $ymm2 $ymm3 $ymm4 $ymm5 $ymm6 $ymm7 $ymm8 $ymm9 $ymm10 $ymm11 $ymm12 $ymm13 $ymm14 $ymm15 $ymm16 $ymm17 $ymm18 $ymm19 $ymm20 $ymm21 $ymm22 $ymm23 $ymm24 $ymm25 $ymm26 $ymm27 $ymm28 $ymm29 $ymm30 $ymm31 $zmm0 $zmm1 $zmm2 $zmm3 $zmm4 $zmm5 $zmm6 $zmm7 $zmm8 $zmm9 $zmm10 $zmm11 $zmm12 $zmm13 $zmm14 $zmm15 $zmm16 $zmm17 $zmm18 $zmm19 $zmm20 $zmm21 $zmm22 $zmm23 $zmm24 $zmm25 $zmm26 $zmm27 $zmm28 $zmm29 $zmm30 $zmm31 $r11b $r11bh $r11d $r11w $r11wh call void @bar1() call void @bar2() ret void diff --git a/llvm/test/CodeGen/X86/pr13577.ll b/llvm/test/CodeGen/X86/pr13577.ll index e0e90f81bc42c..3f9e2f953bae3 100644 --- a/llvm/test/CodeGen/X86/pr13577.ll +++ b/llvm/test/CodeGen/X86/pr13577.ll @@ -14,7 +14,7 @@ define x86_fp80 @foo(x86_fp80 %a) { ; CHECK-NEXT: testb $-128, -{{[0-9]+}}(%rsp) ; CHECK-NEXT: flds {{.*}}(%rip) ; CHECK-NEXT: flds {{.*}}(%rip) -; CHECK-NEXT: fcmovne %st(1), %st(0) +; CHECK-NEXT: fcmovne %st(1), %st ; CHECK-NEXT: fstp %st(1) ; CHECK-NEXT: retq %1 = tail call x86_fp80 @copysignl(x86_fp80 0xK7FFF8000000000000000, x86_fp80 %a) nounwind readnone diff --git a/llvm/test/CodeGen/X86/pr33349.ll b/llvm/test/CodeGen/X86/pr33349.ll index 63edae044f87c..9aa28384f4e81 100644 --- a/llvm/test/CodeGen/X86/pr33349.ll +++ b/llvm/test/CodeGen/X86/pr33349.ll @@ -19,18 +19,18 @@ target triple = "x86_64-unknown-linux-gnu" ; KNL-NEXT: fld1 ; KNL-NEXT: fldz ; KNL-NEXT: fld %st(0) -; KNL-NEXT: fcmovne %st(2), %st(0) +; KNL-NEXT: fcmovne %st(2), %st ; KNL-NEXT: testb $1, %cl ; KNL-NEXT: fld %st(1) -; KNL-NEXT: fcmovne %st(3), %st(0) +; KNL-NEXT: fcmovne %st(3), %st ; KNL-NEXT: kmovw %k2, %eax ; KNL-NEXT: testb $1, %al ; KNL-NEXT: fld %st(2) -; KNL-NEXT: fcmovne %st(4), %st(0) +; KNL-NEXT: fcmovne %st(4), %st ; KNL-NEXT: kmovw %k0, %eax ; KNL-NEXT: testb $1, %al ; KNL-NEXT: fxch %st(3) -; KNL-NEXT: fcmovne %st(4), %st(0) +; KNL-NEXT: fcmovne %st(4), %st ; KNL-NEXT: fstp %st(4) ; KNL-NEXT: fxch %st(3) ; KNL-NEXT: fstpt (%rdi) @@ -55,18 +55,18 @@ target triple = "x86_64-unknown-linux-gnu" ; SKX-NEXT: fld1 ; SKX-NEXT: fldz ; SKX-NEXT: fld %st(0) -; SKX-NEXT: fcmovne %st(2), %st(0) +; SKX-NEXT: fcmovne %st(2), %st ; SKX-NEXT: testb $1, %cl ; SKX-NEXT: fld %st(1) -; SKX-NEXT: fcmovne %st(3), %st(0) +; SKX-NEXT: fcmovne %st(3), %st ; SKX-NEXT: kmovd %k2, %eax ; SKX-NEXT: testb $1, %al ; SKX-NEXT: fld %st(2) -; SKX-NEXT: fcmovne %st(4), %st(0) +; SKX-NEXT: fcmovne %st(4), %st ; SKX-NEXT: kmovd %k0, %eax ; SKX-NEXT: testb $1, %al ; SKX-NEXT: fxch %st(3) -; SKX-NEXT: fcmovne %st(4), %st(0) +; SKX-NEXT: fcmovne %st(4), %st ; SKX-NEXT: fstp %st(4) ; SKX-NEXT: fxch %st(3) ; SKX-NEXT: fstpt (%rdi) diff --git a/llvm/test/CodeGen/X86/pr34080.ll b/llvm/test/CodeGen/X86/pr34080.ll index a709a4840e530..0b23ab7d4b5d7 100644 --- a/llvm/test/CodeGen/X86/pr34080.ll +++ b/llvm/test/CodeGen/X86/pr34080.ll @@ -27,7 +27,7 @@ define void @_Z1fe(x86_fp80 %z) local_unnamed_addr #0 { ; SSE2-NEXT: movsd %xmm0, -32(%rbp) ; SSE2-NEXT: fsubl -32(%rbp) ; SSE2-NEXT: flds {{.*}}(%rip) -; SSE2-NEXT: fmul %st(0), %st(1) +; SSE2-NEXT: fmul %st, %st(1) ; SSE2-NEXT: fnstcw -2(%rbp) ; SSE2-NEXT: movzwl -2(%rbp), %eax ; SSE2-NEXT: movw $3199, -2(%rbp) ## imm = 0xC7F @@ -41,7 +41,7 @@ define void @_Z1fe(x86_fp80 %z) local_unnamed_addr #0 { ; SSE2-NEXT: movsd %xmm0, -56(%rbp) ; SSE2-NEXT: movsd %xmm0, -24(%rbp) ; SSE2-NEXT: fsubl -24(%rbp) -; SSE2-NEXT: fmulp %st(1) +; SSE2-NEXT: fmulp %st, %st(1) ; SSE2-NEXT: fstpl -48(%rbp) ; SSE2-NEXT: popq %rbp ; SSE2-NEXT: retq @@ -65,12 +65,12 @@ define void @_Z1fe(x86_fp80 %z) local_unnamed_addr #0 { ; SSE2-SCHEDULE-NEXT: movsd %xmm0, -64(%rbp) ; SSE2-SCHEDULE-NEXT: movsd %xmm0, -32(%rbp) ; SSE2-SCHEDULE-NEXT: fsubl -32(%rbp) -; SSE2-SCHEDULE-NEXT: fnstcw -2(%rbp) ; SSE2-SCHEDULE-NEXT: flds {{.*}}(%rip) +; SSE2-SCHEDULE-NEXT: fnstcw -2(%rbp) +; SSE2-SCHEDULE-NEXT: fmul %st, %st(1) ; SSE2-SCHEDULE-NEXT: movzwl -2(%rbp), %eax ; SSE2-SCHEDULE-NEXT: movw $3199, -2(%rbp) ## imm = 0xC7F ; SSE2-SCHEDULE-NEXT: fldcw -2(%rbp) -; SSE2-SCHEDULE-NEXT: fmul %st(0), %st(1) ; SSE2-SCHEDULE-NEXT: movw %ax, -2(%rbp) ; SSE2-SCHEDULE-NEXT: fxch %st(1) ; SSE2-SCHEDULE-NEXT: fistl -12(%rbp) @@ -80,7 +80,7 @@ define void @_Z1fe(x86_fp80 %z) local_unnamed_addr #0 { ; SSE2-SCHEDULE-NEXT: movsd %xmm0, -56(%rbp) ; SSE2-SCHEDULE-NEXT: movsd %xmm0, -24(%rbp) ; SSE2-SCHEDULE-NEXT: fsubl -24(%rbp) -; SSE2-SCHEDULE-NEXT: fmulp %st(1) +; SSE2-SCHEDULE-NEXT: fmulp %st, %st(1) ; SSE2-SCHEDULE-NEXT: fstpl -48(%rbp) ; SSE2-SCHEDULE-NEXT: popq %rbp ; SSE2-SCHEDULE-NEXT: retq @@ -100,7 +100,7 @@ define void @_Z1fe(x86_fp80 %z) local_unnamed_addr #0 { ; SSE3-NEXT: movsd %xmm0, -24(%rbp) ; SSE3-NEXT: fsubl -24(%rbp) ; SSE3-NEXT: flds {{.*}}(%rip) -; SSE3-NEXT: fmul %st(0), %st(1) +; SSE3-NEXT: fmul %st, %st(1) ; SSE3-NEXT: fld %st(1) ; SSE3-NEXT: fisttpl -8(%rbp) ; SSE3-NEXT: xorps %xmm0, %xmm0 @@ -109,7 +109,7 @@ define void @_Z1fe(x86_fp80 %z) local_unnamed_addr #0 { ; SSE3-NEXT: movsd %xmm0, -16(%rbp) ; SSE3-NEXT: fxch %st(1) ; SSE3-NEXT: fsubl -16(%rbp) -; SSE3-NEXT: fmulp %st(1) +; SSE3-NEXT: fmulp %st, %st(1) ; SSE3-NEXT: fstpl -32(%rbp) ; SSE3-NEXT: popq %rbp ; SSE3-NEXT: retq @@ -129,7 +129,7 @@ define void @_Z1fe(x86_fp80 %z) local_unnamed_addr #0 { ; AVX-NEXT: vmovsd %xmm0, -24(%rbp) ; AVX-NEXT: fsubl -24(%rbp) ; AVX-NEXT: flds {{.*}}(%rip) -; AVX-NEXT: fmul %st(0), %st(1) +; AVX-NEXT: fmul %st, %st(1) ; AVX-NEXT: fld %st(1) ; AVX-NEXT: fisttpl -8(%rbp) ; AVX-NEXT: vcvtsi2sdl -8(%rbp), %xmm1, %xmm0 @@ -137,7 +137,7 @@ define void @_Z1fe(x86_fp80 %z) local_unnamed_addr #0 { ; AVX-NEXT: vmovsd %xmm0, -16(%rbp) ; AVX-NEXT: fxch %st(1) ; AVX-NEXT: fsubl -16(%rbp) -; AVX-NEXT: fmulp %st(1) +; AVX-NEXT: fmulp %st, %st(1) ; AVX-NEXT: fstpl -32(%rbp) ; AVX-NEXT: popq %rbp ; AVX-NEXT: retq diff --git a/llvm/test/CodeGen/X86/pr34177.ll b/llvm/test/CodeGen/X86/pr34177.ll index 3fe56277fb4b3..f6b8dec3c3b39 100644 --- a/llvm/test/CodeGen/X86/pr34177.ll +++ b/llvm/test/CodeGen/X86/pr34177.ll @@ -20,17 +20,17 @@ define void @test(<4x i64> %a, <4 x x86_fp80> %b, <8 x x86_fp80>* %c) local_unna ; CHECK-NEXT: fld1 ; CHECK-NEXT: fldz ; CHECK-NEXT: fld %st(0) -; CHECK-NEXT: fcmove %st(2), %st(0) +; CHECK-NEXT: fcmove %st(2), %st ; CHECK-NEXT: cmpq %rax, %rsi ; CHECK-NEXT: fld %st(1) -; CHECK-NEXT: fcmove %st(3), %st(0) +; CHECK-NEXT: fcmove %st(3), %st ; CHECK-NEXT: cmpq %rdx, %r9 ; CHECK-NEXT: fld %st(2) -; CHECK-NEXT: fcmove %st(4), %st(0) +; CHECK-NEXT: fcmove %st(4), %st ; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: cmpq %r8, %rax ; CHECK-NEXT: fxch %st(3) -; CHECK-NEXT: fcmove %st(4), %st(0) +; CHECK-NEXT: fcmove %st(4), %st ; CHECK-NEXT: fstp %st(4) ; CHECK-NEXT: fldt {{[0-9]+}}(%rsp) ; CHECK-NEXT: fstpt 70(%rdi) @@ -40,15 +40,15 @@ define void @test(<4x i64> %a, <4 x x86_fp80> %b, <8 x x86_fp80>* %c) local_unna ; CHECK-NEXT: fstpt 30(%rdi) ; CHECK-NEXT: fldt {{[0-9]+}}(%rsp) ; CHECK-NEXT: fstpt 10(%rdi) -; CHECK-NEXT: fadd %st(0), %st(0) +; CHECK-NEXT: fadd %st, %st(0) ; CHECK-NEXT: fstpt 60(%rdi) ; CHECK-NEXT: fxch %st(1) -; CHECK-NEXT: fadd %st(0), %st(0) +; CHECK-NEXT: fadd %st, %st(0) ; CHECK-NEXT: fstpt 40(%rdi) ; CHECK-NEXT: fxch %st(1) -; CHECK-NEXT: fadd %st(0), %st(0) +; CHECK-NEXT: fadd %st, %st(0) ; CHECK-NEXT: fstpt 20(%rdi) -; CHECK-NEXT: fadd %st(0), %st(0) +; CHECK-NEXT: fadd %st, %st(0) ; CHECK-NEXT: fstpt (%rdi) %1 = icmp eq <4 x i64> , %a %2 = select <4 x i1> %1, <4 x x86_fp80> , <4 x x86_fp80> zeroinitializer diff --git a/llvm/test/CodeGen/X86/pr40529.ll b/llvm/test/CodeGen/X86/pr40529.ll new file mode 100644 index 0000000000000..9520ac22d7491 --- /dev/null +++ b/llvm/test/CodeGen/X86/pr40529.ll @@ -0,0 +1,43 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-unknown-linux -mcpu=x86-64 | FileCheck %s + +define x86_fp80 @rem_pio2l_min(x86_fp80 %z) { +; CHECK-LABEL: rem_pio2l_min: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fnstcw -{{[0-9]+}}(%rsp) +; CHECK-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax +; CHECK-NEXT: movw $3199, -{{[0-9]+}}(%rsp) # imm = 0xC7F +; CHECK-NEXT: fldcw -{{[0-9]+}}(%rsp) +; CHECK-NEXT: fldt {{[0-9]+}}(%rsp) +; CHECK-NEXT: movw %ax, -{{[0-9]+}}(%rsp) +; CHECK-NEXT: fistl -{{[0-9]+}}(%rsp) +; CHECK-NEXT: fldcw -{{[0-9]+}}(%rsp) +; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %eax +; CHECK-NEXT: movl %eax, -{{[0-9]+}}(%rsp) +; CHECK-NEXT: fisubl -{{[0-9]+}}(%rsp) +; CHECK-NEXT: flds {{.*}}(%rip) +; CHECK-NEXT: fnstcw -{{[0-9]+}}(%rsp) +; CHECK-NEXT: fmul %st, %st(1) +; CHECK-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax +; CHECK-NEXT: movw $3199, -{{[0-9]+}}(%rsp) # imm = 0xC7F +; CHECK-NEXT: fldcw -{{[0-9]+}}(%rsp) +; CHECK-NEXT: movw %ax, -{{[0-9]+}}(%rsp) +; CHECK-NEXT: fxch %st(1) +; CHECK-NEXT: fistl -{{[0-9]+}}(%rsp) +; CHECK-NEXT: fldcw -{{[0-9]+}}(%rsp) +; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %eax +; CHECK-NEXT: movl %eax, -{{[0-9]+}}(%rsp) +; CHECK-NEXT: fisubl -{{[0-9]+}}(%rsp) +; CHECK-NEXT: fmulp %st, %st(1) +; CHECK-NEXT: retq +entry: + %conv = fptosi x86_fp80 %z to i32 + %conv1 = sitofp i32 %conv to x86_fp80 + %sub = fsub x86_fp80 %z, %conv1 + %mul = fmul x86_fp80 %sub, 0xK40178000000000000000 + %conv2 = fptosi x86_fp80 %mul to i32 + %conv3 = sitofp i32 %conv2 to x86_fp80 + %sub4 = fsub x86_fp80 %mul, %conv3 + %mul5 = fmul x86_fp80 %sub4, 0xK40178000000000000000 + ret x86_fp80 %mul5 +} diff --git a/llvm/test/CodeGen/X86/scalar-fp-to-i64.ll b/llvm/test/CodeGen/X86/scalar-fp-to-i64.ll index 7ed61f8fdc7d2..92361efa49fac 100644 --- a/llvm/test/CodeGen/X86/scalar-fp-to-i64.ll +++ b/llvm/test/CodeGen/X86/scalar-fp-to-i64.ll @@ -1028,7 +1028,7 @@ define i64 @x_to_u64(x86_fp80 %a) nounwind { ; AVX512_32_WIN-NEXT: xorl %edx, %edx ; AVX512_32_WIN-NEXT: fxch %st(1) ; AVX512_32_WIN-NEXT: fucompi %st(2) -; AVX512_32_WIN-NEXT: fcmovnbe %st(1), %st(0) +; AVX512_32_WIN-NEXT: fcmovnbe %st(1), %st ; AVX512_32_WIN-NEXT: fstp %st(1) ; AVX512_32_WIN-NEXT: fisttpll (%esp) ; AVX512_32_WIN-NEXT: setbe %dl @@ -1049,7 +1049,7 @@ define i64 @x_to_u64(x86_fp80 %a) nounwind { ; AVX512_32_LIN-NEXT: xorl %edx, %edx ; AVX512_32_LIN-NEXT: fxch %st(1) ; AVX512_32_LIN-NEXT: fucompi %st(2) -; AVX512_32_LIN-NEXT: fcmovnbe %st(1), %st(0) +; AVX512_32_LIN-NEXT: fcmovnbe %st(1), %st ; AVX512_32_LIN-NEXT: fstp %st(1) ; AVX512_32_LIN-NEXT: fisttpll (%esp) ; AVX512_32_LIN-NEXT: setbe %dl @@ -1069,7 +1069,7 @@ define i64 @x_to_u64(x86_fp80 %a) nounwind { ; AVX512_64_WIN-NEXT: xorl %ecx, %ecx ; AVX512_64_WIN-NEXT: fxch %st(1) ; AVX512_64_WIN-NEXT: fucompi %st(2) -; AVX512_64_WIN-NEXT: fcmovnbe %st(1), %st(0) +; AVX512_64_WIN-NEXT: fcmovnbe %st(1), %st ; AVX512_64_WIN-NEXT: fstp %st(1) ; AVX512_64_WIN-NEXT: fisttpll (%rsp) ; AVX512_64_WIN-NEXT: setbe %cl @@ -1090,7 +1090,7 @@ define i64 @x_to_u64(x86_fp80 %a) nounwind { ; AVX512_64_LIN-NEXT: xorl %ecx, %ecx ; AVX512_64_LIN-NEXT: fxch %st(1) ; AVX512_64_LIN-NEXT: fucompi %st(2) -; AVX512_64_LIN-NEXT: fcmovnbe %st(1), %st(0) +; AVX512_64_LIN-NEXT: fcmovnbe %st(1), %st ; AVX512_64_LIN-NEXT: fstp %st(1) ; AVX512_64_LIN-NEXT: fisttpll -{{[0-9]+}}(%rsp) ; AVX512_64_LIN-NEXT: setbe %cl @@ -1114,7 +1114,7 @@ define i64 @x_to_u64(x86_fp80 %a) nounwind { ; SSE3_32_WIN-NEXT: xorl %edx, %edx ; SSE3_32_WIN-NEXT: fxch %st(1) ; SSE3_32_WIN-NEXT: fucompi %st(2) -; SSE3_32_WIN-NEXT: fcmovnbe %st(1), %st(0) +; SSE3_32_WIN-NEXT: fcmovnbe %st(1), %st ; SSE3_32_WIN-NEXT: fstp %st(1) ; SSE3_32_WIN-NEXT: fisttpll (%esp) ; SSE3_32_WIN-NEXT: setbe %dl @@ -1135,7 +1135,7 @@ define i64 @x_to_u64(x86_fp80 %a) nounwind { ; SSE3_32_LIN-NEXT: xorl %edx, %edx ; SSE3_32_LIN-NEXT: fxch %st(1) ; SSE3_32_LIN-NEXT: fucompi %st(2) -; SSE3_32_LIN-NEXT: fcmovnbe %st(1), %st(0) +; SSE3_32_LIN-NEXT: fcmovnbe %st(1), %st ; SSE3_32_LIN-NEXT: fstp %st(1) ; SSE3_32_LIN-NEXT: fisttpll (%esp) ; SSE3_32_LIN-NEXT: setbe %dl @@ -1155,7 +1155,7 @@ define i64 @x_to_u64(x86_fp80 %a) nounwind { ; SSE3_64_WIN-NEXT: xorl %eax, %eax ; SSE3_64_WIN-NEXT: fxch %st(1) ; SSE3_64_WIN-NEXT: fucompi %st(2) -; SSE3_64_WIN-NEXT: fcmovnbe %st(1), %st(0) +; SSE3_64_WIN-NEXT: fcmovnbe %st(1), %st ; SSE3_64_WIN-NEXT: fstp %st(1) ; SSE3_64_WIN-NEXT: fisttpll (%rsp) ; SSE3_64_WIN-NEXT: setbe %al @@ -1173,7 +1173,7 @@ define i64 @x_to_u64(x86_fp80 %a) nounwind { ; SSE3_64_LIN-NEXT: xorl %eax, %eax ; SSE3_64_LIN-NEXT: fxch %st(1) ; SSE3_64_LIN-NEXT: fucompi %st(2) -; SSE3_64_LIN-NEXT: fcmovnbe %st(1), %st(0) +; SSE3_64_LIN-NEXT: fcmovnbe %st(1), %st ; SSE3_64_LIN-NEXT: fstp %st(1) ; SSE3_64_LIN-NEXT: fisttpll -{{[0-9]+}}(%rsp) ; SSE3_64_LIN-NEXT: setbe %al @@ -1194,7 +1194,7 @@ define i64 @x_to_u64(x86_fp80 %a) nounwind { ; SSE2_32_WIN-NEXT: xorl %edx, %edx ; SSE2_32_WIN-NEXT: fxch %st(1) ; SSE2_32_WIN-NEXT: fucompi %st(2) -; SSE2_32_WIN-NEXT: fcmovnbe %st(1), %st(0) +; SSE2_32_WIN-NEXT: fcmovnbe %st(1), %st ; SSE2_32_WIN-NEXT: fstp %st(1) ; SSE2_32_WIN-NEXT: fnstcw {{[0-9]+}}(%esp) ; SSE2_32_WIN-NEXT: movzwl {{[0-9]+}}(%esp), %eax @@ -1221,7 +1221,7 @@ define i64 @x_to_u64(x86_fp80 %a) nounwind { ; SSE2_32_LIN-NEXT: xorl %edx, %edx ; SSE2_32_LIN-NEXT: fxch %st(1) ; SSE2_32_LIN-NEXT: fucompi %st(2) -; SSE2_32_LIN-NEXT: fcmovnbe %st(1), %st(0) +; SSE2_32_LIN-NEXT: fcmovnbe %st(1), %st ; SSE2_32_LIN-NEXT: fstp %st(1) ; SSE2_32_LIN-NEXT: fnstcw {{[0-9]+}}(%esp) ; SSE2_32_LIN-NEXT: movzwl {{[0-9]+}}(%esp), %eax @@ -1247,7 +1247,7 @@ define i64 @x_to_u64(x86_fp80 %a) nounwind { ; SSE2_64_WIN-NEXT: xorl %eax, %eax ; SSE2_64_WIN-NEXT: fxch %st(1) ; SSE2_64_WIN-NEXT: fucompi %st(2) -; SSE2_64_WIN-NEXT: fcmovnbe %st(1), %st(0) +; SSE2_64_WIN-NEXT: fcmovnbe %st(1), %st ; SSE2_64_WIN-NEXT: fstp %st(1) ; SSE2_64_WIN-NEXT: fnstcw {{[0-9]+}}(%rsp) ; SSE2_64_WIN-NEXT: movzwl {{[0-9]+}}(%rsp), %ecx @@ -1271,7 +1271,7 @@ define i64 @x_to_u64(x86_fp80 %a) nounwind { ; SSE2_64_LIN-NEXT: xorl %eax, %eax ; SSE2_64_LIN-NEXT: fxch %st(1) ; SSE2_64_LIN-NEXT: fucompi %st(2) -; SSE2_64_LIN-NEXT: fcmovnbe %st(1), %st(0) +; SSE2_64_LIN-NEXT: fcmovnbe %st(1), %st ; SSE2_64_LIN-NEXT: fstp %st(1) ; SSE2_64_LIN-NEXT: fnstcw -{{[0-9]+}}(%rsp) ; SSE2_64_LIN-NEXT: movzwl -{{[0-9]+}}(%rsp), %ecx diff --git a/llvm/test/CodeGen/X86/select.ll b/llvm/test/CodeGen/X86/select.ll index 947c95137206d..9429e1854d44c 100644 --- a/llvm/test/CodeGen/X86/select.ll +++ b/llvm/test/CodeGen/X86/select.ll @@ -293,25 +293,25 @@ define void @test6(i32 %C, <4 x float>* %A, <4 x float>* %B) nounwind { ; ATHLON-NEXT: flds 4(%ecx) ; ATHLON-NEXT: flds (%ecx) ; ATHLON-NEXT: flds (%eax) -; ATHLON-NEXT: fmul %st(0), %st(0) +; ATHLON-NEXT: fmul %st, %st(0) ; ATHLON-NEXT: cmpl $0, {{[0-9]+}}(%esp) ; ATHLON-NEXT: fxch %st(1) -; ATHLON-NEXT: fcmove %st(1), %st(0) +; ATHLON-NEXT: fcmove %st(1), %st ; ATHLON-NEXT: fstp %st(1) ; ATHLON-NEXT: flds 4(%eax) -; ATHLON-NEXT: fmul %st(0), %st(0) +; ATHLON-NEXT: fmul %st, %st(0) ; ATHLON-NEXT: fxch %st(2) -; ATHLON-NEXT: fcmove %st(2), %st(0) +; ATHLON-NEXT: fcmove %st(2), %st ; ATHLON-NEXT: fstp %st(2) ; ATHLON-NEXT: flds 8(%eax) -; ATHLON-NEXT: fmul %st(0), %st(0) +; ATHLON-NEXT: fmul %st, %st(0) ; ATHLON-NEXT: fxch %st(3) -; ATHLON-NEXT: fcmove %st(3), %st(0) +; ATHLON-NEXT: fcmove %st(3), %st ; ATHLON-NEXT: fstp %st(3) ; ATHLON-NEXT: flds 12(%eax) -; ATHLON-NEXT: fmul %st(0), %st(0) +; ATHLON-NEXT: fmul %st, %st(0) ; ATHLON-NEXT: fxch %st(4) -; ATHLON-NEXT: fcmove %st(4), %st(0) +; ATHLON-NEXT: fcmove %st(4), %st ; ATHLON-NEXT: fstp %st(4) ; ATHLON-NEXT: fxch %st(3) ; ATHLON-NEXT: fstps 12(%ecx) @@ -332,13 +332,13 @@ define void @test6(i32 %C, <4 x float>* %A, <4 x float>* %B) nounwind { ; MCU-NEXT: flds 4(%ecx) ; MCU-NEXT: flds 8(%ecx) ; MCU-NEXT: flds 12(%ecx) -; MCU-NEXT: fmul %st(0), %st(0) +; MCU-NEXT: fmul %st, %st(0) ; MCU-NEXT: fxch %st(1) -; MCU-NEXT: fmul %st(0), %st(0) +; MCU-NEXT: fmul %st, %st(0) ; MCU-NEXT: fxch %st(2) -; MCU-NEXT: fmul %st(0), %st(0) +; MCU-NEXT: fmul %st, %st(0) ; MCU-NEXT: fxch %st(3) -; MCU-NEXT: fmul %st(0), %st(0) +; MCU-NEXT: fmul %st, %st(0) ; MCU-NEXT: testl %eax, %eax ; MCU-NEXT: flds (%edx) ; MCU-NEXT: je .LBB5_2 diff --git a/llvm/test/CodeGen/X86/sincos-opt.ll b/llvm/test/CodeGen/X86/sincos-opt.ll index b4330ea58ea5a..b64450863427b 100644 --- a/llvm/test/CodeGen/X86/sincos-opt.ll +++ b/llvm/test/CodeGen/X86/sincos-opt.ll @@ -115,13 +115,13 @@ entry: ; GNU_SINCOS: callq sincosl ; GNU_SINCOS: fldt 16(%rsp) ; GNU_SINCOS: fldt 32(%rsp) -; GNU_SINCOS: faddp %st(1) +; GNU_SINCOS: faddp %st, %st(1) ; GNU_SINCOS_FASTMATH-LABEL: test3: ; GNU_SINCOS_FASTMATH: callq sincosl ; GNU_SINCOS_FASTMATH: fldt 16(%{{[re]}}sp) ; GNU_SINCOS_FASTMATH: fldt 32(%{{[re]}}sp) -; GNU_SINCOS_FASTMATH: faddp %st(1) +; GNU_SINCOS_FASTMATH: faddp %st, %st(1) %call = tail call x86_fp80 @sinl(x86_fp80 %x) readnone %call1 = tail call x86_fp80 @cosl(x86_fp80 %x) readnone %add = fadd x86_fp80 %call, %call1 diff --git a/llvm/test/CodeGen/X86/x87-schedule.ll b/llvm/test/CodeGen/X86/x87-schedule.ll index 1921f8c75a3d1..599f313b13025 100644 --- a/llvm/test/CodeGen/X86/x87-schedule.ll +++ b/llvm/test/CodeGen/X86/x87-schedule.ll @@ -180,8 +180,8 @@ define void @test_fadd(float *%a0, double *%a1) optsize { ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %eax ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %ecx ; GENERIC-NEXT: #APP -; GENERIC-NEXT: fadd %st(0), %st(1) -; GENERIC-NEXT: fadd %st(2) +; GENERIC-NEXT: fadd %st, %st(1) +; GENERIC-NEXT: fadd %st(2), %st ; GENERIC-NEXT: fadds (%ecx) ; GENERIC-NEXT: faddl (%eax) ; GENERIC-NEXT: #NO_APP @@ -192,8 +192,8 @@ define void @test_fadd(float *%a0, double *%a1) optsize { ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [1:1.00] ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [1:1.00] ; ATOM-NEXT: #APP -; ATOM-NEXT: fadd %st(0), %st(1) # sched: [5:5.00] -; ATOM-NEXT: fadd %st(2) # sched: [5:5.00] +; ATOM-NEXT: fadd %st, %st(1) # sched: [5:5.00] +; ATOM-NEXT: fadd %st(2), %st # sched: [5:5.00] ; ATOM-NEXT: fadds (%ecx) # sched: [5:5.00] ; ATOM-NEXT: faddl (%eax) # sched: [5:5.00] ; ATOM-NEXT: #NO_APP @@ -204,8 +204,8 @@ define void @test_fadd(float *%a0, double *%a1) optsize { ; SLM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [3:1.00] ; SLM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [3:1.00] ; SLM-NEXT: #APP -; SLM-NEXT: fadd %st(0), %st(1) # sched: [3:1.00] -; SLM-NEXT: fadd %st(2) # sched: [3:1.00] +; SLM-NEXT: fadd %st, %st(1) # sched: [3:1.00] +; SLM-NEXT: fadd %st(2), %st # sched: [3:1.00] ; SLM-NEXT: fadds (%ecx) # sched: [6:1.00] ; SLM-NEXT: faddl (%eax) # sched: [6:1.00] ; SLM-NEXT: #NO_APP @@ -216,8 +216,8 @@ define void @test_fadd(float *%a0, double *%a1) optsize { ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SANDY-NEXT: #APP -; SANDY-NEXT: fadd %st(0), %st(1) # sched: [3:1.00] -; SANDY-NEXT: fadd %st(2) # sched: [3:1.00] +; SANDY-NEXT: fadd %st, %st(1) # sched: [3:1.00] +; SANDY-NEXT: fadd %st(2), %st # sched: [3:1.00] ; SANDY-NEXT: fadds (%ecx) # sched: [10:1.00] ; SANDY-NEXT: faddl (%eax) # sched: [10:1.00] ; SANDY-NEXT: #NO_APP @@ -228,8 +228,8 @@ define void @test_fadd(float *%a0, double *%a1) optsize { ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; HASWELL-NEXT: #APP -; HASWELL-NEXT: fadd %st(0), %st(1) # sched: [3:1.00] -; HASWELL-NEXT: fadd %st(2) # sched: [3:1.00] +; HASWELL-NEXT: fadd %st, %st(1) # sched: [3:1.00] +; HASWELL-NEXT: fadd %st(2), %st # sched: [3:1.00] ; HASWELL-NEXT: fadds (%ecx) # sched: [10:1.00] ; HASWELL-NEXT: faddl (%eax) # sched: [10:1.00] ; HASWELL-NEXT: #NO_APP @@ -240,8 +240,8 @@ define void @test_fadd(float *%a0, double *%a1) optsize { ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BROADWELL-NEXT: #APP -; BROADWELL-NEXT: fadd %st(0), %st(1) # sched: [3:1.00] -; BROADWELL-NEXT: fadd %st(2) # sched: [3:1.00] +; BROADWELL-NEXT: fadd %st, %st(1) # sched: [3:1.00] +; BROADWELL-NEXT: fadd %st(2), %st # sched: [3:1.00] ; BROADWELL-NEXT: fadds (%ecx) # sched: [9:1.00] ; BROADWELL-NEXT: faddl (%eax) # sched: [9:1.00] ; BROADWELL-NEXT: #NO_APP @@ -252,8 +252,8 @@ define void @test_fadd(float *%a0, double *%a1) optsize { ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKYLAKE-NEXT: #APP -; SKYLAKE-NEXT: fadd %st(0), %st(1) # sched: [3:1.00] -; SKYLAKE-NEXT: fadd %st(2) # sched: [3:1.00] +; SKYLAKE-NEXT: fadd %st, %st(1) # sched: [3:1.00] +; SKYLAKE-NEXT: fadd %st(2), %st # sched: [3:1.00] ; SKYLAKE-NEXT: fadds (%ecx) # sched: [10:1.00] ; SKYLAKE-NEXT: faddl (%eax) # sched: [10:1.00] ; SKYLAKE-NEXT: #NO_APP @@ -264,8 +264,8 @@ define void @test_fadd(float *%a0, double *%a1) optsize { ; SKX-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKX-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKX-NEXT: #APP -; SKX-NEXT: fadd %st(0), %st(1) # sched: [3:1.00] -; SKX-NEXT: fadd %st(2) # sched: [3:1.00] +; SKX-NEXT: fadd %st, %st(1) # sched: [3:1.00] +; SKX-NEXT: fadd %st(2), %st # sched: [3:1.00] ; SKX-NEXT: fadds (%ecx) # sched: [10:1.00] ; SKX-NEXT: faddl (%eax) # sched: [10:1.00] ; SKX-NEXT: #NO_APP @@ -276,8 +276,8 @@ define void @test_fadd(float *%a0, double *%a1) optsize { ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BDVER2-NEXT: #APP -; BDVER2-NEXT: fadd %st(0), %st(1) # sched: [5:1.00] -; BDVER2-NEXT: fadd %st(2) # sched: [5:1.00] +; BDVER2-NEXT: fadd %st, %st(1) # sched: [5:1.00] +; BDVER2-NEXT: fadd %st(2), %st # sched: [5:1.00] ; BDVER2-NEXT: fadds (%ecx) # sched: [10:1.00] ; BDVER2-NEXT: faddl (%eax) # sched: [10:1.00] ; BDVER2-NEXT: #NO_APP @@ -288,8 +288,8 @@ define void @test_fadd(float *%a0, double *%a1) optsize { ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:1.00] ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:1.00] ; BTVER2-NEXT: #APP -; BTVER2-NEXT: fadd %st(0), %st(1) # sched: [3:1.00] -; BTVER2-NEXT: fadd %st(2) # sched: [3:1.00] +; BTVER2-NEXT: fadd %st, %st(1) # sched: [3:1.00] +; BTVER2-NEXT: fadd %st(2), %st # sched: [3:1.00] ; BTVER2-NEXT: fadds (%ecx) # sched: [8:1.00] ; BTVER2-NEXT: faddl (%eax) # sched: [8:1.00] ; BTVER2-NEXT: #NO_APP @@ -300,8 +300,8 @@ define void @test_fadd(float *%a0, double *%a1) optsize { ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [8:0.50] ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [8:0.50] ; ZNVER1-NEXT: #APP -; ZNVER1-NEXT: fadd %st(0), %st(1) # sched: [3:1.00] -; ZNVER1-NEXT: fadd %st(2) # sched: [3:1.00] +; ZNVER1-NEXT: fadd %st, %st(1) # sched: [3:1.00] +; ZNVER1-NEXT: fadd %st(2), %st # sched: [3:1.00] ; ZNVER1-NEXT: fadds (%ecx) # sched: [10:1.00] ; ZNVER1-NEXT: faddl (%eax) # sched: [10:1.00] ; ZNVER1-NEXT: #NO_APP @@ -316,8 +316,8 @@ define void @test_faddp_fiadd(i16 *%a0, i32 *%a1) optsize { ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %eax ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %ecx ; GENERIC-NEXT: #APP -; GENERIC-NEXT: faddp %st(1) -; GENERIC-NEXT: faddp %st(2) +; GENERIC-NEXT: faddp %st, %st(1) +; GENERIC-NEXT: faddp %st, %st(2) ; GENERIC-NEXT: fiadds (%ecx) ; GENERIC-NEXT: fiaddl (%eax) ; GENERIC-NEXT: #NO_APP @@ -328,8 +328,8 @@ define void @test_faddp_fiadd(i16 *%a0, i32 *%a1) optsize { ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [1:1.00] ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [1:1.00] ; ATOM-NEXT: #APP -; ATOM-NEXT: faddp %st(1) # sched: [5:5.00] -; ATOM-NEXT: faddp %st(2) # sched: [5:5.00] +; ATOM-NEXT: faddp %st, %st(1) # sched: [5:5.00] +; ATOM-NEXT: faddp %st, %st(2) # sched: [5:5.00] ; ATOM-NEXT: fiadds (%ecx) # sched: [5:5.00] ; ATOM-NEXT: fiaddl (%eax) # sched: [5:5.00] ; ATOM-NEXT: #NO_APP @@ -340,8 +340,8 @@ define void @test_faddp_fiadd(i16 *%a0, i32 *%a1) optsize { ; SLM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [3:1.00] ; SLM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [3:1.00] ; SLM-NEXT: #APP -; SLM-NEXT: faddp %st(1) # sched: [3:1.00] -; SLM-NEXT: faddp %st(2) # sched: [3:1.00] +; SLM-NEXT: faddp %st, %st(1) # sched: [3:1.00] +; SLM-NEXT: faddp %st, %st(2) # sched: [3:1.00] ; SLM-NEXT: fiadds (%ecx) # sched: [6:1.00] ; SLM-NEXT: fiaddl (%eax) # sched: [6:1.00] ; SLM-NEXT: #NO_APP @@ -352,8 +352,8 @@ define void @test_faddp_fiadd(i16 *%a0, i32 *%a1) optsize { ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SANDY-NEXT: #APP -; SANDY-NEXT: faddp %st(1) # sched: [3:1.00] -; SANDY-NEXT: faddp %st(2) # sched: [3:1.00] +; SANDY-NEXT: faddp %st, %st(1) # sched: [3:1.00] +; SANDY-NEXT: faddp %st, %st(2) # sched: [3:1.00] ; SANDY-NEXT: fiadds (%ecx) # sched: [13:2.00] ; SANDY-NEXT: fiaddl (%eax) # sched: [13:2.00] ; SANDY-NEXT: #NO_APP @@ -364,8 +364,8 @@ define void @test_faddp_fiadd(i16 *%a0, i32 *%a1) optsize { ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; HASWELL-NEXT: #APP -; HASWELL-NEXT: faddp %st(1) # sched: [3:1.00] -; HASWELL-NEXT: faddp %st(2) # sched: [3:1.00] +; HASWELL-NEXT: faddp %st, %st(1) # sched: [3:1.00] +; HASWELL-NEXT: faddp %st, %st(2) # sched: [3:1.00] ; HASWELL-NEXT: fiadds (%ecx) # sched: [13:2.00] ; HASWELL-NEXT: fiaddl (%eax) # sched: [13:2.00] ; HASWELL-NEXT: #NO_APP @@ -376,8 +376,8 @@ define void @test_faddp_fiadd(i16 *%a0, i32 *%a1) optsize { ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BROADWELL-NEXT: #APP -; BROADWELL-NEXT: faddp %st(1) # sched: [3:1.00] -; BROADWELL-NEXT: faddp %st(2) # sched: [3:1.00] +; BROADWELL-NEXT: faddp %st, %st(1) # sched: [3:1.00] +; BROADWELL-NEXT: faddp %st, %st(2) # sched: [3:1.00] ; BROADWELL-NEXT: fiadds (%ecx) # sched: [12:2.00] ; BROADWELL-NEXT: fiaddl (%eax) # sched: [12:2.00] ; BROADWELL-NEXT: #NO_APP @@ -388,8 +388,8 @@ define void @test_faddp_fiadd(i16 *%a0, i32 *%a1) optsize { ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKYLAKE-NEXT: #APP -; SKYLAKE-NEXT: faddp %st(1) # sched: [3:1.00] -; SKYLAKE-NEXT: faddp %st(2) # sched: [3:1.00] +; SKYLAKE-NEXT: faddp %st, %st(1) # sched: [3:1.00] +; SKYLAKE-NEXT: faddp %st, %st(2) # sched: [3:1.00] ; SKYLAKE-NEXT: fiadds (%ecx) # sched: [13:2.00] ; SKYLAKE-NEXT: fiaddl (%eax) # sched: [13:2.00] ; SKYLAKE-NEXT: #NO_APP @@ -400,8 +400,8 @@ define void @test_faddp_fiadd(i16 *%a0, i32 *%a1) optsize { ; SKX-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKX-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKX-NEXT: #APP -; SKX-NEXT: faddp %st(1) # sched: [3:1.00] -; SKX-NEXT: faddp %st(2) # sched: [3:1.00] +; SKX-NEXT: faddp %st, %st(1) # sched: [3:1.00] +; SKX-NEXT: faddp %st, %st(2) # sched: [3:1.00] ; SKX-NEXT: fiadds (%ecx) # sched: [13:2.00] ; SKX-NEXT: fiaddl (%eax) # sched: [13:2.00] ; SKX-NEXT: #NO_APP @@ -412,8 +412,8 @@ define void @test_faddp_fiadd(i16 *%a0, i32 *%a1) optsize { ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BDVER2-NEXT: #APP -; BDVER2-NEXT: faddp %st(1) # sched: [5:1.00] -; BDVER2-NEXT: faddp %st(2) # sched: [5:1.00] +; BDVER2-NEXT: faddp %st, %st(1) # sched: [5:1.00] +; BDVER2-NEXT: faddp %st, %st(2) # sched: [5:1.00] ; BDVER2-NEXT: fiadds (%ecx) # sched: [10:1.00] ; BDVER2-NEXT: fiaddl (%eax) # sched: [10:1.00] ; BDVER2-NEXT: #NO_APP @@ -424,8 +424,8 @@ define void @test_faddp_fiadd(i16 *%a0, i32 *%a1) optsize { ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:1.00] ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:1.00] ; BTVER2-NEXT: #APP -; BTVER2-NEXT: faddp %st(1) # sched: [3:1.00] -; BTVER2-NEXT: faddp %st(2) # sched: [3:1.00] +; BTVER2-NEXT: faddp %st, %st(1) # sched: [3:1.00] +; BTVER2-NEXT: faddp %st, %st(2) # sched: [3:1.00] ; BTVER2-NEXT: fiadds (%ecx) # sched: [8:1.00] ; BTVER2-NEXT: fiaddl (%eax) # sched: [8:1.00] ; BTVER2-NEXT: #NO_APP @@ -436,8 +436,8 @@ define void @test_faddp_fiadd(i16 *%a0, i32 *%a1) optsize { ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [8:0.50] ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [8:0.50] ; ZNVER1-NEXT: #APP -; ZNVER1-NEXT: faddp %st(1) # sched: [3:1.00] -; ZNVER1-NEXT: faddp %st(2) # sched: [3:1.00] +; ZNVER1-NEXT: faddp %st, %st(1) # sched: [3:1.00] +; ZNVER1-NEXT: faddp %st, %st(2) # sched: [3:1.00] ; ZNVER1-NEXT: fiadds (%ecx) # sched: [10:1.00] ; ZNVER1-NEXT: fiaddl (%eax) # sched: [10:1.00] ; ZNVER1-NEXT: #NO_APP @@ -807,154 +807,154 @@ define void @test_fcmov() optsize { ; GENERIC-LABEL: test_fcmov: ; GENERIC: # %bb.0: ; GENERIC-NEXT: #APP -; GENERIC-NEXT: fcmovb %st(1), %st(0) -; GENERIC-NEXT: fcmovbe %st(1), %st(0) -; GENERIC-NEXT: fcmove %st(1), %st(0) -; GENERIC-NEXT: fcmovnb %st(1), %st(0) -; GENERIC-NEXT: fcmovnbe %st(1), %st(0) -; GENERIC-NEXT: fcmovne %st(1), %st(0) -; GENERIC-NEXT: fcmovnu %st(1), %st(0) -; GENERIC-NEXT: fcmovu %st(1), %st(0) +; GENERIC-NEXT: fcmovb %st(1), %st +; GENERIC-NEXT: fcmovbe %st(1), %st +; GENERIC-NEXT: fcmove %st(1), %st +; GENERIC-NEXT: fcmovnb %st(1), %st +; GENERIC-NEXT: fcmovnbe %st(1), %st +; GENERIC-NEXT: fcmovne %st(1), %st +; GENERIC-NEXT: fcmovnu %st(1), %st +; GENERIC-NEXT: fcmovu %st(1), %st ; GENERIC-NEXT: #NO_APP ; GENERIC-NEXT: retl ; ; ATOM-LABEL: test_fcmov: ; ATOM: # %bb.0: ; ATOM-NEXT: #APP -; ATOM-NEXT: fcmovb %st(1), %st(0) # sched: [9:4.50] -; ATOM-NEXT: fcmovbe %st(1), %st(0) # sched: [9:4.50] -; ATOM-NEXT: fcmove %st(1), %st(0) # sched: [9:4.50] -; ATOM-NEXT: fcmovnb %st(1), %st(0) # sched: [9:4.50] -; ATOM-NEXT: fcmovnbe %st(1), %st(0) # sched: [9:4.50] -; ATOM-NEXT: fcmovne %st(1), %st(0) # sched: [9:4.50] -; ATOM-NEXT: fcmovnu %st(1), %st(0) # sched: [9:4.50] -; ATOM-NEXT: fcmovu %st(1), %st(0) # sched: [9:4.50] +; ATOM-NEXT: fcmovb %st(1), %st # sched: [9:4.50] +; ATOM-NEXT: fcmovbe %st(1), %st # sched: [9:4.50] +; ATOM-NEXT: fcmove %st(1), %st # sched: [9:4.50] +; ATOM-NEXT: fcmovnb %st(1), %st # sched: [9:4.50] +; ATOM-NEXT: fcmovnbe %st(1), %st # sched: [9:4.50] +; ATOM-NEXT: fcmovne %st(1), %st # sched: [9:4.50] +; ATOM-NEXT: fcmovnu %st(1), %st # sched: [9:4.50] +; ATOM-NEXT: fcmovu %st(1), %st # sched: [9:4.50] ; ATOM-NEXT: #NO_APP ; ATOM-NEXT: retl # sched: [79:39.50] ; ; SLM-LABEL: test_fcmov: ; SLM: # %bb.0: ; SLM-NEXT: #APP -; SLM-NEXT: fcmovb %st(1), %st(0) # sched: [3:1.00] -; SLM-NEXT: fcmovbe %st(1), %st(0) # sched: [3:1.00] -; SLM-NEXT: fcmove %st(1), %st(0) # sched: [3:1.00] -; SLM-NEXT: fcmovnb %st(1), %st(0) # sched: [3:1.00] -; SLM-NEXT: fcmovnbe %st(1), %st(0) # sched: [3:1.00] -; SLM-NEXT: fcmovne %st(1), %st(0) # sched: [3:1.00] -; SLM-NEXT: fcmovnu %st(1), %st(0) # sched: [3:1.00] -; SLM-NEXT: fcmovu %st(1), %st(0) # sched: [3:1.00] +; SLM-NEXT: fcmovb %st(1), %st # sched: [3:1.00] +; SLM-NEXT: fcmovbe %st(1), %st # sched: [3:1.00] +; SLM-NEXT: fcmove %st(1), %st # sched: [3:1.00] +; SLM-NEXT: fcmovnb %st(1), %st # sched: [3:1.00] +; SLM-NEXT: fcmovnbe %st(1), %st # sched: [3:1.00] +; SLM-NEXT: fcmovne %st(1), %st # sched: [3:1.00] +; SLM-NEXT: fcmovnu %st(1), %st # sched: [3:1.00] +; SLM-NEXT: fcmovu %st(1), %st # sched: [3:1.00] ; SLM-NEXT: #NO_APP ; SLM-NEXT: retl # sched: [4:1.00] ; ; SANDY-LABEL: test_fcmov: ; SANDY: # %bb.0: ; SANDY-NEXT: #APP -; SANDY-NEXT: fcmovb %st(1), %st(0) # sched: [3:2.00] -; SANDY-NEXT: fcmovbe %st(1), %st(0) # sched: [3:2.00] -; SANDY-NEXT: fcmove %st(1), %st(0) # sched: [3:2.00] -; SANDY-NEXT: fcmovnb %st(1), %st(0) # sched: [3:2.00] -; SANDY-NEXT: fcmovnbe %st(1), %st(0) # sched: [3:2.00] -; SANDY-NEXT: fcmovne %st(1), %st(0) # sched: [3:2.00] -; SANDY-NEXT: fcmovnu %st(1), %st(0) # sched: [3:2.00] -; SANDY-NEXT: fcmovu %st(1), %st(0) # sched: [3:2.00] +; SANDY-NEXT: fcmovb %st(1), %st # sched: [3:2.00] +; SANDY-NEXT: fcmovbe %st(1), %st # sched: [3:2.00] +; SANDY-NEXT: fcmove %st(1), %st # sched: [3:2.00] +; SANDY-NEXT: fcmovnb %st(1), %st # sched: [3:2.00] +; SANDY-NEXT: fcmovnbe %st(1), %st # sched: [3:2.00] +; SANDY-NEXT: fcmovne %st(1), %st # sched: [3:2.00] +; SANDY-NEXT: fcmovnu %st(1), %st # sched: [3:2.00] +; SANDY-NEXT: fcmovu %st(1), %st # sched: [3:2.00] ; SANDY-NEXT: #NO_APP ; SANDY-NEXT: retl # sched: [6:1.00] ; ; HASWELL-LABEL: test_fcmov: ; HASWELL: # %bb.0: ; HASWELL-NEXT: #APP -; HASWELL-NEXT: fcmovb %st(1), %st(0) # sched: [3:1.00] -; HASWELL-NEXT: fcmovbe %st(1), %st(0) # sched: [3:1.00] -; HASWELL-NEXT: fcmove %st(1), %st(0) # sched: [3:1.00] -; HASWELL-NEXT: fcmovnb %st(1), %st(0) # sched: [3:1.00] -; HASWELL-NEXT: fcmovnbe %st(1), %st(0) # sched: [3:1.00] -; HASWELL-NEXT: fcmovne %st(1), %st(0) # sched: [3:1.00] -; HASWELL-NEXT: fcmovnu %st(1), %st(0) # sched: [3:1.00] -; HASWELL-NEXT: fcmovu %st(1), %st(0) # sched: [3:1.00] +; HASWELL-NEXT: fcmovb %st(1), %st # sched: [3:1.00] +; HASWELL-NEXT: fcmovbe %st(1), %st # sched: [3:1.00] +; HASWELL-NEXT: fcmove %st(1), %st # sched: [3:1.00] +; HASWELL-NEXT: fcmovnb %st(1), %st # sched: [3:1.00] +; HASWELL-NEXT: fcmovnbe %st(1), %st # sched: [3:1.00] +; HASWELL-NEXT: fcmovne %st(1), %st # sched: [3:1.00] +; HASWELL-NEXT: fcmovnu %st(1), %st # sched: [3:1.00] +; HASWELL-NEXT: fcmovu %st(1), %st # sched: [3:1.00] ; HASWELL-NEXT: #NO_APP ; HASWELL-NEXT: retl # sched: [7:1.00] ; ; BROADWELL-LABEL: test_fcmov: ; BROADWELL: # %bb.0: ; BROADWELL-NEXT: #APP -; BROADWELL-NEXT: fcmovb %st(1), %st(0) # sched: [3:1.00] -; BROADWELL-NEXT: fcmovbe %st(1), %st(0) # sched: [3:1.00] -; BROADWELL-NEXT: fcmove %st(1), %st(0) # sched: [3:1.00] -; BROADWELL-NEXT: fcmovnb %st(1), %st(0) # sched: [3:1.00] -; BROADWELL-NEXT: fcmovnbe %st(1), %st(0) # sched: [3:1.00] -; BROADWELL-NEXT: fcmovne %st(1), %st(0) # sched: [3:1.00] -; BROADWELL-NEXT: fcmovnu %st(1), %st(0) # sched: [3:1.00] -; BROADWELL-NEXT: fcmovu %st(1), %st(0) # sched: [3:1.00] +; BROADWELL-NEXT: fcmovb %st(1), %st # sched: [3:1.00] +; BROADWELL-NEXT: fcmovbe %st(1), %st # sched: [3:1.00] +; BROADWELL-NEXT: fcmove %st(1), %st # sched: [3:1.00] +; BROADWELL-NEXT: fcmovnb %st(1), %st # sched: [3:1.00] +; BROADWELL-NEXT: fcmovnbe %st(1), %st # sched: [3:1.00] +; BROADWELL-NEXT: fcmovne %st(1), %st # sched: [3:1.00] +; BROADWELL-NEXT: fcmovnu %st(1), %st # sched: [3:1.00] +; BROADWELL-NEXT: fcmovu %st(1), %st # sched: [3:1.00] ; BROADWELL-NEXT: #NO_APP ; BROADWELL-NEXT: retl # sched: [6:0.50] ; ; SKYLAKE-LABEL: test_fcmov: ; SKYLAKE: # %bb.0: ; SKYLAKE-NEXT: #APP -; SKYLAKE-NEXT: fcmovb %st(1), %st(0) # sched: [3:1.00] -; SKYLAKE-NEXT: fcmovbe %st(1), %st(0) # sched: [3:1.00] -; SKYLAKE-NEXT: fcmove %st(1), %st(0) # sched: [3:1.00] -; SKYLAKE-NEXT: fcmovnb %st(1), %st(0) # sched: [3:1.00] -; SKYLAKE-NEXT: fcmovnbe %st(1), %st(0) # sched: [3:1.00] -; SKYLAKE-NEXT: fcmovne %st(1), %st(0) # sched: [3:1.00] -; SKYLAKE-NEXT: fcmovnu %st(1), %st(0) # sched: [3:1.00] -; SKYLAKE-NEXT: fcmovu %st(1), %st(0) # sched: [3:1.00] +; SKYLAKE-NEXT: fcmovb %st(1), %st # sched: [3:1.00] +; SKYLAKE-NEXT: fcmovbe %st(1), %st # sched: [3:1.00] +; SKYLAKE-NEXT: fcmove %st(1), %st # sched: [3:1.00] +; SKYLAKE-NEXT: fcmovnb %st(1), %st # sched: [3:1.00] +; SKYLAKE-NEXT: fcmovnbe %st(1), %st # sched: [3:1.00] +; SKYLAKE-NEXT: fcmovne %st(1), %st # sched: [3:1.00] +; SKYLAKE-NEXT: fcmovnu %st(1), %st # sched: [3:1.00] +; SKYLAKE-NEXT: fcmovu %st(1), %st # sched: [3:1.00] ; SKYLAKE-NEXT: #NO_APP ; SKYLAKE-NEXT: retl # sched: [6:0.50] ; ; SKX-LABEL: test_fcmov: ; SKX: # %bb.0: ; SKX-NEXT: #APP -; SKX-NEXT: fcmovb %st(1), %st(0) # sched: [3:1.00] -; SKX-NEXT: fcmovbe %st(1), %st(0) # sched: [3:1.00] -; SKX-NEXT: fcmove %st(1), %st(0) # sched: [3:1.00] -; SKX-NEXT: fcmovnb %st(1), %st(0) # sched: [3:1.00] -; SKX-NEXT: fcmovnbe %st(1), %st(0) # sched: [3:1.00] -; SKX-NEXT: fcmovne %st(1), %st(0) # sched: [3:1.00] -; SKX-NEXT: fcmovnu %st(1), %st(0) # sched: [3:1.00] -; SKX-NEXT: fcmovu %st(1), %st(0) # sched: [3:1.00] +; SKX-NEXT: fcmovb %st(1), %st # sched: [3:1.00] +; SKX-NEXT: fcmovbe %st(1), %st # sched: [3:1.00] +; SKX-NEXT: fcmove %st(1), %st # sched: [3:1.00] +; SKX-NEXT: fcmovnb %st(1), %st # sched: [3:1.00] +; SKX-NEXT: fcmovnbe %st(1), %st # sched: [3:1.00] +; SKX-NEXT: fcmovne %st(1), %st # sched: [3:1.00] +; SKX-NEXT: fcmovnu %st(1), %st # sched: [3:1.00] +; SKX-NEXT: fcmovu %st(1), %st # sched: [3:1.00] ; SKX-NEXT: #NO_APP ; SKX-NEXT: retl # sched: [6:0.50] ; ; BDVER2-LABEL: test_fcmov: ; BDVER2: # %bb.0: ; BDVER2-NEXT: #APP -; BDVER2-NEXT: fcmovb %st(1), %st(0) # sched: [1:1.00] -; BDVER2-NEXT: fcmovbe %st(1), %st(0) # sched: [1:1.00] -; BDVER2-NEXT: fcmove %st(1), %st(0) # sched: [1:1.00] -; BDVER2-NEXT: fcmovnb %st(1), %st(0) # sched: [1:1.00] -; BDVER2-NEXT: fcmovnbe %st(1), %st(0) # sched: [1:1.00] -; BDVER2-NEXT: fcmovne %st(1), %st(0) # sched: [1:1.00] -; BDVER2-NEXT: fcmovnu %st(1), %st(0) # sched: [1:1.00] -; BDVER2-NEXT: fcmovu %st(1), %st(0) # sched: [1:1.00] +; BDVER2-NEXT: fcmovb %st(1), %st # sched: [1:1.00] +; BDVER2-NEXT: fcmovbe %st(1), %st # sched: [1:1.00] +; BDVER2-NEXT: fcmove %st(1), %st # sched: [1:1.00] +; BDVER2-NEXT: fcmovnb %st(1), %st # sched: [1:1.00] +; BDVER2-NEXT: fcmovnbe %st(1), %st # sched: [1:1.00] +; BDVER2-NEXT: fcmovne %st(1), %st # sched: [1:1.00] +; BDVER2-NEXT: fcmovnu %st(1), %st # sched: [1:1.00] +; BDVER2-NEXT: fcmovu %st(1), %st # sched: [1:1.00] ; BDVER2-NEXT: #NO_APP ; BDVER2-NEXT: retl # sched: [5:1.00] ; ; BTVER2-LABEL: test_fcmov: ; BTVER2: # %bb.0: ; BTVER2-NEXT: #APP -; BTVER2-NEXT: fcmovb %st(1), %st(0) # sched: [3:1.00] -; BTVER2-NEXT: fcmovbe %st(1), %st(0) # sched: [3:1.00] -; BTVER2-NEXT: fcmove %st(1), %st(0) # sched: [3:1.00] -; BTVER2-NEXT: fcmovnb %st(1), %st(0) # sched: [3:1.00] -; BTVER2-NEXT: fcmovnbe %st(1), %st(0) # sched: [3:1.00] -; BTVER2-NEXT: fcmovne %st(1), %st(0) # sched: [3:1.00] -; BTVER2-NEXT: fcmovnu %st(1), %st(0) # sched: [3:1.00] -; BTVER2-NEXT: fcmovu %st(1), %st(0) # sched: [3:1.00] +; BTVER2-NEXT: fcmovb %st(1), %st # sched: [3:1.00] +; BTVER2-NEXT: fcmovbe %st(1), %st # sched: [3:1.00] +; BTVER2-NEXT: fcmove %st(1), %st # sched: [3:1.00] +; BTVER2-NEXT: fcmovnb %st(1), %st # sched: [3:1.00] +; BTVER2-NEXT: fcmovnbe %st(1), %st # sched: [3:1.00] +; BTVER2-NEXT: fcmovne %st(1), %st # sched: [3:1.00] +; BTVER2-NEXT: fcmovnu %st(1), %st # sched: [3:1.00] +; BTVER2-NEXT: fcmovu %st(1), %st # sched: [3:1.00] ; BTVER2-NEXT: #NO_APP ; BTVER2-NEXT: retl # sched: [4:1.00] ; ; ZNVER1-LABEL: test_fcmov: ; ZNVER1: # %bb.0: ; ZNVER1-NEXT: #APP -; ZNVER1-NEXT: fcmovb %st(1), %st(0) # sched: [100:0.25] -; ZNVER1-NEXT: fcmovbe %st(1), %st(0) # sched: [100:0.25] -; ZNVER1-NEXT: fcmove %st(1), %st(0) # sched: [100:0.25] -; ZNVER1-NEXT: fcmovnb %st(1), %st(0) # sched: [100:0.25] -; ZNVER1-NEXT: fcmovnbe %st(1), %st(0) # sched: [100:0.25] -; ZNVER1-NEXT: fcmovne %st(1), %st(0) # sched: [100:0.25] -; ZNVER1-NEXT: fcmovnu %st(1), %st(0) # sched: [100:0.25] -; ZNVER1-NEXT: fcmovu %st(1), %st(0) # sched: [100:0.25] +; ZNVER1-NEXT: fcmovb %st(1), %st # sched: [100:0.25] +; ZNVER1-NEXT: fcmovbe %st(1), %st # sched: [100:0.25] +; ZNVER1-NEXT: fcmove %st(1), %st # sched: [100:0.25] +; ZNVER1-NEXT: fcmovnb %st(1), %st # sched: [100:0.25] +; ZNVER1-NEXT: fcmovnbe %st(1), %st # sched: [100:0.25] +; ZNVER1-NEXT: fcmovne %st(1), %st # sched: [100:0.25] +; ZNVER1-NEXT: fcmovnu %st(1), %st # sched: [100:0.25] +; ZNVER1-NEXT: fcmovu %st(1), %st # sched: [100:0.25] ; ZNVER1-NEXT: #NO_APP ; ZNVER1-NEXT: retl # sched: [1:0.50] tail call void asm sideeffect "fcmovb %st(1), %st(0) \0A\09 fcmovbe %st(1), %st(0) \0A\09 fcmove %st(1), %st(0) \0A\09 fcmovnb %st(1), %st(0) \0A\09 fcmovnbe %st(1), %st(0) \0A\09 fcmovne %st(1), %st(0) \0A\09 fcmovnu %st(1), %st(0) \0A\09 fcmovu %st(1), %st(0)", ""() nounwind @@ -1248,88 +1248,88 @@ define void @test_fcomi_fcomip() optsize { ; GENERIC-LABEL: test_fcomi_fcomip: ; GENERIC: # %bb.0: ; GENERIC-NEXT: #APP -; GENERIC-NEXT: fcomi %st(3) -; GENERIC-NEXT: fcompi %st(3) +; GENERIC-NEXT: fcomi %st(3), %st +; GENERIC-NEXT: fcompi %st(3), %st ; GENERIC-NEXT: #NO_APP ; GENERIC-NEXT: retl ; ; ATOM-LABEL: test_fcomi_fcomip: ; ATOM: # %bb.0: ; ATOM-NEXT: #APP -; ATOM-NEXT: fcomi %st(3) # sched: [9:4.50] -; ATOM-NEXT: fcompi %st(3) # sched: [9:4.50] +; ATOM-NEXT: fcomi %st(3), %st # sched: [9:4.50] +; ATOM-NEXT: fcompi %st(3), %st # sched: [9:4.50] ; ATOM-NEXT: #NO_APP ; ATOM-NEXT: retl # sched: [79:39.50] ; ; SLM-LABEL: test_fcomi_fcomip: ; SLM: # %bb.0: ; SLM-NEXT: #APP -; SLM-NEXT: fcomi %st(3) # sched: [3:1.00] -; SLM-NEXT: fcompi %st(3) # sched: [3:1.00] +; SLM-NEXT: fcomi %st(3), %st # sched: [3:1.00] +; SLM-NEXT: fcompi %st(3), %st # sched: [3:1.00] ; SLM-NEXT: #NO_APP ; SLM-NEXT: retl # sched: [4:1.00] ; ; SANDY-LABEL: test_fcomi_fcomip: ; SANDY: # %bb.0: ; SANDY-NEXT: #APP -; SANDY-NEXT: fcomi %st(3) # sched: [3:1.00] -; SANDY-NEXT: fcompi %st(3) # sched: [3:1.00] +; SANDY-NEXT: fcomi %st(3), %st # sched: [3:1.00] +; SANDY-NEXT: fcompi %st(3), %st # sched: [3:1.00] ; SANDY-NEXT: #NO_APP ; SANDY-NEXT: retl # sched: [6:1.00] ; ; HASWELL-LABEL: test_fcomi_fcomip: ; HASWELL: # %bb.0: ; HASWELL-NEXT: #APP -; HASWELL-NEXT: fcomi %st(3) # sched: [1:0.50] -; HASWELL-NEXT: fcompi %st(3) # sched: [1:0.50] +; HASWELL-NEXT: fcomi %st(3), %st # sched: [1:0.50] +; HASWELL-NEXT: fcompi %st(3), %st # sched: [1:0.50] ; HASWELL-NEXT: #NO_APP ; HASWELL-NEXT: retl # sched: [7:1.00] ; ; BROADWELL-LABEL: test_fcomi_fcomip: ; BROADWELL: # %bb.0: ; BROADWELL-NEXT: #APP -; BROADWELL-NEXT: fcomi %st(3) # sched: [3:1.00] -; BROADWELL-NEXT: fcompi %st(3) # sched: [3:1.00] +; BROADWELL-NEXT: fcomi %st(3), %st # sched: [3:1.00] +; BROADWELL-NEXT: fcompi %st(3), %st # sched: [3:1.00] ; BROADWELL-NEXT: #NO_APP ; BROADWELL-NEXT: retl # sched: [6:0.50] ; ; SKYLAKE-LABEL: test_fcomi_fcomip: ; SKYLAKE: # %bb.0: ; SKYLAKE-NEXT: #APP -; SKYLAKE-NEXT: fcomi %st(3) # sched: [2:1.00] -; SKYLAKE-NEXT: fcompi %st(3) # sched: [2:1.00] +; SKYLAKE-NEXT: fcomi %st(3), %st # sched: [2:1.00] +; SKYLAKE-NEXT: fcompi %st(3), %st # sched: [2:1.00] ; SKYLAKE-NEXT: #NO_APP ; SKYLAKE-NEXT: retl # sched: [6:0.50] ; ; SKX-LABEL: test_fcomi_fcomip: ; SKX: # %bb.0: ; SKX-NEXT: #APP -; SKX-NEXT: fcomi %st(3) # sched: [2:1.00] -; SKX-NEXT: fcompi %st(3) # sched: [2:1.00] +; SKX-NEXT: fcomi %st(3), %st # sched: [2:1.00] +; SKX-NEXT: fcompi %st(3), %st # sched: [2:1.00] ; SKX-NEXT: #NO_APP ; SKX-NEXT: retl # sched: [6:0.50] ; ; BDVER2-LABEL: test_fcomi_fcomip: ; BDVER2: # %bb.0: ; BDVER2-NEXT: #APP -; BDVER2-NEXT: fcomi %st(3) # sched: [1:1.00] -; BDVER2-NEXT: fcompi %st(3) # sched: [1:1.00] +; BDVER2-NEXT: fcomi %st(3), %st # sched: [1:1.00] +; BDVER2-NEXT: fcompi %st(3), %st # sched: [1:1.00] ; BDVER2-NEXT: #NO_APP ; BDVER2-NEXT: retl # sched: [5:1.00] ; ; BTVER2-LABEL: test_fcomi_fcomip: ; BTVER2: # %bb.0: ; BTVER2-NEXT: #APP -; BTVER2-NEXT: fcomi %st(3) # sched: [3:1.00] -; BTVER2-NEXT: fcompi %st(3) # sched: [3:1.00] +; BTVER2-NEXT: fcomi %st(3), %st # sched: [3:1.00] +; BTVER2-NEXT: fcompi %st(3), %st # sched: [3:1.00] ; BTVER2-NEXT: #NO_APP ; BTVER2-NEXT: retl # sched: [4:1.00] ; ; ZNVER1-LABEL: test_fcomi_fcomip: ; ZNVER1: # %bb.0: ; ZNVER1-NEXT: #APP -; ZNVER1-NEXT: fcomi %st(3) # sched: [9:0.50] -; ZNVER1-NEXT: fcompi %st(3) # sched: [9:0.50] +; ZNVER1-NEXT: fcomi %st(3), %st # sched: [9:0.50] +; ZNVER1-NEXT: fcompi %st(3), %st # sched: [9:0.50] ; ZNVER1-NEXT: #NO_APP ; ZNVER1-NEXT: retl # sched: [1:0.50] tail call void asm sideeffect "fcomi %st(3) \0A\09 fcomip %st(3)", ""() nounwind @@ -1504,8 +1504,8 @@ define void @test_fdiv(float *%a0, double *%a1) optsize { ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %eax ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %ecx ; GENERIC-NEXT: #APP -; GENERIC-NEXT: fdiv %st(0), %st(1) -; GENERIC-NEXT: fdiv %st(2) +; GENERIC-NEXT: fdiv %st, %st(1) +; GENERIC-NEXT: fdiv %st(2), %st ; GENERIC-NEXT: fdivs (%ecx) ; GENERIC-NEXT: fdivl (%eax) ; GENERIC-NEXT: #NO_APP @@ -1516,8 +1516,8 @@ define void @test_fdiv(float *%a0, double *%a1) optsize { ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [1:1.00] ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [1:1.00] ; ATOM-NEXT: #APP -; ATOM-NEXT: fdiv %st(0), %st(1) # sched: [34:17.00] -; ATOM-NEXT: fdiv %st(2) # sched: [34:17.00] +; ATOM-NEXT: fdiv %st, %st(1) # sched: [34:17.00] +; ATOM-NEXT: fdiv %st(2), %st # sched: [34:17.00] ; ATOM-NEXT: fdivs (%ecx) # sched: [34:17.00] ; ATOM-NEXT: fdivl (%eax) # sched: [34:17.00] ; ATOM-NEXT: #NO_APP @@ -1528,8 +1528,8 @@ define void @test_fdiv(float *%a0, double *%a1) optsize { ; SLM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [3:1.00] ; SLM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [3:1.00] ; SLM-NEXT: #APP -; SLM-NEXT: fdiv %st(0), %st(1) # sched: [19:17.00] -; SLM-NEXT: fdiv %st(2) # sched: [19:17.00] +; SLM-NEXT: fdiv %st, %st(1) # sched: [19:17.00] +; SLM-NEXT: fdiv %st(2), %st # sched: [19:17.00] ; SLM-NEXT: fdivs (%ecx) # sched: [22:17.00] ; SLM-NEXT: fdivl (%eax) # sched: [22:17.00] ; SLM-NEXT: #NO_APP @@ -1540,8 +1540,8 @@ define void @test_fdiv(float *%a0, double *%a1) optsize { ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SANDY-NEXT: #APP -; SANDY-NEXT: fdiv %st(0), %st(1) # sched: [14:14.00] -; SANDY-NEXT: fdiv %st(2) # sched: [14:14.00] +; SANDY-NEXT: fdiv %st, %st(1) # sched: [14:14.00] +; SANDY-NEXT: fdiv %st(2), %st # sched: [14:14.00] ; SANDY-NEXT: fdivs (%ecx) # sched: [31:1.00] ; SANDY-NEXT: fdivl (%eax) # sched: [31:1.00] ; SANDY-NEXT: #NO_APP @@ -1552,8 +1552,8 @@ define void @test_fdiv(float *%a0, double *%a1) optsize { ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; HASWELL-NEXT: #APP -; HASWELL-NEXT: fdiv %st(0), %st(1) # sched: [24:1.00] -; HASWELL-NEXT: fdiv %st(2) # sched: [20:1.00] +; HASWELL-NEXT: fdiv %st, %st(1) # sched: [24:1.00] +; HASWELL-NEXT: fdiv %st(2), %st # sched: [20:1.00] ; HASWELL-NEXT: fdivs (%ecx) # sched: [31:1.00] ; HASWELL-NEXT: fdivl (%eax) # sched: [31:1.00] ; HASWELL-NEXT: #NO_APP @@ -1564,8 +1564,8 @@ define void @test_fdiv(float *%a0, double *%a1) optsize { ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BROADWELL-NEXT: #APP -; BROADWELL-NEXT: fdiv %st(0), %st(1) # sched: [15:1.00] -; BROADWELL-NEXT: fdiv %st(2) # sched: [20:1.00] +; BROADWELL-NEXT: fdiv %st, %st(1) # sched: [15:1.00] +; BROADWELL-NEXT: fdiv %st(2), %st # sched: [20:1.00] ; BROADWELL-NEXT: fdivs (%ecx) # sched: [21:1.00] ; BROADWELL-NEXT: fdivl (%eax) # sched: [21:1.00] ; BROADWELL-NEXT: #NO_APP @@ -1576,8 +1576,8 @@ define void @test_fdiv(float *%a0, double *%a1) optsize { ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKYLAKE-NEXT: #APP -; SKYLAKE-NEXT: fdiv %st(0), %st(1) # sched: [15:1.00] -; SKYLAKE-NEXT: fdiv %st(2) # sched: [20:1.00] +; SKYLAKE-NEXT: fdiv %st, %st(1) # sched: [15:1.00] +; SKYLAKE-NEXT: fdiv %st(2), %st # sched: [20:1.00] ; SKYLAKE-NEXT: fdivs (%ecx) # sched: [22:1.00] ; SKYLAKE-NEXT: fdivl (%eax) # sched: [22:1.00] ; SKYLAKE-NEXT: #NO_APP @@ -1588,8 +1588,8 @@ define void @test_fdiv(float *%a0, double *%a1) optsize { ; SKX-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKX-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKX-NEXT: #APP -; SKX-NEXT: fdiv %st(0), %st(1) # sched: [15:1.00] -; SKX-NEXT: fdiv %st(2) # sched: [20:1.00] +; SKX-NEXT: fdiv %st, %st(1) # sched: [15:1.00] +; SKX-NEXT: fdiv %st(2), %st # sched: [20:1.00] ; SKX-NEXT: fdivs (%ecx) # sched: [22:1.00] ; SKX-NEXT: fdivl (%eax) # sched: [22:1.00] ; SKX-NEXT: #NO_APP @@ -1600,8 +1600,8 @@ define void @test_fdiv(float *%a0, double *%a1) optsize { ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BDVER2-NEXT: #APP -; BDVER2-NEXT: fdiv %st(0), %st(1) # sched: [9:9.50] -; BDVER2-NEXT: fdiv %st(2) # sched: [9:9.50] +; BDVER2-NEXT: fdiv %st, %st(1) # sched: [9:9.50] +; BDVER2-NEXT: fdiv %st(2), %st # sched: [9:9.50] ; BDVER2-NEXT: fdivs (%ecx) # sched: [14:9.50] ; BDVER2-NEXT: fdivl (%eax) # sched: [14:9.50] ; BDVER2-NEXT: #NO_APP @@ -1612,8 +1612,8 @@ define void @test_fdiv(float *%a0, double *%a1) optsize { ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:1.00] ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:1.00] ; BTVER2-NEXT: #APP -; BTVER2-NEXT: fdiv %st(0), %st(1) # sched: [19:19.00] -; BTVER2-NEXT: fdiv %st(2) # sched: [19:19.00] +; BTVER2-NEXT: fdiv %st, %st(1) # sched: [19:19.00] +; BTVER2-NEXT: fdiv %st(2), %st # sched: [19:19.00] ; BTVER2-NEXT: fdivs (%ecx) # sched: [24:19.00] ; BTVER2-NEXT: fdivl (%eax) # sched: [24:19.00] ; BTVER2-NEXT: #NO_APP @@ -1624,8 +1624,8 @@ define void @test_fdiv(float *%a0, double *%a1) optsize { ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [8:0.50] ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [8:0.50] ; ZNVER1-NEXT: #APP -; ZNVER1-NEXT: fdiv %st(0), %st(1) # sched: [15:1.00] -; ZNVER1-NEXT: fdiv %st(2) # sched: [15:1.00] +; ZNVER1-NEXT: fdiv %st, %st(1) # sched: [15:1.00] +; ZNVER1-NEXT: fdiv %st(2), %st # sched: [15:1.00] ; ZNVER1-NEXT: fdivs (%ecx) # sched: [22:1.00] ; ZNVER1-NEXT: fdivl (%eax) # sched: [22:1.00] ; ZNVER1-NEXT: #NO_APP @@ -1640,8 +1640,8 @@ define void @test_fdivp_fidiv(i16 *%a0, i32 *%a1) optsize { ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %eax ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %ecx ; GENERIC-NEXT: #APP -; GENERIC-NEXT: fdivp %st(1) -; GENERIC-NEXT: fdivp %st(2) +; GENERIC-NEXT: fdivp %st, %st(1) +; GENERIC-NEXT: fdivp %st, %st(2) ; GENERIC-NEXT: fidivs (%ecx) ; GENERIC-NEXT: fidivl (%eax) ; GENERIC-NEXT: #NO_APP @@ -1652,8 +1652,8 @@ define void @test_fdivp_fidiv(i16 *%a0, i32 *%a1) optsize { ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [1:1.00] ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [1:1.00] ; ATOM-NEXT: #APP -; ATOM-NEXT: fdivp %st(1) # sched: [34:17.00] -; ATOM-NEXT: fdivp %st(2) # sched: [34:17.00] +; ATOM-NEXT: fdivp %st, %st(1) # sched: [34:17.00] +; ATOM-NEXT: fdivp %st, %st(2) # sched: [34:17.00] ; ATOM-NEXT: fidivs (%ecx) # sched: [34:17.00] ; ATOM-NEXT: fidivl (%eax) # sched: [34:17.00] ; ATOM-NEXT: #NO_APP @@ -1664,8 +1664,8 @@ define void @test_fdivp_fidiv(i16 *%a0, i32 *%a1) optsize { ; SLM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [3:1.00] ; SLM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [3:1.00] ; SLM-NEXT: #APP -; SLM-NEXT: fdivp %st(1) # sched: [19:17.00] -; SLM-NEXT: fdivp %st(2) # sched: [19:17.00] +; SLM-NEXT: fdivp %st, %st(1) # sched: [19:17.00] +; SLM-NEXT: fdivp %st, %st(2) # sched: [19:17.00] ; SLM-NEXT: fidivs (%ecx) # sched: [22:17.00] ; SLM-NEXT: fidivl (%eax) # sched: [22:17.00] ; SLM-NEXT: #NO_APP @@ -1676,8 +1676,8 @@ define void @test_fdivp_fidiv(i16 *%a0, i32 *%a1) optsize { ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SANDY-NEXT: #APP -; SANDY-NEXT: fdivp %st(1) # sched: [14:14.00] -; SANDY-NEXT: fdivp %st(2) # sched: [14:14.00] +; SANDY-NEXT: fdivp %st, %st(1) # sched: [14:14.00] +; SANDY-NEXT: fdivp %st, %st(2) # sched: [14:14.00] ; SANDY-NEXT: fidivs (%ecx) # sched: [34:1.00] ; SANDY-NEXT: fidivl (%eax) # sched: [34:1.00] ; SANDY-NEXT: #NO_APP @@ -1688,8 +1688,8 @@ define void @test_fdivp_fidiv(i16 *%a0, i32 *%a1) optsize { ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; HASWELL-NEXT: #APP -; HASWELL-NEXT: fdivp %st(1) # sched: [24:1.00] -; HASWELL-NEXT: fdivp %st(2) # sched: [24:1.00] +; HASWELL-NEXT: fdivp %st, %st(1) # sched: [24:1.00] +; HASWELL-NEXT: fdivp %st, %st(2) # sched: [24:1.00] ; HASWELL-NEXT: fidivs (%ecx) # sched: [34:1.00] ; HASWELL-NEXT: fidivl (%eax) # sched: [34:1.00] ; HASWELL-NEXT: #NO_APP @@ -1700,8 +1700,8 @@ define void @test_fdivp_fidiv(i16 *%a0, i32 *%a1) optsize { ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BROADWELL-NEXT: #APP -; BROADWELL-NEXT: fdivp %st(1) # sched: [15:1.00] -; BROADWELL-NEXT: fdivp %st(2) # sched: [15:1.00] +; BROADWELL-NEXT: fdivp %st, %st(1) # sched: [15:1.00] +; BROADWELL-NEXT: fdivp %st, %st(2) # sched: [15:1.00] ; BROADWELL-NEXT: fidivs (%ecx) # sched: [24:1.00] ; BROADWELL-NEXT: fidivl (%eax) # sched: [24:1.00] ; BROADWELL-NEXT: #NO_APP @@ -1712,8 +1712,8 @@ define void @test_fdivp_fidiv(i16 *%a0, i32 *%a1) optsize { ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKYLAKE-NEXT: #APP -; SKYLAKE-NEXT: fdivp %st(1) # sched: [15:1.00] -; SKYLAKE-NEXT: fdivp %st(2) # sched: [15:1.00] +; SKYLAKE-NEXT: fdivp %st, %st(1) # sched: [15:1.00] +; SKYLAKE-NEXT: fdivp %st, %st(2) # sched: [15:1.00] ; SKYLAKE-NEXT: fidivs (%ecx) # sched: [25:1.00] ; SKYLAKE-NEXT: fidivl (%eax) # sched: [25:1.00] ; SKYLAKE-NEXT: #NO_APP @@ -1724,8 +1724,8 @@ define void @test_fdivp_fidiv(i16 *%a0, i32 *%a1) optsize { ; SKX-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKX-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKX-NEXT: #APP -; SKX-NEXT: fdivp %st(1) # sched: [15:1.00] -; SKX-NEXT: fdivp %st(2) # sched: [15:1.00] +; SKX-NEXT: fdivp %st, %st(1) # sched: [15:1.00] +; SKX-NEXT: fdivp %st, %st(2) # sched: [15:1.00] ; SKX-NEXT: fidivs (%ecx) # sched: [25:1.00] ; SKX-NEXT: fidivl (%eax) # sched: [25:1.00] ; SKX-NEXT: #NO_APP @@ -1736,8 +1736,8 @@ define void @test_fdivp_fidiv(i16 *%a0, i32 *%a1) optsize { ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BDVER2-NEXT: #APP -; BDVER2-NEXT: fdivp %st(1) # sched: [9:9.50] -; BDVER2-NEXT: fdivp %st(2) # sched: [9:9.50] +; BDVER2-NEXT: fdivp %st, %st(1) # sched: [9:9.50] +; BDVER2-NEXT: fdivp %st, %st(2) # sched: [9:9.50] ; BDVER2-NEXT: fidivs (%ecx) # sched: [14:9.50] ; BDVER2-NEXT: fidivl (%eax) # sched: [14:9.50] ; BDVER2-NEXT: #NO_APP @@ -1748,8 +1748,8 @@ define void @test_fdivp_fidiv(i16 *%a0, i32 *%a1) optsize { ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:1.00] ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:1.00] ; BTVER2-NEXT: #APP -; BTVER2-NEXT: fdivp %st(1) # sched: [19:19.00] -; BTVER2-NEXT: fdivp %st(2) # sched: [19:19.00] +; BTVER2-NEXT: fdivp %st, %st(1) # sched: [19:19.00] +; BTVER2-NEXT: fdivp %st, %st(2) # sched: [19:19.00] ; BTVER2-NEXT: fidivs (%ecx) # sched: [24:19.00] ; BTVER2-NEXT: fidivl (%eax) # sched: [24:19.00] ; BTVER2-NEXT: #NO_APP @@ -1760,8 +1760,8 @@ define void @test_fdivp_fidiv(i16 *%a0, i32 *%a1) optsize { ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [8:0.50] ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [8:0.50] ; ZNVER1-NEXT: #APP -; ZNVER1-NEXT: fdivp %st(1) # sched: [15:1.00] -; ZNVER1-NEXT: fdivp %st(2) # sched: [15:1.00] +; ZNVER1-NEXT: fdivp %st, %st(1) # sched: [15:1.00] +; ZNVER1-NEXT: fdivp %st, %st(2) # sched: [15:1.00] ; ZNVER1-NEXT: fidivs (%ecx) # sched: [22:1.00] ; ZNVER1-NEXT: fidivl (%eax) # sched: [22:1.00] ; ZNVER1-NEXT: #NO_APP @@ -1776,8 +1776,8 @@ define void @test_fdivr(float *%a0, double *%a1) optsize { ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %eax ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %ecx ; GENERIC-NEXT: #APP -; GENERIC-NEXT: fdivr %st(0), %st(1) -; GENERIC-NEXT: fdivr %st(2) +; GENERIC-NEXT: fdivr %st, %st(1) +; GENERIC-NEXT: fdivr %st(2), %st ; GENERIC-NEXT: fdivrs (%ecx) ; GENERIC-NEXT: fdivrl (%eax) ; GENERIC-NEXT: #NO_APP @@ -1788,8 +1788,8 @@ define void @test_fdivr(float *%a0, double *%a1) optsize { ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [1:1.00] ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [1:1.00] ; ATOM-NEXT: #APP -; ATOM-NEXT: fdivr %st(0), %st(1) # sched: [34:17.00] -; ATOM-NEXT: fdivr %st(2) # sched: [34:17.00] +; ATOM-NEXT: fdivr %st, %st(1) # sched: [34:17.00] +; ATOM-NEXT: fdivr %st(2), %st # sched: [34:17.00] ; ATOM-NEXT: fdivrs (%ecx) # sched: [34:17.00] ; ATOM-NEXT: fdivrl (%eax) # sched: [34:17.00] ; ATOM-NEXT: #NO_APP @@ -1800,8 +1800,8 @@ define void @test_fdivr(float *%a0, double *%a1) optsize { ; SLM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [3:1.00] ; SLM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [3:1.00] ; SLM-NEXT: #APP -; SLM-NEXT: fdivr %st(0), %st(1) # sched: [19:17.00] -; SLM-NEXT: fdivr %st(2) # sched: [19:17.00] +; SLM-NEXT: fdivr %st, %st(1) # sched: [19:17.00] +; SLM-NEXT: fdivr %st(2), %st # sched: [19:17.00] ; SLM-NEXT: fdivrs (%ecx) # sched: [22:17.00] ; SLM-NEXT: fdivrl (%eax) # sched: [22:17.00] ; SLM-NEXT: #NO_APP @@ -1812,8 +1812,8 @@ define void @test_fdivr(float *%a0, double *%a1) optsize { ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SANDY-NEXT: #APP -; SANDY-NEXT: fdivr %st(0), %st(1) # sched: [14:14.00] -; SANDY-NEXT: fdivr %st(2) # sched: [14:14.00] +; SANDY-NEXT: fdivr %st, %st(1) # sched: [14:14.00] +; SANDY-NEXT: fdivr %st(2), %st # sched: [14:14.00] ; SANDY-NEXT: fdivrs (%ecx) # sched: [31:1.00] ; SANDY-NEXT: fdivrl (%eax) # sched: [31:1.00] ; SANDY-NEXT: #NO_APP @@ -1824,8 +1824,8 @@ define void @test_fdivr(float *%a0, double *%a1) optsize { ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; HASWELL-NEXT: #APP -; HASWELL-NEXT: fdivr %st(0), %st(1) # sched: [20:1.00] -; HASWELL-NEXT: fdivr %st(2) # sched: [24:1.00] +; HASWELL-NEXT: fdivr %st, %st(1) # sched: [20:1.00] +; HASWELL-NEXT: fdivr %st(2), %st # sched: [24:1.00] ; HASWELL-NEXT: fdivrs (%ecx) # sched: [27:1.00] ; HASWELL-NEXT: fdivrl (%eax) # sched: [27:1.00] ; HASWELL-NEXT: #NO_APP @@ -1836,8 +1836,8 @@ define void @test_fdivr(float *%a0, double *%a1) optsize { ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BROADWELL-NEXT: #APP -; BROADWELL-NEXT: fdivr %st(0), %st(1) # sched: [20:1.00] -; BROADWELL-NEXT: fdivr %st(2) # sched: [15:1.00] +; BROADWELL-NEXT: fdivr %st, %st(1) # sched: [20:1.00] +; BROADWELL-NEXT: fdivr %st(2), %st # sched: [15:1.00] ; BROADWELL-NEXT: fdivrs (%ecx) # sched: [26:1.00] ; BROADWELL-NEXT: fdivrl (%eax) # sched: [26:1.00] ; BROADWELL-NEXT: #NO_APP @@ -1848,8 +1848,8 @@ define void @test_fdivr(float *%a0, double *%a1) optsize { ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKYLAKE-NEXT: #APP -; SKYLAKE-NEXT: fdivr %st(0), %st(1) # sched: [20:1.00] -; SKYLAKE-NEXT: fdivr %st(2) # sched: [15:1.00] +; SKYLAKE-NEXT: fdivr %st, %st(1) # sched: [20:1.00] +; SKYLAKE-NEXT: fdivr %st(2), %st # sched: [15:1.00] ; SKYLAKE-NEXT: fdivrs (%ecx) # sched: [27:1.00] ; SKYLAKE-NEXT: fdivrl (%eax) # sched: [27:1.00] ; SKYLAKE-NEXT: #NO_APP @@ -1860,8 +1860,8 @@ define void @test_fdivr(float *%a0, double *%a1) optsize { ; SKX-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKX-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKX-NEXT: #APP -; SKX-NEXT: fdivr %st(0), %st(1) # sched: [20:1.00] -; SKX-NEXT: fdivr %st(2) # sched: [15:1.00] +; SKX-NEXT: fdivr %st, %st(1) # sched: [20:1.00] +; SKX-NEXT: fdivr %st(2), %st # sched: [15:1.00] ; SKX-NEXT: fdivrs (%ecx) # sched: [27:1.00] ; SKX-NEXT: fdivrl (%eax) # sched: [27:1.00] ; SKX-NEXT: #NO_APP @@ -1872,8 +1872,8 @@ define void @test_fdivr(float *%a0, double *%a1) optsize { ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BDVER2-NEXT: #APP -; BDVER2-NEXT: fdivr %st(0), %st(1) # sched: [9:9.50] -; BDVER2-NEXT: fdivr %st(2) # sched: [9:9.50] +; BDVER2-NEXT: fdivr %st, %st(1) # sched: [9:9.50] +; BDVER2-NEXT: fdivr %st(2), %st # sched: [9:9.50] ; BDVER2-NEXT: fdivrs (%ecx) # sched: [14:9.50] ; BDVER2-NEXT: fdivrl (%eax) # sched: [14:9.50] ; BDVER2-NEXT: #NO_APP @@ -1884,8 +1884,8 @@ define void @test_fdivr(float *%a0, double *%a1) optsize { ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:1.00] ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:1.00] ; BTVER2-NEXT: #APP -; BTVER2-NEXT: fdivr %st(0), %st(1) # sched: [19:19.00] -; BTVER2-NEXT: fdivr %st(2) # sched: [19:19.00] +; BTVER2-NEXT: fdivr %st, %st(1) # sched: [19:19.00] +; BTVER2-NEXT: fdivr %st(2), %st # sched: [19:19.00] ; BTVER2-NEXT: fdivrs (%ecx) # sched: [24:19.00] ; BTVER2-NEXT: fdivrl (%eax) # sched: [24:19.00] ; BTVER2-NEXT: #NO_APP @@ -1896,8 +1896,8 @@ define void @test_fdivr(float *%a0, double *%a1) optsize { ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [8:0.50] ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [8:0.50] ; ZNVER1-NEXT: #APP -; ZNVER1-NEXT: fdivr %st(0), %st(1) # sched: [15:1.00] -; ZNVER1-NEXT: fdivr %st(2) # sched: [15:1.00] +; ZNVER1-NEXT: fdivr %st, %st(1) # sched: [15:1.00] +; ZNVER1-NEXT: fdivr %st(2), %st # sched: [15:1.00] ; ZNVER1-NEXT: fdivrs (%ecx) # sched: [22:1.00] ; ZNVER1-NEXT: fdivrl (%eax) # sched: [22:1.00] ; ZNVER1-NEXT: #NO_APP @@ -1912,8 +1912,8 @@ define void @test_fdivrp_fidivr(i16 *%a0, i32 *%a1) optsize { ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %eax ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %ecx ; GENERIC-NEXT: #APP -; GENERIC-NEXT: fdivrp %st(1) -; GENERIC-NEXT: fdivrp %st(2) +; GENERIC-NEXT: fdivrp %st, %st(1) +; GENERIC-NEXT: fdivrp %st, %st(2) ; GENERIC-NEXT: fidivrs (%ecx) ; GENERIC-NEXT: fidivrl (%eax) ; GENERIC-NEXT: #NO_APP @@ -1924,8 +1924,8 @@ define void @test_fdivrp_fidivr(i16 *%a0, i32 *%a1) optsize { ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [1:1.00] ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [1:1.00] ; ATOM-NEXT: #APP -; ATOM-NEXT: fdivrp %st(1) # sched: [34:17.00] -; ATOM-NEXT: fdivrp %st(2) # sched: [34:17.00] +; ATOM-NEXT: fdivrp %st, %st(1) # sched: [34:17.00] +; ATOM-NEXT: fdivrp %st, %st(2) # sched: [34:17.00] ; ATOM-NEXT: fidivrs (%ecx) # sched: [34:17.00] ; ATOM-NEXT: fidivrl (%eax) # sched: [34:17.00] ; ATOM-NEXT: #NO_APP @@ -1936,8 +1936,8 @@ define void @test_fdivrp_fidivr(i16 *%a0, i32 *%a1) optsize { ; SLM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [3:1.00] ; SLM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [3:1.00] ; SLM-NEXT: #APP -; SLM-NEXT: fdivrp %st(1) # sched: [19:17.00] -; SLM-NEXT: fdivrp %st(2) # sched: [19:17.00] +; SLM-NEXT: fdivrp %st, %st(1) # sched: [19:17.00] +; SLM-NEXT: fdivrp %st, %st(2) # sched: [19:17.00] ; SLM-NEXT: fidivrs (%ecx) # sched: [22:17.00] ; SLM-NEXT: fidivrl (%eax) # sched: [22:17.00] ; SLM-NEXT: #NO_APP @@ -1948,8 +1948,8 @@ define void @test_fdivrp_fidivr(i16 *%a0, i32 *%a1) optsize { ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SANDY-NEXT: #APP -; SANDY-NEXT: fdivrp %st(1) # sched: [14:14.00] -; SANDY-NEXT: fdivrp %st(2) # sched: [14:14.00] +; SANDY-NEXT: fdivrp %st, %st(1) # sched: [14:14.00] +; SANDY-NEXT: fdivrp %st, %st(2) # sched: [14:14.00] ; SANDY-NEXT: fidivrs (%ecx) # sched: [34:1.00] ; SANDY-NEXT: fidivrl (%eax) # sched: [34:1.00] ; SANDY-NEXT: #NO_APP @@ -1960,8 +1960,8 @@ define void @test_fdivrp_fidivr(i16 *%a0, i32 *%a1) optsize { ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; HASWELL-NEXT: #APP -; HASWELL-NEXT: fdivrp %st(1) # sched: [20:1.00] -; HASWELL-NEXT: fdivrp %st(2) # sched: [20:1.00] +; HASWELL-NEXT: fdivrp %st, %st(1) # sched: [20:1.00] +; HASWELL-NEXT: fdivrp %st, %st(2) # sched: [20:1.00] ; HASWELL-NEXT: fidivrs (%ecx) # sched: [30:1.00] ; HASWELL-NEXT: fidivrl (%eax) # sched: [30:1.00] ; HASWELL-NEXT: #NO_APP @@ -1972,8 +1972,8 @@ define void @test_fdivrp_fidivr(i16 *%a0, i32 *%a1) optsize { ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BROADWELL-NEXT: #APP -; BROADWELL-NEXT: fdivrp %st(1) # sched: [20:1.00] -; BROADWELL-NEXT: fdivrp %st(2) # sched: [20:1.00] +; BROADWELL-NEXT: fdivrp %st, %st(1) # sched: [20:1.00] +; BROADWELL-NEXT: fdivrp %st, %st(2) # sched: [20:1.00] ; BROADWELL-NEXT: fidivrs (%ecx) # sched: [29:1.00] ; BROADWELL-NEXT: fidivrl (%eax) # sched: [29:1.00] ; BROADWELL-NEXT: #NO_APP @@ -1984,8 +1984,8 @@ define void @test_fdivrp_fidivr(i16 *%a0, i32 *%a1) optsize { ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKYLAKE-NEXT: #APP -; SKYLAKE-NEXT: fdivrp %st(1) # sched: [20:1.00] -; SKYLAKE-NEXT: fdivrp %st(2) # sched: [20:1.00] +; SKYLAKE-NEXT: fdivrp %st, %st(1) # sched: [20:1.00] +; SKYLAKE-NEXT: fdivrp %st, %st(2) # sched: [20:1.00] ; SKYLAKE-NEXT: fidivrs (%ecx) # sched: [30:1.00] ; SKYLAKE-NEXT: fidivrl (%eax) # sched: [30:1.00] ; SKYLAKE-NEXT: #NO_APP @@ -1996,8 +1996,8 @@ define void @test_fdivrp_fidivr(i16 *%a0, i32 *%a1) optsize { ; SKX-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKX-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKX-NEXT: #APP -; SKX-NEXT: fdivrp %st(1) # sched: [20:1.00] -; SKX-NEXT: fdivrp %st(2) # sched: [20:1.00] +; SKX-NEXT: fdivrp %st, %st(1) # sched: [20:1.00] +; SKX-NEXT: fdivrp %st, %st(2) # sched: [20:1.00] ; SKX-NEXT: fidivrs (%ecx) # sched: [30:1.00] ; SKX-NEXT: fidivrl (%eax) # sched: [30:1.00] ; SKX-NEXT: #NO_APP @@ -2008,8 +2008,8 @@ define void @test_fdivrp_fidivr(i16 *%a0, i32 *%a1) optsize { ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BDVER2-NEXT: #APP -; BDVER2-NEXT: fdivrp %st(1) # sched: [9:9.50] -; BDVER2-NEXT: fdivrp %st(2) # sched: [9:9.50] +; BDVER2-NEXT: fdivrp %st, %st(1) # sched: [9:9.50] +; BDVER2-NEXT: fdivrp %st, %st(2) # sched: [9:9.50] ; BDVER2-NEXT: fidivrs (%ecx) # sched: [14:9.50] ; BDVER2-NEXT: fidivrl (%eax) # sched: [14:9.50] ; BDVER2-NEXT: #NO_APP @@ -2020,8 +2020,8 @@ define void @test_fdivrp_fidivr(i16 *%a0, i32 *%a1) optsize { ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:1.00] ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:1.00] ; BTVER2-NEXT: #APP -; BTVER2-NEXT: fdivrp %st(1) # sched: [19:19.00] -; BTVER2-NEXT: fdivrp %st(2) # sched: [19:19.00] +; BTVER2-NEXT: fdivrp %st, %st(1) # sched: [19:19.00] +; BTVER2-NEXT: fdivrp %st, %st(2) # sched: [19:19.00] ; BTVER2-NEXT: fidivrs (%ecx) # sched: [24:19.00] ; BTVER2-NEXT: fidivrl (%eax) # sched: [24:19.00] ; BTVER2-NEXT: #NO_APP @@ -2032,8 +2032,8 @@ define void @test_fdivrp_fidivr(i16 *%a0, i32 *%a1) optsize { ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [8:0.50] ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [8:0.50] ; ZNVER1-NEXT: #APP -; ZNVER1-NEXT: fdivrp %st(1) # sched: [15:1.00] -; ZNVER1-NEXT: fdivrp %st(2) # sched: [15:1.00] +; ZNVER1-NEXT: fdivrp %st, %st(1) # sched: [15:1.00] +; ZNVER1-NEXT: fdivrp %st, %st(2) # sched: [15:1.00] ; ZNVER1-NEXT: fidivrs (%ecx) # sched: [22:1.00] ; ZNVER1-NEXT: fidivrl (%eax) # sched: [22:1.00] ; ZNVER1-NEXT: #NO_APP @@ -3243,8 +3243,8 @@ define void @test_fmul(float *%a0, double *%a1) optsize { ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %eax ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %ecx ; GENERIC-NEXT: #APP -; GENERIC-NEXT: fmul %st(0), %st(1) -; GENERIC-NEXT: fmul %st(2) +; GENERIC-NEXT: fmul %st, %st(1) +; GENERIC-NEXT: fmul %st(2), %st ; GENERIC-NEXT: fmuls (%ecx) ; GENERIC-NEXT: fmull (%eax) ; GENERIC-NEXT: #NO_APP @@ -3255,8 +3255,8 @@ define void @test_fmul(float *%a0, double *%a1) optsize { ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [1:1.00] ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [1:1.00] ; ATOM-NEXT: #APP -; ATOM-NEXT: fmul %st(0), %st(1) # sched: [4:4.00] -; ATOM-NEXT: fmul %st(2) # sched: [4:4.00] +; ATOM-NEXT: fmul %st, %st(1) # sched: [4:4.00] +; ATOM-NEXT: fmul %st(2), %st # sched: [4:4.00] ; ATOM-NEXT: fmuls (%ecx) # sched: [4:4.00] ; ATOM-NEXT: fmull (%eax) # sched: [4:4.00] ; ATOM-NEXT: #NO_APP @@ -3267,8 +3267,8 @@ define void @test_fmul(float *%a0, double *%a1) optsize { ; SLM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [3:1.00] ; SLM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [3:1.00] ; SLM-NEXT: #APP -; SLM-NEXT: fmul %st(0), %st(1) # sched: [5:2.00] -; SLM-NEXT: fmul %st(2) # sched: [5:2.00] +; SLM-NEXT: fmul %st, %st(1) # sched: [5:2.00] +; SLM-NEXT: fmul %st(2), %st # sched: [5:2.00] ; SLM-NEXT: fmuls (%ecx) # sched: [8:2.00] ; SLM-NEXT: fmull (%eax) # sched: [8:2.00] ; SLM-NEXT: #NO_APP @@ -3279,8 +3279,8 @@ define void @test_fmul(float *%a0, double *%a1) optsize { ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SANDY-NEXT: #APP -; SANDY-NEXT: fmul %st(0), %st(1) # sched: [5:1.00] -; SANDY-NEXT: fmul %st(2) # sched: [5:1.00] +; SANDY-NEXT: fmul %st, %st(1) # sched: [5:1.00] +; SANDY-NEXT: fmul %st(2), %st # sched: [5:1.00] ; SANDY-NEXT: fmuls (%ecx) # sched: [12:1.00] ; SANDY-NEXT: fmull (%eax) # sched: [12:1.00] ; SANDY-NEXT: #NO_APP @@ -3291,8 +3291,8 @@ define void @test_fmul(float *%a0, double *%a1) optsize { ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; HASWELL-NEXT: #APP -; HASWELL-NEXT: fmul %st(0), %st(1) # sched: [5:1.00] -; HASWELL-NEXT: fmul %st(2) # sched: [5:1.00] +; HASWELL-NEXT: fmul %st, %st(1) # sched: [5:1.00] +; HASWELL-NEXT: fmul %st(2), %st # sched: [5:1.00] ; HASWELL-NEXT: fmuls (%ecx) # sched: [12:1.00] ; HASWELL-NEXT: fmull (%eax) # sched: [12:1.00] ; HASWELL-NEXT: #NO_APP @@ -3303,8 +3303,8 @@ define void @test_fmul(float *%a0, double *%a1) optsize { ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BROADWELL-NEXT: #APP -; BROADWELL-NEXT: fmul %st(0), %st(1) # sched: [5:1.00] -; BROADWELL-NEXT: fmul %st(2) # sched: [5:1.00] +; BROADWELL-NEXT: fmul %st, %st(1) # sched: [5:1.00] +; BROADWELL-NEXT: fmul %st(2), %st # sched: [5:1.00] ; BROADWELL-NEXT: fmuls (%ecx) # sched: [11:1.00] ; BROADWELL-NEXT: fmull (%eax) # sched: [11:1.00] ; BROADWELL-NEXT: #NO_APP @@ -3315,8 +3315,8 @@ define void @test_fmul(float *%a0, double *%a1) optsize { ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKYLAKE-NEXT: #APP -; SKYLAKE-NEXT: fmul %st(0), %st(1) # sched: [4:1.00] -; SKYLAKE-NEXT: fmul %st(2) # sched: [4:1.00] +; SKYLAKE-NEXT: fmul %st, %st(1) # sched: [4:1.00] +; SKYLAKE-NEXT: fmul %st(2), %st # sched: [4:1.00] ; SKYLAKE-NEXT: fmuls (%ecx) # sched: [11:1.00] ; SKYLAKE-NEXT: fmull (%eax) # sched: [11:1.00] ; SKYLAKE-NEXT: #NO_APP @@ -3327,8 +3327,8 @@ define void @test_fmul(float *%a0, double *%a1) optsize { ; SKX-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKX-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKX-NEXT: #APP -; SKX-NEXT: fmul %st(0), %st(1) # sched: [4:1.00] -; SKX-NEXT: fmul %st(2) # sched: [4:1.00] +; SKX-NEXT: fmul %st, %st(1) # sched: [4:1.00] +; SKX-NEXT: fmul %st(2), %st # sched: [4:1.00] ; SKX-NEXT: fmuls (%ecx) # sched: [11:1.00] ; SKX-NEXT: fmull (%eax) # sched: [11:1.00] ; SKX-NEXT: #NO_APP @@ -3339,8 +3339,8 @@ define void @test_fmul(float *%a0, double *%a1) optsize { ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BDVER2-NEXT: #APP -; BDVER2-NEXT: fmul %st(0), %st(1) # sched: [5:1.00] -; BDVER2-NEXT: fmul %st(2) # sched: [5:1.00] +; BDVER2-NEXT: fmul %st, %st(1) # sched: [5:1.00] +; BDVER2-NEXT: fmul %st(2), %st # sched: [5:1.00] ; BDVER2-NEXT: fmuls (%ecx) # sched: [10:1.00] ; BDVER2-NEXT: fmull (%eax) # sched: [10:1.00] ; BDVER2-NEXT: #NO_APP @@ -3351,8 +3351,8 @@ define void @test_fmul(float *%a0, double *%a1) optsize { ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:1.00] ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:1.00] ; BTVER2-NEXT: #APP -; BTVER2-NEXT: fmul %st(0), %st(1) # sched: [2:1.00] -; BTVER2-NEXT: fmul %st(2) # sched: [2:1.00] +; BTVER2-NEXT: fmul %st, %st(1) # sched: [2:1.00] +; BTVER2-NEXT: fmul %st(2), %st # sched: [2:1.00] ; BTVER2-NEXT: fmuls (%ecx) # sched: [7:1.00] ; BTVER2-NEXT: fmull (%eax) # sched: [7:1.00] ; BTVER2-NEXT: #NO_APP @@ -3363,8 +3363,8 @@ define void @test_fmul(float *%a0, double *%a1) optsize { ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [8:0.50] ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [8:0.50] ; ZNVER1-NEXT: #APP -; ZNVER1-NEXT: fmul %st(0), %st(1) # sched: [3:0.50] -; ZNVER1-NEXT: fmul %st(2) # sched: [3:0.50] +; ZNVER1-NEXT: fmul %st, %st(1) # sched: [3:0.50] +; ZNVER1-NEXT: fmul %st(2), %st # sched: [3:0.50] ; ZNVER1-NEXT: fmuls (%ecx) # sched: [10:0.50] ; ZNVER1-NEXT: fmull (%eax) # sched: [10:0.50] ; ZNVER1-NEXT: #NO_APP @@ -3379,8 +3379,8 @@ define void @test_fmulp_fimul(i16 *%a0, i32 *%a1) optsize { ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %eax ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %ecx ; GENERIC-NEXT: #APP -; GENERIC-NEXT: fmulp %st(1) -; GENERIC-NEXT: fmulp %st(2) +; GENERIC-NEXT: fmulp %st, %st(1) +; GENERIC-NEXT: fmulp %st, %st(2) ; GENERIC-NEXT: fimuls (%ecx) ; GENERIC-NEXT: fimull (%eax) ; GENERIC-NEXT: #NO_APP @@ -3391,8 +3391,8 @@ define void @test_fmulp_fimul(i16 *%a0, i32 *%a1) optsize { ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [1:1.00] ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [1:1.00] ; ATOM-NEXT: #APP -; ATOM-NEXT: fmulp %st(1) # sched: [4:4.00] -; ATOM-NEXT: fmulp %st(2) # sched: [4:4.00] +; ATOM-NEXT: fmulp %st, %st(1) # sched: [4:4.00] +; ATOM-NEXT: fmulp %st, %st(2) # sched: [4:4.00] ; ATOM-NEXT: fimuls (%ecx) # sched: [4:4.00] ; ATOM-NEXT: fimull (%eax) # sched: [4:4.00] ; ATOM-NEXT: #NO_APP @@ -3403,8 +3403,8 @@ define void @test_fmulp_fimul(i16 *%a0, i32 *%a1) optsize { ; SLM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [3:1.00] ; SLM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [3:1.00] ; SLM-NEXT: #APP -; SLM-NEXT: fmulp %st(1) # sched: [5:2.00] -; SLM-NEXT: fmulp %st(2) # sched: [5:2.00] +; SLM-NEXT: fmulp %st, %st(1) # sched: [5:2.00] +; SLM-NEXT: fmulp %st, %st(2) # sched: [5:2.00] ; SLM-NEXT: fimuls (%ecx) # sched: [8:2.00] ; SLM-NEXT: fimull (%eax) # sched: [8:2.00] ; SLM-NEXT: #NO_APP @@ -3415,8 +3415,8 @@ define void @test_fmulp_fimul(i16 *%a0, i32 *%a1) optsize { ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SANDY-NEXT: #APP -; SANDY-NEXT: fmulp %st(1) # sched: [5:1.00] -; SANDY-NEXT: fmulp %st(2) # sched: [5:1.00] +; SANDY-NEXT: fmulp %st, %st(1) # sched: [5:1.00] +; SANDY-NEXT: fmulp %st, %st(2) # sched: [5:1.00] ; SANDY-NEXT: fimuls (%ecx) # sched: [15:1.00] ; SANDY-NEXT: fimull (%eax) # sched: [15:1.00] ; SANDY-NEXT: #NO_APP @@ -3427,8 +3427,8 @@ define void @test_fmulp_fimul(i16 *%a0, i32 *%a1) optsize { ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; HASWELL-NEXT: #APP -; HASWELL-NEXT: fmulp %st(1) # sched: [5:1.00] -; HASWELL-NEXT: fmulp %st(2) # sched: [5:1.00] +; HASWELL-NEXT: fmulp %st, %st(1) # sched: [5:1.00] +; HASWELL-NEXT: fmulp %st, %st(2) # sched: [5:1.00] ; HASWELL-NEXT: fimuls (%ecx) # sched: [15:1.00] ; HASWELL-NEXT: fimull (%eax) # sched: [15:1.00] ; HASWELL-NEXT: #NO_APP @@ -3439,8 +3439,8 @@ define void @test_fmulp_fimul(i16 *%a0, i32 *%a1) optsize { ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BROADWELL-NEXT: #APP -; BROADWELL-NEXT: fmulp %st(1) # sched: [5:1.00] -; BROADWELL-NEXT: fmulp %st(2) # sched: [5:1.00] +; BROADWELL-NEXT: fmulp %st, %st(1) # sched: [5:1.00] +; BROADWELL-NEXT: fmulp %st, %st(2) # sched: [5:1.00] ; BROADWELL-NEXT: fimuls (%ecx) # sched: [14:1.00] ; BROADWELL-NEXT: fimull (%eax) # sched: [14:1.00] ; BROADWELL-NEXT: #NO_APP @@ -3451,8 +3451,8 @@ define void @test_fmulp_fimul(i16 *%a0, i32 *%a1) optsize { ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKYLAKE-NEXT: #APP -; SKYLAKE-NEXT: fmulp %st(1) # sched: [4:1.00] -; SKYLAKE-NEXT: fmulp %st(2) # sched: [4:1.00] +; SKYLAKE-NEXT: fmulp %st, %st(1) # sched: [4:1.00] +; SKYLAKE-NEXT: fmulp %st, %st(2) # sched: [4:1.00] ; SKYLAKE-NEXT: fimuls (%ecx) # sched: [14:1.00] ; SKYLAKE-NEXT: fimull (%eax) # sched: [14:1.00] ; SKYLAKE-NEXT: #NO_APP @@ -3463,8 +3463,8 @@ define void @test_fmulp_fimul(i16 *%a0, i32 *%a1) optsize { ; SKX-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKX-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKX-NEXT: #APP -; SKX-NEXT: fmulp %st(1) # sched: [4:1.00] -; SKX-NEXT: fmulp %st(2) # sched: [4:1.00] +; SKX-NEXT: fmulp %st, %st(1) # sched: [4:1.00] +; SKX-NEXT: fmulp %st, %st(2) # sched: [4:1.00] ; SKX-NEXT: fimuls (%ecx) # sched: [14:1.00] ; SKX-NEXT: fimull (%eax) # sched: [14:1.00] ; SKX-NEXT: #NO_APP @@ -3475,8 +3475,8 @@ define void @test_fmulp_fimul(i16 *%a0, i32 *%a1) optsize { ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BDVER2-NEXT: #APP -; BDVER2-NEXT: fmulp %st(1) # sched: [5:1.00] -; BDVER2-NEXT: fmulp %st(2) # sched: [5:1.00] +; BDVER2-NEXT: fmulp %st, %st(1) # sched: [5:1.00] +; BDVER2-NEXT: fmulp %st, %st(2) # sched: [5:1.00] ; BDVER2-NEXT: fimuls (%ecx) # sched: [10:1.00] ; BDVER2-NEXT: fimull (%eax) # sched: [10:1.00] ; BDVER2-NEXT: #NO_APP @@ -3487,8 +3487,8 @@ define void @test_fmulp_fimul(i16 *%a0, i32 *%a1) optsize { ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:1.00] ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:1.00] ; BTVER2-NEXT: #APP -; BTVER2-NEXT: fmulp %st(1) # sched: [2:1.00] -; BTVER2-NEXT: fmulp %st(2) # sched: [2:1.00] +; BTVER2-NEXT: fmulp %st, %st(1) # sched: [2:1.00] +; BTVER2-NEXT: fmulp %st, %st(2) # sched: [2:1.00] ; BTVER2-NEXT: fimuls (%ecx) # sched: [7:1.00] ; BTVER2-NEXT: fimull (%eax) # sched: [7:1.00] ; BTVER2-NEXT: #NO_APP @@ -3499,8 +3499,8 @@ define void @test_fmulp_fimul(i16 *%a0, i32 *%a1) optsize { ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [8:0.50] ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [8:0.50] ; ZNVER1-NEXT: #APP -; ZNVER1-NEXT: fmulp %st(1) # sched: [3:0.50] -; ZNVER1-NEXT: fmulp %st(2) # sched: [3:0.50] +; ZNVER1-NEXT: fmulp %st, %st(1) # sched: [3:0.50] +; ZNVER1-NEXT: fmulp %st, %st(2) # sched: [3:0.50] ; ZNVER1-NEXT: fimuls (%ecx) # sched: [10:0.50] ; ZNVER1-NEXT: fimull (%eax) # sched: [10:0.50] ; ZNVER1-NEXT: #NO_APP @@ -4983,8 +4983,8 @@ define void @test_fsub(float *%a0, double *%a1) optsize { ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %eax ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %ecx ; GENERIC-NEXT: #APP -; GENERIC-NEXT: fsub %st(0), %st(1) -; GENERIC-NEXT: fsub %st(2) +; GENERIC-NEXT: fsub %st, %st(1) +; GENERIC-NEXT: fsub %st(2), %st ; GENERIC-NEXT: fsubs (%ecx) ; GENERIC-NEXT: fsubl (%eax) ; GENERIC-NEXT: #NO_APP @@ -4995,8 +4995,8 @@ define void @test_fsub(float *%a0, double *%a1) optsize { ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [1:1.00] ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [1:1.00] ; ATOM-NEXT: #APP -; ATOM-NEXT: fsub %st(0), %st(1) # sched: [5:5.00] -; ATOM-NEXT: fsub %st(2) # sched: [5:5.00] +; ATOM-NEXT: fsub %st, %st(1) # sched: [5:5.00] +; ATOM-NEXT: fsub %st(2), %st # sched: [5:5.00] ; ATOM-NEXT: fsubs (%ecx) # sched: [5:5.00] ; ATOM-NEXT: fsubl (%eax) # sched: [5:5.00] ; ATOM-NEXT: #NO_APP @@ -5007,8 +5007,8 @@ define void @test_fsub(float *%a0, double *%a1) optsize { ; SLM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [3:1.00] ; SLM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [3:1.00] ; SLM-NEXT: #APP -; SLM-NEXT: fsub %st(0), %st(1) # sched: [3:1.00] -; SLM-NEXT: fsub %st(2) # sched: [3:1.00] +; SLM-NEXT: fsub %st, %st(1) # sched: [3:1.00] +; SLM-NEXT: fsub %st(2), %st # sched: [3:1.00] ; SLM-NEXT: fsubs (%ecx) # sched: [6:1.00] ; SLM-NEXT: fsubl (%eax) # sched: [6:1.00] ; SLM-NEXT: #NO_APP @@ -5019,8 +5019,8 @@ define void @test_fsub(float *%a0, double *%a1) optsize { ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SANDY-NEXT: #APP -; SANDY-NEXT: fsub %st(0), %st(1) # sched: [3:1.00] -; SANDY-NEXT: fsub %st(2) # sched: [3:1.00] +; SANDY-NEXT: fsub %st, %st(1) # sched: [3:1.00] +; SANDY-NEXT: fsub %st(2), %st # sched: [3:1.00] ; SANDY-NEXT: fsubs (%ecx) # sched: [10:1.00] ; SANDY-NEXT: fsubl (%eax) # sched: [10:1.00] ; SANDY-NEXT: #NO_APP @@ -5031,8 +5031,8 @@ define void @test_fsub(float *%a0, double *%a1) optsize { ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; HASWELL-NEXT: #APP -; HASWELL-NEXT: fsub %st(0), %st(1) # sched: [3:1.00] -; HASWELL-NEXT: fsub %st(2) # sched: [3:1.00] +; HASWELL-NEXT: fsub %st, %st(1) # sched: [3:1.00] +; HASWELL-NEXT: fsub %st(2), %st # sched: [3:1.00] ; HASWELL-NEXT: fsubs (%ecx) # sched: [10:1.00] ; HASWELL-NEXT: fsubl (%eax) # sched: [10:1.00] ; HASWELL-NEXT: #NO_APP @@ -5043,8 +5043,8 @@ define void @test_fsub(float *%a0, double *%a1) optsize { ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BROADWELL-NEXT: #APP -; BROADWELL-NEXT: fsub %st(0), %st(1) # sched: [3:1.00] -; BROADWELL-NEXT: fsub %st(2) # sched: [3:1.00] +; BROADWELL-NEXT: fsub %st, %st(1) # sched: [3:1.00] +; BROADWELL-NEXT: fsub %st(2), %st # sched: [3:1.00] ; BROADWELL-NEXT: fsubs (%ecx) # sched: [9:1.00] ; BROADWELL-NEXT: fsubl (%eax) # sched: [9:1.00] ; BROADWELL-NEXT: #NO_APP @@ -5055,8 +5055,8 @@ define void @test_fsub(float *%a0, double *%a1) optsize { ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKYLAKE-NEXT: #APP -; SKYLAKE-NEXT: fsub %st(0), %st(1) # sched: [3:1.00] -; SKYLAKE-NEXT: fsub %st(2) # sched: [3:1.00] +; SKYLAKE-NEXT: fsub %st, %st(1) # sched: [3:1.00] +; SKYLAKE-NEXT: fsub %st(2), %st # sched: [3:1.00] ; SKYLAKE-NEXT: fsubs (%ecx) # sched: [10:1.00] ; SKYLAKE-NEXT: fsubl (%eax) # sched: [10:1.00] ; SKYLAKE-NEXT: #NO_APP @@ -5067,8 +5067,8 @@ define void @test_fsub(float *%a0, double *%a1) optsize { ; SKX-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKX-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKX-NEXT: #APP -; SKX-NEXT: fsub %st(0), %st(1) # sched: [3:1.00] -; SKX-NEXT: fsub %st(2) # sched: [3:1.00] +; SKX-NEXT: fsub %st, %st(1) # sched: [3:1.00] +; SKX-NEXT: fsub %st(2), %st # sched: [3:1.00] ; SKX-NEXT: fsubs (%ecx) # sched: [10:1.00] ; SKX-NEXT: fsubl (%eax) # sched: [10:1.00] ; SKX-NEXT: #NO_APP @@ -5079,8 +5079,8 @@ define void @test_fsub(float *%a0, double *%a1) optsize { ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BDVER2-NEXT: #APP -; BDVER2-NEXT: fsub %st(0), %st(1) # sched: [5:1.00] -; BDVER2-NEXT: fsub %st(2) # sched: [5:1.00] +; BDVER2-NEXT: fsub %st, %st(1) # sched: [5:1.00] +; BDVER2-NEXT: fsub %st(2), %st # sched: [5:1.00] ; BDVER2-NEXT: fsubs (%ecx) # sched: [10:1.00] ; BDVER2-NEXT: fsubl (%eax) # sched: [10:1.00] ; BDVER2-NEXT: #NO_APP @@ -5091,8 +5091,8 @@ define void @test_fsub(float *%a0, double *%a1) optsize { ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:1.00] ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:1.00] ; BTVER2-NEXT: #APP -; BTVER2-NEXT: fsub %st(0), %st(1) # sched: [3:1.00] -; BTVER2-NEXT: fsub %st(2) # sched: [3:1.00] +; BTVER2-NEXT: fsub %st, %st(1) # sched: [3:1.00] +; BTVER2-NEXT: fsub %st(2), %st # sched: [3:1.00] ; BTVER2-NEXT: fsubs (%ecx) # sched: [8:1.00] ; BTVER2-NEXT: fsubl (%eax) # sched: [8:1.00] ; BTVER2-NEXT: #NO_APP @@ -5103,8 +5103,8 @@ define void @test_fsub(float *%a0, double *%a1) optsize { ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [8:0.50] ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [8:0.50] ; ZNVER1-NEXT: #APP -; ZNVER1-NEXT: fsub %st(0), %st(1) # sched: [3:1.00] -; ZNVER1-NEXT: fsub %st(2) # sched: [3:1.00] +; ZNVER1-NEXT: fsub %st, %st(1) # sched: [3:1.00] +; ZNVER1-NEXT: fsub %st(2), %st # sched: [3:1.00] ; ZNVER1-NEXT: fsubs (%ecx) # sched: [10:1.00] ; ZNVER1-NEXT: fsubl (%eax) # sched: [10:1.00] ; ZNVER1-NEXT: #NO_APP @@ -5119,8 +5119,8 @@ define void @test_fsubp_fisub(i16 *%a0, i32 *%a1) optsize { ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %eax ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %ecx ; GENERIC-NEXT: #APP -; GENERIC-NEXT: fsubp %st(1) -; GENERIC-NEXT: fsubp %st(2) +; GENERIC-NEXT: fsubp %st, %st(1) +; GENERIC-NEXT: fsubp %st, %st(2) ; GENERIC-NEXT: fisubs (%ecx) ; GENERIC-NEXT: fisubl (%eax) ; GENERIC-NEXT: #NO_APP @@ -5131,8 +5131,8 @@ define void @test_fsubp_fisub(i16 *%a0, i32 *%a1) optsize { ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [1:1.00] ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [1:1.00] ; ATOM-NEXT: #APP -; ATOM-NEXT: fsubp %st(1) # sched: [5:5.00] -; ATOM-NEXT: fsubp %st(2) # sched: [5:5.00] +; ATOM-NEXT: fsubp %st, %st(1) # sched: [5:5.00] +; ATOM-NEXT: fsubp %st, %st(2) # sched: [5:5.00] ; ATOM-NEXT: fisubs (%ecx) # sched: [5:5.00] ; ATOM-NEXT: fisubl (%eax) # sched: [5:5.00] ; ATOM-NEXT: #NO_APP @@ -5143,8 +5143,8 @@ define void @test_fsubp_fisub(i16 *%a0, i32 *%a1) optsize { ; SLM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [3:1.00] ; SLM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [3:1.00] ; SLM-NEXT: #APP -; SLM-NEXT: fsubp %st(1) # sched: [3:1.00] -; SLM-NEXT: fsubp %st(2) # sched: [3:1.00] +; SLM-NEXT: fsubp %st, %st(1) # sched: [3:1.00] +; SLM-NEXT: fsubp %st, %st(2) # sched: [3:1.00] ; SLM-NEXT: fisubs (%ecx) # sched: [6:1.00] ; SLM-NEXT: fisubl (%eax) # sched: [6:1.00] ; SLM-NEXT: #NO_APP @@ -5155,8 +5155,8 @@ define void @test_fsubp_fisub(i16 *%a0, i32 *%a1) optsize { ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SANDY-NEXT: #APP -; SANDY-NEXT: fsubp %st(1) # sched: [3:1.00] -; SANDY-NEXT: fsubp %st(2) # sched: [3:1.00] +; SANDY-NEXT: fsubp %st, %st(1) # sched: [3:1.00] +; SANDY-NEXT: fsubp %st, %st(2) # sched: [3:1.00] ; SANDY-NEXT: fisubs (%ecx) # sched: [13:2.00] ; SANDY-NEXT: fisubl (%eax) # sched: [13:2.00] ; SANDY-NEXT: #NO_APP @@ -5167,8 +5167,8 @@ define void @test_fsubp_fisub(i16 *%a0, i32 *%a1) optsize { ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; HASWELL-NEXT: #APP -; HASWELL-NEXT: fsubp %st(1) # sched: [3:1.00] -; HASWELL-NEXT: fsubp %st(2) # sched: [3:1.00] +; HASWELL-NEXT: fsubp %st, %st(1) # sched: [3:1.00] +; HASWELL-NEXT: fsubp %st, %st(2) # sched: [3:1.00] ; HASWELL-NEXT: fisubs (%ecx) # sched: [13:2.00] ; HASWELL-NEXT: fisubl (%eax) # sched: [13:2.00] ; HASWELL-NEXT: #NO_APP @@ -5179,8 +5179,8 @@ define void @test_fsubp_fisub(i16 *%a0, i32 *%a1) optsize { ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BROADWELL-NEXT: #APP -; BROADWELL-NEXT: fsubp %st(1) # sched: [3:1.00] -; BROADWELL-NEXT: fsubp %st(2) # sched: [3:1.00] +; BROADWELL-NEXT: fsubp %st, %st(1) # sched: [3:1.00] +; BROADWELL-NEXT: fsubp %st, %st(2) # sched: [3:1.00] ; BROADWELL-NEXT: fisubs (%ecx) # sched: [12:2.00] ; BROADWELL-NEXT: fisubl (%eax) # sched: [12:2.00] ; BROADWELL-NEXT: #NO_APP @@ -5191,8 +5191,8 @@ define void @test_fsubp_fisub(i16 *%a0, i32 *%a1) optsize { ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKYLAKE-NEXT: #APP -; SKYLAKE-NEXT: fsubp %st(1) # sched: [3:1.00] -; SKYLAKE-NEXT: fsubp %st(2) # sched: [3:1.00] +; SKYLAKE-NEXT: fsubp %st, %st(1) # sched: [3:1.00] +; SKYLAKE-NEXT: fsubp %st, %st(2) # sched: [3:1.00] ; SKYLAKE-NEXT: fisubs (%ecx) # sched: [13:2.00] ; SKYLAKE-NEXT: fisubl (%eax) # sched: [13:2.00] ; SKYLAKE-NEXT: #NO_APP @@ -5203,8 +5203,8 @@ define void @test_fsubp_fisub(i16 *%a0, i32 *%a1) optsize { ; SKX-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKX-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKX-NEXT: #APP -; SKX-NEXT: fsubp %st(1) # sched: [3:1.00] -; SKX-NEXT: fsubp %st(2) # sched: [3:1.00] +; SKX-NEXT: fsubp %st, %st(1) # sched: [3:1.00] +; SKX-NEXT: fsubp %st, %st(2) # sched: [3:1.00] ; SKX-NEXT: fisubs (%ecx) # sched: [13:2.00] ; SKX-NEXT: fisubl (%eax) # sched: [13:2.00] ; SKX-NEXT: #NO_APP @@ -5215,8 +5215,8 @@ define void @test_fsubp_fisub(i16 *%a0, i32 *%a1) optsize { ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BDVER2-NEXT: #APP -; BDVER2-NEXT: fsubp %st(1) # sched: [5:1.00] -; BDVER2-NEXT: fsubp %st(2) # sched: [5:1.00] +; BDVER2-NEXT: fsubp %st, %st(1) # sched: [5:1.00] +; BDVER2-NEXT: fsubp %st, %st(2) # sched: [5:1.00] ; BDVER2-NEXT: fisubs (%ecx) # sched: [10:1.00] ; BDVER2-NEXT: fisubl (%eax) # sched: [10:1.00] ; BDVER2-NEXT: #NO_APP @@ -5227,8 +5227,8 @@ define void @test_fsubp_fisub(i16 *%a0, i32 *%a1) optsize { ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:1.00] ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:1.00] ; BTVER2-NEXT: #APP -; BTVER2-NEXT: fsubp %st(1) # sched: [3:1.00] -; BTVER2-NEXT: fsubp %st(2) # sched: [3:1.00] +; BTVER2-NEXT: fsubp %st, %st(1) # sched: [3:1.00] +; BTVER2-NEXT: fsubp %st, %st(2) # sched: [3:1.00] ; BTVER2-NEXT: fisubs (%ecx) # sched: [8:1.00] ; BTVER2-NEXT: fisubl (%eax) # sched: [8:1.00] ; BTVER2-NEXT: #NO_APP @@ -5239,8 +5239,8 @@ define void @test_fsubp_fisub(i16 *%a0, i32 *%a1) optsize { ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [8:0.50] ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [8:0.50] ; ZNVER1-NEXT: #APP -; ZNVER1-NEXT: fsubp %st(1) # sched: [3:1.00] -; ZNVER1-NEXT: fsubp %st(2) # sched: [3:1.00] +; ZNVER1-NEXT: fsubp %st, %st(1) # sched: [3:1.00] +; ZNVER1-NEXT: fsubp %st, %st(2) # sched: [3:1.00] ; ZNVER1-NEXT: fisubs (%ecx) # sched: [10:1.00] ; ZNVER1-NEXT: fisubl (%eax) # sched: [10:1.00] ; ZNVER1-NEXT: #NO_APP @@ -5255,8 +5255,8 @@ define void @test_fsubr(float *%a0, double *%a1) optsize { ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %eax ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %ecx ; GENERIC-NEXT: #APP -; GENERIC-NEXT: fsubr %st(0), %st(1) -; GENERIC-NEXT: fsubr %st(2) +; GENERIC-NEXT: fsubr %st, %st(1) +; GENERIC-NEXT: fsubr %st(2), %st ; GENERIC-NEXT: fsubrs (%ecx) ; GENERIC-NEXT: fsubrl (%eax) ; GENERIC-NEXT: #NO_APP @@ -5267,8 +5267,8 @@ define void @test_fsubr(float *%a0, double *%a1) optsize { ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [1:1.00] ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [1:1.00] ; ATOM-NEXT: #APP -; ATOM-NEXT: fsubr %st(0), %st(1) # sched: [5:5.00] -; ATOM-NEXT: fsubr %st(2) # sched: [5:5.00] +; ATOM-NEXT: fsubr %st, %st(1) # sched: [5:5.00] +; ATOM-NEXT: fsubr %st(2), %st # sched: [5:5.00] ; ATOM-NEXT: fsubrs (%ecx) # sched: [5:5.00] ; ATOM-NEXT: fsubrl (%eax) # sched: [5:5.00] ; ATOM-NEXT: #NO_APP @@ -5279,8 +5279,8 @@ define void @test_fsubr(float *%a0, double *%a1) optsize { ; SLM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [3:1.00] ; SLM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [3:1.00] ; SLM-NEXT: #APP -; SLM-NEXT: fsubr %st(0), %st(1) # sched: [3:1.00] -; SLM-NEXT: fsubr %st(2) # sched: [3:1.00] +; SLM-NEXT: fsubr %st, %st(1) # sched: [3:1.00] +; SLM-NEXT: fsubr %st(2), %st # sched: [3:1.00] ; SLM-NEXT: fsubrs (%ecx) # sched: [6:1.00] ; SLM-NEXT: fsubrl (%eax) # sched: [6:1.00] ; SLM-NEXT: #NO_APP @@ -5291,8 +5291,8 @@ define void @test_fsubr(float *%a0, double *%a1) optsize { ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SANDY-NEXT: #APP -; SANDY-NEXT: fsubr %st(0), %st(1) # sched: [3:1.00] -; SANDY-NEXT: fsubr %st(2) # sched: [3:1.00] +; SANDY-NEXT: fsubr %st, %st(1) # sched: [3:1.00] +; SANDY-NEXT: fsubr %st(2), %st # sched: [3:1.00] ; SANDY-NEXT: fsubrs (%ecx) # sched: [10:1.00] ; SANDY-NEXT: fsubrl (%eax) # sched: [10:1.00] ; SANDY-NEXT: #NO_APP @@ -5303,8 +5303,8 @@ define void @test_fsubr(float *%a0, double *%a1) optsize { ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; HASWELL-NEXT: #APP -; HASWELL-NEXT: fsubr %st(0), %st(1) # sched: [3:1.00] -; HASWELL-NEXT: fsubr %st(2) # sched: [3:1.00] +; HASWELL-NEXT: fsubr %st, %st(1) # sched: [3:1.00] +; HASWELL-NEXT: fsubr %st(2), %st # sched: [3:1.00] ; HASWELL-NEXT: fsubrs (%ecx) # sched: [10:1.00] ; HASWELL-NEXT: fsubrl (%eax) # sched: [10:1.00] ; HASWELL-NEXT: #NO_APP @@ -5315,8 +5315,8 @@ define void @test_fsubr(float *%a0, double *%a1) optsize { ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BROADWELL-NEXT: #APP -; BROADWELL-NEXT: fsubr %st(0), %st(1) # sched: [3:1.00] -; BROADWELL-NEXT: fsubr %st(2) # sched: [3:1.00] +; BROADWELL-NEXT: fsubr %st, %st(1) # sched: [3:1.00] +; BROADWELL-NEXT: fsubr %st(2), %st # sched: [3:1.00] ; BROADWELL-NEXT: fsubrs (%ecx) # sched: [9:1.00] ; BROADWELL-NEXT: fsubrl (%eax) # sched: [9:1.00] ; BROADWELL-NEXT: #NO_APP @@ -5327,8 +5327,8 @@ define void @test_fsubr(float *%a0, double *%a1) optsize { ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKYLAKE-NEXT: #APP -; SKYLAKE-NEXT: fsubr %st(0), %st(1) # sched: [3:1.00] -; SKYLAKE-NEXT: fsubr %st(2) # sched: [3:1.00] +; SKYLAKE-NEXT: fsubr %st, %st(1) # sched: [3:1.00] +; SKYLAKE-NEXT: fsubr %st(2), %st # sched: [3:1.00] ; SKYLAKE-NEXT: fsubrs (%ecx) # sched: [10:1.00] ; SKYLAKE-NEXT: fsubrl (%eax) # sched: [10:1.00] ; SKYLAKE-NEXT: #NO_APP @@ -5339,8 +5339,8 @@ define void @test_fsubr(float *%a0, double *%a1) optsize { ; SKX-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKX-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKX-NEXT: #APP -; SKX-NEXT: fsubr %st(0), %st(1) # sched: [3:1.00] -; SKX-NEXT: fsubr %st(2) # sched: [3:1.00] +; SKX-NEXT: fsubr %st, %st(1) # sched: [3:1.00] +; SKX-NEXT: fsubr %st(2), %st # sched: [3:1.00] ; SKX-NEXT: fsubrs (%ecx) # sched: [10:1.00] ; SKX-NEXT: fsubrl (%eax) # sched: [10:1.00] ; SKX-NEXT: #NO_APP @@ -5351,8 +5351,8 @@ define void @test_fsubr(float *%a0, double *%a1) optsize { ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BDVER2-NEXT: #APP -; BDVER2-NEXT: fsubr %st(0), %st(1) # sched: [5:1.00] -; BDVER2-NEXT: fsubr %st(2) # sched: [5:1.00] +; BDVER2-NEXT: fsubr %st, %st(1) # sched: [5:1.00] +; BDVER2-NEXT: fsubr %st(2), %st # sched: [5:1.00] ; BDVER2-NEXT: fsubrs (%ecx) # sched: [10:1.00] ; BDVER2-NEXT: fsubrl (%eax) # sched: [10:1.00] ; BDVER2-NEXT: #NO_APP @@ -5363,8 +5363,8 @@ define void @test_fsubr(float *%a0, double *%a1) optsize { ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:1.00] ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:1.00] ; BTVER2-NEXT: #APP -; BTVER2-NEXT: fsubr %st(0), %st(1) # sched: [3:1.00] -; BTVER2-NEXT: fsubr %st(2) # sched: [3:1.00] +; BTVER2-NEXT: fsubr %st, %st(1) # sched: [3:1.00] +; BTVER2-NEXT: fsubr %st(2), %st # sched: [3:1.00] ; BTVER2-NEXT: fsubrs (%ecx) # sched: [8:1.00] ; BTVER2-NEXT: fsubrl (%eax) # sched: [8:1.00] ; BTVER2-NEXT: #NO_APP @@ -5375,8 +5375,8 @@ define void @test_fsubr(float *%a0, double *%a1) optsize { ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [8:0.50] ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [8:0.50] ; ZNVER1-NEXT: #APP -; ZNVER1-NEXT: fsubr %st(0), %st(1) # sched: [3:1.00] -; ZNVER1-NEXT: fsubr %st(2) # sched: [3:1.00] +; ZNVER1-NEXT: fsubr %st, %st(1) # sched: [3:1.00] +; ZNVER1-NEXT: fsubr %st(2), %st # sched: [3:1.00] ; ZNVER1-NEXT: fsubrs (%ecx) # sched: [10:1.00] ; ZNVER1-NEXT: fsubrl (%eax) # sched: [10:1.00] ; ZNVER1-NEXT: #NO_APP @@ -5391,8 +5391,8 @@ define void @test_fsubrp_fisubr(i16 *%a0, i32 *%a1) optsize { ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %eax ; GENERIC-NEXT: movl {{[0-9]+}}(%esp), %ecx ; GENERIC-NEXT: #APP -; GENERIC-NEXT: fsubrp %st(1) -; GENERIC-NEXT: fsubrp %st(2) +; GENERIC-NEXT: fsubrp %st, %st(1) +; GENERIC-NEXT: fsubrp %st, %st(2) ; GENERIC-NEXT: fisubrs (%ecx) ; GENERIC-NEXT: fisubrl (%eax) ; GENERIC-NEXT: #NO_APP @@ -5403,8 +5403,8 @@ define void @test_fsubrp_fisubr(i16 *%a0, i32 *%a1) optsize { ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [1:1.00] ; ATOM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [1:1.00] ; ATOM-NEXT: #APP -; ATOM-NEXT: fsubrp %st(1) # sched: [5:5.00] -; ATOM-NEXT: fsubrp %st(2) # sched: [5:5.00] +; ATOM-NEXT: fsubrp %st, %st(1) # sched: [5:5.00] +; ATOM-NEXT: fsubrp %st, %st(2) # sched: [5:5.00] ; ATOM-NEXT: fisubrs (%ecx) # sched: [5:5.00] ; ATOM-NEXT: fisubrl (%eax) # sched: [5:5.00] ; ATOM-NEXT: #NO_APP @@ -5415,8 +5415,8 @@ define void @test_fsubrp_fisubr(i16 *%a0, i32 *%a1) optsize { ; SLM-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [3:1.00] ; SLM-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [3:1.00] ; SLM-NEXT: #APP -; SLM-NEXT: fsubrp %st(1) # sched: [3:1.00] -; SLM-NEXT: fsubrp %st(2) # sched: [3:1.00] +; SLM-NEXT: fsubrp %st, %st(1) # sched: [3:1.00] +; SLM-NEXT: fsubrp %st, %st(2) # sched: [3:1.00] ; SLM-NEXT: fisubrs (%ecx) # sched: [6:1.00] ; SLM-NEXT: fisubrl (%eax) # sched: [6:1.00] ; SLM-NEXT: #NO_APP @@ -5427,8 +5427,8 @@ define void @test_fsubrp_fisubr(i16 *%a0, i32 *%a1) optsize { ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SANDY-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SANDY-NEXT: #APP -; SANDY-NEXT: fsubrp %st(1) # sched: [3:1.00] -; SANDY-NEXT: fsubrp %st(2) # sched: [3:1.00] +; SANDY-NEXT: fsubrp %st, %st(1) # sched: [3:1.00] +; SANDY-NEXT: fsubrp %st, %st(2) # sched: [3:1.00] ; SANDY-NEXT: fisubrs (%ecx) # sched: [13:2.00] ; SANDY-NEXT: fisubrl (%eax) # sched: [13:2.00] ; SANDY-NEXT: #NO_APP @@ -5439,8 +5439,8 @@ define void @test_fsubrp_fisubr(i16 *%a0, i32 *%a1) optsize { ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; HASWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; HASWELL-NEXT: #APP -; HASWELL-NEXT: fsubrp %st(1) # sched: [3:1.00] -; HASWELL-NEXT: fsubrp %st(2) # sched: [3:1.00] +; HASWELL-NEXT: fsubrp %st, %st(1) # sched: [3:1.00] +; HASWELL-NEXT: fsubrp %st, %st(2) # sched: [3:1.00] ; HASWELL-NEXT: fisubrs (%ecx) # sched: [13:2.00] ; HASWELL-NEXT: fisubrl (%eax) # sched: [13:2.00] ; HASWELL-NEXT: #NO_APP @@ -5451,8 +5451,8 @@ define void @test_fsubrp_fisubr(i16 *%a0, i32 *%a1) optsize { ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BROADWELL-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BROADWELL-NEXT: #APP -; BROADWELL-NEXT: fsubrp %st(1) # sched: [3:1.00] -; BROADWELL-NEXT: fsubrp %st(2) # sched: [3:1.00] +; BROADWELL-NEXT: fsubrp %st, %st(1) # sched: [3:1.00] +; BROADWELL-NEXT: fsubrp %st, %st(2) # sched: [3:1.00] ; BROADWELL-NEXT: fisubrs (%ecx) # sched: [12:2.00] ; BROADWELL-NEXT: fisubrl (%eax) # sched: [12:2.00] ; BROADWELL-NEXT: #NO_APP @@ -5463,8 +5463,8 @@ define void @test_fsubrp_fisubr(i16 *%a0, i32 *%a1) optsize { ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKYLAKE-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKYLAKE-NEXT: #APP -; SKYLAKE-NEXT: fsubrp %st(1) # sched: [3:1.00] -; SKYLAKE-NEXT: fsubrp %st(2) # sched: [3:1.00] +; SKYLAKE-NEXT: fsubrp %st, %st(1) # sched: [3:1.00] +; SKYLAKE-NEXT: fsubrp %st, %st(2) # sched: [3:1.00] ; SKYLAKE-NEXT: fisubrs (%ecx) # sched: [13:2.00] ; SKYLAKE-NEXT: fisubrl (%eax) # sched: [13:2.00] ; SKYLAKE-NEXT: #NO_APP @@ -5475,8 +5475,8 @@ define void @test_fsubrp_fisubr(i16 *%a0, i32 *%a1) optsize { ; SKX-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; SKX-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; SKX-NEXT: #APP -; SKX-NEXT: fsubrp %st(1) # sched: [3:1.00] -; SKX-NEXT: fsubrp %st(2) # sched: [3:1.00] +; SKX-NEXT: fsubrp %st, %st(1) # sched: [3:1.00] +; SKX-NEXT: fsubrp %st, %st(2) # sched: [3:1.00] ; SKX-NEXT: fisubrs (%ecx) # sched: [13:2.00] ; SKX-NEXT: fisubrl (%eax) # sched: [13:2.00] ; SKX-NEXT: #NO_APP @@ -5487,8 +5487,8 @@ define void @test_fsubrp_fisubr(i16 *%a0, i32 *%a1) optsize { ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:0.50] ; BDVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:0.50] ; BDVER2-NEXT: #APP -; BDVER2-NEXT: fsubrp %st(1) # sched: [5:1.00] -; BDVER2-NEXT: fsubrp %st(2) # sched: [5:1.00] +; BDVER2-NEXT: fsubrp %st, %st(1) # sched: [5:1.00] +; BDVER2-NEXT: fsubrp %st, %st(2) # sched: [5:1.00] ; BDVER2-NEXT: fisubrs (%ecx) # sched: [10:1.00] ; BDVER2-NEXT: fisubrl (%eax) # sched: [10:1.00] ; BDVER2-NEXT: #NO_APP @@ -5499,8 +5499,8 @@ define void @test_fsubrp_fisubr(i16 *%a0, i32 *%a1) optsize { ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [5:1.00] ; BTVER2-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [5:1.00] ; BTVER2-NEXT: #APP -; BTVER2-NEXT: fsubrp %st(1) # sched: [3:1.00] -; BTVER2-NEXT: fsubrp %st(2) # sched: [3:1.00] +; BTVER2-NEXT: fsubrp %st, %st(1) # sched: [3:1.00] +; BTVER2-NEXT: fsubrp %st, %st(2) # sched: [3:1.00] ; BTVER2-NEXT: fisubrs (%ecx) # sched: [8:1.00] ; BTVER2-NEXT: fisubrl (%eax) # sched: [8:1.00] ; BTVER2-NEXT: #NO_APP @@ -5511,8 +5511,8 @@ define void @test_fsubrp_fisubr(i16 *%a0, i32 *%a1) optsize { ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %eax # sched: [8:0.50] ; ZNVER1-NEXT: movl {{[0-9]+}}(%esp), %ecx # sched: [8:0.50] ; ZNVER1-NEXT: #APP -; ZNVER1-NEXT: fsubrp %st(1) # sched: [3:1.00] -; ZNVER1-NEXT: fsubrp %st(2) # sched: [3:1.00] +; ZNVER1-NEXT: fsubrp %st, %st(1) # sched: [3:1.00] +; ZNVER1-NEXT: fsubrp %st, %st(2) # sched: [3:1.00] ; ZNVER1-NEXT: fisubrs (%ecx) # sched: [10:1.00] ; ZNVER1-NEXT: fisubrl (%eax) # sched: [10:1.00] ; ZNVER1-NEXT: #NO_APP @@ -5731,88 +5731,88 @@ define void @test_fucomi_fucomip() optsize { ; GENERIC-LABEL: test_fucomi_fucomip: ; GENERIC: # %bb.0: ; GENERIC-NEXT: #APP -; GENERIC-NEXT: fucomi %st(3) -; GENERIC-NEXT: fucompi %st(3) +; GENERIC-NEXT: fucomi %st(3), %st +; GENERIC-NEXT: fucompi %st(3), %st ; GENERIC-NEXT: #NO_APP ; GENERIC-NEXT: retl ; ; ATOM-LABEL: test_fucomi_fucomip: ; ATOM: # %bb.0: ; ATOM-NEXT: #APP -; ATOM-NEXT: fucomi %st(3) # sched: [9:4.50] -; ATOM-NEXT: fucompi %st(3) # sched: [9:4.50] +; ATOM-NEXT: fucomi %st(3), %st # sched: [9:4.50] +; ATOM-NEXT: fucompi %st(3), %st # sched: [9:4.50] ; ATOM-NEXT: #NO_APP ; ATOM-NEXT: retl # sched: [79:39.50] ; ; SLM-LABEL: test_fucomi_fucomip: ; SLM: # %bb.0: ; SLM-NEXT: #APP -; SLM-NEXT: fucomi %st(3) # sched: [3:1.00] -; SLM-NEXT: fucompi %st(3) # sched: [3:1.00] +; SLM-NEXT: fucomi %st(3), %st # sched: [3:1.00] +; SLM-NEXT: fucompi %st(3), %st # sched: [3:1.00] ; SLM-NEXT: #NO_APP ; SLM-NEXT: retl # sched: [4:1.00] ; ; SANDY-LABEL: test_fucomi_fucomip: ; SANDY: # %bb.0: ; SANDY-NEXT: #APP -; SANDY-NEXT: fucomi %st(3) # sched: [3:1.00] -; SANDY-NEXT: fucompi %st(3) # sched: [3:1.00] +; SANDY-NEXT: fucomi %st(3), %st # sched: [3:1.00] +; SANDY-NEXT: fucompi %st(3), %st # sched: [3:1.00] ; SANDY-NEXT: #NO_APP ; SANDY-NEXT: retl # sched: [6:1.00] ; ; HASWELL-LABEL: test_fucomi_fucomip: ; HASWELL: # %bb.0: ; HASWELL-NEXT: #APP -; HASWELL-NEXT: fucomi %st(3) # sched: [1:0.50] -; HASWELL-NEXT: fucompi %st(3) # sched: [1:0.50] +; HASWELL-NEXT: fucomi %st(3), %st # sched: [1:0.50] +; HASWELL-NEXT: fucompi %st(3), %st # sched: [1:0.50] ; HASWELL-NEXT: #NO_APP ; HASWELL-NEXT: retl # sched: [7:1.00] ; ; BROADWELL-LABEL: test_fucomi_fucomip: ; BROADWELL: # %bb.0: ; BROADWELL-NEXT: #APP -; BROADWELL-NEXT: fucomi %st(3) # sched: [3:1.00] -; BROADWELL-NEXT: fucompi %st(3) # sched: [3:1.00] +; BROADWELL-NEXT: fucomi %st(3), %st # sched: [3:1.00] +; BROADWELL-NEXT: fucompi %st(3), %st # sched: [3:1.00] ; BROADWELL-NEXT: #NO_APP ; BROADWELL-NEXT: retl # sched: [6:0.50] ; ; SKYLAKE-LABEL: test_fucomi_fucomip: ; SKYLAKE: # %bb.0: ; SKYLAKE-NEXT: #APP -; SKYLAKE-NEXT: fucomi %st(3) # sched: [2:1.00] -; SKYLAKE-NEXT: fucompi %st(3) # sched: [2:1.00] +; SKYLAKE-NEXT: fucomi %st(3), %st # sched: [2:1.00] +; SKYLAKE-NEXT: fucompi %st(3), %st # sched: [2:1.00] ; SKYLAKE-NEXT: #NO_APP ; SKYLAKE-NEXT: retl # sched: [6:0.50] ; ; SKX-LABEL: test_fucomi_fucomip: ; SKX: # %bb.0: ; SKX-NEXT: #APP -; SKX-NEXT: fucomi %st(3) # sched: [2:1.00] -; SKX-NEXT: fucompi %st(3) # sched: [2:1.00] +; SKX-NEXT: fucomi %st(3), %st # sched: [2:1.00] +; SKX-NEXT: fucompi %st(3), %st # sched: [2:1.00] ; SKX-NEXT: #NO_APP ; SKX-NEXT: retl # sched: [6:0.50] ; ; BDVER2-LABEL: test_fucomi_fucomip: ; BDVER2: # %bb.0: ; BDVER2-NEXT: #APP -; BDVER2-NEXT: fucomi %st(3) # sched: [1:1.00] -; BDVER2-NEXT: fucompi %st(3) # sched: [1:1.00] +; BDVER2-NEXT: fucomi %st(3), %st # sched: [1:1.00] +; BDVER2-NEXT: fucompi %st(3), %st # sched: [1:1.00] ; BDVER2-NEXT: #NO_APP ; BDVER2-NEXT: retl # sched: [5:1.00] ; ; BTVER2-LABEL: test_fucomi_fucomip: ; BTVER2: # %bb.0: ; BTVER2-NEXT: #APP -; BTVER2-NEXT: fucomi %st(3) # sched: [3:1.00] -; BTVER2-NEXT: fucompi %st(3) # sched: [3:1.00] +; BTVER2-NEXT: fucomi %st(3), %st # sched: [3:1.00] +; BTVER2-NEXT: fucompi %st(3), %st # sched: [3:1.00] ; BTVER2-NEXT: #NO_APP ; BTVER2-NEXT: retl # sched: [4:1.00] ; ; ZNVER1-LABEL: test_fucomi_fucomip: ; ZNVER1: # %bb.0: ; ZNVER1-NEXT: #APP -; ZNVER1-NEXT: fucomi %st(3) # sched: [9:0.50] -; ZNVER1-NEXT: fucompi %st(3) # sched: [9:0.50] +; ZNVER1-NEXT: fucomi %st(3), %st # sched: [9:0.50] +; ZNVER1-NEXT: fucompi %st(3), %st # sched: [9:0.50] ; ZNVER1-NEXT: #NO_APP ; ZNVER1-NEXT: retl # sched: [1:0.50] tail call void asm sideeffect "fucomi %st(3) \0A\09 fucomip %st(3)", ""() nounwind diff --git a/llvm/test/MC/Disassembler/X86/fp-stack.txt b/llvm/test/MC/Disassembler/X86/fp-stack.txt index 8c4ad47eb8732..1b1687b2a204b 100644 --- a/llvm/test/MC/Disassembler/X86/fp-stack.txt +++ b/llvm/test/MC/Disassembler/X86/fp-stack.txt @@ -1,52 +1,52 @@ # RUN: llvm-mc --disassemble %s -triple=x86_64 | FileCheck %s # RUN: llvm-mc --disassemble %s -triple=i686-apple-darwin9 | FileCheck %s -# CHECK: fadd %st(0) +# CHECK: fadd %st(0), %st 0xd8,0xc0 -# CHECK: fadd %st(1) +# CHECK: fadd %st(1), %st 0xd8,0xc1 -# CHECK: fadd %st(2) +# CHECK: fadd %st(2), %st 0xd8,0xc2 -# CHECK: fadd %st(3) +# CHECK: fadd %st(3), %st 0xd8,0xc3 -# CHECK: fadd %st(4) +# CHECK: fadd %st(4), %st 0xd8,0xc4 -# CHECK: fadd %st(5) +# CHECK: fadd %st(5), %st 0xd8,0xc5 -# CHECK: fadd %st(6) +# CHECK: fadd %st(6), %st 0xd8,0xc6 -# CHECK: fadd %st(7) +# CHECK: fadd %st(7), %st 0xd8,0xc7 -# CHECK: fmul %st(0) +# CHECK: fmul %st(0), %st 0xd8,0xc8 -# CHECK: fmul %st(1) +# CHECK: fmul %st(1), %st 0xd8,0xc9 -# CHECK: fmul %st(2) +# CHECK: fmul %st(2), %st 0xd8,0xca -# CHECK: fmul %st(3) +# CHECK: fmul %st(3), %st 0xd8,0xcb -# CHECK: fmul %st(4) +# CHECK: fmul %st(4), %st 0xd8,0xcc -# CHECK: fmul %st(5) +# CHECK: fmul %st(5), %st 0xd8,0xcd -# CHECK: fmul %st(6) +# CHECK: fmul %st(6), %st 0xd8,0xce -# CHECK: fmul %st(7) +# CHECK: fmul %st(7), %st 0xd8,0xcf # CHECK: fcom %st(0) @@ -97,100 +97,100 @@ # CHECK: fcomp %st(7) 0xd8,0xdf -# CHECK: fsub %st(0) +# CHECK: fsub %st(0), %st 0xd8,0xe0 -# CHECK: fsub %st(1) +# CHECK: fsub %st(1), %st 0xd8,0xe1 -# CHECK: fsub %st(2) +# CHECK: fsub %st(2), %st 0xd8,0xe2 -# CHECK: fsub %st(3) +# CHECK: fsub %st(3), %st 0xd8,0xe3 -# CHECK: fsub %st(4) +# CHECK: fsub %st(4), %st 0xd8,0xe4 -# CHECK: fsub %st(5) +# CHECK: fsub %st(5), %st 0xd8,0xe5 -# CHECK: fsub %st(6) +# CHECK: fsub %st(6), %st 0xd8,0xe6 -# CHECK: fsub %st(7) +# CHECK: fsub %st(7), %st 0xd8,0xe7 -# CHECK: fsubr %st(0) +# CHECK: fsubr %st(0), %st 0xd8,0xe8 -# CHECK: fsubr %st(1) +# CHECK: fsubr %st(1), %st 0xd8,0xe9 -# CHECK: fsubr %st(2) +# CHECK: fsubr %st(2), %st 0xd8,0xea -# CHECK: fsubr %st(3) +# CHECK: fsubr %st(3), %st 0xd8,0xeb -# CHECK: fsubr %st(4) +# CHECK: fsubr %st(4), %st 0xd8,0xec -# CHECK: fsubr %st(5) +# CHECK: fsubr %st(5), %st 0xd8,0xed -# CHECK: fsubr %st(6) +# CHECK: fsubr %st(6), %st 0xd8,0xee -# CHECK: fsubr %st(7) +# CHECK: fsubr %st(7), %st 0xd8,0xef -# CHECK: fdiv %st(0) +# CHECK: fdiv %st(0), %st 0xd8,0xf0 -# CHECK: fdiv %st(1) +# CHECK: fdiv %st(1), %st 0xd8,0xf1 -# CHECK: fdiv %st(2) +# CHECK: fdiv %st(2), %st 0xd8,0xf2 -# CHECK: fdiv %st(3) +# CHECK: fdiv %st(3), %st 0xd8,0xf3 -# CHECK: fdiv %st(4) +# CHECK: fdiv %st(4), %st 0xd8,0xf4 -# CHECK: fdiv %st(5) +# CHECK: fdiv %st(5), %st 0xd8,0xf5 -# CHECK: fdiv %st(6) +# CHECK: fdiv %st(6), %st 0xd8,0xf6 -# CHECK: fdiv %st(7) +# CHECK: fdiv %st(7), %st 0xd8,0xf7 -# CHECK: fdivr %st(0) +# CHECK: fdivr %st(0), %st 0xd8,0xf8 -# CHECK: fdivr %st(1) +# CHECK: fdivr %st(1), %st 0xd8,0xf9 -# CHECK: fdivr %st(2) +# CHECK: fdivr %st(2), %st 0xd8,0xfa -# CHECK: fdivr %st(3) +# CHECK: fdivr %st(3), %st 0xd8,0xfb -# CHECK: fdivr %st(4) +# CHECK: fdivr %st(4), %st 0xd8,0xfc -# CHECK: fdivr %st(5) +# CHECK: fdivr %st(5), %st 0xd8,0xfd -# CHECK: fdivr %st(6) +# CHECK: fdivr %st(6), %st 0xd8,0xfe -# CHECK: fdivr %st(7) +# CHECK: fdivr %st(7), %st 0xd8,0xff # CHECK: fld %st(0) @@ -325,199 +325,199 @@ # CHECK: fcos 0xd9,0xff -# CHECK: fcmovb %st(0), %st(0) +# CHECK: fcmovb %st(0), %st 0xda,0xc0 -# CHECK: fcmovb %st(1), %st(0) +# CHECK: fcmovb %st(1), %st 0xda,0xc1 -# CHECK: fcmovb %st(2), %st(0) +# CHECK: fcmovb %st(2), %st 0xda,0xc2 -# CHECK: fcmovb %st(3), %st(0) +# CHECK: fcmovb %st(3), %st 0xda,0xc3 -# CHECK: fcmovb %st(4), %st(0) +# CHECK: fcmovb %st(4), %st 0xda,0xc4 -# CHECK: fcmovb %st(5), %st(0) +# CHECK: fcmovb %st(5), %st 0xda,0xc5 -# CHECK: fcmovb %st(6), %st(0) +# CHECK: fcmovb %st(6), %st 0xda,0xc6 -# CHECK: fcmovb %st(7), %st(0) +# CHECK: fcmovb %st(7), %st 0xda,0xc7 -# CHECK: fcmove %st(0), %st(0) +# CHECK: fcmove %st(0), %st 0xda,0xc8 -# CHECK: fcmove %st(1), %st(0) +# CHECK: fcmove %st(1), %st 0xda,0xc9 -# CHECK: fcmove %st(2), %st(0) +# CHECK: fcmove %st(2), %st 0xda,0xca -# CHECK: fcmove %st(3), %st(0) +# CHECK: fcmove %st(3), %st 0xda,0xcb -# CHECK: fcmove %st(4), %st(0) +# CHECK: fcmove %st(4), %st 0xda,0xcc -# CHECK: fcmove %st(5), %st(0) +# CHECK: fcmove %st(5), %st 0xda,0xcd -# CHECK: fcmove %st(6), %st(0) +# CHECK: fcmove %st(6), %st 0xda,0xce -# CHECK: fcmove %st(7), %st(0) +# CHECK: fcmove %st(7), %st 0xda,0xcf -# CHECK: fcmovbe %st(0), %st(0) +# CHECK: fcmovbe %st(0), %st 0xda,0xd0 -# CHECK: fcmovbe %st(1), %st(0) +# CHECK: fcmovbe %st(1), %st 0xda,0xd1 -# CHECK: fcmovbe %st(2), %st(0) +# CHECK: fcmovbe %st(2), %st 0xda,0xd2 -# CHECK: fcmovbe %st(3), %st(0) +# CHECK: fcmovbe %st(3), %st 0xda,0xd3 -# CHECK: fcmovbe %st(4), %st(0) +# CHECK: fcmovbe %st(4), %st 0xda,0xd4 -# CHECK: fcmovbe %st(5), %st(0) +# CHECK: fcmovbe %st(5), %st 0xda,0xd5 -# CHECK: fcmovbe %st(6), %st(0) +# CHECK: fcmovbe %st(6), %st 0xda,0xd6 -# CHECK: fcmovbe %st(7), %st(0) +# CHECK: fcmovbe %st(7), %st 0xda,0xd7 -# CHECK: fcmovu %st(0), %st(0) +# CHECK: fcmovu %st(0), %st 0xda,0xd8 -# CHECK: fcmovu %st(1), %st(0) +# CHECK: fcmovu %st(1), %st 0xda,0xd9 -# CHECK: fcmovu %st(2), %st(0) +# CHECK: fcmovu %st(2), %st 0xda,0xda -# CHECK: fcmovu %st(3), %st(0) +# CHECK: fcmovu %st(3), %st 0xda,0xdb -# CHECK: fcmovu %st(4), %st(0) +# CHECK: fcmovu %st(4), %st 0xda,0xdc -# CHECK: fcmovu %st(5), %st(0) +# CHECK: fcmovu %st(5), %st 0xda,0xdd -# CHECK: fcmovu %st(6), %st(0) +# CHECK: fcmovu %st(6), %st 0xda,0xde -# CHECK: fcmovu %st(7), %st(0) +# CHECK: fcmovu %st(7), %st 0xda,0xdf # CHECK: fucompp 0xda,0xe9 -# CHECK: fcmovnb %st(0), %st(0) +# CHECK: fcmovnb %st(0), %st 0xdb,0xc0 -# CHECK: fcmovnb %st(1), %st(0) +# CHECK: fcmovnb %st(1), %st 0xdb,0xc1 -# CHECK: fcmovnb %st(2), %st(0) +# CHECK: fcmovnb %st(2), %st 0xdb,0xc2 -# CHECK: fcmovnb %st(3), %st(0) +# CHECK: fcmovnb %st(3), %st 0xdb,0xc3 -# CHECK: fcmovnb %st(4), %st(0) +# CHECK: fcmovnb %st(4), %st 0xdb,0xc4 -# CHECK: fcmovnb %st(5), %st(0) +# CHECK: fcmovnb %st(5), %st 0xdb,0xc5 -# CHECK: fcmovnb %st(6), %st(0) +# CHECK: fcmovnb %st(6), %st 0xdb,0xc6 -# CHECK: fcmovnb %st(7), %st(0) +# CHECK: fcmovnb %st(7), %st 0xdb,0xc7 -# CHECK: fcmovne %st(0), %st(0) +# CHECK: fcmovne %st(0), %st 0xdb,0xc8 -# CHECK: fcmovne %st(1), %st(0) +# CHECK: fcmovne %st(1), %st 0xdb,0xc9 -# CHECK: fcmovne %st(2), %st(0) +# CHECK: fcmovne %st(2), %st 0xdb,0xca -# CHECK: fcmovne %st(3), %st(0) +# CHECK: fcmovne %st(3), %st 0xdb,0xcb -# CHECK: fcmovne %st(4), %st(0) +# CHECK: fcmovne %st(4), %st 0xdb,0xcc -# CHECK: fcmovne %st(5), %st(0) +# CHECK: fcmovne %st(5), %st 0xdb,0xcd -# CHECK: fcmovne %st(6), %st(0) +# CHECK: fcmovne %st(6), %st 0xdb,0xce -# CHECK: fcmovne %st(7), %st(0) +# CHECK: fcmovne %st(7), %st 0xdb,0xcf -# CHECK: fcmovnbe %st(0), %st(0) +# CHECK: fcmovnbe %st(0), %st 0xdb,0xd0 -# CHECK: fcmovnbe %st(1), %st(0) +# CHECK: fcmovnbe %st(1), %st 0xdb,0xd1 -# CHECK: fcmovnbe %st(2), %st(0) +# CHECK: fcmovnbe %st(2), %st 0xdb,0xd2 -# CHECK: fcmovnbe %st(3), %st(0) +# CHECK: fcmovnbe %st(3), %st 0xdb,0xd3 -# CHECK: fcmovnbe %st(4), %st(0) +# CHECK: fcmovnbe %st(4), %st 0xdb,0xd4 -# CHECK: fcmovnbe %st(5), %st(0) +# CHECK: fcmovnbe %st(5), %st 0xdb,0xd5 -# CHECK: fcmovnbe %st(6), %st(0) +# CHECK: fcmovnbe %st(6), %st 0xdb,0xd6 -# CHECK: fcmovnbe %st(7), %st(0) +# CHECK: fcmovnbe %st(7), %st 0xdb,0xd7 -# CHECK: fcmovnu %st(0), %st(0) +# CHECK: fcmovnu %st(0), %st 0xdb,0xd8 -# CHECK: fcmovnu %st(1), %st(0) +# CHECK: fcmovnu %st(1), %st 0xdb,0xd9 -# CHECK: fcmovnu %st(2), %st(0) +# CHECK: fcmovnu %st(2), %st 0xdb,0xda -# CHECK: fcmovnu %st(3), %st(0) +# CHECK: fcmovnu %st(3), %st 0xdb,0xdb -# CHECK: fcmovnu %st(4), %st(0) +# CHECK: fcmovnu %st(4), %st 0xdb,0xdc -# CHECK: fcmovnu %st(5), %st(0) +# CHECK: fcmovnu %st(5), %st 0xdb,0xdd -# CHECK: fcmovnu %st(6), %st(0) +# CHECK: fcmovnu %st(6), %st 0xdb,0xde -# CHECK: fcmovnu %st(7), %st(0) +# CHECK: fcmovnu %st(7), %st 0xdb,0xdf # CHECK: fnclex @@ -574,148 +574,148 @@ # CHECK: fcomi %st(7) 0xdb,0xf7 -# CHECK: fadd %st(0), %st(0) +# CHECK: fadd %st, %st(0) 0xdc,0xc0 -# CHECK: fadd %st(0), %st(1) +# CHECK: fadd %st, %st(1) 0xdc,0xc1 -# CHECK: fadd %st(0), %st(2) +# CHECK: fadd %st, %st(2) 0xdc,0xc2 -# CHECK: fadd %st(0), %st(3) +# CHECK: fadd %st, %st(3) 0xdc,0xc3 -# CHECK: fadd %st(0), %st(4) +# CHECK: fadd %st, %st(4) 0xdc,0xc4 -# CHECK: fadd %st(0), %st(5) +# CHECK: fadd %st, %st(5) 0xdc,0xc5 -# CHECK: fadd %st(0), %st(6) +# CHECK: fadd %st, %st(6) 0xdc,0xc6 -# CHECK: fadd %st(0), %st(7) +# CHECK: fadd %st, %st(7) 0xdc,0xc7 -# CHECK: fmul %st(0), %st(0) +# CHECK: fmul %st, %st(0) 0xdc,0xc8 -# CHECK: fmul %st(0), %st(1) +# CHECK: fmul %st, %st(1) 0xdc,0xc9 -# CHECK: fmul %st(0), %st(2) +# CHECK: fmul %st, %st(2) 0xdc,0xca -# CHECK: fmul %st(0), %st(3) +# CHECK: fmul %st, %st(3) 0xdc,0xcb -# CHECK: fmul %st(0), %st(4) +# CHECK: fmul %st, %st(4) 0xdc,0xcc -# CHECK: fmul %st(0), %st(5) +# CHECK: fmul %st, %st(5) 0xdc,0xcd -# CHECK: fmul %st(0), %st(6) +# CHECK: fmul %st, %st(6) 0xdc,0xce -# CHECK: fmul %st(0), %st(7) +# CHECK: fmul %st, %st(7) 0xdc,0xcf -# CHECK: fsub %st(0), %st(0) +# CHECK: fsub %st, %st(0) 0xdc,0xe0 -# CHECK: fsub %st(0), %st(1) +# CHECK: fsub %st, %st(1) 0xdc,0xe1 -# CHECK: fsub %st(0), %st(2) +# CHECK: fsub %st, %st(2) 0xdc,0xe2 -# CHECK: fsub %st(0), %st(3) +# CHECK: fsub %st, %st(3) 0xdc,0xe3 -# CHECK: fsub %st(0), %st(4) +# CHECK: fsub %st, %st(4) 0xdc,0xe4 -# CHECK: fsub %st(0), %st(5) +# CHECK: fsub %st, %st(5) 0xdc,0xe5 -# CHECK: fsub %st(0), %st(6) +# CHECK: fsub %st, %st(6) 0xdc,0xe6 -# CHECK: fsub %st(0), %st(7) +# CHECK: fsub %st, %st(7) 0xdc,0xe7 -# CHECK: fsubr %st(0), %st(0) +# CHECK: fsubr %st, %st(0) 0xdc,0xe8 -# CHECK: fsubr %st(0), %st(1) +# CHECK: fsubr %st, %st(1) 0xdc,0xe9 -# CHECK: fsubr %st(0), %st(2) +# CHECK: fsubr %st, %st(2) 0xdc,0xea -# CHECK: fsubr %st(0), %st(3) +# CHECK: fsubr %st, %st(3) 0xdc,0xeb -# CHECK: fsubr %st(0), %st(4) +# CHECK: fsubr %st, %st(4) 0xdc,0xec -# CHECK: fsubr %st(0), %st(5) +# CHECK: fsubr %st, %st(5) 0xdc,0xed -# CHECK: fsubr %st(0), %st(6) +# CHECK: fsubr %st, %st(6) 0xdc,0xee -# CHECK: fsubr %st(0), %st(7) +# CHECK: fsubr %st, %st(7) 0xdc,0xef -# CHECK: fdiv %st(0), %st(0) +# CHECK: fdiv %st, %st(0) 0xdc,0xf0 -# CHECK: fdiv %st(0), %st(1) +# CHECK: fdiv %st, %st(1) 0xdc,0xf1 -# CHECK: fdiv %st(0), %st(2) +# CHECK: fdiv %st, %st(2) 0xdc,0xf2 -# CHECK: fdiv %st(0), %st(3) +# CHECK: fdiv %st, %st(3) 0xdc,0xf3 -# CHECK: fdiv %st(0), %st(4) +# CHECK: fdiv %st, %st(4) 0xdc,0xf4 -# CHECK: fdiv %st(0), %st(5) +# CHECK: fdiv %st, %st(5) 0xdc,0xf5 -# CHECK: fdiv %st(0), %st(6) +# CHECK: fdiv %st, %st(6) 0xdc,0xf6 -# CHECK: fdiv %st(0), %st(7) +# CHECK: fdiv %st, %st(7) 0xdc,0xf7 -# CHECK: fdivr %st(0), %st(0) +# CHECK: fdivr %st, %st(0) 0xdc,0xf8 -# CHECK: fdivr %st(0), %st(1) +# CHECK: fdivr %st, %st(1) 0xdc,0xf9 -# CHECK: fdivr %st(0), %st(2) +# CHECK: fdivr %st, %st(2) 0xdc,0xfa -# CHECK: fdivr %st(0), %st(3) +# CHECK: fdivr %st, %st(3) 0xdc,0xfb -# CHECK: fdivr %st(0), %st(4) +# CHECK: fdivr %st, %st(4) 0xdc,0xfc -# CHECK: fdivr %st(0), %st(5) +# CHECK: fdivr %st, %st(5) 0xdc,0xfd -# CHECK: fdivr %st(0), %st(6) +# CHECK: fdivr %st, %st(6) 0xdc,0xfe -# CHECK: fdivr %st(0), %st(7) +# CHECK: fdivr %st, %st(7) 0xdc,0xff # CHECK: ffree %st(0) @@ -838,151 +838,151 @@ # CHECK: fucomp %st(7) 0xdd,0xef -# CHECK: faddp %st(0) +# CHECK: faddp %st, %st(0) 0xde,0xc0 -# CHECK: faddp %st(1) +# CHECK: faddp %st, %st(1) 0xde,0xc1 -# CHECK: faddp %st(2) +# CHECK: faddp %st, %st(2) 0xde,0xc2 -# CHECK: faddp %st(3) +# CHECK: faddp %st, %st(3) 0xde,0xc3 -# CHECK: faddp %st(4) +# CHECK: faddp %st, %st(4) 0xde,0xc4 -# CHECK: faddp %st(5) +# CHECK: faddp %st, %st(5) 0xde,0xc5 -# CHECK: faddp %st(6) +# CHECK: faddp %st, %st(6) 0xde,0xc6 -# CHECK: faddp %st(7) +# CHECK: faddp %st, %st(7) 0xde,0xc7 -# CHECK: fmulp %st(0) +# CHECK: fmulp %st, %st(0) 0xde,0xc8 -# CHECK: fmulp %st(1) +# CHECK: fmulp %st, %st(1) 0xde,0xc9 -# CHECK: fmulp %st(2) +# CHECK: fmulp %st, %st(2) 0xde,0xca -# CHECK: fmulp %st(3) +# CHECK: fmulp %st, %st(3) 0xde,0xcb -# CHECK: fmulp %st(4) +# CHECK: fmulp %st, %st(4) 0xde,0xcc -# CHECK: fmulp %st(5) +# CHECK: fmulp %st, %st(5) 0xde,0xcd -# CHECK: fmulp %st(6) +# CHECK: fmulp %st, %st(6) 0xde,0xce -# CHECK: fmulp %st(7) +# CHECK: fmulp %st, %st(7) 0xde,0xcf # CHECK: fcompp 0xde,0xd9 -# CHECK: fsubp %st(0) +# CHECK: fsubp %st, %st(0) 0xde,0xe0 -# CHECK: fsubp %st(1) +# CHECK: fsubp %st, %st(1) 0xde,0xe1 -# CHECK: fsubp %st(2) +# CHECK: fsubp %st, %st(2) 0xde,0xe2 -# CHECK: fsubp %st(3) +# CHECK: fsubp %st, %st(3) 0xde,0xe3 -# CHECK: fsubp %st(4) +# CHECK: fsubp %st, %st(4) 0xde,0xe4 -# CHECK: fsubp %st(5) +# CHECK: fsubp %st, %st(5) 0xde,0xe5 -# CHECK: fsubp %st(6) +# CHECK: fsubp %st, %st(6) 0xde,0xe6 -# CHECK: fsubp %st(7) +# CHECK: fsubp %st, %st(7) 0xde,0xe7 -# CHECK: fsubrp %st(0) +# CHECK: fsubrp %st, %st(0) 0xde,0xe8 -# CHECK: fsubrp %st(1) +# CHECK: fsubrp %st, %st(1) 0xde,0xe9 -# CHECK: fsubrp %st(2) +# CHECK: fsubrp %st, %st(2) 0xde,0xea -# CHECK: fsubrp %st(3) +# CHECK: fsubrp %st, %st(3) 0xde,0xeb -# CHECK: fsubrp %st(4) +# CHECK: fsubrp %st, %st(4) 0xde,0xec -# CHECK: fsubrp %st(5) +# CHECK: fsubrp %st, %st(5) 0xde,0xed -# CHECK: fsubrp %st(6) +# CHECK: fsubrp %st, %st(6) 0xde,0xee -# CHECK: fsubrp %st(7) +# CHECK: fsubrp %st, %st(7) 0xde,0xef -# CHECK: fdivp %st(0) +# CHECK: fdivp %st, %st(0) 0xde,0xf0 -# CHECK: fdivp %st(1) +# CHECK: fdivp %st, %st(1) 0xde,0xf1 -# CHECK: fdivp %st(2) +# CHECK: fdivp %st, %st(2) 0xde,0xf2 -# CHECK: fdivp %st(3) +# CHECK: fdivp %st, %st(3) 0xde,0xf3 -# CHECK: fdivp %st(4) +# CHECK: fdivp %st, %st(4) 0xde,0xf4 -# CHECK: fdivp %st(5) +# CHECK: fdivp %st, %st(5) 0xde,0xf5 -# CHECK: fdivp %st(6) +# CHECK: fdivp %st, %st(6) 0xde,0xf6 -# CHECK: fdivp %st(7) +# CHECK: fdivp %st, %st(7) 0xde,0xf7 -# CHECK: fdivrp %st(0) +# CHECK: fdivrp %st, %st(0) 0xde,0xf8 -# CHECK: fdivrp %st(1) +# CHECK: fdivrp %st, %st(1) 0xde,0xf9 -# CHECK: fdivrp %st(2) +# CHECK: fdivrp %st, %st(2) 0xde,0xfa -# CHECK: fdivrp %st(3) +# CHECK: fdivrp %st, %st(3) 0xde,0xfb -# CHECK: fdivrp %st(4) +# CHECK: fdivrp %st, %st(4) 0xde,0xfc -# CHECK: fdivrp %st(5) +# CHECK: fdivrp %st, %st(5) 0xde,0xfd -# CHECK: fdivrp %st(6) +# CHECK: fdivrp %st, %st(6) 0xde,0xfe -# CHECK: fdivrp %st(7) +# CHECK: fdivrp %st, %st(7) 0xde,0xff # CHECK: ffreep %st(0) diff --git a/llvm/test/MC/Disassembler/X86/x86-16.txt b/llvm/test/MC/Disassembler/X86/x86-16.txt index 43cd09516c3b1..286aa88489cb4 100644 --- a/llvm/test/MC/Disassembler/X86/x86-16.txt +++ b/llvm/test/MC/Disassembler/X86/x86-16.txt @@ -759,10 +759,10 @@ # CHECK: strl %eax 0x66 0x0f 0x00 0xc8 -# CHECK: fsubp %st(1) +# CHECK: fsubp %st, %st(1) 0xde 0xe1 -# CHECK: fsubp %st(2) +# CHECK: fsubp %st, %st(2) 0xde 0xe2 # CHECKX: nop diff --git a/llvm/test/MC/X86/PPRO-32.s b/llvm/test/MC/X86/PPRO-32.s index bbd933e58af09..6deea6de9c449 100644 --- a/llvm/test/MC/X86/PPRO-32.s +++ b/llvm/test/MC/X86/PPRO-32.s @@ -64,37 +64,37 @@ cmovpl %eax, %eax // CHECK: encoding: [0x0f,0x48,0xc0] cmovsl %eax, %eax -// CHECK: fcmovbe %st(4), %st(0) +// CHECK: fcmovbe %st(4), %st // CHECK: encoding: [0xda,0xd4] -fcmovbe %st(4), %st(0) +fcmovbe %st(4), %st -// CHECK: fcmovb %st(4), %st(0) +// CHECK: fcmovb %st(4), %st // CHECK: encoding: [0xda,0xc4] -fcmovb %st(4), %st(0) +fcmovb %st(4), %st -// CHECK: fcmove %st(4), %st(0) +// CHECK: fcmove %st(4), %st // CHECK: encoding: [0xda,0xcc] -fcmove %st(4), %st(0) +fcmove %st(4), %st -// CHECK: fcmovnbe %st(4), %st(0) +// CHECK: fcmovnbe %st(4), %st // CHECK: encoding: [0xdb,0xd4] -fcmovnbe %st(4), %st(0) +fcmovnbe %st(4), %st -// CHECK: fcmovnb %st(4), %st(0) +// CHECK: fcmovnb %st(4), %st // CHECK: encoding: [0xdb,0xc4] -fcmovnb %st(4), %st(0) +fcmovnb %st(4), %st -// CHECK: fcmovne %st(4), %st(0) +// CHECK: fcmovne %st(4), %st // CHECK: encoding: [0xdb,0xcc] -fcmovne %st(4), %st(0) +fcmovne %st(4), %st -// CHECK: fcmovnu %st(4), %st(0) +// CHECK: fcmovnu %st(4), %st // CHECK: encoding: [0xdb,0xdc] -fcmovnu %st(4), %st(0) +fcmovnu %st(4), %st -// CHECK: fcmovu %st(4), %st(0) +// CHECK: fcmovu %st(4), %st // CHECK: encoding: [0xda,0xdc] -fcmovu %st(4), %st(0) +fcmovu %st(4), %st // CHECK: fcomi %st(4) // CHECK: encoding: [0xdb,0xf4] diff --git a/llvm/test/MC/X86/PPRO-64.s b/llvm/test/MC/X86/PPRO-64.s index a41d4a0f93cc9..8004772e8f3de 100644 --- a/llvm/test/MC/X86/PPRO-64.s +++ b/llvm/test/MC/X86/PPRO-64.s @@ -64,37 +64,37 @@ cmovpl %r13d, %r13d // CHECK: encoding: [0x45,0x0f,0x48,0xed] cmovsl %r13d, %r13d -// CHECK: fcmovbe %st(4), %st(0) +// CHECK: fcmovbe %st(4), %st // CHECK: encoding: [0xda,0xd4] -fcmovbe %st(4), %st(0) +fcmovbe %st(4), %st -// CHECK: fcmovb %st(4), %st(0) +// CHECK: fcmovb %st(4), %st // CHECK: encoding: [0xda,0xc4] -fcmovb %st(4), %st(0) +fcmovb %st(4), %st -// CHECK: fcmove %st(4), %st(0) +// CHECK: fcmove %st(4), %st // CHECK: encoding: [0xda,0xcc] -fcmove %st(4), %st(0) +fcmove %st(4), %st -// CHECK: fcmovnbe %st(4), %st(0) +// CHECK: fcmovnbe %st(4), %st // CHECK: encoding: [0xdb,0xd4] -fcmovnbe %st(4), %st(0) +fcmovnbe %st(4), %st -// CHECK: fcmovnb %st(4), %st(0) +// CHECK: fcmovnb %st(4), %st // CHECK: encoding: [0xdb,0xc4] -fcmovnb %st(4), %st(0) +fcmovnb %st(4), %st -// CHECK: fcmovne %st(4), %st(0) +// CHECK: fcmovne %st(4), %st // CHECK: encoding: [0xdb,0xcc] -fcmovne %st(4), %st(0) +fcmovne %st(4), %st -// CHECK: fcmovnu %st(4), %st(0) +// CHECK: fcmovnu %st(4), %st // CHECK: encoding: [0xdb,0xdc] -fcmovnu %st(4), %st(0) +fcmovnu %st(4), %st -// CHECK: fcmovu %st(4), %st(0) +// CHECK: fcmovu %st(4), %st // CHECK: encoding: [0xda,0xdc] -fcmovu %st(4), %st(0) +fcmovu %st(4), %st // CHECK: fcomi %st(4) // CHECK: encoding: [0xdb,0xf4] diff --git a/llvm/test/MC/X86/X87-32.s b/llvm/test/MC/X86/X87-32.s index 967763de93e05..d414ab65b7dc4 100755 --- a/llvm/test/MC/X86/X87-32.s +++ b/llvm/test/MC/X86/X87-32.s @@ -31,7 +31,7 @@ faddl 64(%edx,%eax) // CHECK: encoding: [0xdc,0x02] faddl (%edx) -// CHECK: faddp %st(4) +// CHECK: faddp %st, %st(4) // CHECK: encoding: [0xde,0xc4] faddp %st(4) @@ -59,11 +59,11 @@ fadds 64(%edx,%eax) // CHECK: encoding: [0xd8,0x02] fadds (%edx) -// CHECK: fadd %st(0), %st(4) +// CHECK: fadd %st, %st(4) // CHECK: encoding: [0xdc,0xc4] -fadd %st(0), %st(4) +fadd %st, %st(4) -// CHECK: fadd %st(4) +// CHECK: fadd %st(4), %st // CHECK: encoding: [0xd8,0xc4] fadd %st(4) @@ -259,7 +259,7 @@ fdivl 64(%edx,%eax) // CHECK: encoding: [0xdc,0x32] fdivl (%edx) -// CHECK: fdivp %st(4) +// CHECK: fdivp %st, %st(4) // CHECK: encoding: [0xde,0xf4] fdivp %st(4) @@ -287,7 +287,7 @@ fdivrl 64(%edx,%eax) // CHECK: encoding: [0xdc,0x3a] fdivrl (%edx) -// CHECK: fdivrp %st(4) +// CHECK: fdivrp %st, %st(4) // CHECK: encoding: [0xde,0xfc] fdivrp %st(4) @@ -315,11 +315,11 @@ fdivrs 64(%edx,%eax) // CHECK: encoding: [0xd8,0x3a] fdivrs (%edx) -// CHECK: fdivr %st(0), %st(4) +// CHECK: fdivr %st, %st(4) // CHECK: encoding: [0xdc,0xfc] -fdivr %st(0), %st(4) +fdivr %st, %st(4) -// CHECK: fdivr %st(4) +// CHECK: fdivr %st(4), %st // CHECK: encoding: [0xd8,0xfc] fdivr %st(4) @@ -347,11 +347,11 @@ fdivs 64(%edx,%eax) // CHECK: encoding: [0xd8,0x32] fdivs (%edx) -// CHECK: fdiv %st(0), %st(4) +// CHECK: fdiv %st, %st(4) // CHECK: encoding: [0xdc,0xf4] -fdiv %st(0), %st(4) +fdiv %st, %st(4) -// CHECK: fdiv %st(4) +// CHECK: fdiv %st(4), %st // CHECK: encoding: [0xd8,0xf4] fdiv %st(4) @@ -1119,7 +1119,7 @@ fmull 64(%edx,%eax) // CHECK: encoding: [0xdc,0x0a] fmull (%edx) -// CHECK: fmulp %st(4) +// CHECK: fmulp %st, %st(4) // CHECK: encoding: [0xde,0xcc] fmulp %st(4) @@ -1147,11 +1147,11 @@ fmuls 64(%edx,%eax) // CHECK: encoding: [0xd8,0x0a] fmuls (%edx) -// CHECK: fmul %st(0), %st(4) +// CHECK: fmul %st, %st(4) // CHECK: encoding: [0xdc,0xcc] -fmul %st(0), %st(4) +fmul %st, %st(4) -// CHECK: fmul %st(4) +// CHECK: fmul %st(4), %st // CHECK: encoding: [0xd8,0xcc] fmul %st(4) @@ -1479,7 +1479,7 @@ fsubl 64(%edx,%eax) // CHECK: encoding: [0xdc,0x22] fsubl (%edx) -// CHECK: fsubp %st(4) +// CHECK: fsubp %st, %st(4) // CHECK: encoding: [0xde,0xe4] fsubp %st(4) @@ -1507,7 +1507,7 @@ fsubrl 64(%edx,%eax) // CHECK: encoding: [0xdc,0x2a] fsubrl (%edx) -// CHECK: fsubrp %st(4) +// CHECK: fsubrp %st, %st(4) // CHECK: encoding: [0xde,0xec] fsubrp %st(4) @@ -1535,11 +1535,11 @@ fsubrs 64(%edx,%eax) // CHECK: encoding: [0xd8,0x2a] fsubrs (%edx) -// CHECK: fsubr %st(0), %st(4) +// CHECK: fsubr %st, %st(4) // CHECK: encoding: [0xdc,0xec] -fsubr %st(0), %st(4) +fsubr %st, %st(4) -// CHECK: fsubr %st(4) +// CHECK: fsubr %st(4), %st // CHECK: encoding: [0xd8,0xec] fsubr %st(4) @@ -1567,11 +1567,11 @@ fsubs 64(%edx,%eax) // CHECK: encoding: [0xd8,0x22] fsubs (%edx) -// CHECK: fsub %st(0), %st(4) +// CHECK: fsub %st, %st(4) // CHECK: encoding: [0xdc,0xe4] -fsub %st(0), %st(4) +fsub %st, %st(4) -// CHECK: fsub %st(4) +// CHECK: fsub %st(4), %st // CHECK: encoding: [0xd8,0xe4] fsub %st(4) diff --git a/llvm/test/MC/X86/X87-64.s b/llvm/test/MC/X86/X87-64.s index a3b76b4e4b0ad..1103f326ea047 100755 --- a/llvm/test/MC/X86/X87-64.s +++ b/llvm/test/MC/X86/X87-64.s @@ -31,7 +31,7 @@ faddl 64(%rdx,%rax) // CHECK: encoding: [0xdc,0x02] faddl (%rdx) -// CHECK: faddp %st(4) +// CHECK: faddp %st, %st(4) // CHECK: encoding: [0xde,0xc4] faddp %st(4) @@ -59,11 +59,11 @@ fadds 64(%rdx,%rax) // CHECK: encoding: [0xd8,0x02] fadds (%rdx) -// CHECK: fadd %st(0), %st(4) +// CHECK: fadd %st, %st(4) // CHECK: encoding: [0xdc,0xc4] -fadd %st(0), %st(4) +fadd %st, %st(4) -// CHECK: fadd %st(4) +// CHECK: fadd %st(4), %st // CHECK: encoding: [0xd8,0xc4] fadd %st(4) @@ -259,7 +259,7 @@ fdivl 64(%rdx,%rax) // CHECK: encoding: [0xdc,0x32] fdivl (%rdx) -// CHECK: fdivp %st(4) +// CHECK: fdivp %st, %st(4) // CHECK: encoding: [0xde,0xf4] fdivp %st(4) @@ -287,7 +287,7 @@ fdivrl 64(%rdx,%rax) // CHECK: encoding: [0xdc,0x3a] fdivrl (%rdx) -// CHECK: fdivrp %st(4) +// CHECK: fdivrp %st, %st(4) // CHECK: encoding: [0xde,0xfc] fdivrp %st(4) @@ -315,11 +315,11 @@ fdivrs 64(%rdx,%rax) // CHECK: encoding: [0xd8,0x3a] fdivrs (%rdx) -// CHECK: fdivr %st(0), %st(4) +// CHECK: fdivr %st, %st(4) // CHECK: encoding: [0xdc,0xfc] -fdivr %st(0), %st(4) +fdivr %st, %st(4) -// CHECK: fdivr %st(4) +// CHECK: fdivr %st(4), %st // CHECK: encoding: [0xd8,0xfc] fdivr %st(4) @@ -347,11 +347,11 @@ fdivs 64(%rdx,%rax) // CHECK: encoding: [0xd8,0x32] fdivs (%rdx) -// CHECK: fdiv %st(0), %st(4) +// CHECK: fdiv %st, %st(4) // CHECK: encoding: [0xdc,0xf4] -fdiv %st(0), %st(4) +fdiv %st, %st(4) -// CHECK: fdiv %st(4) +// CHECK: fdiv %st(4), %st // CHECK: encoding: [0xd8,0xf4] fdiv %st(4) @@ -1119,7 +1119,7 @@ fmull 64(%rdx,%rax) // CHECK: encoding: [0xdc,0x0a] fmull (%rdx) -// CHECK: fmulp %st(4) +// CHECK: fmulp %st, %st(4) // CHECK: encoding: [0xde,0xcc] fmulp %st(4) @@ -1147,9 +1147,9 @@ fmuls 64(%rdx,%rax) // CHECK: encoding: [0xd8,0x0a] fmuls (%rdx) -// CHECK: fmul %st(0), %st(4) +// CHECK: fmul %st, %st(4) // CHECK: encoding: [0xdc,0xcc] -fmul %st(0), %st(4) +fmul %st, %st(4) // CHECK: fmul %st(4) // CHECK: encoding: [0xd8,0xcc] @@ -1479,7 +1479,7 @@ fsubl 64(%rdx,%rax) // CHECK: encoding: [0xdc,0x22] fsubl (%rdx) -// CHECK: fsubp %st(4) +// CHECK: fsubp %st, %st(4) // CHECK: encoding: [0xde,0xe4] fsubp %st(4) @@ -1507,7 +1507,7 @@ fsubrl 64(%rdx,%rax) // CHECK: encoding: [0xdc,0x2a] fsubrl (%rdx) -// CHECK: fsubrp %st(4) +// CHECK: fsubrp %st, %st(4) // CHECK: encoding: [0xde,0xec] fsubrp %st(4) @@ -1535,11 +1535,11 @@ fsubrs 64(%rdx,%rax) // CHECK: encoding: [0xd8,0x2a] fsubrs (%rdx) -// CHECK: fsubr %st(0), %st(4) +// CHECK: fsubr %st, %st(4) // CHECK: encoding: [0xdc,0xec] -fsubr %st(0), %st(4) +fsubr %st, %st(4) -// CHECK: fsubr %st(4) +// CHECK: fsubr %st(4), %st // CHECK: encoding: [0xd8,0xec] fsubr %st(4) @@ -1567,11 +1567,11 @@ fsubs 64(%rdx,%rax) // CHECK: encoding: [0xd8,0x22] fsubs (%rdx) -// CHECK: fsub %st(0), %st(4) +// CHECK: fsub %st, %st(4) // CHECK: encoding: [0xdc,0xe4] -fsub %st(0), %st(4) +fsub %st, %st(4) -// CHECK: fsub %st(4) +// CHECK: fsub %st(4), %st // CHECK: encoding: [0xd8,0xe4] fsub %st(4) diff --git a/llvm/test/MC/X86/intel-syntax-2.s b/llvm/test/MC/X86/intel-syntax-2.s index aead5766db4d5..b23965ae52e88 100644 --- a/llvm/test/MC/X86/intel-syntax-2.s +++ b/llvm/test/MC/X86/intel-syntax-2.s @@ -18,14 +18,14 @@ _test2: _test3: fadd -// CHECK: faddp %st(1) +// CHECK: faddp %st, %st(1) fmul -// CHECK: fmulp %st(1) +// CHECK: fmulp %st, %st(1) fsub -// CHECK: fsubp %st(1) +// CHECK: fsubp %st, %st(1) fsubr -// CHECK: fsubrp %st(1) +// CHECK: fsubrp %st, %st(1) fdiv -// CHECK: fdivp %st(1) +// CHECK: fdivp %st, %st(1) fdivr -// CHECK: fdivrp %st(1) +// CHECK: fdivrp %st, %st(1) diff --git a/llvm/test/MC/X86/intel-syntax.s b/llvm/test/MC/X86/intel-syntax.s index 428a7e4ec41f1..171357e1f5212 100644 --- a/llvm/test/MC/X86/intel-syntax.s +++ b/llvm/test/MC/X86/intel-syntax.s @@ -556,12 +556,12 @@ fnstsw fnstsw AX fnstsw WORD PTR [EAX] -// CHECK: faddp %st(1) -// CHECK: fmulp %st(1) -// CHECK: fsubrp %st(1) -// CHECK: fsubp %st(1) -// CHECK: fdivrp %st(1) -// CHECK: fdivp %st(1) +// CHECK: faddp %st, %st(1) +// CHECK: fmulp %st, %st(1) +// CHECK: fsubrp %st, %st(1) +// CHECK: fsubp %st, %st(1) +// CHECK: fdivrp %st, %st(1) +// CHECK: fdivp %st, %st(1) faddp ST(1), ST(0) fmulp ST(1), ST(0) fsubp ST(1), ST(0) @@ -569,12 +569,12 @@ fsubrp ST(1), ST(0) fdivp ST(1), ST(0) fdivrp ST(1), ST(0) -// CHECK: faddp %st(1) -// CHECK: fmulp %st(1) -// CHECK: fsubrp %st(1) -// CHECK: fsubp %st(1) -// CHECK: fdivrp %st(1) -// CHECK: fdivp %st(1) +// CHECK: faddp %st, %st(1) +// CHECK: fmulp %st, %st(1) +// CHECK: fsubrp %st, %st(1) +// CHECK: fsubp %st, %st(1) +// CHECK: fdivrp %st, %st(1) +// CHECK: fdivp %st, %st(1) faddp ST(0), ST(1) fmulp ST(0), ST(1) fsubp ST(0), ST(1) @@ -582,12 +582,12 @@ fsubrp ST(0), ST(1) fdivp ST(0), ST(1) fdivrp ST(0), ST(1) -// CHECK: faddp %st(1) -// CHECK: fmulp %st(1) -// CHECK: fsubrp %st(1) -// CHECK: fsubp %st(1) -// CHECK: fdivrp %st(1) -// CHECK: fdivp %st(1) +// CHECK: faddp %st, %st(1) +// CHECK: fmulp %st, %st(1) +// CHECK: fsubrp %st, %st(1) +// CHECK: fsubp %st, %st(1) +// CHECK: fdivrp %st, %st(1) +// CHECK: fdivp %st, %st(1) faddp ST(1) fmulp ST(1) fsubp ST(1) @@ -596,12 +596,12 @@ fdivp ST(1) fdivrp ST(1) -// CHECK: faddp %st(1) -// CHECK: fmulp %st(1) -// CHECK: fsubrp %st(1) -// CHECK: fsubp %st(1) -// CHECK: fdivrp %st(1) -// CHECK: fdivp %st(1) +// CHECK: faddp %st, %st(1) +// CHECK: fmulp %st, %st(1) +// CHECK: fsubrp %st, %st(1) +// CHECK: fsubp %st, %st(1) +// CHECK: fdivrp %st, %st(1) +// CHECK: fdivp %st, %st(1) fadd fmul fsub @@ -609,12 +609,12 @@ fsubr fdiv fdivr -// CHECK: faddp %st(1) -// CHECK: fmulp %st(1) -// CHECK: fsubrp %st(1) -// CHECK: fsubp %st(1) -// CHECK: fdivrp %st(1) -// CHECK: fdivp %st(1) +// CHECK: faddp %st, %st(1) +// CHECK: fmulp %st, %st(1) +// CHECK: fsubrp %st, %st(1) +// CHECK: fsubp %st, %st(1) +// CHECK: fdivrp %st, %st(1) +// CHECK: fdivp %st, %st(1) faddp fmulp fsubp @@ -622,12 +622,12 @@ fsubrp fdivp fdivrp -// CHECK: fadd %st(1) -// CHECK: fmul %st(1) -// CHECK: fsub %st(1) -// CHECK: fsubr %st(1) -// CHECK: fdiv %st(1) -// CHECK: fdivr %st(1) +// CHECK: fadd %st(1), %st +// CHECK: fmul %st(1), %st +// CHECK: fsub %st(1), %st +// CHECK: fsubr %st(1), %st +// CHECK: fdiv %st(1), %st +// CHECK: fdivr %st(1), %st fadd ST(0), ST(1) fmul ST(0), ST(1) fsub ST(0), ST(1) @@ -635,12 +635,12 @@ fsubr ST(0), ST(1) fdiv ST(0), ST(1) fdivr ST(0), ST(1) -// CHECK: fadd %st(0), %st(1) -// CHECK: fmul %st(0), %st(1) -// CHECK: fsubr %st(0), %st(1) -// CHECK: fsub %st(0), %st(1) -// CHECK: fdivr %st(0), %st(1) -// CHECK: fdiv %st(0), %st(1) +// CHECK: fadd %st, %st(1) +// CHECK: fmul %st, %st(1) +// CHECK: fsubr %st, %st(1) +// CHECK: fsub %st, %st(1) +// CHECK: fdivr %st, %st(1) +// CHECK: fdiv %st, %st(1) fadd ST(1), ST(0) fmul ST(1), ST(0) fsub ST(1), ST(0) @@ -648,12 +648,12 @@ fsubr ST(1), ST(0) fdiv ST(1), ST(0) fdivr ST(1), ST(0) -// CHECK: fadd %st(1) -// CHECK: fmul %st(1) -// CHECK: fsub %st(1) -// CHECK: fsubr %st(1) -// CHECK: fdiv %st(1) -// CHECK: fdivr %st(1) +// CHECK: fadd %st(1), %st +// CHECK: fmul %st(1), %st +// CHECK: fsub %st(1), %st +// CHECK: fsubr %st(1), %st +// CHECK: fdiv %st(1), %st +// CHECK: fdivr %st(1), %st fadd ST(1) fmul ST(1) fsub ST(1) diff --git a/llvm/test/MC/X86/x86-16.s b/llvm/test/MC/X86/x86-16.s index 50263beaa6756..88ee77a6d4143 100644 --- a/llvm/test/MC/X86/x86-16.s +++ b/llvm/test/MC/X86/x86-16.s @@ -920,11 +920,11 @@ pshufw $90, %mm4, %mm0 str %eax -// CHECK: fsubp +// CHECK: fsubp %st, %st(1) // CHECK: encoding: [0xde,0xe1] fsubp %st,%st(1) -// CHECK: fsubp %st(2) +// CHECK: fsubp %st, %st(2) // CHECK: encoding: [0xde,0xe2] fsubp %st, %st(2) diff --git a/llvm/test/MC/X86/x86-32-coverage.s b/llvm/test/MC/X86/x86-32-coverage.s index 32281f4121644..ba59fb357b974 100644 --- a/llvm/test/MC/X86/x86-32-coverage.s +++ b/llvm/test/MC/X86/x86-32-coverage.s @@ -2472,11 +2472,11 @@ // CHECK: encoding: [0xda,0x05,0x78,0x56,0x34,0x12] fiaddl 0x12345678 -// CHECK: faddp %st(2) +// CHECK: faddp %st, %st(2) // CHECK: encoding: [0xde,0xc2] faddp %st(2) -// CHECK: fsub %st(2) +// CHECK: fsub %st(2), %st // CHECK: encoding: [0xd8,0xe2] fsub %st(2) @@ -2504,11 +2504,11 @@ // CHECK: encoding: [0xda,0x25,0x78,0x56,0x34,0x12] fisubl 0x12345678 -// CHECK: fsubp %st(2) +// CHECK: fsubp %st, %st(2) // CHECK: encoding: [0xde,0xe2] fsubp %st(2) -// CHECK: fsubr %st(2) +// CHECK: fsubr %st(2), %st // CHECK: encoding: [0xd8,0xea] fsubr %st(2) @@ -2536,11 +2536,11 @@ // CHECK: encoding: [0xda,0x2d,0x78,0x56,0x34,0x12] fisubrl 0x12345678 -// CHECK: fsubrp %st(2) +// CHECK: fsubrp %st, %st(2) // CHECK: encoding: [0xde,0xea] fsubrp %st(2) -// CHECK: fmul %st(2) +// CHECK: fmul %st(2), %st // CHECK: encoding: [0xd8,0xca] fmul %st(2) @@ -2568,11 +2568,11 @@ // CHECK: encoding: [0xda,0x0d,0x78,0x56,0x34,0x12] fimull 0x12345678 -// CHECK: fmulp %st(2) +// CHECK: fmulp %st, %st(2) // CHECK: encoding: [0xde,0xca] fmulp %st(2) -// CHECK: fdiv %st(2) +// CHECK: fdiv %st(2), %st // CHECK: encoding: [0xd8,0xf2] fdiv %st(2) @@ -2600,11 +2600,11 @@ // CHECK: encoding: [0xda,0x35,0x78,0x56,0x34,0x12] fidivl 0x12345678 -// CHECK: fdivp %st(2) +// CHECK: fdivp %st, %st(2) // CHECK: encoding: [0xde,0xf2] fdivp %st(2) -// CHECK: fdivr %st(2) +// CHECK: fdivr %st(2), %st // CHECK: encoding: [0xd8,0xfa] fdivr %st(2) @@ -2632,7 +2632,7 @@ // CHECK: encoding: [0xda,0x3d,0x78,0x56,0x34,0x12] fidivrl 0x12345678 -// CHECK: fdivrp %st(2) +// CHECK: fdivrp %st, %st(2) // CHECK: encoding: [0xde,0xfa] fdivrp %st(2) @@ -2876,35 +2876,35 @@ // CHECK: encoding: [0x0f,0x0b] ud2 -// CHECK: fcmovb %st(2), %st(0) +// CHECK: fcmovb %st(2), %st // CHECK: encoding: [0xda,0xc2] fcmovb %st(2),%st -// CHECK: fcmove %st(2), %st(0) +// CHECK: fcmove %st(2), %st // CHECK: encoding: [0xda,0xca] fcmove %st(2),%st -// CHECK: fcmovbe %st(2), %st(0) +// CHECK: fcmovbe %st(2), %st // CHECK: encoding: [0xda,0xd2] fcmovbe %st(2),%st -// CHECK: fcmovu %st(2), %st(0) +// CHECK: fcmovu %st(2), %st // CHECK: encoding: [0xda,0xda] fcmovu %st(2),%st -// CHECK: fcmovnb %st(2), %st(0) +// CHECK: fcmovnb %st(2), %st // CHECK: encoding: [0xdb,0xc2] fcmovnb %st(2),%st -// CHECK: fcmovne %st(2), %st(0) +// CHECK: fcmovne %st(2), %st // CHECK: encoding: [0xdb,0xca] fcmovne %st(2),%st -// CHECK: fcmovnbe %st(2), %st(0) +// CHECK: fcmovnbe %st(2), %st // CHECK: encoding: [0xdb,0xd2] fcmovnbe %st(2),%st -// CHECK: fcmovnu %st(2), %st(0) +// CHECK: fcmovnu %st(2), %st // CHECK: encoding: [0xdb,0xda] fcmovnu %st(2),%st diff --git a/llvm/test/MC/X86/x86-32.s b/llvm/test/MC/X86/x86-32.s index 69d3603259345..1593c26b9d029 100644 --- a/llvm/test/MC/X86/x86-32.s +++ b/llvm/test/MC/X86/x86-32.s @@ -1055,7 +1055,7 @@ pshufw $90, %mm4, %mm0 fsubp %st,%st(1) // PR9164 -// CHECK: fsubp %st(2) +// CHECK: fsubp %st, %st(2) // CHECK: encoding: [0xde,0xe2] fsubp %st, %st(2) diff --git a/llvm/test/MC/X86/x86-64.s b/llvm/test/MC/X86/x86-64.s index df811a6c4cf2e..e35ba19fc4f2e 100644 --- a/llvm/test/MC/X86/x86-64.s +++ b/llvm/test/MC/X86/x86-64.s @@ -307,13 +307,13 @@ insl (%dx), %es:(%rdi) // CHECK: fxch %st(1) // CHECK: fucom %st(1) // CHECK: fucomp %st(1) -// CHECK: faddp %st(1) -// CHECK: faddp %st(0) -// CHECK: fsubp %st(1) -// CHECK: fsubrp %st(1) -// CHECK: fmulp %st(1) -// CHECK: fdivp %st(1) -// CHECK: fdivrp %st(1) +// CHECK: faddp %st, %st(1) +// CHECK: faddp %st, %st(0) +// CHECK: fsubp %st, %st(1) +// CHECK: fsubrp %st, %st(1) +// CHECK: fmulp %st, %st(1) +// CHECK: fdivp %st, %st(1) +// CHECK: fdivrp %st, %st(1) fxch fucom @@ -416,21 +416,21 @@ enter $0x7ace,$0x7f mov %cs, %ax // rdar://8456391 -fcmovb %st(1), %st(0) // CHECK: fcmovb %st(1), %st(0) -fcmove %st(1), %st(0) // CHECK: fcmove %st(1), %st(0) -fcmovbe %st(1), %st(0) // CHECK: fcmovbe %st(1), %st(0) -fcmovu %st(1), %st(0) // CHECK: fcmovu %st(1), %st(0) +fcmovb %st(1), %st // CHECK: fcmovb %st(1), %st +fcmove %st(1), %st // CHECK: fcmove %st(1), %st +fcmovbe %st(1), %st // CHECK: fcmovbe %st(1), %st +fcmovu %st(1), %st // CHECK: fcmovu %st(1), %st -fcmovnb %st(1), %st(0) // CHECK: fcmovnb %st(1), %st(0) -fcmovne %st(1), %st(0) // CHECK: fcmovne %st(1), %st(0) -fcmovnbe %st(1), %st(0) // CHECK: fcmovnbe %st(1), %st(0) -fcmovnu %st(1), %st(0) // CHECK: fcmovnu %st(1), %st(0) +fcmovnb %st(1), %st // CHECK: fcmovnb %st(1), %st +fcmovne %st(1), %st // CHECK: fcmovne %st(1), %st +fcmovnbe %st(1), %st // CHECK: fcmovnbe %st(1), %st +fcmovnu %st(1), %st // CHECK: fcmovnu %st(1), %st -fcmovnae %st(1), %st(0) // CHECK: fcmovb %st(1), %st(0) -fcmovna %st(1), %st(0) // CHECK: fcmovbe %st(1), %st(0) +fcmovnae %st(1), %st // CHECK: fcmovb %st(1), %st +fcmovna %st(1), %st // CHECK: fcmovbe %st(1), %st -fcmovae %st(1), %st(0) // CHECK: fcmovnb %st(1), %st(0) -fcmova %st(1), %st(0) // CHECK: fcmovnbe %st(1), %st(0) +fcmovae %st(1), %st // CHECK: fcmovnb %st(1), %st +fcmova %st(1), %st // CHECK: fcmovnbe %st(1), %st // rdar://8456417 .byte (88 + 1) & 15 // CHECK: .byte 9 @@ -456,20 +456,20 @@ mov %rdx, %db15 // CHECK: encoding: [0x44,0x0f,0x23,0xfa] // rdar://8456371 - Handle commutable instructions written backward. -// CHECK: faddp %st(1) -// CHECK: fmulp %st(2) +// CHECK: faddp %st, %st(1) +// CHECK: fmulp %st, %st(2) faddp %st, %st(1) fmulp %st, %st(2) // rdar://8468087 - Encode these accurately, they are not synonyms. -// CHECK: fmul %st(0), %st(1) +// CHECK: fmul %st, %st(1) // CHECK: encoding: [0xdc,0xc9] // CHECK: fmul %st(1) // CHECK: encoding: [0xd8,0xc9] fmul %st, %st(1) fmul %st(1), %st -// CHECK: fadd %st(0), %st(1) +// CHECK: fadd %st, %st(1) // CHECK: encoding: [0xdc,0xc1] // CHECK: fadd %st(1) // CHECK: encoding: [0xd8,0xc1] @@ -582,15 +582,15 @@ movmskpd %xmm6, %eax // CHECK: encoding: [0x66,0x0f,0x50,0xc6] // rdar://8491845 - Gas supports commuted forms of non-commutable instructions. -fdivrp %st(0), %st(1) // CHECK: encoding: [0xde,0xf9] -fdivrp %st(1), %st(0) // CHECK: encoding: [0xde,0xf9] +fdivrp %st, %st(1) // CHECK: encoding: [0xde,0xf9] +fdivrp %st(1), %st // CHECK: encoding: [0xde,0xf9] -fsubrp %st(0), %st(1) // CHECK: encoding: [0xde,0xe9] -fsubrp %st(1), %st(0) // CHECK: encoding: [0xde,0xe9] +fsubrp %st, %st(1) // CHECK: encoding: [0xde,0xe9] +fsubrp %st(1), %st // CHECK: encoding: [0xde,0xe9] // also PR8861 -fdivp %st(0), %st(1) // CHECK: encoding: [0xde,0xf1] -fdivp %st(1), %st(0) // CHECK: encoding: [0xde,0xf1] +fdivp %st, %st(1) // CHECK: encoding: [0xde,0xf1] +fdivp %st(1), %st // CHECK: encoding: [0xde,0xf1] movl foo(%rip), %eax @@ -1391,38 +1391,38 @@ clac // CHECK: encoding: [0x0f,0x01,0xcb] stac -// CHECK: faddp %st(1) -// CHECK: fmulp %st(1) -// CHECK: fsubp %st(1) -// CHECK: fsubrp %st(1) -// CHECK: fdivp %st(1) -// CHECK: fdivrp %st(1) -faddp %st(0), %st(1) -fmulp %st(0), %st(1) -fsubp %st(0), %st(1) -fsubrp %st(0), %st(1) -fdivp %st(0), %st(1) -fdivrp %st(0), %st(1) - -// CHECK: faddp %st(1) -// CHECK: fmulp %st(1) -// CHECK: fsubp %st(1) -// CHECK: fsubrp %st(1) -// CHECK: fdivp %st(1) -// CHECK: fdivrp %st(1) -faddp %st(1), %st(0) -fmulp %st(1), %st(0) -fsubp %st(1), %st(0) -fsubrp %st(1), %st(0) -fdivp %st(1), %st(0) -fdivrp %st(1), %st(0) - -// CHECK: faddp %st(1) -// CHECK: fmulp %st(1) -// CHECK: fsubp %st(1) -// CHECK: fsubrp %st(1) -// CHECK: fdivp %st(1) -// CHECK: fdivrp %st(1) +// CHECK: faddp %st, %st(1) +// CHECK: fmulp %st, %st(1) +// CHECK: fsubp %st, %st(1) +// CHECK: fsubrp %st, %st(1) +// CHECK: fdivp %st, %st(1) +// CHECK: fdivrp %st, %st(1) +faddp %st, %st(1) +fmulp %st, %st(1) +fsubp %st, %st(1) +fsubrp %st, %st(1) +fdivp %st, %st(1) +fdivrp %st, %st(1) + +// CHECK: faddp %st, %st(1) +// CHECK: fmulp %st, %st(1) +// CHECK: fsubp %st, %st(1) +// CHECK: fsubrp %st, %st(1) +// CHECK: fdivp %st, %st(1) +// CHECK: fdivrp %st, %st(1) +faddp %st(1), %st +fmulp %st(1), %st +fsubp %st(1), %st +fsubrp %st(1), %st +fdivp %st(1), %st +fdivrp %st(1), %st + +// CHECK: faddp %st, %st(1) +// CHECK: fmulp %st, %st(1) +// CHECK: fsubp %st, %st(1) +// CHECK: fsubrp %st, %st(1) +// CHECK: fdivp %st, %st(1) +// CHECK: fdivrp %st, %st(1) faddp %st(1) fmulp %st(1) fsubp %st(1) @@ -1430,12 +1430,12 @@ fsubrp %st(1) fdivp %st(1) fdivrp %st(1) -// CHECK: faddp %st(1) -// CHECK: fmulp %st(1) -// CHECK: fsubp %st(1) -// CHECK: fsubrp %st(1) -// CHECK: fdivp %st(1) -// CHECK: fdivrp %st(1) +// CHECK: faddp %st, %st(1) +// CHECK: fmulp %st, %st(1) +// CHECK: fsubp %st, %st(1) +// CHECK: fsubrp %st, %st(1) +// CHECK: fdivp %st, %st(1) +// CHECK: fdivrp %st, %st(1) faddp fmulp fsubp @@ -1449,25 +1449,25 @@ fdivrp // CHECK: fsubr %st(1) // CHECK: fdiv %st(1) // CHECK: fdivr %st(1) -fadd %st(1), %st(0) -fmul %st(1), %st(0) -fsub %st(1), %st(0) -fsubr %st(1), %st(0) -fdiv %st(1), %st(0) -fdivr %st(1), %st(0) - -// CHECK: fadd %st(0), %st(1) -// CHECK: fmul %st(0), %st(1) -// CHECK: fsub %st(0), %st(1) -// CHECK: fsubr %st(0), %st(1) -// CHECK: fdiv %st(0), %st(1) -// CHECK: fdivr %st(0), %st(1) -fadd %st(0), %st(1) -fmul %st(0), %st(1) -fsub %st(0), %st(1) -fsubr %st(0), %st(1) -fdiv %st(0), %st(1) -fdivr %st(0), %st(1) +fadd %st(1), %st +fmul %st(1), %st +fsub %st(1), %st +fsubr %st(1), %st +fdiv %st(1), %st +fdivr %st(1), %st + +// CHECK: fadd %st, %st(1) +// CHECK: fmul %st, %st(1) +// CHECK: fsub %st, %st(1) +// CHECK: fsubr %st, %st(1) +// CHECK: fdiv %st, %st(1) +// CHECK: fdivr %st, %st(1) +fadd %st, %st(1) +fmul %st, %st(1) +fsub %st, %st(1) +fsubr %st, %st(1) +fdiv %st, %st(1) +fdivr %st, %st(1) // CHECK: fadd %st(1) // CHECK: fmul %st(1) diff --git a/llvm/test/tools/llvm-mca/X86/Atom/resources-x87.s b/llvm/test/tools/llvm-mca/X86/Atom/resources-x87.s index c7a990a892eb6..eda0fdebb7d3c 100644 --- a/llvm/test/tools/llvm-mca/X86/Atom/resources-x87.s +++ b/llvm/test/tools/llvm-mca/X86/Atom/resources-x87.s @@ -5,7 +5,7 @@ f2xm1 fabs -fadd %st(0), %st(1) +fadd %st, %st(1) fadd %st(2) fadds (%ecx) faddl (%ecx) @@ -21,14 +21,14 @@ fchs fnclex -fcmovb %st(1), %st(0) -fcmovbe %st(1), %st(0) -fcmove %st(1), %st(0) -fcmovnb %st(1), %st(0) -fcmovnbe %st(1), %st(0) -fcmovne %st(1), %st(0) -fcmovnu %st(1), %st(0) -fcmovu %st(1), %st(0) +fcmovb %st(1), %st +fcmovbe %st(1), %st +fcmove %st(1), %st +fcmovnb %st(1), %st +fcmovnbe %st(1), %st +fcmovne %st(1), %st +fcmovnu %st(1), %st +fcmovu %st(1), %st fcom %st(1) fcom %st(3) @@ -47,7 +47,7 @@ fcos fdecstp -fdiv %st(0), %st(1) +fdiv %st, %st(1) fdiv %st(2) fdivs (%ecx) fdivl (%eax) @@ -56,7 +56,7 @@ fdivp %st(2) fidivs (%ecx) fidivl (%eax) -fdivr %st(0), %st(1) +fdivr %st, %st(1) fdivr %st(2) fdivrs (%ecx) fdivrl (%eax) @@ -106,7 +106,7 @@ fldln2 fldpi fldz -fmul %st(0), %st(1) +fmul %st, %st(1) fmul %st(2) fmuls (%ecx) fmull (%eax) @@ -153,7 +153,7 @@ fnstsw (%eax) frstor (%eax) fsave (%eax) -fsub %st(0), %st(1) +fsub %st, %st(1) fsub %st(2) fsubs (%ecx) fsubl (%eax) @@ -162,7 +162,7 @@ fsubp %st(2) fisubs (%ecx) fisubl (%eax) -fsubr %st(0), %st(1) +fsubr %st, %st(1) fsubr %st(2) fsubrs (%ecx) fsubrl (%eax) @@ -208,26 +208,26 @@ fyl2xp1 # CHECK: [1] [2] [3] [4] [5] [6] Instructions: # CHECK-NEXT: 1 99 49.50 U f2xm1 # CHECK-NEXT: 1 1 1.00 U fabs -# CHECK-NEXT: 1 5 5.00 U fadd %st(0), %st(1) -# CHECK-NEXT: 1 5 5.00 U fadd %st(2) +# CHECK-NEXT: 1 5 5.00 U fadd %st, %st(1) +# CHECK-NEXT: 1 5 5.00 U fadd %st(2), %st # CHECK-NEXT: 1 5 5.00 * U fadds (%ecx) # CHECK-NEXT: 1 5 5.00 * U faddl (%ecx) -# CHECK-NEXT: 1 5 5.00 U faddp %st(1) -# CHECK-NEXT: 1 5 5.00 U faddp %st(2) +# CHECK-NEXT: 1 5 5.00 U faddp %st, %st(1) +# CHECK-NEXT: 1 5 5.00 U faddp %st, %st(2) # CHECK-NEXT: 1 5 5.00 * U fiadds (%ecx) # CHECK-NEXT: 1 5 5.00 * U fiaddl (%ecx) # CHECK-NEXT: 1 100 0.50 U fbld (%ecx) # CHECK-NEXT: 1 100 0.50 U fbstp (%eax) # CHECK-NEXT: 1 1 1.00 U fchs # CHECK-NEXT: 1 25 12.50 U fnclex -# CHECK-NEXT: 1 9 4.50 U fcmovb %st(1), %st(0) -# CHECK-NEXT: 1 9 4.50 U fcmovbe %st(1), %st(0) -# CHECK-NEXT: 1 9 4.50 U fcmove %st(1), %st(0) -# CHECK-NEXT: 1 9 4.50 U fcmovnb %st(1), %st(0) -# CHECK-NEXT: 1 9 4.50 U fcmovnbe %st(1), %st(0) -# CHECK-NEXT: 1 9 4.50 U fcmovne %st(1), %st(0) -# CHECK-NEXT: 1 9 4.50 U fcmovnu %st(1), %st(0) -# CHECK-NEXT: 1 9 4.50 U fcmovu %st(1), %st(0) +# CHECK-NEXT: 1 9 4.50 U fcmovb %st(1), %st +# CHECK-NEXT: 1 9 4.50 U fcmovbe %st(1), %st +# CHECK-NEXT: 1 9 4.50 U fcmove %st(1), %st +# CHECK-NEXT: 1 9 4.50 U fcmovnb %st(1), %st +# CHECK-NEXT: 1 9 4.50 U fcmovnbe %st(1), %st +# CHECK-NEXT: 1 9 4.50 U fcmovne %st(1), %st +# CHECK-NEXT: 1 9 4.50 U fcmovnu %st(1), %st +# CHECK-NEXT: 1 9 4.50 U fcmovu %st(1), %st # CHECK-NEXT: 1 5 5.00 U fcom %st(1) # CHECK-NEXT: 1 5 5.00 U fcom %st(3) # CHECK-NEXT: 1 5 5.00 U fcoms (%ecx) @@ -237,24 +237,24 @@ fyl2xp1 # CHECK-NEXT: 1 5 5.00 U fcomps (%ecx) # CHECK-NEXT: 1 5 5.00 U fcompl (%eax) # CHECK-NEXT: 1 1 1.00 U fcompp -# CHECK-NEXT: 1 9 4.50 U fcomi %st(3) -# CHECK-NEXT: 1 9 4.50 U fcompi %st(3) +# CHECK-NEXT: 1 9 4.50 U fcomi %st(3), %st +# CHECK-NEXT: 1 9 4.50 U fcompi %st(3), %st # CHECK-NEXT: 1 174 87.00 U fcos # CHECK-NEXT: 1 1 0.50 U fdecstp -# CHECK-NEXT: 1 34 17.00 U fdiv %st(0), %st(1) -# CHECK-NEXT: 1 34 17.00 U fdiv %st(2) +# CHECK-NEXT: 1 34 17.00 U fdiv %st, %st(1) +# CHECK-NEXT: 1 34 17.00 U fdiv %st(2), %st # CHECK-NEXT: 1 34 17.00 * U fdivs (%ecx) # CHECK-NEXT: 1 34 17.00 * U fdivl (%eax) -# CHECK-NEXT: 1 34 17.00 U fdivp %st(1) -# CHECK-NEXT: 1 34 17.00 U fdivp %st(2) +# CHECK-NEXT: 1 34 17.00 U fdivp %st, %st(1) +# CHECK-NEXT: 1 34 17.00 U fdivp %st, %st(2) # CHECK-NEXT: 1 34 17.00 * U fidivs (%ecx) # CHECK-NEXT: 1 34 17.00 * U fidivl (%eax) -# CHECK-NEXT: 1 34 17.00 U fdivr %st(0), %st(1) -# CHECK-NEXT: 1 34 17.00 U fdivr %st(2) +# CHECK-NEXT: 1 34 17.00 U fdivr %st, %st(1) +# CHECK-NEXT: 1 34 17.00 U fdivr %st(2), %st # CHECK-NEXT: 1 34 17.00 * U fdivrs (%ecx) # CHECK-NEXT: 1 34 17.00 * U fdivrl (%eax) -# CHECK-NEXT: 1 34 17.00 U fdivrp %st(1) -# CHECK-NEXT: 1 34 17.00 U fdivrp %st(2) +# CHECK-NEXT: 1 34 17.00 U fdivrp %st, %st(1) +# CHECK-NEXT: 1 34 17.00 U fdivrp %st, %st(2) # CHECK-NEXT: 1 34 17.00 * U fidivrs (%ecx) # CHECK-NEXT: 1 34 17.00 * U fidivrl (%eax) # CHECK-NEXT: 1 1 0.50 U ffree %st(0) @@ -288,12 +288,12 @@ fyl2xp1 # CHECK-NEXT: 1 10 5.00 U fldln2 # CHECK-NEXT: 1 10 5.00 U fldpi # CHECK-NEXT: 1 1 0.50 U fldz -# CHECK-NEXT: 1 4 4.00 U fmul %st(0), %st(1) -# CHECK-NEXT: 1 4 4.00 U fmul %st(2) +# CHECK-NEXT: 1 4 4.00 U fmul %st, %st(1) +# CHECK-NEXT: 1 4 4.00 U fmul %st(2), %st # CHECK-NEXT: 1 4 4.00 * U fmuls (%ecx) # CHECK-NEXT: 1 4 4.00 * U fmull (%eax) -# CHECK-NEXT: 1 4 4.00 U fmulp %st(1) -# CHECK-NEXT: 1 4 4.00 U fmulp %st(2) +# CHECK-NEXT: 1 4 4.00 U fmulp %st, %st(1) +# CHECK-NEXT: 1 4 4.00 U fmulp %st, %st(2) # CHECK-NEXT: 1 4 4.00 * U fimuls (%ecx) # CHECK-NEXT: 1 4 4.00 * U fimull (%eax) # CHECK-NEXT: 1 1 0.50 U fnop @@ -321,20 +321,20 @@ fyl2xp1 # CHECK-NEXT: 1 100 0.50 U frstor (%eax) # CHECK-NEXT: 1 1 0.50 U wait # CHECK-NEXT: 1 100 0.50 U fnsave (%eax) -# CHECK-NEXT: 1 5 5.00 U fsub %st(0), %st(1) -# CHECK-NEXT: 1 5 5.00 U fsub %st(2) +# CHECK-NEXT: 1 5 5.00 U fsub %st, %st(1) +# CHECK-NEXT: 1 5 5.00 U fsub %st(2), %st # CHECK-NEXT: 1 5 5.00 * U fsubs (%ecx) # CHECK-NEXT: 1 5 5.00 * U fsubl (%eax) -# CHECK-NEXT: 1 5 5.00 U fsubp %st(1) -# CHECK-NEXT: 1 5 5.00 U fsubp %st(2) +# CHECK-NEXT: 1 5 5.00 U fsubp %st, %st(1) +# CHECK-NEXT: 1 5 5.00 U fsubp %st, %st(2) # CHECK-NEXT: 1 5 5.00 * U fisubs (%ecx) # CHECK-NEXT: 1 5 5.00 * U fisubl (%eax) -# CHECK-NEXT: 1 5 5.00 U fsubr %st(0), %st(1) -# CHECK-NEXT: 1 5 5.00 U fsubr %st(2) +# CHECK-NEXT: 1 5 5.00 U fsubr %st, %st(1) +# CHECK-NEXT: 1 5 5.00 U fsubr %st(2), %st # CHECK-NEXT: 1 5 5.00 * U fsubrs (%ecx) # CHECK-NEXT: 1 5 5.00 * U fsubrl (%eax) -# CHECK-NEXT: 1 5 5.00 U fsubrp %st(1) -# CHECK-NEXT: 1 5 5.00 U fsubrp %st(2) +# CHECK-NEXT: 1 5 5.00 U fsubrp %st, %st(1) +# CHECK-NEXT: 1 5 5.00 U fsubrp %st, %st(2) # CHECK-NEXT: 1 5 5.00 * U fisubrs (%ecx) # CHECK-NEXT: 1 5 5.00 * U fisubrl (%eax) # CHECK-NEXT: 1 9 4.50 U ftst @@ -343,8 +343,8 @@ fyl2xp1 # CHECK-NEXT: 1 1 1.00 U fucomp %st(1) # CHECK-NEXT: 1 1 1.00 U fucomp %st(3) # CHECK-NEXT: 1 1 1.00 U fucompp -# CHECK-NEXT: 1 9 4.50 U fucomi %st(3) -# CHECK-NEXT: 1 9 4.50 U fucompi %st(3) +# CHECK-NEXT: 1 9 4.50 U fucomi %st(3), %st +# CHECK-NEXT: 1 9 4.50 U fucompi %st(3), %st # CHECK-NEXT: 1 1 0.50 U wait # CHECK-NEXT: 1 1 1.00 U fxam # CHECK-NEXT: 1 1 1.00 U fxch %st(1) @@ -367,26 +367,26 @@ fyl2xp1 # CHECK-NEXT: [0] [1] Instructions: # CHECK-NEXT: 49.50 49.50 f2xm1 # CHECK-NEXT: - 1.00 fabs -# CHECK-NEXT: 5.00 - fadd %st(0), %st(1) -# CHECK-NEXT: 5.00 - fadd %st(2) +# CHECK-NEXT: 5.00 - fadd %st, %st(1) +# CHECK-NEXT: 5.00 - fadd %st(2), %st # CHECK-NEXT: 5.00 - fadds (%ecx) # CHECK-NEXT: 5.00 - faddl (%ecx) -# CHECK-NEXT: 5.00 - faddp %st(1) -# CHECK-NEXT: 5.00 - faddp %st(2) +# CHECK-NEXT: 5.00 - faddp %st, %st(1) +# CHECK-NEXT: 5.00 - faddp %st, %st(2) # CHECK-NEXT: 5.00 - fiadds (%ecx) # CHECK-NEXT: 5.00 - fiaddl (%ecx) # CHECK-NEXT: 0.50 0.50 fbld (%ecx) # CHECK-NEXT: 0.50 0.50 fbstp (%eax) # CHECK-NEXT: - 1.00 fchs # CHECK-NEXT: 12.50 12.50 fnclex -# CHECK-NEXT: 4.50 4.50 fcmovb %st(1), %st(0) -# CHECK-NEXT: 4.50 4.50 fcmovbe %st(1), %st(0) -# CHECK-NEXT: 4.50 4.50 fcmove %st(1), %st(0) -# CHECK-NEXT: 4.50 4.50 fcmovnb %st(1), %st(0) -# CHECK-NEXT: 4.50 4.50 fcmovnbe %st(1), %st(0) -# CHECK-NEXT: 4.50 4.50 fcmovne %st(1), %st(0) -# CHECK-NEXT: 4.50 4.50 fcmovnu %st(1), %st(0) -# CHECK-NEXT: 4.50 4.50 fcmovu %st(1), %st(0) +# CHECK-NEXT: 4.50 4.50 fcmovb %st(1), %st +# CHECK-NEXT: 4.50 4.50 fcmovbe %st(1), %st +# CHECK-NEXT: 4.50 4.50 fcmove %st(1), %st +# CHECK-NEXT: 4.50 4.50 fcmovnb %st(1), %st +# CHECK-NEXT: 4.50 4.50 fcmovnbe %st(1), %st +# CHECK-NEXT: 4.50 4.50 fcmovne %st(1), %st +# CHECK-NEXT: 4.50 4.50 fcmovnu %st(1), %st +# CHECK-NEXT: 4.50 4.50 fcmovu %st(1), %st # CHECK-NEXT: 5.00 - fcom %st(1) # CHECK-NEXT: 5.00 - fcom %st(3) # CHECK-NEXT: 5.00 - fcoms (%ecx) @@ -396,24 +396,24 @@ fyl2xp1 # CHECK-NEXT: 5.00 - fcomps (%ecx) # CHECK-NEXT: 5.00 - fcompl (%eax) # CHECK-NEXT: - 1.00 fcompp -# CHECK-NEXT: 4.50 4.50 fcomi %st(3) -# CHECK-NEXT: 4.50 4.50 fcompi %st(3) +# CHECK-NEXT: 4.50 4.50 fcomi %st(3), %st +# CHECK-NEXT: 4.50 4.50 fcompi %st(3), %st # CHECK-NEXT: 87.00 87.00 fcos # CHECK-NEXT: 0.50 0.50 fdecstp -# CHECK-NEXT: 17.00 17.00 fdiv %st(0), %st(1) -# CHECK-NEXT: 17.00 17.00 fdiv %st(2) +# CHECK-NEXT: 17.00 17.00 fdiv %st, %st(1) +# CHECK-NEXT: 17.00 17.00 fdiv %st(2), %st # CHECK-NEXT: 17.00 17.00 fdivs (%ecx) # CHECK-NEXT: 17.00 17.00 fdivl (%eax) -# CHECK-NEXT: 17.00 17.00 fdivp %st(1) -# CHECK-NEXT: 17.00 17.00 fdivp %st(2) +# CHECK-NEXT: 17.00 17.00 fdivp %st, %st(1) +# CHECK-NEXT: 17.00 17.00 fdivp %st, %st(2) # CHECK-NEXT: 17.00 17.00 fidivs (%ecx) # CHECK-NEXT: 17.00 17.00 fidivl (%eax) -# CHECK-NEXT: 17.00 17.00 fdivr %st(0), %st(1) -# CHECK-NEXT: 17.00 17.00 fdivr %st(2) +# CHECK-NEXT: 17.00 17.00 fdivr %st, %st(1) +# CHECK-NEXT: 17.00 17.00 fdivr %st(2), %st # CHECK-NEXT: 17.00 17.00 fdivrs (%ecx) # CHECK-NEXT: 17.00 17.00 fdivrl (%eax) -# CHECK-NEXT: 17.00 17.00 fdivrp %st(1) -# CHECK-NEXT: 17.00 17.00 fdivrp %st(2) +# CHECK-NEXT: 17.00 17.00 fdivrp %st, %st(1) +# CHECK-NEXT: 17.00 17.00 fdivrp %st, %st(2) # CHECK-NEXT: 17.00 17.00 fidivrs (%ecx) # CHECK-NEXT: 17.00 17.00 fidivrl (%eax) # CHECK-NEXT: 0.50 0.50 ffree %st(0) @@ -447,12 +447,12 @@ fyl2xp1 # CHECK-NEXT: 5.00 5.00 fldln2 # CHECK-NEXT: 5.00 5.00 fldpi # CHECK-NEXT: 0.50 0.50 fldz -# CHECK-NEXT: 4.00 - fmul %st(0), %st(1) -# CHECK-NEXT: 4.00 - fmul %st(2) +# CHECK-NEXT: 4.00 - fmul %st, %st(1) +# CHECK-NEXT: 4.00 - fmul %st(2), %st # CHECK-NEXT: 4.00 - fmuls (%ecx) # CHECK-NEXT: 4.00 - fmull (%eax) -# CHECK-NEXT: 4.00 - fmulp %st(1) -# CHECK-NEXT: 4.00 - fmulp %st(2) +# CHECK-NEXT: 4.00 - fmulp %st, %st(1) +# CHECK-NEXT: 4.00 - fmulp %st, %st(2) # CHECK-NEXT: 4.00 - fimuls (%ecx) # CHECK-NEXT: 4.00 - fimull (%eax) # CHECK-NEXT: 0.50 0.50 fnop @@ -480,20 +480,20 @@ fyl2xp1 # CHECK-NEXT: 0.50 0.50 frstor (%eax) # CHECK-NEXT: 0.50 0.50 wait # CHECK-NEXT: 0.50 0.50 fnsave (%eax) -# CHECK-NEXT: 5.00 - fsub %st(0), %st(1) -# CHECK-NEXT: 5.00 - fsub %st(2) +# CHECK-NEXT: 5.00 - fsub %st, %st(1) +# CHECK-NEXT: 5.00 - fsub %st(2), %st # CHECK-NEXT: 5.00 - fsubs (%ecx) # CHECK-NEXT: 5.00 - fsubl (%eax) -# CHECK-NEXT: 5.00 - fsubp %st(1) -# CHECK-NEXT: 5.00 - fsubp %st(2) +# CHECK-NEXT: 5.00 - fsubp %st, %st(1) +# CHECK-NEXT: 5.00 - fsubp %st, %st(2) # CHECK-NEXT: 5.00 - fisubs (%ecx) # CHECK-NEXT: 5.00 - fisubl (%eax) -# CHECK-NEXT: 5.00 - fsubr %st(0), %st(1) -# CHECK-NEXT: 5.00 - fsubr %st(2) +# CHECK-NEXT: 5.00 - fsubr %st, %st(1) +# CHECK-NEXT: 5.00 - fsubr %st(2), %st # CHECK-NEXT: 5.00 - fsubrs (%ecx) # CHECK-NEXT: 5.00 - fsubrl (%eax) -# CHECK-NEXT: 5.00 - fsubrp %st(1) -# CHECK-NEXT: 5.00 - fsubrp %st(2) +# CHECK-NEXT: 5.00 - fsubrp %st, %st(1) +# CHECK-NEXT: 5.00 - fsubrp %st, %st(2) # CHECK-NEXT: 5.00 - fisubrs (%ecx) # CHECK-NEXT: 5.00 - fisubrl (%eax) # CHECK-NEXT: 4.50 4.50 ftst @@ -502,8 +502,8 @@ fyl2xp1 # CHECK-NEXT: - 1.00 fucomp %st(1) # CHECK-NEXT: - 1.00 fucomp %st(3) # CHECK-NEXT: - 1.00 fucompp -# CHECK-NEXT: 4.50 4.50 fucomi %st(3) -# CHECK-NEXT: 4.50 4.50 fucompi %st(3) +# CHECK-NEXT: 4.50 4.50 fucomi %st(3), %st +# CHECK-NEXT: 4.50 4.50 fucompi %st(3), %st # CHECK-NEXT: 0.50 0.50 wait # CHECK-NEXT: 1.00 - fxam # CHECK-NEXT: 1.00 1.00 fxch %st(1) diff --git a/llvm/test/tools/llvm-mca/X86/BdVer2/resources-x87.s b/llvm/test/tools/llvm-mca/X86/BdVer2/resources-x87.s index ad72714c74c1b..4cdddf01104b0 100644 --- a/llvm/test/tools/llvm-mca/X86/BdVer2/resources-x87.s +++ b/llvm/test/tools/llvm-mca/X86/BdVer2/resources-x87.s @@ -5,7 +5,7 @@ f2xm1 fabs -fadd %st(0), %st(1) +fadd %st, %st(1) fadd %st(2) fadds (%ecx) faddl (%ecx) @@ -21,14 +21,14 @@ fchs fnclex -fcmovb %st(1), %st(0) -fcmovbe %st(1), %st(0) -fcmove %st(1), %st(0) -fcmovnb %st(1), %st(0) -fcmovnbe %st(1), %st(0) -fcmovne %st(1), %st(0) -fcmovnu %st(1), %st(0) -fcmovu %st(1), %st(0) +fcmovb %st(1), %st +fcmovbe %st(1), %st +fcmove %st(1), %st +fcmovnb %st(1), %st +fcmovnbe %st(1), %st +fcmovne %st(1), %st +fcmovnu %st(1), %st +fcmovu %st(1), %st fcom %st(1) fcom %st(3) @@ -47,7 +47,7 @@ fcos fdecstp -fdiv %st(0), %st(1) +fdiv %st, %st(1) fdiv %st(2) fdivs (%ecx) fdivl (%eax) @@ -56,7 +56,7 @@ fdivp %st(2) fidivs (%ecx) fidivl (%eax) -fdivr %st(0), %st(1) +fdivr %st, %st(1) fdivr %st(2) fdivrs (%ecx) fdivrl (%eax) @@ -106,7 +106,7 @@ fldln2 fldpi fldz -fmul %st(0), %st(1) +fmul %st, %st(1) fmul %st(2) fmuls (%ecx) fmull (%eax) @@ -153,7 +153,7 @@ fnstsw (%eax) frstor (%eax) fsave (%eax) -fsub %st(0), %st(1) +fsub %st, %st(1) fsub %st(2) fsubs (%ecx) fsubl (%eax) @@ -162,7 +162,7 @@ fsubp %st(2) fisubs (%ecx) fisubl (%eax) -fsubr %st(0), %st(1) +fsubr %st, %st(1) fsubr %st(2) fsubrs (%ecx) fsubrl (%eax) @@ -208,26 +208,26 @@ fyl2xp1 # CHECK: [1] [2] [3] [4] [5] [6] Instructions: # CHECK-NEXT: 1 100 0.50 U f2xm1 # CHECK-NEXT: 1 1 1.00 U fabs -# CHECK-NEXT: 1 5 1.00 U fadd %st(0), %st(1) -# CHECK-NEXT: 1 5 1.00 U fadd %st(2) +# CHECK-NEXT: 1 5 1.00 U fadd %st, %st(1) +# CHECK-NEXT: 1 5 1.00 U fadd %st(2), %st # CHECK-NEXT: 1 10 1.00 * U fadds (%ecx) # CHECK-NEXT: 1 10 1.00 * U faddl (%ecx) -# CHECK-NEXT: 1 5 1.00 U faddp %st(1) -# CHECK-NEXT: 1 5 1.00 U faddp %st(2) +# CHECK-NEXT: 1 5 1.00 U faddp %st, %st(1) +# CHECK-NEXT: 1 5 1.00 U faddp %st, %st(2) # CHECK-NEXT: 1 10 1.00 * U fiadds (%ecx) # CHECK-NEXT: 1 10 1.00 * U fiaddl (%ecx) # CHECK-NEXT: 1 100 0.50 U fbld (%ecx) # CHECK-NEXT: 1 100 0.50 U fbstp (%eax) # CHECK-NEXT: 1 1 1.00 U fchs # CHECK-NEXT: 1 100 0.50 U fnclex -# CHECK-NEXT: 1 1 1.00 U fcmovb %st(1), %st(0) -# CHECK-NEXT: 1 1 1.00 U fcmovbe %st(1), %st(0) -# CHECK-NEXT: 1 1 1.00 U fcmove %st(1), %st(0) -# CHECK-NEXT: 1 1 1.00 U fcmovnb %st(1), %st(0) -# CHECK-NEXT: 1 1 1.00 U fcmovnbe %st(1), %st(0) -# CHECK-NEXT: 1 1 1.00 U fcmovne %st(1), %st(0) -# CHECK-NEXT: 1 1 1.00 U fcmovnu %st(1), %st(0) -# CHECK-NEXT: 1 1 1.00 U fcmovu %st(1), %st(0) +# CHECK-NEXT: 1 1 1.00 U fcmovb %st(1), %st +# CHECK-NEXT: 1 1 1.00 U fcmovbe %st(1), %st +# CHECK-NEXT: 1 1 1.00 U fcmove %st(1), %st +# CHECK-NEXT: 1 1 1.00 U fcmovnb %st(1), %st +# CHECK-NEXT: 1 1 1.00 U fcmovnbe %st(1), %st +# CHECK-NEXT: 1 1 1.00 U fcmovne %st(1), %st +# CHECK-NEXT: 1 1 1.00 U fcmovnu %st(1), %st +# CHECK-NEXT: 1 1 1.00 U fcmovu %st(1), %st # CHECK-NEXT: 2 1 1.00 U fcom %st(1) # CHECK-NEXT: 2 1 1.00 U fcom %st(3) # CHECK-NEXT: 1 6 1.00 U fcoms (%ecx) @@ -237,24 +237,24 @@ fyl2xp1 # CHECK-NEXT: 1 6 1.00 U fcomps (%ecx) # CHECK-NEXT: 1 6 1.00 U fcompl (%eax) # CHECK-NEXT: 1 100 0.50 U fcompp -# CHECK-NEXT: 2 1 1.00 U fcomi %st(3) -# CHECK-NEXT: 2 1 1.00 U fcompi %st(3) +# CHECK-NEXT: 2 1 1.00 U fcomi %st(3), %st +# CHECK-NEXT: 2 1 1.00 U fcompi %st(3), %st # CHECK-NEXT: 1 100 0.50 U fcos # CHECK-NEXT: 1 100 0.50 U fdecstp -# CHECK-NEXT: 1 9 9.50 U fdiv %st(0), %st(1) -# CHECK-NEXT: 1 9 9.50 U fdiv %st(2) +# CHECK-NEXT: 1 9 9.50 U fdiv %st, %st(1) +# CHECK-NEXT: 1 9 9.50 U fdiv %st(2), %st # CHECK-NEXT: 1 14 9.50 * U fdivs (%ecx) # CHECK-NEXT: 1 14 9.50 * U fdivl (%eax) -# CHECK-NEXT: 1 9 9.50 U fdivp %st(1) -# CHECK-NEXT: 1 9 9.50 U fdivp %st(2) +# CHECK-NEXT: 1 9 9.50 U fdivp %st, %st(1) +# CHECK-NEXT: 1 9 9.50 U fdivp %st, %st(2) # CHECK-NEXT: 1 14 9.50 * U fidivs (%ecx) # CHECK-NEXT: 1 14 9.50 * U fidivl (%eax) -# CHECK-NEXT: 1 9 9.50 U fdivr %st(0), %st(1) -# CHECK-NEXT: 1 9 9.50 U fdivr %st(2) +# CHECK-NEXT: 1 9 9.50 U fdivr %st, %st(1) +# CHECK-NEXT: 1 9 9.50 U fdivr %st(2), %st # CHECK-NEXT: 1 14 9.50 * U fdivrs (%ecx) # CHECK-NEXT: 1 14 9.50 * U fdivrl (%eax) -# CHECK-NEXT: 1 9 9.50 U fdivrp %st(1) -# CHECK-NEXT: 1 9 9.50 U fdivrp %st(2) +# CHECK-NEXT: 1 9 9.50 U fdivrp %st, %st(1) +# CHECK-NEXT: 1 9 9.50 U fdivrp %st, %st(2) # CHECK-NEXT: 1 14 9.50 * U fidivrs (%ecx) # CHECK-NEXT: 1 14 9.50 * U fidivrl (%eax) # CHECK-NEXT: 1 100 0.50 U ffree %st(0) @@ -288,12 +288,12 @@ fyl2xp1 # CHECK-NEXT: 1 3 1.00 U fldln2 # CHECK-NEXT: 1 3 1.00 U fldpi # CHECK-NEXT: 1 3 1.00 U fldz -# CHECK-NEXT: 1 5 1.00 U fmul %st(0), %st(1) -# CHECK-NEXT: 1 5 1.00 U fmul %st(2) +# CHECK-NEXT: 1 5 1.00 U fmul %st, %st(1) +# CHECK-NEXT: 1 5 1.00 U fmul %st(2), %st # CHECK-NEXT: 1 10 1.00 * U fmuls (%ecx) # CHECK-NEXT: 1 10 1.00 * U fmull (%eax) -# CHECK-NEXT: 1 5 1.00 U fmulp %st(1) -# CHECK-NEXT: 1 5 1.00 U fmulp %st(2) +# CHECK-NEXT: 1 5 1.00 U fmulp %st, %st(1) +# CHECK-NEXT: 1 5 1.00 U fmulp %st, %st(2) # CHECK-NEXT: 1 10 1.00 * U fimuls (%ecx) # CHECK-NEXT: 1 10 1.00 * U fimull (%eax) # CHECK-NEXT: 1 1 0.50 U fnop @@ -321,20 +321,20 @@ fyl2xp1 # CHECK-NEXT: 1 100 0.50 U frstor (%eax) # CHECK-NEXT: 1 100 0.50 U wait # CHECK-NEXT: 1 100 0.50 U fnsave (%eax) -# CHECK-NEXT: 1 5 1.00 U fsub %st(0), %st(1) -# CHECK-NEXT: 1 5 1.00 U fsub %st(2) +# CHECK-NEXT: 1 5 1.00 U fsub %st, %st(1) +# CHECK-NEXT: 1 5 1.00 U fsub %st(2), %st # CHECK-NEXT: 1 10 1.00 * U fsubs (%ecx) # CHECK-NEXT: 1 10 1.00 * U fsubl (%eax) -# CHECK-NEXT: 1 5 1.00 U fsubp %st(1) -# CHECK-NEXT: 1 5 1.00 U fsubp %st(2) +# CHECK-NEXT: 1 5 1.00 U fsubp %st, %st(1) +# CHECK-NEXT: 1 5 1.00 U fsubp %st, %st(2) # CHECK-NEXT: 1 10 1.00 * U fisubs (%ecx) # CHECK-NEXT: 1 10 1.00 * U fisubl (%eax) -# CHECK-NEXT: 1 5 1.00 U fsubr %st(0), %st(1) -# CHECK-NEXT: 1 5 1.00 U fsubr %st(2) +# CHECK-NEXT: 1 5 1.00 U fsubr %st, %st(1) +# CHECK-NEXT: 1 5 1.00 U fsubr %st(2), %st # CHECK-NEXT: 1 10 1.00 * U fsubrs (%ecx) # CHECK-NEXT: 1 10 1.00 * U fsubrl (%eax) -# CHECK-NEXT: 1 5 1.00 U fsubrp %st(1) -# CHECK-NEXT: 1 5 1.00 U fsubrp %st(2) +# CHECK-NEXT: 1 5 1.00 U fsubrp %st, %st(1) +# CHECK-NEXT: 1 5 1.00 U fsubrp %st, %st(2) # CHECK-NEXT: 1 10 1.00 * U fisubrs (%ecx) # CHECK-NEXT: 1 10 1.00 * U fisubrl (%eax) # CHECK-NEXT: 1 1 1.00 U ftst @@ -343,8 +343,8 @@ fyl2xp1 # CHECK-NEXT: 2 1 1.00 U fucomp %st(1) # CHECK-NEXT: 2 1 1.00 U fucomp %st(3) # CHECK-NEXT: 1 1 1.00 U fucompp -# CHECK-NEXT: 2 1 1.00 U fucomi %st(3) -# CHECK-NEXT: 2 1 1.00 U fucompi %st(3) +# CHECK-NEXT: 2 1 1.00 U fucomi %st(3), %st +# CHECK-NEXT: 2 1 1.00 U fucompi %st(3), %st # CHECK-NEXT: 1 100 0.50 U wait # CHECK-NEXT: 1 100 0.50 U fxam # CHECK-NEXT: 1 1 0.50 U fxch %st(1) @@ -388,26 +388,26 @@ fyl2xp1 # CHECK-NEXT: [0.0] [0.1] [1] [2] [3] [4] [5] [6] [7.0] [7.1] [8.0] [8.1] [9] [10] [11] [12] [13] [14] [15] [16.0] [16.1] [17] [18] Instructions: # CHECK-NEXT: - - - - - 0.50 0.50 - - - - - - - - - - - - - - - - f2xm1 # CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - - 1.00 - - - - - - - fabs -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fadd %st(0), %st(1) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fadd %st(2) +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fadd %st, %st(1) +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fadd %st(2), %st # CHECK-NEXT: 0.50 0.50 - - - - - - 0.50 0.50 - - - - 1.00 - - - - 0.50 0.50 - - fadds (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - 0.50 0.50 - - - - 1.00 - - - - 0.50 0.50 - - faddl (%ecx) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - faddp %st(1) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - faddp %st(2) +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - faddp %st, %st(1) +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - faddp %st, %st(2) # CHECK-NEXT: 0.50 0.50 - - - - - - 0.50 0.50 - - - - 1.00 - - - - 0.50 0.50 - - fiadds (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - 0.50 0.50 - - - - 1.00 - - - - 0.50 0.50 - - fiaddl (%ecx) # CHECK-NEXT: - - - - - 0.50 0.50 - - - - - - - - - - - - - - - - fbld (%ecx) # CHECK-NEXT: - - - - - 0.50 0.50 - - - - - - - - - - - - - - - - fbstp (%eax) # CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - - 1.00 - - - - - - - fchs # CHECK-NEXT: - - - - - 0.50 0.50 - - - - - - - - - - - - - - - - fnclex -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcmovb %st(1), %st(0) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcmovbe %st(1), %st(0) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcmove %st(1), %st(0) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcmovnb %st(1), %st(0) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcmovnbe %st(1), %st(0) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcmovne %st(1), %st(0) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcmovnu %st(1), %st(0) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcmovu %st(1), %st(0) +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcmovb %st(1), %st +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcmovbe %st(1), %st +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcmove %st(1), %st +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcmovnb %st(1), %st +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcmovnbe %st(1), %st +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcmovne %st(1), %st +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcmovnu %st(1), %st +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcmovu %st(1), %st # CHECK-NEXT: - - - - - 1.00 - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcom %st(1) # CHECK-NEXT: - - - - - 1.00 - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcom %st(3) # CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - - 1.00 - - - - - - - fcoms (%ecx) @@ -417,24 +417,24 @@ fyl2xp1 # CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - - 1.00 - - - - - - - fcomps (%ecx) # CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - - 1.00 - - - - - - - fcompl (%eax) # CHECK-NEXT: - - - - - 0.50 0.50 - - - - - - - - - - - - - - - - fcompp -# CHECK-NEXT: - - - - - 1.00 - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcomi %st(3) -# CHECK-NEXT: - - - - - 1.00 - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcompi %st(3) +# CHECK-NEXT: - - - - - 1.00 - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcomi %st(3), %st +# CHECK-NEXT: - - - - - 1.00 - - 0.50 0.50 - - - - 1.00 - - - - - - - - fcompi %st(3), %st # CHECK-NEXT: - - - - - 0.50 0.50 - - - - - - - - - - - - - - - - fcos # CHECK-NEXT: - - - - - 0.50 0.50 - - - - - - - - - - - - - - - - fdecstp -# CHECK-NEXT: - - - - - - - - 9.50 9.50 - - - - - 1.00 - - - - - - - fdiv %st(0), %st(1) -# CHECK-NEXT: - - - - - - - - 9.50 9.50 - - - - - 1.00 - - - - - - - fdiv %st(2) +# CHECK-NEXT: - - - - - - - - 9.50 9.50 - - - - - 1.00 - - - - - - - fdiv %st, %st(1) +# CHECK-NEXT: - - - - - - - - 9.50 9.50 - - - - - 1.00 - - - - - - - fdiv %st(2), %st # CHECK-NEXT: 0.50 0.50 - - - - - - 9.50 9.50 - - - - - 1.00 - - - 0.50 0.50 - - fdivs (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - 9.50 9.50 - - - - - 1.00 - - - 0.50 0.50 - - fdivl (%eax) -# CHECK-NEXT: - - - - - - - - 9.50 9.50 - - - - - 1.00 - - - - - - - fdivp %st(1) -# CHECK-NEXT: - - - - - - - - 9.50 9.50 - - - - - 1.00 - - - - - - - fdivp %st(2) +# CHECK-NEXT: - - - - - - - - 9.50 9.50 - - - - - 1.00 - - - - - - - fdivp %st, %st(1) +# CHECK-NEXT: - - - - - - - - 9.50 9.50 - - - - - 1.00 - - - - - - - fdivp %st, %st(2) # CHECK-NEXT: 0.50 0.50 - - - - - - 9.50 9.50 - - - - - 1.00 - - - 0.50 0.50 - - fidivs (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - 9.50 9.50 - - - - - 1.00 - - - 0.50 0.50 - - fidivl (%eax) -# CHECK-NEXT: - - - - - - - - 9.50 9.50 - - - - - 1.00 - - - - - - - fdivr %st(0), %st(1) -# CHECK-NEXT: - - - - - - - - 9.50 9.50 - - - - - 1.00 - - - - - - - fdivr %st(2) +# CHECK-NEXT: - - - - - - - - 9.50 9.50 - - - - - 1.00 - - - - - - - fdivr %st, %st(1) +# CHECK-NEXT: - - - - - - - - 9.50 9.50 - - - - - 1.00 - - - - - - - fdivr %st(2), %st # CHECK-NEXT: 0.50 0.50 - - - - - - 9.50 9.50 - - - - - 1.00 - - - 0.50 0.50 - - fdivrs (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - 9.50 9.50 - - - - - 1.00 - - - 0.50 0.50 - - fdivrl (%eax) -# CHECK-NEXT: - - - - - - - - 9.50 9.50 - - - - - 1.00 - - - - - - - fdivrp %st(1) -# CHECK-NEXT: - - - - - - - - 9.50 9.50 - - - - - 1.00 - - - - - - - fdivrp %st(2) +# CHECK-NEXT: - - - - - - - - 9.50 9.50 - - - - - 1.00 - - - - - - - fdivrp %st, %st(1) +# CHECK-NEXT: - - - - - - - - 9.50 9.50 - - - - - 1.00 - - - - - - - fdivrp %st, %st(2) # CHECK-NEXT: 0.50 0.50 - - - - - - 9.50 9.50 - - - - - 1.00 - - - 0.50 0.50 - - fidivrs (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - 9.50 9.50 - - - - - 1.00 - - - 0.50 0.50 - - fidivrl (%eax) # CHECK-NEXT: - - - - - 0.50 0.50 - - - - - - - - - - - - - - - - ffree %st(0) @@ -468,12 +468,12 @@ fyl2xp1 # CHECK-NEXT: - - - - - - - - - - - - - 1.00 - 1.00 - - - - - - - fldln2 # CHECK-NEXT: - - - - - - - - - - - - - 1.00 - 1.00 - - - - - - - fldpi # CHECK-NEXT: - - - - - - - - - - - - - 1.00 - 1.00 - - - - - - - fldz -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - - 1.00 - - - - - - - fmul %st(0), %st(1) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - - 1.00 - - - - - - - fmul %st(2) +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - - 1.00 - - - - - - - fmul %st, %st(1) +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - - 1.00 - - - - - - - fmul %st(2), %st # CHECK-NEXT: 0.50 0.50 - - - - - - 0.50 0.50 - - - - - 1.00 - - - 0.50 0.50 - - fmuls (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - 0.50 0.50 - - - - - 1.00 - - - 0.50 0.50 - - fmull (%eax) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - - 1.00 - - - - - - - fmulp %st(1) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - - 1.00 - - - - - - - fmulp %st(2) +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - - 1.00 - - - - - - - fmulp %st, %st(1) +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - - 1.00 - - - - - - - fmulp %st, %st(2) # CHECK-NEXT: 0.50 0.50 - - - - - - 0.50 0.50 - - - - - 1.00 - - - 0.50 0.50 - - fimuls (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - 0.50 0.50 - - - - - 1.00 - - - 0.50 0.50 - - fimull (%eax) # CHECK-NEXT: - - - - - 0.50 0.50 - - - - - - - - - - - - - - - - fnop @@ -501,20 +501,20 @@ fyl2xp1 # CHECK-NEXT: - - - - - 0.50 0.50 - - - - - - - - - - - - - - - - frstor (%eax) # CHECK-NEXT: - - - - - 0.50 0.50 - - - - - - - - - - - - - - - - wait # CHECK-NEXT: - - - - - 0.50 0.50 - - - - - - - - - - - - - - - - fnsave (%eax) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fsub %st(0), %st(1) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fsub %st(2) +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fsub %st, %st(1) +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fsub %st(2), %st # CHECK-NEXT: 0.50 0.50 - - - - - - 0.50 0.50 - - - - 1.00 - - - - 0.50 0.50 - - fsubs (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - 0.50 0.50 - - - - 1.00 - - - - 0.50 0.50 - - fsubl (%eax) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fsubp %st(1) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fsubp %st(2) +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fsubp %st, %st(1) +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fsubp %st, %st(2) # CHECK-NEXT: 0.50 0.50 - - - - - - 0.50 0.50 - - - - 1.00 - - - - 0.50 0.50 - - fisubs (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - 0.50 0.50 - - - - 1.00 - - - - 0.50 0.50 - - fisubl (%eax) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fsubr %st(0), %st(1) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fsubr %st(2) +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fsubr %st, %st(1) +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fsubr %st(2), %st # CHECK-NEXT: 0.50 0.50 - - - - - - 0.50 0.50 - - - - 1.00 - - - - 0.50 0.50 - - fsubrs (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - 0.50 0.50 - - - - 1.00 - - - - 0.50 0.50 - - fsubrl (%eax) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fsubrp %st(1) -# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fsubrp %st(2) +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fsubrp %st, %st(1) +# CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - 1.00 - - - - - - - - fsubrp %st, %st(2) # CHECK-NEXT: 0.50 0.50 - - - - - - 0.50 0.50 - - - - 1.00 - - - - 0.50 0.50 - - fisubrs (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - 0.50 0.50 - - - - 1.00 - - - - 0.50 0.50 - - fisubrl (%eax) # CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - - 1.00 - - - - - - - ftst @@ -523,8 +523,8 @@ fyl2xp1 # CHECK-NEXT: - - - - - 1.00 - - 0.50 0.50 - - - - 1.00 - - - - - - - - fucomp %st(1) # CHECK-NEXT: - - - - - 1.00 - - 0.50 0.50 - - - - 1.00 - - - - - - - - fucomp %st(3) # CHECK-NEXT: - - - - - - - - 0.50 0.50 - - - - - 1.00 - - - - - - - fucompp -# CHECK-NEXT: - - - - - 1.00 - - 0.50 0.50 - - - - 1.00 - - - - - - - - fucomi %st(3) -# CHECK-NEXT: - - - - - 1.00 - - 0.50 0.50 - - - - 1.00 - - - - - - - - fucompi %st(3) +# CHECK-NEXT: - - - - - 1.00 - - 0.50 0.50 - - - - 1.00 - - - - - - - - fucomi %st(3), %st +# CHECK-NEXT: - - - - - 1.00 - - 0.50 0.50 - - - - 1.00 - - - - - - - - fucompi %st(3), %st # CHECK-NEXT: - - - - - 0.50 0.50 - - - - - - - - - - - - - - - - wait # CHECK-NEXT: - - - - - 0.50 0.50 - - - - - - - - - - - - - - - - fxam # CHECK-NEXT: - - - - - 0.50 0.50 - - - - - - - - - - - - - - - - fxch %st(1) diff --git a/llvm/test/tools/llvm-mca/X86/Broadwell/resources-x87.s b/llvm/test/tools/llvm-mca/X86/Broadwell/resources-x87.s index 5cb92be47eabb..2f3a69da99d07 100644 --- a/llvm/test/tools/llvm-mca/X86/Broadwell/resources-x87.s +++ b/llvm/test/tools/llvm-mca/X86/Broadwell/resources-x87.s @@ -5,7 +5,7 @@ f2xm1 fabs -fadd %st(0), %st(1) +fadd %st, %st(1) fadd %st(2) fadds (%ecx) faddl (%ecx) @@ -21,14 +21,14 @@ fchs fnclex -fcmovb %st(1), %st(0) -fcmovbe %st(1), %st(0) -fcmove %st(1), %st(0) -fcmovnb %st(1), %st(0) -fcmovnbe %st(1), %st(0) -fcmovne %st(1), %st(0) -fcmovnu %st(1), %st(0) -fcmovu %st(1), %st(0) +fcmovb %st(1), %st +fcmovbe %st(1), %st +fcmove %st(1), %st +fcmovnb %st(1), %st +fcmovnbe %st(1), %st +fcmovne %st(1), %st +fcmovnu %st(1), %st +fcmovu %st(1), %st fcom %st(1) fcom %st(3) @@ -47,7 +47,7 @@ fcos fdecstp -fdiv %st(0), %st(1) +fdiv %st, %st(1) fdiv %st(2) fdivs (%ecx) fdivl (%eax) @@ -56,7 +56,7 @@ fdivp %st(2) fidivs (%ecx) fidivl (%eax) -fdivr %st(0), %st(1) +fdivr %st, %st(1) fdivr %st(2) fdivrs (%ecx) fdivrl (%eax) @@ -106,7 +106,7 @@ fldln2 fldpi fldz -fmul %st(0), %st(1) +fmul %st, %st(1) fmul %st(2) fmuls (%ecx) fmull (%eax) @@ -153,7 +153,7 @@ fnstsw (%eax) frstor (%eax) fsave (%eax) -fsub %st(0), %st(1) +fsub %st, %st(1) fsub %st(2) fsubs (%ecx) fsubl (%eax) @@ -162,7 +162,7 @@ fsubp %st(2) fisubs (%ecx) fisubl (%eax) -fsubr %st(0), %st(1) +fsubr %st, %st(1) fsubr %st(2) fsubrs (%ecx) fsubrl (%eax) @@ -208,26 +208,26 @@ fyl2xp1 # CHECK: [1] [2] [3] [4] [5] [6] Instructions: # CHECK-NEXT: 1 100 0.25 U f2xm1 # CHECK-NEXT: 1 1 1.00 U fabs -# CHECK-NEXT: 1 3 1.00 U fadd %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fadd %st(2) +# CHECK-NEXT: 1 3 1.00 U fadd %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fadd %st(2), %st # CHECK-NEXT: 2 9 1.00 * U fadds (%ecx) # CHECK-NEXT: 2 9 1.00 * U faddl (%ecx) -# CHECK-NEXT: 1 3 1.00 U faddp %st(1) -# CHECK-NEXT: 1 3 1.00 U faddp %st(2) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(2) # CHECK-NEXT: 3 12 2.00 * U fiadds (%ecx) # CHECK-NEXT: 3 12 2.00 * U fiaddl (%ecx) # CHECK-NEXT: 1 100 0.25 U fbld (%ecx) # CHECK-NEXT: 2 1 1.00 U fbstp (%eax) # CHECK-NEXT: 1 1 1.00 U fchs # CHECK-NEXT: 4 4 1.00 U fnclex -# CHECK-NEXT: 1 3 1.00 U fcmovb %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovbe %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmove %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnb %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnbe %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovne %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnu %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovu %st(1), %st(0) +# CHECK-NEXT: 1 3 1.00 U fcmovb %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovbe %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmove %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnb %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnbe %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovne %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnu %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovu %st(1), %st # CHECK-NEXT: 1 1 1.00 U fcom %st(1) # CHECK-NEXT: 1 1 1.00 U fcom %st(3) # CHECK-NEXT: 2 7 1.00 U fcoms (%ecx) @@ -237,24 +237,24 @@ fyl2xp1 # CHECK-NEXT: 2 7 1.00 U fcomps (%ecx) # CHECK-NEXT: 2 7 1.00 U fcompl (%eax) # CHECK-NEXT: 1 100 0.25 U fcompp -# CHECK-NEXT: 1 3 1.00 U fcomi %st(3) -# CHECK-NEXT: 1 3 1.00 U fcompi %st(3) +# CHECK-NEXT: 1 3 1.00 U fcomi %st(3), %st +# CHECK-NEXT: 1 3 1.00 U fcompi %st(3), %st # CHECK-NEXT: 1 100 0.25 U fcos # CHECK-NEXT: 2 2 1.00 U fdecstp -# CHECK-NEXT: 1 15 1.00 U fdiv %st(0), %st(1) -# CHECK-NEXT: 1 20 1.00 U fdiv %st(2) +# CHECK-NEXT: 1 15 1.00 U fdiv %st, %st(1) +# CHECK-NEXT: 1 20 1.00 U fdiv %st(2), %st # CHECK-NEXT: 2 21 1.00 * U fdivs (%ecx) # CHECK-NEXT: 2 21 1.00 * U fdivl (%eax) -# CHECK-NEXT: 1 15 1.00 U fdivp %st(1) -# CHECK-NEXT: 1 15 1.00 U fdivp %st(2) +# CHECK-NEXT: 1 15 1.00 U fdivp %st, %st(1) +# CHECK-NEXT: 1 15 1.00 U fdivp %st, %st(2) # CHECK-NEXT: 3 24 1.00 * U fidivs (%ecx) # CHECK-NEXT: 3 24 1.00 * U fidivl (%eax) -# CHECK-NEXT: 1 20 1.00 U fdivr %st(0), %st(1) -# CHECK-NEXT: 1 15 1.00 U fdivr %st(2) +# CHECK-NEXT: 1 20 1.00 U fdivr %st, %st(1) +# CHECK-NEXT: 1 15 1.00 U fdivr %st(2), %st # CHECK-NEXT: 2 26 1.00 * U fdivrs (%ecx) # CHECK-NEXT: 2 26 1.00 * U fdivrl (%eax) -# CHECK-NEXT: 1 20 1.00 U fdivrp %st(1) -# CHECK-NEXT: 1 20 1.00 U fdivrp %st(2) +# CHECK-NEXT: 1 20 1.00 U fdivrp %st, %st(1) +# CHECK-NEXT: 1 20 1.00 U fdivrp %st, %st(2) # CHECK-NEXT: 3 29 1.00 * U fidivrs (%ecx) # CHECK-NEXT: 3 29 1.00 * U fidivrl (%eax) # CHECK-NEXT: 1 100 0.25 U ffree %st(0) @@ -288,12 +288,12 @@ fyl2xp1 # CHECK-NEXT: 2 1 1.00 U fldln2 # CHECK-NEXT: 2 1 1.00 U fldpi # CHECK-NEXT: 1 1 0.50 U fldz -# CHECK-NEXT: 1 5 1.00 U fmul %st(0), %st(1) -# CHECK-NEXT: 1 5 1.00 U fmul %st(2) +# CHECK-NEXT: 1 5 1.00 U fmul %st, %st(1) +# CHECK-NEXT: 1 5 1.00 U fmul %st(2), %st # CHECK-NEXT: 2 11 1.00 * U fmuls (%ecx) # CHECK-NEXT: 2 11 1.00 * U fmull (%eax) -# CHECK-NEXT: 1 5 1.00 U fmulp %st(1) -# CHECK-NEXT: 1 5 1.00 U fmulp %st(2) +# CHECK-NEXT: 1 5 1.00 U fmulp %st, %st(1) +# CHECK-NEXT: 1 5 1.00 U fmulp %st, %st(2) # CHECK-NEXT: 3 14 1.00 * U fimuls (%ecx) # CHECK-NEXT: 3 14 1.00 * U fimull (%eax) # CHECK-NEXT: 1 1 0.50 U fnop @@ -321,20 +321,20 @@ fyl2xp1 # CHECK-NEXT: 1 100 0.25 U frstor (%eax) # CHECK-NEXT: 2 2 0.50 U wait # CHECK-NEXT: 1 100 0.25 U fnsave (%eax) -# CHECK-NEXT: 1 3 1.00 U fsub %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsub %st(2) +# CHECK-NEXT: 1 3 1.00 U fsub %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsub %st(2), %st # CHECK-NEXT: 2 9 1.00 * U fsubs (%ecx) # CHECK-NEXT: 2 9 1.00 * U fsubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(2) # CHECK-NEXT: 3 12 2.00 * U fisubs (%ecx) # CHECK-NEXT: 3 12 2.00 * U fisubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubr %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubr %st(2), %st # CHECK-NEXT: 2 9 1.00 * U fsubrs (%ecx) # CHECK-NEXT: 2 9 1.00 * U fsubrl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(2) # CHECK-NEXT: 3 12 2.00 * U fisubrs (%ecx) # CHECK-NEXT: 3 12 2.00 * U fisubrl (%eax) # CHECK-NEXT: 1 3 1.00 U ftst @@ -343,8 +343,8 @@ fyl2xp1 # CHECK-NEXT: 1 1 1.00 U fucomp %st(1) # CHECK-NEXT: 1 1 1.00 U fucomp %st(3) # CHECK-NEXT: 1 3 1.00 U fucompp -# CHECK-NEXT: 1 3 1.00 U fucomi %st(3) -# CHECK-NEXT: 1 3 1.00 U fucompi %st(3) +# CHECK-NEXT: 1 3 1.00 U fucomi %st(3), %st +# CHECK-NEXT: 1 3 1.00 U fucompi %st(3), %st # CHECK-NEXT: 2 2 0.50 U wait # CHECK-NEXT: 1 100 0.25 U fxam # CHECK-NEXT: 12 14 4.00 U fxch %st(1) @@ -375,26 +375,26 @@ fyl2xp1 # CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] Instructions: # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - f2xm1 # CHECK-NEXT: - - - - - - - 1.00 - - fabs -# CHECK-NEXT: - - - 1.00 - - - - - - fadd %st(0), %st(1) -# CHECK-NEXT: - - - 1.00 - - - - - - fadd %st(2) +# CHECK-NEXT: - - - 1.00 - - - - - - fadd %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - - - fadd %st(2), %st # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - fadds (%ecx) # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - faddl (%ecx) -# CHECK-NEXT: - - - 1.00 - - - - - - faddp %st(1) -# CHECK-NEXT: - - - 1.00 - - - - - - faddp %st(2) +# CHECK-NEXT: - - - 1.00 - - - - - - faddp %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - - - faddp %st, %st(2) # CHECK-NEXT: - - - 2.00 0.50 0.50 - - - - fiadds (%ecx) # CHECK-NEXT: - - - 2.00 0.50 0.50 - - - - fiaddl (%ecx) # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - fbld (%ecx) # CHECK-NEXT: - - - - 0.33 0.33 1.00 - - 0.33 fbstp (%eax) # CHECK-NEXT: - - - - - - - 1.00 - - fchs # CHECK-NEXT: - - 1.00 1.00 - - - 1.00 1.00 - fnclex -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovb %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovbe %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmove %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnb %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnbe %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovne %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnu %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovu %st(1), %st(0) +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovb %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovbe %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmove %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnb %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnbe %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovne %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnu %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovu %st(1), %st # CHECK-NEXT: - - - 1.00 - - - - - - fcom %st(1) # CHECK-NEXT: - - - 1.00 - - - - - - fcom %st(3) # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - fcoms (%ecx) @@ -404,24 +404,24 @@ fyl2xp1 # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - fcomps (%ecx) # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - fcompl (%eax) # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - fcompp -# CHECK-NEXT: - - - 1.00 - - - - - - fcomi %st(3) -# CHECK-NEXT: - - - 1.00 - - - - - - fcompi %st(3) +# CHECK-NEXT: - - - 1.00 - - - - - - fcomi %st(3), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcompi %st(3), %st # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - fcos # CHECK-NEXT: - - 1.00 1.00 - - - - - - fdecstp -# CHECK-NEXT: - - 1.00 - - - - - - - fdiv %st(0), %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fdiv %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fdiv %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fdiv %st(2), %st # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fdivs (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fdivl (%eax) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivp %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivp %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivp %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivp %st, %st(2) # CHECK-NEXT: - - 1.00 1.00 0.50 0.50 - - - - fidivs (%ecx) # CHECK-NEXT: - - 1.00 1.00 0.50 0.50 - - - - fidivl (%eax) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivr %st(0), %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivr %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivr %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivr %st(2), %st # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fdivrs (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fdivrl (%eax) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivrp %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivrp %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivrp %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivrp %st, %st(2) # CHECK-NEXT: - - 1.00 1.00 0.50 0.50 - - - - fidivrs (%ecx) # CHECK-NEXT: - - 1.00 1.00 0.50 0.50 - - - - fidivrl (%eax) # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - ffree %st(0) @@ -455,12 +455,12 @@ fyl2xp1 # CHECK-NEXT: - - 1.00 1.00 - - - - - - fldln2 # CHECK-NEXT: - - 1.00 1.00 - - - - - - fldpi # CHECK-NEXT: - - 0.50 0.50 - - - - - - fldz -# CHECK-NEXT: - - 1.00 - - - - - - - fmul %st(0), %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fmul %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fmul %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fmul %st(2), %st # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fmuls (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fmull (%eax) -# CHECK-NEXT: - - 1.00 - - - - - - - fmulp %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fmulp %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fmulp %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fmulp %st, %st(2) # CHECK-NEXT: - - 1.00 1.00 0.50 0.50 - - - - fimuls (%ecx) # CHECK-NEXT: - - 1.00 1.00 0.50 0.50 - - - - fimull (%eax) # CHECK-NEXT: - - 0.50 0.50 - - - - - - fnop @@ -488,20 +488,20 @@ fyl2xp1 # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - frstor (%eax) # CHECK-NEXT: - - 0.50 0.50 - - - 0.50 0.50 - wait # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - fnsave (%eax) -# CHECK-NEXT: - - - 1.00 - - - - - - fsub %st(0), %st(1) -# CHECK-NEXT: - - - 1.00 - - - - - - fsub %st(2) +# CHECK-NEXT: - - - 1.00 - - - - - - fsub %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - - - fsub %st(2), %st # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - fsubs (%ecx) # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - fsubl (%eax) -# CHECK-NEXT: - - - 1.00 - - - - - - fsubp %st(1) -# CHECK-NEXT: - - - 1.00 - - - - - - fsubp %st(2) +# CHECK-NEXT: - - - 1.00 - - - - - - fsubp %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - - - fsubp %st, %st(2) # CHECK-NEXT: - - - 2.00 0.50 0.50 - - - - fisubs (%ecx) # CHECK-NEXT: - - - 2.00 0.50 0.50 - - - - fisubl (%eax) -# CHECK-NEXT: - - - 1.00 - - - - - - fsubr %st(0), %st(1) -# CHECK-NEXT: - - - 1.00 - - - - - - fsubr %st(2) +# CHECK-NEXT: - - - 1.00 - - - - - - fsubr %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - - - fsubr %st(2), %st # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - fsubrs (%ecx) # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - fsubrl (%eax) -# CHECK-NEXT: - - - 1.00 - - - - - - fsubrp %st(1) -# CHECK-NEXT: - - - 1.00 - - - - - - fsubrp %st(2) +# CHECK-NEXT: - - - 1.00 - - - - - - fsubrp %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - - - fsubrp %st, %st(2) # CHECK-NEXT: - - - 2.00 0.50 0.50 - - - - fisubrs (%ecx) # CHECK-NEXT: - - - 2.00 0.50 0.50 - - - - fisubrl (%eax) # CHECK-NEXT: - - - 1.00 - - - - - - ftst @@ -510,8 +510,8 @@ fyl2xp1 # CHECK-NEXT: - - - 1.00 - - - - - - fucomp %st(1) # CHECK-NEXT: - - - 1.00 - - - - - - fucomp %st(3) # CHECK-NEXT: - - - 1.00 - - - - - - fucompp -# CHECK-NEXT: - - - 1.00 - - - - - - fucomi %st(3) -# CHECK-NEXT: - - - 1.00 - - - - - - fucompi %st(3) +# CHECK-NEXT: - - - 1.00 - - - - - - fucomi %st(3), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fucompi %st(3), %st # CHECK-NEXT: - - 0.50 0.50 - - - 0.50 0.50 - wait # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - fxam # CHECK-NEXT: - - 3.25 2.25 - - - 1.25 5.25 - fxch %st(1) diff --git a/llvm/test/tools/llvm-mca/X86/BtVer2/resources-x87.s b/llvm/test/tools/llvm-mca/X86/BtVer2/resources-x87.s index a0e431f6dfe45..2b6b2c4972731 100644 --- a/llvm/test/tools/llvm-mca/X86/BtVer2/resources-x87.s +++ b/llvm/test/tools/llvm-mca/X86/BtVer2/resources-x87.s @@ -5,7 +5,7 @@ f2xm1 fabs -fadd %st(0), %st(1) +fadd %st, %st(1) fadd %st(2) fadds (%ecx) faddl (%ecx) @@ -21,14 +21,14 @@ fchs fnclex -fcmovb %st(1), %st(0) -fcmovbe %st(1), %st(0) -fcmove %st(1), %st(0) -fcmovnb %st(1), %st(0) -fcmovnbe %st(1), %st(0) -fcmovne %st(1), %st(0) -fcmovnu %st(1), %st(0) -fcmovu %st(1), %st(0) +fcmovb %st(1), %st +fcmovbe %st(1), %st +fcmove %st(1), %st +fcmovnb %st(1), %st +fcmovnbe %st(1), %st +fcmovne %st(1), %st +fcmovnu %st(1), %st +fcmovu %st(1), %st fcom %st(1) fcom %st(3) @@ -47,7 +47,7 @@ fcos fdecstp -fdiv %st(0), %st(1) +fdiv %st, %st(1) fdiv %st(2) fdivs (%ecx) fdivl (%eax) @@ -56,7 +56,7 @@ fdivp %st(2) fidivs (%ecx) fidivl (%eax) -fdivr %st(0), %st(1) +fdivr %st, %st(1) fdivr %st(2) fdivrs (%ecx) fdivrl (%eax) @@ -106,7 +106,7 @@ fldln2 fldpi fldz -fmul %st(0), %st(1) +fmul %st, %st(1) fmul %st(2) fmuls (%ecx) fmull (%eax) @@ -153,7 +153,7 @@ fnstsw (%eax) frstor (%eax) fsave (%eax) -fsub %st(0), %st(1) +fsub %st, %st(1) fsub %st(2) fsubs (%ecx) fsubl (%eax) @@ -162,7 +162,7 @@ fsubp %st(2) fisubs (%ecx) fisubl (%eax) -fsubr %st(0), %st(1) +fsubr %st, %st(1) fsubr %st(2) fsubrs (%ecx) fsubrl (%eax) @@ -208,26 +208,26 @@ fyl2xp1 # CHECK: [1] [2] [3] [4] [5] [6] Instructions: # CHECK-NEXT: 1 100 0.50 U f2xm1 # CHECK-NEXT: 1 2 1.00 U fabs -# CHECK-NEXT: 1 3 1.00 U fadd %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fadd %st(2) +# CHECK-NEXT: 1 3 1.00 U fadd %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fadd %st(2), %st # CHECK-NEXT: 1 8 1.00 * U fadds (%ecx) # CHECK-NEXT: 1 8 1.00 * U faddl (%ecx) -# CHECK-NEXT: 1 3 1.00 U faddp %st(1) -# CHECK-NEXT: 1 3 1.00 U faddp %st(2) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(2) # CHECK-NEXT: 1 8 1.00 * U fiadds (%ecx) # CHECK-NEXT: 1 8 1.00 * U fiaddl (%ecx) # CHECK-NEXT: 1 100 0.50 U fbld (%ecx) # CHECK-NEXT: 1 100 0.50 U fbstp (%eax) # CHECK-NEXT: 1 2 1.00 U fchs # CHECK-NEXT: 1 100 0.50 U fnclex -# CHECK-NEXT: 1 3 1.00 U fcmovb %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovbe %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmove %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnb %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnbe %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovne %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnu %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovu %st(1), %st(0) +# CHECK-NEXT: 1 3 1.00 U fcmovb %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovbe %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmove %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnb %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnbe %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovne %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnu %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovu %st(1), %st # CHECK-NEXT: 1 3 1.00 U fcom %st(1) # CHECK-NEXT: 1 3 1.00 U fcom %st(3) # CHECK-NEXT: 1 8 1.00 U fcoms (%ecx) @@ -237,24 +237,24 @@ fyl2xp1 # CHECK-NEXT: 1 8 1.00 U fcomps (%ecx) # CHECK-NEXT: 1 8 1.00 U fcompl (%eax) # CHECK-NEXT: 1 100 0.50 U fcompp -# CHECK-NEXT: 1 3 1.00 U fcomi %st(3) -# CHECK-NEXT: 1 3 1.00 U fcompi %st(3) +# CHECK-NEXT: 1 3 1.00 U fcomi %st(3), %st +# CHECK-NEXT: 1 3 1.00 U fcompi %st(3), %st # CHECK-NEXT: 1 100 0.50 U fcos # CHECK-NEXT: 1 100 0.50 U fdecstp -# CHECK-NEXT: 1 19 19.00 U fdiv %st(0), %st(1) -# CHECK-NEXT: 1 19 19.00 U fdiv %st(2) +# CHECK-NEXT: 1 19 19.00 U fdiv %st, %st(1) +# CHECK-NEXT: 1 19 19.00 U fdiv %st(2), %st # CHECK-NEXT: 1 24 19.00 * U fdivs (%ecx) # CHECK-NEXT: 1 24 19.00 * U fdivl (%eax) -# CHECK-NEXT: 1 19 19.00 U fdivp %st(1) -# CHECK-NEXT: 1 19 19.00 U fdivp %st(2) +# CHECK-NEXT: 1 19 19.00 U fdivp %st, %st(1) +# CHECK-NEXT: 1 19 19.00 U fdivp %st, %st(2) # CHECK-NEXT: 1 24 19.00 * U fidivs (%ecx) # CHECK-NEXT: 1 24 19.00 * U fidivl (%eax) -# CHECK-NEXT: 1 19 19.00 U fdivr %st(0), %st(1) -# CHECK-NEXT: 1 19 19.00 U fdivr %st(2) +# CHECK-NEXT: 1 19 19.00 U fdivr %st, %st(1) +# CHECK-NEXT: 1 19 19.00 U fdivr %st(2), %st # CHECK-NEXT: 1 24 19.00 * U fdivrs (%ecx) # CHECK-NEXT: 1 24 19.00 * U fdivrl (%eax) -# CHECK-NEXT: 1 19 19.00 U fdivrp %st(1) -# CHECK-NEXT: 1 19 19.00 U fdivrp %st(2) +# CHECK-NEXT: 1 19 19.00 U fdivrp %st, %st(1) +# CHECK-NEXT: 1 19 19.00 U fdivrp %st, %st(2) # CHECK-NEXT: 1 24 19.00 * U fidivrs (%ecx) # CHECK-NEXT: 1 24 19.00 * U fidivrl (%eax) # CHECK-NEXT: 1 100 0.50 U ffree %st(0) @@ -288,12 +288,12 @@ fyl2xp1 # CHECK-NEXT: 1 3 1.00 U fldln2 # CHECK-NEXT: 1 3 1.00 U fldpi # CHECK-NEXT: 1 3 1.00 U fldz -# CHECK-NEXT: 1 2 1.00 U fmul %st(0), %st(1) -# CHECK-NEXT: 1 2 1.00 U fmul %st(2) +# CHECK-NEXT: 1 2 1.00 U fmul %st, %st(1) +# CHECK-NEXT: 1 2 1.00 U fmul %st(2), %st # CHECK-NEXT: 1 7 1.00 * U fmuls (%ecx) # CHECK-NEXT: 1 7 1.00 * U fmull (%eax) -# CHECK-NEXT: 1 2 1.00 U fmulp %st(1) -# CHECK-NEXT: 1 2 1.00 U fmulp %st(2) +# CHECK-NEXT: 1 2 1.00 U fmulp %st, %st(1) +# CHECK-NEXT: 1 2 1.00 U fmulp %st, %st(2) # CHECK-NEXT: 1 7 1.00 * U fimuls (%ecx) # CHECK-NEXT: 1 7 1.00 * U fimull (%eax) # CHECK-NEXT: 1 1 0.50 U fnop @@ -321,20 +321,20 @@ fyl2xp1 # CHECK-NEXT: 1 100 0.50 U frstor (%eax) # CHECK-NEXT: 1 100 0.50 U wait # CHECK-NEXT: 1 100 0.50 U fnsave (%eax) -# CHECK-NEXT: 1 3 1.00 U fsub %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsub %st(2) +# CHECK-NEXT: 1 3 1.00 U fsub %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsub %st(2), %st # CHECK-NEXT: 1 8 1.00 * U fsubs (%ecx) # CHECK-NEXT: 1 8 1.00 * U fsubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(2) # CHECK-NEXT: 1 8 1.00 * U fisubs (%ecx) # CHECK-NEXT: 1 8 1.00 * U fisubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubr %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubr %st(2), %st # CHECK-NEXT: 1 8 1.00 * U fsubrs (%ecx) # CHECK-NEXT: 1 8 1.00 * U fsubrl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(2) # CHECK-NEXT: 1 8 1.00 * U fisubrs (%ecx) # CHECK-NEXT: 1 8 1.00 * U fisubrl (%eax) # CHECK-NEXT: 1 3 1.00 U ftst @@ -343,8 +343,8 @@ fyl2xp1 # CHECK-NEXT: 1 3 1.00 U fucomp %st(1) # CHECK-NEXT: 1 3 1.00 U fucomp %st(3) # CHECK-NEXT: 1 3 1.00 U fucompp -# CHECK-NEXT: 1 3 1.00 U fucomi %st(3) -# CHECK-NEXT: 1 3 1.00 U fucompi %st(3) +# CHECK-NEXT: 1 3 1.00 U fucomi %st(3), %st +# CHECK-NEXT: 1 3 1.00 U fucompi %st(3), %st # CHECK-NEXT: 1 100 0.50 U wait # CHECK-NEXT: 1 100 0.50 U fxam # CHECK-NEXT: 1 1 0.50 U fxch %st(1) @@ -379,26 +379,26 @@ fyl2xp1 # CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] Instructions: # CHECK-NEXT: 0.50 0.50 - - - - - - - - - - - - f2xm1 # CHECK-NEXT: - - - - 1.00 - 1.00 - - - - - - - fabs -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fadd %st(0), %st(1) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fadd %st(2) +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fadd %st, %st(1) +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fadd %st(2), %st # CHECK-NEXT: - - - 1.00 - 1.00 - 1.00 - - - - - - fadds (%ecx) # CHECK-NEXT: - - - 1.00 - 1.00 - 1.00 - - - - - - faddl (%ecx) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - faddp %st(1) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - faddp %st(2) +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - faddp %st, %st(1) +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - faddp %st, %st(2) # CHECK-NEXT: - - - 1.00 - 1.00 - 1.00 - - - - - - fiadds (%ecx) # CHECK-NEXT: - - - 1.00 - 1.00 - 1.00 - - - - - - fiaddl (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - - - - - - - fbld (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - - - - - - - fbstp (%eax) # CHECK-NEXT: - - - - 1.00 - 1.00 - - - - - - - fchs # CHECK-NEXT: 0.50 0.50 - - - - - - - - - - - - fnclex -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fcmovb %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fcmovbe %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fcmove %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fcmovnb %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fcmovnbe %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fcmovne %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fcmovnu %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fcmovu %st(1), %st(0) +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fcmovb %st(1), %st +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fcmovbe %st(1), %st +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fcmove %st(1), %st +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fcmovnb %st(1), %st +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fcmovnbe %st(1), %st +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fcmovne %st(1), %st +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fcmovnu %st(1), %st +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fcmovu %st(1), %st # CHECK-NEXT: 1.00 - - 1.00 - 1.00 - - - - - - - - fcom %st(1) # CHECK-NEXT: 1.00 - - 1.00 - 1.00 - - - - - - - - fcom %st(3) # CHECK-NEXT: 1.00 - - 1.00 - 1.00 - 1.00 - - - - - - fcoms (%ecx) @@ -408,24 +408,24 @@ fyl2xp1 # CHECK-NEXT: 1.00 - - 1.00 - 1.00 - 1.00 - - - - - - fcomps (%ecx) # CHECK-NEXT: 1.00 - - 1.00 - 1.00 - 1.00 - - - - - - fcompl (%eax) # CHECK-NEXT: 0.50 0.50 - - - - - - - - - - - - fcompp -# CHECK-NEXT: 1.00 - - 1.00 - 1.00 - - - - - - - - fcomi %st(3) -# CHECK-NEXT: 1.00 - - 1.00 - 1.00 - - - - - - - - fcompi %st(3) +# CHECK-NEXT: 1.00 - - 1.00 - 1.00 - - - - - - - - fcomi %st(3), %st +# CHECK-NEXT: 1.00 - - 1.00 - 1.00 - - - - - - - - fcompi %st(3), %st # CHECK-NEXT: 0.50 0.50 - - - - - - - - - - - - fcos # CHECK-NEXT: 0.50 0.50 - - - - - - - - - - - - fdecstp -# CHECK-NEXT: - - - - 19.00 - 1.00 - - - - - - - fdiv %st(0), %st(1) -# CHECK-NEXT: - - - - 19.00 - 1.00 - - - - - - - fdiv %st(2) +# CHECK-NEXT: - - - - 19.00 - 1.00 - - - - - - - fdiv %st, %st(1) +# CHECK-NEXT: - - - - 19.00 - 1.00 - - - - - - - fdiv %st(2), %st # CHECK-NEXT: - - - - 19.00 - 1.00 1.00 - - - - - - fdivs (%ecx) # CHECK-NEXT: - - - - 19.00 - 1.00 1.00 - - - - - - fdivl (%eax) -# CHECK-NEXT: - - - - 19.00 - 1.00 - - - - - - - fdivp %st(1) -# CHECK-NEXT: - - - - 19.00 - 1.00 - - - - - - - fdivp %st(2) +# CHECK-NEXT: - - - - 19.00 - 1.00 - - - - - - - fdivp %st, %st(1) +# CHECK-NEXT: - - - - 19.00 - 1.00 - - - - - - - fdivp %st, %st(2) # CHECK-NEXT: - - - - 19.00 - 1.00 1.00 - - - - - - fidivs (%ecx) # CHECK-NEXT: - - - - 19.00 - 1.00 1.00 - - - - - - fidivl (%eax) -# CHECK-NEXT: - - - - 19.00 - 1.00 - - - - - - - fdivr %st(0), %st(1) -# CHECK-NEXT: - - - - 19.00 - 1.00 - - - - - - - fdivr %st(2) +# CHECK-NEXT: - - - - 19.00 - 1.00 - - - - - - - fdivr %st, %st(1) +# CHECK-NEXT: - - - - 19.00 - 1.00 - - - - - - - fdivr %st(2), %st # CHECK-NEXT: - - - - 19.00 - 1.00 1.00 - - - - - - fdivrs (%ecx) # CHECK-NEXT: - - - - 19.00 - 1.00 1.00 - - - - - - fdivrl (%eax) -# CHECK-NEXT: - - - - 19.00 - 1.00 - - - - - - - fdivrp %st(1) -# CHECK-NEXT: - - - - 19.00 - 1.00 - - - - - - - fdivrp %st(2) +# CHECK-NEXT: - - - - 19.00 - 1.00 - - - - - - - fdivrp %st, %st(1) +# CHECK-NEXT: - - - - 19.00 - 1.00 - - - - - - - fdivrp %st, %st(2) # CHECK-NEXT: - - - - 19.00 - 1.00 1.00 - - - - - - fidivrs (%ecx) # CHECK-NEXT: - - - - 19.00 - 1.00 1.00 - - - - - - fidivrl (%eax) # CHECK-NEXT: 0.50 0.50 - - - - - - - - - - - - ffree %st(0) @@ -459,12 +459,12 @@ fyl2xp1 # CHECK-NEXT: - - - - - - 1.00 - - - 1.00 - - - fldln2 # CHECK-NEXT: - - - - - - 1.00 - - - 1.00 - - - fldpi # CHECK-NEXT: - - - - - - 1.00 - - - 1.00 - - - fldz -# CHECK-NEXT: - - - - 1.00 - 1.00 - - - - - - - fmul %st(0), %st(1) -# CHECK-NEXT: - - - - 1.00 - 1.00 - - - - - - - fmul %st(2) +# CHECK-NEXT: - - - - 1.00 - 1.00 - - - - - - - fmul %st, %st(1) +# CHECK-NEXT: - - - - 1.00 - 1.00 - - - - - - - fmul %st(2), %st # CHECK-NEXT: - - - - 1.00 - 1.00 1.00 - - - - - - fmuls (%ecx) # CHECK-NEXT: - - - - 1.00 - 1.00 1.00 - - - - - - fmull (%eax) -# CHECK-NEXT: - - - - 1.00 - 1.00 - - - - - - - fmulp %st(1) -# CHECK-NEXT: - - - - 1.00 - 1.00 - - - - - - - fmulp %st(2) +# CHECK-NEXT: - - - - 1.00 - 1.00 - - - - - - - fmulp %st, %st(1) +# CHECK-NEXT: - - - - 1.00 - 1.00 - - - - - - - fmulp %st, %st(2) # CHECK-NEXT: - - - - 1.00 - 1.00 1.00 - - - - - - fimuls (%ecx) # CHECK-NEXT: - - - - 1.00 - 1.00 1.00 - - - - - - fimull (%eax) # CHECK-NEXT: 0.50 0.50 - - - - - - - - - - - - fnop @@ -492,20 +492,20 @@ fyl2xp1 # CHECK-NEXT: 0.50 0.50 - - - - - - - - - - - - frstor (%eax) # CHECK-NEXT: 0.50 0.50 - - - - - - - - - - - - wait # CHECK-NEXT: 0.50 0.50 - - - - - - - - - - - - fnsave (%eax) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fsub %st(0), %st(1) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fsub %st(2) +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fsub %st, %st(1) +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fsub %st(2), %st # CHECK-NEXT: - - - 1.00 - 1.00 - 1.00 - - - - - - fsubs (%ecx) # CHECK-NEXT: - - - 1.00 - 1.00 - 1.00 - - - - - - fsubl (%eax) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fsubp %st(1) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fsubp %st(2) +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fsubp %st, %st(1) +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fsubp %st, %st(2) # CHECK-NEXT: - - - 1.00 - 1.00 - 1.00 - - - - - - fisubs (%ecx) # CHECK-NEXT: - - - 1.00 - 1.00 - 1.00 - - - - - - fisubl (%eax) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fsubr %st(0), %st(1) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fsubr %st(2) +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fsubr %st, %st(1) +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fsubr %st(2), %st # CHECK-NEXT: - - - 1.00 - 1.00 - 1.00 - - - - - - fsubrs (%ecx) # CHECK-NEXT: - - - 1.00 - 1.00 - 1.00 - - - - - - fsubrl (%eax) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fsubrp %st(1) -# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fsubrp %st(2) +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fsubrp %st, %st(1) +# CHECK-NEXT: - - - 1.00 - 1.00 - - - - - - - - fsubrp %st, %st(2) # CHECK-NEXT: - - - 1.00 - 1.00 - 1.00 - - - - - - fisubrs (%ecx) # CHECK-NEXT: - - - 1.00 - 1.00 - 1.00 - - - - - - fisubrl (%eax) # CHECK-NEXT: 1.00 - - 1.00 - 1.00 - - - - - - - - ftst @@ -514,8 +514,8 @@ fyl2xp1 # CHECK-NEXT: 1.00 - - 1.00 - 1.00 - - - - - - - - fucomp %st(1) # CHECK-NEXT: 1.00 - - 1.00 - 1.00 - - - - - - - - fucomp %st(3) # CHECK-NEXT: 1.00 - - 1.00 - 1.00 - - - - - - - - fucompp -# CHECK-NEXT: 1.00 - - 1.00 - 1.00 - - - - - - - - fucomi %st(3) -# CHECK-NEXT: 1.00 - - 1.00 - 1.00 - - - - - - - - fucompi %st(3) +# CHECK-NEXT: 1.00 - - 1.00 - 1.00 - - - - - - - - fucomi %st(3), %st +# CHECK-NEXT: 1.00 - - 1.00 - 1.00 - - - - - - - - fucompi %st(3), %st # CHECK-NEXT: 0.50 0.50 - - - - - - - - - - - - wait # CHECK-NEXT: 0.50 0.50 - - - - - - - - - - - - fxam # CHECK-NEXT: 0.50 0.50 - - - - - - - - - - - - fxch %st(1) diff --git a/llvm/test/tools/llvm-mca/X86/Generic/resources-x87.s b/llvm/test/tools/llvm-mca/X86/Generic/resources-x87.s index 1cba9a7d77fc2..1f3e51e58b33c 100644 --- a/llvm/test/tools/llvm-mca/X86/Generic/resources-x87.s +++ b/llvm/test/tools/llvm-mca/X86/Generic/resources-x87.s @@ -5,7 +5,7 @@ f2xm1 fabs -fadd %st(0), %st(1) +fadd %st, %st(1) fadd %st(2) fadds (%ecx) faddl (%ecx) @@ -21,14 +21,14 @@ fchs fnclex -fcmovb %st(1), %st(0) -fcmovbe %st(1), %st(0) -fcmove %st(1), %st(0) -fcmovnb %st(1), %st(0) -fcmovnbe %st(1), %st(0) -fcmovne %st(1), %st(0) -fcmovnu %st(1), %st(0) -fcmovu %st(1), %st(0) +fcmovb %st(1), %st +fcmovbe %st(1), %st +fcmove %st(1), %st +fcmovnb %st(1), %st +fcmovnbe %st(1), %st +fcmovne %st(1), %st +fcmovnu %st(1), %st +fcmovu %st(1), %st fcom %st(1) fcom %st(3) @@ -47,7 +47,7 @@ fcos fdecstp -fdiv %st(0), %st(1) +fdiv %st, %st(1) fdiv %st(2) fdivs (%ecx) fdivl (%eax) @@ -56,7 +56,7 @@ fdivp %st(2) fidivs (%ecx) fidivl (%eax) -fdivr %st(0), %st(1) +fdivr %st, %st(1) fdivr %st(2) fdivrs (%ecx) fdivrl (%eax) @@ -106,7 +106,7 @@ fldln2 fldpi fldz -fmul %st(0), %st(1) +fmul %st, %st(1) fmul %st(2) fmuls (%ecx) fmull (%eax) @@ -153,7 +153,7 @@ fnstsw (%eax) frstor (%eax) fsave (%eax) -fsub %st(0), %st(1) +fsub %st, %st(1) fsub %st(2) fsubs (%ecx) fsubl (%eax) @@ -162,7 +162,7 @@ fsubp %st(2) fisubs (%ecx) fisubl (%eax) -fsubr %st(0), %st(1) +fsubr %st, %st(1) fsubr %st(2) fsubrs (%ecx) fsubrl (%eax) @@ -208,26 +208,26 @@ fyl2xp1 # CHECK: [1] [2] [3] [4] [5] [6] Instructions: # CHECK-NEXT: 1 100 0.33 U f2xm1 # CHECK-NEXT: 1 1 1.00 U fabs -# CHECK-NEXT: 1 3 1.00 U fadd %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fadd %st(2) +# CHECK-NEXT: 1 3 1.00 U fadd %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fadd %st(2), %st # CHECK-NEXT: 2 10 1.00 * U fadds (%ecx) # CHECK-NEXT: 2 10 1.00 * U faddl (%ecx) -# CHECK-NEXT: 1 3 1.00 U faddp %st(1) -# CHECK-NEXT: 1 3 1.00 U faddp %st(2) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(2) # CHECK-NEXT: 3 13 2.00 * U fiadds (%ecx) # CHECK-NEXT: 3 13 2.00 * U fiaddl (%ecx) # CHECK-NEXT: 1 100 0.33 U fbld (%ecx) # CHECK-NEXT: 1 100 0.33 U fbstp (%eax) # CHECK-NEXT: 1 1 1.00 U fchs # CHECK-NEXT: 1 100 0.33 U fnclex -# CHECK-NEXT: 3 3 2.00 U fcmovb %st(1), %st(0) -# CHECK-NEXT: 3 3 2.00 U fcmovbe %st(1), %st(0) -# CHECK-NEXT: 3 3 2.00 U fcmove %st(1), %st(0) -# CHECK-NEXT: 3 3 2.00 U fcmovnb %st(1), %st(0) -# CHECK-NEXT: 3 3 2.00 U fcmovnbe %st(1), %st(0) -# CHECK-NEXT: 3 3 2.00 U fcmovne %st(1), %st(0) -# CHECK-NEXT: 3 3 2.00 U fcmovnu %st(1), %st(0) -# CHECK-NEXT: 3 3 2.00 U fcmovu %st(1), %st(0) +# CHECK-NEXT: 3 3 2.00 U fcmovb %st(1), %st +# CHECK-NEXT: 3 3 2.00 U fcmovbe %st(1), %st +# CHECK-NEXT: 3 3 2.00 U fcmove %st(1), %st +# CHECK-NEXT: 3 3 2.00 U fcmovnb %st(1), %st +# CHECK-NEXT: 3 3 2.00 U fcmovnbe %st(1), %st +# CHECK-NEXT: 3 3 2.00 U fcmovne %st(1), %st +# CHECK-NEXT: 3 3 2.00 U fcmovnu %st(1), %st +# CHECK-NEXT: 3 3 2.00 U fcmovu %st(1), %st # CHECK-NEXT: 1 1 1.00 U fcom %st(1) # CHECK-NEXT: 1 1 1.00 U fcom %st(3) # CHECK-NEXT: 2 8 1.00 U fcoms (%ecx) @@ -237,24 +237,24 @@ fyl2xp1 # CHECK-NEXT: 2 8 1.00 U fcomps (%ecx) # CHECK-NEXT: 2 8 1.00 U fcompl (%eax) # CHECK-NEXT: 1 100 0.33 U fcompp -# CHECK-NEXT: 3 3 1.00 U fcomi %st(3) -# CHECK-NEXT: 3 3 1.00 U fcompi %st(3) +# CHECK-NEXT: 3 3 1.00 U fcomi %st(3), %st +# CHECK-NEXT: 3 3 1.00 U fcompi %st(3), %st # CHECK-NEXT: 1 100 0.33 U fcos # CHECK-NEXT: 1 1 1.00 U fdecstp -# CHECK-NEXT: 1 14 14.00 U fdiv %st(0), %st(1) -# CHECK-NEXT: 1 14 14.00 U fdiv %st(2) +# CHECK-NEXT: 1 14 14.00 U fdiv %st, %st(1) +# CHECK-NEXT: 1 14 14.00 U fdiv %st(2), %st # CHECK-NEXT: 2 31 1.00 * U fdivs (%ecx) # CHECK-NEXT: 2 31 1.00 * U fdivl (%eax) -# CHECK-NEXT: 1 14 14.00 U fdivp %st(1) -# CHECK-NEXT: 1 14 14.00 U fdivp %st(2) +# CHECK-NEXT: 1 14 14.00 U fdivp %st, %st(1) +# CHECK-NEXT: 1 14 14.00 U fdivp %st, %st(2) # CHECK-NEXT: 3 34 1.00 * U fidivs (%ecx) # CHECK-NEXT: 3 34 1.00 * U fidivl (%eax) -# CHECK-NEXT: 1 14 14.00 U fdivr %st(0), %st(1) -# CHECK-NEXT: 1 14 14.00 U fdivr %st(2) +# CHECK-NEXT: 1 14 14.00 U fdivr %st, %st(1) +# CHECK-NEXT: 1 14 14.00 U fdivr %st(2), %st # CHECK-NEXT: 2 31 1.00 * U fdivrs (%ecx) # CHECK-NEXT: 2 31 1.00 * U fdivrl (%eax) -# CHECK-NEXT: 1 14 14.00 U fdivrp %st(1) -# CHECK-NEXT: 1 14 14.00 U fdivrp %st(2) +# CHECK-NEXT: 1 14 14.00 U fdivrp %st, %st(1) +# CHECK-NEXT: 1 14 14.00 U fdivrp %st, %st(2) # CHECK-NEXT: 3 34 1.00 * U fidivrs (%ecx) # CHECK-NEXT: 3 34 1.00 * U fidivrl (%eax) # CHECK-NEXT: 1 1 1.00 U ffree %st(0) @@ -288,12 +288,12 @@ fyl2xp1 # CHECK-NEXT: 2 1 1.00 U fldln2 # CHECK-NEXT: 2 1 1.00 U fldpi # CHECK-NEXT: 1 1 1.00 U fldz -# CHECK-NEXT: 1 5 1.00 U fmul %st(0), %st(1) -# CHECK-NEXT: 1 5 1.00 U fmul %st(2) +# CHECK-NEXT: 1 5 1.00 U fmul %st, %st(1) +# CHECK-NEXT: 1 5 1.00 U fmul %st(2), %st # CHECK-NEXT: 2 12 1.00 * U fmuls (%ecx) # CHECK-NEXT: 2 12 1.00 * U fmull (%eax) -# CHECK-NEXT: 1 5 1.00 U fmulp %st(1) -# CHECK-NEXT: 1 5 1.00 U fmulp %st(2) +# CHECK-NEXT: 1 5 1.00 U fmulp %st, %st(1) +# CHECK-NEXT: 1 5 1.00 U fmulp %st, %st(2) # CHECK-NEXT: 3 15 1.00 * U fimuls (%ecx) # CHECK-NEXT: 3 15 1.00 * U fimull (%eax) # CHECK-NEXT: 1 1 1.00 U fnop @@ -321,20 +321,20 @@ fyl2xp1 # CHECK-NEXT: 1 100 0.33 U frstor (%eax) # CHECK-NEXT: 1 100 0.33 U wait # CHECK-NEXT: 1 100 0.33 U fnsave (%eax) -# CHECK-NEXT: 1 3 1.00 U fsub %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsub %st(2) +# CHECK-NEXT: 1 3 1.00 U fsub %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsub %st(2), %st # CHECK-NEXT: 2 10 1.00 * U fsubs (%ecx) # CHECK-NEXT: 2 10 1.00 * U fsubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(2) # CHECK-NEXT: 3 13 2.00 * U fisubs (%ecx) # CHECK-NEXT: 3 13 2.00 * U fisubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubr %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubr %st(2), %st # CHECK-NEXT: 2 10 1.00 * U fsubrs (%ecx) # CHECK-NEXT: 2 10 1.00 * U fsubrl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(2) # CHECK-NEXT: 3 13 2.00 * U fisubrs (%ecx) # CHECK-NEXT: 3 13 2.00 * U fisubrl (%eax) # CHECK-NEXT: 1 3 1.00 U ftst @@ -343,8 +343,8 @@ fyl2xp1 # CHECK-NEXT: 1 1 1.00 U fucomp %st(1) # CHECK-NEXT: 1 1 1.00 U fucomp %st(3) # CHECK-NEXT: 1 3 1.00 U fucompp -# CHECK-NEXT: 3 3 1.00 U fucomi %st(3) -# CHECK-NEXT: 3 3 1.00 U fucompi %st(3) +# CHECK-NEXT: 3 3 1.00 U fucomi %st(3), %st +# CHECK-NEXT: 3 3 1.00 U fucompi %st(3), %st # CHECK-NEXT: 1 100 0.33 U wait # CHECK-NEXT: 1 100 0.33 U fxam # CHECK-NEXT: 1 1 0.33 U fxch %st(1) @@ -373,26 +373,26 @@ fyl2xp1 # CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6.0] [6.1] Instructions: # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - f2xm1 # CHECK-NEXT: - - - - - 1.00 - - fabs -# CHECK-NEXT: - - - 1.00 - - - - fadd %st(0), %st(1) -# CHECK-NEXT: - - - 1.00 - - - - fadd %st(2) +# CHECK-NEXT: - - - 1.00 - - - - fadd %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - fadd %st(2), %st # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 fadds (%ecx) # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 faddl (%ecx) -# CHECK-NEXT: - - - 1.00 - - - - faddp %st(1) -# CHECK-NEXT: - - - 1.00 - - - - faddp %st(2) +# CHECK-NEXT: - - - 1.00 - - - - faddp %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - faddp %st, %st(2) # CHECK-NEXT: - - - 2.00 - - 0.50 0.50 fiadds (%ecx) # CHECK-NEXT: - - - 2.00 - - 0.50 0.50 fiaddl (%ecx) # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - fbld (%ecx) # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - fbstp (%eax) # CHECK-NEXT: - - - - - 1.00 - - fchs # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - fnclex -# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovb %st(1), %st(0) -# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovbe %st(1), %st(0) -# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmove %st(1), %st(0) -# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovnb %st(1), %st(0) -# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovnbe %st(1), %st(0) -# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovne %st(1), %st(0) -# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovnu %st(1), %st(0) -# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovu %st(1), %st(0) +# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovb %st(1), %st +# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovbe %st(1), %st +# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmove %st(1), %st +# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovnb %st(1), %st +# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovnbe %st(1), %st +# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovne %st(1), %st +# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovnu %st(1), %st +# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovu %st(1), %st # CHECK-NEXT: - - - 1.00 - - - - fcom %st(1) # CHECK-NEXT: - - - 1.00 - - - - fcom %st(3) # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 fcoms (%ecx) @@ -402,24 +402,24 @@ fyl2xp1 # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 fcomps (%ecx) # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 fcompl (%eax) # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - fcompp -# CHECK-NEXT: - - 1.00 1.00 - 1.00 - - fcomi %st(3) -# CHECK-NEXT: - - 1.00 1.00 - 1.00 - - fcompi %st(3) +# CHECK-NEXT: - - 1.00 1.00 - 1.00 - - fcomi %st(3), %st +# CHECK-NEXT: - - 1.00 1.00 - 1.00 - - fcompi %st(3), %st # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - fcos # CHECK-NEXT: - - - - - 1.00 - - fdecstp -# CHECK-NEXT: - 14.00 1.00 - - - - - fdiv %st(0), %st(1) -# CHECK-NEXT: - 14.00 1.00 - - - - - fdiv %st(2) +# CHECK-NEXT: - 14.00 1.00 - - - - - fdiv %st, %st(1) +# CHECK-NEXT: - 14.00 1.00 - - - - - fdiv %st(2), %st # CHECK-NEXT: - - 1.00 - - - 0.50 0.50 fdivs (%ecx) # CHECK-NEXT: - - 1.00 - - - 0.50 0.50 fdivl (%eax) -# CHECK-NEXT: - 14.00 1.00 - - - - - fdivp %st(1) -# CHECK-NEXT: - 14.00 1.00 - - - - - fdivp %st(2) +# CHECK-NEXT: - 14.00 1.00 - - - - - fdivp %st, %st(1) +# CHECK-NEXT: - 14.00 1.00 - - - - - fdivp %st, %st(2) # CHECK-NEXT: - - 1.00 1.00 - - 0.50 0.50 fidivs (%ecx) # CHECK-NEXT: - - 1.00 1.00 - - 0.50 0.50 fidivl (%eax) -# CHECK-NEXT: - 14.00 1.00 - - - - - fdivr %st(0), %st(1) -# CHECK-NEXT: - 14.00 1.00 - - - - - fdivr %st(2) +# CHECK-NEXT: - 14.00 1.00 - - - - - fdivr %st, %st(1) +# CHECK-NEXT: - 14.00 1.00 - - - - - fdivr %st(2), %st # CHECK-NEXT: - - 1.00 - - - 0.50 0.50 fdivrs (%ecx) # CHECK-NEXT: - - 1.00 - - - 0.50 0.50 fdivrl (%eax) -# CHECK-NEXT: - 14.00 1.00 - - - - - fdivrp %st(1) -# CHECK-NEXT: - 14.00 1.00 - - - - - fdivrp %st(2) +# CHECK-NEXT: - 14.00 1.00 - - - - - fdivrp %st, %st(1) +# CHECK-NEXT: - 14.00 1.00 - - - - - fdivrp %st, %st(2) # CHECK-NEXT: - - 1.00 1.00 - - 0.50 0.50 fidivrs (%ecx) # CHECK-NEXT: - - 1.00 1.00 - - 0.50 0.50 fidivrl (%eax) # CHECK-NEXT: - - - - - 1.00 - - ffree %st(0) @@ -453,12 +453,12 @@ fyl2xp1 # CHECK-NEXT: - - 1.00 1.00 - - - - fldln2 # CHECK-NEXT: - - 1.00 1.00 - - - - fldpi # CHECK-NEXT: - - - - - 1.00 - - fldz -# CHECK-NEXT: - - 1.00 - - - - - fmul %st(0), %st(1) -# CHECK-NEXT: - - 1.00 - - - - - fmul %st(2) +# CHECK-NEXT: - - 1.00 - - - - - fmul %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - fmul %st(2), %st # CHECK-NEXT: - - 1.00 - - - 0.50 0.50 fmuls (%ecx) # CHECK-NEXT: - - 1.00 - - - 0.50 0.50 fmull (%eax) -# CHECK-NEXT: - - 1.00 - - - - - fmulp %st(1) -# CHECK-NEXT: - - 1.00 - - - - - fmulp %st(2) +# CHECK-NEXT: - - 1.00 - - - - - fmulp %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - fmulp %st, %st(2) # CHECK-NEXT: - - 1.00 1.00 - - 0.50 0.50 fimuls (%ecx) # CHECK-NEXT: - - 1.00 1.00 - - 0.50 0.50 fimull (%eax) # CHECK-NEXT: - - - - - 1.00 - - fnop @@ -486,20 +486,20 @@ fyl2xp1 # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - frstor (%eax) # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - wait # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - fnsave (%eax) -# CHECK-NEXT: - - - 1.00 - - - - fsub %st(0), %st(1) -# CHECK-NEXT: - - - 1.00 - - - - fsub %st(2) +# CHECK-NEXT: - - - 1.00 - - - - fsub %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - fsub %st(2), %st # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 fsubs (%ecx) # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 fsubl (%eax) -# CHECK-NEXT: - - - 1.00 - - - - fsubp %st(1) -# CHECK-NEXT: - - - 1.00 - - - - fsubp %st(2) +# CHECK-NEXT: - - - 1.00 - - - - fsubp %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - fsubp %st, %st(2) # CHECK-NEXT: - - - 2.00 - - 0.50 0.50 fisubs (%ecx) # CHECK-NEXT: - - - 2.00 - - 0.50 0.50 fisubl (%eax) -# CHECK-NEXT: - - - 1.00 - - - - fsubr %st(0), %st(1) -# CHECK-NEXT: - - - 1.00 - - - - fsubr %st(2) +# CHECK-NEXT: - - - 1.00 - - - - fsubr %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - fsubr %st(2), %st # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 fsubrs (%ecx) # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 fsubrl (%eax) -# CHECK-NEXT: - - - 1.00 - - - - fsubrp %st(1) -# CHECK-NEXT: - - - 1.00 - - - - fsubrp %st(2) +# CHECK-NEXT: - - - 1.00 - - - - fsubrp %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - fsubrp %st, %st(2) # CHECK-NEXT: - - - 2.00 - - 0.50 0.50 fisubrs (%ecx) # CHECK-NEXT: - - - 2.00 - - 0.50 0.50 fisubrl (%eax) # CHECK-NEXT: - - - 1.00 - - - - ftst @@ -508,8 +508,8 @@ fyl2xp1 # CHECK-NEXT: - - - 1.00 - - - - fucomp %st(1) # CHECK-NEXT: - - - 1.00 - - - - fucomp %st(3) # CHECK-NEXT: - - - 1.00 - - - - fucompp -# CHECK-NEXT: - - 1.00 1.00 - 1.00 - - fucomi %st(3) -# CHECK-NEXT: - - 1.00 1.00 - 1.00 - - fucompi %st(3) +# CHECK-NEXT: - - 1.00 1.00 - 1.00 - - fucomi %st(3), %st +# CHECK-NEXT: - - 1.00 1.00 - 1.00 - - fucompi %st(3), %st # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - wait # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - fxam # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - fxch %st(1) diff --git a/llvm/test/tools/llvm-mca/X86/Haswell/resources-x87.s b/llvm/test/tools/llvm-mca/X86/Haswell/resources-x87.s index 53006bbc3296e..7da8b2802a9a1 100644 --- a/llvm/test/tools/llvm-mca/X86/Haswell/resources-x87.s +++ b/llvm/test/tools/llvm-mca/X86/Haswell/resources-x87.s @@ -5,7 +5,7 @@ f2xm1 fabs -fadd %st(0), %st(1) +fadd %st, %st(1) fadd %st(2) fadds (%ecx) faddl (%ecx) @@ -21,14 +21,14 @@ fchs fnclex -fcmovb %st(1), %st(0) -fcmovbe %st(1), %st(0) -fcmove %st(1), %st(0) -fcmovnb %st(1), %st(0) -fcmovnbe %st(1), %st(0) -fcmovne %st(1), %st(0) -fcmovnu %st(1), %st(0) -fcmovu %st(1), %st(0) +fcmovb %st(1), %st +fcmovbe %st(1), %st +fcmove %st(1), %st +fcmovnb %st(1), %st +fcmovnbe %st(1), %st +fcmovne %st(1), %st +fcmovnu %st(1), %st +fcmovu %st(1), %st fcom %st(1) fcom %st(3) @@ -47,7 +47,7 @@ fcos fdecstp -fdiv %st(0), %st(1) +fdiv %st, %st(1) fdiv %st(2) fdivs (%ecx) fdivl (%eax) @@ -56,7 +56,7 @@ fdivp %st(2) fidivs (%ecx) fidivl (%eax) -fdivr %st(0), %st(1) +fdivr %st, %st(1) fdivr %st(2) fdivrs (%ecx) fdivrl (%eax) @@ -106,7 +106,7 @@ fldln2 fldpi fldz -fmul %st(0), %st(1) +fmul %st, %st(1) fmul %st(2) fmuls (%ecx) fmull (%eax) @@ -153,7 +153,7 @@ fnstsw (%eax) frstor (%eax) fsave (%eax) -fsub %st(0), %st(1) +fsub %st, %st(1) fsub %st(2) fsubs (%ecx) fsubl (%eax) @@ -162,7 +162,7 @@ fsubp %st(2) fisubs (%ecx) fisubl (%eax) -fsubr %st(0), %st(1) +fsubr %st, %st(1) fsubr %st(2) fsubrs (%ecx) fsubrl (%eax) @@ -208,26 +208,26 @@ fyl2xp1 # CHECK: [1] [2] [3] [4] [5] [6] Instructions: # CHECK-NEXT: 1 100 0.25 U f2xm1 # CHECK-NEXT: 1 1 1.00 U fabs -# CHECK-NEXT: 1 3 1.00 U fadd %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fadd %st(2) +# CHECK-NEXT: 1 3 1.00 U fadd %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fadd %st(2), %st # CHECK-NEXT: 2 10 1.00 * U fadds (%ecx) # CHECK-NEXT: 2 10 1.00 * U faddl (%ecx) -# CHECK-NEXT: 1 3 1.00 U faddp %st(1) -# CHECK-NEXT: 1 3 1.00 U faddp %st(2) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(2) # CHECK-NEXT: 3 13 2.00 * U fiadds (%ecx) # CHECK-NEXT: 3 13 2.00 * U fiaddl (%ecx) # CHECK-NEXT: 43 47 10.75 U fbld (%ecx) # CHECK-NEXT: 2 1 1.00 U fbstp (%eax) # CHECK-NEXT: 1 1 1.00 U fchs # CHECK-NEXT: 4 4 1.00 U fnclex -# CHECK-NEXT: 1 3 1.00 U fcmovb %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovbe %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmove %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnb %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnbe %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovne %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnu %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovu %st(1), %st(0) +# CHECK-NEXT: 1 3 1.00 U fcmovb %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovbe %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmove %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnb %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnbe %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovne %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnu %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovu %st(1), %st # CHECK-NEXT: 1 1 1.00 U fcom %st(1) # CHECK-NEXT: 1 1 1.00 U fcom %st(3) # CHECK-NEXT: 2 8 1.00 U fcoms (%ecx) @@ -237,24 +237,24 @@ fyl2xp1 # CHECK-NEXT: 2 8 1.00 U fcomps (%ecx) # CHECK-NEXT: 2 8 1.00 U fcompl (%eax) # CHECK-NEXT: 2 1 0.50 U fcompp -# CHECK-NEXT: 3 1 0.50 U fcomi %st(3) -# CHECK-NEXT: 3 1 0.50 U fcompi %st(3) +# CHECK-NEXT: 3 1 0.50 U fcomi %st(3), %st +# CHECK-NEXT: 3 1 0.50 U fcompi %st(3), %st # CHECK-NEXT: 1 100 0.25 U fcos # CHECK-NEXT: 2 2 1.00 U fdecstp -# CHECK-NEXT: 1 24 1.00 U fdiv %st(0), %st(1) -# CHECK-NEXT: 1 20 1.00 U fdiv %st(2) +# CHECK-NEXT: 1 24 1.00 U fdiv %st, %st(1) +# CHECK-NEXT: 1 20 1.00 U fdiv %st(2), %st # CHECK-NEXT: 2 31 1.00 * U fdivs (%ecx) # CHECK-NEXT: 2 31 1.00 * U fdivl (%eax) -# CHECK-NEXT: 1 24 1.00 U fdivp %st(1) -# CHECK-NEXT: 1 24 1.00 U fdivp %st(2) +# CHECK-NEXT: 1 24 1.00 U fdivp %st, %st(1) +# CHECK-NEXT: 1 24 1.00 U fdivp %st, %st(2) # CHECK-NEXT: 3 34 1.00 * U fidivs (%ecx) # CHECK-NEXT: 3 34 1.00 * U fidivl (%eax) -# CHECK-NEXT: 1 20 1.00 U fdivr %st(0), %st(1) -# CHECK-NEXT: 1 24 1.00 U fdivr %st(2) +# CHECK-NEXT: 1 20 1.00 U fdivr %st, %st(1) +# CHECK-NEXT: 1 24 1.00 U fdivr %st(2), %st # CHECK-NEXT: 2 27 1.00 * U fdivrs (%ecx) # CHECK-NEXT: 2 27 1.00 * U fdivrl (%eax) -# CHECK-NEXT: 1 20 1.00 U fdivrp %st(1) -# CHECK-NEXT: 1 20 1.00 U fdivrp %st(2) +# CHECK-NEXT: 1 20 1.00 U fdivrp %st, %st(1) +# CHECK-NEXT: 1 20 1.00 U fdivrp %st, %st(2) # CHECK-NEXT: 3 30 1.00 * U fidivrs (%ecx) # CHECK-NEXT: 3 30 1.00 * U fidivrl (%eax) # CHECK-NEXT: 1 1 0.50 U ffree %st(0) @@ -288,12 +288,12 @@ fyl2xp1 # CHECK-NEXT: 2 1 1.00 U fldln2 # CHECK-NEXT: 2 1 1.00 U fldpi # CHECK-NEXT: 1 1 0.50 U fldz -# CHECK-NEXT: 1 5 1.00 U fmul %st(0), %st(1) -# CHECK-NEXT: 1 5 1.00 U fmul %st(2) +# CHECK-NEXT: 1 5 1.00 U fmul %st, %st(1) +# CHECK-NEXT: 1 5 1.00 U fmul %st(2), %st # CHECK-NEXT: 2 12 1.00 * U fmuls (%ecx) # CHECK-NEXT: 2 12 1.00 * U fmull (%eax) -# CHECK-NEXT: 1 5 1.00 U fmulp %st(1) -# CHECK-NEXT: 1 5 1.00 U fmulp %st(2) +# CHECK-NEXT: 1 5 1.00 U fmulp %st, %st(1) +# CHECK-NEXT: 1 5 1.00 U fmulp %st, %st(2) # CHECK-NEXT: 3 15 1.00 * U fimuls (%ecx) # CHECK-NEXT: 3 15 1.00 * U fimull (%eax) # CHECK-NEXT: 1 1 0.50 U fnop @@ -321,20 +321,20 @@ fyl2xp1 # CHECK-NEXT: 90 1 22.50 U frstor (%eax) # CHECK-NEXT: 2 2 0.50 U wait # CHECK-NEXT: 147 1 36.75 U fnsave (%eax) -# CHECK-NEXT: 1 3 1.00 U fsub %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsub %st(2) +# CHECK-NEXT: 1 3 1.00 U fsub %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsub %st(2), %st # CHECK-NEXT: 2 10 1.00 * U fsubs (%ecx) # CHECK-NEXT: 2 10 1.00 * U fsubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(2) # CHECK-NEXT: 3 13 2.00 * U fisubs (%ecx) # CHECK-NEXT: 3 13 2.00 * U fisubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubr %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubr %st(2), %st # CHECK-NEXT: 2 10 1.00 * U fsubrs (%ecx) # CHECK-NEXT: 2 10 1.00 * U fsubrl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(2) # CHECK-NEXT: 3 13 2.00 * U fisubrs (%ecx) # CHECK-NEXT: 3 13 2.00 * U fisubrl (%eax) # CHECK-NEXT: 1 1 1.00 U ftst @@ -343,8 +343,8 @@ fyl2xp1 # CHECK-NEXT: 1 1 1.00 U fucomp %st(1) # CHECK-NEXT: 1 1 1.00 U fucomp %st(3) # CHECK-NEXT: 2 1 0.50 U fucompp -# CHECK-NEXT: 3 1 0.50 U fucomi %st(3) -# CHECK-NEXT: 3 1 0.50 U fucompi %st(3) +# CHECK-NEXT: 3 1 0.50 U fucomi %st(3), %st +# CHECK-NEXT: 3 1 0.50 U fucompi %st(3), %st # CHECK-NEXT: 2 2 0.50 U wait # CHECK-NEXT: 2 1 2.00 U fxam # CHECK-NEXT: 15 17 4.00 U fxch %st(1) @@ -375,26 +375,26 @@ fyl2xp1 # CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] Instructions: # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - f2xm1 # CHECK-NEXT: - - 1.00 - - - - - - - fabs -# CHECK-NEXT: - - - 1.00 - - - - - - fadd %st(0), %st(1) -# CHECK-NEXT: - - - 1.00 - - - - - - fadd %st(2) +# CHECK-NEXT: - - - 1.00 - - - - - - fadd %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - - - fadd %st(2), %st # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - fadds (%ecx) # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - faddl (%ecx) -# CHECK-NEXT: - - - 1.00 - - - - - - faddp %st(1) -# CHECK-NEXT: - - - 1.00 - - - - - - faddp %st(2) +# CHECK-NEXT: - - - 1.00 - - - - - - faddp %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - - - faddp %st, %st(2) # CHECK-NEXT: - - - 2.00 0.50 0.50 - - - - fiadds (%ecx) # CHECK-NEXT: - - - 2.00 0.50 0.50 - - - - fiaddl (%ecx) # CHECK-NEXT: - - - - - - - - - - fbld (%ecx) # CHECK-NEXT: - - - - 0.33 0.33 1.00 - - 0.33 fbstp (%eax) # CHECK-NEXT: - - 1.00 - - - - - - - fchs # CHECK-NEXT: - - 1.00 1.00 - - - 1.00 1.00 - fnclex -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovb %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovbe %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmove %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnb %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnbe %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovne %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnu %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovu %st(1), %st(0) +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovb %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovbe %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmove %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnb %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnbe %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovne %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnu %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovu %st(1), %st # CHECK-NEXT: - - - 1.00 - - - - - - fcom %st(1) # CHECK-NEXT: - - - 1.00 - - - - - - fcom %st(3) # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - fcoms (%ecx) @@ -404,24 +404,24 @@ fyl2xp1 # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - fcomps (%ecx) # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - fcompl (%eax) # CHECK-NEXT: - - 0.50 0.50 - - - - - - fcompp -# CHECK-NEXT: - - 0.50 0.50 - - - - - - fcomi %st(3) -# CHECK-NEXT: - - 0.50 0.50 - - - - - - fcompi %st(3) +# CHECK-NEXT: - - 0.50 0.50 - - - - - - fcomi %st(3), %st +# CHECK-NEXT: - - 0.50 0.50 - - - - - - fcompi %st(3), %st # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - fcos # CHECK-NEXT: - - 1.00 1.00 - - - - - - fdecstp -# CHECK-NEXT: - - 1.00 - - - - - - - fdiv %st(0), %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fdiv %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fdiv %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fdiv %st(2), %st # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fdivs (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fdivl (%eax) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivp %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivp %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivp %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivp %st, %st(2) # CHECK-NEXT: - - 1.00 1.00 0.50 0.50 - - - - fidivs (%ecx) # CHECK-NEXT: - - 1.00 1.00 0.50 0.50 - - - - fidivl (%eax) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivr %st(0), %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivr %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivr %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivr %st(2), %st # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fdivrs (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fdivrl (%eax) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivrp %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivrp %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivrp %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivrp %st, %st(2) # CHECK-NEXT: - - 1.00 1.00 0.50 0.50 - - - - fidivrs (%ecx) # CHECK-NEXT: - - 1.00 1.00 0.50 0.50 - - - - fidivrl (%eax) # CHECK-NEXT: - - 0.50 0.50 - - - - - - ffree %st(0) @@ -455,12 +455,12 @@ fyl2xp1 # CHECK-NEXT: - - 1.00 1.00 - - - - - - fldln2 # CHECK-NEXT: - - 1.00 1.00 - - - - - - fldpi # CHECK-NEXT: - - 0.50 0.50 - - - - - - fldz -# CHECK-NEXT: - - 1.00 - - - - - - - fmul %st(0), %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fmul %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fmul %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fmul %st(2), %st # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fmuls (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fmull (%eax) -# CHECK-NEXT: - - 1.00 - - - - - - - fmulp %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fmulp %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fmulp %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fmulp %st, %st(2) # CHECK-NEXT: - - 1.00 1.00 0.50 0.50 - - - - fimuls (%ecx) # CHECK-NEXT: - - 1.00 1.00 0.50 0.50 - - - - fimull (%eax) # CHECK-NEXT: - - 0.50 0.50 - - - - - - fnop @@ -488,20 +488,20 @@ fyl2xp1 # CHECK-NEXT: - - - - - - - - - - frstor (%eax) # CHECK-NEXT: - - 0.50 0.50 - - - 0.50 0.50 - wait # CHECK-NEXT: - - - - - - - - - - fnsave (%eax) -# CHECK-NEXT: - - - 1.00 - - - - - - fsub %st(0), %st(1) -# CHECK-NEXT: - - - 1.00 - - - - - - fsub %st(2) +# CHECK-NEXT: - - - 1.00 - - - - - - fsub %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - - - fsub %st(2), %st # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - fsubs (%ecx) # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - fsubl (%eax) -# CHECK-NEXT: - - - 1.00 - - - - - - fsubp %st(1) -# CHECK-NEXT: - - - 1.00 - - - - - - fsubp %st(2) +# CHECK-NEXT: - - - 1.00 - - - - - - fsubp %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - - - fsubp %st, %st(2) # CHECK-NEXT: - - - 2.00 0.50 0.50 - - - - fisubs (%ecx) # CHECK-NEXT: - - - 2.00 0.50 0.50 - - - - fisubl (%eax) -# CHECK-NEXT: - - - 1.00 - - - - - - fsubr %st(0), %st(1) -# CHECK-NEXT: - - - 1.00 - - - - - - fsubr %st(2) +# CHECK-NEXT: - - - 1.00 - - - - - - fsubr %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - - - fsubr %st(2), %st # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - fsubrs (%ecx) # CHECK-NEXT: - - - 1.00 0.50 0.50 - - - - fsubrl (%eax) -# CHECK-NEXT: - - - 1.00 - - - - - - fsubrp %st(1) -# CHECK-NEXT: - - - 1.00 - - - - - - fsubrp %st(2) +# CHECK-NEXT: - - - 1.00 - - - - - - fsubrp %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - - - fsubrp %st, %st(2) # CHECK-NEXT: - - - 2.00 0.50 0.50 - - - - fisubrs (%ecx) # CHECK-NEXT: - - - 2.00 0.50 0.50 - - - - fisubrl (%eax) # CHECK-NEXT: - - - 1.00 - - - - - - ftst @@ -510,8 +510,8 @@ fyl2xp1 # CHECK-NEXT: - - - 1.00 - - - - - - fucomp %st(1) # CHECK-NEXT: - - - 1.00 - - - - - - fucomp %st(3) # CHECK-NEXT: - - 0.50 0.50 - - - - - - fucompp -# CHECK-NEXT: - - 0.50 0.50 - - - - - - fucomi %st(3) -# CHECK-NEXT: - - 0.50 0.50 - - - - - - fucompi %st(3) +# CHECK-NEXT: - - 0.50 0.50 - - - - - - fucomi %st(3), %st +# CHECK-NEXT: - - 0.50 0.50 - - - - - - fucompi %st(3), %st # CHECK-NEXT: - - 0.50 0.50 - - - 0.50 0.50 - wait # CHECK-NEXT: - - - 2.00 - - - - - - fxam # CHECK-NEXT: - - 4.00 3.00 - - - 3.00 5.00 - fxch %st(1) diff --git a/llvm/test/tools/llvm-mca/X86/SLM/resources-x87.s b/llvm/test/tools/llvm-mca/X86/SLM/resources-x87.s index fe5de61296f56..d6d42e957bfe3 100644 --- a/llvm/test/tools/llvm-mca/X86/SLM/resources-x87.s +++ b/llvm/test/tools/llvm-mca/X86/SLM/resources-x87.s @@ -5,7 +5,7 @@ f2xm1 fabs -fadd %st(0), %st(1) +fadd %st, %st(1) fadd %st(2) fadds (%ecx) faddl (%ecx) @@ -21,14 +21,14 @@ fchs fnclex -fcmovb %st(1), %st(0) -fcmovbe %st(1), %st(0) -fcmove %st(1), %st(0) -fcmovnb %st(1), %st(0) -fcmovnbe %st(1), %st(0) -fcmovne %st(1), %st(0) -fcmovnu %st(1), %st(0) -fcmovu %st(1), %st(0) +fcmovb %st(1), %st +fcmovbe %st(1), %st +fcmove %st(1), %st +fcmovnb %st(1), %st +fcmovnbe %st(1), %st +fcmovne %st(1), %st +fcmovnu %st(1), %st +fcmovu %st(1), %st fcom %st(1) fcom %st(3) @@ -47,7 +47,7 @@ fcos fdecstp -fdiv %st(0), %st(1) +fdiv %st, %st(1) fdiv %st(2) fdivs (%ecx) fdivl (%eax) @@ -56,7 +56,7 @@ fdivp %st(2) fidivs (%ecx) fidivl (%eax) -fdivr %st(0), %st(1) +fdivr %st, %st(1) fdivr %st(2) fdivrs (%ecx) fdivrl (%eax) @@ -106,7 +106,7 @@ fldln2 fldpi fldz -fmul %st(0), %st(1) +fmul %st, %st(1) fmul %st(2) fmuls (%ecx) fmull (%eax) @@ -153,7 +153,7 @@ fnstsw (%eax) frstor (%eax) fsave (%eax) -fsub %st(0), %st(1) +fsub %st, %st(1) fsub %st(2) fsubs (%ecx) fsubl (%eax) @@ -162,7 +162,7 @@ fsubp %st(2) fisubs (%ecx) fisubl (%eax) -fsubr %st(0), %st(1) +fsubr %st, %st(1) fsubr %st(2) fsubrs (%ecx) fsubrl (%eax) @@ -208,26 +208,26 @@ fyl2xp1 # CHECK: [1] [2] [3] [4] [5] [6] Instructions: # CHECK-NEXT: 1 100 1.00 U f2xm1 # CHECK-NEXT: 1 1 0.50 U fabs -# CHECK-NEXT: 1 3 1.00 U fadd %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fadd %st(2) +# CHECK-NEXT: 1 3 1.00 U fadd %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fadd %st(2), %st # CHECK-NEXT: 1 6 1.00 * U fadds (%ecx) # CHECK-NEXT: 1 6 1.00 * U faddl (%ecx) -# CHECK-NEXT: 1 3 1.00 U faddp %st(1) -# CHECK-NEXT: 1 3 1.00 U faddp %st(2) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(2) # CHECK-NEXT: 1 6 1.00 * U fiadds (%ecx) # CHECK-NEXT: 1 6 1.00 * U fiaddl (%ecx) # CHECK-NEXT: 1 100 1.00 U fbld (%ecx) # CHECK-NEXT: 1 100 1.00 U fbstp (%eax) # CHECK-NEXT: 1 1 0.50 U fchs # CHECK-NEXT: 1 100 1.00 U fnclex -# CHECK-NEXT: 1 3 1.00 U fcmovb %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovbe %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmove %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnb %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnbe %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovne %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnu %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovu %st(1), %st(0) +# CHECK-NEXT: 1 3 1.00 U fcmovb %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovbe %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmove %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnb %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnbe %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovne %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnu %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovu %st(1), %st # CHECK-NEXT: 1 3 1.00 U fcom %st(1) # CHECK-NEXT: 1 3 1.00 U fcom %st(3) # CHECK-NEXT: 1 6 1.00 U fcoms (%ecx) @@ -237,24 +237,24 @@ fyl2xp1 # CHECK-NEXT: 1 6 1.00 U fcomps (%ecx) # CHECK-NEXT: 1 6 1.00 U fcompl (%eax) # CHECK-NEXT: 1 100 1.00 U fcompp -# CHECK-NEXT: 1 3 1.00 U fcomi %st(3) -# CHECK-NEXT: 1 3 1.00 U fcompi %st(3) +# CHECK-NEXT: 1 3 1.00 U fcomi %st(3), %st +# CHECK-NEXT: 1 3 1.00 U fcompi %st(3), %st # CHECK-NEXT: 1 100 1.00 U fcos # CHECK-NEXT: 1 100 1.00 U fdecstp -# CHECK-NEXT: 1 19 17.00 U fdiv %st(0), %st(1) -# CHECK-NEXT: 1 19 17.00 U fdiv %st(2) +# CHECK-NEXT: 1 19 17.00 U fdiv %st, %st(1) +# CHECK-NEXT: 1 19 17.00 U fdiv %st(2), %st # CHECK-NEXT: 1 22 17.00 * U fdivs (%ecx) # CHECK-NEXT: 1 22 17.00 * U fdivl (%eax) -# CHECK-NEXT: 1 19 17.00 U fdivp %st(1) -# CHECK-NEXT: 1 19 17.00 U fdivp %st(2) +# CHECK-NEXT: 1 19 17.00 U fdivp %st, %st(1) +# CHECK-NEXT: 1 19 17.00 U fdivp %st, %st(2) # CHECK-NEXT: 1 22 17.00 * U fidivs (%ecx) # CHECK-NEXT: 1 22 17.00 * U fidivl (%eax) -# CHECK-NEXT: 1 19 17.00 U fdivr %st(0), %st(1) -# CHECK-NEXT: 1 19 17.00 U fdivr %st(2) +# CHECK-NEXT: 1 19 17.00 U fdivr %st, %st(1) +# CHECK-NEXT: 1 19 17.00 U fdivr %st(2), %st # CHECK-NEXT: 1 22 17.00 * U fdivrs (%ecx) # CHECK-NEXT: 1 22 17.00 * U fdivrl (%eax) -# CHECK-NEXT: 1 19 17.00 U fdivrp %st(1) -# CHECK-NEXT: 1 19 17.00 U fdivrp %st(2) +# CHECK-NEXT: 1 19 17.00 U fdivrp %st, %st(1) +# CHECK-NEXT: 1 19 17.00 U fdivrp %st, %st(2) # CHECK-NEXT: 1 22 17.00 * U fidivrs (%ecx) # CHECK-NEXT: 1 22 17.00 * U fidivrl (%eax) # CHECK-NEXT: 1 100 1.00 U ffree %st(0) @@ -288,12 +288,12 @@ fyl2xp1 # CHECK-NEXT: 2 1 1.00 U fldln2 # CHECK-NEXT: 2 1 1.00 U fldpi # CHECK-NEXT: 1 1 0.50 U fldz -# CHECK-NEXT: 1 5 2.00 U fmul %st(0), %st(1) -# CHECK-NEXT: 1 5 2.00 U fmul %st(2) +# CHECK-NEXT: 1 5 2.00 U fmul %st, %st(1) +# CHECK-NEXT: 1 5 2.00 U fmul %st(2), %st # CHECK-NEXT: 1 8 2.00 * U fmuls (%ecx) # CHECK-NEXT: 1 8 2.00 * U fmull (%eax) -# CHECK-NEXT: 1 5 2.00 U fmulp %st(1) -# CHECK-NEXT: 1 5 2.00 U fmulp %st(2) +# CHECK-NEXT: 1 5 2.00 U fmulp %st, %st(1) +# CHECK-NEXT: 1 5 2.00 U fmulp %st, %st(2) # CHECK-NEXT: 1 8 2.00 * U fimuls (%ecx) # CHECK-NEXT: 1 8 2.00 * U fimull (%eax) # CHECK-NEXT: 1 1 0.50 U fnop @@ -321,20 +321,20 @@ fyl2xp1 # CHECK-NEXT: 1 100 1.00 U frstor (%eax) # CHECK-NEXT: 1 100 1.00 U wait # CHECK-NEXT: 1 100 1.00 U fnsave (%eax) -# CHECK-NEXT: 1 3 1.00 U fsub %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsub %st(2) +# CHECK-NEXT: 1 3 1.00 U fsub %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsub %st(2), %st # CHECK-NEXT: 1 6 1.00 * U fsubs (%ecx) # CHECK-NEXT: 1 6 1.00 * U fsubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(2) # CHECK-NEXT: 1 6 1.00 * U fisubs (%ecx) # CHECK-NEXT: 1 6 1.00 * U fisubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubr %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubr %st(2), %st # CHECK-NEXT: 1 6 1.00 * U fsubrs (%ecx) # CHECK-NEXT: 1 6 1.00 * U fsubrl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(2) # CHECK-NEXT: 1 6 1.00 * U fisubrs (%ecx) # CHECK-NEXT: 1 6 1.00 * U fisubrl (%eax) # CHECK-NEXT: 1 3 1.00 U ftst @@ -343,8 +343,8 @@ fyl2xp1 # CHECK-NEXT: 1 3 1.00 U fucomp %st(1) # CHECK-NEXT: 1 3 1.00 U fucomp %st(3) # CHECK-NEXT: 1 3 1.00 U fucompp -# CHECK-NEXT: 1 3 1.00 U fucomi %st(3) -# CHECK-NEXT: 1 3 1.00 U fucompi %st(3) +# CHECK-NEXT: 1 3 1.00 U fucomi %st(3), %st +# CHECK-NEXT: 1 3 1.00 U fucompi %st(3), %st # CHECK-NEXT: 1 100 1.00 U wait # CHECK-NEXT: 1 100 1.00 U fxam # CHECK-NEXT: 1 1 0.50 U fxch %st(1) @@ -373,26 +373,26 @@ fyl2xp1 # CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] Instructions: # CHECK-NEXT: - - - 1.00 - - - - f2xm1 # CHECK-NEXT: - - - 0.50 0.50 - - - fabs -# CHECK-NEXT: - - - - 1.00 - - - fadd %st(0), %st(1) -# CHECK-NEXT: - - - - 1.00 - - - fadd %st(2) +# CHECK-NEXT: - - - - 1.00 - - - fadd %st, %st(1) +# CHECK-NEXT: - - - - 1.00 - - - fadd %st(2), %st # CHECK-NEXT: - - - - 1.00 - - 1.00 fadds (%ecx) # CHECK-NEXT: - - - - 1.00 - - 1.00 faddl (%ecx) -# CHECK-NEXT: - - - - 1.00 - - - faddp %st(1) -# CHECK-NEXT: - - - - 1.00 - - - faddp %st(2) +# CHECK-NEXT: - - - - 1.00 - - - faddp %st, %st(1) +# CHECK-NEXT: - - - - 1.00 - - - faddp %st, %st(2) # CHECK-NEXT: - - - - 1.00 - - 1.00 fiadds (%ecx) # CHECK-NEXT: - - - - 1.00 - - 1.00 fiaddl (%ecx) # CHECK-NEXT: - - - 1.00 - - - - fbld (%ecx) # CHECK-NEXT: - - - 1.00 - - - - fbstp (%eax) # CHECK-NEXT: - - - 0.50 0.50 - - - fchs # CHECK-NEXT: - - - 1.00 - - - - fnclex -# CHECK-NEXT: - - - - 1.00 - - - fcmovb %st(1), %st(0) -# CHECK-NEXT: - - - - 1.00 - - - fcmovbe %st(1), %st(0) -# CHECK-NEXT: - - - - 1.00 - - - fcmove %st(1), %st(0) -# CHECK-NEXT: - - - - 1.00 - - - fcmovnb %st(1), %st(0) -# CHECK-NEXT: - - - - 1.00 - - - fcmovnbe %st(1), %st(0) -# CHECK-NEXT: - - - - 1.00 - - - fcmovne %st(1), %st(0) -# CHECK-NEXT: - - - - 1.00 - - - fcmovnu %st(1), %st(0) -# CHECK-NEXT: - - - - 1.00 - - - fcmovu %st(1), %st(0) +# CHECK-NEXT: - - - - 1.00 - - - fcmovb %st(1), %st +# CHECK-NEXT: - - - - 1.00 - - - fcmovbe %st(1), %st +# CHECK-NEXT: - - - - 1.00 - - - fcmove %st(1), %st +# CHECK-NEXT: - - - - 1.00 - - - fcmovnb %st(1), %st +# CHECK-NEXT: - - - - 1.00 - - - fcmovnbe %st(1), %st +# CHECK-NEXT: - - - - 1.00 - - - fcmovne %st(1), %st +# CHECK-NEXT: - - - - 1.00 - - - fcmovnu %st(1), %st +# CHECK-NEXT: - - - - 1.00 - - - fcmovu %st(1), %st # CHECK-NEXT: - - - - 1.00 - - - fcom %st(1) # CHECK-NEXT: - - - - 1.00 - - - fcom %st(3) # CHECK-NEXT: - - - - 1.00 - - 1.00 fcoms (%ecx) @@ -402,24 +402,24 @@ fyl2xp1 # CHECK-NEXT: - - - - 1.00 - - 1.00 fcomps (%ecx) # CHECK-NEXT: - - - - 1.00 - - 1.00 fcompl (%eax) # CHECK-NEXT: - - - 1.00 - - - - fcompp -# CHECK-NEXT: - - - - 1.00 - - - fcomi %st(3) -# CHECK-NEXT: - - - - 1.00 - - - fcompi %st(3) +# CHECK-NEXT: - - - - 1.00 - - - fcomi %st(3), %st +# CHECK-NEXT: - - - - 1.00 - - - fcompi %st(3), %st # CHECK-NEXT: - - - 1.00 - - - - fcos # CHECK-NEXT: - - - 1.00 - - - - fdecstp -# CHECK-NEXT: - 17.00 - 1.00 - - - - fdiv %st(0), %st(1) -# CHECK-NEXT: - 17.00 - 1.00 - - - - fdiv %st(2) +# CHECK-NEXT: - 17.00 - 1.00 - - - - fdiv %st, %st(1) +# CHECK-NEXT: - 17.00 - 1.00 - - - - fdiv %st(2), %st # CHECK-NEXT: - 17.00 - 1.00 - - - 1.00 fdivs (%ecx) # CHECK-NEXT: - 17.00 - 1.00 - - - 1.00 fdivl (%eax) -# CHECK-NEXT: - 17.00 - 1.00 - - - - fdivp %st(1) -# CHECK-NEXT: - 17.00 - 1.00 - - - - fdivp %st(2) +# CHECK-NEXT: - 17.00 - 1.00 - - - - fdivp %st, %st(1) +# CHECK-NEXT: - 17.00 - 1.00 - - - - fdivp %st, %st(2) # CHECK-NEXT: - 17.00 - 1.00 - - - 1.00 fidivs (%ecx) # CHECK-NEXT: - 17.00 - 1.00 - - - 1.00 fidivl (%eax) -# CHECK-NEXT: - 17.00 - 1.00 - - - - fdivr %st(0), %st(1) -# CHECK-NEXT: - 17.00 - 1.00 - - - - fdivr %st(2) +# CHECK-NEXT: - 17.00 - 1.00 - - - - fdivr %st, %st(1) +# CHECK-NEXT: - 17.00 - 1.00 - - - - fdivr %st(2), %st # CHECK-NEXT: - 17.00 - 1.00 - - - 1.00 fdivrs (%ecx) # CHECK-NEXT: - 17.00 - 1.00 - - - 1.00 fdivrl (%eax) -# CHECK-NEXT: - 17.00 - 1.00 - - - - fdivrp %st(1) -# CHECK-NEXT: - 17.00 - 1.00 - - - - fdivrp %st(2) +# CHECK-NEXT: - 17.00 - 1.00 - - - - fdivrp %st, %st(1) +# CHECK-NEXT: - 17.00 - 1.00 - - - - fdivrp %st, %st(2) # CHECK-NEXT: - 17.00 - 1.00 - - - 1.00 fidivrs (%ecx) # CHECK-NEXT: - 17.00 - 1.00 - - - 1.00 fidivrl (%eax) # CHECK-NEXT: - - - 1.00 - - - - ffree %st(0) @@ -453,12 +453,12 @@ fyl2xp1 # CHECK-NEXT: - - - 1.00 1.00 - - - fldln2 # CHECK-NEXT: - - - 1.00 1.00 - - - fldpi # CHECK-NEXT: - - - 0.50 0.50 - - - fldz -# CHECK-NEXT: - - 2.00 1.00 - - - - fmul %st(0), %st(1) -# CHECK-NEXT: - - 2.00 1.00 - - - - fmul %st(2) +# CHECK-NEXT: - - 2.00 1.00 - - - - fmul %st, %st(1) +# CHECK-NEXT: - - 2.00 1.00 - - - - fmul %st(2), %st # CHECK-NEXT: - - 2.00 1.00 - - - 1.00 fmuls (%ecx) # CHECK-NEXT: - - 2.00 1.00 - - - 1.00 fmull (%eax) -# CHECK-NEXT: - - 2.00 1.00 - - - - fmulp %st(1) -# CHECK-NEXT: - - 2.00 1.00 - - - - fmulp %st(2) +# CHECK-NEXT: - - 2.00 1.00 - - - - fmulp %st, %st(1) +# CHECK-NEXT: - - 2.00 1.00 - - - - fmulp %st, %st(2) # CHECK-NEXT: - - 2.00 1.00 - - - 1.00 fimuls (%ecx) # CHECK-NEXT: - - 2.00 1.00 - - - 1.00 fimull (%eax) # CHECK-NEXT: - - - - - - - - fnop @@ -486,20 +486,20 @@ fyl2xp1 # CHECK-NEXT: - - - 1.00 - - - - frstor (%eax) # CHECK-NEXT: - - - 1.00 - - - - wait # CHECK-NEXT: - - - 1.00 - - - - fnsave (%eax) -# CHECK-NEXT: - - - - 1.00 - - - fsub %st(0), %st(1) -# CHECK-NEXT: - - - - 1.00 - - - fsub %st(2) +# CHECK-NEXT: - - - - 1.00 - - - fsub %st, %st(1) +# CHECK-NEXT: - - - - 1.00 - - - fsub %st(2), %st # CHECK-NEXT: - - - - 1.00 - - 1.00 fsubs (%ecx) # CHECK-NEXT: - - - - 1.00 - - 1.00 fsubl (%eax) -# CHECK-NEXT: - - - - 1.00 - - - fsubp %st(1) -# CHECK-NEXT: - - - - 1.00 - - - fsubp %st(2) +# CHECK-NEXT: - - - - 1.00 - - - fsubp %st, %st(1) +# CHECK-NEXT: - - - - 1.00 - - - fsubp %st, %st(2) # CHECK-NEXT: - - - - 1.00 - - 1.00 fisubs (%ecx) # CHECK-NEXT: - - - - 1.00 - - 1.00 fisubl (%eax) -# CHECK-NEXT: - - - - 1.00 - - - fsubr %st(0), %st(1) -# CHECK-NEXT: - - - - 1.00 - - - fsubr %st(2) +# CHECK-NEXT: - - - - 1.00 - - - fsubr %st, %st(1) +# CHECK-NEXT: - - - - 1.00 - - - fsubr %st(2), %st # CHECK-NEXT: - - - - 1.00 - - 1.00 fsubrs (%ecx) # CHECK-NEXT: - - - - 1.00 - - 1.00 fsubrl (%eax) -# CHECK-NEXT: - - - - 1.00 - - - fsubrp %st(1) -# CHECK-NEXT: - - - - 1.00 - - - fsubrp %st(2) +# CHECK-NEXT: - - - - 1.00 - - - fsubrp %st, %st(1) +# CHECK-NEXT: - - - - 1.00 - - - fsubrp %st, %st(2) # CHECK-NEXT: - - - - 1.00 - - 1.00 fisubrs (%ecx) # CHECK-NEXT: - - - - 1.00 - - 1.00 fisubrl (%eax) # CHECK-NEXT: - - - - 1.00 - - - ftst @@ -508,8 +508,8 @@ fyl2xp1 # CHECK-NEXT: - - - - 1.00 - - - fucomp %st(1) # CHECK-NEXT: - - - - 1.00 - - - fucomp %st(3) # CHECK-NEXT: - - - - 1.00 - - - fucompp -# CHECK-NEXT: - - - - 1.00 - - - fucomi %st(3) -# CHECK-NEXT: - - - - 1.00 - - - fucompi %st(3) +# CHECK-NEXT: - - - - 1.00 - - - fucomi %st(3), %st +# CHECK-NEXT: - - - - 1.00 - - - fucompi %st(3), %st # CHECK-NEXT: - - - 1.00 - - - - wait # CHECK-NEXT: - - - 1.00 - - - - fxam # CHECK-NEXT: - - - - - 0.50 0.50 - fxch %st(1) diff --git a/llvm/test/tools/llvm-mca/X86/SandyBridge/resources-x87.s b/llvm/test/tools/llvm-mca/X86/SandyBridge/resources-x87.s index 332f365f1fdd3..1bed53326ced6 100644 --- a/llvm/test/tools/llvm-mca/X86/SandyBridge/resources-x87.s +++ b/llvm/test/tools/llvm-mca/X86/SandyBridge/resources-x87.s @@ -5,7 +5,7 @@ f2xm1 fabs -fadd %st(0), %st(1) +fadd %st, %st(1) fadd %st(2) fadds (%ecx) faddl (%ecx) @@ -21,14 +21,14 @@ fchs fnclex -fcmovb %st(1), %st(0) -fcmovbe %st(1), %st(0) -fcmove %st(1), %st(0) -fcmovnb %st(1), %st(0) -fcmovnbe %st(1), %st(0) -fcmovne %st(1), %st(0) -fcmovnu %st(1), %st(0) -fcmovu %st(1), %st(0) +fcmovb %st(1), %st +fcmovbe %st(1), %st +fcmove %st(1), %st +fcmovnb %st(1), %st +fcmovnbe %st(1), %st +fcmovne %st(1), %st +fcmovnu %st(1), %st +fcmovu %st(1), %st fcom %st(1) fcom %st(3) @@ -47,7 +47,7 @@ fcos fdecstp -fdiv %st(0), %st(1) +fdiv %st, %st(1) fdiv %st(2) fdivs (%ecx) fdivl (%eax) @@ -56,7 +56,7 @@ fdivp %st(2) fidivs (%ecx) fidivl (%eax) -fdivr %st(0), %st(1) +fdivr %st, %st(1) fdivr %st(2) fdivrs (%ecx) fdivrl (%eax) @@ -106,7 +106,7 @@ fldln2 fldpi fldz -fmul %st(0), %st(1) +fmul %st, %st(1) fmul %st(2) fmuls (%ecx) fmull (%eax) @@ -153,7 +153,7 @@ fnstsw (%eax) frstor (%eax) fsave (%eax) -fsub %st(0), %st(1) +fsub %st, %st(1) fsub %st(2) fsubs (%ecx) fsubl (%eax) @@ -162,7 +162,7 @@ fsubp %st(2) fisubs (%ecx) fisubl (%eax) -fsubr %st(0), %st(1) +fsubr %st, %st(1) fsubr %st(2) fsubrs (%ecx) fsubrl (%eax) @@ -208,26 +208,26 @@ fyl2xp1 # CHECK: [1] [2] [3] [4] [5] [6] Instructions: # CHECK-NEXT: 1 100 0.33 U f2xm1 # CHECK-NEXT: 1 1 1.00 U fabs -# CHECK-NEXT: 1 3 1.00 U fadd %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fadd %st(2) +# CHECK-NEXT: 1 3 1.00 U fadd %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fadd %st(2), %st # CHECK-NEXT: 2 10 1.00 * U fadds (%ecx) # CHECK-NEXT: 2 10 1.00 * U faddl (%ecx) -# CHECK-NEXT: 1 3 1.00 U faddp %st(1) -# CHECK-NEXT: 1 3 1.00 U faddp %st(2) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(2) # CHECK-NEXT: 3 13 2.00 * U fiadds (%ecx) # CHECK-NEXT: 3 13 2.00 * U fiaddl (%ecx) # CHECK-NEXT: 1 100 0.33 U fbld (%ecx) # CHECK-NEXT: 1 100 0.33 U fbstp (%eax) # CHECK-NEXT: 1 1 1.00 U fchs # CHECK-NEXT: 1 100 0.33 U fnclex -# CHECK-NEXT: 3 3 2.00 U fcmovb %st(1), %st(0) -# CHECK-NEXT: 3 3 2.00 U fcmovbe %st(1), %st(0) -# CHECK-NEXT: 3 3 2.00 U fcmove %st(1), %st(0) -# CHECK-NEXT: 3 3 2.00 U fcmovnb %st(1), %st(0) -# CHECK-NEXT: 3 3 2.00 U fcmovnbe %st(1), %st(0) -# CHECK-NEXT: 3 3 2.00 U fcmovne %st(1), %st(0) -# CHECK-NEXT: 3 3 2.00 U fcmovnu %st(1), %st(0) -# CHECK-NEXT: 3 3 2.00 U fcmovu %st(1), %st(0) +# CHECK-NEXT: 3 3 2.00 U fcmovb %st(1), %st +# CHECK-NEXT: 3 3 2.00 U fcmovbe %st(1), %st +# CHECK-NEXT: 3 3 2.00 U fcmove %st(1), %st +# CHECK-NEXT: 3 3 2.00 U fcmovnb %st(1), %st +# CHECK-NEXT: 3 3 2.00 U fcmovnbe %st(1), %st +# CHECK-NEXT: 3 3 2.00 U fcmovne %st(1), %st +# CHECK-NEXT: 3 3 2.00 U fcmovnu %st(1), %st +# CHECK-NEXT: 3 3 2.00 U fcmovu %st(1), %st # CHECK-NEXT: 1 1 1.00 U fcom %st(1) # CHECK-NEXT: 1 1 1.00 U fcom %st(3) # CHECK-NEXT: 2 8 1.00 U fcoms (%ecx) @@ -237,24 +237,24 @@ fyl2xp1 # CHECK-NEXT: 2 8 1.00 U fcomps (%ecx) # CHECK-NEXT: 2 8 1.00 U fcompl (%eax) # CHECK-NEXT: 1 100 0.33 U fcompp -# CHECK-NEXT: 3 3 1.00 U fcomi %st(3) -# CHECK-NEXT: 3 3 1.00 U fcompi %st(3) +# CHECK-NEXT: 3 3 1.00 U fcomi %st(3), %st +# CHECK-NEXT: 3 3 1.00 U fcompi %st(3), %st # CHECK-NEXT: 1 100 0.33 U fcos # CHECK-NEXT: 1 1 1.00 U fdecstp -# CHECK-NEXT: 1 14 14.00 U fdiv %st(0), %st(1) -# CHECK-NEXT: 1 14 14.00 U fdiv %st(2) +# CHECK-NEXT: 1 14 14.00 U fdiv %st, %st(1) +# CHECK-NEXT: 1 14 14.00 U fdiv %st(2), %st # CHECK-NEXT: 2 31 1.00 * U fdivs (%ecx) # CHECK-NEXT: 2 31 1.00 * U fdivl (%eax) -# CHECK-NEXT: 1 14 14.00 U fdivp %st(1) -# CHECK-NEXT: 1 14 14.00 U fdivp %st(2) +# CHECK-NEXT: 1 14 14.00 U fdivp %st, %st(1) +# CHECK-NEXT: 1 14 14.00 U fdivp %st, %st(2) # CHECK-NEXT: 3 34 1.00 * U fidivs (%ecx) # CHECK-NEXT: 3 34 1.00 * U fidivl (%eax) -# CHECK-NEXT: 1 14 14.00 U fdivr %st(0), %st(1) -# CHECK-NEXT: 1 14 14.00 U fdivr %st(2) +# CHECK-NEXT: 1 14 14.00 U fdivr %st, %st(1) +# CHECK-NEXT: 1 14 14.00 U fdivr %st(2), %st # CHECK-NEXT: 2 31 1.00 * U fdivrs (%ecx) # CHECK-NEXT: 2 31 1.00 * U fdivrl (%eax) -# CHECK-NEXT: 1 14 14.00 U fdivrp %st(1) -# CHECK-NEXT: 1 14 14.00 U fdivrp %st(2) +# CHECK-NEXT: 1 14 14.00 U fdivrp %st, %st(1) +# CHECK-NEXT: 1 14 14.00 U fdivrp %st, %st(2) # CHECK-NEXT: 3 34 1.00 * U fidivrs (%ecx) # CHECK-NEXT: 3 34 1.00 * U fidivrl (%eax) # CHECK-NEXT: 1 1 1.00 U ffree %st(0) @@ -288,12 +288,12 @@ fyl2xp1 # CHECK-NEXT: 2 1 1.00 U fldln2 # CHECK-NEXT: 2 1 1.00 U fldpi # CHECK-NEXT: 1 1 1.00 U fldz -# CHECK-NEXT: 1 5 1.00 U fmul %st(0), %st(1) -# CHECK-NEXT: 1 5 1.00 U fmul %st(2) +# CHECK-NEXT: 1 5 1.00 U fmul %st, %st(1) +# CHECK-NEXT: 1 5 1.00 U fmul %st(2), %st # CHECK-NEXT: 2 12 1.00 * U fmuls (%ecx) # CHECK-NEXT: 2 12 1.00 * U fmull (%eax) -# CHECK-NEXT: 1 5 1.00 U fmulp %st(1) -# CHECK-NEXT: 1 5 1.00 U fmulp %st(2) +# CHECK-NEXT: 1 5 1.00 U fmulp %st, %st(1) +# CHECK-NEXT: 1 5 1.00 U fmulp %st, %st(2) # CHECK-NEXT: 3 15 1.00 * U fimuls (%ecx) # CHECK-NEXT: 3 15 1.00 * U fimull (%eax) # CHECK-NEXT: 1 1 1.00 U fnop @@ -321,20 +321,20 @@ fyl2xp1 # CHECK-NEXT: 1 100 0.33 U frstor (%eax) # CHECK-NEXT: 1 100 0.33 U wait # CHECK-NEXT: 1 100 0.33 U fnsave (%eax) -# CHECK-NEXT: 1 3 1.00 U fsub %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsub %st(2) +# CHECK-NEXT: 1 3 1.00 U fsub %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsub %st(2), %st # CHECK-NEXT: 2 10 1.00 * U fsubs (%ecx) # CHECK-NEXT: 2 10 1.00 * U fsubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(2) # CHECK-NEXT: 3 13 2.00 * U fisubs (%ecx) # CHECK-NEXT: 3 13 2.00 * U fisubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubr %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubr %st(2), %st # CHECK-NEXT: 2 10 1.00 * U fsubrs (%ecx) # CHECK-NEXT: 2 10 1.00 * U fsubrl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(2) # CHECK-NEXT: 3 13 2.00 * U fisubrs (%ecx) # CHECK-NEXT: 3 13 2.00 * U fisubrl (%eax) # CHECK-NEXT: 1 3 1.00 U ftst @@ -343,8 +343,8 @@ fyl2xp1 # CHECK-NEXT: 1 1 1.00 U fucomp %st(1) # CHECK-NEXT: 1 1 1.00 U fucomp %st(3) # CHECK-NEXT: 1 3 1.00 U fucompp -# CHECK-NEXT: 3 3 1.00 U fucomi %st(3) -# CHECK-NEXT: 3 3 1.00 U fucompi %st(3) +# CHECK-NEXT: 3 3 1.00 U fucomi %st(3), %st +# CHECK-NEXT: 3 3 1.00 U fucompi %st(3), %st # CHECK-NEXT: 1 100 0.33 U wait # CHECK-NEXT: 1 100 0.33 U fxam # CHECK-NEXT: 1 1 0.33 U fxch %st(1) @@ -373,26 +373,26 @@ fyl2xp1 # CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6.0] [6.1] Instructions: # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - f2xm1 # CHECK-NEXT: - - - - - 1.00 - - fabs -# CHECK-NEXT: - - - 1.00 - - - - fadd %st(0), %st(1) -# CHECK-NEXT: - - - 1.00 - - - - fadd %st(2) +# CHECK-NEXT: - - - 1.00 - - - - fadd %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - fadd %st(2), %st # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 fadds (%ecx) # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 faddl (%ecx) -# CHECK-NEXT: - - - 1.00 - - - - faddp %st(1) -# CHECK-NEXT: - - - 1.00 - - - - faddp %st(2) +# CHECK-NEXT: - - - 1.00 - - - - faddp %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - faddp %st, %st(2) # CHECK-NEXT: - - - 2.00 - - 0.50 0.50 fiadds (%ecx) # CHECK-NEXT: - - - 2.00 - - 0.50 0.50 fiaddl (%ecx) # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - fbld (%ecx) # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - fbstp (%eax) # CHECK-NEXT: - - - - - 1.00 - - fchs # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - fnclex -# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovb %st(1), %st(0) -# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovbe %st(1), %st(0) -# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmove %st(1), %st(0) -# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovnb %st(1), %st(0) -# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovnbe %st(1), %st(0) -# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovne %st(1), %st(0) -# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovnu %st(1), %st(0) -# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovu %st(1), %st(0) +# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovb %st(1), %st +# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovbe %st(1), %st +# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmove %st(1), %st +# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovnb %st(1), %st +# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovnbe %st(1), %st +# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovne %st(1), %st +# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovnu %st(1), %st +# CHECK-NEXT: - - 0.50 - - 2.50 - - fcmovu %st(1), %st # CHECK-NEXT: - - - 1.00 - - - - fcom %st(1) # CHECK-NEXT: - - - 1.00 - - - - fcom %st(3) # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 fcoms (%ecx) @@ -402,24 +402,24 @@ fyl2xp1 # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 fcomps (%ecx) # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 fcompl (%eax) # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - fcompp -# CHECK-NEXT: - - 1.00 1.00 - 1.00 - - fcomi %st(3) -# CHECK-NEXT: - - 1.00 1.00 - 1.00 - - fcompi %st(3) +# CHECK-NEXT: - - 1.00 1.00 - 1.00 - - fcomi %st(3), %st +# CHECK-NEXT: - - 1.00 1.00 - 1.00 - - fcompi %st(3), %st # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - fcos # CHECK-NEXT: - - - - - 1.00 - - fdecstp -# CHECK-NEXT: - 14.00 1.00 - - - - - fdiv %st(0), %st(1) -# CHECK-NEXT: - 14.00 1.00 - - - - - fdiv %st(2) +# CHECK-NEXT: - 14.00 1.00 - - - - - fdiv %st, %st(1) +# CHECK-NEXT: - 14.00 1.00 - - - - - fdiv %st(2), %st # CHECK-NEXT: - - 1.00 - - - 0.50 0.50 fdivs (%ecx) # CHECK-NEXT: - - 1.00 - - - 0.50 0.50 fdivl (%eax) -# CHECK-NEXT: - 14.00 1.00 - - - - - fdivp %st(1) -# CHECK-NEXT: - 14.00 1.00 - - - - - fdivp %st(2) +# CHECK-NEXT: - 14.00 1.00 - - - - - fdivp %st, %st(1) +# CHECK-NEXT: - 14.00 1.00 - - - - - fdivp %st, %st(2) # CHECK-NEXT: - - 1.00 1.00 - - 0.50 0.50 fidivs (%ecx) # CHECK-NEXT: - - 1.00 1.00 - - 0.50 0.50 fidivl (%eax) -# CHECK-NEXT: - 14.00 1.00 - - - - - fdivr %st(0), %st(1) -# CHECK-NEXT: - 14.00 1.00 - - - - - fdivr %st(2) +# CHECK-NEXT: - 14.00 1.00 - - - - - fdivr %st, %st(1) +# CHECK-NEXT: - 14.00 1.00 - - - - - fdivr %st(2), %st # CHECK-NEXT: - - 1.00 - - - 0.50 0.50 fdivrs (%ecx) # CHECK-NEXT: - - 1.00 - - - 0.50 0.50 fdivrl (%eax) -# CHECK-NEXT: - 14.00 1.00 - - - - - fdivrp %st(1) -# CHECK-NEXT: - 14.00 1.00 - - - - - fdivrp %st(2) +# CHECK-NEXT: - 14.00 1.00 - - - - - fdivrp %st, %st(1) +# CHECK-NEXT: - 14.00 1.00 - - - - - fdivrp %st, %st(2) # CHECK-NEXT: - - 1.00 1.00 - - 0.50 0.50 fidivrs (%ecx) # CHECK-NEXT: - - 1.00 1.00 - - 0.50 0.50 fidivrl (%eax) # CHECK-NEXT: - - - - - 1.00 - - ffree %st(0) @@ -453,12 +453,12 @@ fyl2xp1 # CHECK-NEXT: - - 1.00 1.00 - - - - fldln2 # CHECK-NEXT: - - 1.00 1.00 - - - - fldpi # CHECK-NEXT: - - - - - 1.00 - - fldz -# CHECK-NEXT: - - 1.00 - - - - - fmul %st(0), %st(1) -# CHECK-NEXT: - - 1.00 - - - - - fmul %st(2) +# CHECK-NEXT: - - 1.00 - - - - - fmul %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - fmul %st(2), %st # CHECK-NEXT: - - 1.00 - - - 0.50 0.50 fmuls (%ecx) # CHECK-NEXT: - - 1.00 - - - 0.50 0.50 fmull (%eax) -# CHECK-NEXT: - - 1.00 - - - - - fmulp %st(1) -# CHECK-NEXT: - - 1.00 - - - - - fmulp %st(2) +# CHECK-NEXT: - - 1.00 - - - - - fmulp %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - fmulp %st, %st(2) # CHECK-NEXT: - - 1.00 1.00 - - 0.50 0.50 fimuls (%ecx) # CHECK-NEXT: - - 1.00 1.00 - - 0.50 0.50 fimull (%eax) # CHECK-NEXT: - - - - - 1.00 - - fnop @@ -486,20 +486,20 @@ fyl2xp1 # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - frstor (%eax) # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - wait # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - fnsave (%eax) -# CHECK-NEXT: - - - 1.00 - - - - fsub %st(0), %st(1) -# CHECK-NEXT: - - - 1.00 - - - - fsub %st(2) +# CHECK-NEXT: - - - 1.00 - - - - fsub %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - fsub %st(2), %st # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 fsubs (%ecx) # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 fsubl (%eax) -# CHECK-NEXT: - - - 1.00 - - - - fsubp %st(1) -# CHECK-NEXT: - - - 1.00 - - - - fsubp %st(2) +# CHECK-NEXT: - - - 1.00 - - - - fsubp %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - fsubp %st, %st(2) # CHECK-NEXT: - - - 2.00 - - 0.50 0.50 fisubs (%ecx) # CHECK-NEXT: - - - 2.00 - - 0.50 0.50 fisubl (%eax) -# CHECK-NEXT: - - - 1.00 - - - - fsubr %st(0), %st(1) -# CHECK-NEXT: - - - 1.00 - - - - fsubr %st(2) +# CHECK-NEXT: - - - 1.00 - - - - fsubr %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - fsubr %st(2), %st # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 fsubrs (%ecx) # CHECK-NEXT: - - - 1.00 - - 0.50 0.50 fsubrl (%eax) -# CHECK-NEXT: - - - 1.00 - - - - fsubrp %st(1) -# CHECK-NEXT: - - - 1.00 - - - - fsubrp %st(2) +# CHECK-NEXT: - - - 1.00 - - - - fsubrp %st, %st(1) +# CHECK-NEXT: - - - 1.00 - - - - fsubrp %st, %st(2) # CHECK-NEXT: - - - 2.00 - - 0.50 0.50 fisubrs (%ecx) # CHECK-NEXT: - - - 2.00 - - 0.50 0.50 fisubrl (%eax) # CHECK-NEXT: - - - 1.00 - - - - ftst @@ -508,8 +508,8 @@ fyl2xp1 # CHECK-NEXT: - - - 1.00 - - - - fucomp %st(1) # CHECK-NEXT: - - - 1.00 - - - - fucomp %st(3) # CHECK-NEXT: - - - 1.00 - - - - fucompp -# CHECK-NEXT: - - 1.00 1.00 - 1.00 - - fucomi %st(3) -# CHECK-NEXT: - - 1.00 1.00 - 1.00 - - fucompi %st(3) +# CHECK-NEXT: - - 1.00 1.00 - 1.00 - - fucomi %st(3), %st +# CHECK-NEXT: - - 1.00 1.00 - 1.00 - - fucompi %st(3), %st # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - wait # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - fxam # CHECK-NEXT: - - 0.33 0.33 - 0.33 - - fxch %st(1) diff --git a/llvm/test/tools/llvm-mca/X86/SkylakeClient/resources-x87.s b/llvm/test/tools/llvm-mca/X86/SkylakeClient/resources-x87.s index 7be9d699573ac..6cd4439a25c1f 100644 --- a/llvm/test/tools/llvm-mca/X86/SkylakeClient/resources-x87.s +++ b/llvm/test/tools/llvm-mca/X86/SkylakeClient/resources-x87.s @@ -5,7 +5,7 @@ f2xm1 fabs -fadd %st(0), %st(1) +fadd %st, %st(1) fadd %st(2) fadds (%ecx) faddl (%ecx) @@ -21,14 +21,14 @@ fchs fnclex -fcmovb %st(1), %st(0) -fcmovbe %st(1), %st(0) -fcmove %st(1), %st(0) -fcmovnb %st(1), %st(0) -fcmovnbe %st(1), %st(0) -fcmovne %st(1), %st(0) -fcmovnu %st(1), %st(0) -fcmovu %st(1), %st(0) +fcmovb %st(1), %st +fcmovbe %st(1), %st +fcmove %st(1), %st +fcmovnb %st(1), %st +fcmovnbe %st(1), %st +fcmovne %st(1), %st +fcmovnu %st(1), %st +fcmovu %st(1), %st fcom %st(1) fcom %st(3) @@ -47,7 +47,7 @@ fcos fdecstp -fdiv %st(0), %st(1) +fdiv %st, %st(1) fdiv %st(2) fdivs (%ecx) fdivl (%eax) @@ -56,7 +56,7 @@ fdivp %st(2) fidivs (%ecx) fidivl (%eax) -fdivr %st(0), %st(1) +fdivr %st, %st(1) fdivr %st(2) fdivrs (%ecx) fdivrl (%eax) @@ -106,7 +106,7 @@ fldln2 fldpi fldz -fmul %st(0), %st(1) +fmul %st, %st(1) fmul %st(2) fmuls (%ecx) fmull (%eax) @@ -153,7 +153,7 @@ fnstsw (%eax) frstor (%eax) fsave (%eax) -fsub %st(0), %st(1) +fsub %st, %st(1) fsub %st(2) fsubs (%ecx) fsubl (%eax) @@ -162,7 +162,7 @@ fsubp %st(2) fisubs (%ecx) fisubl (%eax) -fsubr %st(0), %st(1) +fsubr %st, %st(1) fsubr %st(2) fsubrs (%ecx) fsubrl (%eax) @@ -208,26 +208,26 @@ fyl2xp1 # CHECK: [1] [2] [3] [4] [5] [6] Instructions: # CHECK-NEXT: 1 100 0.25 U f2xm1 # CHECK-NEXT: 1 1 1.00 U fabs -# CHECK-NEXT: 1 3 1.00 U fadd %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fadd %st(2) +# CHECK-NEXT: 1 3 1.00 U fadd %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fadd %st(2), %st # CHECK-NEXT: 2 10 1.00 * U fadds (%ecx) # CHECK-NEXT: 2 10 1.00 * U faddl (%ecx) -# CHECK-NEXT: 1 3 1.00 U faddp %st(1) -# CHECK-NEXT: 1 3 1.00 U faddp %st(2) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(2) # CHECK-NEXT: 3 13 2.00 * U fiadds (%ecx) # CHECK-NEXT: 3 13 2.00 * U fiaddl (%ecx) # CHECK-NEXT: 1 100 0.25 U fbld (%ecx) # CHECK-NEXT: 2 1 1.00 U fbstp (%eax) # CHECK-NEXT: 1 1 1.00 U fchs # CHECK-NEXT: 4 4 1.00 U fnclex -# CHECK-NEXT: 1 3 1.00 U fcmovb %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovbe %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmove %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnb %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnbe %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovne %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnu %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovu %st(1), %st(0) +# CHECK-NEXT: 1 3 1.00 U fcmovb %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovbe %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmove %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnb %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnbe %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovne %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnu %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovu %st(1), %st # CHECK-NEXT: 1 1 1.00 U fcom %st(1) # CHECK-NEXT: 1 1 1.00 U fcom %st(3) # CHECK-NEXT: 2 8 1.00 U fcoms (%ecx) @@ -237,24 +237,24 @@ fyl2xp1 # CHECK-NEXT: 2 8 1.00 U fcomps (%ecx) # CHECK-NEXT: 2 8 1.00 U fcompl (%eax) # CHECK-NEXT: 1 100 0.25 U fcompp -# CHECK-NEXT: 1 2 1.00 U fcomi %st(3) -# CHECK-NEXT: 1 2 1.00 U fcompi %st(3) +# CHECK-NEXT: 1 2 1.00 U fcomi %st(3), %st +# CHECK-NEXT: 1 2 1.00 U fcompi %st(3), %st # CHECK-NEXT: 1 100 0.25 U fcos # CHECK-NEXT: 2 2 1.00 U fdecstp -# CHECK-NEXT: 1 15 1.00 U fdiv %st(0), %st(1) -# CHECK-NEXT: 1 20 1.00 U fdiv %st(2) +# CHECK-NEXT: 1 15 1.00 U fdiv %st, %st(1) +# CHECK-NEXT: 1 20 1.00 U fdiv %st(2), %st # CHECK-NEXT: 2 22 1.00 * U fdivs (%ecx) # CHECK-NEXT: 2 22 1.00 * U fdivl (%eax) -# CHECK-NEXT: 1 15 1.00 U fdivp %st(1) -# CHECK-NEXT: 1 15 1.00 U fdivp %st(2) +# CHECK-NEXT: 1 15 1.00 U fdivp %st, %st(1) +# CHECK-NEXT: 1 15 1.00 U fdivp %st, %st(2) # CHECK-NEXT: 3 25 1.00 * U fidivs (%ecx) # CHECK-NEXT: 3 25 1.00 * U fidivl (%eax) -# CHECK-NEXT: 1 20 1.00 U fdivr %st(0), %st(1) -# CHECK-NEXT: 1 15 1.00 U fdivr %st(2) +# CHECK-NEXT: 1 20 1.00 U fdivr %st, %st(1) +# CHECK-NEXT: 1 15 1.00 U fdivr %st(2), %st # CHECK-NEXT: 2 27 1.00 * U fdivrs (%ecx) # CHECK-NEXT: 2 27 1.00 * U fdivrl (%eax) -# CHECK-NEXT: 1 20 1.00 U fdivrp %st(1) -# CHECK-NEXT: 1 20 1.00 U fdivrp %st(2) +# CHECK-NEXT: 1 20 1.00 U fdivrp %st, %st(1) +# CHECK-NEXT: 1 20 1.00 U fdivrp %st, %st(2) # CHECK-NEXT: 3 30 1.00 * U fidivrs (%ecx) # CHECK-NEXT: 3 30 1.00 * U fidivrl (%eax) # CHECK-NEXT: 1 100 0.25 U ffree %st(0) @@ -288,12 +288,12 @@ fyl2xp1 # CHECK-NEXT: 2 1 1.00 U fldln2 # CHECK-NEXT: 2 1 1.00 U fldpi # CHECK-NEXT: 1 1 0.50 U fldz -# CHECK-NEXT: 1 4 1.00 U fmul %st(0), %st(1) -# CHECK-NEXT: 1 4 1.00 U fmul %st(2) +# CHECK-NEXT: 1 4 1.00 U fmul %st, %st(1) +# CHECK-NEXT: 1 4 1.00 U fmul %st(2), %st # CHECK-NEXT: 2 11 1.00 * U fmuls (%ecx) # CHECK-NEXT: 2 11 1.00 * U fmull (%eax) -# CHECK-NEXT: 1 4 1.00 U fmulp %st(1) -# CHECK-NEXT: 1 4 1.00 U fmulp %st(2) +# CHECK-NEXT: 1 4 1.00 U fmulp %st, %st(1) +# CHECK-NEXT: 1 4 1.00 U fmulp %st, %st(2) # CHECK-NEXT: 3 14 1.00 * U fimuls (%ecx) # CHECK-NEXT: 3 14 1.00 * U fimull (%eax) # CHECK-NEXT: 1 1 0.50 U fnop @@ -321,20 +321,20 @@ fyl2xp1 # CHECK-NEXT: 1 100 0.25 U frstor (%eax) # CHECK-NEXT: 2 2 0.50 U wait # CHECK-NEXT: 1 100 0.25 U fnsave (%eax) -# CHECK-NEXT: 1 3 1.00 U fsub %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsub %st(2) +# CHECK-NEXT: 1 3 1.00 U fsub %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsub %st(2), %st # CHECK-NEXT: 2 10 1.00 * U fsubs (%ecx) # CHECK-NEXT: 2 10 1.00 * U fsubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(2) # CHECK-NEXT: 3 13 2.00 * U fisubs (%ecx) # CHECK-NEXT: 3 13 2.00 * U fisubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubr %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubr %st(2), %st # CHECK-NEXT: 2 10 1.00 * U fsubrs (%ecx) # CHECK-NEXT: 2 10 1.00 * U fsubrl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(2) # CHECK-NEXT: 3 13 2.00 * U fisubrs (%ecx) # CHECK-NEXT: 3 13 2.00 * U fisubrl (%eax) # CHECK-NEXT: 1 2 1.00 U ftst @@ -343,8 +343,8 @@ fyl2xp1 # CHECK-NEXT: 1 1 1.00 U fucomp %st(1) # CHECK-NEXT: 1 1 1.00 U fucomp %st(3) # CHECK-NEXT: 1 2 1.00 U fucompp -# CHECK-NEXT: 1 2 1.00 U fucomi %st(3) -# CHECK-NEXT: 1 2 1.00 U fucompi %st(3) +# CHECK-NEXT: 1 2 1.00 U fucomi %st(3), %st +# CHECK-NEXT: 1 2 1.00 U fucompi %st(3), %st # CHECK-NEXT: 2 2 0.50 U wait # CHECK-NEXT: 1 100 0.25 U fxam # CHECK-NEXT: 15 17 4.00 U fxch %st(1) @@ -375,26 +375,26 @@ fyl2xp1 # CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] Instructions: # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - f2xm1 # CHECK-NEXT: - - 1.00 - - - - - - - fabs -# CHECK-NEXT: - - - - - - - 1.00 - - fadd %st(0), %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - fadd %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - fadd %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - fadd %st(2), %st # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - fadds (%ecx) # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - faddl (%ecx) -# CHECK-NEXT: - - - - - - - 1.00 - - faddp %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - faddp %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - faddp %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - faddp %st, %st(2) # CHECK-NEXT: - - - - 0.50 0.50 - 2.00 - - fiadds (%ecx) # CHECK-NEXT: - - - - 0.50 0.50 - 2.00 - - fiaddl (%ecx) # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - fbld (%ecx) # CHECK-NEXT: - - - - 0.33 0.33 1.00 - - 0.33 fbstp (%eax) # CHECK-NEXT: - - 1.00 - - - - - - - fchs # CHECK-NEXT: - - 1.00 1.00 - - - 1.00 1.00 - fnclex -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovb %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovbe %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmove %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnb %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnbe %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovne %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnu %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovu %st(1), %st(0) +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovb %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovbe %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmove %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnb %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnbe %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovne %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnu %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovu %st(1), %st # CHECK-NEXT: - - - - - - - 1.00 - - fcom %st(1) # CHECK-NEXT: - - - - - - - 1.00 - - fcom %st(3) # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - fcoms (%ecx) @@ -404,24 +404,24 @@ fyl2xp1 # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - fcomps (%ecx) # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - fcompl (%eax) # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - fcompp -# CHECK-NEXT: - - 1.00 - - - - - - - fcomi %st(3) -# CHECK-NEXT: - - 1.00 - - - - - - - fcompi %st(3) +# CHECK-NEXT: - - 1.00 - - - - - - - fcomi %st(3), %st +# CHECK-NEXT: - - 1.00 - - - - - - - fcompi %st(3), %st # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - fcos # CHECK-NEXT: - - 1.00 - - - - 1.00 - - fdecstp -# CHECK-NEXT: - - 1.00 - - - - - - - fdiv %st(0), %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fdiv %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fdiv %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fdiv %st(2), %st # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fdivs (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fdivl (%eax) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivp %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivp %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivp %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivp %st, %st(2) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - 1.00 - - fidivs (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - 1.00 - - fidivl (%eax) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivr %st(0), %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivr %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivr %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivr %st(2), %st # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fdivrs (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fdivrl (%eax) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivrp %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivrp %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivrp %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivrp %st, %st(2) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - 1.00 - - fidivrs (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - 1.00 - - fidivrl (%eax) # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - ffree %st(0) @@ -455,12 +455,12 @@ fyl2xp1 # CHECK-NEXT: - - 1.00 - - - - 1.00 - - fldln2 # CHECK-NEXT: - - 1.00 - - - - 1.00 - - fldpi # CHECK-NEXT: - - 0.50 - - - - 0.50 - - fldz -# CHECK-NEXT: - - 1.00 - - - - - - - fmul %st(0), %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fmul %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fmul %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fmul %st(2), %st # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fmuls (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fmull (%eax) -# CHECK-NEXT: - - 1.00 - - - - - - - fmulp %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fmulp %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fmulp %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fmulp %st, %st(2) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - 1.00 - - fimuls (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - 1.00 - - fimull (%eax) # CHECK-NEXT: - - 0.50 - - - - 0.50 - - fnop @@ -488,20 +488,20 @@ fyl2xp1 # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - frstor (%eax) # CHECK-NEXT: - - 0.50 0.50 - - - 0.50 0.50 - wait # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - fnsave (%eax) -# CHECK-NEXT: - - - - - - - 1.00 - - fsub %st(0), %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - fsub %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - fsub %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - fsub %st(2), %st # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - fsubs (%ecx) # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - fsubl (%eax) -# CHECK-NEXT: - - - - - - - 1.00 - - fsubp %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - fsubp %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - fsubp %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - fsubp %st, %st(2) # CHECK-NEXT: - - - - 0.50 0.50 - 2.00 - - fisubs (%ecx) # CHECK-NEXT: - - - - 0.50 0.50 - 2.00 - - fisubl (%eax) -# CHECK-NEXT: - - - - - - - 1.00 - - fsubr %st(0), %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - fsubr %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - fsubr %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - fsubr %st(2), %st # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - fsubrs (%ecx) # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - fsubrl (%eax) -# CHECK-NEXT: - - - - - - - 1.00 - - fsubrp %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - fsubrp %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - fsubrp %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - fsubrp %st, %st(2) # CHECK-NEXT: - - - - 0.50 0.50 - 2.00 - - fisubrs (%ecx) # CHECK-NEXT: - - - - 0.50 0.50 - 2.00 - - fisubrl (%eax) # CHECK-NEXT: - - 1.00 - - - - - - - ftst @@ -510,8 +510,8 @@ fyl2xp1 # CHECK-NEXT: - - - - - - - 1.00 - - fucomp %st(1) # CHECK-NEXT: - - - - - - - 1.00 - - fucomp %st(3) # CHECK-NEXT: - - 1.00 - - - - - - - fucompp -# CHECK-NEXT: - - 1.00 - - - - - - - fucomi %st(3) -# CHECK-NEXT: - - 1.00 - - - - - - - fucompi %st(3) +# CHECK-NEXT: - - 1.00 - - - - - - - fucomi %st(3), %st +# CHECK-NEXT: - - 1.00 - - - - - - - fucompi %st(3), %st # CHECK-NEXT: - - 0.50 0.50 - - - 0.50 0.50 - wait # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - fxam # CHECK-NEXT: - - 4.00 2.00 - - - 4.00 5.00 - fxch %st(1) diff --git a/llvm/test/tools/llvm-mca/X86/SkylakeServer/resources-x87.s b/llvm/test/tools/llvm-mca/X86/SkylakeServer/resources-x87.s index aecb4a7ab9211..75cca5297704b 100644 --- a/llvm/test/tools/llvm-mca/X86/SkylakeServer/resources-x87.s +++ b/llvm/test/tools/llvm-mca/X86/SkylakeServer/resources-x87.s @@ -5,7 +5,7 @@ f2xm1 fabs -fadd %st(0), %st(1) +fadd %st, %st(1) fadd %st(2) fadds (%ecx) faddl (%ecx) @@ -21,14 +21,14 @@ fchs fnclex -fcmovb %st(1), %st(0) -fcmovbe %st(1), %st(0) -fcmove %st(1), %st(0) -fcmovnb %st(1), %st(0) -fcmovnbe %st(1), %st(0) -fcmovne %st(1), %st(0) -fcmovnu %st(1), %st(0) -fcmovu %st(1), %st(0) +fcmovb %st(1), %st +fcmovbe %st(1), %st +fcmove %st(1), %st +fcmovnb %st(1), %st +fcmovnbe %st(1), %st +fcmovne %st(1), %st +fcmovnu %st(1), %st +fcmovu %st(1), %st fcom %st(1) fcom %st(3) @@ -47,7 +47,7 @@ fcos fdecstp -fdiv %st(0), %st(1) +fdiv %st, %st(1) fdiv %st(2) fdivs (%ecx) fdivl (%eax) @@ -56,7 +56,7 @@ fdivp %st(2) fidivs (%ecx) fidivl (%eax) -fdivr %st(0), %st(1) +fdivr %st, %st(1) fdivr %st(2) fdivrs (%ecx) fdivrl (%eax) @@ -106,7 +106,7 @@ fldln2 fldpi fldz -fmul %st(0), %st(1) +fmul %st, %st(1) fmul %st(2) fmuls (%ecx) fmull (%eax) @@ -153,7 +153,7 @@ fnstsw (%eax) frstor (%eax) fsave (%eax) -fsub %st(0), %st(1) +fsub %st, %st(1) fsub %st(2) fsubs (%ecx) fsubl (%eax) @@ -162,7 +162,7 @@ fsubp %st(2) fisubs (%ecx) fisubl (%eax) -fsubr %st(0), %st(1) +fsubr %st, %st(1) fsubr %st(2) fsubrs (%ecx) fsubrl (%eax) @@ -208,26 +208,26 @@ fyl2xp1 # CHECK: [1] [2] [3] [4] [5] [6] Instructions: # CHECK-NEXT: 1 100 0.25 U f2xm1 # CHECK-NEXT: 1 1 1.00 U fabs -# CHECK-NEXT: 1 3 1.00 U fadd %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fadd %st(2) +# CHECK-NEXT: 1 3 1.00 U fadd %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fadd %st(2), %st # CHECK-NEXT: 2 10 1.00 * U fadds (%ecx) # CHECK-NEXT: 2 10 1.00 * U faddl (%ecx) -# CHECK-NEXT: 1 3 1.00 U faddp %st(1) -# CHECK-NEXT: 1 3 1.00 U faddp %st(2) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(2) # CHECK-NEXT: 3 13 2.00 * U fiadds (%ecx) # CHECK-NEXT: 3 13 2.00 * U fiaddl (%ecx) # CHECK-NEXT: 1 100 0.25 U fbld (%ecx) # CHECK-NEXT: 2 1 1.00 U fbstp (%eax) # CHECK-NEXT: 1 1 1.00 U fchs # CHECK-NEXT: 4 4 1.00 U fnclex -# CHECK-NEXT: 1 3 1.00 U fcmovb %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovbe %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmove %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnb %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnbe %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovne %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovnu %st(1), %st(0) -# CHECK-NEXT: 1 3 1.00 U fcmovu %st(1), %st(0) +# CHECK-NEXT: 1 3 1.00 U fcmovb %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovbe %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmove %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnb %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnbe %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovne %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovnu %st(1), %st +# CHECK-NEXT: 1 3 1.00 U fcmovu %st(1), %st # CHECK-NEXT: 1 1 1.00 U fcom %st(1) # CHECK-NEXT: 1 1 1.00 U fcom %st(3) # CHECK-NEXT: 2 8 1.00 U fcoms (%ecx) @@ -237,24 +237,24 @@ fyl2xp1 # CHECK-NEXT: 2 8 1.00 U fcomps (%ecx) # CHECK-NEXT: 2 8 1.00 U fcompl (%eax) # CHECK-NEXT: 1 100 0.25 U fcompp -# CHECK-NEXT: 1 2 1.00 U fcomi %st(3) -# CHECK-NEXT: 1 2 1.00 U fcompi %st(3) +# CHECK-NEXT: 1 2 1.00 U fcomi %st(3), %st +# CHECK-NEXT: 1 2 1.00 U fcompi %st(3), %st # CHECK-NEXT: 1 100 0.25 U fcos # CHECK-NEXT: 2 2 1.00 U fdecstp -# CHECK-NEXT: 1 15 1.00 U fdiv %st(0), %st(1) -# CHECK-NEXT: 1 20 1.00 U fdiv %st(2) +# CHECK-NEXT: 1 15 1.00 U fdiv %st, %st(1) +# CHECK-NEXT: 1 20 1.00 U fdiv %st(2), %st # CHECK-NEXT: 2 22 1.00 * U fdivs (%ecx) # CHECK-NEXT: 2 22 1.00 * U fdivl (%eax) -# CHECK-NEXT: 1 15 1.00 U fdivp %st(1) -# CHECK-NEXT: 1 15 1.00 U fdivp %st(2) +# CHECK-NEXT: 1 15 1.00 U fdivp %st, %st(1) +# CHECK-NEXT: 1 15 1.00 U fdivp %st, %st(2) # CHECK-NEXT: 3 25 1.00 * U fidivs (%ecx) # CHECK-NEXT: 3 25 1.00 * U fidivl (%eax) -# CHECK-NEXT: 1 20 1.00 U fdivr %st(0), %st(1) -# CHECK-NEXT: 1 15 1.00 U fdivr %st(2) +# CHECK-NEXT: 1 20 1.00 U fdivr %st, %st(1) +# CHECK-NEXT: 1 15 1.00 U fdivr %st(2), %st # CHECK-NEXT: 2 27 1.00 * U fdivrs (%ecx) # CHECK-NEXT: 2 27 1.00 * U fdivrl (%eax) -# CHECK-NEXT: 1 20 1.00 U fdivrp %st(1) -# CHECK-NEXT: 1 20 1.00 U fdivrp %st(2) +# CHECK-NEXT: 1 20 1.00 U fdivrp %st, %st(1) +# CHECK-NEXT: 1 20 1.00 U fdivrp %st, %st(2) # CHECK-NEXT: 3 30 1.00 * U fidivrs (%ecx) # CHECK-NEXT: 3 30 1.00 * U fidivrl (%eax) # CHECK-NEXT: 1 100 0.25 U ffree %st(0) @@ -288,12 +288,12 @@ fyl2xp1 # CHECK-NEXT: 2 1 1.00 U fldln2 # CHECK-NEXT: 2 1 1.00 U fldpi # CHECK-NEXT: 1 1 0.50 U fldz -# CHECK-NEXT: 1 4 1.00 U fmul %st(0), %st(1) -# CHECK-NEXT: 1 4 1.00 U fmul %st(2) +# CHECK-NEXT: 1 4 1.00 U fmul %st, %st(1) +# CHECK-NEXT: 1 4 1.00 U fmul %st(2), %st # CHECK-NEXT: 2 11 1.00 * U fmuls (%ecx) # CHECK-NEXT: 2 11 1.00 * U fmull (%eax) -# CHECK-NEXT: 1 4 1.00 U fmulp %st(1) -# CHECK-NEXT: 1 4 1.00 U fmulp %st(2) +# CHECK-NEXT: 1 4 1.00 U fmulp %st, %st(1) +# CHECK-NEXT: 1 4 1.00 U fmulp %st, %st(2) # CHECK-NEXT: 3 14 1.00 * U fimuls (%ecx) # CHECK-NEXT: 3 14 1.00 * U fimull (%eax) # CHECK-NEXT: 1 1 0.50 U fnop @@ -321,20 +321,20 @@ fyl2xp1 # CHECK-NEXT: 1 100 0.25 U frstor (%eax) # CHECK-NEXT: 2 2 0.50 U wait # CHECK-NEXT: 1 100 0.25 U fnsave (%eax) -# CHECK-NEXT: 1 3 1.00 U fsub %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsub %st(2) +# CHECK-NEXT: 1 3 1.00 U fsub %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsub %st(2), %st # CHECK-NEXT: 2 10 1.00 * U fsubs (%ecx) # CHECK-NEXT: 2 10 1.00 * U fsubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(2) # CHECK-NEXT: 3 13 2.00 * U fisubs (%ecx) # CHECK-NEXT: 3 13 2.00 * U fisubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubr %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubr %st(2), %st # CHECK-NEXT: 2 10 1.00 * U fsubrs (%ecx) # CHECK-NEXT: 2 10 1.00 * U fsubrl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(2) # CHECK-NEXT: 3 13 2.00 * U fisubrs (%ecx) # CHECK-NEXT: 3 13 2.00 * U fisubrl (%eax) # CHECK-NEXT: 1 2 1.00 U ftst @@ -343,8 +343,8 @@ fyl2xp1 # CHECK-NEXT: 1 1 1.00 U fucomp %st(1) # CHECK-NEXT: 1 1 1.00 U fucomp %st(3) # CHECK-NEXT: 1 2 1.00 U fucompp -# CHECK-NEXT: 1 2 1.00 U fucomi %st(3) -# CHECK-NEXT: 1 2 1.00 U fucompi %st(3) +# CHECK-NEXT: 1 2 1.00 U fucomi %st(3), %st +# CHECK-NEXT: 1 2 1.00 U fucompi %st(3), %st # CHECK-NEXT: 2 2 0.50 U wait # CHECK-NEXT: 1 100 0.25 U fxam # CHECK-NEXT: 15 17 4.00 U fxch %st(1) @@ -375,26 +375,26 @@ fyl2xp1 # CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] Instructions: # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - f2xm1 # CHECK-NEXT: - - 1.00 - - - - - - - fabs -# CHECK-NEXT: - - - - - - - 1.00 - - fadd %st(0), %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - fadd %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - fadd %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - fadd %st(2), %st # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - fadds (%ecx) # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - faddl (%ecx) -# CHECK-NEXT: - - - - - - - 1.00 - - faddp %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - faddp %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - faddp %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - faddp %st, %st(2) # CHECK-NEXT: - - - - 0.50 0.50 - 2.00 - - fiadds (%ecx) # CHECK-NEXT: - - - - 0.50 0.50 - 2.00 - - fiaddl (%ecx) # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - fbld (%ecx) # CHECK-NEXT: - - - - 0.33 0.33 1.00 - - 0.33 fbstp (%eax) # CHECK-NEXT: - - 1.00 - - - - - - - fchs # CHECK-NEXT: - - 1.00 1.00 - - - 1.00 1.00 - fnclex -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovb %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovbe %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmove %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnb %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnbe %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovne %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnu %st(1), %st(0) -# CHECK-NEXT: - - - 1.00 - - - - - - fcmovu %st(1), %st(0) +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovb %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovbe %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmove %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnb %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnbe %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovne %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovnu %st(1), %st +# CHECK-NEXT: - - - 1.00 - - - - - - fcmovu %st(1), %st # CHECK-NEXT: - - - - - - - 1.00 - - fcom %st(1) # CHECK-NEXT: - - - - - - - 1.00 - - fcom %st(3) # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - fcoms (%ecx) @@ -404,24 +404,24 @@ fyl2xp1 # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - fcomps (%ecx) # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - fcompl (%eax) # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - fcompp -# CHECK-NEXT: - - 1.00 - - - - - - - fcomi %st(3) -# CHECK-NEXT: - - 1.00 - - - - - - - fcompi %st(3) +# CHECK-NEXT: - - 1.00 - - - - - - - fcomi %st(3), %st +# CHECK-NEXT: - - 1.00 - - - - - - - fcompi %st(3), %st # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - fcos # CHECK-NEXT: - - 1.00 - - - - 1.00 - - fdecstp -# CHECK-NEXT: - - 1.00 - - - - - - - fdiv %st(0), %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fdiv %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fdiv %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fdiv %st(2), %st # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fdivs (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fdivl (%eax) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivp %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivp %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivp %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivp %st, %st(2) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - 1.00 - - fidivs (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - 1.00 - - fidivl (%eax) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivr %st(0), %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivr %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivr %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivr %st(2), %st # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fdivrs (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fdivrl (%eax) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivrp %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fdivrp %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivrp %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fdivrp %st, %st(2) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - 1.00 - - fidivrs (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - 1.00 - - fidivrl (%eax) # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - ffree %st(0) @@ -455,12 +455,12 @@ fyl2xp1 # CHECK-NEXT: - - 1.00 - - - - 1.00 - - fldln2 # CHECK-NEXT: - - 1.00 - - - - 1.00 - - fldpi # CHECK-NEXT: - - 0.50 - - - - 0.50 - - fldz -# CHECK-NEXT: - - 1.00 - - - - - - - fmul %st(0), %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fmul %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fmul %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fmul %st(2), %st # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fmuls (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - - - - fmull (%eax) -# CHECK-NEXT: - - 1.00 - - - - - - - fmulp %st(1) -# CHECK-NEXT: - - 1.00 - - - - - - - fmulp %st(2) +# CHECK-NEXT: - - 1.00 - - - - - - - fmulp %st, %st(1) +# CHECK-NEXT: - - 1.00 - - - - - - - fmulp %st, %st(2) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - 1.00 - - fimuls (%ecx) # CHECK-NEXT: - - 1.00 - 0.50 0.50 - 1.00 - - fimull (%eax) # CHECK-NEXT: - - 0.50 - - - - 0.50 - - fnop @@ -488,20 +488,20 @@ fyl2xp1 # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - frstor (%eax) # CHECK-NEXT: - - 0.50 0.50 - - - 0.50 0.50 - wait # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - fnsave (%eax) -# CHECK-NEXT: - - - - - - - 1.00 - - fsub %st(0), %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - fsub %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - fsub %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - fsub %st(2), %st # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - fsubs (%ecx) # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - fsubl (%eax) -# CHECK-NEXT: - - - - - - - 1.00 - - fsubp %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - fsubp %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - fsubp %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - fsubp %st, %st(2) # CHECK-NEXT: - - - - 0.50 0.50 - 2.00 - - fisubs (%ecx) # CHECK-NEXT: - - - - 0.50 0.50 - 2.00 - - fisubl (%eax) -# CHECK-NEXT: - - - - - - - 1.00 - - fsubr %st(0), %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - fsubr %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - fsubr %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - fsubr %st(2), %st # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - fsubrs (%ecx) # CHECK-NEXT: - - - - 0.50 0.50 - 1.00 - - fsubrl (%eax) -# CHECK-NEXT: - - - - - - - 1.00 - - fsubrp %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - fsubrp %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - fsubrp %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - fsubrp %st, %st(2) # CHECK-NEXT: - - - - 0.50 0.50 - 2.00 - - fisubrs (%ecx) # CHECK-NEXT: - - - - 0.50 0.50 - 2.00 - - fisubrl (%eax) # CHECK-NEXT: - - 1.00 - - - - - - - ftst @@ -510,8 +510,8 @@ fyl2xp1 # CHECK-NEXT: - - - - - - - 1.00 - - fucomp %st(1) # CHECK-NEXT: - - - - - - - 1.00 - - fucomp %st(3) # CHECK-NEXT: - - 1.00 - - - - - - - fucompp -# CHECK-NEXT: - - 1.00 - - - - - - - fucomi %st(3) -# CHECK-NEXT: - - 1.00 - - - - - - - fucompi %st(3) +# CHECK-NEXT: - - 1.00 - - - - - - - fucomi %st(3), %st +# CHECK-NEXT: - - 1.00 - - - - - - - fucompi %st(3), %st # CHECK-NEXT: - - 0.50 0.50 - - - 0.50 0.50 - wait # CHECK-NEXT: - - 0.25 0.25 - - - 0.25 0.25 - fxam # CHECK-NEXT: - - 4.00 2.00 - - - 4.00 5.00 - fxch %st(1) diff --git a/llvm/test/tools/llvm-mca/X86/Znver1/resources-x87.s b/llvm/test/tools/llvm-mca/X86/Znver1/resources-x87.s index 2f5f6ef08f1c7..030b71fb7b63f 100644 --- a/llvm/test/tools/llvm-mca/X86/Znver1/resources-x87.s +++ b/llvm/test/tools/llvm-mca/X86/Znver1/resources-x87.s @@ -5,7 +5,7 @@ f2xm1 fabs -fadd %st(0), %st(1) +fadd %st, %st(1) fadd %st(2) fadds (%ecx) faddl (%ecx) @@ -21,14 +21,14 @@ fchs fnclex -fcmovb %st(1), %st(0) -fcmovbe %st(1), %st(0) -fcmove %st(1), %st(0) -fcmovnb %st(1), %st(0) -fcmovnbe %st(1), %st(0) -fcmovne %st(1), %st(0) -fcmovnu %st(1), %st(0) -fcmovu %st(1), %st(0) +fcmovb %st(1), %st +fcmovbe %st(1), %st +fcmove %st(1), %st +fcmovnb %st(1), %st +fcmovnbe %st(1), %st +fcmovne %st(1), %st +fcmovnu %st(1), %st +fcmovu %st(1), %st fcom %st(1) fcom %st(3) @@ -47,7 +47,7 @@ fcos fdecstp -fdiv %st(0), %st(1) +fdiv %st, %st(1) fdiv %st(2) fdivs (%ecx) fdivl (%eax) @@ -56,7 +56,7 @@ fdivp %st(2) fidivs (%ecx) fidivl (%eax) -fdivr %st(0), %st(1) +fdivr %st, %st(1) fdivr %st(2) fdivrs (%ecx) fdivrl (%eax) @@ -106,7 +106,7 @@ fldln2 fldpi fldz -fmul %st(0), %st(1) +fmul %st, %st(1) fmul %st(2) fmuls (%ecx) fmull (%eax) @@ -153,7 +153,7 @@ fnstsw (%eax) frstor (%eax) fsave (%eax) -fsub %st(0), %st(1) +fsub %st, %st(1) fsub %st(2) fsubs (%ecx) fsubl (%eax) @@ -162,7 +162,7 @@ fsubp %st(2) fisubs (%ecx) fisubl (%eax) -fsubr %st(0), %st(1) +fsubr %st, %st(1) fsubr %st(2) fsubrs (%ecx) fsubrl (%eax) @@ -208,26 +208,26 @@ fyl2xp1 # CHECK: [1] [2] [3] [4] [5] [6] Instructions: # CHECK-NEXT: 1 100 0.25 U f2xm1 # CHECK-NEXT: 1 2 1.00 U fabs -# CHECK-NEXT: 1 3 1.00 U fadd %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fadd %st(2) +# CHECK-NEXT: 1 3 1.00 U fadd %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fadd %st(2), %st # CHECK-NEXT: 1 10 1.00 * U fadds (%ecx) # CHECK-NEXT: 1 10 1.00 * U faddl (%ecx) -# CHECK-NEXT: 1 3 1.00 U faddp %st(1) -# CHECK-NEXT: 1 3 1.00 U faddp %st(2) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U faddp %st, %st(2) # CHECK-NEXT: 1 10 1.00 * U fiadds (%ecx) # CHECK-NEXT: 1 10 1.00 * U fiaddl (%ecx) # CHECK-NEXT: 1 100 0.25 U fbld (%ecx) # CHECK-NEXT: 1 100 0.25 U fbstp (%eax) # CHECK-NEXT: 1 1 1.00 U fchs # CHECK-NEXT: 1 100 0.25 U fnclex -# CHECK-NEXT: 1 100 0.25 U fcmovb %st(1), %st(0) -# CHECK-NEXT: 1 100 0.25 U fcmovbe %st(1), %st(0) -# CHECK-NEXT: 1 100 0.25 U fcmove %st(1), %st(0) -# CHECK-NEXT: 1 100 0.25 U fcmovnb %st(1), %st(0) -# CHECK-NEXT: 1 100 0.25 U fcmovnbe %st(1), %st(0) -# CHECK-NEXT: 1 100 0.25 U fcmovne %st(1), %st(0) -# CHECK-NEXT: 1 100 0.25 U fcmovnu %st(1), %st(0) -# CHECK-NEXT: 1 100 0.25 U fcmovu %st(1), %st(0) +# CHECK-NEXT: 1 100 0.25 U fcmovb %st(1), %st +# CHECK-NEXT: 1 100 0.25 U fcmovbe %st(1), %st +# CHECK-NEXT: 1 100 0.25 U fcmove %st(1), %st +# CHECK-NEXT: 1 100 0.25 U fcmovnb %st(1), %st +# CHECK-NEXT: 1 100 0.25 U fcmovnbe %st(1), %st +# CHECK-NEXT: 1 100 0.25 U fcmovne %st(1), %st +# CHECK-NEXT: 1 100 0.25 U fcmovnu %st(1), %st +# CHECK-NEXT: 1 100 0.25 U fcmovu %st(1), %st # CHECK-NEXT: 1 1 1.00 U fcom %st(1) # CHECK-NEXT: 1 1 1.00 U fcom %st(3) # CHECK-NEXT: 1 8 1.00 U fcoms (%ecx) @@ -237,24 +237,24 @@ fyl2xp1 # CHECK-NEXT: 1 8 1.00 U fcomps (%ecx) # CHECK-NEXT: 1 8 1.00 U fcompl (%eax) # CHECK-NEXT: 1 1 1.00 U fcompp -# CHECK-NEXT: 1 9 0.50 U fcomi %st(3) -# CHECK-NEXT: 1 9 0.50 U fcompi %st(3) +# CHECK-NEXT: 1 9 0.50 U fcomi %st(3), %st +# CHECK-NEXT: 1 9 0.50 U fcompi %st(3), %st # CHECK-NEXT: 1 100 0.25 U fcos # CHECK-NEXT: 1 11 1.00 U fdecstp -# CHECK-NEXT: 1 15 1.00 U fdiv %st(0), %st(1) -# CHECK-NEXT: 1 15 1.00 U fdiv %st(2) +# CHECK-NEXT: 1 15 1.00 U fdiv %st, %st(1) +# CHECK-NEXT: 1 15 1.00 U fdiv %st(2), %st # CHECK-NEXT: 1 22 1.00 * U fdivs (%ecx) # CHECK-NEXT: 1 22 1.00 * U fdivl (%eax) -# CHECK-NEXT: 1 15 1.00 U fdivp %st(1) -# CHECK-NEXT: 1 15 1.00 U fdivp %st(2) +# CHECK-NEXT: 1 15 1.00 U fdivp %st, %st(1) +# CHECK-NEXT: 1 15 1.00 U fdivp %st, %st(2) # CHECK-NEXT: 1 22 1.00 * U fidivs (%ecx) # CHECK-NEXT: 1 22 1.00 * U fidivl (%eax) -# CHECK-NEXT: 1 15 1.00 U fdivr %st(0), %st(1) -# CHECK-NEXT: 1 15 1.00 U fdivr %st(2) +# CHECK-NEXT: 1 15 1.00 U fdivr %st, %st(1) +# CHECK-NEXT: 1 15 1.00 U fdivr %st(2), %st # CHECK-NEXT: 1 22 1.00 * U fdivrs (%ecx) # CHECK-NEXT: 1 22 1.00 * U fdivrl (%eax) -# CHECK-NEXT: 1 15 1.00 U fdivrp %st(1) -# CHECK-NEXT: 1 15 1.00 U fdivrp %st(2) +# CHECK-NEXT: 1 15 1.00 U fdivrp %st, %st(1) +# CHECK-NEXT: 1 15 1.00 U fdivrp %st, %st(2) # CHECK-NEXT: 1 22 1.00 * U fidivrs (%ecx) # CHECK-NEXT: 1 22 1.00 * U fidivrl (%eax) # CHECK-NEXT: 1 11 1.00 U ffree %st(0) @@ -288,12 +288,12 @@ fyl2xp1 # CHECK-NEXT: 1 11 1.00 U fldln2 # CHECK-NEXT: 1 11 1.00 U fldpi # CHECK-NEXT: 1 8 0.50 U fldz -# CHECK-NEXT: 1 3 0.50 U fmul %st(0), %st(1) -# CHECK-NEXT: 1 3 0.50 U fmul %st(2) +# CHECK-NEXT: 1 3 0.50 U fmul %st, %st(1) +# CHECK-NEXT: 1 3 0.50 U fmul %st(2), %st # CHECK-NEXT: 2 10 0.50 * U fmuls (%ecx) # CHECK-NEXT: 2 10 0.50 * U fmull (%eax) -# CHECK-NEXT: 1 3 0.50 U fmulp %st(1) -# CHECK-NEXT: 1 3 0.50 U fmulp %st(2) +# CHECK-NEXT: 1 3 0.50 U fmulp %st, %st(1) +# CHECK-NEXT: 1 3 0.50 U fmulp %st, %st(2) # CHECK-NEXT: 2 10 0.50 * U fimuls (%ecx) # CHECK-NEXT: 2 10 0.50 * U fimull (%eax) # CHECK-NEXT: 1 1 1.00 U fnop @@ -321,20 +321,20 @@ fyl2xp1 # CHECK-NEXT: 1 100 0.25 U frstor (%eax) # CHECK-NEXT: 1 1 1.00 U wait # CHECK-NEXT: 1 100 0.25 U fnsave (%eax) -# CHECK-NEXT: 1 3 1.00 U fsub %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsub %st(2) +# CHECK-NEXT: 1 3 1.00 U fsub %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsub %st(2), %st # CHECK-NEXT: 1 10 1.00 * U fsubs (%ecx) # CHECK-NEXT: 1 10 1.00 * U fsubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubp %st, %st(2) # CHECK-NEXT: 1 10 1.00 * U fisubs (%ecx) # CHECK-NEXT: 1 10 1.00 * U fisubl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(0), %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubr %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubr %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubr %st(2), %st # CHECK-NEXT: 1 10 1.00 * U fsubrs (%ecx) # CHECK-NEXT: 1 10 1.00 * U fsubrl (%eax) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(1) -# CHECK-NEXT: 1 3 1.00 U fsubrp %st(2) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(1) +# CHECK-NEXT: 1 3 1.00 U fsubrp %st, %st(2) # CHECK-NEXT: 1 10 1.00 * U fisubrs (%ecx) # CHECK-NEXT: 1 10 1.00 * U fisubrl (%eax) # CHECK-NEXT: 1 1 1.00 U ftst @@ -343,8 +343,8 @@ fyl2xp1 # CHECK-NEXT: 1 1 1.00 U fucomp %st(1) # CHECK-NEXT: 1 1 1.00 U fucomp %st(3) # CHECK-NEXT: 1 1 1.00 U fucompp -# CHECK-NEXT: 1 9 0.50 U fucomi %st(3) -# CHECK-NEXT: 1 9 0.50 U fucompi %st(3) +# CHECK-NEXT: 1 9 0.50 U fucomi %st(3), %st +# CHECK-NEXT: 1 9 0.50 U fucompi %st(3), %st # CHECK-NEXT: 1 1 1.00 U wait # CHECK-NEXT: 1 1 1.00 U fxam # CHECK-NEXT: 1 1 0.25 U fxch %st(1) @@ -377,26 +377,26 @@ fyl2xp1 # CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] Instructions: # CHECK-NEXT: - - - - - - - - - - - - f2xm1 # CHECK-NEXT: - - - - - - - - - - 1.00 - fabs -# CHECK-NEXT: - - - - - - - 1.00 - - - - fadd %st(0), %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - - - fadd %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - - - fadd %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - - - fadd %st(2), %st # CHECK-NEXT: 0.50 0.50 - - - - - 1.00 - - - - fadds (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - 1.00 - - - - faddl (%ecx) -# CHECK-NEXT: - - - - - - - 1.00 - - - - faddp %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - - - faddp %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - - - faddp %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - - - faddp %st, %st(2) # CHECK-NEXT: 0.50 0.50 - - - - - 1.00 - - - - fiadds (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - 1.00 - - - - fiaddl (%ecx) # CHECK-NEXT: - - - - - - - - - - - - fbld (%ecx) # CHECK-NEXT: - - - - - - - - - - - - fbstp (%eax) # CHECK-NEXT: - - - - - - - - - - 1.00 - fchs # CHECK-NEXT: - - - - - - - - - - - - fnclex -# CHECK-NEXT: - - - - - - - - - - - - fcmovb %st(1), %st(0) -# CHECK-NEXT: - - - - - - - - - - - - fcmovbe %st(1), %st(0) -# CHECK-NEXT: - - - - - - - - - - - - fcmove %st(1), %st(0) -# CHECK-NEXT: - - - - - - - - - - - - fcmovnb %st(1), %st(0) -# CHECK-NEXT: - - - - - - - - - - - - fcmovnbe %st(1), %st(0) -# CHECK-NEXT: - - - - - - - - - - - - fcmovne %st(1), %st(0) -# CHECK-NEXT: - - - - - - - - - - - - fcmovnu %st(1), %st(0) -# CHECK-NEXT: - - - - - - - - - - - - fcmovu %st(1), %st(0) +# CHECK-NEXT: - - - - - - - - - - - - fcmovb %st(1), %st +# CHECK-NEXT: - - - - - - - - - - - - fcmovbe %st(1), %st +# CHECK-NEXT: - - - - - - - - - - - - fcmove %st(1), %st +# CHECK-NEXT: - - - - - - - - - - - - fcmovnb %st(1), %st +# CHECK-NEXT: - - - - - - - - - - - - fcmovnbe %st(1), %st +# CHECK-NEXT: - - - - - - - - - - - - fcmovne %st(1), %st +# CHECK-NEXT: - - - - - - - - - - - - fcmovnu %st(1), %st +# CHECK-NEXT: - - - - - - - - - - - - fcmovu %st(1), %st # CHECK-NEXT: - - - - - - - 1.00 - - - - fcom %st(1) # CHECK-NEXT: - - - - - - - 1.00 - - - - fcom %st(3) # CHECK-NEXT: 0.50 0.50 - - - - - 1.00 - - - - fcoms (%ecx) @@ -406,24 +406,24 @@ fyl2xp1 # CHECK-NEXT: 0.50 0.50 - - - - - 1.00 - - - - fcomps (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - 1.00 - - - - fcompl (%eax) # CHECK-NEXT: - - - - - - - 1.00 - - - - fcompp -# CHECK-NEXT: 0.50 0.50 - - - - - 0.50 - 0.50 - - fcomi %st(3) -# CHECK-NEXT: 0.50 0.50 - - - - - 0.50 - 0.50 - - fcompi %st(3) +# CHECK-NEXT: 0.50 0.50 - - - - - 0.50 - 0.50 - - fcomi %st(3), %st +# CHECK-NEXT: 0.50 0.50 - - - - - 0.50 - 0.50 - - fcompi %st(3), %st # CHECK-NEXT: - - - - - - - - - - - - fcos # CHECK-NEXT: 0.50 0.50 - - - - - - - - 1.00 - fdecstp -# CHECK-NEXT: - - - - - - - - - - 1.00 - fdiv %st(0), %st(1) -# CHECK-NEXT: - - - - - - - - - - 1.00 - fdiv %st(2) +# CHECK-NEXT: - - - - - - - - - - 1.00 - fdiv %st, %st(1) +# CHECK-NEXT: - - - - - - - - - - 1.00 - fdiv %st(2), %st # CHECK-NEXT: 0.50 0.50 - - - - - - - - 1.00 - fdivs (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - - - 1.00 - fdivl (%eax) -# CHECK-NEXT: - - - - - - - - - - 1.00 - fdivp %st(1) -# CHECK-NEXT: - - - - - - - - - - 1.00 - fdivp %st(2) +# CHECK-NEXT: - - - - - - - - - - 1.00 - fdivp %st, %st(1) +# CHECK-NEXT: - - - - - - - - - - 1.00 - fdivp %st, %st(2) # CHECK-NEXT: 0.50 0.50 - - - - - - - - 1.00 - fidivs (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - - - 1.00 - fidivl (%eax) -# CHECK-NEXT: - - - - - - - - - - 1.00 - fdivr %st(0), %st(1) -# CHECK-NEXT: - - - - - - - - - - 1.00 - fdivr %st(2) +# CHECK-NEXT: - - - - - - - - - - 1.00 - fdivr %st, %st(1) +# CHECK-NEXT: - - - - - - - - - - 1.00 - fdivr %st(2), %st # CHECK-NEXT: 0.50 0.50 - - - - - - - - 1.00 - fdivrs (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - - - 1.00 - fdivrl (%eax) -# CHECK-NEXT: - - - - - - - - - - 1.00 - fdivrp %st(1) -# CHECK-NEXT: - - - - - - - - - - 1.00 - fdivrp %st(2) +# CHECK-NEXT: - - - - - - - - - - 1.00 - fdivrp %st, %st(1) +# CHECK-NEXT: - - - - - - - - - - 1.00 - fdivrp %st, %st(2) # CHECK-NEXT: 0.50 0.50 - - - - - - - - 1.00 - fidivrs (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - - - - 1.00 - fidivrl (%eax) # CHECK-NEXT: 0.50 0.50 - - - - - - - - 1.00 - ffree %st(0) @@ -457,12 +457,12 @@ fyl2xp1 # CHECK-NEXT: 0.50 0.50 - - - - - - - - 1.00 - fldln2 # CHECK-NEXT: 0.50 0.50 - - - - - - - - 1.00 - fldpi # CHECK-NEXT: 0.50 0.50 - - - - - - 0.50 - 0.50 - fldz -# CHECK-NEXT: - - - - - - - 0.50 0.50 - - - fmul %st(0), %st(1) -# CHECK-NEXT: - - - - - - - 0.50 0.50 - - - fmul %st(2) +# CHECK-NEXT: - - - - - - - 0.50 0.50 - - - fmul %st, %st(1) +# CHECK-NEXT: - - - - - - - 0.50 0.50 - - - fmul %st(2), %st # CHECK-NEXT: 0.50 0.50 - - - - - 0.50 0.50 - - - fmuls (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - 0.50 0.50 - - - fmull (%eax) -# CHECK-NEXT: - - - - - - - 0.50 0.50 - - - fmulp %st(1) -# CHECK-NEXT: - - - - - - - 0.50 0.50 - - - fmulp %st(2) +# CHECK-NEXT: - - - - - - - 0.50 0.50 - - - fmulp %st, %st(1) +# CHECK-NEXT: - - - - - - - 0.50 0.50 - - - fmulp %st, %st(2) # CHECK-NEXT: 0.50 0.50 - - - - - 0.50 0.50 - - - fimuls (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - 0.50 0.50 - - - fimull (%eax) # CHECK-NEXT: - - - - - - - 1.00 - - - - fnop @@ -490,20 +490,20 @@ fyl2xp1 # CHECK-NEXT: - - - - - - - - - - - - frstor (%eax) # CHECK-NEXT: - - - - - - - 1.00 - - - - wait # CHECK-NEXT: - - - - - - - - - - - - fnsave (%eax) -# CHECK-NEXT: - - - - - - - 1.00 - - - - fsub %st(0), %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - - - fsub %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - - - fsub %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - - - fsub %st(2), %st # CHECK-NEXT: 0.50 0.50 - - - - - 1.00 - - - - fsubs (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - 1.00 - - - - fsubl (%eax) -# CHECK-NEXT: - - - - - - - 1.00 - - - - fsubp %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - - - fsubp %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - - - fsubp %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - - - fsubp %st, %st(2) # CHECK-NEXT: 0.50 0.50 - - - - - 1.00 - - - - fisubs (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - 1.00 - - - - fisubl (%eax) -# CHECK-NEXT: - - - - - - - 1.00 - - - - fsubr %st(0), %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - - - fsubr %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - - - fsubr %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - - - fsubr %st(2), %st # CHECK-NEXT: 0.50 0.50 - - - - - 1.00 - - - - fsubrs (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - 1.00 - - - - fsubrl (%eax) -# CHECK-NEXT: - - - - - - - 1.00 - - - - fsubrp %st(1) -# CHECK-NEXT: - - - - - - - 1.00 - - - - fsubrp %st(2) +# CHECK-NEXT: - - - - - - - 1.00 - - - - fsubrp %st, %st(1) +# CHECK-NEXT: - - - - - - - 1.00 - - - - fsubrp %st, %st(2) # CHECK-NEXT: 0.50 0.50 - - - - - 1.00 - - - - fisubrs (%ecx) # CHECK-NEXT: 0.50 0.50 - - - - - 1.00 - - - - fisubrl (%eax) # CHECK-NEXT: - - - - - - - 1.00 - - - - ftst @@ -512,8 +512,8 @@ fyl2xp1 # CHECK-NEXT: - - - - - - - 1.00 - - - - fucomp %st(1) # CHECK-NEXT: - - - - - - - 1.00 - - - - fucomp %st(3) # CHECK-NEXT: - - - - - - - 1.00 - - - - fucompp -# CHECK-NEXT: 0.50 0.50 - - - - - 0.50 - 0.50 - - fucomi %st(3) -# CHECK-NEXT: 0.50 0.50 - - - - - 0.50 - 0.50 - - fucompi %st(3) +# CHECK-NEXT: 0.50 0.50 - - - - - 0.50 - 0.50 - - fucomi %st(3), %st +# CHECK-NEXT: 0.50 0.50 - - - - - 0.50 - 0.50 - - fucompi %st(3), %st # CHECK-NEXT: - - - - - - - 1.00 - - - - wait # CHECK-NEXT: - - - - - - - - - - 1.00 - fxam # CHECK-NEXT: - - - - - - - 0.25 0.25 0.25 0.25 - fxch %st(1) diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp index 2f9b428b8cfe8..463609edb73b3 100644 --- a/llvm/utils/TableGen/X86RecognizableInstr.cpp +++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp @@ -842,6 +842,7 @@ OperandType RecognizableInstr::typeFromString(const std::string &s, TYPE("f32mem", TYPE_M) TYPE("ssmem", TYPE_M) TYPE("RST", TYPE_ST) + TYPE("RSTi", TYPE_ST) TYPE("i128mem", TYPE_M) TYPE("i256mem", TYPE_M) TYPE("i512mem", TYPE_M) @@ -964,6 +965,7 @@ OperandEncoding RecognizableInstr::rmRegisterEncodingFromString(const std::string &s, uint8_t OpSize) { ENCODING("RST", ENCODING_FP) + ENCODING("RSTi", ENCODING_FP) ENCODING("GR16", ENCODING_RM) ENCODING("GR32", ENCODING_RM) ENCODING("GR32orGR64", ENCODING_RM) From e5523662b5b2583e592e8e74d0b435e0240adde1 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Feb 2019 10:14:10 +0000 Subject: [PATCH 121/274] Merging r353142: ------------------------------------------------------------------------ r353142 | ctopper | 2019-02-05 07:13:14 +0100 (Tue, 05 Feb 2019) | 13 lines [X86] Change MS inline asm clobber list filter to check for 'fpsr' instead of 'fpsw' after D57641. Summary: The backend used to print the x87 FPSW register as 'fpsw', but gcc inline asm uses 'fpsr'. After D57641, the backend now uses 'fpsr' to match. Reviewers: rnk Reviewed By: rnk Subscribers: eraman, cfe-commits, llvm-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57642 ------------------------------------------------------------------------ llvm-svn: 353819 --- clang/lib/Parse/ParseStmtAsm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Parse/ParseStmtAsm.cpp b/clang/lib/Parse/ParseStmtAsm.cpp index 9b96c5150e569..3f5af7d44f36c 100644 --- a/clang/lib/Parse/ParseStmtAsm.cpp +++ b/clang/lib/Parse/ParseStmtAsm.cpp @@ -637,7 +637,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { // Filter out "fpsw" and "mxcsr". They aren't valid GCC asm clobber // constraints. Clang always adds fpsr to the clobber list anyway. llvm::erase_if(Clobbers, [](const std::string &C) { - return C == "fpsw" || C == "mxcsr"; + return C == "fpsr" || C == "mxcsr"; }); // Build the vector of clobber StringRefs. From 2ccd8c108d13c0dce937be23d5ed563317f2566a Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Feb 2019 10:45:41 +0000 Subject: [PATCH 122/274] Merging r353308 and r353383: ------------------------------------------------------------------------ r353308 | tnorthover | 2019-02-06 16:26:35 +0100 (Wed, 06 Feb 2019) | 5 lines AArch64: enforce even/odd register pairs for CASP instructions. ARMv8.1a CASP instructions need the first of the pair to be an even register (otherwise the encoding is unallocated). We enforced this during assembly, but not CodeGen before. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r353383 | tnorthover | 2019-02-07 11:35:34 +0100 (Thu, 07 Feb 2019) | 4 lines AArch64: implement copy for paired GPR registers. When doing 128-bit atomics using CASP we might need to copy a GPRPair to a different register, but that was unimplemented up to now. ------------------------------------------------------------------------ llvm-svn: 353822 --- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 41 +++++++++++++++++++ llvm/lib/Target/AArch64/AArch64InstrInfo.h | 4 ++ .../lib/Target/AArch64/AArch64RegisterInfo.td | 10 +++-- .../Disassembler/AArch64Disassembler.cpp | 4 +- .../CodeGen/AArch64/cmpxchg-lse-even-regs.ll | 17 ++++++++ llvm/test/CodeGen/AArch64/seqpaircopy.mir | 23 +++++++++++ 6 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/cmpxchg-lse-even-regs.ll create mode 100644 llvm/test/CodeGen/AArch64/seqpaircopy.mir diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index ada0678885729..50316ebe218b7 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -2292,6 +2292,31 @@ void AArch64InstrInfo::copyPhysRegTuple(MachineBasicBlock &MBB, } } +void AArch64InstrInfo::copyGPRRegTuple(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + DebugLoc DL, unsigned DestReg, + unsigned SrcReg, bool KillSrc, + unsigned Opcode, unsigned ZeroReg, + llvm::ArrayRef Indices) const { + const TargetRegisterInfo *TRI = &getRegisterInfo(); + unsigned NumRegs = Indices.size(); + +#ifndef NDEBUG + uint16_t DestEncoding = TRI->getEncodingValue(DestReg); + uint16_t SrcEncoding = TRI->getEncodingValue(SrcReg); + assert(DestEncoding % NumRegs == 0 && SrcEncoding % NumRegs == 0 && + "GPR reg sequences should not be able to overlap"); +#endif + + for (unsigned SubReg = 0; SubReg != NumRegs; ++SubReg) { + const MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opcode)); + AddSubReg(MIB, DestReg, Indices[SubReg], RegState::Define, TRI); + MIB.addReg(ZeroReg); + AddSubReg(MIB, SrcReg, Indices[SubReg], getKillRegState(KillSrc), TRI); + MIB.addImm(0); + } +} + void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DestReg, @@ -2431,6 +2456,22 @@ void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB, return; } + if (AArch64::XSeqPairsClassRegClass.contains(DestReg) && + AArch64::XSeqPairsClassRegClass.contains(SrcReg)) { + static const unsigned Indices[] = {AArch64::sube64, AArch64::subo64}; + copyGPRRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRXrs, + AArch64::XZR, Indices); + return; + } + + if (AArch64::WSeqPairsClassRegClass.contains(DestReg) && + AArch64::WSeqPairsClassRegClass.contains(SrcReg)) { + static const unsigned Indices[] = {AArch64::sube32, AArch64::subo32}; + copyGPRRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRWrs, + AArch64::WZR, Indices); + return; + } + if (AArch64::FPR128RegClass.contains(DestReg) && AArch64::FPR128RegClass.contains(SrcReg)) { if (Subtarget.hasNEON()) { diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h index 9954669d56750..e48c26d4a84a0 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h @@ -122,6 +122,10 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo { const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc, unsigned Opcode, llvm::ArrayRef Indices) const; + void copyGPRRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, + DebugLoc DL, unsigned DestReg, unsigned SrcReg, + bool KillSrc, unsigned Opcode, unsigned ZeroReg, + llvm::ArrayRef Indices) const; void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override; diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td index d3710cea0687e..8e6aa69eae854 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -649,10 +649,12 @@ def FPR128Op : RegisterOperand { // ARMv8.1a atomic CASP register operands -def WSeqPairs : RegisterTuples<[sube32, subo32], - [(rotl GPR32, 0), (rotl GPR32, 1)]>; -def XSeqPairs : RegisterTuples<[sube64, subo64], - [(rotl GPR64, 0), (rotl GPR64, 1)]>; +def WSeqPairs : RegisterTuples<[sube32, subo32], + [(decimate (rotl GPR32, 0), 2), + (decimate (rotl GPR32, 1), 2)]>; +def XSeqPairs : RegisterTuples<[sube64, subo64], + [(decimate (rotl GPR64, 0), 2), + (decimate (rotl GPR64, 1), 2)]>; def WSeqPairsClass : RegisterClass<"AArch64", [untyped], 32, (add WSeqPairs)>{ diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index 4102f1eb5cc12..64afabd450c1f 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -1779,8 +1779,8 @@ static DecodeStatus DecodeGPRSeqPairsClassRegisterClass(MCInst &Inst, if (RegNo & 0x1) return Fail; - unsigned Register = AArch64MCRegisterClasses[RegClassID].getRegister(RegNo); - Inst.addOperand(MCOperand::createReg(Register)); + unsigned Reg = AArch64MCRegisterClasses[RegClassID].getRegister(RegNo / 2); + Inst.addOperand(MCOperand::createReg(Reg)); return Success; } diff --git a/llvm/test/CodeGen/AArch64/cmpxchg-lse-even-regs.ll b/llvm/test/CodeGen/AArch64/cmpxchg-lse-even-regs.ll new file mode 100644 index 0000000000000..9c6d8cc205331 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/cmpxchg-lse-even-regs.ll @@ -0,0 +1,17 @@ +; RUN: llc -mtriple arm64-apple-ios -mattr=+lse %s -o - | FileCheck %s + +; Only "even,even+1" pairs are valid for CASP instructions. Make sure LLVM +; doesn't allocate odd ones and that it can copy them around properly. N.b. we +; don't actually check that they're sequential because FileCheck can't; odd/even +; will have to be good enough. +define void @test_atomic_cmpxchg_i128_register_shuffling(i128* %addr, i128 %desired, i128 %new) nounwind { +; CHECK-LABEL: test_atomic_cmpxchg_i128_register_shuffling: +; CHECK-DAG: mov [[DESIRED_LO:x[0-9]*[02468]]], x1 +; CHECK-DAG: mov [[DESIRED_HI:x[0-9]*[13579]]], x2 +; CHECK-DAG: mov [[NEW_LO:x[0-9]*[02468]]], x3 +; CHECK-DAG: mov [[NEW_HI:x[0-9]*[13579]]], x4 +; CHECK: caspal [[DESIRED_LO]], [[DESIRED_HI]], [[NEW_LO]], [[NEW_HI]], [x0] + + %res = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst + ret void +} diff --git a/llvm/test/CodeGen/AArch64/seqpaircopy.mir b/llvm/test/CodeGen/AArch64/seqpaircopy.mir new file mode 100644 index 0000000000000..89511cbf726bd --- /dev/null +++ b/llvm/test/CodeGen/AArch64/seqpaircopy.mir @@ -0,0 +1,23 @@ +# RUN: llc -o - %s -mtriple=aarch64-- -mattr=+v8.1a -run-pass=postrapseudos | FileCheck %s +--- +# CHECK-LABEL: name: copy_xseqpairs +name: copy_xseqpairs +body: | + bb.0: + ; CHECK: $x4_x5 = CASPALX $x4_x5, $x2_x3, $x0 + ; CHECK: $x0 = ORRXrs $xzr, $x4, 0 + ; CHECK: $x1 = ORRXrs $xzr, $x5, 0 + $x4_x5 = CASPALX $x4_x5, $x2_x3, $x0 + $x0_x1 = COPY $x4_x5 +... +--- +# CHECK-LABEL: name: copy_wseqpairs +name: copy_wseqpairs +body: | + bb.0: + ; CHECK: $w4_w5 = CASPALW $w4_w5, $w2_w3, $x0 + ; CHECK: $w0 = ORRWrs $wzr, $w4, 0 + ; CHECK: $w1 = ORRWrs $wzr, $w5, 0 + $w4_w5 = CASPALW $w4_w5, $w2_w3, $x0 + $w0_w1 = COPY $w4_w5 +... From df368fd7b9b92cf6e4034b6cd4a5313df1c72219 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Feb 2019 10:56:21 +0000 Subject: [PATCH 123/274] Merging r353411: ------------------------------------------------------------------------ r353411 | erichkeane | 2019-02-07 16:14:11 +0100 (Thu, 07 Feb 2019) | 7 lines Fix r350643 to limit COFF emission to <= 32 BYTES instead of BITS. The patch in r350643 incorrectly sets the COFF emission based on bits instead of bytes. This patch converts the 32 via CharUnits to bits to compare the correct values. Change-Id: Icf38a16470ad5ae3531374969c033557ddb0d323 ------------------------------------------------------------------------ llvm-svn: 353825 --- clang/lib/CodeGen/CodeGenModule.cpp | 8 +++++--- clang/test/CodeGen/microsoft-no-common-align.c | 3 +++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 244738042cef0..2ac59fb4de25f 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3762,13 +3762,15 @@ static bool isVarDeclStrongDefinition(const ASTContext &Context, } } - // Microsoft's link.exe doesn't support alignments greater than 32 for common - // symbols, so symbols with greater alignment requirements cannot be common. + // Microsoft's link.exe doesn't support alignments greater than 32 bytes for + // common symbols, so symbols with greater alignment requirements cannot be + // common. // Other COFF linkers (ld.bfd and LLD) support arbitrary power-of-two // alignments for common symbols via the aligncomm directive, so this // restriction only applies to MSVC environments. if (Context.getTargetInfo().getTriple().isKnownWindowsMSVCEnvironment() && - Context.getTypeAlignIfKnown(D->getType()) > 32) + Context.getTypeAlignIfKnown(D->getType()) > + Context.toBits(CharUnits::fromQuantity(32))) return true; return false; diff --git a/clang/test/CodeGen/microsoft-no-common-align.c b/clang/test/CodeGen/microsoft-no-common-align.c index fc46946c00ed2..a7a27a062704f 100644 --- a/clang/test/CodeGen/microsoft-no-common-align.c +++ b/clang/test/CodeGen/microsoft-no-common-align.c @@ -6,3 +6,6 @@ TooLargeAlignment TooBig; // CHECK: @TooBig = dso_local global <16 x float> zeroinitializer, align 64 NormalAlignment JustRight; // CHECK: @JustRight = common dso_local global <1 x float> zeroinitializer, align 4 + +TooLargeAlignment *IsAPointer; +// CHECK: @IsAPointer = common dso_local global <16 x float>* null, align 8 From e57cf6c5dc507872a693141f9009dff98e614f0f Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Feb 2019 11:02:43 +0000 Subject: [PATCH 124/274] Merging r353431: ------------------------------------------------------------------------ r353431 | stulova | 2019-02-07 18:32:37 +0100 (Thu, 07 Feb 2019) | 9 lines [OpenCL][PR40603] In C++ preserve compatibility with OpenCL C v2.0 Valid OpenCL C code should still compile in C++ mode. This change enables extensions and OpenCL types. Differential Revision: https://reviews.llvm.org/D57824 ------------------------------------------------------------------------ llvm-svn: 353826 --- clang/include/clang/Basic/OpenCLOptions.h | 29 +++--- clang/lib/Frontend/InitPreprocessor.cpp | 7 +- clang/lib/Parse/ParsePragma.cpp | 9 +- clang/lib/Sema/Sema.cpp | 7 +- clang/test/SemaOpenCL/extension-version.cl | 114 ++++++++++----------- clang/test/SemaOpenCL/extensions.cl | 9 +- 6 files changed, 92 insertions(+), 83 deletions(-) diff --git a/clang/include/clang/Basic/OpenCLOptions.h b/clang/include/clang/Basic/OpenCLOptions.h index cc4e9922dca03..c76fa88092b9b 100644 --- a/clang/include/clang/Basic/OpenCLOptions.h +++ b/clang/include/clang/Basic/OpenCLOptions.h @@ -15,6 +15,7 @@ #ifndef LLVM_CLANG_BASIC_OPENCLOPTIONS_H #define LLVM_CLANG_BASIC_OPENCLOPTIONS_H +#include "clang/Basic/LangOptions.h" #include "llvm/ADT/StringMap.h" namespace clang { @@ -42,25 +43,29 @@ class OpenCLOptions { // Is supported as either an extension or an (optional) core feature for // OpenCL version \p CLVer. - bool isSupported(llvm::StringRef Ext, unsigned CLVer) const { + bool isSupported(llvm::StringRef Ext, LangOptions LO) const { + // In C++ mode all extensions should work at least as in v2.0. + auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion; auto I = OptMap.find(Ext)->getValue(); return I.Supported && I.Avail <= CLVer; } // Is supported (optional) OpenCL core features for OpenCL version \p CLVer. // For supported extension, return false. - bool isSupportedCore(llvm::StringRef Ext, unsigned CLVer) const { + bool isSupportedCore(llvm::StringRef Ext, LangOptions LO) const { + // In C++ mode all extensions should work at least as in v2.0. + auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion; auto I = OptMap.find(Ext)->getValue(); - return I.Supported && I.Avail <= CLVer && - I.Core != ~0U && CLVer >= I.Core; + return I.Supported && I.Avail <= CLVer && I.Core != ~0U && CLVer >= I.Core; } // Is supported OpenCL extension for OpenCL version \p CLVer. // For supported (optional) core feature, return false. - bool isSupportedExtension(llvm::StringRef Ext, unsigned CLVer) const { + bool isSupportedExtension(llvm::StringRef Ext, LangOptions LO) const { + // In C++ mode all extensions should work at least as in v2.0. + auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion; auto I = OptMap.find(Ext)->getValue(); - return I.Supported && I.Avail <= CLVer && - (I.Core == ~0U || CLVer < I.Core); + return I.Supported && I.Avail <= CLVer && (I.Core == ~0U || CLVer < I.Core); } void enable(llvm::StringRef Ext, bool V = true) { @@ -122,10 +127,10 @@ class OpenCLOptions { I->second.Enabled = false; } - void enableSupportedCore(unsigned CLVer) { - for (llvm::StringMap::iterator I = OptMap.begin(), - E = OptMap.end(); I != E; ++I) - if (isSupportedCore(I->getKey(), CLVer)) + void enableSupportedCore(LangOptions LO) { + for (llvm::StringMap::iterator I = OptMap.begin(), E = OptMap.end(); + I != E; ++I) + if (isSupportedCore(I->getKey(), LO)) I->second.Enabled = true; } @@ -133,6 +138,6 @@ class OpenCLOptions { friend class ASTReader; }; -} // end namespace clang +} // end namespace clang #endif diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 66807b097d407..4cde22ce9aa44 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -1059,10 +1059,9 @@ static void InitializePredefinedMacros(const TargetInfo &TI, // OpenCL definitions. if (LangOpts.OpenCL) { -#define OPENCLEXT(Ext) \ - if (TI.getSupportedOpenCLOpts().isSupported(#Ext, \ - LangOpts.OpenCLVersion)) \ - Builder.defineMacro(#Ext); +#define OPENCLEXT(Ext) \ + if (TI.getSupportedOpenCLOpts().isSupported(#Ext, LangOpts)) \ + Builder.defineMacro(#Ext); #include "clang/Basic/OpenCLExtensions.def" auto Arch = TI.getTriple().getArch(); diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 380eb64997a71..7e9b1011e81af 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -693,13 +693,12 @@ void Parser::HandlePragmaOpenCLExtension() { if (Name == "all") { if (State == Disable) { Opt.disableAll(); - Opt.enableSupportedCore(getLangOpts().OpenCLVersion); + Opt.enableSupportedCore(getLangOpts()); } else { PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1; } } else if (State == Begin) { - if (!Opt.isKnown(Name) || - !Opt.isSupported(Name, getLangOpts().OpenCLVersion)) { + if (!Opt.isKnown(Name) || !Opt.isSupported(Name, getLangOpts())) { Opt.support(Name); } Actions.setCurrentOpenCLExtension(Name); @@ -709,9 +708,9 @@ void Parser::HandlePragmaOpenCLExtension() { Actions.setCurrentOpenCLExtension(""); } else if (!Opt.isKnown(Name)) PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident; - else if (Opt.isSupportedExtension(Name, getLangOpts().OpenCLVersion)) + else if (Opt.isSupportedExtension(Name, getLangOpts())) Opt.enable(Name, State == Enable); - else if (Opt.isSupportedCore(Name, getLangOpts().OpenCLVersion)) + else if (Opt.isSupportedCore(Name, getLangOpts())) PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident; else PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident; diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 9fa39968625a6..9d33ec5190924 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -256,11 +256,12 @@ void Sema::Initialize() { // Initialize predefined OpenCL types and supported extensions and (optional) // core features. if (getLangOpts().OpenCL) { - getOpenCLOptions().addSupport(Context.getTargetInfo().getSupportedOpenCLOpts()); - getOpenCLOptions().enableSupportedCore(getLangOpts().OpenCLVersion); + getOpenCLOptions().addSupport( + Context.getTargetInfo().getSupportedOpenCLOpts()); + getOpenCLOptions().enableSupportedCore(getLangOpts()); addImplicitTypedef("sampler_t", Context.OCLSamplerTy); addImplicitTypedef("event_t", Context.OCLEventTy); - if (getLangOpts().OpenCLVersion >= 200) { + if (getLangOpts().OpenCLCPlusPlus || getLangOpts().OpenCLVersion >= 200) { addImplicitTypedef("clk_event_t", Context.OCLClkEventTy); addImplicitTypedef("queue_t", Context.OCLQueueTy); addImplicitTypedef("reserve_id_t", Context.OCLReserveIDTy); diff --git a/clang/test/SemaOpenCL/extension-version.cl b/clang/test/SemaOpenCL/extension-version.cl index a587f1db99af2..d976cfb3a4354 100644 --- a/clang/test/SemaOpenCL/extension-version.cl +++ b/clang/test/SemaOpenCL/extension-version.cl @@ -2,12 +2,14 @@ // RUN: %clang_cc1 -x cl -cl-std=CL1.1 %s -verify -triple spir-unknown-unknown // RUN: %clang_cc1 -x cl -cl-std=CL1.2 %s -verify -triple spir-unknown-unknown // RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple spir-unknown-unknown +// RUN: %clang_cc1 -x cl -cl-std=c++ %s -verify -triple spir-unknown-unknown // RUN: %clang_cc1 -x cl -cl-std=CL %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES // RUN: %clang_cc1 -x cl -cl-std=CL1.1 %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES // RUN: %clang_cc1 -x cl -cl-std=CL1.2 %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES // RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES +// RUN: %clang_cc1 -x cl -cl-std=c++ %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES -#if __OPENCL_C_VERSION__ >= 200 && ! defined TEST_CORE_FEATURES +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) && !defined(TEST_CORE_FEATURES) // expected-no-diagnostics #endif @@ -47,44 +49,44 @@ #ifndef cl_khr_byte_addressable_store #error "Missing cl_khr_byte_addressable_store define" #endif -#pragma OPENCL EXTENSION cl_khr_byte_addressable_store: enable -#if (__OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES +#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES // expected-warning@-2{{OpenCL extension 'cl_khr_byte_addressable_store' is core feature or supported optional core feature - ignoring}} #endif #ifndef cl_khr_global_int32_base_atomics #error "Missing cl_khr_global_int32_base_atomics define" #endif -#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics: enable -#if (__OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES +#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES // expected-warning@-2{{OpenCL extension 'cl_khr_global_int32_base_atomics' is core feature or supported optional core feature - ignoring}} #endif #ifndef cl_khr_global_int32_extended_atomics #error "Missing cl_khr_global_int32_extended_atomics define" #endif -#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics: enable -#if (__OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES +#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES // expected-warning@-2{{OpenCL extension 'cl_khr_global_int32_extended_atomics' is core feature or supported optional core feature - ignoring}} #endif #ifndef cl_khr_local_int32_base_atomics #error "Missing cl_khr_local_int32_base_atomics define" #endif -#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics: enable -#if (__OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES +#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES // expected-warning@-2{{OpenCL extension 'cl_khr_local_int32_base_atomics' is core feature or supported optional core feature - ignoring}} #endif #ifndef cl_khr_local_int32_extended_atomics #error "Missing cl_khr_local_int32_extended_atomics define" #endif -#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics: enable -#if (__OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES +#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES // expected-warning@-2{{OpenCL extension 'cl_khr_local_int32_extended_atomics' is core feature or supported optional core feature - ignoring}} #endif -#if (__OPENCL_C_VERSION__ < 110) +#if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ < 110) // Deprecated abvoe 1.0 #ifndef cl_khr_select_fprounding_mode #error "Missing cl_khr_select_fp_rounding_mode define" @@ -97,8 +99,8 @@ #ifndef cl_khr_fp64 #error "Missing cl_khr_fp64 define" #endif -#pragma OPENCL EXTENSION cl_khr_fp64: enable -#if (__OPENCL_C_VERSION__ >= 120) && defined TEST_CORE_FEATURES +#pragma OPENCL EXTENSION cl_khr_fp64 : enable +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120) && defined TEST_CORE_FEATURES // expected-warning@-2{{OpenCL extension 'cl_khr_fp64' is core feature or supported optional core feature - ignoring}} #endif @@ -106,131 +108,129 @@ #ifndef cl_khr_3d_image_writes #error "Missing cl_khr_3d_image_writes define" #endif -#pragma OPENCL EXTENSION cl_khr_3d_image_writes: enable -#if (__OPENCL_C_VERSION__ >= 200) && defined TEST_CORE_FEATURES +#pragma OPENCL EXTENSION cl_khr_3d_image_writes : enable +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) && defined TEST_CORE_FEATURES // expected-warning@-2{{OpenCL extension 'cl_khr_3d_image_writes' is core feature or supported optional core feature - ignoring}} #endif - - -#if (__OPENCL_C_VERSION__ >= 110) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 110) #ifndef cl_khr_gl_event #error "Missing cl_khr_gl_event define" #endif #else // expected-warning@+2{{unsupported OpenCL extension 'cl_khr_gl_event' - ignoring}} #endif -#pragma OPENCL EXTENSION cl_khr_gl_event: enable +#pragma OPENCL EXTENSION cl_khr_gl_event : enable -#if (__OPENCL_C_VERSION__ >= 110) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 110) #ifndef cl_khr_d3d10_sharing #error "Missing cl_khr_d3d10_sharing define" #endif #else // expected-warning@+2{{unsupported OpenCL extension 'cl_khr_d3d10_sharing' - ignoring}} #endif -#pragma OPENCL EXTENSION cl_khr_d3d10_sharing: enable +#pragma OPENCL EXTENSION cl_khr_d3d10_sharing : enable -#if (__OPENCL_C_VERSION__ >= 110) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 110) #ifndef cles_khr_int64 #error "Missing cles_khr_int64 define" #endif #else // expected-warning@+2{{unsupported OpenCL extension 'cles_khr_int64' - ignoring}} #endif -#pragma OPENCL EXTENSION cles_khr_int64: enable +#pragma OPENCL EXTENSION cles_khr_int64 : enable -#if (__OPENCL_C_VERSION__ >= 120) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120) #ifndef cl_khr_context_abort #error "Missing cl_context_abort define" #endif #else // expected-warning@+2{{unsupported OpenCL extension 'cl_khr_context_abort' - ignoring}} #endif -#pragma OPENCL EXTENSION cl_khr_context_abort: enable +#pragma OPENCL EXTENSION cl_khr_context_abort : enable -#if (__OPENCL_C_VERSION__ >= 120) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120) #ifndef cl_khr_d3d11_sharing #error "Missing cl_khr_d3d11_sharing define" #endif #else // expected-warning@+2{{unsupported OpenCL extension 'cl_khr_d3d11_sharing' - ignoring}} #endif -#pragma OPENCL EXTENSION cl_khr_d3d11_sharing: enable +#pragma OPENCL EXTENSION cl_khr_d3d11_sharing : enable -#if (__OPENCL_C_VERSION__ >= 120) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120) #ifndef cl_khr_dx9_media_sharing #error "Missing cl_khr_dx9_media_sharing define" #endif #else // expected-warning@+2{{unsupported OpenCL extension 'cl_khr_dx9_media_sharing' - ignoring}} #endif -#pragma OPENCL EXTENSION cl_khr_dx9_media_sharing: enable +#pragma OPENCL EXTENSION cl_khr_dx9_media_sharing : enable -#if (__OPENCL_C_VERSION__ >= 120) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120) #ifndef cl_khr_image2d_from_buffer #error "Missing cl_khr_image2d_from_buffer define" #endif #else // expected-warning@+2{{unsupported OpenCL extension 'cl_khr_image2d_from_buffer' - ignoring}} #endif -#pragma OPENCL EXTENSION cl_khr_image2d_from_buffer: enable +#pragma OPENCL EXTENSION cl_khr_image2d_from_buffer : enable -#if (__OPENCL_C_VERSION__ >= 120) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120) #ifndef cl_khr_initialize_memory #error "Missing cl_khr_initialize_memory define" #endif #else // expected-warning@+2{{unsupported OpenCL extension 'cl_khr_initialize_memory' - ignoring}} #endif -#pragma OPENCL EXTENSION cl_khr_initialize_memory: enable +#pragma OPENCL EXTENSION cl_khr_initialize_memory : enable -#if (__OPENCL_C_VERSION__ >= 120) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120) #ifndef cl_khr_gl_depth_images #error "Missing cl_khr_gl_depth_images define" #endif #else // expected-warning@+2{{unsupported OpenCL extension 'cl_khr_gl_depth_images' - ignoring}} #endif -#pragma OPENCL EXTENSION cl_khr_gl_depth_images: enable +#pragma OPENCL EXTENSION cl_khr_gl_depth_images : enable -#if (__OPENCL_C_VERSION__ >= 120) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120) #ifndef cl_khr_gl_msaa_sharing #error "Missing cl_khr_gl_msaa_sharing define" #endif #else // expected-warning@+2{{unsupported OpenCL extension 'cl_khr_gl_msaa_sharing' - ignoring}} #endif -#pragma OPENCL EXTENSION cl_khr_gl_msaa_sharing: enable +#pragma OPENCL EXTENSION cl_khr_gl_msaa_sharing : enable -#if (__OPENCL_C_VERSION__ >= 120) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120) #ifndef cl_khr_spir #error "Missing cl_khr_spir define" #endif #else // expected-warning@+2{{unsupported OpenCL extension 'cl_khr_spir' - ignoring}} #endif -#pragma OPENCL EXTENSION cl_khr_spir: enable +#pragma OPENCL EXTENSION cl_khr_spir : enable -#if (__OPENCL_C_VERSION__ >= 200) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) #ifndef cl_khr_egl_event #error "Missing cl_khr_egl_event define" #endif #else // expected-warning@+2{{unsupported OpenCL extension 'cl_khr_egl_event' - ignoring}} #endif -#pragma OPENCL EXTENSION cl_khr_egl_event: enable +#pragma OPENCL EXTENSION cl_khr_egl_event : enable -#if (__OPENCL_C_VERSION__ >= 200) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) #ifndef cl_khr_egl_image #error "Missing cl_khr_egl_image define" #endif #else // expected-warning@+2{{unsupported OpenCL extension 'cl_khr_egl_image' - ignoring}} #endif -#pragma OPENCL EXTENSION cl_khr_egl_image: enable +#pragma OPENCL EXTENSION cl_khr_egl_image : enable -#if (__OPENCL_C_VERSION__ >= 200) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) #ifndef cl_khr_mipmap_image #error "Missing cl_khr_mipmap_image define" #endif @@ -240,18 +240,18 @@ #endif // expected-warning@+2{{unsupported OpenCL extension 'cl_khr_mipmap_image' - ignoring}} #endif -#pragma OPENCL EXTENSION cl_khr_mipmap_image: enable +#pragma OPENCL EXTENSION cl_khr_mipmap_image : enable -#if (__OPENCL_C_VERSION__ >= 200) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) #ifndef cl_khr_srgb_image_writes #error "Missing cl_khr_srgb_image_writes define" #endif #else // expected-warning@+2{{unsupported OpenCL extension 'cl_khr_srgb_image_writes' - ignoring}} #endif -#pragma OPENCL EXTENSION cl_khr_srgb_image_writes: enable +#pragma OPENCL EXTENSION cl_khr_srgb_image_writes : enable -#if (__OPENCL_C_VERSION__ >= 200) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) #ifndef cl_khr_subgroups #error "Missing cl_khr_subgroups define" #endif @@ -261,9 +261,9 @@ #endif // expected-warning@+2{{unsupported OpenCL extension 'cl_khr_subgroups' - ignoring}} #endif -#pragma OPENCL EXTENSION cl_khr_subgroups: enable +#pragma OPENCL EXTENSION cl_khr_subgroups : enable -#if (__OPENCL_C_VERSION__ >= 200) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) #ifndef cl_khr_terminate_context #error "Missing cl_khr_terminate_context define" #endif @@ -280,9 +280,9 @@ #ifndef cl_amd_media_ops2 #error "Missing cl_amd_media_ops2 define" #endif -#pragma OPENCL EXTENSION cl_amd_media_ops2: enable +#pragma OPENCL EXTENSION cl_amd_media_ops2 : enable -#if (__OPENCL_C_VERSION__ >= 120) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120) #ifndef cl_khr_depth_images #error "Missing cl_khr_depth_images define" #endif @@ -292,9 +292,9 @@ #endif // expected-warning@+2{{unsupported OpenCL extension 'cl_khr_depth_images' - ignoring}} #endif -#pragma OPENCL EXTENSION cl_khr_depth_images: enable +#pragma OPENCL EXTENSION cl_khr_depth_images : enable -#if (__OPENCL_C_VERSION__ >= 120) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120) #ifndef cl_intel_subgroups #error "Missing cl_intel_subgroups define" #endif @@ -303,7 +303,7 @@ #endif #pragma OPENCL EXTENSION cl_intel_subgroups : enable -#if (__OPENCL_C_VERSION__ >= 120) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120) #ifndef cl_intel_subgroups_short #error "Missing cl_intel_subgroups_short define" #endif @@ -312,7 +312,7 @@ #endif #pragma OPENCL EXTENSION cl_intel_subgroups_short : enable -#if (__OPENCL_C_VERSION__ >= 120) +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120) #ifndef cl_intel_device_side_avc_motion_estimation #error "Missing cl_intel_device_side_avc_motion_estimation define" #endif diff --git a/clang/test/SemaOpenCL/extensions.cl b/clang/test/SemaOpenCL/extensions.cl index 5f95e32d4a549..e9dba69ecd7c9 100644 --- a/clang/test/SemaOpenCL/extensions.cl +++ b/clang/test/SemaOpenCL/extensions.cl @@ -28,6 +28,7 @@ // enabled by default with -cl-std=CL2.0). // // RUN: %clang_cc1 %s -triple amdgcn-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL2.0 -finclude-default-header +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=c++ #ifdef _OPENCL_H_ // expected-no-diagnostics @@ -37,7 +38,11 @@ // expected-no-diagnostics #endif -#if __OPENCL_C_VERSION__ < 120 +#ifdef __OPENCL_CPP_VERSION__ +// expected-no-diagnostics +#endif + +#if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ < 120) void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 extension}} double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}} (void) 1.0; // expected-warning {{double precision constant requires cl_khr_fp64}} @@ -89,7 +94,7 @@ void f2(void) { // expected-warning@-2{{unsupported OpenCL extension 'cl_khr_fp64' - ignoring}} #endif -#if __OPENCL_C_VERSION__ < 120 +#if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ < 120) void f3(void) { double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}} } From dfde9d6b350c6793352e2e88a9463675b38962cb Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Feb 2019 11:05:22 +0000 Subject: [PATCH 125/274] Merging r353480: ------------------------------------------------------------------------ r353480 | petarj | 2019-02-07 23:57:33 +0100 (Thu, 07 Feb 2019) | 15 lines [mips][micromips] Fix how values in .gcc_except_table are calculated When a landing pad is calculated in a program that is compiled for micromips with -fPIC flag, it will point to an even address. Such an error will cause a segmentation fault, as the instructions in micromips are aligned on odd addresses. This patch sets the last bit of the offset where a landing pad is, to 1, which will effectively be an odd address and point to the instruction exactly. r344591 fixed this issue for -static compilation. Patch by Aleksandar Beserminji. Differential Revision: https://reviews.llvm.org/D57677 ------------------------------------------------------------------------ llvm-svn: 353827 --- llvm/lib/MC/MCExpr.cpp | 5 +++++ llvm/test/CodeGen/Mips/micromips-b-range.ll | 8 +++---- llvm/test/DebugInfo/Mips/eh_frame.ll | 24 +++++++++++++++------ 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp index 3c022199145fb..0e4174a7a4c94 100644 --- a/llvm/lib/MC/MCExpr.cpp +++ b/llvm/lib/MC/MCExpr.cpp @@ -559,6 +559,11 @@ static void AttemptToFoldSymbolOffsetDifference( if (Asm->isThumbFunc(&SA)) Addend |= 1; + // If symbol is labeled as micromips, we set low-bit to ensure + // correct offset in .gcc_except_table + if (Asm->getBackend().isMicroMips(&SA)) + Addend |= 1; + // Clear the symbol expr pointers to indicate we have folded these // operands. A = B = nullptr; diff --git a/llvm/test/CodeGen/Mips/micromips-b-range.ll b/llvm/test/CodeGen/Mips/micromips-b-range.ll index 5831ae81baeda..27a0db545f743 100644 --- a/llvm/test/CodeGen/Mips/micromips-b-range.ll +++ b/llvm/test/CodeGen/Mips/micromips-b-range.ll @@ -13,7 +13,7 @@ ; CHECK-NEXT: 1e: fb fd 00 00 sw $ra, 0($sp) ; CHECK-NEXT: 22: 41 a1 00 01 lui $1, 1 ; CHECK-NEXT: 26: 40 60 00 02 bal 8 -; CHECK-NEXT: 2a: 30 21 04 68 addiu $1, $1, 1128 +; CHECK-NEXT: 2a: 30 21 04 69 addiu $1, $1, 1129 ; CHECK-NEXT: 2e: 00 3f 09 50 addu $1, $ra, $1 ; CHECK-NEXT: 32: ff fd 00 00 lw $ra, 0($sp) ; CHECK-NEXT: 36: 00 01 0f 3c jr $1 @@ -27,7 +27,7 @@ ; CHECK-NEXT: 56: fb fd 00 00 sw $ra, 0($sp) ; CHECK-NEXT: 5a: 41 a1 00 01 lui $1, 1 ; CHECK-NEXT: 5e: 40 60 00 02 bal 8 -; CHECK-NEXT: 62: 30 21 04 5c addiu $1, $1, 1116 +; CHECK-NEXT: 62: 30 21 04 5d addiu $1, $1, 1117 ; CHECK-NEXT: 66: 00 3f 09 50 addu $1, $ra, $1 ; CHECK-NEXT: 6a: ff fd 00 00 lw $ra, 0($sp) ; CHECK-NEXT: 6e: 00 01 0f 3c jr $1 @@ -39,7 +39,7 @@ ; CHECK-NEXT: 86: fb fd 00 00 sw $ra, 0($sp) ; CHECK-NEXT: 8a: 41 a1 00 01 lui $1, 1 ; CHECK-NEXT: 8e: 40 60 00 02 bal 8 -; CHECK-NEXT: 92: 30 21 04 2c addiu $1, $1, 1068 +; CHECK-NEXT: 92: 30 21 04 2d addiu $1, $1, 1069 ; CHECK-NEXT: 96: 00 3f 09 50 addu $1, $ra, $1 ; CHECK-NEXT: 9a: ff fd 00 00 lw $ra, 0($sp) ; CHECK-NEXT: 9e: 00 01 0f 3c jr $1 @@ -51,7 +51,7 @@ ; CHECK-NEXT: 10476: fb fd 00 00 sw $ra, 0($sp) ; CHECK-NEXT: 1047a: 41 a1 00 01 lui $1, 1 ; CHECK-NEXT: 1047e: 40 60 00 02 bal 8 -; CHECK-NEXT: 10482: 30 21 04 00 addiu $1, $1, 1024 +; CHECK-NEXT: 10482: 30 21 04 01 addiu $1, $1, 1025 ; CHECK-NEXT: 10486: 00 3f 09 50 addu $1, $ra, $1 ; CHECK-NEXT: 1048a: ff fd 00 00 lw $ra, 0($sp) ; CHECK-NEXT: 1048e: 00 01 0f 3c jr $1 diff --git a/llvm/test/DebugInfo/Mips/eh_frame.ll b/llvm/test/DebugInfo/Mips/eh_frame.ll index 4687443cb1cff..122d0a7f6ab2a 100644 --- a/llvm/test/DebugInfo/Mips/eh_frame.ll +++ b/llvm/test/DebugInfo/Mips/eh_frame.ll @@ -1,9 +1,21 @@ -; RUN: llc -mtriple mips-unknown-linux-gnu -mattr=+micromips -O3 -filetype=obj -o - %s | llvm-readelf -r | FileCheck %s - -; CHECK: .rel.eh_frame -; CHECK: DW.ref.__gxx_personality_v0 -; CHECK-NEXT: .text -; CHECK-NEXT: .gcc_except_table +; RUN: llc -mtriple mips-unknown-linux-gnu -mattr=+micromips -relocation-model=static -O3 -filetype=obj -o - %s | \ +; RUN: llvm-readelf -r | FileCheck %s --check-prefix=CHECK-READELF +; RUN: llc -mtriple mips-unknown-linux-gnu -mattr=+micromips -relocation-model=pic -O3 -filetype=obj -o - %s | \ +; RUN: llvm-readelf -r | FileCheck %s --check-prefix=CHECK-READELF +; RUN: llc -mtriple mips-unknown-linux-gnu -mattr=+micromips -relocation-model=static -O3 -filetype=obj -o - %s | \ +; RUN: llvm-objdump -s -j .gcc_except_table - | FileCheck %s --check-prefix=CHECK-EXCEPT-TABLE-STATIC +; RUN: llc -mtriple mips-unknown-linux-gnu -mattr=+micromips -relocation-model=pic -O3 -filetype=obj -o - %s | \ +; RUN: llvm-objdump -s -j .gcc_except_table - | FileCheck %s --check-prefix=CHECK-EXCEPT-TABLE-PIC + +; CHECK-READELF: .rel.eh_frame +; CHECK-READELF: DW.ref.__gxx_personality_v0 +; CHECK-READELF-NEXT: .text +; CHECK-READELF-NEXT: .gcc_except_table + +; CHECK-EXCEPT-TABLE-STATIC: 0000 ff9b1501 0c011500 00150e23 01231e00 ...........#.#.. +; CHECK-EXCEPT-TABLE-STATIC: 0010 00010000 00000000 +; CHECK-EXCEPT-TABLE-PIC: 0000 ff9b1501 0c012d00 002d133f 013f2a00 ......-..-.?.?*. +; CHECK-EXCEPT-TABLE-PIC: 0010 00010000 00000000 ........ @_ZTIi = external constant i8* From eb0faeb15455088b681b90578afcc7932424dd32 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Feb 2019 11:09:24 +0000 Subject: [PATCH 126/274] Merging r353493: ------------------------------------------------------------------------ r353493 | efriedma | 2019-02-08 02:17:49 +0100 (Fri, 08 Feb 2019) | 9 lines [COFF, ARM64] Fix types for _ReadStatusReg, _WriteStatusReg r344765 added those intrinsics, but used the wrong types. Patch by Mike Hommey Differential Revision: https://reviews.llvm.org/D57636 ------------------------------------------------------------------------ llvm-svn: 353828 --- clang/include/clang/Basic/BuiltinsAArch64.def | 4 +- clang/lib/CodeGen/CGBuiltin.cpp | 5 +- clang/lib/Headers/intrin.h | 4 +- .../CodeGen/arm64-microsoft-status-reg.cpp | 108 +++++++++++------- 4 files changed, 71 insertions(+), 50 deletions(-) diff --git a/clang/include/clang/Basic/BuiltinsAArch64.def b/clang/include/clang/Basic/BuiltinsAArch64.def index 690d547f7f3ef..054662e688317 100644 --- a/clang/include/clang/Basic/BuiltinsAArch64.def +++ b/clang/include/clang/Basic/BuiltinsAArch64.def @@ -204,8 +204,8 @@ TARGET_HEADER_BUILTIN(_InterlockedDecrement64_rel, "LLiLLiD*", "nh", "intrin.h", TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__getReg, "ULLii", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_ReadStatusReg, "ii", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_WriteStatusReg, "vii", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_ReadStatusReg, "LLii", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_WriteStatusReg, "viLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") #undef BUILTIN diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index a718f2f19aa65..ccc657493b28b 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -7052,19 +7052,16 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName); llvm::Type *RegisterType = Int64Ty; - llvm::Type *ValueType = Int32Ty; llvm::Type *Types[] = { RegisterType }; if (BuiltinID == AArch64::BI_ReadStatusReg) { llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types); - llvm::Value *Call = Builder.CreateCall(F, Metadata); - return Builder.CreateTrunc(Call, ValueType); + return Builder.CreateCall(F, Metadata); } llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types); llvm::Value *ArgValue = EmitScalarExpr(E->getArg(1)); - ArgValue = Builder.CreateZExt(ArgValue, RegisterType); return Builder.CreateCall(F, { Metadata, ArgValue }); } diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h index c86f41faeb88a..966258bab4b32 100644 --- a/clang/lib/Headers/intrin.h +++ b/clang/lib/Headers/intrin.h @@ -564,8 +564,8 @@ __nop(void) { #if defined(__aarch64__) unsigned __int64 __getReg(int); long _InterlockedAdd(long volatile *Addend, long Value); -int _ReadStatusReg(int); -void _WriteStatusReg(int, int); +__int64 _ReadStatusReg(int); +void _WriteStatusReg(int, __int64); static inline unsigned short _byteswap_ushort (unsigned short val) { return __builtin_bswap16(val); diff --git a/clang/test/CodeGen/arm64-microsoft-status-reg.cpp b/clang/test/CodeGen/arm64-microsoft-status-reg.cpp index eb59bae50f0ae..524b5af120c52 100644 --- a/clang/test/CodeGen/arm64-microsoft-status-reg.cpp +++ b/clang/test/CodeGen/arm64-microsoft-status-reg.cpp @@ -23,88 +23,112 @@ #define ARM64_TPIDRRO_EL0 ARM64_SYSREG(3,3,13, 0,3) // Thread ID Register, User Read Only [CP15_TPIDRURO] #define ARM64_TPIDR_EL1 ARM64_SYSREG(3,0,13, 0,4) // Thread ID Register, Privileged Only [CP15_TPIDRPRW] -void check_ReadWriteStatusReg(int v) { - int ret; +// From intrin.h +__int64 _ReadStatusReg(int); +void _WriteStatusReg(int, __int64); + +void check_ReadWriteStatusReg(__int64 v) { + __int64 ret; ret = _ReadStatusReg(ARM64_CNTVCT); -// CHECK-ASM: mrs x8, CNTVCT_EL0 -// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD2:.*]]) +// CHECK-ASM: mrs x0, CNTVCT_EL0 +// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2:.*]]) +// CHECK-IR-NEXT: store i64 %[[VAR]] ret = _ReadStatusReg(ARM64_PMCCNTR_EL0); -// CHECK-ASM: mrs x8, PMCCNTR_EL0 -// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD3:.*]]) +// CHECK-ASM: mrs x0, PMCCNTR_EL0 +// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD3:.*]]) +// CHECK-IR-NEXT: store i64 %[[VAR]] ret = _ReadStatusReg(ARM64_PMSELR_EL0); -// CHECK-ASM: mrs x8, PMSELR_EL0 -// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD4:.*]]) +// CHECK-ASM: mrs x0, PMSELR_EL0 +// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD4:.*]]) +// CHECK-IR-NEXT: store i64 %[[VAR]] ret = _ReadStatusReg(ARM64_PMXEVCNTR_EL0); -// CHECK-ASM: mrs x8, PMXEVCNTR_EL0 -// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD5:.*]]) +// CHECK-ASM: mrs x0, PMXEVCNTR_EL0 +// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD5:.*]]) +// CHECK-IR-NEXT: store i64 %[[VAR]] ret = _ReadStatusReg(ARM64_PMXEVCNTRn_EL0(0)); -// CHECK-ASM: mrs x8, PMEVCNTR0_EL0 -// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD6:.*]]) +// CHECK-ASM: mrs x0, PMEVCNTR0_EL0 +// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD6:.*]]) +// CHECK-IR-NEXT: store i64 %[[VAR]] ret = _ReadStatusReg(ARM64_PMXEVCNTRn_EL0(1)); -// CHECK-ASM: mrs x8, PMEVCNTR1_EL0 -// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD7:.*]]) +// CHECK-ASM: mrs x0, PMEVCNTR1_EL0 +// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD7:.*]]) +// CHECK-IR-NEXT: store i64 %[[VAR]] ret = _ReadStatusReg(ARM64_PMXEVCNTRn_EL0(30)); -// CHECK-ASM: mrs x8, PMEVCNTR30_EL0 -// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD8:.*]]) +// CHECK-ASM: mrs x0, PMEVCNTR30_EL0 +// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD8:.*]]) +// CHECK-IR-NEXT: store i64 %[[VAR]] ret = _ReadStatusReg(ARM64_TPIDR_EL0); -// CHECK-ASM: mrs x8, TPIDR_EL0 -// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD9:.*]]) +// CHECK-ASM: mrs x0, TPIDR_EL0 +// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD9:.*]]) +// CHECK-IR-NEXT: store i64 %[[VAR]] ret = _ReadStatusReg(ARM64_TPIDRRO_EL0); -// CHECK-ASM: mrs x8, TPIDRRO_EL0 -// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD10:.*]]) +// CHECK-ASM: mrs x0, TPIDRRO_EL0 +// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD10:.*]]) +// CHECK-IR-NEXT: store i64 %[[VAR]] ret = _ReadStatusReg(ARM64_TPIDR_EL1); -// CHECK-ASM: mrs x8, TPIDR_EL1 -// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD11:.*]]) +// CHECK-ASM: mrs x0, TPIDR_EL1 +// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD11:.*]]) +// CHECK-IR-NEXT: store i64 %[[VAR]] _WriteStatusReg(ARM64_CNTVCT, v); -// CHECK-ASM: msr S3_3_C14_C0_2, x8 -// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD2:.*]], i64 {{%.*}}) +// CHECK-ASM: msr S3_3_C14_C0_2, x0 +// CHECK-IR: %[[VAR:.*]] = load i64, +// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD2:.*]], i64 %[[VAR]]) _WriteStatusReg(ARM64_PMCCNTR_EL0, v); -// CHECK-ASM: msr PMCCNTR_EL0, x8 -// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD3:.*]], i64 {{%.*}}) +// CHECK-ASM: msr PMCCNTR_EL0, x0 +// CHECK-IR: %[[VAR:.*]] = load i64, +// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD3:.*]], i64 %[[VAR]]) _WriteStatusReg(ARM64_PMSELR_EL0, v); -// CHECK-ASM: msr PMSELR_EL0, x8 -// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD4:.*]], i64 {{%.*}}) +// CHECK-ASM: msr PMSELR_EL0, x0 +// CHECK-IR: %[[VAR:.*]] = load i64, +// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD4:.*]], i64 %[[VAR]]) _WriteStatusReg(ARM64_PMXEVCNTR_EL0, v); -// CHECK-ASM: msr PMXEVCNTR_EL0, x8 -// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD5:.*]], i64 {{%.*}}) +// CHECK-ASM: msr PMXEVCNTR_EL0, x0 +// CHECK-IR: %[[VAR:.*]] = load i64, +// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD5:.*]], i64 %[[VAR]]) _WriteStatusReg(ARM64_PMXEVCNTRn_EL0(0), v); -// CHECK-ASM: msr PMEVCNTR0_EL0, x8 -// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD6:.*]], i64 {{%.*}}) +// CHECK-ASM: msr PMEVCNTR0_EL0, x0 +// CHECK-IR: %[[VAR:.*]] = load i64, +// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD6:.*]], i64 %[[VAR]]) _WriteStatusReg(ARM64_PMXEVCNTRn_EL0(1), v); -// CHECK-ASM: msr PMEVCNTR1_EL0, x8 -// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD7:.*]], i64 {{%.*}}) +// CHECK-ASM: msr PMEVCNTR1_EL0, x0 +// CHECK-IR: %[[VAR:.*]] = load i64, +// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD7:.*]], i64 %[[VAR]]) _WriteStatusReg(ARM64_PMXEVCNTRn_EL0(30), v); -// CHECK-ASM: msr PMEVCNTR30_EL0, x8 -// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD8:.*]], i64 {{%.*}}) +// CHECK-ASM: msr PMEVCNTR30_EL0, x0 +// CHECK-IR: %[[VAR:.*]] = load i64, +// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD8:.*]], i64 %[[VAR]]) _WriteStatusReg(ARM64_TPIDR_EL0, v); -// CHECK-ASM: msr TPIDR_EL0, x8 -// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD9:.*]], i64 {{%.*}}) +// CHECK-ASM: msr TPIDR_EL0, x0 +// CHECK-IR: %[[VAR:.*]] = load i64, +// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD9:.*]], i64 %[[VAR]]) _WriteStatusReg(ARM64_TPIDRRO_EL0, v); -// CHECK-ASM: msr TPIDRRO_EL0, x8 -// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD10:.*]], i64 {{%.*}}) +// CHECK-ASM: msr TPIDRRO_EL0, x0 +// CHECK-IR: %[[VAR:.*]] = load i64, +// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD10:.*]], i64 %[[VAR]]) _WriteStatusReg(ARM64_TPIDR_EL1, v); -// CHECK-ASM: msr TPIDR_EL1, x8 -// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD11:.*]], i64 {{%.*}}) +// CHECK-ASM: msr TPIDR_EL1, x0 +// CHECK-IR: %[[VAR:.*]] = load i64, +// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD11:.*]], i64 %[[VAR]]) } // CHECK-IR: ![[MD2]] = !{!"3:3:14:0:2"} From a576b44d09080661fc9f83a94f66eccb44d5f3ce Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Feb 2019 11:12:23 +0000 Subject: [PATCH 127/274] Merging r353402: ------------------------------------------------------------------------ r353402 | mstorsjo | 2019-02-07 13:46:49 +0100 (Thu, 07 Feb 2019) | 7 lines [clang-cl] support /Oy- on aarch64 MSVC supports /Oy- on aarch64, so clang-cl should too. Patch by Nathan Froyd! Differential Revision: https://reviews.llvm.org/D57838 ------------------------------------------------------------------------ llvm-svn: 353829 --- clang/lib/Driver/ToolChains/MSVC.cpp | 8 ++++---- clang/test/Driver/cl-options.c | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index 7e34b0df5c8cf..a164fd68e22e7 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -1408,10 +1408,10 @@ static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL, DAL.AddFlagArg( A, Opts.getOption(options::OPT_fno_omit_frame_pointer)); } else { - // Don't warn about /Oy- in 64-bit builds (where + // Don't warn about /Oy- in x86-64 builds (where // SupportsForcingFramePointer is false). The flag having no effect // there is a compiler-internal optimization, and people shouldn't have - // to special-case their build files for 64-bit clang-cl. + // to special-case their build files for x86-64 clang-cl. A->claim(); } break; @@ -1442,8 +1442,8 @@ MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args, DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); const OptTable &Opts = getDriver().getOpts(); - // /Oy and /Oy- only has an effect under X86-32. - bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86; + // /Oy and /Oy- don't have an effect on X86-64 + bool SupportsForcingFramePointer = getArch() != llvm::Triple::x86_64; // The -O[12xd] flag actually expands to several flags. We must desugar the // flags so that options embedded can be negated. For example, the '-O2' flag diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c index f5171d5c040c5..d8db081ac8a68 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -178,6 +178,10 @@ // Oy_2: -momit-leaf-frame-pointer // Oy_2: -O2 +// RUN: %clang_cl --target=aarch64-pc-windows-msvc -Werror /Oy- /O2 -### -- %s 2>&1 | FileCheck -check-prefix=Oy_aarch64 %s +// Oy_aarch64: -mdisable-fp-elim +// Oy_aarch64: -O2 + // RUN: %clang_cl --target=i686-pc-win32 -Werror /O2 /O2 -### -- %s 2>&1 | FileCheck -check-prefix=O2O2 %s // O2O2: "-O2" From ae61627a39b48f4131a27106567a7613be948948 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Feb 2019 11:17:08 +0000 Subject: [PATCH 128/274] Merging r351322: ------------------------------------------------------------------------ r351322 | pfaffe | 2019-01-16 12:14:07 +0100 (Wed, 16 Jan 2019) | 9 lines [MSan] Apply the ctor creation scheme of TSan Summary: To avoid adding an extern function to the global ctors list, apply the changes of D56538 also to MSan. Reviewers: chandlerc, vitalybuka, fedor.sergeev, leonardchan Subscribers: hiraditya, bollu, llvm-commits Differential Revision: https://reviews.llvm.org/D56734 ------------------------------------------------------------------------ llvm-svn: 353830 --- .../Instrumentation/MemorySanitizer.cpp | 24 ++++++++++++++++++- .../MemorySanitizer/global_ctors_2to3.ll | 18 ++++++++++++++ .../MemorySanitizer/msan_basic.ll | 5 ++-- .../MemorySanitizer/msan_llvm_is_constant.ll | 3 +++ 4 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index e6573af2077dc..b2230afa13d8a 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -321,6 +321,7 @@ static cl::opt ClOriginBase("msan-origin-base", cl::desc("Define custom MSan OriginBase"), cl::Hidden, cl::init(0)); +static const char *const kMsanModuleCtorName = "msan.module_ctor"; static const char *const kMsanInitName = "__msan_init"; namespace { @@ -586,6 +587,8 @@ class MemorySanitizer { /// An empty volatile inline asm that prevents callback merge. InlineAsm *EmptyAsm; + + Function *MsanCtorFunction; }; /// A legacy function pass for msan instrumentation. @@ -839,6 +842,8 @@ Value *MemorySanitizer::getKmsanShadowOriginAccessFn(bool isStore, int size) { } /// Module-level initialization. +/// +/// inserts a call to __msan_init to the module's constructor list. void MemorySanitizer::initializeModule(Module &M) { auto &DL = M.getDataLayout(); @@ -913,7 +918,22 @@ void MemorySanitizer::initializeModule(Module &M) { OriginStoreWeights = MDBuilder(*C).createBranchWeights(1, 1000); if (!CompileKernel) { - getOrCreateInitFunction(M, kMsanInitName); + std::tie(MsanCtorFunction, std::ignore) = + getOrCreateSanitizerCtorAndInitFunctions( + M, kMsanModuleCtorName, kMsanInitName, + /*InitArgTypes=*/{}, + /*InitArgs=*/{}, + // This callback is invoked when the functions are created the first + // time. Hook them into the global ctors list in that case: + [&](Function *Ctor, Function *) { + if (!ClWithComdat) { + appendToGlobalCtors(M, Ctor, 0); + return; + } + Comdat *MsanCtorComdat = M.getOrInsertComdat(kMsanModuleCtorName); + Ctor->setComdat(MsanCtorComdat); + appendToGlobalCtors(M, Ctor, 0, Ctor); + }); if (TrackOrigins) M.getOrInsertGlobal("__msan_track_origins", IRB.getInt32Ty(), [&] { @@ -4458,6 +4478,8 @@ static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan, } bool MemorySanitizer::sanitizeFunction(Function &F, TargetLibraryInfo &TLI) { + if (!CompileKernel && (&F == MsanCtorFunction)) + return false; MemorySanitizerVisitor Visitor(F, *this, TLI); // Clear out readonly/readnone attributes. diff --git a/llvm/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll b/llvm/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll new file mode 100644 index 0000000000000..d841c6c05c9b7 --- /dev/null +++ b/llvm/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll @@ -0,0 +1,18 @@ +; MSan converts 2-element global_ctors to 3-element when adding the new entry. +; RUN: opt < %s -msan-with-comdat -S -passes=msan 2>&1 | FileCheck %s +; RUN: opt < %s -msan -msan-with-comdat -S | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; CHECK: $msan.module_ctor = comdat any +; CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @f, i8* null }, { i32, void ()*, i8* } { i32 0, void ()* @msan.module_ctor, i8* bitcast (void ()* @msan.module_ctor to i8*) }] + +@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @f }] + +define internal void @f() { +entry: + ret void +} + +; CHECK: define internal void @msan.module_ctor() comdat { diff --git a/llvm/test/Instrumentation/MemorySanitizer/msan_basic.ll b/llvm/test/Instrumentation/MemorySanitizer/msan_basic.ll index f4cbc637ef1aa..569c2320c5c91 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/msan_basic.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/msan_basic.ll @@ -9,7 +9,7 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" -; CHECK: @llvm.global_ctors {{.*}} { i32 0, void ()* @__msan_init, i8* null } +; CHECK: @llvm.global_ctors {{.*}} { i32 0, void ()* @msan.module_ctor, i8* null } ; Check the presence and the linkage type of __msan_track_origins and ; other interface symbols. @@ -991,4 +991,5 @@ define i8* @MismatchingCallMustTailCall(i32 %a) sanitize_memory { ; CHECK-NEXT: ret i8* -; CHECK: declare void @__msan_init() +; CHECK-LABEL: define internal void @msan.module_ctor() { +; CHECK: call void @__msan_init() diff --git a/llvm/test/Instrumentation/MemorySanitizer/msan_llvm_is_constant.ll b/llvm/test/Instrumentation/MemorySanitizer/msan_llvm_is_constant.ll index b7847db06ac27..4f316be235798 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/msan_llvm_is_constant.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/msan_llvm_is_constant.ll @@ -1,6 +1,9 @@ ; Make sure MSan doesn't insert shadow checks for @llvm.is.constant.* arguments. +; RUN: opt < %s -msan-kernel=1 -S -passes=msan 2>&1 | FileCheck \ +; RUN: -check-prefixes=CHECK %s ; RUN: opt < %s -msan -msan-kernel=1 -S | FileCheck -check-prefixes=CHECK %s +; RUN: opt < %s -S -passes=msan 2>&1 | FileCheck -check-prefixes=CHECK %s ; RUN: opt < %s -msan -S | FileCheck -check-prefixes=CHECK %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" From 33e25307a0562a64247a55dd2a4c774647f8913b Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Feb 2019 11:19:21 +0000 Subject: [PATCH 129/274] Merging r353656: ------------------------------------------------------------------------ r353656 | brad | 2019-02-11 03:53:16 +0100 (Mon, 11 Feb 2019) | 4 lines long double is double on OpenBSD/NetBSD/PPC. Patch by George Koehler. ------------------------------------------------------------------------ llvm-svn: 353831 --- clang/lib/Basic/Targets/PPC.h | 8 +++++++- clang/test/CodeGen/powerpc_types.c | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 058970a0e098b..cbe7a9a2fa85e 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -331,9 +331,15 @@ class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo { break; } - if (getTriple().isOSFreeBSD()) { + switch (getTriple().getOS()) { + case llvm::Triple::FreeBSD: + case llvm::Triple::NetBSD: + case llvm::Triple::OpenBSD: LongDoubleWidth = LongDoubleAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + break; + default: + break; } // PPC32 supports atomics up to 4 bytes. diff --git a/clang/test/CodeGen/powerpc_types.c b/clang/test/CodeGen/powerpc_types.c index b7d0f5de49859..86eb7f8356801 100644 --- a/clang/test/CodeGen/powerpc_types.c +++ b/clang/test/CodeGen/powerpc_types.c @@ -1,4 +1,6 @@ // RUN: %clang_cc1 -triple powerpc-unknown-freebsd -emit-llvm -o - %s| FileCheck -check-prefix=SVR4-CHECK %s +// RUN: %clang_cc1 -triple powerpc-unknown-netbsd -emit-llvm -o - %s| FileCheck -check-prefix=SVR4-CHECK %s +// RUN: %clang_cc1 -triple powerpc-unknown-openbsd -emit-llvm -o - %s| FileCheck -check-prefix=SVR4-CHECK %s #include From ef182d5fb158ba871cdd9a42c0e6e694ba42ecaf Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Feb 2019 12:24:52 +0000 Subject: [PATCH 130/274] [WebAssembly] Backport custom import name changes for lld to 8.0. Specifically, this backports r352645, r352828, and r353473 to the 8.0 branch. The trunk patches don't apply cleanly to 8.0 due to some contemporaneous mass-rename and mass-clang-tidy patches, so this merges them to simplify rebasing. r352645 [WebAssembly] Fix crash with LTO + relocatable + undefined symbols r352828 [WebAssembly] Support imports from custom module names r353473 [WebAssembly] Fix imported function symbol names that differ from their import names in the .o format By Dan Gohman! llvm-svn: 353833 --- lld/test/wasm/data-layout.ll | 6 +- lld/test/wasm/import-module.ll | 21 +++ lld/test/wasm/import-names.ll | 27 ++++ lld/test/wasm/init-fini.ll | 86 ++++++------ lld/test/wasm/locals-duplicate.test | 146 ++++++++++----------- lld/test/wasm/lto/relocatable-undefined.ll | 36 +++++ lld/test/wasm/weak-alias.ll | 28 ++-- lld/wasm/Driver.cpp | 4 +- lld/wasm/InputChunks.cpp | 6 +- lld/wasm/InputFiles.cpp | 11 +- lld/wasm/LTO.cpp | 5 +- lld/wasm/LTO.h | 1 + lld/wasm/MarkLive.cpp | 2 +- lld/wasm/SymbolTable.cpp | 14 +- lld/wasm/SymbolTable.h | 10 +- lld/wasm/Symbols.h | 19 ++- lld/wasm/Writer.cpp | 106 +++++++++------ lld/wasm/Writer.h | 2 + 18 files changed, 332 insertions(+), 198 deletions(-) create mode 100644 lld/test/wasm/import-module.ll create mode 100644 lld/test/wasm/import-names.ll create mode 100644 lld/test/wasm/lto/relocatable-undefined.ll diff --git a/lld/test/wasm/data-layout.ll b/lld/test/wasm/data-layout.ll index b01c13ac9b82a..7c215efb0d8f4 100644 --- a/lld/test/wasm/data-layout.ll +++ b/lld/test/wasm/data-layout.ll @@ -85,10 +85,10 @@ target triple = "wasm32-unknown-unknown" ; RELOC: - Type: DATA ; RELOC-NEXT: Relocations: ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 -; RELOC-NEXT: Index: 6 +; RELOC-NEXT: Index: 3 ; RELOC-NEXT: Offset: 0x00000018 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 -; RELOC-NEXT: Index: 3 +; RELOC-NEXT: Index: 4 ; RELOC-NEXT: Offset: 0x0000002E ; RELOC-NEXT: Addend: 4 ; RELOC-NEXT: Segments: @@ -148,7 +148,7 @@ target triple = "wasm32-unknown-unknown" ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Segment: 2 ; RELOC-NEXT: Size: 4 -; RELOC: - Index: 6 +; RELOC-NEXT: - Index: 3 ; RELOC-NEXT: Kind: DATA ; RELOC-NEXT: Name: hello_str ; RELOC-NEXT: Flags: [ ] diff --git a/lld/test/wasm/import-module.ll b/lld/test/wasm/import-module.ll new file mode 100644 index 0000000000000..9a473194ce2c3 --- /dev/null +++ b/lld/test/wasm/import-module.ll @@ -0,0 +1,21 @@ +; RUN: llc -filetype=obj %s -o %t.o +; RUN: wasm-ld --allow-undefined -o %t.wasm %t.o +; RUN: obj2yaml %t.wasm | FileCheck %s + +target triple = "wasm32-unknown-unknown-wasm" + +define void @_start() { + call void @foo(); + ret void +} + +declare void @foo() #0 + +attributes #0 = { "wasm-import-module"="bar" } + +; CHECK: - Type: IMPORT +; CHECK-NEXT: Imports: +; CHECK-NEXT: - Module: bar +; CHECK-NEXT: Field: foo +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SigIndex: 0 diff --git a/lld/test/wasm/import-names.ll b/lld/test/wasm/import-names.ll new file mode 100644 index 0000000000000..a3953d3356198 --- /dev/null +++ b/lld/test/wasm/import-names.ll @@ -0,0 +1,27 @@ +; RUN: llc -filetype=obj %s -o %t.o +; RUN: wasm-ld --allow-undefined -o %t.wasm %t.o +; RUN: obj2yaml %t.wasm | FileCheck %s + +target triple = "wasm32-unknown-unknown" + +declare void @f0() #0 + +define void @_start() { + call void @f0() + ret void +} + +attributes #0 = { "wasm-import-module"="somewhere" "wasm-import-name"="something" } + +; CHECK: - Type: IMPORT +; CHECK-NEXT: Imports: +; CHECK-NEXT: - Module: somewhere +; CHECK-NEXT: Field: something +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SigIndex: 0 + +; CHECK: - Type: CUSTOM +; CHECK-NEXT: Name: name +; CHECK-NEXT: FunctionNames: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Name: f0 diff --git a/lld/test/wasm/init-fini.ll b/lld/test/wasm/init-fini.ll index 9a7f5357ef015..b17020b177c71 100644 --- a/lld/test/wasm/init-fini.ll +++ b/lld/test/wasm/init-fini.ll @@ -163,64 +163,64 @@ entry: ; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] ; RELOC-NEXT: Function: 7 ; RELOC-NEXT: - Index: 6 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: Name: __dso_handle +; RELOC-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN, UNDEFINED ] +; RELOC-NEXT: - Index: 7 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: externDtor +; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN, UNDEFINED ] +; RELOC-NEXT: Function: 0 +; RELOC-NEXT: - Index: 8 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: externCtor +; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN, UNDEFINED ] +; RELOC-NEXT: Function: 1 +; RELOC-NEXT: - Index: 9 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: myctor +; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; RELOC-NEXT: Function: 14 +; RELOC-NEXT: - Index: 10 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: mydtor +; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; RELOC-NEXT: Function: 15 +; RELOC-NEXT: - Index: 11 +; RELOC-NEXT: Kind: GLOBAL +; RELOC-NEXT: Name: __stack_pointer +; RELOC-NEXT: Flags: [ UNDEFINED ] +; RELOC-NEXT: Global: 0 +; RELOC-NEXT: - Index: 12 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: .Lcall_dtors.101 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] ; RELOC-NEXT: Function: 8 -; RELOC-NEXT: - Index: 7 +; RELOC-NEXT: - Index: 13 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: .Lregister_call_dtors.101 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] ; RELOC-NEXT: Function: 9 -; RELOC-NEXT: - Index: 8 -; RELOC-NEXT: Kind: DATA -; RELOC-NEXT: Name: __dso_handle -; RELOC-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN, UNDEFINED ] -; RELOC-NEXT: - Index: 9 +; RELOC-NEXT: - Index: 14 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: .Lcall_dtors.1001 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] ; RELOC-NEXT: Function: 10 -; RELOC-NEXT: - Index: 10 +; RELOC-NEXT: - Index: 15 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: .Lregister_call_dtors.1001 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] ; RELOC-NEXT: Function: 11 -; RELOC-NEXT: - Index: 11 +; RELOC-NEXT: - Index: 16 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: .Lcall_dtors.4000 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] ; RELOC-NEXT: Function: 12 -; RELOC-NEXT: - Index: 12 -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Name: externDtor -; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN, UNDEFINED ] -; RELOC-NEXT: Function: 0 -; RELOC-NEXT: - Index: 13 +; RELOC-NEXT: - Index: 17 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: .Lregister_call_dtors.4000 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] ; RELOC-NEXT: Function: 13 -; RELOC-NEXT: - Index: 14 -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Name: externCtor -; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN, UNDEFINED ] -; RELOC-NEXT: Function: 1 -; RELOC-NEXT: - Index: 15 -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Name: myctor -; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; RELOC-NEXT: Function: 14 -; RELOC-NEXT: - Index: 16 -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Name: mydtor -; RELOC-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; RELOC-NEXT: Function: 15 -; RELOC-NEXT: - Index: 17 -; RELOC-NEXT: Kind: GLOBAL -; RELOC-NEXT: Name: __stack_pointer -; RELOC-NEXT: Flags: [ UNDEFINED ] -; RELOC-NEXT: Global: 0 ; RELOC-NEXT: - Index: 18 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: .Lcall_dtors.101 @@ -251,36 +251,36 @@ entry: ; RELOC-NEXT: Name: .Lregister_call_dtors.2002 ; RELOC-NEXT: Flags: [ BINDING_LOCAL ] ; RELOC-NEXT: Function: 21 -; RELOC-NEXT: InitFunctions: +; RELOC-NEXT: InitFunctions: ; RELOC-NEXT: - Priority: 101 ; RELOC-NEXT: Symbol: 0 ; RELOC-NEXT: - Priority: 101 ; RELOC-NEXT: Symbol: 1 ; RELOC-NEXT: - Priority: 101 -; RELOC-NEXT: Symbol: 7 +; RELOC-NEXT: Symbol: 13 ; RELOC-NEXT: - Priority: 101 -; RELOC-NEXT: Symbol: 15 +; RELOC-NEXT: Symbol: 9 ; RELOC-NEXT: - Priority: 101 ; RELOC-NEXT: Symbol: 19 ; RELOC-NEXT: - Priority: 202 -; RELOC-NEXT: Symbol: 15 +; RELOC-NEXT: Symbol: 9 ; RELOC-NEXT: - Priority: 202 ; RELOC-NEXT: Symbol: 21 ; RELOC-NEXT: - Priority: 1001 ; RELOC-NEXT: Symbol: 0 ; RELOC-NEXT: - Priority: 1001 -; RELOC-NEXT: Symbol: 10 -; RELOC-NEXT: - Priority: 2002 ; RELOC-NEXT: Symbol: 15 ; RELOC-NEXT: - Priority: 2002 +; RELOC-NEXT: Symbol: 9 +; RELOC-NEXT: - Priority: 2002 ; RELOC-NEXT: Symbol: 23 ; RELOC-NEXT: - Priority: 4000 -; RELOC-NEXT: Symbol: 14 +; RELOC-NEXT: Symbol: 8 ; RELOC-NEXT: - Priority: 4000 -; RELOC-NEXT: Symbol: 13 +; RELOC-NEXT: Symbol: 17 ; RELOC-NEXT: - Type: CUSTOM ; RELOC-NEXT: Name: name -; RELOC-NEXT: FunctionNames: +; RELOC-NEXT: FunctionNames: ; RELOC-NEXT: - Index: 0 ; RELOC-NEXT: Name: externDtor ; RELOC-NEXT: - Index: 1 diff --git a/lld/test/wasm/locals-duplicate.test b/lld/test/wasm/locals-duplicate.test index 2d6bd0df5314c..74383bf429f69 100644 --- a/lld/test/wasm/locals-duplicate.test +++ b/lld/test/wasm/locals-duplicate.test @@ -270,40 +270,40 @@ ; RELOC-NEXT: - Type: CODE ; RELOC-NEXT: Relocations: ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB -; RELOC-NEXT: Index: 4 +; RELOC-NEXT: Index: 18 ; RELOC-NEXT: Offset: 0x00000013 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB -; RELOC-NEXT: Index: 6 +; RELOC-NEXT: Index: 3 ; RELOC-NEXT: Offset: 0x0000001C ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB -; RELOC-NEXT: Index: 8 +; RELOC-NEXT: Index: 19 ; RELOC-NEXT: Offset: 0x00000025 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB -; RELOC-NEXT: Index: 0 +; RELOC-NEXT: Index: 16 ; RELOC-NEXT: Offset: 0x0000002E ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB -; RELOC-NEXT: Index: 1 +; RELOC-NEXT: Index: 0 ; RELOC-NEXT: Offset: 0x00000037 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB -; RELOC-NEXT: Index: 2 +; RELOC-NEXT: Index: 17 ; RELOC-NEXT: Offset: 0x00000040 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB -; RELOC-NEXT: Index: 16 +; RELOC-NEXT: Index: 10 ; RELOC-NEXT: Offset: 0x00000058 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB -; RELOC-NEXT: Index: 18 +; RELOC-NEXT: Index: 22 ; RELOC-NEXT: Offset: 0x00000061 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB -; RELOC-NEXT: Index: 20 +; RELOC-NEXT: Index: 23 ; RELOC-NEXT: Offset: 0x0000006A ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB -; RELOC-NEXT: Index: 12 +; RELOC-NEXT: Index: 8 ; RELOC-NEXT: Offset: 0x00000073 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB -; RELOC-NEXT: Index: 13 +; RELOC-NEXT: Index: 20 ; RELOC-NEXT: Offset: 0x0000007C ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB -; RELOC-NEXT: Index: 14 +; RELOC-NEXT: Index: 21 ; RELOC-NEXT: Offset: 0x00000085 ; RELOC-NEXT: Functions: ; RELOC-NEXT: - Index: 0 @@ -386,133 +386,133 @@ ; RELOC-NEXT: SymbolTable: ; RELOC-NEXT: - Index: 0 ; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Name: colliding_func1 -; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: Function: 0 -; RELOC-NEXT: - Index: 1 -; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: colliding_func2 ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Function: 1 -; RELOC-NEXT: - Index: 2 -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Name: colliding_func3 -; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: Function: 2 -; RELOC-NEXT: - Index: 3 +; RELOC-NEXT: - Index: 1 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: get_global1A ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Function: 3 -; RELOC-NEXT: - Index: 4 -; RELOC-NEXT: Kind: DATA -; RELOC-NEXT: Name: colliding_global1 -; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: Segment: 0 -; RELOC-NEXT: Size: 4 -; RELOC-NEXT: - Index: 5 +; RELOC-NEXT: - Index: 2 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: get_global2A ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Function: 4 -; RELOC-NEXT: - Index: 6 +; RELOC-NEXT: - Index: 3 ; RELOC-NEXT: Kind: DATA ; RELOC-NEXT: Name: colliding_global2 ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Segment: 1 ; RELOC-NEXT: Size: 4 -; RELOC-NEXT: - Index: 7 +; RELOC-NEXT: - Index: 4 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: get_global3A ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Function: 5 -; RELOC-NEXT: - Index: 8 -; RELOC-NEXT: Kind: DATA -; RELOC-NEXT: Name: colliding_global3 -; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: Segment: 2 -; RELOC-NEXT: Size: 4 -; RELOC-NEXT: - Index: 9 +; RELOC-NEXT: - Index: 5 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: get_func1A ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Function: 6 -; RELOC-NEXT: - Index: 10 +; RELOC-NEXT: - Index: 6 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: get_func2A ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Function: 7 -; RELOC-NEXT: - Index: 11 +; RELOC-NEXT: - Index: 7 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: get_func3A ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Function: 8 -; RELOC-NEXT: - Index: 12 +; RELOC-NEXT: - Index: 8 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: colliding_func1 ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Function: 9 -; RELOC-NEXT: - Index: 13 -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Name: colliding_func2 -; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: Function: 10 -; RELOC-NEXT: - Index: 14 -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Name: colliding_func3 -; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: Function: 11 -; RELOC-NEXT: - Index: 15 +; RELOC-NEXT: - Index: 9 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: get_global1B ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Function: 12 -; RELOC-NEXT: - Index: 16 +; RELOC-NEXT: - Index: 10 ; RELOC-NEXT: Kind: DATA ; RELOC-NEXT: Name: colliding_global1 ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Segment: 0 ; RELOC-NEXT: Offset: 4 ; RELOC-NEXT: Size: 4 -; RELOC-NEXT: - Index: 17 +; RELOC-NEXT: - Index: 11 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: get_global2B ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Function: 13 -; RELOC-NEXT: - Index: 18 -; RELOC-NEXT: Kind: DATA -; RELOC-NEXT: Name: colliding_global2 -; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: Segment: 1 -; RELOC-NEXT: Offset: 4 -; RELOC-NEXT: Size: 4 -; RELOC-NEXT: - Index: 19 +; RELOC-NEXT: - Index: 12 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: get_global3B ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Function: 14 -; RELOC-NEXT: - Index: 20 -; RELOC-NEXT: Kind: DATA -; RELOC-NEXT: Name: colliding_global3 -; RELOC-NEXT: Flags: [ BINDING_LOCAL ] -; RELOC-NEXT: Segment: 2 -; RELOC-NEXT: Offset: 4 -; RELOC-NEXT: Size: 4 -; RELOC-NEXT: - Index: 21 +; RELOC-NEXT: - Index: 13 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: get_func1B ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Function: 15 -; RELOC-NEXT: - Index: 22 +; RELOC-NEXT: - Index: 14 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: get_func2B ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Function: 16 -; RELOC-NEXT: - Index: 23 +; RELOC-NEXT: - Index: 15 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: get_func3B ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Function: 17 +; RELOC-NEXT: - Index: 16 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: colliding_func1 +; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: Function: 0 +; RELOC-NEXT: - Index: 17 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: colliding_func3 +; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: Function: 2 +; RELOC-NEXT: - Index: 18 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: Name: colliding_global1 +; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: Segment: 0 +; RELOC-NEXT: Size: 4 +; RELOC-NEXT: - Index: 19 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: Name: colliding_global3 +; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: Segment: 2 +; RELOC-NEXT: Size: 4 +; RELOC-NEXT: - Index: 20 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: colliding_func2 +; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: Function: 10 +; RELOC-NEXT: - Index: 21 +; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: colliding_func3 +; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: Function: 11 +; RELOC-NEXT: - Index: 22 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: Name: colliding_global2 +; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: Segment: 1 +; RELOC-NEXT: Offset: 4 +; RELOC-NEXT: Size: 4 +; RELOC-NEXT: - Index: 23 +; RELOC-NEXT: Kind: DATA +; RELOC-NEXT: Name: colliding_global3 +; RELOC-NEXT: Flags: [ BINDING_LOCAL ] +; RELOC-NEXT: Segment: 2 +; RELOC-NEXT: Offset: 4 +; RELOC-NEXT: Size: 4 ; RELOC-NEXT: SegmentInfo: ; RELOC-NEXT: - Index: 0 ; RELOC-NEXT: Name: .bss.colliding_global1 diff --git a/lld/test/wasm/lto/relocatable-undefined.ll b/lld/test/wasm/lto/relocatable-undefined.ll new file mode 100644 index 0000000000000..b9780ee0309b2 --- /dev/null +++ b/lld/test/wasm/lto/relocatable-undefined.ll @@ -0,0 +1,36 @@ +; RUN: llvm-as %s -o %t.o +; RUN: wasm-ld -r -o %t.wasm %t.o +; RUN: obj2yaml %t.wasm | FileCheck %s + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +@missing_data = external global i32 +declare i32 @missing_func() local_unnamed_addr + +define i32 @foo() { +entry: + %0 = call i32 @missing_func() + %1 = load i32, i32* @missing_data, align 4 + ret i32 %1 +} + + +; CHECK: - Type: CUSTOM +; CHECK-NEXT: Name: linking +; CHECK-NEXT: Version: 2 +; CHECK-NEXT: SymbolTable: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: missing_func +; CHECK-NEXT: Flags: [ UNDEFINED ] +; CHECK-NEXT: Function: 0 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: foo +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: Function: 1 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: missing_data +; CHECK-NEXT: Flags: [ UNDEFINED ] diff --git a/lld/test/wasm/weak-alias.ll b/lld/test/wasm/weak-alias.ll index 0c856e1eafa09..a925c10ccda41 100644 --- a/lld/test/wasm/weak-alias.ll +++ b/lld/test/wasm/weak-alias.ll @@ -187,13 +187,13 @@ entry: ; RELOC-NEXT: - Type: CODE ; RELOC-NEXT: Relocations: ; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB -; RELOC-NEXT: Index: 4 +; RELOC-NEXT: Index: 1 ; RELOC-NEXT: Offset: 0x00000004 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB -; RELOC-NEXT: Index: 1 +; RELOC-NEXT: Index: 2 ; RELOC-NEXT: Offset: 0x00000013 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB -; RELOC-NEXT: Index: 4 +; RELOC-NEXT: Index: 1 ; RELOC-NEXT: Offset: 0x0000001C ; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB ; RELOC-NEXT: Index: 6 @@ -202,10 +202,10 @@ entry: ; RELOC-NEXT: Index: 6 ; RELOC-NEXT: Offset: 0x00000032 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB -; RELOC-NEXT: Index: 4 +; RELOC-NEXT: Index: 1 ; RELOC-NEXT: Offset: 0x0000003A ; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB -; RELOC-NEXT: Index: 4 +; RELOC-NEXT: Index: 1 ; RELOC-NEXT: Offset: 0x00000043 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB ; RELOC-NEXT: Index: 6 @@ -217,10 +217,10 @@ entry: ; RELOC-NEXT: Index: 6 ; RELOC-NEXT: Offset: 0x00000068 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB -; RELOC-NEXT: Index: 1 +; RELOC-NEXT: Index: 2 ; RELOC-NEXT: Offset: 0x00000070 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB -; RELOC-NEXT: Index: 1 +; RELOC-NEXT: Index: 2 ; RELOC-NEXT: Offset: 0x00000079 ; RELOC-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_INDEX_LEB ; RELOC-NEXT: Index: 6 @@ -259,24 +259,24 @@ entry: ; RELOC-NEXT: Function: 0 ; RELOC-NEXT: - Index: 1 ; RELOC-NEXT: Kind: FUNCTION +; RELOC-NEXT: Name: alias_fn +; RELOC-NEXT: Flags: [ BINDING_WEAK ] +; RELOC-NEXT: Function: 1 +; RELOC-NEXT: - Index: 2 +; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: direct_fn ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Function: 1 -; RELOC-NEXT: - Index: 2 +; RELOC-NEXT: - Index: 3 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: call_direct ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Function: 2 -; RELOC-NEXT: - Index: 3 +; RELOC-NEXT: - Index: 4 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: call_alias ; RELOC-NEXT: Flags: [ ] ; RELOC-NEXT: Function: 3 -; RELOC-NEXT: - Index: 4 -; RELOC-NEXT: Kind: FUNCTION -; RELOC-NEXT: Name: alias_fn -; RELOC-NEXT: Flags: [ BINDING_WEAK ] -; RELOC-NEXT: Function: 1 ; RELOC-NEXT: - Index: 5 ; RELOC-NEXT: Kind: FUNCTION ; RELOC-NEXT: Name: call_alias_ptr diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp index fab4c0c4ed8bb..ade15a19f66e0 100644 --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -434,7 +434,9 @@ static Symbol *handleUndefined(StringRef Name) { static UndefinedGlobal * createUndefinedGlobal(StringRef Name, llvm::wasm::WasmGlobalType *Type) { auto *Sym = - cast(Symtab->addUndefinedGlobal(Name, 0, nullptr, Type)); + cast(Symtab->addUndefinedGlobal(Name, Name, + DefaultModule, 0, + nullptr, Type)); Config->AllowUndefinedSymbols.insert(Sym->getName()); Sym->IsUsedInRegularObj = true; return Sym; diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp index 1145c670253c8..f5884a1beea4b 100644 --- a/lld/wasm/InputChunks.cpp +++ b/lld/wasm/InputChunks.cpp @@ -23,7 +23,7 @@ using namespace llvm::support::endian; using namespace lld; using namespace lld::wasm; -static StringRef ReloctTypeToString(uint8_t RelocType) { +static StringRef reloctTypeToString(uint8_t RelocType) { switch (RelocType) { #define WASM_RELOC(NAME, REL) \ case REL: \ @@ -77,7 +77,7 @@ void InputChunk::verifyRelocTargets() const { warn("expected LEB at relocation site be 5-byte padded"); uint32_t ExpectedValue = File->calcExpectedValue(Rel); if (ExpectedValue != ExistingValue) - warn("unexpected existing value for " + ReloctTypeToString(Rel.Type) + + warn("unexpected existing value for " + reloctTypeToString(Rel.Type) + ": existing=" + Twine(ExistingValue) + " expected=" + Twine(ExpectedValue)); } @@ -103,7 +103,7 @@ void InputChunk::writeTo(uint8_t *Buf) const { for (const WasmRelocation &Rel : Relocations) { uint8_t *Loc = Buf + Rel.Offset + Off; uint32_t Value = File->calcNewValue(Rel); - LLVM_DEBUG(dbgs() << "apply reloc: type=" << ReloctTypeToString(Rel.Type) + LLVM_DEBUG(dbgs() << "apply reloc: type=" << reloctTypeToString(Rel.Type) << " addend=" << Rel.Addend << " index=" << Rel.Index << " value=" << Value << " offset=" << Rel.Offset << "\n"); diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp index e5da23db37739..1e54272163545 100644 --- a/lld/wasm/InputFiles.cpp +++ b/lld/wasm/InputFiles.cpp @@ -377,11 +377,15 @@ Symbol *ObjFile::createUndefined(const WasmSymbol &Sym) { switch (Sym.Info.Kind) { case WASM_SYMBOL_TYPE_FUNCTION: - return Symtab->addUndefinedFunction(Name, Flags, this, Sym.Signature); + return Symtab->addUndefinedFunction(Name, Sym.Info.ImportName, + Sym.Info.ImportModule, Flags, this, + Sym.Signature); case WASM_SYMBOL_TYPE_DATA: return Symtab->addUndefinedData(Name, Flags, this); case WASM_SYMBOL_TYPE_GLOBAL: - return Symtab->addUndefinedGlobal(Name, Flags, this, Sym.GlobalType); + return Symtab->addUndefinedGlobal(Name, Sym.Info.ImportName, + Sym.Info.ImportModule, Flags, this, + Sym.GlobalType); case WASM_SYMBOL_TYPE_SECTION: llvm_unreachable("section symbols cannot be undefined"); } @@ -445,7 +449,8 @@ static Symbol *createBitcodeSymbol(const lto::InputFile::Symbol &ObjSym, if (ObjSym.isUndefined()) { if (ObjSym.isExecutable()) - return Symtab->addUndefinedFunction(Name, Flags, &F, nullptr); + return Symtab->addUndefinedFunction(Name, Name, DefaultModule, Flags, &F, + nullptr); return Symtab->addUndefinedData(Name, Flags, &F); } diff --git a/lld/wasm/LTO.cpp b/lld/wasm/LTO.cpp index 96a947e29d412..e994691cceb2e 100644 --- a/lld/wasm/LTO.cpp +++ b/lld/wasm/LTO.cpp @@ -79,8 +79,9 @@ BitcodeCompiler::~BitcodeCompiler() = default; static void undefine(Symbol *S) { if (auto F = dyn_cast(S)) - replaceSymbol(F, F->getName(), 0, F->getFile(), - F->Signature); + replaceSymbol(F, F->getName(), F->getName(), + DefaultModule, 0, + F->getFile(), F->Signature); else if (isa(S)) replaceSymbol(S, S->getName(), 0, S->getFile()); else diff --git a/lld/wasm/LTO.h b/lld/wasm/LTO.h index cf726de5643ae..d771301f224dc 100644 --- a/lld/wasm/LTO.h +++ b/lld/wasm/LTO.h @@ -23,6 +23,7 @@ #include "lld/Common/LLVM.h" #include "llvm/ADT/SmallString.h" +#include "Writer.h" #include #include diff --git a/lld/wasm/MarkLive.cpp b/lld/wasm/MarkLive.cpp index 3bbd1148f6ad3..723ac4e3c6baa 100644 --- a/lld/wasm/MarkLive.cpp +++ b/lld/wasm/MarkLive.cpp @@ -85,7 +85,7 @@ void lld::wasm::markLive() { // equal to null pointer, only reachable via direct call). if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB || Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32) { - FunctionSymbol *FuncSym = cast(Sym); + auto *FuncSym = cast(Sym); if (FuncSym->hasTableIndex() && FuncSym->getTableIndex() == 0) continue; } diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp index c7983196db36c..65441d293b50b 100644 --- a/lld/wasm/SymbolTable.cpp +++ b/lld/wasm/SymbolTable.cpp @@ -314,8 +314,9 @@ Symbol *SymbolTable::addDefinedEvent(StringRef Name, uint32_t Flags, return S; } -Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags, - InputFile *File, +Symbol *SymbolTable::addUndefinedFunction(StringRef Name, StringRef ImportName, + StringRef ImportModule, + uint32_t Flags, InputFile *File, const WasmSignature *Sig) { LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << " [" << (Sig ? toString(*Sig) : "none") << "]\n"); @@ -325,7 +326,8 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags, std::tie(S, WasInserted) = insert(Name, File); if (WasInserted) - replaceSymbol(S, Name, Flags, File, Sig); + replaceSymbol(S, Name, ImportName, ImportModule, Flags, + File, Sig); else if (auto *Lazy = dyn_cast(S)) Lazy->fetch(); else @@ -351,7 +353,8 @@ Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags, return S; } -Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags, +Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, StringRef ImportName, + StringRef ImportModule, uint32_t Flags, InputFile *File, const WasmGlobalType *Type) { LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << Name << "\n"); @@ -361,7 +364,8 @@ Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags, std::tie(S, WasInserted) = insert(Name, File); if (WasInserted) - replaceSymbol(S, Name, Flags, File, Type); + replaceSymbol(S, Name, ImportName, ImportModule, Flags, + File, Type); else if (auto *Lazy = dyn_cast(S)) Lazy->fetch(); else if (S->isDefined()) diff --git a/lld/wasm/SymbolTable.h b/lld/wasm/SymbolTable.h index 5e38e30692abe..64678aee50055 100644 --- a/lld/wasm/SymbolTable.h +++ b/lld/wasm/SymbolTable.h @@ -59,11 +59,13 @@ class SymbolTable { Symbol *addDefinedEvent(StringRef Name, uint32_t Flags, InputFile *File, InputEvent *E); - Symbol *addUndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File, - const WasmSignature *Signature); + Symbol *addUndefinedFunction(StringRef Name, StringRef ImportName, + StringRef ImportModule, uint32_t Flags, + InputFile *File, const WasmSignature *Signature); Symbol *addUndefinedData(StringRef Name, uint32_t Flags, InputFile *File); - Symbol *addUndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File, - const WasmGlobalType *Type); + Symbol *addUndefinedGlobal(StringRef Name, StringRef ImportName, + StringRef ImportModule, uint32_t Flags, + InputFile *File, const WasmGlobalType *Type); void addLazy(ArchiveFile *F, const llvm::object::Archive::Symbol *Sym); diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h index 11ee66550cdcc..a065338ac1e42 100644 --- a/lld/wasm/Symbols.h +++ b/lld/wasm/Symbols.h @@ -149,13 +149,19 @@ class DefinedFunction : public FunctionSymbol { class UndefinedFunction : public FunctionSymbol { public: - UndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File = nullptr, + UndefinedFunction(StringRef Name, StringRef ImportName, + StringRef ImportModule, uint32_t Flags, + InputFile *File = nullptr, const WasmSignature *Type = nullptr) - : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type) {} + : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File, Type), + ImportName(ImportName), ImportModule(ImportModule) {} static bool classof(const Symbol *S) { return S->kind() == UndefinedFunctionKind; } + + StringRef ImportName; + StringRef ImportModule; }; class SectionSymbol : public Symbol { @@ -261,13 +267,18 @@ class DefinedGlobal : public GlobalSymbol { class UndefinedGlobal : public GlobalSymbol { public: - UndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File = nullptr, + UndefinedGlobal(StringRef Name, StringRef ImportName, StringRef ImportModule, + uint32_t Flags, InputFile *File = nullptr, const WasmGlobalType *Type = nullptr) - : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, Type) {} + : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, Type), + ImportName(ImportName), ImportModule(ImportModule) {} static bool classof(const Symbol *S) { return S->kind() == UndefinedGlobalKind; } + + StringRef ImportName; + StringRef ImportModule; }; // Wasm events are features that suspend the current execution and transfer the diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp index 819d4298fef29..902ca61ca19b7 100644 --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -39,8 +39,9 @@ using namespace llvm::wasm; using namespace lld; using namespace lld::wasm; -static constexpr int kStackAlignment = 16; -static constexpr const char *kFunctionTableName = "__indirect_function_table"; +static constexpr int StackAlignment = 16; +static constexpr const char *FunctionTableName = "__indirect_function_table"; +const char *lld::wasm::DefaultModule = "env"; namespace { @@ -155,7 +156,7 @@ void Writer::createImportSection() { if (Config->ImportMemory) { WasmImport Import; - Import.Module = "env"; + Import.Module = DefaultModule; Import.Field = "memory"; Import.Kind = WASM_EXTERNAL_MEMORY; Import.Memory.Flags = 0; @@ -172,8 +173,8 @@ void Writer::createImportSection() { if (Config->ImportTable) { uint32_t TableSize = TableBase + IndirectFunctions.size(); WasmImport Import; - Import.Module = "env"; - Import.Field = kFunctionTableName; + Import.Module = DefaultModule; + Import.Field = FunctionTableName; Import.Kind = WASM_EXTERNAL_TABLE; Import.Table.ElemType = WASM_TYPE_FUNCREF; Import.Table.Limits = {0, TableSize, 0}; @@ -182,8 +183,17 @@ void Writer::createImportSection() { for (const Symbol *Sym : ImportedSymbols) { WasmImport Import; - Import.Module = "env"; - Import.Field = Sym->getName(); + if (auto *F = dyn_cast(Sym)) { + Import.Field = F->ImportName; + Import.Module = F->ImportModule; + } else if (auto *G = dyn_cast(Sym)) { + Import.Field = G->ImportName; + Import.Module = G->ImportModule; + } else { + Import.Field = Sym->getName(); + Import.Module = DefaultModule; + } + if (auto *FunctionSym = dyn_cast(Sym)) { Import.Kind = WASM_EXTERNAL_FUNCTION; Import.SigIndex = lookupType(*FunctionSym->Signature); @@ -441,6 +451,13 @@ static uint32_t getWasmFlags(const Symbol *Sym) { Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; if (Sym->isUndefined()) Flags |= WASM_SYMBOL_UNDEFINED; + if (auto *F = dyn_cast(Sym)) { + if (F->getName() != F->ImportName) + Flags |= WASM_SYMBOL_EXPLICIT_NAME; + } else if (auto *G = dyn_cast(Sym)) { + if (G->getName() != G->ImportName) + Flags |= WASM_SYMBOL_EXPLICIT_NAME; + } return Flags; } @@ -506,15 +523,18 @@ void Writer::createLinkingSection() { if (auto *F = dyn_cast(Sym)) { writeUleb128(Sub.OS, F->getFunctionIndex(), "index"); - if (Sym->isDefined()) + if (Sym->isDefined() || + (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) writeStr(Sub.OS, Sym->getName(), "sym name"); } else if (auto *G = dyn_cast(Sym)) { writeUleb128(Sub.OS, G->getGlobalIndex(), "index"); - if (Sym->isDefined()) + if (Sym->isDefined() || + (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) writeStr(Sub.OS, Sym->getName(), "sym name"); } else if (auto *E = dyn_cast(Sym)) { writeUleb128(Sub.OS, E->getEventIndex(), "index"); - if (Sym->isDefined()) + if (Sym->isDefined() || + (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) writeStr(Sub.OS, Sym->getName(), "sym name"); } else if (isa(Sym)) { writeStr(Sub.OS, Sym->getName(), "sym name"); @@ -663,9 +683,9 @@ void Writer::layoutMemory() { auto PlaceStack = [&]() { if (Config->Relocatable || Config->Shared) return; - MemoryPtr = alignTo(MemoryPtr, kStackAlignment); - if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment)) - error("stack size must be " + Twine(kStackAlignment) + "-byte aligned"); + MemoryPtr = alignTo(MemoryPtr, StackAlignment); + if (Config->ZStackSize != alignTo(Config->ZStackSize, StackAlignment)) + error("stack size must be " + Twine(StackAlignment) + "-byte aligned"); log("mem: stack size = " + Twine(Config->ZStackSize)); log("mem: stack base = " + Twine(MemoryPtr)); MemoryPtr += Config->ZStackSize; @@ -814,7 +834,7 @@ void Writer::calculateExports() { Exports.push_back(WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0}); if (!Config->Relocatable && Config->ExportTable) - Exports.push_back(WasmExport{kFunctionTableName, WASM_EXTERNAL_TABLE, 0}); + Exports.push_back(WasmExport{FunctionTableName, WASM_EXTERNAL_TABLE, 0}); unsigned FakeGlobalIndex = NumImportedGlobals + InputGlobals.size(); @@ -858,40 +878,42 @@ void Writer::assignSymtab() { StringMap SectionSymbolIndices; unsigned SymbolIndex = SymtabEntries.size(); - for (ObjFile *File : Symtab->ObjectFiles) { - LLVM_DEBUG(dbgs() << "Symtab entries: " << File->getName() << "\n"); - for (Symbol *Sym : File->getSymbols()) { - if (Sym->getFile() != File) - continue; - - if (auto *S = dyn_cast(Sym)) { - StringRef Name = S->getName(); - if (CustomSectionMapping.count(Name) == 0) - continue; - - auto SSI = SectionSymbolIndices.find(Name); - if (SSI != SectionSymbolIndices.end()) { - Sym->setOutputSymbolIndex(SSI->second); - continue; - } - SectionSymbolIndices[Name] = SymbolIndex; - CustomSectionSymbols[Name] = cast(Sym); + auto AddSymbol = [&](Symbol *Sym) { + if (auto *S = dyn_cast(Sym)) { + StringRef Name = S->getName(); + if (CustomSectionMapping.count(Name) == 0) + return; - Sym->markLive(); + auto SSI = SectionSymbolIndices.find(Name); + if (SSI != SectionSymbolIndices.end()) { + Sym->setOutputSymbolIndex(SSI->second); + return; } - // (Since this is relocatable output, GC is not performed so symbols must - // be live.) - assert(Sym->isLive()); - Sym->setOutputSymbolIndex(SymbolIndex++); - SymtabEntries.emplace_back(Sym); + SectionSymbolIndices[Name] = SymbolIndex; + CustomSectionSymbols[Name] = cast(Sym); + + Sym->markLive(); } - } - // For the moment, relocatable output doesn't contain any synthetic functions, - // so no need to look through the Symtab for symbols not referenced by - // Symtab->ObjectFiles. + // (Since this is relocatable output, GC is not performed so symbols must + // be live.) + assert(Sym->isLive()); + Sym->setOutputSymbolIndex(SymbolIndex++); + SymtabEntries.emplace_back(Sym); + }; + + for (Symbol *Sym : Symtab->getSymbols()) + if (!Sym->isLazy()) + AddSymbol(Sym); + + for (ObjFile *File : Symtab->ObjectFiles) { + LLVM_DEBUG(dbgs() << "Local symtab entries: " << File->getName() << "\n"); + for (Symbol *Sym : File->getSymbols()) + if (Sym->isLocal()) + AddSymbol(Sym); + } } uint32_t Writer::lookupType(const WasmSignature &Sig) { diff --git a/lld/wasm/Writer.h b/lld/wasm/Writer.h index a931ba9c29a89..e62f470642285 100644 --- a/lld/wasm/Writer.h +++ b/lld/wasm/Writer.h @@ -15,6 +15,8 @@ namespace wasm { void writeResult(); +extern const char *DefaultModule; + } // namespace wasm } // namespace lld From 16b7c0877ddfda5b4d6de21fcbce687854c5216d Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Feb 2019 12:26:10 +0000 Subject: [PATCH 131/274] [WebAssembly] Backport custom import name changes for clang to 8.0. Specifically, this backports r352106, r352108, r352930, and r352936 to the 8.0 branch. The trunk patches don't apply cleanly to 8.0 due to some contemporaneous mass-rename and mass-clang-tidy patches, so this merges them to simplify rebasing. r352106 [WebAssembly] Add an import_module function attribute r352108 [WebAssembly] Add WebAssemblyImportModule to pragma-attribute-supported-attributes-list.test r352930 [WebAssembly] Add an import_field function attribute r352936 [WebAssembly] Fix ImportName's position in this test. By Dan Gohman! llvm-svn: 353834 --- clang/include/clang/Basic/Attr.td | 17 +++++++ clang/include/clang/Basic/AttrDocs.td | 35 ++++++++++++- clang/lib/CodeGen/TargetInfo.cpp | 16 ++++++ clang/lib/Sema/SemaDeclAttr.cpp | 51 +++++++++++++++++++ clang/test/CodeGen/wasm-import-module.c | 11 ++++ clang/test/CodeGen/wasm-import-name.c | 11 ++++ ...a-attribute-supported-attributes-list.test | 2 + 7 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 clang/test/CodeGen/wasm-import-module.c create mode 100644 clang/test/CodeGen/wasm-import-name.c diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 1fe1dd39948a1..bf1068019b77b 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -329,6 +329,7 @@ def TargetMSP430 : TargetArch<["msp430"]>; def TargetRISCV : TargetArch<["riscv32", "riscv64"]>; def TargetX86 : TargetArch<["x86"]>; def TargetAnyX86 : TargetArch<["x86", "x86_64"]>; +def TargetWebAssembly : TargetArch<["wasm32", "wasm64"]>; def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> { let OSes = ["Win32"]; } @@ -1500,6 +1501,22 @@ def AMDGPUNumVGPR : InheritableAttr { let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; } +def WebAssemblyImportModule : InheritableAttr, + TargetSpecificAttr { + let Spellings = [Clang<"import_module">]; + let Args = [StringArgument<"ImportModule">]; + let Documentation = [WebAssemblyImportModuleDocs]; + let Subjects = SubjectList<[Function], ErrorDiag>; +} + +def WebAssemblyImportName : InheritableAttr, + TargetSpecificAttr { + let Spellings = [Clang<"import_name">]; + let Args = [StringArgument<"ImportName">]; + let Documentation = [WebAssemblyImportNameDocs]; + let Subjects = SubjectList<[Function], ErrorDiag>; +} + def NoSplitStack : InheritableAttr { let Spellings = [GCC<"no_split_stack">]; let Subjects = SubjectList<[Function], ErrorDiag>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 5773a92c9c15d..94c8343d2368f 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3652,7 +3652,40 @@ definition ( For more information see `gcc documentation `_ or `msvc documentation `_. -}]; +}]; } + +def WebAssemblyImportModuleDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports the ``__attribute__((import_module()))`` +attribute for the WebAssembly target. This attribute may be attached to a +function declaration, where it modifies how the symbol is to be imported +within the WebAssembly linking environment. + +WebAssembly imports use a two-level namespace scheme, consisting of a module +name, which typically identifies a module from which to import, and a field +name, which typically identifies a field from that module to import. By +default, module names for C/C++ symbols are assigned automatically by the +linker. This attribute can be used to override the default behavior, and +reuqest a specific module name be used instead. + }]; +} + +def WebAssemblyImportNameDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports the ``__attribute__((import_name()))`` +attribute for the WebAssembly target. This attribute may be attached to a +function declaration, where it modifies how the symbol is to be imported +within the WebAssembly linking environment. + +WebAssembly imports use a two-level namespace scheme, consisting of a module +name, which typically identifies a module from which to import, and a field +name, which typically identifies a field from that module to import. By +default, field names for C/C++ symbols are the same as their C/C++ symbol +names. This attribute can be used to override the default behavior, and +reuqest a specific field name be used instead. + }]; } def ArtificialDocs : Documentation { diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index f5a770ed9d844..94fccb15ff6ec 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -761,6 +761,22 @@ class WebAssemblyTargetCodeGenInfo final : public TargetCodeGenInfo { void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const override { + TargetCodeGenInfo::setTargetAttributes(D, GV, CGM); + if (const auto *FD = dyn_cast_or_null(D)) { + if (const auto *Attr = FD->getAttr()) { + llvm::Function *Fn = cast(GV); + llvm::AttrBuilder B; + B.addAttribute("wasm-import-module", Attr->getImportModule()); + Fn->addAttributes(llvm::AttributeList::FunctionIndex, B); + } + if (const auto *Attr = FD->getAttr()) { + llvm::Function *Fn = cast(GV); + llvm::AttrBuilder B; + B.addAttribute("wasm-import-name", Attr->getImportName()); + Fn->addAttributes(llvm::AttributeList::FunctionIndex, B); + } + } + if (auto *FD = dyn_cast_or_null(D)) { llvm::Function *Fn = cast(GV); if (!FD->doesThisDeclarationHaveABody() && !FD->hasPrototype()) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 139ac8aab4333..8819f0396a270 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5577,6 +5577,51 @@ static void handleAVRSignalAttr(Sema &S, Decl *D, const ParsedAttr &AL) { handleSimpleAttribute(S, D, AL); } +static void handleWebAssemblyImportModuleAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + if (!isFunctionOrMethod(D)) { + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'import_module'" << ExpectedFunction; + return; + } + + auto *FD = cast(D); + if (FD->isThisDeclarationADefinition()) { + S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0; + return; + } + + StringRef Str; + SourceLocation ArgLoc; + if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc)) + return; + + FD->addAttr(::new (S.Context) WebAssemblyImportModuleAttr( + AL.getRange(), S.Context, Str, + AL.getAttributeSpellingListIndex())); +} + +static void handleWebAssemblyImportNameAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + if (!isFunctionOrMethod(D)) { + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'import_name'" << ExpectedFunction; + return; + } + + auto *FD = cast(D); + if (FD->isThisDeclarationADefinition()) { + S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0; + return; + } + + StringRef Str; + SourceLocation ArgLoc; + if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc)) + return; + + FD->addAttr(::new (S.Context) WebAssemblyImportNameAttr( + AL.getRange(), S.Context, Str, + AL.getAttributeSpellingListIndex())); +} static void handleRISCVInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) { @@ -6330,6 +6375,12 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case ParsedAttr::AT_AVRSignal: handleAVRSignalAttr(S, D, AL); break; + case ParsedAttr::AT_WebAssemblyImportModule: + handleWebAssemblyImportModuleAttr(S, D, AL); + break; + case ParsedAttr::AT_WebAssemblyImportName: + handleWebAssemblyImportNameAttr(S, D, AL); + break; case ParsedAttr::AT_IBAction: handleSimpleAttribute(S, D, AL); break; diff --git a/clang/test/CodeGen/wasm-import-module.c b/clang/test/CodeGen/wasm-import-module.c new file mode 100644 index 0000000000000..866a3a459949b --- /dev/null +++ b/clang/test/CodeGen/wasm-import-module.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple wasm32-unknown-unknown-wasm -emit-llvm -o - %s | FileCheck %s + +void __attribute__((import_module("bar"))) foo(void); + +void call(void) { + foo(); +} + +// CHECK: declare void @foo() [[A:#[0-9]+]] + +// CHECK: attributes [[A]] = {{{.*}} "wasm-import-module"="bar" {{.*}}} diff --git a/clang/test/CodeGen/wasm-import-name.c b/clang/test/CodeGen/wasm-import-name.c new file mode 100644 index 0000000000000..7c3b094b9e435 --- /dev/null +++ b/clang/test/CodeGen/wasm-import-name.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple wasm32-unknown-unknown-wasm -emit-llvm -o - %s | FileCheck %s + +void __attribute__((import_name("bar"))) foo(void); + +void call(void) { + foo(); +} + +// CHECK: declare void @foo() [[A:#[0-9]+]] + +// CHECK: attributes [[A]] = {{{.*}} "wasm-import-name"="bar" {{.*}}} diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index 9a6bcca1bd36b..98935fc21355b 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -136,6 +136,8 @@ // CHECK-NEXT: WarnUnusedResult (SubjectMatchRule_objc_method, SubjectMatchRule_enum, SubjectMatchRule_record, SubjectMatchRule_hasType_functionType) // CHECK-NEXT: Weak (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record) // CHECK-NEXT: WeakRef (SubjectMatchRule_variable, SubjectMatchRule_function) +// CHECK-NEXT: WebAssemblyImportModule (SubjectMatchRule_function) +// CHECK-NEXT: WebAssemblyImportName (SubjectMatchRule_function) // CHECK-NEXT: WorkGroupSizeHint (SubjectMatchRule_function) // CHECK-NEXT: XRayInstrument (SubjectMatchRule_function, SubjectMatchRule_objc_method) // CHECK-NEXT: XRayLogArgs (SubjectMatchRule_function, SubjectMatchRule_objc_method) From 33a2b521c91475e12126fbe1d5b800d26f90a2fc Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Feb 2019 12:27:08 +0000 Subject: [PATCH 132/274] [WebAssembly] Backport custom import name changes for LLVM to 8.0. Specifically, this backports r352479, r352931, r353474, and r353476 to the 8.0 branch. The trunk patches don't apply cleanly to 8.0 due to some contemporaneous mass-rename and mass-clang-tidy patches, so this merges them to simplify rebasing. r352479 [WebAssembly] Re-enable main-function signature rewriting r352931 [WebAssembly] Add codegen support for the import_field attribute r353474 [WebAssembly] Fix imported function symbol names that differ from their import names in the .o format r353476 [WebAssembly] Update test output after rL353474. NFC. By Dan Gohman! llvm-svn: 353835 --- llvm/include/llvm/BinaryFormat/Wasm.h | 4 ++- llvm/include/llvm/MC/MCSymbolWasm.h | 22 +++++++++--- llvm/lib/MC/WasmObjectWriter.cpp | 25 +++++++------ llvm/lib/Object/WasmObjectFile.cpp | 22 +++++++++--- .../WebAssemblyTargetStreamer.cpp | 11 ++++-- .../MCTargetDesc/WebAssemblyTargetStreamer.h | 13 +++++-- .../WebAssembly/WebAssemblyAsmPrinter.cpp | 9 ++++- .../WebAssemblyFixFunctionBitcasts.cpp | 36 ++++++++++++------- llvm/test/CodeGen/WebAssembly/call.ll | 4 +-- .../WebAssembly/function-bitcasts-varargs.ll | 2 +- .../CodeGen/WebAssembly/function-bitcasts.ll | 2 +- .../test/CodeGen/WebAssembly/import-module.ll | 3 +- .../CodeGen/WebAssembly/main-declaration.ll | 16 ++++----- llvm/test/CodeGen/WebAssembly/main-no-args.ll | 13 +++---- .../CodeGen/WebAssembly/main-three-args.ll | 16 +++++++++ .../CodeGen/WebAssembly/main-with-args.ll | 2 +- .../MC/WebAssembly/external-func-address.ll | 4 +-- llvm/test/MC/WebAssembly/import-module.ll | 31 ++++++++++++++++ llvm/tools/yaml2obj/yaml2wasm.cpp | 3 +- 19 files changed, 176 insertions(+), 62 deletions(-) create mode 100644 llvm/test/CodeGen/WebAssembly/main-three-args.ll create mode 100644 llvm/test/MC/WebAssembly/import-module.ll diff --git a/llvm/include/llvm/BinaryFormat/Wasm.h b/llvm/include/llvm/BinaryFormat/Wasm.h index d9f0f94b298d4..b02ddb6b7e299 100644 --- a/llvm/include/llvm/BinaryFormat/Wasm.h +++ b/llvm/include/llvm/BinaryFormat/Wasm.h @@ -165,7 +165,8 @@ struct WasmSymbolInfo { StringRef Name; uint8_t Kind; uint32_t Flags; - StringRef Module; // For undefined symbols the module name of the import + StringRef ImportModule; // For undefined symbols the module of the import + StringRef ImportName; // For undefined symbols the name of the import union { // For function or global symbols, the index in function or global index // space. @@ -284,6 +285,7 @@ const unsigned WASM_SYMBOL_BINDING_LOCAL = 0x2; const unsigned WASM_SYMBOL_VISIBILITY_DEFAULT = 0x0; const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4; const unsigned WASM_SYMBOL_UNDEFINED = 0x10; +const unsigned WASM_SYMBOL_EXPLICIT_NAME = 0x40; #define WASM_RELOC(name, value) name = value, diff --git a/llvm/include/llvm/MC/MCSymbolWasm.h b/llvm/include/llvm/MC/MCSymbolWasm.h index 8e66dc881d0fb..34639b6ebb640 100644 --- a/llvm/include/llvm/MC/MCSymbolWasm.h +++ b/llvm/include/llvm/MC/MCSymbolWasm.h @@ -19,7 +19,8 @@ class MCSymbolWasm : public MCSymbol { bool IsWeak = false; bool IsHidden = false; bool IsComdat = false; - std::string ModuleName; + Optional ImportModule; + Optional ImportName; wasm::WasmSignature *Signature = nullptr; Optional GlobalType; Optional EventType; @@ -32,7 +33,7 @@ class MCSymbolWasm : public MCSymbol { // Use a module name of "env" for now, for compatibility with existing tools. // This is temporary, and may change, as the ABI is not yet stable. MCSymbolWasm(const StringMapEntry *Name, bool isTemporary) - : MCSymbol(SymbolKindWasm, Name, isTemporary), ModuleName("env") {} + : MCSymbol(SymbolKindWasm, Name, isTemporary) {} static bool classof(const MCSymbol *S) { return S->isWasm(); } const MCExpr *getSize() const { return SymbolSize; } @@ -55,8 +56,21 @@ class MCSymbolWasm : public MCSymbol { bool isComdat() const { return IsComdat; } void setComdat(bool isComdat) { IsComdat = isComdat; } - const StringRef getModuleName() const { return ModuleName; } - void setModuleName(StringRef Name) { ModuleName = Name; } + const StringRef getImportModule() const { + if (ImportModule.hasValue()) { + return ImportModule.getValue(); + } + return "env"; + } + void setImportModule(StringRef Name) { ImportModule = Name; } + + const StringRef getImportName() const { + if (ImportName.hasValue()) { + return ImportName.getValue(); + } + return getName(); + } + void setImportName(StringRef Name) { ImportName = Name; } const wasm::WasmSignature *getSignature() const { return Signature; } void setSignature(wasm::WasmSignature *Sig) { Signature = Sig; } diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp index 0cca3757be907..333748db91904 100644 --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -982,7 +982,8 @@ void WasmObjectWriter::writeLinkingMetaDataSection( case wasm::WASM_SYMBOL_TYPE_GLOBAL: case wasm::WASM_SYMBOL_TYPE_EVENT: encodeULEB128(Sym.ElementIndex, W.OS); - if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) + if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 || + (Sym.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) writeString(Sym.Name); break; case wasm::WASM_SYMBOL_TYPE_DATA: @@ -1162,8 +1163,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, MCSymbolWasm *MemorySym = cast(Ctx.getOrCreateSymbol("__linear_memory")); wasm::WasmImport MemImport; - MemImport.Module = MemorySym->getModuleName(); - MemImport.Field = MemorySym->getName(); + MemImport.Module = MemorySym->getImportModule(); + MemImport.Field = MemorySym->getImportName(); MemImport.Kind = wasm::WASM_EXTERNAL_MEMORY; Imports.push_back(MemImport); @@ -1173,8 +1174,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, MCSymbolWasm *TableSym = cast(Ctx.getOrCreateSymbol("__indirect_function_table")); wasm::WasmImport TableImport; - TableImport.Module = TableSym->getModuleName(); - TableImport.Field = TableSym->getName(); + TableImport.Module = TableSym->getImportModule(); + TableImport.Field = TableSym->getImportName(); TableImport.Kind = wasm::WASM_EXTERNAL_TABLE; TableImport.Table.ElemType = wasm::WASM_TYPE_FUNCREF; Imports.push_back(TableImport); @@ -1200,8 +1201,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, if (!WS.isDefined() && !WS.isComdat()) { if (WS.isFunction()) { wasm::WasmImport Import; - Import.Module = WS.getModuleName(); - Import.Field = WS.getName(); + Import.Module = WS.getImportModule(); + Import.Field = WS.getImportName(); Import.Kind = wasm::WASM_EXTERNAL_FUNCTION; Import.SigIndex = getFunctionType(WS); Imports.push_back(Import); @@ -1211,8 +1212,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, report_fatal_error("undefined global symbol cannot be weak"); wasm::WasmImport Import; - Import.Module = WS.getModuleName(); - Import.Field = WS.getName(); + Import.Module = WS.getImportModule(); + Import.Field = WS.getImportName(); Import.Kind = wasm::WASM_EXTERNAL_GLOBAL; Import.Global = WS.getGlobalType(); Imports.push_back(Import); @@ -1222,8 +1223,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, report_fatal_error("undefined event symbol cannot be weak"); wasm::WasmImport Import; - Import.Module = WS.getModuleName(); - Import.Field = WS.getName(); + Import.Module = WS.getImportModule(); + Import.Field = WS.getImportName(); Import.Kind = wasm::WASM_EXTERNAL_EVENT; Import.Event.Attribute = wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION; Import.Event.SigIndex = getEventType(WS); @@ -1448,6 +1449,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL; if (WS.isUndefined()) Flags |= wasm::WASM_SYMBOL_UNDEFINED; + if (WS.getName() != WS.getImportName()) + Flags |= wasm::WASM_SYMBOL_EXPLICIT_NAME; wasm::WasmSymbolInfo Info; Info.Name = WS.getName(); diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp index d84cb48c9fbd5..66a53becbb056 100644 --- a/llvm/lib/Object/WasmObjectFile.cpp +++ b/llvm/lib/Object/WasmObjectFile.cpp @@ -505,9 +505,13 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { Function.SymbolName = Info.Name; } else { wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex]; + if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) + Info.Name = readString(Ctx); + else + Info.Name = Import.Field; Signature = &Signatures[Import.SigIndex]; - Info.Name = Import.Field; - Info.Module = Import.Module; + Info.ImportName = Import.Field; + Info.ImportModule = Import.Module; } break; @@ -530,8 +534,13 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { Global.SymbolName = Info.Name; } else { wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex]; - Info.Name = Import.Field; + if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) + Info.Name = readString(Ctx); + else + Info.Name = Import.Field; GlobalType = &Import.Global; + Info.ImportName = Import.Field; + Info.ImportModule = Import.Module; } break; @@ -585,9 +594,14 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { } else { wasm::WasmImport &Import = *ImportedEvents[Info.ElementIndex]; + if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) + Info.Name = readString(Ctx); + else + Info.Name = Import.Field; EventType = &Import.Event; Signature = &Signatures[EventType->SigIndex]; - Info.Name = Import.Field; + Info.ImportName = Import.Field; + Info.ImportModule = Import.Module; } break; } diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp index 50143fb0ece36..7caeebb1a9aad 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp @@ -113,8 +113,15 @@ void WebAssemblyTargetAsmStreamer::emitEventType(const MCSymbolWasm *Sym) { } void WebAssemblyTargetAsmStreamer::emitImportModule(const MCSymbolWasm *Sym, - StringRef ModuleName) { - OS << "\t.import_module\t" << Sym->getName() << ", " << ModuleName << '\n'; + StringRef ImportModule) { + OS << "\t.import_module\t" << Sym->getName() << ", " + << ImportModule << '\n'; +} + +void WebAssemblyTargetAsmStreamer::emitImportName(const MCSymbolWasm *Sym, + StringRef ImportName) { + OS << "\t.import_name\t" << Sym->getName() << ", " + << ImportName << '\n'; } void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) { diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h index 3073938118b45..2ee9956c8e384 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h @@ -45,7 +45,10 @@ class WebAssemblyTargetStreamer : public MCTargetStreamer { virtual void emitEventType(const MCSymbolWasm *Sym) = 0; /// .import_module virtual void emitImportModule(const MCSymbolWasm *Sym, - StringRef ModuleName) = 0; + StringRef ImportModule) = 0; + /// .import_name + virtual void emitImportName(const MCSymbolWasm *Sym, + StringRef ImportName) = 0; protected: void emitValueType(wasm::ValType Type); @@ -67,7 +70,8 @@ class WebAssemblyTargetAsmStreamer final : public WebAssemblyTargetStreamer { void emitIndIdx(const MCExpr *Value) override; void emitGlobalType(const MCSymbolWasm *Sym) override; void emitEventType(const MCSymbolWasm *Sym) override; - void emitImportModule(const MCSymbolWasm *Sym, StringRef ModuleName) override; + void emitImportModule(const MCSymbolWasm *Sym, StringRef ImportModule) override; + void emitImportName(const MCSymbolWasm *Sym, StringRef ImportName) override; }; /// This part is for Wasm object output @@ -82,7 +86,9 @@ class WebAssemblyTargetWasmStreamer final : public WebAssemblyTargetStreamer { void emitGlobalType(const MCSymbolWasm *Sym) override {} void emitEventType(const MCSymbolWasm *Sym) override {} void emitImportModule(const MCSymbolWasm *Sym, - StringRef ModuleName) override {} + StringRef ImportModule) override {} + void emitImportName(const MCSymbolWasm *Sym, + StringRef ImportName) override {} }; /// This part is for null output @@ -98,6 +104,7 @@ class WebAssemblyTargetNullStreamer final : public WebAssemblyTargetStreamer { void emitGlobalType(const MCSymbolWasm *) override {} void emitEventType(const MCSymbolWasm *) override {} void emitImportModule(const MCSymbolWasm *, StringRef) override {} + void emitImportName(const MCSymbolWasm *, StringRef) override {} }; } // end namespace llvm diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp index c4f03dfa7f9e4..b492d11469507 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -111,9 +111,16 @@ void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) { F.hasFnAttribute("wasm-import-module")) { StringRef Name = F.getFnAttribute("wasm-import-module").getValueAsString(); - Sym->setModuleName(Name); + Sym->setImportModule(Name); getTargetStreamer()->emitImportModule(Sym, Name); } + if (TM.getTargetTriple().isOSBinFormatWasm() && + F.hasFnAttribute("wasm-import-name")) { + StringRef Name = + F.getFnAttribute("wasm-import-name").getValueAsString(); + Sym->setImportName(Name); + getTargetStreamer()->emitImportName(Sym, Name); + } } } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp index 1a416520f97d0..13f37f611ed05 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp @@ -36,11 +36,6 @@ using namespace llvm; #define DEBUG_TYPE "wasm-fix-function-bitcasts" -static cl::opt - TemporaryWorkarounds("wasm-temporary-workarounds", - cl::desc("Apply certain temporary workarounds"), - cl::init(true), cl::Hidden); - namespace { class FixFunctionBitcasts final : public ModulePass { StringRef getPassName() const override { @@ -227,6 +222,17 @@ static Function *CreateWrapper(Function *F, FunctionType *Ty) { return Wrapper; } +// Test whether a main function with type FuncTy should be rewritten to have +// type MainTy. +bool shouldFixMainFunction(FunctionType *FuncTy, FunctionType *MainTy) { + // Only fix the main function if it's the standard zero-arg form. That way, + // the standard cases will work as expected, and users will see signature + // mismatches from the linker for non-standard cases. + return FuncTy->getReturnType() == MainTy->getReturnType() && + FuncTy->getNumParams() == 0 && + !FuncTy->isVarArg(); +} + bool FixFunctionBitcasts::runOnModule(Module &M) { LLVM_DEBUG(dbgs() << "********** Fix Function Bitcasts **********\n"); @@ -243,14 +249,14 @@ bool FixFunctionBitcasts::runOnModule(Module &M) { // "int main(int argc, char *argv[])", create an artificial call with it // bitcasted to that type so that we generate a wrapper for it, so that // the C runtime can call it. - if (!TemporaryWorkarounds && !F.isDeclaration() && F.getName() == "main") { + if (F.getName() == "main") { Main = &F; LLVMContext &C = M.getContext(); Type *MainArgTys[] = {Type::getInt32Ty(C), PointerType::get(Type::getInt8PtrTy(C), 0)}; FunctionType *MainTy = FunctionType::get(Type::getInt32Ty(C), MainArgTys, /*isVarArg=*/false); - if (F.getFunctionType() != MainTy) { + if (shouldFixMainFunction(F.getFunctionType(), MainTy)) { LLVM_DEBUG(dbgs() << "Found `main` function with incorrect type: " << *F.getFunctionType() << "\n"); Value *Args[] = {UndefValue::get(MainArgTys[0]), @@ -298,12 +304,18 @@ bool FixFunctionBitcasts::runOnModule(Module &M) { Main->setName("__original_main"); Function *MainWrapper = cast(CallMain->getCalledValue()->stripPointerCasts()); - MainWrapper->setName("main"); - MainWrapper->setLinkage(Main->getLinkage()); - MainWrapper->setVisibility(Main->getVisibility()); - Main->setLinkage(Function::PrivateLinkage); - Main->setVisibility(Function::DefaultVisibility); delete CallMain; + if (Main->isDeclaration()) { + // The wrapper is not needed in this case as we don't need to export + // it to anyone else. + MainWrapper->eraseFromParent(); + } else { + // Otherwise give the wrapper the same linkage as the original main + // function, so that it can be called from the same places. + MainWrapper->setName("main"); + MainWrapper->setLinkage(Main->getLinkage()); + MainWrapper->setVisibility(Main->getVisibility()); + } } return true; diff --git a/llvm/test/CodeGen/WebAssembly/call.ll b/llvm/test/CodeGen/WebAssembly/call.ll index db666a6c36686..77f17c850edab 100644 --- a/llvm/test/CodeGen/WebAssembly/call.ll +++ b/llvm/test/CodeGen/WebAssembly/call.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -wasm-temporary-workarounds=false -mattr=+sign-ext,+simd128 | FileCheck %s -; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -fast-isel -fast-isel-abort=1 -wasm-temporary-workarounds=false -mattr=+sign-ext,+simd128 | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -mattr=+sign-ext,+simd128 | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -fast-isel -fast-isel-abort=1 -mattr=+sign-ext,+simd128 | FileCheck %s ; Test that basic call operations assemble as expected. diff --git a/llvm/test/CodeGen/WebAssembly/function-bitcasts-varargs.ll b/llvm/test/CodeGen/WebAssembly/function-bitcasts-varargs.ll index 515c5703d86c0..b542276e068f6 100644 --- a/llvm/test/CodeGen/WebAssembly/function-bitcasts-varargs.ll +++ b/llvm/test/CodeGen/WebAssembly/function-bitcasts-varargs.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false -wasm-temporary-workarounds=false -wasm-keep-registers | FileCheck %s +; RUN: llc < %s -asm-verbose=false -wasm-keep-registers | FileCheck %s ; Test that function pointer casts casting away varargs are replaced with ; wrappers. diff --git a/llvm/test/CodeGen/WebAssembly/function-bitcasts.ll b/llvm/test/CodeGen/WebAssembly/function-bitcasts.ll index a779cbe414225..813e8420ae54b 100644 --- a/llvm/test/CodeGen/WebAssembly/function-bitcasts.ll +++ b/llvm/test/CodeGen/WebAssembly/function-bitcasts.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false -wasm-disable-explicit-locals -wasm-keep-registers -enable-emscripten-cxx-exceptions -wasm-temporary-workarounds=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -wasm-disable-explicit-locals -wasm-keep-registers -enable-emscripten-cxx-exceptions | FileCheck %s ; Test that function pointer casts are replaced with wrappers. diff --git a/llvm/test/CodeGen/WebAssembly/import-module.ll b/llvm/test/CodeGen/WebAssembly/import-module.ll index a8202a77acb5a..0cf0f2f25e0b9 100644 --- a/llvm/test/CodeGen/WebAssembly/import-module.ll +++ b/llvm/test/CodeGen/WebAssembly/import-module.ll @@ -12,8 +12,9 @@ define void @test() { declare void @foo() #0 declare void @plain() -attributes #0 = { "wasm-import-module"="bar" } +attributes #0 = { "wasm-import-module"="bar" "wasm-import-name"="qux" } ; CHECK-NOT: .import_module plain ; CHECK: .import_module foo, bar +; CHECK: .import_name foo, qux ; CHECK-NOT: .import_module plain diff --git a/llvm/test/CodeGen/WebAssembly/main-declaration.ll b/llvm/test/CodeGen/WebAssembly/main-declaration.ll index f9d68db2bae8e..544f5588c5043 100644 --- a/llvm/test/CodeGen/WebAssembly/main-declaration.ll +++ b/llvm/test/CodeGen/WebAssembly/main-declaration.ll @@ -1,20 +1,18 @@ -; RUN: llc < %s -asm-verbose=false -wasm-temporary-workarounds=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false | FileCheck %s ; Test main functions with alternate signatures. target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown" -declare void @main() +declare i32 @main() -define void @foo() { - call void @main() - ret void +define i32 @foo() { + %t = call i32 @main() + ret i32 %t } -; CHECK-NOT: __original_main ; CHECK-LABEL: foo: -; CHECK-NEXT: .functype foo () -> () -; CHECK-NEXT: call main@FUNCTION +; CHECK-NEXT: .functype foo () -> (i32) +; CHECK-NEXT: call __original_main@FUNCTION ; CHECK-NEXT: end_function -; CHECK-NOT: __original_main diff --git a/llvm/test/CodeGen/WebAssembly/main-no-args.ll b/llvm/test/CodeGen/WebAssembly/main-no-args.ll index 0bc46717d97be..97023e269454b 100644 --- a/llvm/test/CodeGen/WebAssembly/main-no-args.ll +++ b/llvm/test/CodeGen/WebAssembly/main-no-args.ll @@ -1,18 +1,19 @@ -; RUN: llc < %s -asm-verbose=false -wasm-temporary-workarounds=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false | FileCheck %s ; Test main functions with alternate signatures. target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown" -define void @main() { - ret void +define i32 @main() { + ret i32 0 } -; CHECK-LABEL: .L__original_main: -; CHECK-NEXT: .functype .L__original_main () -> () +; CHECK-LABEL: __original_main: +; CHECK-NEXT: .functype __original_main () -> (i32) +; CHECK-NEXT: i32.const 0 ; CHECK-NEXT: end_function ; CHECK-LABEL: main: ; CHECK-NEXT: .functype main (i32, i32) -> (i32) -; CHECK: call .L__original_main@FUNCTION +; CHECK: call __original_main@FUNCTION diff --git a/llvm/test/CodeGen/WebAssembly/main-three-args.ll b/llvm/test/CodeGen/WebAssembly/main-three-args.ll new file mode 100644 index 0000000000000..77b3e5b8c3063 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/main-three-args.ll @@ -0,0 +1,16 @@ +; RUN: llc < %s -asm-verbose=false | FileCheck %s + +; Test that main function with a non-standard third argument is +; not wrapped. + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +define i32 @main(i32 %a, i8** %b, i8** %c) { + ret i32 0 +} + +; CHECK-LABEL: main: +; CHECK-NEXT: .functype main (i32, i32, i32) -> (i32) + +; CHECK-NOT: __original_main: diff --git a/llvm/test/CodeGen/WebAssembly/main-with-args.ll b/llvm/test/CodeGen/WebAssembly/main-with-args.ll index d4a11ef14d46e..205cb133f8ca6 100644 --- a/llvm/test/CodeGen/WebAssembly/main-with-args.ll +++ b/llvm/test/CodeGen/WebAssembly/main-with-args.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -asm-verbose=false -wasm-temporary-workarounds=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false | FileCheck %s ; Test that main function with expected signature is not wrapped diff --git a/llvm/test/MC/WebAssembly/external-func-address.ll b/llvm/test/MC/WebAssembly/external-func-address.ll index 60ec23a1a8ed3..8e36c76e84f3b 100644 --- a/llvm/test/MC/WebAssembly/external-func-address.ll +++ b/llvm/test/MC/WebAssembly/external-func-address.ll @@ -8,7 +8,7 @@ target triple = "wasm32-unknown-unknown" declare void @f0(i32) #0 @ptr_to_f0 = hidden global void (i32)* @f0, align 4 -attributes #0 = { "wasm-import-module"="somewhere" } +attributes #0 = { "wasm-import-module"="somewhere" "wasm-import-name"="something" } declare void @f1(i32) #1 @ptr_to_f1 = hidden global void (i32)* @f1, align 4 @@ -47,7 +47,7 @@ define void @call(i32) { ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: SigIndex: 1 ; CHECK: - Module: somewhere -; CHECK-NEXT: Field: f0 +; CHECK-NEXT: Field: something ; CHECK: - Module: env ; CHECK-NEXT: Field: f1 ; CHECK-NEXT: Kind: FUNCTION diff --git a/llvm/test/MC/WebAssembly/import-module.ll b/llvm/test/MC/WebAssembly/import-module.ll new file mode 100644 index 0000000000000..461d5c20ae9b7 --- /dev/null +++ b/llvm/test/MC/WebAssembly/import-module.ll @@ -0,0 +1,31 @@ +; RUN: llc -filetype=obj %s -o - | obj2yaml | FileCheck %s + +target triple = "wasm32-unknown-unknown" + +define void @test() { + call void @foo() + call void @plain() + ret void +} + +declare void @foo() #0 +declare void @plain() + +attributes #0 = { "wasm-import-module"="bar" "wasm-import-name"="qux" } + +; CHECK: - Type: IMPORT +; CHECK-NEXT: Imports: +; CHECK: - Module: bar +; CHECK-NEXT: Field: qux +; CHECK-NEXT: Kind: FUNCTION + +; CHECK: - Module: env +; CHECK-NEXT: Field: plain +; CHECK-NEXT: Kind: FUNCTION + +; CHECK: - Type: CUSTOM +; CHECK: Name: foo +; CHECK-NEXT: Flags: [ UNDEFINED ] + +; CHECK: Name: plain +; CHECK-NEXT: Flags: [ UNDEFINED ] diff --git a/llvm/tools/yaml2obj/yaml2wasm.cpp b/llvm/tools/yaml2obj/yaml2wasm.cpp index 2d3e3b71f0868..7d08e62bcedd8 100644 --- a/llvm/tools/yaml2obj/yaml2wasm.cpp +++ b/llvm/tools/yaml2obj/yaml2wasm.cpp @@ -172,7 +172,8 @@ int WasmWriter::writeSectionContent(raw_ostream &OS, case wasm::WASM_SYMBOL_TYPE_GLOBAL: case wasm::WASM_SYMBOL_TYPE_EVENT: encodeULEB128(Info.ElementIndex, SubSection.GetStream()); - if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) + if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 || + (Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) writeStringRef(Info.Name, SubSection.GetStream()); break; case wasm::WASM_SYMBOL_TYPE_DATA: From be8c9e3e0554b69e18c23698443cd836e3a6cb69 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 13 Feb 2019 10:30:16 +0000 Subject: [PATCH 133/274] Merging r352707, r352714, r352886, r352892, r352895, r352908, r352917, r352935, r353213, r353733, and r353758 ------------------------------------------------------------------------ r352707 | evandro | 2019-01-31 01:49:27 +0100 (Thu, 31 Jan 2019) | 1 line [InstCombine] Simplify check clauses in test (NFC) ------------------------------------------------------------------------ ------------------------------------------------------------------------ r352714 | evandro | 2019-01-31 02:41:39 +0100 (Thu, 31 Jan 2019) | 3 lines [InstCombine] Expand testing for Windows (NFC) Added the checks to the existing cases when the target is Win64. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r352886 | evandro | 2019-02-01 17:57:53 +0100 (Fri, 01 Feb 2019) | 1 line [InstCombine] Refactor test checks (NFC) ------------------------------------------------------------------------ ------------------------------------------------------------------------ r352892 | evandro | 2019-02-01 18:39:48 +0100 (Fri, 01 Feb 2019) | 3 lines [InstCombine] Expand Windows test (NFC) Add checks for Win64 to existing cases. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r352895 | evandro | 2019-02-01 19:34:20 +0100 (Fri, 01 Feb 2019) | 1 line [InstCombine] Refactor test checks (NFC) ------------------------------------------------------------------------ ------------------------------------------------------------------------ r352908 | evandro | 2019-02-01 21:42:03 +0100 (Fri, 01 Feb 2019) | 3 lines [InstCombine] Expand Windows test (NFC) Run checks for Win64 as well. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r352917 | evandro | 2019-02-01 22:14:10 +0100 (Fri, 01 Feb 2019) | 3 lines [InstCombine] Expand Windows test (NFC) Run checks for Win32 as well. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r352935 | evandro | 2019-02-01 23:52:05 +0100 (Fri, 01 Feb 2019) | 1 line [InstCombine] Refactor test checks (NFC) ------------------------------------------------------------------------ ------------------------------------------------------------------------ r353213 | evandro | 2019-02-05 21:24:21 +0100 (Tue, 05 Feb 2019) | 3 lines [TargetLibraryInfo] Regroup run time functions for Windows (NFC) Regroup supported and unsupported functions by precision and C standard. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r353733 | evandro | 2019-02-11 20:02:28 +0100 (Mon, 11 Feb 2019) | 8 lines [TargetLibraryInfo] Update run time support for Windows It seems that the run time for Windows has changed and supports more math functions than it used to, especially on AArch64, ARM, and AMD64. Fixes PR40541. Differential revision: https://reviews.llvm.org/D57625 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r353758 | evandro | 2019-02-11 23:12:01 +0100 (Mon, 11 Feb 2019) | 6 lines [TargetLibraryInfo] Update run time support for Windows It seems that, since VC19, the `float` C99 math functions are supported for all targets, unlike the C89 ones. According to the discussion at https://reviews.llvm.org/D57625. ------------------------------------------------------------------------ llvm-svn: 353934 --- llvm/lib/Analysis/TargetLibraryInfo.cpp | 168 ++++--- .../InstCombine/double-float-shrink-1.ll | 128 +++-- .../InstCombine/double-float-shrink-2.ll | 446 ++++++++---------- llvm/test/Transforms/InstCombine/pow-1.ll | 306 +++++++----- llvm/test/Transforms/InstCombine/win-math.ll | 261 +++++----- 5 files changed, 724 insertions(+), 585 deletions(-) diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp index 4643f75da42d1..ae86ee3d36500 100644 --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -161,25 +161,66 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, } if (T.isOSWindows() && !T.isOSCygMing()) { - // Win32 does not support long double + // XXX: The earliest documentation available at the moment is for VS2015/VC19: + // https://docs.microsoft.com/en-us/cpp/c-runtime-library/floating-point-support?view=vs-2015 + // XXX: In order to use an MSVCRT older than VC19, + // the specific library version must be explicit in the target triple, + // e.g., x86_64-pc-windows-msvc18. + bool hasPartialC99 = true; + if (T.isKnownWindowsMSVCEnvironment()) { + unsigned Major, Minor, Micro; + T.getEnvironmentVersion(Major, Minor, Micro); + hasPartialC99 = (Major == 0 || Major >= 19); + } + + // Latest targets support C89 math functions, in part. + bool isARM = (T.getArch() == Triple::aarch64 || + T.getArch() == Triple::arm); + bool hasPartialFloat = (isARM || + T.getArch() == Triple::x86_64); + + // Win32 does not support float C89 math functions, in general. + if (!hasPartialFloat) { + TLI.setUnavailable(LibFunc_acosf); + TLI.setUnavailable(LibFunc_asinf); + TLI.setUnavailable(LibFunc_atan2f); + TLI.setUnavailable(LibFunc_atanf); + TLI.setUnavailable(LibFunc_ceilf); + TLI.setUnavailable(LibFunc_cosf); + TLI.setUnavailable(LibFunc_coshf); + TLI.setUnavailable(LibFunc_expf); + TLI.setUnavailable(LibFunc_floorf); + TLI.setUnavailable(LibFunc_fmodf); + TLI.setUnavailable(LibFunc_log10f); + TLI.setUnavailable(LibFunc_logf); + TLI.setUnavailable(LibFunc_modff); + TLI.setUnavailable(LibFunc_powf); + TLI.setUnavailable(LibFunc_sinf); + TLI.setUnavailable(LibFunc_sinhf); + TLI.setUnavailable(LibFunc_sqrtf); + TLI.setUnavailable(LibFunc_tanf); + TLI.setUnavailable(LibFunc_tanhf); + } + if (!isARM) + TLI.setUnavailable(LibFunc_fabsf); + TLI.setUnavailable(LibFunc_frexpf); + TLI.setUnavailable(LibFunc_ldexpf); + + // Win32 does not support long double C89 math functions. TLI.setUnavailable(LibFunc_acosl); TLI.setUnavailable(LibFunc_asinl); - TLI.setUnavailable(LibFunc_atanl); TLI.setUnavailable(LibFunc_atan2l); + TLI.setUnavailable(LibFunc_atanl); TLI.setUnavailable(LibFunc_ceill); - TLI.setUnavailable(LibFunc_copysignl); TLI.setUnavailable(LibFunc_cosl); TLI.setUnavailable(LibFunc_coshl); TLI.setUnavailable(LibFunc_expl); - TLI.setUnavailable(LibFunc_fabsf); // Win32 and Win64 both lack fabsf TLI.setUnavailable(LibFunc_fabsl); TLI.setUnavailable(LibFunc_floorl); - TLI.setUnavailable(LibFunc_fmaxl); - TLI.setUnavailable(LibFunc_fminl); TLI.setUnavailable(LibFunc_fmodl); TLI.setUnavailable(LibFunc_frexpl); - TLI.setUnavailable(LibFunc_ldexpf); TLI.setUnavailable(LibFunc_ldexpl); + TLI.setUnavailable(LibFunc_log10l); TLI.setUnavailable(LibFunc_logl); TLI.setUnavailable(LibFunc_modfl); TLI.setUnavailable(LibFunc_powl); @@ -189,81 +230,66 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, TLI.setUnavailable(LibFunc_tanl); TLI.setUnavailable(LibFunc_tanhl); - // Win32 only has C89 math - TLI.setUnavailable(LibFunc_acosh); - TLI.setUnavailable(LibFunc_acoshf); + // Win32 does not fully support C99 math functions. + if (!hasPartialC99) { + TLI.setUnavailable(LibFunc_acosh); + TLI.setUnavailable(LibFunc_acoshf); + TLI.setUnavailable(LibFunc_asinh); + TLI.setUnavailable(LibFunc_asinhf); + TLI.setUnavailable(LibFunc_atanh); + TLI.setUnavailable(LibFunc_atanhf); + TLI.setAvailableWithName(LibFunc_cabs, "_cabs"); + TLI.setUnavailable(LibFunc_cabsf); + TLI.setUnavailable(LibFunc_cbrt); + TLI.setUnavailable(LibFunc_cbrtf); + TLI.setAvailableWithName(LibFunc_copysign, "_copysign"); + TLI.setAvailableWithName(LibFunc_copysignf, "_copysignf"); + TLI.setUnavailable(LibFunc_exp2); + TLI.setUnavailable(LibFunc_exp2f); + TLI.setUnavailable(LibFunc_expm1); + TLI.setUnavailable(LibFunc_expm1f); + TLI.setUnavailable(LibFunc_fmax); + TLI.setUnavailable(LibFunc_fmaxf); + TLI.setUnavailable(LibFunc_fmin); + TLI.setUnavailable(LibFunc_fminf); + TLI.setUnavailable(LibFunc_log1p); + TLI.setUnavailable(LibFunc_log1pf); + TLI.setUnavailable(LibFunc_log2); + TLI.setUnavailable(LibFunc_log2f); + TLI.setAvailableWithName(LibFunc_logb, "_logb"); + if (hasPartialFloat) + TLI.setAvailableWithName(LibFunc_logbf, "_logbf"); + else + TLI.setUnavailable(LibFunc_logbf); + TLI.setUnavailable(LibFunc_rint); + TLI.setUnavailable(LibFunc_rintf); + TLI.setUnavailable(LibFunc_round); + TLI.setUnavailable(LibFunc_roundf); + TLI.setUnavailable(LibFunc_trunc); + TLI.setUnavailable(LibFunc_truncf); + } + + // Win32 does not support long double C99 math functions. TLI.setUnavailable(LibFunc_acoshl); - TLI.setUnavailable(LibFunc_asinh); - TLI.setUnavailable(LibFunc_asinhf); TLI.setUnavailable(LibFunc_asinhl); - TLI.setUnavailable(LibFunc_atanh); - TLI.setUnavailable(LibFunc_atanhf); TLI.setUnavailable(LibFunc_atanhl); - TLI.setUnavailable(LibFunc_cabs); - TLI.setUnavailable(LibFunc_cabsf); TLI.setUnavailable(LibFunc_cabsl); - TLI.setUnavailable(LibFunc_cbrt); - TLI.setUnavailable(LibFunc_cbrtf); TLI.setUnavailable(LibFunc_cbrtl); - TLI.setUnavailable(LibFunc_exp2); - TLI.setUnavailable(LibFunc_exp2f); + TLI.setUnavailable(LibFunc_copysignl); TLI.setUnavailable(LibFunc_exp2l); - TLI.setUnavailable(LibFunc_expm1); - TLI.setUnavailable(LibFunc_expm1f); TLI.setUnavailable(LibFunc_expm1l); - TLI.setUnavailable(LibFunc_log2); - TLI.setUnavailable(LibFunc_log2f); - TLI.setUnavailable(LibFunc_log2l); - TLI.setUnavailable(LibFunc_log1p); - TLI.setUnavailable(LibFunc_log1pf); + TLI.setUnavailable(LibFunc_fmaxl); + TLI.setUnavailable(LibFunc_fminl); TLI.setUnavailable(LibFunc_log1pl); - TLI.setUnavailable(LibFunc_logb); - TLI.setUnavailable(LibFunc_logbf); + TLI.setUnavailable(LibFunc_log2l); TLI.setUnavailable(LibFunc_logbl); - TLI.setUnavailable(LibFunc_nearbyint); - TLI.setUnavailable(LibFunc_nearbyintf); TLI.setUnavailable(LibFunc_nearbyintl); - TLI.setUnavailable(LibFunc_rint); - TLI.setUnavailable(LibFunc_rintf); TLI.setUnavailable(LibFunc_rintl); - TLI.setUnavailable(LibFunc_round); - TLI.setUnavailable(LibFunc_roundf); TLI.setUnavailable(LibFunc_roundl); - TLI.setUnavailable(LibFunc_trunc); - TLI.setUnavailable(LibFunc_truncf); TLI.setUnavailable(LibFunc_truncl); - // Win32 provides some C99 math with mangled names - TLI.setAvailableWithName(LibFunc_copysign, "_copysign"); - - if (T.getArch() == Triple::x86) { - // Win32 on x86 implements single-precision math functions as macros - TLI.setUnavailable(LibFunc_acosf); - TLI.setUnavailable(LibFunc_asinf); - TLI.setUnavailable(LibFunc_atanf); - TLI.setUnavailable(LibFunc_atan2f); - TLI.setUnavailable(LibFunc_ceilf); - TLI.setUnavailable(LibFunc_copysignf); - TLI.setUnavailable(LibFunc_cosf); - TLI.setUnavailable(LibFunc_coshf); - TLI.setUnavailable(LibFunc_expf); - TLI.setUnavailable(LibFunc_floorf); - TLI.setUnavailable(LibFunc_fminf); - TLI.setUnavailable(LibFunc_fmaxf); - TLI.setUnavailable(LibFunc_fmodf); - TLI.setUnavailable(LibFunc_logf); - TLI.setUnavailable(LibFunc_log10f); - TLI.setUnavailable(LibFunc_modff); - TLI.setUnavailable(LibFunc_powf); - TLI.setUnavailable(LibFunc_sinf); - TLI.setUnavailable(LibFunc_sinhf); - TLI.setUnavailable(LibFunc_sqrtf); - TLI.setUnavailable(LibFunc_tanf); - TLI.setUnavailable(LibFunc_tanhf); - } - - // Win32 does *not* provide these functions, but they are - // generally available on POSIX-compliant systems: + // Win32 does not support these functions, but + // they are generally available on POSIX-compliant systems. TLI.setUnavailable(LibFunc_access); TLI.setUnavailable(LibFunc_bcmp); TLI.setUnavailable(LibFunc_bcopy); @@ -318,12 +344,6 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, TLI.setUnavailable(LibFunc_utime); TLI.setUnavailable(LibFunc_utimes); TLI.setUnavailable(LibFunc_write); - - // Win32 does *not* provide provide these functions, but they are - // specified by C99: - TLI.setUnavailable(LibFunc_atoll); - TLI.setUnavailable(LibFunc_frexpf); - TLI.setUnavailable(LibFunc_llabs); } switch (T.getOS()) { diff --git a/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll b/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll index c170f2ca74ba6..e8f7f720b1527 100644 --- a/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll +++ b/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll @@ -1,8 +1,8 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -instcombine -S | FileCheck %s - -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux-gnu" +; RUN: opt < %s -instcombine -S -mtriple x86_64-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK,LINUX,ISC99 +; RUN: opt < %s -instcombine -S -mtriple x86_64-pc-win32 | FileCheck %s --check-prefixes=CHECK,ISC99 +; RUN: opt < %s -instcombine -S -mtriple x86_64-pc-windows-msvc16 | FileCheck %s --check-prefixes=CHECK,MS64,ISC89 +; RUN: opt < %s -instcombine -S -mtriple i386-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,ISC99 +; RUN: opt < %s -instcombine -S -mtriple i686-pc-windows-msvc17 | FileCheck %s --check-prefixes=CHECK,MS32,ISC89 ; Check for and against shrinkage when using the ; unsafe-fp-math function attribute on a math lib @@ -12,8 +12,10 @@ target triple = "x86_64-unknown-linux-gnu" define float @acos_test1(float %f) { ; CHECK-LABEL: @acos_test1( -; CHECK-NEXT: [[ACOSF:%.*]] = call fast float @acosf(float [[F:%.*]]) -; CHECK-NEXT: ret float [[ACOSF]] +; LINUX-NEXT: [[ACOSF:%.*]] = call fast float @acosf(float [[F:%.*]]) +; LINUX-NEXT: ret float [[ACOSF]] +; MS32: [[ACOSF:%.*]] = call fast double @acos(double [[F:%.*]]) +; MS64-NEXT: [[ACOSF:%.*]] = call fast float @acosf(float [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @acos(double %conv) @@ -34,8 +36,9 @@ define double @acos_test2(float %f) { define float @acosh_test1(float %f) { ; CHECK-LABEL: @acosh_test1( -; CHECK-NEXT: [[ACOSHF:%.*]] = call fast float @acoshf(float [[F:%.*]]) -; CHECK-NEXT: ret float [[ACOSHF]] +; ISC99-NEXT: [[ACOSHF:%.*]] = call fast float @acoshf(float [[F:%.*]]) +; ISC99-NEXT: ret float [[ACOSHF]] +; ISC89: [[ACOSHF:%.*]] = call fast double @acosh(double [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @acosh(double %conv) @@ -56,8 +59,10 @@ define double @acosh_test2(float %f) { define float @asin_test1(float %f) { ; CHECK-LABEL: @asin_test1( -; CHECK-NEXT: [[ASINF:%.*]] = call fast float @asinf(float [[F:%.*]]) -; CHECK-NEXT: ret float [[ASINF]] +; LINUX-NEXT: [[ASINF:%.*]] = call fast float @asinf(float [[F:%.*]]) +; LINUX-NEXT: ret float [[ASINF]] +; MS32: [[ASINF:%.*]] = call fast double @asin(double [[F:%.*]]) +; MS64-NEXT: [[ASINF:%.*]] = call fast float @asinf(float [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @asin(double %conv) @@ -78,8 +83,9 @@ define double @asin_test2(float %f) { define float @asinh_test1(float %f) { ; CHECK-LABEL: @asinh_test1( -; CHECK-NEXT: [[ASINHF:%.*]] = call fast float @asinhf(float [[F:%.*]]) -; CHECK-NEXT: ret float [[ASINHF]] +; ISC99-NEXT: [[ASINHF:%.*]] = call fast float @asinhf(float [[F:%.*]]) +; ISC99-NEXT: ret float [[ASINHF]] +; ISC89: [[ASINHF:%.*]] = call fast double @asinh(double [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @asinh(double %conv) @@ -100,8 +106,10 @@ define double @asinh_test2(float %f) { define float @atan_test1(float %f) { ; CHECK-LABEL: @atan_test1( -; CHECK-NEXT: [[ATANF:%.*]] = call fast float @atanf(float [[F:%.*]]) -; CHECK-NEXT: ret float [[ATANF]] +; LINUX-NEXT: [[ATANF:%.*]] = call fast float @atanf(float [[F:%.*]]) +; LINUX-NEXT: ret float [[ATANF]] +; MS32: [[ATANF:%.*]] = call fast double @atan(double [[F:%.*]]) +; MS64-NEXT: [[ATANF:%.*]] = call fast float @atanf(float [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @atan(double %conv) @@ -122,8 +130,9 @@ define double @atan_test2(float %f) { define float @atanh_test1(float %f) { ; CHECK-LABEL: @atanh_test1( -; CHECK-NEXT: [[ATANHF:%.*]] = call fast float @atanhf(float [[F:%.*]]) -; CHECK-NEXT: ret float [[ATANHF]] +; ISC99-NEXT: [[ATANHF:%.*]] = call fast float @atanhf(float [[F:%.*]]) +; ISC99-NEXT: ret float [[ATANHF]] +; ISC89: [[ATANHF:%.*]] = call fast double @atanh(double [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @atanh(double %conv) @@ -144,8 +153,9 @@ define double @atanh_test2(float %f) { define float @cbrt_test1(float %f) { ; CHECK-LABEL: @cbrt_test1( -; CHECK-NEXT: [[CBRTF:%.*]] = call fast float @cbrtf(float [[F:%.*]]) -; CHECK-NEXT: ret float [[CBRTF]] +; ISC99-NEXT: [[CBRTF:%.*]] = call fast float @cbrtf(float [[F:%.*]]) +; ISC99-NEXT: ret float [[CBRTF]] +; ISC89: [[CBRTF:%.*]] = call fast double @cbrt(double [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @cbrt(double %conv) @@ -166,8 +176,10 @@ define double @cbrt_test2(float %f) { define float @exp_test1(float %f) { ; CHECK-LABEL: @exp_test1( -; CHECK-NEXT: [[EXPF:%.*]] = call fast float @expf(float [[F:%.*]]) -; CHECK-NEXT: ret float [[EXPF]] +; LINUX-NEXT: [[EXPF:%.*]] = call fast float @expf(float [[F:%.*]]) +; LINUX-NEXT: ret float [[EXPF]] +; MS32: [[EXPF:%.*]] = call fast double @exp(double [[F:%.*]]) +; MS64-NEXT: [[EXPF:%.*]] = call fast float @expf(float [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @exp(double %conv) @@ -188,8 +200,9 @@ define double @exp_test2(float %f) { define float @expm1_test1(float %f) { ; CHECK-LABEL: @expm1_test1( -; CHECK-NEXT: [[EXPM1F:%.*]] = call fast float @expm1f(float [[F:%.*]]) -; CHECK-NEXT: ret float [[EXPM1F]] +; ISC99-NEXT: [[EXPM1F:%.*]] = call fast float @expm1f(float [[F:%.*]]) +; ISC99-NEXT: ret float [[EXPM1F]] +; ISC89: [[EXPM1F:%.*]] = call fast double @expm1(double [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @expm1(double %conv) @@ -236,8 +249,10 @@ define double @exp10_test2(float %f) { define float @log_test1(float %f) { ; CHECK-LABEL: @log_test1( -; CHECK-NEXT: [[LOGF:%.*]] = call fast float @logf(float [[F:%.*]]) -; CHECK-NEXT: ret float [[LOGF]] +; LINUX-NEXT: [[LOGF:%.*]] = call fast float @logf(float [[F:%.*]]) +; LINUX-NEXT: ret float [[LOGF]] +; MS32: [[LOGF:%.*]] = call fast double @log(double [[F:%.*]]) +; MS64-NEXT: [[LOGF:%.*]] = call fast float @logf(float [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @log(double %conv) @@ -258,8 +273,10 @@ define double @log_test2(float %f) { define float @log10_test1(float %f) { ; CHECK-LABEL: @log10_test1( -; CHECK-NEXT: [[LOG10F:%.*]] = call fast float @log10f(float [[F:%.*]]) -; CHECK-NEXT: ret float [[LOG10F]] +; LINUX-NEXT: [[LOG10F:%.*]] = call fast float @log10f(float [[F:%.*]]) +; LINUX-NEXT: ret float [[LOG10F]] +; MS32: [[LOG10F:%.*]] = call fast double @log10(double [[F:%.*]]) +; MS64-NEXT: [[LOG10F:%.*]] = call fast float @log10f(float [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @log10(double %conv) @@ -280,8 +297,9 @@ define double @log10_test2(float %f) { define float @log1p_test1(float %f) { ; CHECK-LABEL: @log1p_test1( -; CHECK-NEXT: [[LOG1PF:%.*]] = call fast float @log1pf(float [[F:%.*]]) -; CHECK-NEXT: ret float [[LOG1PF]] +; ISC99-NEXT: [[LOG1PF:%.*]] = call fast float @log1pf(float [[F:%.*]]) +; ISC99-NEXT: ret float [[LOG1PF]] +; ISC89: [[LOG1PF:%.*]] = call fast double @log1p(double [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @log1p(double %conv) @@ -302,8 +320,9 @@ define double @log1p_test2(float %f) { define float @log2_test1(float %f) { ; CHECK-LABEL: @log2_test1( -; CHECK-NEXT: [[LOG2F:%.*]] = call fast float @log2f(float [[F:%.*]]) -; CHECK-NEXT: ret float [[LOG2F]] +; ISC99-NEXT: [[LOG2F:%.*]] = call fast float @log2f(float [[F:%.*]]) +; ISC99-NEXT: ret float [[LOG2F]] +; ISC89: [[LOG2F:%.*]] = call fast double @log2(double [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @log2(double %conv) @@ -324,8 +343,10 @@ define double @log2_test2(float %f) { define float @logb_test1(float %f) { ; CHECK-LABEL: @logb_test1( -; CHECK-NEXT: [[LOGBF:%.*]] = call fast float @logbf(float [[F:%.*]]) -; CHECK-NEXT: ret float [[LOGBF]] +; LINUX-NEXT: [[LOGBF:%.*]] = call fast float @logbf(float [[F:%.*]]) +; LINUX-NEXT: ret float [[LOGBF]] +; MS32: [[POWF:%.*]] = call fast double @logb(double [[F:%.*]]) +; MS64-NEXT: [[LOGBF:%.*]] = call fast float @logbf(float [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @logb(double %conv) @@ -346,8 +367,10 @@ define double @logb_test2(float %f) { define float @pow_test1(float %f, float %g) { ; CHECK-LABEL: @pow_test1( -; CHECK-NEXT: [[POWF:%.*]] = call fast float @powf(float %f, float %g) -; CHECK-NEXT: ret float [[POWF]] +; LINUX-NEXT: [[POWF:%.*]] = call fast float @powf(float %f, float %g) +; LINUX-NEXT: ret float [[POWF]] +; MS32: [[POWF:%.*]] = call fast double @pow(double %df, double %dg) +; MS64-NEXT: [[POWF:%.*]] = call fast float @powf(float %f, float %g) ; %df = fpext float %f to double %dg = fpext float %g to double @@ -369,8 +392,10 @@ define double @pow_test2(float %f, float %g) { define float @sin_test1(float %f) { ; CHECK-LABEL: @sin_test1( -; CHECK-NEXT: [[SINF:%.*]] = call fast float @sinf(float [[F:%.*]]) -; CHECK-NEXT: ret float [[SINF]] +; LINUX-NEXT: [[SINF:%.*]] = call fast float @sinf(float [[F:%.*]]) +; LINUX-NEXT: ret float [[SINF]] +; MS32: [[SINF:%.*]] = call fast double @sin(double [[F:%.*]]) +; MS64-NEXT: [[SINF:%.*]] = call fast float @sinf(float [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @sin(double %conv) @@ -391,8 +416,10 @@ define double @sin_test2(float %f) { define float @sqrt_test1(float %f) { ; CHECK-LABEL: @sqrt_test1( -; CHECK-NEXT: [[SQRTF:%.*]] = call float @sqrtf(float [[F:%.*]]) -; CHECK-NEXT: ret float [[SQRTF]] +; LINUX-NEXT: [[SQRTF:%.*]] = call float @sqrtf(float [[F:%.*]]) +; LINUX-NEXT: ret float [[SQRTF]] +; MS32: [[SQRTF:%.*]] = call double @sqrt(double [[F:%.*]]) +; MS64-NEXT: [[SQRTF:%.*]] = call float @sqrtf(float [[F:%.*]]) ; %conv = fpext float %f to double %call = call double @sqrt(double %conv) @@ -413,8 +440,10 @@ define double @sqrt_test2(float %f) { define float @sqrt_int_test1(float %f) { ; CHECK-LABEL: @sqrt_int_test1( -; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.sqrt.f32(float [[F:%.*]]) -; CHECK-NEXT: ret float [[TMP1]] +; LINUX-NEXT: [[TMP1:%.*]] = call float @llvm.sqrt.f32(float [[F:%.*]]) +; LINUX-NEXT: ret float [[TMP1]] +; MS32: [[TMP1:%.*]] = call double @llvm.sqrt.f64(double [[F:%.*]]) +; MS64-NEXT: [[TMP1:%.*]] = call float @llvm.sqrt.f32(float [[F:%.*]]) ; %conv = fpext float %f to double %call = call double @llvm.sqrt.f64(double %conv) @@ -435,8 +464,10 @@ define double @sqrt_int_test2(float %f) { define float @tan_test1(float %f) { ; CHECK-LABEL: @tan_test1( -; CHECK-NEXT: [[TANF:%.*]] = call fast float @tanf(float [[F:%.*]]) -; CHECK-NEXT: ret float [[TANF]] +; LINUX-NEXT: [[TANF:%.*]] = call fast float @tanf(float [[F:%.*]]) +; LINUX-NEXT: ret float [[TANF]] +; MS32: [[TANF:%.*]] = call fast double @tan(double [[F:%.*]]) +; MS64-NEXT: [[TANF:%.*]] = call fast float @tanf(float [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @tan(double %conv) @@ -456,8 +487,10 @@ define double @tan_test2(float %f) { } define float @tanh_test1(float %f) { ; CHECK-LABEL: @tanh_test1( -; CHECK-NEXT: [[TANHF:%.*]] = call fast float @tanhf(float [[F:%.*]]) -; CHECK-NEXT: ret float [[TANHF]] +; LINUX-NEXT: [[TANHF:%.*]] = call fast float @tanhf(float [[F:%.*]]) +; LINUX-NEXT: ret float [[TANHF]] +; MS32: [[TANHF:%.*]] = call fast double @tanh(double [[F:%.*]]) +; MS64-NEXT: [[TANHF:%.*]] = call fast float @tanhf(float [[F:%.*]]) ; %conv = fpext float %f to double %call = call fast double @tanh(double %conv) @@ -480,8 +513,9 @@ define double @tanh_test2(float %f) { ; flags are propagated for shrunken *binary* double FP calls. define float @max1(float %a, float %b) { ; CHECK-LABEL: @max1( -; CHECK-NEXT: [[FMAXF:%.*]] = call arcp float @fmaxf(float [[A:%.*]], float [[B:%.*]]) -; CHECK-NEXT: ret float [[FMAXF]] +; ISC99-NEXT: [[FMAXF:%.*]] = call arcp float @fmaxf(float [[A:%.*]], float [[B:%.*]]) +; ISC99-NEXT: ret float [[FMAXF]] +; ISC89: [[FMAXF:%.*]] = call arcp double @fmax(double [[A:%.*]], double [[B:%.*]]) ; %c = fpext float %a to double %d = fpext float %b to double diff --git a/llvm/test/Transforms/InstCombine/double-float-shrink-2.ll b/llvm/test/Transforms/InstCombine/double-float-shrink-2.ll index 5bdeaf7d9d7e0..76e497bd68fc7 100644 --- a/llvm/test/Transforms/InstCombine/double-float-shrink-2.ll +++ b/llvm/test/Transforms/InstCombine/double-float-shrink-2.ll @@ -1,11 +1,11 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -instcombine -S -mtriple "i386-pc-linux" | FileCheck -check-prefix=ALL -check-prefix=DO-SIMPLIFY %s -; RUN: opt < %s -instcombine -S -mtriple "i386-pc-win32" | FileCheck -check-prefix=ALL -check-prefix=DONT-SIMPLIFY %s -; RUN: opt < %s -instcombine -S -mtriple "x86_64-pc-win32" | FileCheck -check-prefix=ALL -check-prefix=C89-SIMPLIFY %s -; RUN: opt < %s -instcombine -S -mtriple "i386-pc-mingw32" | FileCheck -check-prefix=ALL -check-prefix=DO-SIMPLIFY %s -; RUN: opt < %s -instcombine -S -mtriple "x86_64-pc-mingw32" | FileCheck -check-prefix=ALL -check-prefix=DO-SIMPLIFY %s -; RUN: opt < %s -instcombine -S -mtriple "sparc-sun-solaris" | FileCheck -check-prefix=ALL -check-prefix=DO-SIMPLIFY %s -; RUN: opt < %s -enable-debugify -instcombine -S -mtriple "x86_64-pc-win32" 2>&1 | FileCheck -check-prefix=DBG-VALID %s +; RUN: opt < %s -instcombine -S -mtriple "i386-pc-linux" | FileCheck %s +; RUN: opt < %s -instcombine -S -mtriple "i386-pc-win32" | FileCheck %s +; RUN: opt < %s -instcombine -S -mtriple "x86_64-pc-win32" | FileCheck %s +; RUN: opt < %s -instcombine -S -mtriple "i386-pc-mingw32" | FileCheck %s +; RUN: opt < %s -instcombine -S -mtriple "x86_64-pc-mingw32" | FileCheck %s +; RUN: opt < %s -instcombine -S -mtriple "sparc-sun-solaris" | FileCheck %s +; RUN: opt < %s -instcombine -S -mtriple "x86_64-pc-win32" -enable-debugify 2>&1 | FileCheck --check-prefix=DBG-VALID %s declare double @floor(double) declare double @ceil(double) @@ -36,9 +36,9 @@ declare double @llvm.trunc.f64(double) declare <2 x double> @llvm.trunc.v2f64(<2 x double>) define float @test_shrink_libcall_floor(float %C) { -; ALL-LABEL: @test_shrink_libcall_floor( -; ALL-NEXT: [[F:%.*]] = call float @llvm.floor.f32(float [[C:%.*]]) -; ALL-NEXT: ret float [[F]] +; CHECK-LABEL: @test_shrink_libcall_floor( +; CHECK-NEXT: [[F:%.*]] = call float @llvm.floor.f32(float [[C:%.*]]) +; CHECK-NEXT: ret float [[F]] ; %D = fpext float %C to double ; --> floorf @@ -48,9 +48,9 @@ define float @test_shrink_libcall_floor(float %C) { } define float @test_shrink_libcall_ceil(float %C) { -; ALL-LABEL: @test_shrink_libcall_ceil( -; ALL-NEXT: [[F:%.*]] = call float @llvm.ceil.f32(float [[C:%.*]]) -; ALL-NEXT: ret float [[F]] +; CHECK-LABEL: @test_shrink_libcall_ceil( +; CHECK-NEXT: [[F:%.*]] = call float @llvm.ceil.f32(float [[C:%.*]]) +; CHECK-NEXT: ret float [[F]] ; %D = fpext float %C to double ; --> ceilf @@ -60,21 +60,9 @@ define float @test_shrink_libcall_ceil(float %C) { } define float @test_shrink_libcall_round(float %C) { -; DO-SIMPLIFY-LABEL: @test_shrink_libcall_round( -; DO-SIMPLIFY-NEXT: [[F:%.*]] = call float @llvm.round.f32(float [[C:%.*]]) -; DO-SIMPLIFY-NEXT: ret float [[F]] -; -; DONT-SIMPLIFY-LABEL: @test_shrink_libcall_round( -; DONT-SIMPLIFY-NEXT: [[D:%.*]] = fpext float [[C:%.*]] to double -; DONT-SIMPLIFY-NEXT: [[E:%.*]] = call double @round(double [[D]]) -; DONT-SIMPLIFY-NEXT: [[F:%.*]] = fptrunc double [[E]] to float -; DONT-SIMPLIFY-NEXT: ret float [[F]] -; -; C89-SIMPLIFY-LABEL: @test_shrink_libcall_round( -; C89-SIMPLIFY-NEXT: [[D:%.*]] = fpext float [[C:%.*]] to double -; C89-SIMPLIFY-NEXT: [[E:%.*]] = call double @round(double [[D]]) -; C89-SIMPLIFY-NEXT: [[F:%.*]] = fptrunc double [[E]] to float -; C89-SIMPLIFY-NEXT: ret float [[F]] +; CHECK-LABEL: @test_shrink_libcall_round( +; CHECK-NEXT: [[F:%.*]] = call float @llvm.round.f32(float [[C:%.*]]) +; CHECK-NEXT: ret float [[F]] ; %D = fpext float %C to double ; --> roundf @@ -84,21 +72,9 @@ define float @test_shrink_libcall_round(float %C) { } define float @test_shrink_libcall_nearbyint(float %C) { -; DO-SIMPLIFY-LABEL: @test_shrink_libcall_nearbyint( -; DO-SIMPLIFY-NEXT: [[F:%.*]] = call float @llvm.nearbyint.f32(float [[C:%.*]]) -; DO-SIMPLIFY-NEXT: ret float [[F]] -; -; DONT-SIMPLIFY-LABEL: @test_shrink_libcall_nearbyint( -; DONT-SIMPLIFY-NEXT: [[D:%.*]] = fpext float [[C:%.*]] to double -; DONT-SIMPLIFY-NEXT: [[E:%.*]] = call double @nearbyint(double [[D]]) -; DONT-SIMPLIFY-NEXT: [[F:%.*]] = fptrunc double [[E]] to float -; DONT-SIMPLIFY-NEXT: ret float [[F]] -; -; C89-SIMPLIFY-LABEL: @test_shrink_libcall_nearbyint( -; C89-SIMPLIFY-NEXT: [[D:%.*]] = fpext float [[C:%.*]] to double -; C89-SIMPLIFY-NEXT: [[E:%.*]] = call double @nearbyint(double [[D]]) -; C89-SIMPLIFY-NEXT: [[F:%.*]] = fptrunc double [[E]] to float -; C89-SIMPLIFY-NEXT: ret float [[F]] +; CHECK-LABEL: @test_shrink_libcall_nearbyint( +; CHECK-NEXT: [[F:%.*]] = call float @llvm.nearbyint.f32(float [[C:%.*]]) +; CHECK-NEXT: ret float [[F]] ; %D = fpext float %C to double ; --> nearbyintf @@ -108,21 +84,9 @@ define float @test_shrink_libcall_nearbyint(float %C) { } define float @test_shrink_libcall_trunc(float %C) { -; DO-SIMPLIFY-LABEL: @test_shrink_libcall_trunc( -; DO-SIMPLIFY-NEXT: [[F:%.*]] = call float @llvm.trunc.f32(float [[C:%.*]]) -; DO-SIMPLIFY-NEXT: ret float [[F]] -; -; DONT-SIMPLIFY-LABEL: @test_shrink_libcall_trunc( -; DONT-SIMPLIFY-NEXT: [[D:%.*]] = fpext float [[C:%.*]] to double -; DONT-SIMPLIFY-NEXT: [[E:%.*]] = call double @trunc(double [[D]]) -; DONT-SIMPLIFY-NEXT: [[F:%.*]] = fptrunc double [[E]] to float -; DONT-SIMPLIFY-NEXT: ret float [[F]] -; -; C89-SIMPLIFY-LABEL: @test_shrink_libcall_trunc( -; C89-SIMPLIFY-NEXT: [[D:%.*]] = fpext float [[C:%.*]] to double -; C89-SIMPLIFY-NEXT: [[E:%.*]] = call double @trunc(double [[D]]) -; C89-SIMPLIFY-NEXT: [[F:%.*]] = fptrunc double [[E]] to float -; C89-SIMPLIFY-NEXT: ret float [[F]] +; CHECK-LABEL: @test_shrink_libcall_trunc( +; CHECK-NEXT: [[F:%.*]] = call float @llvm.trunc.f32(float [[C:%.*]]) +; CHECK-NEXT: ret float [[F]] ; %D = fpext float %C to double ; --> truncf @@ -132,11 +96,11 @@ define float @test_shrink_libcall_trunc(float %C) { } ; This is replaced with the intrinsic, which does the right thing on -; all platforms. +; CHECK platforms. define float @test_shrink_libcall_fabs(float %C) { -; ALL-LABEL: @test_shrink_libcall_fabs( -; ALL-NEXT: [[F:%.*]] = call float @llvm.fabs.f32(float [[C:%.*]]) -; ALL-NEXT: ret float [[F]] +; CHECK-LABEL: @test_shrink_libcall_fabs( +; CHECK-NEXT: [[F:%.*]] = call float @llvm.fabs.f32(float [[C:%.*]]) +; CHECK-NEXT: ret float [[F]] ; %D = fpext float %C to double %E = call double @fabs(double %D) @@ -146,9 +110,9 @@ define float @test_shrink_libcall_fabs(float %C) { ; Make sure fast math flags are preserved define float @test_shrink_libcall_fabs_fast(float %C) { -; ALL-LABEL: @test_shrink_libcall_fabs_fast( -; ALL-NEXT: [[F:%.*]] = call fast float @llvm.fabs.f32(float [[C:%.*]]) -; ALL-NEXT: ret float [[F]] +; CHECK-LABEL: @test_shrink_libcall_fabs_fast( +; CHECK-NEXT: [[F:%.*]] = call fast float @llvm.fabs.f32(float [[C:%.*]]) +; CHECK-NEXT: ret float [[F]] ; %D = fpext float %C to double %E = call fast double @fabs(double %D) @@ -157,9 +121,9 @@ define float @test_shrink_libcall_fabs_fast(float %C) { } define float @test_shrink_intrin_ceil(float %C) { -; ALL-LABEL: @test_shrink_intrin_ceil( -; ALL-NEXT: [[TMP1:%.*]] = call float @llvm.ceil.f32(float [[C:%.*]]) -; ALL-NEXT: ret float [[TMP1]] +; CHECK-LABEL: @test_shrink_intrin_ceil( +; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.ceil.f32(float [[C:%.*]]) +; CHECK-NEXT: ret float [[TMP1]] ; %D = fpext float %C to double %E = call double @llvm.ceil.f64(double %D) @@ -168,9 +132,9 @@ define float @test_shrink_intrin_ceil(float %C) { } define float @test_shrink_intrin_fabs(float %C) { -; ALL-LABEL: @test_shrink_intrin_fabs( -; ALL-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[C:%.*]]) -; ALL-NEXT: ret float [[TMP1]] +; CHECK-LABEL: @test_shrink_intrin_fabs( +; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[C:%.*]]) +; CHECK-NEXT: ret float [[TMP1]] ; %D = fpext float %C to double %E = call double @llvm.fabs.f64(double %D) @@ -179,9 +143,9 @@ define float @test_shrink_intrin_fabs(float %C) { } define float @test_shrink_intrin_floor(float %C) { -; ALL-LABEL: @test_shrink_intrin_floor( -; ALL-NEXT: [[TMP1:%.*]] = call float @llvm.floor.f32(float [[C:%.*]]) -; ALL-NEXT: ret float [[TMP1]] +; CHECK-LABEL: @test_shrink_intrin_floor( +; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.floor.f32(float [[C:%.*]]) +; CHECK-NEXT: ret float [[TMP1]] ; %D = fpext float %C to double %E = call double @llvm.floor.f64(double %D) @@ -190,9 +154,9 @@ define float @test_shrink_intrin_floor(float %C) { } define float @test_shrink_intrin_nearbyint(float %C) { -; ALL-LABEL: @test_shrink_intrin_nearbyint( -; ALL-NEXT: [[TMP1:%.*]] = call float @llvm.nearbyint.f32(float [[C:%.*]]) -; ALL-NEXT: ret float [[TMP1]] +; CHECK-LABEL: @test_shrink_intrin_nearbyint( +; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.nearbyint.f32(float [[C:%.*]]) +; CHECK-NEXT: ret float [[TMP1]] ; %D = fpext float %C to double %E = call double @llvm.nearbyint.f64(double %D) @@ -201,9 +165,9 @@ define float @test_shrink_intrin_nearbyint(float %C) { } define half @test_shrink_intrin_rint(half %C) { -; ALL-LABEL: @test_shrink_intrin_rint( -; ALL-NEXT: [[TMP1:%.*]] = call half @llvm.rint.f16(half [[C:%.*]]) -; ALL-NEXT: ret half [[TMP1]] +; CHECK-LABEL: @test_shrink_intrin_rint( +; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.rint.f16(half [[C:%.*]]) +; CHECK-NEXT: ret half [[TMP1]] ; %D = fpext half %C to float %E = call float @llvm.rint.f32(float %D) @@ -212,9 +176,9 @@ define half @test_shrink_intrin_rint(half %C) { } define float @test_shrink_intrin_round(float %C) { -; ALL-LABEL: @test_shrink_intrin_round( -; ALL-NEXT: [[TMP1:%.*]] = call float @llvm.round.f32(float [[C:%.*]]) -; ALL-NEXT: ret float [[TMP1]] +; CHECK-LABEL: @test_shrink_intrin_round( +; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.round.f32(float [[C:%.*]]) +; CHECK-NEXT: ret float [[TMP1]] ; %D = fpext float %C to double %E = call double @llvm.round.f64(double %D) @@ -223,9 +187,9 @@ define float @test_shrink_intrin_round(float %C) { } define float @test_shrink_intrin_trunc(float %C) { -; ALL-LABEL: @test_shrink_intrin_trunc( -; ALL-NEXT: [[TMP1:%.*]] = call float @llvm.trunc.f32(float [[C:%.*]]) -; ALL-NEXT: ret float [[TMP1]] +; CHECK-LABEL: @test_shrink_intrin_trunc( +; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.trunc.f32(float [[C:%.*]]) +; CHECK-NEXT: ret float [[TMP1]] ; %D = fpext float %C to double %E = call double @llvm.trunc.f64(double %D) @@ -237,12 +201,12 @@ declare void @use_v2f64(<2 x double>) declare void @use_v2f32(<2 x float>) define <2 x float> @test_shrink_intrin_ceil_multi_use(<2 x float> %C) { -; ALL-LABEL: @test_shrink_intrin_ceil_multi_use( -; ALL-NEXT: [[D:%.*]] = fpext <2 x float> [[C:%.*]] to <2 x double> -; ALL-NEXT: [[E:%.*]] = call <2 x double> @llvm.ceil.v2f64(<2 x double> [[D]]) -; ALL-NEXT: [[F:%.*]] = fptrunc <2 x double> [[E]] to <2 x float> -; ALL-NEXT: call void @use_v2f64(<2 x double> [[D]]) -; ALL-NEXT: ret <2 x float> [[F]] +; CHECK-LABEL: @test_shrink_intrin_ceil_multi_use( +; CHECK-NEXT: [[D:%.*]] = fpext <2 x float> [[C:%.*]] to <2 x double> +; CHECK-NEXT: [[E:%.*]] = call <2 x double> @llvm.ceil.v2f64(<2 x double> [[D]]) +; CHECK-NEXT: [[F:%.*]] = fptrunc <2 x double> [[E]] to <2 x float> +; CHECK-NEXT: call void @use_v2f64(<2 x double> [[D]]) +; CHECK-NEXT: ret <2 x float> [[F]] ; %D = fpext <2 x float> %C to <2 x double> %E = call <2 x double> @llvm.ceil.v2f64(<2 x double> %D) @@ -252,11 +216,11 @@ define <2 x float> @test_shrink_intrin_ceil_multi_use(<2 x float> %C) { } define <2 x float> @test_shrink_intrin_fabs_multi_use(<2 x float> %C) { -; ALL-LABEL: @test_shrink_intrin_fabs_multi_use( -; ALL-NEXT: [[TMP1:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[C:%.*]]) -; ALL-NEXT: [[E:%.*]] = fpext <2 x float> [[TMP1]] to <2 x double> -; ALL-NEXT: call void @use_v2f64(<2 x double> [[E]]) -; ALL-NEXT: ret <2 x float> [[TMP1]] +; CHECK-LABEL: @test_shrink_intrin_fabs_multi_use( +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[C:%.*]]) +; CHECK-NEXT: [[E:%.*]] = fpext <2 x float> [[TMP1]] to <2 x double> +; CHECK-NEXT: call void @use_v2f64(<2 x double> [[E]]) +; CHECK-NEXT: ret <2 x float> [[TMP1]] ; %D = fpext <2 x float> %C to <2 x double> %E = call <2 x double> @llvm.fabs.v2f64(<2 x double> %D) @@ -266,13 +230,13 @@ define <2 x float> @test_shrink_intrin_fabs_multi_use(<2 x float> %C) { } define <2 x float> @test_shrink_intrin_floor_multi_use(<2 x float> %C) { -; ALL-LABEL: @test_shrink_intrin_floor_multi_use( -; ALL-NEXT: [[D:%.*]] = fpext <2 x float> [[C:%.*]] to <2 x double> -; ALL-NEXT: [[E:%.*]] = call <2 x double> @llvm.floor.v2f64(<2 x double> [[D]]) -; ALL-NEXT: [[F:%.*]] = fptrunc <2 x double> [[E]] to <2 x float> -; ALL-NEXT: call void @use_v2f64(<2 x double> [[D]]) -; ALL-NEXT: call void @use_v2f64(<2 x double> [[E]]) -; ALL-NEXT: ret <2 x float> [[F]] +; CHECK-LABEL: @test_shrink_intrin_floor_multi_use( +; CHECK-NEXT: [[D:%.*]] = fpext <2 x float> [[C:%.*]] to <2 x double> +; CHECK-NEXT: [[E:%.*]] = call <2 x double> @llvm.floor.v2f64(<2 x double> [[D]]) +; CHECK-NEXT: [[F:%.*]] = fptrunc <2 x double> [[E]] to <2 x float> +; CHECK-NEXT: call void @use_v2f64(<2 x double> [[D]]) +; CHECK-NEXT: call void @use_v2f64(<2 x double> [[E]]) +; CHECK-NEXT: ret <2 x float> [[F]] ; %D = fpext <2 x float> %C to <2 x double> %E = call <2 x double> @llvm.floor.v2f64(<2 x double> %D) @@ -283,12 +247,12 @@ define <2 x float> @test_shrink_intrin_floor_multi_use(<2 x float> %C) { } define <2 x float> @test_shrink_intrin_nearbyint_multi_use(<2 x float> %C) { -; ALL-LABEL: @test_shrink_intrin_nearbyint_multi_use( -; ALL-NEXT: [[D:%.*]] = fpext <2 x float> [[C:%.*]] to <2 x double> -; ALL-NEXT: [[E:%.*]] = call <2 x double> @llvm.nearbyint.v2f64(<2 x double> [[D]]) -; ALL-NEXT: [[F:%.*]] = fptrunc <2 x double> [[E]] to <2 x float> -; ALL-NEXT: call void @use_v2f64(<2 x double> [[D]]) -; ALL-NEXT: ret <2 x float> [[F]] +; CHECK-LABEL: @test_shrink_intrin_nearbyint_multi_use( +; CHECK-NEXT: [[D:%.*]] = fpext <2 x float> [[C:%.*]] to <2 x double> +; CHECK-NEXT: [[E:%.*]] = call <2 x double> @llvm.nearbyint.v2f64(<2 x double> [[D]]) +; CHECK-NEXT: [[F:%.*]] = fptrunc <2 x double> [[E]] to <2 x float> +; CHECK-NEXT: call void @use_v2f64(<2 x double> [[D]]) +; CHECK-NEXT: ret <2 x float> [[F]] ; %D = fpext <2 x float> %C to <2 x double> %E = call <2 x double> @llvm.nearbyint.v2f64(<2 x double> %D) @@ -298,11 +262,11 @@ define <2 x float> @test_shrink_intrin_nearbyint_multi_use(<2 x float> %C) { } define <2 x half> @test_shrink_intrin_rint_multi_use(<2 x half> %C) { -; ALL-LABEL: @test_shrink_intrin_rint_multi_use( -; ALL-NEXT: [[TMP1:%.*]] = call <2 x half> @llvm.rint.v2f16(<2 x half> [[C:%.*]]) -; ALL-NEXT: [[E:%.*]] = fpext <2 x half> [[TMP1]] to <2 x float> -; ALL-NEXT: call void @use_v2f32(<2 x float> [[E]]) -; ALL-NEXT: ret <2 x half> [[TMP1]] +; CHECK-LABEL: @test_shrink_intrin_rint_multi_use( +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x half> @llvm.rint.v2f16(<2 x half> [[C:%.*]]) +; CHECK-NEXT: [[E:%.*]] = fpext <2 x half> [[TMP1]] to <2 x float> +; CHECK-NEXT: call void @use_v2f32(<2 x float> [[E]]) +; CHECK-NEXT: ret <2 x half> [[TMP1]] ; %D = fpext <2 x half> %C to <2 x float> %E = call <2 x float> @llvm.rint.v2f32(<2 x float> %D) @@ -312,13 +276,13 @@ define <2 x half> @test_shrink_intrin_rint_multi_use(<2 x half> %C) { } define <2 x float> @test_shrink_intrin_round_multi_use(<2 x float> %C) { -; ALL-LABEL: @test_shrink_intrin_round_multi_use( -; ALL-NEXT: [[D:%.*]] = fpext <2 x float> [[C:%.*]] to <2 x double> -; ALL-NEXT: [[E:%.*]] = call <2 x double> @llvm.round.v2f64(<2 x double> [[D]]) -; ALL-NEXT: [[F:%.*]] = fptrunc <2 x double> [[E]] to <2 x float> -; ALL-NEXT: call void @use_v2f64(<2 x double> [[D]]) -; ALL-NEXT: call void @use_v2f64(<2 x double> [[E]]) -; ALL-NEXT: ret <2 x float> [[F]] +; CHECK-LABEL: @test_shrink_intrin_round_multi_use( +; CHECK-NEXT: [[D:%.*]] = fpext <2 x float> [[C:%.*]] to <2 x double> +; CHECK-NEXT: [[E:%.*]] = call <2 x double> @llvm.round.v2f64(<2 x double> [[D]]) +; CHECK-NEXT: [[F:%.*]] = fptrunc <2 x double> [[E]] to <2 x float> +; CHECK-NEXT: call void @use_v2f64(<2 x double> [[D]]) +; CHECK-NEXT: call void @use_v2f64(<2 x double> [[E]]) +; CHECK-NEXT: ret <2 x float> [[F]] ; %D = fpext <2 x float> %C to <2 x double> %E = call <2 x double> @llvm.round.v2f64(<2 x double> %D) @@ -329,12 +293,12 @@ define <2 x float> @test_shrink_intrin_round_multi_use(<2 x float> %C) { } define <2 x float> @test_shrink_intrin_trunc_multi_use(<2 x float> %C) { -; ALL-LABEL: @test_shrink_intrin_trunc_multi_use( -; ALL-NEXT: [[D:%.*]] = fpext <2 x float> [[C:%.*]] to <2 x double> -; ALL-NEXT: [[E:%.*]] = call <2 x double> @llvm.trunc.v2f64(<2 x double> [[D]]) -; ALL-NEXT: [[F:%.*]] = fptrunc <2 x double> [[E]] to <2 x float> -; ALL-NEXT: call void @use_v2f64(<2 x double> [[D]]) -; ALL-NEXT: ret <2 x float> [[F]] +; CHECK-LABEL: @test_shrink_intrin_trunc_multi_use( +; CHECK-NEXT: [[D:%.*]] = fpext <2 x float> [[C:%.*]] to <2 x double> +; CHECK-NEXT: [[E:%.*]] = call <2 x double> @llvm.trunc.v2f64(<2 x double> [[D]]) +; CHECK-NEXT: [[F:%.*]] = fptrunc <2 x double> [[E]] to <2 x float> +; CHECK-NEXT: call void @use_v2f64(<2 x double> [[D]]) +; CHECK-NEXT: ret <2 x float> [[F]] ; %D = fpext <2 x float> %C to <2 x double> %E = call <2 x double> @llvm.trunc.v2f64(<2 x double> %D) @@ -345,9 +309,9 @@ define <2 x float> @test_shrink_intrin_trunc_multi_use(<2 x float> %C) { ; Make sure fast math flags are preserved define float @test_shrink_intrin_fabs_fast(float %C) { -; ALL-LABEL: @test_shrink_intrin_fabs_fast( -; ALL-NEXT: [[TMP1:%.*]] = call fast float @llvm.fabs.f32(float [[C:%.*]]) -; ALL-NEXT: ret float [[TMP1]] +; CHECK-LABEL: @test_shrink_intrin_fabs_fast( +; CHECK-NEXT: [[TMP1:%.*]] = call fast float @llvm.fabs.f32(float [[C:%.*]]) +; CHECK-NEXT: ret float [[TMP1]] ; %D = fpext float %C to double %E = call fast double @llvm.fabs.f64(double %D) @@ -356,10 +320,10 @@ define float @test_shrink_intrin_fabs_fast(float %C) { } define float @test_no_shrink_intrin_floor(double %D) { -; ALL-LABEL: @test_no_shrink_intrin_floor( -; ALL-NEXT: [[E:%.*]] = call double @llvm.floor.f64(double [[D:%.*]]) -; ALL-NEXT: [[F:%.*]] = fptrunc double [[E]] to float -; ALL-NEXT: ret float [[F]] +; CHECK-LABEL: @test_no_shrink_intrin_floor( +; CHECK-NEXT: [[E:%.*]] = call double @llvm.floor.f64(double [[D:%.*]]) +; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to float +; CHECK-NEXT: ret float [[F]] ; %E = call double @llvm.floor.f64(double %D) %F = fptrunc double %E to float @@ -367,10 +331,10 @@ define float @test_no_shrink_intrin_floor(double %D) { } define float @test_no_shrink_intrin_ceil(double %D) { -; ALL-LABEL: @test_no_shrink_intrin_ceil( -; ALL-NEXT: [[E:%.*]] = call double @llvm.ceil.f64(double [[D:%.*]]) -; ALL-NEXT: [[F:%.*]] = fptrunc double [[E]] to float -; ALL-NEXT: ret float [[F]] +; CHECK-LABEL: @test_no_shrink_intrin_ceil( +; CHECK-NEXT: [[E:%.*]] = call double @llvm.ceil.f64(double [[D:%.*]]) +; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to float +; CHECK-NEXT: ret float [[F]] ; %E = call double @llvm.ceil.f64(double %D) %F = fptrunc double %E to float @@ -378,10 +342,10 @@ define float @test_no_shrink_intrin_ceil(double %D) { } define float @test_no_shrink_intrin_round(double %D) { -; ALL-LABEL: @test_no_shrink_intrin_round( -; ALL-NEXT: [[E:%.*]] = call double @llvm.round.f64(double [[D:%.*]]) -; ALL-NEXT: [[F:%.*]] = fptrunc double [[E]] to float -; ALL-NEXT: ret float [[F]] +; CHECK-LABEL: @test_no_shrink_intrin_round( +; CHECK-NEXT: [[E:%.*]] = call double @llvm.round.f64(double [[D:%.*]]) +; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to float +; CHECK-NEXT: ret float [[F]] ; %E = call double @llvm.round.f64(double %D) %F = fptrunc double %E to float @@ -389,10 +353,10 @@ define float @test_no_shrink_intrin_round(double %D) { } define float @test_no_shrink_intrin_nearbyint(double %D) { -; ALL-LABEL: @test_no_shrink_intrin_nearbyint( -; ALL-NEXT: [[E:%.*]] = call double @llvm.nearbyint.f64(double [[D:%.*]]) -; ALL-NEXT: [[F:%.*]] = fptrunc double [[E]] to float -; ALL-NEXT: ret float [[F]] +; CHECK-LABEL: @test_no_shrink_intrin_nearbyint( +; CHECK-NEXT: [[E:%.*]] = call double @llvm.nearbyint.f64(double [[D:%.*]]) +; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to float +; CHECK-NEXT: ret float [[F]] ; %E = call double @llvm.nearbyint.f64(double %D) %F = fptrunc double %E to float @@ -400,10 +364,10 @@ define float @test_no_shrink_intrin_nearbyint(double %D) { } define float @test_no_shrink_intrin_trunc(double %D) { -; ALL-LABEL: @test_no_shrink_intrin_trunc( -; ALL-NEXT: [[E:%.*]] = call double @llvm.trunc.f64(double [[D:%.*]]) -; ALL-NEXT: [[F:%.*]] = fptrunc double [[E]] to float -; ALL-NEXT: ret float [[F]] +; CHECK-LABEL: @test_no_shrink_intrin_trunc( +; CHECK-NEXT: [[E:%.*]] = call double @llvm.trunc.f64(double [[D:%.*]]) +; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to float +; CHECK-NEXT: ret float [[F]] ; %E = call double @llvm.trunc.f64(double %D) %F = fptrunc double %E to float @@ -411,10 +375,10 @@ define float @test_no_shrink_intrin_trunc(double %D) { } define float @test_shrink_intrin_fabs_double_src(double %D) { -; ALL-LABEL: @test_shrink_intrin_fabs_double_src( -; ALL-NEXT: [[TMP1:%.*]] = fptrunc double [[D:%.*]] to float -; ALL-NEXT: [[F:%.*]] = call float @llvm.fabs.f32(float [[TMP1]]) -; ALL-NEXT: ret float [[F]] +; CHECK-LABEL: @test_shrink_intrin_fabs_double_src( +; CHECK-NEXT: [[TMP1:%.*]] = fptrunc double [[D:%.*]] to float +; CHECK-NEXT: [[F:%.*]] = call float @llvm.fabs.f32(float [[TMP1]]) +; CHECK-NEXT: ret float [[F]] ; %E = call double @llvm.fabs.f64(double %D) %F = fptrunc double %E to float @@ -423,10 +387,10 @@ define float @test_shrink_intrin_fabs_double_src(double %D) { ; Make sure fast math flags are preserved define float @test_shrink_intrin_fabs_fast_double_src(double %D) { -; ALL-LABEL: @test_shrink_intrin_fabs_fast_double_src( -; ALL-NEXT: [[TMP1:%.*]] = fptrunc double [[D:%.*]] to float -; ALL-NEXT: [[F:%.*]] = call fast float @llvm.fabs.f32(float [[TMP1]]) -; ALL-NEXT: ret float [[F]] +; CHECK-LABEL: @test_shrink_intrin_fabs_fast_double_src( +; CHECK-NEXT: [[TMP1:%.*]] = fptrunc double [[D:%.*]] to float +; CHECK-NEXT: [[F:%.*]] = call fast float @llvm.fabs.f32(float [[TMP1]]) +; CHECK-NEXT: ret float [[F]] ; %E = call fast double @llvm.fabs.f64(double %D) %F = fptrunc double %E to float @@ -434,8 +398,8 @@ define float @test_shrink_intrin_fabs_fast_double_src(double %D) { } define float @test_shrink_float_convertible_constant_intrin_floor() { -; ALL-LABEL: @test_shrink_float_convertible_constant_intrin_floor( -; ALL-NEXT: ret float 2.000000e+00 +; CHECK-LABEL: @test_shrink_float_convertible_constant_intrin_floor( +; CHECK-NEXT: ret float 2.000000e+00 ; %E = call double @llvm.floor.f64(double 2.1) %F = fptrunc double %E to float @@ -443,8 +407,8 @@ define float @test_shrink_float_convertible_constant_intrin_floor() { } define float @test_shrink_float_convertible_constant_intrin_ceil() { -; ALL-LABEL: @test_shrink_float_convertible_constant_intrin_ceil( -; ALL-NEXT: ret float 3.000000e+00 +; CHECK-LABEL: @test_shrink_float_convertible_constant_intrin_ceil( +; CHECK-NEXT: ret float 3.000000e+00 ; %E = call double @llvm.ceil.f64(double 2.1) %F = fptrunc double %E to float @@ -452,8 +416,8 @@ define float @test_shrink_float_convertible_constant_intrin_ceil() { } define float @test_shrink_float_convertible_constant_intrin_round() { -; ALL-LABEL: @test_shrink_float_convertible_constant_intrin_round( -; ALL-NEXT: ret float 2.000000e+00 +; CHECK-LABEL: @test_shrink_float_convertible_constant_intrin_round( +; CHECK-NEXT: ret float 2.000000e+00 ; %E = call double @llvm.round.f64(double 2.1) %F = fptrunc double %E to float @@ -461,8 +425,8 @@ define float @test_shrink_float_convertible_constant_intrin_round() { } define float @test_shrink_float_convertible_constant_intrin_nearbyint() { -; ALL-LABEL: @test_shrink_float_convertible_constant_intrin_nearbyint( -; ALL-NEXT: ret float 2.000000e+00 +; CHECK-LABEL: @test_shrink_float_convertible_constant_intrin_nearbyint( +; CHECK-NEXT: ret float 2.000000e+00 ; %E = call double @llvm.nearbyint.f64(double 2.1) %F = fptrunc double %E to float @@ -470,8 +434,8 @@ define float @test_shrink_float_convertible_constant_intrin_nearbyint() { } define float @test_shrink_float_convertible_constant_intrin_trunc() { -; ALL-LABEL: @test_shrink_float_convertible_constant_intrin_trunc( -; ALL-NEXT: ret float 2.000000e+00 +; CHECK-LABEL: @test_shrink_float_convertible_constant_intrin_trunc( +; CHECK-NEXT: ret float 2.000000e+00 ; %E = call double @llvm.trunc.f64(double 2.1) %F = fptrunc double %E to float @@ -479,8 +443,8 @@ define float @test_shrink_float_convertible_constant_intrin_trunc() { } define float @test_shrink_float_convertible_constant_intrin_fabs() { -; ALL-LABEL: @test_shrink_float_convertible_constant_intrin_fabs( -; ALL-NEXT: ret float 0x4000CCCCC0000000 +; CHECK-LABEL: @test_shrink_float_convertible_constant_intrin_fabs( +; CHECK-NEXT: ret float 0x4000CCCCC0000000 ; %E = call double @llvm.fabs.f64(double 2.1) %F = fptrunc double %E to float @@ -489,8 +453,8 @@ define float @test_shrink_float_convertible_constant_intrin_fabs() { ; Make sure fast math flags are preserved define float @test_shrink_float_convertible_constant_intrin_fabs_fast() { -; ALL-LABEL: @test_shrink_float_convertible_constant_intrin_fabs_fast( -; ALL-NEXT: ret float 0x4000CCCCC0000000 +; CHECK-LABEL: @test_shrink_float_convertible_constant_intrin_fabs_fast( +; CHECK-NEXT: ret float 0x4000CCCCC0000000 ; %E = call fast double @llvm.fabs.f64(double 2.1) %F = fptrunc double %E to float @@ -498,10 +462,10 @@ define float @test_shrink_float_convertible_constant_intrin_fabs_fast() { } define half @test_no_shrink_mismatched_type_intrin_floor(double %D) { -; ALL-LABEL: @test_no_shrink_mismatched_type_intrin_floor( -; ALL-NEXT: [[E:%.*]] = call double @llvm.floor.f64(double [[D:%.*]]) -; ALL-NEXT: [[F:%.*]] = fptrunc double [[E]] to half -; ALL-NEXT: ret half [[F]] +; CHECK-LABEL: @test_no_shrink_mismatched_type_intrin_floor( +; CHECK-NEXT: [[E:%.*]] = call double @llvm.floor.f64(double [[D:%.*]]) +; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to half +; CHECK-NEXT: ret half [[F]] ; %E = call double @llvm.floor.f64(double %D) %F = fptrunc double %E to half @@ -509,10 +473,10 @@ define half @test_no_shrink_mismatched_type_intrin_floor(double %D) { } define half @test_no_shrink_mismatched_type_intrin_ceil(double %D) { -; ALL-LABEL: @test_no_shrink_mismatched_type_intrin_ceil( -; ALL-NEXT: [[E:%.*]] = call double @llvm.ceil.f64(double [[D:%.*]]) -; ALL-NEXT: [[F:%.*]] = fptrunc double [[E]] to half -; ALL-NEXT: ret half [[F]] +; CHECK-LABEL: @test_no_shrink_mismatched_type_intrin_ceil( +; CHECK-NEXT: [[E:%.*]] = call double @llvm.ceil.f64(double [[D:%.*]]) +; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to half +; CHECK-NEXT: ret half [[F]] ; %E = call double @llvm.ceil.f64(double %D) %F = fptrunc double %E to half @@ -520,10 +484,10 @@ define half @test_no_shrink_mismatched_type_intrin_ceil(double %D) { } define half @test_no_shrink_mismatched_type_intrin_round(double %D) { -; ALL-LABEL: @test_no_shrink_mismatched_type_intrin_round( -; ALL-NEXT: [[E:%.*]] = call double @llvm.round.f64(double [[D:%.*]]) -; ALL-NEXT: [[F:%.*]] = fptrunc double [[E]] to half -; ALL-NEXT: ret half [[F]] +; CHECK-LABEL: @test_no_shrink_mismatched_type_intrin_round( +; CHECK-NEXT: [[E:%.*]] = call double @llvm.round.f64(double [[D:%.*]]) +; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to half +; CHECK-NEXT: ret half [[F]] ; %E = call double @llvm.round.f64(double %D) %F = fptrunc double %E to half @@ -531,10 +495,10 @@ define half @test_no_shrink_mismatched_type_intrin_round(double %D) { } define half @test_no_shrink_mismatched_type_intrin_nearbyint(double %D) { -; ALL-LABEL: @test_no_shrink_mismatched_type_intrin_nearbyint( -; ALL-NEXT: [[E:%.*]] = call double @llvm.nearbyint.f64(double [[D:%.*]]) -; ALL-NEXT: [[F:%.*]] = fptrunc double [[E]] to half -; ALL-NEXT: ret half [[F]] +; CHECK-LABEL: @test_no_shrink_mismatched_type_intrin_nearbyint( +; CHECK-NEXT: [[E:%.*]] = call double @llvm.nearbyint.f64(double [[D:%.*]]) +; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to half +; CHECK-NEXT: ret half [[F]] ; %E = call double @llvm.nearbyint.f64(double %D) %F = fptrunc double %E to half @@ -542,10 +506,10 @@ define half @test_no_shrink_mismatched_type_intrin_nearbyint(double %D) { } define half @test_no_shrink_mismatched_type_intrin_trunc(double %D) { -; ALL-LABEL: @test_no_shrink_mismatched_type_intrin_trunc( -; ALL-NEXT: [[E:%.*]] = call double @llvm.trunc.f64(double [[D:%.*]]) -; ALL-NEXT: [[F:%.*]] = fptrunc double [[E]] to half -; ALL-NEXT: ret half [[F]] +; CHECK-LABEL: @test_no_shrink_mismatched_type_intrin_trunc( +; CHECK-NEXT: [[E:%.*]] = call double @llvm.trunc.f64(double [[D:%.*]]) +; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to half +; CHECK-NEXT: ret half [[F]] ; %E = call double @llvm.trunc.f64(double %D) %F = fptrunc double %E to half @@ -553,10 +517,10 @@ define half @test_no_shrink_mismatched_type_intrin_trunc(double %D) { } define half @test_shrink_mismatched_type_intrin_fabs_double_src(double %D) { -; ALL-LABEL: @test_shrink_mismatched_type_intrin_fabs_double_src( -; ALL-NEXT: [[TMP1:%.*]] = fptrunc double [[D:%.*]] to half -; ALL-NEXT: [[F:%.*]] = call half @llvm.fabs.f16(half [[TMP1]]) -; ALL-NEXT: ret half [[F]] +; CHECK-LABEL: @test_shrink_mismatched_type_intrin_fabs_double_src( +; CHECK-NEXT: [[TMP1:%.*]] = fptrunc double [[D:%.*]] to half +; CHECK-NEXT: [[F:%.*]] = call half @llvm.fabs.f16(half [[TMP1]]) +; CHECK-NEXT: ret half [[F]] ; %E = call double @llvm.fabs.f64(double %D) %F = fptrunc double %E to half @@ -565,10 +529,10 @@ define half @test_shrink_mismatched_type_intrin_fabs_double_src(double %D) { ; Make sure fast math flags are preserved define half @test_mismatched_type_intrin_fabs_fast_double_src(double %D) { -; ALL-LABEL: @test_mismatched_type_intrin_fabs_fast_double_src( -; ALL-NEXT: [[TMP1:%.*]] = fptrunc double [[D:%.*]] to half -; ALL-NEXT: [[F:%.*]] = call fast half @llvm.fabs.f16(half [[TMP1]]) -; ALL-NEXT: ret half [[F]] +; CHECK-LABEL: @test_mismatched_type_intrin_fabs_fast_double_src( +; CHECK-NEXT: [[TMP1:%.*]] = fptrunc double [[D:%.*]] to half +; CHECK-NEXT: [[F:%.*]] = call fast half @llvm.fabs.f16(half [[TMP1]]) +; CHECK-NEXT: ret half [[F]] ; %E = call fast double @llvm.fabs.f64(double %D) %F = fptrunc double %E to half @@ -576,10 +540,10 @@ define half @test_mismatched_type_intrin_fabs_fast_double_src(double %D) { } define <2 x double> @test_shrink_intrin_floor_fp16_vec(<2 x half> %C) { -; ALL-LABEL: @test_shrink_intrin_floor_fp16_vec( -; ALL-NEXT: [[TMP1:%.*]] = call arcp <2 x half> @llvm.floor.v2f16(<2 x half> [[C:%.*]]) -; ALL-NEXT: [[E:%.*]] = fpext <2 x half> [[TMP1]] to <2 x double> -; ALL-NEXT: ret <2 x double> [[E]] +; CHECK-LABEL: @test_shrink_intrin_floor_fp16_vec( +; CHECK-NEXT: [[TMP1:%.*]] = call arcp <2 x half> @llvm.floor.v2f16(<2 x half> [[C:%.*]]) +; CHECK-NEXT: [[E:%.*]] = fpext <2 x half> [[TMP1]] to <2 x double> +; CHECK-NEXT: ret <2 x double> [[E]] ; %D = fpext <2 x half> %C to <2 x double> %E = call arcp <2 x double> @llvm.floor.v2f64(<2 x double> %D) @@ -587,10 +551,10 @@ define <2 x double> @test_shrink_intrin_floor_fp16_vec(<2 x half> %C) { } define float @test_shrink_intrin_ceil_fp16_src(half %C) { -; ALL-LABEL: @test_shrink_intrin_ceil_fp16_src( -; ALL-NEXT: [[TMP1:%.*]] = call half @llvm.ceil.f16(half [[C:%.*]]) -; ALL-NEXT: [[F:%.*]] = fpext half [[TMP1]] to float -; ALL-NEXT: ret float [[F]] +; CHECK-LABEL: @test_shrink_intrin_ceil_fp16_src( +; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.ceil.f16(half [[C:%.*]]) +; CHECK-NEXT: [[F:%.*]] = fpext half [[TMP1]] to float +; CHECK-NEXT: ret float [[F]] ; %D = fpext half %C to double %E = call double @llvm.ceil.f64(double %D) @@ -599,10 +563,10 @@ define float @test_shrink_intrin_ceil_fp16_src(half %C) { } define <2 x double> @test_shrink_intrin_round_fp16_vec(<2 x half> %C) { -; ALL-LABEL: @test_shrink_intrin_round_fp16_vec( -; ALL-NEXT: [[TMP1:%.*]] = call <2 x half> @llvm.round.v2f16(<2 x half> [[C:%.*]]) -; ALL-NEXT: [[E:%.*]] = fpext <2 x half> [[TMP1]] to <2 x double> -; ALL-NEXT: ret <2 x double> [[E]] +; CHECK-LABEL: @test_shrink_intrin_round_fp16_vec( +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x half> @llvm.round.v2f16(<2 x half> [[C:%.*]]) +; CHECK-NEXT: [[E:%.*]] = fpext <2 x half> [[TMP1]] to <2 x double> +; CHECK-NEXT: ret <2 x double> [[E]] ; %D = fpext <2 x half> %C to <2 x double> %E = call <2 x double> @llvm.round.v2f64(<2 x double> %D) @@ -610,10 +574,10 @@ define <2 x double> @test_shrink_intrin_round_fp16_vec(<2 x half> %C) { } define float @test_shrink_intrin_nearbyint_fp16_src(half %C) { -; ALL-LABEL: @test_shrink_intrin_nearbyint_fp16_src( -; ALL-NEXT: [[TMP1:%.*]] = call half @llvm.nearbyint.f16(half [[C:%.*]]) -; ALL-NEXT: [[F:%.*]] = fpext half [[TMP1]] to float -; ALL-NEXT: ret float [[F]] +; CHECK-LABEL: @test_shrink_intrin_nearbyint_fp16_src( +; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.nearbyint.f16(half [[C:%.*]]) +; CHECK-NEXT: [[F:%.*]] = fpext half [[TMP1]] to float +; CHECK-NEXT: ret float [[F]] ; %D = fpext half %C to double %E = call double @llvm.nearbyint.f64(double %D) @@ -622,10 +586,10 @@ define float @test_shrink_intrin_nearbyint_fp16_src(half %C) { } define <2 x double> @test_shrink_intrin_trunc_fp16_src(<2 x half> %C) { -; ALL-LABEL: @test_shrink_intrin_trunc_fp16_src( -; ALL-NEXT: [[TMP1:%.*]] = call <2 x half> @llvm.trunc.v2f16(<2 x half> [[C:%.*]]) -; ALL-NEXT: [[E:%.*]] = fpext <2 x half> [[TMP1]] to <2 x double> -; ALL-NEXT: ret <2 x double> [[E]] +; CHECK-LABEL: @test_shrink_intrin_trunc_fp16_src( +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x half> @llvm.trunc.v2f16(<2 x half> [[C:%.*]]) +; CHECK-NEXT: [[E:%.*]] = fpext <2 x half> [[TMP1]] to <2 x double> +; CHECK-NEXT: ret <2 x double> [[E]] ; %D = fpext <2 x half> %C to <2 x double> %E = call <2 x double> @llvm.trunc.v2f64(<2 x double> %D) @@ -633,10 +597,10 @@ define <2 x double> @test_shrink_intrin_trunc_fp16_src(<2 x half> %C) { } define float @test_shrink_intrin_fabs_fp16_src(half %C) { -; ALL-LABEL: @test_shrink_intrin_fabs_fp16_src( -; ALL-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[C:%.*]]) -; ALL-NEXT: [[F:%.*]] = fpext half [[TMP1]] to float -; ALL-NEXT: ret float [[F]] +; CHECK-LABEL: @test_shrink_intrin_fabs_fp16_src( +; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[C:%.*]]) +; CHECK-NEXT: [[F:%.*]] = fpext half [[TMP1]] to float +; CHECK-NEXT: ret float [[F]] ; %D = fpext half %C to double %E = call double @llvm.fabs.f64(double %D) @@ -646,10 +610,10 @@ define float @test_shrink_intrin_fabs_fp16_src(half %C) { ; Make sure fast math flags are preserved define float @test_shrink_intrin_fabs_fast_fp16_src(half %C) { -; ALL-LABEL: @test_shrink_intrin_fabs_fast_fp16_src( -; ALL-NEXT: [[TMP1:%.*]] = call fast half @llvm.fabs.f16(half [[C:%.*]]) -; ALL-NEXT: [[F:%.*]] = fpext half [[TMP1]] to float -; ALL-NEXT: ret float [[F]] +; CHECK-LABEL: @test_shrink_intrin_fabs_fast_fp16_src( +; CHECK-NEXT: [[TMP1:%.*]] = call fast half @llvm.fabs.f16(half [[C:%.*]]) +; CHECK-NEXT: [[F:%.*]] = fpext half [[TMP1]] to float +; CHECK-NEXT: ret float [[F]] ; %D = fpext half %C to double %E = call fast double @llvm.fabs.f64(double %D) @@ -658,12 +622,12 @@ define float @test_shrink_intrin_fabs_fast_fp16_src(half %C) { } define float @test_no_shrink_intrin_floor_multi_use_fpext(half %C) { -; ALL-LABEL: @test_no_shrink_intrin_floor_multi_use_fpext( -; ALL-NEXT: [[D:%.*]] = fpext half [[C:%.*]] to double -; ALL-NEXT: store volatile double [[D]], double* undef, align 8 -; ALL-NEXT: [[E:%.*]] = call double @llvm.floor.f64(double [[D]]) -; ALL-NEXT: [[F:%.*]] = fptrunc double [[E]] to float -; ALL-NEXT: ret float [[F]] +; CHECK-LABEL: @test_no_shrink_intrin_floor_multi_use_fpext( +; CHECK-NEXT: [[D:%.*]] = fpext half [[C:%.*]] to double +; CHECK-NEXT: store volatile double [[D]], double* undef, align 8 +; CHECK-NEXT: [[E:%.*]] = call double @llvm.floor.f64(double [[D]]) +; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to float +; CHECK-NEXT: ret float [[F]] ; %D = fpext half %C to double store volatile double %D, double* undef @@ -673,12 +637,12 @@ define float @test_no_shrink_intrin_floor_multi_use_fpext(half %C) { } define float @test_no_shrink_intrin_fabs_multi_use_fpext(half %C) { -; ALL-LABEL: @test_no_shrink_intrin_fabs_multi_use_fpext( -; ALL-NEXT: [[D:%.*]] = fpext half [[C:%.*]] to double -; ALL-NEXT: store volatile double [[D]], double* undef, align 8 -; ALL-NEXT: [[E:%.*]] = call double @llvm.fabs.f64(double [[D]]) -; ALL-NEXT: [[F:%.*]] = fptrunc double [[E]] to float -; ALL-NEXT: ret float [[F]] +; CHECK-LABEL: @test_no_shrink_intrin_fabs_multi_use_fpext( +; CHECK-NEXT: [[D:%.*]] = fpext half [[C:%.*]] to double +; CHECK-NEXT: store volatile double [[D]], double* undef, align 8 +; CHECK-NEXT: [[E:%.*]] = call double @llvm.fabs.f64(double [[D]]) +; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to float +; CHECK-NEXT: ret float [[F]] ; %D = fpext half %C to double store volatile double %D, double* undef diff --git a/llvm/test/Transforms/InstCombine/pow-1.ll b/llvm/test/Transforms/InstCombine/pow-1.ll index 672ec70e71ec2..957e2488b721b 100644 --- a/llvm/test/Transforms/InstCombine/pow-1.ll +++ b/llvm/test/Transforms/InstCombine/pow-1.ll @@ -1,15 +1,18 @@ ; Test that the pow library call simplifier works correctly. ; -; RUN: opt -instcombine -S < %s | FileCheck %s --check-prefixes=ANY -; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.9 | FileCheck %s --check-prefixes=ANY,CHECK-EXP10 -; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios7.0 | FileCheck %s --check-prefixes=ANY,CHECK-EXP10 -; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.8 | FileCheck %s --check-prefixes=ANY,CHECK-NO-EXP10 -; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios6.0 | FileCheck %s --check-prefixes=ANY,CHECK-NO-EXP10 -; RUN: opt -instcombine -S < %s -mtriple=x86_64-netbsd | FileCheck %s --check-prefixes=ANY,CHECK-NO-EXP10 -; RUN: opt -instcombine -S < %s -mtriple=arm-apple-tvos9.0 | FileCheck %s --check-prefixes=ANY,CHECK-EXP10 -; RUN: opt -instcombine -S < %s -mtriple=arm-apple-watchos2.0 | FileCheck %s --check-prefixes=ANY,CHECK-EXP10 +; RUN: opt -instcombine -S < %s | FileCheck %s --check-prefixes=CHECK,ANY +; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.9 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios7.0 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.8 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-NO-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios6.0 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-NO-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=x86_64-netbsd | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-NO-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=arm-apple-tvos9.0 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=arm-apple-watchos2.0 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10 ; rdar://7251832 -; RUN: opt -instcombine -S < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK-WIN +; RUN: opt -instcombine -S < %s -mtriple=i386-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,MSVC,VC32,CHECK-NO-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=i386-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,MSVC,VC51,VC19,CHECK-NO-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=x86_64-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,MSVC,VC64,CHECK-NO-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,MSVC,VC83,VC19,CHECK-NO-EXP10 ; NOTE: The readonly attribute on the pow call should be preserved ; in the cases below where pow is transformed into another function call. @@ -23,32 +26,39 @@ declare <2 x double> @llvm.pow.v2f64(<2 x double>, <2 x double>) nounwind readon ; Check pow(1.0, x) -> 1.0. define float @test_simplify1(float %x) { -; ANY-LABEL: @test_simplify1( +; CHECK-LABEL: @test_simplify1( ; ANY-NEXT: ret float 1.000000e+00 +; VC32-NEXT: [[POW:%.*]] = call float @powf(float 1.000000e+00, float [[X:%.*]]) +; VC32-NEXT: ret float [[POW]] +; VC64-NEXT: ret float 1.000000e+00 ; %retval = call float @powf(float 1.0, float %x) ret float %retval } define <2 x float> @test_simplify1v(<2 x float> %x) { -; ANY-LABEL: @test_simplify1v( +; CHECK-LABEL: @test_simplify1v( ; ANY-NEXT: ret <2 x float> +; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> [[X:%.*]]) +; MSVC-NEXT: ret <2 x float> [[POW]] ; %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> %x) ret <2 x float> %retval } define double @test_simplify2(double %x) { -; ANY-LABEL: @test_simplify2( -; ANY-NEXT: ret double 1.000000e+00 +; CHECK-LABEL: @test_simplify2( +; CHECK-NEXT: ret double 1.000000e+00 ; %retval = call double @pow(double 1.0, double %x) ret double %retval } define <2 x double> @test_simplify2v(<2 x double> %x) { -; ANY-LABEL: @test_simplify2v( +; CHECK-LABEL: @test_simplify2v( ; ANY-NEXT: ret <2 x double> +; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> [[X:%.*]]) +; MSVC-NEXT: ret <2 x double> [[POW]] ; %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> %x) ret <2 x double> %retval @@ -57,104 +67,114 @@ define <2 x double> @test_simplify2v(<2 x double> %x) { ; Check pow(2.0 ** n, x) -> exp2(n * x). define float @test_simplify3(float %x) { -; ANY-LABEL: @test_simplify3( -; ANY-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[X:%.*]]) [[NUW_RO:#[0-9]+]] +; CHECK-LABEL: @test_simplify3( +; ANY-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[X:%.*]]) ; ANY-NEXT: ret float [[EXP2F]] -; -; CHECK-WIN-LABEL: @test_simplify3( -; CHECK-WIN-NEXT: [[POW:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]]) -; CHECK-WIN-NEXT: ret float [[POW]] +; VC32-NEXT: [[POW:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]]) +; VC32-NEXT: ret float [[POW]] +; VC51-NEXT: [[POW:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]]) +; VC51-NEXT: ret float [[POW]] +; VC64-NEXT: [[POW:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]]) +; VC64-NEXT: ret float [[POW]] +; VC83-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[X:%.*]]) +; VC83-NEXT: ret float [[EXP2F]] ; %retval = call float @powf(float 2.0, float %x) ret float %retval } define double @test_simplify3n(double %x) { -; ANY-LABEL: @test_simplify3n( +; CHECK-LABEL: @test_simplify3n( ; ANY-NEXT: [[MUL:%.*]] = fmul double [[X:%.*]], -2.000000e+00 -; ANY-NEXT: [[EXP2:%.*]] = call double @exp2(double [[MUL]]) [[NUW_RO]] +; ANY-NEXT: [[EXP2:%.*]] = call double @exp2(double [[MUL]]) ; ANY-NEXT: ret double [[EXP2]] -; -; CHECK-WIN-LABEL: @test_simplify3n( -; CHECK-WIN-NEXT: [[POW:%.*]] = call double @pow(double 2.500000e-01, double [[X:%.*]]) -; CHECK-WIN-NEXT: ret double [[POW]] +; VC19-NEXT: [[MUL:%.*]] = fmul double [[X:%.*]], -2.000000e+00 +; VC19-NEXT: [[EXP2:%.*]] = call double @exp2(double [[MUL]]) +; VC19-NEXT: ret double [[EXP2]] +; VC32-NEXT: [[POW:%.*]] = call double @pow(double 2.500000e-01, double [[X:%.*]]) +; VC32-NEXT: ret double [[POW]] +; VC64-NEXT: [[POW:%.*]] = call double @pow(double 2.500000e-01, double [[X:%.*]]) +; VC64-NEXT: ret double [[POW]] ; %retval = call double @pow(double 0.25, double %x) ret double %retval } define <2 x float> @test_simplify3v(<2 x float> %x) { -; ANY-LABEL: @test_simplify3v( +; CHECK-LABEL: @test_simplify3v( ; ANY-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[X:%.*]]) ; ANY-NEXT: ret <2 x float> [[EXP2]] -; -; CHECK-WIN-LABEL: @test_simplify3v( -; CHECK-WIN-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> [[X:%.*]]) -; CHECK-WIN-NEXT: ret <2 x float> [[POW]] +; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> [[X:%.*]]) +; MSVC-NEXT: ret <2 x float> [[POW]] ; %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> %x) ret <2 x float> %retval } define <2 x double> @test_simplify3vn(<2 x double> %x) { -; ANY-LABEL: @test_simplify3vn( +; CHECK-LABEL: @test_simplify3vn( ; ANY-NEXT: [[MUL:%.*]] = fmul <2 x double> [[X:%.*]], ; ANY-NEXT: [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[MUL]]) ; ANY-NEXT: ret <2 x double> [[EXP2]] +; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> [[X:%.*]]) +; MSVC-NEXT: ret <2 x double> [[POW]] ; %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> %x) ret <2 x double> %retval } define double @test_simplify4(double %x) { -; ANY-LABEL: @test_simplify4( -; ANY-NEXT: [[EXP2:%.*]] = call double @exp2(double [[X:%.*]]) [[NUW_RO]] +; CHECK-LABEL: @test_simplify4( +; ANY-NEXT: [[EXP2:%.*]] = call double @exp2(double [[X:%.*]]) ; ANY-NEXT: ret double [[EXP2]] -; -; CHECK-WIN-LABEL: @test_simplify4( -; CHECK-WIN-NEXT: [[POW:%.*]] = call double @pow(double 2.000000e+00, double [[X:%.*]]) -; CHECK-WIN-NEXT: ret double [[POW]] +; VC19-NEXT: [[EXP2:%.*]] = call double @exp2(double [[X:%.*]]) +; VC19-NEXT: ret double [[EXP2]] +; VC32-NEXT: [[POW:%.*]] = call double @pow(double 2.000000e+00, double [[X:%.*]]) +; VC32-NEXT: ret double [[POW]] +; VC64-NEXT: [[POW:%.*]] = call double @pow(double 2.000000e+00, double [[X:%.*]]) +; VC64-NEXT: ret double [[POW]] ; %retval = call double @pow(double 2.0, double %x) ret double %retval } define float @test_simplify4n(float %x) { -; ANY-LABEL: @test_simplify4n( +; CHECK-LABEL: @test_simplify4n( ; ANY-NEXT: [[MUL:%.*]] = fmul float [[X:%.*]], 3.000000e+00 -; ANY-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[MUL]]) [[NUW_RO]] +; ANY-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[MUL]]) ; ANY-NEXT: ret float [[EXP2F]] -; -; CHECK-WIN-LABEL: @test_simplify4n( -; CHECK-WIN-NEXT: [[POW:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]]) -; CHECK-WIN-NEXT: ret float [[POW]] +; VC32-NEXT: [[POW:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]]) +; VC32-NEXT: ret float [[POW]] +; VC51-NEXT: [[POW:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]]) +; VC51-NEXT: ret float [[POW]] +; VC64-NEXT: [[POW:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]]) +; VC64-NEXT: ret float [[POW]] +; VC83-NEXT: [[MUL:%.*]] = fmul float [[X:%.*]], 3.000000e+00 +; VC83-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[MUL]]) +; VC83-NEXT: ret float [[EXP2F]] ; %retval = call float @powf(float 8.0, float %x) ret float %retval } define <2 x double> @test_simplify4v(<2 x double> %x) { -; ANY-LABEL: @test_simplify4v( +; CHECK-LABEL: @test_simplify4v( ; ANY-NEXT: [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[X:%.*]]) ; ANY-NEXT: ret <2 x double> [[EXP2]] -; -; CHECK-WIN-LABEL: @test_simplify4v( -; CHECK-WIN-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> [[X:%.*]]) -; CHECK-WIN-NEXT: ret <2 x double> [[POW]] +; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> [[X:%.*]]) +; MSVC-NEXT: ret <2 x double> [[POW]] ; %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> %x) ret <2 x double> %retval } define <2 x float> @test_simplify4vn(<2 x float> %x) { -; ANY-LABEL: @test_simplify4vn( +; CHECK-LABEL: @test_simplify4vn( ; ANY-NEXT: [[MUL:%.*]] = fsub <2 x float> , [[X:%.*]] ; ANY-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[MUL]]) ; ANY-NEXT: ret <2 x float> [[EXP2]] -; -; CHECK-WIN-LABEL: @test_simplify4vn( -; CHECK-WIN-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> [[X:%.*]]) -; CHECK-WIN-NEXT: ret <2 x float> [[POW]] +; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> [[X:%.*]]) +; MSVC-NEXT: ret <2 x float> [[POW]] ; %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> %x) ret <2 x float> %retval @@ -163,32 +183,42 @@ define <2 x float> @test_simplify4vn(<2 x float> %x) { ; Check pow(x, 0.0) -> 1.0. define float @test_simplify5(float %x) { -; ANY-LABEL: @test_simplify5( +; CHECK-LABEL: @test_simplify5( ; ANY-NEXT: ret float 1.000000e+00 +; VC32-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 0.000000e+00) +; VC32-NEXT: ret float [[POW]] +; VC51-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 0.000000e+00) +; VC51-NEXT: ret float [[POW]] +; VC64-NEXT: ret float 1.000000e+00 +; VC83-NEXT: ret float 1.000000e+00 ; %retval = call float @powf(float %x, float 0.0) ret float %retval } define <2 x float> @test_simplify5v(<2 x float> %x) { -; ANY-LABEL: @test_simplify5v( +; CHECK-LABEL: @test_simplify5v( ; ANY-NEXT: ret <2 x float> +; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> zeroinitializer) +; MSVC-NEXT: ret <2 x float> [[POW]] ; %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) ret <2 x float> %retval } define double @test_simplify6(double %x) { -; ANY-LABEL: @test_simplify6( -; ANY-NEXT: ret double 1.000000e+00 +; CHECK-LABEL: @test_simplify6( +; CHECK-NEXT: ret double 1.000000e+00 ; %retval = call double @pow(double %x, double 0.0) ret double %retval } define <2 x double> @test_simplify6v(<2 x double> %x) { -; ANY-LABEL: @test_simplify6v( +; CHECK-LABEL: @test_simplify6v( ; ANY-NEXT: ret <2 x double> +; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> zeroinitializer) +; MSVC-NEXT: ret <2 x double> [[POW]] ; %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) ret <2 x double> %retval @@ -197,24 +227,38 @@ define <2 x double> @test_simplify6v(<2 x double> %x) { ; Check pow(x, 0.5) -> fabs(sqrt(x)), where x != -infinity. define float @test_simplify7(float %x) { -; ANY-LABEL: @test_simplify7( -; ANY-NEXT: [[SQRTF:%.*]] = call float @sqrtf(float [[X:%.*]]) [[NUW_RO]] +; CHECK-LABEL: @test_simplify7( +; ANY-NEXT: [[SQRTF:%.*]] = call float @sqrtf(float [[X:%.*]]) ; ANY-NEXT: [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRTF]]) ; ANY-NEXT: [[ISINF:%.*]] = fcmp oeq float [[X]], 0xFFF0000000000000 ; ANY-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], float 0x7FF0000000000000, float [[ABS]] ; ANY-NEXT: ret float [[TMP1]] +; VC32-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 5.000000e-01) +; VC32-NEXT: ret float [[POW]] +; VC51-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 5.000000e-01) +; VC51-NEXT: ret float [[POW]] +; VC64-NEXT: [[SQRTF:%.*]] = call float @sqrtf(float [[X:%.*]]) +; VC64-NEXT: [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRTF]]) +; VC64-NEXT: [[ISINF:%.*]] = fcmp oeq float [[X]], 0xFFF0000000000000 +; VC64-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], float 0x7FF0000000000000, float [[ABS]] +; VC64-NEXT: ret float [[TMP1]] +; VC83-NEXT: [[SQRTF:%.*]] = call float @sqrtf(float [[X:%.*]]) +; VC83-NEXT: [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRTF]]) +; VC83-NEXT: [[ISINF:%.*]] = fcmp oeq float [[X]], 0xFFF0000000000000 +; VC83-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], float 0x7FF0000000000000, float [[ABS]] +; VC83-NEXT: ret float [[TMP1]] ; %retval = call float @powf(float %x, float 0.5) ret float %retval } define double @test_simplify8(double %x) { -; ANY-LABEL: @test_simplify8( -; ANY-NEXT: [[SQRT:%.*]] = call double @sqrt(double [[X:%.*]]) [[NUW_RO]] -; ANY-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]]) -; ANY-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000 -; ANY-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]] -; ANY-NEXT: ret double [[TMP1]] +; CHECK-LABEL: @test_simplify8( +; CHECK-NEXT: [[SQRT:%.*]] = call double @sqrt(double [[X:%.*]]) +; CHECK-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]]) +; CHECK-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000 +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]] +; CHECK-NEXT: ret double [[TMP1]] ; %retval = call double @pow(double %x, double 0.5) ret double %retval @@ -223,16 +267,22 @@ define double @test_simplify8(double %x) { ; Check pow(-infinity, 0.5) -> +infinity. define float @test_simplify9(float %x) { -; ANY-LABEL: @test_simplify9( +; CHECK-LABEL: @test_simplify9( ; ANY-NEXT: ret float 0x7FF0000000000000 +; VC32-NEXT: [[POW:%.*]] = call float @powf(float 0xFFF0000000000000, float 5.000000e-01) +; VC32-NEXT: ret float [[POW]] +; VC51-NEXT: [[POW:%.*]] = call float @powf(float 0xFFF0000000000000, float 5.000000e-01) +; VC51-NEXT: ret float [[POW]] +; VC64-NEXT: ret float 0x7FF0000000000000 +; VC83-NEXT: ret float 0x7FF0000000000000 ; %retval = call float @powf(float 0xFFF0000000000000, float 0.5) ret float %retval } define double @test_simplify10(double %x) { -; ANY-LABEL: @test_simplify10( -; ANY-NEXT: ret double 0x7FF0000000000000 +; CHECK-LABEL: @test_simplify10( +; CHECK-NEXT: ret double 0x7FF0000000000000 ; %retval = call double @pow(double 0xFFF0000000000000, double 0.5) ret double %retval @@ -241,32 +291,42 @@ define double @test_simplify10(double %x) { ; Check pow(x, 1.0) -> x. define float @test_simplify11(float %x) { -; ANY-LABEL: @test_simplify11( +; CHECK-LABEL: @test_simplify11( ; ANY-NEXT: ret float [[X:%.*]] +; VC32-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 1.000000e+00) +; VC32-NEXT: ret float [[POW]] +; VC51-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 1.000000e+00) +; VC51-NEXT: ret float [[POW]] +; VC64-NEXT: ret float [[X:%.*]] +; VC83-NEXT: ret float [[X:%.*]] ; %retval = call float @powf(float %x, float 1.0) ret float %retval } define <2 x float> @test_simplify11v(<2 x float> %x) { -; ANY-LABEL: @test_simplify11v( +; CHECK-LABEL: @test_simplify11v( ; ANY-NEXT: ret <2 x float> [[X:%.*]] +; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> ) +; MSVC-NEXT: ret <2 x float> [[POW]] ; %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) ret <2 x float> %retval } define double @test_simplify12(double %x) { -; ANY-LABEL: @test_simplify12( -; ANY-NEXT: ret double [[X:%.*]] +; CHECK-LABEL: @test_simplify12( +; CHECK-NEXT: ret double [[X:%.*]] ; %retval = call double @pow(double %x, double 1.0) ret double %retval } define <2 x double> @test_simplify12v(<2 x double> %x) { -; ANY-LABEL: @test_simplify12v( +; CHECK-LABEL: @test_simplify12v( ; ANY-NEXT: ret <2 x double> [[X:%.*]] +; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> ) +; MSVC-NEXT: ret <2 x double> [[POW]] ; %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) ret <2 x double> %retval @@ -275,36 +335,48 @@ define <2 x double> @test_simplify12v(<2 x double> %x) { ; Check pow(x, 2.0) -> x*x. define float @pow2_strict(float %x) { -; ANY-LABEL: @pow2_strict( +; CHECK-LABEL: @pow2_strict( ; ANY-NEXT: [[SQUARE:%.*]] = fmul float [[X:%.*]], [[X]] ; ANY-NEXT: ret float [[SQUARE]] +; VC32-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 2.000000e+00) +; VC32-NEXT: ret float [[POW]] +; VC51-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 2.000000e+00) +; VC51-NEXT: ret float [[POW]] +; VC64-NEXT: [[SQUARE:%.*]] = fmul float [[X:%.*]], [[X]] +; VC64-NEXT: ret float [[SQUARE]] +; VC83-NEXT: [[SQUARE:%.*]] = fmul float [[X:%.*]], [[X]] +; VC83-NEXT: ret float [[SQUARE]] ; %r = call float @powf(float %x, float 2.0) ret float %r } define <2 x float> @pow2_strictv(<2 x float> %x) { -; ANY-LABEL: @pow2_strictv( +; CHECK-LABEL: @pow2_strictv( ; ANY-NEXT: [[SQUARE:%.*]] = fmul <2 x float> [[X:%.*]], [[X]] ; ANY-NEXT: ret <2 x float> [[SQUARE]] +; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> ) +; MSVC-NEXT: ret <2 x float> [[POW]] ; %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) ret <2 x float> %r } define double @pow2_double_strict(double %x) { -; ANY-LABEL: @pow2_double_strict( -; ANY-NEXT: [[SQUARE:%.*]] = fmul double [[X:%.*]], [[X]] -; ANY-NEXT: ret double [[SQUARE]] +; CHECK-LABEL: @pow2_double_strict( +; CHECK-NEXT: [[SQUARE:%.*]] = fmul double [[X:%.*]], [[X]] +; CHECK-NEXT: ret double [[SQUARE]] ; %r = call double @pow(double %x, double 2.0) ret double %r } define <2 x double> @pow2_double_strictv(<2 x double> %x) { -; ANY-LABEL: @pow2_double_strictv( +; CHECK-LABEL: @pow2_double_strictv( ; ANY-NEXT: [[SQUARE:%.*]] = fmul <2 x double> [[X:%.*]], [[X]] ; ANY-NEXT: ret <2 x double> [[SQUARE]] +; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> ) +; MSVC-NEXT: ret <2 x double> [[POW]] ; %r = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) ret <2 x double> %r @@ -313,9 +385,17 @@ define <2 x double> @pow2_double_strictv(<2 x double> %x) { ; Don't drop the FMF - PR35601 ( https://bugs.llvm.org/show_bug.cgi?id=35601 ) define float @pow2_fast(float %x) { -; ANY-LABEL: @pow2_fast( +; CHECK-LABEL: @pow2_fast( ; ANY-NEXT: [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]] ; ANY-NEXT: ret float [[SQUARE]] +; VC32-NEXT: [[POW:%.*]] = call fast float @powf(float [[X:%.*]], float 2.000000e+00) +; VC32-NEXT: ret float [[POW]] +; VC51-NEXT: [[POW:%.*]] = call fast float @powf(float [[X:%.*]], float 2.000000e+00) +; VC51-NEXT: ret float [[POW]] +; VC64-NEXT: [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]] +; VC64-NEXT: ret float [[SQUARE]] +; VC83-NEXT: [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]] +; VC83-NEXT: ret float [[SQUARE]] ; %r = call fast float @powf(float %x, float 2.0) ret float %r @@ -324,48 +404,60 @@ define float @pow2_fast(float %x) { ; Check pow(x, -1.0) -> 1.0/x. define float @pow_neg1_strict(float %x) { -; ANY-LABEL: @pow_neg1_strict( +; CHECK-LABEL: @pow_neg1_strict( ; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X:%.*]] ; ANY-NEXT: ret float [[RECIPROCAL]] +; VC32-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float -1.000000e+00) +; VC32-NEXT: ret float [[POW]] +; VC51-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float -1.000000e+00) +; VC51-NEXT: ret float [[POW]] +; VC64-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X:%.*]] +; VC64-NEXT: ret float [[RECIPROCAL]] +; VC83-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X:%.*]] +; VC83-NEXT: ret float [[RECIPROCAL]] ; %r = call float @powf(float %x, float -1.0) ret float %r } define <2 x float> @pow_neg1_strictv(<2 x float> %x) { -; ANY-LABEL: @pow_neg1_strictv( +; CHECK-LABEL: @pow_neg1_strictv( ; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv <2 x float> , [[X:%.*]] ; ANY-NEXT: ret <2 x float> [[RECIPROCAL]] +; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> ) +; MSVC-NEXT: ret <2 x float> [[POW]] ; %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) ret <2 x float> %r } define double @pow_neg1_double_fast(double %x) { -; ANY-LABEL: @pow_neg1_double_fast( -; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[X:%.*]] -; ANY-NEXT: ret double [[RECIPROCAL]] +; CHECK-LABEL: @pow_neg1_double_fast( +; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[X:%.*]] +; CHECK-NEXT: ret double [[RECIPROCAL]] ; %r = call fast double @pow(double %x, double -1.0) ret double %r } define <2 x double> @pow_neg1_double_fastv(<2 x double> %x) { -; ANY-LABEL: @pow_neg1_double_fastv( +; CHECK-LABEL: @pow_neg1_double_fastv( ; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv fast <2 x double> , [[X:%.*]] ; ANY-NEXT: ret <2 x double> [[RECIPROCAL]] +; MSVC-NEXT: [[POW:%.*]] = call fast <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> ) +; MSVC-NEXT: ret <2 x double> [[POW]] ; %r = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) ret <2 x double> %r } define double @test_simplify17(double %x) { -; ANY-LABEL: @test_simplify17( -; ANY-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X:%.*]]) -; ANY-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]]) -; ANY-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000 -; ANY-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]] -; ANY-NEXT: ret double [[TMP1]] +; CHECK-LABEL: @test_simplify17( +; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X:%.*]]) +; CHECK-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]]) +; CHECK-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000 +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]] +; CHECK-NEXT: ret double [[TMP1]] ; %retval = call double @llvm.pow.f64(double %x, double 0.5) ret double %retval @@ -374,29 +466,23 @@ define double @test_simplify17(double %x) { ; Check pow(10.0, x) -> __exp10(x) on OS X 10.9+ and iOS 7.0+. define float @test_simplify18(float %x) { -; CHECK-EXP10-LABEL: @test_simplify18( -; CHECK-EXP10-NEXT: [[__EXP10F:%.*]] = call float @__exp10f(float [[X:%.*]]) [[NUW_RO]] -; CHECK-EXP10-NEXT: ret float [[__EXP10F]] -; -; CHECK-NO-EXP10-LABEL: @test_simplify18( -; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X:%.*]]) -; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]] +; CHECK-LABEL: @test_simplify18( +; CHECK-EXP10-NEXT: [[__EXP10F:%.*]] = call float @__exp10f(float [[X:%.*]]) +; CHECK-EXP10-NEXT: ret float [[__EXP10F]] +; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X:%.*]]) +; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]] ; %retval = call float @powf(float 10.0, float %x) ret float %retval } define double @test_simplify19(double %x) { -; CHECK-EXP10-LABEL: @test_simplify19( -; CHECK-EXP10-NEXT: [[__EXP10:%.*]] = call double @__exp10(double [[X:%.*]]) [[NUW_RO]] -; CHECK-EXP10-NEXT: ret double [[__EXP10]] -; -; CHECK-NO-EXP10-LABEL: @test_simplify19( -; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X:%.*]]) -; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]] +; CHECK-LABEL: @test_simplify19( +; CHECK-EXP10-NEXT: [[__EXP10:%.*]] = call double @__exp10(double [[X:%.*]]) +; CHECK-EXP10-NEXT: ret double [[__EXP10]] +; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X:%.*]]) +; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]] ; %retval = call double @pow(double 10.0, double %x) ret double %retval } - -; CHECK-EXP10: attributes [[NUW_RO]] = { nounwind readonly } diff --git a/llvm/test/Transforms/InstCombine/win-math.ll b/llvm/test/Transforms/InstCombine/win-math.ll index 36947791393d9..38ed949e949dc 100644 --- a/llvm/test/Transforms/InstCombine/win-math.ll +++ b/llvm/test/Transforms/InstCombine/win-math.ll @@ -1,17 +1,21 @@ -; RUN: opt -O2 -S -mtriple=i386-pc-win32 < %s | FileCheck %s -check-prefix=WIN32 -; RUN: opt -O2 -S -mtriple=x86_64-pc-win32 < %s | FileCheck %s -check-prefix=WIN64 -; RUN: opt -O2 -S -mtriple=i386-pc-mingw32 < %s | FileCheck %s -check-prefix=MINGW32 -; RUN: opt -O2 -S -mtriple=x86_64-pc-mingw32 < %s | FileCheck %s -check-prefix=MINGW64 +; RUN: opt < %s -O2 -S -mtriple=i386-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,MSVCXX,MSVC32 +; RUN: opt < %s -O2 -S -mtriple=i386-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,MSVC19,MSVC51 +; RUN: opt < %s -O2 -S -mtriple=x86_64-pc-windows-msvc17 | FileCheck %s --check-prefixes=CHECK,MSVCXX,MSVC64 +; RUN: opt < %s -O2 -S -mtriple=x86_64-pc-win32 | FileCheck %s --check-prefixes=CHECK,MSVC19,MSVC83 +; RUN: opt < %s -O2 -S -mtriple=i386-pc-mingw32 | FileCheck %s --check-prefixes=CHECK,MINGW32 +; RUN: opt < %s -O2 -S -mtriple=x86_64-pc-mingw32 | FileCheck %s --check-prefixes=CHECK,MINGW64 ; x86 win32 msvcrt does not provide entry points for single-precision libm. -; x86-64 win32 msvcrt does (except for fabsf) -; msvcrt does not provide C99 math, but mingw32 does. +; x86-64 win32 msvcrt does, but with exceptions +; msvcrt does not provide all of C99 math, but mingw32 does. declare double @acos(double %x) define float @float_acos(float %x) nounwind readnone { -; WIN32-LABEL: @float_acos( -; WIN32-NOT: float @acosf -; WIN32: double @acos +; CHECK-LABEL: @float_acos( +; MSVCXX-NOT: float @acosf +; MSVCXX: double @acos +; MSVC19-NOT: float @acosf +; MSVC19: double @acos %1 = fpext float %x to double %2 = call double @acos(double %1) %3 = fptrunc double %2 to float @@ -20,9 +24,11 @@ define float @float_acos(float %x) nounwind readnone { declare double @asin(double %x) define float @float_asin(float %x) nounwind readnone { -; WIN32-LABEL: @float_asin( -; WIN32-NOT: float @asinf -; WIN32: double @asin +; CHECK-LABEL: @float_asin( +; MSVCXX-NOT: float @asinf +; MSVCXX: double @asin +; MSVC19-NOT: float @asinf +; MSVC19: double @asin %1 = fpext float %x to double %2 = call double @asin(double %1) %3 = fptrunc double %2 to float @@ -31,9 +37,11 @@ define float @float_asin(float %x) nounwind readnone { declare double @atan(double %x) define float @float_atan(float %x) nounwind readnone { -; WIN32-LABEL: @float_atan( -; WIN32-NOT: float @atanf -; WIN32: double @atan +; CHECK-LABEL: @float_atan( +; MSVCXX-NOT: float @atanf +; MSVCXX: double @atan +; MSVC19-NOT: float @atanf +; MSVC19: double @atan %1 = fpext float %x to double %2 = call double @atan(double %1) %3 = fptrunc double %2 to float @@ -42,9 +50,11 @@ define float @float_atan(float %x) nounwind readnone { declare double @atan2(double %x, double %y) define float @float_atan2(float %x, float %y) nounwind readnone { -; WIN32-LABEL: @float_atan2( -; WIN32-NOT: float @atan2f -; WIN32: double @atan2 +; CHECK-LABEL: @float_atan2( +; MSVCXX-NOT: float @atan2f +; MSVCXX: double @atan2 +; MSVC19-NOT: float @atan2f +; MSVC19: double @atan2 %1 = fpext float %x to double %2 = fpext float %y to double %3 = call double @atan2(double %1, double %2) @@ -54,18 +64,15 @@ define float @float_atan2(float %x, float %y) nounwind readnone { declare double @ceil(double %x) define float @float_ceil(float %x) nounwind readnone { -; WIN32-LABEL: @float_ceil( -; WIN32-NOT: float @ceilf -; WIN32: float @llvm.ceil.f32 -; WIN64-LABEL: @float_ceil( -; WIN64: float @llvm.ceil.f32 -; WIN64-NOT: double @ceil -; MINGW32-LABEL: @float_ceil( -; MINGW32: float @llvm.ceil.f32 +; CHECK-LABEL: @float_ceil( +; MSVCXX-NOT: float @ceilf +; MSVCXX: float @llvm.ceil.f32 +; MSVC19-NOT: double @ceil +; MSVC19: float @llvm.ceil.f32 ; MINGW32-NOT: double @ceil -; MINGW64-LABEL: @float_ceil( -; MINGW64: float @llvm.ceil.f32 +; MINGW32: float @llvm.ceil.f32 ; MINGW64-NOT: double @ceil +; MINGW64: float @llvm.ceil.f32 %1 = fpext float %x to double %2 = call double @ceil(double %1) %3 = fptrunc double %2 to float @@ -74,10 +81,11 @@ define float @float_ceil(float %x) nounwind readnone { declare double @_copysign(double %x) define float @float_copysign(float %x) nounwind readnone { -; WIN32-LABEL: @float_copysign( -; WIN32-NOT: float @copysignf -; WIN32-NOT: float @_copysignf -; WIN32: double @_copysign +; CHECK-LABEL: @float_copysign( +; MSVCXX-NOT: float @_copysignf +; MSVCXX: double @_copysign +; MSVC19-NOT: float @_copysignf +; MSVC19: double @_copysign %1 = fpext float %x to double %2 = call double @_copysign(double %1) %3 = fptrunc double %2 to float @@ -86,9 +94,11 @@ define float @float_copysign(float %x) nounwind readnone { declare double @cos(double %x) define float @float_cos(float %x) nounwind readnone { -; WIN32-LABEL: @float_cos( -; WIN32-NOT: float @cosf -; WIN32: double @cos +; CHECK-LABEL: @float_cos( +; MSVCXX-NOT: float @cosf +; MSVCXX: double @cos +; MSVC19-NOT: float @cosf +; MSVC19: double @cos %1 = fpext float %x to double %2 = call double @cos(double %1) %3 = fptrunc double %2 to float @@ -97,9 +107,11 @@ define float @float_cos(float %x) nounwind readnone { declare double @cosh(double %x) define float @float_cosh(float %x) nounwind readnone { -; WIN32-LABEL: @float_cosh( -; WIN32-NOT: float @coshf -; WIN32: double @cosh +; CHECK-LABEL: @float_cosh( +; MSVCXX-NOT: float @coshf +; MSVCXX: double @cosh +; MSVC19-NOT: float @coshf +; MSVC19: double @cosh %1 = fpext float %x to double %2 = call double @cosh(double %1) %3 = fptrunc double %2 to float @@ -108,9 +120,11 @@ define float @float_cosh(float %x) nounwind readnone { declare double @exp(double %x, double %y) define float @float_exp(float %x, float %y) nounwind readnone { -; WIN32-LABEL: @float_exp( -; WIN32-NOT: float @expf -; WIN32: double @exp +; CHECK-LABEL: @float_exp( +; MSVCXX-NOT: float @expf +; MSVCXX: double @exp +; MSVC19-NOT: float @expf +; MSVC19: double @exp %1 = fpext float %x to double %2 = fpext float %y to double %3 = call double @exp(double %1, double %2) @@ -120,12 +134,11 @@ define float @float_exp(float %x, float %y) nounwind readnone { declare double @fabs(double %x, double %y) define float @float_fabs(float %x, float %y) nounwind readnone { -; WIN32-LABEL: @float_fabs( -; WIN32-NOT: float @fabsf -; WIN32: double @fabs -; WIN64-LABEL: @float_fabs( -; WIN64-NOT: float @fabsf -; WIN64: double @fabs +; CHECK-LABEL: @float_fabs( +; MSVCXX-NOT: float @fabsf +; MSVCXX: double @fabs +; MSVC19-NOT: float @fabsf +; MSVC19: double @fabs %1 = fpext float %x to double %2 = fpext float %y to double %3 = call double @fabs(double %1, double %2) @@ -135,18 +148,15 @@ define float @float_fabs(float %x, float %y) nounwind readnone { declare double @floor(double %x) define float @float_floor(float %x) nounwind readnone { -; WIN32-LABEL: @float_floor( -; WIN32-NOT: float @floorf -; WIN32: float @llvm.floor.f32 -; WIN64-LABEL: @float_floor( -; WIN64: float @llvm.floor.f32 -; WIN64-NOT: double @floor -; MINGW32-LABEL: @float_floor( -; MINGW32: float @llvm.floor.f32 +; CHECK-LABEL: @float_floor( +; MSVCXX-NOT: float @floorf +; MSVCXX: float @llvm.floor.f32 +; MSVC19-NOT: double @floor +; MSVC19: float @llvm.floor.f32 ; MINGW32-NOT: double @floor -; MINGW64-LABEL: @float_floor( -; MINGW64: float @llvm.floor.f32 +; MINGW32: float @llvm.floor.f32 ; MINGW64-NOT: double @floor +; MINGW64: float @llvm.floor.f32 %1 = fpext float %x to double %2 = call double @floor(double %1) %3 = fptrunc double %2 to float @@ -155,9 +165,11 @@ define float @float_floor(float %x) nounwind readnone { declare double @fmod(double %x, double %y) define float @float_fmod(float %x, float %y) nounwind readnone { -; WIN32-LABEL: @float_fmod( -; WIN32-NOT: float @fmodf -; WIN32: double @fmod +; MSVCXX-LABEL: @float_fmod( +; MSVCXX-NOT: float @fmodf +; MSVCXX: double @fmod +; MSVC19-NOT: float @fmodf +; MSVC19: double @fmod %1 = fpext float %x to double %2 = fpext float %y to double %3 = call double @fmod(double %1, double %2) @@ -167,20 +179,37 @@ define float @float_fmod(float %x, float %y) nounwind readnone { declare double @log(double %x) define float @float_log(float %x) nounwind readnone { -; WIN32-LABEL: @float_log( -; WIN32-NOT: float @logf -; WIN32: double @log +; CHECK-LABEL: @float_log( +; MSVCXX-NOT: float @logf +; MSVCXX: double @log +; MSVC19-NOT: float @logf +; MSVC19: double @log %1 = fpext float %x to double %2 = call double @log(double %1) %3 = fptrunc double %2 to float ret float %3 } +declare double @logb(double %x) +define float @float_logb(float %x) nounwind readnone { +; CHECK-LABEL: @float_logb( +; MSVCXX-NOT: float @logbf +; MSVCXX: double @logb +; MSVC19-NOT: float @logbf +; MSVC19: double @logb + %1 = fpext float %x to double + %2 = call double @logb(double %1) + %3 = fptrunc double %2 to float + ret float %3 +} + declare double @pow(double %x, double %y) define float @float_pow(float %x, float %y) nounwind readnone { -; WIN32-LABEL: @float_pow( -; WIN32-NOT: float @powf -; WIN32: double @pow +; CHECK-LABEL: @float_pow( +; MSVCXX-NOT: float @powf +; MSVCXX: double @pow +; MSVC19-NOT: float @powf +; MSVC19: double @pow %1 = fpext float %x to double %2 = fpext float %y to double %3 = call double @pow(double %1, double %2) @@ -190,9 +219,11 @@ define float @float_pow(float %x, float %y) nounwind readnone { declare double @sin(double %x) define float @float_sin(float %x) nounwind readnone { -; WIN32-LABEL: @float_sin( -; WIN32-NOT: float @sinf -; WIN32: double @sin +; CHECK-LABEL: @float_sin( +; MSVCXX-NOT: float @sinf +; MSVCXX: double @sin +; MSVC19-NOT: float @sinf +; MSVC19: double @sin %1 = fpext float %x to double %2 = call double @sin(double %1) %3 = fptrunc double %2 to float @@ -201,9 +232,11 @@ define float @float_sin(float %x) nounwind readnone { declare double @sinh(double %x) define float @float_sinh(float %x) nounwind readnone { -; WIN32-LABEL: @float_sinh( -; WIN32-NOT: float @sinhf -; WIN32: double @sinh +; CHECK-LABEL: @float_sinh( +; MSVCXX-NOT: float @sinhf +; MSVCXX: double @sinh +; MSVC19-NOT: float @sinhf +; MSVC19: double @sinh %1 = fpext float %x to double %2 = call double @sinh(double %1) %3 = fptrunc double %2 to float @@ -212,18 +245,19 @@ define float @float_sinh(float %x) nounwind readnone { declare double @sqrt(double %x) define float @float_sqrt(float %x) nounwind readnone { -; WIN32-LABEL: @float_sqrt( -; WIN32-NOT: float @sqrtf -; WIN32: double @sqrt -; WIN64-LABEL: @float_sqrt( -; WIN64: float @sqrtf -; WIN64-NOT: double @sqrt -; MINGW32-LABEL: @float_sqrt( -; MINGW32: float @sqrtf +; CHECK-LABEL: @float_sqrt( +; MSVC32-NOT: float @sqrtf +; MSVC32: double @sqrt +; MSVC51-NOT: float @sqrtf +; MSVC51: double @sqrt +; MSVC64-NOT: double @sqrt +; MSVC64: float @sqrtf +; MSVC83-NOT: double @sqrt +; MSVC83: float @sqrtf ; MINGW32-NOT: double @sqrt -; MINGW64-LABEL: @float_sqrt( -; MINGW64: float @sqrtf +; MINGW32: float @sqrtf ; MINGW64-NOT: double @sqrt +; MINGW64: float @sqrtf %1 = fpext float %x to double %2 = call double @sqrt(double %1) %3 = fptrunc double %2 to float @@ -232,9 +266,11 @@ define float @float_sqrt(float %x) nounwind readnone { declare double @tan(double %x) define float @float_tan(float %x) nounwind readnone { -; WIN32-LABEL: @float_tan( -; WIN32-NOT: float @tanf -; WIN32: double @tan +; CHECK-LABEL: @float_tan( +; MSVCXX-NOT: float @tanf +; MSVCXX: double @tan +; MSVC19-NOT: float @tanf +; MSVC19: double @tan %1 = fpext float %x to double %2 = call double @tan(double %1) %3 = fptrunc double %2 to float @@ -243,30 +279,29 @@ define float @float_tan(float %x) nounwind readnone { declare double @tanh(double %x) define float @float_tanh(float %x) nounwind readnone { -; WIN32-LABEL: @float_tanh( -; WIN32-NOT: float @tanhf -; WIN32: double @tanh +; CHECK-LABEL: @float_tanh( +; MSVCXX-NOT: float @tanhf +; MSVCXX: double @tanh +; MSVC19-NOT: float @tanhf +; MSVC19: double @tanh %1 = fpext float %x to double %2 = call double @tanh(double %1) %3 = fptrunc double %2 to float ret float %3 } -; win32 does not have round; mingw32 does +; win32 does not have roundf; mingw32 does declare double @round(double %x) define float @float_round(float %x) nounwind readnone { -; WIN32-LABEL: @float_round( -; WIN32-NOT: float @roundf -; WIN32: double @round -; WIN64-LABEL: @float_round( -; WIN64-NOT: float @roundf -; WIN64: double @round -; MINGW32-LABEL: @float_round( -; MINGW32: float @llvm.round.f32 +; CHECK-LABEL: @float_round( +; MSVCXX-NOT: double @roundf +; MSVCXX: double @round +; MSVC19-NOT: double @round +; MSVC19: float @llvm.round.f32 ; MINGW32-NOT: double @round -; MINGW64-LABEL: @float_round( -; MINGW64: float @llvm.round.f32 +; MINGW32: float @llvm.round.f32 ; MINGW64-NOT: double @round +; MINGW64: float @llvm.round.f32 %1 = fpext float %x to double %2 = call double @round(double %1) %3 = fptrunc double %2 to float @@ -275,26 +310,26 @@ define float @float_round(float %x) nounwind readnone { declare float @powf(float, float) -; win32 lacks sqrtf&fabsf, win64 lacks fabsf, but +; win32 lacks sqrtf & fabsf, win64 lacks fabsf, but ; calls to the intrinsics can be emitted instead. define float @float_powsqrt(float %x) nounwind readnone { -; WIN32-LABEL: @float_powsqrt( -; WIN32-NOT: float @sqrtf -; WIN32: float @powf - -; WIN64-LABEL: @float_powsqrt( -; WIN64: float @sqrtf -; WIN64: float @llvm.fabs.f32( -; WIN64-NOT: float @powf - -; MINGW32-LABEL: @float_powsqrt( +; CHECK-LABEL: @float_powsqrt( +; MSVC32-NOT: float @sqrtf +; MSVC32: float @powf +; MSVC51-NOT: float @sqrtf +; MSVC51: float @powf +; MSVC64-NOT: float @powf +; MSVC64: float @sqrtf +; MSVC64: float @llvm.fabs.f32( +; MSVC83-NOT: float @powf +; MSVC83: float @sqrtf +; MSVC83: float @llvm.fabs.f32( +; MINGW32-NOT: float @powf ; MINGW32: float @sqrtf ; MINGW32: float @llvm.fabs.f32 -; MINGW32-NOT: float @powf -; MINGW64-LABEL: @float_powsqrt( +; MINGW64-NOT: float @powf ; MINGW64: float @sqrtf ; MINGW64: float @llvm.fabs.f32( -; MINGW64-NOT: float @powf %1 = call float @powf(float %x, float 0.5) ret float %1 } From 6e3c4d584b71628f25bd567335d32f7e00d682eb Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 13 Feb 2019 10:47:50 +0000 Subject: [PATCH 134/274] Revert r350404 This caused https://bugs.llvm.org/show_bug.cgi?id=40642: "After 350404, clang drops volatile load" > Refactor the way we handle diagnosing unused expression results. > > Rather than sprinkle calls to DiagnoseUnusedExprResult() around in places > where we want diagnostics, we now diagnose unused expression statements and > full expressions in a more generic way when acting on the final expression > statement. This results in more appropriate diagnostics for [[nodiscard]] where > we were previously lacking them, such as when the body of a for loop is not a > compound statement. > > This patch fixes PR39837. llvm-svn: 353935 --- clang/include/clang/Parse/Parser.h | 5 -- clang/include/clang/Sema/Sema.h | 19 +++--- clang/lib/Parse/ParseObjc.cpp | 2 +- clang/lib/Parse/ParseOpenMP.cpp | 14 ++-- clang/lib/Parse/ParseStmt.cpp | 26 ++------ clang/lib/Sema/SemaCoroutine.cpp | 17 ++--- clang/lib/Sema/SemaDecl.cpp | 6 +- clang/lib/Sema/SemaDeclCXX.cpp | 14 ++-- clang/lib/Sema/SemaExpr.cpp | 5 +- clang/lib/Sema/SemaExprCXX.cpp | 2 - clang/lib/Sema/SemaLambda.cpp | 2 +- clang/lib/Sema/SemaOpenMP.cpp | 55 +++++++--------- clang/lib/Sema/SemaStmt.cpp | 65 +++++++++++-------- clang/lib/Sema/TreeTransform.h | 15 ++--- clang/test/CXX/stmt.stmt/stmt.select/p3.cpp | 9 +-- .../pragma-macro-token-caching.c | 2 +- clang/test/Parser/cxx1z-init-statement.cpp | 8 +-- clang/test/Parser/switch-recovery.cpp | 2 +- clang/test/SemaCXX/cxx1z-init-statement.cpp | 8 +-- clang/test/SemaCXX/for-range-examples.cpp | 2 +- clang/test/SemaCXX/warn-unused-result.cpp | 40 ------------ 21 files changed, 122 insertions(+), 196 deletions(-) diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 438ff0e2ed450..46e4431913e76 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -360,11 +360,6 @@ class Parser : public CodeCompletionHandler { /// just a regular sub-expression. SourceLocation ExprStatementTokLoc; - /// Tests whether an expression value is discarded based on token lookahead. - /// It will return true if the lexer is currently processing the }) - /// terminating a GNU statement expression and false otherwise. - bool isExprValueDiscarded(); - public: Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies); ~Parser() override; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index e5b7465820a98..ced5773f0c073 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -1369,7 +1369,6 @@ class Sema { void PopCompoundScope(); sema::CompoundScopeInfo &getCurCompoundScope() const; - bool isCurCompoundStmtAStmtExpr() const; bool hasAnyUnrecoverableErrorsInThisFunction() const; @@ -3690,17 +3689,16 @@ class Sema { return MakeFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation()); } FullExprArg MakeFullExpr(Expr *Arg, SourceLocation CC) { - return FullExprArg( - ActOnFinishFullExpr(Arg, CC, /*DiscardedValue*/ false).get()); + return FullExprArg(ActOnFinishFullExpr(Arg, CC).get()); } FullExprArg MakeFullDiscardedValueExpr(Expr *Arg) { ExprResult FE = - ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(), - /*DiscardedValue*/ true); + ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(), + /*DiscardedValue*/ true); return FullExprArg(FE.get()); } - StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue = true); + StmtResult ActOnExprStmt(ExprResult Arg); StmtResult ActOnExprStmtError(); StmtResult ActOnNullStmt(SourceLocation SemiLoc, @@ -5346,12 +5344,13 @@ class Sema { CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary, bool BoundToLvalueReference); - ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue) { - return ActOnFinishFullExpr( - Expr, Expr ? Expr->getExprLoc() : SourceLocation(), DiscardedValue); + ExprResult ActOnFinishFullExpr(Expr *Expr) { + return ActOnFinishFullExpr(Expr, Expr ? Expr->getExprLoc() + : SourceLocation()); } ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC, - bool DiscardedValue, bool IsConstexpr = false); + bool DiscardedValue = false, + bool IsConstexpr = false); StmtResult ActOnFinishFullStmt(Stmt *Stmt); // Marks SS invalid if it represents an incomplete type. diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index bd55f71793995..c8d7bda3d6e91 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -2741,7 +2741,7 @@ StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) { // Otherwise, eat the semicolon. ExpectAndConsumeSemi(diag::err_expected_semi_after_expr); - return Actions.ActOnExprStmt(Res, isExprValueDiscarded()); + return Actions.ActOnExprStmt(Res); } ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index dd2a8aae9f2fb..17c3fa3cf2aa5 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -314,7 +314,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) { Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D); ExprResult CombinerResult = Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(), - D->getLocation(), /*DiscardedValue*/ false); + D->getLocation(), /*DiscardedValue=*/true); Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get()); if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) && @@ -356,7 +356,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) { if (Actions.getLangOpts().CPlusPlus) { InitializerResult = Actions.ActOnFinishFullExpr( ParseAssignmentExpression().get(), D->getLocation(), - /*DiscardedValue*/ false); + /*DiscardedValue=*/true); } else { ConsumeToken(); ParseOpenMPReductionInitializerForDecl(OmpPrivParm); @@ -364,7 +364,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) { } else { InitializerResult = Actions.ActOnFinishFullExpr( ParseAssignmentExpression().get(), D->getLocation(), - /*DiscardedValue*/ false); + /*DiscardedValue=*/true); } Actions.ActOnOpenMPDeclareReductionInitializerEnd( D, InitializerResult.get(), OmpPrivParm); @@ -1455,7 +1455,7 @@ ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName, ExprResult LHS(ParseCastExpression( /*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast)); ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); - Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false); + Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc); // Parse ')'. RLoc = Tok.getLocation(); @@ -1711,8 +1711,7 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, SourceLocation ELoc = Tok.getLocation(); ExprResult LHS(ParseCastExpression(false, false, NotTypeCast)); Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional); - Val = - Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false); + Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc); } // Parse ')'. @@ -1997,8 +1996,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, Data.ColonLoc = Tok.getLocation(); SourceLocation ELoc = ConsumeToken(); ExprResult Tail = ParseAssignmentExpression(); - Tail = - Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false); + Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc); if (Tail.isUsable()) Data.TailExpr = Tail.get(); else diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 2974e6a245b0e..313793c3e8fb8 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -439,7 +439,7 @@ StmtResult Parser::ParseExprStatement() { // Otherwise, eat the semicolon. ExpectAndConsumeSemi(diag::err_expected_semi_after_expr); - return Actions.ActOnExprStmt(Expr, isExprValueDiscarded()); + return Actions.ActOnExprStmt(Expr); } /// ParseSEHTryBlockCommon @@ -958,16 +958,6 @@ bool Parser::ConsumeNullStmt(StmtVector &Stmts) { return true; } -bool Parser::isExprValueDiscarded() { - if (Actions.isCurCompoundStmtAStmtExpr()) { - // Look to see if the next two tokens close the statement expression; - // if so, this expression statement is the last statement in a - // statment expression. - return Tok.isNot(tok::r_brace) || NextToken().isNot(tok::r_paren); - } - return true; -} - /// ParseCompoundStatementBody - Parse a sequence of statements and invoke the /// ActOnCompoundStmt action. This expects the '{' to be the current token, and /// consume the '}' at the end of the block. It does not manipulate the scope @@ -1072,7 +1062,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { // Eat the semicolon at the end of stmt and convert the expr into a // statement. ExpectAndConsumeSemi(diag::err_expected_semi_after_expr); - R = Actions.ActOnExprStmt(Res, isExprValueDiscarded()); + R = Actions.ActOnExprStmt(Res); } } @@ -1708,16 +1698,8 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { if (!Value.isInvalid()) { if (ForEach) FirstPart = Actions.ActOnForEachLValueExpr(Value.get()); - else { - // We already know this is not an init-statement within a for loop, so - // if we are parsing a C++11 range-based for loop, we should treat this - // expression statement as being a discarded value expression because - // we will err below. This way we do not warn on an unused expression - // that was an error in the first place, like with: for (expr : expr); - bool IsRangeBasedFor = - getLangOpts().CPlusPlus11 && !ForEach && Tok.is(tok::colon); - FirstPart = Actions.ActOnExprStmt(Value, !IsRangeBasedFor); - } + else + FirstPart = Actions.ActOnExprStmt(Value); } if (Tok.is(tok::semi)) { diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp index 181efa6d3dd09..e282bb62f0326 100644 --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/clang/lib/Sema/SemaCoroutine.cpp @@ -646,7 +646,7 @@ bool Sema::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc, return StmtError(); Suspend = BuildResolvedCoawaitExpr(Loc, Suspend.get(), /*IsImplicit*/ true); - Suspend = ActOnFinishFullExpr(Suspend.get(), /*DiscardedValue*/ false); + Suspend = ActOnFinishFullExpr(Suspend.get()); if (Suspend.isInvalid()) { Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required) << ((Name == "initial_suspend") ? 0 : 1); @@ -867,7 +867,7 @@ StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E, if (PC.isInvalid()) return StmtError(); - Expr *PCE = ActOnFinishFullExpr(PC.get(), /*DiscardedValue*/ false).get(); + Expr *PCE = ActOnFinishFullExpr(PC.get()).get(); Stmt *Res = new (Context) CoreturnStmt(Loc, E, PCE, IsImplicit); return Res; @@ -1236,7 +1236,7 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() { ExprResult NewExpr = S.ActOnCallExpr(S.getCurScope(), NewRef.get(), Loc, NewArgs, Loc); - NewExpr = S.ActOnFinishFullExpr(NewExpr.get(), /*DiscardedValue*/ false); + NewExpr = S.ActOnFinishFullExpr(NewExpr.get()); if (NewExpr.isInvalid()) return false; @@ -1262,8 +1262,7 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() { ExprResult DeleteExpr = S.ActOnCallExpr(S.getCurScope(), DeleteRef.get(), Loc, DeleteArgs, Loc); - DeleteExpr = - S.ActOnFinishFullExpr(DeleteExpr.get(), /*DiscardedValue*/ false); + DeleteExpr = S.ActOnFinishFullExpr(DeleteExpr.get()); if (DeleteExpr.isInvalid()) return false; @@ -1348,8 +1347,7 @@ bool CoroutineStmtBuilder::makeOnException() { ExprResult UnhandledException = buildPromiseCall(S, Fn.CoroutinePromise, Loc, "unhandled_exception", None); - UnhandledException = S.ActOnFinishFullExpr(UnhandledException.get(), Loc, - /*DiscardedValue*/ false); + UnhandledException = S.ActOnFinishFullExpr(UnhandledException.get(), Loc); if (UnhandledException.isInvalid()) return false; @@ -1402,8 +1400,7 @@ bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() { "get_return_object type must no longer be dependent"); if (FnRetType->isVoidType()) { - ExprResult Res = - S.ActOnFinishFullExpr(this->ReturnValue, Loc, /*DiscardedValue*/ false); + ExprResult Res = S.ActOnFinishFullExpr(this->ReturnValue, Loc); if (Res.isInvalid()) return false; @@ -1435,7 +1432,7 @@ bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() { if (Res.isInvalid()) return false; - Res = S.ActOnFinishFullExpr(Res.get(), /*DiscardedValue*/ false); + Res = S.ActOnFinishFullExpr(Res.get()); if (Res.isInvalid()) return false; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 23c99d45a78d4..7ddf2e88b7871 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11200,9 +11200,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { // struct T { S a, b; } t = { Temp(), Temp() } // // we should destroy the first Temp before constructing the second. - ExprResult Result = - ActOnFinishFullExpr(Init, VDecl->getLocation(), - /*DiscardedValue*/ false, VDecl->isConstexpr()); + ExprResult Result = ActOnFinishFullExpr(Init, VDecl->getLocation(), + false, + VDecl->isConstexpr()); if (Result.isInvalid()) { VDecl->setInvalidDecl(); return; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 8b3556f715bfd..950a63aa451be 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1205,7 +1205,7 @@ static bool checkTupleLikeDecomposition(Sema &S, E = Seq.Perform(S, Entity, Kind, Init); if (E.isInvalid()) return true; - E = S.ActOnFinishFullExpr(E.get(), Loc, /*DiscardedValue*/ false); + E = S.ActOnFinishFullExpr(E.get(), Loc); if (E.isInvalid()) return true; RefVD->setInit(E.get()); @@ -3686,7 +3686,7 @@ void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D, // C++11 [class.base.init]p7: // The initialization of each base and member constitutes a // full-expression. - Init = ActOnFinishFullExpr(Init.get(), InitLoc, /*DiscardedValue*/ false); + Init = ActOnFinishFullExpr(Init.get(), InitLoc); if (Init.isInvalid()) { FD->setInvalidDecl(); return; @@ -4044,8 +4044,7 @@ Sema::BuildMemberInitializer(ValueDecl *Member, Expr *Init, // C++11 [class.base.init]p7: // The initialization of each base and member constitutes a // full-expression. - MemberInit = ActOnFinishFullExpr(MemberInit.get(), InitRange.getBegin(), - /*DiscardedValue*/ false); + MemberInit = ActOnFinishFullExpr(MemberInit.get(), InitRange.getBegin()); if (MemberInit.isInvalid()) return true; @@ -4100,8 +4099,8 @@ Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo, Expr *Init, // C++11 [class.base.init]p7: // The initialization of each base and member constitutes a // full-expression. - DelegationInit = ActOnFinishFullExpr( - DelegationInit.get(), InitRange.getBegin(), /*DiscardedValue*/ false); + DelegationInit = ActOnFinishFullExpr(DelegationInit.get(), + InitRange.getBegin()); if (DelegationInit.isInvalid()) return true; @@ -4230,8 +4229,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo, // C++11 [class.base.init]p7: // The initialization of each base and member constitutes a // full-expression. - BaseInit = ActOnFinishFullExpr(BaseInit.get(), InitRange.getBegin(), - /*DiscardedValue*/ false); + BaseInit = ActOnFinishFullExpr(BaseInit.get(), InitRange.getBegin()); if (BaseInit.isInvalid()) return true; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 2bcd47abe3569..db0c62630a9ec 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4723,9 +4723,8 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD, if (Result.isInvalid()) return true; - Result = - ActOnFinishFullExpr(Result.getAs(), Param->getOuterLocStart(), - /*DiscardedValue*/ false); + Result = ActOnFinishFullExpr(Result.getAs(), + Param->getOuterLocStart()); if (Result.isInvalid()) return true; diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 8c89a3cee3dbb..cce7a216548ff 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -7815,8 +7815,6 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, FullExpr = IgnoredValueConversions(FullExpr.get()); if (FullExpr.isInvalid()) return ExprError(); - - DiagnoseUnusedExprResult(FullExpr.get()); } FullExpr = CorrectDelayedTyposInExpr(FullExpr.get()); diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index af233b96d69b4..4e002a853dc21 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1724,7 +1724,7 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation, /*NRVO=*/false), CurrentLocation, Src); if (!Init.isInvalid()) - Init = ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); + Init = ActOnFinishFullExpr(Init.get()); if (Init.isInvalid()) return ExprError(); diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 36048a38b999c..aedec746af9e7 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -5367,7 +5367,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, LastIteration.get(), UB.get()); EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), CondOp.get()); - EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); + EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); // If we have a combined directive that combines 'distribute', 'for' or // 'simd' we need to be able to access the bounds of the schedule of the @@ -5396,8 +5396,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, LastIteration.get(), CombUB.get()); CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), CombCondOp.get()); - CombEUB = - SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); + CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get()); const CapturedDecl *CD = cast(AStmt)->getCapturedDecl(); // We expect to have at least 2 more parameters than the 'parallel' @@ -5431,7 +5430,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, ? LB.get() : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); - Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); + Init = SemaRef.ActOnFinishFullExpr(Init.get()); if (isOpenMPLoopBoundSharingDirective(DKind)) { Expr *CombRHS = @@ -5442,8 +5441,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); CombInit = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); - CombInit = - SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); + CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get()); } } @@ -5475,7 +5473,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, if (!Inc.isUsable()) return 0; Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); - Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); + Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); if (!Inc.isUsable()) return 0; @@ -5493,8 +5491,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // LB = LB + ST NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); - NextLB = - SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); + NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); if (!NextLB.isUsable()) return 0; // UB + ST @@ -5504,8 +5501,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // UB = UB + ST NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); - NextUB = - SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); + NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); if (!NextUB.isUsable()) return 0; if (isOpenMPLoopBoundSharingDirective(DKind)) { @@ -5516,8 +5512,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // LB = LB + ST CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), CombNextLB.get()); - CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), - /*DiscardedValue*/ false); + CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get()); if (!CombNextLB.isUsable()) return 0; // UB + ST @@ -5528,8 +5523,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // UB = UB + ST CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), CombNextUB.get()); - CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), - /*DiscardedValue*/ false); + CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get()); if (!CombNextUB.isUsable()) return 0; } @@ -5550,8 +5544,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, assert(DistInc.isUsable() && "distribute inc expr was not built"); DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), DistInc.get()); - DistInc = - SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); + DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get()); assert(DistInc.isUsable() && "distribute inc expr was not built"); // Build expression: UB = min(UB, prevUB) for #for in composite or combined @@ -5563,8 +5556,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), CondOp.get()); - PrevEUB = - SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); + PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get()); // Build IV <= PrevUB to be used in parallel for is in combination with // a distribute directive with schedule(static, 1) @@ -5680,10 +5672,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Built.IterationVarRef = IV.get(); Built.LastIteration = LastIteration.get(); Built.NumIterations = NumIterations.get(); - Built.CalcLastIteration = SemaRef - .ActOnFinishFullExpr(CalcLastIteration.get(), - /*DiscardedValue*/ false) - .get(); + Built.CalcLastIteration = + SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); Built.PreCond = PreCond.get(); Built.PreInits = buildPreInits(C, Captures); Built.Cond = Cond.get(); @@ -10358,8 +10348,8 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef VarList, PseudoDstExpr, PseudoSrcExpr); if (AssignmentOp.isInvalid()) continue; - AssignmentOp = - ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); + AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, + /*DiscardedValue=*/true); if (AssignmentOp.isInvalid()) continue; @@ -11357,8 +11347,7 @@ static bool actOnOMPReductionKindClause( BO_Assign, LHSDRE, ConditionalOp); } if (ReductionOp.isUsable()) - ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), - /*DiscardedValue*/ false); + ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get()); } if (!ReductionOp.isUsable()) continue; @@ -11688,7 +11677,7 @@ OMPClause *Sema::ActOnOpenMPLinearClause( buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); ExprResult CalcStep = BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); - CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); + CalcStep = ActOnFinishFullExpr(CalcStep.get()); // Warn about zero linear step (it would be probably better specified as // making corresponding variables 'const'). @@ -11776,7 +11765,7 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, else Update = *CurPrivate; Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), - /*DiscardedValue*/ false); + /*DiscardedValue=*/true); // Build final: Var = InitExpr + NumIterations * Step ExprResult Final; @@ -11787,7 +11776,7 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, else Final = *CurPrivate; Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), - /*DiscardedValue*/ false); + /*DiscardedValue=*/true); if (!Update.isUsable() || !Final.isUsable()) { Updates.push_back(nullptr); @@ -11955,7 +11944,7 @@ OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef VarList, if (AssignmentOp.isInvalid()) continue; AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), - /*DiscardedValue*/ false); + /*DiscardedValue=*/true); if (AssignmentOp.isInvalid()) continue; @@ -12063,8 +12052,8 @@ OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef VarList, DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); if (AssignmentOp.isInvalid()) continue; - AssignmentOp = - ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); + AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, + /*DiscardedValue=*/true); if (AssignmentOp.isInvalid()) continue; diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 9e30c9a396c0a..dacf8d0cf4e7f 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -42,11 +42,12 @@ using namespace clang; using namespace sema; -StmtResult Sema::ActOnExprStmt(ExprResult FE, bool DiscardedValue) { +StmtResult Sema::ActOnExprStmt(ExprResult FE) { if (FE.isInvalid()) return StmtError(); - FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(), DiscardedValue); + FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(), + /*DiscardedValue*/ true); if (FE.isInvalid()) return StmtError(); @@ -347,10 +348,6 @@ sema::CompoundScopeInfo &Sema::getCurCompoundScope() const { return getCurFunction()->CompoundScopes.back(); } -bool Sema::isCurCompoundStmtAStmtExpr() const { - return getCurCompoundScope().IsStmtExpr; -} - StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef Elts, bool isStmtExpr) { const unsigned NumElts = Elts.size(); @@ -373,6 +370,14 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R, Diag(D->getLocation(), diag::ext_mixed_decls_code); } } + // Warn about unused expressions in statements. + for (unsigned i = 0; i != NumElts; ++i) { + // Ignore statements that are last in a statement expression. + if (isStmtExpr && i == NumElts - 1) + continue; + + DiagnoseUnusedExprResult(Elts[i]); + } // Check for suspicious empty body (null statement) in `for' and `while' // statements. Don't do anything for template instantiations, this just adds @@ -464,12 +469,15 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHSVal, /// ActOnCaseStmtBody - This installs a statement as the body of a case. void Sema::ActOnCaseStmtBody(Stmt *S, Stmt *SubStmt) { + DiagnoseUnusedExprResult(SubStmt); cast(S)->setSubStmt(SubStmt); } StmtResult Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, Stmt *SubStmt, Scope *CurScope) { + DiagnoseUnusedExprResult(SubStmt); + if (getCurFunction()->SwitchStack.empty()) { Diag(DefaultLoc, diag::err_default_not_in_switch); return SubStmt; @@ -563,6 +571,9 @@ StmtResult Sema::BuildIfStmt(SourceLocation IfLoc, bool IsConstexpr, if (IsConstexpr || isa(Cond.get().second)) setFunctionHasBranchProtectedScope(); + DiagnoseUnusedExprResult(thenStmt); + DiagnoseUnusedExprResult(elseStmt); + return IfStmt::Create(Context, IfLoc, IsConstexpr, InitStmt, Cond.get().first, Cond.get().second, thenStmt, ElseLoc, elseStmt); } @@ -1290,6 +1301,8 @@ StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond, !Diags.isIgnored(diag::warn_comma_operator, CondVal.second->getExprLoc())) CommaVisitor(*this).Visit(CondVal.second); + DiagnoseUnusedExprResult(Body); + if (isa(Body)) getCurCompoundScope().setHasEmptyLoopBodies(); @@ -1309,7 +1322,7 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, return StmtError(); Cond = CondResult.get(); - CondResult = ActOnFinishFullExpr(Cond, DoLoc, /*DiscardedValue*/ false); + CondResult = ActOnFinishFullExpr(Cond, DoLoc); if (CondResult.isInvalid()) return StmtError(); Cond = CondResult.get(); @@ -1319,6 +1332,8 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, !Diags.isIgnored(diag::warn_comma_operator, Cond->getExprLoc())) CommaVisitor(*this).Visit(Cond); + DiagnoseUnusedExprResult(Body); + return new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen); } @@ -1763,6 +1778,11 @@ StmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, CommaVisitor(*this).Visit(Second.get().second); Expr *Third = third.release().getAs(); + + DiagnoseUnusedExprResult(First); + DiagnoseUnusedExprResult(Third); + DiagnoseUnusedExprResult(Body); + if (isa(Body)) getCurCompoundScope().setHasEmptyLoopBodies(); @@ -1782,7 +1802,7 @@ StmtResult Sema::ActOnForEachLValueExpr(Expr *E) { if (result.isInvalid()) return StmtError(); E = result.get(); - ExprResult FullExpr = ActOnFinishFullExpr(E, /*DiscardedValue*/ false); + ExprResult FullExpr = ActOnFinishFullExpr(E); if (FullExpr.isInvalid()) return StmtError(); return StmtResult(static_cast(FullExpr.get())); @@ -1936,8 +1956,7 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc, if (CollectionExprResult.isInvalid()) return StmtError(); - CollectionExprResult = - ActOnFinishFullExpr(CollectionExprResult.get(), /*DiscardedValue*/ false); + CollectionExprResult = ActOnFinishFullExpr(CollectionExprResult.get()); if (CollectionExprResult.isInvalid()) return StmtError(); @@ -2574,8 +2593,7 @@ StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, if (!NotEqExpr.isInvalid()) NotEqExpr = CheckBooleanCondition(ColonLoc, NotEqExpr.get()); if (!NotEqExpr.isInvalid()) - NotEqExpr = - ActOnFinishFullExpr(NotEqExpr.get(), /*DiscardedValue*/ false); + NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get()); if (NotEqExpr.isInvalid()) { Diag(RangeLoc, diag::note_for_range_invalid_iterator) << RangeLoc << 0 << BeginRangeRef.get()->getType(); @@ -2598,7 +2616,7 @@ StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, // co_await during the initial parse. IncrExpr = ActOnCoawaitExpr(S, CoawaitLoc, IncrExpr.get()); if (!IncrExpr.isInvalid()) - IncrExpr = ActOnFinishFullExpr(IncrExpr.get(), /*DiscardedValue*/ false); + IncrExpr = ActOnFinishFullExpr(IncrExpr.get()); if (IncrExpr.isInvalid()) { Diag(RangeLoc, diag::note_for_range_invalid_iterator) << RangeLoc << 2 << BeginRangeRef.get()->getType() ; @@ -2853,7 +2871,7 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, return StmtError(); } - ExprResult ExprRes = ActOnFinishFullExpr(E, /*DiscardedValue*/ false); + ExprResult ExprRes = ActOnFinishFullExpr(E); if (ExprRes.isInvalid()) return StmtError(); E = ExprRes.get(); @@ -3203,8 +3221,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { ExpressionEvaluationContext::DiscardedStatement && (HasDeducedReturnType || CurCap->HasImplicitReturnType)) { if (RetValExp) { - ExprResult ER = - ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false); + ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); if (ER.isInvalid()) return StmtError(); RetValExp = ER.get(); @@ -3331,8 +3348,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } if (RetValExp) { - ExprResult ER = - ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false); + ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); if (ER.isInvalid()) return StmtError(); RetValExp = ER.get(); @@ -3562,8 +3578,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { ExpressionEvaluationContext::DiscardedStatement && FnRetType->getContainedAutoType()) { if (RetValExp) { - ExprResult ER = - ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false); + ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); if (ER.isInvalid()) return StmtError(); RetValExp = ER.get(); @@ -3657,8 +3672,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } if (RetValExp) { - ExprResult ER = - ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false); + ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); if (ER.isInvalid()) return StmtError(); RetValExp = ER.get(); @@ -3737,8 +3751,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } if (RetValExp) { - ExprResult ER = - ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false); + ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); if (ER.isInvalid()) return StmtError(); RetValExp = ER.get(); @@ -3791,7 +3804,7 @@ StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) { if (Result.isInvalid()) return StmtError(); - Result = ActOnFinishFullExpr(Result.get(), /*DiscardedValue*/ false); + Result = ActOnFinishFullExpr(Result.get()); if (Result.isInvalid()) return StmtError(); Throw = Result.get(); @@ -3863,7 +3876,7 @@ Sema::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand) { } // The operand to @synchronized is a full-expression. - return ActOnFinishFullExpr(operand, /*DiscardedValue*/ false); + return ActOnFinishFullExpr(operand); } StmtResult diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index df14768cbe812..9de4e8d654f96 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -328,7 +328,7 @@ class TreeTransform { /// other mechanism. /// /// \returns the transformed statement. - StmtResult TransformStmt(Stmt *S, bool DiscardedValue = false); + StmtResult TransformStmt(Stmt *S); /// Transform the given statement. /// @@ -3269,8 +3269,8 @@ class TreeTransform { bool DeducibleTSTContext); }; -template -StmtResult TreeTransform::TransformStmt(Stmt *S, bool DiscardedValue) { +template +StmtResult TreeTransform::TransformStmt(Stmt *S) { if (!S) return S; @@ -3294,7 +3294,7 @@ StmtResult TreeTransform::TransformStmt(Stmt *S, bool DiscardedValue) { if (E.isInvalid()) return StmtError(); - return getSema().ActOnExprStmt(E, DiscardedValue); + return getSema().ActOnExprStmt(E); } } @@ -4715,8 +4715,7 @@ TreeTransform::TransformVariableArrayType(TypeLocBuilder &TLB, } if (SizeResult.isInvalid()) return QualType(); - SizeResult = - SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ false); + SizeResult = SemaRef.ActOnFinishFullExpr(SizeResult.get()); if (SizeResult.isInvalid()) return QualType(); @@ -6521,9 +6520,7 @@ TreeTransform::TransformCompoundStmt(CompoundStmt *S, bool SubStmtChanged = false; SmallVector Statements; for (auto *B : S->body()) { - StmtResult Result = - getDerived().TransformStmt(B, !IsStmtExpr || B != S->body_back()); - + StmtResult Result = getDerived().TransformStmt(B); if (Result.isInvalid()) { // Immediately fail if this was a DeclStmt, since it's very // likely that this will cause problems for future statements. diff --git a/clang/test/CXX/stmt.stmt/stmt.select/p3.cpp b/clang/test/CXX/stmt.stmt/stmt.select/p3.cpp index 4804cc559d007..7a6a408ec955b 100644 --- a/clang/test/CXX/stmt.stmt/stmt.select/p3.cpp +++ b/clang/test/CXX/stmt.stmt/stmt.select/p3.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify %s -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -std=c++1z -Wc++14-compat -verify %s -DCPP17 +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++1z -Wc++14-compat -verify %s -DCPP17 int f(); @@ -71,6 +71,7 @@ void whileInitStatement() { // last loop above. It would be nice to remove this. void whileInitStatement2() { while (; false) {} // expected-error {{expected expression}} - // expected-error@-1 {{expected ';' after expression}} - // expected-error@-2 {{expected expression}} + // expected-warning@-1 {{expression result unused}} + // expected-error@-2 {{expected ';' after expression}} + // expected-error@-3 {{expected expression}} } diff --git a/clang/test/CodeCompletion/pragma-macro-token-caching.c b/clang/test/CodeCompletion/pragma-macro-token-caching.c index 59b6621b56ad4..432706e85ceb9 100644 --- a/clang/test/CodeCompletion/pragma-macro-token-caching.c +++ b/clang/test/CodeCompletion/pragma-macro-token-caching.c @@ -12,7 +12,7 @@ void completeParam(int param) { void completeParamPragmaError(int param) { Outer(__extension__({ _Pragma(2) })); // expected-error {{_Pragma takes a parenthesized string literal}} - param; // expected-warning {{expression result unused}} + param; } // RUN: %clang_cc1 -fsyntax-only -verify -code-completion-at=%s:16:1 %s | FileCheck %s diff --git a/clang/test/Parser/cxx1z-init-statement.cpp b/clang/test/Parser/cxx1z-init-statement.cpp index ade60dc762d5c..3d119ef8e709c 100644 --- a/clang/test/Parser/cxx1z-init-statement.cpp +++ b/clang/test/Parser/cxx1z-init-statement.cpp @@ -13,9 +13,9 @@ int f() { if (T(n) = 0; n) {} // init-statement expressions - if (T{f()}; f()) {} // expected-warning {{expression result unused}} - if (T{f()}, g, h; f()) {} // expected-warning 2{{unused}} expected-warning {{expression result unused}} - if (T(f()), g, h + 1; f()) {} // expected-warning 2{{unused}} expected-warning {{expression result unused}} + if (T{f()}; f()) {} + if (T{f()}, g, h; f()) {} // expected-warning 2{{unused}} + if (T(f()), g, h + 1; f()) {} // expected-warning 2{{unused}} // condition declarations if (T(n){g}) {} @@ -35,7 +35,7 @@ int f() { // Likewise for 'switch' switch (int n; n) {} - switch (g; int g = 5) {} // expected-warning {{expression result unused}} + switch (g; int g = 5) {} if (int a, b; int c = a) { // expected-note 6{{previous}} int a; // expected-error {{redefinition}} diff --git a/clang/test/Parser/switch-recovery.cpp b/clang/test/Parser/switch-recovery.cpp index eacd017ab2364..a3a0178cd10b6 100644 --- a/clang/test/Parser/switch-recovery.cpp +++ b/clang/test/Parser/switch-recovery.cpp @@ -105,7 +105,7 @@ void test9(int x) { // expected-note {{'x' declared here}} expected-error {{expected expression}} 8:: x; // expected-error {{expected ';' after expression}} \ expected-error {{no member named 'x' in the global namespace; did you mean simply 'x'?}} \ - expected-warning {{expression result unused}} + expected-warning 2 {{expression result unused}} 9:: :y; // expected-error {{expected ';' after expression}} \ expected-error {{expected unqualified-id}} \ expected-warning {{expression result unused}} diff --git a/clang/test/SemaCXX/cxx1z-init-statement.cpp b/clang/test/SemaCXX/cxx1z-init-statement.cpp index eea2589ab7c62..d37acd08ce77d 100644 --- a/clang/test/SemaCXX/cxx1z-init-statement.cpp +++ b/clang/test/SemaCXX/cxx1z-init-statement.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -std=c++1z -Wno-unused-value -verify %s -// RUN: %clang_cc1 -std=c++17 -Wno-unused-value -verify %s +// RUN: %clang_cc1 -std=c++1z -verify %s +// RUN: %clang_cc1 -std=c++17 -verify %s void testIf() { int x = 0; @@ -12,7 +12,7 @@ void testIf() { int x = 0; // expected-error {{redefinition of 'x'}} if (x; int a = 0) ++a; - if (x, +x; int a = 0) // expected-note 2 {{previous definition is here}} + if (x, +x; int a = 0) // expected-note 2 {{previous definition is here}} expected-warning {{unused}} int a = 0; // expected-error {{redefinition of 'a'}} else int a = 0; // expected-error {{redefinition of 'a'}} @@ -48,7 +48,7 @@ void testSwitch() { ++a; } - switch (x, +x; int a = 0) { // expected-note {{previous definition is here}} + switch (x, +x; int a = 0) { // expected-note {{previous definition is here}} expected-warning {{unused}} case 0: int a = 0; // expected-error {{redefinition of 'a'}} // expected-note {{previous definition is here}} case 1: diff --git a/clang/test/SemaCXX/for-range-examples.cpp b/clang/test/SemaCXX/for-range-examples.cpp index 5424b7a8ee797..477789b56c142 100644 --- a/clang/test/SemaCXX/for-range-examples.cpp +++ b/clang/test/SemaCXX/for-range-examples.cpp @@ -244,7 +244,7 @@ void foo () { int b = 1, a[b]; a[0] = 0; - [&] { for (int c : a) 0; } (); // expected-warning {{expression result unused}} + [&] { for (int c : a) 0; } (); } diff --git a/clang/test/SemaCXX/warn-unused-result.cpp b/clang/test/SemaCXX/warn-unused-result.cpp index f1de4618a741a..88f5ab1e85c06 100644 --- a/clang/test/SemaCXX/warn-unused-result.cpp +++ b/clang/test/SemaCXX/warn-unused-result.cpp @@ -33,36 +33,6 @@ void test() { const S &s4 = g1(); } -void testSubstmts(int i) { - switch (i) { - case 0: - f(); // expected-warning {{ignoring return value}} - default: - f(); // expected-warning {{ignoring return value}} - } - - if (i) - f(); // expected-warning {{ignoring return value}} - else - f(); // expected-warning {{ignoring return value}} - - while (i) - f(); // expected-warning {{ignoring return value}} - - do - f(); // expected-warning {{ignoring return value}} - while (i); - - for (f(); // expected-warning {{ignoring return value}} - ; - f() // expected-warning {{ignoring return value}} - ) - f(); // expected-warning {{ignoring return value}} - - f(), // expected-warning {{ignoring return value}} - (void)f(); -} - struct X { int foo() __attribute__((warn_unused_result)); }; @@ -236,13 +206,3 @@ void f() { (void)++p; } } // namespace - -namespace PR39837 { -[[clang::warn_unused_result]] int f(int); - -void g() { - int a[2]; - for (int b : a) - f(b); // expected-warning {{ignoring return value}} -} -} // namespace PR39837 From c957a992959b7c1e5a613d8a953df8a029f922c0 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 14 Feb 2019 10:47:35 +0000 Subject: [PATCH 135/274] Merging r353976: ------------------------------------------------------------------------ r353976 | epilk | 2019-02-13 21:32:37 +0100 (Wed, 13 Feb 2019) | 11 lines [Sema] Delay checking whether objc_designated_initializer is being applied to an init method This fixes a regression that was caused by r335084, which reversed the order that attributes are applied. objc_method_family can change whether a method is an init method, so the order that these attributes are applied matters. The commit fixes this by delaying the init check until after all attributes have been applied. rdar://47829358 Differential revision: https://reviews.llvm.org/D58152 ------------------------------------------------------------------------ llvm-svn: 354015 --- clang/include/clang/Basic/Attr.td | 9 +------ .../clang/Basic/DiagnosticSemaKinds.td | 3 +++ clang/lib/Sema/SemaDeclAttr.cpp | 26 +++++++++++++++++-- ...a-attribute-supported-attributes-list.test | 1 + clang/test/SemaObjC/attr-designated-init.m | 15 ++++++++++- 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index bf1068019b77b..b792db2852a80 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -103,13 +103,6 @@ def ObjCInstanceMethod : SubsetSubjectisInstanceMethod()}], "Objective-C instance methods">; -def ObjCInterfaceDeclInitMethod : SubsetSubjectgetMethodFamily() == OMF_init && - (isa(S->getDeclContext()) || - (isa(S->getDeclContext()) && - cast(S->getDeclContext())->IsClassExtension()))}], - "init methods of interface or class extension declarations">; - def Struct : SubsetSubjectisUnion()}], "structs">; @@ -1762,7 +1755,7 @@ def ObjCExplicitProtocolImpl : InheritableAttr { def ObjCDesignatedInitializer : Attr { let Spellings = [Clang<"objc_designated_initializer">]; - let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag>; + let Subjects = SubjectList<[ObjCMethod], ErrorDiag>; let Documentation = [Undocumented]; } diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index b71f65d146cab..7ef57b02fe1c6 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3460,6 +3460,9 @@ def warn_objc_secondary_init_missing_init_call : Warning< def warn_objc_implementation_missing_designated_init_override : Warning< "method override for the designated initializer of the superclass %objcinstance0 not found">, InGroup; +def err_designated_init_attr_non_init : Error< + "'objc_designated_initializer' attribute only applies to init methods " + "of interface or class extension declarations">; // objc_bridge attribute diagnostics. def err_objc_attr_not_id : Error< diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 8819f0396a270..c4c3598ee7f3c 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5116,11 +5116,22 @@ static void handleObjCBridgeRelatedAttr(Sema &S, Decl *D, static void handleObjCDesignatedInitializer(Sema &S, Decl *D, const ParsedAttr &AL) { + DeclContext *Ctx = D->getDeclContext(); + + // This attribute can only be applied to methods in interfaces or class + // extensions. + if (!isa(Ctx) && + !(isa(Ctx) && + cast(Ctx)->IsClassExtension())) { + S.Diag(D->getLocation(), diag::err_designated_init_attr_non_init); + return; + } + ObjCInterfaceDecl *IFace; - if (auto *CatDecl = dyn_cast(D->getDeclContext())) + if (auto *CatDecl = dyn_cast(Ctx)) IFace = CatDecl->getClassInterface(); else - IFace = cast(D->getDeclContext()); + IFace = cast(Ctx); if (!IFace) return; @@ -7067,6 +7078,17 @@ void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, } } } + + // Do this check after processing D's attributes because the attribute + // objc_method_family can change whether the given method is in the init + // family, and it can be applied after objc_designated_initializer. This is a + // bit of a hack, but we need it to be compatible with versions of clang that + // processed the attribute list in the wrong order. + if (D->hasAttr() && + cast(D)->getMethodFamily() != OMF_init) { + Diag(D->getLocation(), diag::err_designated_init_attr_non_init); + D->dropAttr(); + } } // Helper for delayed processing TransparentUnion attribute. diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index 98935fc21355b..5ae4a7ca7bbe9 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -94,6 +94,7 @@ // CHECK-NEXT: ObjCBridge (SubjectMatchRule_record, SubjectMatchRule_type_alias) // CHECK-NEXT: ObjCBridgeMutable (SubjectMatchRule_record) // CHECK-NEXT: ObjCBridgeRelated (SubjectMatchRule_record) +// CHECK-NEXT: ObjCDesignatedInitializer (SubjectMatchRule_objc_method) // CHECK-NEXT: ObjCException (SubjectMatchRule_objc_interface) // CHECK-NEXT: ObjCExplicitProtocolImpl (SubjectMatchRule_objc_protocol) // CHECK-NEXT: ObjCExternallyRetained (SubjectMatchRule_variable_not_is_parameter, SubjectMatchRule_function, SubjectMatchRule_block, SubjectMatchRule_objc_method) diff --git a/clang/test/SemaObjC/attr-designated-init.m b/clang/test/SemaObjC/attr-designated-init.m index 05085884784b0..3558916dbe54a 100644 --- a/clang/test/SemaObjC/attr-designated-init.m +++ b/clang/test/SemaObjC/attr-designated-init.m @@ -3,7 +3,7 @@ #define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) #define NS_UNAVAILABLE __attribute__((unavailable)) -void fnfoo(void) NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}} +void fnfoo(void) NS_DESIGNATED_INITIALIZER; // expected-error {{'objc_designated_initializer' attribute only applies to Objective-C methods}} @protocol P1 -(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}} @@ -428,3 +428,16 @@ - (instancetype)init NS_DESIGNATED_INITIALIZER; @interface CategoryForMissingInterface(Cat) // expected-error{{cannot find interface declaration}} - (instancetype)init NS_DESIGNATED_INITIALIZER; // expected-error{{only applies to init methods of interface or class extension declarations}} @end + +@interface TwoAttrs +-(instancetype)foo + __attribute__((objc_designated_initializer)) + __attribute__((objc_method_family(init))); +-(instancetype)bar + __attribute__((objc_method_family(init))) + __attribute__((objc_designated_initializer)); +-(instancetype)baz + __attribute__((objc_designated_initializer, objc_method_family(init))); +-(instancetype)quux + __attribute__((objc_method_family(init), objc_designated_initializer)); +@end From 11521347aff95e61fee986fb937dd5395e41ef57 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 14 Feb 2019 10:49:15 +0000 Subject: [PATCH 136/274] Merging r353968: ------------------------------------------------------------------------ r353968 | ruiu | 2019-02-13 19:51:15 +0100 (Wed, 13 Feb 2019) | 10 lines Recover elf32-bigmips and elf32-powerpc support in LLD This fixes a 7.0 -> 8.0 regression when parsing OUTPUT_FORMAT("elf32-powerpc"); or elf32-bigmips directive in ldscripts as well as an unknown emulation error when lld is invoked by clang due to missed elf32ppclinux case. Patch by vit9696 Differential Revision: https://reviews.llvm.org/D58005 ------------------------------------------------------------------------ llvm-svn: 354016 --- lld/ELF/Driver.cpp | 2 +- lld/ELF/ScriptParser.cpp | 3 ++- lld/test/ELF/emulation-mips.s | 3 +++ lld/test/ELF/emulation-ppc.s | 37 +++++++++++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 2e2036310fb21..bce9d944a4a64 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -130,7 +130,7 @@ static std::tuple parseEmulation(StringRef Emul) { .Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS}) .Cases("elf32ltsmip", "elf32ltsmipn32", {ELF32LEKind, EM_MIPS}) .Case("elf32lriscv", {ELF32LEKind, EM_RISCV}) - .Case("elf32ppc", {ELF32BEKind, EM_PPC}) + .Cases("elf32ppc", "elf32ppclinux", {ELF32BEKind, EM_PPC}) .Case("elf64btsmip", {ELF64BEKind, EM_MIPS}) .Case("elf64ltsmip", {ELF64LEKind, EM_MIPS}) .Case("elf64lriscv", {ELF64LEKind, EM_RISCV}) diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 7cce94659c9e9..7dbe1641622b6 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -392,10 +392,11 @@ static std::pair parseBfdName(StringRef S) { .Case("elf32-x86-64", {ELF32LEKind, EM_X86_64}) .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64}) .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64}) + .Case("elf32-powerpc", {ELF32BEKind, EM_PPC}) .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64}) .Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64}) .Case("elf64-x86-64", {ELF64LEKind, EM_X86_64}) - .Case("elf32-tradbigmips", {ELF32BEKind, EM_MIPS}) + .Cases("elf32-tradbigmips", "elf32-bigmips", {ELF32BEKind, EM_MIPS}) .Case("elf32-ntradbigmips", {ELF32BEKind, EM_MIPS}) .Case("elf32-tradlittlemips", {ELF32LEKind, EM_MIPS}) .Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS}) diff --git a/lld/test/ELF/emulation-mips.s b/lld/test/ELF/emulation-mips.s index 42d0dd973eb36..6d7a1198b761f 100644 --- a/lld/test/ELF/emulation-mips.s +++ b/lld/test/ELF/emulation-mips.s @@ -7,6 +7,9 @@ # RUN: echo 'OUTPUT_FORMAT(elf32-tradbigmips)' > %tmips.script # RUN: ld.lld %tmips.script -e _start %tmips -o %t4mips # RUN: llvm-readobj -file-headers %t4mips | FileCheck --check-prefix=MIPS %s +# RUN: echo 'OUTPUT_FORMAT(elf32-bigmips)' > %tmips2.script +# RUN: ld.lld %tmips2.script -e _start %tmips -o %t5mips +# RUN: llvm-readobj -file-headers %t5mips | FileCheck --check-prefix=MIPS %s # MIPS: ElfHeader { # MIPS-NEXT: Ident { # MIPS-NEXT: Magic: (7F 45 4C 46) diff --git a/lld/test/ELF/emulation-ppc.s b/lld/test/ELF/emulation-ppc.s index 843e77604779b..4c8beb10159e6 100644 --- a/lld/test/ELF/emulation-ppc.s +++ b/lld/test/ELF/emulation-ppc.s @@ -103,5 +103,42 @@ # PPC64LE-NEXT: StringTableSectionIndex: # PPC64LE-NEXT: } +# RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-linux %s -o %tppc32 +# RUN: ld.lld -m elf32ppc %tppc32 -o %t2ppc32 +# RUN: llvm-readobj -file-headers %t2ppc32 | FileCheck --check-prefix=PPC32 %s +# RUN: ld.lld %tppc32 -o %t3ppc32 +# RUN: llvm-readobj -file-headers %t3ppc32 | FileCheck --check-prefix=PPC32 %s +# RUN: echo 'OUTPUT_FORMAT(elf32-powerpc)' > %tppc32.script +# RUN: ld.lld %tppc32.script %tppc32 -o %t4ppc32 +# RUN: llvm-readobj -file-headers %t4ppc32 | FileCheck --check-prefix=PPC32 %s +# RUN: ld.lld -m elf32ppclinux %tppc32 -o %t5ppc32 +# RUN: llvm-readobj -file-headers %t5ppc32 | FileCheck --check-prefix=PPC32 %s + +# PPC32: ElfHeader { +# PPC32-NEXT: Ident { +# PPC32-NEXT: Magic: (7F 45 4C 46) +# PPC32-NEXT: Class: 32-bit (0x1) +# PPC32-NEXT: DataEncoding: BigEndian (0x2) +# PPC32-NEXT: FileVersion: 1 +# PPC32-NEXT: OS/ABI: SystemV (0x0) +# PPC32-NEXT: ABIVersion: 0 +# PPC32-NEXT: Unused: (00 00 00 00 00 00 00) +# PPC32-NEXT: } +# PPC32-NEXT: Type: Executable (0x2) +# PPC32-NEXT: Machine: EM_PPC (0x14) +# PPC32-NEXT: Version: 1 +# PPC32-NEXT: Entry: +# PPC32-NEXT: ProgramHeaderOffset: 0x34 +# PPC32-NEXT: SectionHeaderOffset: +# PPC32-NEXT: Flags [ (0x0) +# PPC32-NEXT: ] +# PPC32-NEXT: HeaderSize: 52 +# PPC32-NEXT: ProgramHeaderEntrySize: 32 +# PPC32-NEXT: ProgramHeaderCount: +# PPC32-NEXT: SectionHeaderEntrySize: 40 +# PPC32-NEXT: SectionHeaderCount: +# PPC32-NEXT: StringTableSectionIndex: +# PPC32-NEXT: } + .globl _start _start: From ff290924df20d33f34cc330432ed5a3e4b8428e6 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 15 Feb 2019 13:54:42 +0000 Subject: [PATCH 137/274] Merging r354074: ------------------------------------------------------------------------ r354074 | epilk | 2019-02-14 23:48:01 +0100 (Thu, 14 Feb 2019) | 9 lines [Sema] Fix-up a -Wfloat-conversion diagnostic We were warning on valid ObjC property reference exprs, and passing in the wrong arguments to DiagnoseFloatingImpCast (leading to a badly worded diagnostic). rdar://47644670 Differential revision: https://reviews.llvm.org/D58145 ------------------------------------------------------------------------ llvm-svn: 354129 --- clang/lib/Sema/SemaChecking.cpp | 20 ++++++++++---------- clang/test/SemaCXX/warn-float-conversion.cpp | 12 ++++++------ clang/test/SemaObjC/conversion.m | 7 +++++++ 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 8dc1fdb76988d..b2c727b5c483b 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -10622,16 +10622,16 @@ static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E) { // The below checks assume source is floating point. if (!ResultBT || !RBT || !RBT->isFloatingPoint()) return; - // If source is floating point but target is not. - if (!ResultBT->isFloatingPoint()) - return DiagnoseFloatingImpCast(S, E, E->getRHS()->getType(), - E->getExprLoc()); - - // If both source and target are floating points. - // Builtin FP kinds are ordered by increasing FP rank. - if (ResultBT->getKind() < RBT->getKind() && - // We don't want to warn for system macro. - !S.SourceMgr.isInSystemMacro(E->getOperatorLoc())) + // If source is floating point but target is an integer. + if (ResultBT->isInteger()) + DiagnoseImpCast(S, E, E->getRHS()->getType(), E->getLHS()->getType(), + E->getExprLoc(), diag::warn_impcast_float_integer); + // If both source and target are floating points. Builtin FP kinds are ordered + // by increasing FP rank. FIXME: except _Float16, we currently emit a bogus + // warning. + else if (ResultBT->isFloatingPoint() && ResultBT->getKind() < RBT->getKind() && + // We don't want to warn for system macro. + !S.SourceMgr.isInSystemMacro(E->getOperatorLoc())) // warn about dropping FP rank. DiagnoseImpCast(S, E->getRHS(), E->getLHS()->getType(), E->getOperatorLoc(), diag::warn_impcast_float_result_precision); diff --git a/clang/test/SemaCXX/warn-float-conversion.cpp b/clang/test/SemaCXX/warn-float-conversion.cpp index 7dec4844b062e..fad1ff147e492 100644 --- a/clang/test/SemaCXX/warn-float-conversion.cpp +++ b/clang/test/SemaCXX/warn-float-conversion.cpp @@ -44,17 +44,17 @@ void Convert(float f, double d, long double ld) { void CompoundAssignment() { int x = 3; - x += 1.234; //expected-warning{{conversion}} - x -= -0.0; //expected-warning{{conversion}} - x *= 1.1f; //expected-warning{{conversion}} - x /= -2.2f; //expected-warning{{conversion}} + x += 1.234; // expected-warning {{implicit conversion turns floating-point number into integer: 'double' to 'int'}} + x -= -0.0; // expected-warning {{implicit conversion turns floating-point number into integer: 'double' to 'int'}} + x *= 1.1f; // expected-warning {{implicit conversion turns floating-point number into integer: 'float' to 'int'}} + x /= -2.2f; // expected-warning {{implicit conversion turns floating-point number into integer: 'float' to 'int'}} - int y = x += 1.4f; //expected-warning{{conversion}} + int y = x += 1.4f; // expected-warning {{implicit conversion turns floating-point number into integer: 'float' to 'int'}} float z = 1.1f; double w = -2.2; - y += z + w; //expected-warning{{conversion}} + y += z + w; // expected-warning {{implicit conversion turns floating-point number into integer: 'double' to 'int'}} } # 1 "foo.h" 3 diff --git a/clang/test/SemaObjC/conversion.m b/clang/test/SemaObjC/conversion.m index 88a1a44b2177b..743f7440e2e43 100644 --- a/clang/test/SemaObjC/conversion.m +++ b/clang/test/SemaObjC/conversion.m @@ -14,4 +14,11 @@ void radar14415662(RDar14415662 *f, char x, int y) { x = y; // expected-warning {{implicit conversion loses integer precision: 'int' to 'char'}} } +__attribute__((objc_root_class)) @interface DoubleProp +@property double d; +@end +void use_double_prop(DoubleProp *dp) { + double local = 42; + dp.d += local; // no warning +} From 8015928085708fd021c3b0ceb75a0b817d9c5faa Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 15 Feb 2019 14:00:25 +0000 Subject: [PATCH 138/274] Merging r353943: ------------------------------------------------------------------------ r353943 | baloghadamsoftware | 2019-02-13 13:25:47 +0100 (Wed, 13 Feb 2019) | 22 lines [Analyzer] Crash fix for FindLastStoreBRVisitor FindLastStoreBRVisitor tries to find the first node in the exploded graph where the current value was assigned to a region. This node is called the "store site". It is identified by a pair of Pred and Succ nodes where Succ already has the binding for the value while Pred does not have it. However the visitor mistakenly identifies a node pair as the store site where the value is a `LazyCompoundVal` and `Pred` does not have a store yet but `Succ` has it. In this case the `LazyCompoundVal` is different in the `Pred` node because it also contains the store which is different in the two nodes. This error may lead to crashes (a declaration is cast to a parameter declaration without check) or misleading bug path notes. In this patch we fix this problem by checking for unequal `LazyCompoundVals`: if their region is equal, and their store is the same as the store of their nodes we consider them as equal when looking for the "store site". This is an approximation because we do not check for differences of the subvalues (structure members or array elements) in the stores. Differential Revision: https://reviews.llvm.org/D58067 ------------------------------------------------------------------------ llvm-svn: 354130 --- .../Core/BugReporterVisitors.cpp | 29 ++++++++++++++++++- clang/test/Analysis/PR40625.cpp | 16 ++++++++++ clang/test/Analysis/uninit-vals.m | 8 ++--- 3 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 clang/test/Analysis/PR40625.cpp diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index da94b6eb21e9b..ea695c4736a3e 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -154,6 +154,32 @@ const Expr *bugreporter::getDerefExpr(const Stmt *S) { return E; } +/// Comparing internal representations of symbolic values (via +/// SVal::operator==()) is a valid way to check if the value was updated, +/// unless it's a LazyCompoundVal that may have a different internal +/// representation every time it is loaded from the state. In this function we +/// do an approximate comparison for lazy compound values, checking that they +/// are the immediate snapshots of the tracked region's bindings within the +/// node's respective states but not really checking that these snapshots +/// actually contain the same set of bindings. +bool hasVisibleUpdate(const ExplodedNode *LeftNode, SVal LeftVal, + const ExplodedNode *RightNode, SVal RightVal) { + if (LeftVal == RightVal) + return true; + + const auto LLCV = LeftVal.getAs(); + if (!LLCV) + return false; + + const auto RLCV = RightVal.getAs(); + if (!RLCV) + return false; + + return LLCV->getRegion() == RLCV->getRegion() && + LLCV->getStore() == LeftNode->getState()->getStore() && + RLCV->getStore() == RightNode->getState()->getStore(); +} + //===----------------------------------------------------------------------===// // Definitions for bug reporter visitors. //===----------------------------------------------------------------------===// @@ -1188,7 +1214,7 @@ FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ, if (Succ->getState()->getSVal(R) != V) return nullptr; - if (Pred->getState()->getSVal(R) == V) { + if (hasVisibleUpdate(Pred, Pred->getState()->getSVal(R), Succ, V)) { Optional PS = Succ->getLocationAs(); if (!PS || PS->getLocationValue() != R) return nullptr; @@ -1209,6 +1235,7 @@ FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ, // UndefinedVal.) if (Optional CE = Succ->getLocationAs()) { if (const auto *VR = dyn_cast(R)) { + const auto *Param = cast(VR->getDecl()); ProgramStateManager &StateMgr = BRC.getStateManager(); diff --git a/clang/test/Analysis/PR40625.cpp b/clang/test/Analysis/PR40625.cpp new file mode 100644 index 0000000000000..6cc27d39b6c08 --- /dev/null +++ b/clang/test/Analysis/PR40625.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,alpha.core.CallAndMessageUnInitRefArg %s -verify + +void f(const int *end); + +void g(const int (&arrr)[10]) { + f(arrr+sizeof(arrr)); // expected-warning{{1st function call argument is a pointer to uninitialized value}} + // FIXME: This is a false positive that should be fixed. Until then this + // tests the crash fix in FindLastStoreBRVisitor (beside + // uninit-vals.m). +} + +void h() { + int arr[10]; + + g(arr); +} diff --git a/clang/test/Analysis/uninit-vals.m b/clang/test/Analysis/uninit-vals.m index f97af1a6633cc..33352122ca5aa 100644 --- a/clang/test/Analysis/uninit-vals.m +++ b/clang/test/Analysis/uninit-vals.m @@ -394,11 +394,11 @@ void testSmallStructBitfieldsFirstUnnamed() { struct { int : 4; int y : 4; - } a, b, c; + } a, b, c; // expected-note{{'c' initialized here}} a.y = 2; - b = a; // expected-note{{Value assigned to 'c'}} + b = a; clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}} // expected-note@-1{{TRUE}} @@ -411,11 +411,11 @@ void testSmallStructBitfieldsSecondUnnamed() { struct { int x : 4; int : 4; - } a, b, c; + } a, b, c; // expected-note{{'c' initialized here}} a.x = 1; - b = a; // expected-note{{Value assigned to 'c'}} + b = a; clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}} // expected-note@-1{{TRUE}} From a7da36bd971a50e8489bdc885a21f4376be9bbca Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 18 Feb 2019 09:31:05 +0000 Subject: [PATCH 139/274] Merging r354035: ------------------------------------------------------------------------ r354035 | brunoricci | 2019-02-14 16:43:17 +0100 (Thu, 14 Feb 2019) | 23 lines [Sema] Fix a regression introduced in "[AST][Sema] Remove CallExpr::setNumArgs" D54902 removed CallExpr::setNumArgs in preparation of tail-allocating the arguments of CallExpr. It did this by allocating storage for max(number of arguments, number of parameters in the prototype). The temporarily nulled arguments however causes issues in BuildResolvedCallExpr when typo correction is done just after the creation of the call expression. This was unfortunately missed by the tests /: To fix this, delay setting the number of arguments to max(number of arguments, number of parameters in the prototype) until we are ready for it. It would be nice to have this encapsulated in CallExpr but this is the best I can come up with under the constraint that we cannot add anything the CallExpr. Fixes PR40286. Differential Revision: https://reviews.llvm.org/D57948 Reviewed By: aaron.ballman ------------------------------------------------------------------------ llvm-svn: 354247 --- clang/include/clang/AST/Expr.h | 5 +++++ clang/lib/Sema/SemaExpr.cpp | 26 ++++++++++++++++++++++---- clang/test/Sema/typo-correction.c | 15 +++++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 3de73428829b3..bf4f3babbd3c6 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -2577,6 +2577,11 @@ class CallExpr : public Expr { NumArgs = NewNumArgs; } + /// Bluntly set a new number of arguments without doing any checks whatsoever. + /// Only used during construction of a CallExpr in a few places in Sema. + /// FIXME: Find a way to remove it. + void setNumArgsUnsafe(unsigned NewNumArgs) { NumArgs = NewNumArgs; } + typedef ExprIterator arg_iterator; typedef ConstExprIterator const_arg_iterator; typedef llvm::iterator_range arg_range; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index db0c62630a9ec..ff9393a56b9cb 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5676,18 +5676,36 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, } if (!getLangOpts().CPlusPlus) { + // Forget about the nulled arguments since typo correction + // do not handle them well. + TheCall->shrinkNumArgs(Args.size()); // C cannot always handle TypoExpr nodes in builtin calls and direct // function calls as their argument checking don't necessarily handle // dependent types properly, so make sure any TypoExprs have been // dealt with. ExprResult Result = CorrectDelayedTyposInExpr(TheCall); if (!Result.isUsable()) return ExprError(); + CallExpr *TheOldCall = TheCall; TheCall = dyn_cast(Result.get()); + bool CorrectedTypos = TheCall != TheOldCall; if (!TheCall) return Result; - // TheCall at this point has max(Args.size(), NumParams) arguments, - // with extra arguments nulled. We don't want to introduce nulled - // arguments in Args and so we only take the first Args.size() arguments. - Args = llvm::makeArrayRef(TheCall->getArgs(), Args.size()); + Args = llvm::makeArrayRef(TheCall->getArgs(), TheCall->getNumArgs()); + + // A new call expression node was created if some typos were corrected. + // However it may not have been constructed with enough storage. In this + // case, rebuild the node with enough storage. The waste of space is + // immaterial since this only happens when some typos were corrected. + if (CorrectedTypos && Args.size() < NumParams) { + if (Config) + TheCall = CUDAKernelCallExpr::Create( + Context, Fn, cast(Config), Args, ResultTy, VK_RValue, + RParenLoc, NumParams); + else + TheCall = CallExpr::Create(Context, Fn, Args, ResultTy, VK_RValue, + RParenLoc, NumParams, UsesADL); + } + // We can now handle the nulled arguments for the default arguments. + TheCall->setNumArgsUnsafe(std::max(Args.size(), NumParams)); } // Bail out early if calling a builtin with custom type checking. diff --git a/clang/test/Sema/typo-correction.c b/clang/test/Sema/typo-correction.c index e7992ac90bb3d..73ba265509e4c 100644 --- a/clang/test/Sema/typo-correction.c +++ b/clang/test/Sema/typo-correction.c @@ -100,3 +100,18 @@ void rdar38642201_caller() { structVar1.fieldName1.member1, //expected-error{{use of undeclared identifier 'structVar1'}} structVar2.fieldName2.member2); //expected-error{{use of undeclared identifier 'structVar2'}} } + +void PR40286_g(int x, int y); +void PR40286_h(int x, int y, int z); +void PR40286_1(int the_value) { + PR40286_g(the_walue); // expected-error {{use of undeclared identifier 'the_walue'}} +} +void PR40286_2(int the_value) { + PR40286_h(the_value, the_walue); // expected-error {{use of undeclared identifier 'the_walue'}} +} +void PR40286_3(int the_value) { + PR40286_h(the_walue); // expected-error {{use of undeclared identifier 'the_walue'}} +} +void PR40286_4(int the_value) { // expected-note {{'the_value' declared here}} + PR40286_h(the_value, the_value, the_walue); // expected-error {{use of undeclared identifier 'the_walue'; did you mean 'the_value'?}} +} From 07a7439486a3a7afef93d3c02b9430e1d5552832 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 18 Feb 2019 09:33:35 +0000 Subject: [PATCH 140/274] Merging r354147: ------------------------------------------------------------------------ r354147 | jfb | 2019-02-15 18:26:29 +0100 (Fri, 15 Feb 2019) | 27 lines Variable auto-init of blocks capturing self after init bugfix Summary: Blocks that capture themselves (and escape) after initialization currently codegen wrong because this: bool capturedByInit = Init && emission.IsEscapingByRef && isCapturedBy(D, Init); Address Loc = capturedByInit ? emission.Addr : emission.getObjectAddress(*this); Already adjusts Loc from thr alloca to a GEP. This code: if (emission.IsEscapingByRef) Loc = emitBlockByrefAddress(Loc, &D, /*follow=*/false); Was trying to do the same adjustment, and a GEP on a GEP (returning an int) triggers an assertion. Reviewers: ahatanak Subscribers: jkorous, dexonsmith, cfe-commits, rjmccall Tags: #clang Differential Revision: https://reviews.llvm.org/D58218 ------------------------------------------------------------------------ llvm-svn: 354248 --- clang/lib/CodeGen/CGDecl.cpp | 14 ++++----- .../test/CodeGenCXX/trivial-auto-var-init.cpp | 31 ++++++++++++++++--- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index b98657ffd8006..790a8df3d7e41 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1620,8 +1620,9 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { bool capturedByInit = Init && emission.IsEscapingByRef && isCapturedBy(D, Init); - Address Loc = - capturedByInit ? emission.Addr : emission.getObjectAddress(*this); + bool locIsByrefHeader = !capturedByInit; + const Address Loc = + locIsByrefHeader ? emission.getObjectAddress(*this) : emission.Addr; // Note: constexpr already initializes everything correctly. LangOptions::TrivialAutoVarInitKind trivialAutoVarInit = @@ -1637,7 +1638,7 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { return; // Only initialize a __block's storage: we always initialize the header. - if (emission.IsEscapingByRef) + if (emission.IsEscapingByRef && !locIsByrefHeader) Loc = emitBlockByrefAddress(Loc, &D, /*follow=*/false); CharUnits Size = getContext().getTypeSizeInChars(type); @@ -1745,10 +1746,9 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { } llvm::Type *BP = CGM.Int8Ty->getPointerTo(Loc.getAddressSpace()); - if (Loc.getType() != BP) - Loc = Builder.CreateBitCast(Loc, BP); - - emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant); + emitStoresForConstant( + CGM, D, (Loc.getType() == BP) ? Loc : Builder.CreateBitCast(Loc, BP), + isVolatile, Builder, constant); } /// Emit an expression as an initializer for an object (variable, field, etc.) diff --git a/clang/test/CodeGenCXX/trivial-auto-var-init.cpp b/clang/test/CodeGenCXX/trivial-auto-var-init.cpp index 37ff770abf57e..0a9ad86c7e2fe 100644 --- a/clang/test/CodeGenCXX/trivial-auto-var-init.cpp +++ b/clang/test/CodeGenCXX/trivial-auto-var-init.cpp @@ -45,14 +45,35 @@ void test_block() { // PATTERN: %captured1 = getelementptr inbounds %struct.__block_byref_captured, %struct.__block_byref_captured* %captured, i32 0, i32 4 // PATTERN-NEXT: store %struct.XYZ* inttoptr (i64 -6148914691236517206 to %struct.XYZ*), %struct.XYZ** %captured1, align 8 // PATTERN: %call = call %struct.XYZ* @create( +using Block = void (^)(); +typedef struct XYZ { + Block block; +} * xyz_t; void test_block_self_init() { - using Block = void (^)(); - typedef struct XYZ { - Block block; - } * xyz_t; extern xyz_t create(Block block); __block xyz_t captured = create(^() { - (void)captured; + used(captured); + }); +} + +// Capturing with escape after initialization is also an edge case. +// +// UNINIT-LABEL: test_block_captures_self_after_init( +// ZERO-LABEL: test_block_captures_self_after_init( +// ZERO: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8 +// ZERO: %captured1 = getelementptr inbounds %struct.__block_byref_captured.1, %struct.__block_byref_captured.1* %captured, i32 0, i32 4 +// ZERO-NEXT: store %struct.XYZ* null, %struct.XYZ** %captured1, align 8 +// ZERO: %call = call %struct.XYZ* @create( +// PATTERN-LABEL: test_block_captures_self_after_init( +// PATTERN: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8 +// PATTERN: %captured1 = getelementptr inbounds %struct.__block_byref_captured.1, %struct.__block_byref_captured.1* %captured, i32 0, i32 4 +// PATTERN-NEXT: store %struct.XYZ* inttoptr (i64 -6148914691236517206 to %struct.XYZ*), %struct.XYZ** %captured1, align 8 +// PATTERN: %call = call %struct.XYZ* @create( +void test_block_captures_self_after_init() { + extern xyz_t create(Block block); + __block xyz_t captured; + captured = create(^() { + used(captured); }); } From 25c79d978447cd53224884d1acbe6274578854d0 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 18 Feb 2019 09:56:01 +0000 Subject: [PATCH 141/274] Merging r354128 and r354131: ------------------------------------------------------------------------ r354128 | courbet | 2019-02-15 13:58:06 +0100 (Fri, 15 Feb 2019) | 1 line [MergeICmps][NFC] Improve doc. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r354131 | courbet | 2019-02-15 15:17:17 +0100 (Fri, 15 Feb 2019) | 15 lines [MergeICmps] Make base ordering really deterministic. Summary: The idea is that we now manipulate bases through a `unsigned BaseID` based on order of appearance in the comparison chain rather than through the `Value*`. Fixes 40714. Reviewers: gchatelet Subscribers: mgrang, jfb, jdoerfert, llvm-commits, hans Tags: #llvm Differential Revision: https://reviews.llvm.org/D58274 ------------------------------------------------------------------------ llvm-svn: 354249 --- llvm/lib/Transforms/Scalar/MergeICmps.cpp | 227 +++++++++++++--------- 1 file changed, 135 insertions(+), 92 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/MergeICmps.cpp b/llvm/lib/Transforms/Scalar/MergeICmps.cpp index 69fd8b163a070..a24fee54949d3 100644 --- a/llvm/lib/Transforms/Scalar/MergeICmps.cpp +++ b/llvm/lib/Transforms/Scalar/MergeICmps.cpp @@ -11,21 +11,37 @@ // later typically inlined as a chain of efficient hardware comparisons). This // typically benefits c++ member or nonmember operator==(). // -// The basic idea is to replace a larger chain of integer comparisons loaded -// from contiguous memory locations into a smaller chain of such integer +// The basic idea is to replace a longer chain of integer comparisons loaded +// from contiguous memory locations into a shorter chain of larger integer // comparisons. Benefits are double: // - There are less jumps, and therefore less opportunities for mispredictions // and I-cache misses. // - Code size is smaller, both because jumps are removed and because the // encoding of a 2*n byte compare is smaller than that of two n-byte // compares. - +// +// Example: +// +// struct S { +// int a; +// char b; +// char c; +// uint16_t d; +// bool operator==(const S& o) const { +// return a == o.a && b == o.b && c == o.c && d == o.d; +// } +// }; +// +// Is optimized as : +// +// bool S::operator==(const S& o) const { +// return memcmp(this, &o, 8) == 0; +// } +// +// Which will later be expanded (ExpandMemCmp) as a single 8-bytes icmp. +// //===----------------------------------------------------------------------===// -#include -#include -#include -#include #include "llvm/Analysis/Loads.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" @@ -34,6 +50,10 @@ #include "llvm/Pass.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/BuildLibCalls.h" +#include +#include +#include +#include using namespace llvm; @@ -50,76 +70,95 @@ static bool isSimpleLoadOrStore(const Instruction *I) { return false; } -// A BCE atom. +// A BCE atom "Binary Compare Expression Atom" represents an integer load +// that is a constant offset from a base value, e.g. `a` or `o.c` in the example +// at the top. struct BCEAtom { - BCEAtom() : GEP(nullptr), LoadI(nullptr), Offset() {} - - const Value *Base() const { return GEP ? GEP->getPointerOperand() : nullptr; } - + BCEAtom() = default; + BCEAtom(GetElementPtrInst *GEP, LoadInst *LoadI, int BaseId, APInt Offset) + : GEP(GEP), LoadI(LoadI), BaseId(BaseId), Offset(Offset) {} + + // We want to order BCEAtoms by (Base, Offset). However we cannot use + // the pointer values for Base because these are non-deterministic. + // To make sure that the sort order is stable, we first assign to each atom + // base value an index based on its order of appearance in the chain of + // comparisons. We call this index `BaseOrdering`. For example, for: + // b[3] == c[2] && a[1] == d[1] && b[4] == c[3] + // | block 1 | | block 2 | | block 3 | + // b gets assigned index 0 and a index 1, because b appears as LHS in block 1, + // which is before block 2. + // We then sort by (BaseOrdering[LHS.Base()], LHS.Offset), which is stable. bool operator<(const BCEAtom &O) const { - assert(Base() && "invalid atom"); - assert(O.Base() && "invalid atom"); - // Just ordering by (Base(), Offset) is sufficient. However because this - // means that the ordering will depend on the addresses of the base - // values, which are not reproducible from run to run. To guarantee - // stability, we use the names of the values if they exist; we sort by: - // (Base.getName(), Base(), Offset). - const int NameCmp = Base()->getName().compare(O.Base()->getName()); - if (NameCmp == 0) { - if (Base() == O.Base()) { - return Offset.slt(O.Offset); - } - return Base() < O.Base(); - } - return NameCmp < 0; + return BaseId != O.BaseId ? BaseId < O.BaseId : Offset.slt(O.Offset); } - GetElementPtrInst *GEP; - LoadInst *LoadI; + GetElementPtrInst *GEP = nullptr; + LoadInst *LoadI = nullptr; + unsigned BaseId = 0; APInt Offset; }; +// A class that assigns increasing ids to values in the order in which they are +// seen. See comment in `BCEAtom::operator<()``. +class BaseIdentifier { +public: + // Returns the id for value `Base`, after assigning one if `Base` has not been + // seen before. + int getBaseId(const Value *Base) { + assert(Base && "invalid base"); + const auto Insertion = BaseToIndex.try_emplace(Base, Order); + if (Insertion.second) + ++Order; + return Insertion.first->second; + } + +private: + unsigned Order = 1; + DenseMap BaseToIndex; +}; + // If this value is a load from a constant offset w.r.t. a base address, and // there are no other users of the load or address, returns the base address and // the offset. -BCEAtom visitICmpLoadOperand(Value *const Val) { - BCEAtom Result; - if (auto *const LoadI = dyn_cast(Val)) { - LLVM_DEBUG(dbgs() << "load\n"); - if (LoadI->isUsedOutsideOfBlock(LoadI->getParent())) { - LLVM_DEBUG(dbgs() << "used outside of block\n"); - return {}; - } - // Do not optimize atomic loads to non-atomic memcmp - if (!LoadI->isSimple()) { - LLVM_DEBUG(dbgs() << "volatile or atomic\n"); - return {}; - } - Value *const Addr = LoadI->getOperand(0); - if (auto *const GEP = dyn_cast(Addr)) { - LLVM_DEBUG(dbgs() << "GEP\n"); - if (GEP->isUsedOutsideOfBlock(LoadI->getParent())) { - LLVM_DEBUG(dbgs() << "used outside of block\n"); - return {}; - } - const auto &DL = GEP->getModule()->getDataLayout(); - if (!isDereferenceablePointer(GEP, DL)) { - LLVM_DEBUG(dbgs() << "not dereferenceable\n"); - // We need to make sure that we can do comparison in any order, so we - // require memory to be unconditionnally dereferencable. - return {}; - } - Result.Offset = APInt(DL.getPointerTypeSizeInBits(GEP->getType()), 0); - if (GEP->accumulateConstantOffset(DL, Result.Offset)) { - Result.GEP = GEP; - Result.LoadI = LoadI; - } - } +BCEAtom visitICmpLoadOperand(Value *const Val, BaseIdentifier &BaseId) { + auto *const LoadI = dyn_cast(Val); + if (!LoadI) + return {}; + LLVM_DEBUG(dbgs() << "load\n"); + if (LoadI->isUsedOutsideOfBlock(LoadI->getParent())) { + LLVM_DEBUG(dbgs() << "used outside of block\n"); + return {}; + } + // Do not optimize atomic loads to non-atomic memcmp + if (!LoadI->isSimple()) { + LLVM_DEBUG(dbgs() << "volatile or atomic\n"); + return {}; } - return Result; + Value *const Addr = LoadI->getOperand(0); + auto *const GEP = dyn_cast(Addr); + if (!GEP) + return {}; + LLVM_DEBUG(dbgs() << "GEP\n"); + if (GEP->isUsedOutsideOfBlock(LoadI->getParent())) { + LLVM_DEBUG(dbgs() << "used outside of block\n"); + return {}; + } + const auto &DL = GEP->getModule()->getDataLayout(); + if (!isDereferenceablePointer(GEP, DL)) { + LLVM_DEBUG(dbgs() << "not dereferenceable\n"); + // We need to make sure that we can do comparison in any order, so we + // require memory to be unconditionnally dereferencable. + return {}; + } + APInt Offset = APInt(DL.getPointerTypeSizeInBits(GEP->getType()), 0); + if (!GEP->accumulateConstantOffset(DL, Offset)) + return {}; + return BCEAtom(GEP, LoadI, BaseId.getBaseId(GEP->getPointerOperand()), + Offset); } -// A basic block with a comparison between two BCE atoms. +// A basic block with a comparison between two BCE atoms, e.g. `a == o.a` in the +// example at the top. // The block might do extra work besides the atom comparison, in which case // doesOtherWork() returns true. Under some conditions, the block can be // split into the atom comparison part and the "other work" part @@ -137,9 +176,7 @@ class BCECmpBlock { if (Rhs_ < Lhs_) std::swap(Rhs_, Lhs_); } - bool IsValid() const { - return Lhs_.Base() != nullptr && Rhs_.Base() != nullptr; - } + bool IsValid() const { return Lhs_.BaseId != 0 && Rhs_.BaseId != 0; } // Assert the block is consistent: If valid, it should also have // non-null members besides Lhs_ and Rhs_. @@ -265,7 +302,8 @@ bool BCECmpBlock::doesOtherWork() const { // Visit the given comparison. If this is a comparison between two valid // BCE atoms, returns the comparison. BCECmpBlock visitICmp(const ICmpInst *const CmpI, - const ICmpInst::Predicate ExpectedPredicate) { + const ICmpInst::Predicate ExpectedPredicate, + BaseIdentifier &BaseId) { // The comparison can only be used once: // - For intermediate blocks, as a branch condition. // - For the final block, as an incoming value for the Phi. @@ -275,25 +313,27 @@ BCECmpBlock visitICmp(const ICmpInst *const CmpI, LLVM_DEBUG(dbgs() << "cmp has several uses\n"); return {}; } - if (CmpI->getPredicate() == ExpectedPredicate) { - LLVM_DEBUG(dbgs() << "cmp " - << (ExpectedPredicate == ICmpInst::ICMP_EQ ? "eq" : "ne") - << "\n"); - auto Lhs = visitICmpLoadOperand(CmpI->getOperand(0)); - if (!Lhs.Base()) return {}; - auto Rhs = visitICmpLoadOperand(CmpI->getOperand(1)); - if (!Rhs.Base()) return {}; - const auto &DL = CmpI->getModule()->getDataLayout(); - return BCECmpBlock(std::move(Lhs), std::move(Rhs), - DL.getTypeSizeInBits(CmpI->getOperand(0)->getType())); - } - return {}; + if (CmpI->getPredicate() != ExpectedPredicate) + return {}; + LLVM_DEBUG(dbgs() << "cmp " + << (ExpectedPredicate == ICmpInst::ICMP_EQ ? "eq" : "ne") + << "\n"); + auto Lhs = visitICmpLoadOperand(CmpI->getOperand(0), BaseId); + if (!Lhs.BaseId) + return {}; + auto Rhs = visitICmpLoadOperand(CmpI->getOperand(1), BaseId); + if (!Rhs.BaseId) + return {}; + const auto &DL = CmpI->getModule()->getDataLayout(); + return BCECmpBlock(std::move(Lhs), std::move(Rhs), + DL.getTypeSizeInBits(CmpI->getOperand(0)->getType())); } // Visit the given comparison block. If this is a comparison between two valid // BCE atoms, returns the comparison. BCECmpBlock visitCmpBlock(Value *const Val, BasicBlock *const Block, - const BasicBlock *const PhiBlock) { + const BasicBlock *const PhiBlock, + BaseIdentifier &BaseId) { if (Block->empty()) return {}; auto *const BranchI = dyn_cast(Block->getTerminator()); if (!BranchI) return {}; @@ -306,7 +346,7 @@ BCECmpBlock visitCmpBlock(Value *const Val, BasicBlock *const Block, auto *const CmpI = dyn_cast(Val); if (!CmpI) return {}; LLVM_DEBUG(dbgs() << "icmp\n"); - auto Result = visitICmp(CmpI, ICmpInst::ICMP_EQ); + auto Result = visitICmp(CmpI, ICmpInst::ICMP_EQ, BaseId); Result.CmpI = CmpI; Result.BranchI = BranchI; return Result; @@ -323,7 +363,8 @@ BCECmpBlock visitCmpBlock(Value *const Val, BasicBlock *const Block, assert(BranchI->getNumSuccessors() == 2 && "expecting a cond branch"); BasicBlock *const FalseBlock = BranchI->getSuccessor(1); auto Result = visitICmp( - CmpI, FalseBlock == PhiBlock ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE); + CmpI, FalseBlock == PhiBlock ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE, + BaseId); Result.CmpI = CmpI; Result.BranchI = BranchI; return Result; @@ -335,9 +376,9 @@ static inline void enqueueBlock(std::vector &Comparisons, BCECmpBlock &Comparison) { LLVM_DEBUG(dbgs() << "Block '" << Comparison.BB->getName() << "': Found cmp of " << Comparison.SizeBits() - << " bits between " << Comparison.Lhs().Base() << " + " + << " bits between " << Comparison.Lhs().BaseId << " + " << Comparison.Lhs().Offset << " and " - << Comparison.Rhs().Base() << " + " + << Comparison.Rhs().BaseId << " + " << Comparison.Rhs().Offset << "\n"); LLVM_DEBUG(dbgs() << "\n"); Comparisons.push_back(Comparison); @@ -360,8 +401,8 @@ class BCECmpChain { private: static bool IsContiguous(const BCECmpBlock &First, const BCECmpBlock &Second) { - return First.Lhs().Base() == Second.Lhs().Base() && - First.Rhs().Base() == Second.Rhs().Base() && + return First.Lhs().BaseId == Second.Lhs().BaseId && + First.Rhs().BaseId == Second.Rhs().BaseId && First.Lhs().Offset + First.SizeBits() / 8 == Second.Lhs().Offset && First.Rhs().Offset + First.SizeBits() / 8 == Second.Rhs().Offset; } @@ -385,11 +426,12 @@ BCECmpChain::BCECmpChain(const std::vector &Blocks, PHINode &Phi, assert(!Blocks.empty() && "a chain should have at least one block"); // Now look inside blocks to check for BCE comparisons. std::vector Comparisons; + BaseIdentifier BaseId; for (size_t BlockIdx = 0; BlockIdx < Blocks.size(); ++BlockIdx) { BasicBlock *const Block = Blocks[BlockIdx]; assert(Block && "invalid block"); BCECmpBlock Comparison = visitCmpBlock(Phi.getIncomingValueForBlock(Block), - Block, Phi.getParent()); + Block, Phi.getParent(), BaseId); Comparison.BB = Block; if (!Comparison.IsValid()) { LLVM_DEBUG(dbgs() << "chain with invalid BCECmpBlock, no merge.\n"); @@ -466,9 +508,10 @@ BCECmpChain::BCECmpChain(const std::vector &Blocks, PHINode &Phi, #endif // MERGEICMPS_DOT_ON // Reorder blocks by LHS. We can do that without changing the // semantics because we are only accessing dereferencable memory. - llvm::sort(Comparisons_, [](const BCECmpBlock &a, const BCECmpBlock &b) { - return a.Lhs() < b.Lhs(); - }); + llvm::sort(Comparisons_, + [](const BCECmpBlock &LhsBlock, const BCECmpBlock &RhsBlock) { + return LhsBlock.Lhs() < RhsBlock.Lhs(); + }); #ifdef MERGEICMPS_DOT_ON errs() << "AFTER REORDERING:\n\n"; dump(); From 783fd931b518135bebc62c72aef4828c884523bf Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 18 Feb 2019 10:23:16 +0000 Subject: [PATCH 142/274] Merging r354144: ------------------------------------------------------------------------ r354144 | spatel | 2019-02-15 17:31:55 +0100 (Fri, 15 Feb 2019) | 3 lines [InstCombine] fix crash while trying to narrow a binop of shuffles (PR40734) https://bugs.llvm.org/show_bug.cgi?id=40734 ------------------------------------------------------------------------ llvm-svn: 354252 --- .../InstCombine/InstructionCombining.cpp | 3 ++- llvm/test/Transforms/InstCombine/vec_shuffle.ll | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index f530ee1246e8c..fef051aa1b7c3 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1376,7 +1376,8 @@ Instruction *InstCombiner::foldVectorBinop(BinaryOperator &Inst) { if (match(LHS, m_ShuffleVector(m_Value(L0), m_Value(L1), m_Constant(Mask))) && match(RHS, m_ShuffleVector(m_Value(R0), m_Value(R1), m_Specific(Mask))) && LHS->hasOneUse() && RHS->hasOneUse() && - cast(LHS)->isConcat()) { + cast(LHS)->isConcat() && + cast(RHS)->isConcat()) { // This transform does not have the speculative execution constraint as // below because the shuffle is a concatenation. The new binops are // operating on exactly the same elements as the existing binop. diff --git a/llvm/test/Transforms/InstCombine/vec_shuffle.ll b/llvm/test/Transforms/InstCombine/vec_shuffle.ll index b82c8117eebf5..8f6818f4eb79d 100644 --- a/llvm/test/Transforms/InstCombine/vec_shuffle.ll +++ b/llvm/test/Transforms/InstCombine/vec_shuffle.ll @@ -1114,3 +1114,18 @@ define <2 x float> @frem_splat_constant1(<2 x float> %x) { ret <2 x float> %r } +; Equivalent shuffle masks, but only one is a narrowing op. + +define <2 x i1> @PR40734(<1 x i1> %x, <4 x i1> %y) { +; CHECK-LABEL: @PR40734( +; CHECK-NEXT: [[WIDEN:%.*]] = shufflevector <1 x i1> zeroinitializer, <1 x i1> [[X:%.*]], <2 x i32> +; CHECK-NEXT: [[NARROW:%.*]] = shufflevector <4 x i1> [[Y:%.*]], <4 x i1> undef, <2 x i32> +; CHECK-NEXT: [[R:%.*]] = and <2 x i1> [[WIDEN]], [[NARROW]] +; CHECK-NEXT: ret <2 x i1> [[R]] +; + %widen = shufflevector <1 x i1> zeroinitializer, <1 x i1> %x, <2 x i32> + %narrow = shufflevector <4 x i1> %y, <4 x i1> undef, <2 x i32> + %r = and <2 x i1> %widen, %narrow + ret <2 x i1> %r +} + From 46fbca3530b2052985f2461e3579a60320944f79 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 18 Feb 2019 10:25:29 +0000 Subject: [PATCH 143/274] Merging r353642: ------------------------------------------------------------------------ r353642 | teemperor | 2019-02-10 16:23:58 +0100 (Sun, 10 Feb 2019) | 13 lines lldb: Fix compilation on OpenBSD Summary: Update the OpenBSD Host.cpp for the new SetFile() function signature. Fixes compiling lldb on OpenBSD. Reviewers: krytarowski Reviewed By: krytarowski Subscribers: lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D57907 ------------------------------------------------------------------------ llvm-svn: 354253 --- lldb/source/Host/openbsd/Host.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lldb/source/Host/openbsd/Host.cpp b/lldb/source/Host/openbsd/Host.cpp index cba1f4ee6b7cb..8db0498d14b56 100644 --- a/lldb/source/Host/openbsd/Host.cpp +++ b/lldb/source/Host/openbsd/Host.cpp @@ -68,8 +68,7 @@ GetOpenBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr, cstr = data.GetCStr(&offset); if (cstr) { - process_info.GetExecutableFile().SetFile(cstr, false, - FileSpec::Style::native); + process_info.GetExecutableFile().SetFile(cstr, FileSpec::Style::native); if (!(match_info_ptr == NULL || NameMatches( From 096ef4c9f2ecb0b17df61c48d6601d32f9eaeeef Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 18 Feb 2019 10:30:57 +0000 Subject: [PATCH 144/274] Merging r354029: ------------------------------------------------------------------------ r354029 | mgorny | 2019-02-14 14:52:31 +0100 (Thu, 14 Feb 2019) | 7 lines [lldb] [MainLoop] Report errno for failed kevent() Modify the kevent() error reporting to use errno rather than returning the return value. At least on FreeBSD and NetBSD, kevent() always returns -1 in case of error, and the actual error is returned via errno. Differential Revision: https://reviews.llvm.org/D58229 ------------------------------------------------------------------------ llvm-svn: 354254 --- lldb/source/Host/common/MainLoop.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Host/common/MainLoop.cpp b/lldb/source/Host/common/MainLoop.cpp index 39c353e6717ec..2887feb3e2645 100644 --- a/lldb/source/Host/common/MainLoop.cpp +++ b/lldb/source/Host/common/MainLoop.cpp @@ -109,7 +109,7 @@ Status MainLoop::RunImpl::Poll() { out_events, llvm::array_lengthof(out_events), nullptr); if (num_events < 0) - return Status("kevent() failed with error %d\n", num_events); + return Status(errno, eErrorTypePOSIX); return Status(); } From 81bd9dbdab9b0f514339927cd33ca105956d7dfe Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 18 Feb 2019 10:31:46 +0000 Subject: [PATCH 145/274] Merging r354122: ------------------------------------------------------------------------ r354122 | mgorny | 2019-02-15 13:13:02 +0100 (Fri, 15 Feb 2019) | 10 lines [lldb] [MainLoop] Add kevent() EINTR handling Add missing EINTR handling for kevent() calls. If the call is interrupted, return from Poll() as if zero events were returned and let the polling resume on next iteration. This fixes test flakiness on NetBSD. Includes a test case suggested by Pavel Labath on D42206. Differential Revision: https://reviews.llvm.org/D58230 ------------------------------------------------------------------------ llvm-svn: 354255 --- lldb/source/Host/common/MainLoop.cpp | 10 ++++++++-- lldb/unittests/Host/MainLoopTest.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/lldb/source/Host/common/MainLoop.cpp b/lldb/source/Host/common/MainLoop.cpp index 2887feb3e2645..337ddd51dd6b9 100644 --- a/lldb/source/Host/common/MainLoop.cpp +++ b/lldb/source/Host/common/MainLoop.cpp @@ -108,8 +108,14 @@ Status MainLoop::RunImpl::Poll() { num_events = kevent(loop.m_kqueue, in_events.data(), in_events.size(), out_events, llvm::array_lengthof(out_events), nullptr); - if (num_events < 0) - return Status(errno, eErrorTypePOSIX); + if (num_events < 0) { + if (errno == EINTR) { + // in case of EINTR, let the main loop run one iteration + // we need to zero num_events to avoid assertions failing + num_events = 0; + } else + return Status(errno, eErrorTypePOSIX); + } return Status(); } diff --git a/lldb/unittests/Host/MainLoopTest.cpp b/lldb/unittests/Host/MainLoopTest.cpp index 8f2c55c2416df..6b7a5cf1f55de 100644 --- a/lldb/unittests/Host/MainLoopTest.cpp +++ b/lldb/unittests/Host/MainLoopTest.cpp @@ -137,4 +137,28 @@ TEST_F(MainLoopTest, Signal) { ASSERT_TRUE(loop.Run().Success()); ASSERT_EQ(1u, callback_count); } + +// Test that a signal which is not monitored by the MainLoop does not +// cause a premature exit. +TEST_F(MainLoopTest, UnmonitoredSignal) { + MainLoop loop; + Status error; + struct sigaction sa; + sa.sa_sigaction = [](int, siginfo_t *, void *) { }; + sa.sa_flags = SA_SIGINFO; // important: no SA_RESTART + sigemptyset(&sa.sa_mask); + ASSERT_EQ(0, sigaction(SIGUSR2, &sa, nullptr)); + + auto handle = loop.RegisterSignal(SIGUSR1, make_callback(), error); + ASSERT_TRUE(error.Success()); + std::thread killer([]() { + sleep(1); + kill(getpid(), SIGUSR2); + sleep(1); + kill(getpid(), SIGUSR1); + }); + ASSERT_TRUE(loop.Run().Success()); + killer.join(); + ASSERT_EQ(1u, callback_count); +} #endif From 60514070986e558b264f9174249da70728b421a1 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 18 Feb 2019 10:39:35 +0000 Subject: [PATCH 146/274] Merging r353907: ------------------------------------------------------------------------ r353907 | rnk | 2019-02-13 02:39:32 +0100 (Wed, 13 Feb 2019) | 6 lines [MC] Make symbol version errors non-fatal We stil don't have a source location, which is pretty lame, but at least we won't tell the user to file a clang bug report anymore. Fixes PR40712 ------------------------------------------------------------------------ llvm-svn: 354257 --- llvm/lib/MC/ELFObjectWriter.cpp | 18 ++++++++++++------ llvm/test/MC/ELF/invalid-symver.s | 2 +- llvm/test/MC/ELF/multiple-different-symver.s | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index 89f3b30cddd6f..ade858113a300 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -1275,14 +1275,20 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, if (!Symbol.isUndefined() && !Rest.startswith("@@@")) continue; - // FIXME: produce a better error message. + // FIXME: Get source locations for these errors or diagnose them earlier. if (Symbol.isUndefined() && Rest.startswith("@@") && - !Rest.startswith("@@@")) - report_fatal_error("A @@ version cannot be undefined"); + !Rest.startswith("@@@")) { + Asm.getContext().reportError(SMLoc(), "versioned symbol " + AliasName + + " must be defined"); + continue; + } - if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) - report_fatal_error(llvm::Twine("Multiple symbol versions defined for ") + - Symbol.getName()); + if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) { + Asm.getContext().reportError( + SMLoc(), llvm::Twine("multiple symbol versions defined for ") + + Symbol.getName()); + continue; + } Renames.insert(std::make_pair(&Symbol, Alias)); } diff --git a/llvm/test/MC/ELF/invalid-symver.s b/llvm/test/MC/ELF/invalid-symver.s index 3c4f8c084b94b..d9f97b102b579 100644 --- a/llvm/test/MC/ELF/invalid-symver.s +++ b/llvm/test/MC/ELF/invalid-symver.s @@ -1,7 +1,7 @@ // RUN: not llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t 2> %t.out // RUN: FileCheck --input-file=%t.out %s -// CHECK: A @@ version cannot be undefined +// CHECK: error: versioned symbol foo@@bar must be defined .symver undefined, foo@@bar .long undefined diff --git a/llvm/test/MC/ELF/multiple-different-symver.s b/llvm/test/MC/ELF/multiple-different-symver.s index d7706f89f4198..c34626c08173c 100644 --- a/llvm/test/MC/ELF/multiple-different-symver.s +++ b/llvm/test/MC/ELF/multiple-different-symver.s @@ -1,6 +1,6 @@ // RUN: not llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t 2>&1 | FileCheck %s -// CHECK: Multiple symbol versions defined for foo +// CHECK: error: multiple symbol versions defined for foo .symver foo, foo@1 .symver foo, foo@2 From cc3d3f1f0762c8d9bee54748d840669db4654690 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 18 Feb 2019 11:21:42 +0000 Subject: [PATCH 147/274] Merging r354034 and r354117: ------------------------------------------------------------------------ r354034 | rksimon | 2019-02-14 15:45:32 +0100 (Thu, 14 Feb 2019) | 1 line [X86][AVX] Add PR40730 test case ------------------------------------------------------------------------ ------------------------------------------------------------------------ r354117 | rksimon | 2019-02-15 12:39:21 +0100 (Fri, 15 Feb 2019) | 9 lines [X86][AVX] lowerShuffleAsLanePermuteAndPermute - fully populate the lane shuffle mask (PR40730) As detailed on PR40730, we are not correctly filling in the lane shuffle mask (D53148/rL344446) - we fill in for the correct src lane but don't add it to the correct mask element, so any reference to the correct element is likely to see an UNDEF mask index. This allows constant folding to propagate UNDEFs prior to the lane mask being (correctly) lowered to vperm2f128. This patch fixes the issue by fully populating the lane shuffle mask - this is more than is necessary (if we only filled in the required mask elements we might be able to match other shuffle instructions - broadcasts etc.), but its the most cautious approach as this needs to be cherrypicked into the 8.0.0 release branch. Differential Revision: https://reviews.llvm.org/D58237 ------------------------------------------------------------------------ llvm-svn: 354260 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 13 +++++++-- llvm/test/CodeGen/X86/pr40730.ll | 36 +++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/X86/pr40730.ll diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index f4f37a894620e..e1a6d22f06165 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -13884,7 +13884,6 @@ static SDValue lowerVectorShuffleAsLanePermuteAndPermute( int NumEltsPerLane = NumElts / NumLanes; SmallVector SrcLaneMask(NumLanes, SM_SentinelUndef); - SmallVector LaneMask(NumElts, SM_SentinelUndef); SmallVector PermMask(NumElts, SM_SentinelUndef); for (int i = 0; i != NumElts; ++i) { @@ -13899,10 +13898,20 @@ static SDValue lowerVectorShuffleAsLanePermuteAndPermute( return SDValue(); SrcLaneMask[DstLane] = SrcLane; - LaneMask[i] = (SrcLane * NumEltsPerLane) + (i % NumEltsPerLane); PermMask[i] = (DstLane * NumEltsPerLane) + (M % NumEltsPerLane); } + // Make sure we set all elements of the lane mask, to avoid undef propagation. + SmallVector LaneMask(NumElts, SM_SentinelUndef); + for (int DstLane = 0; DstLane != NumLanes; ++DstLane) { + int SrcLane = SrcLaneMask[DstLane]; + if (0 <= SrcLane) + for (int j = 0; j != NumEltsPerLane; ++j) { + LaneMask[(DstLane * NumEltsPerLane) + j] = + (SrcLane * NumEltsPerLane) + j; + } + } + // If we're only shuffling a single lowest lane and the rest are identity // then don't bother. // TODO - isShuffleMaskInputInPlace could be extended to something like this. diff --git a/llvm/test/CodeGen/X86/pr40730.ll b/llvm/test/CodeGen/X86/pr40730.ll new file mode 100644 index 0000000000000..12b372dea33bb --- /dev/null +++ b/llvm/test/CodeGen/X86/pr40730.ll @@ -0,0 +1,36 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s + +define <8 x i32> @shuffle_v8i32_0dcd3f14(<8 x i32> %a, <8 x i32> %b) { +; CHECK-LABEL: shuffle_v8i32_0dcd3f14: +; CHECK: # %bb.0: +; CHECK-NEXT: vextractf128 $1, %ymm0, %xmm2 +; CHECK-NEXT: vblendps {{.*#+}} xmm2 = xmm2[0],xmm0[1,2,3] +; CHECK-NEXT: vpermilps {{.*#+}} xmm2 = xmm2[3,1,1,0] +; CHECK-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0 +; CHECK-NEXT: vperm2f128 {{.*#+}} ymm1 = ymm1[2,3,2,3] +; CHECK-NEXT: vpermilpd {{.*#+}} ymm1 = ymm1[0,0,3,2] +; CHECK-NEXT: vblendps {{.*#+}} ymm0 = ymm0[0],ymm1[1,2,3],ymm0[4],ymm1[5],ymm0[6,7] +; CHECK-NEXT: retq + %shuffle = shufflevector <8 x i32> %a, <8 x i32> %b, <8 x i32> + ret <8 x i32> %shuffle +} + +; CHECK: .LCPI1_0: +; CHECK-NEXT: .quad 60129542157 +; CHECK-NEXT: .quad 60129542157 +; CHECK-NEXT: .quad 68719476736 +; CHECK-NEXT: .quad 60129542157 + +define <8 x i32> @shuffle_v8i32_0dcd3f14_constant(<8 x i32> %a0) { +; CHECK-LABEL: shuffle_v8i32_0dcd3f14_constant: +; CHECK: # %bb.0: +; CHECK-NEXT: vextractf128 $1, %ymm0, %xmm1 +; CHECK-NEXT: vblendps {{.*#+}} xmm1 = xmm1[0],xmm0[1,2,3] +; CHECK-NEXT: vpermilps {{.*#+}} xmm1 = xmm1[3,1,1,0] +; CHECK-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 +; CHECK-NEXT: vblendps {{.*#+}} ymm0 = ymm0[0],mem[1,2,3],ymm0[4],mem[5],ymm0[6,7] +; CHECK-NEXT: retq + %res = shufflevector <8 x i32> %a0, <8 x i32> , <8 x i32> + ret <8 x i32> %res +} From e3d91da768ac1ae40b2059471676ef3574aa2a1a Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 18 Feb 2019 17:59:47 +0000 Subject: [PATCH 148/274] [ReleaseNotes] Add note about removal of Nios2 backend. Add some notes on X86 changes. llvm-svn: 354281 --- llvm/docs/ReleaseNotes.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 9e2ee95c65194..7129b69c9a648 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -134,6 +134,18 @@ Changes to the X86 Target * Machine model for AMD bdver2 (Piledriver) CPU was added. It is used to support instruction scheduling and other instruction cost heuristics. +* New AVX512F gather and scatter intrinsics were added that take a mask + instead of a scalar integer. This removes the need for a bitcast in IR. The + new intrinsics are named like the old intrinsics with ``llvm.avx512.`` + replaced with ``llvm.avx512.mask.``. The old intrinsics will be removed in a + future release. + +* Added ``cascadelake`` as a CPU name for -march. This is ``skylake-avx512`` + with the addition of the ``avx512vnni`` instruction set. + +* ADCX instruction will no longer be emitted. This instruction is rarely better + than the legacy ADC instruction and just increased code size. + Changes to the AMDGPU Target ----------------------------- @@ -156,6 +168,10 @@ use for it will be to add support for returning small structs as multiple return values, once the underlying WebAssembly platform itself supports it. Additionally, multithreading support is not yet included in the stable ABI. +Changes to the Nios2 Target +--------------------------- + +* The Nios2 target was removed from this release. Changes to the OCaml bindings ----------------------------- From 79a42b61791952bf5ff7e5e2eaa32402ac65d06f Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 19 Feb 2019 13:14:28 +0000 Subject: [PATCH 149/274] docs: Remove in-progress warning llvm-svn: 354320 --- llvm/docs/ReleaseNotes.rst | 45 ++++++++++++++++++-------------------- llvm/docs/index.rst | 5 ----- 2 files changed, 21 insertions(+), 29 deletions(-) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 7129b69c9a648..5de898cd77950 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -5,12 +5,6 @@ LLVM 8.0.0 Release Notes .. contents:: :local: -.. warning:: - These are in-progress notes for the upcoming LLVM 8 release. - Release notes for previous releases can be found on - `the Download Page `_. - - Introduction ============ @@ -31,6 +25,25 @@ LLVM web page, this document applies to the *next* release, not the current one. To see the release notes for a specific release, please see the `releases page `_. +Minimum Required Compiler Version +================================= +As `discussed on the mailing list +`_, +building LLVM will soon require more recent toolchains as follows: + +============= ==== +Clang 3.5 +Apple Clang 6.0 +GCC 5.1 +Visual Studio 2017 +============= ==== + +A new CMake check when configuring LLVM provides a soft-error if your +toolchain will become unsupported soon. You can opt out of the soft-error by +setting the ``LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN`` CMake variable to +``ON``. + + Non-comprehensive list of changes in this release ================================================= .. NOTE @@ -40,27 +53,11 @@ Non-comprehensive list of changes in this release functionality, or simply have a lot to talk about), see the `NOTE` below for adding a new subsection. -* As `discussed on the mailing list - `_, - building LLVM will soon require more recent toolchains as follows: - - ============= ==== - Clang 3.5 - Apple Clang 6.0 - GCC 5.1 - Visual Studio 2017 - ============= ==== - - A new CMake check when configuring LLVM provides a soft-error if your - toolchain will become unsupported soon. You can opt out of the soft-error by - setting the ``LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN`` CMake variable to - ``ON``. - * The **llvm-cov** tool can now export lcov trace files using the `-format=lcov` option of the `export` command. -* The add_llvm_loadable_module CMake macro has been removed. The - add_llvm_library macro with the MODULE argument now provides the same +* The ``add_llvm_loadable_module`` CMake macro has been removed. The + ``add_llvm_library`` macro with the ``MODULE`` argument now provides the same functionality. See `Writing an LLVM Pass `_. diff --git a/llvm/docs/index.rst b/llvm/docs/index.rst index 4527fe5105346..49bd327f47dec 100644 --- a/llvm/docs/index.rst +++ b/llvm/docs/index.rst @@ -1,11 +1,6 @@ Overview ======== -.. warning:: - - If you are using a released version of LLVM, see `the download page - `_ to find your documentation. - The LLVM compiler infrastructure supports a wide range of projects, from industrial strength compilers to specialized JIT applications to small research projects. From 81717ef7132c92ef47db5e7c81dc6dc81ebac982 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 19 Feb 2019 13:19:05 +0000 Subject: [PATCH 150/274] remove another in-progress note llvm-svn: 354321 --- llvm/docs/ReleaseNotes.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 5de898cd77950..1a5099cdba9a7 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -20,11 +20,6 @@ have questions or comments, the `LLVM Developer's Mailing List `_ is a good place to send them. -Note that if you are reading this file from a Subversion checkout or the main -LLVM web page, this document applies to the *next* release, not the current -one. To see the release notes for a specific release, please see the `releases -page `_. - Minimum Required Compiler Version ================================= As `discussed on the mailing list From 6a57428aa6c92a5cd47783f21bebb5758d8f6367 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 19 Feb 2019 13:53:16 +0000 Subject: [PATCH 151/274] ReleaseNotes: remove in-progress warning, and minor tweaks llvm-svn: 354326 --- clang/docs/ReleaseNotes.rst | 21 +++++---------------- clang/docs/UsersManual.rst | 2 ++ 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 50bf636a51f43..62c426f9f2f32 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1,6 +1,6 @@ -======================================= -Clang 8.0.0 (In-Progress) Release Notes -======================================= +========================= +Clang 8.0.0 Release Notes +========================= .. contents:: :local: @@ -8,12 +8,6 @@ Clang 8.0.0 (In-Progress) Release Notes Written by the `LLVM Team `_ -.. warning:: - - These are in-progress notes for the upcoming Clang 8 release. - Release notes for previous releases can be found on - `the Download Page `_. - Introduction ============ @@ -30,11 +24,6 @@ For more information about Clang or LLVM, including information about the latest release, please see the `Clang Web Site `_ or the `LLVM Web Site `_. -Note that if you are reading this file from a Subversion checkout or the -main Clang web page, this document applies to the *next* release, not -the current one. To see the release notes for a specific release, please -see the `releases page `_. - What's New in Clang 8.0.0? ========================== @@ -50,7 +39,7 @@ Major New Features profile data captured for one version of a program to be applied when building another version where symbols have changed (for example, due to renaming a class or namespace). - See the :doc:`UsersManual` for details. + See the :ref:`UsersManual ` for details. Improvements to Clang's diagnostics ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -138,7 +127,7 @@ New Compiler Flags Clang has now options to filter or exclude some files when instrumenting for gcov-based profiling. - See the :doc:`UsersManual` for details. + See the `UsersManual `_ for details. - When using a custom stack alignment, the ``stackrealign`` attribute is now implicitly set on the main function. diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 7634d24eb5a6a..38f7615bf95b0 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -1799,6 +1799,8 @@ In these cases, you can use the flag ``-fno-profile-instr-generate`` (or Note that these flags should appear after the corresponding profile flags to have an effect. +.. _profile_remapping: + Profile remapping ^^^^^^^^^^^^^^^^^ From 363f1d0f800b3e390f16c7effa4da7e92b35a15e Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 19 Feb 2019 13:58:21 +0000 Subject: [PATCH 152/274] ReleaseNotes: remove in-progress warning and doxygen link llvm-svn: 354327 --- clang-tools-extra/docs/ReleaseNotes.rst | 17 +++-------------- clang-tools-extra/docs/index.rst | 18 ------------------ 2 files changed, 3 insertions(+), 32 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 8731dc73c6487..09445ae21592f 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -1,6 +1,6 @@ -=================================================== -Extra Clang Tools 8.0.0 (In-Progress) Release Notes -=================================================== +===================================== +Extra Clang Tools 8.0.0 Release Notes +===================================== .. contents:: :local: @@ -8,12 +8,6 @@ Extra Clang Tools 8.0.0 (In-Progress) Release Notes Written by the `LLVM Team `_ -.. warning:: - - These are in-progress notes for the upcoming Extra Clang Tools 8 release. - Release notes for previous releases can be found on - `the Download Page `_. - Introduction ============ @@ -27,11 +21,6 @@ For more information about Clang or LLVM, including information about the latest release, please see the `Clang Web Site `_ or the `LLVM Web Site `_. -Note that if you are reading this file from a Subversion checkout or the -main Clang web page, this document applies to the *next* release, not -the current one. To see the release notes for a specific release, please -see the `releases page `_. - What's New in Extra Clang Tools 8.0.0? ====================================== diff --git a/clang-tools-extra/docs/index.rst b/clang-tools-extra/docs/index.rst index 8e6beb35a6091..55fd1a6d08be2 100644 --- a/clang-tools-extra/docs/index.rst +++ b/clang-tools-extra/docs/index.rst @@ -29,24 +29,6 @@ Contents clang-doc -Doxygen Documentation -===================== -The Doxygen documentation describes the **internal** software that makes up the -tools of clang-tools-extra, not the **external** use of these tools. The Doxygen -documentation contains no instructions about how to use the tools, only the APIs -that make up the software. For usage instructions, please see the user's guide -or reference manual for each tool. - -* `Doxygen documentation`_ - -.. _`Doxygen documentation`: doxygen/annotated.html - -.. note:: - This documentation is generated directly from the source code with doxygen. - Since the tools of clang-tools-extra are constantly under active - development, what you're about to read is out of date! - - Indices and tables ================== From b1c5e90a1f9246332b42c95ffe0b33619c818a90 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 19 Feb 2019 14:37:52 +0000 Subject: [PATCH 153/274] ReleaseNotes: remove in-progress warning llvm-svn: 354331 --- lld/docs/ReleaseNotes.rst | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst index 0bebfb3fb1cec..aab52573d925a 100644 --- a/lld/docs/ReleaseNotes.rst +++ b/lld/docs/ReleaseNotes.rst @@ -5,11 +5,6 @@ lld 8.0.0 Release Notes .. contents:: :local: -.. warning:: - These are in-progress notes for the upcoming LLVM 8.0.0 release. - Release notes for previous releases can be found on - `the Download Page `_. - Introduction ============ @@ -18,7 +13,7 @@ Mach-O (macOS), MinGW and WebAssembly. lld is command-line-compatible with GNU linkers and Microsoft link.exe and is significantly faster than the system default linkers. -nlld 8.0.0 has lots of feature improvements and bug fixes. +lld 8.0.0 has lots of feature improvements and bug fixes. Non-comprehensive list of changes in this release ================================================= From fbaa8ef44d5a88b59da5f0c11edb01e44e9cb57e Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 19 Feb 2019 14:49:37 +0000 Subject: [PATCH 154/274] ReleaseNotes: remove in-progress warning llvm-svn: 354334 --- libcxx/docs/ReleaseNotes.rst | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst index 20be9f627ef86..c6db1e7683430 100644 --- a/libcxx/docs/ReleaseNotes.rst +++ b/libcxx/docs/ReleaseNotes.rst @@ -1,6 +1,6 @@ -======================================== -Libc++ 8.0.0 (In-Progress) Release Notes -======================================== +========================== +Libc++ 8.0.0 Release Notes +========================== .. contents:: :local: @@ -8,12 +8,6 @@ Libc++ 8.0.0 (In-Progress) Release Notes Written by the `Libc++ Team `_ -.. warning:: - - These are in-progress notes for the upcoming libc++ 8 release. - Release notes for previous releases can be found on - `the Download Page `_. - Introduction ============ @@ -27,11 +21,6 @@ be downloaded from the `LLVM releases web site `_. For more information about libc++, please see the `Libc++ Web Site `_ or the `LLVM Web Site `_. -Note that if you are reading this file from a Subversion checkout or the -main Libc++ web page, this document applies to the *next* release, not -the current one. To see the release notes for a specific release, please -see the `releases page `_. - What's New in Libc++ 8.0.0? =========================== From 5decb13379c14539c5b8920817e2cc66625e8ecf Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 20 Feb 2019 08:21:37 +0000 Subject: [PATCH 155/274] Merging r354422: ------------------------------------------------------------------------ r354422 | tstellar | 2019-02-20 02:40:35 +0100 (Wed, 20 Feb 2019) | 11 lines ELF: Fix typo in --build-id option description Reviewers: ruiu, espindola Reviewed By: ruiu Subscribers: emaste, arichardson, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D58265 ------------------------------------------------------------------------ llvm-svn: 354440 --- lld/ELF/Options.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index bc203193661b4..439fe341644c8 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -30,7 +30,7 @@ def Bstatic: F<"Bstatic">, HelpText<"Do not link against shared libraries">; def build_id: F<"build-id">, HelpText<"Alias for --build-id=fast">; def build_id_eq: J<"build-id=">, HelpText<"Generate build ID note">, - MetaVarName<"[fast,md5,sha,uuid,0x]">; + MetaVarName<"[fast,md5,sha1,uuid,0x]">; defm check_sections: B<"check-sections", "Check section addresses for overlaps (default)", From d6e87c2d2e00a418c2d08e5fff93adbd6f6cb312 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 20 Feb 2019 11:31:40 +0000 Subject: [PATCH 156/274] ReleaseNotes: initial ppc support in llvm-exegesis llvm-svn: 354448 --- llvm/docs/ReleaseNotes.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 1a5099cdba9a7..8113ef3fa8f37 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -118,7 +118,8 @@ Changes to the MIPS Target Changes to the PowerPC Target ----------------------------- - During this release ... +* Initial PowerPC support in llvm-exegesis, just enough to run it in latency + mode for at least some opcodes. Changes to the X86 Target ------------------------- From 6977a571fc1609b3e99155c8744b645787439e96 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 20 Feb 2019 11:40:19 +0000 Subject: [PATCH 157/274] ReleaseNotes: mention the new rotation builtins, text by Sanjay llvm-svn: 354450 --- clang/docs/ReleaseNotes.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 62c426f9f2f32..b0b09f14e3b73 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -120,6 +120,13 @@ Non-comprehensive list of changes in this release - Improved support for MIPS N32 ABI and MIPS R6 target triples. +- Clang now includes builtin functions for bitwise rotation of common value + sizes, such as: `__builtin_rotateleft32 + `_ + +- Improved optimization for the corresponding MSVC compatibility builtins such + as ``_rotl()``. + New Compiler Flags ------------------ From e4bde922b56fe2d9f15540fe5009683eb0e50bed Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 20 Feb 2019 12:38:35 +0000 Subject: [PATCH 158/274] ReleaseNotes: AArch64 tiny code model llvm-svn: 354457 --- llvm/docs/ReleaseNotes.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 8113ef3fa8f37..4851c8c215a95 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -79,6 +79,9 @@ Changes to the LLVM IR Changes to the AArch64 Target ----------------------------- +* Initial support for the Tiny code model, where code and its statically + defined symbols must live within 1MB of each other. + * Added support for the ``.arch_extension`` assembler directive, just like on ARM. From b936e1cf9766ce2f0e98b2ea1ceb3d96ed029bac Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 20 Feb 2019 12:43:20 +0000 Subject: [PATCH 159/274] ReleaseNotes: all PowerPC changes llvm-svn: 354458 --- llvm/docs/ReleaseNotes.rst | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 4851c8c215a95..ddf12f61de300 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -121,8 +121,40 @@ Changes to the MIPS Target Changes to the PowerPC Target ----------------------------- -* Initial PowerPC support in llvm-exegesis, just enough to run it in latency - mode for at least some opcodes. +* Switched to non-PIC default + +* Deprecated Darwin support + +* Enabled Out-of-Order scheduling for P9 + +* Better overload rules for compatible vector type parameter + +* Support constraint ‘wi’, modifier ‘x’ and VSX registers in inline asm + +* More ``__float128`` support + +* Added new builtins like vector int128 ``pack``/``unpack`` and + ``stxvw4x.be``/``stxvd2x.be`` + +* Provided significant improvements to the automatic vectorizer + +* Code-gen improvements (especially for Power9) + +* Fixed some long-standing bugs in the back end + +* Added experimental prologue/epilogue improvements + +* Enabled builtins tests in compiler-rt + +* Add ``___fixunstfti``/``floattitf`` in compiler-rt to support conversion + between IBM double-double and unsigned int128 + +* Disable randomized address space when running the sanitizers on Linux ppc64le + +* Completed support in LLD for ELFv2 + +* Enabled llvm-exegesis latency mode for PPC + Changes to the X86 Target ------------------------- From 83dcd05f7b3bb23509bbaea752cb4dfa781a1fa9 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 20 Feb 2019 12:51:02 +0000 Subject: [PATCH 160/274] Merging r354351: ------------------------------------------------------------------------ r354351 | hans | 2019-02-19 17:58:25 +0100 (Tue, 19 Feb 2019) | 12 lines Remove extraneous space in MSVC-style diagnostic output There was an extra space between the file location and the diagnostic message: /tmp/a.c(1,12): warning: unused parameter 'unused' the tests didn't catch this due to FileCheck not running in --strict-whitespace mode. Reported by Marco: http://lists.llvm.org/pipermail/cfe-dev/2019-February/061326.html Differential revision: https://reviews.llvm.org/D58377 ------------------------------------------------------------------------ llvm-svn: 354459 --- clang/lib/Frontend/TextDiagnostic.cpp | 2 +- clang/test/Misc/diag-format.c | 44 +++++++++++++-------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index 35b99b10f94a4..8b18fcccb4623 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -838,7 +838,7 @@ void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc, if (LangOpts.MSCompatibilityVersion && !LangOpts.isCompatibleWithMSVC(LangOptions::MSVC2015)) OS << ' '; - OS << ": "; + OS << ':'; break; } diff --git a/clang/test/Misc/diag-format.c b/clang/test/Misc/diag-format.c index bc29894ad03e2..b24aeb9356ae3 100644 --- a/clang/test/Misc/diag-format.c +++ b/clang/test/Misc/diag-format.c @@ -1,30 +1,30 @@ -// RUN: %clang -fsyntax-only %s 2>&1 | FileCheck %s -check-prefix=DEFAULT -// RUN: %clang -fsyntax-only -fdiagnostics-format=clang %s 2>&1 | FileCheck %s -check-prefix=DEFAULT -// RUN: %clang -fsyntax-only -fdiagnostics-format=clang -target x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=DEFAULT +// RUN: %clang -fsyntax-only %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=DEFAULT +// RUN: %clang -fsyntax-only -fdiagnostics-format=clang %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=DEFAULT +// RUN: %clang -fsyntax-only -fdiagnostics-format=clang -target x86_64-pc-win32 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=DEFAULT // -// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1300 %s 2>&1 | FileCheck %s -check-prefix=MSVC2010 -// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fms-compatibility-version=13.00 %s 2>&1 | FileCheck %s -check-prefix=MSVC2010 -// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1300 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=MSVC2010 -// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fms-compatibility-version=13.00 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=MSVC2010 -// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1300 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s -check-prefix=MSVC2010 -// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1800 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=MSVC2013 -// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -target x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=MSVC -// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1900 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=MSVC2015 -// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fms-compatibility-version=13.00 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s -check-prefix=MSVC2010 -// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1800 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s -check-prefix=MSVC2013 -// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s -check-prefix=MSVC -// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1900 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s -check-prefix=MSVC2015 +// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1300 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010 +// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fms-compatibility-version=13.00 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010 +// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1300 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010 +// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fms-compatibility-version=13.00 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010 +// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1300 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010 +// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1800 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2013 +// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -target x86_64-pc-win32 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC +// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1900 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2015 +// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fms-compatibility-version=13.00 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010 +// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1800 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2013 +// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC +// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1900 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2015 // -// RUN: %clang -fsyntax-only -fdiagnostics-format=vi %s 2>&1 | FileCheck %s -check-prefix=VI +// RUN: %clang -fsyntax-only -fdiagnostics-format=vi %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=VI // -// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fno-show-column -fmsc-version=1900 %s 2>&1 | FileCheck %s -check-prefix=MSVC2015_ORIG +// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fno-show-column -fmsc-version=1900 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2015_ORIG // -// RUN: %clang -fsyntax-only -fno-show-column %s 2>&1 | FileCheck %s -check-prefix=NO_COLUMN +// RUN: %clang -fsyntax-only -fno-show-column %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=NO_COLUMN // -// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fmsc-version=1300 %s 2>&1 | FileCheck %s -check-prefix=MSVC2010-FALLBACK -// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fms-compatibility-version=13.00 %s 2>&1 | FileCheck %s -check-prefix=MSVC2010-FALLBACK -// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fmsc-version=1800 %s 2>&1 | FileCheck %s -check-prefix=MSVC2013-FALLBACK -// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fmsc-version=1900 %s 2>&1 | FileCheck %s -check-prefix=MSVC2015-FALLBACK +// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fmsc-version=1300 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010-FALLBACK +// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fms-compatibility-version=13.00 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010-FALLBACK +// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fmsc-version=1800 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2013-FALLBACK +// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fmsc-version=1900 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2015-FALLBACK From cd76cbaa8cbbae2db81f36aa59c05028e0268bbe Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 20 Feb 2019 13:00:59 +0000 Subject: [PATCH 161/274] Merging r354402: ------------------------------------------------------------------------ r354402 | eugenis | 2019-02-20 00:41:42 +0100 (Wed, 20 Feb 2019) | 3 lines [msan] Fix name_to_handle_at test on overlayfs. Udev supports name_to_handle_at. Use /dev/null instead of /bin/cat. ------------------------------------------------------------------------ llvm-svn: 354460 --- compiler-rt/test/msan/Linux/name_to_handle_at.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler-rt/test/msan/Linux/name_to_handle_at.cc b/compiler-rt/test/msan/Linux/name_to_handle_at.cc index 0ff8d982f4f77..a8bc75fa2ae5c 100644 --- a/compiler-rt/test/msan/Linux/name_to_handle_at.cc +++ b/compiler-rt/test/msan/Linux/name_to_handle_at.cc @@ -14,7 +14,7 @@ int main(void) { handle->handle_bytes = MAX_HANDLE_SZ; int mount_id; - int res = name_to_handle_at(AT_FDCWD, "/bin/cat", handle, &mount_id, 0); + int res = name_to_handle_at(AT_FDCWD, "/dev/null", handle, &mount_id, 0); assert(!res); __msan_check_mem_is_initialized(&mount_id, sizeof(mount_id)); __msan_check_mem_is_initialized(&handle->handle_bytes, From 0157e01845f55d897e2c7e76407e12f8314229fc Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 21 Feb 2019 08:53:01 +0000 Subject: [PATCH 162/274] ReleaseNotes: profile-driven cache prefetching. Text by Mircea! llvm-svn: 354554 --- llvm/docs/ReleaseNotes.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index ddf12f61de300..7adfd13c54f3f 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -62,6 +62,24 @@ Non-comprehensive list of changes in this release * Added support for labels as offsets in ``.reloc`` directive. +* Support for precise identification of X86 instructions with memory operands, + by using debug information. This supports profile-driven cache prefetching. + It is enabled with the ``-x86-discriminate-memops`` LLVM Flag. + +* Support for profile-driven software cache prefetching on X86. This is part of + a larger system, consisting of: an offline cache prefetches recommender, + AutoFDO tooling, and LLVM. In this system, a binary compiled with + ``-x86-discriminate-memops`` is run under the observation of the recommender. + The recommender identifies certain memory access instructions by their binary + file address, and recommends a prefetch of a specific type (NTA, T0, etc) be + performed at a specified fixed offset from such an instruction's memory + operand. Next, this information needs to be converted to the AutoFDO syntax + and the resulting profile may be passed back to the compiler with the LLVM + flag ``-prefetch-hints-file``, together with the exact same set of + compilation parameters used for the original binary. More information is + available in the `RFC + `_. + .. NOTE If you would like to document a larger change, then you can add a subsection about it right here. You can copy the following boilerplate From 96ddd7d7f00100f9e553d29239a424a6bfefdfdb Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 21 Feb 2019 08:57:12 +0000 Subject: [PATCH 163/274] Merging r354497: ------------------------------------------------------------------------ r354497 | tstellar | 2019-02-20 19:43:45 +0100 (Wed, 20 Feb 2019) | 16 lines AArch64/test: Add check for function name to machine-outliner-bad-adrp.mir Summary: This test was failing in one of our setups because the generated ModuleID had the full path of the test file and that path contained the string BL. Reviewers: t.p.northover, jpaquette, paquette Reviewed By: paquette Subscribers: javed.absar, kristof.beyls, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D58217 ------------------------------------------------------------------------ llvm-svn: 354555 --- llvm/test/CodeGen/AArch64/machine-outliner-bad-adrp.mir | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-bad-adrp.mir b/llvm/test/CodeGen/AArch64/machine-outliner-bad-adrp.mir index af89ac5885ebe..2fc2cfd5d492e 100644 --- a/llvm/test/CodeGen/AArch64/machine-outliner-bad-adrp.mir +++ b/llvm/test/CodeGen/AArch64/machine-outliner-bad-adrp.mir @@ -10,6 +10,7 @@ ... --- name: foo +# CHECK-LABEL: name: foo tracksRegLiveness: true constants: - id: 0 From 9d332ffc219a47af33737a52949e8bd85126e43d Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 21 Feb 2019 14:16:48 +0000 Subject: [PATCH 164/274] ReleaseNotes: speculative load hardening; text by Kristof llvm-svn: 354582 --- llvm/docs/ReleaseNotes.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 7adfd13c54f3f..29a1e01c8f9ca 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -93,10 +93,16 @@ Non-comprehensive list of changes in this release Changes to the LLVM IR ---------------------- +* Function attribute ``speculative_load_hardening`` has been introduced to + allow indicating that `Speculative Load Hardening + `_ must be enabled for the function body. + Changes to the AArch64 Target ----------------------------- +* Support for Speculative Load Hardening has been added. + * Initial support for the Tiny code model, where code and its statically defined symbols must live within 1MB of each other. From 5a681e47f1f1cc87eccd60437c0087b30ab6d580 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 21 Feb 2019 14:19:52 +0000 Subject: [PATCH 165/274] ReleaseNotes: speculative load hardening; text by Kristof llvm-svn: 354583 --- clang/docs/ReleaseNotes.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b0b09f14e3b73..c7d62933f4bfa 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -130,6 +130,9 @@ Non-comprehensive list of changes in this release New Compiler Flags ------------------ +- ``-mspeculative-load-hardening`` Clang now has an option to enable + Speculative Load Hardening. + - ``-fprofile-filter-files=[regexes]`` and ``-fprofile-exclude-files=[regexes]``. Clang has now options to filter or exclude some files when @@ -171,7 +174,9 @@ New Pragmas in Clang Attribute Changes in Clang -------------------------- -- ... +* Clang now supports enabling/disabling speculative load hardening on a + per-function basis using the function attribute + ``speculative_load_hardening``/``no_speculative_load_hardening``. Windows Support --------------- From 6f2b277f2bed3ad6544a87d8700f9dc7249a703f Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 22 Feb 2019 08:09:08 +0000 Subject: [PATCH 166/274] Release notes: a few lldb changes, by Raphael Isemann! llvm-svn: 354659 --- llvm/docs/ReleaseNotes.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 29a1e01c8f9ca..eafe1f17f7600 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -237,6 +237,14 @@ Changes to the C API Changes to the DAG infrastructure --------------------------------- +Changes to LLDB +=============== +* Printed source code is now syntax highlighted in the terminal (only for C + languages). + +* The expression command now supports tab completing expressions. + + External Open Source Projects Using LLVM 8 ========================================== From b821974465fe070c07e7b235b051641468950147 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 22 Feb 2019 08:45:10 +0000 Subject: [PATCH 167/274] ReleaseNotes: -ftrivial-auto-var-init llvm-svn: 354660 --- clang/docs/ReleaseNotes.rst | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index c7d62933f4bfa..4c593977e2c32 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -41,6 +41,37 @@ Major New Features example, due to renaming a class or namespace). See the :ref:`UsersManual ` for details. +- Clang has new options to initialize automatic variables with either a pattern or with zeroes. The default is still that automatic variables are uninitialized. This isn't meant to change the semantics of C and C++. Rather, it's meant to be a last resort when programmers inadvertently have some undefined behavior in their code. These options aim to make undefined behavior hurt less, which security-minded people will be very happy about. Notably, this means that there's no inadvertent information leak when: + + * The compiler re-uses stack slots, and a value is used uninitialized. + + * The compiler re-uses a register, and a value is used uninitialized. + + * Stack structs / arrays / unions with padding are copied. + + These options only address stack and register information leaks. + + Caveats: + + * Variables declared in unreachable code and used later aren't initialized. This affects goto statements, Duff's device, and other objectionable uses of switch statements. This should instead be a hard-error in any serious codebase. + + * These options don't affect volatile stack variables. + + * Padding isn't fully handled yet. + + How to use it on the command line: + + * ``-ftrivial-auto-var-init=uninitialized`` (the default) + + * ``-ftrivial-auto-var-init=pattern`` + + * ``-ftrivial-auto-var-init=zero`` ``-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang`` + + There is also a new attribute to request a variable to not be initialized, mainly to disable initialization of large stack arrays when deemed too expensive: + + * ``int dont_initialize_me __attribute((uninitialized));`` + + Improvements to Clang's diagnostics ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 16667e0626dfa6e56cc423405b0295d5a568b78e Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 25 Feb 2019 16:06:37 +0000 Subject: [PATCH 168/274] ReleaseNotes: drop mention of -ftrivial-auto-var-init=zero llvm-svn: 354794 --- clang/docs/ReleaseNotes.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 4c593977e2c32..54a7a4c1b976c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -41,7 +41,7 @@ Major New Features example, due to renaming a class or namespace). See the :ref:`UsersManual ` for details. -- Clang has new options to initialize automatic variables with either a pattern or with zeroes. The default is still that automatic variables are uninitialized. This isn't meant to change the semantics of C and C++. Rather, it's meant to be a last resort when programmers inadvertently have some undefined behavior in their code. These options aim to make undefined behavior hurt less, which security-minded people will be very happy about. Notably, this means that there's no inadvertent information leak when: +- Clang has new options to initialize automatic variables with a pattern. The default is still that automatic variables are uninitialized. This isn't meant to change the semantics of C and C++. Rather, it's meant to be a last resort when programmers inadvertently have some undefined behavior in their code. These options aim to make undefined behavior hurt less, which security-minded people will be very happy about. Notably, this means that there's no inadvertent information leak when: * The compiler re-uses stack slots, and a value is used uninitialized. @@ -65,8 +65,6 @@ Major New Features * ``-ftrivial-auto-var-init=pattern`` - * ``-ftrivial-auto-var-init=zero`` ``-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang`` - There is also a new attribute to request a variable to not be initialized, mainly to disable initialization of large stack arrays when deemed too expensive: * ``int dont_initialize_me __attribute((uninitialized));`` From bb92074a2786bfc9ff478adf60ad09056b85d5fc Mon Sep 17 00:00:00 2001 From: Anastasia Stulova Date: Mon, 25 Feb 2019 17:07:58 +0000 Subject: [PATCH 169/274] Release notes for OpenCL Differential Revision: https://reviews.llvm.org/D58504 llvm-svn: 354799 --- clang/docs/ReleaseNotes.rst | 58 ++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 54a7a4c1b976c..bdf4bcf70b8b9 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -11,7 +11,7 @@ Written by the `LLVM Team `_ Introduction ============ -This document contains the release notes for the Clang C/C++/Objective-C +This document contains the release notes for the Clang C/C++/Objective-C/OpenCL frontend, part of the LLVM Compiler Infrastructure, release 8.0.0. Here we describe the status of Clang in some detail, including major improvements from the previous release and new feature work. For the @@ -259,10 +259,60 @@ Objective-C Language Changes in Clang ... -OpenCL C Language Changes in Clang ----------------------------------- +OpenCL Kernel Language Changes in Clang +--------------------------------------- + +Misc: + +- Improved address space support with Clang builtins. + +- Improved various diagnostics for vectors with element types from extensions; + values used in attributes; duplicate address spaces. + +- Allow blocks to capture arrays. + +- Allow zero assignment and comparisons between variables of ``queue_t`` type. + +- Improved diagnostics of formatting specifiers and argument promotions for + vector types in ``printf``. + +- Fixed return type of enqueued kernel and pipe builtins. + +- Fixed address space of ``clk_event_t`` generated in the IR. + +- Fixed address space when passing/returning structs. + +Header file fixes: + +- Added missing extension guards around several builtin function overloads. + +- Fixed serialization support when registering vendor extensions using pragmas. + +- Fixed OpenCL version in declarations of builtin functions with sampler-less + image accesses. + +New vendor extensions added: + +- ``cl_intel_planar_yuv`` + +- ``cl_intel_device_side_avc_motion_estimation`` + + +C++ for OpenCL: + +- Added support of address space conversions in C style casts. + +- Enabled address spaces for references. + +- Fixed use of address spaces in templates: address space deduction and diagnostics. + +- Changed default address space to work with C++ specific concepts: class members, + template parameters, etc. + +- Added generic address space by default to the generated hidden 'this' parameter. + +- Extend overload ranking rules for address spaces. -... ABI Changes in Clang -------------------- From 0777c34a304885588c6372f1f4bb618895b6ff26 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 26 Feb 2019 09:54:36 +0000 Subject: [PATCH 170/274] ReleaseNotes: ARM64 SEH, pointed out by David Major llvm-svn: 354855 --- clang/docs/ReleaseNotes.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index bdf4bcf70b8b9..65ab1314d3744 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -210,7 +210,7 @@ Attribute Changes in Clang Windows Support --------------- -- clang-cl now supports the use of the precompiled header options /Yc and /Yu +- clang-cl now supports the use of the precompiled header options ``/Yc`` and ``/Yu`` without the filename argument. When these options are used without the filename, a `#pragma hdrstop` inside the source marks the end of the precompiled code. @@ -229,7 +229,8 @@ Windows Support - Allow using Address Sanitizer and Undefined Behaviour Sanitizer on MinGW. -- ... +- Structured Exception Handling support for ARM64 Windows. The ARM64 Windows + target is in pretty good shape now. C Language Changes in Clang From ee57e9e190b8d610739471024fa8eed68f678091 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 26 Feb 2019 10:02:05 +0000 Subject: [PATCH 171/274] Merging r354764: ------------------------------------------------------------------------ r354764 | lebedevri | 2019-02-25 08:39:07 +0100 (Mon, 25 Feb 2019) | 123 lines [XRay][tools] Revert "Use Support/JSON.h in llvm-xray convert" Summary: This reverts D50129 / rL338834: [XRay][tools] Use Support/JSON.h in llvm-xray convert Abstractions are great. Readable code is great. JSON support library is a *good* idea. However unfortunately, there is an internal detail that one needs to be aware of in `llvm::json::Object` - it uses `llvm::DenseMap`. So for **every** `llvm::json::Object`, even if you only store a single `int` entry there, you pay the whole price of `llvm::DenseMap`. Unfortunately, it matters for `llvm-xray`. I was trying to analyse the `llvm-exegesis` analysis mode performance, and for that i wanted to view the LLVM X-Ray log visualization in Chrome trace viewer. And the `llvm-xray convert` is sluggish, and sometimes even ended up being killed by OOM. `xray-log.llvm-exegesis.lwZ0sT` was acquired from `llvm-exegesis` (compiled with ` -fxray-instruction-threshold=128`) analysis mode over `-benchmarks-file` with 10099 points (one full latency measurement set), with normal runtime of 0.387s. Timings: Old: (copied from D58580) ``` $ perf stat -r 5 ./bin/llvm-xray convert -sort -symbolize -instr_map=./bin/llvm-exegesis -output-format=trace_event -output=/tmp/trace.yml xray-log.llvm-exegesis.lwZ0sT Performance counter stats for './bin/llvm-xray convert -sort -symbolize -instr_map=./bin/llvm-exegesis -output-format=trace_event -output=/tmp/trace.yml xray-log.llvm-exegesis.lwZ0sT' (5 runs): 21346.24 msec task-clock # 1.000 CPUs utilized ( +- 0.28% ) 314 context-switches # 14.701 M/sec ( +- 59.13% ) 1 cpu-migrations # 0.037 M/sec ( +-100.00% ) 2181354 page-faults # 102191.251 M/sec ( +- 0.02% ) 85477442102 cycles # 4004415.019 GHz ( +- 0.28% ) (83.33%) 14526427066 stalled-cycles-frontend # 16.99% frontend cycles idle ( +- 0.70% ) (83.33%) 32371533721 stalled-cycles-backend # 37.87% backend cycles idle ( +- 0.27% ) (33.34%) 67896890228 instructions # 0.79 insn per cycle # 0.48 stalled cycles per insn ( +- 0.03% ) (50.00%) 14592654840 branches # 683631198.653 M/sec ( +- 0.02% ) (66.67%) 212207534 branch-misses # 1.45% of all branches ( +- 0.94% ) (83.34%) 21.3502 +- 0.0585 seconds time elapsed ( +- 0.27% ) ``` New: ``` $ perf stat -r 9 ./bin/llvm-xray convert -sort -symbolize -instr_map=./bin/llvm-exegesis -output-format=trace_event -output=/tmp/trace.yml xray-log.llvm-exegesis.lwZ0sT Performance counter stats for './bin/llvm-xray convert -sort -symbolize -instr_map=./bin/llvm-exegesis -output-format=trace_event -output=/tmp/trace.yml xray-log.llvm-exegesis.lwZ0sT' (9 runs): 7178.38 msec task-clock # 1.000 CPUs utilized ( +- 0.26% ) 182 context-switches # 25.402 M/sec ( +- 28.84% ) 0 cpu-migrations # 0.046 M/sec ( +- 70.71% ) 33701 page-faults # 4694.994 M/sec ( +- 0.88% ) 28761053971 cycles # 4006833.933 GHz ( +- 0.26% ) (83.32%) 2028297997 stalled-cycles-frontend # 7.05% frontend cycles idle ( +- 1.61% ) (83.32%) 10773154901 stalled-cycles-backend # 37.46% backend cycles idle ( +- 0.38% ) (33.36%) 36199132874 instructions # 1.26 insn per cycle # 0.30 stalled cycles per insn ( +- 0.03% ) (50.02%) 6434504227 branches # 896420204.421 M/sec ( +- 0.03% ) (66.68%) 73355176 branch-misses # 1.14% of all branches ( +- 1.46% ) (83.33%) 7.1807 +- 0.0190 seconds time elapsed ( +- 0.26% ) ``` So using `llvm::json` nearly triples run-time on that test case. (+3x is times, not percent.) Memory: Old: ``` total runtime: 39.88s. bytes allocated in total (ignoring deallocations): 79.07GB (1.98GB/s) calls to allocation functions: 33267816 (834135/s) temporary memory allocations: 5832298 (146235/s) peak heap memory consumption: 9.21GB peak RSS (including heaptrack overhead): 147.98GB total memory leaked: 1.09MB ``` New: ``` total runtime: 17.42s. bytes allocated in total (ignoring deallocations): 5.12GB (293.86MB/s) calls to allocation functions: 21382982 (1227284/s) temporary memory allocations: 232858 (13364/s) peak heap memory consumption: 350.69MB peak RSS (including heaptrack overhead): 2.55GB total memory leaked: 79.95KB ``` Diff: ``` total runtime: -22.46s. bytes allocated in total (ignoring deallocations): -73.95GB (3.29GB/s) calls to allocation functions: -11884834 (529155/s) temporary memory allocations: -5599440 (249307/s) peak heap memory consumption: -8.86GB peak RSS (including heaptrack overhead): 0B total memory leaked: -1.01MB ``` So using `llvm::json` increases *peak* memory consumption on *this* testcase ~+27x. And total allocation count +15x. Both of these numbers are times, *not* percent. And note that memory usage is clearly unbound with `llvm::json`, it directly depends on the length of the log, so peak memory consumption is always increasing. This isn't so with the dumb code, there is no accumulating memory consumption, peak memory consumption is fixed. Naturally, that means it will handle *much* larger logs without OOM'ing. Readability is good, but the price is simply unacceptable here. Too bad none of this analysis was done as part of the development/review D50129 itself. Reviewers: dberris, kpw, sammccall Reviewed By: dberris Subscribers: riccibruno, hans, courbet, jdoerfert, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D58584 ------------------------------------------------------------------------ llvm-svn: 354856 --- llvm/tools/llvm-xray/xray-converter.cpp | 109 +++++++++++++----------- 1 file changed, 61 insertions(+), 48 deletions(-) diff --git a/llvm/tools/llvm-xray/xray-converter.cpp b/llvm/tools/llvm-xray/xray-converter.cpp index 3f153b99bc936..a682dbe53e3bd 100644 --- a/llvm/tools/llvm-xray/xray-converter.cpp +++ b/llvm/tools/llvm-xray/xray-converter.cpp @@ -18,7 +18,6 @@ #include "llvm/Support/EndianStream.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FormatVariadic.h" -#include "llvm/Support/JSON.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/YAMLTraits.h" #include "llvm/Support/raw_ostream.h" @@ -242,6 +241,31 @@ StackTrieNode *findOrCreateStackNode( return CurrentStack; } +void writeTraceViewerRecord(uint16_t Version, raw_ostream &OS, int32_t FuncId, + uint32_t TId, uint32_t PId, bool Symbolize, + const FuncIdConversionHelper &FuncIdHelper, + double EventTimestampUs, + const StackTrieNode &StackCursor, + StringRef FunctionPhenotype) { + OS << " "; + if (Version >= 3) { + OS << llvm::formatv( + R"({ "name" : "{0}", "ph" : "{1}", "tid" : "{2}", "pid" : "{3}", )" + R"("ts" : "{4:f4}", "sf" : "{5}" })", + (Symbolize ? FuncIdHelper.SymbolOrNumber(FuncId) + : llvm::to_string(FuncId)), + FunctionPhenotype, TId, PId, EventTimestampUs, + StackCursor.ExtraData.id); + } else { + OS << llvm::formatv( + R"({ "name" : "{0}", "ph" : "{1}", "tid" : "{2}", "pid" : "1", )" + R"("ts" : "{3:f3}", "sf" : "{4}" })", + (Symbolize ? FuncIdHelper.SymbolOrNumber(FuncId) + : llvm::to_string(FuncId)), + FunctionPhenotype, TId, EventTimestampUs, StackCursor.ExtraData.id); + } +} + } // namespace void TraceConverter::exportAsChromeTraceEventFormat(const Trace &Records, @@ -252,14 +276,18 @@ void TraceConverter::exportAsChromeTraceEventFormat(const Trace &Records, unsigned id_counter = 0; + OS << "{\n \"traceEvents\": ["; DenseMap StackCursorByThreadId{}; DenseMap> StackRootsByThreadId{}; DenseMap StacksByStackId{}; std::forward_list NodeStore{}; - - // Create a JSON Array which will hold all trace events. - json::Array TraceEvents; + int loop_count = 0; for (const auto &R : Records) { + if (loop_count++ == 0) + OS << "\n"; + else + OS << ",\n"; + // Chrome trace event format always wants data in micros. // CyclesPerMicro = CycleHertz / 10^6 // TSC / CyclesPerMicro == TSC * 10^6 / CycleHertz == MicroTimestamp @@ -284,15 +312,8 @@ void TraceConverter::exportAsChromeTraceEventFormat(const Trace &Records, // type of B for begin or E for end, thread id, process id, // timestamp in microseconds, and a stack frame id. The ids are logged // in an id dictionary after the events. - TraceEvents.push_back(json::Object({ - {"name", Symbolize ? FuncIdHelper.SymbolOrNumber(R.FuncId) - : llvm::to_string(R.FuncId)}, - {"ph", "B"}, - {"tid", llvm::to_string(R.TId)}, - {"pid", llvm::to_string(Version >= 3 ? R.PId : 1)}, - {"ts", llvm::formatv("{0:f4}", EventTimestampUs)}, - {"sf", llvm::to_string(StackCursor->ExtraData.id)}, - })); + writeTraceViewerRecord(Version, OS, R.FuncId, R.TId, R.PId, Symbolize, + FuncIdHelper, EventTimestampUs, *StackCursor, "B"); break; case RecordTypes::EXIT: case RecordTypes::TAIL_EXIT: @@ -303,51 +324,43 @@ void TraceConverter::exportAsChromeTraceEventFormat(const Trace &Records, // (And/Or in loop termination below) StackTrieNode *PreviousCursor = nullptr; do { - TraceEvents.push_back(json::Object({ - {"name", Symbolize - ? FuncIdHelper.SymbolOrNumber(StackCursor->FuncId) - : llvm::to_string(StackCursor->FuncId)}, - {"ph", "E"}, - {"tid", llvm::to_string(R.TId)}, - {"pid", llvm::to_string(Version >= 3 ? R.PId : 1)}, - {"ts", llvm::formatv("{0:f4}", EventTimestampUs)}, - {"sf", llvm::to_string(StackCursor->ExtraData.id)}, - })); + if (PreviousCursor != nullptr) { + OS << ",\n"; + } + writeTraceViewerRecord(Version, OS, StackCursor->FuncId, R.TId, R.PId, + Symbolize, FuncIdHelper, EventTimestampUs, + *StackCursor, "E"); PreviousCursor = StackCursor; StackCursor = StackCursor->Parent; } while (PreviousCursor->FuncId != R.FuncId && StackCursor != nullptr); break; } } + OS << "\n ],\n"; // Close the Trace Events array. + OS << " " + << "\"displayTimeUnit\": \"ns\",\n"; // The stackFrames dictionary substantially reduces size of the output file by // avoiding repeating the entire call stack of function names for each entry. - json::Object StackFrames; - for (const auto &Stack : StacksByStackId) { - const auto &StackId = Stack.first; - const auto &StackFunctionNode = Stack.second; - json::Object::iterator It; - std::tie(It, std::ignore) = StackFrames.insert({ - llvm::to_string(StackId), - json::Object{ - {"name", - Symbolize ? FuncIdHelper.SymbolOrNumber(StackFunctionNode->FuncId) - : llvm::to_string(StackFunctionNode->FuncId)}}, - }); - - if (StackFunctionNode->Parent != nullptr) - It->second.getAsObject()->insert( - {"parent", llvm::to_string(StackFunctionNode->Parent->ExtraData.id)}); + OS << R"( "stackFrames": {)"; + int stack_frame_count = 0; + for (auto map_iter : StacksByStackId) { + if (stack_frame_count++ == 0) + OS << "\n"; + else + OS << ",\n"; + OS << " "; + OS << llvm::formatv( + R"("{0}" : { "name" : "{1}")", map_iter.first, + (Symbolize ? FuncIdHelper.SymbolOrNumber(map_iter.second->FuncId) + : llvm::to_string(map_iter.second->FuncId))); + if (map_iter.second->Parent != nullptr) + OS << llvm::formatv(R"(, "parent": "{0}")", + map_iter.second->Parent->ExtraData.id); + OS << " }"; } - - json::Object TraceJSON{ - {"displayTimeUnit", "ns"}, - {"traceEvents", std::move(TraceEvents)}, - {"stackFrames", std::move(StackFrames)}, - }; - - // Pretty-print the JSON using two spaces for indentations. - OS << formatv("{0:2}", json::Value(std::move(TraceJSON))); + OS << "\n }\n"; // Close the stack frames map. + OS << "}\n"; // Close the JSON entry. } namespace llvm { From e745d6ddde3ee886d085a8572735182412c8ff43 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 26 Feb 2019 10:21:19 +0000 Subject: [PATCH 172/274] Merging r354756: ------------------------------------------------------------------------ r354756 | ctopper | 2019-02-24 20:33:37 +0100 (Sun, 24 Feb 2019) | 36 lines [X86] Fix tls variable lowering issue with large code model Summary: The problem here is the lowering for tls variable. Below is the DAG for the code. SelectionDAG has 11 nodes: t0: ch = EntryToken t8: i64,ch = load<(load 8 from `i8 addrspace(257)* null`, addrspace 257)> t0, Constant:i64<0>, undef:i64 t10: i64 = X86ISD::WrapperRIP TargetGlobalTLSAddress:i64 0 [TF=10] t11: i64,ch = load<(load 8 from got)> t0, t10, undef:i64 t12: i64 = add t8, t11 t4: i32,ch = load<(dereferenceable load 4 from @x)> t0, t12, undef:i64 t6: ch = CopyToReg t0, Register:i32 %0, t4 And when mcmodel is large, below instruction can NOT be folded. t10: i64 = X86ISD::WrapperRIP TargetGlobalTLSAddress:i64 0 [TF=10] t11: i64,ch = load<(load 8 from got)> t0, t10, undef:i64 So "t11: i64,ch = load<(load 8 from got)> t0, t10, undef:i64" is lowered to " Morphed node: t11: i64,ch = MOV64rm t10, TargetConstant:i8<1>, Register:i64 $noreg, TargetConstant:i32<0>, Register:i32 $noreg, t0" When llvm start to lower "t10: i64 = X86ISD::WrapperRIP TargetGlobalTLSAddress:i64 0 [TF=10]", it fails. The patch is to fold the load and X86ISD::WrapperRIP. Fixes PR26906 Patch by LuoYuanke Reviewers: craig.topper, rnk, annita.zhang, wxiao3 Reviewed By: rnk Subscribers: llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D58336 ------------------------------------------------------------------------ llvm-svn: 354857 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 18 +++++-- llvm/test/CodeGen/X86/code-model-elf.ll | 66 +++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 5ac153244df92..fe75dbd8eff4e 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -1138,15 +1138,23 @@ bool X86DAGToDAGISel::matchWrapper(SDValue N, X86ISelAddressMode &AM) { if (AM.hasSymbolicDisplacement()) return true; + bool IsRIPRelTLS = false; bool IsRIPRel = N.getOpcode() == X86ISD::WrapperRIP; + if (IsRIPRel) { + SDValue Val = N.getOperand(0); + if (Val.getOpcode() == ISD::TargetGlobalTLSAddress) + IsRIPRelTLS = true; + } - // We can't use an addressing mode in the 64-bit large code model. In the - // medium code model, we use can use an mode when RIP wrappers are present. - // That signifies access to globals that are known to be "near", such as the - // GOT itself. + // We can't use an addressing mode in the 64-bit large code model. + // Global TLS addressing is an exception. In the medium code model, + // we use can use a mode when RIP wrappers are present. + // That signifies access to globals that are known to be "near", + // such as the GOT itself. CodeModel::Model M = TM.getCodeModel(); if (Subtarget->is64Bit() && - (M == CodeModel::Large || (M == CodeModel::Medium && !IsRIPRel))) + ((M == CodeModel::Large && !IsRIPRelTLS) || + (M == CodeModel::Medium && !IsRIPRel))) return true; // Base and index reg must be 0 in order to use %rip as base. diff --git a/llvm/test/CodeGen/X86/code-model-elf.ll b/llvm/test/CodeGen/X86/code-model-elf.ll index 56d3f4c102f0f..f7ffd6ea1eb7c 100644 --- a/llvm/test/CodeGen/X86/code-model-elf.ll +++ b/llvm/test/CodeGen/X86/code-model-elf.ll @@ -37,6 +37,8 @@ target triple = "x86_64--linux" @global_data = dso_local global [10 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0], align 16 @static_data = internal global [10 x i32] zeroinitializer, align 16 @extern_data = external global [10 x i32], align 16 +@thread_data = external thread_local global i32, align 4 + define dso_local i32* @lea_static_data() #0 { ; SMALL-STATIC-LABEL: lea_static_data: @@ -373,6 +375,70 @@ define dso_local void ()* @lea_extern_fn() #0 { ret void ()* @extern_fn } +; FIXME: The result is same for small, medium and large model, because we +; specify pie option in the test case. And the type of tls is initial exec tls. +; For pic code. The large model code for pic tls should be emitted as below. + +; .L3: +; leaq .L3(%rip), %rbx +; movabsq $_GLOBAL_OFFSET_TABLE_-.L3, %r11 +; addq %r11, %rbx +; leaq thread_data@TLSGD(%rip), %rdi +; movabsq $__tls_get_addr@PLTOFF, %rax +; addq %rbx, %rax +; call *%rax +; movl (%rax), %eax + +; The medium and small model code for pic tls should be emitted as below. +; data16 +; leaq thread_data@TLSGD(%rip), %rdi +; data16 +; data16 +; rex64 +; callq __tls_get_addr@PLT +; movl (%rax), %eax + +define dso_local i32 @load_thread_data() #0 { +; SMALL-STATIC-LABEL: load_thread_data: +; SMALL-STATIC: # %bb.0: +; SMALL-STATIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax +; SMALL-STATIC-NEXT: movl %fs:(%rax), %eax +; SMALL-STATIC-NEXT: retq +; +; MEDIUM-STATIC-LABEL: load_thread_data: +; MEDIUM-STATIC: # %bb.0: +; MEDIUM-STATIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax +; MEDIUM-STATIC-NEXT: movl %fs:(%rax), %eax +; MEDIUM-STATIC-NEXT: retq +; +; LARGE-STATIC-LABEL: load_thread_data: +; LARGE-STATIC: # %bb.0: +; LARGE-STATIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax +; LARGE-STATIC-NEXT: movl %fs:(%rax), %eax +; LARGE-STATIC-NEXT: retq +; +; SMALL-PIC-LABEL: load_thread_data: +; SMALL-PIC: # %bb.0: +; SMALL-PIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax +; SMALL-PIC-NEXT: movl %fs:(%rax), %eax +; SMALL-PIC-NEXT: retq +; +; MEDIUM-PIC-LABEL: load_thread_data: +; MEDIUM-PIC: # %bb.0: +; MEDIUM-PIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax +; MEDIUM-PIC-NEXT: movl %fs:(%rax), %eax +; MEDIUM-PIC-NEXT: retq +; +; LARGE-PIC-LABEL: load_thread_data: +; LARGE-PIC: # %bb.0: +; LARGE-PIC-NEXT: movq thread_data@GOTTPOFF(%rip), %rax +; LARGE-PIC-NEXT: movl %fs:(%rax), %eax +; LARGE-PIC-NEXT: retq +; + %1 = load i32, i32* @thread_data, align 4 + ret i32 %1 +} + attributes #0 = { noinline nounwind uwtable } !llvm.module.flags = !{!0, !1, !2} From 319e7dfd47d76223105ede35db184ddb7bf57e8f Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 26 Feb 2019 10:25:44 +0000 Subject: [PATCH 173/274] Merging r354721: ------------------------------------------------------------------------ r354721 | brad | 2019-02-23 07:19:28 +0100 (Sat, 23 Feb 2019) | 4 lines Remove sanitizer context workaround no longer necessary The base linker is now lld. ------------------------------------------------------------------------ llvm-svn: 354858 --- clang/lib/Driver/ToolChains/OpenBSD.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/clang/lib/Driver/ToolChains/OpenBSD.cpp b/clang/lib/Driver/ToolChains/OpenBSD.cpp index 3d35d37b7db32..6b02e68965df1 100644 --- a/clang/lib/Driver/ToolChains/OpenBSD.cpp +++ b/clang/lib/Driver/ToolChains/OpenBSD.cpp @@ -227,9 +227,7 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend))); } - const char *Exec = Args.MakeArgString( - !NeedsSanitizerDeps ? ToolChain.GetLinkerPath() - : ToolChain.GetProgramPath("ld.lld")); + const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs, Inputs)); } From 35782c5639bffa56ba2972d4c3c29567d83d9860 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 26 Feb 2019 10:28:10 +0000 Subject: [PATCH 174/274] Merging r354723: ------------------------------------------------------------------------ r354723 | brad | 2019-02-23 08:21:19 +0100 (Sat, 23 Feb 2019) | 3 lines Remove OpenBSD case for old system libstdc++ header path as OpenBSD has switched to libc++. ------------------------------------------------------------------------ llvm-svn: 354859 --- clang/lib/Frontend/InitHeaderSearch.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/clang/lib/Frontend/InitHeaderSearch.cpp b/clang/lib/Frontend/InitHeaderSearch.cpp index ac3bb713ddccc..67842b5dca296 100644 --- a/clang/lib/Frontend/InitHeaderSearch.cpp +++ b/clang/lib/Frontend/InitHeaderSearch.cpp @@ -433,14 +433,6 @@ void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths( case llvm::Triple::DragonFly: AddPath("/usr/include/c++/5.0", CXXSystem, false); break; - case llvm::Triple::OpenBSD: { - std::string t = triple.getTriple(); - if (t.substr(0, 6) == "x86_64") - t.replace(0, 6, "amd64"); - AddGnuCPlusPlusIncludePaths("/usr/include/g++", - t, "", "", triple); - break; - } case llvm::Triple::Minix: AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3", "", "", "", triple); From e56517b25e9ef43fbc5bb3473235b7fe00bb9497 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 26 Feb 2019 10:31:22 +0000 Subject: [PATCH 175/274] Merging r354733: ------------------------------------------------------------------------ r354733 | nikic | 2019-02-23 19:59:01 +0100 (Sat, 23 Feb 2019) | 10 lines [WebAssembly] Fix select of and (PR40805) Fixes https://bugs.llvm.org/show_bug.cgi?id=40805 introduced by patterns added in D53676. I'm removing the patterns entirely here, as they are not correct in the general case. If necessary something more specific can be added in the future. Differential Revision: https://reviews.llvm.org/D58575 ------------------------------------------------------------------------ llvm-svn: 354860 --- .../WebAssembly/WebAssemblyInstrInteger.td | 7 ------ llvm/test/CodeGen/WebAssembly/select.ll | 25 ++++++++++++++++--- llvm/test/CodeGen/WebAssembly/simd-select.ll | 12 ++++----- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td index d5b63d6436973..bd41f46214a35 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td @@ -122,10 +122,3 @@ def : Pat<(select (i32 (seteq I32:$cond, 0)), I32:$lhs, I32:$rhs), (SELECT_I32 I32:$rhs, I32:$lhs, I32:$cond)>; def : Pat<(select (i32 (seteq I32:$cond, 0)), I64:$lhs, I64:$rhs), (SELECT_I64 I64:$rhs, I64:$lhs, I32:$cond)>; - -// The legalizer inserts an unnecessary `and 1` to make input conform -// to getBooleanContents, which we can lower away. -def : Pat<(select (i32 (and I32:$cond, 1)), I32:$lhs, I32:$rhs), - (SELECT_I32 I32:$lhs, I32:$rhs, I32:$cond)>; -def : Pat<(select (i32 (and I32:$cond, 1)), I64:$lhs, I64:$rhs), - (SELECT_I64 I64:$lhs, I64:$rhs, I32:$cond)>; diff --git a/llvm/test/CodeGen/WebAssembly/select.ll b/llvm/test/CodeGen/WebAssembly/select.ll index daa934f448448..ef18d9183e50d 100644 --- a/llvm/test/CodeGen/WebAssembly/select.ll +++ b/llvm/test/CodeGen/WebAssembly/select.ll @@ -17,8 +17,10 @@ define i32 @select_i32_bool(i1 zeroext %a, i32 %b, i32 %c) { ; CHECK-LABEL: select_i32_bool_nozext: ; CHECK-NEXT: .functype select_i32_bool_nozext (i32, i32, i32) -> (i32){{$}} -; SLOW-NEXT: i32.select $push0=, $1, $2, $0{{$}} -; SLOW-NEXT: return $pop0{{$}} +; SLOW-NEXT: i32.const $push0=, 1{{$}} +; SLOW-NEXT: i32.and $push1=, $0, $pop0{{$}} +; SLOW-NEXT: i32.select $push2=, $1, $2, $pop1{{$}} +; SLOW-NEXT: return $pop2{{$}} define i32 @select_i32_bool_nozext(i1 %a, i32 %b, i32 %c) { %cond = select i1 %a, i32 %b, i32 %c ret i32 %cond @@ -55,8 +57,10 @@ define i64 @select_i64_bool(i1 zeroext %a, i64 %b, i64 %c) { ; CHECK-LABEL: select_i64_bool_nozext: ; CHECK-NEXT: .functype select_i64_bool_nozext (i32, i64, i64) -> (i64){{$}} -; SLOW-NEXT: i64.select $push0=, $1, $2, $0{{$}} -; SLOW-NEXT: return $pop0{{$}} +; SLOW-NEXT: i32.const $push0=, 1{{$}} +; SLOW-NEXT: i32.and $push1=, $0, $pop0{{$}} +; SLOW-NEXT: i64.select $push2=, $1, $2, $pop1{{$}} +; SLOW-NEXT: return $pop2{{$}} define i64 @select_i64_bool_nozext(i1 %a, i64 %b, i64 %c) { %cond = select i1 %a, i64 %b, i64 %c ret i64 %cond @@ -157,3 +161,16 @@ define double @select_f64_ne(i32 %a, double %b, double %c) { %cond = select i1 %cmp, double %b, double %c ret double %cond } + +; CHECK-LABEL: pr40805: +; CHECK-NEXT: .functype pr40805 (i32, i32, i32) -> (i32){{$}} +; SLOW-NEXT: i32.const $push0=, 1{{$}} +; SLOW-NEXT: i32.and $push1=, $0, $pop0{{$}} +; SLOW-NEXT: i32.select $push2=, $1, $2, $pop1{{$}} +; SLOW-NEXT: return $pop2{{$}} +define i32 @pr40805(i32 %x, i32 %y, i32 %z) { + %a = and i32 %x, 1 + %b = icmp ne i32 %a, 0 + %c = select i1 %b, i32 %y, i32 %z + ret i32 %c +} diff --git a/llvm/test/CodeGen/WebAssembly/simd-select.ll b/llvm/test/CodeGen/WebAssembly/simd-select.ll index c871f60e6454c..c3af6f9abe60b 100644 --- a/llvm/test/CodeGen/WebAssembly/simd-select.ll +++ b/llvm/test/CodeGen/WebAssembly/simd-select.ll @@ -29,7 +29,7 @@ define <16 x i8> @vselect_v16i8(<16 x i1> %c, <16 x i8> %x, <16 x i8> %y) { ; CHECK-NEXT: i8x16.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} ; CHECK-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $pop[[L3]]{{$}} ; CHECK-NEXT: return $pop[[R]]{{$}} -define <16 x i8> @select_v16i8(i1 %c, <16 x i8> %x, <16 x i8> %y) { +define <16 x i8> @select_v16i8(i1 zeroext %c, <16 x i8> %x, <16 x i8> %y) { %res = select i1 %c, <16 x i8> %x, <16 x i8> %y ret <16 x i8> %res } @@ -99,7 +99,7 @@ define <8 x i16> @vselect_v8i16(<8 x i1> %c, <8 x i16> %x, <8 x i16> %y) { ; CHECK-NEXT: i16x8.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} ; CHECK-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $pop[[L3]]{{$}} ; CHECK-NEXT: return $pop[[R]]{{$}} -define <8 x i16> @select_v8i16(i1 %c, <8 x i16> %x, <8 x i16> %y) { +define <8 x i16> @select_v8i16(i1 zeroext %c, <8 x i16> %x, <8 x i16> %y) { %res = select i1 %c, <8 x i16> %x, <8 x i16> %y ret <8 x i16> %res } @@ -170,7 +170,7 @@ define <4 x i32> @vselect_v4i32(<4 x i1> %c, <4 x i32> %x, <4 x i32> %y) { ; CHECK-NEXT: i32x4.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} ; CHECK-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $pop[[L3]]{{$}} ; CHECK-NEXT: return $pop[[R]]{{$}} -define <4 x i32> @select_v4i32(i1 %c, <4 x i32> %x, <4 x i32> %y) { +define <4 x i32> @select_v4i32(i1 zeroext %c, <4 x i32> %x, <4 x i32> %y) { %res = select i1 %c, <4 x i32> %x, <4 x i32> %y ret <4 x i32> %res } @@ -240,7 +240,7 @@ define <2 x i64> @vselect_v2i64(<2 x i1> %c, <2 x i64> %x, <2 x i64> %y) { ; CHECK-NEXT: i64x2.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} ; CHECK-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $pop[[L3]]{{$}} ; CHECK-NEXT: return $pop[[R]]{{$}} -define <2 x i64> @select_v2i64(i1 %c, <2 x i64> %x, <2 x i64> %y) { +define <2 x i64> @select_v2i64(i1 zeroext %c, <2 x i64> %x, <2 x i64> %y) { %res = select i1 %c, <2 x i64> %x, <2 x i64> %y ret <2 x i64> %res } @@ -313,7 +313,7 @@ define <4 x float> @vselect_v4f32(<4 x i1> %c, <4 x float> %x, <4 x float> %y) { ; CHECK-NEXT: i32x4.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} ; CHECK-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $pop[[L3]]{{$}} ; CHECK-NEXT: return $pop[[R]]{{$}} -define <4 x float> @select_v4f32(i1 %c, <4 x float> %x, <4 x float> %y) { +define <4 x float> @select_v4f32(i1 zeroext %c, <4 x float> %x, <4 x float> %y) { %res = select i1 %c, <4 x float> %x, <4 x float> %y ret <4 x float> %res } @@ -383,7 +383,7 @@ define <2 x double> @vselect_v2f64(<2 x i1> %c, <2 x double> %x, <2 x double> %y ; CHECK-NEXT: i64x2.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} ; CHECK-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $pop[[L3]]{{$}} ; CHECK-NEXT: return $pop[[R]]{{$}} -define <2 x double> @select_v2f64(i1 %c, <2 x double> %x, <2 x double> %y) { +define <2 x double> @select_v2f64(i1 zeroext %c, <2 x double> %x, <2 x double> %y) { %res = select i1 %c, <2 x double> %x, <2 x double> %y ret <2 x double> %res } From 8eb2ef13b790b7f3b40065f2e46a5119b2b81490 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 26 Feb 2019 16:19:38 +0000 Subject: [PATCH 176/274] Add note on libFuzzer for Windows to release notes By Jonathan Metzman! Differential revision: https://reviews.llvm.org/D58676 llvm-svn: 354892 --- llvm/docs/ReleaseNotes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index eafe1f17f7600..f7b3ef4ac2b30 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -80,6 +80,8 @@ Non-comprehensive list of changes in this release available in the `RFC `_. +* Windows support for libFuzzer (x86_64). + .. NOTE If you would like to document a larger change, then you can add a subsection about it right here. You can copy the following boilerplate From 992552edc2c501391dfde659c13e224ab168021d Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 27 Feb 2019 10:14:58 +0000 Subject: [PATCH 177/274] Merging r354207: ------------------------------------------------------------------------ r354207 | whitequark | 2019-02-16 23:33:10 +0100 (Sat, 16 Feb 2019) | 16 lines [bindings/go] Fix building on 32-bit systems (ARM etc.) Summary: The patch in https://reviews.llvm.org/D53883 (by me) fails to build on 32-bit systems like ARM. Fix the array size to be less ridiculously large. 2<<20 should still be enough for all practical purposes. Bug: https://bugs.llvm.org/show_bug.cgi?id=40426 Reviewers: whitequark, pcc Reviewed By: whitequark Subscribers: javed.absar, kristof.beyls, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D58030 ------------------------------------------------------------------------ llvm-svn: 354956 --- llvm/bindings/go/llvm/ir.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/bindings/go/llvm/ir.go b/llvm/bindings/go/llvm/ir.go index 1872a2ffe5109..3e85137a751a0 100644 --- a/llvm/bindings/go/llvm/ir.go +++ b/llvm/bindings/go/llvm/ir.go @@ -1263,7 +1263,7 @@ func (v Value) Indices() []uint32 { num := C.LLVMGetNumIndices(v.C) indicesPtr := C.LLVMGetIndices(v.C) // https://github.com/golang/go/wiki/cgo#turning-c-arrays-into-go-slices - rawIndices := (*[1 << 30]C.uint)(unsafe.Pointer(indicesPtr))[:num:num] + rawIndices := (*[1 << 20]C.uint)(unsafe.Pointer(indicesPtr))[:num:num] indices := make([]uint32, num) for i := range indices { indices[i] = uint32(rawIndices[i]) From 1733050f7b074f0cc67c90e8fc9c4f15d5446e28 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 27 Feb 2019 13:02:26 +0000 Subject: [PATCH 178/274] Re-generate attribute docs llvm-svn: 354967 --- clang/docs/AttributeReference.rst | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/clang/docs/AttributeReference.rst b/clang/docs/AttributeReference.rst index 01938f64f56c1..c502af1217aa4 100644 --- a/clang/docs/AttributeReference.rst +++ b/clang/docs/AttributeReference.rst @@ -1317,6 +1317,46 @@ The ``ifunc`` attribute may only be used on a function declaration. A function Not all targets support this attribute. ELF target support depends on both the linker and runtime linker, and is available in at least lld 4.0 and later, binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later. Non-ELF targets currently do not support this attribute. +import_module +------------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``import_module``","``clang::import_module``","``clang::import_module``","","","","Yes" + +Clang supports the ``__attribute__((import_module()))`` +attribute for the WebAssembly target. This attribute may be attached to a +function declaration, where it modifies how the symbol is to be imported +within the WebAssembly linking environment. + +WebAssembly imports use a two-level namespace scheme, consisting of a module +name, which typically identifies a module from which to import, and a field +name, which typically identifies a field from that module to import. By +default, module names for C/C++ symbols are assigned automatically by the +linker. This attribute can be used to override the default behavior, and +reuqest a specific module name be used instead. + + +import_name +----------- +.. csv-table:: Supported Syntaxes + :header: "GNU", "C++11", "C2x", "``__declspec``", "Keyword", "``#pragma``", "``#pragma clang attribute``" + + "``import_name``","``clang::import_name``","``clang::import_name``","","","","Yes" + +Clang supports the ``__attribute__((import_name()))`` +attribute for the WebAssembly target. This attribute may be attached to a +function declaration, where it modifies how the symbol is to be imported +within the WebAssembly linking environment. + +WebAssembly imports use a two-level namespace scheme, consisting of a module +name, which typically identifies a module from which to import, and a field +name, which typically identifies a field from that module to import. By +default, field names for C/C++ symbols are the same as their C/C++ symbol +names. This attribute can be used to override the default behavior, and +reuqest a specific field name be used instead. + + internal_linkage ---------------- .. csv-table:: Supported Syntaxes From 6b486a44ff7a7cc09672ca9726169070dcae95d2 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 27 Feb 2019 13:12:14 +0000 Subject: [PATCH 179/274] Merging r354968: ------------------------------------------------------------------------ r354968 | hans | 2019-02-27 14:11:37 +0100 (Wed, 27 Feb 2019) | 1 line AttrDocs.td: fix broken bullet-point indentation ------------------------------------------------------------------------ llvm-svn: 354970 --- clang/include/clang/Basic/AttrDocs.td | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 94c8343d2368f..ff1905f685d7c 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3821,13 +3821,13 @@ The ``gnu_inline`` changes the meaning of ``extern inline`` to use GNU inline semantics, meaning: * If any declaration that is declared ``inline`` is not declared ``extern``, -then the ``inline`` keyword is just a hint. In particular, an out-of-line -definition is still emitted for a function with external linkage, even if all -call sites are inlined, unlike in C99 and C++ inline semantics. + then the ``inline`` keyword is just a hint. In particular, an out-of-line + definition is still emitted for a function with external linkage, even if all + call sites are inlined, unlike in C99 and C++ inline semantics. * If all declarations that are declared ``inline`` are also declared -``extern``, then the function body is present only for inlining and no -out-of-line version is emitted. + ``extern``, then the function body is present only for inlining and no + out-of-line version is emitted. Some important consequences: ``static inline`` emits an out-of-line version if needed, a plain ``inline`` definition emits an out-of-line version From 8e077e9f58986db3b7338242d310bc8ed62be03c Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 27 Feb 2019 13:12:48 +0000 Subject: [PATCH 180/274] Re-generate AttributeReference.rst again llvm-svn: 354971 --- clang/docs/AttributeReference.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/docs/AttributeReference.rst b/clang/docs/AttributeReference.rst index c502af1217aa4..ce7a0f3cca860 100644 --- a/clang/docs/AttributeReference.rst +++ b/clang/docs/AttributeReference.rst @@ -1274,13 +1274,13 @@ The ``gnu_inline`` changes the meaning of ``extern inline`` to use GNU inline semantics, meaning: * If any declaration that is declared ``inline`` is not declared ``extern``, -then the ``inline`` keyword is just a hint. In particular, an out-of-line -definition is still emitted for a function with external linkage, even if all -call sites are inlined, unlike in C99 and C++ inline semantics. + then the ``inline`` keyword is just a hint. In particular, an out-of-line + definition is still emitted for a function with external linkage, even if all + call sites are inlined, unlike in C99 and C++ inline semantics. * If all declarations that are declared ``inline`` are also declared -``extern``, then the function body is present only for inlining and no -out-of-line version is emitted. + ``extern``, then the function body is present only for inlining and no + out-of-line version is emitted. Some important consequences: ``static inline`` emits an out-of-line version if needed, a plain ``inline`` definition emits an out-of-line version From ec4aab6167ab950a415e3ac1b1e9b86b09e74527 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 27 Feb 2019 13:54:21 +0000 Subject: [PATCH 181/274] ReleaseNotes: add Known Issues, clean up, etc. llvm-svn: 354973 --- llvm/docs/ReleaseNotes.rst | 61 +++++++++++--------------------------- 1 file changed, 17 insertions(+), 44 deletions(-) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index f7b3ef4ac2b30..3007a1bcf78bf 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -12,7 +12,7 @@ This document contains the release notes for the LLVM Compiler Infrastructure, release 8.0.0. Here we describe the status of LLVM, including major improvements from the previous release, improvements in various subprojects of LLVM, and some of the current users of the code. All LLVM releases may be downloaded -from the `LLVM releases web site `_. +from the `LLVM releases web site `_. For more information about LLVM, including information about the latest release, please check out the `main LLVM web site `_. If you @@ -39,14 +39,19 @@ setting the ``LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN`` CMake variable to ``ON``. +Known Issues +============ + +These are issues that couldn't be fixed before the release. See the bug reports +for the latest status. + +* `PR40547 `_ Clang gets miscompiled by trunk GCC. + +* `PR40761 `_ "asan-dynamic" doesn't work on FreeBSD. + + Non-comprehensive list of changes in this release ================================================= -.. NOTE - For small 1-3 sentence descriptions, just add an entry at the end of - this list. If your description won't fit comfortably in one bullet - point (e.g. maybe you would like to give an example of the - functionality, or simply have a lot to talk about), see the `NOTE` below - for adding a new subsection. * The **llvm-cov** tool can now export lcov trace files using the `-format=lcov` option of the `export` command. @@ -82,16 +87,6 @@ Non-comprehensive list of changes in this release * Windows support for libFuzzer (x86_64). -.. NOTE - If you would like to document a larger change, then you can add a - subsection about it right here. You can copy the following boilerplate - and un-indent it (the indentation causes it to be inside this comment). - - Special New Feature - ------------------- - - Makes programs 10x faster by doing Special New Thing. - Changes to the LLVM IR ---------------------- @@ -112,17 +107,12 @@ Changes to the AArch64 Target on ARM. -Changes to the ARM Backend --------------------------- - - During this release ... - - Changes to the Hexagon Target ----------------------------- * Added support for Hexagon/HVX V66 ISA. + Changes to the MIPS Target -------------------------- @@ -144,6 +134,7 @@ Changes to the MIPS Target * Numerous bug fixes and code cleanups. + Changes to the PowerPC Target ----------------------------- @@ -155,7 +146,7 @@ Changes to the PowerPC Target * Better overload rules for compatible vector type parameter -* Support constraint ‘wi’, modifier ‘x’ and VSX registers in inline asm +* Support constraint 'wi', modifier 'x' and VSX registers in inline asm * More ``__float128`` support @@ -200,15 +191,6 @@ Changes to the X86 Target * ADCX instruction will no longer be emitted. This instruction is rarely better than the legacy ADC instruction and just increased code size. -Changes to the AMDGPU Target ------------------------------ - - During this release ... - -Changes to the AVR Target ------------------------------ - - During this release ... Changes to the WebAssembly Target --------------------------------- @@ -222,25 +204,16 @@ use for it will be to add support for returning small structs as multiple return values, once the underlying WebAssembly platform itself supports it. Additionally, multithreading support is not yet included in the stable ABI. + Changes to the Nios2 Target --------------------------- * The Nios2 target was removed from this release. -Changes to the OCaml bindings ------------------------------ - - - -Changes to the C API --------------------- - - -Changes to the DAG infrastructure ---------------------------------- Changes to LLDB =============== + * Printed source code is now syntax highlighted in the terminal (only for C languages). From 566608315c7d59a0676e3682b2a41178cea90d8c Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 27 Feb 2019 14:29:40 +0000 Subject: [PATCH 182/274] ReleaseNotes: tidy up llvm-svn: 354977 --- clang/docs/ReleaseNotes.rst | 112 ++++-------------------------------- 1 file changed, 10 insertions(+), 102 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 65ab1314d3744..e6892203f4571 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -17,8 +17,8 @@ describe the status of Clang in some detail, including major improvements from the previous release and new feature work. For the general LLVM release notes, see `the LLVM documentation `_. All LLVM -releases may be downloaded from the `LLVM releases web -site `_. +releases may be downloaded +from the `LLVM releases web site `_. For more information about Clang or LLVM, including information about the latest release, please see the `Clang Web Site `_ or the @@ -175,23 +175,13 @@ New Compiler Flags be controlled by the ``-mrelax-pic-calls`` and ``-mno-relax-pic-calls`` options. -- ... - -Deprecated Compiler Flags -------------------------- - -The following options are deprecated and ignored. They will be removed in -future versions of Clang. - -- ... - Modified Compiler Flags ----------------------- -- As of clang 8, `alignof` and `_Alignof` return the ABI alignment of a type, - as opposed to the preferred alignment. `__alignof` still returns the - preferred alignment. `-fclang-abi-compat=7` (and previous) will make - `alignof` and `_Alignof` return preferred alignment again. +- As of clang 8, ``alignof`` and ``_Alignof`` return the ABI alignment of a type, + as opposed to the preferred alignment. ``__alignof`` still returns the + preferred alignment. ``-fclang-abi-compat=7`` (and previous) will make + ``alignof`` and ``_Alignof`` return preferred alignment again. New Pragmas in Clang @@ -233,33 +223,6 @@ Windows Support target is in pretty good shape now. -C Language Changes in Clang ---------------------------- - -- ... - -... - -C11 Feature Support -^^^^^^^^^^^^^^^^^^^ - -... - -C++ Language Changes in Clang ------------------------------ - -- ... - -C++1z Feature Support -^^^^^^^^^^^^^^^^^^^^^ - -... - -Objective-C Language Changes in Clang -------------------------------------- - -... - OpenCL Kernel Language Changes in Clang --------------------------------------- @@ -318,17 +281,17 @@ C++ for OpenCL: ABI Changes in Clang -------------------- -- `_Alignof` and `alignof` now return the ABI alignment of a type, as opposed +- ``_Alignof`` and ``alignof`` now return the ABI alignment of a type, as opposed to the preferred alignment. - This is more in keeping with the language of the standards, as well as being compatible with gcc - - `__alignof` and `__alignof__` still return the preferred alignment of + - ``__alignof`` and ``__alignof__`` still return the preferred alignment of a type - This shouldn't break any ABI except for things that explicitly ask for - `alignas(alignof(T))`. + ``alignas(alignof(T))``. - If you have interfaces that break with this change, you may wish to switch - to `alignas(__alignof(T))`, instead of using the `-fclang-abi-compat` + to ``alignas(__alignof(T))``, instead of using the ``-fclang-abi-compat`` switch. OpenMP Support in Clang @@ -365,42 +328,6 @@ New features supported for Cuda devices: - General performance improvement. -CUDA Support in Clang ---------------------- - - -Internal API Changes --------------------- - -These are major API changes that have happened since the 7.0.0 release of -Clang. If upgrading an external codebase that uses Clang as a library, -this section should help get you past the largest hurdles of upgrading. - -- ... - -AST Matchers ------------- - -- ... - -clang-format ------------- - - -- ... - -libclang --------- - -... - - -Static Analyzer ---------------- - -- ... - -... .. _release-notes-ubsan: @@ -477,25 +404,6 @@ Undefined Behavior Sanitizer (UBSan) data[x] *= data[x]; } -Core Analysis Improvements -========================== - -- ... - -New Issues Found -================ - -- ... - -Python Binding Changes ----------------------- - -The following methods have been added: - -- ... - -Significant Known Problems -========================== Additional Information ====================== From b02e2366c7d1eede659c479ad372aa60f1e7fc23 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 27 Feb 2019 14:51:08 +0000 Subject: [PATCH 183/274] ReleaseNotes: tidy up (clangd notes are still expected) llvm-svn: 354979 --- clang-tools-extra/docs/ReleaseNotes.rst | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 09445ae21592f..da3097d03e127 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -14,8 +14,8 @@ Introduction This document contains the release notes for the Extra Clang Tools, part of the Clang release 8.0.0. Here we describe the status of the Extra Clang Tools in some detail, including major improvements from the previous release and new -feature work. All LLVM releases may be downloaded from the `LLVM releases web -site `_. +feature work. All LLVM releases may be downloaded +from the `LLVM releases web site `_. For more information about Clang or LLVM, including information about the latest release, please see the `Clang Web Site `_ or @@ -28,20 +28,12 @@ Some of the major new features and improvements to Extra Clang Tools are listed here. Generic improvements to Extra Clang Tools as a whole or to its underlying infrastructure are described first, followed by tool-specific sections. -Major New Features ------------------- - -... Improvements to clangd ---------------------- The improvements are... -Improvements to clang-doc -------------------------- - -The improvements are... Improvements to clang-query --------------------------- @@ -291,13 +283,3 @@ Improvements to clang-tidy - The :doc:`readability-uppercase-literal-suffix ` check does not warn about literal suffixes inside macros anymore by default. - -Improvements to include-fixer ------------------------------ - -The improvements are... - -Improvements to modularize --------------------------- - -The improvements are... From a4fc3887e7837406e3fd8a46400d958abbcc240e Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 27 Feb 2019 14:52:42 +0000 Subject: [PATCH 184/274] Merging r353422: ------------------------------------------------------------------------ r353422 | kadircet | 2019-02-07 17:04:30 +0100 (Thu, 07 Feb 2019) | 18 lines [clangd] Reduce number of threads used by BackgroundIndex to number of physical cores. Summary: clangd is using as many threads as logical cores for BackgroundIndex by default. We observed that it increases latency of foreground tasks. This patch aims to change that default to number of physical cores to get rid of that extra latency. Reviewers: ilya-biryukov Reviewed By: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57819 ------------------------------------------------------------------------ llvm-svn: 354980 --- clang-tools-extra/clangd/index/Background.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/clangd/index/Background.h b/clang-tools-extra/clangd/index/Background.h index 81675be55b5a0..ffa83e60d826d 100644 --- a/clang-tools-extra/clangd/index/Background.h +++ b/clang-tools-extra/clangd/index/Background.h @@ -68,11 +68,12 @@ class BackgroundIndex : public SwapIndex { /// If BuildIndexPeriodMs is greater than 0, the symbol index will only be /// rebuilt periodically (one per \p BuildIndexPeriodMs); otherwise, index is /// rebuilt for each indexed file. - BackgroundIndex(Context BackgroundContext, const FileSystemProvider &, - const GlobalCompilationDatabase &CDB, - BackgroundIndexStorage::Factory IndexStorageFactory, - size_t BuildIndexPeriodMs = 0, - size_t ThreadPoolSize = llvm::hardware_concurrency()); + BackgroundIndex( + Context BackgroundContext, const FileSystemProvider &, + const GlobalCompilationDatabase &CDB, + BackgroundIndexStorage::Factory IndexStorageFactory, + size_t BuildIndexPeriodMs = 0, + size_t ThreadPoolSize = llvm::heavyweight_hardware_concurrency()); ~BackgroundIndex(); // Blocks while the current task finishes. // Enqueue translation units for indexing. From c57a1fccff9056f31f327aee6fdfd398b3a4c8a4 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 27 Feb 2019 14:56:14 +0000 Subject: [PATCH 185/274] Merging r354505: ------------------------------------------------------------------------ r354505 | ibiryukov | 2019-02-20 20:08:06 +0100 (Wed, 20 Feb 2019) | 13 lines [clangd] Store index in '.clangd/index' instead of '.clangd-index' Summary: To take up the .clangd folder for other potential uses in the future. Reviewers: kadircet, sammccall Reviewed By: kadircet Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58440 ------------------------------------------------------------------------ llvm-svn: 354981 --- llvm/.gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/.gitignore b/llvm/.gitignore index 0aa0a8a80a966..be58944c9b3a1 100644 --- a/llvm/.gitignore +++ b/llvm/.gitignore @@ -72,6 +72,8 @@ docs/_build # VS2017 and VSCode config files. .vscode .vs +# clangd index +.clangd #==============================================================================# # Files created in tree by the Go bindings. From 3043a72f815b2dbafbdeb9df26522da00e50ec1d Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 27 Feb 2019 14:56:39 +0000 Subject: [PATCH 186/274] Merging r354505: ------------------------------------------------------------------------ r354505 | ibiryukov | 2019-02-20 20:08:06 +0100 (Wed, 20 Feb 2019) | 13 lines [clangd] Store index in '.clangd/index' instead of '.clangd-index' Summary: To take up the .clangd folder for other potential uses in the future. Reviewers: kadircet, sammccall Reviewed By: kadircet Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58440 ------------------------------------------------------------------------ llvm-svn: 354982 --- clang-tools-extra/clangd/index/Background.h | 2 +- clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp | 8 ++++---- clang-tools-extra/test/clangd/background-index.test | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/clang-tools-extra/clangd/index/Background.h b/clang-tools-extra/clangd/index/Background.h index ffa83e60d826d..4978ccb77f521 100644 --- a/clang-tools-extra/clangd/index/Background.h +++ b/clang-tools-extra/clangd/index/Background.h @@ -55,7 +55,7 @@ class BackgroundIndexStorage { llvm::unique_function; // Creates an Index Storage that saves shards into disk. Index storage uses - // CDBDirectory + ".clangd-index/" as the folder to save shards. + // CDBDirectory + ".clangd/index/" as the folder to save shards. static Factory createDiskBackedStorageFactory(); }; diff --git a/clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp b/clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp index a83bec6f27dbe..b75944785ee50 100644 --- a/clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp +++ b/clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp @@ -64,19 +64,19 @@ writeAtomically(llvm::StringRef OutPath, } // Uses disk as a storage for index shards. Creates a directory called -// ".clangd-index/" under the path provided during construction. +// ".clangd/index/" under the path provided during construction. class DiskBackedIndexStorage : public BackgroundIndexStorage { std::string DiskShardRoot; public: - // Sets DiskShardRoot to (Directory + ".clangd-index/") which is the base + // Sets DiskShardRoot to (Directory + ".clangd/index/") which is the base // directory for all shard files. DiskBackedIndexStorage(llvm::StringRef Directory) { llvm::SmallString<128> CDBDirectory(Directory); - llvm::sys::path::append(CDBDirectory, ".clangd-index/"); + llvm::sys::path::append(CDBDirectory, ".clangd", "index"); DiskShardRoot = CDBDirectory.str(); std::error_code OK; - std::error_code EC = llvm::sys::fs::create_directory(DiskShardRoot); + std::error_code EC = llvm::sys::fs::create_directories(DiskShardRoot); if (EC != OK) { elog("Failed to create directory {0} for index storage: {1}", DiskShardRoot, EC.message()); diff --git a/clang-tools-extra/test/clangd/background-index.test b/clang-tools-extra/test/clangd/background-index.test index 34c419ac68299..1d11736dfe821 100644 --- a/clang-tools-extra/test/clangd/background-index.test +++ b/clang-tools-extra/test/clangd/background-index.test @@ -13,7 +13,7 @@ # RUN: clangd -background-index -background-index-rebuild-period=0 -lit-test < %t/definition.jsonrpc | FileCheck %t/definition.jsonrpc # Test that the index is writing files in the expected location. -# RUN: ls %t/.clangd-index/foo.cpp.*.idx +# RUN: ls %t/.clangd/index/foo.cpp.*.idx # Test the index is read from disk: delete code and restart clangd. # RUN: rm %t/foo.cpp From c6a1d4911033dab6e0fd44dcd95834f4f32281d6 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 27 Feb 2019 14:57:46 +0000 Subject: [PATCH 187/274] Merging r354765: ------------------------------------------------------------------------ r354765 | kadircet | 2019-02-25 10:19:26 +0100 (Mon, 25 Feb 2019) | 9 lines [clangd] Add thread priority lowering for MacOS as well Reviewers: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58492 ------------------------------------------------------------------------ llvm-svn: 354983 --- clang-tools-extra/clangd/Threading.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/clang-tools-extra/clangd/Threading.cpp b/clang-tools-extra/clangd/Threading.cpp index 139fcc2f878d9..695e30d8aed94 100644 --- a/clang-tools-extra/clangd/Threading.cpp +++ b/clang-tools-extra/clangd/Threading.cpp @@ -7,6 +7,8 @@ #include #ifdef __USE_POSIX #include +#elif defined(__APPLE__) +#include #endif namespace clang { @@ -121,6 +123,12 @@ void setCurrentThreadPriority(ThreadPriority Priority) { Priority == ThreadPriority::Low && !AvoidThreadStarvation ? SCHED_IDLE : SCHED_OTHER, &priority); +#elif defined(__APPLE__) + // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getpriority.2.html + setpriority(PRIO_DARWIN_THREAD, 0, + Priority == ThreadPriority::Low && !AvoidThreadStarvation + ? PRIO_DARWIN_BG + : 0); #endif } From e811d1186477411c91ee3c78c0696099ab77f95b Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 27 Feb 2019 14:58:48 +0000 Subject: [PATCH 188/274] Merging r354957: ------------------------------------------------------------------------ r354957 | ibiryukov | 2019-02-27 11:16:03 +0100 (Wed, 27 Feb 2019) | 11 lines [clangd] Set thread priority on Windows Reviewers: kadircet, gribozavr Reviewed By: kadircet, gribozavr Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58683 ------------------------------------------------------------------------ llvm-svn: 354984 --- clang-tools-extra/clangd/Threading.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clang-tools-extra/clangd/Threading.cpp b/clang-tools-extra/clangd/Threading.cpp index 695e30d8aed94..733267c0e706c 100644 --- a/clang-tools-extra/clangd/Threading.cpp +++ b/clang-tools-extra/clangd/Threading.cpp @@ -9,6 +9,8 @@ #include #elif defined(__APPLE__) #include +#elif defined (_WIN32) +#include #endif namespace clang { @@ -129,6 +131,11 @@ void setCurrentThreadPriority(ThreadPriority Priority) { Priority == ThreadPriority::Low && !AvoidThreadStarvation ? PRIO_DARWIN_BG : 0); +#elif defined(_WIN32) + SetThreadPriority(GetCurrentThread(), + Priority == ThreadPriority::Low && !AvoidThreadStarvation + ? THREAD_MODE_BACKGROUND_BEGIN + : THREAD_MODE_BACKGROUND_END); #endif } From 06a9d7d2c6688623201a4511d4ad0884679f714d Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 27 Feb 2019 15:01:51 +0000 Subject: [PATCH 189/274] ReleaseNotes: remove another empty section llvm-svn: 354985 --- clang-tools-extra/docs/ReleaseNotes.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index da3097d03e127..a9a9c563ba915 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -80,11 +80,6 @@ Improvements to clang-query disable output detailed-ast m functionDecl() -Improvements to clang-rename ----------------------------- - -The improvements are... - Improvements to clang-tidy -------------------------- From 8c0e32b84d947a00b9689ff5bd1d01447064a71e Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 27 Feb 2019 15:03:56 +0000 Subject: [PATCH 190/274] ReleaseNotes: tidy up llvm-svn: 354986 --- libcxx/docs/ReleaseNotes.rst | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst index c6db1e7683430..ca5a534ae846e 100644 --- a/libcxx/docs/ReleaseNotes.rst +++ b/libcxx/docs/ReleaseNotes.rst @@ -16,7 +16,7 @@ part of the LLVM Compiler Infrastructure, release 8.0.0. Here we describe the status of libc++ in some detail, including major improvements from the previous release and new feature work. For the general LLVM release notes, see `the LLVM documentation `_. All LLVM releases may -be downloaded from the `LLVM releases web site `_. +be downloaded from the `LLVM releases web site `_. For more information about libc++, please see the `Libc++ Web Site `_ or the `LLVM Web Site `_. @@ -24,9 +24,6 @@ For more information about libc++, please see the `Libc++ Web Site What's New in Libc++ 8.0.0? =========================== -New Features ------------- - API Changes ----------- - Building libc++ for Mac OSX 10.6 is not supported anymore. From f7be79e540b1bee4cbc57d733322b7164ae66d73 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 27 Feb 2019 16:18:46 +0000 Subject: [PATCH 191/274] Merging r354777, r354778, r354779, r354786, r354865, and r354992 ------------------------------------------------------------------------ r354777 | gribozavr | 2019-02-25 13:48:52 +0100 (Mon, 25 Feb 2019) | 9 lines Removed an unhelpful comment in index.rst Reviewers: ilya-biryukov Subscribers: arphaman, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58602 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r354778 | gribozavr | 2019-02-25 13:49:27 +0100 (Mon, 25 Feb 2019) | 7 lines Fixed grammar in index.rst Subscribers: arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58601 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r354779 | gribozavr | 2019-02-25 14:03:44 +0100 (Mon, 25 Feb 2019) | 9 lines Updated the documentation build instructions for the current CMake build system Reviewers: ilya-biryukov Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58603 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r354786 | gribozavr | 2019-02-25 14:43:48 +0100 (Mon, 25 Feb 2019) | 9 lines Moved clangd docs to a separate directory in preparation to restructure them into multiple files Reviewers: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58607 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r354865 | kadircet | 2019-02-26 12:08:04 +0100 (Tue, 26 Feb 2019) | 11 lines [clangd] Update docs to mention YCM integration and new LSP features Reviewers: gribozavr Reviewed By: gribozavr Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D56718 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r354992 | gribozavr | 2019-02-27 16:53:05 +0100 (Wed, 27 Feb 2019) | 13 lines Added more detailed documentation for clangd Summary: The text was written mostly by Sam McCall, screenshots are mostly made by me. Reviewers: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58710 ------------------------------------------------------------------------ llvm-svn: 354997 --- clang-tools-extra/docs/README.txt | 15 +- .../docs/_static/clang-tools-extra-styles.css | 23 ++ clang-tools-extra/docs/_templates/layout.html | 3 + clang-tools-extra/docs/clangd.rst | 162 +------- .../docs/clangd/ApplyClangTidyFixInVSCode.gif | Bin 0 -> 95232 bytes .../docs/clangd/ApplyFixInVSCode.gif | Bin 0 -> 73814 bytes .../CodeCompletionInEmacsCompanyMode.png | Bin 0 -> 10480 bytes .../clangd/CodeCompletionInSublimeText.png | Bin 0 -> 19894 bytes .../docs/clangd/CodeCompletionInVSCode.png | Bin 0 -> 15094 bytes .../docs/clangd/CodeCompletionInYCM.png | Bin 0 -> 17028 bytes ...tionInsertsNamespaceQualifiersInVSCode.gif | Bin 0 -> 110759 bytes .../docs/clangd/DeveloperDocumentation.rst | 29 ++ .../docs/clangd/DiagnosticsInEmacsEglot.png | Bin 0 -> 16634 bytes .../docs/clangd/ErrorsInVSCode.png | Bin 0 -> 76993 bytes clang-tools-extra/docs/clangd/Extensions.rst | 173 ++++++++ clang-tools-extra/docs/clangd/Features.rst | 231 +++++++++++ .../docs/clangd/FindAllReferencesInVSCode.gif | Bin 0 -> 76027 bytes .../docs/clangd/FormatSelectionInVSCode.gif | Bin 0 -> 167887 bytes .../docs/clangd/GoToDefinitionInVSCode.gif | Bin 0 -> 123395 bytes .../docs/clangd/Installation.rst | 369 ++++++++++++++++++ .../NavigationWithBreadcrumbsInVSCode.gif | Bin 0 -> 123365 bytes .../docs/clangd/OutlineInVSCode.png | Bin 0 -> 15443 bytes .../docs/clangd/SignatureHelpInVSCode.gif | Bin 0 -> 36923 bytes clang-tools-extra/docs/clangd/index.rst | 27 ++ clang-tools-extra/docs/conf.py | 2 +- clang-tools-extra/docs/index.rst | 10 +- 26 files changed, 867 insertions(+), 177 deletions(-) create mode 100644 clang-tools-extra/docs/_static/clang-tools-extra-styles.css create mode 100644 clang-tools-extra/docs/_templates/layout.html create mode 100644 clang-tools-extra/docs/clangd/ApplyClangTidyFixInVSCode.gif create mode 100644 clang-tools-extra/docs/clangd/ApplyFixInVSCode.gif create mode 100644 clang-tools-extra/docs/clangd/CodeCompletionInEmacsCompanyMode.png create mode 100644 clang-tools-extra/docs/clangd/CodeCompletionInSublimeText.png create mode 100644 clang-tools-extra/docs/clangd/CodeCompletionInVSCode.png create mode 100644 clang-tools-extra/docs/clangd/CodeCompletionInYCM.png create mode 100644 clang-tools-extra/docs/clangd/CodeCompletionInsertsNamespaceQualifiersInVSCode.gif create mode 100644 clang-tools-extra/docs/clangd/DeveloperDocumentation.rst create mode 100644 clang-tools-extra/docs/clangd/DiagnosticsInEmacsEglot.png create mode 100644 clang-tools-extra/docs/clangd/ErrorsInVSCode.png create mode 100644 clang-tools-extra/docs/clangd/Extensions.rst create mode 100644 clang-tools-extra/docs/clangd/Features.rst create mode 100644 clang-tools-extra/docs/clangd/FindAllReferencesInVSCode.gif create mode 100644 clang-tools-extra/docs/clangd/FormatSelectionInVSCode.gif create mode 100644 clang-tools-extra/docs/clangd/GoToDefinitionInVSCode.gif create mode 100644 clang-tools-extra/docs/clangd/Installation.rst create mode 100644 clang-tools-extra/docs/clangd/NavigationWithBreadcrumbsInVSCode.gif create mode 100644 clang-tools-extra/docs/clangd/OutlineInVSCode.png create mode 100644 clang-tools-extra/docs/clangd/SignatureHelpInVSCode.gif create mode 100644 clang-tools-extra/docs/clangd/index.rst diff --git a/clang-tools-extra/docs/README.txt b/clang-tools-extra/docs/README.txt index 4b60777583017..cebbf63bcd6a7 100644 --- a/clang-tools-extra/docs/README.txt +++ b/clang-tools-extra/docs/README.txt @@ -1,11 +1,10 @@ -------------------------------------------------------------- -Documentation for the tools of clang-tools-extra repo project -------------------------------------------------------------- +---------------------------------- +Documentation in clang-tools-extra +---------------------------------- -Sphinx and doxygen documentation is generated by executing make. +To generate documentation in HTML format from files in clang-tools-extra/docs, +build the docs-clang-tools-html target. -Sphinx html files can be generated separately using make html. +To generate documentation from the source code using Doxygen, build the +doxygen-clang-tools target. -Doxygen html files can also be generated using make doxygen. - -The generated documentation will be placed in _build/html. diff --git a/clang-tools-extra/docs/_static/clang-tools-extra-styles.css b/clang-tools-extra/docs/_static/clang-tools-extra-styles.css new file mode 100644 index 0000000000000..1a6cd710e483a --- /dev/null +++ b/clang-tools-extra/docs/_static/clang-tools-extra-styles.css @@ -0,0 +1,23 @@ +details { + background-color: rgba(50, 150, 220, 0.08); + margin-bottom: 0.5em; + padding: 0 1em; + overflow-y: hidden; /* Suppress margin-collapsing */ +} +details[open] { + border-bottom: 1px solid rgba(0, 0, 128, 0.2); + margin-bottom: 1em; +} +details summary { + font-weight: bold; + background-color: rgba(50, 150, 220, 0.1); + border-color: rgba(0, 0, 128, 0.2); + border-width: 1px; + border-style: solid none; + padding: 0.2em; + margin: 0 -1em; +} +details summary:hover { + background-color: rgba(50, 150, 220, 0.2); + cursor: pointer; +} diff --git a/clang-tools-extra/docs/_templates/layout.html b/clang-tools-extra/docs/_templates/layout.html new file mode 100644 index 0000000000000..b4f5b4e1ebd0d --- /dev/null +++ b/clang-tools-extra/docs/_templates/layout.html @@ -0,0 +1,3 @@ +{% extends "!layout.html" %} + +{% set css_files = css_files + ['_static/clang-tools-extra-styles.css'] %} diff --git a/clang-tools-extra/docs/clangd.rst b/clang-tools-extra/docs/clangd.rst index 0b276380000a7..8feca331c5d78 100644 --- a/clang-tools-extra/docs/clangd.rst +++ b/clang-tools-extra/docs/clangd.rst @@ -1,161 +1 @@ -============ -Clangd -============ - -.. contents:: - -.. toctree:: - :maxdepth: 1 - -:program:`Clangd` is an implementation of the `Language Server Protocol -`_ leveraging Clang. -Clangd's goal is to provide language "smartness" features like code completion, -find references, etc. for clients such as C/C++ Editors. - -Using Clangd -================== - -:program:`Clangd` is not meant to be used by C/C++ developers directly but -rather from a client implementing the protocol. A client would be typically -implemented in an IDE or an editor. - -At the moment, `Visual Studio Code `_ is mainly -used in order to test :program:`Clangd` but more clients are likely to make -use of :program:`Clangd` in the future as it matures and becomes a production -quality tool. If you are interested in trying :program:`Clangd` in combination -with Visual Studio Code, you can start by `installing Clangd`_ or -`building Clangd`_, then open Visual Studio Code in the clangd-vscode folder and -launch the extension. - -Installing Clangd -================== - -Packages are available for debian-based distributions, see the `LLVM packages -page `_. :program:`Clangd` is included in the -`clang-tools` package. -However, it is a good idea to check your distribution's packaging system first -as it might already be available. - -Otherwise, you can install :program:`Clangd` by `building Clangd`_ first. - -Building Clangd -================== - -You can follow the instructions for `building Clang -`_ but "extra Clang tools" is **not** -optional. - -Current Status -================== - -Many features could be implemented in :program:`Clangd`. -Here is a list of features that could be useful with the status of whether or -not they are already implemented in :program:`Clangd` and specified in the -Language Server Protocol. Note that for some of the features, it is not clear -whether or not they should be part of the Language Server Protocol, so those -features might be eventually developed outside :program:`Clangd` or as an -extension to the protocol. - -+-------------------------------------+------------+----------+ -| C/C++ Editor feature | LSP | Clangd | -+=====================================+============+==========+ -| Formatting | Yes | Yes | -+-------------------------------------+------------+----------+ -| Completion | Yes | Yes | -+-------------------------------------+------------+----------+ -| Diagnostics | Yes | Yes | -+-------------------------------------+------------+----------+ -| Fix-its | Yes | Yes | -+-------------------------------------+------------+----------+ -| Go to Definition | Yes | Yes | -+-------------------------------------+------------+----------+ -| Signature Help | Yes | Yes | -+-------------------------------------+------------+----------+ -| Document Highlights | Yes | Yes | -+-------------------------------------+------------+----------+ -| Rename | Yes | Yes | -+-------------------------------------+------------+----------+ -| Source hover | Yes | Yes | -+-------------------------------------+------------+----------+ -| Find References | Yes | No | -+-------------------------------------+------------+----------+ -| Code Lens | Yes | No | -+-------------------------------------+------------+----------+ -| Document Symbols | Yes | Yes | -+-------------------------------------+------------+----------+ -| Workspace Symbols | Yes | Yes | -+-------------------------------------+------------+----------+ -| Syntax and Semantic Coloring | No | No | -+-------------------------------------+------------+----------+ -| Code folding | No | No | -+-------------------------------------+------------+----------+ -| Call hierarchy | No | No | -+-------------------------------------+------------+----------+ -| Type hierarchy | No | No | -+-------------------------------------+------------+----------+ -| Organize Includes | No | No | -+-------------------------------------+------------+----------+ -| Quick Assist | No | No | -+-------------------------------------+------------+----------+ -| Extract Local Variable | No | No | -+-------------------------------------+------------+----------+ -| Extract Function/Method | No | No | -+-------------------------------------+------------+----------+ -| Hide Method | No | No | -+-------------------------------------+------------+----------+ -| Implement Method | No | No | -+-------------------------------------+------------+----------+ -| Gen. Getters/Setters | No | No | -+-------------------------------------+------------+----------+ - -Editor Integration -================== - -Any full-featured Language Server Protocol Client implementation should work -with :program:`Clangd`. This `list -`_ contains information about -extensions and plugins that are known to work for different editors. - -Vim Integration ---------------- - -LanguageClient-neovim -~~~~~~~~~~~~~~~~~~~~~ - -One of the options of using :program:`Clangd` in :program:`vim` (or -:program:`nvim`) is to utilize `LanguageClient-neovim -`_ plugin. Please see the -`Clangd Wiki page -`_ for -instructions. - -VSCode Integration ------------------- - -:program:`VSCode` provides `vscode-clangd -`_ -which is published in Visual Studio Marketplace and can be installed direcetly -from :program:`VSCode`. - -Emacs Integration ------------------ - -:program:`Emacs` provides `lsp-mode `_ and -`Eglot `_ plugins for LSP integration. - -Getting Involved -================== - -A good place for interested contributors is the `Clangd developer mailing list -`_. For discussions with the -broader community on topics not only related to Clangd, use -`Clang developer mailing list -`_. -If you're also interested in contributing patches to :program:`Clangd`, take a -look at the `LLVM Developer Policy -`_ and `Code Reviews -`_ page. Contributions of new features -to the `Language Server Protocol -`_ itself would also be -very useful, so that :program:`Clangd` can eventually implement them in a -conforming way. +:orphan: diff --git a/clang-tools-extra/docs/clangd/ApplyClangTidyFixInVSCode.gif b/clang-tools-extra/docs/clangd/ApplyClangTidyFixInVSCode.gif new file mode 100644 index 0000000000000000000000000000000000000000..b07bdeb437df29d1f93f62735de37bdbd3e8dbf9 GIT binary patch literal 95232 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 literal 0 HcmV?d00001 diff --git a/clang-tools-extra/docs/clangd/ApplyFixInVSCode.gif b/clang-tools-extra/docs/clangd/ApplyFixInVSCode.gif new file mode 100644 index 0000000000000000000000000000000000000000..929a98c31798ea5547c47ee804e92852e9ada70f GIT binary patch literal 73814 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 Q5Fg1yM$pOsYbgA`0Rbe;W&i*H literal 0 HcmV?d00001 diff --git a/clang-tools-extra/docs/clangd/CodeCompletionInEmacsCompanyMode.png b/clang-tools-extra/docs/clangd/CodeCompletionInEmacsCompanyMode.png new file mode 100644 index 0000000000000000000000000000000000000000..1accc5af57713ea28282ead0bbfe5d20384bef1e GIT binary patch literal 10480 zcmdT~V{;}zkdAHJ*x0sh+qTV(?TxvylZ|aVd1Kq!ym4}Sb$3TnNyV&@Y|ktth!!v0dS{ttI@^YTE*=_Smdy znQaAx12kNgd#Gunf=T>tnFpo6b}31dk|4k%lFqhMBTwgMo>3c+6Lrs2optD|`kbv}2)R z68kwfkzZQ4m7E)4g2UP0dV*HAZNhhjJHoaw_Im$lC;;Aw26OQ z@e@@m@S&sX6wu}AbV^(Y#f{sUDu>h*4b~$RmrcR|&nyWRX<5`LkHa3uv?v!~;_zza zFe&;|{Oat0_mGwOSAGFr6|e-(pzf(9Tx_*a0aA%i7<#iv>onE+j<2RcC5je za#3#H1q_fU>gY!xpZfd!DAA#$@rEroE?mtH!4aGe%N$PxQ{+OPq17V&=4G0^sD4ICMx#pJU#y{*fR=8htsZ)@YjvtSYgVng=j!eTY8w`X3mxx_M*sN0{nPyq{n{)487Badf;;aim+6oqr zt6slZE#yePK;aXc+|-zm>2zBb%ogi#VkA<2Sf6kd%e?^n%_lZ`xVa8g;i?VHu=7P7DOnQ1npfOM?E~Kx+{O?`Y9%7YRFC$t6a+dO%#eko z8Nh{eeHmzXTcWFf4oVl(h{Y3t=y%Nqe(GXG@W(8It>h=u%Ty8R=-I7LQL343Gt z^6FwRA+ZAs-Dqq6iNWu3ar!SrF+o=LJ?S)K8kc#5|IpT!yvq^#Df}|yit|MWhb)qh z^%uY^z(9U-((;~x!6&zj?w9@a<{z0iJ+H;F2s_6Ctt1EqT-(B3%i)Bmvw5>-0>#%L zKXnF5JT%o?T?t_gJ~VPRy~VuLUcG?G(lVj&Xs!=}#$jkb^NR?M_T%`xI5?jdv!bIh zrD4stl2-%2VLys0t3aBPHbc4r1y}p03`z6x0A7fCO9qV`HM$xhg=0ey!{4NL=I1&>kZO{(O7&SAt_6heto&`r47O% ztIp*?E%?_K-)}pVU};imZ2lq$IFN zr>Y0>d@9ULbAUpJ(&4d?c@aD-BY{1}h0QmcqUAsAUuk5`(SXp1(ap}n8*=p<>mm8U zsHBhcP15G`eX^CwK7nQ{V>)ftSd!S47suHe?^h2seYghUfJKXI5?I#Ge$?0VEoXlu zR99dACviLxu8+>s)*%l)BUk?mer}qnPQDlT9s8(C_LJ#$%bmL{@R^9HN+21?vyj;- zE^MHnuM@j;Yj!H*-v>3o;~a!23Yl8hHyqRqJ$XX*5C z>zl-VEStEW={9mbvln`M(B%S2b@;3g<%XsmgVCZmrjRz1e$tzf8Q&h)S4aoJW%4IP zMxNZjBSO;z=#k)>zti2sLQ=>} z1yX#9vjokz)NtnYfgkLX=kl5{xPkgpNN6Bmzvdl#wcf;p8kYQkTfP8hAA)~QWZXzv zJLVJD6$+QXBUW;#@f>89FoGDqIbvTwpZ(9jqwJwtiCad=rJ54S`kpLGu|!iI$WNeE zQ4D#_Dbjov3pB8kn9<$S>@Ym3&Btv(bMw>J|P$lT-c2O5eoW)8-JUPk6A zI4t>14|Ftpb+2x&^3&YuBs(7xQQu)0Tw_VP{UY!8{58GKdlAMoXci#Q2=6>agHPz|` zvR7Eu%Z}CZ5M63Hb{}09G9}RAnCo~5^}0OWURMzWb%+6iQc*kT)sBC)m-dw6HB|gc zK&@!?zFIglzQlv8UyDM$W8CeUEICBZx)QZ)9Hg8z=UBam&5@?VI zOoq8y$Y#I4{;i9>*_<_Xv5x4|>Ew379HfC*kkO^1YZ}mdy+0xc<5Ya*p~l77&UAji zhBVXr+WI}VeeF%t*yj+hp<*z-{ocK~PWrhM4UdX;2qjUDH{5g!bh$ceZEE7j{(fVK zW}IDXIN1!Jo7}*NJ!Ln!N*i(FsAP)U_3}RL-mH8;7axAJfAah|MqfS(`q|~)a(eQ6 z$DrY>9)z_DC8xzplK#&1I%;M0x_Vo|_y328gx?b&*BWxbcE{LW|jCr4!B zRSf!M1Zk^>-S>ToWlP=MRKm;Wt`)7n#(~6CkcJL`l{6kG3gJ!#d!@)G>2O)lcXRra zI(2V(+QZomKg&cHcwWMAd)GeGm8ZXYwcOovS&-VrBHqz7glgZFMJE-o&Fwp}YDILn zg*E#GJc$OK zm~?6O&xV0!js-^TpRVtQfkughKA-0&0&sX3TJbzNmN^_5HgsBD!%|j)@YC|xI^I1T z-ZNYGp|_<#7y3wCH7oyPoL2kiB9gkX(4x;SH#xeiR6}i=Y_bXy9X0g}BLfI`N?3Zf zdVuFh8xuVbP=3*C*GJRv{$TJU6T zpmEt;We>>Q`h*Uo`?U$5T%15hjchl|hoL_0u;$U(^~3l*zkn#oEu<*Xr%q|Ks|Ue| z-Qk+NkWR)ptSGsojNG47(e%25$d8GZ$tYILHiKxENdDoZkTss{*w8&nS_f@7ns3MM zj~D}j21I2%(>;cixJ0?!3bu=?Exgd z;478@w{j!;HFDyb`RMN&BHUOSTg`XSDn3ack(m~CM@_~RFK$DujGoal_sNl1NhcHh za#H^;Wc-vTS}RviJMVFcqk>0LTUE6+ zcUV}y41}H%(s1OhX3)|hyqg^>XDB9pt)?`yO;0FjBY64y!|ST6z(9S{2DlyCh-BaN zHq^w{ab z!ua?|kloSG2;WqYBv?3_sFqyr1ND&+YmmMBKcpG#|0-~abU1oK)^2Od4}K!1DgSbZV#(`uDN&CY?WOAd>t2#>Fy_~%r7vmGk=MxuQOL{(h~KQ zZh>;x-W^uMhGcCD<9R=L82-!yoa~{Aks~!7Jrh)uQ6vO5d{^BEuWkeg+A|Qhe@)w4 z7}>}hZ$4%A*v?d~3rt?IVA8DOP)y3gF?izablD+emuDan5EzM445Q_6>}S%raXwvd z)mvPWIsxB&KgRstWjDMR9?MrH7zEEQZ~nyw9qtBv-QY&OA55~HPkQYm?WDKfdXMzi zn}K|5)vQJw_CK#AcS?4M1q$Z)oZ+`D5Y+)D{r2B}FqN+N)3>?<1y4E{h8cfeNj zDMtLt<$l>#l*BKOH>D?p9>Gm__s{S3 z4*0yRcM5Lk=8o!XN)?_b|L$?_{w|P+ZDFT|n@Qkh{V-28hlA>JW18@(Eg=_^B{($; zt@Tp8e}Kho+Z>V^chl<=V7zq(P6w59Izq%7^xEY1Y>Qo+9ejOtF^yHe)uF%?sRDUg z8c;E_AtzSRhF~vw^wbZAxKV`L<7H^iMm%IZr36|tjCpY=vv#TZ(=E^_YuJIefri|tyk#(}^|JTESt*q;Xj%t1 zhsmbDEKk$F!367hqv~+e39}>a;gj1~-ei>!x|kNPtrMZNsJpet|EdIOM^OzG!j;e& zxSeAHQ1kP~KQy7U_S^39`2Ic~a%!#HA@z|zRYVyRFdsitY5o3GE#hvxZbo|I31l}+ zv6I*C2GgWRf9BF8xIT5ZzP%bz;aOB&uOk%7wju5`Kg70MqL>^HN9bM6Wm(b(>y2hw zRbaOmZ?anglpg8epel1HVqg>LoSmJo2L}ik+LiwE2__LKWN*1mc*2OYa$Fmzo0Y3p zd~-qxF|o0oK@Y3pw>|6A9V$7!#I;78Tlv#*&HLs{g?Y_-=F`!1Ht~GiJe}IjW~^uu zd%m6C&P%sO$@+tex!ja*hB#9_sj0=@89RQy3@Qq3laBLm)rUiVhXZ)ucMp+}Gds2? z6AB-<(!M%&j0!={&HWu}VtU~r;%X5DQdUytr54tiqp?eBY$CWoKnYv_j6;M^Y}Wna67JP;wAuqyU}s79vSqMAq*V4kkYP@z#MUGE~258UV+kZ zNYnbP$E~?|eUjKw5E%f z?m8GYFWYGMyw+u+W!Ax&PIP_rryF9umcd%UU3(n_%Y3MnNo2Tw(y{c%hdG=$w1Z0^ zWdg5qDK6LgkjkgaiZHC-? ztX)o{yf@X+c}&hptXxw6tr!P{iotAa^{a#|`5Wwg_A?kxX#Bf#&zw5_f~g6OXU;Z6># zp_*KPSzu{8BL^2iD{1q#G)8Y{XCnINC|Z+>@~FS)1IeiG`+Ql`3F(U8$*YgCgA^L6 zY9)dlLnZBFELU!hulsYR8_IlFj^NpN6IdM5r}S#;*yY%x_ZM%;Z==Br{gwP8SeV2l$<#vdDlwIzJdSAc5TI{P;v$@ z71TH`fh$n4GJL?Puau%x=rx+BL;9Sy^6oK#ZW4UhJFwwvj`AkDj# zx@g|L1ldruv%yV#!B3jZY7$K_`A-8wQAPVh0r(B|HNs1pM z66?_m>%0>&ma2X*-Ha*1DC(OB)k#Sk;CUzZ!7$7F`~&89fU`7p4o1gk7`fWQgC`wy zJZ$Eb4y3I47)87Z7?g@3mZHBq03G7oy%Zmc@{zOS0xv{^=huAdlxqu>#Q=sxrxR+a zu*PP&Wuh@=usfRQh_GOLp^y&m$d7Tayrj{~roWz|cXK_qF53pFSidLw6rBsh0iAkxKc_dt z!*E4;67tmjw#^X14Lxz^%N%zTu|LP!@Z;!%&5(iO#}{k(!k>C@uu&c=>ndEwDWC(l z3YQ~AI_^N}PCM3s?NU)o@?;kkXJrrr$(^kX7)yC$D2Wz{5b-dKtE52buEQ-vxA) zX2bS$8ALgY8s42QiE-TLEfqG}U&%ekhHr37*XB6_ z>^9^8M@sl(ml455bLh(}(6Q{#vw6G5B$+ouu6gcBadxbrBtgg6qtgBueJjUepFhAb zVQ_Ze$iOZ4>XXYQbt&PO-nksN0AR(TO_EHTav89~rME+W7HPmV$c+6{NNf(8bGR}Y ztmFbKGY*pBT6Wb@tC}dgZ$hAKdnP`fI<={ir8Li^R>^pLb~HWlX=Nmc026A`WDz9zCxDAF zG_<+gI82`L@@7j0W6rf7ycrNMiuErK?bp+0N~ZarJc_qo2PrHe{B)%+f!wc*R7`Q! zAwsw;lYZ_GMK#CK6D7{J9<(;2_Gs!=8l<}OA|=a+V4XLe3cI;aPs}%2PLlNk#Hgv2 zzhr)bIsb-450JT6VS7;UefyQ>g(W|uqOUE(OFKy^BL0D~t6rZo`Mb0i0_-0MMK&j= z^333KJ|<|plH_iPecRNO-gS+tgI@*Wh>&=6wP2MB&tOWNS9pcoh@wy#RcxS89X7^X z!B29NoA6PE11+(^33iDNHWtxa_SgAtivm`^vwFe9z=Oa@`*-`%D-&y8Q}T?P{$w+z zqmMW-oH;*$&>>aYmgG#1FWW?Y* zrdUsKCGVou=Fw6YedA+;@vbCr0~~tzcwx{F*jjXId|(U59q-xBzqA_MXVj4sa;vdjH@;1uj3}y!q=vz+ ztK3y8;P>=;esd(uJPCiJj+0CAk30U{if-CtM#wjZPvj++61K|VweM}#6VS9&b@fa} zf`YKEG&{P!u$WlwD@~ZC*tgKpQZ)MI=D6)D>Q;>k_7*f}Q2rQ(cQ22w0)YSusv%QB ze%YKI!b0e+*ENK3{F=&xupS9`L9^mGtPG8GhF7A7TzZttwa|#^_+i=)ojV-$jw$lX5cR)swPcm{ z18rr&a8aTV!PmX(6s!&rxVV{_FQU#qp+MduT^*=ZjDRC7ZpZh8C^YFHz?7o;JA9Nr45gsRN zi$veolF|IOZ$t#v;U1PRBj8qTCE7^pTlzJZ3G*v2C8z+M{d(N-loF8?S=E+NUp0H@ z(H)hjnIy|!(Lu} z5aEZ9q1=(aG&7sSz=6B?P{q{T*CG61ee{ibCuF%}Y=3s~$6)jwQi_Rq5mc0qe5JC|{M3IWDH(GX zjBui_$=>YL*h4^kd;#WRq^yzz+FCjva%!&W& zt(yZ#?_nQMmcN1hniBGz{C7S%j^UxLZMj^Zw1VvCi7PtsVotImqZ&~Q2=vFo47jHz zGuP1jJLz;1yJOa2`_N{`)jI>R^WmLz8G|)#1qilN$r4Qa6tr0)Q3ZDF`%zfUbTo-{ zgb(-((8at)8UPSvykvd2UQl(x&!;1tkxhDlX%$cbzM z5=b+bWfUcu{lifc<7~$`C^K6RaF-~dSZ;jEs?kw@X0jSRO~bg8Ud*n$2LT2?ZUdIStchXlDRy~}l?>aH=A5ZQ@o z#CHTz6N_N`NF^#Dmm?*N4ji~6(})F9Lvpz}Q54=mz3wuL6hhXV`{lMpkoWS0aqJiZX#RzWqb zdL|%w-rZQg^q$)5#sZ{qz5j-A9UB?E)bD(0J(Ar8RfdYjP}SeM!8AL-QS43Ub?oiw zyXSIlTIHK>?U!8)Z3ZwQgfG7P6IXXt;XkR!@<5YwBzZe{cxvyCkde{hk+la#sQbGK z<~6MSb+KH8Q6)c>Ue5hx!Ws){22r&p6#a>Gl2=j!Y+Jew0%G^e#AdYt9farBAJM|& z3V&Y>iWfS9;_%5`9@N|kLqmo2yMnR&jO>H6yAVUT=4}gyb2Xgt22iaRN8d33tZ(R&JG$|+g476Qs zyz{&xF_ePDA}s-KSTnxyI{L|C({!Ziu+v`tV53O;3$m`gWS?uH`Xs|Mvjcb_zvIjR zsgXWE*z?TUaWzKQx|j7T2=?y4EGKvSVkQusJzwJ3=iA$=;Pm8XsCBfGsAd5nJwbFl zJ6m&BsR|~!i`a;AjKrL~j%#!|K7HkVcn;+bM@?~J)!&e^F5QPEv$?{zS+H8iKoX2A zq%Zgzq#)bEq`xvMV2i8)nXG9s)Sff+OVX}5+J+w|zQ!?FCgU*5=}Sp=k&9(Q5ET?>$acCZr2qaH2LAs|eIc*> X4Z@>NBFXw!!U!TGp(tJ_Y8?6>F>Xa6 literal 0 HcmV?d00001 diff --git a/clang-tools-extra/docs/clangd/CodeCompletionInSublimeText.png b/clang-tools-extra/docs/clangd/CodeCompletionInSublimeText.png new file mode 100644 index 0000000000000000000000000000000000000000..b09fed3bdfa26fefcd025376e9b8ec083ae1e9b6 GIT binary patch literal 19894 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 ZNuI({N3NdSfHd6$WF!>DD@Bci{ug$Gwxs|7 literal 0 HcmV?d00001 diff --git a/clang-tools-extra/docs/clangd/CodeCompletionInYCM.png b/clang-tools-extra/docs/clangd/CodeCompletionInYCM.png new file mode 100644 index 0000000000000000000000000000000000000000..b74508d6dfaf7b48813b6ef7b5abc1aa757af44c GIT binary patch literal 17028 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 F{a>I*%D4ak literal 0 HcmV?d00001 diff --git a/clang-tools-extra/docs/clangd/CodeCompletionInsertsNamespaceQualifiersInVSCode.gif b/clang-tools-extra/docs/clangd/CodeCompletionInsertsNamespaceQualifiersInVSCode.gif new file mode 100644 index 0000000000000000000000000000000000000000..f0d49d630787cd4cad4c787dcef8f78f46090f05 GIT binary patch literal 110759 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 and include LLVM, Clang, and the +"extra Clang tools" in your build. + +Contributing to clangd +====================== + +A good place for interested contributors is the `Clangd developer mailing list +`_. For discussions with +the broader community on topics not only related to Clangd, use `Clang +developer mailing list `_. If +you're also interested in contributing patches to clangd, take a look at the +`LLVM Developer Policy `_ and `Code +Reviews `_ page. Contributions of new +features to the `Language Server Protocol +`_ itself would also be +very useful, so that clangd can eventually implement them in a conforming way. diff --git a/clang-tools-extra/docs/clangd/DiagnosticsInEmacsEglot.png b/clang-tools-extra/docs/clangd/DiagnosticsInEmacsEglot.png new file mode 100644 index 0000000000000000000000000000000000000000..f5be84bf5ac792f4d050e0f03501965a39bef77e GIT binary patch literal 16634 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 J^8fVvKLBM#h7bS% literal 0 HcmV?d00001 diff --git a/clang-tools-extra/docs/clangd/ErrorsInVSCode.png b/clang-tools-extra/docs/clangd/ErrorsInVSCode.png new file mode 100644 index 0000000000000000000000000000000000000000..52de402962703e3763d143bbdb837b15c3841d51 GIT binary patch literal 76993 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 literal 0 HcmV?d00001 diff --git a/clang-tools-extra/docs/clangd/Extensions.rst b/clang-tools-extra/docs/clangd/Extensions.rst new file mode 100644 index 0000000000000..4ff0525045847 --- /dev/null +++ b/clang-tools-extra/docs/clangd/Extensions.rst @@ -0,0 +1,173 @@ +=================== +Protocol extensions +=================== + +clangd supports some features that are not in the official +`Language Server Protocol specification +`__. + +We cautious about adding extensions. The most important considerations are: + +- **Editor support**: How many users will the feature be available to? +- **Standardization**: Is the feature stable? Is it likely to be adopted by more + editors over time? +- **Utility**: Does the feature provide a lot of value? +- **Complexity**: Is this hard to implement in clangd, or constrain future work? + Is the protocol complicated? + +These extensions may evolve or disappear over time. If you use them, try to +recover gracefully if the structures aren't what's expected. + +Switch between the implementation file and the header +===================================================== + +*This extension is supported in clangd 6 and newer.* + +Switching between the implementation file and the header is an important +feature for C++. A language server that understands C++ can do a better job +than the editor. + +**New client->server request**: ``textDocument/switchSourceHeader``. + +Lets editors switch between the main source file (``*.cpp``) and header (``*.h``). + +Parameter: ``TextDocumentIdentifier``: an open file. + +Result: ``string``: the URI of the corresponding header (if a source file was +provided) or source file (if a header was provided). + +If the corresponding file can't be determined, ``""`` is returned. + +File status +=========== + +*This extension is supported in clangd 8 and newer.* + +It is important to provide feedback to the user when the UI is not responsive. + +This extension provides information about activity on clangd's per-file worker +thread. This information can be displayed to users to let them know that the +language server is busy with something. For example, in clangd, building the +AST blocks many other operations. + +**New server->client notification**: ``textDocument/clangd.fileStatus`` + +Sent when the current activity for a file changes. Replaces previous activity +for that file. + +Parameter: ``FileStatus`` object with properties: + +- ``uri : string``: the document whose status is being updated. +- ``state : string``: human-readable information about current activity. + +**New initialization option**: ``initializationOptions.clangdFileStatus : bool`` + +Enables receiving ``textDocument/clangd.fileStatus`` notifications. + +Compilation commands +==================== + +*This extension is supported in clangd 8 and newer.* + +clangd relies on knowing accurate compilation options to correctly interpret a +file. Typically they are found in a ``compile_commands.json`` file in a +directory that contains the file, or an ancestor directory. The following +extensions allow editors to supply the commands over LSP instead. + +**New initialization option**: ``initializationOptions.compilationDatabasePath : string`` + +Specifies the directory containing the compilation database (e.g., +``compile_commands.json``). This path will be used for all files, instead of +searching their ancestor directories. + +**New initialization option**: ``initializationOptions.fallbackFlags : string[]`` + +Controls the flags used when no specific compile command is found. The compile +command will be approximately ``clang $FILE $fallbackFlags`` in this case. + +**New configuration setting**: ``settings.compilationDatabaseChanges : {string: CompileCommand}`` + +Provides compile commands for files. This can also be provided on startup as +``initializationOptions.compilationDatabaseChanges``. + +Keys are file paths (Not URIs!) + +Values are ``{workingDirectory: string, compilationCommand: string[]}``. + +Force diagnostics generation +============================ + +*This extension is supported in clangd 7 and newer.* + +Clangd does not regenerate diagnostics for every version of a file (e.g., after +every keystroke), as that would be too slow. Its heuristics ensure: + +- diagnostics do not get too stale, +- if you stop editing, diagnostics will catch up. + +This extension allows editors to force diagnostics to be generated or not +generated at a particular revision. + +**New property of** ``textDocument/didChange`` **request**: ``wantDiagnostics : bool`` + +- if true, diagnostics will be produced for exactly this version. +- if false, diagnostics will not be produced for this version, even if there + are no further edits. +- if unset, diagnostics will be produced for this version or some subsequent + one in a bounded amount of time. + +Diagnostic categories +===================== + +*This extension is supported in clangd 8 and newer.* + +Clang compiler groups diagnostics into categories (e.g., "Inline Assembly +Issue"). Clangd can emit these categories for interested editors. + +**New property of** ``Diagnostic`` **object**: ``category : string``: + +A human-readable name for a group of related diagnostics. Diagnostics with the +same code will always have the same category. + +**New client capability**: ``textDocument.publishDiagnostics.categorySupport``: + +Requests that clangd send ``Diagnostic.category``. + +Inline fixes for diagnostics +============================ + +*This extension is supported in clangd 8 and newer.* + +LSP specifies that code actions for diagnostics (fixes) are retrieved +asynchronously using ``textDocument/codeAction``. clangd always computes fixes +eagerly. Providing them alongside diagnostics can improve the UX in editors. + +**New property of** ``Diagnostic`` **object**: ``codeActions : CodeAction[]``: + +All the code actions that address this diagnostic. + +**New client capability**: ``textDocument.publishDiagnostics.codeActionsInline : bool`` + +Requests clangd to send ``Diagnostic.codeActions``. + +Symbol info request +=================== + +*This extension is supported in clangd 8 and newer.* + +**New client->server request**: ``textDocument/symbolInfo``: + +This request attempts to resolve the symbol under the cursor, without +retrieving further information (like definition location, which may require +consulting an index). This request was added to support integration with +indexes outside clangd. + +Parameter: ``TextDocumentPositionParams`` + +Response: ``SymbolDetails``, an object with properties: + +- ``name : string`` the unqualified name of the symbol +- ``containerName : string`` the enclosing namespace, class etc (without + trailing ``::``) +- ``usr : string``: the clang-specific "unified symbol resolution" identifier +- ``id : string?``: the clangd-specific opaque symbol ID diff --git a/clang-tools-extra/docs/clangd/Features.rst b/clang-tools-extra/docs/clangd/Features.rst new file mode 100644 index 0000000000000..f6a8c501480ea --- /dev/null +++ b/clang-tools-extra/docs/clangd/Features.rst @@ -0,0 +1,231 @@ +======== +Features +======== + +.. role:: raw-html(raw) + :format: html + +Here is what clangd can do for you. Screenshots below show `VSCode +`__; the available features and UI depend on +the editor. + +Errors and warnings +=================== + +clangd runs the clang compiler on your code as you type, and shows errors and +warnings in-place. Some errors are suppressed: diagnostics that require +expanding templates in headers are disabled for performance reasons. + +:raw-html:`

Screenshot` + +.. image:: ErrorsInVSCode.png + :align: center + :alt: Demonstration of errors + +:raw-html:`
` + +Fixes in errors and warnings +---------------------------- + +The compiler can suggest fixes for many common problems automatically, and +clangd can update the code for you. + +:raw-html:`
Animated demo` + +.. image:: ApplyFixInVSCode.gif + :align: center + :alt: Applying a fix suggested by the compiler + +:raw-html:`
` + +Code completion +=============== + +You'll see suggestions as you type based on what methods, variables, etc are +available in this context. + +:raw-html:`
Screenshot` + +.. image:: CodeCompletionInVSCode.png + :align: center + :alt: Code completion demonstration + +:raw-html:`
` + +Abbreviating words may help you find the right result faster. If you type in +``camelCase`` but the function you're looking for is ``snake_case``, that's OK. + +Insertion of namespace qualifiers and includes +---------------------------------------------- + +**(New in v8)** +clangd will sometimes suggest results from other files and namespaces. In this +case the correct qualifier and ``#include`` directive will be inserted. + +:raw-html:`
Animated demo` + +.. image:: CodeCompletionInsertsNamespaceQualifiersInVSCode.gif + :align: center + :alt: Code completion inserts namespace qualifiers + +:raw-html:`
` + +Signature help +-------------- + +Some editors will show you the parameters of the function you're calling, as +you fill them in. + +:raw-html:`
Animated demo` + +.. image:: SignatureHelpInVSCode.gif + :align: center + :alt: Demonstration of the signature help feature + +:raw-html:`
` + +Cross-references +================ + +The following features let you navigate your codebase. + +If there is no project-wide index, cross-references work across the files +you have opened. + +Find definition/declaration +--------------------------- + +Jump to the definition or declaration of a symbol under the cursor. + +:raw-html:`
Animated demo` + +.. image:: GoToDefinitionInVSCode.gif + :align: center + :alt: Demonstration of the "Go to definition" feature + +:raw-html:`
` + +Find references +--------------- + +Show all references to a symbol under the cursor. + +:raw-html:`
Animated demo` + +.. image:: FindAllReferencesInVSCode.gif + :align: center + :alt: Demonstration of the "Find all references" feature + +:raw-html:`
` + +Some editors will automatically highlight local references to the selected +symbol as you move around a file. + +Navigation +========== + +clangd informs the editor of the code structure in the current file. +Some editors use this to present an outline view: + +:raw-html:`
Screenshot` + +.. image:: OutlineInVSCode.png + :align: center + :alt: Outline of a file + +:raw-html:`
` + +In VSCode, the outline is also presented as breadcrumbs that allow jumping to a +symbol within the current file. Searching for symbols within the scope of the +whole project is also possible. + +:raw-html:`
Animated demo` + +.. image:: NavigationWithBreadcrumbsInVSCode.gif + :align: center + :alt: Navigation with breadcrumbs + +:raw-html:`
` + +Formatting +========== + +clangd embeds `clang-format `__, +which can reformat your code: fixing indentation, breaking lines, and reflowing +comments. + +:raw-html:`
Animated demo` + +.. image:: FormatSelectionInVSCode.gif + :align: center + :alt: Formatting selected code + +:raw-html:`
` + +clangd respects your project's ``.clang-format`` file which controls styling +options. + +Format-as-you-type is experimental and doesn't work well yet. + +Complete list of features +========================= + +Here is a list of features that could be useful for editors, together with the +implementation status in clangd, and specification in the Language Server +Protocol. + +It is not clear whether or not some of the features mentioned below should be a +part of the Language Server Protocol; those features might be eventually +developed outside clangd or become clangd extensions to LSP. + ++-------------------------------------+------------+----------+ +| C/C++ Editor feature | LSP | Clangd | ++=====================================+============+==========+ +| Formatting | Yes | Yes | ++-------------------------------------+------------+----------+ +| Completion | Yes | Yes | ++-------------------------------------+------------+----------+ +| Diagnostics | Yes | Yes | ++-------------------------------------+------------+----------+ +| Fix-its | Yes | Yes | ++-------------------------------------+------------+----------+ +| Go to Definition | Yes | Yes | ++-------------------------------------+------------+----------+ +| Signature Help | Yes | Yes | ++-------------------------------------+------------+----------+ +| Document Highlights | Yes | Yes | ++-------------------------------------+------------+----------+ +| Rename | Yes | Yes | ++-------------------------------------+------------+----------+ +| Source hover | Yes | Yes | ++-------------------------------------+------------+----------+ +| Find References | Yes | Yes | ++-------------------------------------+------------+----------+ +| Document Symbols | Yes | Yes | ++-------------------------------------+------------+----------+ +| Workspace Symbols | Yes | Yes | ++-------------------------------------+------------+----------+ +| Code Lens | Yes | No | ++-------------------------------------+------------+----------+ +| Code folding | Yes | No | ++-------------------------------------+------------+----------+ +| Extract Local Variable | Yes | No | ++-------------------------------------+------------+----------+ +| Extract Function/Method | Yes | No | ++-------------------------------------+------------+----------+ +| Quick Assist | Yes | No | ++-------------------------------------+------------+----------+ +| Hide Method | Yes | No | ++-------------------------------------+------------+----------+ +| Implement Method | Yes | No | ++-------------------------------------+------------+----------+ +| Gen. Getters/Setters | Yes | No | ++-------------------------------------+------------+----------+ +| Syntax and Semantic Coloring | No | No | ++-------------------------------------+------------+----------+ +| Call hierarchy | No | No | ++-------------------------------------+------------+----------+ +| Type hierarchy | No | No | ++-------------------------------------+------------+----------+ +| Organize Includes | No | No | ++-------------------------------------+------------+----------+ diff --git a/clang-tools-extra/docs/clangd/FindAllReferencesInVSCode.gif b/clang-tools-extra/docs/clangd/FindAllReferencesInVSCode.gif new file mode 100644 index 0000000000000000000000000000000000000000..b9eecf3c864295351d04120b54ca825187bb361b GIT binary patch literal 76027 zcmWifc{~&TAIEo@VYa#D+~z);`7>Gb{hoh){`$NhkI(yazTU5ogOk0vMX)|Z1-Jz?0GxXQ-~+&5uzKYmvnpQU2|Dase@psgT zxTB|}q!&!nCzAK?$Kf1J3~;6f1}27anMOuN#yCA=V-sVy0F!_)6RNxEKjQ1m%*@Tq z4wxHQo15sEo10tW30D8-z`+9tZET3PR>rn*nIt7ek};YTSzw<+c5rZTJYDFRlJ69G z*4fF$+1b^ZUghEyLtqcQ>1O^5jJGx)#*u?|K^4usCO0c11 zNJwbtor-X?eGw6n5$8=Ja@>!b%N@T;jJ)P?;_BrnQ|0KW=$Po(n0phk(I?~n5ubK4 zuZ|kubn4Wpct_ncVc}g|Ixr@Cmv_B*|~?6b93_wxMlzS zS6G-Ee2rp#Ey3m5&Eg_vVo~9(>({TBobD{SoKjL!a{C_-2XFV^zCC)cw6v_uL$WN> zzpSCPJV>`9BCMjKykc;qGE}AVzsq-+?$sqR)&J`wyv&r=4QiD+s1~v#)gKb z+Uh1wW6S;f4+`>IbE?~D2ih9D+uB+mJ-YwsA5#sFrf;<;>vjC2>v6|iUT11V=VjN< z@!77Dquu}KF_*>VUa{tKxxKx;ecky30|SF21A|kwyymmK$y>uyxlf)v87-xZPEL>C zAWd{%o}QVVY4DouJvY}KJ2#vCtitozMDnxQThCwId-?L^%KJ}i@7{g+viWmsdv9+K z!xwS0^YXN{A=?@1HOf{Y^~q@s8=HoYM(Vy`mz*V9@ag-A31&R z=#z)_FI%ZABR5@I8(wuJegANvhSIJbV$E* z{itfQYV*6Nw&{@(qmSN2PMmNEeAsD;wMgUy3%2*_XH*338yiSF5CiMc*vL?olU^NZ z%gijksiN_*rRP+%lC!PEs+9Uw67MI*Q9kQuZe$ppAF5F=k(*r
G+vv#jui%CRpI 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 literal 0 HcmV?d00001 diff --git a/clang-tools-extra/docs/clangd/FormatSelectionInVSCode.gif b/clang-tools-extra/docs/clangd/FormatSelectionInVSCode.gif new file mode 100644 index 0000000000000000000000000000000000000000..1d4be410b4c6876e91331a0abc074957ed3691a5 GIT binary patch literal 167887 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�!t5x;*W0E%idOU7KvwX8d*-h)Fvf{|P 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 literal 0 HcmV?d00001 diff --git a/clang-tools-extra/docs/clangd/GoToDefinitionInVSCode.gif b/clang-tools-extra/docs/clangd/GoToDefinitionInVSCode.gif new file mode 100644 index 0000000000000000000000000000000000000000..396966f7ae3a45895f713cda9a69c1efa488cb07 GIT binary patch literal 123395 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%0D8_`oXNM>NMO5Od0M|W5l)~>g;3+JY!Gfr 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%0D;kIC@0C5ov2HtmW;Lv}1|+sYkZ&Sl8lsiB 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 literal 0 HcmV?d00001 diff --git a/clang-tools-extra/docs/clangd/Installation.rst b/clang-tools-extra/docs/clangd/Installation.rst new file mode 100644 index 0000000000000..2daf42ba5328d --- /dev/null +++ b/clang-tools-extra/docs/clangd/Installation.rst @@ -0,0 +1,369 @@ +=========================== +Getting started with clangd +=========================== + +.. role:: raw-html(raw) + :format: html + +To use clangd, you need to: + +- install clangd, +- install a plugin for your editor, +- tell clangd how your project is built. + +Installing clangd +================= + +You need a **recent** version of clangd: 7.0 was the first usable release, and +8.0 is much better. + +After installing, ``clangd --version`` should print ``clangd version 7.0.0`` or +later. + +:raw-html:`
macOS` + +`Homebrew `__ can install clangd along with LLVM: + +.. code-block:: console + + $ brew install llvm + +If you don't want to use Homebrew, you can download the a binary release of +LLVM from `releases.llvm.org `__. +Alongside ``bin/clangd`` you will need at least ``lib/clang/*/include``: + +.. code-block:: console + + $ cp clang+llvm-7.0.0/bin/clangd /usr/local/bin/clangd + $ cp -r clang+llvm-7.0.0/lib/clang/ /usr/local/lib/ + +:raw-html:`
` + +:raw-html:`
Windows` + +Download and run the LLVM installer from `releases.llvm.org +`__. + +:raw-html:`
` + +:raw-html:`
Debian/Ubuntu` + +The ``clang-tools`` package usually contains an old version of clangd. + +Try to install the latest release (8.0): + +.. code-block:: console + + $ sudo apt-get install clang-tools-8 + +If that is not found, at least ``clang-tools-7`` should be available. + +The ``clangd`` executable will be installed as ``/usr/bin/clangd-8``. Make it +the default ``clangd``: + +.. code-block:: console + + $ sudo update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-8 100 + +:raw-html:`
` + +:raw-html:`
Other systems` + +Most distributions include clangd in a ``clang-tools`` package, or in the full +``llvm`` distribution. + +For some platforms, binaries are also avaliable at `releases.llvm.org +`__. + +:raw-html:`
` + +Editor plugins +============== + +Language Server plugins are available for many editors. In principle, clangd +should work with any of them, though the feature set and UI may vary. + +Here are some plugins we know work well with clangd. + +:raw-html:`
YouCompleteMe for Vim` + +`YouCompleteMe `__ supports clangd. +However, clangd support is not turned on by default, so you must install +YouCompleteMe with ``install.py --clangd-completer``. + +We recommend changing a couple of YCM's default settings. In ``.vimrc`` add: + +:: + + " Let clangd fully control code completion + let g:ycm_clangd_uses_ycmd_caching = 0 + " Use installed clangd, not YCM-bundled clangd which doesn't get updates. + let g:ycm_clangd_binary_path = exepath("clangd") + +You should see errors highlighted and code completions as you type. + +.. image:: CodeCompletionInYCM.png + :align: center + :alt: Code completion in YouCompleteMe + +YouCompleteMe supports many of clangd's features: + +- code completion, +- diagnostics and fixes (``:YcmCompleter FixIt``), +- find declarations, references, and definitions (``:YcmCompleter GoTo`` etc), +- rename symbol (``:YcmCompleter RefactorRename``). + +**Under the hood** + +- **Debug logs**: run ``:YcmDebugInfo`` to see clangd status, and ``:YcmToggleLogs`` + to view clangd's debug logs. +- **Command-line flags**: Set ``g:ycm_clangd_args`` in ``.vimrc``, e.g.: + + :: + + let g:ycm_clangd_args = ['-log=verbose', '-pretty'] + +- **Alternate clangd binary**: set ``g:ycm_clangd_binary_path`` in ``.vimrc``. + +:raw-html:`
` + +:raw-html:`
LanguageClient for Vim and Neovim` + +`LanguageClient-neovim `__ +has `instructions for using clangd +`__, and **may** +be easier to install than YouCompleteMe. + +:raw-html:`
` + +:raw-html:`
Eglot for Emacs` + +`eglot `__ can be configured to work with +clangd. + +Install eglot with ``M-x package-install RET eglot RET``. + +Add the following to ``~/.emacs`` to enable clangd: + +:: + + (require 'eglot) + (add-to-list 'eglot-server-programs '((c++-mode c-mode) "clangd")) + (add-hook 'c-mode-hook 'eglot-ensure) + (add-hook 'c++-mode-hook 'eglot-ensure) + +After restarting you should see diagnostics for errors in your code, and ``M-x +completion-at-point`` should work. + +.. image:: DiagnosticsInEmacsEglot.png + :align: center + :alt: Diagnostics in Emacs + +eglot supports many of clangd's features, with caveats: + +- code completion, though the interaction is quite poor (even with + ``company-mode``, see below), +- diagnostics and fixes, +- find definitions and references (``M-x xref-find-definitions`` etc), +- hover and highlights, +- code actions (``M-x eglot-code-actions``). + +**company-mode** + +eglot does have basic integration with company-mode, which provides a more +fluent completion UI. + +You can install it with ``M-x package-install RET company RET``, and enable it +with ``M-x company-mode``. + +**company-clang is enabled by default**, and will interfere with clangd. +Disable it in ``M-x customize-variable RET company-backends RET``. + +Completion still has some major limitations: + +- completions are alphabetically sorted, not ranked. +- only pure-prefix completions are shown - no fuzzy matches. +- completion triggering seems to be a bit hit-and-miss. + +.. image:: CodeCompletionInEmacsCompanyMode.png + :align: center + :alt: Completion in company-mode + +**Under the hood** + +- **Debug logs**: available in the ``EGLOT stderr`` buffer. +- **Command-line flags and alternate binary**: instead of adding ``"clangd"`` + to ``eglot-server-programs``, add ``("/path/to/clangd" "-log=verbose")`` etc. + +:raw-html:`
` + +:raw-html:`
Visual Studio Code` + +The official extension is `vscode-clangd +`__ +and can be installed from within VSCode. + +Choose **View** --> **Extensions**, then search for "clangd". (Make sure the +Microsoft C/C++ extension is **not** installed). + +After restarting, you should see red underlines underneath errors, and you +should get rich code completions including e.g. function parameters. + +.. image:: CodeCompletionInVSCode.png + :align: center + :alt: Code completion in VSCode + +vscode-clangd has excellent support for all clangd features, including: + +- code completion +- diagnostics and fixes +- find declarations, references, and definitions +- find symbol in file (``Ctrl-P @foo``) or workspace (``Ctrl-P #foo``) +- hover and highlights +- code actions + +**Under the hood** + +- **Debug logs**: when clangd is running, you should see "Clang Language + Server" in the dropdown of the Output panel (**View** -> **Output**). + +- **Command-line flags**: these can be passed in the ``clangd.arguments`` array + in your ``settings.json``. (**File** -> **Preferences** -> **Settings**). + +- **Alternate clangd binary**: set the ``clangd.path`` string in + ``settings.json``. + +:raw-html:`
` + +:raw-html:`
Sublime Text` + +`tomv564/LSP `__ works with clangd out of the box. + +Select **Tools** --> **Install Package Control** (if you haven't installed it +yet). + +Press ``Ctrl-Shift-P`` and select **Package Control: Install Package**. Select +**LSP**. + +Press ``Ctrl-Shift-P`` and select **LSP: Enable Language Server Globally**. +Select **clangd**. + +Open a C++ file, and you should see diagnostics and completion: + +.. image:: CodeCompletionInSublimeText.png + :align: center + :alt: Code completion in Sublime Text + + +The LSP package has excellent support for all most clangd features, including: + +- code completion (a bit noisy due to how snippets are presented) +- diagnostics and fixes +- find definition and references +- hover and highlights +- code actions + +**Under the hood** + +Settings can be tweaked under **Preferences** --> **Package Settings** --> +**LSP**. + +- **Debug logs**: add ``"log_stderr": true`` +- **Command-line flags and alternate clangd binary**: inside the ``"clients": + {"clangd": { ... } }`` section, add ``"command": ["/path/to/clangd", + "-log=verbose"]`` etc. + +:raw-html:`
` + +:raw-html:`
Other editors` + +There is a directory of LSP clients at `langserver.org +`__. + +A generic client should be configured to run the command ``clangd``, and +communicate via the language server protocol on standard input/output. + +If you don't have strong feelings about an editor, we suggest you try out +`VSCode `__, it has excellent language server +support and most faithfully demonstrates what clangd can do. + +:raw-html:`
` + +Project setup +============= + +To understand source code in your project, clangd needs to know the build +flags. (This is just a fact of life in C++, source files are not +self-contained.) + +By default, clangd will assume that source code is built as ``clang +some_file.cc``, and you'll probably get spurious errors about missing +``#include``\ d files, etc. There are a couple of ways to fix this. + +``compile_commands.json`` +------------------------- + +``compile_commands.json`` file provides compile commands for all source files +in the project. This file is usually generated by the build system, or tools +integrated with the build system. Clangd will look for this file in the parent +directories of the files you edit. + +:raw-html:`
CMake-based projects` + +If your project builds with CMake, it can generate ``compile_commands.json``. +You should enable it with: + +:: + + $ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 + +``compile_commands.json`` will be written to your build directory. You should +symlink it (or copy it) to the root of your source tree, if they are different. + +:: + + $ ln -s ~/myproject/compile_commands.json ~/myproject-build/ + +:raw-html:`
` + +:raw-html:`
Other build systems, using Bear` + +`Bear `__ is a tool that generates a +``compile_commands.json`` file by recording a complete build. + +For a ``make``-based build, you can run ``make clean; bear make`` to generate the +file (and run a clean build!) + +:raw-html:`
` + +Other tools can also generate this file. See `the compile_commands.json +specification `__. + +``compile_flags.txt`` +--------------------- + +If all files in a project use the same build flags, you can put those flags, +one flag per line, in ``compile_flags.txt`` in your source root. + +Clangd will assume the compile command is ``clang $FLAGS some_file.cc``. + +Creating this file by hand is a reasonable place to start if your project is +quite simple. + +Project-wide Index +================== + +By default clangd only has a view on symbols coming from files you are +currently editing. You can extend this view to whole project by providing a +project-wide index to clangd. There are two ways to do this. + +- Pass an experimental `-background-index` command line argument. With + this feature enabled, clangd incrementally builds an index of projects + that you work on and uses the just-built index automatically. + +- Generate an index file using `clangd-indexer + `__ + Then you can pass generated index file to clangd using + `-index-file=/path/to/index_file`. *Note that clangd-indexer isn't + included alongside clangd in the Debian clang-tools package. You will + likely have to build clangd from source to use this option.* diff --git a/clang-tools-extra/docs/clangd/NavigationWithBreadcrumbsInVSCode.gif b/clang-tools-extra/docs/clangd/NavigationWithBreadcrumbsInVSCode.gif new file mode 100644 index 0000000000000000000000000000000000000000..499f5c1af8468b178e8db515b8da54cb0c09f4bd GIT binary patch literal 123365 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 Lb{z=snl0P*Y>PrJaGOt|P@iu><( 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 D6>|d1 literal 0 HcmV?d00001 diff --git a/clang-tools-extra/docs/clangd/OutlineInVSCode.png b/clang-tools-extra/docs/clangd/OutlineInVSCode.png new file mode 100644 index 0000000000000000000000000000000000000000..570a80de8b71ca211eb1f70ad1fddb7386ef7a6f GIT binary patch literal 15443 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 literal 0 HcmV?d00001 diff --git a/clang-tools-extra/docs/clangd/SignatureHelpInVSCode.gif b/clang-tools-extra/docs/clangd/SignatureHelpInVSCode.gif new file mode 100644 index 0000000000000000000000000000000000000000..e5700f22b57dbad57fe9beec1aab8c4027b13315 GIT binary patch literal 36923 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 sJF_o~@MJCJI_FY_Ol;)CvgAG1I3Z~dmF^8f$< literal 0 HcmV?d00001 diff --git a/clang-tools-extra/docs/clangd/index.rst b/clang-tools-extra/docs/clangd/index.rst new file mode 100644 index 0000000000000..46939062876f1 --- /dev/null +++ b/clang-tools-extra/docs/clangd/index.rst @@ -0,0 +1,27 @@ +====== +clangd +====== + +.. toctree:: + :maxdepth: 1 + + Installation + Features + +What is clangd? +=============== + +clangd understands your C++ code and adds smart features to your editor: code +completion, compile errors, go-to-definition and more. + +clangd is a language server that implements the `Language Server Protocol +`__; it can work with +many editors through a plugin. Here's Visual Studio Code with the clangd +plugin, demonstrating code completion: + +.. image:: CodeCompletionInVSCode.png + :align: center + :alt: Code completion in VSCode + +clangd is based on the `Clang `__ C++ compiler, and is +part of the `LLVM `__ project. diff --git a/clang-tools-extra/docs/conf.py b/clang-tools-extra/docs/conf.py index 1b07e8efe5ec5..badb8efa3709f 100644 --- a/clang-tools-extra/docs/conf.py +++ b/clang-tools-extra/docs/conf.py @@ -121,7 +121,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = [] +html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. diff --git a/clang-tools-extra/docs/index.rst b/clang-tools-extra/docs/index.rst index 55fd1a6d08be2..b20f0485c84a2 100644 --- a/clang-tools-extra/docs/index.rst +++ b/clang-tools-extra/docs/index.rst @@ -1,14 +1,9 @@ -.. Extra Clang Tools documentation master file, created by - sphinx-quickstart on Wed Feb 13 10:00:18 2013. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - .. title:: Welcome to Extra Clang Tools's documentation! Introduction ============ Welcome to the clang-tools-extra project which contains extra tools built using -Clang's tooling API's. +Clang's tooling APIs. .. toctree:: :maxdepth: 1 @@ -25,7 +20,8 @@ Contents modularize pp-trace clang-rename - clangd + clangd/index + clangd/DeveloperDocumentation clang-doc From 95e1c294cb0415a377a7b1d6c7c7d4f89e1c04e4 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 27 Feb 2019 16:51:33 +0000 Subject: [PATCH 192/274] Added release notes for clangd 8 By Dmitri Gribenko! Differential revision: https://reviews.llvm.org/D58721 llvm-svn: 355004 --- clang-tools-extra/docs/ReleaseNotes.rst | 52 ++++++++++++++++++- clang-tools-extra/docs/clangd/Extensions.rst | 8 +++ .../docs/clangd/Installation.rst | 2 + 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index a9a9c563ba915..56a6cd074f873 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -32,7 +32,57 @@ infrastructure are described first, followed by tool-specific sections. Improvements to clangd ---------------------- -The improvements are... +- clangd now adds namespace qualifiers in code completion, for example, if you + type "``vec``", the list of completions will include "``std::vector``". + + See also: `r343248 `__. + +- When a :ref:`global index ` is available, clangd will use it to augment the + results of "go to definition" and "find references" queries. Global index + also enables global code completion, which suggests symbols that are not + imported in the current file and automatically inserts the missing + ``#include`` directives. + +- clangd stores the symbol index on disk in a new compact binary serialization + format. It is 10x more compact than YAML and 40% more compact than gzipped + YAML. + + See also: `r341375 `__. + +- clangd has a new efficient symbol index suitable for complex and fuzzy + queries and large code bases (e.g., LLVM, Chromium). This index is used for + code completion, go to definition, and cross-references. The architecture of + the index allows for complex and fuzzy retrieval criteria and sophisticated + scoring. + + See also: `discussion on the mailing list + `__, `design + doc + `__. + +- clangd has a new LSP extension that communicates information about activity + on clangd's per-file worker thread. This information can be displayed to + users to let them know that the language server is busy with something. For + example, in clangd, building the AST blocks many other operations. + + More info: :ref:`lsp-extension-file-status`. + +- clangd has a new LSP extension that allows the client to supply the + compilation commands over LSP, instead of finding compile_commands.json on + disk. + + More info: :ref:`lsp-extension-compilation-commands`. + +- clangd has a new LSP extension that allows the client to request fixes to be + sent together with diagnostics, instead of asynchronously. + + More info: :ref:`lsp-extension-code-actions-in-diagnostics`. + +- clangd has a new LSP extension that allows the client to resolve a symbol in + a light-weight manner, without retrieving further information (like + definition location, which may require consulting an index). + + More info: :ref:`lsp-extension-symbol-info`. Improvements to clang-query diff --git a/clang-tools-extra/docs/clangd/Extensions.rst b/clang-tools-extra/docs/clangd/Extensions.rst index 4ff0525045847..1f340ae088714 100644 --- a/clang-tools-extra/docs/clangd/Extensions.rst +++ b/clang-tools-extra/docs/clangd/Extensions.rst @@ -38,6 +38,8 @@ provided) or source file (if a header was provided). If the corresponding file can't be determined, ``""`` is returned. +.. _lsp-extension-file-status: + File status =========== @@ -64,6 +66,8 @@ Parameter: ``FileStatus`` object with properties: Enables receiving ``textDocument/clangd.fileStatus`` notifications. +.. _lsp-extension-compilation-commands: + Compilation commands ==================== @@ -133,6 +137,8 @@ same code will always have the same category. Requests that clangd send ``Diagnostic.category``. +.. _lsp-extension-code-actions-in-diagnostics: + Inline fixes for diagnostics ============================ @@ -150,6 +156,8 @@ All the code actions that address this diagnostic. Requests clangd to send ``Diagnostic.codeActions``. +.. _lsp-extension-symbol-info: + Symbol info request =================== diff --git a/clang-tools-extra/docs/clangd/Installation.rst b/clang-tools-extra/docs/clangd/Installation.rst index 2daf42ba5328d..3c7b36401dec1 100644 --- a/clang-tools-extra/docs/clangd/Installation.rst +++ b/clang-tools-extra/docs/clangd/Installation.rst @@ -350,6 +350,8 @@ Clangd will assume the compile command is ``clang $FLAGS some_file.cc``. Creating this file by hand is a reasonable place to start if your project is quite simple. +.. _project-wide-index: + Project-wide Index ================== From e65cd4e71a3f2096c7d9b0ecf4d06e33d51fa759 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 4 Mar 2019 12:41:39 +0000 Subject: [PATCH 193/274] Merging r355116 and r355117: ------------------------------------------------------------------------ r355116 | ctopper | 2019-02-28 19:49:29 +0100 (Thu, 28 Feb 2019) | 7 lines [X86] Don't peek through bitcasts before checking ISD::isBuildVectorOfConstantSDNodes in combineTruncatedArithmetic We don't have any combines that can look through a bitcast to truncate a build vector of constants. So the truncate will stick around and give us something like this pattern (binop (trunc X), (trunc (bitcast (build_vector)))) which has two truncates in it. Which will be reversed by hoistLogicOpWithSameOpcodeHands in the generic DAG combiner. Thus causing an infinite loop. Even if we had a combine for (truncate (bitcast (build_vector))), I think it would need to be implemented in getNode otherwise DAG combiner visit ordering would probably still visit the binop first and reverse it. Or combineTruncatedArithmetic would need to do its own constant folding. Differential Revision: https://reviews.llvm.org/D58705 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r355117 | ctopper | 2019-02-28 19:50:16 +0100 (Thu, 28 Feb 2019) | 1 line [X86] Add test case that was supposed to go with r355116. ------------------------------------------------------------------------ llvm-svn: 355310 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 7 +++++-- llvm/test/CodeGen/X86/pr40891.ll | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/X86/pr40891.ll diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index e1a6d22f06165..2dfee3a4701e6 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -38134,8 +38134,11 @@ static SDValue combineTruncatedArithmetic(SDNode *N, SelectionDAG &DAG, return true; // See if this is a single use constant which can be constant folded. - SDValue BC = peekThroughOneUseBitcasts(Op); - return ISD::isBuildVectorOfConstantSDNodes(BC.getNode()); + // NOTE: We don't peek throught bitcasts here because there is currently + // no support for constant folding truncate+bitcast+vector_of_constants. So + // we'll just send up with a truncate on both operands which will + // get turned back into (truncate (binop)) causing an infinite loop. + return ISD::isBuildVectorOfConstantSDNodes(Op.getNode()); }; auto TruncateArithmetic = [&](SDValue N0, SDValue N1) { diff --git a/llvm/test/CodeGen/X86/pr40891.ll b/llvm/test/CodeGen/X86/pr40891.ll new file mode 100644 index 0000000000000..3f3cfb23d03d9 --- /dev/null +++ b/llvm/test/CodeGen/X86/pr40891.ll @@ -0,0 +1,22 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=avx2 | FileCheck %s + +; Make sure this sequence doesn't hang in DAG combine. + +define <8 x i32> @foo(<8 x i64> %x, <4 x i64> %y) { +; CHECK-LABEL: foo: +; CHECK: # %bb.0: +; CHECK-NEXT: vandps %ymm2, %ymm0, %ymm0 +; CHECK-NEXT: vandps {{\.LCPI.*}}, %ymm1, %ymm1 +; CHECK-NEXT: vpermilps {{.*#+}} ymm0 = ymm0[0,2,2,3,4,6,6,7] +; CHECK-NEXT: vpermpd {{.*#+}} ymm0 = ymm0[0,2,2,3] +; CHECK-NEXT: vpermilps {{.*#+}} ymm1 = ymm1[0,2,2,3,4,6,6,7] +; CHECK-NEXT: vpermpd {{.*#+}} ymm1 = ymm1[0,2,2,3] +; CHECK-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 +; CHECK-NEXT: retl + %a = shufflevector <4 x i64> %y, <4 x i64> , <8 x i32> + %b = and <8 x i64> %x, %a + %c = trunc <8 x i64> %b to <8 x i32> + ret <8 x i32> %c +} + From 502c6557aa1aa6917fe5ce0ee26cfe936d45eb98 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 4 Mar 2019 12:44:42 +0000 Subject: [PATCH 194/274] Merging r352465: ------------------------------------------------------------------------ r352465 | mstorsjo | 2019-01-29 10:36:48 +0100 (Tue, 29 Jan 2019) | 17 lines [COFF, ARM64] Don't put jump table into a separate COFF section for EK_LabelDifference32 Windows ARM64 has PIC relocation model and uses jump table kind EK_LabelDifference32. This produces jump table entry as ".word LBB123 - LJTI1_2" which represents the distance between the block and jump table. A new relocation type (IMAGE_REL_ARM64_REL32) is needed to do the fixup correctly if they are in different COFF section. This change saves the jump table to the same COFF section as the associated code. An ideal fix could be utilizing IMAGE_REL_ARM64_REL32 relocation type. Patch by Tom Tan! Differential Revision: https://reviews.llvm.org/D57277 ------------------------------------------------------------------------ llvm-svn: 355311 --- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 13 ++++- .../Target/AArch64/AArch64TargetMachine.cpp | 4 +- llvm/test/CodeGen/AArch64/win64-jumptable.ll | 48 +++++++++++++++++++ 3 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/win64-jumptable.ll diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 0254a572434f4..2e1d1f1130a9d 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -471,9 +471,18 @@ void AArch64AsmPrinter::EmitJumpTableInfo() { const std::vector &JT = MJTI->getJumpTables(); if (JT.empty()) return; + const Function &F = MF->getFunction(); const TargetLoweringObjectFile &TLOF = getObjFileLowering(); - MCSection *ReadOnlySec = TLOF.getSectionForJumpTable(MF->getFunction(), TM); - OutStreamer->SwitchSection(ReadOnlySec); + bool JTInDiffSection = + !STI->isTargetCOFF() || + !TLOF.shouldPutJumpTableInFunctionSection( + MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32, + F); + if (JTInDiffSection) { + // Drop it in the readonly section. + MCSection *ReadOnlySec = TLOF.getSectionForJumpTable(F, TM); + OutStreamer->SwitchSection(ReadOnlySec); + } auto AFI = MF->getInfo(); for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) { diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp index 4e016525f7e4e..219c33ef73c51 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -209,8 +209,8 @@ static std::string computeDataLayout(const Triple &TT, static Reloc::Model getEffectiveRelocModel(const Triple &TT, Optional RM) { - // AArch64 Darwin is always PIC. - if (TT.isOSDarwin()) + // AArch64 Darwin and Windows are always PIC. + if (TT.isOSDarwin() || TT.isOSWindows()) return Reloc::PIC_; // On ELF platforms the default static relocation model has a smart enough // linker to cope with referencing external symbols defined in a shared diff --git a/llvm/test/CodeGen/AArch64/win64-jumptable.ll b/llvm/test/CodeGen/AArch64/win64-jumptable.ll new file mode 100644 index 0000000000000..8148a593c91b7 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/win64-jumptable.ll @@ -0,0 +1,48 @@ +; RUN: llc -o - %s -mtriple=aarch64-windows -aarch64-enable-compress-jump-tables=0 | FileCheck %s + +define void @f(i32 %x) { +entry: + switch i32 %x, label %sw.epilog [ + i32 0, label %sw.bb + i32 1, label %sw.bb1 + i32 2, label %sw.bb2 + i32 3, label %sw.bb3 + ] + +sw.bb: ; preds = %entry + tail call void @g(i32 0) #2 + br label %sw.epilog + +sw.bb1: ; preds = %entry + tail call void @g(i32 1) #2 + br label %sw.epilog + +sw.bb2: ; preds = %entry + tail call void @g(i32 2) #2 + br label %sw.epilog + +sw.bb3: ; preds = %entry + tail call void @g(i32 3) #2 + br label %sw.epilog + +sw.epilog: ; preds = %entry, %sw.bb3, %sw.bb2, %sw.bb1, %sw.bb + tail call void @g(i32 10) #2 + ret void +} + +declare void @g(i32) + +; CHECK: .text +; CHECK: f: +; CHECK: .seh_proc f +; CHECK: b g +; CHECK-NEXT: .p2align 2 +; CHECK-NEXT: .LJTI0_0: +; CHECK: .word .LBB0_2-.LJTI0_0 +; CHECK: .word .LBB0_3-.LJTI0_0 +; CHECK: .word .LBB0_4-.LJTI0_0 +; CHECK: .word .LBB0_5-.LJTI0_0 +; CHECK: .section .xdata,"dr" +; CHECK: .seh_handlerdata +; CHECK: .text +; CHECK: .seh_endproc From d1786389da278381d02324739dd1bd5825c6f860 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 4 Mar 2019 12:56:31 +0000 Subject: [PATCH 195/274] Merging r355136: ------------------------------------------------------------------------ r355136 | efriedma | 2019-02-28 21:38:45 +0100 (Thu, 28 Feb 2019) | 12 lines [AArch64] [Windows] Don't skip constructing UnwindHelp. In certain cases, the first non-frame-setup instruction in a function is a branch. For example, it could be a cbz on an argument. Make sure we correctly allocate the UnwindHelp, and find an appropriate register to use to initialize it. Fixes https://bugs.llvm.org/show_bug.cgi?id=40184 Differential Revision: https://reviews.llvm.org/D58752 ------------------------------------------------------------------------ llvm-svn: 355313 --- .../Target/AArch64/AArch64FrameLowering.cpp | 9 ++--- .../CodeGen/AArch64/wineh-try-catch-cbz.ll | 40 +++++++++++++++++++ llvm/test/CodeGen/AArch64/wineh-try-catch.ll | 4 +- 3 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/wineh-try-catch-cbz.ll diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index 621aa8bc783a6..57f630a18c8ad 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -2108,9 +2108,6 @@ void AArch64FrameLowering::processFunctionBeforeFrameFinalized( while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup)) ++MBBI; - if (MBBI->isTerminator()) - return; - // Create an UnwindHelp object. int UnwindHelpFI = MFI.CreateStackObject(/*size*/8, /*alignment*/16, false); @@ -2118,8 +2115,10 @@ void AArch64FrameLowering::processFunctionBeforeFrameFinalized( // We need to store -2 into the UnwindHelp object at the start of the // function. DebugLoc DL; - RS->enterBasicBlock(MBB); - unsigned DstReg = RS->scavengeRegister(&AArch64::GPR64RegClass, MBBI, 0); + RS->enterBasicBlockEnd(MBB); + RS->backward(std::prev(MBBI)); + unsigned DstReg = RS->FindUnusedReg(&AArch64::GPR64commonRegClass); + assert(DstReg && "There must be a free register after frame setup"); BuildMI(MBB, MBBI, DL, TII.get(AArch64::MOVi64imm), DstReg).addImm(-2); BuildMI(MBB, MBBI, DL, TII.get(AArch64::STURXi)) .addReg(DstReg, getKillRegState(true)) diff --git a/llvm/test/CodeGen/AArch64/wineh-try-catch-cbz.ll b/llvm/test/CodeGen/AArch64/wineh-try-catch-cbz.ll new file mode 100644 index 0000000000000..7c64328f0a7d2 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/wineh-try-catch-cbz.ll @@ -0,0 +1,40 @@ +; RUN: llc < %s | FileCheck %s + +; Make sure the prologue is sane. (Doesn't need to exactly match this, +; but the original issue only reproduced if the cbz was immediately +; after the frame setup.) + +; CHECK: sub sp, sp, #32 +; CHECK-NEXT: stp x29, x30, [sp, #16] +; CHECK-NEXT: add x29, sp, #16 +; CHECK-NEXT: orr x1, xzr, #0xfffffffffffffffe +; CHECK-NEXT: stur x1, [x29, #-16] +; CHECK-NEXT: cbz w0, .LBB0_2 + +target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128" +target triple = "aarch64-unknown-windows-msvc19.11.0" + +; Function Attrs: uwtable +define dso_local void @"?f@@YAXH@Z"(i32 %x) local_unnamed_addr #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { +entry: + %cmp = icmp eq i32 %x, 0 + br i1 %cmp, label %try.cont, label %if.then + +if.then: ; preds = %entry + invoke void @"?g@@YAXXZ"() + to label %try.cont unwind label %catch.dispatch + +catch.dispatch: ; preds = %if.then + %0 = catchswitch within none [label %catch] unwind to caller + +catch: ; preds = %catch.dispatch + %1 = catchpad within %0 [i8* null, i32 64, i8* null] + catchret from %1 to label %try.cont + +try.cont: ; preds = %entry, %if.then, %catch + ret void +} + +declare dso_local void @"?g@@YAXXZ"() local_unnamed_addr #1 + +declare dso_local i32 @__CxxFrameHandler3(...) diff --git a/llvm/test/CodeGen/AArch64/wineh-try-catch.ll b/llvm/test/CodeGen/AArch64/wineh-try-catch.ll index 940a86282d39a..f4bb9d50a4347 100644 --- a/llvm/test/CodeGen/AArch64/wineh-try-catch.ll +++ b/llvm/test/CodeGen/AArch64/wineh-try-catch.ll @@ -22,8 +22,8 @@ ; CHECK: add x29, sp, #32 ; CHECK: sub sp, sp, #624 ; CHECK: mov x19, sp -; CHECK: orr x1, xzr, #0xfffffffffffffffe -; CHECK: stur x1, [x19] +; CHECK: orr x0, xzr, #0xfffffffffffffffe +; CHECK: stur x0, [x19] ; Now check that x is stored at fp - 20. We check that this is the same ; location accessed from the funclet to retrieve x. From d39b590a4123aadff60a1b5c808fae6ab7cea362 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 5 Mar 2019 09:58:41 +0000 Subject: [PATCH 196/274] Merging r355227 and r355228: ------------------------------------------------------------------------ r355227 | ctopper | 2019-03-01 22:02:34 +0100 (Fri, 01 Mar 2019) | 3 lines [X86] Add test case for D58805. NFC This demonstrates dead store elimination removing a store that may alias a gather that uses null as its base. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r355228 | ctopper | 2019-03-01 22:02:40 +0100 (Fri, 01 Mar 2019) | 7 lines [X86] Remove IntrArgMemOnly from target specific gather/scatter intrinsics IntrArgMemOnly implies that only memory pointed to by pointer typed arguments will be accessed. But these intrinsics allow you to pass null to the pointer argument and put the full address into the index argument. Other passes won't be able to understand this. A colleague found that ISPC was creating gathers like this and then dead store elimination removed some stores because it didn't understand what the gather was doing since the pointer argument was null. Differential Revision: https://reviews.llvm.org/D58805 ------------------------------------------------------------------------ llvm-svn: 355383 --- llvm/include/llvm/IR/IntrinsicsX86.td | 254 +++++++++--------- .../X86/gather-null-pointer.ll | 21 ++ 2 files changed, 155 insertions(+), 120 deletions(-) create mode 100644 llvm/test/Transforms/DeadStoreElimination/X86/gather-null-pointer.ll diff --git a/llvm/include/llvm/IR/IntrinsicsX86.td b/llvm/include/llvm/IR/IntrinsicsX86.td index 8d8cc8e97678f..4f4bcbc67bfb8 100644 --- a/llvm/include/llvm/IR/IntrinsicsX86.td +++ b/llvm/include/llvm/IR/IntrinsicsX86.td @@ -1677,71 +1677,73 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // Gather ops let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". + // NOTE: These can't be ArgMemOnly because you can put the address completely + // in the index register. def int_x86_avx2_gather_d_pd : GCCBuiltin<"__builtin_ia32_gatherd_pd">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2f64_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx2_gather_d_pd_256 : GCCBuiltin<"__builtin_ia32_gatherd_pd256">, Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4f64_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx2_gather_q_pd : GCCBuiltin<"__builtin_ia32_gatherq_pd">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2f64_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx2_gather_q_pd_256 : GCCBuiltin<"__builtin_ia32_gatherq_pd256">, Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4f64_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx2_gather_d_ps : GCCBuiltin<"__builtin_ia32_gatherd_ps">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx2_gather_d_ps_256 : GCCBuiltin<"__builtin_ia32_gatherd_ps256">, Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8f32_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx2_gather_q_ps : GCCBuiltin<"__builtin_ia32_gatherq_ps">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx2_gather_q_ps_256 : GCCBuiltin<"__builtin_ia32_gatherq_ps256">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx2_gather_d_q : GCCBuiltin<"__builtin_ia32_gatherd_q">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2i64_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx2_gather_d_q_256 : GCCBuiltin<"__builtin_ia32_gatherd_q256">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i64_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx2_gather_q_q : GCCBuiltin<"__builtin_ia32_gatherq_q">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx2_gather_q_q_256 : GCCBuiltin<"__builtin_ia32_gatherq_q256">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx2_gather_d_d : GCCBuiltin<"__builtin_ia32_gatherd_d">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx2_gather_d_d_256 : GCCBuiltin<"__builtin_ia32_gatherd_d256">, Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx2_gather_q_d : GCCBuiltin<"__builtin_ia32_gatherq_d">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx2_gather_q_d_256 : GCCBuiltin<"__builtin_ia32_gatherq_d256">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; } // Misc. @@ -3564,530 +3566,542 @@ let TargetPrefix = "x86" in { // Gather and Scatter ops let TargetPrefix = "x86" in { // NOTE: These are deprecated in favor of the versions that take a vXi1 mask. + // NOTE: These can't be ArgMemOnly because you can put the address completely + // in the index register. def int_x86_avx512_gather_dpd_512 : GCCBuiltin<"__builtin_ia32_gathersiv8df">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather_dps_512 : GCCBuiltin<"__builtin_ia32_gathersiv16sf">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_ptr_ty, llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather_qpd_512 : GCCBuiltin<"__builtin_ia32_gatherdiv8df">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather_qps_512 : GCCBuiltin<"__builtin_ia32_gatherdiv16sf">, Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather_dpq_512 : GCCBuiltin<"__builtin_ia32_gathersiv8di">, Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather_dpi_512 : GCCBuiltin<"__builtin_ia32_gathersiv16si">, Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_ptr_ty, llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather_qpq_512 : GCCBuiltin<"__builtin_ia32_gatherdiv8di">, Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather_qpi_512 : GCCBuiltin<"__builtin_ia32_gatherdiv16si">, Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather3div2_df : GCCBuiltin<"__builtin_ia32_gather3div2df">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather3div2_di : GCCBuiltin<"__builtin_ia32_gather3div2di">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather3div4_df : GCCBuiltin<"__builtin_ia32_gather3div4df">, Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather3div4_di : GCCBuiltin<"__builtin_ia32_gather3div4di">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather3div4_sf : GCCBuiltin<"__builtin_ia32_gather3div4sf">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather3div4_si : GCCBuiltin<"__builtin_ia32_gather3div4si">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather3div8_sf : GCCBuiltin<"__builtin_ia32_gather3div8sf">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather3div8_si : GCCBuiltin<"__builtin_ia32_gather3div8si">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather3siv2_df : GCCBuiltin<"__builtin_ia32_gather3siv2df">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather3siv2_di : GCCBuiltin<"__builtin_ia32_gather3siv2di">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather3siv4_df : GCCBuiltin<"__builtin_ia32_gather3siv4df">, Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather3siv4_di : GCCBuiltin<"__builtin_ia32_gather3siv4di">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather3siv4_sf : GCCBuiltin<"__builtin_ia32_gather3siv4sf">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather3siv4_si : GCCBuiltin<"__builtin_ia32_gather3siv4si">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather3siv8_sf : GCCBuiltin<"__builtin_ia32_gather3siv8sf">, Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_gather3siv8_si : GCCBuiltin<"__builtin_ia32_gather3siv8si">, Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; // scatter // NOTE: These are deprecated in favor of the versions that take a vXi1 mask. + // NOTE: These can't be ArgMemOnly because you can put the address completely + // in the index register. def int_x86_avx512_scatter_dpd_512 : GCCBuiltin<"__builtin_ia32_scattersiv8df">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v8i32_ty, llvm_v8f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scatter_dps_512 : GCCBuiltin<"__builtin_ia32_scattersiv16sf">, Intrinsic<[], [llvm_ptr_ty, llvm_i16_ty, llvm_v16i32_ty, llvm_v16f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scatter_qpd_512 : GCCBuiltin<"__builtin_ia32_scatterdiv8df">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v8i64_ty, llvm_v8f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scatter_qps_512 : GCCBuiltin<"__builtin_ia32_scatterdiv16sf">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v8i64_ty, llvm_v8f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scatter_dpq_512 : GCCBuiltin<"__builtin_ia32_scattersiv8di">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v8i32_ty, llvm_v8i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scatter_dpi_512 : GCCBuiltin<"__builtin_ia32_scattersiv16si">, Intrinsic<[], [llvm_ptr_ty, llvm_i16_ty, llvm_v16i32_ty, llvm_v16i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scatter_qpq_512 : GCCBuiltin<"__builtin_ia32_scatterdiv8di">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty,llvm_v8i64_ty, llvm_v8i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scatter_qpi_512 : GCCBuiltin<"__builtin_ia32_scatterdiv16si">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v8i64_ty, llvm_v8i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scatterdiv2_df : GCCBuiltin<"__builtin_ia32_scatterdiv2df">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v2i64_ty, llvm_v2f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scatterdiv2_di : GCCBuiltin<"__builtin_ia32_scatterdiv2di">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scatterdiv4_df : GCCBuiltin<"__builtin_ia32_scatterdiv4df">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i64_ty, llvm_v4f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scatterdiv4_di : GCCBuiltin<"__builtin_ia32_scatterdiv4di">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scatterdiv4_sf : GCCBuiltin<"__builtin_ia32_scatterdiv4sf">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v2i64_ty, llvm_v4f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scatterdiv4_si : GCCBuiltin<"__builtin_ia32_scatterdiv4si">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v2i64_ty, llvm_v4i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scatterdiv8_sf : GCCBuiltin<"__builtin_ia32_scatterdiv8sf">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i64_ty, llvm_v4f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scatterdiv8_si : GCCBuiltin<"__builtin_ia32_scatterdiv8si">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i64_ty, llvm_v4i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scattersiv2_df : GCCBuiltin<"__builtin_ia32_scattersiv2df">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v2f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scattersiv2_di : GCCBuiltin<"__builtin_ia32_scattersiv2di">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v2i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scattersiv4_df : GCCBuiltin<"__builtin_ia32_scattersiv4df">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v4f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scattersiv4_di : GCCBuiltin<"__builtin_ia32_scattersiv4di">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v4i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scattersiv4_sf : GCCBuiltin<"__builtin_ia32_scattersiv4sf">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v4f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scattersiv4_si : GCCBuiltin<"__builtin_ia32_scattersiv4si">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scattersiv8_sf : GCCBuiltin<"__builtin_ia32_scattersiv8sf">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v8i32_ty, llvm_v8f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_scattersiv8_si : GCCBuiltin<"__builtin_ia32_scattersiv8si">, Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; // gather prefetch + // NOTE: These can't be ArgMemOnly because you can put the address completely + // in the index register. def int_x86_avx512_gatherpf_dpd_512 : GCCBuiltin<"__builtin_ia32_gatherpfdpd">, Intrinsic<[], [llvm_i8_ty, llvm_v8i32_ty, llvm_ptr_ty, - llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; + llvm_i32_ty, llvm_i32_ty], []>; def int_x86_avx512_gatherpf_dps_512 : GCCBuiltin<"__builtin_ia32_gatherpfdps">, Intrinsic<[], [llvm_i16_ty, llvm_v16i32_ty, llvm_ptr_ty, - llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; + llvm_i32_ty, llvm_i32_ty], []>; def int_x86_avx512_gatherpf_qpd_512 : GCCBuiltin<"__builtin_ia32_gatherpfqpd">, Intrinsic<[], [llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty, - llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; + llvm_i32_ty, llvm_i32_ty], []>; def int_x86_avx512_gatherpf_qps_512 : GCCBuiltin<"__builtin_ia32_gatherpfqps">, Intrinsic<[], [llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty, - llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; + llvm_i32_ty, llvm_i32_ty], []>; // scatter prefetch + // NOTE: These can't be ArgMemOnly because you can put the address completely + // in the index register. def int_x86_avx512_scatterpf_dpd_512 : GCCBuiltin<"__builtin_ia32_scatterpfdpd">, Intrinsic<[], [llvm_i8_ty, llvm_v8i32_ty, llvm_ptr_ty, - llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; + llvm_i32_ty, llvm_i32_ty], []>; def int_x86_avx512_scatterpf_dps_512 : GCCBuiltin<"__builtin_ia32_scatterpfdps">, Intrinsic<[], [llvm_i16_ty, llvm_v16i32_ty, llvm_ptr_ty, - llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; + llvm_i32_ty, llvm_i32_ty], []>; def int_x86_avx512_scatterpf_qpd_512 : GCCBuiltin<"__builtin_ia32_scatterpfqpd">, Intrinsic<[], [llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty, - llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; + llvm_i32_ty, llvm_i32_ty], []>; def int_x86_avx512_scatterpf_qps_512 : GCCBuiltin<"__builtin_ia32_scatterpfqps">, Intrinsic<[], [llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty, - llvm_i32_ty, llvm_i32_ty], [IntrArgMemOnly]>; + llvm_i32_ty, llvm_i32_ty], []>; } // AVX512 gather/scatter intrinsics that use vXi1 masks. let TargetPrefix = "x86" in { + // NOTE: These can't be ArgMemOnly because you can put the address completely + // in the index register. def int_x86_avx512_mask_gather_dpd_512 : Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather_dps_512 : Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_ptr_ty, llvm_v16i32_ty, llvm_v16i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather_qpd_512 : Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_ptr_ty, llvm_v8i64_ty, llvm_v8i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather_qps_512 : Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i64_ty, llvm_v8i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather_dpq_512 : Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather_dpi_512 : Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_ptr_ty, llvm_v16i32_ty, llvm_v16i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather_qpq_512 : Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_ptr_ty, llvm_v8i64_ty, llvm_v8i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather_qpi_512 : Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i64_ty, llvm_v8i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather3div2_df : Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather3div2_di : Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather3div4_df : Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather3div4_di : Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather3div4_sf : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather3div4_si : Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather3div8_sf : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather3div8_si : Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather3siv2_df : Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather3siv2_di : Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather3siv4_df : Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather3siv4_di : Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather3siv4_sf : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather3siv4_si : Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather3siv8_sf : Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_gather3siv8_si : Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i1_ty, llvm_i32_ty], - [IntrReadMem, IntrArgMemOnly]>; + [IntrReadMem]>; def int_x86_avx512_mask_scatter_dpd_512 : Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty, llvm_v8i32_ty, llvm_v8f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scatter_dps_512 : Intrinsic<[], [llvm_ptr_ty, llvm_v16i1_ty, llvm_v16i32_ty, llvm_v16f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scatter_qpd_512 : Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty, llvm_v8i64_ty, llvm_v8f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scatter_qps_512 : Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty, llvm_v8i64_ty, llvm_v8f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; + // NOTE: These can't be ArgMemOnly because you can put the address completely + // in the index register. def int_x86_avx512_mask_scatter_dpq_512 : Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty, llvm_v8i32_ty, llvm_v8i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scatter_dpi_512 : Intrinsic<[], [llvm_ptr_ty, llvm_v16i1_ty, llvm_v16i32_ty, llvm_v16i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scatter_qpq_512 : Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty,llvm_v8i64_ty, llvm_v8i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scatter_qpi_512 : Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty, llvm_v8i64_ty, llvm_v8i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scatterdiv2_df : Intrinsic<[], [llvm_ptr_ty, llvm_v2i1_ty, llvm_v2i64_ty, llvm_v2f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scatterdiv2_di : Intrinsic<[], [llvm_ptr_ty, llvm_v2i1_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scatterdiv4_df : Intrinsic<[], [llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i64_ty, llvm_v4f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scatterdiv4_di : Intrinsic<[], [llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scatterdiv4_sf : Intrinsic<[], [llvm_ptr_ty, llvm_v2i1_ty, llvm_v2i64_ty, llvm_v4f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scatterdiv4_si : Intrinsic<[], [llvm_ptr_ty, llvm_v2i1_ty, llvm_v2i64_ty, llvm_v4i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scatterdiv8_sf : Intrinsic<[], [llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i64_ty, llvm_v4f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scatterdiv8_si : Intrinsic<[], [llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i64_ty, llvm_v4i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scattersiv2_df : Intrinsic<[], [llvm_ptr_ty, llvm_v2i1_ty, llvm_v4i32_ty, llvm_v2f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scattersiv2_di : Intrinsic<[], [llvm_ptr_ty, llvm_v2i1_ty, llvm_v4i32_ty, llvm_v2i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scattersiv4_df : Intrinsic<[], [llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i32_ty, llvm_v4f64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scattersiv4_di : Intrinsic<[], [llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i32_ty, llvm_v4i64_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scattersiv4_sf : Intrinsic<[], [llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i32_ty, llvm_v4f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scattersiv4_si : Intrinsic<[], [llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scattersiv8_sf : Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty, llvm_v8i32_ty, llvm_v8f32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; def int_x86_avx512_mask_scattersiv8_si : Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty], - [IntrArgMemOnly]>; + []>; } // AVX-512 conflict detection instruction diff --git a/llvm/test/Transforms/DeadStoreElimination/X86/gather-null-pointer.ll b/llvm/test/Transforms/DeadStoreElimination/X86/gather-null-pointer.ll new file mode 100644 index 0000000000000..6a5f4bb9eb25c --- /dev/null +++ b/llvm/test/Transforms/DeadStoreElimination/X86/gather-null-pointer.ll @@ -0,0 +1,21 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -dse -S | FileCheck %s + +; Both stores should be emitted because we can't tell if the gather aliases. + +define <4 x i32> @bar(<4 x i32> %arg, i32* %arg1) { +; CHECK-LABEL: @bar( +; CHECK-NEXT: bb: +; CHECK-NEXT: store i32 5, i32* [[ARG1:%.*]] +; CHECK-NEXT: [[TMP:%.*]] = tail call <4 x i32> @llvm.x86.avx2.gather.d.d(<4 x i32> zeroinitializer, i8* null, <4 x i32> [[ARG:%.*]], <4 x i32> , i8 1) +; CHECK-NEXT: store i32 10, i32* [[ARG1]] +; CHECK-NEXT: ret <4 x i32> [[TMP]] +; +bb: + store i32 5, i32* %arg1 + %tmp = tail call <4 x i32> @llvm.x86.avx2.gather.d.d(<4 x i32> zeroinitializer, i8* null, <4 x i32> %arg, <4 x i32> , i8 1) + store i32 10, i32* %arg1 + ret <4 x i32> %tmp +} + +declare <4 x i32> @llvm.x86.avx2.gather.d.d(<4 x i32>, i8*, <4 x i32>, <4 x i32>, i8) From 0a0560be4d230a9930fb523ade995238eadd28ac Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 7 Mar 2019 08:47:57 +0000 Subject: [PATCH 197/274] ReleaseNotes: Open Dylan; by Peter Housel llvm-svn: 355584 --- llvm/docs/ReleaseNotes.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 3007a1bcf78bf..70d31a625abbc 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -238,6 +238,22 @@ x86/x86_64 systems like Linux, OS X, FreeBSD and Windows and also Linux on ARM and PowerPC (32/64 bit). Ports to other architectures like AArch64 and MIPS64 are underway. +Open Dylan Compiler +------------------- + +`Dylan `_ is a multi-paradigm functional +and object-oriented programming language. It is dynamic while +providing a programming model designed to support efficient machine +code generation, including fine-grained control over dynamic and +static behavior. Dylan also features a powerful macro facility for +expressive metaprogramming. + +The Open Dylan compiler can use LLVM as one of its code-generating +back-ends, including full support for debug info generation. (Open +Dylan generates LLVM bitcode directly using a native Dylan IR and +bitcode library.) Development of a Dylan debugger and interactive REPL +making use of the LLDB libraries is in progress. + Zig Programming Language ------------------------ From 768197544c71234dfc83cfc9984a0e9ed7ab33be Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 8 Mar 2019 09:09:28 +0000 Subject: [PATCH 198/274] Merging r354937: ------------------------------------------------------------------------ r354937 | joerg | 2019-02-27 01:40:59 +0100 (Wed, 27 Feb 2019) | 9 lines Fix inline assembler constraint validation The current constraint logic is both too lax and too strict. It fails for input outside the [INT_MIN..INT_MAX] range, but it also implicitly accepts 0 as value when it should not. Adjust logic to handle both correctly. Differential Revision: https://reviews.llvm.org/D58649 ------------------------------------------------------------------------ llvm-svn: 355673 --- clang/include/clang/Basic/TargetInfo.h | 10 ++++++---- clang/test/Sema/inline-asm-validate-x86.c | 4 ++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 1e835d992bbeb..c95cf599ffd4a 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -807,6 +807,7 @@ class TargetInfo : public RefCountedBase { struct { int Min; int Max; + bool isConstrained; } ImmRange; llvm::SmallSet ImmSet; @@ -817,6 +818,7 @@ class TargetInfo : public RefCountedBase { : Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()), Name(Name.str()) { ImmRange.Min = ImmRange.Max = 0; + ImmRange.isConstrained = false; } const std::string &getConstraintStr() const { return ConstraintStr; } @@ -845,8 +847,9 @@ class TargetInfo : public RefCountedBase { return (Flags & CI_ImmediateConstant) != 0; } bool isValidAsmImmediate(const llvm::APInt &Value) const { - return (Value.sge(ImmRange.Min) && Value.sle(ImmRange.Max)) || - ImmSet.count(Value.getZExtValue()) != 0; + if (!ImmSet.empty()) + return ImmSet.count(Value.getZExtValue()) != 0; + return !ImmRange.isConstrained || (Value.sge(ImmRange.Min) && Value.sle(ImmRange.Max)); } void setIsReadWrite() { Flags |= CI_ReadWrite; } @@ -858,6 +861,7 @@ class TargetInfo : public RefCountedBase { Flags |= CI_ImmediateConstant; ImmRange.Min = Min; ImmRange.Max = Max; + ImmRange.isConstrained = true; } void setRequiresImmediate(llvm::ArrayRef Exacts) { Flags |= CI_ImmediateConstant; @@ -870,8 +874,6 @@ class TargetInfo : public RefCountedBase { } void setRequiresImmediate() { Flags |= CI_ImmediateConstant; - ImmRange.Min = INT_MIN; - ImmRange.Max = INT_MAX; } /// Indicate that this is an input operand that is tied to diff --git a/clang/test/Sema/inline-asm-validate-x86.c b/clang/test/Sema/inline-asm-validate-x86.c index f21ef6940a6da..b238ab8a5038f 100644 --- a/clang/test/Sema/inline-asm-validate-x86.c +++ b/clang/test/Sema/inline-asm-validate-x86.c @@ -55,6 +55,7 @@ void K(int i, int j) { void L(int i, int j) { static const int Invalid1 = 1; static const int Invalid2 = 42; + static const int Invalid3 = 0; static const int Valid1 = 0xff; static const int Valid2 = 0xffff; static const int Valid3 = 0xffffffff; @@ -67,6 +68,9 @@ void L(int i, int j) { __asm__("xorl %0,%2" : "=r"(i) : "0"(i), "L"(Invalid2)); // expected-error{{value '42' out of range for constraint 'L'}} + __asm__("xorl %0,%2" + : "=r"(i) + : "0"(i), "L"(Invalid3)); // expected-error{{value '0' out of range for constraint 'L'}} __asm__("xorl %0,%2" : "=r"(i) : "0"(i), "L"(Valid1)); // expected-no-error From 2cc470aae1a15e6ac06a4c0e04b1ac44976b20c4 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 8 Mar 2019 09:16:31 +0000 Subject: [PATCH 199/274] Merging r355491: ------------------------------------------------------------------------ r355491 | hans | 2019-03-06 11:26:19 +0100 (Wed, 06 Mar 2019) | 9 lines Inline asm constraints: allow ICE-like pointers for the "n" constraint (PR40890) Apparently GCC allows this, and there's code relying on it (see bug). The idea is to allow expression that would have been allowed if they were cast to int. So I based the code on how such a cast would be done (the CK_PointerToIntegral case in IntExprEvaluator::VisitCastExpr()). Differential Revision: https://reviews.llvm.org/D58821 ------------------------------------------------------------------------ llvm-svn: 355674 --- clang/include/clang/AST/APValue.h | 6 ++++++ clang/lib/AST/APValue.cpp | 20 ++++++++++++++++++++ clang/lib/AST/ExprConstant.cpp | 11 +++++------ clang/lib/CodeGen/CGStmt.cpp | 11 +++++++++-- clang/lib/Sema/SemaStmtAsm.cpp | 15 ++++++++++++--- clang/test/CodeGen/x86-64-inline-asm.c | 15 +++++++++++++++ clang/test/Sema/inline-asm-validate-x86.c | 20 +++++++++++++++++++- 7 files changed, 86 insertions(+), 12 deletions(-) diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h index d4057c9da5f38..055f13f3620b4 100644 --- a/clang/include/clang/AST/APValue.h +++ b/clang/include/clang/AST/APValue.h @@ -257,6 +257,12 @@ class APValue { return const_cast(this)->getInt(); } + /// Try to convert this value to an integral constant. This works if it's an + /// integer, null pointer, or offset from a null pointer. Returns true on + /// success. + bool toIntegralConstant(APSInt &Result, QualType SrcTy, + const ASTContext &Ctx) const; + APFloat &getFloat() { assert(isFloat() && "Invalid accessor"); return *(APFloat*)(char*)Data.buffer; diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index c05b160b8e3d9..0c2ba57f7986b 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -600,6 +600,26 @@ std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const { return Result; } +bool APValue::toIntegralConstant(APSInt &Result, QualType SrcTy, + const ASTContext &Ctx) const { + if (isInt()) { + Result = getInt(); + return true; + } + + if (isLValue() && isNullPointer()) { + Result = Ctx.MakeIntValue(Ctx.getTargetNullPointerValue(SrcTy), SrcTy); + return true; + } + + if (isLValue() && !getLValueBase()) { + Result = Ctx.MakeIntValue(getLValueOffset().getQuantity(), SrcTy); + return true; + } + + return false; +} + const APValue::LValueBase APValue::getLValueBase() const { assert(isLValue() && "Invalid accessor"); return ((const LV*)(const void*)Data.buffer)->Base; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index da093ff22c123..1f82b4add0c48 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -9821,13 +9821,12 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) { return true; } - uint64_t V; - if (LV.isNullPointer()) - V = Info.Ctx.getTargetNullPointerValue(SrcType); - else - V = LV.getLValueOffset().getQuantity(); + APSInt AsInt; + APValue V; + LV.moveInto(V); + if (!V.toIntegralConstant(AsInt, SrcType, Info.Ctx)) + llvm_unreachable("Can't cast this!"); - APSInt AsInt = Info.Ctx.MakeIntValue(V, SrcType); return Success(HandleIntToIntCast(Info, E, DestType, SrcType, AsInt), E); } diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 0242b48659d10..b2b32759b6f73 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -1821,8 +1821,15 @@ llvm::Value* CodeGenFunction::EmitAsmInput( // (immediate or symbolic), try to emit it as such. if (!Info.allowsRegister() && !Info.allowsMemory()) { if (Info.requiresImmediateConstant()) { - llvm::APSInt AsmConst = InputExpr->EvaluateKnownConstInt(getContext()); - return llvm::ConstantInt::get(getLLVMContext(), AsmConst); + Expr::EvalResult EVResult; + InputExpr->EvaluateAsRValue(EVResult, getContext(), true); + + llvm::APSInt IntResult; + if (!EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(), + getContext())) + llvm_unreachable("Invalid immediate constant!"); + + return llvm::ConstantInt::get(getLLVMContext(), IntResult); } Expr::EvalResult Result; diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index 9e084c99d0dd4..2d8864bab171d 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -383,11 +383,20 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, return StmtError( Diag(InputExpr->getBeginLoc(), diag::err_asm_immediate_expected) << Info.getConstraintStr() << InputExpr->getSourceRange()); - llvm::APSInt Result = EVResult.Val.getInt(); - if (!Info.isValidAsmImmediate(Result)) + + // For compatibility with GCC, we also allow pointers that would be + // integral constant expressions if they were cast to int. + llvm::APSInt IntResult; + if (!EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(), + Context)) + return StmtError( + Diag(InputExpr->getBeginLoc(), diag::err_asm_immediate_expected) + << Info.getConstraintStr() << InputExpr->getSourceRange()); + + if (!Info.isValidAsmImmediate(IntResult)) return StmtError(Diag(InputExpr->getBeginLoc(), diag::err_invalid_asm_value_for_constraint) - << Result.toString(10) << Info.getConstraintStr() + << IntResult.toString(10) << Info.getConstraintStr() << InputExpr->getSourceRange()); } diff --git a/clang/test/CodeGen/x86-64-inline-asm.c b/clang/test/CodeGen/x86-64-inline-asm.c index bb46eda633b70..79c1bd95f38b5 100644 --- a/clang/test/CodeGen/x86-64-inline-asm.c +++ b/clang/test/CodeGen/x86-64-inline-asm.c @@ -1,6 +1,7 @@ // REQUIRES: x86-registered-target // RUN: %clang_cc1 -triple x86_64 %s -S -o /dev/null -DWARN -verify // RUN: %clang_cc1 -triple x86_64 %s -S -o /dev/null -Werror -verify +// RUN: %clang_cc1 -triple x86_64-linux-gnu %s -S -o - | FileCheck %s void f() { asm("movaps %xmm3, (%esi, 2)"); // expected-note@1 {{instantiated into assembly here}} @@ -15,3 +16,17 @@ static unsigned var[1] = {}; void g(void) { asm volatile("movd %%xmm0, %0" : : "m"(var)); } + +void pr40890(void) { + struct s { + int a, b; + } s; + __asm__ __volatile__("\n#define S_A abcd%0\n" : : "n"(&((struct s*)0)->a)); + __asm__ __volatile__("\n#define S_B abcd%0\n" : : "n"(&((struct s*)0)->b)); + __asm__ __volatile__("\n#define BEEF abcd%0\n" : : "n"((int*)0xdeadbeeeeeef)); + +// CHECK-LABEL: pr40890 +// CHECK: #define S_A abcd$0 +// CHECK: #define S_B abcd$4 +// CHECK: #define BEEF abcd$244837814038255 +} diff --git a/clang/test/Sema/inline-asm-validate-x86.c b/clang/test/Sema/inline-asm-validate-x86.c index b238ab8a5038f..5ea20eec05995 100644 --- a/clang/test/Sema/inline-asm-validate-x86.c +++ b/clang/test/Sema/inline-asm-validate-x86.c @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -triple i686 -fsyntax-only -verify %s -// RUN: %clang_cc1 -triple x86_64 -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple x86_64 -fsyntax-only -verify -DAMD64 %s void I(int i, int j) { static const int BelowMin = -1; @@ -133,3 +133,21 @@ void O(int i, int j) { : "0"(i), "O"(64)); // expected-no-error } +void pr40890(void) { + struct s { + int a, b; + }; + static struct s s; + // This null pointer can be used as an integer constant expression. + __asm__ __volatile__("\n#define S_A abcd%0\n" : : "n"(&((struct s*)0)->a)); + // This offset-from-null pointer can be used as an integer constant expression. + __asm__ __volatile__("\n#define S_B abcd%0\n" : : "n"(&((struct s*)0)->b)); + // This pointer cannot be used as an integer constant expression. + __asm__ __volatile__("\n#define GLOBAL_A abcd%0\n" : : "n"(&s.a)); // expected-error{{constraint 'n' expects an integer constant expression}} + // Floating-point is also not okay. + __asm__ __volatile__("\n#define PI abcd%0\n" : : "n"(3.14f)); // expected-error{{constraint 'n' expects an integer constant expression}} +#ifdef AMD64 + // This arbitrary pointer is fine. + __asm__ __volatile__("\n#define BEEF abcd%0\n" : : "n"((int*)0xdeadbeeeeeef)); +#endif +} From 2a1c7bde42261e02cb9f54a1e5b5397e7d18507c Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 8 Mar 2019 09:25:36 +0000 Subject: [PATCH 200/274] Merging r352119: ------------------------------------------------------------------------ r352119 | rnk | 2019-01-24 23:26:51 +0100 (Thu, 24 Jan 2019) | 7 lines [clang-cl] Ignore space-separated /AI arguments The /AI flag is for #using directives, which I don't think we support. This is consistent with how the /I flag is handled by MSVC. Add a test for it. Differential Revision: https://reviews.llvm.org/D57189 ------------------------------------------------------------------------ llvm-svn: 355675 --- clang/include/clang/Driver/CLCompatOptions.td | 2 +- clang/test/Driver/cl-options.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Driver/CLCompatOptions.td b/clang/include/clang/Driver/CLCompatOptions.td index 3e0dc2db7d07e..ce5a435362c1b 100644 --- a/clang/include/clang/Driver/CLCompatOptions.td +++ b/clang/include/clang/Driver/CLCompatOptions.td @@ -395,7 +395,7 @@ def _SLASH_Zo_ : CLIgnoredFlag<"Zo-">; // Unsupported: -def _SLASH_AI : CLJoined<"AI">; +def _SLASH_AI : CLJoinedOrSeparate<"AI">; def _SLASH_Bt : CLFlag<"Bt">; def _SLASH_Bt_plus : CLFlag<"Bt+">; def _SLASH_clr : CLJoined<"clr">; diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c index d8db081ac8a68..1fa2ae3914b1e 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -391,6 +391,7 @@ // (/Zs is for syntax-only) // RUN: %clang_cl /Zs \ // RUN: /AIfoo \ +// RUN: /AI foo_does_not_exist \ // RUN: /Bt \ // RUN: /Bt+ \ // RUN: /clr:pure \ From 60c055135da0c00c07875c7e9b6b8627088860c5 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 8 Mar 2019 09:27:18 +0000 Subject: [PATCH 201/274] Merging r355489: ------------------------------------------------------------------------ r355489 | hans | 2019-03-06 10:38:04 +0100 (Wed, 06 Mar 2019) | 1 line clang-cl: Parse /Qspectre and a few other missing options (PR40964) ------------------------------------------------------------------------ llvm-svn: 355677 --- clang/include/clang/Driver/CLCompatOptions.td | 5 +++++ clang/test/Driver/cl-options.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/clang/include/clang/Driver/CLCompatOptions.td b/clang/include/clang/Driver/CLCompatOptions.td index ce5a435362c1b..ca23f7b819654 100644 --- a/clang/include/clang/Driver/CLCompatOptions.td +++ b/clang/include/clang/Driver/CLCompatOptions.td @@ -395,6 +395,8 @@ def _SLASH_Zo_ : CLIgnoredFlag<"Zo-">; // Unsupported: +def _SLASH_await : CLFlag<"await">; +def _SLASH_constexpr : CLJoined<"constexpr:">; def _SLASH_AI : CLJoinedOrSeparate<"AI">; def _SLASH_Bt : CLFlag<"Bt">; def _SLASH_Bt_plus : CLFlag<"Bt+">; @@ -430,6 +432,9 @@ def _SLASH_Qfast_transcendentals : CLFlag<"Qfast_transcendentals">; def _SLASH_QIfist : CLFlag<"QIfist">; def _SLASH_Qimprecise_fwaits : CLFlag<"Qimprecise_fwaits">; def _SLASH_Qpar : CLFlag<"Qpar">; +def _SLASH_Qpar_report : CLJoined<"Qpar-report">; +def _SLASH_Qsafe_fp_loads : CLFlag<"Qsafe_fp_loads">; +def _SLASH_Qspectre : CLFlag<"Qspectre">; def _SLASH_Qvec_report : CLJoined<"Qvec-report">; def _SLASH_u : CLFlag<"u">; def _SLASH_V : CLFlag<"V">; diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c index 1fa2ae3914b1e..909e391cec6ab 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -390,6 +390,8 @@ // Unsupported but parsed options. Check that we don't error on them. // (/Zs is for syntax-only) // RUN: %clang_cl /Zs \ +// RUN: /await \ +// RUN: /constexpr:depth1000 /constexpr:backtrace1000 /constexpr:steps1000 \ // RUN: /AIfoo \ // RUN: /AI foo_does_not_exist \ // RUN: /Bt \ @@ -443,6 +445,9 @@ // RUN: /QIfist \ // RUN: /Qimprecise_fwaits \ // RUN: /Qpar \ +// RUN: /Qpar-report:1 \ +// RUN: /Qsafe_fp_loads \ +// RUN: /Qspectre \ // RUN: /Qvec-report:2 \ // RUN: /u \ // RUN: /V \ From 25292d1cd55b9a4c788b1c6b0c78647ab88822dd Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Mar 2019 08:29:08 +0000 Subject: [PATCH 202/274] Merging r355743: ------------------------------------------------------------------------ r355743 | ericwf | 2019-03-08 23:06:48 +0100 (Fri, 08 Mar 2019) | 26 lines [8.0 Regression] Fix handling of `__builtin_constant_p` inside template arguments, enumerators, case statements, and the enable_if attribute. Summary: The following code is accepted by Clang 7 and prior but rejected by the upcoming 8 release and in trunk [1] ``` // error {{never produces a constant expression}} void foo(const char* s) __attribute__((enable_if(__builtin_constant_p(*s) == false, "trap"))) {} void test() { foo("abc"); } ``` Prior to Clang 8, the call to `__builtin_constant_p` was a constant expression returning false. Currently, it's not a valid constant expression. The bug is caused because we failed to set `InConstantContext` when attempting to evaluate unevaluated constant expressions. [1] https://godbolt.org/z/ksAjmq Reviewers: rsmith, hans, sbenza Reviewed By: rsmith Subscribers: kristina, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D59038 ------------------------------------------------------------------------ llvm-svn: 355898 --- clang/lib/AST/ExprConstant.cpp | 3 +++ .../SemaCXX/constant-expression-cxx1y.cpp | 24 +++++++++++++++++++ clang/test/SemaCXX/enable_if.cpp | 8 +++++++ 3 files changed, 35 insertions(+) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 1f82b4add0c48..bfe6c78a0ddcb 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -10985,6 +10985,7 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, ConstExprUsage Usage, const ASTContext &Ctx) const { EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression; EvalInfo Info(Ctx, Result, EM); + Info.InConstantContext = true; if (!::Evaluate(Result.Val, Info, this)) return false; @@ -11625,6 +11626,7 @@ bool Expr::EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx, const Expr *This) const { Expr::EvalStatus Status; EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated); + Info.InConstantContext = true; LValue ThisVal; const LValue *ThisPtr = nullptr; @@ -11708,6 +11710,7 @@ bool Expr::isPotentialConstantExprUnevaluated(Expr *E, EvalInfo Info(FD->getASTContext(), Status, EvalInfo::EM_PotentialConstantExpressionUnevaluated); + Info.InConstantContext = true; // Fabricate a call stack frame to give the arguments a plausible cover story. ArrayRef Args; diff --git a/clang/test/SemaCXX/constant-expression-cxx1y.cpp b/clang/test/SemaCXX/constant-expression-cxx1y.cpp index 3c57ac573f2cb..ed51cca82ecac 100644 --- a/clang/test/SemaCXX/constant-expression-cxx1y.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx1y.cpp @@ -1135,3 +1135,27 @@ constexpr bool indirect_builtin_constant_p(const char *__s) { return __builtin_constant_p(*__s); } constexpr bool n = indirect_builtin_constant_p("a"); + +__attribute__((enable_if(indirect_builtin_constant_p("a") == n, "OK"))) +int test_in_enable_if() { return 0; } +int n2 = test_in_enable_if(); + +template +int test_in_template_param() { return 0; } +int n3 = test_in_template_param(); + +void test_in_case(int n) { + switch (n) { + case indirect_builtin_constant_p("abc"): + break; + } +} +enum InEnum1 { + ONE = indirect_builtin_constant_p("abc") +}; +enum InEnum2 : int { + TWO = indirect_builtin_constant_p("abc") +}; +enum class InEnum3 { + THREE = indirect_builtin_constant_p("abc") +}; diff --git a/clang/test/SemaCXX/enable_if.cpp b/clang/test/SemaCXX/enable_if.cpp index ba520b047a324..4bc974dafc289 100644 --- a/clang/test/SemaCXX/enable_if.cpp +++ b/clang/test/SemaCXX/enable_if.cpp @@ -514,3 +514,11 @@ namespace TypeOfFn { static_assert(is_same<__typeof__(foo)*, decltype(&foo)>::value, ""); } + +namespace InConstantContext { +void foo(const char *s) __attribute__((enable_if(((void)__builtin_constant_p(*s), true), "trap"))) {} + +void test() { + InConstantContext::foo("abc"); +} +} // namespace InConstantContext From a73e76ab38fdd9ea6e640fab347e2e0a69f36b09 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 12 Mar 2019 12:52:54 +0000 Subject: [PATCH 203/274] ReleaseNotes: SystemZ, by Ulrich Weigand. llvm-svn: 355916 --- llvm/docs/ReleaseNotes.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 70d31a625abbc..26b0d9d91b640 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -173,6 +173,26 @@ Changes to the PowerPC Target * Enabled llvm-exegesis latency mode for PPC +Changes to the SystemZ Target +----------------------------- + +* A number of bugs related to C/C++ language vector extension support were + fixed: the ``-mzvector`` option now actually enables the ``__vector`` and + ``__bool`` keywords, the ``vec_step`` intrinsic now works, and the + ``vec_insert_and_zero`` and ``vec_orc`` intrinsics now generate correct code. + +* The ``__float128`` keyword, which had been accidentally enabled in some + earlier releases, is now no longer supported. On SystemZ, the ``long double`` + data type itself already uses the IEEE 128-bit floating-point format. + +* When the compiler inlines ``strcmp`` or ``memcmp``, the generated code no + longer returns ``INT_MIN`` as the negative result value under any + circumstances. + +* Various code-gen improvements, in particular related to improved + auto-vectorization, inlining, and instruction scheduling. + + Changes to the X86 Target ------------------------- From 0712a5fe3905b1370ec2045a056ccdf42f9430bd Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 13 Mar 2019 08:49:53 +0000 Subject: [PATCH 204/274] ReleaseNotes: fix sorting, spotted by Eugene Zelenko llvm-svn: 356033 --- clang-tools-extra/docs/ReleaseNotes.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 56a6cd074f873..7c24d28c99f86 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -252,18 +252,18 @@ Improvements to clang-tidy Adds ``[[nodiscard]]`` attributes (introduced in C++17) to member functions to highlight at compile time which return values should not be ignored. -- New :doc:`readability-isolate-decl - ` check. - - Detects local variable declarations declaring more than one variable and - tries to refactor the code to one statement per declaration. - - New :doc:`readability-const-return-type ` check. Checks for functions with a ``const``-qualified return type and recommends removal of the ``const`` keyword. +- New :doc:`readability-isolate-decl + ` check. + + Detects local variable declarations declaring more than one variable and + tries to refactor the code to one statement per declaration. + - New :doc:`readability-magic-numbers ` check. From 2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 13 Mar 2019 08:53:49 +0000 Subject: [PATCH 205/274] ReleaseNotes: Changes to the JIT APIs; by Lang Hames llvm-svn: 356034 --- llvm/docs/ReleaseNotes.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 26b0d9d91b640..8209c08889edc 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -95,6 +95,22 @@ Changes to the LLVM IR `_ must be enabled for the function body. +Changes to the JIT APIs +----------------------- + +The ORC (On Request Compilation) JIT APIs have been updated to support +concurrent compilation. The existing (non-concurrent) ORC layer classes and +related APIs are deprecated, have been renamed with a "Legacy" prefix (e.g. +LegacyIRCompileLayer). The deprecated clasess will be removed in LLVM 9. + +An example JIT stack using the concurrent ORC APIs, called LLJIT, has been +added (see include/llvm/ExecutionEngine/Orc/LLJIT.h). The lli tool has been +updated to use LLJIT. + +MCJIT and ExecutionEngine continue to be supported, though ORC should be +preferred for new projects. + + Changes to the AArch64 Target ----------------------------- From d2298e74235598f15594fe2c99bbac870a507c59 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 15 Mar 2019 08:44:10 +0000 Subject: [PATCH 206/274] Re-generate DiagnosticsReference.rst (PR41080) $ bin/clang-tblgen -gen-diag-docs -I../cfe.src/include -I../cfe.src/include/clang/Basic/ ../cfe.src/include/clang/Basic/Diagnostic.td -o ../cfe.src/docs/DiagnosticsReference.rst llvm-svn: 356240 --- clang/docs/DiagnosticsReference.rst | 2107 ++++++++++++++++++--------- 1 file changed, 1431 insertions(+), 676 deletions(-) diff --git a/clang/docs/DiagnosticsReference.rst b/clang/docs/DiagnosticsReference.rst index 7d9b1e8359a8d..ef0218e8b49e4 100644 --- a/clang/docs/DiagnosticsReference.rst +++ b/clang/docs/DiagnosticsReference.rst @@ -207,17 +207,6 @@ This diagnostic is enabled by default. Controls `-Wpointer-bool-conversion`_, `-Wstring-compare`_, `-Wtautological-pointer-compare`_. --Waddress-of-array-temporary ----------------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+---------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pointer is initialized by a temporary array, which will be destroyed at the end of the full-expression`| -+---------------------------------------------------------------------------------------------------------------------------------------------+ - - -Waddress-of-packed-member -------------------------- This diagnostic is enabled by default. @@ -244,21 +233,6 @@ This diagnostic is an error by default, but the flag ``-Wno-address-of-temporary ------------------ This diagnostic flag exists for GCC compatibility, and has no effect in Clang. --Waligned-allocation-unavailable --------------------------------- -This diagnostic is an error by default, but the flag ``-Wno-aligned-allocation-unavailable`` can be used to disable the error. - -**Diagnostic text:** - -+--------------------------------------------------+--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`aligned` |nbsp| |+------------------------+| |nbsp| :diagtext:`function of type '`:placeholder:`B`:diagtext:`' is only available on` |nbsp| :placeholder:`C` |nbsp| :placeholder:`D` |nbsp| :diagtext:`or newer`| -| ||:diagtext:`allocation` || | -| |+------------------------+| | -| ||:diagtext:`deallocation`|| | -| |+------------------------+| | -+--------------------------------------------------+--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - -Wall ----- Some of the diagnostics controlled by this flag are enabled by default. @@ -473,6 +447,17 @@ This diagnostic is enabled by default. +-----------------------------------------------------------------------------------------------------------------------------+ +-Wargument-outside-range +------------------------ +This diagnostic is an error by default, but the flag ``-Wno-argument-outside-range`` can be used to disable the error. + +**Diagnostic text:** + ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:error:`error:` |nbsp| :diagtext:`argument value` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is outside the valid range \[`:placeholder:`B`:diagtext:`,` |nbsp| :placeholder:`C`:diagtext:`\]`| ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Warray-bounds -------------- This diagnostic is enabled by default. @@ -572,13 +557,41 @@ This diagnostic is enabled by default. -Wat-protocol ------------- +This diagnostic flag exists for GCC compatibility, and has no effect in Clang. + +-Watimport-in-framework-header +------------------------------ This diagnostic is enabled by default. **Diagnostic text:** -+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`@protocol is using a forward protocol declaration of` |nbsp| :placeholder:`A`| -+-------------------------------------------------------------------------------------------------------------------+ ++------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`use of '@import' in framework header is discouraged, including this header requires -fmodules`| ++------------------------------------------------------------------------------------------------------------------------------------+ + + +-Watomic-alignment +------------------ +This diagnostic is enabled by default. + +**Diagnostic text:** + ++---------------------------+------------------------+------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| |+----------------------+| |nbsp| :diagtext:`atomic operation may incur significant performance penalty`| +| ||:diagtext:`large` || | +| |+----------------------+| | +| ||:diagtext:`misaligned`|| | +| |+----------------------+| | ++---------------------------+------------------------+------------------------------------------------------------------------------+ + + +-Watomic-implicit-seq-cst +------------------------- +**Diagnostic text:** + ++---------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`implicit use of sequentially-consistent atomic may incur stronger memory barriers than necessary`| ++---------------------------------------------------------------------------------------------------------------------------------------+ -Watomic-memory-ordering @@ -690,6 +703,20 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`'unavailable' availability overrides all other availability information`| +--------------------------------------------------------------------------------------------------------------+ ++------------------------------------------------------------------------------+----------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ignoring availability attribute` |nbsp| |+--------------------------------------+| +| ||:diagtext:`on '+load' method` || +| |+--------------------------------------+| +| ||:diagtext:`with constructor attribute`|| +| |+--------------------------------------+| +| ||:diagtext:`with destructor attribute` || +| |+--------------------------------------+| ++------------------------------------------------------------------------------+----------------------------------------+ + ++---------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`only 'unavailable' and 'deprecated' are supported for Swift availability`| ++---------------------------------------------------------------------------------------------------------------+ + +------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`unknown platform` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in availability macro`| +------------------------------------------------------------------------------------------------------------------------+ @@ -779,31 +806,44 @@ Also controls `-Wc++98-compat-bind-to-temporary-copy`_. | |+---------------------+| +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------+ -+--------------------------------------------------------------------+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no viable constructor` |nbsp| |+---------------------------------------+| |nbsp| :diagtext:`of type` |nbsp| :placeholder:`B`:diagtext:`; C++98 requires a copy constructor when binding a reference to a temporary`| -| ||:diagtext:`copying variable` || | -| |+---------------------------------------+| | -| ||:diagtext:`copying parameter` || | -| |+---------------------------------------+| | -| ||:diagtext:`returning object` || | -| |+---------------------------------------+| | -| ||:diagtext:`throwing object` || | -| |+---------------------------------------+| | -| ||:diagtext:`copying member subobject` || | -| |+---------------------------------------+| | -| ||:diagtext:`copying array element` || | -| |+---------------------------------------+| | -| ||:diagtext:`allocating object` || | -| |+---------------------------------------+| | -| ||:diagtext:`copying temporary` || | -| |+---------------------------------------+| | -| ||:diagtext:`initializing base subobject`|| | -| |+---------------------------------------+| | -| ||:diagtext:`initializing vector element`|| | -| |+---------------------------------------+| | -| ||:diagtext:`capturing value` || | -| |+---------------------------------------+| | -+--------------------------------------------------------------------+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ ++--------------------------------------------------------------------+------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`no viable constructor` |nbsp| |+----------------------------------------------------+| |nbsp| :diagtext:`of type` |nbsp| :placeholder:`B`:diagtext:`; C++98 requires a copy constructor when binding a reference to a temporary`| +| ||:diagtext:`copying variable` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`copying parameter` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`returning object` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`initializing statement expression result`|| | +| |+----------------------------------------------------+| | +| ||:diagtext:`throwing object` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`copying member subobject` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`copying array element` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`allocating object` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`copying temporary` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`initializing base subobject` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`initializing vector element` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`capturing value` || | +| |+----------------------------------------------------+| | ++--------------------------------------------------------------------+------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + + +-Wbinding-in-condition +---------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++--------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ISO C++17 does not permit structured binding declaration in a condition`| ++--------------------------------------------------------------------------------------------------------------+ -Wbitfield-constant-conversion @@ -944,9 +984,9 @@ This diagnostic is enabled by default. **Diagnostic text:** -+------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`will always overflow destination buffer`| -+------------------------------------------------------------------------------------------------------+ ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' will always overflow; destination buffer has size` |nbsp| :placeholder:`B`:diagtext:`, but size argument is` |nbsp| :placeholder:`C`| ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -Wbuiltin-requires-header @@ -1180,28 +1220,6 @@ Also controls `-Wc++11-extra-semi`_, `-Wc++11-inline-namespace`_, `-Wc++11-long- |:warning:`warning:` |nbsp| :diagtext:`default template arguments for a function template are a C++11 extension`| +---------------------------------------------------------------------------------------------------------------+ -+-------------------------------------------------------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`first declaration of` |nbsp| |+-------------------------------------+| |nbsp| :diagtext:`specialization of` |nbsp| :placeholder:`B` |nbsp| :diagtext:`outside namespace` |nbsp| :placeholder:`C` |nbsp| :diagtext:`is a C++11 extension`| -| ||:diagtext:`class template` || | -| |+-------------------------------------+| | -| ||:diagtext:`class template partial` || | -| |+-------------------------------------+| | -| ||:diagtext:`variable template` || | -| |+-------------------------------------+| | -| ||:diagtext:`variable template partial`|| | -| |+-------------------------------------+| | -| ||:diagtext:`function template` || | -| |+-------------------------------------+| | -| ||:diagtext:`member function` || | -| |+-------------------------------------+| | -| ||:diagtext:`static data member` || | -| |+-------------------------------------+| | -| ||:diagtext:`member class` || | -| |+-------------------------------------+| | -| ||:diagtext:`member enumeration` || | -| |+-------------------------------------+| | -+-------------------------------------------------------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - +------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`'typename' occurs outside of a template`| +------------------------------------------------------------------------------+ @@ -1402,6 +1420,10 @@ Some of the diagnostics controlled by this flag are enabled by default. **Diagnostic text:** ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ISO C++ standards before C++17 do not allow new expression for type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to use list-initialization`| ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`constexpr if is a C++17 extension`| +------------------------------------------------------------------------+ @@ -1501,8 +1523,22 @@ Synonym for `-Wc++17-extensions`_. -Wc++2a-compat -------------- +Some of the diagnostics controlled by this flag are enabled by default. + **Diagnostic text:** ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`aggregate initialization of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`with user-declared constructors is incompatible with C++2a`| ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + ++------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'<=>' is a single token in C++2a; add a space to avoid a change in behavior`| ++------------------------------------------------------------------------------------------------------------------+ + ++--------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`type of UTF-8 string literal will change from array of const char to array of const char8\_t in C++2a`| ++--------------------------------------------------------------------------------------------------------------------------------------------+ + +-------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is a keyword in C++2a`| +-------------------------------------------------------------------------------------------+ @@ -1523,10 +1559,34 @@ Some of the diagnostics controlled by this flag are enabled by default. |:warning:`warning:` |nbsp| :diagtext:`default member initializer for bit-field is a C++2a extension`| +----------------------------------------------------------------------------------------------------+ ++-----------------------------------------------------------------------------------+-------------------------+----------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`use of this statement in a constexpr` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is a C++2a extension`| +| ||:diagtext:`function` || | +| |+-----------------------+| | +| ||:diagtext:`constructor`|| | +| |+-----------------------+| | ++-----------------------------------------------------------------------------------+-------------------------+----------------------------------------+ + ++------------------------------------------------------------------------------+-------------------------+----------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`function try block in constexpr` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is a C++2a extension`| +| ||:diagtext:`function` || | +| |+-----------------------+| | +| ||:diagtext:`constructor`|| | +| |+-----------------------+| | ++------------------------------------------------------------------------------+-------------------------+----------------------------------------+ + +--------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`explicit capture of 'this' with a capture default of '=' is a C++2a extension`| +--------------------------------------------------------------------------------------------------------------------+ ++-----------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`range-based for loop initialization statements are a C++2a extension`| ++-----------------------------------------------------------------------------------------------------------+ + ++----------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`inline nested namespace definition is a C++2a extension`| ++----------------------------------------------------------------------------------------------+ + +--------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`invoking a pointer to a 'const &' member function on an rvalue is a C++2a extension`| +--------------------------------------------------------------------------------------------------------------------------+ @@ -1540,10 +1600,66 @@ Some of the diagnostics controlled by this flag are enabled by default. |:warning:`warning:` |nbsp| :diagtext:`default member initializer for bit-field is incompatible with C++ standards before C++2a`| +-------------------------------------------------------------------------------------------------------------------------------+ ++-----------------------------------------------------------------------------------+-------------------------+-------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`use of this statement in a constexpr` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is incompatible with C++ standards before C++2a`| +| ||:diagtext:`function` || | +| |+-----------------------+| | +| ||:diagtext:`constructor`|| | +| |+-----------------------+| | ++-----------------------------------------------------------------------------------+-------------------------+-------------------------------------------------------------------+ + ++------------------------------------------------------------------------------+-------------------------+-------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`function try block in constexpr` |nbsp| |+-----------------------+| |nbsp| :diagtext:`is incompatible with C++ standards before C++2a`| +| ||:diagtext:`function` || | +| |+-----------------------+| | +| ||:diagtext:`constructor`|| | +| |+-----------------------+| | ++------------------------------------------------------------------------------+-------------------------+-------------------------------------------------------------------+ + ++-------------------------------------------------------------------------+--------------------------------------+----------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`explicitly defaulting this` |nbsp| |+------------------------------------+| |nbsp| :diagtext:`with a type different from the implicit type is incompatible with C++ standards before C++2a`| +| ||:diagtext:`default constructor` || | +| |+------------------------------------+| | +| ||:diagtext:`copy constructor` || | +| |+------------------------------------+| | +| ||:diagtext:`move constructor` || | +| |+------------------------------------+| | +| ||:diagtext:`copy assignment operator`|| | +| |+------------------------------------+| | +| ||:diagtext:`move assignment operator`|| | +| |+------------------------------------+| | +| ||:diagtext:`destructor` || | +| |+------------------------------------+| | ++-------------------------------------------------------------------------+--------------------------------------+----------------------------------------------------------------------------------------------------------------+ + +-----------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`explicit capture of 'this' with a capture default of '=' is incompatible with C++ standards before C++2a`| +-----------------------------------------------------------------------------------------------------------------------------------------------+ ++--------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`range-based for loop initialization statements are incompatible with C++ standards before C++2a`| ++--------------------------------------------------------------------------------------------------------------------------------------+ + ++-------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`inline nested namespace definition is incompatible with C++ standards before C++2a`| ++-------------------------------------------------------------------------------------------------------------------------+ + ++---------------------------+----------------------------------+-----------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| |+--------------------------------+| |nbsp| :diagtext:`of lambda is incompatible with C++ standards before C++2a`| +| ||:diagtext:`default construction`|| | +| |+--------------------------------+| | +| ||:diagtext:`assignment` || | +| |+--------------------------------+| | ++---------------------------+----------------------------------+-----------------------------------------------------------------------------+ + ++-----------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'<=>' operator is incompatible with C++ standards before C++2a`| ++-----------------------------------------------------------------------------------------------------+ + ++----------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'char8\_t' type specifier is incompatible with C++ standards before C++20`| ++----------------------------------------------------------------------------------------------------------------+ + -Wc++98-c++11-c++14-c++17-compat-pedantic ----------------------------------------- @@ -1560,6 +1676,16 @@ Also controls `-Wc++98-c++11-c++14-c++17-compat`_. -------------------------- **Diagnostic text:** ++------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`class template argument deduction is incompatible with C++ standards before C++17`|+---------------------------------------------------------------------------------+| +| || || +| |+---------------------------------------------------------------------------------+| +| ||+-------------------------------------------------------------------------------+|| +| |||:diagtext:`; for compatibility, use explicit type name` |nbsp| :placeholder:`B`||| +| ||+-------------------------------------------------------------------------------+|| +| |+---------------------------------------------------------------------------------+| ++------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------+ + +---------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`constexpr if is incompatible with C++ standards before C++17`| +---------------------------------------------------------------------------------------------------+ @@ -1688,10 +1814,18 @@ Also controls `-Wc++98-c++11-c++14-compat`_. |:warning:`warning:` |nbsp| :diagtext:`'decltype(auto)' type specifier is incompatible with C++ standards before C++14`| +----------------------------------------------------------------------------------------------------------------------+ ++------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`return type deduction is incompatible with C++ standards before C++14`| ++------------------------------------------------------------------------------------------------------------+ + +--------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`digit separators are incompatible with C++ standards before C++14`| +--------------------------------------------------------------------------------------------------------+ ++----------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`generic lambdas are incompatible with C++11`| ++----------------------------------------------------------------------------------+ + +-------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`initialized lambda captures are incompatible with C++ standards before C++14`| +-------------------------------------------------------------------------------------------------------------------+ @@ -1855,7 +1989,7 @@ Also controls `-Wc++98-c++11-c++14-c++17-compat`_, `-Wc++98-c++11-c++14-compat`_ +---------------------------+------------------------------+------------------------------------------------------------------------------------------------+--------------------------------------+----------------------------------------------+ |:warning:`warning:` |nbsp| |+----------------------------+| |nbsp| :diagtext:`member` |nbsp| :placeholder:`B` |nbsp| :diagtext:`with a non-trivial` |nbsp| |+------------------------------------+| |nbsp| :diagtext:`is incompatible with C++98`| -| ||:diagtext:`anonymous struct`|| ||:diagtext:`constructor` || | +| ||:diagtext:`anonymous struct`|| ||:diagtext:`default constructor` || | | |+----------------------------+| |+------------------------------------+| | | ||:diagtext:`union` || ||:diagtext:`copy constructor` || | | |+----------------------------+| |+------------------------------------+| | @@ -1949,28 +2083,6 @@ Also controls `-Wc++98-c++11-c++14-c++17-compat`_, `-Wc++98-c++11-c++14-compat`_ |:warning:`warning:` |nbsp| :diagtext:`default template arguments for a function template are incompatible with C++98`| +---------------------------------------------------------------------------------------------------------------------+ -+---------------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------------------------+| |nbsp| :diagtext:`specialization of` |nbsp| :placeholder:`B` |nbsp| :diagtext:`outside namespace` |nbsp| :placeholder:`C` |nbsp| :diagtext:`is incompatible with C++98`| -| ||:diagtext:`class template` || | -| |+-------------------------------------+| | -| ||:diagtext:`class template partial` || | -| |+-------------------------------------+| | -| ||:diagtext:`variable template` || | -| |+-------------------------------------+| | -| ||:diagtext:`variable template partial`|| | -| |+-------------------------------------+| | -| ||:diagtext:`function template` || | -| |+-------------------------------------+| | -| ||:diagtext:`member function` || | -| |+-------------------------------------+| | -| ||:diagtext:`static data member` || | -| |+-------------------------------------+| | -| ||:diagtext:`member class` || | -| |+-------------------------------------+| | -| ||:diagtext:`member enumeration` || | -| |+-------------------------------------+| | -+---------------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - +----------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`trailing return types are incompatible with C++98`| +----------------------------------------------------------------------------------------+ @@ -2022,29 +2134,42 @@ Also controls `-Wc++98-c++11-c++14-c++17-compat`_, `-Wc++98-c++11-c++14-compat`_ ------------------------------------- **Diagnostic text:** -+---------------------------+-----------------------------------------+----------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+----------------------------+ -|:warning:`warning:` |nbsp| |+---------------------------------------+| |nbsp| :diagtext:`of type` |nbsp| :placeholder:`C` |nbsp| :diagtext:`when binding a reference to a temporary would` |nbsp| |+----------------------------------------------+| |nbsp| :diagtext:`in C++98`| -| ||:diagtext:`copying variable` || ||:diagtext:`invoke an inaccessible constructor`|| | -| |+---------------------------------------+| |+----------------------------------------------+| | -| ||:diagtext:`copying parameter` || ||:diagtext:`find no viable constructor` || | -| |+---------------------------------------+| |+----------------------------------------------+| | -| ||:diagtext:`returning object` || ||:diagtext:`find ambiguous constructors` || | -| |+---------------------------------------+| |+----------------------------------------------+| | -| ||:diagtext:`throwing object` || ||:diagtext:`invoke a deleted constructor` || | -| |+---------------------------------------+| |+----------------------------------------------+| | -| ||:diagtext:`copying member subobject` || | | | -| |+---------------------------------------+| | | | -| ||:diagtext:`copying array element` || | | | -| |+---------------------------------------+| | | | -| ||:diagtext:`allocating object` || | | | -| |+---------------------------------------+| | | | -| ||:diagtext:`copying temporary` || | | | -| |+---------------------------------------+| | | | -| ||:diagtext:`initializing base subobject`|| | | | -| |+---------------------------------------+| | | | -| ||:diagtext:`initializing vector element`|| | | | -| |+---------------------------------------+| | | | -+---------------------------+-----------------------------------------+----------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+----------------------------+ ++---------------------------+------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+----------------------------+ +|:warning:`warning:` |nbsp| |+----------------------------------------------------+| |nbsp| :diagtext:`of type` |nbsp| :placeholder:`C` |nbsp| :diagtext:`when binding a reference to a temporary would` |nbsp| |+----------------------------------------------+| |nbsp| :diagtext:`in C++98`| +| ||:diagtext:`copying variable` || ||:diagtext:`invoke an inaccessible constructor`|| | +| |+----------------------------------------------------+| |+----------------------------------------------+| | +| ||:diagtext:`copying parameter` || ||:diagtext:`find no viable constructor` || | +| |+----------------------------------------------------+| |+----------------------------------------------+| | +| ||:diagtext:`returning object` || ||:diagtext:`find ambiguous constructors` || | +| |+----------------------------------------------------+| |+----------------------------------------------+| | +| ||:diagtext:`initializing statement expression result`|| ||:diagtext:`invoke a deleted constructor` || | +| |+----------------------------------------------------+| |+----------------------------------------------+| | +| ||:diagtext:`throwing object` || | | | +| |+----------------------------------------------------+| | | | +| ||:diagtext:`copying member subobject` || | | | +| |+----------------------------------------------------+| | | | +| ||:diagtext:`copying array element` || | | | +| |+----------------------------------------------------+| | | | +| ||:diagtext:`allocating object` || | | | +| |+----------------------------------------------------+| | | | +| ||:diagtext:`copying temporary` || | | | +| |+----------------------------------------------------+| | | | +| ||:diagtext:`initializing base subobject` || | | | +| |+----------------------------------------------------+| | | | +| ||:diagtext:`initializing vector element` || | | | +| |+----------------------------------------------------+| | | | +| ||:diagtext:`capturing value` || | | | +| |+----------------------------------------------------+| | | | ++---------------------------+------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+----------------------------+ + + +-Wc++98-compat-extra-semi +------------------------- +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`extra ';' outside of a function is incompatible with C++98`| ++-------------------------------------------------------------------------------------------------+ -Wc++98-compat-local-type-template-args @@ -2058,7 +2183,7 @@ Also controls `-Wc++98-c++11-c++14-c++17-compat`_, `-Wc++98-c++11-c++14-compat`_ -Wc++98-compat-pedantic ----------------------- -Also controls `-Wc++98-c++11-c++14-c++17-compat-pedantic`_, `-Wc++98-c++11-c++14-compat-pedantic`_, `-Wc++98-c++11-compat-pedantic`_, `-Wc++98-compat`_, `-Wc++98-compat-bind-to-temporary-copy`_. +Also controls `-Wc++98-c++11-c++14-c++17-compat-pedantic`_, `-Wc++98-c++11-c++14-compat-pedantic`_, `-Wc++98-c++11-compat-pedantic`_, `-Wc++98-compat`_, `-Wc++98-compat-bind-to-temporary-copy`_, `-Wc++98-compat-extra-semi`_. **Diagnostic text:** @@ -2098,10 +2223,6 @@ Also controls `-Wc++98-c++11-c++14-c++17-compat-pedantic`_, `-Wc++98-c++11-c++14 |:warning:`warning:` |nbsp| :diagtext:`#line number greater than 32767 is incompatible with C++98`| +-------------------------------------------------------------------------------------------------+ -+-------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`extra ';' outside of a function is incompatible with C++98`| -+-------------------------------------------------------------------------------------------------+ - +----------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`variadic macros are incompatible with C++98`| +----------------------------------------------------------------------------------+ @@ -2225,6 +2346,21 @@ Some of the diagnostics controlled by this flag are enabled by default. +---------------------------------------------------------------------------------------+ +-Wcall-to-pure-virtual-from-ctor-dtor +------------------------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+----------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`call to pure virtual member function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`has undefined behavior; overrides of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in subclasses are not available in the` |nbsp| |+-----------------------+| |nbsp| :diagtext:`of` |nbsp| :placeholder:`C`| +| ||:diagtext:`constructor`|| | +| |+-----------------------+| | +| ||:diagtext:`destructor` || | +| |+-----------------------+| | ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+----------------------------------------------+ + + -Wcast-align ------------ **Diagnostic text:** @@ -2275,6 +2411,29 @@ This diagnostic is enabled by default. +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-Wcast-qual-unrelated +--------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++---------------------------------------------------------------------+-----------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ISO C++ does not allow` |nbsp| |+---------------------------------+| |nbsp| :diagtext:`from` |nbsp| :placeholder:`B` |nbsp| :diagtext:`to` |nbsp| :placeholder:`C` |nbsp| :diagtext:`because it casts away qualifiers, even though the source and destination types are unrelated`| +| ||:diagtext:`const\_cast` || | +| |+---------------------------------+| | +| ||:diagtext:`static\_cast` || | +| |+---------------------------------+| | +| ||:diagtext:`reinterpret\_cast` || | +| |+---------------------------------+| | +| ||:diagtext:`dynamic\_cast` || | +| |+---------------------------------+| | +| ||:diagtext:`C-style cast` || | +| |+---------------------------------+| | +| ||:diagtext:`functional-style cast`|| | +| |+---------------------------------+| | ++---------------------------------------------------------------------+-----------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wchar-align ------------ This diagnostic flag exists for GCC compatibility, and has no effect in Clang. @@ -2310,14 +2469,18 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`support for '/Yc' and '/Yu' with different filenames not implemented yet; flags ignored`| +------------------------------------------------------------------------------------------------------------------------------+ -+--------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`support for '`:placeholder:`A`:diagtext:`' without a filename not implemented yet; flag ignored`| -+--------------------------------------------------------------------------------------------------------------------------------------+ - +----------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`support for '`:placeholder:`A`:diagtext:`' without a corresponding /FI flag not implemented yet; flag ignored`| +----------------------------------------------------------------------------------------------------------------------------------------------------+ ++-------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`#pragma hdrstop filename not supported, /Fp can be used to specify precompiled header filename`| ++-------------------------------------------------------------------------------------------------------------------------------------+ + ++-----------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`definition of macro` |nbsp| :placeholder:`A` |nbsp| :diagtext:`does not match definition in precompiled header`| ++-----------------------------------------------------------------------------------------------------------------------------------------------------+ + -Wclass-varargs --------------- @@ -2516,7 +2679,7 @@ This diagnostic is enabled by default. ------------ Some of the diagnostics controlled by this flag are enabled by default. -Also controls `-Wbitfield-enum-conversion`_, `-Wbool-conversion`_, `-Wconstant-conversion`_, `-Wenum-conversion`_, `-Wfloat-conversion`_, `-Wint-conversion`_, `-Wliteral-conversion`_, `-Wnon-literal-null-conversion`_, `-Wnull-conversion`_, `-Wobjc-literal-conversion`_, `-Wshorten-64-to-32`_, `-Wsign-conversion`_, `-Wstring-conversion`_. +Also controls `-Wbitfield-enum-conversion`_, `-Wbool-conversion`_, `-Wconstant-conversion`_, `-Wenum-conversion`_, `-Wfloat-conversion`_, `-Wimplicit-float-conversion`_, `-Wimplicit-int-conversion`_, `-Wint-conversion`_, `-Wliteral-conversion`_, `-Wnon-literal-null-conversion`_, `-Wnull-conversion`_, `-Wobjc-literal-conversion`_, `-Wshorten-64-to-32`_, `-Wsign-conversion`_, `-Wstring-conversion`_. **Diagnostic text:** @@ -2524,18 +2687,14 @@ Also controls `-Wbitfield-enum-conversion`_, `-Wbool-conversion`_, `-Wconstant-c |:warning:`warning:` |nbsp| :diagtext:`implicit conversion discards imaginary component:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| +--------------------------------------------------------------------------------------------------------------------------------------------------------------+ -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion loses floating-point precision:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+----------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion loses integer precision:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------+ - +--------------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`implicit conversion turns vector to scalar:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| +--------------------------------------------------------------------------------------------------------------------------------------------------------+ ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`passing non-generic address space pointer to` |nbsp| :placeholder:`A` |nbsp| :diagtext:`may cause dynamic conversion affecting performance`| ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`non-type template argument with value '`:placeholder:`A`:diagtext:`' converted to '`:placeholder:`B`:diagtext:`' for unsigned template parameter of type` |nbsp| :placeholder:`C`| +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ @@ -2597,6 +2756,17 @@ Synonym for `-W#warnings`_. ------------------- This diagnostic flag exists for GCC compatibility, and has no effect in Clang. +-Wctu +----- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`imported AST from '`:placeholder:`A`:diagtext:`' had been generated for a different target, current:` |nbsp| :placeholder:`B`:diagtext:`, imported:` |nbsp| :placeholder:`C`| ++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wcuda-compat ------------- Some of the diagnostics controlled by this flag are enabled by default. @@ -2637,6 +2807,55 @@ Some of the diagnostics controlled by this flag are enabled by default. +---------------------------------------------------------------------------------------------------------------------------------------+--------------------+----------------------------------------------------------------------------+ +-Wdangling +---------- +This diagnostic is enabled by default. + +Also controls `-Wdangling-field`_, `-Wdangling-initializer-list`_, `-Wreturn-stack-address`_. + +**Diagnostic text:** + ++---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+----------------------------+---------------------------------------------------------------+ +|:warning:`warning:` |nbsp| |+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| |nbsp| |+--------------------------+|:diagtext:`will be destroyed at the end of the full-expression`| +| ||+-----------------------------+---------------------------------------------------------+--------+------------------------------------------------------------------------+|| ||+------------------------+|| | +| |||:diagtext:`temporary` |nbsp| |+-------------------------------------------------------+| |nbsp| |+----------------------------------------------------------------------+||| |||:placeholder:`D` |nbsp| ||| | +| ||| ||:diagtext:`whose address is used as value of` || ||+-------------------------------+------------------------------------+|||| ||+------------------------+|| | +| ||| |+-------------------------------------------------------+| |||+-----------------------------+|:diagtext:`member of local variable`||||| |+--------------------------+| | +| ||| ||+--------------------------------+--------------------+|| |||| || ||||| || || | +| ||| |||+------------------------------+|:diagtext:`bound to`||| |||+-----------------------------+| ||||| |+--------------------------+| | +| ||| |||| || ||| ||||:diagtext:`reference` |nbsp| || ||||| | | | +| ||| |||+------------------------------+| ||| |||+-----------------------------+| ||||| | | | +| ||| ||||:diagtext:`implicitly` |nbsp| || ||| ||+-------------------------------+------------------------------------+|||| | | | +| ||| |||+------------------------------+| ||| |+----------------------------------------------------------------------+||| | | | +| ||| ||+--------------------------------+--------------------+|| ||+-------------------------+-----------------------+ |||| | | | +| ||| |+-------------------------------------------------------+| |||:diagtext:`local` |nbsp| |+---------------------+| |||| | | | +| ||| | | ||| ||:diagtext:`variable` || |||| | | | +| ||| | | ||| |+---------------------+| |||| | | | +| ||| | | ||| ||:diagtext:`reference`|| |||| | | | +| ||| | | ||| |+---------------------+| |||| | | | +| ||| | | ||+-------------------------+-----------------------+ |||| | | | +| ||| | | |+----------------------------------------------------------------------+||| | | | +| ||+-----------------------------+---------------------------------------------------------+--------+------------------------------------------------------------------------+|| | | | +| |+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| | | | +| ||+---------------------------------+----------------------------------------------------------+ || | | | +| |||:diagtext:`array backing` |nbsp| |+--------------------------------------------------------+| || | | | +| ||| ||:diagtext:`initializer list subobject of local variable`|| || | | | +| ||| |+--------------------------------------------------------+| || | | | +| ||| ||:diagtext:`local initializer list` || || | | | +| ||| |+--------------------------------------------------------+| || | | | +| ||+---------------------------------+----------------------------------------------------------+ || | | | +| |+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| | | | ++---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+----------------------------+---------------------------------------------------------------+ + ++---------------------------------------------------------------------------+-----------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+---------------------------+--------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`sorry, lifetime extension of` |nbsp| |+---------------------------------------------+| |nbsp| :diagtext:`created by aggregate initialization using default member initializer is not supported; lifetime of` |nbsp| |+-------------------------+| |nbsp| :diagtext:`will end at the end of the full-expression`| +| ||:diagtext:`temporary` || ||:diagtext:`temporary` || | +| |+---------------------------------------------+| |+-------------------------+| | +| ||:diagtext:`backing array of initializer list`|| ||:diagtext:`backing array`|| | +| |+---------------------------------------------+| |+-------------------------+| | ++---------------------------------------------------------------------------+-----------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+---------------------------+--------------------------------------------------------------+ + + -Wdangling-else --------------- This diagnostic is enabled by default. @@ -2654,21 +2873,33 @@ This diagnostic is enabled by default. **Diagnostic text:** -+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`binding reference member` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to stack allocated parameter` |nbsp| :placeholder:`B`| -+---------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++-------------------------------------------------------------------------------------------------------------------------------------+-----------------------+------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`binding reference member` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to stack allocated` |nbsp| |+---------------------+| |nbsp| :placeholder:`B`| +| ||:diagtext:`variable` || | +| |+---------------------+| | +| ||:diagtext:`parameter`|| | +| |+---------------------+| | ++-------------------------------------------------------------------------------------------------------------------------------------+-----------------------+------------------------+ -+----------------------------------------------------------------+----------------------------------+----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`binding reference` |nbsp| |+--------------------------------+|:diagtext:`member` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to a temporary value`| -| || || | -| |+--------------------------------+| | -| ||:diagtext:`subobject of` |nbsp| || | -| |+--------------------------------+| | -+----------------------------------------------------------------+----------------------------------+----------------------------------------------------------------------------------+ ++---------------------------+--------------------------------------------------------+--------+----------------------------------+--------------------------------------------------+----------------------+------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| |+------------------------------------------------------+| |nbsp| |+--------------------------------+|:diagtext:`member` |nbsp| :placeholder:`A` |nbsp| |+--------------------+| |nbsp| :diagtext:`a temporary object whose lifetime is shorter than the lifetime of the constructed object`| +| ||:diagtext:`reference` || || || ||:diagtext:`binds to`|| | +| |+------------------------------------------------------+| |+--------------------------------+| |+--------------------+| | +| ||:diagtext:`backing array for 'std::initializer\_list'`|| ||:diagtext:`subobject of` |nbsp| || ||:diagtext:`is` || | +| |+------------------------------------------------------+| |+--------------------------------+| |+--------------------+| | ++---------------------------+--------------------------------------------------------+--------+----------------------------------+--------------------------------------------------+----------------------+------------------------------------------------------------------------------------------------------------+ -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`initializing pointer member` |nbsp| :placeholder:`A` |nbsp| :diagtext:`with the stack address of parameter` |nbsp| :placeholder:`B`| -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++-----------------------------------------------------------------------------------------------------------------------------------------------+-----------------------+------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`initializing pointer member` |nbsp| :placeholder:`A` |nbsp| :diagtext:`with the stack address of` |nbsp| |+---------------------+| |nbsp| :placeholder:`B`| +| ||:diagtext:`variable` || | +| |+---------------------+| | +| ||:diagtext:`parameter`|| | +| |+---------------------+| | ++-----------------------------------------------------------------------------------------------------------------------------------------------+-----------------------+------------------------+ + ++--------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`temporary bound to reference member of allocated object will be destroyed at the end of the full-expression`| ++--------------------------------------------------------------------------------------------------------------------------------------------------+ -Wdangling-initializer-list @@ -2677,13 +2908,24 @@ This diagnostic is enabled by default. **Diagnostic text:** -+-----------------------------------------------------------------------------------------------------------------+---------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`array backing the initializer list will be destroyed at the end of` |nbsp| |+-------------------------------+| -| ||:diagtext:`the full-expression`|| -| |+-------------------------------+| -| ||:diagtext:`the constructor` || -| |+-------------------------------+| -+-----------------------------------------------------------------------------------------------------------------+---------------------------------+ ++------------------------------------------------------------+----------------------------------------------------------------+-----------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`array backing` |nbsp| |+--------------------------------------------------------------+| |nbsp| :diagtext:`will be destroyed at the end of the full-expression`| +| ||:diagtext:`initializer list subobject of the allocated object`|| | +| |+--------------------------------------------------------------+| | +| ||:diagtext:`the allocated initializer list` || | +| |+--------------------------------------------------------------+| | ++------------------------------------------------------------+----------------------------------------------------------------+-----------------------------------------------------------------------+ + + +-Wdarwin-sdk-settings +--------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++----------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`SDK settings were ignored as 'SDKSettings.json' could not be parsed`| ++----------------------------------------------------------------------------------------------------------+ -Wdate-time @@ -2726,6 +2968,29 @@ This diagnostic is enabled by default. +-----------------------------------------------------------------------------------+ +-Wdefaulted-function-deleted +---------------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-------------------------------------------------------------------+--------------------------------------+-----------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`explicitly defaulted` |nbsp| |+------------------------------------+| |nbsp| :diagtext:`is implicitly deleted`| +| ||:diagtext:`default constructor` || | +| |+------------------------------------+| | +| ||:diagtext:`copy constructor` || | +| |+------------------------------------+| | +| ||:diagtext:`move constructor` || | +| |+------------------------------------+| | +| ||:diagtext:`copy assignment operator`|| | +| |+------------------------------------+| | +| ||:diagtext:`move assignment operator`|| | +| |+------------------------------------+| | +| ||:diagtext:`destructor` || | +| |+------------------------------------+| | ++-------------------------------------------------------------------+--------------------------------------+-----------------------------------------+ + + -Wdelegating-ctor-cycles ------------------------ This diagnostic is an error by default, but the flag ``-Wno-delegating-ctor-cycles`` can be used to disable the error. @@ -2737,6 +3002,21 @@ This diagnostic is an error by default, but the flag ``-Wno-delegating-ctor-cycl +------------------------------------------------------------------------------------------------------------------------+ +-Wdelete-abstract-non-virtual-dtor +---------------------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++---------------------------+------------------------+------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| |+----------------------+| |nbsp| :diagtext:`called on` |nbsp| :placeholder:`B` |nbsp| :diagtext:`that is abstract but has non-virtual destructor`| +| ||:diagtext:`delete` || | +| |+----------------------+| | +| ||:diagtext:`destructor`|| | +| |+----------------------+| | ++---------------------------+------------------------+------------------------------------------------------------------------------------------------------------------------+ + + -Wdelete-incomplete ------------------- This diagnostic is enabled by default. @@ -2752,20 +3032,10 @@ This diagnostic is enabled by default. +--------------------------------------------------------------------------------------------------------------------------------------------------+ --Wdelete-non-virtual-dtor -------------------------- -Some of the diagnostics controlled by this flag are enabled by default. - +-Wdelete-non-abstract-non-virtual-dtor +-------------------------------------- **Diagnostic text:** -+---------------------------+------------------------+------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+----------------------+| |nbsp| :diagtext:`called on` |nbsp| :placeholder:`B` |nbsp| :diagtext:`that is abstract but has non-virtual destructor`| -| ||:diagtext:`delete` || | -| |+----------------------+| | -| ||:diagtext:`destructor`|| | -| |+----------------------+| | -+---------------------------+------------------------+------------------------------------------------------------------------------------------------------------------------+ - +---------------------------+------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| |+----------------------+| |nbsp| :diagtext:`called on non-final` |nbsp| :placeholder:`B` |nbsp| :diagtext:`that has virtual functions but non-virtual destructor`| | ||:diagtext:`delete` || | @@ -2775,11 +3045,18 @@ Some of the diagnostics controlled by this flag are enabled by default. +---------------------------+------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +-Wdelete-non-virtual-dtor +------------------------- +Some of the diagnostics controlled by this flag are enabled by default. + +Controls `-Wdelete-abstract-non-virtual-dtor`_, `-Wdelete-non-abstract-non-virtual-dtor`_. + + -Wdeprecated ------------ Some of the diagnostics controlled by this flag are enabled by default. -Also controls `-Wdeprecated-attributes`_, `-Wdeprecated-declarations`_, `-Wdeprecated-dynamic-exception-spec`_, `-Wdeprecated-increment-bool`_, `-Wdeprecated-register`_, `-Wdeprecated-writable-strings`_. +Also controls `-Wdeprecated-attributes`_, `-Wdeprecated-declarations`_, `-Wdeprecated-dynamic-exception-spec`_, `-Wdeprecated-increment-bool`_, `-Wdeprecated-register`_, `-Wdeprecated-this-capture`_, `-Wdeprecated-writable-strings`_. **Diagnostic text:** @@ -2957,6 +3234,15 @@ This diagnostic is enabled by default. +-------------------------------------------------------------------------------------------------------------------+ +-Wdeprecated-this-capture +------------------------- +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`implicit capture of 'this' with a capture default of '=' is deprecated`| ++-------------------------------------------------------------------------------------------------------------+ + + -Wdeprecated-writable-strings ----------------------------- Synonym for `-Wc++11-compat-deprecated-writable-strings`_. @@ -3283,7 +3569,7 @@ Also controls `-Wdocumentation-unknown-command`_. -Wduplicate-decl-specifier -------------------------- -This diagnostic is enabled by default. +Some of the diagnostics controlled by this flag are enabled by default. **Diagnostic text:** @@ -3295,6 +3581,14 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`duplicate '`:placeholder:`A`:diagtext:`' declaration specifier`| +-----------------------------------------------------------------------------------------------------+ ++-------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`multiple identical address spaces specified for type`| ++-------------------------------------------------------------------------------------------+ + ++-----------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`duplicate '`:placeholder:`A`:diagtext:`' declaration specifier`| ++-----------------------------------------------------------------------------------------------------+ + -Wduplicate-enum ---------------- @@ -3418,6 +3712,21 @@ This diagnostic is enabled by default. +-------------------------------------------------------------------------------------------------+ +-Wempty-init-stmt +----------------- +**Diagnostic text:** + ++--------------------------------------------------------------------------+-----------------------------+---------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`empty initialization statement of '`|+---------------------------+|:diagtext:`' has no effect`| +| ||:diagtext:`if` || | +| |+---------------------------+| | +| ||:diagtext:`switch` || | +| |+---------------------------+| | +| ||:diagtext:`range-based for`|| | +| |+---------------------------+| | ++--------------------------------------------------------------------------+-----------------------------+---------------------------+ + + -Wempty-translation-unit ------------------------ **Diagnostic text:** @@ -3540,6 +3849,21 @@ Some of the diagnostics controlled by this flag are enabled by default. +-------------------------------------------------------------------------------------------------+ +-Wexperimental-isel +------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`-fexperimental-isel support for the '`:placeholder:`A`:diagtext:`' architecture is incomplete`| ++------------------------------------------------------------------------------------------------------------------------------------+ + ++----------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`-fexperimental-isel support is incomplete for this architecture at the current optimization level`| ++----------------------------------------------------------------------------------------------------------------------------------------+ + + -Wexplicit-initialize-call -------------------------- This diagnostic is enabled by default. @@ -3564,15 +3888,6 @@ This diagnostic is enabled by default. +-------------------------------------------------------------------------------------------------------------------------------------+ --Wextended-offsetof -------------------- -**Diagnostic text:** - -+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`using extended field designator is an extension`| -+--------------------------------------------------------------------------------------+ - - -Wextern-c-compat ----------------- This diagnostic is enabled by default. @@ -3603,7 +3918,7 @@ This diagnostic is enabled by default. ------- Some of the diagnostics controlled by this flag are enabled by default. -Also controls `-Wignored-qualifiers`_, `-Winitializer-overrides`_, `-Wmissing-field-initializers`_, `-Wmissing-method-return-type`_, `-Wnull-pointer-arithmetic`_, `-Wsemicolon-before-method-body`_, `-Wsign-compare`_, `-Wunused-parameter`_. +Also controls `-Wempty-init-stmt`_, `-Wignored-qualifiers`_, `-Winitializer-overrides`_, `-Wmissing-field-initializers`_, `-Wmissing-method-return-type`_, `-Wnull-pointer-arithmetic`_, `-Wsemicolon-before-method-body`_, `-Wsign-compare`_, `-Wunused-parameter`_. **Diagnostic text:** @@ -3625,7 +3940,7 @@ This diagnostic is enabled by default. -Wextra-semi ------------ -Also controls `-Wc++11-extra-semi`_. +Also controls `-Wc++11-extra-semi`_, `-Wc++98-compat-extra-semi`_. **Diagnostic text:** @@ -3648,6 +3963,17 @@ Also controls `-Wc++11-extra-semi`_. +---------------------------------------------------------------------------------+ +-Wextra-semi-stmt +----------------- +Also controls `-Wempty-init-stmt`_. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`empty expression statement has no effect; remove unnecessary ';' to silence this warning`| ++-------------------------------------------------------------------------------------------------------------------------------+ + + -Wextra-tokens -------------- This diagnostic is enabled by default. @@ -3674,6 +4000,15 @@ This diagnostic is enabled by default. +------------------------------------------------------------------------------+ +-Wfixed-enum-extension +---------------------- +**Diagnostic text:** + ++-----------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`enumeration types with a fixed underlying type are a Clang extension`| ++-----------------------------------------------------------------------------------------------------------+ + + -Wflag-enum ----------- This diagnostic is enabled by default. @@ -3722,9 +4057,13 @@ Also controls `-Wfloat-overflow-conversion`_, `-Wfloat-zero-conversion`_. --------------------------- **Diagnostic text:** -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit conversion of out of range value from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`changes value from` |nbsp| :placeholder:`C` |nbsp| :diagtext:`to` |nbsp| :placeholder:`D`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`implicit conversion from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`changes value from` |nbsp| :placeholder:`C` |nbsp| :diagtext:`to` |nbsp| :placeholder:`D`| ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`implicit conversion of out of range value from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is undefined`| ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -Wfloat-zero-conversion @@ -3960,6 +4299,14 @@ This diagnostic is enabled by default. ----------------- **Diagnostic text:** ++---------------------------+----------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| |+--------------------------------------------+| |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' should not be used as format arguments; add an explicit cast to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`instead`| +| ||:diagtext:`values of type` || | +| |+--------------------------------------------+| | +| ||:diagtext:`enum values with underlying type`|| | +| |+--------------------------------------------+| | ++---------------------------+----------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------------+ |:warning:`warning:` |nbsp| :diagtext:`format specifies type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`but the argument has` |nbsp| |+---------------------------+| |nbsp| :placeholder:`B`| | ||:diagtext:`type` || | @@ -4024,6 +4371,17 @@ The text of this diagnostic is not controlled by Clang. +--------------------------------------------------------------------------------------------------------------------------------------+ +-Wframework-include-private-from-public +--------------------------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`public framework header includes private framework header '`:placeholder:`A`:diagtext:`'`| ++-------------------------------------------------------------------------------------------------------------------------------+ + + -Wfunction-def-in-objc-container -------------------------------- This diagnostic is enabled by default. @@ -4035,6 +4393,21 @@ This diagnostic is enabled by default. +--------------------------------------------------------------------------------------------------------+ +-Wfunction-multiversion +----------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`body of cpu\_dispatch function will be ignored`| ++-------------------------------------------------------------------------------------+ + ++---------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`CPU list contains duplicate entries; attribute ignored`| ++---------------------------------------------------------------------------------------------+ + + -Wfuture-compat --------------- This diagnostic flag exists for GCC compatibility, and has no effect in Clang. @@ -4073,6 +4446,14 @@ Some of the diagnostics controlled by this flag are enabled by default. |:warning:`warning:` |nbsp| :diagtext:`GCC does not allow an attribute in this position on a function declaration`| +-----------------------------------------------------------------------------------------------------------------+ ++------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`GCC does not allow the` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute to be written on a type`| ++------------------------------------------------------------------------------------------------------------------------------------------+ + ++-------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`GCC does not allow variable declarations in for loop initializers before C99`| ++-------------------------------------------------------------------------------------------------------------------+ + +----------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is bound to current loop, GCC binds it to the enclosing loop`| +----------------------------------------------------------------------------------------------------------------------------------+ @@ -4433,6 +4814,10 @@ This diagnostic is enabled by default. **Diagnostic text:** ++--------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'trivial\_abi' cannot be applied to` |nbsp| :placeholder:`A`| ++--------------------------------------------------------------------------------------------------+ + +---------------------------+-------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| |+-----------------+| |nbsp| :diagtext:`will always resolve to` |nbsp| :placeholder:`A` |nbsp| :diagtext:`even if weak definition of` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is overridden`| | ||:diagtext:`alias`|| | @@ -4557,103 +4942,39 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`\_\_weak attribute cannot be specified on an automatic variable when ARC is not enabled`| +------------------------------------------------------------------------------------------------------------------------------+ -+------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute only applies to` |nbsp| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`unions` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`variables and functions` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions and global variables` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions, variables, and Objective-C interfaces` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions and methods` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`parameters` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions, methods and blocks` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions, methods, and classes` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions, methods, and parameters` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions, methods, and global variables` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`classes` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`enums` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`variables` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`methods` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`fields and global variables` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`structs` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`parameters and typedefs` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`variables and typedefs` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`thread-local variables` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`variables and fields` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`variables, data members and tag types` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`types and namespaces` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`Objective-C interfaces` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`methods and properties` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions, methods, and properties` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`struct or union` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`struct, union or class` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`types` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`Objective-C instance methods` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`init methods of interface or class extension declarations` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`variables, functions and classes` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions, variables, classes, and Objective-C interfaces` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`Objective-C protocols` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`variables with static or thread storage duration` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions, methods, properties, and global variables` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`structs, unions, and typedefs` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`structs and typedefs` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`interface or protocol declarations` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`kernel functions` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`non-K&R-style functions` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`variables, enums, fields and typedefs` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`functions, methods, enums, and classes` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`structs, classes, variables, functions, and inline namespaces` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members`|| -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`classes and enumerations` || -| |+----------------------------------------------------------------------------------------------------------------+| -| ||:diagtext:`named declarations` || -| |+----------------------------------------------------------------------------------------------------------------+| -+------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+ ++------------------------------------------------------------------------------------------------+---------------------------------------------------+ +|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute only applies to` |nbsp| |+-------------------------------------------------+| +| ||:diagtext:`functions` || +| |+-------------------------------------------------+| +| ||:diagtext:`unions` || +| |+-------------------------------------------------+| +| ||:diagtext:`variables and functions` || +| |+-------------------------------------------------+| +| ||:diagtext:`functions and methods` || +| |+-------------------------------------------------+| +| ||:diagtext:`functions, methods and blocks` || +| |+-------------------------------------------------+| +| ||:diagtext:`functions, methods, and parameters` || +| |+-------------------------------------------------+| +| ||:diagtext:`variables` || +| |+-------------------------------------------------+| +| ||:diagtext:`variables and fields` || +| |+-------------------------------------------------+| +| ||:diagtext:`variables, data members and tag types`|| +| |+-------------------------------------------------+| +| ||:diagtext:`types and namespaces` || +| |+-------------------------------------------------+| +| ||:diagtext:`variables, functions and classes` || +| |+-------------------------------------------------+| +| ||:diagtext:`kernel functions` || +| |+-------------------------------------------------+| +| ||:diagtext:`non-K&R-style functions` || +| |+-------------------------------------------------+| ++------------------------------------------------------------------------------------------------+---------------------------------------------------+ + ++----------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute only applies to` |nbsp| :placeholder:`B`| ++----------------------------------------------------------------------------------------------------------------+ +--------------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`attribute` |nbsp| :placeholder:`A` |nbsp| :diagtext:`ignored, because it cannot be applied to omitted return type`| @@ -4721,6 +5042,14 @@ This diagnostic is enabled by default. | |+----------------------------------+| +---------------------------------------------------------------------------+------------------------------------+ ++------------------------------------------------------------------------------------------------------------------+-----------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'objc\_externally\_retained' can only be applied to local variables` |nbsp| |+---------------------------------+| +| ||:diagtext:`of retainable type` || +| |+---------------------------------+| +| ||:diagtext:`with strong ownership`|| +| |+---------------------------------+| ++------------------------------------------------------------------------------------------------------------------+-----------------------------------+ + +--------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`'internal\_linkage' attribute on a non-static local variable is ignored`| +--------------------------------------------------------------------------------------------------------------+ @@ -4741,15 +5070,33 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`unknown attribute '`:placeholder:`A`:diagtext:`'`| +---------------------------------------------------------------------------------------+ -+------------------------------------------------------------------------------------------------+-----------------------------------+------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute only applies to` |nbsp| |+---------------------------------+| |nbsp| :diagtext:`parameters`| -| ||:diagtext:`Objective-C object` || | -| |+---------------------------------+| | -| ||:diagtext:`pointer` || | -| |+---------------------------------+| | -| ||:diagtext:`pointer-to-CF-pointer`|| | -| |+---------------------------------+| | -+------------------------------------------------------------------------------------------------+-----------------------------------+------------------------------+ ++---------------------------------------------------------------------------------------------------------------+----------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`MSP430 'interrupt' attribute only applies to functions that have` |nbsp| |+--------------------------------+| +| ||:diagtext:`no parameters` || +| |+--------------------------------+| +| ||:diagtext:`a 'void' return type`|| +| |+--------------------------------+| ++---------------------------------------------------------------------------------------------------------------+----------------------------------+ + ++-------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'nocf\_check' attribute ignored; use -fcf-protection to enable the attribute`| ++-------------------------------------------------------------------------------------------------------------------+ + ++---------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'noderef' can only be used on an array or pointer type`| ++---------------------------------------------------------------------------------------------+ + ++------------------------------------------------------------------------------------------------+---------------------------------------------------+------------------------------+ +|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute only applies to` |nbsp| |+-------------------------------------------------+| |nbsp| :diagtext:`parameters`| +| ||:diagtext:`Objective-C object` || | +| |+-------------------------------------------------+| | +| ||:diagtext:`pointer` || | +| |+-------------------------------------------------+| | +| ||:diagtext:`pointer-to-CF-pointer` || | +| |+-------------------------------------------------+| | +| ||:diagtext:`pointer/reference-to-OSObject-pointer`|| | +| |+-------------------------------------------------+| | ++------------------------------------------------------------------------------------------------+---------------------------------------------------+------------------------------+ +------------------------------------------------------------------------------------------------+------------------------+---------------------------------------+--------------------------------------+ |:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute only applies to` |nbsp| |+----------------------+| |nbsp| :diagtext:`that return` |nbsp| |+------------------------------------+| @@ -4765,6 +5112,18 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute is deprecated and ignored in OpenCL version` |nbsp| :placeholder:`B`| +--------------------------------------------------------------------------------------------------------------------------------------------+ ++---------------------------------------------------------------------------------------------------------------+----------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`RISC-V 'interrupt' attribute only applies to functions that have` |nbsp| |+--------------------------------+| +| ||:diagtext:`no parameters` || +| |+--------------------------------+| +| ||:diagtext:`a 'void' return type`|| +| |+--------------------------------+| ++---------------------------------------------------------------------------------------------------------------+----------------------------------+ + ++----------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`repeated RISC-V 'interrupt' attribute`| ++----------------------------------------------------------------------------+ + +---------------------------+-----------------------+---------------------------------------------------------------------------------------------------------------------------------------------+-----------------------+-------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| |+---------------------+| |nbsp| :diagtext:`of field` |nbsp| :placeholder:`B` |nbsp| :diagtext:`(`:placeholder:`C` |nbsp| :diagtext:`bits) does not match the` |nbsp| |+---------------------+| |nbsp| :diagtext:`of the first field in transparent union; transparent\_union attribute ignored`| | ||:diagtext:`alignment`|| ||:diagtext:`alignment`|| | @@ -4803,13 +5162,17 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`\_\_declspec attribute` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not supported`| +-------------------------------------------------------------------------------------------------------------------------+ -+-------------------------------------------------------+-------------------------+----------------------------------+---------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring` |nbsp| |+-----------------------+|+--------------------------------+| |nbsp| :diagtext:`'`:placeholder:`C`:diagtext:`' in the target attribute string`| -| ||:diagtext:`unsupported`||| || | -| |+-----------------------+|+--------------------------------+| | -| ||:diagtext:`duplicate` ||| |nbsp| :diagtext:`architecture`|| | -| |+-----------------------+|+--------------------------------+| | -+-------------------------------------------------------+-------------------------+----------------------------------+---------------------------------------------------------------------------------+ ++---------------------------+-------------------------+----------------------------------+---------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| |+-----------------------+|+--------------------------------+| |nbsp| :diagtext:`'`:placeholder:`C`:diagtext:`' in the 'target' attribute string; 'target' attribute ignored`| +| ||:diagtext:`unsupported`||| || | +| |+-----------------------+|+--------------------------------+| | +| ||:diagtext:`duplicate` ||| |nbsp| :diagtext:`architecture`|| | +| |+-----------------------+|+--------------------------------+| | ++---------------------------+-------------------------+----------------------------------+---------------------------------------------------------------------------------------------------------------+ + ++----------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'\_\_clang\_\_' is a predefined macro name, not an attribute scope specifier; did you mean '\_Clang' instead?`| ++----------------------------------------------------------------------------------------------------------------------------------------------------+ -Wignored-optimization-argument @@ -4842,11 +5205,22 @@ This diagnostic is enabled by default. +------------------------------------------------------------------------------------------+------------------------------------------------------------------------------+ +-Wignored-pragma-optimize +------------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++--------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'#pragma optimize' is not supported`| ++--------------------------------------------------------------------------+ + + -Wignored-pragmas ----------------- This diagnostic is enabled by default. -Also controls `-Wignored-pragma-intrinsic`_. +Also controls `-Wignored-pragma-intrinsic`_, `-Wignored-pragma-optimize`_. **Diagnostic text:** @@ -4894,6 +5268,10 @@ Also controls `-Wignored-pragma-intrinsic`_. |:warning:`warning:` |nbsp| :diagtext:`missing ':' or ')' after` |nbsp| :placeholder:`A` |nbsp| :diagtext:`- ignoring`| +---------------------------------------------------------------------------------------------------------------------+ ++----------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`expected ',' in '#pragma` |nbsp| :placeholder:`A`:diagtext:`'`| ++----------------------------------------------------------------------------------------------------+ + +---------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`expected identifier in '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`| +---------------------------------------------------------------------------------------------------------------------+ @@ -4942,6 +5320,10 @@ Also controls `-Wignored-pragma-intrinsic`_. |:warning:`warning:` |nbsp| :diagtext:`expected push, pop or a string literal for the section name in '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`| +-------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++--------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`expected string literal in '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignoring`| ++--------------------------------------------------------------------------------------------------------------------------+ + +---------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`extra tokens at end of '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`| +---------------------------------------------------------------------------------------------------------------------+ @@ -4958,10 +5340,30 @@ Also controls `-Wignored-pragma-intrinsic`_. |:warning:`warning:` |nbsp| :diagtext:`unknown action for '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`| +-----------------------------------------------------------------------------------------------------------------+ ++------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`unexpected argument '`:placeholder:`A`:diagtext:`' to '#pragma` |nbsp| :placeholder:`B`:diagtext:`'`|+------------------------------------------------+| +| || || +| |+------------------------------------------------+| +| ||+----------------------------------------------+|| +| |||:diagtext:`; expected` |nbsp| :placeholder:`D`||| +| ||+----------------------------------------------+|| +| |+------------------------------------------------+| ++------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------+ + +------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`unknown action '`:placeholder:`B`:diagtext:`' for '#pragma` |nbsp| :placeholder:`A`:diagtext:`' - ignored`| +------------------------------------------------------------------------------------------------------------------------------------------------+ ++--------------------------------------------------------------------------------------------------------+--------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`missing argument to '#pragma` |nbsp| :placeholder:`A`:diagtext:`'`|+------------------------------------------------+| +| || || +| |+------------------------------------------------+| +| ||+----------------------------------------------+|| +| |||:diagtext:`; expected` |nbsp| :placeholder:`C`||| +| ||+----------------------------------------------+|| +| |+------------------------------------------------+| ++--------------------------------------------------------------------------------------------------------+--------------------------------------------------+ + +----------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`incorrect use of '#pragma ms\_struct on\|off' - ignored`| +----------------------------------------------------------------------------------------------+ @@ -5039,13 +5441,13 @@ Some of the diagnostics controlled by this flag are enabled by default. |:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' qualifier on omitted return type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`has no effect`| +---------------------------------------------------------------------------------------------------------------------------------------------------------------+ -+------------------------------------------------------------------------------------+---------------+------------------------------------------+-------------------+-----------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' type qualifier`|+-------------+| |nbsp| :diagtext:`on return type` |nbsp| |+-----------------+| |nbsp| :diagtext:`no effect`| -| || || ||:diagtext:`:has` || | -| |+-------------+| |+-----------------+| | -| ||:diagtext:`s`|| ||:diagtext:`:have`|| | -| |+-------------+| |+-----------------+| | -+------------------------------------------------------------------------------------+---------------+------------------------------------------+-------------------+-----------------------------+ ++------------------------------------------------------------------------------------+---------------+------------------------------------------+------------------+-----------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' type qualifier`|+-------------+| |nbsp| :diagtext:`on return type` |nbsp| |+----------------+| |nbsp| :diagtext:`no effect`| +| || || ||:diagtext:`has` || | +| |+-------------+| |+----------------+| | +| ||:diagtext:`s`|| ||:diagtext:`have`|| | +| |+-------------+| |+----------------+| | ++------------------------------------------------------------------------------------+---------------+------------------------------------------+------------------+-----------------------------+ +---------------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' qualifier on function type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`has no effect`| @@ -5126,19 +5528,28 @@ Also controls `-Wimplicit-fallthrough-per-function`_. +------------------------------------------------------------------------------------------------------------------+ +-Wimplicit-float-conversion +--------------------------- +**Diagnostic text:** + ++----------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`implicit conversion loses floating-point precision:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| ++----------------------------------------------------------------------------------------------------------------------------------------------------------------+ + ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`implicit conversion when assigning computation result loses floating-point precision:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wimplicit-function-declaration ------------------------------- Some of the diagnostics controlled by this flag are enabled by default. **Diagnostic text:** -+----------------------------------------------------------------------------------------------------------------------------------------+--------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit declaration of function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is invalid in` |nbsp| |+------------------+| -| ||:diagtext:`C99` || -| |+------------------+| -| ||:diagtext:`OpenCL`|| -| |+------------------+| -+----------------------------------------------------------------------------------------------------------------------------------------+--------------------+ ++------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`implicit declaration of function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is invalid in C99`| ++------------------------------------------------------------------------------------------------------------------------------------+ +---------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`implicitly declaring library function '`:placeholder:`A`:diagtext:`' with type` |nbsp| :placeholder:`B`| @@ -5164,6 +5575,19 @@ This diagnostic is enabled by default. +--------------------------------------------------------------------------------+ +-Wimplicit-int-conversion +------------------------- +**Diagnostic text:** + ++---------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`higher order bits are zeroes after implicit conversion`| ++---------------------------------------------------------------------------------------------+ + ++---------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`implicit conversion loses integer precision:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| ++---------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wimplicit-retain-self ---------------------- **Diagnostic text:** @@ -5295,6 +5719,10 @@ This diagnostic is an error by default, but the flag ``-Wno-incompatible-ms-stru |:error:`error:` |nbsp| :diagtext:`ms\_struct may not produce Microsoft-compatible layouts for classes with base classes or virtual functions`| +---------------------------------------------------------------------------------------------------------------------------------------------+ ++------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:error:`error:` |nbsp| :diagtext:`ms\_struct may not produce Microsoft-compatible layouts with fundamental data types with sizes that aren't a power of two`| ++------------------------------------------------------------------------------------------------------------------------------------------------------------+ + -Wincompatible-pointer-types ---------------------------- @@ -5388,6 +5816,17 @@ This diagnostic is enabled by default. +------------------------------------------------------------------------------------------------------------------------------------+ +-Wincomplete-framework-module-declaration +----------------------------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`skipping '`:placeholder:`A`:diagtext:`' because module declaration of '`:placeholder:`B`:diagtext:`' lacks the 'framework' qualifier`| ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wincomplete-implementation --------------------------- This diagnostic is enabled by default. @@ -5642,6 +6081,18 @@ Also controls `-Wignored-optimization-argument`_. **Diagnostic text:** ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`the given MCU supports` |nbsp| :placeholder:`A` |nbsp| :diagtext:`hardware multiply, but -mhwmult is set to` |nbsp| :placeholder:`B`:diagtext:`.`| ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`no MCU device specified, but '-mhwmult' is set to 'auto', assuming no hardware multiply. Use -mmcu to specify a MSP430 device, or -mhwmult to set hardware multiply type explicitly.`| ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + ++----------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`the given MCU does not support hardware multiply, but -mhwmult is set to` |nbsp| :placeholder:`A`:diagtext:`.`| ++----------------------------------------------------------------------------------------------------------------------------------------------------+ + +-----------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`the object size sanitizer has no effect at -O0, but is explicitly enabled:` |nbsp| :placeholder:`A`| +-----------------------------------------------------------------------------------------------------------------------------------------+ @@ -5900,6 +6351,10 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`implicit conversion from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`changes value from` |nbsp| :placeholder:`C` |nbsp| :diagtext:`to` |nbsp| :placeholder:`D`| +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`implicit conversion of out of range value from` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is undefined`| ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + -Wliteral-range --------------- @@ -6065,6 +6520,21 @@ This diagnostic is enabled by default. +----------------------------------------------------------------+---------------------------------------+------------------------------------------------------+ +-Wmemset-transposed-args +------------------------ +This diagnostic is enabled by default. + +**Diagnostic text:** + ++---------------------------+-----------------------------------------------------+---------------------------------------------------------------+ +|:warning:`warning:` |nbsp| |+---------------------------------------------------+|:diagtext:`; did you mean to transpose the last two arguments?`| +| ||:diagtext:`'size' argument to memset is '0'` || | +| |+---------------------------------------------------+| | +| ||:diagtext:`setting buffer to a 'sizeof' expression`|| | +| |+---------------------------------------------------+| | ++---------------------------+-----------------------------------------------------+---------------------------------------------------------------+ + + -Wmemsize-comparison -------------------- This diagnostic is enabled by default. @@ -6333,6 +6803,17 @@ This diagnostic is enabled by default. +----------------------------------------------------------------------------------------------------------+ +-Wmicrosoft-inaccessible-base +----------------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`accessing inaccessible direct base` |nbsp| :placeholder:`A` |nbsp| :diagtext:`of` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is a Microsoft extension`| ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wmicrosoft-include ------------------- This diagnostic is enabled by default. @@ -6400,10 +6881,6 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`use of identifier` |nbsp| :placeholder:`A` |nbsp| :diagtext:`found via unqualified lookup into dependent bases of class templates is a Microsoft extension`| +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`explicit specialization of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`within class scope is a Microsoft extension`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------+ - +-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`using the undeclared type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`as a default template argument is a Microsoft extension`| +-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ @@ -6412,27 +6889,27 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`non-type template argument containing a dereference operation is a Microsoft extension`| +-----------------------------------------------------------------------------------------------------------------------------+ -+---------------------------+---------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------------------------+| |nbsp| :diagtext:`specialization of` |nbsp| :placeholder:`B` |nbsp| :diagtext:`outside namespace enclosing` |nbsp| :placeholder:`C` |nbsp| :diagtext:`is a Microsoft extension`| -| ||:diagtext:`class template` || | -| |+-------------------------------------+| | -| ||:diagtext:`class template partial` || | -| |+-------------------------------------+| | -| ||:diagtext:`variable template` || | -| |+-------------------------------------+| | -| ||:diagtext:`variable template partial`|| | -| |+-------------------------------------+| | -| ||:diagtext:`function template` || | -| |+-------------------------------------+| | -| ||:diagtext:`member function` || | -| |+-------------------------------------+| | -| ||:diagtext:`static data member` || | -| |+-------------------------------------+| | -| ||:diagtext:`member class` || | -| |+-------------------------------------+| | -| ||:diagtext:`member enumeration` || | -| |+-------------------------------------+| | -+---------------------------+---------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++---------------------------+---------------------------------------+-----------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------+--------------------------------------------+ +|:warning:`warning:` |nbsp| |+-------------------------------------+| |nbsp| :diagtext:`specialization of` |nbsp| :placeholder:`B` |nbsp| :diagtext:`not in` |nbsp| |+----------------------------------------------------------------------------------------+| |nbsp| :diagtext:`is a Microsoft extension`| +| ||:diagtext:`class template` || ||+---------------------------------------------------------+ || | +| |+-------------------------------------+| |||:diagtext:`a namespace enclosing` |nbsp| :placeholder:`C`| || | +| ||:diagtext:`class template partial` || ||+---------------------------------------------------------+ || | +| |+-------------------------------------+| |+----------------------------------------------------------------------------------------+| | +| ||:diagtext:`variable template` || ||+--------------------------------------------------------------------------------------+|| | +| |+-------------------------------------+| |||:diagtext:`class` |nbsp| :placeholder:`C` |nbsp| :diagtext:`or an enclosing namespace`||| | +| ||:diagtext:`variable template partial`|| ||+--------------------------------------------------------------------------------------+|| | +| |+-------------------------------------+| |+----------------------------------------------------------------------------------------+| | +| ||:diagtext:`function template` || | | | +| |+-------------------------------------+| | | | +| ||:diagtext:`member function` || | | | +| |+-------------------------------------+| | | | +| ||:diagtext:`static data member` || | | | +| |+-------------------------------------+| | | | +| ||:diagtext:`member class` || | | | +| |+-------------------------------------+| | | | +| ||:diagtext:`member enumeration` || | | | +| |+-------------------------------------+| | | | ++---------------------------+---------------------------------------+-----------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------+--------------------------------------------+ +------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`template argument for template type parameter must be a type; omitted 'typename' is a Microsoft extension`| @@ -6528,25 +7005,25 @@ This diagnostic is enabled by default. ----------------- **Diagnostic text:** -+---------------------------------------------------------------------------------+--------------------------+------------------------------+-----------------------------------------------------------+--------------------------+------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`C` |nbsp| :diagtext:`defined as` |nbsp| |+------------------------+|+----------------------------+| |nbsp| :diagtext:`here but previously declared as` |nbsp| |+------------------------+|+----------------------------+| -| ||:diagtext:`a struct` ||| || ||:diagtext:`a struct` ||| || -| |+------------------------+|+----------------------------+| |+------------------------+|+----------------------------+| -| ||:diagtext:`an interface`||| |nbsp| :diagtext:`template`|| ||:diagtext:`an interface`||| |nbsp| :diagtext:`template`|| -| |+------------------------+|+----------------------------+| |+------------------------+|+----------------------------+| -| ||:diagtext:`a class` || | ||:diagtext:`a class` || | -| |+------------------------+| | |+------------------------+| | -+---------------------------------------------------------------------------------+--------------------------+------------------------------+-----------------------------------------------------------+--------------------------+------------------------------+ ++---------------------------------------------------------------------------------+--------------------------+------------------------------+-----------------------------------------------------------+--------------------------+------------------------------+----------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :placeholder:`C` |nbsp| :diagtext:`defined as` |nbsp| |+------------------------+|+----------------------------+| |nbsp| :diagtext:`here but previously declared as` |nbsp| |+------------------------+|+----------------------------+|:diagtext:`; this is valid, but may result in linker errors under the Microsoft C++ ABI`| +| ||:diagtext:`a struct` ||| || ||:diagtext:`a struct` ||| || | +| |+------------------------+|+----------------------------+| |+------------------------+|+----------------------------+| | +| ||:diagtext:`an interface`||| |nbsp| :diagtext:`template`|| ||:diagtext:`an interface`||| |nbsp| :diagtext:`template`|| | +| |+------------------------+|+----------------------------+| |+------------------------+|+----------------------------+| | +| ||:diagtext:`a class` || | ||:diagtext:`a class` || | | +| |+------------------------+| | |+------------------------+| | | ++---------------------------------------------------------------------------------+--------------------------+------------------------------+-----------------------------------------------------------+--------------------------+------------------------------+----------------------------------------------------------------------------------------+ -+---------------------------+-----------------------+------------------------------+--------------------------------------------------------------------------------+-----------------------+------------------------------+ -|:warning:`warning:` |nbsp| |+---------------------+|+----------------------------+| |nbsp| :placeholder:`C` |nbsp| :diagtext:`was previously declared as a` |nbsp| |+---------------------+|+----------------------------+| -| ||:diagtext:`struct` ||| || ||:diagtext:`struct` ||| || -| |+---------------------+|+----------------------------+| |+---------------------+|+----------------------------+| -| ||:diagtext:`interface`||| |nbsp| :diagtext:`template`|| ||:diagtext:`interface`||| |nbsp| :diagtext:`template`|| -| |+---------------------+|+----------------------------+| |+---------------------+|+----------------------------+| -| ||:diagtext:`class` || | ||:diagtext:`class` || | -| |+---------------------+| | |+---------------------+| | -+---------------------------+-----------------------+------------------------------+--------------------------------------------------------------------------------+-----------------------+------------------------------+ ++---------------------------+-----------------------+------------------------------+--------------------------------------------------------------------------------+-----------------------+------------------------------+----------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| |+---------------------+|+----------------------------+| |nbsp| :placeholder:`C` |nbsp| :diagtext:`was previously declared as a` |nbsp| |+---------------------+|+----------------------------+|:diagtext:`; this is valid, but may result in linker errors under the Microsoft C++ ABI`| +| ||:diagtext:`struct` ||| || ||:diagtext:`struct` ||| || | +| |+---------------------+|+----------------------------+| |+---------------------+|+----------------------------+| | +| ||:diagtext:`interface`||| |nbsp| :diagtext:`template`|| ||:diagtext:`interface`||| |nbsp| :diagtext:`template`|| | +| |+---------------------+|+----------------------------+| |+---------------------+|+----------------------------+| | +| ||:diagtext:`class` || | ||:diagtext:`class` || | | +| |+---------------------+| | |+---------------------+| | | ++---------------------------+-----------------------+------------------------------+--------------------------------------------------------------------------------+-----------------------+------------------------------+----------------------------------------------------------------------------------------+ -Wmissing-braces @@ -6797,7 +7274,7 @@ Controls `-Wcast-of-sel-type`_, `-Wchar-subscripts`_, `-Wcomment`_, `-Wdelete-no -Wmove ------ -Controls `-Wpessimizing-move`_, `-Wredundant-move`_, `-Wself-move`_. +Controls `-Wpessimizing-move`_, `-Wredundant-move`_, `-Wreturn-std-move`_, `-Wself-move`_. -Wmsvc-include @@ -6888,6 +7365,25 @@ This diagnostic is enabled by default. +----------------------------------------------------------------+ +-Wnoderef +--------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++----------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`dereferencing` |nbsp| :placeholder:`A`:diagtext:`; was declared with a 'noderef' type`| ++----------------------------------------------------------------------------------------------------------------------------+ + ++-----------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`dereferencing expression marked as 'noderef'`| ++-----------------------------------------------------------------------------------+ + ++-----------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`casting to dereferenceable pointer removes 'noderef' attribute`| ++-----------------------------------------------------------------------------------------------------+ + + -Wnoexcept-type --------------- Synonym for `-Wc++17-compat-mangling`_. @@ -7033,6 +7529,25 @@ This diagnostic is enabled by default. +---------------------------------------------------------------------------------------------------------------------+ +-Wnontrivial-memaccess +---------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++---------------------------+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------+ +|:warning:`warning:` |nbsp| |+-----------------------------+| |nbsp| :diagtext:`this` |nbsp| :placeholder:`B` |nbsp| :diagtext:`call is a pointer to record` |nbsp| :placeholder:`C` |nbsp| :diagtext:`that is not trivial to` |nbsp| |+----------------------------------------+| +| ||:diagtext:`destination for` || ||:diagtext:`primitive-default-initialize`|| +| |+-----------------------------+| |+----------------------------------------+| +| ||:diagtext:`source of` || ||:diagtext:`primitive-copy` || +| |+-----------------------------+| |+----------------------------------------+| +| ||:diagtext:`first operand of` || | | +| |+-----------------------------+| | | +| ||:diagtext:`second operand of`|| | | +| |+-----------------------------+| | | ++---------------------------+-------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------+ + + -Wnsconsumed-mismatch --------------------- This diagnostic is enabled by default. @@ -7280,9 +7795,9 @@ This diagnostic is enabled by default. **Diagnostic text:** -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`adding '`:placeholder:`A`:diagtext:`' to '`:placeholder:`B`:diagtext:`' might cause circular dependency in container`| -+-----------------------------------------------------------------------------------------------------------------------------------------------------------+ ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`adding` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B` |nbsp| :diagtext:`might cause circular dependency in container`| ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -Wobjc-cocoa-api @@ -7504,6 +8019,15 @@ This diagnostic is enabled by default. +-----------------------------------------------------------------------------------------------------------------------------+ +-Wobjc-property-assign-on-object-type +------------------------------------- +**Diagnostic text:** + ++--------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'assign' property of object type may become a dangling reference; consider using 'unsafe\_unretained'`| ++--------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wobjc-property-implementation ------------------------------ This diagnostic is enabled by default. @@ -7772,6 +8296,14 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`The OpenMP offloading target '`:placeholder:`A`:diagtext:`' is similar to target '`:placeholder:`B`:diagtext:`' already specified - will be ignored.`| +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`No library '`:placeholder:`A`:diagtext:`' found in the default clang lib directory or in LIBRARY\_PATH. Expect degraded performance due to no inlining of runtime functions on target devices.`| ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`Non-trivial type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is mapped, only trivial types are guaranteed to be mapped correctly`| ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +-----------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`declaration is not declared in any declare target region`| +-----------------------------------------------------------------------------------------------+ @@ -7787,14 +8319,14 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`option '-ffine-grained-bitfield-accesses' cannot be enabled together with a sanitizer; flag ignored`| +------------------------------------------------------------------------------------------------------------------------------------------+ ++-------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`The '`:placeholder:`A`:diagtext:`' architecture does not support -moutline; flag ignored`| ++-------------------------------------------------------------------------------------------------------------------------------+ + +----------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`option '`:placeholder:`A`:diagtext:`' was ignored by the PS4 toolchain, using '-fPIC'`| +----------------------------------------------------------------------------------------------------------------------------+ -+-------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ignoring '-mabicalls' option as it cannot be used with non position-independent code and the N64 ABI`| -+-------------------------------------------------------------------------------------------------------------------------------------------+ - +-------------------------------------------------------------------------------------------------------------------+-------------------------------------------+----------------------+ |:warning:`warning:` |nbsp| :diagtext:`ignoring '-mlong-calls' option as it is not currently supported with` |nbsp| |+-----------------------------------------+|:diagtext:`-mabicalls`| | || || | @@ -7803,6 +8335,29 @@ This diagnostic is enabled by default. | |+-----------------------------------------+| | +-------------------------------------------------------------------------------------------------------------------+-------------------------------------------+----------------------+ ++-----------------------------------------------------------------------------------------------------------------------+-------------------------------+----------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ignoring '`:placeholder:`A`:diagtext:`' option as it cannot be used with` |nbsp| |+-----------------------------+| |nbsp| :diagtext:`-mabicalls and the N64 ABI`| +| ||:diagtext:`implicit usage of`|| | +| |+-----------------------------+| | +| || || | +| |+-----------------------------+| | ++-----------------------------------------------------------------------------------------------------------------------+-------------------------------+----------------------------------------------+ + ++----------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`auto-vectorization requires HVX, use -mhvx to enable it`| ++----------------------------------------------------------------------------------------------+ + + +-Wordered-compare-function-pointers +----------------------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ordered comparison of function pointers (`:placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B`:diagtext:`)`| ++------------------------------------------------------------------------------------------------------------------------------------------------------------+ + -Wout-of-line-declaration ------------------------- @@ -7885,6 +8440,7 @@ This diagnostic is enabled by default. | |+---------------------+| +-----------------------------------------------------------------------------------------------+-----------------------+ + -Woverride-init --------------- Synonym for `-Winitializer-overrides`_. @@ -8079,10 +8635,14 @@ This diagnostic is enabled by default. -Wpedantic ---------- -Also controls `-Wc++11-extra-semi`_, `-Wc++11-long-long`_, `-Wc++14-binary-literal`_, `-Wc11-extensions`_, `-Wcomplex-component-init`_, `-Wdeclaration-after-statement`_, `-Wdollar-in-identifier-extension`_, `-Wembedded-directive`_, `-Wempty-translation-unit`_, `-Wextended-offsetof`_, `-Wflexible-array-extensions`_, `-Wformat-pedantic`_, `-Wfour-char-constants`_, `-Wgnu-anonymous-struct`_, `-Wgnu-auto-type`_, `-Wgnu-binary-literal`_, `-Wgnu-case-range`_, `-Wgnu-complex-integer`_, `-Wgnu-compound-literal-initializer`_, `-Wgnu-conditional-omitted-operand`_, `-Wgnu-empty-initializer`_, `-Wgnu-empty-struct`_, `-Wgnu-flexible-array-initializer`_, `-Wgnu-flexible-array-union-member`_, `-Wgnu-folding-constant`_, `-Wgnu-imaginary-constant`_, `-Wgnu-include-next`_, `-Wgnu-label-as-value`_, `-Wgnu-redeclared-enum`_, `-Wgnu-statement-expression`_, `-Wgnu-union-cast`_, `-Wgnu-zero-line-directive`_, `-Wgnu-zero-variadic-macro-arguments`_, `-Wimport-preprocessor-directive-pedantic`_, `-Wkeyword-macro`_, `-Wlanguage-extension-token`_, `-Wlong-long`_, `-Wmicrosoft-charize`_, `-Wmicrosoft-comment-paste`_, `-Wmicrosoft-cpp-macro`_, `-Wmicrosoft-end-of-file`_, `-Wmicrosoft-enum-value`_, `-Wmicrosoft-fixed-enum`_, `-Wmicrosoft-flexible-array`_, `-Wmicrosoft-redeclare-static`_, `-Wnested-anon-types`_, `-Wnullability-extension`_, `-Woverlength-strings`_, `-Wretained-language-linkage`_, `-Wundefined-internal-type`_, `-Wvla-extension`_, `-Wzero-length-array`_. +Also controls `-Wc++11-extra-semi`_, `-Wc++11-long-long`_, `-Wc++14-binary-literal`_, `-Wc11-extensions`_, `-Wcomplex-component-init`_, `-Wdeclaration-after-statement`_, `-Wdollar-in-identifier-extension`_, `-Wembedded-directive`_, `-Wempty-translation-unit`_, `-Wfixed-enum-extension`_, `-Wflexible-array-extensions`_, `-Wfour-char-constants`_, `-Wgnu-anonymous-struct`_, `-Wgnu-auto-type`_, `-Wgnu-binary-literal`_, `-Wgnu-case-range`_, `-Wgnu-complex-integer`_, `-Wgnu-compound-literal-initializer`_, `-Wgnu-conditional-omitted-operand`_, `-Wgnu-empty-initializer`_, `-Wgnu-empty-struct`_, `-Wgnu-flexible-array-initializer`_, `-Wgnu-flexible-array-union-member`_, `-Wgnu-folding-constant`_, `-Wgnu-imaginary-constant`_, `-Wgnu-include-next`_, `-Wgnu-label-as-value`_, `-Wgnu-redeclared-enum`_, `-Wgnu-statement-expression`_, `-Wgnu-union-cast`_, `-Wgnu-zero-line-directive`_, `-Wgnu-zero-variadic-macro-arguments`_, `-Wimport-preprocessor-directive-pedantic`_, `-Wkeyword-macro`_, `-Wlanguage-extension-token`_, `-Wlong-long`_, `-Wmicrosoft-charize`_, `-Wmicrosoft-comment-paste`_, `-Wmicrosoft-cpp-macro`_, `-Wmicrosoft-end-of-file`_, `-Wmicrosoft-enum-value`_, `-Wmicrosoft-fixed-enum`_, `-Wmicrosoft-flexible-array`_, `-Wmicrosoft-redeclare-static`_, `-Wnested-anon-types`_, `-Wnullability-extension`_, `-Woverlength-strings`_, `-Wretained-language-linkage`_, `-Wundefined-internal-type`_, `-Wvla-extension`_, `-Wzero-length-array`_. **Diagnostic text:** ++-----------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`duplicate '`:placeholder:`A`:diagtext:`' declaration specifier`| ++-----------------------------------------------------------------------------------------------------+ + +------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`'enable\_if' is a clang extension`| +------------------------------------------------------------------------+ @@ -8115,31 +8675,37 @@ Also controls `-Wc++11-extra-semi`_, `-Wc++11-long-long`_, `-Wc++14-binary-liter | |+------------------+| | +--------------------------------------------------------+--------------------+------------------------------------------------------------+ -+--------------------------------------------------------------------+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`no viable constructor` |nbsp| |+---------------------------------------+| |nbsp| :diagtext:`of type` |nbsp| :placeholder:`B`:diagtext:`; C++98 requires a copy constructor when binding a reference to a temporary`| -| ||:diagtext:`copying variable` || | -| |+---------------------------------------+| | -| ||:diagtext:`copying parameter` || | -| |+---------------------------------------+| | -| ||:diagtext:`returning object` || | -| |+---------------------------------------+| | -| ||:diagtext:`throwing object` || | -| |+---------------------------------------+| | -| ||:diagtext:`copying member subobject` || | -| |+---------------------------------------+| | -| ||:diagtext:`copying array element` || | -| |+---------------------------------------+| | -| ||:diagtext:`allocating object` || | -| |+---------------------------------------+| | -| ||:diagtext:`copying temporary` || | -| |+---------------------------------------+| | -| ||:diagtext:`initializing base subobject`|| | -| |+---------------------------------------+| | -| ||:diagtext:`initializing vector element`|| | -| |+---------------------------------------+| | -| ||:diagtext:`capturing value` || | -| |+---------------------------------------+| | -+--------------------------------------------------------------------+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ ++--------------------------------------------------------------------+------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`no viable constructor` |nbsp| |+----------------------------------------------------+| |nbsp| :diagtext:`of type` |nbsp| :placeholder:`B`:diagtext:`; C++98 requires a copy constructor when binding a reference to a temporary`| +| ||:diagtext:`copying variable` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`copying parameter` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`returning object` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`initializing statement expression result`|| | +| |+----------------------------------------------------+| | +| ||:diagtext:`throwing object` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`copying member subobject` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`copying array element` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`allocating object` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`copying temporary` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`initializing base subobject` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`initializing vector element` || | +| |+----------------------------------------------------+| | +| ||:diagtext:`capturing value` || | +| |+----------------------------------------------------+| | ++--------------------------------------------------------------------+------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ + ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ISO C++ standards before C++17 do not allow new expression for type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to use list-initialization`| ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +--------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`parameter` |nbsp| :placeholder:`A` |nbsp| :diagtext:`was not declared, defaulting to type 'int'`| @@ -8185,25 +8751,33 @@ Also controls `-Wc++11-extra-semi`_, `-Wc++11-long-long`_, `-Wc++14-binary-liter |:warning:`warning:` |nbsp| :diagtext:`flexible array members are a C99 feature`| +-------------------------------------------------------------------------------+ -+---------------------------------------------------------------+-----------------------+--------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invalid application of '`|+---------------------+|:diagtext:`' to a function type`| -| ||:diagtext:`sizeof` || | -| |+---------------------+| | -| ||:diagtext:`alignof` || | -| |+---------------------+| | -| ||:diagtext:`vec\_step`|| | -| |+---------------------+| | -+---------------------------------------------------------------+-----------------------+--------------------------------+ - -+---------------------------------------------------------------+-----------------------+----------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invalid application of '`|+---------------------+|:diagtext:`' to a void type`| -| ||:diagtext:`sizeof` || | -| |+---------------------+| | -| ||:diagtext:`alignof` || | -| |+---------------------+| | -| ||:diagtext:`vec\_step`|| | -| |+---------------------+| | -+---------------------------------------------------------------+-----------------------+----------------------------+ ++---------------------------------------------------------------+-----------------------------------------------------+--------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`invalid application of '`|+---------------------------------------------------+|:diagtext:`' to a function type`| +| ||:diagtext:`sizeof` || | +| |+---------------------------------------------------+| | +| ||:diagtext:`alignof` || | +| |+---------------------------------------------------+| | +| ||:diagtext:`vec\_step` || | +| |+---------------------------------------------------+| | +| ||:diagtext:`\_\_builtin\_omp\_required\_simd\_align`|| | +| |+---------------------------------------------------+| | +| ||:diagtext:`\_\_alignof` || | +| |+---------------------------------------------------+| | ++---------------------------------------------------------------+-----------------------------------------------------+--------------------------------+ + ++---------------------------------------------------------------+-----------------------------------------------------+----------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`invalid application of '`|+---------------------------------------------------+|:diagtext:`' to a void type`| +| ||:diagtext:`sizeof` || | +| |+---------------------------------------------------+| | +| ||:diagtext:`alignof` || | +| |+---------------------------------------------------+| | +| ||:diagtext:`vec\_step` || | +| |+---------------------------------------------------+| | +| ||:diagtext:`\_\_builtin\_omp\_required\_simd\_align`|| | +| |+---------------------------------------------------+| | +| ||:diagtext:`\_\_alignof` || | +| |+---------------------------------------------------+| | ++---------------------------------------------------------------+-----------------------------------------------------+----------------------------+ +-------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`ISO C90 does not allow subscripting non-lvalue array`| @@ -8313,6 +8887,14 @@ Also controls `-Wc++11-extra-semi`_, `-Wc++11-long-long`_, `-Wc++14-binary-liter | |+------------------+| | +-----------------------------------------------------------------------------+--------------------+---------------------------------------------+ ++------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`format specifies type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`but the argument has` |nbsp| |+---------------------------+| |nbsp| :placeholder:`B`| +| ||:diagtext:`type` || | +| |+---------------------------+| | +| ||:diagtext:`underlying type`|| | +| |+---------------------------+| | ++------------------------------------------------------------------------------------------------------------------------------------+-----------------------------+------------------------+ + +---------------------------------------------------+----------------------+-----------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`void` |nbsp| |+--------------------+| |nbsp| :placeholder:`A` |nbsp| :diagtext:`should not return void expression`| | ||:diagtext:`function`|| | @@ -8510,25 +9092,33 @@ Some of the diagnostics controlled by this flag are enabled by default. | |+---------------------+| |+-------------+| | +----------------------------------------------------+-----------------------+---------------------------+---------------+----------------------------------------------+ -+---------------------------------------------------------------+-----------------------+--------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invalid application of '`|+---------------------+|:diagtext:`' to a function type`| -| ||:diagtext:`sizeof` || | -| |+---------------------+| | -| ||:diagtext:`alignof` || | -| |+---------------------+| | -| ||:diagtext:`vec\_step`|| | -| |+---------------------+| | -+---------------------------------------------------------------+-----------------------+--------------------------------+ - -+---------------------------------------------------------------+-----------------------+----------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`invalid application of '`|+---------------------+|:diagtext:`' to a void type`| -| ||:diagtext:`sizeof` || | -| |+---------------------+| | -| ||:diagtext:`alignof` || | -| |+---------------------+| | -| ||:diagtext:`vec\_step`|| | -| |+---------------------+| | -+---------------------------------------------------------------+-----------------------+----------------------------+ ++---------------------------------------------------------------+-----------------------------------------------------+--------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`invalid application of '`|+---------------------------------------------------+|:diagtext:`' to a function type`| +| ||:diagtext:`sizeof` || | +| |+---------------------------------------------------+| | +| ||:diagtext:`alignof` || | +| |+---------------------------------------------------+| | +| ||:diagtext:`vec\_step` || | +| |+---------------------------------------------------+| | +| ||:diagtext:`\_\_builtin\_omp\_required\_simd\_align`|| | +| |+---------------------------------------------------+| | +| ||:diagtext:`\_\_alignof` || | +| |+---------------------------------------------------+| | ++---------------------------------------------------------------+-----------------------------------------------------+--------------------------------+ + ++---------------------------------------------------------------+-----------------------------------------------------+----------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`invalid application of '`|+---------------------------------------------------+|:diagtext:`' to a void type`| +| ||:diagtext:`sizeof` || | +| |+---------------------------------------------------+| | +| ||:diagtext:`alignof` || | +| |+---------------------------------------------------+| | +| ||:diagtext:`vec\_step` || | +| |+---------------------------------------------------+| | +| ||:diagtext:`\_\_builtin\_omp\_required\_simd\_align`|| | +| |+---------------------------------------------------+| | +| ||:diagtext:`\_\_alignof` || | +| |+---------------------------------------------------+| | ++---------------------------------------------------------------+-----------------------------------------------------+----------------------------+ +-----------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`subtraction of pointers to type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`of zero size has undefined behavior`| @@ -8560,6 +9150,17 @@ This diagnostic is enabled by default. +-------------------------------------------------+------------------------------+---------------------------------------------------------------------------------+ +-Wpointer-integer-compare +------------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-----------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`comparison between pointer and integer (`:placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B`:diagtext:`)`| ++-----------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wpointer-sign -------------- This diagnostic is enabled by default. @@ -8726,26 +9327,34 @@ This diagnostic is enabled by default. **Diagnostic text:** -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`top-level module '`:placeholder:`A`:diagtext:`' in private module map, expected a submodule of '`:placeholder:`B`:diagtext:`'`| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++----------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`expected canonical name for private module '`:placeholder:`A`:diagtext:`'`| ++----------------------------------------------------------------------------------------------------------------+ + ++----------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`private submodule '`:placeholder:`A`:diagtext:`' in private module map, expected top-level module`| ++----------------------------------------------------------------------------------------------------------------------------------------+ +----------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`module '`:placeholder:`A`:diagtext:`' already re-exported as '`:placeholder:`B`:diagtext:`'`| +----------------------------------------------------------------------------------------------------------------------------------+ ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`no submodule named` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in module '`:placeholder:`B`:diagtext:`'; using top level '`:placeholder:`C`:diagtext:`'`| ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + -Wprofile-instr-missing ----------------------- **Diagnostic text:** -+-----------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+-------------------+---------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`profile data may be incomplete: of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`function`|+-------------+|:diagtext:`,` |nbsp| :placeholder:`B` |nbsp| |+-----------------+| |nbsp| :diagtext:`no data`| -| || || ||:diagtext:`:has` || | -| |+-------------+| |+-----------------+| | -| ||:diagtext:`s`|| ||:diagtext:`:have`|| | -| |+-------------+| |+-----------------+| | -+-----------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+-------------------+---------------------------+ ++-----------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+------------------+---------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`profile data may be incomplete: of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`function`|+-------------+|:diagtext:`,` |nbsp| :placeholder:`B` |nbsp| |+----------------+| |nbsp| :diagtext:`no data`| +| || || ||:diagtext:`has` || | +| |+-------------+| |+----------------+| | +| ||:diagtext:`s`|| ||:diagtext:`have`|| | +| |+-------------+| |+----------------+| | ++-----------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+------------------+---------------------------+ -Wprofile-instr-out-of-date @@ -8754,13 +9363,13 @@ This diagnostic is enabled by default. **Diagnostic text:** -+------------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+-------------------+--------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`profile data may be out of date: of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`function`|+-------------+|:diagtext:`,` |nbsp| :placeholder:`B` |nbsp| |+-----------------+| |nbsp| :diagtext:`mismatched data that will be ignored`| -| || || ||:diagtext:`:has` || | -| |+-------------+| |+-----------------+| | -| ||:diagtext:`s`|| ||:diagtext:`:have`|| | -| |+-------------+| |+-----------------+| | -+------------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+-------------------+--------------------------------------------------------+ ++------------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+------------------+--------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`profile data may be out of date: of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`function`|+-------------+|:diagtext:`,` |nbsp| :placeholder:`B` |nbsp| |+----------------+| |nbsp| :diagtext:`mismatched data that will be ignored`| +| || || ||:diagtext:`has` || | +| |+-------------+| |+----------------+| | +| ||:diagtext:`s`|| ||:diagtext:`have`|| | +| |+-------------+| |+----------------+| | ++------------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+------------------+--------------------------------------------------------+ -Wprofile-instr-unprofiled @@ -8861,6 +9470,15 @@ This diagnostic is enabled by default. +---------------------------------------------------------------------------------------------------------+ +-Wquoted-include-in-framework-header +------------------------------------ +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`double-quoted include "`:placeholder:`A`:diagtext:`" in framework header, expected angle-bracketed instead`| ++-------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wrange-loop-analysis --------------------- **Diagnostic text:** @@ -9064,13 +9682,35 @@ This diagnostic is enabled by default. | |+------------------------+| | +--------------------------------------------------------+--------------------------+------------------------------------------+ -+---------------------------+--------------------------+-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------+| |nbsp| :diagtext:`stack memory associated with local variable` |nbsp| :placeholder:`B` |nbsp| :diagtext:`returned`| -| ||:diagtext:`address of` || | -| |+------------------------+| | -| ||:diagtext:`reference to`|| | -| |+------------------------+| | -+---------------------------+--------------------------+-------------------------------------------------------------------------------------------------------------------+ ++---------------------------+--------------------------+--------------------------------------------------------+----------------------------+----------------------------------------------------+ +|:warning:`warning:` |nbsp| |+------------------------+| |nbsp| :diagtext:`stack memory associated with` |nbsp| |+--------------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`returned`| +| ||:diagtext:`address of` || ||:diagtext:`local variable`|| | +| |+------------------------+| |+--------------------------+| | +| ||:diagtext:`reference to`|| ||:diagtext:`parameter` || | +| |+------------------------+| |+--------------------------+| | ++---------------------------+--------------------------+--------------------------------------------------------+----------------------------+----------------------------------------------------+ + + +-Wreturn-std-move +----------------- +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------------+----------------------+---------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`local variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`will be copied despite being` |nbsp| |+--------------------+| |nbsp| :diagtext:`by name`| +| ||:diagtext:`returned`|| | +| |+--------------------+| | +| ||:diagtext:`thrown` || | +| |+--------------------+| | ++-------------------------------------------------------------------------------------------------------------------------------------+----------------------+---------------------------+ + + +-Wreturn-std-move-in-c++11 +-------------------------- +**Diagnostic text:** + ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`prior to the resolution of a defect report against ISO C++11, local variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`would have been copied despite being returned by name, due to its not matching the function return type`| ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -Wreturn-type @@ -9149,17 +9789,6 @@ This diagnostic is enabled by default. +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ --Wrtti-for-exceptions ---------------------- -This diagnostic is enabled by default. - -**Diagnostic text:** - -+--------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicitly enabling rtti for exception handling`| -+--------------------------------------------------------------------------------------+ - - -Rsanitize-address ------------------ **Diagnostic text:** @@ -9199,9 +9828,17 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`section attribute is specified on redeclared variable`| +--------------------------------------------------------------------------------------------+ -+----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`section does not match previous declaration`| -+----------------------------------------------------------------------------------+ ++------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`duplicate code segment specifiers`| ++------------------------------------------------------------------------+ + ++---------------------------+---------------------+-------------------------------------------------------+ +|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`does not match previous declaration`| +| ||:diagtext:`codeseg`|| | +| |+-------------------+| | +| ||:diagtext:`section`|| | +| |+-------------------+| | ++---------------------------+---------------------+-------------------------------------------------------+ -Wselector @@ -9228,7 +9865,7 @@ Also controls `-Wselector-type-mismatch`_. ------------- Some of the diagnostics controlled by this flag are enabled by default. -Also controls `-Wself-assign-field`_. +Also controls `-Wself-assign-field`_, `-Wself-assign-overloaded`_. **Diagnostic text:** @@ -9252,6 +9889,15 @@ This diagnostic is enabled by default. +--------------------------------------------------------+-------------------------------+-----------------------------+ +-Wself-assign-overloaded +------------------------ +**Diagnostic text:** + ++------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`explicitly assigning value of variable of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to itself`| ++------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wself-move ----------- **Diagnostic text:** @@ -9357,9 +10003,15 @@ Controls `-Wshadow`_, `-Wshadow-field`_, `-Wshadow-field-in-constructor`_, `-Wsh -------------- **Diagnostic text:** -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-static data member '`:placeholder:`A`:diagtext:`' of '`:placeholder:`B`:diagtext:`' shadows member inherited from type '`:placeholder:`C`:diagtext:`'`| -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++---------------------------+------------------------------------+--------------------------------+--------------------------------------------------+----------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| |+----------------------------------+| |nbsp| :placeholder:`A` |nbsp| |+------------------------------------------------+|:diagtext:`shadows member inherited from type` |nbsp| :placeholder:`C`| +| ||:diagtext:`parameter` || || || | +| |+----------------------------------+| |+------------------------------------------------+| | +| ||:diagtext:`non-static data member`|| ||+----------------------------------------------+|| | +| |+----------------------------------+| |||:diagtext:`of` |nbsp| :placeholder:`B` |nbsp| ||| | +| | | ||+----------------------------------------------+|| | +| | | |+------------------------------------------------+| | ++---------------------------+------------------------------------+--------------------------------+--------------------------------------------------+----------------------------------------------------------------------+ -Wshadow-field-in-constructor @@ -9518,6 +10170,10 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`operand of ? changes signedness:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`| +---------------------------------------------------------------------------------------------------------------------------------------------+ ++-----------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`the resulting value is always non-negative after implicit conversion`| ++-----------------------------------------------------------------------------------------------------------+ + -Wsign-promo ------------ @@ -9554,6 +10210,17 @@ This diagnostic is enabled by default. +--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-Wsizeof-pointer-div +-------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' will return the size of the pointer, not the array itself`| ++-------------------------------------------------------------------------------------------------------------------------------+ + + -Wsizeof-pointer-memaccess -------------------------- This diagnostic is enabled by default. @@ -9728,6 +10395,17 @@ This diagnostic is enabled by default. +----------------------------------------------------------------------------------------------------------------------------------------------------+ +-Wstdlibcxx-not-found +--------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`include path for stdlibc++ headers not found; pass '-stdlib=libc++' on the command line to use the libc++ standard library instead`| ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wstrict-aliasing ----------------- This diagnostic flag exists for GCC compatibility, and has no effect in Clang. @@ -9896,6 +10574,24 @@ This diagnostic is enabled by default. +--------------------------------------------------------------------------------------------------------------------------------+ +-Wsuspicious-bzero +------------------ +This diagnostic is enabled by default. + +**Diagnostic text:** + ++----------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'size' argument to bzero is '0'`| ++----------------------------------------------------------------------+ + + +-Wsuspicious-memaccess +---------------------- +This diagnostic is enabled by default. + +Controls `-Wdynamic-class-memaccess`_, `-Wmemset-transposed-args`_, `-Wnontrivial-memaccess`_, `-Wsizeof-pointer-memaccess`_, `-Wsuspicious-bzero`_. + + -Wswitch -------- This diagnostic is enabled by default. @@ -9906,25 +10602,25 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`overflow converting case value to switch condition type (`:placeholder:`A` |nbsp| :diagtext:`to` |nbsp| :placeholder:`B`:diagtext:`)`| +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -+---------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -| ||+-----------------------------------------------------------------------------------------------+ || -| |||:diagtext:`:enumeration value` |nbsp| :placeholder:`B` |nbsp| :diagtext:`not handled in switch`| || -| ||+-----------------------------------------------------------------------------------------------+ || -| |+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -| ||+-----------------------------------------------------------------------------------------------------------------------------------------------+ || -| |||:diagtext:`:enumeration values` |nbsp| :placeholder:`B` |nbsp| :diagtext:`and` |nbsp| :placeholder:`C` |nbsp| :diagtext:`not handled in switch`| || -| ||+-----------------------------------------------------------------------------------------------------------------------------------------------+ || -| |+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -| ||+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || -| |||:diagtext:`:enumeration values` |nbsp| :placeholder:`B`:diagtext:`,` |nbsp| :placeholder:`C`:diagtext:`, and` |nbsp| :placeholder:`D` |nbsp| :diagtext:`not handled in switch`| || -| ||+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || -| |+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -| ||+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+|| -| |||:diagtext:`:`:placeholder:`A` |nbsp| :diagtext:`enumeration values not handled in switch:` |nbsp| :placeholder:`B`:diagtext:`,` |nbsp| :placeholder:`C`:diagtext:`,` |nbsp| :placeholder:`D`:diagtext:`...`||| -| ||+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+|| -| |+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -+---------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++---------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| |+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| +| ||+----------------------------------------------------------------------------------------------+ || +| |||:diagtext:`enumeration value` |nbsp| :placeholder:`B` |nbsp| :diagtext:`not handled in switch`| || +| ||+----------------------------------------------------------------------------------------------+ || +| |+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| +| ||+----------------------------------------------------------------------------------------------------------------------------------------------+ || +| |||:diagtext:`enumeration values` |nbsp| :placeholder:`B` |nbsp| :diagtext:`and` |nbsp| :placeholder:`C` |nbsp| :diagtext:`not handled in switch`| || +| ||+----------------------------------------------------------------------------------------------------------------------------------------------+ || +| |+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| +| ||+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || +| |||:diagtext:`enumeration values` |nbsp| :placeholder:`B`:diagtext:`,` |nbsp| :placeholder:`C`:diagtext:`, and` |nbsp| :placeholder:`D` |nbsp| :diagtext:`not handled in switch`| || +| ||+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || +| |+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| +| ||+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+|| +| |||:placeholder:`A` |nbsp| :diagtext:`enumeration values not handled in switch:` |nbsp| :placeholder:`B`:diagtext:`,` |nbsp| :placeholder:`C`:diagtext:`,` |nbsp| :placeholder:`D`:diagtext:`...`||| +| ||+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+|| +| |+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| ++---------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`case value not in enumerated type` |nbsp| :placeholder:`A`| @@ -9950,25 +10646,25 @@ This diagnostic flag exists for GCC compatibility, and has no effect in Clang. ------------- **Diagnostic text:** -+---------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -| ||+----------------------------------------------------------------------------------------------------------+ || -| |||:diagtext:`:enumeration value` |nbsp| :placeholder:`B` |nbsp| :diagtext:`not explicitly handled in switch`| || -| ||+----------------------------------------------------------------------------------------------------------+ || -| |+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -| ||+----------------------------------------------------------------------------------------------------------------------------------------------------------+ || -| |||:diagtext:`:enumeration values` |nbsp| :placeholder:`B` |nbsp| :diagtext:`and` |nbsp| :placeholder:`C` |nbsp| :diagtext:`not explicitly handled in switch`| || -| ||+----------------------------------------------------------------------------------------------------------------------------------------------------------+ || -| |+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -| ||+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || -| |||:diagtext:`:enumeration values` |nbsp| :placeholder:`B`:diagtext:`,` |nbsp| :placeholder:`C`:diagtext:`, and` |nbsp| :placeholder:`D` |nbsp| :diagtext:`not explicitly handled in switch`| || -| ||+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || -| |+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -| ||+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+|| -| |||:diagtext:`:`:placeholder:`A` |nbsp| :diagtext:`enumeration values not explicitly handled in switch:` |nbsp| :placeholder:`B`:diagtext:`,` |nbsp| :placeholder:`C`:diagtext:`,` |nbsp| :placeholder:`D`:diagtext:`...`||| -| ||+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+|| -| |+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| -+---------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++---------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| |+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| +| ||+---------------------------------------------------------------------------------------------------------+ || +| |||:diagtext:`enumeration value` |nbsp| :placeholder:`B` |nbsp| :diagtext:`not explicitly handled in switch`| || +| ||+---------------------------------------------------------------------------------------------------------+ || +| |+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| +| ||+---------------------------------------------------------------------------------------------------------------------------------------------------------+ || +| |||:diagtext:`enumeration values` |nbsp| :placeholder:`B` |nbsp| :diagtext:`and` |nbsp| :placeholder:`C` |nbsp| :diagtext:`not explicitly handled in switch`| || +| ||+---------------------------------------------------------------------------------------------------------------------------------------------------------+ || +| |+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| +| ||+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || +| |||:diagtext:`enumeration values` |nbsp| :placeholder:`B`:diagtext:`,` |nbsp| :placeholder:`C`:diagtext:`, and` |nbsp| :placeholder:`D` |nbsp| :diagtext:`not explicitly handled in switch`| || +| ||+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ || +| |+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| +| ||+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+|| +| |||:placeholder:`A` |nbsp| :diagtext:`enumeration values not explicitly handled in switch:` |nbsp| :placeholder:`B`:diagtext:`,` |nbsp| :placeholder:`C`:diagtext:`,` |nbsp| :placeholder:`D`:diagtext:`...`||| +| ||+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+|| +| |+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| ++---------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -Wsync-fetch-and-nand-semantics-changed @@ -9996,12 +10692,10 @@ Also controls `-Wtautological-constant-compare`_, `-Wtautological-overlap-compar +---------------------------+---------------------------+--------------------------------------------------+------------------------+ |:warning:`warning:` |nbsp| |+-------------------------+|:diagtext:`comparison always evaluates to` |nbsp| |+----------------------+| -| ||:diagtext:`self-` || ||:diagtext:`false` || +| ||:diagtext:`self-` || ||:diagtext:`a constant`|| | |+-------------------------+| |+----------------------+| -| ||:diagtext:`array` |nbsp| || ||:diagtext:`true` || +| ||:diagtext:`array` |nbsp| || ||:placeholder:`C` || | |+-------------------------+| |+----------------------+| -| | | ||:diagtext:`a constant`|| -| | | |+----------------------+| +---------------------------+---------------------------+--------------------------------------------------+------------------------+ +-------------------------------------------------------------------------------------+-------------------+ @@ -10017,17 +10711,26 @@ Also controls `-Wtautological-constant-compare`_, `-Wtautological-overlap-compar ------------------------------- This diagnostic is enabled by default. -Also controls `-Wtautological-constant-out-of-range-compare`_, `-Wtautological-unsigned-enum-zero-compare`_, `-Wtautological-unsigned-zero-compare`_. +Also controls `-Wtautological-constant-out-of-range-compare`_. **Diagnostic text:** -+---------------------------------------------------------+------------------+--------------------------------+------------------+-------------------------------------+-------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison` |nbsp| |+----------------+| |nbsp| :placeholder:`C` |nbsp| |+----------------+| |nbsp| :diagtext:`is always` |nbsp| |+-----------------+| -| ||:placeholder:`D`|| ||:placeholder:`B`|| ||:diagtext:`false`|| -| |+----------------+| |+----------------+| |+-----------------+| -| ||:placeholder:`B`|| ||:placeholder:`D`|| ||:diagtext:`true` || -| |+----------------+| |+----------------+| |+-----------------+| -+---------------------------------------------------------+------------------+--------------------------------+------------------+-------------------------------------+-------------------+ ++----------------------------------------------------------------------+------------------------------------------------+--------------------------------+----------------------------------------------------------+-----------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`result of comparison of` |nbsp| |+----------------------------------------------+| |nbsp| :diagtext:`with` |nbsp| |+--------------------------------------------------------+| |nbsp| :diagtext:`is always` |nbsp| :placeholder:`E`| +| ||+--------------------------------------------+|| ||+------------------------------------------------------+|| | +| |||:diagtext:`constant` |nbsp| :placeholder:`A`||| |||:diagtext:`expression of type` |nbsp| :placeholder:`C`||| | +| ||+--------------------------------------------+|| ||+------------------------------------------------------+|| | +| |+----------------------------------------------+| |+--------------------------------------------------------+| | +| ||:diagtext:`true` || ||:diagtext:`boolean expression` || | +| |+----------------------------------------------+| |+--------------------------------------------------------+| | +| ||:diagtext:`false` || | | | +| |+----------------------------------------------+| | | | ++----------------------------------------------------------------------+------------------------------------------------+--------------------------------+----------------------------------------------------------+-----------------------------------------------------+ + + +-Wtautological-constant-in-range-compare +---------------------------------------- +Controls `-Wtautological-type-limit-compare`_, `-Wtautological-unsigned-enum-zero-compare`_, `-Wtautological-unsigned-zero-compare`_. -Wtautological-constant-out-of-range-compare @@ -10036,17 +10739,17 @@ This diagnostic is enabled by default. **Diagnostic text:** -+------------------------------------------------------------+------------------------------------------------+--------------------------------+----------------------------------------------------------+-------------------------------------+-------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison of` |nbsp| |+----------------------------------------------+| |nbsp| :diagtext:`with` |nbsp| |+--------------------------------------------------------+| |nbsp| :diagtext:`is always` |nbsp| |+-----------------+| -| ||+--------------------------------------------+|| ||+------------------------------------------------------+|| ||:diagtext:`false`|| -| |||:diagtext:`constant` |nbsp| :placeholder:`A`||| |||:diagtext:`expression of type` |nbsp| :placeholder:`C`||| |+-----------------+| -| ||+--------------------------------------------+|| ||+------------------------------------------------------+|| ||:diagtext:`true` || -| |+----------------------------------------------+| |+--------------------------------------------------------+| |+-----------------+| -| ||:diagtext:`true` || ||:diagtext:`boolean expression` || | | -| |+----------------------------------------------+| |+--------------------------------------------------------+| | | -| ||:diagtext:`false` || | | | | -| |+----------------------------------------------+| | | | | -+------------------------------------------------------------+------------------------------------------------+--------------------------------+----------------------------------------------------------+-------------------------------------+-------------------+ ++----------------------------------------------------------------------+------------------------------------------------+--------------------------------+----------------------------------------------------------+-----------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`result of comparison of` |nbsp| |+----------------------------------------------+| |nbsp| :diagtext:`with` |nbsp| |+--------------------------------------------------------+| |nbsp| :diagtext:`is always` |nbsp| :placeholder:`E`| +| ||+--------------------------------------------+|| ||+------------------------------------------------------+|| | +| |||:diagtext:`constant` |nbsp| :placeholder:`A`||| |||:diagtext:`expression of type` |nbsp| :placeholder:`C`||| | +| ||+--------------------------------------------+|| ||+------------------------------------------------------+|| | +| |+----------------------------------------------+| |+--------------------------------------------------------+| | +| ||:diagtext:`true` || ||:diagtext:`boolean expression` || | +| |+----------------------------------------------+| |+--------------------------------------------------------+| | +| ||:diagtext:`false` || | | | +| |+----------------------------------------------+| | | | ++----------------------------------------------------------------------+------------------------------------------------+--------------------------------+----------------------------------------------------------+-----------------------------------------------------+ -Wtautological-overlap-compare @@ -10087,6 +10790,19 @@ This diagnostic is enabled by default. +------------------------------------------------------------+------------------------+----------------------------------------------------------+-------------------------+-----------------------------------------------------+-------------------+ +-Wtautological-type-limit-compare +--------------------------------- +**Diagnostic text:** + ++-------------------------------------------------------------------+------------------+--------------------------------+------------------+-----------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`result of comparison` |nbsp| |+----------------+| |nbsp| :placeholder:`C` |nbsp| |+----------------+| |nbsp| :diagtext:`is always` |nbsp| :placeholder:`E`| +| ||:placeholder:`D`|| ||:placeholder:`B`|| | +| |+----------------+| |+----------------+| | +| ||:placeholder:`B`|| ||:placeholder:`D`|| | +| |+----------------+| |+----------------+| | ++-------------------------------------------------------------------+------------------+--------------------------------+------------------+-----------------------------------------------------+ + + -Wtautological-undefined-compare -------------------------------- This diagnostic is enabled by default. @@ -10112,32 +10828,28 @@ This diagnostic is enabled by default. -Wtautological-unsigned-enum-zero-compare ----------------------------------------- -This diagnostic is enabled by default. - **Diagnostic text:** -+------------------------------------------------------------+--------------------------------------+--------------------------------+--------------------------------------+-------------------------------------+-------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison of` |nbsp| |+------------------------------------+| |nbsp| :placeholder:`C` |nbsp| |+------------------------------------+| |nbsp| :diagtext:`is always` |nbsp| |+-----------------+| -| ||:placeholder:`D` || ||:diagtext:`unsigned enum expression`|| ||:diagtext:`false`|| -| |+------------------------------------+| |+------------------------------------+| |+-----------------+| -| ||:diagtext:`unsigned enum expression`|| ||:placeholder:`D` || ||:diagtext:`true` || -| |+------------------------------------+| |+------------------------------------+| |+-----------------+| -+------------------------------------------------------------+--------------------------------------+--------------------------------+--------------------------------------+-------------------------------------+-------------------+ ++----------------------------------------------------------------------+--------------------------------------+--------------------------------+--------------------------------------+-----------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`result of comparison of` |nbsp| |+------------------------------------+| |nbsp| :placeholder:`C` |nbsp| |+------------------------------------+| |nbsp| :diagtext:`is always` |nbsp| :placeholder:`E`| +| ||:placeholder:`D` || ||:diagtext:`unsigned enum expression`|| | +| |+------------------------------------+| |+------------------------------------+| | +| ||:diagtext:`unsigned enum expression`|| ||:placeholder:`D` || | +| |+------------------------------------+| |+------------------------------------+| | ++----------------------------------------------------------------------+--------------------------------------+--------------------------------+--------------------------------------+-----------------------------------------------------+ -Wtautological-unsigned-zero-compare ------------------------------------ -This diagnostic is enabled by default. - **Diagnostic text:** -+------------------------------------------------------------+---------------------------------+--------------------------------+---------------------------------+-------------------------------------+-------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison of` |nbsp| |+-------------------------------+| |nbsp| :placeholder:`C` |nbsp| |+-------------------------------+| |nbsp| :diagtext:`is always` |nbsp| |+-----------------+| -| ||:placeholder:`D` || ||:diagtext:`unsigned expression`|| ||:diagtext:`false`|| -| |+-------------------------------+| |+-------------------------------+| |+-----------------+| -| ||:diagtext:`unsigned expression`|| ||:placeholder:`D` || ||:diagtext:`true` || -| |+-------------------------------+| |+-------------------------------+| |+-----------------+| -+------------------------------------------------------------+---------------------------------+--------------------------------+---------------------------------+-------------------------------------+-------------------+ ++----------------------------------------------------------------------+---------------------------------+--------------------------------+---------------------------------+-----------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`result of comparison of` |nbsp| |+-------------------------------+| |nbsp| :placeholder:`C` |nbsp| |+-------------------------------+| |nbsp| :diagtext:`is always` |nbsp| :placeholder:`E`| +| ||:placeholder:`D` || ||:diagtext:`unsigned expression`|| | +| |+-------------------------------+| |+-------------------------------+| | +| ||:diagtext:`unsigned expression`|| ||:placeholder:`D` || | +| |+-------------------------------+| |+-------------------------------+| | ++----------------------------------------------------------------------+---------------------------------+--------------------------------+---------------------------------+-----------------------------------------------------+ -Wtentative-definition-incomplete-type @@ -10188,17 +10900,17 @@ Controls `-Wthread-safety-analysis`_, `-Wthread-safety-attributes`_, `-Wthread-s |:warning:`warning:` |nbsp| :diagtext:`cannot call function '`:placeholder:`B`:diagtext:`' while` |nbsp| :placeholder:`A` |nbsp| :diagtext:`'`:placeholder:`C`:diagtext:`' is held`| +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -+---------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`calling function '`:placeholder:`B`:diagtext:`' requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| -| ||+------------------------------------------+ || -| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || -| ||+------------------------------------------+ || -| |+--------------------------------------------------------+| -| ||+------------------------------------------------------+|| -| |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| -| ||+------------------------------------------------------+|| -| |+--------------------------------------------------------+| -+---------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ ++---------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`calling function` |nbsp| :placeholder:`B` |nbsp| :diagtext:`requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| +| ||+------------------------------------------+ || +| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || +| ||+------------------------------------------+ || +| |+--------------------------------------------------------+| +| ||+------------------------------------------------------+|| +| |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| +| ||+------------------------------------------------------+|| +| |+--------------------------------------------------------+| ++---------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ +--------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`'`:placeholder:`B`:diagtext:`' is acquired exclusively and shared in the same scope`| @@ -10224,45 +10936,45 @@ Controls `-Wthread-safety-analysis`_, `-Wthread-safety-attributes`_, `-Wthread-s | |+---------------------+| |+---------------------+| | +----------------------------------------------------------------------------------------------------------------------------------------+-----------------------+--------------------------------------------+-----------------------+--------------------------+ -+---------------------------+---------------------+---------------------------------------------------------------------------------------------------+-----------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`the value pointed to by '`:placeholder:`A`:diagtext:`' requires holding` |nbsp| |+---------------------------------+| -| ||:diagtext:`reading`|| ||:diagtext:`any mutex` || -| |+-------------------+| |+---------------------------------+| -| ||:diagtext:`writing`|| ||:diagtext:`any mutex exclusively`|| -| |+-------------------+| |+---------------------------------+| -+---------------------------+---------------------+---------------------------------------------------------------------------------------------------+-----------------------------------+ - -+---------------------------+---------------------+---------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`the value pointed to by '`:placeholder:`B`:diagtext:`' requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| -| ||:diagtext:`reading`|| ||+------------------------------------------+ || -| |+-------------------+| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || -| ||:diagtext:`writing`|| ||+------------------------------------------+ || -| |+-------------------+| |+--------------------------------------------------------+| -| | | ||+------------------------------------------------------+|| -| | | |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| -| | | ||+------------------------------------------------------+|| -| | | |+--------------------------------------------------------+| -+---------------------------+---------------------+---------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ - -+---------------------------+---------------------+------------------------------------------------------------------------------------+-----------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`variable '`:placeholder:`A`:diagtext:`' requires holding` |nbsp| |+---------------------------------+| -| ||:diagtext:`reading`|| ||:diagtext:`any mutex` || -| |+-------------------+| |+---------------------------------+| -| ||:diagtext:`writing`|| ||:diagtext:`any mutex exclusively`|| -| |+-------------------+| |+---------------------------------+| -+---------------------------+---------------------+------------------------------------------------------------------------------------+-----------------------------------+ - -+---------------------------+---------------------+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`variable '`:placeholder:`B`:diagtext:`' requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| -| ||:diagtext:`reading`|| ||+------------------------------------------+ || -| |+-------------------+| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || -| ||:diagtext:`writing`|| ||+------------------------------------------+ || -| |+-------------------+| |+--------------------------------------------------------+| -| | | ||+------------------------------------------------------+|| -| | | |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| -| | | ||+------------------------------------------------------+|| -| | | |+--------------------------------------------------------+| -+---------------------------+---------------------+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ ++---------------------------+---------------------+---------------------------------------------------------------------------------------------------------------+-----------------------------------+ +|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`the value pointed to by` |nbsp| :placeholder:`A` |nbsp| :diagtext:`requires holding` |nbsp| |+---------------------------------+| +| ||:diagtext:`reading`|| ||:diagtext:`any mutex` || +| |+-------------------+| |+---------------------------------+| +| ||:diagtext:`writing`|| ||:diagtext:`any mutex exclusively`|| +| |+-------------------+| |+---------------------------------+| ++---------------------------+---------------------+---------------------------------------------------------------------------------------------------------------+-----------------------------------+ + ++---------------------------+---------------------+---------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ +|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`the value pointed to by` |nbsp| :placeholder:`B` |nbsp| :diagtext:`requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| +| ||:diagtext:`reading`|| ||+------------------------------------------+ || +| |+-------------------+| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || +| ||:diagtext:`writing`|| ||+------------------------------------------+ || +| |+-------------------+| |+--------------------------------------------------------+| +| | | ||+------------------------------------------------------+|| +| | | |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| +| | | ||+------------------------------------------------------+|| +| | | |+--------------------------------------------------------+| ++---------------------------+---------------------+---------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ + ++---------------------------+---------------------+------------------------------------------------------------------------------------------------+-----------------------------------+ +|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`variable` |nbsp| :placeholder:`A` |nbsp| :diagtext:`requires holding` |nbsp| |+---------------------------------+| +| ||:diagtext:`reading`|| ||:diagtext:`any mutex` || +| |+-------------------+| |+---------------------------------+| +| ||:diagtext:`writing`|| ||:diagtext:`any mutex exclusively`|| +| |+-------------------+| |+---------------------------------+| ++---------------------------+---------------------+------------------------------------------------------------------------------------------------+-----------------------------------+ + ++---------------------------+---------------------+------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ +|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`variable` |nbsp| :placeholder:`B` |nbsp| :diagtext:`requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| +| ||:diagtext:`reading`|| ||+------------------------------------------+ || +| |+-------------------+| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || +| ||:diagtext:`writing`|| ||+------------------------------------------+ || +| |+-------------------+| |+--------------------------------------------------------+| +| | | ||+------------------------------------------------------+|| +| | | |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| +| | | ||+------------------------------------------------------+|| +| | | |+--------------------------------------------------------+| ++---------------------------+---------------------+------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -Wthread-safety-attributes @@ -10289,6 +11001,14 @@ Controls `-Wthread-safety-analysis`_, `-Wthread-safety-attributes`_, `-Wthread-s |:warning:`warning:` |nbsp| :diagtext:`ignoring` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute because its argument is invalid`| +------------------------------------------------------------------------------------------------------------------------------------+ ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute without capability arguments refers to 'this', but` |nbsp| :placeholder:`B` |nbsp| :diagtext:`isn't annotated with 'capability' or 'scoped\_lockable' attribute`| ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + ++----------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute without capability arguments can only be applied to non-static methods of a class`| ++----------------------------------------------------------------------------------------------------------------------------------------------------------+ + -Wthread-safety-beta -------------------- @@ -10312,70 +11032,70 @@ Controls `-Wthread-safety-analysis`_, `-Wthread-safety-attributes`_, `-Wthread-s ----------------------- **Diagnostic text:** -+---------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`calling function '`:placeholder:`B`:diagtext:`' requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| -| ||+------------------------------------------+ || -| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || -| ||+------------------------------------------+ || -| |+--------------------------------------------------------+| -| ||+------------------------------------------------------+|| -| |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| -| ||+------------------------------------------------------+|| -| |+--------------------------------------------------------+| -+---------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ - -+---------------------------+---------------------+---------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`the value pointed to by '`:placeholder:`B`:diagtext:`' requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| -| ||:diagtext:`reading`|| ||+------------------------------------------+ || -| |+-------------------+| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || -| ||:diagtext:`writing`|| ||+------------------------------------------+ || -| |+-------------------+| |+--------------------------------------------------------+| -| | | ||+------------------------------------------------------+|| -| | | |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| -| | | ||+------------------------------------------------------+|| -| | | |+--------------------------------------------------------+| -+---------------------------+---------------------+---------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ - -+---------------------------+---------------------+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`variable '`:placeholder:`B`:diagtext:`' requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| -| ||:diagtext:`reading`|| ||+------------------------------------------+ || -| |+-------------------+| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || -| ||:diagtext:`writing`|| ||+------------------------------------------+ || -| |+-------------------+| |+--------------------------------------------------------+| -| | | ||+------------------------------------------------------+|| -| | | |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| -| | | ||+------------------------------------------------------+|| -| | | |+--------------------------------------------------------+| -+---------------------------+---------------------+------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ ++---------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`calling function` |nbsp| :placeholder:`B` |nbsp| :diagtext:`requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| +| ||+------------------------------------------+ || +| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || +| ||+------------------------------------------+ || +| |+--------------------------------------------------------+| +| ||+------------------------------------------------------+|| +| |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| +| ||+------------------------------------------------------+|| +| |+--------------------------------------------------------+| ++---------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ + ++---------------------------+---------------------+---------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ +|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`the value pointed to by` |nbsp| :placeholder:`B` |nbsp| :diagtext:`requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| +| ||:diagtext:`reading`|| ||+------------------------------------------+ || +| |+-------------------+| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || +| ||:diagtext:`writing`|| ||+------------------------------------------+ || +| |+-------------------+| |+--------------------------------------------------------+| +| | | ||+------------------------------------------------------+|| +| | | |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| +| | | ||+------------------------------------------------------+|| +| | | |+--------------------------------------------------------+| ++---------------------------+---------------------+---------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ + ++---------------------------+---------------------+------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ +|:warning:`warning:` |nbsp| |+-------------------+| |nbsp| :diagtext:`variable` |nbsp| :placeholder:`B` |nbsp| :diagtext:`requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| +| ||:diagtext:`reading`|| ||+------------------------------------------+ || +| |+-------------------+| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || +| ||:diagtext:`writing`|| ||+------------------------------------------+ || +| |+-------------------+| |+--------------------------------------------------------+| +| | | ||+------------------------------------------------------+|| +| | | |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| +| | | ||+------------------------------------------------------+|| +| | | |+--------------------------------------------------------+| ++---------------------------+---------------------+------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -Wthread-safety-reference ------------------------- **Diagnostic text:** -+----------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`passing variable '`:placeholder:`B`:diagtext:`' by reference requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| -| ||+------------------------------------------+ || -| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || -| ||+------------------------------------------+ || -| |+--------------------------------------------------------+| -| ||+------------------------------------------------------+|| -| |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| -| ||+------------------------------------------------------+|| -| |+--------------------------------------------------------+| -+----------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`passing the value that '`:placeholder:`B`:diagtext:`' points to by reference requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| -| ||+------------------------------------------+ || -| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || -| ||+------------------------------------------+ || -| |+--------------------------------------------------------+| -| ||+------------------------------------------------------+|| -| |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| -| ||+------------------------------------------------------+|| -| |+--------------------------------------------------------+| -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ ++----------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`passing variable` |nbsp| :placeholder:`B` |nbsp| :diagtext:`by reference requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| +| ||+------------------------------------------+ || +| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || +| ||+------------------------------------------+ || +| |+--------------------------------------------------------+| +| ||+------------------------------------------------------+|| +| |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| +| ||+------------------------------------------------------+|| +| |+--------------------------------------------------------+| ++----------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ + ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`passing the value that` |nbsp| :placeholder:`B` |nbsp| :diagtext:`points to by reference requires holding` |nbsp| :placeholder:`A` |nbsp| |+--------------------------------------------------------+| +| ||+------------------------------------------+ || +| |||:diagtext:`'`:placeholder:`C`:diagtext:`'`| || +| ||+------------------------------------------+ || +| |+--------------------------------------------------------+| +| ||+------------------------------------------------------+|| +| |||:diagtext:`'`:placeholder:`C`:diagtext:`' exclusively`||| +| ||+------------------------------------------------------+|| +| |+--------------------------------------------------------+| ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------+ -Wthread-safety-verbose @@ -10656,6 +11376,17 @@ This diagnostic is enabled by default. +---------------------------------------------------------------------------------------------+ +-Wunicode-homoglyph +------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`treating Unicode character as identifier character rather than as '`:placeholder:`B`:diagtext:`' symbol`| ++-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wunicode-whitespace -------------------- This diagnostic is enabled by default. @@ -10667,6 +11398,17 @@ This diagnostic is enabled by default. +-------------------------------------------------------------------------------+ +-Wunicode-zero-width +-------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++----------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`identifier contains Unicode character that is invisible in some environments`| ++----------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wuninitialized --------------- Some of the diagnostics controlled by this flag are enabled by default. @@ -10718,6 +11460,10 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`unknown argument ignored in clang-cl: '`:placeholder:`A`:diagtext:`'`| +-----------------------------------------------------------------------------------------------------------+ ++---------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`unknown argument ignored in clang-cl '`:placeholder:`A`:diagtext:`' (did you mean '`:placeholder:`B`:diagtext:`'?)`| ++---------------------------------------------------------------------------------------------------------------------------------------------------------+ + -Wunknown-attributes -------------------- @@ -11048,6 +11794,17 @@ This diagnostic is enabled by default. +-------------------------------------------------------------------------------------------------------------------------------------------------+ +-Wunsupported-target-opt +------------------------ +This diagnostic is enabled by default. + +**Diagnostic text:** + ++---------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`debug information option '`:placeholder:`A`:diagtext:`' is not supported for target '`:placeholder:`B`:diagtext:`'`| ++---------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wunsupported-visibility ------------------------ This diagnostic is enabled by default. @@ -11138,19 +11895,17 @@ This diagnostic is enabled by default. **Diagnostic text:** -+---------------------------+-----------------------------------------+--------------------------------------------+ -|:warning:`warning:` |nbsp| |+---------------------------------------+| |nbsp| :diagtext:`comparison result unused`| -| ||+----------------+--------------------+|| | -| |||+--------------+|:diagtext:`equality`||| | -| |||| || ||| | -| |||+--------------+| ||| | -| ||||:diagtext:`in`|| ||| | -| |||+--------------+| ||| | -| ||+----------------+--------------------+|| | -| |+---------------------------------------+| | -| ||:diagtext:`relational` || | -| |+---------------------------------------+| | -+---------------------------+-----------------------------------------+--------------------------------------------+ ++---------------------------+------------------------+--------------------------------------------+ +|:warning:`warning:` |nbsp| |+----------------------+| |nbsp| :diagtext:`comparison result unused`| +| ||:diagtext:`equality` || | +| |+----------------------+| | +| ||:diagtext:`inequality`|| | +| |+----------------------+| | +| ||:diagtext:`relational`|| | +| |+----------------------+| | +| ||:diagtext:`three-way` || | +| |+----------------------+| | ++---------------------------+------------------------+--------------------------------------------+ -Wunused-const-variable From db4cf6bdbf2acb92691396e8bda7c509ceac3ca0 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 21 Mar 2019 20:32:00 +0000 Subject: [PATCH 207/274] Bump version to 8.0.1 llvm-svn: 356708 --- libcxx/CMakeLists.txt | 2 +- libunwind/CMakeLists.txt | 2 +- llvm/CMakeLists.txt | 2 +- llvm/utils/lit/lit/__init__.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index 3a6c3c9df4d6a..6b83bce1ae72d 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -27,7 +27,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) project(libcxx CXX C) set(PACKAGE_NAME libcxx) - set(PACKAGE_VERSION 8.0.0) + set(PACKAGE_VERSION 8.0.1) set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org") diff --git a/libunwind/CMakeLists.txt b/libunwind/CMakeLists.txt index c9ba7527afb28..3d06073cfe747 100644 --- a/libunwind/CMakeLists.txt +++ b/libunwind/CMakeLists.txt @@ -81,7 +81,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) endif() set(PACKAGE_NAME libunwind) - set(PACKAGE_VERSION 8.0.0) + set(PACKAGE_VERSION 8.0.1) set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org") diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index 27754f339493b..81c2bab39ec96 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -18,7 +18,7 @@ if(NOT DEFINED LLVM_VERSION_MINOR) set(LLVM_VERSION_MINOR 0) endif() if(NOT DEFINED LLVM_VERSION_PATCH) - set(LLVM_VERSION_PATCH 0) + set(LLVM_VERSION_PATCH 1) endif() if(NOT DEFINED LLVM_VERSION_SUFFIX) set(LLVM_VERSION_SUFFIX "") diff --git a/llvm/utils/lit/lit/__init__.py b/llvm/utils/lit/lit/__init__.py index 0d849d16f076e..023bed817075f 100644 --- a/llvm/utils/lit/lit/__init__.py +++ b/llvm/utils/lit/lit/__init__.py @@ -2,7 +2,7 @@ __author__ = 'Daniel Dunbar' __email__ = 'daniel@minormatter.com' -__versioninfo__ = (0, 8, 0) +__versioninfo__ = (0, 8, 1) __version__ = '.'.join(str(v) for v in __versioninfo__) + 'dev' __all__ = [] From bf2f5abb8e3caf7afab323376226f8610cee4d63 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 21 Mar 2019 20:45:59 +0000 Subject: [PATCH 208/274] git-llvm: Update for release_80 branch llvm-svn: 356714 --- llvm/utils/git-svn/git-llvm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/utils/git-svn/git-llvm b/llvm/utils/git-svn/git-llvm index 53c0b24ae2c85..bf234301f1321 100755 --- a/llvm/utils/git-svn/git-llvm +++ b/llvm/utils/git-svn/git-llvm @@ -42,7 +42,7 @@ else: # It's *almost* a straightforward mapping from the monorepo to svn... GIT_TO_SVN_DIR = { - d: (d + '/trunk') + d: (d + '/branches/release_80') for d in [ 'clang-tools-extra', 'compiler-rt', @@ -63,8 +63,8 @@ GIT_TO_SVN_DIR = { 'pstl', ] } -GIT_TO_SVN_DIR.update({'clang': 'cfe/trunk'}) -GIT_TO_SVN_DIR.update({'': 'monorepo-root/trunk'}) +GIT_TO_SVN_DIR.update({'clang': 'cfe/branches/release_80'}) +GIT_TO_SVN_DIR.update({'': 'monorepo-root/branches/release_80'}) VERBOSE = False QUIET = False From 25895ad2836e63d2e6c77d4dbfb008c6898e5bf9 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 29 Mar 2019 03:37:22 +0000 Subject: [PATCH 209/274] Merging r356924: ------------------------------------------------------------------------ r356924 | tstellar | 2019-03-25 10:01:29 -0700 (Mon, 25 Mar 2019) | 1 line merge-request.sh: Update 8.0 metabug for 8.0.1 ------------------------------------------------------------------------ llvm-svn: 357234 --- llvm/utils/release/merge-request.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/llvm/utils/release/merge-request.sh b/llvm/utils/release/merge-request.sh index 333b9043af356..c9763ee3cec43 100755 --- a/llvm/utils/release/merge-request.sh +++ b/llvm/utils/release/merge-request.sh @@ -101,6 +101,9 @@ case $stable_version in 7.0) release_metabug="39106" ;; + 8.0) + release_metabug="41221" + ;; *) echo "error: invalid stable version" exit 1 From 79c29c6b53c371b9ec79ec440564e4cc0f823030 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Mon, 22 Apr 2019 18:15:57 +0000 Subject: [PATCH 210/274] Merging r355854: ------------------------------------------------------------------------ r355854 | jonpa | 2019-03-11 12:00:37 -0700 (Mon, 11 Mar 2019) | 13 lines [RegAlloc] Avoid compile time regression with multiple copy hints. As a fix for https://bugs.llvm.org/show_bug.cgi?id=40986 ("excessive compile time building opencollada"), this patch makes sure that no phys reg is hinted more than once from getRegAllocationHints(). This handles the case were many virtual registers are assigned to the same physreg. The previous compile time fix (r343686) in weightCalcHelper() only made sure that physical/virtual registers are passed no more than once to addRegAllocationHint(). Review: Dimitry Andric, Quentin Colombet https://reviews.llvm.org/D59201 ------------------------------------------------------------------------ llvm-svn: 358905 --- llvm/lib/CodeGen/TargetRegisterInfo.cpp | 6 + llvm/test/CodeGen/X86/regalloc-copy-hints.mir | 805 ++++++++++++++++++ 2 files changed, 811 insertions(+) create mode 100644 llvm/test/CodeGen/X86/regalloc-copy-hints.mir diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp index 661dc18f7a85e..d3059280a60fc 100644 --- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp +++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp @@ -14,6 +14,7 @@ #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -398,6 +399,7 @@ TargetRegisterInfo::getRegAllocationHints(unsigned VirtReg, const std::pair> &Hints_MRI = MRI.getRegAllocationHints(VirtReg); + SmallSet HintedRegs; // First hint may be a target hint. bool Skip = (Hints_MRI.first != 0); for (auto Reg : Hints_MRI.second) { @@ -411,6 +413,10 @@ TargetRegisterInfo::getRegAllocationHints(unsigned VirtReg, if (VRM && isVirtualRegister(Phys)) Phys = VRM->getPhys(Phys); + // Don't add the same reg twice (Hints_MRI may contain multiple virtual + // registers allocated to the same physreg). + if (!HintedRegs.insert(Phys).second) + continue; // Check that Phys is a valid hint in VirtReg's register class. if (!isPhysicalRegister(Phys)) continue; diff --git a/llvm/test/CodeGen/X86/regalloc-copy-hints.mir b/llvm/test/CodeGen/X86/regalloc-copy-hints.mir new file mode 100644 index 0000000000000..6287066e64fe0 --- /dev/null +++ b/llvm/test/CodeGen/X86/regalloc-copy-hints.mir @@ -0,0 +1,805 @@ +# RUN: llc -mtriple=i386-unknown-unknown -mcpu=i486 %s -o - -run-pass greedy \ +# RUN: -debug-only=regalloc 2>&1 | FileCheck %s +# REQUIRES: asserts + +--- | + %0 = type { %1 } + %1 = type { %2, %23, %23*, %27*, %28*, %29, %33*, %34, %42, i8, i32, i32, i32 } + %2 = type { %3, %6, %14, %14, i8, i8*, i8*, %16 } + %3 = type { i32 (...)**, %4*, %5* } + %4 = type { i32 (...)**, %3* } + %5 = type { i32 (...)** } + %6 = type { %7 } + %7 = type { %8, i32, %12 } + %8 = type { %9**, %9**, %9**, %10 } + %9 = type { i32, i32, i32, i8* } + %10 = type { %11 } + %11 = type { %9** } + %12 = type { %13 } + %13 = type { i32 } + %14 = type { i32, %15* } + %15 = type { i32, i32, i8* } + %16 = type { %17 } + %17 = type { %18*, %20, %22 } + %18 = type { %19* } + %19 = type <{ %18, %19*, %18*, i8, [3 x i8] }> + %20 = type { %21 } + %21 = type { %18 } + %22 = type { %13 } + %23 = type { %24 } + %24 = type { %18*, %25, %26 } + %25 = type { %21 } + %26 = type { %13 } + %27 = type { i32 (...)** } + %28 = type { i32 (...)** } + %29 = type { %30 } + %30 = type { %18*, %31, %32 } + %31 = type { %21 } + %32 = type { %13 } + %33 = type { i32 (...)** } + %34 = type { %35 } + %35 = type { %36 } + %36 = type { %37, i32, %41 } + %37 = type { %38**, %38**, %38**, %39 } + %38 = type { %42, i32 } + %39 = type { %40 } + %40 = type { %38** } + %41 = type { %13 } + %42 = type { %43 } + %43 = type { %18*, %44, %45 } + %44 = type { %21 } + %45 = type { %13 } + %46 = type { %47, %48 } + %47 = type <{ %18, %19*, %18*, i8 }> + %48 = type { %49 } + %49 = type { i32, %50 } + %50 = type { { i32, i32 }, { i32, i32 }, { i32, i32 }, { i32, i32 }, { i32, i32 }, { i32, i32 } } + + define void @fun(%0* %arg) local_unnamed_addr #0 align 2 personality i32 (...)* @__gxx_personality_v0 { + bb: + %tmp = getelementptr inbounds %0, %0* %arg, i32 0, i32 0, i32 1 + %tmp1 = getelementptr inbounds %0, %0* %arg, i32 0, i32 0, i32 1, i32 0, i32 1, i32 0, i32 0 + br i1 undef, label %bb5, label %bb6 + + bb5: ; preds = %bb + unreachable + + bb6: ; preds = %bb + %tmp8 = getelementptr inbounds %0, %0* %arg, i32 0, i32 0, i32 8, i32 0, i32 1, i32 0, i32 0 + br i1 undef, label %bb10, label %bb9 + + bb9: ; preds = %bb6 + unreachable + + bb10: ; preds = %bb6 + store %18* %tmp8, %18** undef + br i1 undef, label %bb14, label %bb13 + + bb13: ; preds = %bb10 + unreachable + + bb14: ; preds = %bb10 + br i1 undef, label %bb17, label %bb18 + + bb17: ; preds = %bb14 + unreachable + + bb18: ; preds = %bb14 + br i1 undef, label %bb20, label %bb19 + + bb19: ; preds = %bb18 + unreachable + + bb20: ; preds = %bb18 + br i1 undef, label %bb25, label %bb24 + + bb24: ; preds = %bb20 + unreachable + + bb25: ; preds = %bb20 + br i1 undef, label %bb29, label %bb30 + + bb29: ; preds = %bb25 + unreachable + + bb30: ; preds = %bb25 + br i1 undef, label %bb38, label %bb31 + + bb31: ; preds = %bb30 + %tmp32 = getelementptr inbounds %0, %0* %arg, i32 0, i32 0, i32 1, i32 0, i32 1, i32 0, i32 0, i32 0 + br i1 undef, label %bb34, label %bb35 + + bb34: ; preds = %bb31 + unreachable + + bb35: ; preds = %bb31 + br i1 undef, label %bb40, label %bb36 + + bb36: ; preds = %bb35 + unreachable + + bb38: ; preds = %bb30 + %tmp391 = bitcast %18* %tmp1 to %19** + br label %bb40 + + bb40: ; preds = %bb35, %bb38 + %tmp41 = phi %18* [ %tmp1, %bb38 ], [ null, %bb35 ] + %tmp42 = phi %19** [ %tmp391, %bb38 ], [ %tmp32, %bb35 ] + br i1 undef, label %bb43, label %bb48 + + bb43: ; preds = %bb40 + %tmp44 = tail call i8* @_Znwj() + store %18* %tmp41, %18** undef + %tmp46 = bitcast %19** %tmp42 to i8** + store i8* %tmp44, i8** %tmp46 + %0 = bitcast i8* %tmp44 to %46* + tail call void @_ZNSt3__127__tree_balance_after_insertIPNS_16__tree_node_baseIPvEEEEvT_S5_() + br label %bb48 + + bb48: ; preds = %bb43, %bb40 + %tmp49 = phi %46* [ %0, %bb43 ], [ undef, %bb40 ] + %tmp50 = getelementptr inbounds %46, %46* %tmp49, i32 0, i32 1, i32 0, i32 1, i32 4, i32 0 + store i32 ptrtoint (i1 (%0*)* @_ZN15COLLADASaxFWL1429ColladaParserAutoGen14Private15_preEnd__authorEv to i32), i32* %tmp50 + br i1 undef, label %bb52, label %bb53 + + bb52: ; preds = %bb48 + unreachable + + bb53: ; preds = %bb48 + br i1 undef, label %bb55, label %bb54 + + bb54: ; preds = %bb53 + unreachable + + bb55: ; preds = %bb53 + br i1 undef, label %bb59, label %bb58 + + bb58: ; preds = %bb55 + unreachable + + bb59: ; preds = %bb55 + br i1 undef, label %bb62, label %bb61 + + bb61: ; preds = %bb59 + unreachable + + bb62: ; preds = %bb59 + br i1 undef, label %bb64, label %bb65 + + bb64: ; preds = %bb62 + unreachable + + bb65: ; preds = %bb62 + %tmp66 = icmp eq %46* null, null + br i1 %tmp66, label %bb72, label %bb67 + + bb67: ; preds = %bb65 + %tmp68 = getelementptr inbounds %0, %0* %arg, i32 0, i32 0, i32 1, i32 0, i32 1, i32 0, i32 0, i32 0 + br i1 undef, label %bb70, label %bb74 + + bb70: ; preds = %bb67 + unreachable + + bb72: ; preds = %bb65 + %tmp732 = bitcast %18* %tmp1 to %19** + br label %bb74 + + bb74: ; preds = %bb67, %bb72 + %tmp75 = phi %18* [ %tmp1, %bb72 ], [ null, %bb67 ] + %tmp76 = phi %19** [ %tmp732, %bb72 ], [ %tmp68, %bb67 ] + %tmp77 = tail call i8* @_Znwj() + store %18* %tmp75, %18** undef + %tmp79 = bitcast %19** %tmp76 to i8** + store i8* %tmp77, i8** %tmp79 + %1 = bitcast i8* %tmp77 to %46* + tail call void @_ZNSt3__127__tree_balance_after_insertIPNS_16__tree_node_baseIPvEEEEvT_S5_() + %tmp81 = getelementptr inbounds %46, %46* %1, i32 0, i32 1, i32 0, i32 1, i32 2, i32 0 + store i32 ptrtoint (i1 (%0*)* @_ZN15COLLADASaxFWL1429ColladaParserAutoGen14Private14_end__commentsEv to i32), i32* %tmp81 + store %18* %tmp8, %18** undef + %2 = bitcast %0* %arg to i8* + %sunkaddr = getelementptr i8, i8* %2, i32 140 + %3 = bitcast i8* %sunkaddr to %18** + %tmp85 = load %18*, %18** %3 + %tmp864 = bitcast %18* %tmp85 to %19** + %tmp87 = load %19*, %19** %tmp864 + %tmp88 = icmp eq %19* %tmp87, null + br i1 %tmp88, label %bb90, label %bb89 + + bb89: ; preds = %bb74 + unreachable + + bb90: ; preds = %bb74 + br i1 undef, label %bb94, label %bb92 + + bb92: ; preds = %bb90 + br i1 undef, label %bb96, label %bb97 + + bb94: ; preds = %bb90 + unreachable + + bb96: ; preds = %bb92 + unreachable + + bb97: ; preds = %bb92 + br i1 undef, label %bb101, label %bb102 + + bb101: ; preds = %bb97 + unreachable + + bb102: ; preds = %bb97 + br i1 undef, label %bb104, label %bb103 + + bb103: ; preds = %bb102 + unreachable + + bb104: ; preds = %bb102 + br i1 undef, label %bb109, label %bb108 + + bb108: ; preds = %bb104 + unreachable + + bb109: ; preds = %bb104 + br i1 undef, label %bb111, label %bb112 + + bb111: ; preds = %bb109 + unreachable + + bb112: ; preds = %bb109 + br i1 undef, label %bb118, label %bb117 + + bb117: ; preds = %bb112 + unreachable + + bb118: ; preds = %bb112 + br i1 undef, label %bb120, label %bb121 + + bb120: ; preds = %bb118 + unreachable + + bb121: ; preds = %bb118 + br i1 undef, label %bb124, label %bb125 + + bb124: ; preds = %bb121 + unreachable + + bb125: ; preds = %bb121 + %4 = bitcast %18* %tmp1 to %46** + %tmp126 = load %46*, %46** %4 + %tmp127 = icmp eq %46* %tmp126, null + br i1 %tmp127, label %bb135, label %bb128 + + bb128: ; preds = %bb125 + br label %bb129 + + bb129: ; preds = %bb131, %bb128 + %tmp130 = icmp ugt i32 undef, 95406324 + br i1 %tmp130, label %bb131, label %bb133 + + bb131: ; preds = %bb129 + br label %bb129 + + bb133: ; preds = %bb129 + unreachable + + bb135: ; preds = %bb125 + br i1 undef, label %bb137, label %bb138 + + bb137: ; preds = %bb135 + unreachable + + bb138: ; preds = %bb135 + unreachable + } + + declare zeroext i1 @_ZN15COLLADASaxFWL1429ColladaParserAutoGen14Private15_preEnd__authorEv(%0*) #0 + + declare zeroext i1 @_ZN15COLLADASaxFWL1429ColladaParserAutoGen14Private14_end__commentsEv(%0*) #0 align 2 + + declare i32 @__gxx_personality_v0(...) #0 + + declare noalias nonnull i8* @_Znwj() local_unnamed_addr #0 + + declare void @_ZNSt3__127__tree_balance_after_insertIPNS_16__tree_node_baseIPvEEEEvT_S5_() local_unnamed_addr #0 + + ; Function Attrs: nounwind + declare void @llvm.stackprotector(i8*, i8**) #1 + + attributes #0 = { "target-cpu"="i486" } + attributes #1 = { nounwind } + +... +--- +# A physreg should always only be hinted once per getRegAllocationHints() query. +# CHECK: hints: $ebx $edi +# CHECK-NOT: hints: $ebx $edi $ebx $edi +name: fun +alignment: 4 +tracksRegLiveness: true +registers: + - { id: 0, class: gr32 } + - { id: 1, class: gr32 } + - { id: 2, class: gr32 } + - { id: 3, class: gr32 } + - { id: 4, class: gr32 } + - { id: 5, class: gr32 } + - { id: 6, class: gr32 } + - { id: 7, class: gr32 } + - { id: 8, class: gr32 } + - { id: 9, class: gr32 } + - { id: 10, class: gr32 } + - { id: 11, class: gr32 } + - { id: 12, class: gr32 } + - { id: 13, class: gr32_abcd } + - { id: 14, class: gr8 } + - { id: 15, class: gr32_abcd } + - { id: 16, class: gr8 } + - { id: 17, class: gr32 } + - { id: 18, class: gr32_abcd } + - { id: 19, class: gr8 } + - { id: 20, class: gr32_abcd } + - { id: 21, class: gr8 } + - { id: 22, class: gr32_abcd } + - { id: 23, class: gr8 } + - { id: 24, class: gr32_abcd } + - { id: 25, class: gr8 } + - { id: 26, class: gr32_abcd } + - { id: 27, class: gr8 } + - { id: 28, class: gr32_abcd } + - { id: 29, class: gr8 } + - { id: 30, class: gr32_abcd } + - { id: 31, class: gr8 } + - { id: 32, class: gr32_abcd } + - { id: 33, class: gr8 } + - { id: 34, class: gr32 } + - { id: 35, class: gr32_abcd } + - { id: 36, class: gr8 } + - { id: 37, class: gr32 } + - { id: 38, class: gr32 } + - { id: 39, class: gr32_abcd } + - { id: 40, class: gr8 } + - { id: 41, class: gr32_abcd } + - { id: 42, class: gr8 } + - { id: 43, class: gr32_abcd } + - { id: 44, class: gr8 } + - { id: 45, class: gr32_abcd } + - { id: 46, class: gr8 } + - { id: 47, class: gr32_abcd } + - { id: 48, class: gr8 } + - { id: 49, class: gr8 } + - { id: 50, class: gr32_abcd } + - { id: 51, class: gr8 } + - { id: 52, class: gr32 } + - { id: 53, class: gr32 } + - { id: 54, class: gr32 } + - { id: 55, class: gr32 } + - { id: 56, class: gr32_abcd } + - { id: 57, class: gr8 } + - { id: 58, class: gr32_abcd } + - { id: 59, class: gr8 } + - { id: 60, class: gr32_abcd } + - { id: 61, class: gr8 } + - { id: 62, class: gr32_abcd } + - { id: 63, class: gr8 } + - { id: 64, class: gr32_abcd } + - { id: 65, class: gr8 } + - { id: 66, class: gr32_abcd } + - { id: 67, class: gr8 } + - { id: 68, class: gr32_abcd } + - { id: 69, class: gr8 } + - { id: 70, class: gr32_abcd } + - { id: 71, class: gr8 } + - { id: 72, class: gr32_abcd } + - { id: 73, class: gr8 } + - { id: 74, class: gr32 } + - { id: 75, class: gr32 } + - { id: 76, class: gr32_abcd } + - { id: 77, class: gr8 } + - { id: 78, class: gr32_abcd } + - { id: 79, class: gr32 } + - { id: 80, class: gr32 } + - { id: 81, class: gr32_abcd } + - { id: 82, class: gr32 } +frameInfo: + maxAlignment: 4 + hasCalls: true +fixedStack: + - { id: 0, size: 4, alignment: 4, stack-id: 0, isImmutable: true } +body: | + bb.0.bb: + successors: %bb.1(0x00000001), %bb.2(0x7fffffff) + + %13:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %13.sub_8bit, %13.sub_8bit, implicit-def $eflags + JNE_1 %bb.2, implicit killed $eflags + JMP_1 %bb.1 + + bb.1.bb5: + successors: + + + bb.2.bb6: + successors: %bb.4(0x7fffffff), %bb.3(0x00000001) + + %15:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %15.sub_8bit, %15.sub_8bit, implicit-def $eflags + JNE_1 %bb.4, implicit killed $eflags + JMP_1 %bb.3 + + bb.3.bb9: + successors: + + + bb.4.bb10: + successors: %bb.6(0x7fffffff), %bb.5(0x00000001) + + %12:gr32 = MOV32rm %fixed-stack.0, 1, $noreg, 0, $noreg :: (load 4 from %fixed-stack.0) + %1:gr32 = LEA32r %12, 1, $noreg, 144, $noreg + MOV32mr undef %17:gr32, 1, $noreg, 0, $noreg, %1 :: (store 4 into `%18** undef`) + %18:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %18.sub_8bit, %18.sub_8bit, implicit-def $eflags + JNE_1 %bb.6, implicit killed $eflags + JMP_1 %bb.5 + + bb.5.bb13: + successors: + + + bb.6.bb14: + successors: %bb.7(0x00000001), %bb.8(0x7fffffff) + + %20:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %20.sub_8bit, %20.sub_8bit, implicit-def $eflags + JNE_1 %bb.8, implicit killed $eflags + JMP_1 %bb.7 + + bb.7.bb17: + successors: + + + bb.8.bb18: + successors: %bb.10(0x7fffffff), %bb.9(0x00000001) + + %22:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %22.sub_8bit, %22.sub_8bit, implicit-def $eflags + JNE_1 %bb.10, implicit killed $eflags + JMP_1 %bb.9 + + bb.9.bb19: + successors: + + + bb.10.bb20: + successors: %bb.12(0x7fffffff), %bb.11(0x00000001) + + %24:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %24.sub_8bit, %24.sub_8bit, implicit-def $eflags + JNE_1 %bb.12, implicit killed $eflags + JMP_1 %bb.11 + + bb.11.bb24: + successors: + + + bb.12.bb25: + successors: %bb.13(0x00000001), %bb.14(0x7fffffff) + + %26:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %26.sub_8bit, %26.sub_8bit, implicit-def $eflags + JNE_1 %bb.14, implicit killed $eflags + JMP_1 %bb.13 + + bb.13.bb29: + successors: + + + bb.14.bb30: + %0:gr32 = LEA32r %12, 1, $noreg, 80, $noreg + %28:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %28.sub_8bit, %28.sub_8bit, implicit-def $eflags + JNE_1 %bb.20, implicit killed $eflags + JMP_1 %bb.15 + + bb.15.bb31: + successors: %bb.16(0x00000001), %bb.17(0x7fffffff) + + %78:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %78.sub_8bit, %78.sub_8bit, implicit-def $eflags + JNE_1 %bb.17, implicit killed $eflags + JMP_1 %bb.16 + + bb.16.bb34: + successors: + + + bb.17.bb35: + successors: %bb.18(0x7fffffff), %bb.19(0x00000001) + + TEST8rr %78.sub_8bit, %78.sub_8bit, implicit-def $eflags + JE_1 %bb.19, implicit killed $eflags + + bb.18: + %79:gr32 = LEA32r %12, 1, $noreg, 80, $noreg + JMP_1 %bb.21 + + bb.19.bb36: + successors: + + + bb.20.bb38: + %78:gr32_abcd = COPY %0 + %79:gr32 = COPY %0 + + bb.21.bb40: + successors: %bb.22, %bb.23 + + %35:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %35.sub_8bit, %35.sub_8bit, implicit-def $eflags + %80:gr32 = IMPLICIT_DEF + JNE_1 %bb.23, implicit killed $eflags + JMP_1 %bb.22 + + bb.22.bb43: + ADJCALLSTACKDOWN32 0, 0, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp + CALLpcrel32 @_Znwj, csr_32, implicit $esp, implicit $ssp, implicit-def $esp, implicit-def $ssp, implicit-def $eax + ADJCALLSTACKUP32 0, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp + %80:gr32 = COPY killed $eax + MOV32mr undef %38:gr32, 1, $noreg, 0, $noreg, %78 :: (store 4 into `%18** undef`) + MOV32mr %79, 1, $noreg, 0, $noreg, %80 :: (store 4 into %ir.tmp46) + ADJCALLSTACKDOWN32 0, 0, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp + CALLpcrel32 @_ZNSt3__127__tree_balance_after_insertIPNS_16__tree_node_baseIPvEEEEvT_S5_, csr_32, implicit $esp, implicit $ssp, implicit-def $esp, implicit-def $ssp + ADJCALLSTACKUP32 0, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp + + bb.23.bb48: + successors: %bb.24(0x00000001), %bb.25(0x7fffffff) + + MOV32mi %80, 1, $noreg, 52, $noreg, @_ZN15COLLADASaxFWL1429ColladaParserAutoGen14Private15_preEnd__authorEv :: (store 4 into %ir.tmp50) + %39:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %39.sub_8bit, %39.sub_8bit, implicit-def $eflags + JNE_1 %bb.25, implicit killed $eflags + JMP_1 %bb.24 + + bb.24.bb52: + successors: + + + bb.25.bb53: + successors: %bb.27(0x7fffffff), %bb.26(0x00000001) + + %41:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %41.sub_8bit, %41.sub_8bit, implicit-def $eflags + JNE_1 %bb.27, implicit killed $eflags + JMP_1 %bb.26 + + bb.26.bb54: + successors: + + + bb.27.bb55: + successors: %bb.29(0x7fffffff), %bb.28(0x00000001) + + %43:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %43.sub_8bit, %43.sub_8bit, implicit-def $eflags + JNE_1 %bb.29, implicit killed $eflags + JMP_1 %bb.28 + + bb.28.bb58: + successors: + + + bb.29.bb59: + successors: %bb.31(0x7fffffff), %bb.30(0x00000001) + + %45:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %45.sub_8bit, %45.sub_8bit, implicit-def $eflags + JNE_1 %bb.31, implicit killed $eflags + JMP_1 %bb.30 + + bb.30.bb61: + successors: + + + bb.31.bb62: + successors: %bb.32(0x00000001), %bb.33(0x7fffffff) + + %47:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %47.sub_8bit, %47.sub_8bit, implicit-def $eflags + JNE_1 %bb.33, implicit killed $eflags + JMP_1 %bb.32 + + bb.32.bb64: + successors: + + + bb.33.bb65: + successors: %bb.37(0x30000000), %bb.34(0x50000000) + + %49:gr8 = MOV8ri 1 + TEST8rr %49, %49, implicit-def $eflags + JNE_1 %bb.37, implicit killed $eflags + JMP_1 %bb.34 + + bb.34.bb67: + successors: %bb.36(0x00000001), %bb.35(0x7fffffff) + + %81:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %81.sub_8bit, %81.sub_8bit, implicit-def $eflags + JE_1 %bb.36, implicit killed $eflags + + bb.35: + %82:gr32 = LEA32r %12, 1, $noreg, 80, $noreg + JMP_1 %bb.38 + + bb.36.bb70: + successors: + + + bb.37.bb72: + %81:gr32_abcd = COPY %0 + %82:gr32 = COPY %0 + + bb.38.bb74: + successors: %bb.40(0x7fffffff), %bb.39(0x00000001) + + ADJCALLSTACKDOWN32 0, 0, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp + CALLpcrel32 @_Znwj, csr_32, implicit $esp, implicit $ssp, implicit-def $esp, implicit-def $ssp, implicit-def $eax + ADJCALLSTACKUP32 0, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp + %52:gr32 = COPY killed $eax + MOV32mr undef %53:gr32, 1, $noreg, 0, $noreg, %81 :: (store 4 into `%18** undef`) + MOV32mr %82, 1, $noreg, 0, $noreg, %52 :: (store 4 into %ir.tmp79) + ADJCALLSTACKDOWN32 0, 0, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp + CALLpcrel32 @_ZNSt3__127__tree_balance_after_insertIPNS_16__tree_node_baseIPvEEEEvT_S5_, csr_32, implicit $esp, implicit $ssp, implicit-def $esp, implicit-def $ssp + ADJCALLSTACKUP32 0, 0, implicit-def dead $esp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $esp, implicit $ssp + MOV32mi %52, 1, $noreg, 36, $noreg, @_ZN15COLLADASaxFWL1429ColladaParserAutoGen14Private14_end__commentsEv :: (store 4 into %ir.tmp81) + MOV32mr undef %54:gr32, 1, $noreg, 0, $noreg, %1 :: (store 4 into `%18** undef`) + %55:gr32 = MOV32rm %12, 1, $noreg, 140, $noreg :: (load 4 from %ir.3) + CMP32mi8 %55, 1, $noreg, 0, $noreg, 0, implicit-def $eflags :: (load 4 from %ir.tmp864) + JE_1 %bb.40, implicit killed $eflags + JMP_1 %bb.39 + + bb.39.bb89: + successors: + + + bb.40.bb90: + successors: %bb.42(0x00000001), %bb.41(0x7fffffff) + + %56:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %56.sub_8bit, %56.sub_8bit, implicit-def $eflags + JNE_1 %bb.42, implicit killed $eflags + JMP_1 %bb.41 + + bb.41.bb92: + successors: %bb.43(0x00000001), %bb.44(0x7fffffff) + + %58:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %58.sub_8bit, %58.sub_8bit, implicit-def $eflags + JNE_1 %bb.43, implicit killed $eflags + JMP_1 %bb.44 + + bb.42.bb94: + successors: + + + bb.43.bb96: + successors: + + + bb.44.bb97: + successors: %bb.45(0x00000001), %bb.46(0x7fffffff) + + %60:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %60.sub_8bit, %60.sub_8bit, implicit-def $eflags + JNE_1 %bb.46, implicit killed $eflags + JMP_1 %bb.45 + + bb.45.bb101: + successors: + + + bb.46.bb102: + successors: %bb.48(0x7fffffff), %bb.47(0x00000001) + + %62:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %62.sub_8bit, %62.sub_8bit, implicit-def $eflags + JNE_1 %bb.48, implicit killed $eflags + JMP_1 %bb.47 + + bb.47.bb103: + successors: + + + bb.48.bb104: + successors: %bb.50(0x7fffffff), %bb.49(0x00000001) + + %64:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %64.sub_8bit, %64.sub_8bit, implicit-def $eflags + JNE_1 %bb.50, implicit killed $eflags + JMP_1 %bb.49 + + bb.49.bb108: + successors: + + + bb.50.bb109: + successors: %bb.51(0x00000001), %bb.52(0x7fffffff) + + %66:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %66.sub_8bit, %66.sub_8bit, implicit-def $eflags + JNE_1 %bb.52, implicit killed $eflags + JMP_1 %bb.51 + + bb.51.bb111: + successors: + + + bb.52.bb112: + successors: %bb.54(0x7fffffff), %bb.53(0x00000001) + + %68:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %68.sub_8bit, %68.sub_8bit, implicit-def $eflags + JNE_1 %bb.54, implicit killed $eflags + JMP_1 %bb.53 + + bb.53.bb117: + successors: + + + bb.54.bb118: + successors: %bb.55(0x00000001), %bb.56(0x7fffffff) + + %70:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %70.sub_8bit, %70.sub_8bit, implicit-def $eflags + JNE_1 %bb.56, implicit killed $eflags + JMP_1 %bb.55 + + bb.55.bb120: + successors: + + + bb.56.bb121: + successors: %bb.57(0x00000001), %bb.58(0x7fffffff) + + %72:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %72.sub_8bit, %72.sub_8bit, implicit-def $eflags + JNE_1 %bb.58, implicit killed $eflags + JMP_1 %bb.57 + + bb.57.bb124: + successors: + + + bb.58.bb125: + successors: %bb.62(0x00000001), %bb.59(0x7fffffff) + + CMP32mi8 %0, 1, $noreg, 0, $noreg, 0, implicit-def $eflags :: (load 4 from %ir.4) + JE_1 %bb.62, implicit killed $eflags + JMP_1 %bb.59 + + bb.59.bb128: + + bb.60.bb129: + successors: %bb.60(0x7fffffff), %bb.61(0x00000001) + + CMP32ri undef %75:gr32, 95406325, implicit-def $eflags + JB_1 %bb.61, implicit killed $eflags + JMP_1 %bb.60 + + bb.61.bb133: + successors: + + + bb.62.bb135: + successors: %bb.63, %bb.64 + + %76:gr32_abcd = MOV32r0 implicit-def dead $eflags + TEST8rr %76.sub_8bit, %76.sub_8bit, implicit-def $eflags + JNE_1 %bb.64, implicit killed $eflags + JMP_1 %bb.63 + + bb.63.bb137: + successors: + + + bb.64.bb138: + +... From aaac4e0ac6eed4d0aeedafd8088b90b6180d7f0a Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Mon, 22 Apr 2019 21:24:13 +0000 Subject: [PATCH 211/274] Merging r354672: ------------------------------------------------------------------------ r354672 | petarj | 2019-02-22 06:53:58 -0800 (Fri, 22 Feb 2019) | 13 lines [mips][micromips] fix filling delay slots for PseudoIndirectBranch_MM Filling a delay slot in 32bit jump instructions with a 16bit instruction can cause issues. According to the documentation such an operation is unpredictable. This patch adds opcode Mips::PseudoIndirectBranch_MM alongside Mips::PseudoIndirectBranch and other instructions that are expanded to jr instruction and do not allow a 16bit instruction in their delay slots. Patch by Mirko Brkusanin. Differential Revision: https://reviews.llvm.org/D58507 ------------------------------------------------------------------------ llvm-svn: 358920 --- llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 1 + llvm/test/CodeGen/Mips/pseudo-jump-fill.ll | 68 ++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 llvm/test/CodeGen/Mips/pseudo-jump-fill.ll diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp index e3823e0dfdb8a..61e77fbeea6d3 100644 --- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -726,6 +726,7 @@ bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin, // but we don't have enough information to make that decision. if (InMicroMipsMode && TII->getInstSizeInBytes(*CurrI) == 2 && (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch || + Opcode == Mips::PseudoIndirectBranch_MM || Opcode == Mips::PseudoReturn || Opcode == Mips::TAILCALL)) continue; // Instructions LWP/SWP and MOVEP should not be in a delay slot as that diff --git a/llvm/test/CodeGen/Mips/pseudo-jump-fill.ll b/llvm/test/CodeGen/Mips/pseudo-jump-fill.ll new file mode 100644 index 0000000000000..31f077d57a933 --- /dev/null +++ b/llvm/test/CodeGen/Mips/pseudo-jump-fill.ll @@ -0,0 +1,68 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=mipsel-linux-gnu -mattr=+micromips -relocation-model=pic < %s | FileCheck %s + +; Test that the delay slot filler correctly handles indirect branches for +; microMIPS in regard to incorrectly using 16bit instructions in delay slots of +; 32bit instructions. + +define i32 @test(i32 signext %x, i32 signext %c) { +; CHECK-LABEL: test: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lui $2, %hi(_gp_disp) +; CHECK-NEXT: addiu $2, $2, %lo(_gp_disp) +; CHECK-NEXT: addiur2 $5, $5, -1 +; CHECK-NEXT: sltiu $1, $5, 4 +; CHECK-NEXT: beqz $1, $BB0_3 +; CHECK-NEXT: addu $3, $2, $25 +; CHECK-NEXT: $BB0_1: # %entry +; CHECK-NEXT: li16 $2, 0 +; CHECK-NEXT: sll16 $5, $5, 2 +; CHECK-NEXT: lw $6, %got($JTI0_0)($3) +; CHECK-NEXT: addu16 $5, $5, $6 +; CHECK-NEXT: lw $5, %lo($JTI0_0)($5) +; CHECK-NEXT: addu16 $3, $5, $3 +; CHECK-NEXT: jr $3 +; CHECK-NEXT: nop +; CHECK-NEXT: $BB0_2: # %sw.bb2 +; CHECK-NEXT: addiur2 $2, $4, 1 +; CHECK-NEXT: jrc $ra +; CHECK-NEXT: $BB0_3: +; CHECK-NEXT: move $2, $4 +; CHECK-NEXT: jrc $ra +; CHECK-NEXT: $BB0_4: # %sw.bb3 +; CHECK-NEXT: addius5 $4, 2 +; CHECK-NEXT: move $2, $4 +; CHECK-NEXT: jrc $ra +; CHECK-NEXT: $BB0_5: # %sw.bb5 +; CHECK-NEXT: addius5 $4, 3 +; CHECK-NEXT: move $2, $4 +; CHECK-NEXT: $BB0_6: # %for.cond.cleanup +; CHECK-NEXT: jrc $ra +entry: + switch i32 %c, label %sw.epilog [ + i32 4, label %sw.bb5 + i32 1, label %for.cond.cleanup + i32 2, label %sw.bb2 + i32 3, label %sw.bb3 + ] + +sw.bb2: + %add = add nsw i32 %x, 1 + br label %sw.epilog + +sw.bb3: + %add4 = add nsw i32 %x, 2 + br label %sw.epilog + +sw.bb5: + %add6 = add nsw i32 %x, 3 + br label %sw.epilog + +sw.epilog: + %a.0 = phi i32 [ %add6, %sw.bb5 ], [ %add4, %sw.bb3 ], [ %add, %sw.bb2 ], [ %x, %entry ] + br label %for.cond.cleanup + +for.cond.cleanup: + %a.028 = phi i32 [ %a.0, %sw.epilog ], [ 0, %entry ] + ret i32 %a.028 +} From 1cef8c2433394fe956f03166756e51a65d7263dc Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Mon, 22 Apr 2019 22:12:21 +0000 Subject: [PATCH 212/274] Merging r356198: ------------------------------------------------------------------------ r356198 | abataev | 2019-03-14 13:36:00 -0700 (Thu, 14 Mar 2019) | 5 lines [OPENMP]Fix crash for the ordered(n) clause. If the doacross lop construct is used and the loop counter is declare outside of the loop, the compiler might crash trying to get the address of the loop counter. Patch fixes this problem. ------------------------------------------------------------------------ llvm-svn: 358923 --- clang/lib/CodeGen/CGStmtOpenMP.cpp | 5 +++-- clang/lib/Sema/SemaOpenMP.cpp | 3 +-- clang/test/OpenMP/ordered_doacross_codegen.cpp | 13 ++++++++++++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index eb1304d89345e..44dc1cdee0b53 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -1518,8 +1518,9 @@ void CodeGenFunction::EmitOMPPrivateLoopCounters( I < E; ++I) { const auto *DRE = cast(C->getLoopCounter(I)); const auto *VD = cast(DRE->getDecl()); - // Override only those variables that are really emitted already. - if (LocalDeclMap.count(VD)) { + // Override only those variables that can be captured to avoid re-emission + // of the variables declared within the loops. + if (DRE->refersToEnclosingVariableOrCapture()) { (void)LoopScope.addPrivate(VD, [this, DRE, VD]() { return CreateMemTemp(DRE->getType(), VD->getName()); }); diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index aedec746af9e7..8a0be0c472de9 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -4602,8 +4602,7 @@ DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( Captures.insert(std::make_pair(LCRef, Ref)); return Ref; } - return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(), - DefaultLoc); + return cast(LCRef); } Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { diff --git a/clang/test/OpenMP/ordered_doacross_codegen.cpp b/clang/test/OpenMP/ordered_doacross_codegen.cpp index 2f19e9c2d5ef9..a3abf248d7617 100644 --- a/clang/test/OpenMP/ordered_doacross_codegen.cpp +++ b/clang/test/OpenMP/ordered_doacross_codegen.cpp @@ -16,6 +16,17 @@ extern int n; int a[10], b[10], c[10], d[10]; void foo(); +// CHECK-LABEL:bar +void bar() { + int i,j; +// CHECK: call void @__kmpc_doacross_init( +// CHECK: call void @__kmpc_doacross_fini( +#pragma omp parallel for ordered(2) + for (i = 0; i < n; ++i) + for (j = 0; j < n; ++j) + a[i] = b[i] + 1; +} + // CHECK-LABEL: @main() int main() { int i; @@ -35,7 +46,7 @@ int main() { // CHECK: call void @__kmpc_doacross_init([[IDENT]], i32 [[GTID]], i32 1, i8* [[CAST]]) // CHECK: call void @__kmpc_for_static_init_4( #pragma omp for ordered(1) - for (i = 0; i < n; ++i) { + for (int i = 0; i < n; ++i) { a[i] = b[i] + 1; foo(); // CHECK: invoke void [[FOO:.+]]( From 257c01056b206b845957c08ede4b28a9600ece45 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Mon, 22 Apr 2019 22:31:50 +0000 Subject: [PATCH 213/274] Merging r354808: ------------------------------------------------------------------------ r354808 | nikic | 2019-02-25 10:54:17 -0800 (Mon, 25 Feb 2019) | 11 lines [Mips] Fix missing masking in fast-isel of br (PR40325) Fixes https://bugs.llvm.org/show_bug.cgi?id=40325 by zero extending (and x, 1) the condition before branching on it. To avoid regressing trivial cases, I'm combining emission of cmp+br sequences for the single-use + same block case (similar to what we do in x86). icmpbr1.ll still regresses due to the cross-bb usage of the condition. Differential Revision: https://reviews.llvm.org/D58576 ------------------------------------------------------------------------ llvm-svn: 358925 --- llvm/lib/Target/Mips/MipsFastISel.cpp | 35 ++++++++++++++------- llvm/test/CodeGen/Mips/Fast-ISel/icmpbr1.ll | 3 +- llvm/test/CodeGen/Mips/Fast-ISel/pr40325.ll | 23 ++++++++++++++ 3 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 llvm/test/CodeGen/Mips/Fast-ISel/pr40325.ll diff --git a/llvm/lib/Target/Mips/MipsFastISel.cpp b/llvm/lib/Target/Mips/MipsFastISel.cpp index a18416b9e8610..168750b2cba93 100644 --- a/llvm/lib/Target/Mips/MipsFastISel.cpp +++ b/llvm/lib/Target/Mips/MipsFastISel.cpp @@ -954,21 +954,34 @@ bool MipsFastISel::selectBranch(const Instruction *I) { // MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)]; MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)]; - // For now, just try the simplest case where it's fed by a compare. + + // Fold the common case of a conditional branch with a comparison + // in the same block. + unsigned ZExtCondReg = 0; if (const CmpInst *CI = dyn_cast(BI->getCondition())) { - MVT CIMVT = - TLI.getValueType(DL, CI->getOperand(0)->getType(), true).getSimpleVT(); - if (CIMVT == MVT::i1) + if (CI->hasOneUse() && CI->getParent() == I->getParent()) { + ZExtCondReg = createResultReg(&Mips::GPR32RegClass); + if (!emitCmp(ZExtCondReg, CI)) + return false; + } + } + + // For the general case, we need to mask with 1. + if (ZExtCondReg == 0) { + unsigned CondReg = getRegForValue(BI->getCondition()); + if (CondReg == 0) return false; - unsigned CondReg = getRegForValue(CI); - BuildMI(*BrBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::BGTZ)) - .addReg(CondReg) - .addMBB(TBB); - finishCondBranch(BI->getParent(), TBB, FBB); - return true; + ZExtCondReg = emitIntExt(MVT::i1, CondReg, MVT::i32, true); + if (ZExtCondReg == 0) + return false; } - return false; + + BuildMI(*BrBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::BGTZ)) + .addReg(ZExtCondReg) + .addMBB(TBB); + finishCondBranch(BI->getParent(), TBB, FBB); + return true; } bool MipsFastISel::selectCmp(const Instruction *I) { diff --git a/llvm/test/CodeGen/Mips/Fast-ISel/icmpbr1.ll b/llvm/test/CodeGen/Mips/Fast-ISel/icmpbr1.ll index ef8e1c2b0140c..e44ab36532c5b 100644 --- a/llvm/test/CodeGen/Mips/Fast-ISel/icmpbr1.ll +++ b/llvm/test/CodeGen/Mips/Fast-ISel/icmpbr1.ll @@ -17,7 +17,8 @@ bb0: bb1: ; CHECK: # %bb.1: # %bb1 ; CHECK-NEXT: lw $[[REG2:[0-9]+]], [[SPILL]]($sp) # 4-byte Folded Reload -; CHECK-NEXT: bgtz $[[REG2]], $BB0_3 +; CHECK-NEXT: andi $[[REG3:[0-9]+]], $[[REG2]], 1 +; CHECK-NEXT: bgtz $[[REG3]], $BB0_3 br i1 %2, label %bb2, label %bb3 bb2: ; CHECK: $BB0_3: # %bb2 diff --git a/llvm/test/CodeGen/Mips/Fast-ISel/pr40325.ll b/llvm/test/CodeGen/Mips/Fast-ISel/pr40325.ll new file mode 100644 index 0000000000000..a9ce70fe8afc5 --- /dev/null +++ b/llvm/test/CodeGen/Mips/Fast-ISel/pr40325.ll @@ -0,0 +1,23 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=mipsel -relocation-model=pic -O0 -mcpu=mips32 < %s | FileCheck %s + +define void @test(i32 %x, i1* %p) nounwind { +; CHECK-LABEL: test: +; CHECK: # %bb.0: +; CHECK-NEXT: move $1, $4 +; CHECK-NEXT: andi $4, $4, 1 +; CHECK-NEXT: sb $4, 0($5) +; CHECK-NEXT: andi $1, $1, 1 +; CHECK-NEXT: bgtz $1, $BB0_1 +; CHECK-NEXT: nop +; CHECK-NEXT: # %bb.1: # %foo +; CHECK-NEXT: jr $ra +; CHECK-NEXT: nop + %y = and i32 %x, 1 + %c = icmp eq i32 %y, 1 + store i1 %c, i1* %p + br i1 %c, label %foo, label %foo + +foo: + ret void +} From 25b6e82d72b16eec9dcda583b4db5e2973f23ad6 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Mon, 22 Apr 2019 22:57:01 +0000 Subject: [PATCH 214/274] Merging r354882: ------------------------------------------------------------------------ r354882 | atanasyan | 2019-02-26 06:45:17 -0800 (Tue, 26 Feb 2019) | 4 lines [mips] Emit `.module softfloat` directive This change fixes crash on an assertion in case of using `soft float` ABI for mips32r6 target. ------------------------------------------------------------------------ llvm-svn: 358934 --- llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp | 7 +++++-- llvm/lib/Target/Mips/MipsAsmPrinter.cpp | 3 ++- llvm/test/CodeGen/Mips/abiflags32.ll | 8 ++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 58f9717e1cc61..a46f84bd1c9cb 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -700,8 +700,11 @@ void MipsTargetAsmStreamer::emitDirectiveCpreturn(unsigned SaveLocation, } void MipsTargetAsmStreamer::emitDirectiveModuleFP() { - OS << "\t.module\tfp="; - OS << ABIFlagsSection.getFpABIString(ABIFlagsSection.getFpABI()) << "\n"; + MipsABIFlagsSection::FpABIKind FpABI = ABIFlagsSection.getFpABI(); + if (FpABI == MipsABIFlagsSection::FpABIKind::SOFT) + OS << "\t.module\tsoftfloat\n"; + else + OS << "\t.module\tfp=" << ABIFlagsSection.getFpABIString(FpABI) << "\n"; } void MipsTargetAsmStreamer::emitDirectiveSetFp( diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp index a7a748b0840e1..c35f5beb68804 100644 --- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp @@ -813,7 +813,8 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) { // We should always emit a '.module fp=...' but binutils 2.24 does not accept // it. We therefore emit it when it contradicts the ABI defaults (-mfpxx or // -mfp64) and omit it otherwise. - if (ABI.IsO32() && (STI.isABI_FPXX() || STI.isFP64bit())) + if ((ABI.IsO32() && (STI.isABI_FPXX() || STI.isFP64bit())) || + STI.useSoftFloat()) TS.emitDirectiveModuleFP(); // We should always emit a '.module [no]oddspreg' but binutils 2.24 does not diff --git a/llvm/test/CodeGen/Mips/abiflags32.ll b/llvm/test/CodeGen/Mips/abiflags32.ll index 39e2a90151e3e..65201ec03814d 100644 --- a/llvm/test/CodeGen/Mips/abiflags32.ll +++ b/llvm/test/CodeGen/Mips/abiflags32.ll @@ -1,6 +1,12 @@ ; RUN: llc -filetype=asm -mtriple mipsel-unknown-linux -mcpu=mips32 %s -o - | FileCheck %s ; RUN: llc -filetype=asm -mtriple mipsel-unknown-linux -mcpu=mips32 -mattr=fp64 %s -o - | FileCheck -check-prefix=CHECK-64 %s ; RUN: llc -filetype=asm -mtriple mipsel-unknown-linux -mcpu=mips64 -target-abi n32 %s -o - | FileCheck -check-prefix=CHECK-64n %s +; RUN: llc -filetype=asm -mtriple mipsel-unknown-linux -mcpu=mips32 \ +; RUN: -mattr=soft-float %s -o - | FileCheck -check-prefix=SOFT %s +; RUN: llc -filetype=asm -mtriple mipsel-unknown-linux -mcpu=mips32r6 \ +; RUN: -mattr=soft-float %s -o - | FileCheck -check-prefix=SOFT %s +; RUN: llc -filetype=asm -mtriple mipsel-unknown-linux -mcpu=mips64 \ +; RUN: -mattr=soft-float -target-abi n64 %s -o - | FileCheck -check-prefix=SOFT %s ; CHECK: .nan legacy ; We don't emit '.module fp=32' for compatibility with binutils 2.24 which @@ -15,3 +21,5 @@ ; We don't emit '.module fp=64' for compatibility with binutils 2.24 which ; doesn't accept .module. ; CHECK-64n-NOT: .module fp=64 + +; SOFT: .module softfloat From 047302e0421983914e90efdf6bbaeba60a653803 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Mon, 22 Apr 2019 23:47:28 +0000 Subject: [PATCH 215/274] Merging r355825: ------------------------------------------------------------------------ r355825 | petarj | 2019-03-11 07:13:31 -0700 (Mon, 11 Mar 2019) | 10 lines [MIPS][microMIPS] Add a pattern to match TruncIntFP A pattern needed to match TruncIntFP was missing. This was causing multiple tests from llvm test suite to fail during compilation for micromips. Patch by Mirko Brkusanin. Differential Revision: https://reviews.llvm.org/D58722 ------------------------------------------------------------------------ llvm-svn: 358936 --- .../lib/Target/Mips/MicroMips32r6InstrInfo.td | 4 +- llvm/lib/Target/Mips/MicroMipsInstrFPU.td | 5 + llvm/test/CodeGen/Mips/llvm-ir/fptosi.ll | 418 ++++++++++++++++++ 3 files changed, 426 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/Mips/llvm-ir/fptosi.ll diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td index c441aa76ad40f..994a8882f9425 100644 --- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -1040,7 +1040,7 @@ class TRUNC_L_D_MMR6_DESC : ABSS_FT_MMR6_DESC_BASE<"trunc.l.d", FGR64Opnd, class TRUNC_W_S_MMR6_DESC : ABSS_FT_MMR6_DESC_BASE<"trunc.w.s", FGR32Opnd, FGR32Opnd, II_TRUNC>; class TRUNC_W_D_MMR6_DESC : ABSS_FT_MMR6_DESC_BASE<"trunc.w.d", FGR32Opnd, - AFGR64Opnd, II_TRUNC>; + FGR64Opnd, II_TRUNC>; class SQRT_S_MMR6_DESC : ABSS_FT_MMR6_DESC_BASE<"sqrt.s", FGR32Opnd, FGR32Opnd, II_SQRT_S, fsqrt>; class SQRT_D_MMR6_DESC : ABSS_FT_MMR6_DESC_BASE<"sqrt.d", AFGR64Opnd, AFGR64Opnd, @@ -1750,6 +1750,8 @@ def : MipsPat<(f32 fpimm0), (MTC1_MMR6 ZERO)>, ISA_MICROMIPS32R6; def : MipsPat<(f32 fpimm0neg), (FNEG_S_MMR6 (MTC1_MMR6 ZERO))>, ISA_MICROMIPS32R6; def : MipsPat<(MipsTruncIntFP FGR64Opnd:$src), (TRUNC_W_D_MMR6 FGR64Opnd:$src)>, ISA_MICROMIPS32R6; +def : MipsPat<(MipsTruncIntFP FGR32Opnd:$src), + (TRUNC_W_S_MMR6 FGR32Opnd:$src)>, ISA_MICROMIPS32R6; def : MipsPat<(and GPRMM16:$src, immZExtAndi16:$imm), (ANDI16_MMR6 GPRMM16:$src, immZExtAndi16:$imm)>, diff --git a/llvm/lib/Target/Mips/MicroMipsInstrFPU.td b/llvm/lib/Target/Mips/MicroMipsInstrFPU.td index 1731afc1961f8..9e76165e7ad71 100644 --- a/llvm/lib/Target/Mips/MicroMipsInstrFPU.td +++ b/llvm/lib/Target/Mips/MicroMipsInstrFPU.td @@ -425,6 +425,11 @@ def : MipsPat<(f64 (fpextend FGR32Opnd:$src)), def : MipsPat<(MipsTruncIntFP AFGR64Opnd:$src), (TRUNC_W_MM AFGR64Opnd:$src)>, ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32; +def : MipsPat<(MipsTruncIntFP FGR64Opnd:$src), + (CVT_W_D64_MM FGR64Opnd:$src)>, ISA_MICROMIPS32_NOT_MIPS32R6, + FGR_64; +def : MipsPat<(MipsTruncIntFP FGR32Opnd:$src), + (TRUNC_W_S_MM FGR32Opnd:$src)>, ISA_MICROMIPS32_NOT_MIPS32R6; // Selects defm : MovzPats0, diff --git a/llvm/test/CodeGen/Mips/llvm-ir/fptosi.ll b/llvm/test/CodeGen/Mips/llvm-ir/fptosi.ll new file mode 100644 index 0000000000000..03a0de7466452 --- /dev/null +++ b/llvm/test/CodeGen/Mips/llvm-ir/fptosi.ll @@ -0,0 +1,418 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=mips-linux-gnu -mcpu=mips32 -asm-show-inst |\ +; RUN: FileCheck %s -check-prefixes=M32 +; RUN: llc < %s -mtriple=mips-linux-gnu -mcpu=mips32r2 -asm-show-inst |\ +; RUN: FileCheck %s -check-prefixes=M32 +; RUN: llc < %s -mtriple=mips-linux-gnu -mcpu=mips32r2 -mattr=+fp64 -asm-show-inst |\ +; RUN: FileCheck %s -check-prefixes=M32R2-FP64 +; RUN: llc < %s -mtriple=mips-linux-gnu -mcpu=mips32r2 -mattr=+soft-float -asm-show-inst |\ +; RUN: FileCheck %s -check-prefixes=M32R2-SF +; RUN: llc < %s -mtriple=mips-linux-gnu -mcpu=mips32r3 -asm-show-inst |\ +; RUN: FileCheck %s -check-prefixes=M32R3R5 +; RUN: llc < %s -mtriple=mips-linux-gnu -mcpu=mips32r5 -asm-show-inst |\ +; RUN: FileCheck %s -check-prefixes=M32R3R5 +; RUN: llc < %s -mtriple=mips-linux-gnu -mcpu=mips32r6 -asm-show-inst |\ +; RUN: FileCheck %s -check-prefixes=M32R6 +; RUN: llc < %s -mtriple=mips64-linux-gnu -mcpu=mips3 -asm-show-inst |\ +; RUN: FileCheck %s -check-prefixes=M64 +; RUN: llc < %s -mtriple=mips64-linux-gnu -mcpu=mips64 -asm-show-inst |\ +; RUN: FileCheck %s -check-prefixes=M64 +; RUN: llc < %s -mtriple=mips64-linux-gnu -mcpu=mips64r2 -asm-show-inst |\ +; RUN: FileCheck %s -check-prefixes=M64 +; RUN: llc < %s -mtriple=mips64-linux-gnu -mcpu=mips64r6 -asm-show-inst |\ +; RUN: FileCheck %s -check-prefixes=M64R6 +; RUN: llc < %s -mtriple=mips-linux-gnu -mcpu=mips32r2 -mattr=+micromips -asm-show-inst |\ +; RUN: FileCheck %s -check-prefixes=MMR2-FP32 +; RUN: llc < %s -mtriple=mips-linux-gnu -mcpu=mips32r2 -mattr=+micromips,fp64 -asm-show-inst |\ +; RUN: FileCheck %s -check-prefixes=MMR2-FP64 +; RUN: llc < %s -mtriple=mips-linux-gnu -mcpu=mips32r2 -mattr=+micromips,soft-float -asm-show-inst |\ +; RUN: FileCheck %s -check-prefixes=MMR2-SF +; RUN: llc < %s -mtriple=mips-linux-gnu -mcpu=mips32r6 -mattr=+micromips -asm-show-inst |\ +; RUN: FileCheck %s -check-prefixes=MMR6 +; RUN: llc < %s -mtriple=mips-linux-gnu -mcpu=mips32r6 -mattr=+micromips,soft-float -asm-show-inst |\ +; RUN: FileCheck %s -check-prefixes=MMR6-SF + +; Test that fptosi can be matched for MIPS targets for various FPU +; configurations + +define i32 @test1(float %t) { +; M32-LABEL: test1: +; M32: # %bb.0: # %entry +; M32-NEXT: trunc.w.s $f0, $f12 # +; M32-NEXT: # > +; M32-NEXT: jr $ra # > +; M32-NEXT: mfc1 $2, $f0 # +; M32-NEXT: # > +; +; M32R2-FP64-LABEL: test1: +; M32R2-FP64: # %bb.0: # %entry +; M32R2-FP64-NEXT: trunc.w.s $f0, $f12 # +; M32R2-FP64-NEXT: # > +; M32R2-FP64-NEXT: jr $ra # > +; M32R2-FP64-NEXT: mfc1 $2, $f0 # +; M32R2-FP64-NEXT: # > +; +; M32R2-SF-LABEL: test1: +; M32R2-SF: # %bb.0: # %entry +; M32R2-SF-NEXT: addiu $sp, $sp, -24 # +; M32R2-SF-NEXT: # +; M32R2-SF-NEXT: # > +; M32R2-SF-NEXT: .cfi_def_cfa_offset 24 +; M32R2-SF-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill +; M32R2-SF-NEXT: # +; M32R2-SF-NEXT: # +; M32R2-SF-NEXT: # > +; M32R2-SF-NEXT: .cfi_offset 31, -4 +; M32R2-SF-NEXT: jal __fixsfsi # > +; M32R2-SF-NEXT: nop # +; M32R2-SF-NEXT: # +; M32R2-SF-NEXT: # > +; M32R2-SF-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload +; M32R2-SF-NEXT: # +; M32R2-SF-NEXT: # +; M32R2-SF-NEXT: # > +; M32R2-SF-NEXT: jr $ra # > +; M32R2-SF-NEXT: addiu $sp, $sp, 24 # +; M32R2-SF-NEXT: # +; M32R2-SF-NEXT: # > +; +; M32R3R5-LABEL: test1: +; M32R3R5: # %bb.0: # %entry +; M32R3R5-NEXT: trunc.w.s $f0, $f12 # +; M32R3R5-NEXT: # > +; M32R3R5-NEXT: jr $ra # > +; M32R3R5-NEXT: mfc1 $2, $f0 # +; M32R3R5-NEXT: # > +; +; M32R6-LABEL: test1: +; M32R6: # %bb.0: # %entry +; M32R6-NEXT: trunc.w.s $f0, $f12 # +; M32R6-NEXT: # > +; M32R6-NEXT: jr $ra # +; M32R6-NEXT: # > +; M32R6-NEXT: mfc1 $2, $f0 # +; M32R6-NEXT: # > +; +; M64-LABEL: test1: +; M64: # %bb.0: # %entry +; M64-NEXT: trunc.w.s $f0, $f12 # +; M64-NEXT: # > +; M64-NEXT: jr $ra # > +; M64-NEXT: mfc1 $2, $f0 # +; M64-NEXT: # > +; +; M64R6-LABEL: test1: +; M64R6: # %bb.0: # %entry +; M64R6-NEXT: trunc.w.s $f0, $f12 # +; M64R6-NEXT: # > +; M64R6-NEXT: jr $ra # +; M64R6-NEXT: # > +; M64R6-NEXT: mfc1 $2, $f0 # +; M64R6-NEXT: # > +; +; MMR2-FP32-LABEL: test1: +; MMR2-FP32: # %bb.0: # %entry +; MMR2-FP32-NEXT: trunc.w.s $f0, $f12 # +; MMR2-FP32-NEXT: # > +; MMR2-FP32-NEXT: jr $ra # > +; MMR2-FP32-NEXT: mfc1 $2, $f0 # +; MMR2-FP32-NEXT: # > +; +; MMR2-FP64-LABEL: test1: +; MMR2-FP64: # %bb.0: # %entry +; MMR2-FP64-NEXT: trunc.w.s $f0, $f12 # +; MMR2-FP64-NEXT: # > +; MMR2-FP64-NEXT: jr $ra # > +; MMR2-FP64-NEXT: mfc1 $2, $f0 # +; MMR2-FP64-NEXT: # > +; +; MMR2-SF-LABEL: test1: +; MMR2-SF: # %bb.0: # %entry +; MMR2-SF-NEXT: addiusp -24 # > +; MMR2-SF-NEXT: .cfi_def_cfa_offset 24 +; MMR2-SF-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill +; MMR2-SF-NEXT: # +; MMR2-SF-NEXT: # +; MMR2-SF-NEXT: # > +; MMR2-SF-NEXT: .cfi_offset 31, -4 +; MMR2-SF-NEXT: jal __fixsfsi # > +; MMR2-SF-NEXT: nop # +; MMR2-SF-NEXT: # +; MMR2-SF-NEXT: # > +; MMR2-SF-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload +; MMR2-SF-NEXT: # +; MMR2-SF-NEXT: # +; MMR2-SF-NEXT: # > +; MMR2-SF-NEXT: addiusp 24 # > +; MMR2-SF-NEXT: jrc $ra # > +; +; MMR6-LABEL: test1: +; MMR6: # %bb.0: # %entry +; MMR6-NEXT: trunc.w.s $f0, $f12 # +; MMR6-NEXT: # > +; MMR6-NEXT: mfc1 $2, $f0 # +; MMR6-NEXT: # > +; MMR6-NEXT: jrc $ra # > +; +; MMR6-SF-LABEL: test1: +; MMR6-SF: # %bb.0: # %entry +; MMR6-SF-NEXT: addiu $sp, $sp, -24 # +; MMR6-SF-NEXT: # +; MMR6-SF-NEXT: # > +; MMR6-SF-NEXT: .cfi_def_cfa_offset 24 +; MMR6-SF-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill +; MMR6-SF-NEXT: # +; MMR6-SF-NEXT: # +; MMR6-SF-NEXT: # > +; MMR6-SF-NEXT: .cfi_offset 31, -4 +; MMR6-SF-NEXT: jalr __fixsfsi # > +; MMR6-SF-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload +; MMR6-SF-NEXT: # +; MMR6-SF-NEXT: # +; MMR6-SF-NEXT: # > +; MMR6-SF-NEXT: addiu $sp, $sp, 24 # +; MMR6-SF-NEXT: # +; MMR6-SF-NEXT: # > +; MMR6-SF-NEXT: jrc $ra # > +entry: + %conv = fptosi float %t to i32 + ret i32 %conv +} + +define i32 @test2(double %t) { +; M32-LABEL: test2: +; M32: # %bb.0: # %entry +; M32-NEXT: trunc.w.d $f0, $f12 # +; M32-NEXT: # > +; M32-NEXT: jr $ra # > +; M32-NEXT: mfc1 $2, $f0 # +; M32-NEXT: # > +; +; M32R2-FP64-LABEL: test2: +; M32R2-FP64: # %bb.0: # %entry +; M32R2-FP64-NEXT: trunc.w.d $f0, $f12 # +; M32R2-FP64-NEXT: # > +; M32R2-FP64-NEXT: jr $ra # > +; M32R2-FP64-NEXT: mfc1 $2, $f0 # +; M32R2-FP64-NEXT: # > +; +; M32R2-SF-LABEL: test2: +; M32R2-SF: # %bb.0: # %entry +; M32R2-SF-NEXT: addiu $sp, $sp, -24 # +; M32R2-SF-NEXT: # +; M32R2-SF-NEXT: # > +; M32R2-SF-NEXT: .cfi_def_cfa_offset 24 +; M32R2-SF-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill +; M32R2-SF-NEXT: # +; M32R2-SF-NEXT: # +; M32R2-SF-NEXT: # > +; M32R2-SF-NEXT: .cfi_offset 31, -4 +; M32R2-SF-NEXT: jal __fixdfsi # > +; M32R2-SF-NEXT: nop # +; M32R2-SF-NEXT: # +; M32R2-SF-NEXT: # > +; M32R2-SF-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload +; M32R2-SF-NEXT: # +; M32R2-SF-NEXT: # +; M32R2-SF-NEXT: # > +; M32R2-SF-NEXT: jr $ra # > +; M32R2-SF-NEXT: addiu $sp, $sp, 24 # +; M32R2-SF-NEXT: # +; M32R2-SF-NEXT: # > +; +; M32R3R5-LABEL: test2: +; M32R3R5: # %bb.0: # %entry +; M32R3R5-NEXT: trunc.w.d $f0, $f12 # +; M32R3R5-NEXT: # > +; M32R3R5-NEXT: jr $ra # > +; M32R3R5-NEXT: mfc1 $2, $f0 # +; M32R3R5-NEXT: # > +; +; M32R6-LABEL: test2: +; M32R6: # %bb.0: # %entry +; M32R6-NEXT: trunc.w.d $f0, $f12 # +; M32R6-NEXT: # > +; M32R6-NEXT: jr $ra # +; M32R6-NEXT: # > +; M32R6-NEXT: mfc1 $2, $f0 # +; M32R6-NEXT: # > +; +; M64-LABEL: test2: +; M64: # %bb.0: # %entry +; M64-NEXT: trunc.w.d $f0, $f12 # +; M64-NEXT: # > +; M64-NEXT: jr $ra # > +; M64-NEXT: mfc1 $2, $f0 # +; M64-NEXT: # > +; +; M64R6-LABEL: test2: +; M64R6: # %bb.0: # %entry +; M64R6-NEXT: trunc.w.d $f0, $f12 # +; M64R6-NEXT: # > +; M64R6-NEXT: jr $ra # +; M64R6-NEXT: # > +; M64R6-NEXT: mfc1 $2, $f0 # +; M64R6-NEXT: # > +; +; MMR2-FP32-LABEL: test2: +; MMR2-FP32: # %bb.0: # %entry +; MMR2-FP32-NEXT: trunc.w.d $f0, $f12 # +; MMR2-FP32-NEXT: # > +; MMR2-FP32-NEXT: jr $ra # > +; MMR2-FP32-NEXT: mfc1 $2, $f0 # +; MMR2-FP32-NEXT: # > +; +; MMR2-FP64-LABEL: test2: +; MMR2-FP64: # %bb.0: # %entry +; MMR2-FP64-NEXT: cvt.w.d $f0, $f12 # +; MMR2-FP64-NEXT: # > +; MMR2-FP64-NEXT: jr $ra # > +; MMR2-FP64-NEXT: mfc1 $2, $f0 # +; MMR2-FP64-NEXT: # > +; +; MMR2-SF-LABEL: test2: +; MMR2-SF: # %bb.0: # %entry +; MMR2-SF-NEXT: addiusp -24 # > +; MMR2-SF-NEXT: .cfi_def_cfa_offset 24 +; MMR2-SF-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill +; MMR2-SF-NEXT: # +; MMR2-SF-NEXT: # +; MMR2-SF-NEXT: # > +; MMR2-SF-NEXT: .cfi_offset 31, -4 +; MMR2-SF-NEXT: jal __fixdfsi # > +; MMR2-SF-NEXT: nop # +; MMR2-SF-NEXT: # +; MMR2-SF-NEXT: # > +; MMR2-SF-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload +; MMR2-SF-NEXT: # +; MMR2-SF-NEXT: # +; MMR2-SF-NEXT: # > +; MMR2-SF-NEXT: addiusp 24 # > +; MMR2-SF-NEXT: jrc $ra # > +; +; MMR6-LABEL: test2: +; MMR6: # %bb.0: # %entry +; MMR6-NEXT: trunc.w.d $f0, $f12 # +; MMR6-NEXT: # > +; MMR6-NEXT: mfc1 $2, $f0 # +; MMR6-NEXT: # > +; MMR6-NEXT: jrc $ra # > +; +; MMR6-SF-LABEL: test2: +; MMR6-SF: # %bb.0: # %entry +; MMR6-SF-NEXT: addiu $sp, $sp, -24 # +; MMR6-SF-NEXT: # +; MMR6-SF-NEXT: # > +; MMR6-SF-NEXT: .cfi_def_cfa_offset 24 +; MMR6-SF-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill +; MMR6-SF-NEXT: # +; MMR6-SF-NEXT: # +; MMR6-SF-NEXT: # > +; MMR6-SF-NEXT: .cfi_offset 31, -4 +; MMR6-SF-NEXT: jalr __fixdfsi # > +; MMR6-SF-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload +; MMR6-SF-NEXT: # +; MMR6-SF-NEXT: # +; MMR6-SF-NEXT: # > +; MMR6-SF-NEXT: addiu $sp, $sp, 24 # +; MMR6-SF-NEXT: # +; MMR6-SF-NEXT: # > +; MMR6-SF-NEXT: jrc $ra # > +entry: + %conv = fptosi double %t to i32 + ret i32 %conv +} From 1ff9bed88583ff62fefe75483891b2c51dd2d11b Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Tue, 23 Apr 2019 02:28:49 +0000 Subject: [PATCH 216/274] Merging r356039: ------------------------------------------------------------------------ r356039 | atanasyan | 2019-03-13 04:04:38 -0700 (Wed, 13 Mar 2019) | 11 lines [MIPS][microMIPS] Fix PseudoMTLOHI_MM matching and expansion On micromips MipsMTLOHI is always matched to PseudoMTLOHI_DSP regardless of +dsp argument. This patch checks is HasDSP predicate is present for PseudoMTLOHI_DSP so PseudoMTLOHI_MM can be matched when appropriate. Add expansion of PseudoMTLOHI_MM instruction into a mtlo/mthi pair. Patch by Mirko Brkusanin. Differential Revision: http://reviews.llvm.org/D59203 ------------------------------------------------------------------------ llvm-svn: 358941 --- llvm/lib/Target/Mips/MipsDSPInstrInfo.td | 4 +- llvm/lib/Target/Mips/MipsSEInstrInfo.cpp | 3 + .../Mips/micromips-pseudo-mtlohi-expand.ll | 63 +++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/Mips/micromips-pseudo-mtlohi-expand.ll diff --git a/llvm/lib/Target/Mips/MipsDSPInstrInfo.td b/llvm/lib/Target/Mips/MipsDSPInstrInfo.td index b9824220b5580..a4078026e4f9f 100644 --- a/llvm/lib/Target/Mips/MipsDSPInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsDSPInstrInfo.td @@ -1314,7 +1314,9 @@ def PseudoCMPU_LE_QB : PseudoCMP; def PseudoPICK_PH : PseudoPICK; def PseudoPICK_QB : PseudoPICK; -def PseudoMTLOHI_DSP : PseudoMTLOHI; +let AdditionalPredicates = [HasDSP] in { + def PseudoMTLOHI_DSP : PseudoMTLOHI; +} // Patterns. class DSPPat : diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp index c7ab90ed2a3ba..2b26caaa9f49c 100644 --- a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp +++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp @@ -447,6 +447,9 @@ bool MipsSEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { case Mips::PseudoMTLOHI_DSP: expandPseudoMTLoHi(MBB, MI, Mips::MTLO_DSP, Mips::MTHI_DSP, true); break; + case Mips::PseudoMTLOHI_MM: + expandPseudoMTLoHi(MBB, MI, Mips::MTLO_MM, Mips::MTHI_MM, false); + break; case Mips::PseudoCVT_S_W: expandCvtFPInt(MBB, MI, Mips::CVT_S_W, Mips::MTC1, false); break; diff --git a/llvm/test/CodeGen/Mips/micromips-pseudo-mtlohi-expand.ll b/llvm/test/CodeGen/Mips/micromips-pseudo-mtlohi-expand.ll new file mode 100644 index 0000000000000..3f86bd24f34ff --- /dev/null +++ b/llvm/test/CodeGen/Mips/micromips-pseudo-mtlohi-expand.ll @@ -0,0 +1,63 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips32r2 -mattr=+micromips -asm-show-inst < %s |\ +; RUN: FileCheck %s -check-prefixes=MMR2 +; RUN: llc -mtriple=mipsel-linux-gnu -mcpu=mips32r2 -mattr=+dsp,+micromips -asm-show-inst < %s |\ +; RUN: FileCheck %s -check-prefixes=MMR2-DSP + +define i64 @test(i32 signext %a, i32 signext %b) { +; MMR2-LABEL: test: +; MMR2: # %bb.0: # %entry +; MMR2-NEXT: li16 $2, 0 # +; MMR2-NEXT: # > +; MMR2-NEXT: li16 $3, 1 # +; MMR2-NEXT: # > +; MMR2-NEXT: mtlo $3 # > +; MMR2-NEXT: mthi $2 # > +; MMR2-NEXT: madd $4, $5 # +; MMR2-NEXT: # > +; MMR2-NEXT: mflo16 $2 # > +; MMR2-NEXT: mfhi16 $3 # > +; MMR2-NEXT: jrc $ra # > +; +; MMR2-DSP-LABEL: test: +; MMR2-DSP: # %bb.0: # %entry +; MMR2-DSP-NEXT: li16 $2, 0 # +; MMR2-DSP-NEXT: # > +; MMR2-DSP-NEXT: li16 $3, 1 # +; MMR2-DSP-NEXT: # > +; MMR2-DSP-NEXT: mtlo $3, $ac0 # +; MMR2-DSP-NEXT: # > +; MMR2-DSP-NEXT: mthi $2, $ac0 # +; MMR2-DSP-NEXT: # > +; MMR2-DSP-NEXT: madd $ac0, $4, $5 # +; MMR2-DSP-NEXT: # +; MMR2-DSP-NEXT: # +; MMR2-DSP-NEXT: # > +; MMR2-DSP-NEXT: mflo $2, $ac0 # +; MMR2-DSP-NEXT: # > +; MMR2-DSP-NEXT: jr $ra # > +; MMR2-DSP-NEXT: mfhi $3, $ac0 # +; MMR2-DSP-NEXT: # > +entry: + %conv = sext i32 %a to i64 + %conv1 = sext i32 %b to i64 + %mul = mul nsw i64 %conv, %conv1 + %add = add nsw i64 %mul, 1 + ret i64 %add +} From 7aa4dc9458ae0ad3d8b23a65fc9ddcd094853169 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Tue, 23 Apr 2019 03:32:01 +0000 Subject: [PATCH 217/274] Merging r357506: ------------------------------------------------------------------------ r357506 | atanasyan | 2019-04-02 11:03:31 -0700 (Tue, 02 Apr 2019) | 7 lines [driver][mips] Check both `gnuabi64` and `gnu` suffixes in `getMultiarchTriple` In case of N64 ABI toolchain paths migth have `mips-linux-gnuabi64` or `mips-linux-gnu` directory regardless of selected environment. Check both variants while detecting a multiarch triple. Fix for the bug https://bugs.llvm.org/show_bug.cgi?id=41204 ------------------------------------------------------------------------ llvm-svn: 358947 --- clang/lib/Driver/ToolChains/Linux.cpp | 33 +++++++++++++++------------ clang/test/Driver/linux-ld.c | 10 ++++++++ 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index 65ab9b2daf549..dfdfb18319abe 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -45,6 +45,7 @@ static std::string getMultiarchTriple(const Driver &D, TargetTriple.getEnvironment(); bool IsAndroid = TargetTriple.isAndroid(); bool IsMipsR6 = TargetTriple.getSubArch() == llvm::Triple::MipsSubArch_r6; + bool IsMipsN32Abi = TargetTriple.getEnvironment() == llvm::Triple::GNUABIN32; // For most architectures, just use whatever we have rather than trying to be // clever. @@ -103,33 +104,37 @@ static std::string getMultiarchTriple(const Driver &D, return "aarch64_be-linux-gnu"; break; case llvm::Triple::mips: { - std::string Arch = IsMipsR6 ? "mipsisa32r6" : "mips"; - if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-gnu")) - return Arch + "-linux-gnu"; + std::string MT = IsMipsR6 ? "mipsisa32r6-linux-gnu" : "mips-linux-gnu"; + if (D.getVFS().exists(SysRoot + "/lib/" + MT)) + return MT; break; } case llvm::Triple::mipsel: { if (IsAndroid) return "mipsel-linux-android"; - std::string Arch = IsMipsR6 ? "mipsisa32r6el" : "mipsel"; - if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-gnu")) - return Arch + "-linux-gnu"; + std::string MT = IsMipsR6 ? "mipsisa32r6el-linux-gnu" : "mipsel-linux-gnu"; + if (D.getVFS().exists(SysRoot + "/lib/" + MT)) + return MT; break; } case llvm::Triple::mips64: { - std::string Arch = IsMipsR6 ? "mipsisa64r6" : "mips64"; - std::string ABI = llvm::Triple::getEnvironmentTypeName(TargetEnvironment); - if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-" + ABI)) - return Arch + "-linux-" + ABI; + std::string MT = std::string(IsMipsR6 ? "mipsisa64r6" : "mips64") + + "-linux-" + (IsMipsN32Abi ? "gnuabin32" : "gnuabi64"); + if (D.getVFS().exists(SysRoot + "/lib/" + MT)) + return MT; + if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnu")) + return "mips64-linux-gnu"; break; } case llvm::Triple::mips64el: { if (IsAndroid) return "mips64el-linux-android"; - std::string Arch = IsMipsR6 ? "mipsisa64r6el" : "mips64el"; - std::string ABI = llvm::Triple::getEnvironmentTypeName(TargetEnvironment); - if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-" + ABI)) - return Arch + "-linux-" + ABI; + std::string MT = std::string(IsMipsR6 ? "mipsisa64r6el" : "mips64el") + + "-linux-" + (IsMipsN32Abi ? "gnuabin32" : "gnuabi64"); + if (D.getVFS().exists(SysRoot + "/lib/" + MT)) + return MT; + if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnu")) + return "mips64el-linux-gnu"; break; } case llvm::Triple::ppc: diff --git a/clang/test/Driver/linux-ld.c b/clang/test/Driver/linux-ld.c index 3ab81be4906aa..a817347802932 100644 --- a/clang/test/Driver/linux-ld.c +++ b/clang/test/Driver/linux-ld.c @@ -1632,6 +1632,11 @@ // CHECK-DEBIAN-ML-MIPS64EL-N32: "-L[[SYSROOT]]/usr/lib" // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: --target=mips64-unknown-linux-gnu \ +// RUN: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/debian_6_mips64_tree \ +// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64-GNUABI %s +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=mips64-linux-gnuabi64 -mabi=n64 \ // RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/debian_6_mips64_tree \ @@ -1652,6 +1657,11 @@ // CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../mips64-linux-gnuabi64{{/|\\\\}}crtn.o" // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: --target=mips64el-unknown-linux-gnu \ +// RUN: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/debian_6_mips64_tree \ +// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64EL-GNUABI %s +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=mips64el-linux-gnuabi64 -mabi=n64 \ // RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/debian_6_mips64_tree \ From 604a4178228c4b39c635a262a8faf9025cc31274 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 25 Apr 2019 17:42:47 +0000 Subject: [PATCH 218/274] Merging r358885: ------------------------------------------------------------------------ r358885 | grimar | 2019-04-22 06:40:42 -0700 (Mon, 22 Apr 2019) | 8 lines [LLD][ELF] - Do not forget to use ch_addralign field after decompressing the sections. LLD did not use ELF::Chdr::ch_addralign for decompressed sections. This resulted in a broken output. Fixes https://bugs.llvm.org/show_bug.cgi?id=40482. Differential revision: https://reviews.llvm.org/D60959 ------------------------------------------------------------------------ llvm-svn: 359209 --- lld/ELF/InputSection.cpp | 2 + lld/test/ELF/compressed-input-alignment.test | 67 ++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 lld/test/ELF/compressed-input-alignment.test diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 839bff7011eb8..4148413b67985 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -248,6 +248,7 @@ void InputSectionBase::parseCompressedHeader() { } UncompressedSize = Hdr->ch_size; + Alignment = std::max(Hdr->ch_addralign, 1); RawData = RawData.slice(sizeof(*Hdr)); return; } @@ -265,6 +266,7 @@ void InputSectionBase::parseCompressedHeader() { } UncompressedSize = Hdr->ch_size; + Alignment = std::max(Hdr->ch_addralign, 1); RawData = RawData.slice(sizeof(*Hdr)); } diff --git a/lld/test/ELF/compressed-input-alignment.test b/lld/test/ELF/compressed-input-alignment.test new file mode 100644 index 0000000000000..a1f679034b77d --- /dev/null +++ b/lld/test/ELF/compressed-input-alignment.test @@ -0,0 +1,67 @@ +# REQUIRES: zlib, x86 + +# RUN: yaml2obj -docnum=1 %s -o %t.o +# RUN: ld.lld %t.o %t.o -o %t2 +# RUN: llvm-readobj -sections -section-data %t2 | FileCheck %s + +# RUN: yaml2obj -docnum=2 %s -o %t.o +# RUN: ld.lld %t.o %t.o -o %t2 +# RUN: llvm-readobj -sections -section-data %t2 | FileCheck %s + +# CHECK: Name: .debug_info +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x0 +# CHECK-NEXT: Offset: 0xE8 +# CHECK-NEXT: Size: 108 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 1 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: SectionData ( +# CHECK-NEXT: 0000: {{.*}} |ABCDEFGHIJKLMNOP| +# CHECK-NEXT: 0010: {{.*}} |QRSTUVWXYZ.ABCDE| +# CHECK-NEXT: 0020: {{.*}} |FGHIJKLMNOPQRSTU| +# CHECK-NEXT: 0030: {{.*}} |VWXYZ.ABCDEFGHIJ| +# CHECK-NEXT: 0040: {{.*}} |KLMNOPQRSTUVWXYZ| +# CHECK-NEXT: 0050: {{.*}} |.ABCDEFGHIJKLMNO| +# CHECK-NEXT: 0060: {{.*}} |PQRSTUVWXYZ.| +# CHECK-NEXT: ) +# CHECK-NEXT: } + +## YAML below is produced from the following code. AddressAlign of .debug_info is 8, +## while compressed header has ch_addralign = 1. LLD had a bug and did not use the +## value of ch_addralign at all. We produced broken section content. +## +## .section .debug_info,"",@progbits +## .string "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +## .string "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .debug_info + Type: SHT_PROGBITS + Flags: [ SHF_COMPRESSED ] + AddressAlign: 0x0000000000000008 + Content: 010000000000000036000000000000000100000000000000789C73747276717573F7F0F4F2F6F1F5F30F080C0A0E090D0B8F888C6270C42D0500ADA00FBF + +## YAML below is the same as above, with a single change: ch_addralign field of the compressed +## header was set to 0. This is allowed by the standard, we have to support it. +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .debug_info + Type: SHT_PROGBITS + Flags: [ SHF_COMPRESSED ] + AddressAlign: 0x0000000000000008 + Content: 010000000000000036000000000000000000000000000000789C73747276717573F7F0F4F2F6F1F5F30F080C0A0E090D0B8F888C6270C42D0500ADA00FBF From 68f2f7cc08fc559570913771e237456474f8a39d Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 3 May 2019 00:12:22 +0000 Subject: [PATCH 219/274] Merging r355607: ------------------------------------------------------------------------ r355607 | petarj | 2019-03-07 08:31:08 -0800 (Thu, 07 Mar 2019) | 11 lines [DebugInfo] Fix the type of the formated variable Change the format type of *Personality and *LSDAAddress to PRIx64 since they are of type uint64_t. The problem was detected on mips builds, where it was printing junk values and causing test failure. Patch by Milos Stojanovic. Differential Revision: https://reviews.llvm.org/D58451 ------------------------------------------------------------------------ llvm-svn: 359851 --- llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp | 4 ++-- llvm/test/tools/llvm-objdump/eh_frame-coff.test | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp index ba55ffc28174f..8a88a2fa3a09a 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp @@ -301,7 +301,7 @@ void CIE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const { OS << format(" Data alignment factor: %d\n", (int32_t)DataAlignmentFactor); OS << format(" Return address column: %d\n", (int32_t)ReturnAddressRegister); if (Personality) - OS << format(" Personality Address: %08x\n", *Personality); + OS << format(" Personality Address: %016" PRIx64 "\n", *Personality); if (!AugmentationData.empty()) { OS << " Augmentation data: "; for (uint8_t Byte : AugmentationData) @@ -320,7 +320,7 @@ void FDE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const { (uint32_t)InitialLocation, (uint32_t)InitialLocation + (uint32_t)AddressRange); if (LSDAAddress) - OS << format(" LSDA Address: %08x\n", *LSDAAddress); + OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress); CFIs.dump(OS, MRI, IsEH); OS << "\n"; } diff --git a/llvm/test/tools/llvm-objdump/eh_frame-coff.test b/llvm/test/tools/llvm-objdump/eh_frame-coff.test index 74eceeec4f31a..cb481939dcc83 100644 --- a/llvm/test/tools/llvm-objdump/eh_frame-coff.test +++ b/llvm/test/tools/llvm-objdump/eh_frame-coff.test @@ -8,7 +8,7 @@ # CHECK: Code alignment factor: 1 # CHECK: Data alignment factor: -4 # CHECK: Return address column: 8 -# CHECK: Personality Address: 004025d7 +# CHECK: Personality Address: 00000000004025d7 # CHECK: Augmentation data: 00 D7 25 40 00 00 00 # CHECK: DW_CFA_def_cfa: reg4 +4 @@ -17,7 +17,7 @@ # CHECK: DW_CFA_nop: # CHECK: 00000020 0000001c 00000024 FDE cie=00000024 pc=00401410...00401488 -# CHECK: LSDA Address: 00406000 +# CHECK: LSDA Address: 0000000000406000 # CHECK: DW_CFA_advance_loc: 1 # CHECK: DW_CFA_def_cfa_offset: +8 # CHECK: DW_CFA_offset: reg5 -8 From 9465a4c3ed5529532e3e875f086268fea1c25679 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 3 May 2019 01:51:07 +0000 Subject: [PATCH 220/274] Merging r357701: ------------------------------------------------------------------------ r357701 | mgorny | 2019-04-04 07:21:38 -0700 (Thu, 04 Apr 2019) | 8 lines [llvm] [cmake] Add additional headers only if they exist Modify the add_header_files_for_glob() function to only add files that do exist, rather than all matches of the glob. This fixes CMake error when one of the include directories (which happen to include /usr/include) contain broken symlinks. Differential Revision: https://reviews.llvm.org/D59632 ------------------------------------------------------------------------ llvm-svn: 359857 --- llvm/cmake/modules/LLVMProcessSources.cmake | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/llvm/cmake/modules/LLVMProcessSources.cmake b/llvm/cmake/modules/LLVMProcessSources.cmake index 7cbd2863500cf..d0be0e8b3ba3d 100644 --- a/llvm/cmake/modules/LLVMProcessSources.cmake +++ b/llvm/cmake/modules/LLVMProcessSources.cmake @@ -30,7 +30,15 @@ endmacro(add_td_sources) function(add_header_files_for_glob hdrs_out glob) file(GLOB hds ${glob}) - set(${hdrs_out} ${hds} PARENT_SCOPE) + set(filtered) + foreach(file ${hds}) + # Explicit existence check is necessary to filter dangling symlinks + # out. See https://bugs.gentoo.org/674662. + if(EXISTS ${file}) + list(APPEND filtered ${file}) + endif() + endforeach() + set(${hdrs_out} ${filtered} PARENT_SCOPE) endfunction(add_header_files_for_glob) function(find_all_header_files hdrs_out additional_headerdirs) From 87c0dbbedac53330a26e70e6bfc37d4fa42d7ab0 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 3 May 2019 23:33:28 +0000 Subject: [PATCH 221/274] Merging r357376 and r359120: ------------------------------------------------------------------------ r357376 | labath | 2019-04-01 01:11:46 -0700 (Mon, 01 Apr 2019) | 27 lines [Linux/x86] Fix writing of non-gpr registers on newer processors Summary: We're using ptrace(PTRACE_SETREGSET, NT_X86_XSTATE) to write all non-gpt registers on x86 linux. Unfortunately, this method has a quirk, where the kernel rejects all attempts to write to this area if one supplies a buffer which is smaller than the area size (even though the kernel will happily accept partial reads from it). This means that if the CPU supports some new registers/extensions that we don't know about (in my case it was the PKRU extension), we will fail to write *any* non-gpr registers, even those that we know about. Since this is a situation that's likely to appear again and again, I add code to NativeRegisterContextLinux_x86_64 to detect the runtime size of the area, and allocate an appropriate buffer. This does not mean that we will start automatically supporting all new extensions, but it does mean that the new extensions will not prevent the old ones from working. This fixes tests attempting to write to non-gpr registers on new intel processors (cca Kaby Lake Refresh). Reviewers: jankratochvil, davezarzycki Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D59991 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r359120 | josepht | 2019-04-24 11:00:12 -0700 (Wed, 24 Apr 2019) | 15 lines [lldb] Use local definition of get_cpuid_count Summary: This is needed for gcc/cstdlib++ 5.4.0, where __get_cpuid_count is not defined in cpuid.h. Reviewers: labath Reviewed By: labath Subscribers: lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D61036 ------------------------------------------------------------------------ llvm-svn: 359945 --- .../NativeRegisterContextLinux_x86_64.cpp | 136 +++++++++++------- .../Linux/NativeRegisterContextLinux_x86_64.h | 3 +- 2 files changed, 88 insertions(+), 51 deletions(-) diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp index 50bf29b094df0..c7313e6f98773 100644 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp @@ -19,9 +19,26 @@ #include "Plugins/Process/Utility/RegisterContextLinux_i386.h" #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" - +#include #include +// Newer toolchains define __get_cpuid_count in cpuid.h, but some +// older-but-still-supported ones (e.g. gcc 5.4.0) don't, so we +// define it locally here, following the definition in clang/lib/Headers. +static inline int get_cpuid_count(unsigned int __leaf, + unsigned int __subleaf, + unsigned int *__eax, unsigned int *__ebx, + unsigned int *__ecx, unsigned int *__edx) +{ + unsigned int __max_leaf = __get_cpuid_max(__leaf & 0x80000000, 0); + + if (__max_leaf == 0 || __max_leaf < __leaf) + return 0; + + __cpuid_count(__leaf, __subleaf, *__eax, *__ebx, *__ecx, *__edx); + return 1; +} + using namespace lldb_private; using namespace lldb_private::process_linux; @@ -268,12 +285,29 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) { } } +// Return the size of the XSTATE area supported on this cpu. It is necessary to +// allocate the full size of the area even if we do not use/recognise all of it +// because ptrace(PTRACE_SETREGSET, NT_X86_XSTATE) will refuse to write to it if +// we do not pass it a buffer of sufficient size. The size is always at least +// sizeof(FPR) so that the allocated buffer can be safely cast to FPR*. +static std::size_t GetXSTATESize() { + unsigned int eax, ebx, ecx, edx; + // First check whether the XSTATE are is supported at all. + if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx) || !(ecx & bit_XSAVE)) + return sizeof(FPR); + + // Then fetch the maximum size of the area. + if (!get_cpuid_count(0x0d, 0, &eax, &ebx, &ecx, &edx)) + return sizeof(FPR); + return std::max(ecx, sizeof(FPR)); +} + NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64( const ArchSpec &target_arch, NativeThreadProtocol &native_thread) : NativeRegisterContextLinux(native_thread, CreateRegisterInfoInterface(target_arch)), - m_xstate_type(XStateType::Invalid), m_fpr(), m_iovec(), m_ymm_set(), - m_mpx_set(), m_reg_info(), m_gpr_x86_64() { + m_xstate_type(XStateType::Invalid), m_ymm_set(), m_mpx_set(), + m_reg_info(), m_gpr_x86_64() { // Set up data about ranges of valid registers. switch (target_arch.GetMachine()) { case llvm::Triple::x86: @@ -329,14 +363,13 @@ NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64( break; } - // Initialize m_iovec to point to the buffer and buffer size using the - // conventions of Berkeley style UIO structures, as required by PTRACE - // extensions. - m_iovec.iov_base = &m_fpr; - m_iovec.iov_len = sizeof(m_fpr); + std::size_t xstate_size = GetXSTATESize(); + m_xstate.reset(static_cast(std::malloc(xstate_size))); + m_iovec.iov_base = m_xstate.get(); + m_iovec.iov_len = xstate_size; // Clear out the FPR state. - ::memset(&m_fpr, 0, sizeof(m_fpr)); + ::memset(m_xstate.get(), 0, xstate_size); // Store byte offset of fctrl (i.e. first register of FPR) const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl"); @@ -439,14 +472,17 @@ NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info, if (byte_order != lldb::eByteOrderInvalid) { if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st) - reg_value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_st].bytes, - reg_info->byte_size, byte_order); + reg_value.SetBytes( + m_xstate->fxsave.stmm[reg - m_reg_info.first_st].bytes, + reg_info->byte_size, byte_order); if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm) - reg_value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_mm].bytes, - reg_info->byte_size, byte_order); + reg_value.SetBytes( + m_xstate->fxsave.stmm[reg - m_reg_info.first_mm].bytes, + reg_info->byte_size, byte_order); if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm) - reg_value.SetBytes(m_fpr.fxsave.xmm[reg - m_reg_info.first_xmm].bytes, - reg_info->byte_size, byte_order); + reg_value.SetBytes( + m_xstate->fxsave.xmm[reg - m_reg_info.first_xmm].bytes, + reg_info->byte_size, byte_order); if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) { // Concatenate ymm using the register halves in xmm.bytes and // ymmh.bytes @@ -488,7 +524,7 @@ NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info, return error; } - // Get pointer to m_fpr.fxsave variable and set the data from it. + // Get pointer to m_xstate->fxsave variable and set the data from it. // Byte offsets of all registers are calculated wrt 'UserArea' structure. // However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)} @@ -499,9 +535,9 @@ NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info, // Since, FPR structure is also one of the member of UserArea structure. // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) - // byte_offset(fctrl wrt UserArea) - assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr)); - uint8_t *src = - (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea; + assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(FPR)); + uint8_t *src = (uint8_t *)m_xstate.get() + reg_info->byte_offset - + m_fctrl_offset_in_userarea; switch (reg_info->byte_size) { case 1: reg_value.SetUInt8(*(uint8_t *)src); @@ -527,7 +563,7 @@ NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info, void NativeRegisterContextLinux_x86_64::UpdateXSTATEforWrite( uint32_t reg_index) { - XSAVE_HDR::XFeature &xstate_bv = m_fpr.xsave.header.xstate_bv; + XSAVE_HDR::XFeature &xstate_bv = m_xstate->xsave.header.xstate_bv; if (IsFPR(reg_index)) { // IsFPR considers both %st and %xmm registers as floating point, but these // map to two features. Set both flags, just in case. @@ -559,15 +595,15 @@ Status NativeRegisterContextLinux_x86_64::WriteRegister( if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) { if (reg_info->encoding == lldb::eEncodingVector) { if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st) - ::memcpy(m_fpr.fxsave.stmm[reg_index - m_reg_info.first_st].bytes, + ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_st].bytes, reg_value.GetBytes(), reg_value.GetByteSize()); if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm) - ::memcpy(m_fpr.fxsave.stmm[reg_index - m_reg_info.first_mm].bytes, + ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_mm].bytes, reg_value.GetBytes(), reg_value.GetByteSize()); if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm) - ::memcpy(m_fpr.fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes, + ::memcpy(m_xstate->fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes, reg_value.GetBytes(), reg_value.GetByteSize()); if (reg_index >= m_reg_info.first_ymm && @@ -596,7 +632,7 @@ Status NativeRegisterContextLinux_x86_64::WriteRegister( return Status("CopyMPXtoXSTATE() failed"); } } else { - // Get pointer to m_fpr.fxsave variable and set the data to it. + // Get pointer to m_xstate->fxsave variable and set the data to it. // Byte offsets of all registers are calculated wrt 'UserArea' structure. // However, WriteFPR() takes m_fpr (of type FPR structure) and writes @@ -608,8 +644,8 @@ Status NativeRegisterContextLinux_x86_64::WriteRegister( // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) - // byte_offset(fctrl wrt UserArea) assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < - sizeof(m_fpr)); - uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset - + sizeof(FPR)); + uint8_t *dst = (uint8_t *)m_xstate.get() + reg_info->byte_offset - m_fctrl_offset_in_userarea; switch (reg_info->byte_size) { case 1: @@ -667,7 +703,7 @@ Status NativeRegisterContextLinux_x86_64::ReadAllRegisterValues( ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize()); dst += GetRegisterInfoInterface().GetGPRSize(); if (m_xstate_type == XStateType::FXSAVE) - ::memcpy(dst, &m_fpr.fxsave, sizeof(m_fpr.fxsave)); + ::memcpy(dst, &m_xstate->fxsave, sizeof(m_xstate->fxsave)); else if (m_xstate_type == XStateType::XSAVE) { lldb::ByteOrder byte_order = GetByteOrder(); @@ -700,7 +736,7 @@ Status NativeRegisterContextLinux_x86_64::ReadAllRegisterValues( } } // Copy the extended register state including the assembled ymm registers. - ::memcpy(dst, &m_fpr, sizeof(m_fpr)); + ::memcpy(dst, m_xstate.get(), sizeof(FPR)); } else { assert(false && "how do we save the floating point registers?"); error.SetErrorString("unsure how to save the floating point registers"); @@ -758,9 +794,9 @@ Status NativeRegisterContextLinux_x86_64::WriteAllRegisterValues( src += GetRegisterInfoInterface().GetGPRSize(); if (m_xstate_type == XStateType::FXSAVE) - ::memcpy(&m_fpr.fxsave, src, sizeof(m_fpr.fxsave)); + ::memcpy(&m_xstate->fxsave, src, sizeof(m_xstate->fxsave)); else if (m_xstate_type == XStateType::XSAVE) - ::memcpy(&m_fpr.xsave, src, sizeof(m_fpr.xsave)); + ::memcpy(&m_xstate->xsave, src, sizeof(m_xstate->xsave)); error = WriteFPR(); if (error.Fail()) @@ -814,12 +850,12 @@ bool NativeRegisterContextLinux_x86_64::IsCPUFeatureAvailable( return true; case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by // reading in the XCR0 area of XSAVE. - if ((m_fpr.xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX) + if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX) return true; break; case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by // reading in the XCR0 area of XSAVE. - if ((m_fpr.xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX) + if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX) return true; break; } @@ -856,10 +892,10 @@ Status NativeRegisterContextLinux_x86_64::WriteFPR() { switch (m_xstate_type) { case XStateType::FXSAVE: return WriteRegisterSet( - &m_iovec, sizeof(m_fpr.fxsave), + &m_iovec, sizeof(m_xstate->fxsave), fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture())); case XStateType::XSAVE: - return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xsave), NT_X86_XSTATE); + return WriteRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE); default: return Status("Unrecognized FPR type."); } @@ -879,11 +915,11 @@ bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM( if (byte_order == lldb::eByteOrderLittle) { ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes, - m_fpr.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes, + m_xstate->fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes, sizeof(XMMReg)); ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes + sizeof(XMMReg), - m_fpr.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes, + m_xstate->xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes, sizeof(YMMHReg)); return true; } @@ -891,10 +927,10 @@ bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM( if (byte_order == lldb::eByteOrderBig) { ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes + sizeof(XMMReg), - m_fpr.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes, + m_xstate->fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes, sizeof(XMMReg)); ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes, - m_fpr.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes, + m_xstate->xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes, sizeof(YMMHReg)); return true; } @@ -907,19 +943,19 @@ bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE( return false; if (byte_order == lldb::eByteOrderLittle) { - ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes, + ::memcpy(m_xstate->fxsave.xmm[reg - m_reg_info.first_ymm].bytes, m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(XMMReg)); - ::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes, + ::memcpy(m_xstate->xsave.ymmh[reg - m_reg_info.first_ymm].bytes, m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg), sizeof(YMMHReg)); return true; } if (byte_order == lldb::eByteOrderBig) { - ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes, + ::memcpy(m_xstate->fxsave.xmm[reg - m_reg_info.first_ymm].bytes, m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg), sizeof(XMMReg)); - ::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes, + ::memcpy(m_xstate->xsave.ymmh[reg - m_reg_info.first_ymm].bytes, m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(YMMHReg)); return true; } @@ -929,7 +965,7 @@ bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE( void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() { switch (m_xstate_type) { case XStateType::FXSAVE: - return &m_fpr.fxsave; + return &m_xstate->fxsave; case XStateType::XSAVE: return &m_iovec; default: @@ -940,7 +976,7 @@ void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() { size_t NativeRegisterContextLinux_x86_64::GetFPRSize() { switch (m_xstate_type) { case XStateType::FXSAVE: - return sizeof(m_fpr.fxsave); + return sizeof(m_xstate->fxsave); case XStateType::XSAVE: return sizeof(m_iovec); default: @@ -953,14 +989,14 @@ Status NativeRegisterContextLinux_x86_64::ReadFPR() { // Probe XSAVE and if it is not supported fall back to FXSAVE. if (m_xstate_type != XStateType::FXSAVE) { - error = ReadRegisterSet(&m_iovec, sizeof(m_fpr.xsave), NT_X86_XSTATE); + error = ReadRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE); if (!error.Fail()) { m_xstate_type = XStateType::XSAVE; return error; } } error = ReadRegisterSet( - &m_iovec, sizeof(m_fpr.xsave), + &m_iovec, sizeof(m_xstate->xsave), fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture())); if (!error.Fail()) { m_xstate_type = XStateType::FXSAVE; @@ -982,11 +1018,11 @@ bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoMPX(uint32_t reg) { if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) { ::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, - m_fpr.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes, + m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg)); } else { ::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, - m_fpr.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes, + m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr)); } return true; @@ -997,10 +1033,10 @@ bool NativeRegisterContextLinux_x86_64::CopyMPXtoXSTATE(uint32_t reg) { return false; if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) { - ::memcpy(m_fpr.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes, + ::memcpy(m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes, m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg)); } else { - ::memcpy(m_fpr.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes, + ::memcpy(m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes, m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr)); } return true; diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h index 9dcf82f50a458..2970326306e53 100644 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h @@ -109,7 +109,8 @@ class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextLinux { // Private member variables. mutable XStateType m_xstate_type; - FPR m_fpr; // Extended States Area, named FPR for historical reasons. + std::unique_ptr + m_xstate; // Extended States Area, named FPR for historical reasons. struct iovec m_iovec; YMM m_ymm_set; MPX m_mpx_set; From 2a5c205ccd2ab4ad2f59b532dd25ed1fa65f0a8e Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 3 May 2019 23:50:08 +0000 Subject: [PATCH 222/274] Merging r359834: ------------------------------------------------------------------------ r359834 | evandro | 2019-05-02 15:01:39 -0700 (Thu, 02 May 2019) | 3 lines [AArch64] Update for Exynos Fix the forwarding of multiplication results for Exynos M4. ------------------------------------------------------------------------ llvm-svn: 359946 --- .../Target/AArch64/AArch64SchedExynosM4.td | 36 ++++++------- .../Target/AArch64/AArch64SchedPredExynos.td | 11 ---- .../Target/AArch64/AArch64SchedPredicates.td | 53 ------------------- 3 files changed, 18 insertions(+), 82 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64SchedExynosM4.td b/llvm/lib/Target/AArch64/AArch64SchedExynosM4.td index 4d892465b3f27..61652b1d8e3dc 100644 --- a/llvm/lib/Target/AArch64/AArch64SchedExynosM4.td +++ b/llvm/lib/Target/AArch64/AArch64SchedExynosM4.td @@ -239,7 +239,6 @@ def M4WriteNEONK : SchedWriteRes<[M4UnitNSHF, M4UnitS0]> { let Latency = 5; let NumMicroOps = 2; } def M4WriteNEONL : SchedWriteRes<[M4UnitNMUL]> { let Latency = 3; } -def M4WriteNEONM : SchedWriteRes<[M4UnitNMUL]> { let Latency = 3; } def M4WriteNEONN : SchedWriteRes<[M4UnitNMSC, M4UnitNMSC]> { let Latency = 5; let NumMicroOps = 2; } @@ -480,8 +479,6 @@ def M4WriteCOPY : SchedWriteVariant<[SchedVar, SchedVar]>; def M4WriteMOVI : SchedWriteVariant<[SchedVar, SchedVar]>; -def M4WriteMULL : SchedWriteVariant<[SchedVar, - SchedVar]>; // Fast forwarding. def M4ReadAESM1 : SchedReadAdvance<+1, [M4WriteNCRY1]>; @@ -489,7 +486,8 @@ def M4ReadFMACM1 : SchedReadAdvance<+1, [M4WriteFMAC4, M4WriteFMAC4H, M4WriteFMAC5]>; def M4ReadNMULM1 : SchedReadAdvance<+1, [M4WriteNMUL3]>; -def M4ReadMULLP2 : SchedReadAdvance<-2, [M4WriteNEONM]>; +def M4ReadNMULP2 : SchedReadAdvance<-2, [M4WriteNMUL3]>; + //===----------------------------------------------------------------------===// // Coarse scheduling model. @@ -662,10 +660,8 @@ def : InstRW<[M4WriteNEONK], (instregex "^FMOVDXHighr")>; def : InstRW<[M4WriteFCVT3H], (instregex "^F(RECP|RSQRT)Ev1f16")>; def : InstRW<[M4WriteFCVT3], (instregex "^F(RECP|RSQRT)Ev1i(32|64)")>; def : InstRW<[M4WriteNMSC1], (instregex "^FRECPXv1")>; -def : InstRW<[M4WriteFMAC4H, - M4ReadFMACM1], (instregex "^F(RECP|RSQRT)S16")>; -def : InstRW<[M4WriteFMAC4, - M4ReadFMACM1], (instregex "^F(RECP|RSQRT)S(32|64)")>; +def : InstRW<[M4WriteFMAC4H], (instregex "^F(RECP|RSQRT)S16")>; +def : InstRW<[M4WriteFMAC4], (instregex "^F(RECP|RSQRT)S(32|64)")>; // FP load instructions. def : InstRW<[WriteVLD], (instregex "^LDR[SDQ]l")>; @@ -736,14 +732,20 @@ def : InstRW<[M4WriteNALU1], (instregex "^(AND|BIC|EOR|NOT|ORN|ORR)v")>; def : InstRW<[M4WriteNMSC1], (instregex "^[SU](MIN|MAX)v")>; def : InstRW<[M4WriteNMSC2], (instregex "^[SU](MIN|MAX)Pv")>; def : InstRW<[M4WriteNHAD3], (instregex "^[SU](MIN|MAX)Vv")>; -def : InstRW<[M4WriteNMUL3], (instregex "^(SQR?D)?MULH?v")>; def : InstRW<[M4WriteNMUL3, M4ReadNMULM1], (instregex "^ML[AS]v")>; -def : InstRW<[M4WriteNMUL3], (instregex "^SQRDML[AS]H")>; -def : InstRW<[M4WriteMULL, - M4ReadMULLP2], (instregex "^(S|U|SQD)ML[AS]Lv")>; -def : InstRW<[M4WriteMULL, - M4ReadMULLP2], (instregex "^(S|U|SQD)MULLv")>; +def : InstRW<[M4WriteNMUL3, + M4ReadNMULM1], (instregex "^(SQR?D)?MULH?v")>; +def : InstRW<[M4WriteNMUL3, + M4ReadNMULM1], (instregex "^SQRDML[AS]H")>; +def : InstRW<[M4WriteNMUL3, + M4ReadNMULM1], (instregex "^(S|U|SQD)ML[AS]L(v1(i32|i64)|v2i32|v4i16|v8i8)")>; +def : InstRW<[M4WriteNMUL3, + M4ReadNMULP2], (instregex "^(S|U|SQD)ML[AS]L(v4i32|v8i16|v16i8)")>; +def : InstRW<[M4WriteNMUL3, + M4ReadNMULM1], (instregex "^(S|U|SQD)MULL(v1(i32|i64)|v2i32|v4i16|v8i8)")>; +def : InstRW<[M4WriteNMUL3, + M4ReadNMULP2], (instregex "^(S|U|SQD)MULL(v4i32|v8i16|v16i8)")>; def : InstRW<[M4WriteNMUL3], (instregex "^[SU]DOT(lane)?v")>; def : InstRW<[M4WriteNHAD3], (instregex "^[SU]ADALPv")>; def : InstRW<[M4WriteNSHT4A], (instregex "^[SU]R?SRA[dv]")>; @@ -808,10 +810,8 @@ def : InstRW<[M4WriteNALU1], (instregex "^FMOVv.f(32|64)")>; def : InstRW<[M4WriteFCVT3H], (instregex "^F(RECP|RSQRT)Ev[248]f16")>; def : InstRW<[M4WriteFCVT3], (instregex "^F(RECP|RSQRT)Ev[248]f(32|64)")>; def : InstRW<[M4WriteFCVT3], (instregex "^U(RECP|RSQRT)Ev[24]i32")>; -def : InstRW<[M4WriteFMAC4H, - M4ReadFMACM1], (instregex "^F(RECP|RSQRT)Sv.f16")>; -def : InstRW<[M4WriteFMAC4, - M4ReadFMACM1], (instregex "^F(RECP|RSQRT)Sv.f(32|64)")>; +def : InstRW<[M4WriteFMAC4H], (instregex "^F(RECP|RSQRT)Sv.f16")>; +def : InstRW<[M4WriteFMAC4], (instregex "^F(RECP|RSQRT)Sv.f(32|64)")>; def : InstRW<[M4WriteNSHF1], (instregex "^REV(16|32|64)v")>; def : InstRW<[M4WriteNSHFA], (instregex "^TB[LX]v(8|16)i8One")>; def : InstRW<[M4WriteNSHFB], (instregex "^TB[LX]v(8|16)i8Two")>; diff --git a/llvm/lib/Target/AArch64/AArch64SchedPredExynos.td b/llvm/lib/Target/AArch64/AArch64SchedPredExynos.td index 48c54230e9d85..316036d894064 100644 --- a/llvm/lib/Target/AArch64/AArch64SchedPredExynos.td +++ b/llvm/lib/Target/AArch64/AArch64SchedPredExynos.td @@ -103,17 +103,6 @@ def ExynosScaledIdxPred : MCSchedPredicate; // Identify FP instructions. def ExynosFPPred : MCSchedPredicate>; -// Identify whether an instruction whose result is a long vector -// operates on the upper half of the input registers. -def ExynosLongVectorUpperFn : TIIPredicate< - "isExynosLongVectorUpper", - MCOpcodeSwitchStatement< - [MCOpcodeSwitchCase< - IsLongVectorUpperOp.ValidOpcodes, - MCReturnStatement>], - MCReturnStatement>>; -def ExynosLongVectorUpperPred : MCSchedPredicate; - // Identify 128-bit NEON instructions. def ExynosQFormPred : MCSchedPredicate; diff --git a/llvm/lib/Target/AArch64/AArch64SchedPredicates.td b/llvm/lib/Target/AArch64/AArch64SchedPredicates.td index dbaf11fc95dd2..b23572b41b9cc 100644 --- a/llvm/lib/Target/AArch64/AArch64SchedPredicates.td +++ b/llvm/lib/Target/AArch64/AArch64SchedPredicates.td @@ -268,59 +268,6 @@ def IsStoreRegOffsetOp : CheckOpcode<[STRBBroW, STRBBroX, def IsLoadStoreRegOffsetOp : CheckOpcode; -// Identify whether an instruction whose result is a long vector -// operates on the upper half of the input registers. -def IsLongVectorUpperOp : CheckOpcode<[FCVTLv8i16, FCVTLv4i32, - FCVTNv8i16, FCVTNv4i32, - FCVTXNv4f32, - PMULLv16i8, PMULLv2i64, - RADDHNv8i16_v16i8, RADDHNv4i32_v8i16, RADDHNv2i64_v4i32, - RSHRNv16i8_shift, RSHRNv8i16_shift, RSHRNv4i32_shift, - RSUBHNv8i16_v16i8, RSUBHNv4i32_v8i16, RSUBHNv2i64_v4i32, - SABALv16i8_v8i16, SABALv8i16_v4i32, SABALv4i32_v2i64, - SABDLv16i8_v8i16, SABDLv8i16_v4i32, SABDLv4i32_v2i64, - SADDLv16i8_v8i16, SADDLv8i16_v4i32, SADDLv4i32_v2i64, - SADDWv16i8_v8i16, SADDWv8i16_v4i32, SADDWv4i32_v2i64, - SHLLv16i8, SHLLv8i16, SHLLv4i32, - SHRNv16i8_shift, SHRNv8i16_shift, SHRNv4i32_shift, - SMLALv16i8_v8i16, SMLALv8i16_v4i32, SMLALv4i32_v2i64, - SMLALv8i16_indexed, SMLALv4i32_indexed, - SMLSLv16i8_v8i16, SMLSLv8i16_v4i32, SMLSLv4i32_v2i64, - SMLSLv8i16_indexed, SMLSLv4i32_indexed, - SMULLv16i8_v8i16, SMULLv8i16_v4i32, SMULLv4i32_v2i64, - SMULLv8i16_indexed, SMULLv4i32_indexed, - SQDMLALv8i16_v4i32, SQDMLALv4i32_v2i64, - SQDMLALv8i16_indexed, SQDMLALv4i32_indexed, - SQDMLSLv8i16_v4i32, SQDMLSLv4i32_v2i64, - SQDMLSLv8i16_indexed, SQDMLSLv4i32_indexed, - SQDMULLv8i16_v4i32, SQDMULLv4i32_v2i64, - SQDMULLv8i16_indexed, SQDMULLv4i32_indexed, - SQRSHRNv16i8_shift, SQRSHRNv8i16_shift, SQRSHRNv4i32_shift, - SQRSHRUNv16i8_shift, SQRSHRUNv8i16_shift, SQRSHRUNv4i32_shift, - SQSHRNv16i8_shift, SQSHRNv8i16_shift, SQSHRNv4i32_shift, - SQSHRUNv16i8_shift, SQSHRUNv8i16_shift, SQSHRUNv4i32_shift, - SQXTNv16i8, SQXTNv8i16, SQXTNv4i32, - SQXTUNv16i8, SQXTUNv8i16, SQXTUNv4i32, - SSHLLv16i8_shift, SSHLLv8i16_shift, SSHLLv4i32_shift, - SSUBLv16i8_v8i16, SSUBLv8i16_v4i32, SSUBLv4i32_v2i64, - SSUBWv16i8_v8i16, SSUBWv8i16_v4i32, SSUBWv4i32_v2i64, - UABALv16i8_v8i16, UABALv8i16_v4i32, UABALv4i32_v2i64, - UABDLv16i8_v8i16, UABDLv8i16_v4i32, UABDLv4i32_v2i64, - UADDLv16i8_v8i16, UADDLv8i16_v4i32, UADDLv4i32_v2i64, - UADDWv16i8_v8i16, UADDWv8i16_v4i32, UADDWv4i32_v2i64, - UMLALv16i8_v8i16, UMLALv8i16_v4i32, UMLALv4i32_v2i64, - UMLALv8i16_indexed, UMLALv4i32_indexed, - UMLSLv16i8_v8i16, UMLSLv8i16_v4i32, UMLSLv4i32_v2i64, - UMLSLv8i16_indexed, UMLSLv4i32_indexed, - UMULLv16i8_v8i16, UMULLv8i16_v4i32, UMULLv4i32_v2i64, - UMULLv8i16_indexed, UMULLv4i32_indexed, - UQSHRNv16i8_shift, UQSHRNv8i16_shift, UQSHRNv4i32_shift, - UQXTNv16i8, UQXTNv8i16, UQXTNv4i32, - USHLLv16i8_shift, USHLLv8i16_shift, USHLLv4i32_shift, - USUBLv16i8_v8i16, USUBLv8i16_v4i32, USUBLv4i32_v2i64, - USUBWv16i8_v8i16, USUBWv8i16_v4i32, USUBWv4i32_v2i64, - XTNv16i8, XTNv8i16, XTNv4i32]>; - // Target predicates. // Identify an instruction that effectively transfers a register to another. From 0d754fd0166c80c6bad1a8e0fac8e76557bafa7d Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Sat, 4 May 2019 00:24:26 +0000 Subject: [PATCH 223/274] Merging r359496: ------------------------------------------------------------------------ r359496 | mstorsjo | 2019-04-29 13:25:51 -0700 (Mon, 29 Apr 2019) | 8 lines [X86] Run CFIInstrInserter on Windows if Dwarf is used This is necessary since SVN r330706, as tail merging can include CFI instructions since then. This fixes PR40322 and PR40012. Differential Revision: https://reviews.llvm.org/D61252 ------------------------------------------------------------------------ llvm-svn: 359952 --- llvm/lib/Target/X86/X86TargetMachine.cpp | 6 +- llvm/test/CodeGen/X86/PR40322.ll | 164 +++++++++++++++++++++++ 2 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/X86/PR40322.ll diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp index afcb49dc22632..217a12ddf896e 100644 --- a/llvm/lib/Target/X86/X86TargetMachine.cpp +++ b/llvm/lib/Target/X86/X86TargetMachine.cpp @@ -38,6 +38,7 @@ #include "llvm/IR/Attributes.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/Pass.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/CommandLine.h" @@ -512,6 +513,9 @@ void X86PassConfig::addPreEmitPass2() { // correct CFA calculation rule where needed by inserting appropriate CFI // instructions. const Triple &TT = TM->getTargetTriple(); - if (!TT.isOSDarwin() && !TT.isOSWindows()) + const MCAsmInfo *MAI = TM->getMCAsmInfo(); + if (!TT.isOSDarwin() && + (!TT.isOSWindows() || + MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI)) addPass(createCFIInstrInserter()); } diff --git a/llvm/test/CodeGen/X86/PR40322.ll b/llvm/test/CodeGen/X86/PR40322.ll new file mode 100644 index 0000000000000..22bf1822c65af --- /dev/null +++ b/llvm/test/CodeGen/X86/PR40322.ll @@ -0,0 +1,164 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=i686-windows-gnu | FileCheck %s --check-prefix=CHECK-MINGW-X86 + +%struct.as = type { i32* } + +@_ZZ2amiE2au = internal unnamed_addr global %struct.as zeroinitializer, align 4 +@_ZGVZ2amiE2au = internal global i64 0, align 8 +@_ZTIi = external constant i8* + +define void @_Z2ami(i32) #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +; CHECK-MINGW-X86-LABEL: _Z2ami: +; CHECK-MINGW-X86: # %bb.0: # %entry +; CHECK-MINGW-X86-NEXT: pushl %edi +; CHECK-MINGW-X86-NEXT: .cfi_def_cfa_offset 8 +; CHECK-MINGW-X86-NEXT: pushl %esi +; CHECK-MINGW-X86-NEXT: .cfi_def_cfa_offset 12 +; CHECK-MINGW-X86-NEXT: .cfi_offset %esi, -12 +; CHECK-MINGW-X86-NEXT: .cfi_offset %edi, -8 +; CHECK-MINGW-X86-NEXT: movb __ZGVZ2amiE2au, %al +; CHECK-MINGW-X86-NEXT: testb %al, %al +; CHECK-MINGW-X86-NEXT: jne LBB0_4 +; CHECK-MINGW-X86-NEXT: # %bb.1: # %init.check +; CHECK-MINGW-X86-NEXT: .cfi_escape 0x2e, 0x04 +; CHECK-MINGW-X86-NEXT: pushl $__ZGVZ2amiE2au +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset 4 +; CHECK-MINGW-X86-NEXT: calll ___cxa_guard_acquire +; CHECK-MINGW-X86-NEXT: addl $4, %esp +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset -4 +; CHECK-MINGW-X86-NEXT: testl %eax, %eax +; CHECK-MINGW-X86-NEXT: je LBB0_4 +; CHECK-MINGW-X86-NEXT: # %bb.2: # %init +; CHECK-MINGW-X86-NEXT: Ltmp0: +; CHECK-MINGW-X86-NEXT: .cfi_escape 0x2e, 0x04 +; CHECK-MINGW-X86-NEXT: pushl $4 +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset 4 +; CHECK-MINGW-X86-NEXT: calll __Znwj +; CHECK-MINGW-X86-NEXT: addl $4, %esp +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset -4 +; CHECK-MINGW-X86-NEXT: Ltmp1: +; CHECK-MINGW-X86-NEXT: # %bb.3: # %invoke.cont +; CHECK-MINGW-X86-NEXT: movl %eax, __ZZ2amiE2au +; CHECK-MINGW-X86-NEXT: .cfi_escape 0x2e, 0x04 +; CHECK-MINGW-X86-NEXT: pushl $__ZGVZ2amiE2au +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset 4 +; CHECK-MINGW-X86-NEXT: calll ___cxa_guard_release +; CHECK-MINGW-X86-NEXT: addl $4, %esp +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset -4 +; CHECK-MINGW-X86-NEXT: LBB0_4: # %init.end +; CHECK-MINGW-X86-NEXT: .cfi_escape 0x2e, 0x04 +; CHECK-MINGW-X86-NEXT: pushl $4 +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset 4 +; CHECK-MINGW-X86-NEXT: calll __Znwj +; CHECK-MINGW-X86-NEXT: addl $4, %esp +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset -4 +; CHECK-MINGW-X86-NEXT: movl %eax, %esi +; CHECK-MINGW-X86-NEXT: .cfi_escape 0x2e, 0x04 +; CHECK-MINGW-X86-NEXT: pushl $4 +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset 4 +; CHECK-MINGW-X86-NEXT: calll ___cxa_allocate_exception +; CHECK-MINGW-X86-NEXT: addl $4, %esp +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset -4 +; CHECK-MINGW-X86-NEXT: movl $0, (%eax) +; CHECK-MINGW-X86-NEXT: Ltmp3: +; CHECK-MINGW-X86-NEXT: .cfi_escape 0x2e, 0x0c +; CHECK-MINGW-X86-NEXT: movl .refptr.__ZTIi, %ecx +; CHECK-MINGW-X86-NEXT: pushl $0 +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset 4 +; CHECK-MINGW-X86-NEXT: pushl %ecx +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset 4 +; CHECK-MINGW-X86-NEXT: pushl %eax +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset 4 +; CHECK-MINGW-X86-NEXT: calll ___cxa_throw +; CHECK-MINGW-X86-NEXT: addl $12, %esp +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset -12 +; CHECK-MINGW-X86-NEXT: Ltmp4: +; CHECK-MINGW-X86-NEXT: # %bb.8: # %unreachable +; CHECK-MINGW-X86-NEXT: LBB0_5: # %lpad +; CHECK-MINGW-X86-NEXT: Ltmp2: +; CHECK-MINGW-X86-NEXT: movl %eax, %edi +; CHECK-MINGW-X86-NEXT: .cfi_escape 0x2e, 0x04 +; CHECK-MINGW-X86-NEXT: pushl $__ZGVZ2amiE2au +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset 4 +; CHECK-MINGW-X86-NEXT: calll ___cxa_guard_abort +; CHECK-MINGW-X86-NEXT: jmp LBB0_7 +; CHECK-MINGW-X86-NEXT: LBB0_6: # %lpad1 +; CHECK-MINGW-X86-NEXT: .cfi_def_cfa_offset 12 +; CHECK-MINGW-X86-NEXT: Ltmp5: +; CHECK-MINGW-X86-NEXT: movl %eax, %edi +; CHECK-MINGW-X86-NEXT: .cfi_escape 0x2e, 0x04 +; CHECK-MINGW-X86-NEXT: pushl %esi +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset 4 +; CHECK-MINGW-X86-NEXT: calll __ZdlPv +; CHECK-MINGW-X86-NEXT: LBB0_7: # %eh.resume +; CHECK-MINGW-X86-NEXT: addl $4, %esp +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset -4 +; CHECK-MINGW-X86-NEXT: .cfi_escape 0x2e, 0x04 +; CHECK-MINGW-X86-NEXT: pushl %edi +; CHECK-MINGW-X86-NEXT: .cfi_adjust_cfa_offset 4 +; CHECK-MINGW-X86-NEXT: calll __Unwind_Resume +; CHECK-MINGW-X86-NEXT: Lfunc_end0: +entry: + %1 = load atomic i8, i8* bitcast (i64* @_ZGVZ2amiE2au to i8*) acquire, align 8 + %guard.uninitialized = icmp eq i8 %1, 0 + br i1 %guard.uninitialized, label %init.check, label %init.end + +init.check: ; preds = %entry + %2 = tail call i32 @__cxa_guard_acquire(i64* nonnull @_ZGVZ2amiE2au) + %tobool = icmp eq i32 %2, 0 + br i1 %tobool, label %init.end, label %init + +init: ; preds = %init.check + %call.i3 = invoke i8* @_Znwj(i32 4) + to label %invoke.cont unwind label %lpad + +invoke.cont: ; preds = %init + store i8* %call.i3, i8** bitcast (%struct.as* @_ZZ2amiE2au to i8**), align 4 + tail call void @__cxa_guard_release(i64* nonnull @_ZGVZ2amiE2au) + br label %init.end + +init.end: ; preds = %init.check, %invoke.cont, %entry + %call.i = tail call i8* @_Znwj(i32 4) + %exception = tail call i8* @__cxa_allocate_exception(i32 4) + %3 = bitcast i8* %exception to i32* + store i32 0, i32* %3, align 16 + invoke void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) + to label %unreachable unwind label %lpad1 + +lpad: ; preds = %init + %4 = landingpad { i8*, i32 } + cleanup + %5 = extractvalue { i8*, i32 } %4, 0 + %6 = extractvalue { i8*, i32 } %4, 1 + tail call void @__cxa_guard_abort(i64* nonnull @_ZGVZ2amiE2au) #1 + br label %eh.resume + +lpad1: ; preds = %init.end + %7 = landingpad { i8*, i32 } + cleanup + %8 = extractvalue { i8*, i32 } %7, 0 + %9 = extractvalue { i8*, i32 } %7, 1 + tail call void @_ZdlPv(i8* nonnull %call.i) + br label %eh.resume + +eh.resume: ; preds = %lpad1, %lpad + %exn.slot.0 = phi i8* [ %8, %lpad1 ], [ %5, %lpad ] + %ehselector.slot.0 = phi i32 [ %9, %lpad1 ], [ %6, %lpad ] + %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn.slot.0, 0 + %lpad.val2 = insertvalue { i8*, i32 } %lpad.val, i32 %ehselector.slot.0, 1 + resume { i8*, i32 } %lpad.val2 + +unreachable: ; preds = %init.end + unreachable +} + +declare i32 @__cxa_guard_acquire(i64*) +declare i32 @__gxx_personality_v0(...) +declare void @__cxa_guard_abort(i64*) +declare void @__cxa_guard_release(i64*) +declare i8* @__cxa_allocate_exception(i32) +declare void @__cxa_throw(i8*, i8*, i8*) +declare noalias nonnull i8* @_Znwj(i32) +declare i8* @__cxa_begin_catch(i8*) +declare void @__cxa_end_catch() +declare void @_ZdlPv(i8*) From 7c1f15e355fbbf8e238ffc4e8ffd7b80db4d9f93 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Sat, 4 May 2019 02:51:01 +0000 Subject: [PATCH 224/274] Merging r357885: ------------------------------------------------------------------------ r357885 | ruiu | 2019-04-07 23:45:07 -0700 (Sun, 07 Apr 2019) | 13 lines Fix -emit-reloc against local symbols. Previously, we drop symbols starting with .L from the symbol table, so if there is a relocation that refers a .L symbol, it ended up referencing a null -- which happened to be interpreted as an absolute symbol. This patch copies all symbols including local ones if -emit-reloc is given. Fixes https://bugs.llvm.org/show_bug.cgi?id=41385 Differential Revision: https://reviews.llvm.org/D60306 ------------------------------------------------------------------------ llvm-svn: 359956 --- lld/ELF/Writer.cpp | 5 +++++ lld/test/ELF/emit-relocs-mergeable2.s | 14 ++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 lld/test/ELF/emit-relocs-mergeable2.s diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 17f4c7961d30e..a3ef3f1c6e9f8 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -547,6 +547,11 @@ static bool shouldKeepInSymtab(SectionBase *Sec, StringRef SymName, if (Config->Discard == DiscardPolicy::None) return true; + // If -emit-reloc is given, all symbols including local ones need to be + // copied because they may be referenced by relocations. + if (Config->EmitRelocs) + return true; + // In ELF assembly .L symbols are normally discarded by the assembler. // If the assembler fails to do so, the linker discards them if // * --discard-locals is used. diff --git a/lld/test/ELF/emit-relocs-mergeable2.s b/lld/test/ELF/emit-relocs-mergeable2.s new file mode 100644 index 0000000000000..22d4cf4238af9 --- /dev/null +++ b/lld/test/ELF/emit-relocs-mergeable2.s @@ -0,0 +1,14 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld --emit-relocs %t.o -o %t.exe +# RUN: llvm-readelf --relocations %t.exe | FileCheck %s + +# CHECK: 0000000000201004 000000010000000b R_X86_64_32S 0000000000200120 .Lfoo + 8 + +.globl _start +_start: + movq .Lfoo+8, %rax +.section .rodata.cst16,"aM",@progbits,16 +.Lfoo: + .quad 0 + .quad 0 From 0203f70b7685e137abff634de5dec00bb54cb55d Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Wed, 15 May 2019 04:49:11 +0000 Subject: [PATCH 225/274] Merging r360512: ------------------------------------------------------------------------ r360512 | ctopper | 2019-05-10 21:19:33 -0700 (Fri, 10 May 2019) | 5 lines [X86] Don't emit MOVNTDQA loads from fast-isel without SSE4.1. We were checking for SSE4.1 for FP types, but not integer 128-bit types. Fixes PR41837. ------------------------------------------------------------------------ llvm-svn: 360749 --- llvm/lib/Target/X86/X86FastISel.cpp | 2 +- .../test/CodeGen/X86/fast-isel-nontemporal.ll | 72 ++++++++++++++----- 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp index 9dd3f2652543a..12cd613c34cbe 100644 --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -399,7 +399,7 @@ bool X86FastISel::X86FastEmitLoad(EVT VT, X86AddressMode &AM, case MVT::v2i64: case MVT::v8i16: case MVT::v16i8: - if (IsNonTemporal && Alignment >= 16) + if (IsNonTemporal && Alignment >= 16 && HasSSE41) Opc = HasVLX ? X86::VMOVNTDQAZ128rm : HasAVX ? X86::VMOVNTDQArm : X86::MOVNTDQArm; else if (Alignment >= 16) diff --git a/llvm/test/CodeGen/X86/fast-isel-nontemporal.ll b/llvm/test/CodeGen/X86/fast-isel-nontemporal.ll index db1ebfe6060f8..37e380b2b48c9 100644 --- a/llvm/test/CodeGen/X86/fast-isel-nontemporal.ll +++ b/llvm/test/CodeGen/X86/fast-isel-nontemporal.ll @@ -300,10 +300,20 @@ entry: } define <16 x i8> @test_load_nt16xi8(<16 x i8>* nocapture %ptr) { -; SSE-LABEL: test_load_nt16xi8: -; SSE: # %bb.0: # %entry -; SSE-NEXT: movntdqa (%rdi), %xmm0 -; SSE-NEXT: retq +; SSE2-LABEL: test_load_nt16xi8: +; SSE2: # %bb.0: # %entry +; SSE2-NEXT: movdqa (%rdi), %xmm0 +; SSE2-NEXT: retq +; +; SSE4A-LABEL: test_load_nt16xi8: +; SSE4A: # %bb.0: # %entry +; SSE4A-NEXT: movdqa (%rdi), %xmm0 +; SSE4A-NEXT: retq +; +; SSE41-LABEL: test_load_nt16xi8: +; SSE41: # %bb.0: # %entry +; SSE41-NEXT: movntdqa (%rdi), %xmm0 +; SSE41-NEXT: retq ; ; AVX-LABEL: test_load_nt16xi8: ; AVX: # %bb.0: # %entry @@ -320,10 +330,20 @@ entry: } define <8 x i16> @test_load_nt8xi16(<8 x i16>* nocapture %ptr) { -; SSE-LABEL: test_load_nt8xi16: -; SSE: # %bb.0: # %entry -; SSE-NEXT: movntdqa (%rdi), %xmm0 -; SSE-NEXT: retq +; SSE2-LABEL: test_load_nt8xi16: +; SSE2: # %bb.0: # %entry +; SSE2-NEXT: movdqa (%rdi), %xmm0 +; SSE2-NEXT: retq +; +; SSE4A-LABEL: test_load_nt8xi16: +; SSE4A: # %bb.0: # %entry +; SSE4A-NEXT: movdqa (%rdi), %xmm0 +; SSE4A-NEXT: retq +; +; SSE41-LABEL: test_load_nt8xi16: +; SSE41: # %bb.0: # %entry +; SSE41-NEXT: movntdqa (%rdi), %xmm0 +; SSE41-NEXT: retq ; ; AVX-LABEL: test_load_nt8xi16: ; AVX: # %bb.0: # %entry @@ -340,10 +360,20 @@ entry: } define <4 x i32> @test_load_nt4xi32(<4 x i32>* nocapture %ptr) { -; SSE-LABEL: test_load_nt4xi32: -; SSE: # %bb.0: # %entry -; SSE-NEXT: movntdqa (%rdi), %xmm0 -; SSE-NEXT: retq +; SSE2-LABEL: test_load_nt4xi32: +; SSE2: # %bb.0: # %entry +; SSE2-NEXT: movdqa (%rdi), %xmm0 +; SSE2-NEXT: retq +; +; SSE4A-LABEL: test_load_nt4xi32: +; SSE4A: # %bb.0: # %entry +; SSE4A-NEXT: movdqa (%rdi), %xmm0 +; SSE4A-NEXT: retq +; +; SSE41-LABEL: test_load_nt4xi32: +; SSE41: # %bb.0: # %entry +; SSE41-NEXT: movntdqa (%rdi), %xmm0 +; SSE41-NEXT: retq ; ; AVX-LABEL: test_load_nt4xi32: ; AVX: # %bb.0: # %entry @@ -360,10 +390,20 @@ entry: } define <2 x i64> @test_load_nt2xi64(<2 x i64>* nocapture %ptr) { -; SSE-LABEL: test_load_nt2xi64: -; SSE: # %bb.0: # %entry -; SSE-NEXT: movntdqa (%rdi), %xmm0 -; SSE-NEXT: retq +; SSE2-LABEL: test_load_nt2xi64: +; SSE2: # %bb.0: # %entry +; SSE2-NEXT: movdqa (%rdi), %xmm0 +; SSE2-NEXT: retq +; +; SSE4A-LABEL: test_load_nt2xi64: +; SSE4A: # %bb.0: # %entry +; SSE4A-NEXT: movdqa (%rdi), %xmm0 +; SSE4A-NEXT: retq +; +; SSE41-LABEL: test_load_nt2xi64: +; SSE41: # %bb.0: # %entry +; SSE41-NEXT: movntdqa (%rdi), %xmm0 +; SSE41-NEXT: retq ; ; AVX-LABEL: test_load_nt2xi64: ; AVX: # %bb.0: # %entry From 74cfa7acc7b44bde7d950e89d7a21068fb63a907 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Wed, 15 May 2019 04:59:27 +0000 Subject: [PATCH 226/274] Merging r356982: ------------------------------------------------------------------------ r356982 | mstorsjo | 2019-03-26 02:02:44 -0700 (Tue, 26 Mar 2019) | 12 lines [llvm-dlltool] Set a proper machine type for weak symbol object files This makes GNU binutils not reject the libraries outright. GNU ld handles weak externals slightly differently though, so it can't use them for aliases in import libraries, but this makes GNU ld able to use the rest of the import libraries. LLD accepted object files with machine type 0 aka IMAGE_FILE_MACHINE_UNKNOWN. Differential Revision: https://reviews.llvm.org/D59742 ------------------------------------------------------------------------ llvm-svn: 360750 --- llvm/lib/Object/COFFImportFile.cpp | 2 +- llvm/test/tools/llvm-dlltool/coff-weak-exports.def | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Object/COFFImportFile.cpp b/llvm/lib/Object/COFFImportFile.cpp index dc11cc4bcffe6..e7c7efe436764 100644 --- a/llvm/lib/Object/COFFImportFile.cpp +++ b/llvm/lib/Object/COFFImportFile.cpp @@ -496,7 +496,7 @@ NewArchiveMember ObjectFactory::createWeakExternal(StringRef Sym, // COFF Header coff_file_header Header{ - u16(0), + u16(Machine), u16(NumberOfSections), u32(0), u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section))), diff --git a/llvm/test/tools/llvm-dlltool/coff-weak-exports.def b/llvm/test/tools/llvm-dlltool/coff-weak-exports.def index dbc59be8ae189..60f835233a555 100644 --- a/llvm/test/tools/llvm-dlltool/coff-weak-exports.def +++ b/llvm/test/tools/llvm-dlltool/coff-weak-exports.def @@ -1,5 +1,6 @@ ; RUN: llvm-dlltool -m i386:x86-64 --input-def %s --output-lib %t.a ; RUN: llvm-nm %t.a | FileCheck %s +; RUN: llvm-readobj %t.a | FileCheck -check-prefix=ARCH %s LIBRARY test.dll EXPORTS @@ -26,3 +27,5 @@ ImpLibName3 = kernel32.Sleep ; CHECK-NEXT: W __imp_ImpLibName2 ; CHECK: T ImpLibName3 ; CHECK-NEXT: T __imp_ImpLibName3 + +; ARCH-NOT: unknown arch From d9ccd0db27889cbd016637c06290ffaa13faaf70 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Wed, 15 May 2019 05:35:34 +0000 Subject: [PATCH 227/274] Merging r359883: ------------------------------------------------------------------------ r359883 | arsenm | 2019-05-03 06:42:56 -0700 (Fri, 03 May 2019) | 6 lines AMDGPU: Fix incorrect commute with sub when folding immediates When a fold of an immediate into a sub/subrev required shrinking the instruction, the wrong VOP2 opcode was used. This was using the VOP2 equivalent of the original instruction, not the commuted instruction with the inverted opcode. ------------------------------------------------------------------------ llvm-svn: 360752 --- llvm/lib/Target/AMDGPU/SIFoldOperands.cpp | 5 ++++- .../AMDGPU/fold-immediate-operand-shrink.mir | 16 ++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp index f4e8669583699..4e29b73f6fac5 100644 --- a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp +++ b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp @@ -357,7 +357,10 @@ static bool tryAddToFoldList(SmallVectorImpl &FoldList, assert(MI->getOperand(1).isDef()); - int Op32 = AMDGPU::getVOPe32(Opc); + // Make sure to get the 32-bit version of the commuted opcode. + unsigned MaybeCommutedOpc = MI->getOpcode(); + int Op32 = AMDGPU::getVOPe32(MaybeCommutedOpc); + FoldList.push_back(FoldCandidate(MI, CommuteOpNo, OpToFold, true, Op32)); return true; diff --git a/llvm/test/CodeGen/AMDGPU/fold-immediate-operand-shrink.mir b/llvm/test/CodeGen/AMDGPU/fold-immediate-operand-shrink.mir index 847c2b720cd4e..e4ea36f4b1fbf 100644 --- a/llvm/test/CodeGen/AMDGPU/fold-immediate-operand-shrink.mir +++ b/llvm/test/CodeGen/AMDGPU/fold-immediate-operand-shrink.mir @@ -250,8 +250,8 @@ body: | ; GCN-LABEL: name: shrink_scalar_imm_vgpr_v_sub_i32_e64_no_carry_out_use ; GCN: [[S_MOV_B32_:%[0-9]+]]:sreg_32_xm0 = S_MOV_B32 12345 ; GCN: [[DEF:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF - ; GCN: [[V_SUBREV_I32_e32_:%[0-9]+]]:vgpr_32 = V_SUBREV_I32_e32 [[S_MOV_B32_]], [[DEF]], implicit-def $vcc, implicit $exec - ; GCN: S_ENDPGM implicit [[V_SUBREV_I32_e32_]] + ; GCN: [[V_SUB_I32_e32_:%[0-9]+]]:vgpr_32 = V_SUB_I32_e32 [[S_MOV_B32_]], [[DEF]], implicit-def $vcc, implicit $exec + ; GCN: S_ENDPGM implicit [[V_SUB_I32_e32_]] %0:sreg_32_xm0 = S_MOV_B32 12345 %1:vgpr_32 = IMPLICIT_DEF %2:vgpr_32, %3:sreg_64 = V_SUB_I32_e64 %0, %1, implicit $exec @@ -269,8 +269,8 @@ body: | ; GCN-LABEL: name: shrink_vgpr_scalar_imm_v_sub_i32_e64_no_carry_out_use ; GCN: [[DEF:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF ; GCN: [[S_MOV_B32_:%[0-9]+]]:sreg_32_xm0 = S_MOV_B32 12345 - ; GCN: [[V_SUB_I32_e32_:%[0-9]+]]:vgpr_32 = V_SUB_I32_e32 [[S_MOV_B32_]], [[DEF]], implicit-def $vcc, implicit $exec - ; GCN: S_ENDPGM implicit [[V_SUB_I32_e32_]] + ; GCN: [[V_SUBREV_I32_e32_:%[0-9]+]]:vgpr_32 = V_SUBREV_I32_e32 [[S_MOV_B32_]], [[DEF]], implicit-def $vcc, implicit $exec + ; GCN: S_ENDPGM implicit [[V_SUBREV_I32_e32_]] %0:vgpr_32 = IMPLICIT_DEF %1:sreg_32_xm0 = S_MOV_B32 12345 %2:vgpr_32, %3:sreg_64 = V_SUB_I32_e64 %0, %1, implicit $exec @@ -288,8 +288,8 @@ body: | ; GCN-LABEL: name: shrink_scalar_imm_vgpr_v_subrev_i32_e64_no_carry_out_use ; GCN: [[S_MOV_B32_:%[0-9]+]]:sreg_32_xm0 = S_MOV_B32 12345 ; GCN: [[DEF:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF - ; GCN: [[V_SUB_I32_e32_:%[0-9]+]]:vgpr_32 = V_SUB_I32_e32 [[S_MOV_B32_]], [[DEF]], implicit-def $vcc, implicit $exec - ; GCN: S_ENDPGM implicit [[V_SUB_I32_e32_]] + ; GCN: [[V_SUBREV_I32_e32_:%[0-9]+]]:vgpr_32 = V_SUBREV_I32_e32 [[S_MOV_B32_]], [[DEF]], implicit-def $vcc, implicit $exec + ; GCN: S_ENDPGM implicit [[V_SUBREV_I32_e32_]] %0:sreg_32_xm0 = S_MOV_B32 12345 %1:vgpr_32 = IMPLICIT_DEF %2:vgpr_32, %3:sreg_64 = V_SUBREV_I32_e64 %0, %1, implicit $exec @@ -307,8 +307,8 @@ body: | ; GCN-LABEL: name: shrink_vgpr_scalar_imm_v_subrev_i32_e64_no_carry_out_use ; GCN: [[DEF:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF ; GCN: [[S_MOV_B32_:%[0-9]+]]:sreg_32_xm0 = S_MOV_B32 12345 - ; GCN: [[V_SUBREV_I32_e32_:%[0-9]+]]:vgpr_32 = V_SUBREV_I32_e32 [[S_MOV_B32_]], [[DEF]], implicit-def $vcc, implicit $exec - ; GCN: S_ENDPGM implicit [[V_SUBREV_I32_e32_]] + ; GCN: [[V_SUB_I32_e32_:%[0-9]+]]:vgpr_32 = V_SUB_I32_e32 [[S_MOV_B32_]], [[DEF]], implicit-def $vcc, implicit $exec + ; GCN: S_ENDPGM implicit [[V_SUB_I32_e32_]] %0:vgpr_32 = IMPLICIT_DEF %1:sreg_32_xm0 = S_MOV_B32 12345 %2:vgpr_32, %3:sreg_64 = V_SUBREV_I32_e64 %0, %1, implicit $exec From 0eebd31dff806031041214f0121bc2d6d5deb6a6 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Wed, 15 May 2019 18:43:15 +0000 Subject: [PATCH 228/274] Merging r358547: ------------------------------------------------------------------------ r358547 | ruiu | 2019-04-16 19:12:47 -0700 (Tue, 16 Apr 2019) | 9 lines Fix a crash bug caused by a nested call of parallelForEach. parallelForEach is not reentrant. We use parallelForEach to call each section's writeTo(), so calling the same function within writeTo() is not safe. Fixes https://bugs.llvm.org/show_bug.cgi?id=41508 Differential Revision: https://reviews.llvm.org/D60757 ------------------------------------------------------------------------ llvm-svn: 360791 --- lld/wasm/OutputSections.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp index 4123d63b74662..6b7b18d4ca77d 100644 --- a/lld/wasm/OutputSections.cpp +++ b/lld/wasm/OutputSections.cpp @@ -111,8 +111,8 @@ void CodeSection::writeTo(uint8_t *Buf) { memcpy(Buf, CodeSectionHeader.data(), CodeSectionHeader.size()); // Write code section bodies - parallelForEach(Functions, - [&](const InputChunk *Chunk) { Chunk->writeTo(Buf); }); + for (const InputChunk *Chunk : Functions) + Chunk->writeTo(Buf); } uint32_t CodeSection::numRelocations() const { @@ -176,7 +176,7 @@ void DataSection::writeTo(uint8_t *Buf) { // Write data section headers memcpy(Buf, DataSectionHeader.data(), DataSectionHeader.size()); - parallelForEach(Segments, [&](const OutputSegment *Segment) { + for (const OutputSegment *Segment : Segments) { // Write data segment header uint8_t *SegStart = Buf + Segment->SectionOffset; memcpy(SegStart, Segment->Header.data(), Segment->Header.size()); @@ -184,7 +184,7 @@ void DataSection::writeTo(uint8_t *Buf) { // Write segment data payload for (const InputChunk *Chunk : Segment->InputSegments) Chunk->writeTo(Buf); - }); + } } uint32_t DataSection::numRelocations() const { @@ -232,8 +232,8 @@ void CustomSection::writeTo(uint8_t *Buf) { Buf += NameData.size(); // Write custom sections payload - parallelForEach(InputSections, - [&](const InputSection *Section) { Section->writeTo(Buf); }); + for (const InputSection *Section : InputSections) + Section->writeTo(Buf); } uint32_t CustomSection::numRelocations() const { From 3f38b9ebadfdabb34f9f86ef6137e70ed89cdecc Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Wed, 15 May 2019 18:47:52 +0000 Subject: [PATCH 229/274] Merging r355621: ------------------------------------------------------------------------ r355621 | petarj | 2019-03-07 10:28:44 -0800 (Thu, 07 Mar 2019) | 5 lines fix expected format in test/ELF/eh-frame-hdr-augmentation.s Follow-up for r355605. Fix expected format in test/ELF/eh-frame-hdr-augmentation.s ------------------------------------------------------------------------ llvm-svn: 360792 --- lld/test/ELF/eh-frame-hdr-augmentation.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lld/test/ELF/eh-frame-hdr-augmentation.s b/lld/test/ELF/eh-frame-hdr-augmentation.s index 934f9200a27ca..c51ea1c4976b9 100644 --- a/lld/test/ELF/eh-frame-hdr-augmentation.s +++ b/lld/test/ELF/eh-frame-hdr-augmentation.s @@ -11,7 +11,7 @@ // CHECK-NEXT: Code alignment factor: 1 // CHECK-NEXT: Data alignment factor: -8 // CHECK-NEXT: Return address column: 16 -// CHECK-NEXT: Personality Address: 00000dad +// CHECK-NEXT: Personality Address: 0000000000000dad // CHECK-NEXT: Augmentation data: // CHECK: DW_CFA_def_cfa: reg7 +8 @@ -20,7 +20,7 @@ // CHECK-NEXT: DW_CFA_nop: // CHECK: 00000020 00000014 00000024 FDE cie=00000024 pc=00000d98...00000d98 -// CHECK-NEXT: LSDA Address: 00000d8f +// CHECK-NEXT: LSDA Address: 0000000000000d8f // CHECK-NEXT: DW_CFA_nop: // CHECK-NEXT: DW_CFA_nop: // CHECK-NEXT: DW_CFA_nop: From 2570e4bb99c902bd59e42d04c355648297479348 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Wed, 15 May 2019 18:59:16 +0000 Subject: [PATCH 230/274] Merging r360099: ------------------------------------------------------------------------ r360099 | efriedma | 2019-05-06 16:21:59 -0700 (Mon, 06 May 2019) | 26 lines [ARM] Glue register copies to tail calls. This generally follows what other targets do. I don't completely understand why the special case for tail calls existed in the first place; even when the code was committed in r105413, call lowering didn't work in the way described in the comments. Stack protector lowering breaks if the register copies are not glued to a tail call: we have to insert the stack protector check before the tail call, and we choose the location based on the assumption that all physical register dependencies of a tail call are adjacent to the tail call. (See FindSplitPointForStackProtector.) This is sort of fragile, but I don't see any reason to break that assumption. I'm guessing nobody has seen this before just because it's hard to convince the scheduler to actually schedule the code in a way that breaks; even without the glue, the only computation that could actually be scheduled after the register copies is the computation of the call address, and the scheduler usually prefers to schedule that before the copies anyway. Fixes https://bugs.llvm.org/show_bug.cgi?id=41417 Differential Revision: https://reviews.llvm.org/D60427 ------------------------------------------------------------------------ llvm-svn: 360793 --- llvm/lib/Target/ARM/ARMISelLowering.cpp | 30 +++------------- llvm/test/CodeGen/ARM/tail-call-scheduling.ll | 35 +++++++++++++++++++ 2 files changed, 39 insertions(+), 26 deletions(-) create mode 100644 llvm/test/CodeGen/ARM/tail-call-scheduling.ll diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 21de0f6a7630e..7e90edbbdabb9 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -1984,32 +1984,10 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // Build a sequence of copy-to-reg nodes chained together with token chain // and flag operands which copy the outgoing args into the appropriate regs. SDValue InFlag; - // Tail call byval lowering might overwrite argument registers so in case of - // tail call optimization the copies to registers are lowered later. - if (!isTailCall) - for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { - Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, - RegsToPass[i].second, InFlag); - InFlag = Chain.getValue(1); - } - - // For tail calls lower the arguments to the 'real' stack slot. - if (isTailCall) { - // Force all the incoming stack arguments to be loaded from the stack - // before any new outgoing arguments are stored to the stack, because the - // outgoing stack slots may alias the incoming argument stack slots, and - // the alias isn't otherwise explicit. This is slightly more conservative - // than necessary, because it means that each store effectively depends - // on every argument instead of just those arguments it would clobber. - - // Do not flag preceding copytoreg stuff together with the following stuff. - InFlag = SDValue(); - for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { - Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, - RegsToPass[i].second, InFlag); - InFlag = Chain.getValue(1); - } - InFlag = SDValue(); + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { + Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, + RegsToPass[i].second, InFlag); + InFlag = Chain.getValue(1); } // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every diff --git a/llvm/test/CodeGen/ARM/tail-call-scheduling.ll b/llvm/test/CodeGen/ARM/tail-call-scheduling.ll new file mode 100644 index 0000000000000..591da10256ba4 --- /dev/null +++ b/llvm/test/CodeGen/ARM/tail-call-scheduling.ll @@ -0,0 +1,35 @@ +; RUN: llc < %s | FileCheck %s +target triple = "armv6kz-unknown-unknown-gnueabihf" + +; Make sure this doesn't crash, and we actually emit a tail call. +; Unfortunately, this test is sort of fragile... the original issue only +; shows up if scheduling happens in a very specific order. But including +; it anyway just to demonstrate the issue. +; CHECK: pop {r4, lr} + +@e = external local_unnamed_addr constant [0 x i32 (i32, i32)*], align 4 + +; Function Attrs: nounwind sspstrong +define i32 @AVI_ChunkRead_p_chk(i32 %g) nounwind sspstrong "target-cpu"="arm1176jzf-s" { +entry: + %b = alloca i8, align 1 + %tobool = icmp eq i32 %g, 0 + br i1 %tobool, label %if.end, label %if.then + +if.then: ; preds = %entry + %add = add nsw i32 %g, 1 + %arrayidx = getelementptr inbounds [0 x i32 (i32, i32)*], [0 x i32 (i32, i32)*]* @e, i32 0, i32 %add + %0 = load i32 (i32, i32)*, i32 (i32, i32)** %arrayidx, align 4 + %call = tail call i32 %0(i32 0, i32 0) #3 + br label %return + +if.end: ; preds = %entry + call void @c(i8* nonnull %b) + br label %return + +return: ; preds = %if.end, %if.then + %retval.0 = phi i32 [ %call, %if.then ], [ 0, %if.end ] + ret i32 %retval.0 +} + +declare void @c(i8*) From 35349ba713a0c30b3c1849bcfab20d85add38ebd Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Wed, 15 May 2019 20:12:49 +0000 Subject: [PATCH 231/274] Merging r359569: ------------------------------------------------------------------------ r359569 | russell_gallop | 2019-04-30 08:35:16 -0700 (Tue, 30 Apr 2019) | 7 lines Add llvm-profdata to LLVM_TOOLCHAIN_TOOLS This is required for using PGO on Windows but isn't in the Windows release packages. Windows packages are built with LLVM_INSTALL_TOOLCHAIN_ONLY so only includes llvm "tools" listed here. Differential Revision: https://reviews.llvm.org/D61317 ------------------------------------------------------------------------ llvm-svn: 360801 --- llvm/cmake/modules/AddLLVM.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index 0df6845aaa71d..1a417447278b8 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -855,6 +855,7 @@ if(NOT LLVM_TOOLCHAIN_TOOLS) llvm-lib llvm-objdump llvm-rc + llvm-profdata ) endif() From 9916d8de7da5c9438af96203602aeeeaca033d84 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Wed, 15 May 2019 20:17:25 +0000 Subject: [PATCH 232/274] Merging r355141: ------------------------------------------------------------------------ r355141 | rnk | 2019-02-28 13:05:41 -0800 (Thu, 28 Feb 2019) | 11 lines [COFF] Add address-taken import thunks to the fid table Summary: Fixes PR39799 Reviewers: dmajor, hans Subscribers: jdoerfert, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D58739 ------------------------------------------------------------------------ llvm-svn: 360803 --- lld/COFF/Writer.cpp | 50 +++++++++++++++++++++++++++-------- lld/test/COFF/guardcf-thunk.s | 43 ++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 lld/test/COFF/guardcf-thunk.s diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 6acfaf9a44545..56b797451cfc7 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -1351,19 +1351,47 @@ static void addSymbolToRVASet(SymbolRVASet &RVASet, Defined *S) { // symbol in an executable section. static void maybeAddAddressTakenFunction(SymbolRVASet &AddressTakenSyms, Symbol *S) { - auto *D = dyn_cast_or_null(S); - - // Ignore undefined symbols and references to non-functions (e.g. globals and - // labels). - if (!D || - D->getCOFFSymbol().getComplexType() != COFF::IMAGE_SYM_DTYPE_FUNCTION) + if (!S) return; - // Mark the symbol as address taken if it's in an executable section. - Chunk *RefChunk = D->getChunk(); - OutputSection *OS = RefChunk ? RefChunk->getOutputSection() : nullptr; - if (OS && OS->Header.Characteristics & IMAGE_SCN_MEM_EXECUTE) - addSymbolToRVASet(AddressTakenSyms, D); + switch (S->kind()) { + case Symbol::DefinedLocalImportKind: + case Symbol::DefinedImportDataKind: + // Defines an __imp_ pointer, so it is data, so it is ignored. + break; + case Symbol::DefinedCommonKind: + // Common is always data, so it is ignored. + break; + case Symbol::DefinedAbsoluteKind: + case Symbol::DefinedSyntheticKind: + // Absolute is never code, synthetic generally isn't and usually isn't + // determinable. + break; + case Symbol::LazyKind: + case Symbol::UndefinedKind: + // Undefined symbols resolve to zero, so they don't have an RVA. Lazy + // symbols shouldn't have relocations. + break; + + case Symbol::DefinedImportThunkKind: + // Thunks are always code, include them. + addSymbolToRVASet(AddressTakenSyms, cast(S)); + break; + + case Symbol::DefinedRegularKind: { + // This is a regular, defined, symbol from a COFF file. Mark the symbol as + // address taken if the symbol type is function and it's in an executable + // section. + auto *D = cast(S); + if (D->getCOFFSymbol().getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) { + Chunk *RefChunk = D->getChunk(); + OutputSection *OS = RefChunk ? RefChunk->getOutputSection() : nullptr; + if (OS && OS->Header.Characteristics & IMAGE_SCN_MEM_EXECUTE) + addSymbolToRVASet(AddressTakenSyms, D); + } + break; + } + } } // Visit all relocations from all section contributions of this object file and diff --git a/lld/test/COFF/guardcf-thunk.s b/lld/test/COFF/guardcf-thunk.s new file mode 100644 index 0000000000000..0969c580ac9f6 --- /dev/null +++ b/lld/test/COFF/guardcf-thunk.s @@ -0,0 +1,43 @@ +# REQUIRES: x86 + +# Make a DLL that exports exportfn1. +# RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj +# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /implib:%t.lib + +# Make an obj that takes the address of that exported function. +# RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc %s -o %t2.obj +# RUN: lld-link -entry:main -guard:cf %t2.obj %t.lib -nodefaultlib -out:%t.exe +# RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s + +# Check that the gfids table contains *exactly* two entries, one for exportfn1 +# and one for main. +# CHECK: GuardFidTable [ +# CHECK-NEXT: 0x{{[0-9A-Fa-f]+0$}} +# CHECK-NEXT: 0x{{[0-9A-Fa-f]+0$}} +# CHECK-NEXT: ] + + + .def @feat.00; + .scl 3; + .type 0; + .endef + .globl @feat.00 +@feat.00 = 0x001 + + .section .text,"rx" + .def main; .scl 2; .type 32; .endef + .global main +main: + leaq exportfn1(%rip), %rax + retq + + .section .rdata,"dr" +.globl _load_config_used +_load_config_used: + .long 256 + .fill 124, 1, 0 + .quad __guard_fids_table + .quad __guard_fids_count + .long __guard_flags + .fill 128, 1, 0 + From e58d5a45e1e1c283d3247852fa659d324f4e2e8f Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Wed, 15 May 2019 20:29:49 +0000 Subject: [PATCH 233/274] Merging r360212: ------------------------------------------------------------------------ r360212 | kamil | 2019-05-07 17:44:41 -0700 (Tue, 07 May 2019) | 6 lines Fix build on NetBSD 8.99.38 With recent changes the dev/nvmm/nvmm_ioctl.h header is no longer a standalone NVMM header. Disable it until the NVMM operations will stabilize and be included in the ioctl(2) interceptors. ------------------------------------------------------------------------ llvm-svn: 360811 --- .../lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc index c112e044b1d82..c32c80b3e48be 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc @@ -124,7 +124,9 @@ #include #include #include +#if 0 #include +#endif #include #include #include From bc6695ca2dd240650a0df7b61906c77da8a8dac6 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Wed, 15 May 2019 23:31:56 +0000 Subject: [PATCH 234/274] Merging r354846: ------------------------------------------------------------------------ r354846 | djg | 2019-02-25 21:20:19 -0800 (Mon, 25 Feb 2019) | 12 lines [WebAssembly] Properly align fp128 arguments in outgoing varargs arguments For outgoing varargs arguments, it's necessary to check the OrigAlign field of the corresponding OutputArg entry to determine argument alignment, rather than just computing an alignment from the argument value type. This is because types like fp128 are split into multiple argument values, with narrower types that don't reflect the ABI alignment of the full fp128. This fixes the printf("printfL: %4.*Lf\n", 2, lval); testcase. Differential Revision: https://reviews.llvm.org/D58656 ------------------------------------------------------------------------ llvm-svn: 360826 --- .../WebAssembly/WebAssemblyISelLowering.cpp | 9 ++++--- llvm/test/CodeGen/WebAssembly/varargs.ll | 26 +++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index 003848e342279..f7f29d85cbb27 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -669,13 +669,16 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI, if (IsVarArg) { // Outgoing non-fixed arguments are placed in a buffer. First // compute their offsets and the total amount of buffer space needed. - for (SDValue Arg : - make_range(OutVals.begin() + NumFixedArgs, OutVals.end())) { + for (unsigned I = NumFixedArgs; I < Outs.size(); ++I) { + const ISD::OutputArg &Out = Outs[I]; + SDValue &Arg = OutVals[I]; EVT VT = Arg.getValueType(); assert(VT != MVT::iPTR && "Legalized args should be concrete"); Type *Ty = VT.getTypeForEVT(*DAG.getContext()); + unsigned Align = std::max(Out.Flags.getOrigAlign(), + Layout.getABITypeAlignment(Ty)); unsigned Offset = CCInfo.AllocateStack(Layout.getTypeAllocSize(Ty), - Layout.getABITypeAlignment(Ty)); + Align); CCInfo.addLoc(CCValAssign::getMem(ArgLocs.size(), VT.getSimpleVT(), Offset, VT.getSimpleVT(), CCValAssign::Full)); diff --git a/llvm/test/CodeGen/WebAssembly/varargs.ll b/llvm/test/CodeGen/WebAssembly/varargs.ll index 1a73716c2a67c..5a8df4cd2fec4 100644 --- a/llvm/test/CodeGen/WebAssembly/varargs.ll +++ b/llvm/test/CodeGen/WebAssembly/varargs.ll @@ -163,6 +163,32 @@ define void @nonlegal_fixed(fp128 %x, ...) nounwind { ret void } +; Test that an fp128 argument is properly aligned and allocated +; within a vararg buffer. + +; CHECK-LABEL: call_fp128_alignment: +; CHECK: global.get $push7=, __stack_pointer +; CHECK-NEXT: i32.const $push8=, 32 +; CHECK-NEXT: i32.sub $push12=, $pop7, $pop8 +; CHECK-NEXT: local.tee $push11=, $1=, $pop12 +; CHECK-NEXT: global.set __stack_pointer@GLOBAL, $pop11 +; CHECK-NEXT: i32.const $push0=, 24 +; CHECK-NEXT: i32.add $push1=, $1, $pop0 +; CHECK-NEXT: i64.const $push2=, -9223372036854775808 +; CHECK-NEXT: i64.store 0($pop1), $pop2 +; CHECK-NEXT: i32.const $push3=, 16 +; CHECK-NEXT: i32.add $push4=, $1, $pop3 +; CHECK-NEXT: i64.const $push5=, 1 +; CHECK-NEXT: i64.store 0($pop4), $pop5 +; CHECK-NEXT: i32.const $push6=, 7 +; CHECK-NEXT: i32.store 0($1), $pop6 +; CHECK-NEXT: call callee@FUNCTION, $1 +define void @call_fp128_alignment(i8* %p) { +entry: + call void (...) @callee(i8 7, fp128 0xL00000000000000018000000000000000) + ret void +} + declare void @llvm.va_start(i8*) declare void @llvm.va_end(i8*) declare void @llvm.va_copy(i8*, i8*) From 05288f5020de74ced1c22a11d9406ee2c90bb807 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 16 May 2019 00:07:53 +0000 Subject: [PATCH 235/274] Merging r360674: ------------------------------------------------------------------------ r360674 | russell_gallop | 2019-05-14 07:01:40 -0700 (Tue, 14 May 2019) | 7 lines [Driver][Windows] Add dependent lib argument for profile instr generate This is needed so lld-link can find clang_rt.profile when self hosting on Windows with PGO. Using clang-cl as a linker knows to add the library but self hosting, using -DCMAKE_LINKER=<...>/lld-link.exe doesn't. Differential Revision: https://reviews.llvm.org/D61742 ------------------------------------------------------------------------ llvm-svn: 360828 --- clang/lib/Driver/ToolChains/Clang.cpp | 12 +++++++++--- clang/test/Driver/cl-options.c | 2 +- clang/test/Driver/instrprof-ld.c | 14 ++++++++++++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 589f53b119217..78ee7a78176ff 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -718,8 +718,9 @@ static void appendUserToPath(SmallVectorImpl &Result) { Result.append(UID.begin(), UID.end()); } -static void addPGOAndCoverageFlags(Compilation &C, const Driver &D, - const InputInfo &Output, const ArgList &Args, +static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C, + const Driver &D, const InputInfo &Output, + const ArgList &Args, ArgStringList &CmdArgs) { auto *PGOGenerateArg = Args.getLastArg(options::OPT_fprofile_generate, @@ -759,6 +760,11 @@ static void addPGOAndCoverageFlags(Compilation &C, const Driver &D, ProfileGenerateArg->getValue())); // The default is to use Clang Instrumentation. CmdArgs.push_back("-fprofile-instrument=clang"); + if (TC.getTriple().isWindowsMSVCEnvironment()) { + // Add dependent lib for clang_rt.profile + CmdArgs.push_back(Args.MakeArgString("--dependent-lib=" + + TC.getCompilerRT(Args, "profile"))); + } } if (PGOGenerateArg) { @@ -4118,7 +4124,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // sampling, overhead of call arc collection is way too high and there's no // way to collect the output. if (!Triple.isNVPTX()) - addPGOAndCoverageFlags(C, D, Output, Args, CmdArgs); + addPGOAndCoverageFlags(TC, C, D, Output, Args, CmdArgs); if (auto *ABICompatArg = Args.getLastArg(options::OPT_fclang_abi_compat_EQ)) ABICompatArg->render(Args, CmdArgs); diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c index 909e391cec6ab..5048fd25c4a7d 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -66,7 +66,7 @@ // RUN: %clang_cl -### /FA -fprofile-instr-generate=/tmp/somefile.profraw -- %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE-FILE %s // RUN: %clang_cl -### /FA -fprofile-instr-generate -fprofile-instr-use -- %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MIX-GEN-USE %s // RUN: %clang_cl -### /FA -fprofile-instr-generate -fprofile-instr-use=file -- %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MIX-GEN-USE %s -// CHECK-PROFILE-GENERATE: "-fprofile-instrument=clang" +// CHECK-PROFILE-GENERATE: "-fprofile-instrument=clang" "--dependent-lib={{[^"]*}}clang_rt.profile-{{[^"]*}}.lib" // CHECK-PROFILE-GENERATE-FILE: "-fprofile-instrument-path=/tmp/somefile.profraw" // CHECK-NO-MIX-GEN-USE: '{{[a-z=-]*}}' not allowed with '{{[a-z=-]*}}' diff --git a/clang/test/Driver/instrprof-ld.c b/clang/test/Driver/instrprof-ld.c index ea20105699758..1ac3f9650ff3e 100644 --- a/clang/test/Driver/instrprof-ld.c +++ b/clang/test/Driver/instrprof-ld.c @@ -121,3 +121,17 @@ // // CHECK-WINDOWS-X86-64: "{{.*}}link{{(.exe)?}}" // CHECK-WINDOWS-X86-64: "{{.*}}clang_rt.profile-x86_64.lib" + +// Test instrumented profiling dependent-lib flags +// +// RUN: %clang %s -### -o %t.o -target x86_64-pc-win32 \ +// RUN: -fprofile-instr-generate 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-WINDOWS-X86-64-DEPENDENT-LIB %s +// +// CHECK-WINDOWS-X86-64-DEPENDENT-LIB: "--dependent-lib={{[^"]*}}clang_rt.profile-{{[^"]*}}.lib" +// +// RUN: %clang %s -### -o %t.o -target x86_64-mingw32 \ +// RUN: -fprofile-instr-generate 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-MINGW-X86-64-DEPENDENT-LIB %s +// +// CHECK-MINGW-X86-64-DEPENDENT-LIB-NOT: "--dependent-lib={{[^"]*}}clang_rt.profile-{{[^"]*}}.a" From 4b1712f7006ca2ef05408e46cd7b745f153870bc Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 16 May 2019 22:36:46 +0000 Subject: [PATCH 236/274] Merging r352806: ------------------------------------------------------------------------ r352806 | sbc | 2019-01-31 14:38:22 -0800 (Thu, 31 Jan 2019) | 5 lines [WebAssembly] MC: Fix for outputing wasm object to /dev/null Subscribers: dschuff, jgravelle-google, aheejin, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D57479 ------------------------------------------------------------------------ llvm-svn: 360949 --- llvm/lib/MC/WasmObjectWriter.cpp | 8 +++++++- llvm/test/MC/WebAssembly/null-output.s | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 llvm/test/MC/WebAssembly/null-output.s diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp index 333748db91904..b07fe05cad5b9 100644 --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -368,7 +368,13 @@ void WasmObjectWriter::startCustomSection(SectionBookkeeping &Section, // Now that the section is complete and we know how big it is, patch up the // section size field at the start of the section. void WasmObjectWriter::endSection(SectionBookkeeping &Section) { - uint64_t Size = W.OS.tell() - Section.PayloadOffset; + uint64_t Size = W.OS.tell(); + // /dev/null doesn't support seek/tell and can report offset of 0. + // Simply skip this patching in that case. + if (!Size) + return; + + Size -= Section.PayloadOffset; if (uint32_t(Size) != Size) report_fatal_error("section size does not fit in a uint32_t"); diff --git a/llvm/test/MC/WebAssembly/null-output.s b/llvm/test/MC/WebAssembly/null-output.s new file mode 100644 index 0000000000000..a25d095e0cbef --- /dev/null +++ b/llvm/test/MC/WebAssembly/null-output.s @@ -0,0 +1,10 @@ +# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -o /dev/null < %s + + .text + .section .text.main,"",@ + .type main,@function +main: + .functype main (i32, i32) -> (i32) + end_function +.Lfunc_end0: + .size main, .Lfunc_end0-main From 9124fda0adfec205856a1ecca76d2cead11a0e2c Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 16 May 2019 22:49:01 +0000 Subject: [PATCH 237/274] Merging r355038: ------------------------------------------------------------------------ r355038 | joerg | 2019-02-27 13:53:14 -0800 (Wed, 27 Feb 2019) | 3 lines Default to Secure PLT on PPC for NetBSD and OpenBSD. This matches the default settings of clang. ------------------------------------------------------------------------ llvm-svn: 360950 --- llvm/lib/Target/PowerPC/PPCSubtarget.cpp | 3 +++ llvm/test/CodeGen/PowerPC/ppc32-pic-large.ll | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp index c0cbfd779cb90..1fdf74549dec1 100644 --- a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp +++ b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp @@ -138,6 +138,9 @@ void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) { if (isDarwin()) HasLazyResolverStubs = true; + if (TargetTriple.isOSNetBSD() || TargetTriple.isOSOpenBSD()) + SecurePlt = true; + if (HasSPE && IsPPC64) report_fatal_error( "SPE is only supported for 32-bit targets.\n", false); if (HasSPE && (HasAltivec || HasQPX || HasVSX || HasFPU)) diff --git a/llvm/test/CodeGen/PowerPC/ppc32-pic-large.ll b/llvm/test/CodeGen/PowerPC/ppc32-pic-large.ll index d6e491ea2734c..272138e5121bf 100644 --- a/llvm/test/CodeGen/PowerPC/ppc32-pic-large.ll +++ b/llvm/test/CodeGen/PowerPC/ppc32-pic-large.ll @@ -1,5 +1,9 @@ ; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic | FileCheck -check-prefix=LARGE-BSS %s ; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -mattr=+secure-plt -relocation-model=pic | FileCheck -check-prefix=LARGE-SECUREPLT %s +; RUN: llc < %s -mtriple=powerpc-unknown-netbsd -mattr=+secure-plt -relocation-model=pic | FileCheck -check-prefix=LARGE-SECUREPLT %s +; RUN: llc < %s -mtriple=powerpc-unknown-netbsd -relocation-model=pic | FileCheck -check-prefix=LARGE-SECUREPLT %s +; RUN: llc < %s -mtriple=powerpc-unknown-openbsd -mattr=+secure-plt -relocation-model=pic | FileCheck -check-prefix=LARGE-SECUREPLT %s +; RUN: llc < %s -mtriple=powerpc-unknown-openbsd -relocation-model=pic | FileCheck -check-prefix=LARGE-SECUREPLT %s @bar = common global i32 0, align 4 declare i32 @call_foo(i32, ...) From 1a19847514e073ebd31f32914bd018236bb911a8 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 23 May 2019 20:44:14 +0000 Subject: [PATCH 238/274] Merging r351523: ------------------------------------------------------------------------ r351523 | dylanmckay | 2019-01-17 22:10:41 -0800 (Thu, 17 Jan 2019) | 12 lines [AVR] Expand 8/16-bit multiplication to libcalls on MCUs that don't have hardware MUL This change modifies the LLVM ISel lowering settings so that 8-bit/16-bit multiplication is expanded to calls into the compiler runtime library if the MCU being targeted does not support multiplication in hardware. Before this, MUL instructions would be generated on CPUs like the ATtiny85, triggering a CPU reset due to an illegal instruction at runtime. First raised in https://github.com/avr-rust/rust/issues/124. ------------------------------------------------------------------------ llvm-svn: 361551 --- llvm/lib/Target/AVR/AVRISelLowering.cpp | 28 +++++++++++-------- llvm/lib/Target/AVR/AVRISelLowering.h | 8 +++++- llvm/lib/Target/AVR/AVRSubtarget.cpp | 12 ++++++-- llvm/lib/Target/AVR/AVRSubtarget.h | 5 +++- .../CodeGen/AVR/{mul.ll => hardware-mul.ll} | 2 ++ llvm/test/CodeGen/AVR/smul-with-overflow.ll | 2 +- llvm/test/CodeGen/AVR/software-mul.ll | 28 +++++++++++++++++++ llvm/test/CodeGen/AVR/umul-with-overflow.ll | 2 +- 8 files changed, 70 insertions(+), 17 deletions(-) rename llvm/test/CodeGen/AVR/{mul.ll => hardware-mul.ll} (90%) create mode 100644 llvm/test/CodeGen/AVR/software-mul.ll diff --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp index 57fc978b54bb6..5db7577823226 100644 --- a/llvm/lib/Target/AVR/AVRISelLowering.cpp +++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp @@ -26,19 +26,21 @@ #include "AVR.h" #include "AVRMachineFunctionInfo.h" +#include "AVRSubtarget.h" #include "AVRTargetMachine.h" #include "MCTargetDesc/AVRMCTargetDesc.h" namespace llvm { -AVRTargetLowering::AVRTargetLowering(AVRTargetMachine &tm) - : TargetLowering(tm) { +AVRTargetLowering::AVRTargetLowering(const AVRTargetMachine &TM, + const AVRSubtarget &STI) + : TargetLowering(TM), Subtarget(STI) { // Set up the register classes. addRegisterClass(MVT::i8, &AVR::GPR8RegClass); addRegisterClass(MVT::i16, &AVR::DREGSRegClass); // Compute derived properties from the register classes. - computeRegisterProperties(tm.getSubtargetImpl()->getRegisterInfo()); + computeRegisterProperties(Subtarget.getRegisterInfo()); setBooleanContents(ZeroOrOneBooleanContent); setBooleanVectorContents(ZeroOrOneBooleanContent); @@ -163,6 +165,13 @@ AVRTargetLowering::AVRTargetLowering(AVRTargetMachine &tm) setOperationAction(ISD::SMUL_LOHI, MVT::i16, Expand); setOperationAction(ISD::UMUL_LOHI, MVT::i16, Expand); + // Expand multiplications to libcalls when there is + // no hardware MUL. + if (!Subtarget.supportsMultiplication()) { + setOperationAction(ISD::SMUL_LOHI, MVT::i8, Expand); + setOperationAction(ISD::UMUL_LOHI, MVT::i8, Expand); + } + for (MVT VT : MVT::integer_valuetypes()) { setOperationAction(ISD::MULHS, VT, Expand); setOperationAction(ISD::MULHU, VT, Expand); @@ -1271,7 +1280,7 @@ SDValue AVRTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // Add a register mask operand representing the call-preserved registers. const AVRTargetMachine &TM = (const AVRTargetMachine &)getTargetMachine(); - const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo(); + const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); const uint32_t *Mask = TRI->getCallPreservedMask(DAG.getMachineFunction(), CallConv); assert(Mask && "Missing call preserved mask for calling convention"); @@ -1434,7 +1443,7 @@ MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI, MachineFunction *F = BB->getParent(); MachineRegisterInfo &RI = F->getRegInfo(); const AVRTargetMachine &TM = (const AVRTargetMachine &)getTargetMachine(); - const TargetInstrInfo &TII = *TM.getSubtargetImpl()->getInstrInfo(); + const TargetInstrInfo &TII = *Subtarget.getInstrInfo(); DebugLoc dl = MI.getDebugLoc(); switch (MI.getOpcode()) { @@ -1575,7 +1584,7 @@ static bool isCopyMulResult(MachineBasicBlock::iterator const &I) { MachineBasicBlock *AVRTargetLowering::insertMul(MachineInstr &MI, MachineBasicBlock *BB) const { const AVRTargetMachine &TM = (const AVRTargetMachine &)getTargetMachine(); - const TargetInstrInfo &TII = *TM.getSubtargetImpl()->getInstrInfo(); + const TargetInstrInfo &TII = *Subtarget.getInstrInfo(); MachineBasicBlock::iterator I(MI); ++I; // in any case insert *after* the mul instruction if (isCopyMulResult(I)) @@ -1838,9 +1847,6 @@ std::pair AVRTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const { - auto STI = static_cast(this->getTargetMachine()) - .getSubtargetImpl(); - // We only support i8 and i16. // //:FIXME: remove this assert for now since it gets sometimes executed @@ -1884,8 +1890,8 @@ AVRTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, } } - return TargetLowering::getRegForInlineAsmConstraint(STI->getRegisterInfo(), - Constraint, VT); + return TargetLowering::getRegForInlineAsmConstraint( + Subtarget.getRegisterInfo(), Constraint, VT); } void AVRTargetLowering::LowerAsmOperandForConstraint(SDValue Op, diff --git a/llvm/lib/Target/AVR/AVRISelLowering.h b/llvm/lib/Target/AVR/AVRISelLowering.h index c90c65c81f700..7d77dd8fb0188 100644 --- a/llvm/lib/Target/AVR/AVRISelLowering.h +++ b/llvm/lib/Target/AVR/AVRISelLowering.h @@ -64,12 +64,14 @@ enum NodeType { } // end of namespace AVRISD +class AVRSubtarget; class AVRTargetMachine; /// Performs target lowering for the AVR. class AVRTargetLowering : public TargetLowering { public: - explicit AVRTargetLowering(AVRTargetMachine &TM); + explicit AVRTargetLowering(const AVRTargetMachine &TM, + const AVRSubtarget &STI); public: MVT getScalarShiftAmountTy(const DataLayout &, EVT LHSTy) const override { @@ -164,6 +166,10 @@ class AVRTargetLowering : public TargetLowering { const SDLoc &dl, SelectionDAG &DAG, SmallVectorImpl &InVals) const; +protected: + + const AVRSubtarget &Subtarget; + private: MachineBasicBlock *insertShift(MachineInstr &MI, MachineBasicBlock *BB) const; MachineBasicBlock *insertMul(MachineInstr &MI, MachineBasicBlock *BB) const; diff --git a/llvm/lib/Target/AVR/AVRSubtarget.cpp b/llvm/lib/Target/AVR/AVRSubtarget.cpp index 556d69ec52341..c7c566270f432 100644 --- a/llvm/lib/Target/AVR/AVRSubtarget.cpp +++ b/llvm/lib/Target/AVR/AVRSubtarget.cpp @@ -29,9 +29,9 @@ namespace llvm { AVRSubtarget::AVRSubtarget(const Triple &TT, const std::string &CPU, - const std::string &FS, AVRTargetMachine &TM) + const std::string &FS, const AVRTargetMachine &TM) : AVRGenSubtargetInfo(TT, CPU, FS), InstrInfo(), FrameLowering(), - TLInfo(TM), TSInfo(), + TLInfo(TM, initializeSubtargetDependencies(CPU, FS, TM)), TSInfo(), // Subtarget features m_hasSRAM(false), m_hasJMPCALL(false), m_hasIJMPCALL(false), @@ -44,4 +44,12 @@ AVRSubtarget::AVRSubtarget(const Triple &TT, const std::string &CPU, ParseSubtargetFeatures(CPU, FS); } +AVRSubtarget & +AVRSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS, + const TargetMachine &TM) { + // Parse features string. + ParseSubtargetFeatures(CPU, FS); + return *this; +} + } // end of namespace llvm diff --git a/llvm/lib/Target/AVR/AVRSubtarget.h b/llvm/lib/Target/AVR/AVRSubtarget.h index fa26738da1900..ba036d5e40616 100644 --- a/llvm/lib/Target/AVR/AVRSubtarget.h +++ b/llvm/lib/Target/AVR/AVRSubtarget.h @@ -37,7 +37,7 @@ class AVRSubtarget : public AVRGenSubtargetInfo { //! \param FS The feature string. //! \param TM The target machine. AVRSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS, - AVRTargetMachine &TM); + const AVRTargetMachine &TM); const AVRInstrInfo *getInstrInfo() const override { return &InstrInfo; } const TargetFrameLowering *getFrameLowering() const override { return &FrameLowering; } @@ -49,6 +49,9 @@ class AVRSubtarget : public AVRGenSubtargetInfo { /// \note Definition of function is auto generated by `tblgen`. void ParseSubtargetFeatures(StringRef CPU, StringRef FS); + AVRSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS, + const TargetMachine &TM); + // Subtarget feature getters. // See AVR.td for details. bool hasSRAM() const { return m_hasSRAM; } diff --git a/llvm/test/CodeGen/AVR/mul.ll b/llvm/test/CodeGen/AVR/hardware-mul.ll similarity index 90% rename from llvm/test/CodeGen/AVR/mul.ll rename to llvm/test/CodeGen/AVR/hardware-mul.ll index 2f169347c46e0..650697857b76b 100644 --- a/llvm/test/CodeGen/AVR/mul.ll +++ b/llvm/test/CodeGen/AVR/hardware-mul.ll @@ -1,5 +1,7 @@ ; RUN: llc -mattr=mul,movw < %s -march=avr | FileCheck %s +; Tests lowering of multiplication to hardware instructions. + define i8 @mult8(i8 %a, i8 %b) { ; CHECK-LABEL: mult8: ; CHECK: muls r22, r24 diff --git a/llvm/test/CodeGen/AVR/smul-with-overflow.ll b/llvm/test/CodeGen/AVR/smul-with-overflow.ll index 745e93005cc2f..9eb2c7411dee8 100644 --- a/llvm/test/CodeGen/AVR/smul-with-overflow.ll +++ b/llvm/test/CodeGen/AVR/smul-with-overflow.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=avr | FileCheck %s +; RUN: llc -mattr=avr6 < %s -march=avr | FileCheck %s define i1 @signed_multiplication_did_overflow(i8, i8) unnamed_addr { ; CHECK-LABEL: signed_multiplication_did_overflow: diff --git a/llvm/test/CodeGen/AVR/software-mul.ll b/llvm/test/CodeGen/AVR/software-mul.ll new file mode 100644 index 0000000000000..9a4d28127eb87 --- /dev/null +++ b/llvm/test/CodeGen/AVR/software-mul.ll @@ -0,0 +1,28 @@ +; RUN: llc -mattr=avr6,-mul < %s -march=avr | FileCheck %s +; RUN: llc -mcpu=attiny85 < %s -march=avr | FileCheck %s +; RUN: llc -mcpu=ata5272 < %s -march=avr | FileCheck %s +; RUN: llc -mcpu=attiny861a < %s -march=avr | FileCheck %s +; RUN: llc -mcpu=at90usb82 < %s -march=avr | FileCheck %s + +; Tests lowering of multiplication to compiler support routines. + +; CHECK-LABEL: mul8: +define i8 @mul8(i8 %a, i8 %b) { +; CHECK: mov r25, r24 +; CHECK: mov r24, r22 +; CHECK: mov r22, r25 +; CHECK: call __mulqi3 + %mul = mul i8 %b, %a + ret i8 %mul +} + +; CHECK-LABEL: mul16: +define i16 @mul16(i16 %a, i16 %b) { +; CHECK: movw r18, r24 +; CHECK: movw r24, r22 +; CHECK: movw r22, r18 +; CHECK: call __mulhi3 + %mul = mul nsw i16 %b, %a + ret i16 %mul +} + diff --git a/llvm/test/CodeGen/AVR/umul-with-overflow.ll b/llvm/test/CodeGen/AVR/umul-with-overflow.ll index aa8b10a313d38..c6457552dea88 100644 --- a/llvm/test/CodeGen/AVR/umul-with-overflow.ll +++ b/llvm/test/CodeGen/AVR/umul-with-overflow.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=avr | FileCheck %s +; RUN: llc -mattr=avr6 < %s -march=avr | FileCheck %s define i1 @unsigned_multiplication_did_overflow(i8, i8) unnamed_addr { ; CHECK-LABEL: unsigned_multiplication_did_overflow: From 11c3a5c0f988cc3f412daf13ef8e47d813cc77f1 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 23 May 2019 23:08:33 +0000 Subject: [PATCH 239/274] Merging r360825: ------------------------------------------------------------------------ r360825 | atanasyan | 2019-05-15 15:27:19 -0700 (Wed, 15 May 2019) | 14 lines [mips] Always use _LARGEFILE_SOURCE / _FILE_OFFSET_BITS for building MIPS 32-bit When MIPS 32-bit compiler-rt is building on 32-bit host or using 32-bit `DLLVM_HOST_TRIPLE` the `_LARGEFILE_SOURCE` and the `_FILE_OFFSET_BITS=64` macros defined by statements from the `HandleLLVMOptions.cmake`. In case of building 32-bit libraries on 64-bit host using default host triple these macros are not defined. As a result assertions check a consistency between the `struct_kernel_stat_sz` constant and the `struct_kernel_stat_sz` start to fail. To resolve this problem and enable building both 32/64-bit versions of MIPS compiler-rt libraries on 64-bit host at once always explicitly define the `_LARGEFILE_SOURCE` and the `_FILE_OFFSET_BITS=64` macros for MIPS 32-bit. ------------------------------------------------------------------------ llvm-svn: 361568 --- compiler-rt/cmake/base-config-ix.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake index 6684d7371d68f..aeabf17653f5e 100644 --- a/compiler-rt/cmake/base-config-ix.cmake +++ b/compiler-rt/cmake/base-config-ix.cmake @@ -195,10 +195,10 @@ macro(test_targets) # clang's default CPU's. In the 64-bit case, we must also specify the ABI # since the default ABI differs between gcc and clang. # FIXME: Ideally, we would build the N32 library too. - test_target_arch(mipsel "" "-mips32r2" "-mabi=32") + test_target_arch(mipsel "" "-mips32r2" "-mabi=32" "-D_LARGEFILE_SOURCE" "-D_FILE_OFFSET_BITS=64") test_target_arch(mips64el "" "-mips64r2" "-mabi=64") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mips") - test_target_arch(mips "" "-mips32r2" "-mabi=32") + test_target_arch(mips "" "-mips32r2" "-mabi=32" "-D_LARGEFILE_SOURCE" "-D_FILE_OFFSET_BITS=64") test_target_arch(mips64 "" "-mips64r2" "-mabi=64") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "arm") if(WIN32) From c743d72d7f5c21df632ea47b87a6a91179d388ec Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Wed, 29 May 2019 03:26:49 +0000 Subject: [PATCH 240/274] Merging r354184: ------------------------------------------------------------------------ r354184 | ruiu | 2019-02-15 15:11:18 -0800 (Fri, 15 Feb 2019) | 10 lines [PPC64] Preserve LocalEntry when linking On PowerPC64, it is necessary to keep the LocalEntry bits in st_other, especially when -r is used. Otherwise, when the resulting object is used in a posterior linking, LocalEntry info will be unavailable and functions may be called through the wrong entrypoint. Patch by Leandro Lupori. Differential Revision: https://reviews.llvm.org/D56782 ------------------------------------------------------------------------ llvm-svn: 361921 --- lld/ELF/SyntheticSections.cpp | 5 ++++ lld/test/ELF/ppc64-local-entry.s | 47 ++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 lld/test/ELF/ppc64-local-entry.s diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index b1a3f8bc70aec..10675588ebe2e 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2001,6 +2001,11 @@ template void SymbolTableSection::writeTo(uint8_t *Buf) { ESym->setVisibility(Sym->Visibility); } + // The 3 most significant bits of st_other are used by OpenPOWER ABI. + // See getPPC64GlobalEntryToLocalEntryOffset() for more details. + if (Config->EMachine == EM_PPC64) + ESym->st_other |= Sym->StOther & 0xe0; + ESym->st_name = Ent.StrTabOffset; ESym->st_shndx = getSymSectionIndex(Ent.Sym); diff --git a/lld/test/ELF/ppc64-local-entry.s b/lld/test/ELF/ppc64-local-entry.s new file mode 100644 index 0000000000000..2a2295169b958 --- /dev/null +++ b/lld/test/ELF/ppc64-local-entry.s @@ -0,0 +1,47 @@ +# REQUIRES: ppc + +# RUN: llvm-mc -filetype=obj -triple=powerpc64 %s -o %t +# RUN: ld.lld -r %t -o %t2 +# RUN: llvm-objdump -s -section=.symtab %t2 | FileCheck %s + +.text +.abiversion 2 +.globl _start +.p2align 2 +.type _start,@function + +_start: +.Lfunc_begin0: +.Lfunc_gep0: + addis 2, 12, .TOC.-.Lfunc_gep0@ha + addi 2, 2, .TOC.-.Lfunc_gep0@l +.Lfunc_lep0: + .localentry _start, .Lfunc_lep0-.Lfunc_gep0 + # The code below is not important, it just needs to access some + # global data or function, in order to use the TOC. + # In this case, it performs the following: + # g += 10; + # Also note that this code is not intended to be run, but only + # to check if the linker will preserve the localentry info. + addis 3, 2, g@toc@ha + addi 3, 3, g@toc@l + lwz 4, 0(3) + addi 4, 4, 10 + stw 4, 0(3) + blr + .long 0 + .quad 0 +.Lfunc_end0: + .size _start, .Lfunc_end0-.Lfunc_begin0 + + .type g,@object # @g + .lcomm g,4,4 + +// We expect the st_other byte to be 0x60: +// localentry = 011 (gep + 2 instructions), reserved = 000, +// visibility = 00 (STV_DEFAULT) +// Currently, llvm-objdump does not support displaying +// st_other's PPC64 specific flags, thus we check the +// result of the hexdump of .symtab section. + +// CHECK: 0070 00000000 00000000 00000009 12600001 From d44634951a4dc5577a271da591a1e189d5960375 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Wed, 29 May 2019 19:26:53 +0000 Subject: [PATCH 241/274] Merging r353700: ------------------------------------------------------------------------ r353700 | mgorny | 2019-02-11 06:09:43 -0800 (Mon, 11 Feb 2019) | 7 lines [lldb] [test] Skip lldb-mi test if LLDB_DISABLE_PYTHON is used Skip running lldb-mi tests when Python support is disabled. This causes lldb-mi to unconditionally fail, and therefore all the relevant tests fail as well. Differential Revision: https://reviews.llvm.org/D58000 ------------------------------------------------------------------------ llvm-svn: 362016 --- lldb/lit/helper/toolchain.py | 3 ++- lldb/lit/lit.site.cfg.py.in | 1 + lldb/lit/tools/lldb-mi/lit.local.cfg | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 lldb/lit/tools/lldb-mi/lit.local.cfg diff --git a/lldb/lit/helper/toolchain.py b/lldb/lit/helper/toolchain.py index 938f343badcc2..11aa0bcf4e7c7 100644 --- a/lldb/lit/helper/toolchain.py +++ b/lldb/lit/helper/toolchain.py @@ -51,7 +51,8 @@ def use_lldb_substitutions(config): llvm_config.add_tool_substitutions(primary_tools, [config.lldb_tools_dir]) - if lldbmi.was_resolved: + # lldb-mi always fails without Python support + if lldbmi.was_resolved and not config.lldb_disable_python: config.available_features.add('lldb-mi') def _use_msvc_substitutions(config): diff --git a/lldb/lit/lit.site.cfg.py.in b/lldb/lit/lit.site.cfg.py.in index fbf88efcc2f58..738b25d09310e 100644 --- a/lldb/lit/lit.site.cfg.py.in +++ b/lldb/lit/lit.site.cfg.py.in @@ -17,6 +17,7 @@ config.python_executable = "@PYTHON_EXECUTABLE@" config.have_zlib = @LLVM_ENABLE_ZLIB@ config.host_triple = "@LLVM_HOST_TRIPLE@" config.lldb_bitness = 64 if @LLDB_IS_64_BITS@ else 32 +config.lldb_disable_python = @LLDB_DISABLE_PYTHON@ # Support substitution of the tools and libs dirs with user parameters. This is # used when we can't determine the tool dir at configuration time. diff --git a/lldb/lit/tools/lldb-mi/lit.local.cfg b/lldb/lit/tools/lldb-mi/lit.local.cfg new file mode 100644 index 0000000000000..ff28e265b3f13 --- /dev/null +++ b/lldb/lit/tools/lldb-mi/lit.local.cfg @@ -0,0 +1,2 @@ +if not "lldb-mi" in config.available_features: + config.unsupported = True From e31804dc85d2b3f6718a1b010be7c5272a1f9045 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Wed, 29 May 2019 19:31:21 +0000 Subject: [PATCH 242/274] Merging r353701: ------------------------------------------------------------------------ r353701 | mgorny | 2019-02-11 06:09:48 -0800 (Mon, 11 Feb 2019) | 8 lines [lldb] [lit] Fix finding lld-link when it is not in 'compiler dir' Fix the build helper to find lld-link via PATH lookup, rather than making a fragile assumption that it will be present in the 'compiler directory'. This fixes tests on Gentoo where clang and lld are installed in different directories. Differential Revision: https://reviews.llvm.org/D58001 ------------------------------------------------------------------------ llvm-svn: 362017 --- lldb/lit/helper/build.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lldb/lit/helper/build.py b/lldb/lit/helper/build.py index 26f321d709f8b..fd52b7db4b869 100755 --- a/lldb/lit/helper/build.py +++ b/lldb/lit/helper/build.py @@ -283,19 +283,17 @@ def __init__(self, toolchain_type, args): print('Using alternate compiler "{0}" to match selected target.'.format(self.compiler)) if self.mode == 'link' or self.mode == 'compile-and-link': - self.linker = self._find_linker('link') if toolchain_type == 'msvc' else self._find_linker('lld-link') + self.linker = self._find_linker('link') if toolchain_type == 'msvc' else self._find_linker('lld-link', args.tools_dir) if not self.linker: raise ValueError('Unable to find an appropriate linker.') self.compile_env, self.link_env = self._get_visual_studio_environment() - def _find_linker(self, name): - if sys.platform == 'win32': - name = name + '.exe' + def _find_linker(self, name, search_paths=[]): compiler_dir = os.path.dirname(self.compiler) - linker_path = os.path.join(compiler_dir, name) - if not os.path.exists(linker_path): - raise ValueError('Could not find \'{}\''.format(linker_path)) + linker_path = find_executable(name, [compiler_dir] + search_paths) + if linker_path is None: + raise ValueError('Could not find \'{}\''.format(name)) return linker_path def _get_vc_install_dir(self): From f0bd598148675a650b0778f085c90bf442370248 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Wed, 29 May 2019 20:16:38 +0000 Subject: [PATCH 243/274] Merging r359606: ------------------------------------------------------------------------ r359606 | amyk | 2019-04-30 13:09:00 -0700 (Tue, 30 Apr 2019) | 12 lines [compiler-rt][builtins][sanitizers] Update compiler-rt test cases for compatibility with system's toolchain This patch aims to: - Guard ompiler-rt/test/builtins/Unit/compiler_rt_logb_test.c with macros, so the test runs on GLIBC versions >= 2.23. This is because the test relies on comparing its computed values to libm. Oolder versions might not compute to the same value as the compiler-rt value. - Update compiler-rt/test/sanitizer_common/TestCases/Posix/getpw_getgr.cc so that std::string is not used, since false positives may be detected. Differential Revision: https://reviews.llvm.org/D60644 ------------------------------------------------------------------------ llvm-svn: 362024 --- compiler-rt/test/builtins/Unit/compiler_rt_logb_test.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compiler-rt/test/builtins/Unit/compiler_rt_logb_test.c b/compiler-rt/test/builtins/Unit/compiler_rt_logb_test.c index 79676598089c6..9625881316bb8 100644 --- a/compiler-rt/test/builtins/Unit/compiler_rt_logb_test.c +++ b/compiler-rt/test/builtins/Unit/compiler_rt_logb_test.c @@ -37,6 +37,10 @@ double cases[] = { }; int main() { + // Do not the run the compiler-rt logb test case if using GLIBC version + // < 2.23. Older versions might not compute to the same value as the + // compiler-rt value. +#if !defined(__GLIBC__) || (defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 23)) const unsigned N = sizeof(cases) / sizeof(cases[0]); unsigned i; for (i = 0; i < N; ++i) { @@ -58,6 +62,9 @@ int main() { if (test__compiler_rt_logb(fromRep(signBit ^ x))) return 1; x >>= 1; } +#else + printf("skipped\n"); +#endif return 0; } From e3dc222bd3ce1060e82ab2a8f2802a18abac834c Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 30 May 2019 00:31:30 +0000 Subject: [PATCH 244/274] Merging r353865, r353866, and r353874: ------------------------------------------------------------------------ r353865 | sfertile | 2019-02-12 09:48:22 -0800 (Tue, 12 Feb 2019) | 1 line [PowerPC] Fix printing of negative offsets in call instruction dissasembly. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r353866 | sfertile | 2019-02-12 09:49:04 -0800 (Tue, 12 Feb 2019) | 4 lines [PPC64] Update tests to reflect change in printing of call operand. [NFC] The printing of branch operands for call instructions was changed to properly handle negative offsets. Updating the tests to reflect that. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r353874 | sfertile | 2019-02-12 12:03:04 -0800 (Tue, 12 Feb 2019) | 5 lines Fix undefined behaviour in PPCInstPrinter::printBranchOperand. Fix the undefined behaviour introduced by my previous patch r353865 (left shifting a potentially negative value), which was caught by the bots that run UBSan. ------------------------------------------------------------------------ llvm-svn: 362043 --- lld/test/ELF/ppc64-bsymbolic-toc-restore.s | 2 +- lld/test/ELF/ppc64-call-reach.s | 4 +- lld/test/ELF/ppc64-ifunc.s | 4 +- lld/test/ELF/ppc64-local-dynamic.s | 2 +- lld/test/ELF/ppc64-plt-stub.s | 2 +- lld/test/ELF/ppc64-rel-calls.s | 5 +-- .../ELF/ppc64-toc-restore-recursive-call.s | 2 +- lld/test/ELF/ppc64-toc-restore.s | 6 +-- .../PowerPC/Disassembler/PPCDisassembler.cpp | 8 ++++ .../PowerPC/InstPrinter/PPCInstPrinter.cpp | 7 ++- llvm/lib/Target/PowerPC/PPCInstrInfo.td | 2 + .../llvm-objdump/PowerPC/branch-offset.s | 43 +++++++++++++++++++ .../tools/llvm-objdump/PowerPC/lit.local.cfg | 2 + 13 files changed, 73 insertions(+), 16 deletions(-) create mode 100644 llvm/test/tools/llvm-objdump/PowerPC/branch-offset.s create mode 100644 llvm/test/tools/llvm-objdump/PowerPC/lit.local.cfg diff --git a/lld/test/ELF/ppc64-bsymbolic-toc-restore.s b/lld/test/ELF/ppc64-bsymbolic-toc-restore.s index 49d347c489927..b7d9edd45d433 100644 --- a/lld/test/ELF/ppc64-bsymbolic-toc-restore.s +++ b/lld/test/ELF/ppc64-bsymbolic-toc-restore.s @@ -53,7 +53,7 @@ caller: # CHECK-LABEL: caller # CHECK: bl .+44 # CHECK-NEXT: mr 31, 3 -# CHECK-NEXT: bl .+67108816 +# CHECK-NEXT: bl .-48 # CHECK-NEXT: ld 2, 24(1) # CHECK-NEXT: add 3, 3, 31 # CHECK-NEXT: addi 1, 1, 32 diff --git a/lld/test/ELF/ppc64-call-reach.s b/lld/test/ELF/ppc64-call-reach.s index a02bfa8299335..e32497b358fcd 100644 --- a/lld/test/ELF/ppc64-call-reach.s +++ b/lld/test/ELF/ppc64-call-reach.s @@ -62,7 +62,7 @@ test: # CHECK: 10010024: {{.*}} b .+33554428 # NEGOFFSET-LABEL: test -# NEGOFFSET: 10010014: {{.*}} bl .+33554432 +# NEGOFFSET: 10010014: {{.*}} bl .-33554432 # NEGOFFSET: 10010024: {{.*}} b .+33554432 # .branch_lt[0] @@ -83,7 +83,7 @@ test: # the offset is interpreted as a signed 26 bit value so 67108812 is actually # -52. # THUNK-LABEL: test: -# THUNK: 10010034: {{.*}} bl .+67108812 +# THUNK: 10010034: {{.*}} bl .-52 # THUNK: 10010044: {{.*}} b .+67108812 # The offset from the TOC to the .branch_lt section is (-1 << 16) - 32768. diff --git a/lld/test/ELF/ppc64-ifunc.s b/lld/test/ELF/ppc64-ifunc.s index 6f2d3318b9c28..bd7f761973de2 100644 --- a/lld/test/ELF/ppc64-ifunc.s +++ b/lld/test/ELF/ppc64-ifunc.s @@ -42,9 +42,9 @@ # CHECK: _start: # CHECK-NEXT: addis 2, 12, 2 # CHECK-NEXT: addi 2, 2, -32588 -# CHECK-NEXT: bl .+67108812 +# CHECK-NEXT: bl .-52 # CHECK-NEXT: ld 2, 24(1) -# CHECK-NEXT: bl .+67108824 +# CHECK-NEXT: bl .-40 # CHECK-NEXT: ld 2, 24(1) # Check tocbase diff --git a/lld/test/ELF/ppc64-local-dynamic.s b/lld/test/ELF/ppc64-local-dynamic.s index 6ed3b0fd8f076..8a23863f67dee 100644 --- a/lld/test/ELF/ppc64-local-dynamic.s +++ b/lld/test/ELF/ppc64-local-dynamic.s @@ -113,7 +113,7 @@ k: // Dis: test: // Dis: addis 3, 2, 0 // Dis-NEXT: addi 3, 3, -32760 -// Dis-NEXT: bl .+67108804 +// Dis-NEXT: bl .-60 // Dis-NEXT: ld 2, 24(1) // Dis-NEXT: addis 3, 3, 0 // Dis-NEXT: lwa 3, -32768(3) diff --git a/lld/test/ELF/ppc64-plt-stub.s b/lld/test/ELF/ppc64-plt-stub.s index a644f487b8bed..95e28a5850a9e 100644 --- a/lld/test/ELF/ppc64-plt-stub.s +++ b/lld/test/ELF/ppc64-plt-stub.s @@ -22,7 +22,7 @@ // CHECK: _start: -// CHECK: bl .+67108824 +// CHECK: bl .-40 .text .abiversion 2 .globl _start diff --git a/lld/test/ELF/ppc64-rel-calls.s b/lld/test/ELF/ppc64-rel-calls.s index 4c79498dc56bd..8423eb43f2199 100644 --- a/lld/test/ELF/ppc64-rel-calls.s +++ b/lld/test/ELF/ppc64-rel-calls.s @@ -30,9 +30,8 @@ bar: nop blr -# FIXME: The printing here is misleading, the branch offset here is negative. -# CHECK: 1001000c: {{.*}} bl .+67108852 +# CHECK: 1001000c: {{.*}} bl .-12 # CHECK: 10010010: {{.*}} nop -# CHECK: 10010014: {{.*}} bl .+67108844 +# CHECK: 10010014: {{.*}} bl .-20 # CHECK: 10010018: {{.*}} nop # CHECK: 1001001c: {{.*}} blr diff --git a/lld/test/ELF/ppc64-toc-restore-recursive-call.s b/lld/test/ELF/ppc64-toc-restore-recursive-call.s index 4bedcfecf3830..d194ada842050 100644 --- a/lld/test/ELF/ppc64-toc-restore-recursive-call.s +++ b/lld/test/ELF/ppc64-toc-restore-recursive-call.s @@ -18,7 +18,7 @@ # CHECK-NEXT: 10000: # CHECK-LABEL: recursive_func # CHECK-NEXT: 10014: -# CHECK: 1003c: {{[0-9a-fA-F ]+}} bl .+67108804 +# CHECK: 1003c: {{.*}} bl .-60 # CHECK-NEXT: ld 2, 24(1) .abiversion 2 diff --git a/lld/test/ELF/ppc64-toc-restore.s b/lld/test/ELF/ppc64-toc-restore.s index d9e06ca6e5968..8c262076bce5a 100644 --- a/lld/test/ELF/ppc64-toc-restore.s +++ b/lld/test/ELF/ppc64-toc-restore.s @@ -32,10 +32,10 @@ _start: // CHECK: Disassembly of section .text: // CHECK: _start: -// CHECK: 1001001c: {{.*}} bl .+67108836 +// CHECK: 1001001c: {{.*}} bl .-28 // CHECK-NOT: 10010020: {{.*}} nop // CHECK: 10010020: {{.*}} ld 2, 24(1) -// CHECK: 10010024: {{.*}} bl .+67108848 +// CHECK: 10010024: {{.*}} bl .-16 // CHECK-NOT: 10010028: {{.*}} nop // CHECK-NOT: 10010028: {{.*}} ld 2, 24(1) @@ -68,5 +68,5 @@ last: bl foo nop // CHECK: last: -// CHECK: 10010038: {{.*}} bl .+67108808 +// CHECK: 10010038: {{.*}} bl .-56 // CHECK-NEXT: 1001003c: {{.*}} ld 2, 24(1) diff --git a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp index 26869f2508231..cce239cac970e 100644 --- a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp +++ b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp @@ -61,6 +61,14 @@ extern "C" void LLVMInitializePowerPCDisassembler() { createPPCLEDisassembler); } +static DecodeStatus DecodePCRel24BranchTarget(MCInst &Inst, unsigned Imm, + uint64_t Addr, + const void *Decoder) { + int32_t Offset = SignExtend32<24>(Imm); + Inst.addOperand(MCOperand::createImm(Offset)); + return MCDisassembler::Success; +} + // FIXME: These can be generated by TableGen from the existing register // encoding values! diff --git a/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp b/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp index fc29e4effbb12..6824168b890dd 100644 --- a/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp +++ b/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp @@ -382,8 +382,11 @@ void PPCInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo, // Branches can take an immediate operand. This is used by the branch // selection pass to print .+8, an eight byte displacement from the PC. - O << ".+"; - printAbsBranchOperand(MI, OpNo, O); + O << "."; + int32_t Imm = SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2); + if (Imm >= 0) + O << "+"; + O << Imm; } void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo, diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td index dd3f1ac790894..77aa4fe3d4158 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -737,7 +737,9 @@ def abscondbrtarget : Operand { def calltarget : Operand { let PrintMethod = "printBranchOperand"; let EncoderMethod = "getDirectBrEncoding"; + let DecoderMethod = "DecodePCRel24BranchTarget"; let ParserMatchClass = PPCDirectBrAsmOperand; + let OperandType = "OPERAND_PCREL"; } def abscalltarget : Operand { let PrintMethod = "printAbsBranchOperand"; diff --git a/llvm/test/tools/llvm-objdump/PowerPC/branch-offset.s b/llvm/test/tools/llvm-objdump/PowerPC/branch-offset.s new file mode 100644 index 0000000000000..b0b3f05f9cdb5 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/PowerPC/branch-offset.s @@ -0,0 +1,43 @@ +# RUN: llvm-mc -triple=powerpc64le-unknown-linux -filetype=obj %s -o %t.o +# RUN: llvm-objdump -d %t.o | FileCheck %s + +# RUN: llvm-mc -triple=powerpc64-unknown-linux -filetype=obj %s -o %t.o +# RUN: llvm-objdump -d %t.o | FileCheck %s + +# RUN: llvm-mc -triple=powerpc-unknown-linux -filetype=obj %s -o %t.o +# RUN: llvm-objdump -d %t.o | FileCheck %s + +# CHECK: 0000000000000000 callee_back: +# CHECK: 18: {{.*}} bl .-24 +# CHECK: 20: {{.*}} bl .+16 +# CHECK: 0000000000000030 callee_forward: + + .text + .global caller + .type caller,@function + .type callee_forward,@function + .type callee_back,@function + + .p2align 4 +callee_back: + li 3, 55 + blr + + .p2align 4 +caller: +.Lgep: + addis 2, 12, .TOC.-.Lgep@ha + addi 2, 2, .TOC.-.Lgep@l +.Llep: + .localentry caller, .Llep-.Lgep + bl callee_back + mr 31, 3 + bl callee_forward + add 3, 3, 31 + blr + + .p2align 4 +callee_forward: + li 3, 66 + blr + diff --git a/llvm/test/tools/llvm-objdump/PowerPC/lit.local.cfg b/llvm/test/tools/llvm-objdump/PowerPC/lit.local.cfg new file mode 100644 index 0000000000000..b77510721e100 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/PowerPC/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'PowerPC' in config.root.targets: + config.unsupported = True From 5733e36371a242a2fc11ac4adcacccca75d0df9f Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Thu, 30 May 2019 21:54:55 +0000 Subject: [PATCH 245/274] Merging r359883: ------------------------------------------------------------------------ r359883 | arsenm | 2019-05-03 06:42:56 -0700 (Fri, 03 May 2019) | 6 lines AMDGPU: Fix incorrect commute with sub when folding immediates When a fold of an immediate into a sub/subrev required shrinking the instruction, the wrong VOP2 opcode was used. This was using the VOP2 equivalent of the original instruction, not the commuted instruction with the inverted opcode. ------------------------------------------------------------------------ llvm-svn: 362161 From f1cacab458fe9a80b3dcbc6a230d3c7b798a9f57 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 31 May 2019 22:44:16 +0000 Subject: [PATCH 246/274] Merging part of r358975: Only merged the test changes in files that were also changed in r360405. ------------------------------------------------------------------------ r358975 | maskray | 2019-04-23 04:47:28 -0700 (Tue, 23 Apr 2019) | 18 lines [PPC][PPC64] Improve some llvm-objdump -d -D tests Various improvement: Some offsets in disassembly are incorrect after several layout adjustment. Fix them. llvm-objdump -D should not be used. -D dumps unrelated non-text sections. Replace them with llvm-objdump -d, llvm-readelf -x, etc Many llvm-objdump -d tests use {{.*}} . Add the option --no-show-raw-insn to avoid check hex bytes. ppc64-long-branch.s does not need a shared object. Delete it. Make ppc64-ifunc.s check 2 ifuncs. Reviewers: ruiu, espindola Subscribers: emaste, nemanjai, arichardson, kbarton, jsji, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D60998 ------------------------------------------------------------------------ llvm-svn: 362273 --- lld/test/ELF/ppc64-call-reach.s | 33 +++--- lld/test/ELF/ppc64-ifunc.s | 100 ++++++++---------- .../ELF/ppc64-toc-restore-recursive-call.s | 10 +- lld/test/ELF/ppc64-toc-restore.s | 32 +++--- 4 files changed, 81 insertions(+), 94 deletions(-) diff --git a/lld/test/ELF/ppc64-call-reach.s b/lld/test/ELF/ppc64-call-reach.s index e32497b358fcd..085e68f9aebd0 100644 --- a/lld/test/ELF/ppc64-call-reach.s +++ b/lld/test/ELF/ppc64-call-reach.s @@ -3,16 +3,16 @@ # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o # RUN: ld.lld --defsym callee=0x12010010 --defsym tail_callee=0x12010020 \ # RUN: %t.o -o %t -# RUN: llvm-objdump -d %t | FileCheck %s +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s # RUN: ld.lld --defsym callee=0x12010010 --defsym tail_callee=0x12010020 \ # RUN: %t.o -o %t -# RUN: llvm-objdump -d %t | FileCheck %s +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s # RUN: ld.lld --defsym callee=0xE010014 --defsym tail_callee=0xE010024 \ # RUN: %t.o -o %t -# RUN: llvm-objdump -d %t | FileCheck --check-prefix=NEGOFFSET %s +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=NEGOFFSET %s # RUN: ld.lld --defsym callee=0x12010018 --defsym tail_callee=0x12010028 \ # RUN: %t.o -o %t -# RUN: llvm-objdump -d %t | FileCheck --check-prefix=THUNK %s +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=THUNK %s # RUN: llvm-readelf --sections %t | FileCheck --check-prefix=BRANCHLT %s # RUN: not ld.lld --defsym callee=0x1001002D --defsym tail_callee=0x1001002F \ # RUN: %t.o -o %t 2>&1 | FileCheck --check-prefix=MISSALIGNED %s @@ -20,16 +20,16 @@ # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o # RUN: ld.lld --defsym callee=0x12010010 --defsym tail_callee=0x12010020 \ # RUN: %t.o -o %t -# RUN: llvm-objdump -d %t | FileCheck %s +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s # RUN: ld.lld --defsym callee=0x12010010 --defsym tail_callee=0x12010020 \ # RUN: %t.o -o %t -# RUN: llvm-objdump -d %t | FileCheck %s +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s # RUN: ld.lld --defsym callee=0xE010014 --defsym tail_callee=0xE010024 \ # RUN: %t.o -o %t -# RUN: llvm-objdump -d %t | FileCheck --check-prefix=NEGOFFSET %s +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=NEGOFFSET %s # RUN: ld.lld --defsym callee=0x12010018 --defsym tail_callee=0x12010028 \ # RUN: %t.o -o %t -# RUN: llvm-objdump -d %t | FileCheck --check-prefix=THUNK %s +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=THUNK %s # RUN: llvm-readelf --sections %t | FileCheck --check-prefix=BRANCHLT %s # RUN: not ld.lld --defsym callee=0x1001002D --defsym tail_callee=0x1001002F \ # RUN: %t.o -o %t 2>&1 | FileCheck --check-prefix=MISSALIGNED %s @@ -58,23 +58,23 @@ test: # Check that we are branching to the definitions, and not range-extending # thunks. # CHECK-LABEL: test -# CHECK: 10010014: {{.*}} bl .+33554428 -# CHECK: 10010024: {{.*}} b .+33554428 +# CHECK: 10010014: bl .+33554428 +# CHECK: 10010024: b .+33554428 # NEGOFFSET-LABEL: test -# NEGOFFSET: 10010014: {{.*}} bl .-33554432 -# NEGOFFSET: 10010024: {{.*}} b .+33554432 +# NEGOFFSET: 10010014: bl .-33554432 +# NEGOFFSET: 10010024: b .+33554432 # .branch_lt[0] # THUNK-LABEL: __long_branch_callee: -# THUNK-NEXT: 10010000: {{.*}} addis 12, 2, -1 +# THUNK-NEXT: 10010000: addis 12, 2, -1 # THUNK-NEXT: ld 12, -32768(12) # THUNK-NEXT: mtctr 12 # THUNK-NEXT: bctr # .branch_lt[1] # THUNK-LABEL: __long_branch_tail_callee: -# THUNK-NEXT: 10010010: {{.*}} addis 12, 2, -1 +# THUNK-NEXT: 10010010: addis 12, 2, -1 # THUNK-NEXT: ld 12, -32760(12) # THUNK-NEXT: mtctr 12 # THUNK-NEXT: bctr @@ -83,12 +83,11 @@ test: # the offset is interpreted as a signed 26 bit value so 67108812 is actually # -52. # THUNK-LABEL: test: -# THUNK: 10010034: {{.*}} bl .-52 -# THUNK: 10010044: {{.*}} b .+67108812 +# THUNK: 10010034: bl .-52 +# THUNK: 10010044: b .+67108812 # The offset from the TOC to the .branch_lt section is (-1 << 16) - 32768. # Name Type Address Off Size # BRANCHLT: .branch_lt PROGBITS 0000000010020000 020000 000010 # BRANCHLT: .got PROGBITS 0000000010030000 030000 000008 # BRANCHLT-NOT: .plt - diff --git a/lld/test/ELF/ppc64-ifunc.s b/lld/test/ELF/ppc64-ifunc.s index bd7f761973de2..4bf50b98db111 100644 --- a/lld/test/ELF/ppc64-ifunc.s +++ b/lld/test/ELF/ppc64-ifunc.s @@ -1,79 +1,67 @@ # REQUIRES: ppc # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o -# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o -# RUN: ld.lld -shared %t2.o -o %t2.so -# RUN: ld.lld %t.o %t2.so -o %t -# RUN: llvm-objdump -D %t | FileCheck %s -# RUN: llvm-readelf -dynamic-table %t | FileCheck --check-prefix=DT %s -# RUN: llvm-readelf -dyn-relocations %t | FileCheck --check-prefix=DYNREL %s +# RUN: ld.lld %t.o -o %t +# RUN: llvm-nm %t | FileCheck --check-prefix=NM %s +# RUN: llvm-readelf -S %t | FileCheck --check-prefix=SECTIONS %s +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s +# RUN: llvm-readelf -r %t | FileCheck --check-prefix=DYNREL %s # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o -# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o -# RUN: ld.lld -shared %t2.o -o %t2.so -# RUN: ld.lld %t.o %t2.so -o %t -# RUN: llvm-objdump -D %t | FileCheck %s -# RUN: llvm-readelf -dynamic-table %t | FileCheck --check-prefix=DT %s -# RUN: llvm-readelf -dyn-relocations %t | FileCheck --check-prefix=DYNREL %s +# RUN: ld.lld %t.o -o %t +# RUN: llvm-nm %t | FileCheck --check-prefix=NM %s +# RUN: llvm-readelf -S %t | FileCheck --check-prefix=SECTIONS %s +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s +# RUN: llvm-readelf -r %t | FileCheck --check-prefix=DYNREL %s -# CHECK: Disassembly of section .text: +# NM-DAG: 0000000010028000 d .TOC. +# NM-DAG: 0000000010010028 T ifunc +# NM-DAG: 000000001001002c T ifunc2 -# Tocbase + (0 << 16) + 32560 -# 0x100280e0 + 0 + 32560 = 0x10030010 (.plt[2]) -# CHECK: __plt_foo: +# SECTIONS: .plt NOBITS 0000000010030000 + +# .plt[0] - .TOC. = 0x10030000 - 0x10028000 = (1<<16) - 32768 +# CHECK: __plt_ifunc: # CHECK-NEXT: std 2, 24(1) -# CHECK-NEXT: addis 12, 2, 0 -# CHECK-NEXT: ld 12, 32560(12) +# CHECK-NEXT: addis 12, 2, 1 +# CHECK-NEXT: ld 12, -32768(12) # CHECK-NEXT: mtctr 12 # CHECK-NEXT: bctr -# Tocbase + (0 << 16) + 32568 -# 0x100280e0 + 0 + 32568 = 0x1003018 (.plt[3]) -# CHECK: __plt_ifunc: +# .plt[1] - .TOC. = 0x10030000+8 - 0x10028000 = (1<<16) - 32760 +# CHECK: __plt_ifunc2: # CHECK-NEXT: std 2, 24(1) -# CHECK-NEXT: addis 12, 2, 0 -# CHECK-NEXT: ld 12, 32568(12) +# CHECK-NEXT: addis 12, 2, 1 +# CHECK-NEXT: ld 12, -32760(12) # CHECK-NEXT: mtctr 12 # CHECK-NEXT: bctr -# CHECK: ifunc: -# CHECK-NEXT: 10010028: {{.*}} nop - +# __plt_ifunc - . = 0x10010000 - 0x10010038 = -56 +# __plt_ifunc2 - . = 0x10010014 - 0x10010040 = -44 # CHECK: _start: -# CHECK-NEXT: addis 2, 12, 2 -# CHECK-NEXT: addi 2, 2, -32588 -# CHECK-NEXT: bl .-52 -# CHECK-NEXT: ld 2, 24(1) -# CHECK-NEXT: bl .-40 -# CHECK-NEXT: ld 2, 24(1) - -# Check tocbase -# CHECK: Disassembly of section .got: -# CHECK-NEXT: .got: -# CHECK-NEXT: 100200e0 - -# Check .plt address -# DT_PLTGOT should point to the start of the .plt section. -# DT: 0x0000000000000003 PLTGOT 0x10030000 - -# Check that we emit the correct dynamic relocation type for an ifunc -# DYNREL: 'PLT' relocation section at offset 0x{{[0-9a-f]+}} contains 48 bytes: -# 48 bytes --> 2 Elf64_Rela relocations -# DYNREL-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend -# DYNREL-NEXT: {{[0-9a-f]+}} {{[0-9a-f]+}} R_PPC64_JMP_SLOT {{0+}} foo + 0 -# DYNREL-NEXT: {{[0-9a-f]+}} {{[0-9a-f]+}} R_PPC64_IRELATIVE 10010028 +# CHECK-NEXT: addis 2, 12, 1 +# CHECK-NEXT: addi 2, 2, 32720 +# CHECK-NEXT: 10010038: bl .-56 +# CHECK-NEXT: ld 2, 24(1) +# CHECK-NEXT: 10010040: bl .-44 +# CHECK-NEXT: ld 2, 24(1) - - .text - .abiversion 2 +# Check that we emit 2 R_PPC64_IRELATIVE. +# DYNREL: R_PPC64_IRELATIVE 10010028 +# DYNREL: R_PPC64_IRELATIVE 1001002c .type ifunc STT_GNU_IFUNC .globl ifunc ifunc: - nop + nop + +.type ifunc2 STT_GNU_IFUNC +.globl ifunc2 +ifunc2: + nop - .global _start - .type _start,@function +.global _start +.type _start,@function _start: .Lfunc_gep0: @@ -81,7 +69,7 @@ _start: addi 2, 2, .TOC.-.Lfunc_gep0@l .Lfunc_lep0: .localentry _start, .Lfunc_lep0-.Lfunc_gep0 - bl foo - nop bl ifunc nop + bl ifunc2 + nop diff --git a/lld/test/ELF/ppc64-toc-restore-recursive-call.s b/lld/test/ELF/ppc64-toc-restore-recursive-call.s index d194ada842050..538b12c7c90e5 100644 --- a/lld/test/ELF/ppc64-toc-restore-recursive-call.s +++ b/lld/test/ELF/ppc64-toc-restore-recursive-call.s @@ -1,8 +1,8 @@ # REQUIRES: ppc -# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t1.o -# RUN: ld.lld -shared %t1.o -o %t -# RUN: llvm-objdump -d -r %t | FileCheck %s +# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o +# RUN: ld.lld -shared %t.o -o %t.so +# RUN: llvm-objdump -d --no-show-raw-insn -r %t.so | FileCheck %s # For a recursive call that is interposable the linker calls the plt-stub rather # then calling the function directly. Since the call is through a plt stub and @@ -18,8 +18,8 @@ # CHECK-NEXT: 10000: # CHECK-LABEL: recursive_func # CHECK-NEXT: 10014: -# CHECK: 1003c: {{.*}} bl .-60 -# CHECK-NEXT: ld 2, 24(1) +# CHECK: 1003c: bl .-60 +# CHECK-NEXT: 10040: ld 2, 24(1) .abiversion 2 .section ".text" diff --git a/lld/test/ELF/ppc64-toc-restore.s b/lld/test/ELF/ppc64-toc-restore.s index 8c262076bce5a..8ffe2136591d0 100644 --- a/lld/test/ELF/ppc64-toc-restore.s +++ b/lld/test/ELF/ppc64-toc-restore.s @@ -5,14 +5,14 @@ // RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func.s -o %t3.o // RUN: ld.lld -shared %t2.o -o %t2.so // RUN: ld.lld %t.o %t2.so %t3.o -o %t -// RUN: llvm-objdump -d %t | FileCheck %s +// RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-func.s -o %t3.o // RUN: ld.lld -shared %t2.o -o %t2.so // RUN: ld.lld %t.o %t2.so %t3.o -o %t -// RUN: llvm-objdump -d %t | FileCheck %s +// RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s .text .abiversion 2 @@ -32,12 +32,12 @@ _start: // CHECK: Disassembly of section .text: // CHECK: _start: -// CHECK: 1001001c: {{.*}} bl .-28 -// CHECK-NOT: 10010020: {{.*}} nop -// CHECK: 10010020: {{.*}} ld 2, 24(1) -// CHECK: 10010024: {{.*}} bl .-16 -// CHECK-NOT: 10010028: {{.*}} nop -// CHECK-NOT: 10010028: {{.*}} ld 2, 24(1) +// CHECK: 1001001c: bl .-28 +// CHECK-NOT: 10010020: nop +// CHECK: 10010020: ld 2, 24(1) +// CHECK: 10010024: bl .-16 +// CHECK-NOT: 10010028: nop +// CHECK-NOT: 10010028: ld 2, 24(1) # Calling a function in another object file which will have same # TOC base does not need a nop. If nop present, do not rewrite to @@ -49,18 +49,18 @@ _diff_object: nop // CHECK: _diff_object: -// CHECK-NEXT: 10010028: {{.*}} bl .+24 -// CHECK-NEXT: 1001002c: {{.*}} bl .+20 -// CHECK-NEXT: 10010030: {{.*}} nop +// CHECK-NEXT: 10010028: bl .+24 +// CHECK-NEXT: 1001002c: bl .+20 +// CHECK-NEXT: 10010030: nop # Branching to a local function does not need a nop .global noretbranch noretbranch: b bar_local // CHECK: noretbranch: -// CHECK: 10010034: {{.*}} b .+67108832 -// CHECK-NOT: 10010038: {{.*}} nop -// CHECK-NOT: 1001003c: {{.*}} ld 2, 24(1) +// CHECK: 10010034: b .+67108832 +// CHECK-NOT: 10010038: nop +// CHECK-NOT: 1001003c: ld 2, 24(1) // This should come last to check the end-of-buffer condition. .global last @@ -68,5 +68,5 @@ last: bl foo nop // CHECK: last: -// CHECK: 10010038: {{.*}} bl .-56 -// CHECK-NEXT: 1001003c: {{.*}} ld 2, 24(1) +// CHECK: 10010038: bl .-56 +// CHECK-NEXT: 1001003c: ld 2, 24(1) From 0489682ef3b5659eaf05dd7d51ab6c049575ca6b Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 31 May 2019 22:44:22 +0000 Subject: [PATCH 247/274] Merging r360405: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------------------------------------------------------------------ r360405 | maskray | 2019-05-09 22:51:00 -0700 (Thu, 09 May 2019) | 25 lines [PPC64] Define getThunkSectionSpacing() based on the range of R_PPC64_REL24 Suggested by Sean Fertile and Peter Smith. Thunk section spacing decrease the total number of thunks. I measured a decrease of 1% or less in some large programs, with no perceivable slowdown in link time. Override getThunkSectionSpacing() to enable it. 0x2000000 is the farthest point R_PPC64_REL24 can reach. I tried several numbers and found 0x2000000 works the best. Numbers near 0x2000000 work as well but let's just use the simpler number. As demonstrated by the updated tests, this essentially changes placement of most thunks to the end of the output section. We leverage this property to fix PR40740 reported by Alfredo Dal'Ava Júnior: The output section .init consists of input sections from several object files (crti.o crtbegin.o crtend.o crtn.o). Sections other than the last one do not have a terminator. With this patch, we create the thunk after the last .init input section and thus fix the issue. This is not foolproof but works quite well for such sections (with no terminator) in practice. Reviewed By: ruiu, sfertile Differential Revision: https://reviews.llvm.org/D61720 ------------------------------------------------------------------------ llvm-svn: 362274 --- lld/ELF/Arch/PPC64.cpp | 9 ++++ lld/test/ELF/ppc64-bsymbolic-toc-restore.s | 4 +- lld/test/ELF/ppc64-call-reach.s | 15 +++---- lld/test/ELF/ppc64-ifunc.s | 28 ++++++------ lld/test/ELF/ppc64-local-dynamic.s | 2 +- lld/test/ELF/ppc64-long-branch-init.s | 43 +++++++++++++++++++ lld/test/ELF/ppc64-plt-stub.s | 11 ++--- .../ELF/ppc64-toc-restore-recursive-call.s | 11 +++-- lld/test/ELF/ppc64-toc-restore.s | 37 +++++++--------- 9 files changed, 101 insertions(+), 59 deletions(-) create mode 100644 lld/test/ELF/ppc64-long-branch-init.s diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp index 8a320c9a4e9ef..cbfa8073d33fe 100644 --- a/lld/ELF/Arch/PPC64.cpp +++ b/lld/ELF/Arch/PPC64.cpp @@ -113,6 +113,7 @@ class PPC64 final : public TargetInfo { void writeGotHeader(uint8_t *Buf) const override; bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File, uint64_t BranchAddr, const Symbol &S) const override; + uint32_t getThunkSectionSpacing() const override; bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override; RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data, RelExpr Expr) const override; @@ -759,6 +760,14 @@ bool PPC64::needsThunk(RelExpr Expr, RelType Type, const InputFile *File, return !inBranchRange(Type, BranchAddr, S.getVA()); } +uint32_t PPC64::getThunkSectionSpacing() const { + // See comment in Arch/ARM.cpp for a more detailed explanation of + // getThunkSectionSpacing(). For PPC64 we pick the constant here based on + // R_PPC64_REL24, which is used by unconditional branch instructions. + // 0x2000000 = (1 << 24-1) * 4 + return 0x2000000; +} + bool PPC64::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const { int64_t Offset = Dst - Src; if (Type == R_PPC64_REL14) diff --git a/lld/test/ELF/ppc64-bsymbolic-toc-restore.s b/lld/test/ELF/ppc64-bsymbolic-toc-restore.s index b7d9edd45d433..d467d22ff7b1e 100644 --- a/lld/test/ELF/ppc64-bsymbolic-toc-restore.s +++ b/lld/test/ELF/ppc64-bsymbolic-toc-restore.s @@ -53,7 +53,7 @@ caller: # CHECK-LABEL: caller # CHECK: bl .+44 # CHECK-NEXT: mr 31, 3 -# CHECK-NEXT: bl .-48 +# CHECK-NEXT: bl .+44 # CHECK-NEXT: ld 2, 24(1) # CHECK-NEXT: add 3, 3, 31 # CHECK-NEXT: addi 1, 1, 32 @@ -63,6 +63,6 @@ caller: # CHECK-EMPTY: # CHECK-NEXT: def: # CHECK-NEXT: addis 2, 12, 2 -# CHECK-NEXT: addi 2, 2, -32636 +# CHECK-NEXT: addi 2, 2, -32616 # CHECK-NEXT: li 3, 55 # CHECK-NEXT: blr diff --git a/lld/test/ELF/ppc64-call-reach.s b/lld/test/ELF/ppc64-call-reach.s index 085e68f9aebd0..b843e7e531c91 100644 --- a/lld/test/ELF/ppc64-call-reach.s +++ b/lld/test/ELF/ppc64-call-reach.s @@ -65,27 +65,24 @@ test: # NEGOFFSET: 10010014: bl .-33554432 # NEGOFFSET: 10010024: b .+33554432 +# THUNK-LABEL: test: +# THUNK: 10010014: bl .+20 +# THUNK: 10010024: b .+20 + # .branch_lt[0] # THUNK-LABEL: __long_branch_callee: -# THUNK-NEXT: 10010000: addis 12, 2, -1 +# THUNK-NEXT: 10010028: addis 12, 2, -1 # THUNK-NEXT: ld 12, -32768(12) # THUNK-NEXT: mtctr 12 # THUNK-NEXT: bctr # .branch_lt[1] # THUNK-LABEL: __long_branch_tail_callee: -# THUNK-NEXT: 10010010: addis 12, 2, -1 +# THUNK-NEXT: 10010038: addis 12, 2, -1 # THUNK-NEXT: ld 12, -32760(12) # THUNK-NEXT: mtctr 12 # THUNK-NEXT: bctr -# Each call now branches to a thunk, and although it is printed as positive -# the offset is interpreted as a signed 26 bit value so 67108812 is actually -# -52. -# THUNK-LABEL: test: -# THUNK: 10010034: bl .-52 -# THUNK: 10010044: b .+67108812 - # The offset from the TOC to the .branch_lt section is (-1 << 16) - 32768. # Name Type Address Off Size # BRANCHLT: .branch_lt PROGBITS 0000000010020000 020000 000010 diff --git a/lld/test/ELF/ppc64-ifunc.s b/lld/test/ELF/ppc64-ifunc.s index 4bf50b98db111..32e317f3c059d 100644 --- a/lld/test/ELF/ppc64-ifunc.s +++ b/lld/test/ELF/ppc64-ifunc.s @@ -15,11 +15,21 @@ # RUN: llvm-readelf -r %t | FileCheck --check-prefix=DYNREL %s # NM-DAG: 0000000010028000 d .TOC. -# NM-DAG: 0000000010010028 T ifunc -# NM-DAG: 000000001001002c T ifunc2 +# NM-DAG: 0000000010010000 T ifunc +# NM-DAG: 0000000010010004 T ifunc2 # SECTIONS: .plt NOBITS 0000000010030000 +# __plt_ifunc - . = 0x10010020 - 0x10010010 = 16 +# __plt_ifunc2 - . = 0x10010044 - 0x10010018 = 28 +# CHECK: _start: +# CHECK-NEXT: addis 2, 12, 1 +# CHECK-NEXT: addi 2, 2, 32760 +# CHECK-NEXT: 10010010: bl .+16 +# CHECK-NEXT: ld 2, 24(1) +# CHECK-NEXT: 10010018: bl .+28 +# CHECK-NEXT: ld 2, 24(1) + # .plt[0] - .TOC. = 0x10030000 - 0x10028000 = (1<<16) - 32768 # CHECK: __plt_ifunc: # CHECK-NEXT: std 2, 24(1) @@ -36,19 +46,9 @@ # CHECK-NEXT: mtctr 12 # CHECK-NEXT: bctr -# __plt_ifunc - . = 0x10010000 - 0x10010038 = -56 -# __plt_ifunc2 - . = 0x10010014 - 0x10010040 = -44 -# CHECK: _start: -# CHECK-NEXT: addis 2, 12, 1 -# CHECK-NEXT: addi 2, 2, 32720 -# CHECK-NEXT: 10010038: bl .-56 -# CHECK-NEXT: ld 2, 24(1) -# CHECK-NEXT: 10010040: bl .-44 -# CHECK-NEXT: ld 2, 24(1) - # Check that we emit 2 R_PPC64_IRELATIVE. -# DYNREL: R_PPC64_IRELATIVE 10010028 -# DYNREL: R_PPC64_IRELATIVE 1001002c +# DYNREL: R_PPC64_IRELATIVE 10010000 +# DYNREL: R_PPC64_IRELATIVE 10010004 .type ifunc STT_GNU_IFUNC .globl ifunc diff --git a/lld/test/ELF/ppc64-local-dynamic.s b/lld/test/ELF/ppc64-local-dynamic.s index 8a23863f67dee..87e33b784b8b4 100644 --- a/lld/test/ELF/ppc64-local-dynamic.s +++ b/lld/test/ELF/ppc64-local-dynamic.s @@ -113,7 +113,7 @@ k: // Dis: test: // Dis: addis 3, 2, 0 // Dis-NEXT: addi 3, 3, -32760 -// Dis-NEXT: bl .-60 +// Dis-NEXT: bl .+60 // Dis-NEXT: ld 2, 24(1) // Dis-NEXT: addis 3, 3, 0 // Dis-NEXT: lwa 3, -32768(3) diff --git a/lld/test/ELF/ppc64-long-branch-init.s b/lld/test/ELF/ppc64-long-branch-init.s new file mode 100644 index 0000000000000..80b3919cc4555 --- /dev/null +++ b/lld/test/ELF/ppc64-long-branch-init.s @@ -0,0 +1,43 @@ +# REQUIRES: ppc + +# RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-freebsd13.0 %s -o %t.o +# RUN: ld.lld %t.o -o %t +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s + +## .init consists of sections from several object files. Sections other than the +## last one do not have a terminator. Check we do not create a long branch stub +## in the middle. +## We currently use thunk section spacing to ensure the stub is in the end. This +## is not foolproof but good enough to not break in practice. + +# CHECK: Disassembly of section .init: +# CHECK-LABEL: _init: +# CHECK: blr +# CHECK-EMPTY: +# CHECK-LABEL: __long_branch_foo: + +.globl foo +foo: + .space 0x2000000 + blr + +.section .init,"ax",@progbits,unique,0 +.globl _init +_init: + stdu 1, -48(1) + mflr 0 + std 0, 64(1) + +.section .init,"ax",@progbits,unique,1 + bl foo + nop + +.section .init,"ax",@progbits,unique,2 + bl foo + nop + +.section .init,"ax",@progbits,unique,3 + ld 1, 0(1) + ld 0, 16(1) + mtlr 0 + blr diff --git a/lld/test/ELF/ppc64-plt-stub.s b/lld/test/ELF/ppc64-plt-stub.s index 95e28a5850a9e..bf3ac09fd516d 100644 --- a/lld/test/ELF/ppc64-plt-stub.s +++ b/lld/test/ELF/ppc64-plt-stub.s @@ -4,16 +4,19 @@ // RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o // RUN: ld.lld -shared %t2.o -o %t2.so // RUN: ld.lld %t.o %t2.so -o %t -// RUN: llvm-objdump -d %t | FileCheck %s +// RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o // RUN: ld.lld -shared %t2.o -o %t2.so // RUN: ld.lld %t.o %t2.so -o %t -// RUN: llvm-objdump -d %t | FileCheck %s +// RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s // CHECK: Disassembly of section .text: -// CHECK-NEXT: __plt_foo: +// CHECK-NEXT: _start: +// CHECK: 10010008: bl .+16 + +// CHECK-LABEL: 0000000010010018 __plt_foo: // CHECK-NEXT: std 2, 24(1) // CHECK-NEXT: addis 12, 2, 0 // CHECK-NEXT: ld 12, 32560(12) @@ -21,8 +24,6 @@ // CHECK-NEXT: bctr -// CHECK: _start: -// CHECK: bl .-40 .text .abiversion 2 .globl _start diff --git a/lld/test/ELF/ppc64-toc-restore-recursive-call.s b/lld/test/ELF/ppc64-toc-restore-recursive-call.s index 538b12c7c90e5..756a058cc5650 100644 --- a/lld/test/ELF/ppc64-toc-restore-recursive-call.s +++ b/lld/test/ELF/ppc64-toc-restore-recursive-call.s @@ -14,12 +14,11 @@ # for recursive calls as well as keeps the logic for recursive calls consistent # with non-recursive calls. -# CHECK-LABEL: __plt_recursive_func: -# CHECK-NEXT: 10000: -# CHECK-LABEL: recursive_func -# CHECK-NEXT: 10014: -# CHECK: 1003c: bl .-60 -# CHECK-NEXT: 10040: ld 2, 24(1) +# CHECK-LABEL: 0000000000010000 recursive_func: +# CHECK: 10028: bl .+32 +# CHECK-NEXT: ld 2, 24(1) + +# CHECK-LABEL: 0000000000010048 __plt_recursive_func: .abiversion 2 .section ".text" diff --git a/lld/test/ELF/ppc64-toc-restore.s b/lld/test/ELF/ppc64-toc-restore.s index 8ffe2136591d0..d65bef847a7b2 100644 --- a/lld/test/ELF/ppc64-toc-restore.s +++ b/lld/test/ELF/ppc64-toc-restore.s @@ -28,16 +28,11 @@ _start: bl foo nop bl bar_local - - -// CHECK: Disassembly of section .text: -// CHECK: _start: -// CHECK: 1001001c: bl .-28 -// CHECK-NOT: 10010020: nop -// CHECK: 10010020: ld 2, 24(1) -// CHECK: 10010024: bl .-16 -// CHECK-NOT: 10010028: nop -// CHECK-NOT: 10010028: ld 2, 24(1) +// CHECK-LABEL: _start: +// CHECK-NEXT: 10010008: bl .+64 +// CHECK-NEXT: 1001000c: ld 2, 24(1) +// CHECK-NEXT: 10010010: bl .-16 +// CHECK-EMPTY: # Calling a function in another object file which will have same # TOC base does not need a nop. If nop present, do not rewrite to @@ -47,26 +42,24 @@ _diff_object: bl foo_not_shared bl foo_not_shared nop - -// CHECK: _diff_object: -// CHECK-NEXT: 10010028: bl .+24 -// CHECK-NEXT: 1001002c: bl .+20 -// CHECK-NEXT: 10010030: nop +// CHECK-LABEL: _diff_object: +// CHECK-NEXT: 10010014: bl .+28 +// CHECK-NEXT: 10010018: bl .+24 +// CHECK-NEXT: 1001001c: nop # Branching to a local function does not need a nop .global noretbranch noretbranch: b bar_local -// CHECK: noretbranch: -// CHECK: 10010034: b .+67108832 -// CHECK-NOT: 10010038: nop -// CHECK-NOT: 1001003c: ld 2, 24(1) +// CHECK-LABEL: noretbranch: +// CHECK: 10010020: b .+67108832 +// CHECK-EMPTY: // This should come last to check the end-of-buffer condition. .global last last: bl foo nop -// CHECK: last: -// CHECK: 10010038: bl .-56 -// CHECK-NEXT: 1001003c: ld 2, 24(1) +// CHECK-LABEL: last: +// CHECK-NEXT: 10010024: bl .+36 +// CHECK-NEXT: 10010028: ld 2, 24(1) From 836f1e2be4cf0e458bbf9333dcb01d5c65dc3c56 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Wed, 5 Jun 2019 19:06:41 +0000 Subject: [PATCH 248/274] Merging r359891: ------------------------------------------------------------------------ r359891 | arsenm | 2019-05-03 07:40:10 -0700 (Fri, 03 May 2019) | 9 lines AMDGPU: Replace shrunk instruction with dummy implicit_def This was broken if the original operand was killed. The kill flag would appear on both instructions, and fail the verifier. Keep the kill flag, but remove the operands from the old instruction. This has an added benefit of really reducing the use count for future folds. Ideally the pass would be structured more like what PeepholeOptimizer does to avoid this hack to avoid breaking instruction iterators. ------------------------------------------------------------------------ llvm-svn: 362634 --- llvm/lib/Target/AMDGPU/SIFoldOperands.cpp | 12 ++-- .../AMDGPU/fold-immediate-operand-shrink.mir | 56 +++++++++++++++++++ 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp index 4e29b73f6fac5..50a109dae2229 100644 --- a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp +++ b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp @@ -218,8 +218,6 @@ static bool updateOperand(FoldCandidate &Fold, const TargetRegisterClass *Dst0RC = MRI.getRegClass(Dst0.getReg()); unsigned NewReg0 = MRI.createVirtualRegister(Dst0RC); - const TargetRegisterClass *Dst1RC = MRI.getRegClass(Dst1.getReg()); - unsigned NewReg1 = MRI.createVirtualRegister(Dst1RC); MachineInstr *Inst32 = TII.buildShrunkInst(*MI, Op32); @@ -229,9 +227,15 @@ static bool updateOperand(FoldCandidate &Fold, } // Keep the old instruction around to avoid breaking iterators, but - // replace the outputs with dummy registers. + // replace it with a dummy instruction to remove uses. + // + // FIXME: We should not invert how this pass looks at operands to avoid + // this. Should track set of foldable movs instead of looking for uses + // when looking at a use. Dst0.setReg(NewReg0); - Dst1.setReg(NewReg1); + for (unsigned I = MI->getNumOperands() - 1; I > 0; --I) + MI->RemoveOperand(I); + MI->setDesc(TII.get(AMDGPU::IMPLICIT_DEF)); if (Fold.isCommuted()) TII.commuteInstruction(*Inst32, false); diff --git a/llvm/test/CodeGen/AMDGPU/fold-immediate-operand-shrink.mir b/llvm/test/CodeGen/AMDGPU/fold-immediate-operand-shrink.mir index e4ea36f4b1fbf..ce02e37b5ce65 100644 --- a/llvm/test/CodeGen/AMDGPU/fold-immediate-operand-shrink.mir +++ b/llvm/test/CodeGen/AMDGPU/fold-immediate-operand-shrink.mir @@ -590,3 +590,59 @@ body: | S_ENDPGM implicit %2 ... + +--- +name: shrink_add_kill_flags_src0 +tracksRegLiveness: true +body: | + bb.0: + liveins: $vgpr0 + ; GCN-LABEL: name: shrink_add_kill_flags_src0 + ; GCN: liveins: $vgpr0 + ; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 518144, implicit $exec + ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 killed [[V_MOV_B32_e32_]], [[COPY]], implicit-def $vcc, implicit $exec + ; GCN: S_ENDPGM 0, implicit [[V_ADD_I32_e32_]] + %0:vgpr_32 = COPY $vgpr0 + %1:vgpr_32 = V_MOV_B32_e32 518144, implicit $exec + %2:vgpr_32, %3:sreg_64_xexec = V_ADD_I32_e64 killed %1, %0, 0, implicit $exec + S_ENDPGM 0, implicit %2 +... + +--- +name: shrink_add_kill_flags_src1 +tracksRegLiveness: true +body: | + bb.0: + liveins: $vgpr0 + ; GCN-LABEL: name: shrink_add_kill_flags_src1 + ; GCN: liveins: $vgpr0 + ; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 518144, implicit $exec + ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 [[V_MOV_B32_e32_]], killed [[COPY]], implicit-def $vcc, implicit $exec + ; GCN: S_ENDPGM 0, implicit [[V_ADD_I32_e32_]] + %0:vgpr_32 = COPY $vgpr0 + %1:vgpr_32 = V_MOV_B32_e32 518144, implicit $exec + %2:vgpr_32, %3:sreg_64_xexec = V_ADD_I32_e64 %1, killed %0, 0, implicit $exec + S_ENDPGM 0, implicit %2 +... + +--- +name: shrink_addc_kill_flags_src2 +tracksRegLiveness: true +body: | + bb.0: + liveins: $vgpr0, $vcc + ; GCN-LABEL: name: shrink_addc_kill_flags_src2 + ; GCN: liveins: $vgpr0, $vcc + ; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 518144, implicit $exec + ; GCN: [[COPY1:%[0-9]+]]:sreg_64_xexec = COPY $vcc + ; GCN: [[V_ADDC_U32_e64_:%[0-9]+]]:vgpr_32, [[V_ADDC_U32_e64_1:%[0-9]+]]:sreg_64_xexec = V_ADDC_U32_e64 [[V_MOV_B32_e32_]], [[COPY]], [[COPY1]], 0, implicit $exec + ; GCN: S_ENDPGM 0, implicit [[V_ADDC_U32_e64_]] + %0:vgpr_32 = COPY $vgpr0 + %1:vgpr_32 = V_MOV_B32_e32 518144, implicit $exec + %2:sreg_64_xexec = COPY $vcc + %3:vgpr_32, %4:sreg_64_xexec = V_ADDC_U32_e64 %1, %0, %2, 0, implicit $exec + S_ENDPGM 0, implicit %3 +... From b73bafaff701aaabc18fe3d28a6afecb211cf485 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Wed, 5 Jun 2019 19:42:03 +0000 Subject: [PATCH 249/274] Correct test in r362634 llvm-svn: 362635 --- .../AMDGPU/fold-immediate-operand-shrink.mir | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/llvm/test/CodeGen/AMDGPU/fold-immediate-operand-shrink.mir b/llvm/test/CodeGen/AMDGPU/fold-immediate-operand-shrink.mir index ce02e37b5ce65..15c453f36f631 100644 --- a/llvm/test/CodeGen/AMDGPU/fold-immediate-operand-shrink.mir +++ b/llvm/test/CodeGen/AMDGPU/fold-immediate-operand-shrink.mir @@ -602,11 +602,11 @@ body: | ; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 518144, implicit $exec ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 killed [[V_MOV_B32_e32_]], [[COPY]], implicit-def $vcc, implicit $exec - ; GCN: S_ENDPGM 0, implicit [[V_ADD_I32_e32_]] + ; GCN: S_ENDPGM implicit [[V_ADD_I32_e32_]] %0:vgpr_32 = COPY $vgpr0 %1:vgpr_32 = V_MOV_B32_e32 518144, implicit $exec - %2:vgpr_32, %3:sreg_64_xexec = V_ADD_I32_e64 killed %1, %0, 0, implicit $exec - S_ENDPGM 0, implicit %2 + %2:vgpr_32, %3:sreg_64_xexec = V_ADD_I32_e64 killed %1, %0, implicit $exec + S_ENDPGM implicit %2 ... --- @@ -620,11 +620,11 @@ body: | ; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 518144, implicit $exec ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 [[V_MOV_B32_e32_]], killed [[COPY]], implicit-def $vcc, implicit $exec - ; GCN: S_ENDPGM 0, implicit [[V_ADD_I32_e32_]] + ; GCN: S_ENDPGM implicit [[V_ADD_I32_e32_]] %0:vgpr_32 = COPY $vgpr0 %1:vgpr_32 = V_MOV_B32_e32 518144, implicit $exec - %2:vgpr_32, %3:sreg_64_xexec = V_ADD_I32_e64 %1, killed %0, 0, implicit $exec - S_ENDPGM 0, implicit %2 + %2:vgpr_32, %3:sreg_64_xexec = V_ADD_I32_e64 %1, killed %0, implicit $exec + S_ENDPGM implicit %2 ... --- @@ -638,11 +638,11 @@ body: | ; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 518144, implicit $exec ; GCN: [[COPY1:%[0-9]+]]:sreg_64_xexec = COPY $vcc - ; GCN: [[V_ADDC_U32_e64_:%[0-9]+]]:vgpr_32, [[V_ADDC_U32_e64_1:%[0-9]+]]:sreg_64_xexec = V_ADDC_U32_e64 [[V_MOV_B32_e32_]], [[COPY]], [[COPY1]], 0, implicit $exec - ; GCN: S_ENDPGM 0, implicit [[V_ADDC_U32_e64_]] + ; GCN: [[V_ADDC_U32_e64_:%[0-9]+]]:vgpr_32, [[V_ADDC_U32_e64_1:%[0-9]+]]:sreg_64_xexec = V_ADDC_U32_e64 [[V_MOV_B32_e32_]], [[COPY]], [[COPY1]], implicit $exec + ; GCN: S_ENDPGM implicit [[V_ADDC_U32_e64_]] %0:vgpr_32 = COPY $vgpr0 %1:vgpr_32 = V_MOV_B32_e32 518144, implicit $exec %2:sreg_64_xexec = COPY $vcc - %3:vgpr_32, %4:sreg_64_xexec = V_ADDC_U32_e64 %1, %0, %2, 0, implicit $exec - S_ENDPGM 0, implicit %3 + %3:vgpr_32, %4:sreg_64_xexec = V_ADDC_U32_e64 %1, %0, %2, implicit $exec + S_ENDPGM implicit %3 ... From c8af2415480e5562c953b2ed76584e60f55a660f Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Wed, 5 Jun 2019 21:02:10 +0000 Subject: [PATCH 250/274] Merging r359898: ------------------------------------------------------------------------ r359898 | arsenm | 2019-05-03 08:21:53 -0700 (Fri, 03 May 2019) | 3 lines AMDGPU: Support shrinking add with FI in SIFoldOperands Avoids test regression in a future patch ------------------------------------------------------------------------ llvm-svn: 362648 --- llvm/lib/Target/AMDGPU/SIFoldOperands.cpp | 72 +++--- .../CodeGen/AMDGPU/fold-fi-operand-shrink.mir | 230 ++++++++++++++++++ 2 files changed, 267 insertions(+), 35 deletions(-) create mode 100644 llvm/test/CodeGen/AMDGPU/fold-fi-operand-shrink.mir diff --git a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp index 50a109dae2229..d679abd107d21 100644 --- a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp +++ b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp @@ -201,53 +201,55 @@ static bool updateOperand(FoldCandidate &Fold, Mod.setImm(Mod.getImm() & ~SISrcMods::OP_SEL_1); } } + } - if (Fold.needsShrink()) { - MachineBasicBlock *MBB = MI->getParent(); - auto Liveness = MBB->computeRegisterLiveness(&TRI, AMDGPU::VCC, MI); - if (Liveness != MachineBasicBlock::LQR_Dead) - return false; + if ((Fold.isImm() || Fold.isFI()) && Fold.needsShrink()) { + MachineBasicBlock *MBB = MI->getParent(); + auto Liveness = MBB->computeRegisterLiveness(&TRI, AMDGPU::VCC, MI); + if (Liveness != MachineBasicBlock::LQR_Dead) + return false; - MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); - int Op32 = Fold.getShrinkOpcode(); - MachineOperand &Dst0 = MI->getOperand(0); - MachineOperand &Dst1 = MI->getOperand(1); - assert(Dst0.isDef() && Dst1.isDef()); + MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); + int Op32 = Fold.getShrinkOpcode(); + MachineOperand &Dst0 = MI->getOperand(0); + MachineOperand &Dst1 = MI->getOperand(1); + assert(Dst0.isDef() && Dst1.isDef()); - bool HaveNonDbgCarryUse = !MRI.use_nodbg_empty(Dst1.getReg()); + bool HaveNonDbgCarryUse = !MRI.use_nodbg_empty(Dst1.getReg()); - const TargetRegisterClass *Dst0RC = MRI.getRegClass(Dst0.getReg()); - unsigned NewReg0 = MRI.createVirtualRegister(Dst0RC); + const TargetRegisterClass *Dst0RC = MRI.getRegClass(Dst0.getReg()); + unsigned NewReg0 = MRI.createVirtualRegister(Dst0RC); - MachineInstr *Inst32 = TII.buildShrunkInst(*MI, Op32); + MachineInstr *Inst32 = TII.buildShrunkInst(*MI, Op32); - if (HaveNonDbgCarryUse) { - BuildMI(*MBB, MI, MI->getDebugLoc(), TII.get(AMDGPU::COPY), Dst1.getReg()) - .addReg(AMDGPU::VCC, RegState::Kill); - } - - // Keep the old instruction around to avoid breaking iterators, but - // replace it with a dummy instruction to remove uses. - // - // FIXME: We should not invert how this pass looks at operands to avoid - // this. Should track set of foldable movs instead of looking for uses - // when looking at a use. - Dst0.setReg(NewReg0); - for (unsigned I = MI->getNumOperands() - 1; I > 0; --I) - MI->RemoveOperand(I); - MI->setDesc(TII.get(AMDGPU::IMPLICIT_DEF)); - - if (Fold.isCommuted()) - TII.commuteInstruction(*Inst32, false); - return true; + if (HaveNonDbgCarryUse) { + BuildMI(*MBB, MI, MI->getDebugLoc(), TII.get(AMDGPU::COPY), Dst1.getReg()) + .addReg(AMDGPU::VCC, RegState::Kill); } - Old.ChangeToImmediate(Fold.ImmToFold); + // Keep the old instruction around to avoid breaking iterators, but + // replace it with a dummy instruction to remove uses. + // + // FIXME: We should not invert how this pass looks at operands to avoid + // this. Should track set of foldable movs instead of looking for uses + // when looking at a use. + Dst0.setReg(NewReg0); + for (unsigned I = MI->getNumOperands() - 1; I > 0; --I) + MI->RemoveOperand(I); + MI->setDesc(TII.get(AMDGPU::IMPLICIT_DEF)); + + if (Fold.isCommuted()) + TII.commuteInstruction(*Inst32, false); return true; } assert(!Fold.needsShrink() && "not handled"); + if (Fold.isImm()) { + Old.ChangeToImmediate(Fold.ImmToFold); + return true; + } + if (Fold.isFI()) { Old.ChangeToFrameIndex(Fold.FrameIndexToFold); return true; @@ -348,7 +350,7 @@ static bool tryAddToFoldList(SmallVectorImpl &FoldList, if ((Opc == AMDGPU::V_ADD_I32_e64 || Opc == AMDGPU::V_SUB_I32_e64 || Opc == AMDGPU::V_SUBREV_I32_e64) && // FIXME - OpToFold->isImm()) { + (OpToFold->isImm() || OpToFold->isFI())) { MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo(); // Verify the other operand is a VGPR, otherwise we would violate the diff --git a/llvm/test/CodeGen/AMDGPU/fold-fi-operand-shrink.mir b/llvm/test/CodeGen/AMDGPU/fold-fi-operand-shrink.mir new file mode 100644 index 0000000000000..ab544665efb41 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/fold-fi-operand-shrink.mir @@ -0,0 +1,230 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=amdgcn-amd-amdhsa -verify-machineinstrs -run-pass si-fold-operands,dead-mi-elimination %s -o - | FileCheck -check-prefix=GCN %s + +--- + +# First operand is FI is in a VGPR, other operand is a VGPR +name: shrink_vgpr_fi_vgpr_v_add_i32_e64_no_carry_out_use +tracksRegLiveness: true +stack: + - { id: 0, type: default, offset: 0, size: 64, alignment: 16 } +body: | + bb.0: + liveins: $vgpr0 + + ; GCN-LABEL: name: shrink_vgpr_fi_vgpr_v_add_i32_e64_no_carry_out_use + ; GCN: liveins: $vgpr0 + ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec + ; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 [[V_MOV_B32_e32_]], [[COPY]], implicit-def $vcc, implicit $exec + ; GCN: S_ENDPGM implicit [[V_ADD_I32_e32_]] + %0:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec + %1:vgpr_32 = COPY $vgpr0 + %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec + S_ENDPGM implicit %2 + +... + +--- + +# First operand is a VGPR, other operand FI is in a VGPR +name: shrink_vgpr_vgpr_fi_v_add_i32_e64_no_carry_out_use +tracksRegLiveness: true +stack: + - { id: 0, type: default, offset: 0, size: 64, alignment: 16 } +body: | + bb.0: + liveins: $vgpr0 + + ; GCN-LABEL: name: shrink_vgpr_vgpr_fi_v_add_i32_e64_no_carry_out_use + ; GCN: liveins: $vgpr0 + ; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec + ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 [[COPY]], [[V_MOV_B32_e32_]], implicit-def $vcc, implicit $exec + ; GCN: S_ENDPGM implicit [[V_ADD_I32_e32_]] + %0:vgpr_32 = COPY $vgpr0 + %1:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec + %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec + S_ENDPGM implicit %2 + +... + +--- + +# First operand is FI is in an SGPR, other operand is a VGPR +name: shrink_vgpr_fi_sgpr_v_add_i32_e64_no_carry_out_use +tracksRegLiveness: true +stack: + - { id: 0, type: default, offset: 0, size: 64, alignment: 16 } +body: | + bb.0: + liveins: $sgpr0 + + ; GCN-LABEL: name: shrink_vgpr_fi_sgpr_v_add_i32_e64_no_carry_out_use + ; GCN: liveins: $sgpr0 + ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec + ; GCN: [[COPY:%[0-9]+]]:sreg_32_xm0 = COPY $sgpr0 + ; GCN: [[V_ADD_I32_e64_:%[0-9]+]]:vgpr_32, [[V_ADD_I32_e64_1:%[0-9]+]]:sreg_64 = V_ADD_I32_e64 [[COPY]], [[V_MOV_B32_e32_]], implicit $exec + ; GCN: S_ENDPGM implicit [[V_ADD_I32_e64_]] + %0:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec + %1:sreg_32_xm0 = COPY $sgpr0 + %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec + S_ENDPGM implicit %2 + +... + +--- + +# First operand is an SGPR, other operand FI is in a VGPR +name: shrink_sgpr_vgpr_fi_v_add_i32_e64_no_carry_out_use +tracksRegLiveness: true +stack: + - { id: 0, type: default, offset: 0, size: 64, alignment: 16 } +body: | + bb.0: + liveins: $sgpr0 + + ; GCN-LABEL: name: shrink_sgpr_vgpr_fi_v_add_i32_e64_no_carry_out_use + ; GCN: liveins: $sgpr0 + ; GCN: [[COPY:%[0-9]+]]:sreg_32_xm0 = COPY $sgpr0 + ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec + ; GCN: [[V_ADD_I32_e64_:%[0-9]+]]:vgpr_32, [[V_ADD_I32_e64_1:%[0-9]+]]:sreg_64 = V_ADD_I32_e64 [[V_MOV_B32_e32_]], [[COPY]], implicit $exec + ; GCN: S_ENDPGM implicit [[V_ADD_I32_e64_]] + %0:sreg_32_xm0 = COPY $sgpr0 + %1:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec + %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec + S_ENDPGM implicit %2 + +... + +--- + +# First operand is FI is in an SGPR, other operand is a VGPR +name: shrink_sgpr_fi_vgpr_v_add_i32_e64_no_carry_out_use +tracksRegLiveness: true +stack: + - { id: 0, type: default, offset: 0, size: 64, alignment: 16 } +body: | + bb.0: + liveins: $vgpr0 + + ; GCN-LABEL: name: shrink_sgpr_fi_vgpr_v_add_i32_e64_no_carry_out_use + ; GCN: liveins: $vgpr0 + ; GCN: [[S_MOV_B32_:%[0-9]+]]:sreg_32_xm0 = S_MOV_B32 %stack.0 + ; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 [[S_MOV_B32_]], [[COPY]], implicit-def $vcc, implicit $exec + ; GCN: S_ENDPGM implicit [[V_ADD_I32_e32_]] + %0:sreg_32_xm0 = S_MOV_B32 %stack.0 + %1:vgpr_32 = COPY $vgpr0 + %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec + S_ENDPGM implicit %2 + +... + +--- + +# First operand is a VGPR, other operand FI is in an SGPR +name: shrink_vgpr_sgpr_fi_v_add_i32_e64_no_carry_out_use +tracksRegLiveness: true +stack: + - { id: 0, type: default, offset: 0, size: 64, alignment: 16} +body: | + bb.0: + liveins: $vgpr0 + + ; GCN-LABEL: name: shrink_vgpr_sgpr_fi_v_add_i32_e64_no_carry_out_use + ; GCN: liveins: $vgpr0 + ; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; GCN: [[S_MOV_B32_:%[0-9]+]]:sreg_32_xm0 = S_MOV_B32 %stack.0 + ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 [[S_MOV_B32_]], [[COPY]], implicit-def $vcc, implicit $exec + ; GCN: S_ENDPGM implicit [[V_ADD_I32_e32_]] + %0:vgpr_32 = COPY $vgpr0 + %1:sreg_32_xm0 = S_MOV_B32 %stack.0 + %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec + S_ENDPGM implicit %2 + +... + +--- + +# First operand is FI is in a VGPR, other operand is an inline imm in a VGPR +name: shrink_vgpr_imm_fi_vgpr_v_add_i32_e64_no_carry_out_use +tracksRegLiveness: true +stack: + - { id: 0, type: default, offset: 0, size: 64, alignment: 16 } +body: | + bb.0: + + ; GCN-LABEL: name: shrink_vgpr_imm_fi_vgpr_v_add_i32_e64_no_carry_out_use + ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec + ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 16, [[V_MOV_B32_e32_]], implicit-def $vcc, implicit $exec + ; GCN: S_ENDPGM implicit [[V_ADD_I32_e32_]] + %0:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec + %1:vgpr_32 = V_MOV_B32_e32 16, implicit $exec + %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec + S_ENDPGM implicit %2 + +... + +--- + +# First operand is an inline imm in a VGPR, other operand FI is in a VGPR +name: shrink_vgpr_imm_vgpr_fi_v_add_i32_e64_no_carry_out_use +tracksRegLiveness: true +stack: + - { id: 0, type: default, offset: 0, size: 64, alignment: 16 } +body: | + bb.0: + + ; GCN-LABEL: name: shrink_vgpr_imm_vgpr_fi_v_add_i32_e64_no_carry_out_use + ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec + ; GCN: [[V_ADD_I32_e64_:%[0-9]+]]:vgpr_32, [[V_ADD_I32_e64_1:%[0-9]+]]:sreg_64 = V_ADD_I32_e64 16, [[V_MOV_B32_e32_]], implicit $exec + ; GCN: S_ENDPGM implicit [[V_ADD_I32_e64_]] + %0:vgpr_32 = V_MOV_B32_e32 16, implicit $exec + %1:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec + %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec + S_ENDPGM implicit %2 + +... + +--- + +# First operand is FI is in a VGPR, other operand is an literal constant in a VGPR +name: shrink_vgpr_k_fi_vgpr_v_add_i32_e64_no_carry_out_use +tracksRegLiveness: true +stack: + - { id: 0, type: default, offset: 0, size: 64, alignment: 16 } +body: | + bb.0: + + ; GCN-LABEL: name: shrink_vgpr_k_fi_vgpr_v_add_i32_e64_no_carry_out_use + ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec + ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 1234, [[V_MOV_B32_e32_]], implicit-def $vcc, implicit $exec + ; GCN: S_ENDPGM implicit [[V_ADD_I32_e32_]] + %0:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec + %1:vgpr_32 = V_MOV_B32_e32 1234, implicit $exec + %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec + S_ENDPGM implicit %2 + +... + +--- + +# First operand is a literal constant in a VGPR, other operand FI is in a VGPR +name: shrink_vgpr_k_vgpr_fi_v_add_i32_e64_no_carry_out_use +tracksRegLiveness: true +stack: + - { id: 0, type: default, offset: 0, size: 64, alignment: 16 } +body: | + bb.0: + + ; GCN-LABEL: name: shrink_vgpr_k_vgpr_fi_v_add_i32_e64_no_carry_out_use + ; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 1234, implicit $exec + ; GCN: [[V_ADD_I32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_I32_e32 %stack.0, [[V_MOV_B32_e32_]], implicit-def $vcc, implicit $exec + ; GCN: S_ENDPGM implicit [[V_ADD_I32_e32_]] + %0:vgpr_32 = V_MOV_B32_e32 1234, implicit $exec + %1:vgpr_32 = V_MOV_B32_e32 %stack.0, implicit $exec + %2:vgpr_32, %3:sreg_64 = V_ADD_I32_e64 %0, %1, implicit $exec + S_ENDPGM implicit %2 + +... From 5b37d896a02fd5a5fd8c231ec014fe7d8aeb9d4e Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Wed, 5 Jun 2019 21:23:44 +0000 Subject: [PATCH 251/274] Merging r359899: ------------------------------------------------------------------------ r359899 | arsenm | 2019-05-03 08:37:07 -0700 (Fri, 03 May 2019) | 7 lines AMDGPU: Select VOP3 form of sub The VOP3 form should always be the preferred selection form to be shrunk later. The r600 sub test needs to be split out because it asserts on the arguments in the new test during the calling convention lowering. ------------------------------------------------------------------------ llvm-svn: 362654 --- llvm/lib/Target/AMDGPU/VOP2Instructions.td | 8 +- llvm/test/CodeGen/AMDGPU/r600.sub.ll | 152 +++++++++++++++++++++ llvm/test/CodeGen/AMDGPU/sub.ll | 90 ++++++------ 3 files changed, 197 insertions(+), 53 deletions(-) create mode 100644 llvm/test/CodeGen/AMDGPU/r600.sub.ll diff --git a/llvm/lib/Target/AMDGPU/VOP2Instructions.td b/llvm/lib/Target/AMDGPU/VOP2Instructions.td index e3fd7b5f9fadd..77a042cb21859 100644 --- a/llvm/lib/Target/AMDGPU/VOP2Instructions.td +++ b/llvm/lib/Target/AMDGPU/VOP2Instructions.td @@ -516,15 +516,13 @@ let AddedComplexity = 1 in { let SubtargetPredicate = HasAddNoCarryInsts in { def : DivergentBinOp; - def : DivergentBinOp; - def : DivergentBinOp; + + def : DivergentBinOp; } def : DivergentBinOp; - -def : DivergentBinOp; -def : DivergentBinOp; +def : DivergentBinOp; def : DivergentBinOp; diff --git a/llvm/test/CodeGen/AMDGPU/r600.sub.ll b/llvm/test/CodeGen/AMDGPU/r600.sub.ll new file mode 100644 index 0000000000000..2ded4f64328d4 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/r600.sub.ll @@ -0,0 +1,152 @@ +; RUN: llc -amdgpu-scalarize-global-loads=false -march=r600 -mcpu=redwood -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=EG,FUNC %s + +declare i32 @llvm.r600.read.tidig.x() readnone + +; FUNC-LABEL: {{^}}s_sub_i32: +define amdgpu_kernel void @s_sub_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) { + %result = sub i32 %a, %b + store i32 %result, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}s_sub_imm_i32: +define amdgpu_kernel void @s_sub_imm_i32(i32 addrspace(1)* %out, i32 %a) { + %result = sub i32 1234, %a + store i32 %result, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}test_sub_i32: +; EG: SUB_INT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +define amdgpu_kernel void @test_sub_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) { + %b_ptr = getelementptr i32, i32 addrspace(1)* %in, i32 1 + %a = load i32, i32 addrspace(1)* %in + %b = load i32, i32 addrspace(1)* %b_ptr + %result = sub i32 %a, %b + store i32 %result, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}test_sub_imm_i32: +; EG: SUB_INT +define amdgpu_kernel void @test_sub_imm_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) { + %a = load i32, i32 addrspace(1)* %in + %result = sub i32 123, %a + store i32 %result, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}test_sub_v2i32: +; EG: SUB_INT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; EG: SUB_INT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +define amdgpu_kernel void @test_sub_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> addrspace(1)* %in) { + %b_ptr = getelementptr <2 x i32>, <2 x i32> addrspace(1)* %in, i32 1 + %a = load <2 x i32>, <2 x i32> addrspace(1) * %in + %b = load <2 x i32>, <2 x i32> addrspace(1) * %b_ptr + %result = sub <2 x i32> %a, %b + store <2 x i32> %result, <2 x i32> addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}test_sub_v4i32: +; EG: SUB_INT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; EG: SUB_INT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; EG: SUB_INT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; EG: SUB_INT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +define amdgpu_kernel void @test_sub_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %in) { + %b_ptr = getelementptr <4 x i32>, <4 x i32> addrspace(1)* %in, i32 1 + %a = load <4 x i32>, <4 x i32> addrspace(1) * %in + %b = load <4 x i32>, <4 x i32> addrspace(1) * %b_ptr + %result = sub <4 x i32> %a, %b + store <4 x i32> %result, <4 x i32> addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}test_sub_i16: +define amdgpu_kernel void @test_sub_i16(i16 addrspace(1)* %out, i16 addrspace(1)* %in) { + %tid = call i32 @llvm.r600.read.tidig.x() + %gep = getelementptr i16, i16 addrspace(1)* %in, i32 %tid + %b_ptr = getelementptr i16, i16 addrspace(1)* %gep, i32 1 + %a = load volatile i16, i16 addrspace(1)* %gep + %b = load volatile i16, i16 addrspace(1)* %b_ptr + %result = sub i16 %a, %b + store i16 %result, i16 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}test_sub_v2i16: +define amdgpu_kernel void @test_sub_v2i16(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %in) { + %tid = call i32 @llvm.r600.read.tidig.x() + %gep = getelementptr <2 x i16>, <2 x i16> addrspace(1)* %in, i32 %tid + %b_ptr = getelementptr <2 x i16>, <2 x i16> addrspace(1)* %gep, i16 1 + %a = load <2 x i16>, <2 x i16> addrspace(1)* %gep + %b = load <2 x i16>, <2 x i16> addrspace(1)* %b_ptr + %result = sub <2 x i16> %a, %b + store <2 x i16> %result, <2 x i16> addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}test_sub_v4i16: +define amdgpu_kernel void @test_sub_v4i16(<4 x i16> addrspace(1)* %out, <4 x i16> addrspace(1)* %in) { + %tid = call i32 @llvm.r600.read.tidig.x() + %gep = getelementptr <4 x i16>, <4 x i16> addrspace(1)* %in, i32 %tid + %b_ptr = getelementptr <4 x i16>, <4 x i16> addrspace(1)* %gep, i16 1 + %a = load <4 x i16>, <4 x i16> addrspace(1) * %gep + %b = load <4 x i16>, <4 x i16> addrspace(1) * %b_ptr + %result = sub <4 x i16> %a, %b + store <4 x i16> %result, <4 x i16> addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}s_sub_i64: +; EG: MEM_RAT_CACHELESS STORE_RAW T{{[0-9]+}}.XY +; EG-DAG: SUB_INT {{[* ]*}} +; EG-DAG: SUBB_UINT +; EG-DAG: SUB_INT +; EG-DAG: SUB_INT {{[* ]*}} +define amdgpu_kernel void @s_sub_i64(i64 addrspace(1)* noalias %out, i64 %a, i64 %b) nounwind { + %result = sub i64 %a, %b + store i64 %result, i64 addrspace(1)* %out, align 8 + ret void +} + +; FUNC-LABEL: {{^}}v_sub_i64: +; EG: MEM_RAT_CACHELESS STORE_RAW T{{[0-9]+}}.XY +; EG-DAG: SUB_INT {{[* ]*}} +; EG-DAG: SUBB_UINT +; EG-DAG: SUB_INT +; EG-DAG: SUB_INT {{[* ]*}} +define amdgpu_kernel void @v_sub_i64(i64 addrspace(1)* noalias %out, i64 addrspace(1)* noalias %inA, i64 addrspace(1)* noalias %inB) nounwind { + %tid = call i32 @llvm.r600.read.tidig.x() readnone + %a_ptr = getelementptr i64, i64 addrspace(1)* %inA, i32 %tid + %b_ptr = getelementptr i64, i64 addrspace(1)* %inB, i32 %tid + %a = load i64, i64 addrspace(1)* %a_ptr + %b = load i64, i64 addrspace(1)* %b_ptr + %result = sub i64 %a, %b + store i64 %result, i64 addrspace(1)* %out, align 8 + ret void +} + +; FUNC-LABEL: {{^}}v_test_sub_v2i64: +define amdgpu_kernel void @v_test_sub_v2i64(<2 x i64> addrspace(1)* %out, <2 x i64> addrspace(1)* noalias %inA, <2 x i64> addrspace(1)* noalias %inB) { + %tid = call i32 @llvm.r600.read.tidig.x() readnone + %a_ptr = getelementptr <2 x i64>, <2 x i64> addrspace(1)* %inA, i32 %tid + %b_ptr = getelementptr <2 x i64>, <2 x i64> addrspace(1)* %inB, i32 %tid + %a = load <2 x i64>, <2 x i64> addrspace(1)* %a_ptr + %b = load <2 x i64>, <2 x i64> addrspace(1)* %b_ptr + %result = sub <2 x i64> %a, %b + store <2 x i64> %result, <2 x i64> addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}v_test_sub_v4i64: +define amdgpu_kernel void @v_test_sub_v4i64(<4 x i64> addrspace(1)* %out, <4 x i64> addrspace(1)* noalias %inA, <4 x i64> addrspace(1)* noalias %inB) { + %tid = call i32 @llvm.r600.read.tidig.x() readnone + %a_ptr = getelementptr <4 x i64>, <4 x i64> addrspace(1)* %inA, i32 %tid + %b_ptr = getelementptr <4 x i64>, <4 x i64> addrspace(1)* %inB, i32 %tid + %a = load <4 x i64>, <4 x i64> addrspace(1)* %a_ptr + %b = load <4 x i64>, <4 x i64> addrspace(1)* %b_ptr + %result = sub <4 x i64> %a, %b + store <4 x i64> %result, <4 x i64> addrspace(1)* %out + ret void +} diff --git a/llvm/test/CodeGen/AMDGPU/sub.ll b/llvm/test/CodeGen/AMDGPU/sub.ll index 4bd346dc586d1..485b374454de6 100644 --- a/llvm/test/CodeGen/AMDGPU/sub.ll +++ b/llvm/test/CodeGen/AMDGPU/sub.ll @@ -1,11 +1,10 @@ -; RUN: llc -amdgpu-scalarize-global-loads=false -march=amdgcn -mcpu=verde -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,SI,FUNC %s -; RUN: llc -amdgpu-scalarize-global-loads=false -march=amdgcn -mcpu=fiji -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,VI,GFX89,FUNC %s -; RUN: llc -amdgpu-scalarize-global-loads=false -march=amdgcn -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX9,GFX89,FUNC %s -; RUN: llc -amdgpu-scalarize-global-loads=false -march=r600 -mcpu=redwood -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=EG,FUNC %s +; RUN: llc -amdgpu-scalarize-global-loads=false -march=amdgcn -mcpu=verde -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,SI %s +; RUN: llc -amdgpu-scalarize-global-loads=false -march=amdgcn -mcpu=fiji -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,VI,GFX89 %s +; RUN: llc -amdgpu-scalarize-global-loads=false -march=amdgcn -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX9,GFX89 %s -declare i32 @llvm.r600.read.tidig.x() readnone +declare i32 @llvm.amdgcn.workitem.id.x() nounwind readnone speculatable -; FUNC-LABEL: {{^}}s_sub_i32: +; GCN-LABEL: {{^}}s_sub_i32: ; GCN: s_load_dwordx2 ; GCN: s_load_dwordx2 s{{\[}}[[A:[0-9]+]]:[[B:[0-9]+]]{{\]}} ; GCN: s_sub_i32 s{{[0-9]+}}, s[[A]], s[[B]] @@ -15,7 +14,7 @@ define amdgpu_kernel void @s_sub_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) { ret void } -; FUNC-LABEL: {{^}}s_sub_imm_i32: +; GCN-LABEL: {{^}}s_sub_imm_i32: ; GCN: s_load_dword [[A:s[0-9]+]] ; GCN: s_sub_i32 s{{[0-9]+}}, 0x4d2, [[A]] define amdgpu_kernel void @s_sub_imm_i32(i32 addrspace(1)* %out, i32 %a) { @@ -24,9 +23,7 @@ define amdgpu_kernel void @s_sub_imm_i32(i32 addrspace(1)* %out, i32 %a) { ret void } -; FUNC-LABEL: {{^}}test_sub_i32: -; EG: SUB_INT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} - +; GCN-LABEL: {{^}}test_sub_i32: ; SI: v_subrev_i32_e32 v{{[0-9]+, vcc, v[0-9]+, v[0-9]+}} ; GFX9: v_sub_u32_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} define amdgpu_kernel void @test_sub_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) { @@ -38,9 +35,7 @@ define amdgpu_kernel void @test_sub_i32(i32 addrspace(1)* %out, i32 addrspace(1) ret void } -; FUNC-LABEL: {{^}}test_sub_imm_i32: -; EG: SUB_INT - +; GCN-LABEL: {{^}}test_sub_imm_i32: ; SI: v_sub_i32_e32 v{{[0-9]+}}, vcc, 0x7b, v{{[0-9]+}} ; GFX9: v_sub_u32_e32 v{{[0-9]+}}, 0x7b, v{{[0-9]+}} define amdgpu_kernel void @test_sub_imm_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) { @@ -50,10 +45,7 @@ define amdgpu_kernel void @test_sub_imm_i32(i32 addrspace(1)* %out, i32 addrspac ret void } -; FUNC-LABEL: {{^}}test_sub_v2i32: -; EG: SUB_INT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} -; EG: SUB_INT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} - +; GCN-LABEL: {{^}}test_sub_v2i32: ; SI: v_sub_i32_e32 v{{[0-9]+, vcc, v[0-9]+, v[0-9]+}} ; SI: v_sub_i32_e32 v{{[0-9]+, vcc, v[0-9]+, v[0-9]+}} @@ -68,12 +60,7 @@ define amdgpu_kernel void @test_sub_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32 ret void } -; FUNC-LABEL: {{^}}test_sub_v4i32: -; EG: SUB_INT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} -; EG: SUB_INT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} -; EG: SUB_INT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} -; EG: SUB_INT {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} - +; GCN-LABEL: {{^}}test_sub_v4i32: ; SI: v_sub_i32_e32 v{{[0-9]+, vcc, v[0-9]+, v[0-9]+}} ; SI: v_sub_i32_e32 v{{[0-9]+, vcc, v[0-9]+, v[0-9]+}} ; SI: v_sub_i32_e32 v{{[0-9]+, vcc, v[0-9]+, v[0-9]+}} @@ -92,11 +79,11 @@ define amdgpu_kernel void @test_sub_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32 ret void } -; FUNC-LABEL: {{^}}test_sub_i16: +; GCN-LABEL: {{^}}test_sub_i16: ; SI: v_sub_i32_e32 v{{[0-9]+}}, vcc, ; GFX89: v_sub_u16_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} define amdgpu_kernel void @test_sub_i16(i16 addrspace(1)* %out, i16 addrspace(1)* %in) { - %tid = call i32 @llvm.r600.read.tidig.x() + %tid = call i32 @llvm.amdgcn.workitem.id.x() %gep = getelementptr i16, i16 addrspace(1)* %in, i32 %tid %b_ptr = getelementptr i16, i16 addrspace(1)* %gep, i32 1 %a = load volatile i16, i16 addrspace(1)* %gep @@ -106,13 +93,13 @@ define amdgpu_kernel void @test_sub_i16(i16 addrspace(1)* %out, i16 addrspace(1) ret void } -; FUNC-LABEL: {{^}}test_sub_v2i16: +; GCN-LABEL: {{^}}test_sub_v2i16: ; VI: v_sub_u16_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} ; VI: v_sub_u16_sdwa v{{[0-9]+, v[0-9]+, v[0-9]+}} ; GFX9: v_pk_sub_i16 define amdgpu_kernel void @test_sub_v2i16(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %in) { - %tid = call i32 @llvm.r600.read.tidig.x() + %tid = call i32 @llvm.amdgcn.workitem.id.x() %gep = getelementptr <2 x i16>, <2 x i16> addrspace(1)* %in, i32 %tid %b_ptr = getelementptr <2 x i16>, <2 x i16> addrspace(1)* %gep, i16 1 %a = load <2 x i16>, <2 x i16> addrspace(1)* %gep @@ -122,7 +109,7 @@ define amdgpu_kernel void @test_sub_v2i16(<2 x i16> addrspace(1)* %out, <2 x i16 ret void } -; FUNC-LABEL: {{^}}test_sub_v4i16: +; GCN-LABEL: {{^}}test_sub_v4i16: ; VI: v_sub_u16_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} ; VI: v_sub_u16_sdwa v{{[0-9]+, v[0-9]+, v[0-9]+}} ; VI: v_sub_u16_e32 v{{[0-9]+, v[0-9]+, v[0-9]+}} @@ -131,7 +118,7 @@ define amdgpu_kernel void @test_sub_v2i16(<2 x i16> addrspace(1)* %out, <2 x i16 ; GFX9: v_pk_sub_i16 ; GFX9: v_pk_sub_i16 define amdgpu_kernel void @test_sub_v4i16(<4 x i16> addrspace(1)* %out, <4 x i16> addrspace(1)* %in) { - %tid = call i32 @llvm.r600.read.tidig.x() + %tid = call i32 @llvm.amdgcn.workitem.id.x() %gep = getelementptr <4 x i16>, <4 x i16> addrspace(1)* %in, i32 %tid %b_ptr = getelementptr <4 x i16>, <4 x i16> addrspace(1)* %gep, i16 1 %a = load <4 x i16>, <4 x i16> addrspace(1) * %gep @@ -141,22 +128,16 @@ define amdgpu_kernel void @test_sub_v4i16(<4 x i16> addrspace(1)* %out, <4 x i16 ret void } -; FUNC-LABEL: {{^}}s_sub_i64: +; GCN-LABEL: {{^}}s_sub_i64: ; GCN: s_sub_u32 ; GCN: s_subb_u32 - -; EG: MEM_RAT_CACHELESS STORE_RAW T{{[0-9]+}}.XY -; EG-DAG: SUB_INT {{[* ]*}} -; EG-DAG: SUBB_UINT -; EG-DAG: SUB_INT -; EG-DAG: SUB_INT {{[* ]*}} define amdgpu_kernel void @s_sub_i64(i64 addrspace(1)* noalias %out, i64 %a, i64 %b) nounwind { %result = sub i64 %a, %b store i64 %result, i64 addrspace(1)* %out, align 8 ret void } -; FUNC-LABEL: {{^}}v_sub_i64: +; GCN-LABEL: {{^}}v_sub_i64: ; SI: v_sub_i32_e32 ; SI: v_subb_u32_e32 @@ -165,14 +146,8 @@ define amdgpu_kernel void @s_sub_i64(i64 addrspace(1)* noalias %out, i64 %a, i64 ; GFX9: v_sub_co_u32_e32 ; GFX9: v_subb_co_u32_e32 - -; EG: MEM_RAT_CACHELESS STORE_RAW T{{[0-9]+}}.XY -; EG-DAG: SUB_INT {{[* ]*}} -; EG-DAG: SUBB_UINT -; EG-DAG: SUB_INT -; EG-DAG: SUB_INT {{[* ]*}} define amdgpu_kernel void @v_sub_i64(i64 addrspace(1)* noalias %out, i64 addrspace(1)* noalias %inA, i64 addrspace(1)* noalias %inB) nounwind { - %tid = call i32 @llvm.r600.read.tidig.x() readnone + %tid = call i32 @llvm.amdgcn.workitem.id.x() readnone %a_ptr = getelementptr i64, i64 addrspace(1)* %inA, i32 %tid %b_ptr = getelementptr i64, i64 addrspace(1)* %inB, i32 %tid %a = load i64, i64 addrspace(1)* %a_ptr @@ -182,7 +157,7 @@ define amdgpu_kernel void @v_sub_i64(i64 addrspace(1)* noalias %out, i64 addrspa ret void } -; FUNC-LABEL: {{^}}v_test_sub_v2i64: +; GCN-LABEL: {{^}}v_test_sub_v2i64: ; SI: v_sub_i32_e32 v{{[0-9]+}}, vcc, ; SI: v_subb_u32_e32 v{{[0-9]+}}, vcc, ; SI: v_sub_i32_e32 v{{[0-9]+}}, vcc, @@ -198,7 +173,7 @@ define amdgpu_kernel void @v_sub_i64(i64 addrspace(1)* noalias %out, i64 addrspa ; GFX9: v_sub_co_u32_e32 v{{[0-9]+}}, vcc, ; GFX9: v_subb_co_u32_e32 v{{[0-9]+}}, vcc, define amdgpu_kernel void @v_test_sub_v2i64(<2 x i64> addrspace(1)* %out, <2 x i64> addrspace(1)* noalias %inA, <2 x i64> addrspace(1)* noalias %inB) { - %tid = call i32 @llvm.r600.read.tidig.x() readnone + %tid = call i32 @llvm.amdgcn.workitem.id.x() readnone %a_ptr = getelementptr <2 x i64>, <2 x i64> addrspace(1)* %inA, i32 %tid %b_ptr = getelementptr <2 x i64>, <2 x i64> addrspace(1)* %inB, i32 %tid %a = load <2 x i64>, <2 x i64> addrspace(1)* %a_ptr @@ -208,7 +183,7 @@ define amdgpu_kernel void @v_test_sub_v2i64(<2 x i64> addrspace(1)* %out, <2 x i ret void } -; FUNC-LABEL: {{^}}v_test_sub_v4i64: +; GCN-LABEL: {{^}}v_test_sub_v4i64: ; SI: v_sub_i32_e32 v{{[0-9]+}}, vcc, ; SI: v_subb_u32_e32 v{{[0-9]+}}, vcc, ; SI: v_sub_i32_e32 v{{[0-9]+}}, vcc, @@ -236,7 +211,7 @@ define amdgpu_kernel void @v_test_sub_v2i64(<2 x i64> addrspace(1)* %out, <2 x i ; GFX9: v_sub_co_u32_e32 v{{[0-9]+}}, vcc, ; GFX9: v_subb_co_u32_e32 v{{[0-9]+}}, vcc, define amdgpu_kernel void @v_test_sub_v4i64(<4 x i64> addrspace(1)* %out, <4 x i64> addrspace(1)* noalias %inA, <4 x i64> addrspace(1)* noalias %inB) { - %tid = call i32 @llvm.r600.read.tidig.x() readnone + %tid = call i32 @llvm.amdgcn.workitem.id.x() readnone %a_ptr = getelementptr <4 x i64>, <4 x i64> addrspace(1)* %inA, i32 %tid %b_ptr = getelementptr <4 x i64>, <4 x i64> addrspace(1)* %inB, i32 %tid %a = load <4 x i64>, <4 x i64> addrspace(1)* %a_ptr @@ -245,3 +220,22 @@ define amdgpu_kernel void @v_test_sub_v4i64(<4 x i64> addrspace(1)* %out, <4 x i store <4 x i64> %result, <4 x i64> addrspace(1)* %out ret void } + +; Make sure the VOP3 form of sub is initially selected. Otherwise pair +; of opies from/to VCC would be necessary + +; GCN-LABEL: {{^}}sub_select_vop3: +; SI: v_subrev_i32_e64 v0, s[0:1], s0, v0 +; VI: v_subrev_u32_e64 v0, s[0:1], s0, v0 +; GFX9: v_subrev_u32_e32 v0, s0, v0 + +; GCN: ; def vcc +; GCN: ds_write_b32 +; GCN: ; use vcc +define amdgpu_ps void @sub_select_vop3(i32 inreg %s, i32 %v) { + %vcc = call i64 asm sideeffect "; def vcc", "={vcc}"() + %sub = sub i32 %v, %s + store i32 %sub, i32 addrspace(3)* undef + call void asm sideeffect "; use vcc", "{vcc}"(i64 %vcc) + ret void +} From d95b14d04ee640f5bca3076375508ae87d270875 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Wed, 5 Jun 2019 21:43:28 +0000 Subject: [PATCH 252/274] Merging r360293: ------------------------------------------------------------------------ r360293 | arsenm | 2019-05-08 15:09:57 -0700 (Wed, 08 May 2019) | 21 lines AMDGPU: Select VOP3 form of add The VOP3 form should always be the preferred selection, to be shrunk later. This should only be an optimization issue, but this partially works around a problem from clobbering VCC when SIFixSGPRCopies rewrites an SCC defining operation directly to VCC. 3 of the testcases are regressions from failing to fold the immediate in cases it should. These can be avoided by improving the VCC liveness handling in SIFoldOperands. Simply increasing the threshold to computeRegisterLiveness works, although this is common enough that VCC liveness should probably be tracked throughout the pass. The hack of leaving behind an implicit_def instruction to avoid breaking iterator wastes instruction count, which inhibits finding the VCC def in long chains of adds. Doing this however exposes different, worse looking regressions from poor scheduling behavior. This could probably be avoided around by forcing the shrink of the addc here, but the scheduler should probably be fixed. The r600 add test needs to be split out because it asserts on the arguments in the new test during the calling convention lowering. ------------------------------------------------------------------------ llvm-svn: 362658 --- llvm/lib/Target/AMDGPU/VOP2Instructions.td | 8 +- llvm/test/CodeGen/AMDGPU/add.ll | 83 +++------ ...ds-negative-offset-addressing-mode-loop.ll | 6 +- llvm/test/CodeGen/AMDGPU/fence-barrier.ll | 3 +- .../CodeGen/AMDGPU/llvm.amdgcn.update.dpp.ll | 3 +- llvm/test/CodeGen/AMDGPU/r600.add.ll | 167 ++++++++++++++++++ llvm/test/CodeGen/AMDGPU/salu-to-valu.ll | 2 +- .../tools/llvm-objdump/AMDGPU/source-lines.ll | 4 +- 8 files changed, 202 insertions(+), 74 deletions(-) create mode 100644 llvm/test/CodeGen/AMDGPU/r600.add.ll diff --git a/llvm/lib/Target/AMDGPU/VOP2Instructions.td b/llvm/lib/Target/AMDGPU/VOP2Instructions.td index 77a042cb21859..8cf524a5128d8 100644 --- a/llvm/lib/Target/AMDGPU/VOP2Instructions.td +++ b/llvm/lib/Target/AMDGPU/VOP2Instructions.td @@ -515,17 +515,13 @@ let AddedComplexity = 1 in { } let SubtargetPredicate = HasAddNoCarryInsts in { - def : DivergentBinOp; - + def : DivergentBinOp; def : DivergentBinOp; } - -def : DivergentBinOp; +def : DivergentBinOp; def : DivergentBinOp; -def : DivergentBinOp; - def : DivergentBinOp; def : DivergentBinOp; def : DivergentBinOp; diff --git a/llvm/test/CodeGen/AMDGPU/add.ll b/llvm/test/CodeGen/AMDGPU/add.ll index 6a108db879cc7..bce924ec4a081 100644 --- a/llvm/test/CodeGen/AMDGPU/add.ll +++ b/llvm/test/CodeGen/AMDGPU/add.ll @@ -1,11 +1,8 @@ ; RUN: llc -march=amdgcn -mcpu=verde -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,SIVI,FUNC %s ; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,SIVI,FUNC %s ; RUN: llc -march=amdgcn -mcpu=gfx900 -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX9,FUNC %s -; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck -enable-var-scope -check-prefix=EG -check-prefix=FUNC %s ; FUNC-LABEL: {{^}}s_add_i32: -; EG: ADD_INT {{[* ]*}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} - ; GCN: s_add_i32 s[[REG:[0-9]+]], {{s[0-9]+, s[0-9]+}} ; GCN: v_mov_b32_e32 v[[V_REG:[0-9]+]], s[[REG]] ; GCN: buffer_store_dword v[[V_REG]], @@ -19,9 +16,6 @@ define amdgpu_kernel void @s_add_i32(i32 addrspace(1)* %out, i32 addrspace(1)* % } ; FUNC-LABEL: {{^}}s_add_v2i32: -; EG: ADD_INT {{[* ]*}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} -; EG: ADD_INT {{[* ]*}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} - ; GCN: s_add_i32 s{{[0-9]+, s[0-9]+, s[0-9]+}} ; GCN: s_add_i32 s{{[0-9]+, s[0-9]+, s[0-9]+}} define amdgpu_kernel void @s_add_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> addrspace(1)* %in) { @@ -34,11 +28,6 @@ define amdgpu_kernel void @s_add_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> a } ; FUNC-LABEL: {{^}}s_add_v4i32: -; EG: ADD_INT {{[* ]*}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} -; EG: ADD_INT {{[* ]*}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} -; EG: ADD_INT {{[* ]*}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} -; EG: ADD_INT {{[* ]*}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} - ; GCN: s_add_i32 s{{[0-9]+, s[0-9]+, s[0-9]+}} ; GCN: s_add_i32 s{{[0-9]+, s[0-9]+, s[0-9]+}} ; GCN: s_add_i32 s{{[0-9]+, s[0-9]+, s[0-9]+}} @@ -53,15 +42,6 @@ define amdgpu_kernel void @s_add_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> a } ; FUNC-LABEL: {{^}}s_add_v8i32: -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT - ; GCN: s_add_i32 ; GCN: s_add_i32 ; GCN: s_add_i32 @@ -78,23 +58,6 @@ entry: } ; FUNC-LABEL: {{^}}s_add_v16i32: -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT -; EG: ADD_INT - ; GCN: s_add_i32 ; GCN: s_add_i32 ; GCN: s_add_i32 @@ -124,7 +87,7 @@ entry: ; SIVI: v_add_{{i|u}}32_e32 v{{[0-9]+}}, vcc, [[A]], [[B]] ; GFX9: v_add_u32_e32 v{{[0-9]+}}, [[A]], [[B]] define amdgpu_kernel void @v_add_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 { - %tid = call i32 @llvm.r600.read.tidig.x() + %tid = call i32 @llvm.amdgcn.workitem.id.x() %gep = getelementptr inbounds i32, i32 addrspace(1)* %in, i32 %tid %b_ptr = getelementptr i32, i32 addrspace(1)* %gep, i32 1 %a = load volatile i32, i32 addrspace(1)* %gep @@ -139,7 +102,7 @@ define amdgpu_kernel void @v_add_i32(i32 addrspace(1)* %out, i32 addrspace(1)* % ; SIVI: v_add_{{i|u}}32_e32 v{{[0-9]+}}, vcc, 0x7b, [[A]] ; GFX9: v_add_u32_e32 v{{[0-9]+}}, 0x7b, [[A]] define amdgpu_kernel void @v_add_imm_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 { - %tid = call i32 @llvm.r600.read.tidig.x() + %tid = call i32 @llvm.amdgcn.workitem.id.x() %gep = getelementptr inbounds i32, i32 addrspace(1)* %in, i32 %tid %b_ptr = getelementptr i32, i32 addrspace(1)* %gep, i32 1 %a = load volatile i32, i32 addrspace(1)* %gep @@ -151,13 +114,6 @@ define amdgpu_kernel void @v_add_imm_i32(i32 addrspace(1)* %out, i32 addrspace(1 ; FUNC-LABEL: {{^}}add64: ; GCN: s_add_u32 ; GCN: s_addc_u32 - -; EG: MEM_RAT_CACHELESS STORE_RAW [[LO:T[0-9]+\.XY]] -; EG-DAG: ADD_INT {{[* ]*}} -; EG-DAG: ADDC_UINT -; EG-DAG: ADD_INT -; EG-DAG: ADD_INT {{[* ]*}} -; EG-NOT: SUB define amdgpu_kernel void @add64(i64 addrspace(1)* %out, i64 %a, i64 %b) { entry: %add = add i64 %a, %b @@ -172,13 +128,6 @@ entry: ; FUNC-LABEL: {{^}}add64_sgpr_vgpr: ; GCN-NOT: v_addc_u32_e32 s - -; EG: MEM_RAT_CACHELESS STORE_RAW [[LO:T[0-9]+\.XY]] -; EG-DAG: ADD_INT {{[* ]*}} -; EG-DAG: ADDC_UINT -; EG-DAG: ADD_INT -; EG-DAG: ADD_INT {{[* ]*}} -; EG-NOT: SUB define amdgpu_kernel void @add64_sgpr_vgpr(i64 addrspace(1)* %out, i64 %a, i64 addrspace(1)* %in) { entry: %0 = load i64, i64 addrspace(1)* %in @@ -191,13 +140,6 @@ entry: ; FUNC-LABEL: {{^}}add64_in_branch: ; GCN: s_add_u32 ; GCN: s_addc_u32 - -; EG: MEM_RAT_CACHELESS STORE_RAW [[LO:T[0-9]+\.XY]] -; EG-DAG: ADD_INT {{[* ]*}} -; EG-DAG: ADDC_UINT -; EG-DAG: ADD_INT -; EG-DAG: ADD_INT {{[* ]*}} -; EG-NOT: SUB define amdgpu_kernel void @add64_in_branch(i64 addrspace(1)* %out, i64 addrspace(1)* %in, i64 %a, i64 %b, i64 %c) { entry: %0 = icmp eq i64 %a, 0 @@ -217,7 +159,26 @@ endif: ret void } -declare i32 @llvm.r600.read.tidig.x() #1 +; Make sure the VOP3 form of add is initially selected. Otherwise pair +; of opies from/to VCC would be necessary + +; GCN-LABEL: {{^}}add_select_vop3: +; SI: v_add_i32_e64 v0, s[0:1], s0, v0 +; VI: v_add_u32_e64 v0, s[0:1], s0, v0 +; GFX9: v_add_u32_e32 v0, s0, v0 + +; GCN: ; def vcc +; GCN: ds_write_b32 +; GCN: ; use vcc +define amdgpu_ps void @add_select_vop3(i32 inreg %s, i32 %v) { + %vcc = call i64 asm sideeffect "; def vcc", "={vcc}"() + %sub = add i32 %v, %s + store i32 %sub, i32 addrspace(3)* undef + call void asm sideeffect "; use vcc", "{vcc}"(i64 %vcc) + ret void +} + +declare i32 @llvm.amdgcn.workitem.id.x() #1 attributes #0 = { nounwind } attributes #1 = { nounwind readnone speculatable } diff --git a/llvm/test/CodeGen/AMDGPU/ds-negative-offset-addressing-mode-loop.ll b/llvm/test/CodeGen/AMDGPU/ds-negative-offset-addressing-mode-loop.ll index 5997e27fd815e..e2c7f1c47cf9f 100644 --- a/llvm/test/CodeGen/AMDGPU/ds-negative-offset-addressing-mode-loop.ll +++ b/llvm/test/CodeGen/AMDGPU/ds-negative-offset-addressing-mode-loop.ll @@ -7,6 +7,8 @@ declare void @llvm.amdgcn.s.barrier() #1 ; Function Attrs: nounwind ; CHECK-LABEL: {{^}}signed_ds_offset_addressing_loop: +; SI: s_movk_i32 [[K_0X88:s[0-9]+]], 0x +; SI: s_movk_i32 [[K_0X100:s[0-9]+]], 0x100 ; CHECK: BB0_1: ; CHECK: v_add_i32_e32 [[VADDR:v[0-9]+]], ; SI-DAG: ds_read_b32 v{{[0-9]+}}, [[VADDR]] @@ -14,9 +16,9 @@ declare void @llvm.amdgcn.s.barrier() #1 ; SI-DAG: ds_read_b32 v{{[0-9]+}}, [[VADDR8]] ; SI-DAG: v_add_i32_e32 [[VADDR0x80:v[0-9]+]], vcc, 0x80, [[VADDR]] ; SI-DAG: ds_read_b32 v{{[0-9]+}}, [[VADDR0x80]] -; SI-DAG: v_add_i32_e32 [[VADDR0x88:v[0-9]+]], vcc, 0x88, [[VADDR]] +; SI-DAG: v_add_i32_e32 [[VADDR0x88:v[0-9]+]], vcc, [[K_0X88]], [[VADDR]] ; SI-DAG: ds_read_b32 v{{[0-9]+}}, [[VADDR0x88]] -; SI-DAG: v_add_i32_e32 [[VADDR0x100:v[0-9]+]], vcc, 0x100, [[VADDR]] +; SI-DAG: v_add_i32_e32 [[VADDR0x100:v[0-9]+]], vcc, [[K_0X100]], [[VADDR]] ; SI-DAG: ds_read_b32 v{{[0-9]+}}, [[VADDR0x100]] ; CI-DAG: ds_read2_b32 v{{\[[0-9]+:[0-9]+\]}}, [[VADDR]] offset1:2 diff --git a/llvm/test/CodeGen/AMDGPU/fence-barrier.ll b/llvm/test/CodeGen/AMDGPU/fence-barrier.ll index 8f5a06d01fa22..7de4f1796b08a 100644 --- a/llvm/test/CodeGen/AMDGPU/fence-barrier.ll +++ b/llvm/test/CodeGen/AMDGPU/fence-barrier.ll @@ -54,7 +54,8 @@ define amdgpu_kernel void @test_local(i32 addrspace(1)*) { } ; GCN-LABEL: {{^}}test_global -; GCN: v_add_u32_e32 v{{[0-9]+}}, vcc, 0x888, v{{[0-9]+}} +; GCN: s_movk_i32 [[K:s[0-9]+]], 0x888 +; GCN: v_add_u32_e32 v{{[0-9]+}}, vcc, [[K]], v{{[0-9]+}} ; GCN: flat_store_dword ; GCN: s_waitcnt vmcnt(0) lgkmcnt(0){{$}} ; GCN-NEXT: s_barrier diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.update.dpp.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.update.dpp.ll index 18abf607aea5a..77d518f503ab7 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.update.dpp.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.update.dpp.ll @@ -15,7 +15,8 @@ define amdgpu_kernel void @dpp_test(i32 addrspace(1)* %out, i32 %in1, i32 %in2) } ; VI-LABEL: {{^}}dpp_test1: -; VI: v_add_u32_e32 [[REG:v[0-9]+]], vcc, v{{[0-9]+}}, v{{[0-9]+}} +; VI-OPT: v_add_u32_e32 [[REG:v[0-9]+]], vcc, v{{[0-9]+}}, v{{[0-9]+}} +; VI-NOOPT: v_add_u32_e64 [[REG:v[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, v{{[0-9]+}}, v{{[0-9]+}} ; VI-NOOPT: v_mov_b32_e32 v{{[0-9]+}}, 0 ; VI-NEXT: s_nop 0 ; VI-NEXT: s_nop 0 diff --git a/llvm/test/CodeGen/AMDGPU/r600.add.ll b/llvm/test/CodeGen/AMDGPU/r600.add.ll new file mode 100644 index 0000000000000..73eea3ef21774 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/r600.add.ll @@ -0,0 +1,167 @@ +; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck -enable-var-scope -check-prefix=EG -check-prefix=FUNC %s + +; FUNC-LABEL: {{^}}s_add_i32: +; EG: ADD_INT {{[* ]*}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +define amdgpu_kernel void @s_add_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 { + %b_ptr = getelementptr i32, i32 addrspace(1)* %in, i32 1 + %a = load i32, i32 addrspace(1)* %in + %b = load i32, i32 addrspace(1)* %b_ptr + %result = add i32 %a, %b + store i32 %result, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}s_add_v2i32: +; EG: ADD_INT {{[* ]*}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; EG: ADD_INT {{[* ]*}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +define amdgpu_kernel void @s_add_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> addrspace(1)* %in) { + %b_ptr = getelementptr <2 x i32>, <2 x i32> addrspace(1)* %in, i32 1 + %a = load <2 x i32>, <2 x i32> addrspace(1)* %in + %b = load <2 x i32>, <2 x i32> addrspace(1)* %b_ptr + %result = add <2 x i32> %a, %b + store <2 x i32> %result, <2 x i32> addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}s_add_v4i32: +; EG: ADD_INT {{[* ]*}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; EG: ADD_INT {{[* ]*}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; EG: ADD_INT {{[* ]*}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; EG: ADD_INT {{[* ]*}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +define amdgpu_kernel void @s_add_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %in) { + %b_ptr = getelementptr <4 x i32>, <4 x i32> addrspace(1)* %in, i32 1 + %a = load <4 x i32>, <4 x i32> addrspace(1)* %in + %b = load <4 x i32>, <4 x i32> addrspace(1)* %b_ptr + %result = add <4 x i32> %a, %b + store <4 x i32> %result, <4 x i32> addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}s_add_v8i32: +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +define amdgpu_kernel void @s_add_v8i32(<8 x i32> addrspace(1)* %out, <8 x i32> %a, <8 x i32> %b) { +entry: + %0 = add <8 x i32> %a, %b + store <8 x i32> %0, <8 x i32> addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}s_add_v16i32: +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +; EG: ADD_INT +define amdgpu_kernel void @s_add_v16i32(<16 x i32> addrspace(1)* %out, <16 x i32> %a, <16 x i32> %b) { +entry: + %0 = add <16 x i32> %a, %b + store <16 x i32> %0, <16 x i32> addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}v_add_i32: +define amdgpu_kernel void @v_add_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 { + %tid = call i32 @llvm.r600.read.tidig.x() + %gep = getelementptr inbounds i32, i32 addrspace(1)* %in, i32 %tid + %b_ptr = getelementptr i32, i32 addrspace(1)* %gep, i32 1 + %a = load volatile i32, i32 addrspace(1)* %gep + %b = load volatile i32, i32 addrspace(1)* %b_ptr + %result = add i32 %a, %b + store i32 %result, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}v_add_imm_i32: +define amdgpu_kernel void @v_add_imm_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 { + %tid = call i32 @llvm.r600.read.tidig.x() + %gep = getelementptr inbounds i32, i32 addrspace(1)* %in, i32 %tid + %b_ptr = getelementptr i32, i32 addrspace(1)* %gep, i32 1 + %a = load volatile i32, i32 addrspace(1)* %gep + %result = add i32 %a, 123 + store i32 %result, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: {{^}}add64: +; EG: MEM_RAT_CACHELESS STORE_RAW [[LO:T[0-9]+\.XY]] +; EG-DAG: ADD_INT {{[* ]*}} +; EG-DAG: ADDC_UINT +; EG-DAG: ADD_INT +; EG-DAG: ADD_INT {{[* ]*}} +; EG-NOT: SUB +define amdgpu_kernel void @add64(i64 addrspace(1)* %out, i64 %a, i64 %b) { +entry: + %add = add i64 %a, %b + store i64 %add, i64 addrspace(1)* %out + ret void +} + +; The v_addc_u32 and v_add_i32 instruction can't read SGPRs, because they +; use VCC. The test is designed so that %a will be stored in an SGPR and +; %0 will be stored in a VGPR, so the comiler will be forced to copy %a +; to a VGPR before doing the add. + +; FUNC-LABEL: {{^}}add64_sgpr_vgpr: +; EG: MEM_RAT_CACHELESS STORE_RAW [[LO:T[0-9]+\.XY]] +; EG-DAG: ADD_INT {{[* ]*}} +; EG-DAG: ADDC_UINT +; EG-DAG: ADD_INT +; EG-DAG: ADD_INT {{[* ]*}} +; EG-NOT: SUB +define amdgpu_kernel void @add64_sgpr_vgpr(i64 addrspace(1)* %out, i64 %a, i64 addrspace(1)* %in) { +entry: + %0 = load i64, i64 addrspace(1)* %in + %1 = add i64 %a, %0 + store i64 %1, i64 addrspace(1)* %out + ret void +} + +; Test i64 add inside a branch. +; FUNC-LABEL: {{^}}add64_in_branch: +; EG: MEM_RAT_CACHELESS STORE_RAW [[LO:T[0-9]+\.XY]] +; EG-DAG: ADD_INT {{[* ]*}} +; EG-DAG: ADDC_UINT +; EG-DAG: ADD_INT +; EG-DAG: ADD_INT {{[* ]*}} +; EG-NOT: SUB +define amdgpu_kernel void @add64_in_branch(i64 addrspace(1)* %out, i64 addrspace(1)* %in, i64 %a, i64 %b, i64 %c) { +entry: + %0 = icmp eq i64 %a, 0 + br i1 %0, label %if, label %else + +if: + %1 = load i64, i64 addrspace(1)* %in + br label %endif + +else: + %2 = add i64 %a, %b + br label %endif + +endif: + %3 = phi i64 [%1, %if], [%2, %else] + store i64 %3, i64 addrspace(1)* %out + ret void +} + +declare i32 @llvm.r600.read.tidig.x() #1 + +attributes #0 = { nounwind } +attributes #1 = { nounwind readnone speculatable } diff --git a/llvm/test/CodeGen/AMDGPU/salu-to-valu.ll b/llvm/test/CodeGen/AMDGPU/salu-to-valu.ll index 9b46962108c28..cf42ee9b39ba0 100644 --- a/llvm/test/CodeGen/AMDGPU/salu-to-valu.ll +++ b/llvm/test/CodeGen/AMDGPU/salu-to-valu.ll @@ -458,7 +458,7 @@ bb7: ; preds = %bb3 } ; GCN-LABEL: {{^}}phi_visit_order: -; GCN: v_add_i32_e32 v{{[0-9]+}}, vcc, 1, v{{[0-9]+}} +; GCN: v_add_i32_e64 v{{[0-9]+}}, s{{\[[0-9]+:[0-9]+\]}}, 1, v{{[0-9]+}} define amdgpu_kernel void @phi_visit_order() { bb: br label %bb1 diff --git a/llvm/test/tools/llvm-objdump/AMDGPU/source-lines.ll b/llvm/test/tools/llvm-objdump/AMDGPU/source-lines.ll index 748f04754e4b3..4a4203d2a52e0 100644 --- a/llvm/test/tools/llvm-objdump/AMDGPU/source-lines.ll +++ b/llvm/test/tools/llvm-objdump/AMDGPU/source-lines.ll @@ -12,7 +12,7 @@ ; LINE: v_mov_b32_e32 v{{[0-9]+}}, 0x888 ; LINE: ; {{.*}}source-lines.cl:3 ; LINE: ; {{.*}}source-lines.cl:4 -; LINE: v_add_u32_e32 +; LINE: v_add_u32_e64 ; LINE: ; {{.*}}source-lines.cl:5 ; LINE: flat_store_dword ; Epilogue. @@ -28,7 +28,7 @@ ; SOURCE: v_mov_b32_e32 v{{[0-9]+}}, 0x888 ; SOURCE: ; int var1 = 0x888; ; SOURCE: ; int var2 = var0 + var1; -; SOURCE: v_add_u32_e32 +; SOURCE: v_add_u32_e64 ; SOURCE: ; *Out = var2; ; SOURCE: flat_store_dword ; Epilogue. From c493057bdeede0e41902a2e8de6b5c8541a4237b Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 6 Jun 2019 02:22:34 +0000 Subject: [PATCH 253/274] Merging r360439: ------------------------------------------------------------------------ r360439 | maskray | 2019-05-10 09:24:57 -0700 (Fri, 10 May 2019) | 8 lines [llvm-objdump] Print st_other Add support for ".hidden" ".internal" ".protected" and " 0x%02x" for other st_other bits used by some architectures. Reviewed By: sfertile Differential Revision: https://reviews.llvm.org/D61718 ------------------------------------------------------------------------ llvm-svn: 362668 --- lld/test/ELF/gc-sections-metadata-startstop.s | 2 +- lld/test/ELF/mips-micro-relocs.s | 6 +-- lld/test/ELF/mips-micror6-relocs.s | 4 +- .../llvm-objdump/elf-symbol-visibility.test | 37 +++++++++++++++++++ llvm/tools/llvm-objdump/llvm-objdump.cpp | 30 ++++++++++++--- 5 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 llvm/test/tools/llvm-objdump/elf-symbol-visibility.test diff --git a/lld/test/ELF/gc-sections-metadata-startstop.s b/lld/test/ELF/gc-sections-metadata-startstop.s index ede1899698c4f..0a1efb7e60758 100644 --- a/lld/test/ELF/gc-sections-metadata-startstop.s +++ b/lld/test/ELF/gc-sections-metadata-startstop.s @@ -11,7 +11,7 @@ # CHECK-NOT: yy # CHECK: SYMBOL TABLE: -# CHECK: xx 00000000 __start_xx +# CHECK: xx 00000000 .protected __start_xx # CHECK: w *UND* 00000000 __start_yy .weak __start_xx diff --git a/lld/test/ELF/mips-micro-relocs.s b/lld/test/ELF/mips-micro-relocs.s index b539aa9467634..566f6810f6e91 100644 --- a/lld/test/ELF/mips-micro-relocs.s +++ b/lld/test/ELF/mips-micro-relocs.s @@ -39,9 +39,9 @@ # EL-NEXT: 20028: 00 00 00 00 nop # EL-NEXT: 2002c: 00 94 e8 ff b -44 -# SYM: 00037ff0 .got 00000000 .hidden _gp -# SYM: 00020000 g F .text 00000000 foo -# SYM: 00020010 .text 00000000 __start +# SYM: 00037ff0 .got 00000000 .hidden _gp +# SYM: 00020000 g F .text 00000000 0x80 foo +# SYM: 00020010 .text 00000000 0x80 __start .text .set micromips diff --git a/lld/test/ELF/mips-micror6-relocs.s b/lld/test/ELF/mips-micror6-relocs.s index ca2c1c064f560..fb450ba5cf3c5 100644 --- a/lld/test/ELF/mips-micror6-relocs.s +++ b/lld/test/ELF/mips-micror6-relocs.s @@ -26,8 +26,8 @@ # EL-NEXT: 20014: 7f 80 f6 ff beqzc $3, -36 # EL-NEXT: 20018: ff b7 f4 ff balc -24 -# SYM: 00020000 g F .text 00000000 foo -# SYM: 00020010 .text 00000000 __start +# SYM: 00020000 g F .text 00000000 0x80 foo +# SYM: 00020010 .text 00000000 0x80 __start .text .set micromips diff --git a/llvm/test/tools/llvm-objdump/elf-symbol-visibility.test b/llvm/test/tools/llvm-objdump/elf-symbol-visibility.test new file mode 100644 index 0000000000000..da7f6d285166a --- /dev/null +++ b/llvm/test/tools/llvm-objdump/elf-symbol-visibility.test @@ -0,0 +1,37 @@ +# RUN: yaml2obj %s -o %t +# RUN: llvm-objdump --syms %t | FileCheck %s + +# CHECK: SYMBOL TABLE: +# CHECK-NEXT: .text 00000000 default +# CHECK-NEXT: .text 00000000 .internal internal +# CHECK-NEXT: .text 00000000 .hidden hidden +# CHECK-NEXT: .text 00000000 .protected protected +# CHECK-NEXT: .text 00000000 0x20 mips_pic + +!ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [ EF_MIPS_ABI_O32, EF_MIPS_ARCH_32 ] +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] +Symbols: + Local: + - Name: default + Section: .text + - Name: internal + Visibility: STV_INTERNAL + Section: .text + - Name: hidden + Visibility: STV_HIDDEN + Section: .text + - Name: protected + Visibility: STV_PROTECTED + Section: .text + - Name: mips_pic + Other: [ STO_MIPS_PIC ] + Section: .text diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index ba8d3c5b8d5c0..9bd4528ef7f7e 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -2087,20 +2087,38 @@ void llvm::printSymbolTable(const ObjectFile *O, StringRef ArchiveName, outs() << SectionName; } - outs() << '\t'; if (Common || isa(O)) { uint64_t Val = Common ? Symbol.getAlignment() : ELFSymbolRef(Symbol).getSize(); - outs() << format("\t %08" PRIx64 " ", Val); + outs() << format("\t%08" PRIx64, Val); } - if (Hidden) - outs() << ".hidden "; + if (isa(O)) { + uint8_t Other = ELFSymbolRef(Symbol).getOther(); + switch (Other) { + case ELF::STV_DEFAULT: + break; + case ELF::STV_INTERNAL: + outs() << " .internal"; + break; + case ELF::STV_HIDDEN: + outs() << " .hidden"; + break; + case ELF::STV_PROTECTED: + outs() << " .protected"; + break; + default: + outs() << format(" 0x%02x", Other); + break; + } + } else if (Hidden) { + outs() << " .hidden"; + } if (Demangle) - outs() << demangle(Name) << '\n'; + outs() << ' ' << demangle(Name) << '\n'; else - outs() << Name << '\n'; + outs() << ' ' << Name << '\n'; } } From 0462c73f7610c1606f3f6fd80494ddd3e7b9cbab Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 6 Jun 2019 02:32:26 +0000 Subject: [PATCH 254/274] Merging r360442: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------------------------------------------------------------------ r360442 | maskray | 2019-05-10 10:09:25 -0700 (Fri, 10 May 2019) | 12 lines [MC][ELF] Copy top 3 bits of st_other to .symver aliases On PowerPC64 ELFv2 ABI, the top 3 bits of st_other encode the local entry offset. A versioned symbol alias created by .symver should copy the bits from the source symbol. This partly fixes PR41048. A full fix needs tracking of .set assignments and updating st_other fields when finish() is called, see D56586. Patch by Alfredo Dal'Ava Júnior Differential Revision: https://reviews.llvm.org/D59436 ------------------------------------------------------------------------ llvm-svn: 362669 --- llvm/lib/MC/ELFObjectWriter.cpp | 1 + llvm/test/MC/PowerPC/ppc64-localentry-symver.s | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 llvm/test/MC/PowerPC/ppc64-localentry-symver.s diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index ade858113a300..1b505776ca19b 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -1271,6 +1271,7 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, // This is the first place we are able to copy this information. Alias->setExternal(Symbol.isExternal()); Alias->setBinding(Symbol.getBinding()); + Alias->setOther(Symbol.getOther()); if (!Symbol.isUndefined() && !Rest.startswith("@@@")) continue; diff --git a/llvm/test/MC/PowerPC/ppc64-localentry-symver.s b/llvm/test/MC/PowerPC/ppc64-localentry-symver.s new file mode 100644 index 0000000000000..4c7490646db03 --- /dev/null +++ b/llvm/test/MC/PowerPC/ppc64-localentry-symver.s @@ -0,0 +1,17 @@ +# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-freebsd13.0 %s -o %t +# RUN: llvm-objdump -t %t | FileCheck %s + +# CHECK: 0000000000000000 gw F .text 00000000 0x60 __impl_foo +# CHECK: 0000000000000000 g F .text 00000000 0x60 foo +# CHECK: 0000000000000000 gw F .text 00000000 0x60 foo@FBSD_1.1 + +.globl foo +.type foo,@function +foo: + nop + nop + .localentry foo, 8 + +.symver __impl_foo, foo@FBSD_1.1 +.weak __impl_foo +.set __impl_foo, foo From 4db27e1d1e10e88f6e6f145b58ec84d557ff9d9f Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 6 Jun 2019 02:45:39 +0000 Subject: [PATCH 255/274] Skip globals-fundamental test when Python is disabled llvm-svn: 362670 --- lldb/lit/SymbolFile/NativePDB/globals-fundamental.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/lit/SymbolFile/NativePDB/globals-fundamental.cpp b/lldb/lit/SymbolFile/NativePDB/globals-fundamental.cpp index 8891eddf66896..b3d3e37fbebbc 100644 --- a/lldb/lit/SymbolFile/NativePDB/globals-fundamental.cpp +++ b/lldb/lit/SymbolFile/NativePDB/globals-fundamental.cpp @@ -1,5 +1,5 @@ // clang-format off -// REQUIRES: lld +// REQUIRES: lld, python // Test that we can display tag types. // RUN: %build --compiler=clang-cl --nodefaultlib -o %t.exe -- %s From 897fd6e1bb9c6bb84dd0248f6ef56cadf8410197 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 6 Jun 2019 03:18:22 +0000 Subject: [PATCH 256/274] Merging r361237: ------------------------------------------------------------------------ r361237 | maskray | 2019-05-21 03:41:25 -0700 (Tue, 21 May 2019) | 14 lines [PPC64] Update LocalEntry from assigned symbols On PowerPC64 ELFv2 ABI, functions may have 2 entry points: global and local. The local entry point location of a function is stored in the st_other field of the symbol, as an offset relative to the global entry point. In order to make symbol assignments (e.g. .equ/.set) work properly with this, PPCTargetELFStreamer already copies the local entry bits from the source symbol to the destination one, on emitAssignment(). The problem is that this copy is performed only at the assignment location, where the source symbol may not yet have processed the .localentry directive, that sets the local entry. This may cause the destination symbol to end up with wrong local entry information. Other symbol info is not affected by this because, in this case, the destination symbol value is actually a symbol reference. This change keeps track of these assignments, and update all needed st_other fields when finish() is called. Patch by Leandro Lupori! Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D56586 ------------------------------------------------------------------------ llvm-svn: 362671 --- .../PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp | 30 +++++++++++++++---- ...ry-symver.s => ppc64-localentry-symbols.s} | 17 +++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) rename llvm/test/MC/PowerPC/{ppc64-localentry-symver.s => ppc64-localentry-symbols.s} (58%) diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp index a1e4e07b25af4..78609ef3d4e09 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp @@ -15,6 +15,7 @@ #include "InstPrinter/PPCInstPrinter.h" #include "MCTargetDesc/PPCMCAsmInfo.h" #include "PPCTargetStreamer.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/BinaryFormat/ELF.h" @@ -182,16 +183,33 @@ class PPCTargetELFStreamer : public PPCTargetStreamer { void emitAssignment(MCSymbol *S, const MCExpr *Value) override { auto *Symbol = cast(S); + // When encoding an assignment to set symbol A to symbol B, also copy // the st_other bits encoding the local entry point offset. - if (Value->getKind() != MCExpr::SymbolRef) - return; - const auto &RhsSym = cast( - static_cast(Value)->getSymbol()); - unsigned Other = Symbol->getOther(); + if (copyLocalEntry(Symbol, Value)) + UpdateOther.insert(Symbol); + else + UpdateOther.erase(Symbol); + } + + void finish() override { + for (auto *Sym : UpdateOther) + copyLocalEntry(Sym, Sym->getVariableValue()); + } + +private: + SmallPtrSet UpdateOther; + + bool copyLocalEntry(MCSymbolELF *D, const MCExpr *S) { + auto *Ref = dyn_cast(S); + if (!Ref) + return false; + const auto &RhsSym = cast(Ref->getSymbol()); + unsigned Other = D->getOther(); Other &= ~ELF::STO_PPC64_LOCAL_MASK; Other |= RhsSym.getOther() & ELF::STO_PPC64_LOCAL_MASK; - Symbol->setOther(Other); + D->setOther(Other); + return true; } }; diff --git a/llvm/test/MC/PowerPC/ppc64-localentry-symver.s b/llvm/test/MC/PowerPC/ppc64-localentry-symbols.s similarity index 58% rename from llvm/test/MC/PowerPC/ppc64-localentry-symver.s rename to llvm/test/MC/PowerPC/ppc64-localentry-symbols.s index 4c7490646db03..f1d5c5d0ab1ac 100644 --- a/llvm/test/MC/PowerPC/ppc64-localentry-symver.s +++ b/llvm/test/MC/PowerPC/ppc64-localentry-symbols.s @@ -4,6 +4,11 @@ # CHECK: 0000000000000000 gw F .text 00000000 0x60 __impl_foo # CHECK: 0000000000000000 g F .text 00000000 0x60 foo # CHECK: 0000000000000000 gw F .text 00000000 0x60 foo@FBSD_1.1 +# CHECK: 0000000000000008 g F .text 00000000 0x60 func +# CHECK: 0000000000000008 gw F .text 00000000 0x60 weak_func + +.text +.abiversion 2 .globl foo .type foo,@function @@ -15,3 +20,15 @@ foo: .symver __impl_foo, foo@FBSD_1.1 .weak __impl_foo .set __impl_foo, foo + +.globl func +# Mimick FreeBSD weak function/reference +.weak weak_func +.equ weak_func, func + +.p2align 2 +.type func,@function +func: + nop + nop + .localentry func, 8 From e98c4c8cc770538c2b601e98c59532d0714f0942 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 6 Jun 2019 18:24:30 +0000 Subject: [PATCH 257/274] Merging r355154: ------------------------------------------------------------------------ r355154 | joerg | 2019-02-28 15:33:09 -0800 (Thu, 28 Feb 2019) | 2 lines [PPC] Secure PLT only has meaning for PIC ------------------------------------------------------------------------ llvm-svn: 362729 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 31acd0ff870fd..70e9049a2ab32 100644 --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -4359,8 +4359,8 @@ void PPCDAGToDAGISel::Select(SDNode *N) { const Module *M = MF->getFunction().getParent(); if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) != MVT::i32 || - !PPCSubTarget->isSecurePlt() || !PPCSubTarget->isTargetELF() || - M->getPICLevel() == PICLevel::SmallPIC) + (!TM.isPositionIndependent() || !PPCSubTarget->isSecurePlt()) || + !PPCSubTarget->isTargetELF() || M->getPICLevel() == PICLevel::SmallPIC) break; SDValue Op = N->getOperand(1); From 0e657d45762612228ed6e33c07f4543ee338435a Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 7 Jun 2019 02:44:23 +0000 Subject: [PATCH 258/274] Merging r353905: ------------------------------------------------------------------------ r353905 | hubert.reinterpretcast | 2019-02-12 16:55:30 -0800 (Tue, 12 Feb 2019) | 17 lines [xray][tests][RHDTS] Add -lstdc++ after LLVM libs, resolving link error with RHDTS Summary: A link error was encountered when using the Red Hat Developer Toolset. In the RHDTS, `libstdc++.so` is a linker script that may resolve symbols to a static library. This patch places `-lstdc++` later in the ordering. Reviewers: sfertile, nemanjai, tstellar, dberris Reviewed By: dberris Subscribers: dberris, mgorny, delcypher, jdoerfert, #sanitizers, llvm-commits Tags: #llvm, #sanitizers Differential Revision: https://reviews.llvm.org/D58144 ------------------------------------------------------------------------ llvm-svn: 362765 --- compiler-rt/lib/xray/tests/CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler-rt/lib/xray/tests/CMakeLists.txt b/compiler-rt/lib/xray/tests/CMakeLists.txt index deddc5101e76b..145852904549b 100644 --- a/compiler-rt/lib/xray/tests/CMakeLists.txt +++ b/compiler-rt/lib/xray/tests/CMakeLists.txt @@ -48,8 +48,7 @@ endfunction() set(XRAY_TEST_ARCH ${XRAY_SUPPORTED_ARCH}) set(XRAY_UNITTEST_LINK_FLAGS - ${CMAKE_THREAD_LIBS_INIT} - -l${SANITIZER_CXX_ABI_LIBRARY}) + ${CMAKE_THREAD_LIBS_INIT}) if (NOT APPLE) # Needed by LLVMSupport. @@ -81,6 +80,8 @@ if (NOT APPLE) append_list_if(COMPILER_RT_HAS_LIBEXECINFO -lexecinfo XRAY_UNITTEST_LINK_FLAGS) endif() +list(APPEND XRAY_UNITTEST_LINK_FLAGS -l${SANITIZER_CXX_ABI_LIBRARY}) + macro(add_xray_unittest testname) cmake_parse_arguments(TEST "" "" "SOURCES;HEADERS" ${ARGN}) if(UNIX AND NOT APPLE) From ad5bcd4ee602b24478dc0acc586102cab3839004 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Sat, 8 Jun 2019 00:07:13 +0000 Subject: [PATCH 259/274] Merging r361090: ------------------------------------------------------------------------ r361090 | maskray | 2019-05-17 20:16:00 -0700 (Fri, 17 May 2019) | 34 lines [ARM][AArch64] Revert Android Bionic PT_TLS overaligning hack This reverts D53906. D53906 increased p_align of PT_TLS on ARM/AArch64 to 32/64 to make the static TLS layout compatible with Android Bionic's ELF TLS. However, this may cause glibc ARM/AArch64 programs to crash (see PR41527). The faulty PT_TLS in the executable satisfies p_vaddr%p_align != 0. The remainder is normally 0 but may be non-zero with the hack in place. The problem is that we increase PT_TLS's p_align after OutputSections' addresses are fixed (assignAddress()). It is possible that p_vaddr%old_p_align = 0 while p_vaddr%new_p_align != 0. For a thread local variable defined in the executable, lld computed TLS offset (local exec) is different from glibc computed TLS offset from another module (initial exec/generic dynamic). Note: PR41527 said the bug affects initial exec but actually generic dynamic is affected as well. (glibc is correct in that it compute offsets that satisfy `offset%p_align == p_vaddr%p_align`, which is a basic ELF requirement. This hack appears to work on FreeBSD rtld, musl<=1.1.22, and Bionic, but that is just because they (and lld) incorrectly compute offsets that satisfy `offset%p_align = 0` instead.) Android developers are fine to revert this patch, carry this patch in their tree before figuring out a long-term solution (e.g. a dummy .tdata with sh_addralign=64 sh_size={0,1} in crtbegin*.o files. The overhead is now insignificant after D62059). Reviewed By: rprichard, srhines Differential Revision: https://reviews.llvm.org/D62055 ------------------------------------------------------------------------ llvm-svn: 362858 --- lld/ELF/InputSection.cpp | 4 -- lld/ELF/Writer.cpp | 11 ---- .../ELF/aarch64-cortex-a53-843419-tlsrelax.s | 4 +- lld/test/ELF/aarch64-tls-gdle.s | 4 +- lld/test/ELF/aarch64-tls-iele.s | 6 +-- lld/test/ELF/aarch64-tls-le.s | 8 +-- lld/test/ELF/aarch64-tlsld-ldst.s | 50 +++++++++---------- lld/test/ELF/arm-tls-le32.s | 12 ++--- lld/test/ELF/arm-tls-norelax-ie-le.s | 4 +- 9 files changed, 44 insertions(+), 59 deletions(-) diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 4148413b67985..ca2f49c07bb71 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -580,10 +580,6 @@ static int64_t getTlsTpOffset() { // Variant 1. The thread pointer points to a TCB with a fixed 2-word size, // followed by a variable amount of alignment padding, followed by the TLS // segment. - // - // NB: While the ARM/AArch64 ABI formally has a 2-word TCB size, lld - // effectively increases the TCB size to 8 words for Android compatibility. - // It accomplishes this by increasing the segment's alignment. return alignTo(Config->Wordsize * 2, Out::TlsPhdr->p_align); case EM_386: case EM_X86_64: diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index a3ef3f1c6e9f8..36ba025326388 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -2197,17 +2197,6 @@ template void Writer::setPhdrs() { } if (P->p_type == PT_TLS && P->p_memsz) { - if (!Config->Shared && - (Config->EMachine == EM_ARM || Config->EMachine == EM_AARCH64)) { - // On ARM/AArch64, reserve extra space (8 words) between the thread - // pointer and an executable's TLS segment by overaligning the segment. - // This reservation is needed for backwards compatibility with Android's - // TCB, which allocates several slots after the thread pointer (e.g. - // TLS_SLOT_STACK_GUARD==5). For simplicity, this overalignment is also - // done on other operating systems. - P->p_align = std::max(P->p_align, Config->Wordsize * 8); - } - // The TLS pointer goes after PT_TLS for variant 2 targets. At least glibc // will align it, so round up the size to make sure the offsets are // correct. diff --git a/lld/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s b/lld/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s index 2db5c7e36bbce..bff72d3725f4c 100644 --- a/lld/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s +++ b/lld/test/ELF/aarch64-cortex-a53-843419-tlsrelax.s @@ -26,9 +26,9 @@ _start: // CHECK: _start: // CHECK-NEXT: 210ff8: 41 d0 3b d5 mrs x1, TPIDR_EL0 // CHECK-NEXT: 210ffc: 00 00 a0 d2 movz x0, #0, lsl #16 -// CHECK-NEXT: 211000: 01 08 80 f2 movk x1, #64 +// CHECK-NEXT: 211000: 01 02 80 f2 movk x1, #16 // CHECK-NEXT: 211004: 00 00 a0 d2 movz x0, #0, lsl #16 -// CHECK-NEXT: 211008: 01 08 80 f2 movk x1, #64 +// CHECK-NEXT: 211008: 01 02 80 f2 movk x1, #16 // CHECK-NEXT: 21100c: c0 03 5f d6 ret .type v,@object diff --git a/lld/test/ELF/aarch64-tls-gdle.s b/lld/test/ELF/aarch64-tls-gdle.s index 882ec8c1ae176..19fdc1d35c5d5 100644 --- a/lld/test/ELF/aarch64-tls-gdle.s +++ b/lld/test/ELF/aarch64-tls-gdle.s @@ -9,11 +9,11 @@ #RELOC: Relocations [ #RELOC-NEXT: ] -# TCB size = 64 and foo is first element from TLS register. +# TCB size = 0x16 and foo is first element from TLS register. # CHECK: Disassembly of section .text: # CHECK: _start: # CHECK: 210000: 00 00 a0 d2 movz x0, #0, lsl #16 -# CHECK: 210004: 00 08 80 f2 movk x0, #64 +# CHECK: 210004: 00 02 80 f2 movk x0, #16 # CHECK: 210008: 1f 20 03 d5 nop # CHECK: 21000c: 1f 20 03 d5 nop diff --git a/lld/test/ELF/aarch64-tls-iele.s b/lld/test/ELF/aarch64-tls-iele.s index 0229d6676cd59..9fec4ee7dc92a 100644 --- a/lld/test/ELF/aarch64-tls-iele.s +++ b/lld/test/ELF/aarch64-tls-iele.s @@ -9,13 +9,13 @@ # RELOC: Relocations [ # RELOC-NEXT: ] -# TCB size = 64 and foo is first element from TLS register. +# TCB size = 0x16 and foo is first element from TLS register. # CHECK: Disassembly of section .text: # CHECK: _start: # CHECK-NEXT: 210000: 00 00 a0 d2 movz x0, #0, lsl #16 -# CHECK-NEXT: 210004: 80 08 80 f2 movk x0, #68 +# CHECK-NEXT: 210004: 80 02 80 f2 movk x0, #20 # CHECK-NEXT: 210008: 00 00 a0 d2 movz x0, #0, lsl #16 -# CHECK-NEXT: 21000c: 00 08 80 f2 movk x0, #64 +# CHECK-NEXT: 21000c: 00 02 80 f2 movk x0, #16 .section .tdata .align 2 diff --git a/lld/test/ELF/aarch64-tls-le.s b/lld/test/ELF/aarch64-tls-le.s index 49c322facb128..eda1375865626 100644 --- a/lld/test/ELF/aarch64-tls-le.s +++ b/lld/test/ELF/aarch64-tls-le.s @@ -17,12 +17,12 @@ _start: add x0, x0, :tprel_hi12:v2 add x0, x0, :tprel_lo12_nc:v2 -# TCB size = 64 and foo is first element from TLS register. +# TCB size = 0x16 and foo is first element from TLS register. #CHECK: Disassembly of section .text: #CHECK: _start: #CHECK: 210000: 40 d0 3b d5 mrs x0, TPIDR_EL0 #CHECK: 210004: 00 00 40 91 add x0, x0, #0, lsl #12 -#CHECK: 210008: 00 00 01 91 add x0, x0, #64 +#CHECK: 210008: 00 40 00 91 add x0, x0, #16 #CHECK: 21000c: 40 d0 3b d5 mrs x0, TPIDR_EL0 #CHECK: 210010: 00 fc 7f 91 add x0, x0, #4095, lsl #12 #CHECK: 210014: 00 e0 3f 91 add x0, x0, #4088 @@ -36,9 +36,9 @@ v1: .word 0 .size v1, 4 -# The current offset from the thread pointer is 68. Raise it to just below the +# The current offset from the thread pointer is 20. Raise it to just below the # 24-bit limit. -.space (0xfffff8 - 68) +.space (0xfffff8 - 20) .type v2,@object .globl v2 diff --git a/lld/test/ELF/aarch64-tlsld-ldst.s b/lld/test/ELF/aarch64-tlsld-ldst.s index 8ebdc2f152a6c..3144ca5d99afd 100644 --- a/lld/test/ELF/aarch64-tlsld-ldst.s +++ b/lld/test/ELF/aarch64-tlsld-ldst.s @@ -26,27 +26,27 @@ _start: mrs x8, TPIDR_EL0 // CHECK: _start: // CHECK-NEXT: 210000: 48 d0 3b d5 mrs x8, TPIDR_EL0 -// 0x0 + c40 = 0xc40 = tcb (64-bytes) + var0 -// CHECK-NEXT: 210004: 08 01 40 91 add x8, x8, #0, lsl #12 -// CHECK-NEXT: 210008: 14 11 c3 3d ldr q20, [x8, #3136] -// 0x1000 + 0x850 = 0x1850 = tcb + var1 -// CHECK-NEXT: 21000c: 08 05 40 91 add x8, x8, #1, lsl #12 -// CHECK-NEXT: 210010: 00 29 44 f9 ldr x0, [x8, #2128] -// 0x2000 + 0x458 = 0x2458 = tcb + var2 -// CHECK-NEXT: 210014: 08 09 40 91 add x8, x8, #2, lsl #12 -// CHECK-NEXT: 210018: 00 59 44 b9 ldr w0, [x8, #1112] -// 0x3000 + 0x5c = 0x305c = tcb + var3 -// CHECK-NEXT: 21001c: 08 0d 40 91 add x8, x8, #3, lsl #12 -// CHECK-NEXT: 210020: 00 b9 40 79 ldrh w0, [x8, #92] -// 0x3000 + 0xc5e = 0x3c5e = tcb + var4 -// CHECK-NEXT: 210024: 08 0d 40 91 add x8, x8, #3, lsl #12 -// CHECK-NEXT: 210028: 00 79 71 39 ldrb w0, [x8, #3166] +// 0x0 + c10 = 0xc10 = tcb (16-bytes) + var0 +// CHECK-NEXT: 210004: 08 01 40 91 add x8, x8, #0, lsl #12 +// CHECK-NEXT: 210008: 14 05 c3 3d ldr q20, [x8, #3088] +// 0x1000 + 0x820 = 0x1820 = tcb + var1 +// CHECK-NEXT: 21000c: 08 05 40 91 add x8, x8, #1, lsl #12 +// CHECK-NEXT: 210010: 00 11 44 f9 ldr x0, [x8, #2080] +// 0x2000 + 0x428 = 0x2428 = tcb + var2 +// CHECK-NEXT: 210014: 08 09 40 91 add x8, x8, #2, lsl #12 +// CHECK-NEXT: 210018: 00 29 44 b9 ldr w0, [x8, #1064] +// 0x3000 + 0x2c = 0x302c = tcb + var3 +// CHECK-NEXT: 21001c: 08 0d 40 91 add x8, x8, #3, lsl #12 +// CHECK-NEXT: 210020: 00 59 40 79 ldrh w0, [x8, #44] +// 0x3000 + 0xc2e = 0x32ce = tcb + var4 +// CHECK-NEXT: 210024: 08 0d 40 91 add x8, x8, #3, lsl #12 +// CHECK-NEXT: 210028: 00 b9 70 39 ldrb w0, [x8, #3118] -// CHECK-SYMS: 0000000000000c00 16 TLS GLOBAL DEFAULT 2 var0 -// CHECK-SYMS-NEXT: 0000000000001810 8 TLS GLOBAL DEFAULT 2 var1 -// CHECK-SYMS-NEXT: 0000000000002418 4 TLS GLOBAL DEFAULT 2 var2 -// CHECK-SYMS-NEXT: 000000000000301c 2 TLS GLOBAL DEFAULT 2 var3 -// CHECK-SYMS-NEXT: 0000000000003c1e 1 TLS GLOBAL DEFAULT 2 var4 +// CHECK-SYMS: 0000000000000c00 0 TLS GLOBAL DEFAULT 2 var0 +// CHECK-SYMS-NEXT: 0000000000001810 4 TLS GLOBAL DEFAULT 2 var1 +// CHECK-SYMS-NEXT: 0000000000002418 2 TLS GLOBAL DEFAULT 2 var2 +// CHECK-SYMS-NEXT: 000000000000301c 1 TLS GLOBAL DEFAULT 2 var3 +// CHECK-SYMS-NEXT: 0000000000003c1e 0 TLS GLOBAL DEFAULT 2 var4 .globl var0 .globl var1 @@ -59,12 +59,12 @@ _start: mrs x8, TPIDR_EL0 .type var3,@object .section .tbss,"awT",@nobits - .balign 64 + .balign 16 .space 1024 * 3 var0: .quad 0 .quad 0 - .size var0, 16 + .size var1, 16 .space 1024 * 3 var1: .quad 0 @@ -72,14 +72,14 @@ var1: .space 1024 * 3 var2: .word 0 - .size var2, 4 + .size var1, 4 .space 1024 * 3 var3: .hword 0 - .size var3, 2 + .size var2, 2 .space 1024 * 3 var4: .byte 0 - .size var4, 1 + .size var3, 1 .space 1024 * 3 diff --git a/lld/test/ELF/arm-tls-le32.s b/lld/test/ELF/arm-tls-le32.s index f9a5fa9b2fc90..7834dedf1be0f 100644 --- a/lld/test/ELF/arm-tls-le32.s +++ b/lld/test/ELF/arm-tls-le32.s @@ -69,9 +69,9 @@ x: // CHECK: Disassembly of section .text: // CHECK-NEXT: _start: -// offset of x from Thread pointer = (TcbSize + 0x0 = 0x20) -// CHECK-NEXT: 11000: 20 00 00 00 -// offset of z from Thread pointer = (TcbSize + 0x8 = 0x28) -// CHECK-NEXT: 11004: 28 00 00 00 -// offset of y from Thread pointer = (TcbSize + 0x4 = 0x24) -// CHECK-NEXT: 11008: 24 00 00 00 +// offset of x from Thread pointer = (TcbSize + 0x0 = 0x8) +// CHECK-NEXT: 11000: 08 00 00 00 +// offset of z from Thread pointer = (TcbSize + 0x8 = 0x10) +// CHECK-NEXT: 11004: 10 00 00 00 +// offset of y from Thread pointer = (TcbSize + 0x4 = 0xc) +// CHECK-NEXT: 11008: 0c 00 00 00 diff --git a/lld/test/ELF/arm-tls-norelax-ie-le.s b/lld/test/ELF/arm-tls-norelax-ie-le.s index 11c3e4f5dc1a2..4a52f547f0a93 100644 --- a/lld/test/ELF/arm-tls-norelax-ie-le.s +++ b/lld/test/ELF/arm-tls-norelax-ie-le.s @@ -37,5 +37,5 @@ x2: .type x2, %object // CHECK: Contents of section .got: -// x1 at offset 0x20 from TP, x2 at offset 0x24 from TP. Offsets include TCB size of 0x20 -// CHECK-NEXT: 13064 20000000 24000000 +// x1 at offset 8 from TP, x2 at offset 0xc from TP. Offsets include TCB size of 8 +// CHECK-NEXT: 13064 08000000 0c000000 From 90c370c33dca77ccabc4eeebe57c3c7f05a0ce61 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Mon, 10 Jun 2019 23:25:00 +0000 Subject: [PATCH 260/274] Merging r351577: ------------------------------------------------------------------------ r351577 | ssijaric | 2019-01-18 11:34:20 -0800 (Fri, 18 Jan 2019) | 5 lines Fix the buildbot issue introduced by r351421 The EXPENSIVE_CHECK x86_64 Windows buildbot is failing due to this change. Fix the map access. ------------------------------------------------------------------------ llvm-svn: 363006 --- llvm/lib/MC/MCWin64EH.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/MC/MCWin64EH.cpp b/llvm/lib/MC/MCWin64EH.cpp index 8bc1f08c88750..3ef1514455af3 100644 --- a/llvm/lib/MC/MCWin64EH.cpp +++ b/llvm/lib/MC/MCWin64EH.cpp @@ -522,7 +522,7 @@ static void ARM64EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) { if (MatchingEpilog) { assert(EpilogInfo.find(MatchingEpilog) != EpilogInfo.end() && "Duplicate epilog not found"); - EpilogInfo[EpilogStart] = EpilogInfo[MatchingEpilog]; + EpilogInfo[EpilogStart] = EpilogInfo.lookup(MatchingEpilog); // Clear the unwind codes in the EpilogMap, so that they don't get output // in the logic below. EpilogInstrs.clear(); From 9a2cfaed4ebeb20583e86c0c41c4fa113d7a017c Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Mon, 10 Jun 2019 23:34:50 +0000 Subject: [PATCH 261/274] Merging r358042: ------------------------------------------------------------------------ r358042 | jimlin | 2019-04-09 18:56:32 -0700 (Tue, 09 Apr 2019) | 34 lines [Sparc] Fix incorrect MI insertion position for spilling f128. Summary: Obviously, new built MI (sethi+add or sethi+xor+add) for constructing large offset should be inserted before new created MI for storing even register into memory. So the insertion position should be *StMI instead of II. before fixed: std %f0, [%g1+80] sethi 4, %g1 <<< add %g1, %sp, %g1 <<< this two instructions should be put before "std %f0, [%g1+80]". sethi 4, %g1 add %g1, %sp, %g1 std %f2, [%g1+88] after fixed: sethi 4, %g1 add %g1, %sp, %g1 std %f0, [%g1+80] sethi 4, %g1 add %g1, %sp, %g1 std %f2, [%g1+88] Reviewers: venkatra, jyknight Reviewed By: jyknight Subscribers: jyknight, fedor.sergeev, jrtc27, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D60397 ------------------------------------------------------------------------ llvm-svn: 363010 --- llvm/lib/Target/Sparc/SparcRegisterInfo.cpp | 4 ++-- llvm/test/CodeGen/SPARC/fp128.ll | 23 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp b/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp index 33caa66154ff2..ad6ea3760feee 100644 --- a/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp +++ b/llvm/lib/Target/Sparc/SparcRegisterInfo.cpp @@ -189,7 +189,7 @@ SparcRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, MachineInstr *StMI = BuildMI(*MI.getParent(), II, dl, TII.get(SP::STDFri)) .addReg(FrameReg).addImm(0).addReg(SrcEvenReg); - replaceFI(MF, II, *StMI, dl, 0, Offset, FrameReg); + replaceFI(MF, *StMI, *StMI, dl, 0, Offset, FrameReg); MI.setDesc(TII.get(SP::STDFri)); MI.getOperand(2).setReg(SrcOddReg); Offset += 8; @@ -201,7 +201,7 @@ SparcRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, MachineInstr *StMI = BuildMI(*MI.getParent(), II, dl, TII.get(SP::LDDFri), DestEvenReg) .addReg(FrameReg).addImm(0); - replaceFI(MF, II, *StMI, dl, 1, Offset, FrameReg); + replaceFI(MF, *StMI, *StMI, dl, 1, Offset, FrameReg); MI.setDesc(TII.get(SP::LDDFri)); MI.getOperand(0).setReg(DestOddReg); diff --git a/llvm/test/CodeGen/SPARC/fp128.ll b/llvm/test/CodeGen/SPARC/fp128.ll index 535f0ef60c404..21a9cdf77e0de 100644 --- a/llvm/test/CodeGen/SPARC/fp128.ll +++ b/llvm/test/CodeGen/SPARC/fp128.ll @@ -53,6 +53,29 @@ entry: ret void } +; CHECK-LABEL: f128_spill_large: +; CHECK: sethi 4, %g1 +; CHECK: sethi 4, %g1 +; CHECK-NEXT: add %g1, %sp, %g1 +; CHECK-NEXT: std %f{{.+}}, [%g1] +; CHECK: sethi 4, %g1 +; CHECK-NEXT: add %g1, %sp, %g1 +; CHECK-NEXT: std %f{{.+}}, [%g1+8] +; CHECK: sethi 4, %g1 +; CHECK-NEXT: add %g1, %sp, %g1 +; CHECK-NEXT: ldd [%g1], %f{{.+}} +; CHECK: sethi 4, %g1 +; CHECK-NEXT: add %g1, %sp, %g1 +; CHECK-NEXT: ldd [%g1+8], %f{{.+}} + +define void @f128_spill_large(<251 x fp128>* noalias sret %scalar.result, <251 x fp128>* byval %a) { +entry: + %0 = load <251 x fp128>, <251 x fp128>* %a, align 8 + call void asm sideeffect "", "~{f0},~{f1},~{f2},~{f3},~{f4},~{f5},~{f6},~{f7},~{f8},~{f9},~{f10},~{f11},~{f12},~{f13},~{f14},~{f15},~{f16},~{f17},~{f18},~{f19},~{f20},~{f21},~{f22},~{f23},~{f24},~{f25},~{f26},~{f27},~{f28},~{f29},~{f30},~{f31}"() + store <251 x fp128> %0, <251 x fp128>* %scalar.result, align 8 + ret void +} + ; CHECK-LABEL: f128_compare: ; HARD: fcmpq ; HARD-NEXT: nop From 213f2edbe61b23ae15cb8a65ad4dc7b22ce874a6 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Tue, 11 Jun 2019 03:07:31 +0000 Subject: [PATCH 262/274] Add release note for DIBuilder API changes llvm-svn: 363027 --- llvm/docs/ReleaseNotes.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 8209c08889edc..16121585d24fb 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -110,6 +110,26 @@ updated to use LLJIT. MCJIT and ExecutionEngine continue to be supported, though ORC should be preferred for new projects. +Changes to the C++ APIs +----------------------- + +Three of the IR library methods related to debugging information for +functions and methods have changed their prototypes: + + DIBuilder::createMethod + DIBuilder::createFunction + DIBuilder::createTempFunctionFwdDecl + +In all cases, several individual parameters were removed, and replaced +by a single 'SPFlags' (subprogram flags) parameter. The individual +parameters are: 'isLocalToUnit'; 'isDefinition'; 'isOptimized'; and +for 'createMethod', 'Virtuality'. The new 'SPFlags' parameter has a +default value equivalent to passing 'false' for the three 'bool' +parameters, and zero (non-virtual) to the 'Virtuality' parameter. For +any old-style API call that passed 'true' or a non-zero virtuality to +these methods, you will need to substitute the correct 'SPFlags' value. +The helper method 'DISubprogram::toSPFlags()' might be useful in making +this conversion. Changes to the AArch64 Target ----------------------------- From 2fb27a25fcb66e33152a278a6c6f284453fe5228 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Tue, 11 Jun 2019 03:47:50 +0000 Subject: [PATCH 263/274] Merging r360862: ------------------------------------------------------------------------ r360862 | mstorsjo | 2019-05-15 23:49:20 -0700 (Wed, 15 May 2019) | 12 lines [PPC] Fix 32-bit build of libunwind Clang integrated assembler was unable to build libunwind PPC32 assembly code, present in functions used to save/restore register context. This change consists in replacing the assembly style used in libunwind source, to one that is compatible with both Clang integrated assembler as well as GNU assembler. Patch by Leandro Lupori! Differential Revision: https://reviews.llvm.org/D61792 ------------------------------------------------------------------------ llvm-svn: 363030 --- libunwind/src/UnwindRegistersRestore.S | 238 +++++++++++----------- libunwind/src/UnwindRegistersSave.S | 270 ++++++++++++------------- libunwind/src/assembly.h | 2 - 3 files changed, 254 insertions(+), 256 deletions(-) diff --git a/libunwind/src/UnwindRegistersRestore.S b/libunwind/src/UnwindRegistersRestore.S index 389db67579cdf..a155fbe2ddf2b 100644 --- a/libunwind/src/UnwindRegistersRestore.S +++ b/libunwind/src/UnwindRegistersRestore.S @@ -396,119 +396,119 @@ Lnovec: #elif defined(__ppc__) DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv) -; -; void libunwind::Registers_ppc::jumpto() -; -; On entry: -; thread_state pointer is in r3 -; - - ; restore integral registerrs - ; skip r0 for now - ; skip r1 for now - lwz r2, 16(r3) - ; skip r3 for now - ; skip r4 for now - ; skip r5 for now - lwz r6, 32(r3) - lwz r7, 36(r3) - lwz r8, 40(r3) - lwz r9, 44(r3) - lwz r10, 48(r3) - lwz r11, 52(r3) - lwz r12, 56(r3) - lwz r13, 60(r3) - lwz r14, 64(r3) - lwz r15, 68(r3) - lwz r16, 72(r3) - lwz r17, 76(r3) - lwz r18, 80(r3) - lwz r19, 84(r3) - lwz r20, 88(r3) - lwz r21, 92(r3) - lwz r22, 96(r3) - lwz r23,100(r3) - lwz r24,104(r3) - lwz r25,108(r3) - lwz r26,112(r3) - lwz r27,116(r3) - lwz r28,120(r3) - lwz r29,124(r3) - lwz r30,128(r3) - lwz r31,132(r3) - - ; restore float registers - lfd f0, 160(r3) - lfd f1, 168(r3) - lfd f2, 176(r3) - lfd f3, 184(r3) - lfd f4, 192(r3) - lfd f5, 200(r3) - lfd f6, 208(r3) - lfd f7, 216(r3) - lfd f8, 224(r3) - lfd f9, 232(r3) - lfd f10,240(r3) - lfd f11,248(r3) - lfd f12,256(r3) - lfd f13,264(r3) - lfd f14,272(r3) - lfd f15,280(r3) - lfd f16,288(r3) - lfd f17,296(r3) - lfd f18,304(r3) - lfd f19,312(r3) - lfd f20,320(r3) - lfd f21,328(r3) - lfd f22,336(r3) - lfd f23,344(r3) - lfd f24,352(r3) - lfd f25,360(r3) - lfd f26,368(r3) - lfd f27,376(r3) - lfd f28,384(r3) - lfd f29,392(r3) - lfd f30,400(r3) - lfd f31,408(r3) - - ; restore vector registers if any are in use - lwz r5,156(r3) ; test VRsave - cmpwi r5,0 - beq Lnovec - - subi r4,r1,16 - rlwinm r4,r4,0,0,27 ; mask low 4-bits - ; r4 is now a 16-byte aligned pointer into the red zone - ; the _vectorRegisters may not be 16-byte aligned so copy via red zone temp buffer +// +// void libunwind::Registers_ppc::jumpto() +// +// On entry: +// thread_state pointer is in r3 +// + + // restore integral registerrs + // skip r0 for now + // skip r1 for now + lwz %r2, 16(%r3) + // skip r3 for now + // skip r4 for now + // skip r5 for now + lwz %r6, 32(%r3) + lwz %r7, 36(%r3) + lwz %r8, 40(%r3) + lwz %r9, 44(%r3) + lwz %r10, 48(%r3) + lwz %r11, 52(%r3) + lwz %r12, 56(%r3) + lwz %r13, 60(%r3) + lwz %r14, 64(%r3) + lwz %r15, 68(%r3) + lwz %r16, 72(%r3) + lwz %r17, 76(%r3) + lwz %r18, 80(%r3) + lwz %r19, 84(%r3) + lwz %r20, 88(%r3) + lwz %r21, 92(%r3) + lwz %r22, 96(%r3) + lwz %r23,100(%r3) + lwz %r24,104(%r3) + lwz %r25,108(%r3) + lwz %r26,112(%r3) + lwz %r27,116(%r3) + lwz %r28,120(%r3) + lwz %r29,124(%r3) + lwz %r30,128(%r3) + lwz %r31,132(%r3) + + // restore float registers + lfd %f0, 160(%r3) + lfd %f1, 168(%r3) + lfd %f2, 176(%r3) + lfd %f3, 184(%r3) + lfd %f4, 192(%r3) + lfd %f5, 200(%r3) + lfd %f6, 208(%r3) + lfd %f7, 216(%r3) + lfd %f8, 224(%r3) + lfd %f9, 232(%r3) + lfd %f10,240(%r3) + lfd %f11,248(%r3) + lfd %f12,256(%r3) + lfd %f13,264(%r3) + lfd %f14,272(%r3) + lfd %f15,280(%r3) + lfd %f16,288(%r3) + lfd %f17,296(%r3) + lfd %f18,304(%r3) + lfd %f19,312(%r3) + lfd %f20,320(%r3) + lfd %f21,328(%r3) + lfd %f22,336(%r3) + lfd %f23,344(%r3) + lfd %f24,352(%r3) + lfd %f25,360(%r3) + lfd %f26,368(%r3) + lfd %f27,376(%r3) + lfd %f28,384(%r3) + lfd %f29,392(%r3) + lfd %f30,400(%r3) + lfd %f31,408(%r3) + + // restore vector registers if any are in use + lwz %r5, 156(%r3) // test VRsave + cmpwi %r5, 0 + beq Lnovec + subi %r4, %r1, 16 + rlwinm %r4, %r4, 0, 0, 27 // mask low 4-bits + // r4 is now a 16-byte aligned pointer into the red zone + // the _vectorRegisters may not be 16-byte aligned so copy via red zone temp buffer + #define LOAD_VECTOR_UNALIGNEDl(_index) \ - andis. r0,r5,(1<<(15-_index)) @\ - beq Ldone ## _index @\ - lwz r0, 424+_index*16(r3) @\ - stw r0, 0(r4) @\ - lwz r0, 424+_index*16+4(r3) @\ - stw r0, 4(r4) @\ - lwz r0, 424+_index*16+8(r3) @\ - stw r0, 8(r4) @\ - lwz r0, 424+_index*16+12(r3)@\ - stw r0, 12(r4) @\ - lvx v ## _index,0,r4 @\ -Ldone ## _index: + andis. %r0, %r5, (1<<(15-_index)) SEPARATOR \ + beq Ldone ## _index SEPARATOR \ + lwz %r0, 424+_index*16(%r3) SEPARATOR \ + stw %r0, 0(%r4) SEPARATOR \ + lwz %r0, 424+_index*16+4(%r3) SEPARATOR \ + stw %r0, 4(%r4) SEPARATOR \ + lwz %r0, 424+_index*16+8(%r3) SEPARATOR \ + stw %r0, 8(%r4) SEPARATOR \ + lwz %r0, 424+_index*16+12(%r3) SEPARATOR \ + stw %r0, 12(%r4) SEPARATOR \ + lvx %v ## _index, 0, %r4 SEPARATOR \ + Ldone ## _index: #define LOAD_VECTOR_UNALIGNEDh(_index) \ - andi. r0,r5,(1<<(31-_index)) @\ - beq Ldone ## _index @\ - lwz r0, 424+_index*16(r3) @\ - stw r0, 0(r4) @\ - lwz r0, 424+_index*16+4(r3) @\ - stw r0, 4(r4) @\ - lwz r0, 424+_index*16+8(r3) @\ - stw r0, 8(r4) @\ - lwz r0, 424+_index*16+12(r3)@\ - stw r0, 12(r4) @\ - lvx v ## _index,0,r4 @\ - Ldone ## _index: + andi. %r0, %r5, (1<<(31-_index)) SEPARATOR \ + beq Ldone ## _index SEPARATOR \ + lwz %r0, 424+_index*16(%r3) SEPARATOR \ + stw %r0, 0(%r4) SEPARATOR \ + lwz %r0, 424+_index*16+4(%r3) SEPARATOR \ + stw %r0, 4(%r4) SEPARATOR \ + lwz %r0, 424+_index*16+8(%r3) SEPARATOR \ + stw %r0, 8(%r4) SEPARATOR \ + lwz %r0, 424+_index*16+12(%r3) SEPARATOR \ + stw %r0, 12(%r4) SEPARATOR \ + lvx %v ## _index, 0, %r4 SEPARATOR \ + Ldone ## _index: LOAD_VECTOR_UNALIGNEDl(0) @@ -545,17 +545,17 @@ Ldone ## _index: LOAD_VECTOR_UNALIGNEDh(31) Lnovec: - lwz r0, 136(r3) ; __cr - mtocrf 255,r0 - lwz r0, 148(r3) ; __ctr - mtctr r0 - lwz r0, 0(r3) ; __ssr0 - mtctr r0 - lwz r0, 8(r3) ; do r0 now - lwz r5,28(r3) ; do r5 now - lwz r4,24(r3) ; do r4 now - lwz r1,12(r3) ; do sp now - lwz r3,20(r3) ; do r3 last + lwz %r0, 136(%r3) // __cr + mtcr %r0 + lwz %r0, 148(%r3) // __ctr + mtctr %r0 + lwz %r0, 0(%r3) // __ssr0 + mtctr %r0 + lwz %r0, 8(%r3) // do r0 now + lwz %r5, 28(%r3) // do r5 now + lwz %r4, 24(%r3) // do r4 now + lwz %r1, 12(%r3) // do sp now + lwz %r3, 20(%r3) // do r3 last bctr #elif defined(__arm64__) || defined(__aarch64__) diff --git a/libunwind/src/UnwindRegistersSave.S b/libunwind/src/UnwindRegistersSave.S index 48ecb0aec70f1..4b674afc6bdc8 100644 --- a/libunwind/src/UnwindRegistersSave.S +++ b/libunwind/src/UnwindRegistersSave.S @@ -557,144 +557,144 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) #elif defined(__ppc__) -; -; extern int unw_getcontext(unw_context_t* thread_state) -; -; On entry: -; thread_state pointer is in r3 -; +// +// extern int unw_getcontext(unw_context_t* thread_state) +// +// On entry: +// thread_state pointer is in r3 +// DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) - stw r0, 8(r3) - mflr r0 - stw r0, 0(r3) ; store lr as ssr0 - stw r1, 12(r3) - stw r2, 16(r3) - stw r3, 20(r3) - stw r4, 24(r3) - stw r5, 28(r3) - stw r6, 32(r3) - stw r7, 36(r3) - stw r8, 40(r3) - stw r9, 44(r3) - stw r10, 48(r3) - stw r11, 52(r3) - stw r12, 56(r3) - stw r13, 60(r3) - stw r14, 64(r3) - stw r15, 68(r3) - stw r16, 72(r3) - stw r17, 76(r3) - stw r18, 80(r3) - stw r19, 84(r3) - stw r20, 88(r3) - stw r21, 92(r3) - stw r22, 96(r3) - stw r23,100(r3) - stw r24,104(r3) - stw r25,108(r3) - stw r26,112(r3) - stw r27,116(r3) - stw r28,120(r3) - stw r29,124(r3) - stw r30,128(r3) - stw r31,132(r3) - - ; save VRSave register - mfspr r0,256 - stw r0,156(r3) - ; save CR registers - mfcr r0 - stw r0,136(r3) - ; save CTR register - mfctr r0 - stw r0,148(r3) - - ; save float registers - stfd f0, 160(r3) - stfd f1, 168(r3) - stfd f2, 176(r3) - stfd f3, 184(r3) - stfd f4, 192(r3) - stfd f5, 200(r3) - stfd f6, 208(r3) - stfd f7, 216(r3) - stfd f8, 224(r3) - stfd f9, 232(r3) - stfd f10,240(r3) - stfd f11,248(r3) - stfd f12,256(r3) - stfd f13,264(r3) - stfd f14,272(r3) - stfd f15,280(r3) - stfd f16,288(r3) - stfd f17,296(r3) - stfd f18,304(r3) - stfd f19,312(r3) - stfd f20,320(r3) - stfd f21,328(r3) - stfd f22,336(r3) - stfd f23,344(r3) - stfd f24,352(r3) - stfd f25,360(r3) - stfd f26,368(r3) - stfd f27,376(r3) - stfd f28,384(r3) - stfd f29,392(r3) - stfd f30,400(r3) - stfd f31,408(r3) - - - ; save vector registers - - subi r4,r1,16 - rlwinm r4,r4,0,0,27 ; mask low 4-bits - ; r4 is now a 16-byte aligned pointer into the red zone + stw %r0, 8(%r3) + mflr %r0 + stw %r0, 0(%r3) // store lr as ssr0 + stw %r1, 12(%r3) + stw %r2, 16(%r3) + stw %r3, 20(%r3) + stw %r4, 24(%r3) + stw %r5, 28(%r3) + stw %r6, 32(%r3) + stw %r7, 36(%r3) + stw %r8, 40(%r3) + stw %r9, 44(%r3) + stw %r10, 48(%r3) + stw %r11, 52(%r3) + stw %r12, 56(%r3) + stw %r13, 60(%r3) + stw %r14, 64(%r3) + stw %r15, 68(%r3) + stw %r16, 72(%r3) + stw %r17, 76(%r3) + stw %r18, 80(%r3) + stw %r19, 84(%r3) + stw %r20, 88(%r3) + stw %r21, 92(%r3) + stw %r22, 96(%r3) + stw %r23,100(%r3) + stw %r24,104(%r3) + stw %r25,108(%r3) + stw %r26,112(%r3) + stw %r27,116(%r3) + stw %r28,120(%r3) + stw %r29,124(%r3) + stw %r30,128(%r3) + stw %r31,132(%r3) + + // save VRSave register + mfspr %r0, 256 + stw %r0, 156(%r3) + // save CR registers + mfcr %r0 + stw %r0, 136(%r3) + // save CTR register + mfctr %r0 + stw %r0, 148(%r3) + + // save float registers + stfd %f0, 160(%r3) + stfd %f1, 168(%r3) + stfd %f2, 176(%r3) + stfd %f3, 184(%r3) + stfd %f4, 192(%r3) + stfd %f5, 200(%r3) + stfd %f6, 208(%r3) + stfd %f7, 216(%r3) + stfd %f8, 224(%r3) + stfd %f9, 232(%r3) + stfd %f10,240(%r3) + stfd %f11,248(%r3) + stfd %f12,256(%r3) + stfd %f13,264(%r3) + stfd %f14,272(%r3) + stfd %f15,280(%r3) + stfd %f16,288(%r3) + stfd %f17,296(%r3) + stfd %f18,304(%r3) + stfd %f19,312(%r3) + stfd %f20,320(%r3) + stfd %f21,328(%r3) + stfd %f22,336(%r3) + stfd %f23,344(%r3) + stfd %f24,352(%r3) + stfd %f25,360(%r3) + stfd %f26,368(%r3) + stfd %f27,376(%r3) + stfd %f28,384(%r3) + stfd %f29,392(%r3) + stfd %f30,400(%r3) + stfd %f31,408(%r3) + + + // save vector registers + + subi %r4, %r1, 16 + rlwinm %r4, %r4, 0, 0, 27 // mask low 4-bits + // r4 is now a 16-byte aligned pointer into the red zone #define SAVE_VECTOR_UNALIGNED(_vec, _offset) \ - stvx _vec,0,r4 @\ - lwz r5, 0(r4) @\ - stw r5, _offset(r3) @\ - lwz r5, 4(r4) @\ - stw r5, _offset+4(r3) @\ - lwz r5, 8(r4) @\ - stw r5, _offset+8(r3) @\ - lwz r5, 12(r4) @\ - stw r5, _offset+12(r3) - - SAVE_VECTOR_UNALIGNED( v0, 424+0x000) - SAVE_VECTOR_UNALIGNED( v1, 424+0x010) - SAVE_VECTOR_UNALIGNED( v2, 424+0x020) - SAVE_VECTOR_UNALIGNED( v3, 424+0x030) - SAVE_VECTOR_UNALIGNED( v4, 424+0x040) - SAVE_VECTOR_UNALIGNED( v5, 424+0x050) - SAVE_VECTOR_UNALIGNED( v6, 424+0x060) - SAVE_VECTOR_UNALIGNED( v7, 424+0x070) - SAVE_VECTOR_UNALIGNED( v8, 424+0x080) - SAVE_VECTOR_UNALIGNED( v9, 424+0x090) - SAVE_VECTOR_UNALIGNED(v10, 424+0x0A0) - SAVE_VECTOR_UNALIGNED(v11, 424+0x0B0) - SAVE_VECTOR_UNALIGNED(v12, 424+0x0C0) - SAVE_VECTOR_UNALIGNED(v13, 424+0x0D0) - SAVE_VECTOR_UNALIGNED(v14, 424+0x0E0) - SAVE_VECTOR_UNALIGNED(v15, 424+0x0F0) - SAVE_VECTOR_UNALIGNED(v16, 424+0x100) - SAVE_VECTOR_UNALIGNED(v17, 424+0x110) - SAVE_VECTOR_UNALIGNED(v18, 424+0x120) - SAVE_VECTOR_UNALIGNED(v19, 424+0x130) - SAVE_VECTOR_UNALIGNED(v20, 424+0x140) - SAVE_VECTOR_UNALIGNED(v21, 424+0x150) - SAVE_VECTOR_UNALIGNED(v22, 424+0x160) - SAVE_VECTOR_UNALIGNED(v23, 424+0x170) - SAVE_VECTOR_UNALIGNED(v24, 424+0x180) - SAVE_VECTOR_UNALIGNED(v25, 424+0x190) - SAVE_VECTOR_UNALIGNED(v26, 424+0x1A0) - SAVE_VECTOR_UNALIGNED(v27, 424+0x1B0) - SAVE_VECTOR_UNALIGNED(v28, 424+0x1C0) - SAVE_VECTOR_UNALIGNED(v29, 424+0x1D0) - SAVE_VECTOR_UNALIGNED(v30, 424+0x1E0) - SAVE_VECTOR_UNALIGNED(v31, 424+0x1F0) - - li r3, 0 ; return UNW_ESUCCESS + stvx _vec, 0, %r4 SEPARATOR \ + lwz %r5, 0(%r4) SEPARATOR \ + stw %r5, _offset(%r3) SEPARATOR \ + lwz %r5, 4(%r4) SEPARATOR \ + stw %r5, _offset+4(%r3) SEPARATOR \ + lwz %r5, 8(%r4) SEPARATOR \ + stw %r5, _offset+8(%r3) SEPARATOR \ + lwz %r5, 12(%r4) SEPARATOR \ + stw %r5, _offset+12(%r3) + + SAVE_VECTOR_UNALIGNED( %v0, 424+0x000) + SAVE_VECTOR_UNALIGNED( %v1, 424+0x010) + SAVE_VECTOR_UNALIGNED( %v2, 424+0x020) + SAVE_VECTOR_UNALIGNED( %v3, 424+0x030) + SAVE_VECTOR_UNALIGNED( %v4, 424+0x040) + SAVE_VECTOR_UNALIGNED( %v5, 424+0x050) + SAVE_VECTOR_UNALIGNED( %v6, 424+0x060) + SAVE_VECTOR_UNALIGNED( %v7, 424+0x070) + SAVE_VECTOR_UNALIGNED( %v8, 424+0x080) + SAVE_VECTOR_UNALIGNED( %v9, 424+0x090) + SAVE_VECTOR_UNALIGNED(%v10, 424+0x0A0) + SAVE_VECTOR_UNALIGNED(%v11, 424+0x0B0) + SAVE_VECTOR_UNALIGNED(%v12, 424+0x0C0) + SAVE_VECTOR_UNALIGNED(%v13, 424+0x0D0) + SAVE_VECTOR_UNALIGNED(%v14, 424+0x0E0) + SAVE_VECTOR_UNALIGNED(%v15, 424+0x0F0) + SAVE_VECTOR_UNALIGNED(%v16, 424+0x100) + SAVE_VECTOR_UNALIGNED(%v17, 424+0x110) + SAVE_VECTOR_UNALIGNED(%v18, 424+0x120) + SAVE_VECTOR_UNALIGNED(%v19, 424+0x130) + SAVE_VECTOR_UNALIGNED(%v20, 424+0x140) + SAVE_VECTOR_UNALIGNED(%v21, 424+0x150) + SAVE_VECTOR_UNALIGNED(%v22, 424+0x160) + SAVE_VECTOR_UNALIGNED(%v23, 424+0x170) + SAVE_VECTOR_UNALIGNED(%v24, 424+0x180) + SAVE_VECTOR_UNALIGNED(%v25, 424+0x190) + SAVE_VECTOR_UNALIGNED(%v26, 424+0x1A0) + SAVE_VECTOR_UNALIGNED(%v27, 424+0x1B0) + SAVE_VECTOR_UNALIGNED(%v28, 424+0x1C0) + SAVE_VECTOR_UNALIGNED(%v29, 424+0x1D0) + SAVE_VECTOR_UNALIGNED(%v30, 424+0x1E0) + SAVE_VECTOR_UNALIGNED(%v31, 424+0x1F0) + + li %r3, 0 // return UNW_ESUCCESS blr diff --git a/libunwind/src/assembly.h b/libunwind/src/assembly.h index 2df930214fae5..7806892e9dcf9 100644 --- a/libunwind/src/assembly.h +++ b/libunwind/src/assembly.h @@ -29,8 +29,6 @@ #ifdef _ARCH_PWR8 #define PPC64_HAS_VMX #endif -#elif defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__) -#define SEPARATOR @ #elif defined(__arm64__) #define SEPARATOR %% #else From c2be20806736116b64eacae4ae05c102f46e54e1 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Mon, 17 Jun 2019 22:57:11 +0000 Subject: [PATCH 264/274] Merging r361158: ------------------------------------------------------------------------ r361158 | jprotze | 2019-05-20 07:21:42 -0700 (Mon, 20 May 2019) | 11 lines [OpenMP][OMPT] Fix locking testcases for 32 bit architectures https://reviews.llvm.org/D58454 did not fix the problem for a typical use case of building LLVM with gcc or icc and then testing with the newly built clang compiler. The compilers do not agree on how to extend a 32-bit pointer to uint64, so make the pointer unsigned first, before adjusting the size. Patch by Joachim Protze Differential Revision: https://reviews.llvm.org/D58506 ------------------------------------------------------------------------ llvm-svn: 363628 --- openmp/runtime/src/kmp_atomic.h | 6 +- openmp/runtime/src/kmp_csupport.cpp | 131 ++++++++++-------- openmp/runtime/src/ompt-specific.cpp | 2 +- .../runtime/test/ompt/synchronization/lock.c | 2 +- .../test/ompt/synchronization/nest_lock.c | 2 +- 5 files changed, 76 insertions(+), 67 deletions(-) diff --git a/openmp/runtime/src/kmp_atomic.h b/openmp/runtime/src/kmp_atomic.h index 288916cd27c9d..004d1a6cdd6bc 100644 --- a/openmp/runtime/src/kmp_atomic.h +++ b/openmp/runtime/src/kmp_atomic.h @@ -364,7 +364,7 @@ static inline void __kmp_acquire_atomic_lock(kmp_atomic_lock_t *lck, #if OMPT_SUPPORT && OMPT_OPTIONAL if (ompt_enabled.ompt_callback_mutex_acquire) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquire)( - ompt_mutex_atomic, 0, kmp_mutex_impl_queuing, (ompt_wait_id_t)lck, + ompt_mutex_atomic, 0, kmp_mutex_impl_queuing, (ompt_wait_id_t)(uintptr_t)lck, OMPT_GET_RETURN_ADDRESS(0)); } #endif @@ -374,7 +374,7 @@ static inline void __kmp_acquire_atomic_lock(kmp_atomic_lock_t *lck, #if OMPT_SUPPORT && OMPT_OPTIONAL if (ompt_enabled.ompt_callback_mutex_acquired) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquired)( - ompt_mutex_atomic, (ompt_wait_id_t)lck, OMPT_GET_RETURN_ADDRESS(0)); + ompt_mutex_atomic, (ompt_wait_id_t)(uintptr_t)lck, OMPT_GET_RETURN_ADDRESS(0)); } #endif } @@ -390,7 +390,7 @@ static inline void __kmp_release_atomic_lock(kmp_atomic_lock_t *lck, #if OMPT_SUPPORT && OMPT_OPTIONAL if (ompt_enabled.ompt_callback_mutex_released) { ompt_callbacks.ompt_callback(ompt_callback_mutex_released)( - ompt_mutex_atomic, (ompt_wait_id_t)lck, OMPT_GET_RETURN_ADDRESS(0)); + ompt_mutex_atomic, (ompt_wait_id_t)(uintptr_t)lck, OMPT_GET_RETURN_ADDRESS(0)); } #endif } diff --git a/openmp/runtime/src/kmp_csupport.cpp b/openmp/runtime/src/kmp_csupport.cpp index 61d4a93011205..3afefed560fd6 100644 --- a/openmp/runtime/src/kmp_csupport.cpp +++ b/openmp/runtime/src/kmp_csupport.cpp @@ -848,7 +848,7 @@ void __kmpc_ordered(ident_t *loc, kmp_int32 gtid) { if (ompt_enabled.enabled) { OMPT_STORE_RETURN_ADDRESS(gtid); team = __kmp_team_from_gtid(gtid); - lck = (ompt_wait_id_t)&team->t.t_ordered.dt.t_value; + lck = (ompt_wait_id_t)(uintptr_t)&team->t.t_ordered.dt.t_value; /* OMPT state update */ th->th.ompt_thread_info.wait_id = lck; th->th.ompt_thread_info.state = ompt_state_wait_ordered; @@ -857,8 +857,8 @@ void __kmpc_ordered(ident_t *loc, kmp_int32 gtid) { codeptr_ra = OMPT_LOAD_RETURN_ADDRESS(gtid); if (ompt_enabled.ompt_callback_mutex_acquire) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquire)( - ompt_mutex_ordered, omp_lock_hint_none, kmp_mutex_impl_spin, - (ompt_wait_id_t)lck, codeptr_ra); + ompt_mutex_ordered, omp_lock_hint_none, kmp_mutex_impl_spin, lck, + codeptr_ra); } } #endif @@ -877,7 +877,7 @@ void __kmpc_ordered(ident_t *loc, kmp_int32 gtid) { /* OMPT event callback */ if (ompt_enabled.ompt_callback_mutex_acquired) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquired)( - ompt_mutex_ordered, (ompt_wait_id_t)lck, codeptr_ra); + ompt_mutex_ordered, (ompt_wait_id_t)(uintptr_t)lck, codeptr_ra); } } #endif @@ -917,7 +917,8 @@ void __kmpc_end_ordered(ident_t *loc, kmp_int32 gtid) { if (ompt_enabled.ompt_callback_mutex_released) { ompt_callbacks.ompt_callback(ompt_callback_mutex_released)( ompt_mutex_ordered, - (ompt_wait_id_t)&__kmp_team_from_gtid(gtid)->t.t_ordered.dt.t_value, + (ompt_wait_id_t)(uintptr_t)&__kmp_team_from_gtid(gtid) + ->t.t_ordered.dt.t_value, OMPT_LOAD_RETURN_ADDRESS(gtid)); } #endif @@ -1188,7 +1189,7 @@ void __kmpc_critical(ident_t *loc, kmp_int32 global_tid, ti = __kmp_threads[global_tid]->th.ompt_thread_info; /* OMPT state update */ prev_state = ti.state; - ti.wait_id = (ompt_wait_id_t)lck; + ti.wait_id = (ompt_wait_id_t)(uintptr_t)lck; ti.state = ompt_state_wait_critical; /* OMPT event callback */ @@ -1196,7 +1197,7 @@ void __kmpc_critical(ident_t *loc, kmp_int32 global_tid, if (ompt_enabled.ompt_callback_mutex_acquire) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquire)( ompt_mutex_critical, omp_lock_hint_none, __ompt_get_mutex_impl_type(), - (ompt_wait_id_t)crit, codeptr_ra); + (ompt_wait_id_t)(uintptr_t)lck, codeptr_ra); } } #endif @@ -1216,7 +1217,7 @@ void __kmpc_critical(ident_t *loc, kmp_int32 global_tid, /* OMPT event callback */ if (ompt_enabled.ompt_callback_mutex_acquired) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquired)( - ompt_mutex_critical, (ompt_wait_id_t)crit, codeptr_ra); + ompt_mutex_critical, (ompt_wait_id_t)(uintptr_t)lck, codeptr_ra); } } #endif @@ -1402,14 +1403,15 @@ void __kmpc_critical_with_hint(ident_t *loc, kmp_int32 global_tid, ti = __kmp_threads[global_tid]->th.ompt_thread_info; /* OMPT state update */ prev_state = ti.state; - ti.wait_id = (ompt_wait_id_t)lck; + ti.wait_id = (ompt_wait_id_t)(uintptr_t)lck; ti.state = ompt_state_wait_critical; /* OMPT event callback */ if (ompt_enabled.ompt_callback_mutex_acquire) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquire)( ompt_mutex_critical, (unsigned int)hint, - __ompt_get_mutex_impl_type(crit), (ompt_wait_id_t)crit, codeptr); + __ompt_get_mutex_impl_type(crit), (ompt_wait_id_t)(uintptr_t)lck, + codeptr); } } #endif @@ -1440,14 +1442,15 @@ void __kmpc_critical_with_hint(ident_t *loc, kmp_int32 global_tid, ti = __kmp_threads[global_tid]->th.ompt_thread_info; /* OMPT state update */ prev_state = ti.state; - ti.wait_id = (ompt_wait_id_t)lck; + ti.wait_id = (ompt_wait_id_t)(uintptr_t)lck; ti.state = ompt_state_wait_critical; /* OMPT event callback */ if (ompt_enabled.ompt_callback_mutex_acquire) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquire)( ompt_mutex_critical, (unsigned int)hint, - __ompt_get_mutex_impl_type(0, ilk), (ompt_wait_id_t)crit, codeptr); + __ompt_get_mutex_impl_type(0, ilk), (ompt_wait_id_t)(uintptr_t)lck, + codeptr); } } #endif @@ -1467,7 +1470,7 @@ void __kmpc_critical_with_hint(ident_t *loc, kmp_int32 global_tid, /* OMPT event callback */ if (ompt_enabled.ompt_callback_mutex_acquired) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquired)( - ompt_mutex_critical, (ompt_wait_id_t)crit, codeptr); + ompt_mutex_critical, (ompt_wait_id_t)(uintptr_t)lck, codeptr); } } #endif @@ -1565,7 +1568,8 @@ void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid, OMPT_STORE_RETURN_ADDRESS(global_tid); if (ompt_enabled.ompt_callback_mutex_released) { ompt_callbacks.ompt_callback(ompt_callback_mutex_released)( - ompt_mutex_critical, (ompt_wait_id_t)crit, OMPT_LOAD_RETURN_ADDRESS(0)); + ompt_mutex_critical, (ompt_wait_id_t)(uintptr_t)lck, + OMPT_LOAD_RETURN_ADDRESS(0)); } #endif @@ -2189,8 +2193,8 @@ void __kmpc_init_lock_with_hint(ident_t *loc, kmp_int32 gtid, void **user_lock, if (ompt_enabled.ompt_callback_lock_init) { ompt_callbacks.ompt_callback(ompt_callback_lock_init)( ompt_mutex_lock, (omp_lock_hint_t)hint, - __ompt_get_mutex_impl_type(user_lock), (ompt_wait_id_t)user_lock, - codeptr); + __ompt_get_mutex_impl_type(user_lock), + (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } #endif } @@ -2213,8 +2217,8 @@ void __kmpc_init_nest_lock_with_hint(ident_t *loc, kmp_int32 gtid, if (ompt_enabled.ompt_callback_lock_init) { ompt_callbacks.ompt_callback(ompt_callback_lock_init)( ompt_mutex_nest_lock, (omp_lock_hint_t)hint, - __ompt_get_mutex_impl_type(user_lock), (ompt_wait_id_t)user_lock, - codeptr); + __ompt_get_mutex_impl_type(user_lock), + (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } #endif } @@ -2239,8 +2243,8 @@ void __kmpc_init_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_lock_init) { ompt_callbacks.ompt_callback(ompt_callback_lock_init)( ompt_mutex_lock, omp_lock_hint_none, - __ompt_get_mutex_impl_type(user_lock), (ompt_wait_id_t)user_lock, - codeptr); + __ompt_get_mutex_impl_type(user_lock), + (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } #endif @@ -2282,7 +2286,7 @@ void __kmpc_init_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_lock_init) { ompt_callbacks.ompt_callback(ompt_callback_lock_init)( ompt_mutex_lock, omp_lock_hint_none, __ompt_get_mutex_impl_type(), - (ompt_wait_id_t)user_lock, codeptr); + (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } #endif @@ -2311,8 +2315,8 @@ void __kmpc_init_nest_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_lock_init) { ompt_callbacks.ompt_callback(ompt_callback_lock_init)( ompt_mutex_nest_lock, omp_lock_hint_none, - __ompt_get_mutex_impl_type(user_lock), (ompt_wait_id_t)user_lock, - codeptr); + __ompt_get_mutex_impl_type(user_lock), + (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } #endif @@ -2357,7 +2361,7 @@ void __kmpc_init_nest_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_lock_init) { ompt_callbacks.ompt_callback(ompt_callback_lock_init)( ompt_mutex_nest_lock, omp_lock_hint_none, __ompt_get_mutex_impl_type(), - (ompt_wait_id_t)user_lock, codeptr); + (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } #endif @@ -2393,7 +2397,7 @@ void __kmpc_destroy_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { lck = (kmp_user_lock_p)user_lock; } ompt_callbacks.ompt_callback(ompt_callback_lock_destroy)( - ompt_mutex_lock, (ompt_wait_id_t)user_lock, codeptr); + ompt_mutex_lock, (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } #endif KMP_D_LOCK_FUNC(user_lock, destroy)((kmp_dyna_lock_t *)user_lock); @@ -2421,7 +2425,7 @@ void __kmpc_destroy_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { codeptr = OMPT_GET_RETURN_ADDRESS(0); if (ompt_enabled.ompt_callback_lock_destroy) { ompt_callbacks.ompt_callback(ompt_callback_lock_destroy)( - ompt_mutex_lock, (ompt_wait_id_t)user_lock, codeptr); + ompt_mutex_lock, (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } #endif @@ -2461,7 +2465,7 @@ void __kmpc_destroy_nest_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { codeptr = OMPT_GET_RETURN_ADDRESS(0); if (ompt_enabled.ompt_callback_lock_destroy) { ompt_callbacks.ompt_callback(ompt_callback_lock_destroy)( - ompt_mutex_nest_lock, (ompt_wait_id_t)user_lock, codeptr); + ompt_mutex_nest_lock, (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } #endif KMP_D_LOCK_FUNC(user_lock, destroy)((kmp_dyna_lock_t *)user_lock); @@ -2493,7 +2497,7 @@ void __kmpc_destroy_nest_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { codeptr = OMPT_GET_RETURN_ADDRESS(0); if (ompt_enabled.ompt_callback_lock_destroy) { ompt_callbacks.ompt_callback(ompt_callback_lock_destroy)( - ompt_mutex_nest_lock, (ompt_wait_id_t)user_lock, codeptr); + ompt_mutex_nest_lock, (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } #endif @@ -2538,8 +2542,8 @@ void __kmpc_set_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_mutex_acquire) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquire)( ompt_mutex_lock, omp_lock_hint_none, - __ompt_get_mutex_impl_type(user_lock), (ompt_wait_id_t)user_lock, - codeptr); + __ompt_get_mutex_impl_type(user_lock), + (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } #endif #if KMP_USE_INLINED_TAS @@ -2560,7 +2564,7 @@ void __kmpc_set_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { #if OMPT_SUPPORT && OMPT_OPTIONAL if (ompt_enabled.ompt_callback_mutex_acquired) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquired)( - ompt_mutex_lock, (ompt_wait_id_t)user_lock, codeptr); + ompt_mutex_lock, (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } #endif @@ -2593,7 +2597,7 @@ void __kmpc_set_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_mutex_acquire) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquire)( ompt_mutex_lock, omp_lock_hint_none, __ompt_get_mutex_impl_type(), - (ompt_wait_id_t)lck, codeptr); + (ompt_wait_id_t)(uintptr_t)lck, codeptr); } #endif @@ -2606,7 +2610,7 @@ void __kmpc_set_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { #if OMPT_SUPPORT && OMPT_OPTIONAL if (ompt_enabled.ompt_callback_mutex_acquired) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquired)( - ompt_mutex_lock, (ompt_wait_id_t)lck, codeptr); + ompt_mutex_lock, (ompt_wait_id_t)(uintptr_t)lck, codeptr); } #endif @@ -2628,8 +2632,8 @@ void __kmpc_set_nest_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_mutex_acquire) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquire)( ompt_mutex_nest_lock, omp_lock_hint_none, - __ompt_get_mutex_impl_type(user_lock), (ompt_wait_id_t)user_lock, - codeptr); + __ompt_get_mutex_impl_type(user_lock), + (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } } #endif @@ -2646,13 +2650,14 @@ void __kmpc_set_nest_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_mutex_acquired) { // lock_first ompt_callbacks.ompt_callback(ompt_callback_mutex_acquired)( - ompt_mutex_nest_lock, (ompt_wait_id_t)user_lock, codeptr); + ompt_mutex_nest_lock, (ompt_wait_id_t)(uintptr_t)user_lock, + codeptr); } } else { if (ompt_enabled.ompt_callback_nest_lock) { // lock_next ompt_callbacks.ompt_callback(ompt_callback_nest_lock)( - ompt_scope_begin, (ompt_wait_id_t)user_lock, codeptr); + ompt_scope_begin, (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } } } @@ -2690,7 +2695,8 @@ void __kmpc_set_nest_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_mutex_acquire) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquire)( ompt_mutex_nest_lock, omp_lock_hint_none, - __ompt_get_mutex_impl_type(), (ompt_wait_id_t)lck, codeptr); + __ompt_get_mutex_impl_type(), (ompt_wait_id_t)(uintptr_t)lck, + codeptr); } } #endif @@ -2707,13 +2713,13 @@ void __kmpc_set_nest_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_mutex_acquired) { // lock_first ompt_callbacks.ompt_callback(ompt_callback_mutex_acquired)( - ompt_mutex_nest_lock, (ompt_wait_id_t)lck, codeptr); + ompt_mutex_nest_lock, (ompt_wait_id_t)(uintptr_t)lck, codeptr); } } else { if (ompt_enabled.ompt_callback_nest_lock) { // lock_next ompt_callbacks.ompt_callback(ompt_callback_nest_lock)( - ompt_scope_begin, (ompt_wait_id_t)lck, codeptr); + ompt_scope_begin, (ompt_wait_id_t)(uintptr_t)lck, codeptr); } } } @@ -2749,7 +2755,7 @@ void __kmpc_unset_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { codeptr = OMPT_GET_RETURN_ADDRESS(0); if (ompt_enabled.ompt_callback_mutex_released) { ompt_callbacks.ompt_callback(ompt_callback_mutex_released)( - ompt_mutex_lock, (ompt_wait_id_t)user_lock, codeptr); + ompt_mutex_lock, (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } #endif @@ -2778,7 +2784,7 @@ void __kmpc_unset_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { codeptr = OMPT_GET_RETURN_ADDRESS(0); if (ompt_enabled.ompt_callback_mutex_released) { ompt_callbacks.ompt_callback(ompt_callback_mutex_released)( - ompt_mutex_lock, (ompt_wait_id_t)lck, codeptr); + ompt_mutex_lock, (ompt_wait_id_t)(uintptr_t)lck, codeptr); } #endif @@ -2810,7 +2816,7 @@ void __kmpc_unset_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { codeptr = OMPT_GET_RETURN_ADDRESS(0); if (ompt_enabled.ompt_callback_mutex_released) { ompt_callbacks.ompt_callback(ompt_callback_mutex_released)( - ompt_mutex_lock, (ompt_wait_id_t)lck, codeptr); + ompt_mutex_lock, (ompt_wait_id_t)(uintptr_t)lck, codeptr); } #endif @@ -2838,12 +2844,13 @@ void __kmpc_unset_nest_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_mutex_released) { // release_lock_last ompt_callbacks.ompt_callback(ompt_callback_mutex_released)( - ompt_mutex_nest_lock, (ompt_wait_id_t)user_lock, codeptr); + ompt_mutex_nest_lock, (ompt_wait_id_t)(uintptr_t)user_lock, + codeptr); } } else if (ompt_enabled.ompt_callback_nest_lock) { // release_lock_prev ompt_callbacks.ompt_callback(ompt_callback_nest_lock)( - ompt_scope_end, (ompt_wait_id_t)user_lock, codeptr); + ompt_scope_end, (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } } #endif @@ -2887,12 +2894,12 @@ void __kmpc_unset_nest_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_mutex_released) { // release_lock_last ompt_callbacks.ompt_callback(ompt_callback_mutex_released)( - ompt_mutex_nest_lock, (ompt_wait_id_t)lck, codeptr); + ompt_mutex_nest_lock, (ompt_wait_id_t)(uintptr_t)lck, codeptr); } } else if (ompt_enabled.ompt_callback_nest_lock) { // release_lock_previous ompt_callbacks.ompt_callback(ompt_callback_nest_lock)( - ompt_mutex_scope_end, (ompt_wait_id_t)lck, codeptr); + ompt_mutex_scope_end, (ompt_wait_id_t)(uintptr_t)lck, codeptr); } } #endif @@ -2929,12 +2936,12 @@ void __kmpc_unset_nest_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_mutex_released) { // release_lock_last ompt_callbacks.ompt_callback(ompt_callback_mutex_released)( - ompt_mutex_nest_lock, (ompt_wait_id_t)lck, codeptr); + ompt_mutex_nest_lock, (ompt_wait_id_t)(uintptr_t)lck, codeptr); } } else if (ompt_enabled.ompt_callback_nest_lock) { // release_lock_previous ompt_callbacks.ompt_callback(ompt_callback_nest_lock)( - ompt_mutex_scope_end, (ompt_wait_id_t)lck, codeptr); + ompt_mutex_scope_end, (ompt_wait_id_t)(uintptr_t)lck, codeptr); } } #endif @@ -2960,8 +2967,8 @@ int __kmpc_test_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_mutex_acquire) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquire)( ompt_mutex_lock, omp_lock_hint_none, - __ompt_get_mutex_impl_type(user_lock), (ompt_wait_id_t)user_lock, - codeptr); + __ompt_get_mutex_impl_type(user_lock), + (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } #endif #if KMP_USE_INLINED_TAS @@ -2983,7 +2990,7 @@ int __kmpc_test_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { #if OMPT_SUPPORT && OMPT_OPTIONAL if (ompt_enabled.ompt_callback_mutex_acquired) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquired)( - ompt_mutex_lock, (ompt_wait_id_t)user_lock, codeptr); + ompt_mutex_lock, (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } #endif return FTN_TRUE; @@ -3024,7 +3031,7 @@ int __kmpc_test_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_mutex_acquire) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquire)( ompt_mutex_lock, omp_lock_hint_none, __ompt_get_mutex_impl_type(), - (ompt_wait_id_t)lck, codeptr); + (ompt_wait_id_t)(uintptr_t)lck, codeptr); } #endif @@ -3039,7 +3046,7 @@ int __kmpc_test_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { #if OMPT_SUPPORT && OMPT_OPTIONAL if (rc && ompt_enabled.ompt_callback_mutex_acquired) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquired)( - ompt_mutex_lock, (ompt_wait_id_t)lck, codeptr); + ompt_mutex_lock, (ompt_wait_id_t)(uintptr_t)lck, codeptr); } #endif @@ -3065,8 +3072,8 @@ int __kmpc_test_nest_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_mutex_acquire) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquire)( ompt_mutex_nest_lock, omp_lock_hint_none, - __ompt_get_mutex_impl_type(user_lock), (ompt_wait_id_t)user_lock, - codeptr); + __ompt_get_mutex_impl_type(user_lock), + (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } #endif rc = KMP_D_LOCK_FUNC(user_lock, test)((kmp_dyna_lock_t *)user_lock, gtid); @@ -3083,13 +3090,14 @@ int __kmpc_test_nest_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_mutex_acquired) { // lock_first ompt_callbacks.ompt_callback(ompt_callback_mutex_acquired)( - ompt_mutex_nest_lock, (ompt_wait_id_t)user_lock, codeptr); + ompt_mutex_nest_lock, (ompt_wait_id_t)(uintptr_t)user_lock, + codeptr); } } else { if (ompt_enabled.ompt_callback_nest_lock) { // lock_next ompt_callbacks.ompt_callback(ompt_callback_nest_lock)( - ompt_scope_begin, (ompt_wait_id_t)user_lock, codeptr); + ompt_scope_begin, (ompt_wait_id_t)(uintptr_t)user_lock, codeptr); } } } @@ -3130,7 +3138,8 @@ int __kmpc_test_nest_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { ompt_enabled.ompt_callback_mutex_acquire) { ompt_callbacks.ompt_callback(ompt_callback_mutex_acquire)( ompt_mutex_nest_lock, omp_lock_hint_none, - __ompt_get_mutex_impl_type(), (ompt_wait_id_t)lck, codeptr); + __ompt_get_mutex_impl_type(), (ompt_wait_id_t)(uintptr_t)lck, + codeptr); } #endif @@ -3148,13 +3157,13 @@ int __kmpc_test_nest_lock(ident_t *loc, kmp_int32 gtid, void **user_lock) { if (ompt_enabled.ompt_callback_mutex_acquired) { // lock_first ompt_callbacks.ompt_callback(ompt_callback_mutex_acquired)( - ompt_mutex_nest_lock, (ompt_wait_id_t)lck, codeptr); + ompt_mutex_nest_lock, (ompt_wait_id_t)(uintptr_t)lck, codeptr); } } else { if (ompt_enabled.ompt_callback_nest_lock) { // lock_next ompt_callbacks.ompt_callback(ompt_callback_nest_lock)( - ompt_mutex_scope_begin, (ompt_wait_id_t)lck, codeptr); + ompt_mutex_scope_begin, (ompt_wait_id_t)(uintptr_t)lck, codeptr); } } } diff --git a/openmp/runtime/src/ompt-specific.cpp b/openmp/runtime/src/ompt-specific.cpp index a6d02ddb85e3c..b985f84614481 100644 --- a/openmp/runtime/src/ompt-specific.cpp +++ b/openmp/runtime/src/ompt-specific.cpp @@ -211,7 +211,7 @@ ompt_data_t *__ompt_get_thread_data_internal() { void __ompt_thread_assign_wait_id(void *variable) { kmp_info_t *ti = ompt_get_thread(); - ti->th.ompt_thread_info.wait_id = (ompt_wait_id_t)variable; + ti->th.ompt_thread_info.wait_id = (ompt_wait_id_t)(uintptr_t)variable; } int __ompt_get_state_internal(ompt_wait_id_t *omp_wait_id) { diff --git a/openmp/runtime/test/ompt/synchronization/lock.c b/openmp/runtime/test/ompt/synchronization/lock.c index eae15757d6f28..2a934ee855aba 100644 --- a/openmp/runtime/test/ompt/synchronization/lock.c +++ b/openmp/runtime/test/ompt/synchronization/lock.c @@ -10,7 +10,7 @@ int main() print_ids(0); omp_lock_t lock; - printf("%" PRIu64 ": &lock: %" PRIu64 "\n", ompt_get_thread_data()->value, (uint64_t) &lock); + printf("%" PRIu64 ": &lock: %" PRIu64 "\n", ompt_get_thread_data()->value, (ompt_wait_id_t)(uintptr_t) &lock); omp_init_lock(&lock); print_fuzzy_address(1); omp_set_lock(&lock); diff --git a/openmp/runtime/test/ompt/synchronization/nest_lock.c b/openmp/runtime/test/ompt/synchronization/nest_lock.c index c83ceaf5d0d13..159048e2e74de 100644 --- a/openmp/runtime/test/ompt/synchronization/nest_lock.c +++ b/openmp/runtime/test/ompt/synchronization/nest_lock.c @@ -10,7 +10,7 @@ int main() print_ids(0); omp_nest_lock_t nest_lock; - printf("%" PRIu64 ": &nest_lock: %lli\n", ompt_get_thread_data()->value, (long long) &nest_lock); + printf("%" PRIu64 ": &nest_lock: %lli\n", ompt_get_thread_data()->value, (ompt_wait_id_t)(uintptr_t) &nest_lock); omp_init_nest_lock(&nest_lock); print_fuzzy_address(1); omp_set_nest_lock(&nest_lock); From 4ebe62d309daeb0d2d69ec0470ad66a269685a9e Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Mon, 24 Jun 2019 17:42:13 +0000 Subject: [PATCH 265/274] Merging r359094: ------------------------------------------------------------------------ r359094 | maskray | 2019-04-24 07:03:30 -0700 (Wed, 24 Apr 2019) | 12 lines [PPC64] Consider localentry offset when computing branch distance Summary: We don't take localentry offset into account, and thus may fail to create a long branch when the gap is just a few bytes smaller than 2^25. relocation R_PPC64_REL24 out of range: 33554432 is not in [-33554432, 33554431] relocation R_PPC64_REL24 out of range: 33554436 is not in [-33554432, 33554431] Fix that by adding the offset to the symbol VA. Differential Revision: https://reviews.llvm.org/D61058 ------------------------------------------------------------------------ llvm-svn: 364209 --- lld/ELF/Arch/PPC64.cpp | 5 +++- .../ELF/ppc64-long-branch-localentry-offset.s | 30 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 lld/test/ELF/ppc64-long-branch-localentry-offset.s diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp index cbfa8073d33fe..f02e818daee53 100644 --- a/lld/ELF/Arch/PPC64.cpp +++ b/lld/ELF/Arch/PPC64.cpp @@ -757,7 +757,10 @@ bool PPC64::needsThunk(RelExpr Expr, RelType Type, const InputFile *File, // If the offset exceeds the range of the branch type then it will need // a range-extending thunk. - return !inBranchRange(Type, BranchAddr, S.getVA()); + // See the comment in getRelocTargetVA() about R_PPC64_CALL. + return !inBranchRange(Type, BranchAddr, + S.getVA() + + getPPC64GlobalEntryToLocalEntryOffset(S.StOther)); } uint32_t PPC64::getThunkSectionSpacing() const { diff --git a/lld/test/ELF/ppc64-long-branch-localentry-offset.s b/lld/test/ELF/ppc64-long-branch-localentry-offset.s new file mode 100644 index 0000000000000..fd37c13db6ba2 --- /dev/null +++ b/lld/test/ELF/ppc64-long-branch-localentry-offset.s @@ -0,0 +1,30 @@ +# REQUIRES: ppc + +# RUN: llvm-mc -filetype=obj -triple=ppc64le %s -o %t.o +# RUN: ld.lld %t.o -o %t +# RUN: llvm-nm %t | FileCheck %s + +# CHECK-DAG: 0000000010010000 t __long_branch_callee +# CHECK-DAG: 0000000010010010 T _start +# CHECK-DAG: 0000000012010008 T callee + +# The bl instruction jumps to the local entry. The distance requires a long branch stub: +# localentry(callee) - _start = 0x12010008+8 - 0x10010010 = 0x2000000 + +# We used to compute globalentry(callee) - _start and caused a "R_PPC64_REL24 +# out of range" error because we didn't create the stub. + +.globl _start +_start: + bl callee + +.space 0x1fffff4 + +.globl callee +callee: +.Lgep0: + addis 2, 12, .TOC.-.Lgep0@ha + addi 2, 2, .TOC.-.Lgep0@l +.Llep0: + .localentry callee, .Llep0-.Lgep0 + blr From 464c365c0f73daf7af495a383312ed066e4a386e Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Mon, 24 Jun 2019 18:40:58 +0000 Subject: [PATCH 266/274] Merging r360861: ------------------------------------------------------------------------ r360861 | mstorsjo | 2019-05-15 23:49:13 -0700 (Wed, 15 May 2019) | 13 lines [PPC64][libunwind] Fix r2 not properly restored This change makes each unwind step inspect the instruction at the return address and, if needed, read r2 from its saved location and modify the context appropriately. The unwind logic is able to handle both ELFv1 and ELFv2 stacks. Reported by Bug 41050 Patch by Leandro Lupori! Differential Revision: https://reviews.llvm.org/D59694 ------------------------------------------------------------------------ llvm-svn: 364217 --- libunwind/src/DwarfInstructions.hpp | 25 +++++++++++++++++++++++++ libunwind/src/assembly.h | 18 +++++++++++++++++- libunwind/test/lit.cfg | 3 +++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/libunwind/src/DwarfInstructions.hpp b/libunwind/src/DwarfInstructions.hpp index ec70c0a11f70f..4109549a911b1 100644 --- a/libunwind/src/DwarfInstructions.hpp +++ b/libunwind/src/DwarfInstructions.hpp @@ -234,6 +234,31 @@ int DwarfInstructions::stepWithDwarf(A &addressSpace, pint_t pc, } #endif +#if defined(_LIBUNWIND_TARGET_PPC64) +#define PPC64_ELFV1_R2_LOAD_INST_ENCODING 0xe8410028u // ld r2,40(r1) +#define PPC64_ELFV1_R2_OFFSET 40 +#define PPC64_ELFV2_R2_LOAD_INST_ENCODING 0xe8410018u // ld r2,24(r1) +#define PPC64_ELFV2_R2_OFFSET 24 + // If the instruction at return address is a TOC (r2) restore, + // then r2 was saved and needs to be restored. + // ELFv2 ABI specifies that the TOC Pointer must be saved at SP + 24, + // while in ELFv1 ABI it is saved at SP + 40. + if (R::getArch() == REGISTERS_PPC64 && returnAddress != 0) { + pint_t sp = newRegisters.getRegister(UNW_REG_SP); + pint_t r2 = 0; + switch (addressSpace.get32(returnAddress)) { + case PPC64_ELFV1_R2_LOAD_INST_ENCODING: + r2 = addressSpace.get64(sp + PPC64_ELFV1_R2_OFFSET); + break; + case PPC64_ELFV2_R2_LOAD_INST_ENCODING: + r2 = addressSpace.get64(sp + PPC64_ELFV2_R2_OFFSET); + break; + } + if (r2) + newRegisters.setRegister(UNW_PPC64_R2, r2); + } +#endif + // Return address is address after call site instruction, so setting IP to // that does simualates a return. newRegisters.setIP(returnAddress); diff --git a/libunwind/src/assembly.h b/libunwind/src/assembly.h index 7806892e9dcf9..02ac36d90fe16 100644 --- a/libunwind/src/assembly.h +++ b/libunwind/src/assembly.h @@ -35,6 +35,20 @@ #define SEPARATOR ; #endif +#if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF == 1) +#define PPC64_OPD1 .section .opd,"aw",@progbits SEPARATOR +#define PPC64_OPD2 SEPARATOR \ + .p2align 3 SEPARATOR \ + .quad .Lfunc_begin0 SEPARATOR \ + .quad .TOC.@tocbase SEPARATOR \ + .quad 0 SEPARATOR \ + .text SEPARATOR \ +.Lfunc_begin0: +#else +#define PPC64_OPD1 +#define PPC64_OPD2 +#endif + #define GLUE2(a, b) a ## b #define GLUE(a, b) GLUE2(a, b) #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name) @@ -95,7 +109,9 @@ .globl SYMBOL_NAME(name) SEPARATOR \ EXPORT_SYMBOL(name) SEPARATOR \ SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ - SYMBOL_NAME(name): + PPC64_OPD1 \ + SYMBOL_NAME(name): \ + PPC64_OPD2 #define DEFINE_LIBUNWIND_PRIVATE_FUNCTION(name) \ .globl SYMBOL_NAME(name) SEPARATOR \ diff --git a/libunwind/test/lit.cfg b/libunwind/test/lit.cfg index 272bc163bb37b..1d284bdfd771a 100644 --- a/libunwind/test/lit.cfg +++ b/libunwind/test/lit.cfg @@ -23,6 +23,9 @@ config.suffixes = ['.cpp', '.s'] # test_source_root: The root path where tests are located. config.test_source_root = os.path.dirname(__file__) +# needed to test libunwind with code that throws exceptions +config.enable_exceptions = True + # Infer the libcxx_test_source_root for configuration import. # If libcxx_source_root isn't specified in the config, assume that the libcxx # and libunwind source directories are sibling directories. From d37559239de81b23fdad253669e43185f9a71195 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Tue, 25 Jun 2019 00:14:16 +0000 Subject: [PATCH 267/274] Merging r361114: ------------------------------------------------------------------------ r361114 | mgorny | 2019-05-18 23:05:31 -0700 (Sat, 18 May 2019) | 3 lines [lldb] [lit] Driver/TestConvenienceVariables.test requires Python Differential Revision: https://reviews.llvm.org/D62096 ------------------------------------------------------------------------ llvm-svn: 364257 --- lldb/lit/Driver/TestConvenienceVariables.test | 3 ++- lldb/lit/lit.cfg.py | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lldb/lit/Driver/TestConvenienceVariables.test b/lldb/lit/Driver/TestConvenienceVariables.test index 99536e4c02907..a7b6faa34cb39 100644 --- a/lldb/lit/Driver/TestConvenienceVariables.test +++ b/lldb/lit/Driver/TestConvenienceVariables.test @@ -1,3 +1,4 @@ +REQUIRES: python RUN: %build %p/Inputs/hello.cpp -o %t RUN: %lldb %t -s %p/Inputs/convenience.in -o quit | FileCheck %s @@ -19,4 +20,4 @@ CHECK: 8 CHECK: script lldb.frame.GetLineEntry().GetFileSpec().GetFilename() CHECK: hello.c CHECK: script lldb.frame.GetFunctionName() -CHECK: main \ No newline at end of file +CHECK: main diff --git a/lldb/lit/lit.cfg.py b/lldb/lit/lit.cfg.py index e1db7621e3280..ff4e60e5b4bd5 100644 --- a/lldb/lit/lit.cfg.py +++ b/lldb/lit/lit.cfg.py @@ -73,3 +73,6 @@ def calculate_arch_features(arch_string): if os.path.isdir(cachedir): print("Deleting module cache at %s."%cachedir) shutil.rmtree(cachedir) + +if not config.lldb_disable_python: + config.available_features.add('python') From 21f32a9683fcd7114c18e24463a55377c9efb8ac Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Tue, 25 Jun 2019 00:37:55 +0000 Subject: [PATCH 268/274] Merging r355033: ------------------------------------------------------------------------ r355033 | joerg | 2019-02-27 13:46:01 -0800 (Wed, 27 Feb 2019) | 2 lines Use Secure PLT as default on NetBSD/PowerPC. ------------------------------------------------------------------------ llvm-svn: 364258 --- clang/lib/Driver/ToolChains/Arch/PPC.cpp | 2 +- clang/test/Driver/netbsd.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/clang/lib/Driver/ToolChains/Arch/PPC.cpp b/clang/lib/Driver/ToolChains/Arch/PPC.cpp index 791f1206cf257..e83c263d29010 100644 --- a/clang/lib/Driver/ToolChains/Arch/PPC.cpp +++ b/clang/lib/Driver/ToolChains/Arch/PPC.cpp @@ -116,7 +116,7 @@ ppc::ReadGOTPtrMode ppc::getPPCReadGOTPtrMode(const Driver &D, const llvm::Tripl const ArgList &Args) { if (Args.getLastArg(options::OPT_msecure_plt)) return ppc::ReadGOTPtrMode::SecurePlt; - if (Triple.isOSOpenBSD()) + if (Triple.isOSNetBSD() || Triple.isOSOpenBSD()) return ppc::ReadGOTPtrMode::SecurePlt; else return ppc::ReadGOTPtrMode::Bss; diff --git a/clang/test/Driver/netbsd.c b/clang/test/Driver/netbsd.c index f5352e2486f06..221264a525976 100644 --- a/clang/test/Driver/netbsd.c +++ b/clang/test/Driver/netbsd.c @@ -446,3 +446,8 @@ // PTHREAD-NOT: _POSIX_THREADS // PTHREAD: _REENTRANT // PTHREAD-NOT: _POSIX_THREADS + +// Check PowerPC for Secure PLT +// RUN: %clang -target powerpc-unknown-netbsd -### -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=POWERPC-SECUREPLT %s +// POWERPC-SECUREPLT: "-target-feature" "+secure-plt" From cf7a59f2d7dd5b2caa80c21b2e196a0a0a202409 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Wed, 26 Jun 2019 21:59:19 +0000 Subject: [PATCH 269/274] Merging r359809: ------------------------------------------------------------------------ r359809 | rnk | 2019-05-02 10:45:54 -0700 (Thu, 02 May 2019) | 27 lines Use primary template parameter names for variable template debug info Summary: Fixes PR41677 Consider: template constexpr bool is_same_v = false; template constexpr bool is_same_v = true; template constexpr bool is_same_v; Before this change, when emitting debug info for the `is_same_v` global variable, clang would crash because it would try to use the template parameter list from the partial specialization to give parameter names to template arguments. This doesn't work in general, since a partial specialization can have fewer arguments than the primary template. Therefore, always use the primary template. Hypothetically we could try to use the parameter names from the partial specialization when possible, but it's not clear this really helps debugging in practice. Reviewers: JDevlieghere, aprantl, ormris, dblaikie Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D61408 ------------------------------------------------------------------------ llvm-svn: 364483 --- clang/lib/CodeGen/CGDebugInfo.cpp | 36 ++++++++----------- .../CodeGenCXX/debug-info-template-member.cpp | 2 +- .../debug-info-var-template-partial.cpp | 17 +++++++++ 3 files changed, 32 insertions(+), 23 deletions(-) create mode 100644 clang/test/CodeGenCXX/debug-info-var-template-partial.cpp diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 41f8721468a32..ad1a9157a127a 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1817,32 +1817,24 @@ CGDebugInfo::CollectFunctionTemplateParams(const FunctionDecl *FD, } llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(const VarDecl *VL, - llvm::DIFile *Unit) { - if (auto *TS = dyn_cast(VL)) { - auto T = TS->getSpecializedTemplateOrPartial(); - auto TA = TS->getTemplateArgs().asArray(); - // Collect parameters for a partial specialization - if (T.is()) { - const TemplateParameterList *TList = - T.get() - ->getTemplateParameters(); - return CollectTemplateParams(TList, TA, Unit); - } - - // Collect parameters for an explicit specialization - if (T.is()) { - const TemplateParameterList *TList = T.get() - ->getTemplateParameters(); - return CollectTemplateParams(TList, TA, Unit); - } - } - return llvm::DINodeArray(); + llvm::DIFile *Unit) { + // Always get the full list of parameters, not just the ones from the + // specialization. A partial specialization may have fewer parameters than + // there are arguments. + auto *TS = dyn_cast(VL); + if (!TS) + return llvm::DINodeArray(); + VarTemplateDecl *T = TS->getSpecializedTemplate(); + const TemplateParameterList *TList = T->getTemplateParameters(); + auto TA = TS->getTemplateArgs().asArray(); + return CollectTemplateParams(TList, TA, Unit); } llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams( const ClassTemplateSpecializationDecl *TSpecial, llvm::DIFile *Unit) { - // Always get the full list of parameters, not just the ones from - // the specialization. + // Always get the full list of parameters, not just the ones from the + // specialization. A partial specialization may have fewer parameters than + // there are arguments. TemplateParameterList *TPList = TSpecial->getSpecializedTemplate()->getTemplateParameters(); const TemplateArgumentList &TAList = TSpecial->getTemplateArgs(); diff --git a/clang/test/CodeGenCXX/debug-info-template-member.cpp b/clang/test/CodeGenCXX/debug-info-template-member.cpp index db6006cab8205..3d5b04d164142 100644 --- a/clang/test/CodeGenCXX/debug-info-template-member.cpp +++ b/clang/test/CodeGenCXX/debug-info-template-member.cpp @@ -30,7 +30,7 @@ inline int add3(int x) { // CHECK: {{![0-9]+}} = distinct !DIGlobalVariable( // CHECK-SAME: name: "var" // CHECK-SAME: templateParams: {{![0-9]+}} -// CHECK: !DITemplateTypeParameter(name: "P", type: {{![0-9]+}}) +// CHECK: !DITemplateTypeParameter(name: "T", type: {{![0-9]+}}) // CHECK: {{![0-9]+}} = distinct !DIGlobalVariable( // CHECK-SAME: name: "varray" // CHECK-SAME: templateParams: {{![0-9]+}} diff --git a/clang/test/CodeGenCXX/debug-info-var-template-partial.cpp b/clang/test/CodeGenCXX/debug-info-var-template-partial.cpp new file mode 100644 index 0000000000000..16c5f82c72e18 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-var-template-partial.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64-linux-gnu %s -o - -debug-info-kind=limited | FileCheck %s + +template constexpr bool is_same_v = false; +template constexpr bool is_same_v = true; + +template constexpr bool is_same_v; +static_assert(is_same_v, "should get partial spec"); + +// Note that the template arguments for the instantiated variable use the +// parameter names from the primary template. The partial specialization might +// not have enough parameters. + +// CHECK: distinct !DIGlobalVariable(name: "is_same_v", linkageName: "_ZL9is_same_vIiiE", {{.*}} templateParams: ![[PARAMS:[0-9]+]]) +// CHECK: ![[PARAMS]] = !{![[LHS:[0-9]+]], ![[RHS:[0-9]+]]} +// CHECK: ![[LHS]] = !DITemplateTypeParameter(name: "LHS", type: ![[INT:[0-9]+]]) +// CHECK: ![[INT]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +// CHECK: ![[RHS]] = !DITemplateTypeParameter(name: "RHS", type: ![[INT]]) From 180a937d9a66237e061190e9865383236db5d0c0 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Wed, 26 Jun 2019 23:02:24 +0000 Subject: [PATCH 270/274] Merging r354633: ------------------------------------------------------------------------ r354633 | rsmith | 2019-02-21 15:04:35 -0800 (Thu, 21 Feb 2019) | 3 lines Use _Q as MS ABI mangling for char8_t. Thanks to Yuriy Solodkyy for letting us know the mangling here. ------------------------------------------------------------------------ llvm-svn: 364487 --- clang/lib/AST/MicrosoftMangle.cpp | 7 +++++-- clang/test/CodeGenCXX/char8_t.cpp | 12 +++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 92e9679e49aa3..896c4a1cf2b39 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -1937,8 +1937,9 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers, // ::= _M # unsigned __int128 // ::= _N # bool // _O # - // ::= _T # __float80 (Intel) + // ::= _Q # char8_t // ::= _S # char16_t + // ::= _T # __float80 (Intel) // ::= _U # char32_t // ::= _W # wchar_t // ::= _Z # __float80 (Digital Mars) @@ -1999,6 +2000,9 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers, case BuiltinType::Bool: Out << "_N"; break; + case BuiltinType::Char8: + Out << "_Q"; + break; case BuiltinType::Char16: Out << "_S"; break; @@ -2094,7 +2098,6 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers, case BuiltinType::SatUShortFract: case BuiltinType::SatUFract: case BuiltinType::SatULongFract: - case BuiltinType::Char8: case BuiltinType::Float128: { DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID( diff --git a/clang/test/CodeGenCXX/char8_t.cpp b/clang/test/CodeGenCXX/char8_t.cpp index f24f12d6df404..1016d6346ba27 100644 --- a/clang/test/CodeGenCXX/char8_t.cpp +++ b/clang/test/CodeGenCXX/char8_t.cpp @@ -1,9 +1,11 @@ -// RUN: %clang_cc1 -std=c++17 -emit-llvm -fchar8_t -triple x86_64-linux %s -o - | FileCheck %s -// RUN: %clang_cc1 -std=c++17 -emit-llvm -fchar8_t -triple x86_64-windows %s -o - -verify +// RUN: %clang_cc1 -std=c++17 -emit-llvm -fchar8_t -triple x86_64-linux %s -o - | FileCheck %s --check-prefix=ITANIUM +// RUN: %clang_cc1 -std=c++17 -emit-llvm -fchar8_t -triple x86_64-windows %s -o - | FileCheck %s --check-prefix=MSABI -// CHECK: define void @_Z1fDu( -void f(char8_t c) {} // expected-error {{cannot mangle this built-in char8_t type yet}} +// ITANIUM: define void @_Z1fDu( +// MSABI: define {{.*}}void @"?f@@YAX_Q@Z"( +void f(char8_t c) {} -// CHECK: define weak_odr void @_Z1gIiEvDTplplcvT__ELA4_KDuELDu114EE +// ITANIUM: define weak_odr void @_Z1gIiEvDTplplcvT__ELA4_KDuELDu114EE( +// MSABI: define weak_odr {{.*}}void @"??$g@H@@YAXPEB_Q@Z"( template void g(decltype(T() + u8"foo" + u8'r')) {} template void g(const char8_t*); From 635f8ffdbd7b93d34a866f2acee916f76b35fb6a Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Tue, 9 Jul 2019 19:14:43 +0000 Subject: [PATCH 271/274] Revert merge of r360861: ------------------------------------------------------------------------ r360861 | mstorsjo | 2019-05-15 23:49:13 -0700 (Wed, 15 May 2019) | 13 lines [PPC64][libunwind] Fix r2 not properly restored This change makes each unwind step inspect the instruction at the return address and, if needed, read r2 from its saved location and modify the context appropriately. The unwind logic is able to handle both ELFv1 and ELFv2 stacks. Reported by Bug 41050 Patch by Leandro Lupori! Differential Revision: https://reviews.llvm.org/D59694 ------------------------------------------------------------------------ llvm-svn: 365539 --- libunwind/src/DwarfInstructions.hpp | 25 ------------------------- libunwind/src/assembly.h | 18 +----------------- libunwind/test/lit.cfg | 3 --- 3 files changed, 1 insertion(+), 45 deletions(-) diff --git a/libunwind/src/DwarfInstructions.hpp b/libunwind/src/DwarfInstructions.hpp index 4109549a911b1..ec70c0a11f70f 100644 --- a/libunwind/src/DwarfInstructions.hpp +++ b/libunwind/src/DwarfInstructions.hpp @@ -234,31 +234,6 @@ int DwarfInstructions::stepWithDwarf(A &addressSpace, pint_t pc, } #endif -#if defined(_LIBUNWIND_TARGET_PPC64) -#define PPC64_ELFV1_R2_LOAD_INST_ENCODING 0xe8410028u // ld r2,40(r1) -#define PPC64_ELFV1_R2_OFFSET 40 -#define PPC64_ELFV2_R2_LOAD_INST_ENCODING 0xe8410018u // ld r2,24(r1) -#define PPC64_ELFV2_R2_OFFSET 24 - // If the instruction at return address is a TOC (r2) restore, - // then r2 was saved and needs to be restored. - // ELFv2 ABI specifies that the TOC Pointer must be saved at SP + 24, - // while in ELFv1 ABI it is saved at SP + 40. - if (R::getArch() == REGISTERS_PPC64 && returnAddress != 0) { - pint_t sp = newRegisters.getRegister(UNW_REG_SP); - pint_t r2 = 0; - switch (addressSpace.get32(returnAddress)) { - case PPC64_ELFV1_R2_LOAD_INST_ENCODING: - r2 = addressSpace.get64(sp + PPC64_ELFV1_R2_OFFSET); - break; - case PPC64_ELFV2_R2_LOAD_INST_ENCODING: - r2 = addressSpace.get64(sp + PPC64_ELFV2_R2_OFFSET); - break; - } - if (r2) - newRegisters.setRegister(UNW_PPC64_R2, r2); - } -#endif - // Return address is address after call site instruction, so setting IP to // that does simualates a return. newRegisters.setIP(returnAddress); diff --git a/libunwind/src/assembly.h b/libunwind/src/assembly.h index 02ac36d90fe16..7806892e9dcf9 100644 --- a/libunwind/src/assembly.h +++ b/libunwind/src/assembly.h @@ -35,20 +35,6 @@ #define SEPARATOR ; #endif -#if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF == 1) -#define PPC64_OPD1 .section .opd,"aw",@progbits SEPARATOR -#define PPC64_OPD2 SEPARATOR \ - .p2align 3 SEPARATOR \ - .quad .Lfunc_begin0 SEPARATOR \ - .quad .TOC.@tocbase SEPARATOR \ - .quad 0 SEPARATOR \ - .text SEPARATOR \ -.Lfunc_begin0: -#else -#define PPC64_OPD1 -#define PPC64_OPD2 -#endif - #define GLUE2(a, b) a ## b #define GLUE(a, b) GLUE2(a, b) #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name) @@ -109,9 +95,7 @@ .globl SYMBOL_NAME(name) SEPARATOR \ EXPORT_SYMBOL(name) SEPARATOR \ SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ - PPC64_OPD1 \ - SYMBOL_NAME(name): \ - PPC64_OPD2 + SYMBOL_NAME(name): #define DEFINE_LIBUNWIND_PRIVATE_FUNCTION(name) \ .globl SYMBOL_NAME(name) SEPARATOR \ diff --git a/libunwind/test/lit.cfg b/libunwind/test/lit.cfg index 1d284bdfd771a..272bc163bb37b 100644 --- a/libunwind/test/lit.cfg +++ b/libunwind/test/lit.cfg @@ -23,9 +23,6 @@ config.suffixes = ['.cpp', '.s'] # test_source_root: The root path where tests are located. config.test_source_root = os.path.dirname(__file__) -# needed to test libunwind with code that throws exceptions -config.enable_exceptions = True - # Infer the libcxx_test_source_root for configuration import. # If libcxx_source_root isn't specified in the config, assume that the libcxx # and libunwind source directories are sibling directories. From 19a71f6bdf2dddb10764939e7f0ec2b98dba76c9 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Tue, 9 Jul 2019 19:22:59 +0000 Subject: [PATCH 272/274] Merging r360861, with an additional change to also add the PPC64_OPD1 and PPC64_OPD2 lines to the DEFINE_LIBUNWIND_PRIVATE_FUNCTION() macro, which was removed in r357640: ------------------------------------------------------------------------ r360861 | mstorsjo | 2019-05-15 23:49:13 -0700 (Wed, 15 May 2019) | 13 lines [PPC64][libunwind] Fix r2 not properly restored This change makes each unwind step inspect the instruction at the return address and, if needed, read r2 from its saved location and modify the context appropriately. The unwind logic is able to handle both ELFv1 and ELFv2 stacks. Reported by Bug 41050 Patch by Leandro Lupori! Differential Revision: https://reviews.llvm.org/D59694 ------------------------------------------------------------------------ llvm-svn: 365542 --- libunwind/src/DwarfInstructions.hpp | 25 +++++++++++++++++++++++++ libunwind/src/assembly.h | 22 ++++++++++++++++++++-- libunwind/test/lit.cfg | 3 +++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/libunwind/src/DwarfInstructions.hpp b/libunwind/src/DwarfInstructions.hpp index ec70c0a11f70f..4109549a911b1 100644 --- a/libunwind/src/DwarfInstructions.hpp +++ b/libunwind/src/DwarfInstructions.hpp @@ -234,6 +234,31 @@ int DwarfInstructions::stepWithDwarf(A &addressSpace, pint_t pc, } #endif +#if defined(_LIBUNWIND_TARGET_PPC64) +#define PPC64_ELFV1_R2_LOAD_INST_ENCODING 0xe8410028u // ld r2,40(r1) +#define PPC64_ELFV1_R2_OFFSET 40 +#define PPC64_ELFV2_R2_LOAD_INST_ENCODING 0xe8410018u // ld r2,24(r1) +#define PPC64_ELFV2_R2_OFFSET 24 + // If the instruction at return address is a TOC (r2) restore, + // then r2 was saved and needs to be restored. + // ELFv2 ABI specifies that the TOC Pointer must be saved at SP + 24, + // while in ELFv1 ABI it is saved at SP + 40. + if (R::getArch() == REGISTERS_PPC64 && returnAddress != 0) { + pint_t sp = newRegisters.getRegister(UNW_REG_SP); + pint_t r2 = 0; + switch (addressSpace.get32(returnAddress)) { + case PPC64_ELFV1_R2_LOAD_INST_ENCODING: + r2 = addressSpace.get64(sp + PPC64_ELFV1_R2_OFFSET); + break; + case PPC64_ELFV2_R2_LOAD_INST_ENCODING: + r2 = addressSpace.get64(sp + PPC64_ELFV2_R2_OFFSET); + break; + } + if (r2) + newRegisters.setRegister(UNW_PPC64_R2, r2); + } +#endif + // Return address is address after call site instruction, so setting IP to // that does simualates a return. newRegisters.setIP(returnAddress); diff --git a/libunwind/src/assembly.h b/libunwind/src/assembly.h index 7806892e9dcf9..0b7d24389a40b 100644 --- a/libunwind/src/assembly.h +++ b/libunwind/src/assembly.h @@ -35,6 +35,20 @@ #define SEPARATOR ; #endif +#if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF == 1) +#define PPC64_OPD1 .section .opd,"aw",@progbits SEPARATOR +#define PPC64_OPD2 SEPARATOR \ + .p2align 3 SEPARATOR \ + .quad .Lfunc_begin0 SEPARATOR \ + .quad .TOC.@tocbase SEPARATOR \ + .quad 0 SEPARATOR \ + .text SEPARATOR \ +.Lfunc_begin0: +#else +#define PPC64_OPD1 +#define PPC64_OPD2 +#endif + #define GLUE2(a, b) a ## b #define GLUE(a, b) GLUE2(a, b) #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name) @@ -95,13 +109,17 @@ .globl SYMBOL_NAME(name) SEPARATOR \ EXPORT_SYMBOL(name) SEPARATOR \ SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ - SYMBOL_NAME(name): + PPC64_OPD1 \ + SYMBOL_NAME(name): \ + PPC64_OPD2 #define DEFINE_LIBUNWIND_PRIVATE_FUNCTION(name) \ .globl SYMBOL_NAME(name) SEPARATOR \ HIDDEN_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \ SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ - SYMBOL_NAME(name): + PPC64_OPD1 \ + SYMBOL_NAME(name): \ + PPC64_OPD2 #if defined(__arm__) #if !defined(__ARM_ARCH) diff --git a/libunwind/test/lit.cfg b/libunwind/test/lit.cfg index 272bc163bb37b..1d284bdfd771a 100644 --- a/libunwind/test/lit.cfg +++ b/libunwind/test/lit.cfg @@ -23,6 +23,9 @@ config.suffixes = ['.cpp', '.s'] # test_source_root: The root path where tests are located. config.test_source_root = os.path.dirname(__file__) +# needed to test libunwind with code that throws exceptions +config.enable_exceptions = True + # Infer the libcxx_test_source_root for configuration import. # If libcxx_source_root isn't specified in the config, assume that the libcxx # and libunwind source directories are sibling directories. From 465f4e2c94aaf044beb4ecb3529ed8c2ed04fe73 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sun, 18 Aug 2019 15:40:39 +0000 Subject: [PATCH 273/274] [bindings/go] Add ParseIR This commit adds a single method to the Context object to parse a textual IR file. This is useful for reading input IR in unit tests. Differential Revision: https://reviews.llvm.org/D66379 llvm-svn: 369210 --- llvm/bindings/go/llvm/irreader.go | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 llvm/bindings/go/llvm/irreader.go diff --git a/llvm/bindings/go/llvm/irreader.go b/llvm/bindings/go/llvm/irreader.go new file mode 100644 index 0000000000000..71064497a583b --- /dev/null +++ b/llvm/bindings/go/llvm/irreader.go @@ -0,0 +1,37 @@ +//===- irreader.go - Bindings for irreader --------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines bindings for the irreader component. +// +//===----------------------------------------------------------------------===// + +package llvm + +/* +#include "llvm-c/IRReader.h" +#include +*/ +import "C" + +import ( + "errors" + "unsafe" +) + +// ParseIR parses the textual IR given in the memory buffer and returns a new +// LLVM module in this context. +func (c *Context) ParseIR(buf MemoryBuffer) (Module, error) { + var m Module + var errmsg *C.char + if C.LLVMParseIRInContext(c.C, buf.C, &m.C, &errmsg) != 0 { + err := errors.New(C.GoString(errmsg)) + C.free(unsafe.Pointer(errmsg)) + return Module{}, err + } + return m, nil +} From 89de0d8dfbb9a6ff1f8b141ed70b563ecc094878 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 20 Aug 2019 09:10:27 +0000 Subject: [PATCH 274/274] Revert r369210 which got committed to the branch by mistake llvm-svn: 369350 --- llvm/bindings/go/llvm/irreader.go | 37 ------------------------------- 1 file changed, 37 deletions(-) delete mode 100644 llvm/bindings/go/llvm/irreader.go diff --git a/llvm/bindings/go/llvm/irreader.go b/llvm/bindings/go/llvm/irreader.go deleted file mode 100644 index 71064497a583b..0000000000000 --- a/llvm/bindings/go/llvm/irreader.go +++ /dev/null @@ -1,37 +0,0 @@ -//===- irreader.go - Bindings for irreader --------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// -// -// This file defines bindings for the irreader component. -// -//===----------------------------------------------------------------------===// - -package llvm - -/* -#include "llvm-c/IRReader.h" -#include -*/ -import "C" - -import ( - "errors" - "unsafe" -) - -// ParseIR parses the textual IR given in the memory buffer and returns a new -// LLVM module in this context. -func (c *Context) ParseIR(buf MemoryBuffer) (Module, error) { - var m Module - var errmsg *C.char - if C.LLVMParseIRInContext(c.C, buf.C, &m.C, &errmsg) != 0 { - err := errors.New(C.GoString(errmsg)) - C.free(unsafe.Pointer(errmsg)) - return Module{}, err - } - return m, nil -}