111 changes: 111 additions & 0 deletions compiler-rt/test/orc/TestCases/Darwin/arm64/objc-imageinfo.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Test merging of __objc_imageinfo flags and ensure we can run mixed objc and
// swift code in a single jit dylib.

// REQUIRES: system-darwin && asserts

// RUN: rm -rf %t
// RUN: split-file %s %t
// RUN: (cd %t; %clang -c *.S)

// Check individual versions are loadable.

// RUN: %llvm_jitlink -debug-only=orc %t/main.o %t/objc_old.o 2>&1 | FileCheck %s -check-prefix=OLD
// OLD: MachOPlatform: Registered __objc_imageinfo for main
// OLD-SAME: flags = 0x0000
// RUN: %llvm_jitlink -debug-only=orc %t/main.o %t/objc_new.o 2>&1 | FileCheck %s -check-prefix=NEW
// NEW: MachOPlatform: Registered __objc_imageinfo for main
// NEW-SAME: flags = 0x0040
// RUN: %llvm_jitlink -debug-only=orc %t/main.o %t/swift_4.o 2>&1 | FileCheck %s -check-prefix=SWIFT_4
// SWIFT_4: MachOPlatform: Registered __objc_imageinfo for main
// SWIFT_4-SAME: flags = 0x0640
// RUN: %llvm_jitlink -debug-only=orc %t/main.o %t/swift_5.o 2>&1 | FileCheck %s -check-prefix=SWIFT_5
// SWIFT_5: MachOPlatform: Registered __objc_imageinfo for main
// SWIFT_5-SAME: flags = 0x5000740
// RUN: %llvm_jitlink -debug-only=orc %t/main.o %t/swift_59.o 2>&1 | FileCheck %s -check-prefix=SWIFT_59
// SWIFT_59: MachOPlatform: Registered __objc_imageinfo for main
// SWIFT_59-SAME: flags = 0x5090740

// Check error conditions.

// RUN: not %llvm_jitlink %t/main.o %t/objc_old.o %t/objc_new.o 2>&1 | FileCheck %s -check-prefix=CATEGORY
// CATEGORY: ObjC category class property support in {{.*}} does not match first registered flags

// RUN: not %llvm_jitlink %t/main.o %t/swift_4.o %t/swift_5.o 2>&1 | FileCheck %s -check-prefix=SWIFT_ABI
// SWIFT_ABI: Swift ABI version in {{.*}} does not match first registered flags

// Check merging.

// Take the lowest swift version.
// RUN: %llvm_jitlink -debug-only=orc %t/main.o %t/swift_59.o %t/swift_5.o 2>&1 | FileCheck %s -check-prefix=SWIFT_MIX1
// SWIFT_MIX1: MachOPlatform: Merging __objc_imageinfo flags for main {{.*}} -> 0x5000740

// Add swift to objc.
// RUN: %llvm_jitlink -debug-only=orc %t/main.o %t/swift_59.o %t/objc_new.o 2>&1 | FileCheck %s -check-prefix=SWIFT_MIX2
// SWIFT_MIX2: MachOPlatform: Merging __objc_imageinfo flags for main {{.*}} -> 0x5090740

// Add multiple swift to objc.
// RUN: %llvm_jitlink -debug-only=orc %t/main.o %t/swift_59.o %t/swift_5.o %t/objc_new.o 2>&1 | FileCheck %s -check-prefix=SWIFT_MIX3
// SWIFT_MIX3: MachOPlatform: Merging __objc_imageinfo flags for main {{.*}} -> 0x5000740

//--- main.S
.section __TEXT,__text,regular,pure_instructions
.globl _main
_main:
mov w0, #0
ret

//--- objc_old.S
.section __TEXT,__text,regular,pure_instructions
.globl _objc1
_objc1:
ret

.section __DATA,__objc_imageinfo,regular,no_dead_strip
L_OBJC_IMAGE_INFO:
.long 0
.long 0

//--- objc_new.S
.section __TEXT,__text,regular,pure_instructions
.globl _objc2
_objc2:
ret

.section __DATA,__objc_imageinfo,regular,no_dead_strip
L_OBJC_IMAGE_INFO:
.long 0
.long 64

//--- swift_4.S
.section __TEXT,__text,regular,pure_instructions
.globl _swift4
_swift4:
ret

.section __DATA,__objc_imageinfo,regular,no_dead_strip
L_OBJC_IMAGE_INFO:
.long 0
.long 1600

//--- swift_5.S
.section __TEXT,__text,regular,pure_instructions
.globl _swift5
_swift5:
ret

.section __DATA,__objc_imageinfo,regular,no_dead_strip
L_OBJC_IMAGE_INFO:
.long 0
.long 83887936

//--- swift_59.S
.section __TEXT,__text,regular,pure_instructions
.globl _swift59
_swift59:
ret

.section __DATA,__objc_imageinfo,regular,no_dead_strip
L_OBJC_IMAGE_INFO:
.long 0
.long 84477760

111 changes: 111 additions & 0 deletions compiler-rt/test/orc/TestCases/Darwin/x86-64/objc-imageinfo.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Test merging of __objc_imageinfo flags and ensure we can run mixed objc and
// swift code in a single jit dylib.

// REQUIRES: system-darwin && asserts

// RUN: rm -rf %t
// RUN: split-file %s %t
// RUN: (cd %t; %clang -c *.S)

// Check individual versions are loadable.

// RUN: %llvm_jitlink -debug-only=orc %t/main.o %t/objc_old.o 2>&1 | FileCheck %s -check-prefix=OLD
// OLD: MachOPlatform: Registered __objc_imageinfo for main
// OLD-SAME: flags = 0x0000
// RUN: %llvm_jitlink -debug-only=orc %t/main.o %t/objc_new.o 2>&1 | FileCheck %s -check-prefix=NEW
// NEW: MachOPlatform: Registered __objc_imageinfo for main
// NEW-SAME: flags = 0x0040
// RUN: %llvm_jitlink -debug-only=orc %t/main.o %t/swift_4.o 2>&1 | FileCheck %s -check-prefix=SWIFT_4
// SWIFT_4: MachOPlatform: Registered __objc_imageinfo for main
// SWIFT_4-SAME: flags = 0x0640
// RUN: %llvm_jitlink -debug-only=orc %t/main.o %t/swift_5.o 2>&1 | FileCheck %s -check-prefix=SWIFT_5
// SWIFT_5: MachOPlatform: Registered __objc_imageinfo for main
// SWIFT_5-SAME: flags = 0x5000740
// RUN: %llvm_jitlink -debug-only=orc %t/main.o %t/swift_59.o 2>&1 | FileCheck %s -check-prefix=SWIFT_59
// SWIFT_59: MachOPlatform: Registered __objc_imageinfo for main
// SWIFT_59-SAME: flags = 0x5090740

// Check error conditions.

// RUN: not %llvm_jitlink %t/main.o %t/objc_old.o %t/objc_new.o 2>&1 | FileCheck %s -check-prefix=CATEGORY
// CATEGORY: ObjC category class property support in {{.*}} does not match first registered flags

// RUN: not %llvm_jitlink %t/main.o %t/swift_4.o %t/swift_5.o 2>&1 | FileCheck %s -check-prefix=SWIFT_ABI
// SWIFT_ABI: Swift ABI version in {{.*}} does not match first registered flags

// Check merging.

// Take the lowest swift version.
// RUN: %llvm_jitlink -debug-only=orc %t/main.o %t/swift_59.o %t/swift_5.o 2>&1 | FileCheck %s -check-prefix=SWIFT_MIX1
// SWIFT_MIX1: MachOPlatform: Merging __objc_imageinfo flags for main {{.*}} -> 0x5000740

// Add swift to objc.
// RUN: %llvm_jitlink -debug-only=orc %t/main.o %t/swift_59.o %t/objc_new.o 2>&1 | FileCheck %s -check-prefix=SWIFT_MIX2
// SWIFT_MIX2: MachOPlatform: Merging __objc_imageinfo flags for main {{.*}} -> 0x5090740

// Add multiple swift to objc.
// RUN: %llvm_jitlink -debug-only=orc %t/main.o %t/swift_59.o %t/swift_5.o %t/objc_new.o 2>&1 | FileCheck %s -check-prefix=SWIFT_MIX3
// SWIFT_MIX3: MachOPlatform: Merging __objc_imageinfo flags for main {{.*}} -> 0x5000740

//--- main.S
.section __TEXT,__text,regular,pure_instructions
.globl _main
_main:
xorl %eax, %eax
ret

//--- objc_old.S
.section __TEXT,__text,regular,pure_instructions
.globl _objc1
_objc1:
ret

.section __DATA,__objc_imageinfo,regular,no_dead_strip
L_OBJC_IMAGE_INFO:
.long 0
.long 0

//--- objc_new.S
.section __TEXT,__text,regular,pure_instructions
.globl _objc2
_objc2:
ret

.section __DATA,__objc_imageinfo,regular,no_dead_strip
L_OBJC_IMAGE_INFO:
.long 0
.long 64

//--- swift_4.S
.section __TEXT,__text,regular,pure_instructions
.globl _swift4
_swift4:
ret

.section __DATA,__objc_imageinfo,regular,no_dead_strip
L_OBJC_IMAGE_INFO:
.long 0
.long 1600

//--- swift_5.S
.section __TEXT,__text,regular,pure_instructions
.globl _swift5
_swift5:
ret

.section __DATA,__objc_imageinfo,regular,no_dead_strip
L_OBJC_IMAGE_INFO:
.long 0
.long 83887936

//--- swift_59.S
.section __TEXT,__text,regular,pure_instructions
.globl _swift59
_swift59:
ret

.section __DATA,__objc_imageinfo,regular,no_dead_strip
L_OBJC_IMAGE_INFO:
.long 0
.long 84477760

18 changes: 18 additions & 0 deletions flang/lib/Optimizer/Transforms/StackArrays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ namespace fir {

#define DEBUG_TYPE "stack-arrays"

static llvm::cl::opt<std::size_t> maxAllocsPerFunc(
"stack-arrays-max-allocs",
llvm::cl::desc("The maximum number of heap allocations to consider in one "
"function before skipping (to save compilation time). Set "
"to 0 for no limit."),
llvm::cl::init(1000), llvm::cl::Hidden);

namespace {

/// The state of an SSA value at each program point
Expand Down Expand Up @@ -411,6 +418,17 @@ void AllocationAnalysis::processOperation(mlir::Operation *op) {
mlir::LogicalResult
StackArraysAnalysisWrapper::analyseFunction(mlir::Operation *func) {
assert(mlir::isa<mlir::func::FuncOp>(func));
size_t nAllocs = 0;
func->walk([&nAllocs](fir::AllocMemOp) { nAllocs++; });
// don't bother with the analysis if there are no heap allocations
if (nAllocs == 0)
return mlir::success();
if ((maxAllocsPerFunc != 0) && (nAllocs > maxAllocsPerFunc)) {
LLVM_DEBUG(llvm::dbgs() << "Skipping stack arrays for function with "
<< nAllocs << " heap allocations");
return mlir::success();
}

mlir::DataFlowSolver solver;
// constant propagation is required for dead code analysis, dead code analysis
// is required to mark blocks live (required for mlir dense dfa)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
set(LIBCXX_HARDENING_MODE "hardened" CACHE STRING "")
set(LIBCXX_ABI_DEFINES "_LIBCPP_ABI_BOUNDED_ITERATORS" CACHE STRING "")
4 changes: 4 additions & 0 deletions libcxx/cmake/config-ix.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ elseif(FUCHSIA)
set(LIBCXX_HAS_PTHREAD_LIB NO)
set(LIBCXX_HAS_RT_LIB NO)
check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB)
elseif(ANDROID)
set(LIBCXX_HAS_PTHREAD_LIB NO)
set(LIBCXX_HAS_RT_LIB NO)
set(LIBCXX_HAS_ATOMIC_LIB NO)
else()
check_library_exists(pthread pthread_create "" LIBCXX_HAS_PTHREAD_LIB)
check_library_exists(rt clock_gettime "" LIBCXX_HAS_RT_LIB)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

// Make sure that std::span's iterators check for OOB accesses when the debug mode is enabled.

// REQUIRES: has-unix-headers
// UNSUPPORTED: !libcpp-has-legacy-debug-mode
// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators
// UNSUPPORTED: libcpp-hardening-mode=unchecked

#include <span>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

// Make sure that std::string_view's iterators check for OOB accesses when the debug mode is enabled.

// REQUIRES: has-unix-headers
// UNSUPPORTED: !libcpp-has-legacy-debug-mode
// REQUIRES: has-unix-headers, libcpp-has-abi-bounded-iterators
// UNSUPPORTED: libcpp-hardening-mode=unchecked

#include <string_view>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
//
//===----------------------------------------------------------------------===//

// XFAIL: suse-linux-enterprise-server-11
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10|11|12}}

// <system_error>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

// const error_category& system_category();

// XFAIL: suse-linux-enterprise-server-11
// XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10|11|12}}

#include <system_error>
Expand Down
18 changes: 18 additions & 0 deletions libcxx/utils/ci/buildkite-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,24 @@ steps:
limit: 2
timeout_in_minutes: 120

- label: "Hardened mode with ABI breaks"
command: "libcxx/utils/ci/run-buildbot generic-hardened-mode-with-abi-breaks"
artifact_paths:
- "**/test-results.xml"
- "**/*.abilist"
env:
CC: "clang-${LLVM_HEAD_VERSION}"
CXX: "clang++-${LLVM_HEAD_VERSION}"
ENABLE_CLANG_TIDY: "On"
agents:
queue: "libcxx-builders"
os: "linux"
retry:
automatic:
- exit_status: -1 # Agent was lost
limit: 2
timeout_in_minutes: 120

- label: "Safe mode"
command: "libcxx/utils/ci/run-buildbot generic-safe-mode"
artifact_paths:
Expand Down
6 changes: 6 additions & 0 deletions libcxx/utils/ci/run-buildbot
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,12 @@ generic-hardened-mode)
check-runtimes
check-abi-list
;;
generic-hardened-mode-with-abi-breaks)
clean
generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-hardened-mode-with-abi-breaks.cmake"
check-runtimes
check-abi-list
;;
generic-safe-mode)
clean
generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-safe-mode.cmake"
Expand Down
1 change: 1 addition & 0 deletions libcxx/utils/libcxx/test/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ def _getAndroidDeviceApi(cfg):
"_LIBCPP_HAS_THREAD_API_PTHREAD": "libcpp-has-thread-api-pthread",
"_LIBCPP_NO_VCRUNTIME": "libcpp-no-vcruntime",
"_LIBCPP_ABI_VERSION": "libcpp-abi-version",
"_LIBCPP_ABI_BOUNDED_ITERATORS": "libcpp-has-abi-bounded-iterators",
"_LIBCPP_HAS_NO_FILESYSTEM": "no-filesystem",
"_LIBCPP_HAS_NO_RANDOM_DEVICE": "no-random-device",
"_LIBCPP_HAS_NO_LOCALIZATION": "no-localization",
Expand Down
5 changes: 5 additions & 0 deletions libcxxabi/cmake/config-ix.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ if(FUCHSIA)
set(LIBCXXABI_HAS_PTHREAD_LIB NO)
check_library_exists(c __cxa_thread_atexit_impl ""
LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL)
elseif(ANDROID)
set(LIBCXXABI_HAS_DL_LIB YES)
set(LIBCXXABI_HAS_PTHREAD_LIB NO)
check_library_exists(c __cxa_thread_atexit_impl ""
LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL)
else()
check_library_exists(dl dladdr "" LIBCXXABI_HAS_DL_LIB)
check_library_exists(pthread pthread_once "" LIBCXXABI_HAS_PTHREAD_LIB)
Expand Down
10 changes: 8 additions & 2 deletions lld/ELF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2023,10 +2023,16 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
});
if (!allNeededIsKnown)
continue;
for (Symbol *sym : file->requiredSymbols)
if (sym->isUndefined() && !sym->isWeak())
for (Symbol *sym : file->requiredSymbols) {
if (sym->isUndefined() && !sym->isWeak()) {
diagnose("undefined reference due to --no-allow-shlib-undefined: " +
toString(*sym) + "\n>>> referenced by " + toString(file));
} else if (sym->isDefined() && sym->computeBinding() == STB_LOCAL) {
diagnose("non-exported symbol '" + toString(*sym) + "' in '" +
toString(sym->file) + "' is referenced by DSO '" +
toString(file) + "'");
}
}
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion lld/test/ELF/Inputs/allow-shlib-undefined.s
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.globl _shared
.weak x2
_shared:
callq _unresolved@PLT
callq x1@PLT

callq x2@PLT
125 changes: 76 additions & 49 deletions lld/test/ELF/allow-shlib-undefined.s
Original file line number Diff line number Diff line change
@@ -1,60 +1,87 @@
# REQUIRES: x86

# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
# RUN: %p/Inputs/allow-shlib-undefined.s -o %t1.o
# RUN: ld.lld -shared %t1.o -o %t.so

# RUN: ld.lld --allow-shlib-undefined %t.o %t.so -o /dev/null
# RUN: not ld.lld --no-allow-shlib-undefined %t.o %t.so -o /dev/null 2>&1 | FileCheck %s
# Executable defaults to --no-allow-shlib-undefined
# RUN: not ld.lld %t.o %t.so -o /dev/null 2>&1 | FileCheck %s
# RUN: ld.lld %t.o %t.so --noinhibit-exec -o /dev/null 2>&1 | FileCheck %s --check-prefix=WARN
# RUN: ld.lld %t.o %t.so --warn-unresolved-symbols -o /dev/null 2>&1 | FileCheck %s --check-prefix=WARN
# -shared defaults to --allow-shlib-undefined
# RUN: ld.lld -shared %t.o %t.so -o /dev/null

# RUN: echo | llvm-mc -filetype=obj -triple=x86_64-unknown-linux -o %tempty.o
# RUN: ld.lld -shared %tempty.o -o %tempty.so
# RUN: ld.lld -shared %t1.o %tempty.so -o %t2.so
# RUN: ld.lld --no-allow-shlib-undefined %t.o %t2.so -o /dev/null

# DSO with undefines:
# should link with or without any of these options.
# RUN: ld.lld -shared %t1.o -o /dev/null
# RUN: ld.lld -shared --allow-shlib-undefined %t1.o -o /dev/null
# RUN: ld.lld -shared --no-allow-shlib-undefined %t1.o -o /dev/null

## Check that the error is reported if an unresolved symbol is first seen in a
## regular object file.
# RUN: echo 'callq _unresolved@PLT' | \
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %tref.o
# RUN: not ld.lld --gc-sections %t.o %tref.o %t.so -o /dev/null 2>&1 | FileCheck %s
# RUN: rm -rf %t && split-file %s %t && cd %t
# RUN: llvm-mc -filetype=obj -triple=x86_64 main.s -o main.o
# RUN: llvm-mc -filetype=obj -triple=x86_64 def.s -o def.o
# RUN: llvm-mc -filetype=obj -triple=x86_64 def-hidden.s -o def-hidden.o
# RUN: llvm-mc -filetype=obj -triple=x86_64 ref.s -o ref.o
# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o && ld.lld -shared a.o -o a.so
# RUN: cp a.so b.so
# RUN: llvm-mc -filetype=obj -triple=x86_64 empty.s -o empty.o && ld.lld -shared empty.o -o empty.so

# RUN: ld.lld --allow-shlib-undefined main.o a.so -o /dev/null
# RUN: not ld.lld --no-allow-shlib-undefined main.o a.so -o /dev/null 2>&1 | FileCheck %s
## Executable linking defaults to --no-allow-shlib-undefined.
# RUN: not ld.lld main.o a.so -o /dev/null 2>&1 | FileCheck %s
# RUN: ld.lld main.o a.so --noinhibit-exec -o /dev/null 2>&1 | FileCheck %s --check-prefix=WARN
# RUN: ld.lld main.o a.so --warn-unresolved-symbols -o /dev/null 2>&1 | FileCheck %s --check-prefix=WARN
## -shared linking defaults to --allow-shlib-undefined.
# RUN: ld.lld -shared main.o a.so -o /dev/null

## DSO with undefines should link with or without any of these options.
# RUN: ld.lld -shared --allow-shlib-undefined a.o -o /dev/null
# RUN: ld.lld -shared --no-allow-shlib-undefined a.o -o /dev/null

## Perform checking even if an unresolved symbol is first seen in a regular object file.
# RUN: not ld.lld --gc-sections main.o ref.o a.so -o /dev/null 2>&1 | FileCheck %s

## Check that the error is reported for each shared library where the symbol
## is referenced.
# RUN: cp %t.so %t2.so
# RUN: not ld.lld %t.o %t.so %t2.so -o /dev/null 2>&1 | \
# RUN: FileCheck %s --check-prefixes=CHECK,CHECK2
# RUN: not ld.lld main.o a.so empty.so b.so -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK2

## Test some cases where relocatable object files provide a hidden definition.
# RUN: echo '.globl _unresolved; _unresolved:' | llvm-mc -filetype=obj -triple=x86_64 -o %tdef.o
# RUN: echo '.globl _unresolved; .hidden _unresolved; _unresolved:' | llvm-mc -filetype=obj -triple=x86_64 -o %tdef-hidden.o
# RUN: ld.lld %t.o %t.so %tdef-hidden.o -o /dev/null 2>&1 | count 0
## Test some cases when a relocatable object file provides a non-exported definition.
# RUN: not ld.lld main.o a.so def-hidden.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=NONEXPORTED
# RUN: not ld.lld main.o a.so def-hidden.o -shared --no-allow-shlib-undefined -o /dev/null 2>&1 | FileCheck %s --check-prefix=NONEXPORTED
# RUN: ld.lld main.o a.so def-hidden.o --allow-shlib-undefined --fatal-warnings -o /dev/null
## Test a relocatable object file definition that is converted to STB_LOCAL.
# RUN: not ld.lld main.o a.so def-hidden.o --version-script=local.ver -o /dev/null 2>&1 | FileCheck %s --check-prefix=NONEXPORTED

## The section containing the definition is discarded, and we report an error.
# RUN: not ld.lld --gc-sections %t.o %t.so %tdef-hidden.o -o /dev/null 2>&1 | FileCheck %s
## The definition %tdef.so is ignored.
# RUN: ld.lld -shared -soname=tdef.so %tdef.o -o %tdef.so
# RUN: not ld.lld --gc-sections %t.o %t.so %tdef.so %tdef-hidden.o -o /dev/null 2>&1 | FileCheck %s
# RUN: not ld.lld --gc-sections main.o a.so def-hidden.o -o /dev/null 2>&1 | FileCheck %s
## The definition def.so is ignored.
# RUN: ld.lld -shared def.o -o def.so
# RUN: not ld.lld --gc-sections main.o a.so def.so def-hidden.o -o /dev/null 2>&1 | FileCheck %s

# CHECK-NOT: error:
# CHECK: error: undefined reference due to --no-allow-shlib-undefined: x1{{$}}
# CHECK-NEXT: >>> referenced by a.so{{$}}
# CHECK-NOT: {{.}}

# CHECK2-NOT: error:
# CHECK2: error: undefined reference due to --no-allow-shlib-undefined: x1
# CHECK2-NEXT: >>> referenced by a.so
# CHECK2: error: undefined reference due to --no-allow-shlib-undefined: x1
# CHECK2-NEXT: >>> referenced by b.so
# CHECK2-NOT: {{.}}

# WARN: warning: undefined reference due to --no-allow-shlib-undefined: x1
# WARN-NEXT: >>> referenced by a.so

# NONEXPORTED-NOT: error:
# NONEXPORTED: error: non-exported symbol 'x1' in 'def-hidden.o' is referenced by DSO 'a.so'
# NONEXPORTED-NOT: {{.}}

#--- main.s
.globl _start
_start:
callq _shared@PLT

# CHECK: error: undefined reference due to --no-allow-shlib-undefined: _unresolved
# CHECK-NEXT: >>> referenced by {{.*}}.so
# CHECK2: error: undefined reference due to --no-allow-shlib-undefined: _unresolved
# CHECK2-NEXT: >>> referenced by {{.*}}2.so
# WARN: warning: undefined reference due to --no-allow-shlib-undefined: _unresolved
# WARN-NEXT: >>> referenced by {{.*}}.so
callq shared@PLT
#--- ref.s
callq x1@PLT
#--- def.s
.globl x1
x1:
#--- def-hidden.s
.globl x1
.hidden x1
x1:

#--- a.s
.globl shared
.weak x2
shared:
callq x1@PLT
movq x2@GOTPCREL(%rip), %rax

#--- empty.s
#--- local.ver
v1 { local: x1; };
15 changes: 8 additions & 7 deletions lldb/packages/Python/lldbsuite/test/builders/darwin.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,17 +88,18 @@ def getExtraMakeArgs(self):
args["FRAMEWORK_INCLUDES"] = "-F{}".format(private_frameworks)

operating_system, env = get_os_and_env()
if operating_system and operating_system != "macosx":
builder_dir = os.path.dirname(os.path.abspath(__file__))
test_dir = os.path.dirname(builder_dir)

builder_dir = os.path.dirname(os.path.abspath(__file__))
test_dir = os.path.dirname(builder_dir)
if not operating_system:
entitlements_file = "entitlements-macos.plist"
else:
if env == "simulator":
entitlements_file = "entitlements-simulator.plist"
else:
entitlements_file = "entitlements.plist"
entitlements = os.path.join(test_dir, "make", entitlements_file)
args["CODESIGN"] = "codesign --entitlements {}".format(entitlements)
else:
args["CODESIGN"] = "codesign"
entitlements = os.path.join(test_dir, "make", entitlements_file)
args["CODESIGN"] = "codesign --entitlements {}".format(entitlements)

# Return extra args as a formatted string.
return ["{}={}".format(key, value) for key, value in args.items()]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>
2 changes: 1 addition & 1 deletion lldb/source/DataFormatters/StringPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ DecodedCharBuffer GetPrintableImpl<StringElementType::UTF8>(
&buffer_for_conversion, buffer_end, &codepoint, llvm::strictConversion);
assert(result == llvm::conversionOK &&
"Failed to convert legal utf8 sequence");
(void)result;
UNUSED_IF_ASSERT_DISABLED(result);

// The UTF8 helper always advances by the utf8 encoded length.
const unsigned utf8_encoded_len = buffer_for_conversion - buffer;
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Expression/IRInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1509,7 +1509,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
size_t dataSize = 0;

bool Success = execution_unit.GetAllocSize(addr, dataSize);
(void)Success;
UNUSED_IF_ASSERT_DISABLED(Success);
assert(Success &&
"unable to locate host data for transfer to device");
// Create the required buffer
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Host/common/PseudoTerminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ std::string PseudoTerminal::GetSecondaryName() const {
char buf[PATH_MAX];
buf[0] = '\0';
int r = ptsname_r(m_primary_fd, buf, sizeof(buf));
(void)r;
UNUSED_IF_ASSERT_DISABLED(r);
assert(r == 0);
return buf;
#if defined(__APPLE__)
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout,
ssize_t bytes_read =
llvm::sys::RetryAfterSignal(-1, ::read, pipe_fd, &c, 1);
assert(bytes_read == 1);
(void)bytes_read;
UNUSED_IF_ASSERT_DISABLED(bytes_read);
switch (c) {
case 'q':
LLDB_LOGF(log,
Expand Down
6 changes: 3 additions & 3 deletions lldb/source/Host/posix/MainLoopPosix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ sigset_t MainLoopPosix::RunImpl::get_sigmask() {
sigset_t sigmask;
int ret = pthread_sigmask(SIG_SETMASK, nullptr, &sigmask);
assert(ret == 0);
(void)ret;
UNUSED_IF_ASSERT_DISABLED(ret);

for (const auto &sig : loop.m_signals)
sigdelset(&sigmask, sig.first);
Expand Down Expand Up @@ -299,7 +299,7 @@ MainLoopPosix::RegisterSignal(int signo, const Callback &callback,
// Even if using kqueue, the signal handler will still be invoked, so it's
// important to replace it with our "benign" handler.
int ret = sigaction(signo, &new_action, &info.old_action);
(void)ret;
UNUSED_IF_ASSERT_DISABLED(ret);
assert(ret == 0 && "sigaction failed");

#if HAVE_SYS_EVENT_H
Expand Down Expand Up @@ -346,7 +346,7 @@ void MainLoopPosix::UnregisterSignal(
int ret = pthread_sigmask(it->second.was_blocked ? SIG_BLOCK : SIG_UNBLOCK,
&set, nullptr);
assert(ret == 0);
(void)ret;
UNUSED_IF_ASSERT_DISABLED(ret);

#if HAVE_SYS_EVENT_H
struct kevent ev;
Expand Down
8 changes: 4 additions & 4 deletions lldb/source/Host/windows/MainLoopWindows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ MainLoopWindows::~MainLoopWindows() {
assert(m_read_fds.empty());
BOOL result = WSACloseEvent(m_trigger_event);
assert(result == TRUE);
(void)result;
UNUSED_IF_ASSERT_DISABLED(result);
}

llvm::Expected<size_t> MainLoopWindows::Poll() {
Expand All @@ -39,7 +39,7 @@ llvm::Expected<size_t> MainLoopWindows::Poll() {
for (auto &[fd, info] : m_read_fds) {
int result = WSAEventSelect(fd, info.event, FD_READ | FD_ACCEPT | FD_CLOSE);
assert(result == 0);
(void)result;
UNUSED_IF_ASSERT_DISABLED(result);

events.push_back(info.event);
}
Expand All @@ -51,7 +51,7 @@ llvm::Expected<size_t> MainLoopWindows::Poll() {
for (auto &fd : m_read_fds) {
int result = WSAEventSelect(fd.first, WSA_INVALID_EVENT, 0);
assert(result == 0);
(void)result;
UNUSED_IF_ASSERT_DISABLED(result);
}

if (result >= WSA_WAIT_EVENT_0 && result <= WSA_WAIT_EVENT_0 + events.size())
Expand Down Expand Up @@ -99,7 +99,7 @@ void MainLoopWindows::UnregisterReadObject(IOObject::WaitableHandle handle) {
assert(it != m_read_fds.end());
BOOL result = WSACloseEvent(it->second.event);
assert(result == TRUE);
(void)result;
UNUSED_IF_ASSERT_DISABLED(result);
m_read_fds.erase(it);
}

Expand Down
3 changes: 2 additions & 1 deletion lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ static CompilerType GetLLDBNSPairType(TargetSP target_sp) {
if (!compiler_type) {
compiler_type = scratch_ts_sp->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
g_lldb_autogen_nspair, clang::TTK_Struct, lldb::eLanguageTypeC);
g_lldb_autogen_nspair, llvm::to_underlying(clang::TagTypeKind::Struct),
lldb::eLanguageTypeC);

if (compiler_type) {
TypeSystemClang::StartTagDeclarationDefinition(compiler_type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ AppleObjCRuntimeV1::CreateObjectChecker(std::string name,
" \n",
name.c_str());
assert(strformatsize < (int)sizeof(buf->contents));
(void)strformatsize;
UNUSED_IF_ASSERT_DISABLED(strformatsize);

return GetTargetRef().CreateUtilityFunction(buf->contents, std::move(name),
eLanguageTypeC, exe_ctx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,13 @@ AppleObjCTypeEncodingParser::ReadStructElement(TypeSystemClang &ast_ctx,
clang::QualType AppleObjCTypeEncodingParser::BuildStruct(
TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) {
return BuildAggregate(ast_ctx, type, for_expression, _C_STRUCT_B, _C_STRUCT_E,
clang::TTK_Struct);
llvm::to_underlying(clang::TagTypeKind::Struct));
}

clang::QualType AppleObjCTypeEncodingParser::BuildUnion(
TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) {
return BuildAggregate(ast_ctx, type, for_expression, _C_UNION_B, _C_UNION_E,
clang::TTK_Union);
llvm::to_underlying(clang::TagTypeKind::Union));
}

clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
Expand Down
3 changes: 2 additions & 1 deletion lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h"
#include "lldb/lldb-defines.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Endian.h"
Expand Down Expand Up @@ -119,7 +120,7 @@ static UUID parseModuleId(llvm::Triple::OSType os, llvm::StringRef str) {
uint32_t age;
bool success = to_integer(age_str, age, 16);
assert(success);
(void)success;
UNUSED_IF_ASSERT_DISABLED(success);
data.age = age;

// On non-windows, the age field should always be zero, so we don't include to
Expand Down
6 changes: 3 additions & 3 deletions lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ CompilerType PlatformFreeBSD::GetSiginfoType(const llvm::Triple &triple) {

CompilerType sigval_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_sigval_t",
clang::TTK_Union, lldb::eLanguageTypeC);
llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(sigval_type);
ast->AddFieldToRecordType(sigval_type, "sival_int", int_type,
lldb::eAccessPublic, 0);
Expand All @@ -217,7 +217,7 @@ CompilerType PlatformFreeBSD::GetSiginfoType(const llvm::Triple &triple) {
// siginfo_t
CompilerType siginfo_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_siginfo_t",
clang::TTK_Struct, lldb::eLanguageTypeC);
llvm::to_underlying(clang::TagTypeKind::Struct), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(siginfo_type);
ast->AddFieldToRecordType(siginfo_type, "si_signo", int_type,
lldb::eAccessPublic, 0);
Expand All @@ -239,7 +239,7 @@ CompilerType PlatformFreeBSD::GetSiginfoType(const llvm::Triple &triple) {
// union used to hold the signal data
CompilerType union_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",
clang::TTK_Union, lldb::eLanguageTypeC);
llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(union_type);

ast->AddFieldToRecordType(
Expand Down
8 changes: 4 additions & 4 deletions lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ CompilerType PlatformLinux::GetSiginfoType(const llvm::Triple &triple) {

CompilerType sigval_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_sigval_t",
clang::TTK_Union, lldb::eLanguageTypeC);
llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(sigval_type);
ast->AddFieldToRecordType(sigval_type, "sival_int", int_type,
lldb::eAccessPublic, 0);
Expand All @@ -358,7 +358,7 @@ CompilerType PlatformLinux::GetSiginfoType(const llvm::Triple &triple) {

CompilerType sigfault_bounds_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",
clang::TTK_Union, lldb::eLanguageTypeC);
llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(sigfault_bounds_type);
ast->AddFieldToRecordType(
sigfault_bounds_type, "_addr_bnd",
Expand All @@ -375,7 +375,7 @@ CompilerType PlatformLinux::GetSiginfoType(const llvm::Triple &triple) {
// siginfo_t
CompilerType siginfo_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_siginfo_t",
clang::TTK_Struct, lldb::eLanguageTypeC);
llvm::to_underlying(clang::TagTypeKind::Struct), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(siginfo_type);
ast->AddFieldToRecordType(siginfo_type, "si_signo", int_type,
lldb::eAccessPublic, 0);
Expand All @@ -400,7 +400,7 @@ CompilerType PlatformLinux::GetSiginfoType(const llvm::Triple &triple) {
// union used to hold the signal data
CompilerType union_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",
clang::TTK_Union, lldb::eLanguageTypeC);
llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(union_type);

ast->AddFieldToRecordType(
Expand Down
10 changes: 5 additions & 5 deletions lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ CompilerType PlatformNetBSD::GetSiginfoType(const llvm::Triple &triple) {

CompilerType sigval_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_sigval_t",
clang::TTK_Union, lldb::eLanguageTypeC);
llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(sigval_type);
ast->AddFieldToRecordType(sigval_type, "sival_int", int_type,
lldb::eAccessPublic, 0);
Expand All @@ -238,7 +238,7 @@ CompilerType PlatformNetBSD::GetSiginfoType(const llvm::Triple &triple) {

CompilerType ptrace_option_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",
clang::TTK_Union, lldb::eLanguageTypeC);
llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(ptrace_option_type);
ast->AddFieldToRecordType(ptrace_option_type, "_pe_other_pid", pid_type,
lldb::eAccessPublic, 0);
Expand All @@ -249,13 +249,13 @@ CompilerType PlatformNetBSD::GetSiginfoType(const llvm::Triple &triple) {
// siginfo_t
CompilerType siginfo_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "__lldb_siginfo_t",
clang::TTK_Union, lldb::eLanguageTypeC);
llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(siginfo_type);

// struct _ksiginfo
CompilerType ksiginfo_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",
clang::TTK_Struct, lldb::eLanguageTypeC);
llvm::to_underlying(clang::TagTypeKind::Struct), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(ksiginfo_type);
ast->AddFieldToRecordType(ksiginfo_type, "_signo", int_type,
lldb::eAccessPublic, 0);
Expand All @@ -272,7 +272,7 @@ CompilerType PlatformNetBSD::GetSiginfoType(const llvm::Triple &triple) {
// union used to hold the signal data
CompilerType union_type = ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "",
clang::TTK_Union, lldb::eLanguageTypeC);
llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeC);
ast->StartTagDeclarationDefinition(union_type);

ast->AddFieldToRecordType(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ NativeProcessFreeBSD::Manager::Launch(ProcessLaunchInfo &launch_info,
int wstatus;
::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
assert(wpid == pid);
(void)wpid;
UNUSED_IF_ASSERT_DISABLED(wpid);
if (!WIFSTOPPED(wstatus)) {
LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
WaitStatus::Decode(wstatus));
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ NativeProcessLinux::Manager::Launch(ProcessLaunchInfo &launch_info,
int wstatus = 0;
::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
assert(wpid == pid);
(void)wpid;
UNUSED_IF_ASSERT_DISABLED(wpid);
if (!WIFSTOPPED(wstatus)) {
LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
WaitStatus::Decode(wstatus));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ CompilerType RegisterTypeBuilderClang::GetRegisterType(

fields_type = type_system->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
register_type_name, clang::TTK_Struct, lldb::eLanguageTypeC);
register_type_name, llvm::to_underlying(clang::TagTypeKind::Struct),
lldb::eLanguageTypeC);
type_system->StartTagDeclarationDefinition(fields_type);

// We assume that RegisterFlags has padded and sorted the fields
Expand Down
14 changes: 7 additions & 7 deletions lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,12 +320,12 @@ static uint32_t GetBytes(uint32_t bits) { return bits / sizeof(unsigned); }
static clang::TagTypeKind TranslateRecordKind(CTFType::Kind type) {
switch (type) {
case CTFType::Kind::eStruct:
return clang::TTK_Struct;
return clang::TagTypeKind::Struct;
case CTFType::Kind::eUnion:
return clang::TTK_Union;
return clang::TagTypeKind::Union;
default:
lldbassert(false && "Invalid record kind!");
return clang::TTK_Struct;
return clang::TagTypeKind::Struct;
}
}

Expand Down Expand Up @@ -503,9 +503,9 @@ SymbolFileCTF::CreateFunction(const CTFFunction &ctf_function) {
llvm::Expected<lldb::TypeSP>
SymbolFileCTF::CreateRecord(const CTFRecord &ctf_record) {
const clang::TagTypeKind tag_kind = TranslateRecordKind(ctf_record.kind);
CompilerType record_type =
m_ast->CreateRecordType(nullptr, OptionalClangModuleID(), eAccessPublic,
ctf_record.name.data(), tag_kind, eLanguageTypeC);
CompilerType record_type = m_ast->CreateRecordType(
nullptr, OptionalClangModuleID(), eAccessPublic, ctf_record.name.data(),
llvm::to_underlying(tag_kind), eLanguageTypeC);
m_compiler_types[record_type.GetOpaqueQualType()] = &ctf_record;
Declaration decl;
return MakeType(ctf_record.uid, ConstString(ctf_record.name), ctf_record.size,
Expand Down Expand Up @@ -562,7 +562,7 @@ llvm::Expected<lldb::TypeSP>
SymbolFileCTF::CreateForward(const CTFForward &ctf_forward) {
CompilerType forward_compiler_type = m_ast->CreateRecordType(
nullptr, OptionalClangModuleID(), eAccessPublic, ctf_forward.name,
clang::TTK_Struct, eLanguageTypeC);
llvm::to_underlying(clang::TagTypeKind::Struct), eLanguageTypeC);
Declaration decl;
return MakeType(ctf_forward.uid, ConstString(ctf_forward.name), 0, nullptr,
LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
Expand Down
13 changes: 7 additions & 6 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1637,13 +1637,13 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
int tag_decl_kind = -1;
AccessType default_accessibility = eAccessNone;
if (tag == DW_TAG_structure_type) {
tag_decl_kind = clang::TTK_Struct;
tag_decl_kind = llvm::to_underlying(clang::TagTypeKind::Struct);
default_accessibility = eAccessPublic;
} else if (tag == DW_TAG_union_type) {
tag_decl_kind = clang::TTK_Union;
tag_decl_kind = llvm::to_underlying(clang::TagTypeKind::Union);
default_accessibility = eAccessPublic;
} else if (tag == DW_TAG_class_type) {
tag_decl_kind = clang::TTK_Class;
tag_decl_kind = llvm::to_underlying(clang::TagTypeKind::Class);
default_accessibility = eAccessPrivate;
}

Expand Down Expand Up @@ -1762,7 +1762,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
}
}
assert(tag_decl_kind != -1);
(void)tag_decl_kind;
UNUSED_IF_ASSERT_DISABLED(tag_decl_kind);
bool clang_type_was_created = false;
clang_type = CompilerType(
m_ast.weak_from_this(),
Expand Down Expand Up @@ -3852,7 +3852,7 @@ void DWARFASTParserClang::ParseRustVariantPart(
decl_context, OptionalClangModuleID(), lldb::eAccessPublic,
std::string(
llvm::formatv("{0}$Inner", class_clang_type.GetTypeName(false))),
clang::TTK_Union, lldb::eLanguageTypeRust);
llvm::to_underlying(clang::TagTypeKind::Union), lldb::eLanguageTypeRust);
m_ast.StartTagDeclarationDefinition(inner_holder);
m_ast.SetIsPacked(inner_holder);

Expand All @@ -3866,7 +3866,8 @@ void DWARFASTParserClang::ParseRustVariantPart(
m_ast.GetDeclContextForType(inner_holder), OptionalClangModuleID(),
lldb::eAccessPublic,
std::string(llvm::formatv("{0}$Variant", member.GetName())),
clang::TTK_Struct, lldb::eLanguageTypeRust);
llvm::to_underlying(clang::TagTypeKind::Struct),
lldb::eLanguageTypeRust);

m_ast.StartTagDeclarationDefinition(field_type);
auto offset = member.byte_offset;
Expand Down
23 changes: 12 additions & 11 deletions lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,18 @@ struct CreateMethodDecl : public TypeVisitorCallbacks {
static clang::TagTypeKind TranslateUdtKind(const TagRecord &cr) {
switch (cr.Kind) {
case TypeRecordKind::Class:
return clang::TTK_Class;
return clang::TagTypeKind::Class;
case TypeRecordKind::Struct:
return clang::TTK_Struct;
return clang::TagTypeKind::Struct;
case TypeRecordKind::Union:
return clang::TTK_Union;
return clang::TagTypeKind::Union;
case TypeRecordKind::Interface:
return clang::TTK_Interface;
return clang::TagTypeKind::Interface;
case TypeRecordKind::Enum:
return clang::TTK_Enum;
return clang::TagTypeKind::Enum;
default:
lldbassert(false && "Invalid tag record kind!");
return clang::TTK_Struct;
return clang::TagTypeKind::Struct;
}
}

Expand Down Expand Up @@ -608,16 +608,17 @@ clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id,
return {};

clang::TagTypeKind ttk = TranslateUdtKind(record);
lldb::AccessType access =
(ttk == clang::TTK_Class) ? lldb::eAccessPrivate : lldb::eAccessPublic;
lldb::AccessType access = (ttk == clang::TagTypeKind::Class)
? lldb::eAccessPrivate
: lldb::eAccessPublic;

ClangASTMetadata metadata;
metadata.SetUserID(toOpaqueUid(id));
metadata.SetIsDynamicCXXType(false);

CompilerType ct =
m_clang.CreateRecordType(context, OptionalClangModuleID(), access, uname,
ttk, lldb::eLanguageTypeC_plus_plus, &metadata);
CompilerType ct = m_clang.CreateRecordType(
context, OptionalClangModuleID(), access, uname, llvm::to_underlying(ttk),
lldb::eLanguageTypeC_plus_plus, &metadata);

lldbassert(ct.IsValid());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,14 +356,14 @@ UdtRecordCompleter::AddMember(TypeSystemClang &clang, Member *field,
case Member::Struct:
case Member::Union: {
clang::TagTypeKind kind = field->kind == Member::Struct
? clang::TagTypeKind::TTK_Struct
: clang::TagTypeKind::TTK_Union;
? clang::TagTypeKind::Struct
: clang::TagTypeKind::Union;
ClangASTMetadata metadata;
metadata.SetUserID(pdb->anonymous_id);
metadata.SetIsDynamicCXXType(false);
CompilerType record_ct = clang.CreateRecordType(
parent_decl_ctx, OptionalClangModuleID(), lldb::eAccessPublic, "", kind,
lldb::eLanguageTypeC_plus_plus, &metadata);
parent_decl_ctx, OptionalClangModuleID(), lldb::eAccessPublic, "",
llvm::to_underlying(kind), lldb::eLanguageTypeC_plus_plus, &metadata);
TypeSystemClang::StartTagDeclarationDefinition(record_ct);
ClangASTImporter::LayoutInfo layout;
clang::DeclContext *decl_ctx = clang.GetDeclContextForType(record_ct);
Expand Down
14 changes: 7 additions & 7 deletions lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ using namespace llvm::pdb;
static int TranslateUdtKind(PDB_UdtType pdb_kind) {
switch (pdb_kind) {
case PDB_UdtType::Class:
return clang::TTK_Class;
return llvm::to_underlying(clang::TagTypeKind::Class);
case PDB_UdtType::Struct:
return clang::TTK_Struct;
return llvm::to_underlying(clang::TagTypeKind::Struct);
case PDB_UdtType::Union:
return clang::TTK_Union;
return llvm::to_underlying(clang::TagTypeKind::Union);
case PDB_UdtType::Interface:
return clang::TTK_Interface;
return llvm::to_underlying(clang::TagTypeKind::Interface);
}
llvm_unreachable("unsuported PDB UDT type");
}
Expand Down Expand Up @@ -1387,9 +1387,9 @@ void PDBASTParser::AddRecordBases(
auto is_virtual = base->isVirtualBaseClass();

std::unique_ptr<clang::CXXBaseSpecifier> base_spec =
m_ast.CreateBaseClassSpecifier(base_comp_type.GetOpaqueQualType(),
access, is_virtual,
record_kind == clang::TTK_Class);
m_ast.CreateBaseClassSpecifier(
base_comp_type.GetOpaqueQualType(), access, is_virtual,
record_kind == llvm::to_underlying(clang::TagTypeKind::Class));
lldbassert(base_spec);

base_classes.push_back(std::move(base_spec));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,8 @@ void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexes() {
scratch_ts_sp->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 16);
CompilerType dispatch_tsd_indexes_s = scratch_ts_sp->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
"__lldb_dispatch_tsd_indexes_s", clang::TTK_Struct,
"__lldb_dispatch_tsd_indexes_s",
llvm::to_underlying(clang::TagTypeKind::Struct),
lldb::eLanguageTypeC);

TypeSystemClang::StartTagDeclarationDefinition(dispatch_tsd_indexes_s);
Expand Down
5 changes: 3 additions & 2 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2320,8 +2320,9 @@ CompilerType TypeSystemClang::CreateStructForIdentifier(
return type;
}

type = CreateRecordType(nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
type_name, clang::TTK_Struct, lldb::eLanguageTypeC);
type = CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, type_name,
llvm::to_underlying(clang::TagTypeKind::Struct), lldb::eLanguageTypeC);
StartTagDeclarationDefinition(type);
for (const auto &field : type_fields)
AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic,
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Symbol/SymbolFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ void SymbolFileCommon::SetCompileUnitAtIndex(uint32_t idx,
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
const size_t num_compile_units = GetNumCompileUnits();
assert(idx < num_compile_units);
(void)num_compile_units;
UNUSED_IF_ASSERT_DISABLED(num_compile_units);

// Fire off an assertion if this compile unit already exists for now. The
// partial parsing should take care of only setting the compile unit
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Utility/Log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ void Log::Warning(const char *format, ...) {
void Log::Register(llvm::StringRef name, Channel &channel) {
auto iter = g_channel_map->try_emplace(name, channel);
assert(iter.second == true);
(void)iter;
UNUSED_IF_ASSERT_DISABLED(iter);
}

void Log::Unregister(llvm::StringRef name) {
Expand Down
12 changes: 9 additions & 3 deletions lldb/test/API/functionalities/vtable/TestVTableValue.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,19 @@ def test_overwrite_vtable(self):
# Overwrite the first entry in the vtable and make sure we can still
# see the bogus value which should have no summary
vtable_addr = vtable.GetValueAsUnsigned()
data = str("\x01\x01\x01\x01\x01\x01\x01\x01")

is_64bit = self.process().GetAddressByteSize() == 8
data = str(
"\x01\x01\x01\x01\x01\x01\x01\x01" if is_64bit else "\x01\x01\x01\x01"
)
error = lldb.SBError()
process.WriteMemory(vtable_addr, data, error)

scribbled_child = vtable.GetChildAtIndex(0)
self.assertEquals(scribbled_child.GetValueAsUnsigned(0),
0x0101010101010101)
self.assertEquals(
scribbled_child.GetValueAsUnsigned(0),
0x0101010101010101 if is_64bit else 0x01010101,
)
self.assertEquals(scribbled_child.GetSummary(), None)

def expected_vtable_addr(self, var: lldb.SBValue) -> int:
Expand Down
2 changes: 1 addition & 1 deletion lldb/tools/lldb-dap/DAP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ DAP::DAP()
int result = _setmode(fileno(stdout), _O_BINARY);
assert(result);
result = _setmode(fileno(stdin), _O_BINARY);
(void)result;
UNUSED_IF_ASSERT_DISABLED(result);
assert(result);
#endif
if (log_file_path)
Expand Down
27 changes: 17 additions & 10 deletions lldb/unittests/Symbol/TestTypeSystemClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,8 @@ TEST_F(TestTypeSystemClang, TestOwningModule) {

CompilerType record_type = ast.CreateRecordType(
nullptr, OptionalClangModuleID(200), lldb::eAccessPublic, "FooRecord",
clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
llvm::to_underlying(clang::TagTypeKind::Struct),
lldb::eLanguageTypeC_plus_plus, nullptr);
auto *rd = TypeSystemClang::GetAsRecordDecl(record_type);
EXPECT_FALSE(!rd);
EXPECT_EQ(rd->getOwningModuleID(), 200u);
Expand All @@ -315,7 +316,8 @@ TEST_F(TestTypeSystemClang, TestIsClangType) {
CompilerType bool_type(m_ast->weak_from_this(), bool_ctype);
CompilerType record_type = m_ast->CreateRecordType(
nullptr, OptionalClangModuleID(100), lldb::eAccessPublic, "FooRecord",
clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
llvm::to_underlying(clang::TagTypeKind::Struct),
lldb::eLanguageTypeC_plus_plus, nullptr);
// Clang builtin type and record type should pass
EXPECT_TRUE(ClangUtil::IsClangType(bool_type));
EXPECT_TRUE(ClangUtil::IsClangType(record_type));
Expand All @@ -327,7 +329,8 @@ TEST_F(TestTypeSystemClang, TestIsClangType) {
TEST_F(TestTypeSystemClang, TestRemoveFastQualifiers) {
CompilerType record_type = m_ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "FooRecord",
clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
llvm::to_underlying(clang::TagTypeKind::Struct),
lldb::eLanguageTypeC_plus_plus, nullptr);
QualType qt;

qt = ClangUtil::GetQualType(record_type);
Expand Down Expand Up @@ -399,7 +402,8 @@ TEST_F(TestTypeSystemClang, TestRecordHasFields) {
// Test that a record with no fields returns false
CompilerType empty_base = m_ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyBase",
clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
llvm::to_underlying(clang::TagTypeKind::Struct),
lldb::eLanguageTypeC_plus_plus, nullptr);
TypeSystemClang::StartTagDeclarationDefinition(empty_base);
TypeSystemClang::CompleteTagDeclarationDefinition(empty_base);

Expand All @@ -410,7 +414,8 @@ TEST_F(TestTypeSystemClang, TestRecordHasFields) {
// Test that a record with direct fields returns true
CompilerType non_empty_base = m_ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "NonEmptyBase",
clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
llvm::to_underlying(clang::TagTypeKind::Struct),
lldb::eLanguageTypeC_plus_plus, nullptr);
TypeSystemClang::StartTagDeclarationDefinition(non_empty_base);
FieldDecl *non_empty_base_field_decl = m_ast->AddFieldToRecordType(
non_empty_base, "MyField", int_type, eAccessPublic, 0);
Expand All @@ -426,7 +431,8 @@ TEST_F(TestTypeSystemClang, TestRecordHasFields) {
// Test that a record with no direct fields, but fields in a base returns true
CompilerType empty_derived = m_ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived",
clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
llvm::to_underlying(clang::TagTypeKind::Struct),
lldb::eLanguageTypeC_plus_plus, nullptr);
TypeSystemClang::StartTagDeclarationDefinition(empty_derived);
std::unique_ptr<clang::CXXBaseSpecifier> non_empty_base_spec =
m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(),
Expand All @@ -448,7 +454,8 @@ TEST_F(TestTypeSystemClang, TestRecordHasFields) {
// returns true
CompilerType empty_derived2 = m_ast->CreateRecordType(
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived2",
clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
llvm::to_underlying(clang::TagTypeKind::Struct),
lldb::eLanguageTypeC_plus_plus, nullptr);
TypeSystemClang::StartTagDeclarationDefinition(empty_derived2);
std::unique_ptr<CXXBaseSpecifier> non_empty_vbase_spec =
m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(),
Expand Down Expand Up @@ -479,14 +486,14 @@ TEST_F(TestTypeSystemClang, TemplateArguments) {
// template<typename T, int I> struct foo;
ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl(
m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic,
"foo", TTK_Struct, infos);
"foo", llvm::to_underlying(clang::TagTypeKind::Struct), infos);
ASSERT_NE(decl, nullptr);

// foo<int, 47>
ClassTemplateSpecializationDecl *spec_decl =
m_ast->CreateClassTemplateSpecializationDecl(
m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), decl,
TTK_Struct, infos);
llvm::to_underlying(clang::TagTypeKind::Struct), infos);
ASSERT_NE(spec_decl, nullptr);
CompilerType type = m_ast->CreateClassTemplateSpecializationType(spec_decl);
ASSERT_TRUE(type);
Expand Down Expand Up @@ -543,7 +550,7 @@ class TestCreateClassTemplateDecl : public TestTypeSystemClang {
CreateClassTemplate(const TypeSystemClang::TemplateParameterInfos &infos) {
ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl(
m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic,
"foo", TTK_Struct, infos);
"foo", llvm::to_underlying(clang::TagTypeKind::Struct), infos);
return decl;
}

Expand Down
2 changes: 2 additions & 0 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5094,6 +5094,8 @@ AArch64:
offsets). (However, LLVM currently does this for the ``m`` constraint as
well.)
- ``r``: A 32 or 64-bit integer register (W* or X*).
- ``Uci``: Like r, but restricted to registers 8 to 11 inclusive.
- ``Ucj``: Like r, but restricted to registers 12 to 15 inclusive.
- ``w``: A 32, 64, or 128-bit floating-point, SIMD or SVE vector register.
- ``x``: Like w, but restricted to registers 0 to 15 inclusive.
- ``y``: Like w, but restricted to SVE vector registers Z0 to Z7 inclusive.
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/ADT/bit.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#endif

#if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \
defined(__Fuchsia__) || defined(__EMSCRIPTEN__)
defined(__Fuchsia__) || defined(__EMSCRIPTEN__) || defined(__OpenBSD__)
#include <endian.h>
#elif defined(_AIX)
#include <sys/machine.h>
Expand Down
5 changes: 4 additions & 1 deletion llvm/include/llvm/CodeGen/ISDOpcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,10 @@ enum NodeType {
/// into new bits.
SIGN_EXTEND,

/// ZERO_EXTEND - Used for integer types, zeroing the new bits.
/// ZERO_EXTEND - Used for integer types, zeroing the new bits. Can carry
/// the NonNeg SDNodeFlag to indicate that the input is known to be
/// non-negative. If the flag is present and the input is negative, the result
/// is poison.
ZERO_EXTEND,

/// ANY_EXTEND - Used for integer types. The high bits are undefined.
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/CodeGen/MachineInstr.h
Original file line number Diff line number Diff line change
Expand Up @@ -1364,6 +1364,10 @@ class MachineInstr
return getOpcode() == TargetOpcode::INLINEASM ||
getOpcode() == TargetOpcode::INLINEASM_BR;
}
/// Returns true if the register operand can be folded with a load or store
/// into a frame index. Does so by checking the InlineAsm::Flag immediate
/// operand at OpId - 1.
bool mayFoldInlineAsmRegOp(unsigned OpId) const;

bool isStackAligningInlineAsm() const;
InlineAsm::AsmDialect getInlineAsmDialect() const;
Expand Down
10 changes: 7 additions & 3 deletions llvm/include/llvm/CodeGen/SelectionDAGNodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ struct SDNodeFlags {
bool NoUnsignedWrap : 1;
bool NoSignedWrap : 1;
bool Exact : 1;
bool NonNeg : 1;
bool NoNaNs : 1;
bool NoInfs : 1;
bool NoSignedZeros : 1;
Expand All @@ -401,9 +402,9 @@ struct SDNodeFlags {
public:
/// Default constructor turns off all optimization flags.
SDNodeFlags()
: NoUnsignedWrap(false), NoSignedWrap(false), Exact(false), NoNaNs(false),
NoInfs(false), NoSignedZeros(false), AllowReciprocal(false),
AllowContract(false), ApproximateFuncs(false),
: NoUnsignedWrap(false), NoSignedWrap(false), Exact(false), NonNeg(false),
NoNaNs(false), NoInfs(false), NoSignedZeros(false),
AllowReciprocal(false), AllowContract(false), ApproximateFuncs(false),
AllowReassociation(false), NoFPExcept(false), Unpredictable(false) {}

/// Propagate the fast-math-flags from an IR FPMathOperator.
Expand All @@ -421,6 +422,7 @@ struct SDNodeFlags {
void setNoUnsignedWrap(bool b) { NoUnsignedWrap = b; }
void setNoSignedWrap(bool b) { NoSignedWrap = b; }
void setExact(bool b) { Exact = b; }
void setNonNeg(bool b) { NonNeg = b; }
void setNoNaNs(bool b) { NoNaNs = b; }
void setNoInfs(bool b) { NoInfs = b; }
void setNoSignedZeros(bool b) { NoSignedZeros = b; }
Expand All @@ -435,6 +437,7 @@ struct SDNodeFlags {
bool hasNoUnsignedWrap() const { return NoUnsignedWrap; }
bool hasNoSignedWrap() const { return NoSignedWrap; }
bool hasExact() const { return Exact; }
bool hasNonNeg() const { return NonNeg; }
bool hasNoNaNs() const { return NoNaNs; }
bool hasNoInfs() const { return NoInfs; }
bool hasNoSignedZeros() const { return NoSignedZeros; }
Expand All @@ -451,6 +454,7 @@ struct SDNodeFlags {
NoUnsignedWrap &= Flags.NoUnsignedWrap;
NoSignedWrap &= Flags.NoSignedWrap;
Exact &= Flags.Exact;
NonNeg &= Flags.Exact;
NoNaNs &= Flags.NoNaNs;
NoInfs &= Flags.NoInfs;
NoSignedZeros &= Flags.NoSignedZeros;
Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ class MachOPlatform : public Platform {
struct ObjCImageInfo {
uint32_t Version = 0;
uint32_t Flags = 0;
/// Whether this image info can no longer be mutated, as it may have been
/// registered with the objc runtime.
bool Finalized = false;
};

Error bootstrapPipelineStart(jitlink::LinkGraph &G);
Expand All @@ -173,6 +176,9 @@ class MachOPlatform : public Platform {

Error processObjCImageInfo(jitlink::LinkGraph &G,
MaterializationResponsibility &MR);
Error mergeImageInfoFlags(jitlink::LinkGraph &G,
MaterializationResponsibility &MR,
ObjCImageInfo &Info, uint32_t NewFlags);

Error fixTLVSectionsAndEdges(jitlink::LinkGraph &G, JITDylib &JD);

Expand Down
3 changes: 0 additions & 3 deletions llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,6 @@ __OMP_RTL(__kmpc_end_serialized_parallel, false, Void, IdentPtr, Int32)
__OMP_RTL(__kmpc_shuffle_int32, false, Int32, Int32, Int16, Int16)
__OMP_RTL(__kmpc_nvptx_parallel_reduce_nowait_v2, false, Int32, IdentPtr, Int32,
Int32, SizeTy, VoidPtr, ShuffleReducePtr, InterWarpCopyPtr)
__OMP_RTL(__kmpc_nvptx_end_reduce_nowait, false, Void, Int32)
__OMP_RTL(__kmpc_nvptx_teams_reduce_nowait_v2, false, Int32, IdentPtr, Int32,
VoidPtr, Int32, VoidPtr, ShuffleReducePtr, InterWarpCopyPtr,
GlobalListPtr, GlobalListPtr, GlobalListPtr, GlobalListPtr)
Expand Down Expand Up @@ -1042,8 +1041,6 @@ __OMP_RTL_ATTRS(__kmpc_shuffle_int32, AttributeSet(), SExt,
ParamAttrs(SExt, SExt, SExt))
__OMP_RTL_ATTRS(__kmpc_nvptx_parallel_reduce_nowait_v2, AttributeSet(), SExt,
ParamAttrs(AttributeSet(), SExt, SExt, SizeTyExt))
__OMP_RTL_ATTRS(__kmpc_nvptx_end_reduce_nowait, AttributeSet(), AttributeSet(),
ParamAttrs(SExt))
__OMP_RTL_ATTRS(__kmpc_nvptx_teams_reduce_nowait_v2, AttributeSet(), SExt,
ParamAttrs(AttributeSet(), SExt, AttributeSet(), ZExt))
__OMP_RTL_ATTRS(__kmpc_reduction_get_fixed_buffer, GetterAttrs, AttributeSet(), ParamAttrs())
Expand Down
35 changes: 30 additions & 5 deletions llvm/include/llvm/IR/InlineAsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,18 +291,23 @@ class InlineAsm final : public Value {
// Bits 30-16 - A ConstraintCode:: value indicating the original
// constraint code. (MemConstraintCode)
// Else:
// Bits 30-16 - The register class ID to use for the operand. (RegClass)
// Bits 29-16 - The register class ID to use for the operand. (RegClass)
// Bit 30 - If the register is permitted to be spilled.
// (RegMayBeFolded)
// Defaults to false "r", may be set for constraints like
// "rm" (or "g").
//
// As such, MatchedOperandNo, MemConstraintCode, and RegClass are views of
// the same slice of bits, but are mutually exclusive depending on the
// fields IsMatched then KindField.
// As such, MatchedOperandNo, MemConstraintCode, and
// (RegClass+RegMayBeFolded) are views of the same slice of bits, but are
// mutually exclusive depending on the fields IsMatched then KindField.
class Flag {
uint32_t Storage;
using KindField = Bitfield::Element<Kind, 0, 3, Kind::Func>;
using NumOperands = Bitfield::Element<unsigned, 3, 13>;
using MatchedOperandNo = Bitfield::Element<unsigned, 16, 15>;
using MemConstraintCode = Bitfield::Element<ConstraintCode, 16, 15, ConstraintCode::Max>;
using RegClass = Bitfield::Element<unsigned, 16, 15>;
using RegClass = Bitfield::Element<unsigned, 16, 14>;
using RegMayBeFolded = Bitfield::Element<bool, 30, 1>;
using IsMatched = Bitfield::Element<bool, 31, 1>;


Expand Down Expand Up @@ -413,6 +418,26 @@ class InlineAsm final : public Value {
"Flag is not a memory or function constraint!");
Bitfield::set<MemConstraintCode>(Storage, ConstraintCode::Unknown);
}

/// Set a bit to denote that while this operand is some kind of register
/// (use, def, ...), a memory flag did appear in the original constraint
/// list. This is set by the instruction selection framework, and consumed
/// by the register allocator. While the register allocator is generally
/// responsible for spilling registers, we need to be able to distinguish
/// between registers that the register allocator has permission to fold
/// ("rm") vs ones it does not ("r"). This is because the inline asm may use
/// instructions which don't support memory addressing modes for that
/// operand.
void setRegMayBeFolded(bool B) {
assert((isRegDefKind() || isRegDefEarlyClobberKind() || isRegUseKind()) &&
"Must be reg");
Bitfield::set<RegMayBeFolded>(Storage, B);
}
bool getRegMayBeFolded() const {
assert((isRegDefKind() || isRegDefEarlyClobberKind() || isRegUseKind()) &&
"Must be reg");
return Bitfield::get<RegMayBeFolded>(Storage);
}
};

static std::vector<StringRef> getExtraInfoNames(unsigned ExtraInfo) {
Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsAMDGPU.td
Original file line number Diff line number Diff line change
Expand Up @@ -1944,6 +1944,12 @@ def int_amdgcn_s_bitreplicate :
def int_amdgcn_s_quadmask :
DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyint_ty], [IntrNoMem, IntrConvergent]>;

// Lowers to S_WQM_B{32,64}
// The argument must be uniform; otherwise, the result is undefined.
// Does not set WQM; merely calculates the bitmask.
def int_amdgcn_s_wqm :
DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyint_ty], [IntrNoMem, IntrConvergent]>;

class AMDGPUWaveReduce<LLVMType data_ty = llvm_anyint_ty> : Intrinsic<
[data_ty],
[
Expand Down
2 changes: 0 additions & 2 deletions llvm/include/llvm/IR/Operator.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,6 @@ class LShrOperator
: public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
};

class ZExtOperator : public ConcreteOperator<Operator, Instruction::ZExt> {};

class GEPOperator
: public ConcreteOperator<Operator, Instruction::GetElementPtr> {
friend class GetElementPtrInst;
Expand Down
22 changes: 8 additions & 14 deletions llvm/include/llvm/IR/OptBisect.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,14 @@ class OptBisect : public OptPassGate {

/// Checks the bisect limit to determine if the specified pass should run.
///
/// This forwards to checkPass().
/// The method prints the name of the pass, its assigned bisect number, and
/// whether or not the pass will be executed. It returns true if the pass
/// should run, i.e. if the bisect limit is set to -1 or has not yet been
/// exceeded.
///
/// Most passes should not call this routine directly. Instead, it is called
/// through helper routines provided by the base classes of the pass. For
/// instance, function passes should call FunctionPass::skipFunction().
bool shouldRunPass(const StringRef PassName,
StringRef IRDescription) override;

Expand All @@ -67,19 +74,6 @@ class OptBisect : public OptPassGate {
LastBisectNum = 0;
}

/// Checks the bisect limit to determine if the specified pass should run.
///
/// If the bisect limit is set to -1, the function prints a message describing
/// the pass and the bisect number assigned to it and return true. Otherwise,
/// the function prints a message with the bisect number assigned to the
/// pass and indicating whether or not the pass will be run and return true if
/// the bisect limit has not yet been exceeded or false if it has.
///
/// Most passes should not call this routine directly. Instead, they are
/// called through helper routines provided by the pass base classes. For
/// instance, function passes should call FunctionPass::skipFunction().
bool checkPass(const StringRef PassName, const StringRef TargetDesc);

static const int Disabled = std::numeric_limits<int>::max();

private:
Expand Down
82 changes: 49 additions & 33 deletions llvm/include/llvm/IR/PatternMatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -1576,10 +1576,10 @@ m_Store(const ValueOpTy &ValueOp, const PointerOpTy &PointerOp) {
// Matchers for CastInst classes
//

template <typename Op_t, unsigned Opcode> struct CastClass_match {
template <typename Op_t, unsigned Opcode> struct CastOperator_match {
Op_t Op;

CastClass_match(const Op_t &OpMatch) : Op(OpMatch) {}
CastOperator_match(const Op_t &OpMatch) : Op(OpMatch) {}

template <typename OpTy> bool match(OpTy *V) {
if (auto *O = dyn_cast<Operator>(V))
Expand All @@ -1588,6 +1588,18 @@ template <typename Op_t, unsigned Opcode> struct CastClass_match {
}
};

template <typename Op_t, unsigned Opcode> struct CastInst_match {
Op_t Op;

CastInst_match(const Op_t &OpMatch) : Op(OpMatch) {}

template <typename OpTy> bool match(OpTy *V) {
if (auto *I = dyn_cast<Instruction>(V))
return I->getOpcode() == Opcode && Op.match(I->getOperand(0));
return false;
}
};

template <typename Op_t> struct PtrToIntSameSize_match {
const DataLayout &DL;
Op_t Op;
Expand All @@ -1607,14 +1619,16 @@ template <typename Op_t> struct PtrToIntSameSize_match {

/// Matches BitCast.
template <typename OpTy>
inline CastClass_match<OpTy, Instruction::BitCast> m_BitCast(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::BitCast>(Op);
inline CastOperator_match<OpTy, Instruction::BitCast>
m_BitCast(const OpTy &Op) {
return CastOperator_match<OpTy, Instruction::BitCast>(Op);
}

/// Matches PtrToInt.
template <typename OpTy>
inline CastClass_match<OpTy, Instruction::PtrToInt> m_PtrToInt(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::PtrToInt>(Op);
inline CastOperator_match<OpTy, Instruction::PtrToInt>
m_PtrToInt(const OpTy &Op) {
return CastOperator_match<OpTy, Instruction::PtrToInt>(Op);
}

template <typename OpTy>
Expand All @@ -1625,90 +1639,92 @@ inline PtrToIntSameSize_match<OpTy> m_PtrToIntSameSize(const DataLayout &DL,

/// Matches IntToPtr.
template <typename OpTy>
inline CastClass_match<OpTy, Instruction::IntToPtr> m_IntToPtr(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::IntToPtr>(Op);
inline CastOperator_match<OpTy, Instruction::IntToPtr>
m_IntToPtr(const OpTy &Op) {
return CastOperator_match<OpTy, Instruction::IntToPtr>(Op);
}

/// Matches Trunc.
template <typename OpTy>
inline CastClass_match<OpTy, Instruction::Trunc> m_Trunc(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::Trunc>(Op);
inline CastOperator_match<OpTy, Instruction::Trunc> m_Trunc(const OpTy &Op) {
return CastOperator_match<OpTy, Instruction::Trunc>(Op);
}

template <typename OpTy>
inline match_combine_or<CastClass_match<OpTy, Instruction::Trunc>, OpTy>
inline match_combine_or<CastOperator_match<OpTy, Instruction::Trunc>, OpTy>
m_TruncOrSelf(const OpTy &Op) {
return m_CombineOr(m_Trunc(Op), Op);
}

/// Matches SExt.
template <typename OpTy>
inline CastClass_match<OpTy, Instruction::SExt> m_SExt(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::SExt>(Op);
inline CastInst_match<OpTy, Instruction::SExt> m_SExt(const OpTy &Op) {
return CastInst_match<OpTy, Instruction::SExt>(Op);
}

/// Matches ZExt.
template <typename OpTy>
inline CastClass_match<OpTy, Instruction::ZExt> m_ZExt(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::ZExt>(Op);
inline CastInst_match<OpTy, Instruction::ZExt> m_ZExt(const OpTy &Op) {
return CastInst_match<OpTy, Instruction::ZExt>(Op);
}

template <typename OpTy>
inline match_combine_or<CastClass_match<OpTy, Instruction::ZExt>, OpTy>
inline match_combine_or<CastInst_match<OpTy, Instruction::ZExt>, OpTy>
m_ZExtOrSelf(const OpTy &Op) {
return m_CombineOr(m_ZExt(Op), Op);
}

template <typename OpTy>
inline match_combine_or<CastClass_match<OpTy, Instruction::SExt>, OpTy>
inline match_combine_or<CastInst_match<OpTy, Instruction::SExt>, OpTy>
m_SExtOrSelf(const OpTy &Op) {
return m_CombineOr(m_SExt(Op), Op);
}

template <typename OpTy>
inline match_combine_or<CastClass_match<OpTy, Instruction::ZExt>,
CastClass_match<OpTy, Instruction::SExt>>
inline match_combine_or<CastInst_match<OpTy, Instruction::ZExt>,
CastInst_match<OpTy, Instruction::SExt>>
m_ZExtOrSExt(const OpTy &Op) {
return m_CombineOr(m_ZExt(Op), m_SExt(Op));
}

template <typename OpTy>
inline match_combine_or<
match_combine_or<CastClass_match<OpTy, Instruction::ZExt>,
CastClass_match<OpTy, Instruction::SExt>>,
match_combine_or<CastInst_match<OpTy, Instruction::ZExt>,
CastInst_match<OpTy, Instruction::SExt>>,
OpTy>
m_ZExtOrSExtOrSelf(const OpTy &Op) {
return m_CombineOr(m_ZExtOrSExt(Op), Op);
}

template <typename OpTy>
inline CastClass_match<OpTy, Instruction::UIToFP> m_UIToFP(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::UIToFP>(Op);
inline CastOperator_match<OpTy, Instruction::UIToFP> m_UIToFP(const OpTy &Op) {
return CastOperator_match<OpTy, Instruction::UIToFP>(Op);
}

template <typename OpTy>
inline CastClass_match<OpTy, Instruction::SIToFP> m_SIToFP(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::SIToFP>(Op);
inline CastOperator_match<OpTy, Instruction::SIToFP> m_SIToFP(const OpTy &Op) {
return CastOperator_match<OpTy, Instruction::SIToFP>(Op);
}

template <typename OpTy>
inline CastClass_match<OpTy, Instruction::FPToUI> m_FPToUI(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::FPToUI>(Op);
inline CastOperator_match<OpTy, Instruction::FPToUI> m_FPToUI(const OpTy &Op) {
return CastOperator_match<OpTy, Instruction::FPToUI>(Op);
}

template <typename OpTy>
inline CastClass_match<OpTy, Instruction::FPToSI> m_FPToSI(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::FPToSI>(Op);
inline CastOperator_match<OpTy, Instruction::FPToSI> m_FPToSI(const OpTy &Op) {
return CastOperator_match<OpTy, Instruction::FPToSI>(Op);
}

template <typename OpTy>
inline CastClass_match<OpTy, Instruction::FPTrunc> m_FPTrunc(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::FPTrunc>(Op);
inline CastOperator_match<OpTy, Instruction::FPTrunc>
m_FPTrunc(const OpTy &Op) {
return CastOperator_match<OpTy, Instruction::FPTrunc>(Op);
}

template <typename OpTy>
inline CastClass_match<OpTy, Instruction::FPExt> m_FPExt(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::FPExt>(Op);
inline CastOperator_match<OpTy, Instruction::FPExt> m_FPExt(const OpTy &Op) {
return CastOperator_match<OpTy, Instruction::FPExt>(Op);
}

//===----------------------------------------------------------------------===//
Expand Down
4 changes: 2 additions & 2 deletions llvm/include/llvm/Support/TypeName.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ inline StringRef getTypeName() {
assert(!Name.empty() && "Unable to find the template parameter!");
Name = Name.drop_front(Key.size());

assert(Name.endswith("]") && "Name doesn't end in the substitution key!");
assert(Name.ends_with("]") && "Name doesn't end in the substitution key!");
return Name.drop_back(1);
#elif defined(_MSC_VER)
StringRef Name = __FUNCSIG__;
Expand All @@ -44,7 +44,7 @@ inline StringRef getTypeName() {
Name = Name.drop_front(Key.size());

for (StringRef Prefix : {"class ", "struct ", "union ", "enum "})
if (Name.startswith(Prefix)) {
if (Name.starts_with(Prefix)) {
Name = Name.drop_front(Prefix.size());
break;
}
Expand Down
8 changes: 4 additions & 4 deletions llvm/include/llvm/Support/YAMLTraits.h
Original file line number Diff line number Diff line change
Expand Up @@ -584,11 +584,11 @@ inline bool isNumeric(StringRef S) {
// Section 10.3.2 Tag Resolution
// YAML 1.2 Specification prohibits Base 8 and Base 16 numbers prefixed with
// [-+], so S should be used instead of Tail.
if (S.startswith("0o"))
if (S.starts_with("0o"))
return S.size() > 2 &&
S.drop_front(2).find_first_not_of("01234567") == StringRef::npos;

if (S.startswith("0x"))
if (S.starts_with("0x"))
return S.size() > 2 && S.drop_front(2).find_first_not_of(
"0123456789abcdefABCDEF") == StringRef::npos;

Expand All @@ -598,12 +598,12 @@ inline bool isNumeric(StringRef S) {
// Handle cases when the number starts with '.' and hence needs at least one
// digit after dot (as opposed by number which has digits before the dot), but
// doesn't have one.
if (S.startswith(".") &&
if (S.starts_with(".") &&
(S.equals(".") ||
(S.size() > 1 && std::strchr("0123456789", S[1]) == nullptr)))
return false;

if (S.startswith("E") || S.startswith("e"))
if (S.starts_with("E") || S.starts_with("e"))
return false;

enum ParseState {
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/TargetParser/AArch64TargetParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ enum ArchExtKind : unsigned {
AEK_SSVE_FP8DOT4 = 66, // FEAT_SSVE_FP8DOT4
AEK_LUT = 67, // FEAT_LUT
AEK_SME_LUTv2 = 68, // FEAT_SME_LUTv2
AEK_SMEF8F16 = 69, // FEAT_SME_F8F16
AEK_SMEF8F32 = 70, // FEAT_SME_F8F32
AEK_NUM_EXTENSIONS
};
using ExtensionBitset = Bitset<AEK_NUM_EXTENSIONS>;
Expand Down Expand Up @@ -289,6 +291,8 @@ inline constexpr ExtensionInfo Extensions[] = {
{"ssve-fp8dot4", AArch64::AEK_SSVE_FP8DOT4, "+ssve-fp8dot4", "-ssve-fp8dot4", FEAT_INIT, "+sme2", 0},
{"lut", AArch64::AEK_LUT, "+lut", "-lut", FEAT_INIT, "", 0},
{"sme-lutv2", AArch64::AEK_SME_LUTv2, "+sme-lutv2", "-sme-lutv2", FEAT_INIT, "", 0},
{"sme-f8f16", AArch64::AEK_SMEF8F16, "+sme-f8f16", "-sme-f8f16", FEAT_INIT, "+sme2,+fp8", 0},
{"sme-f8f32", AArch64::AEK_SMEF8F32, "+sme-f8f32", "-sme-f8f32", FEAT_INIT, "+sme2,+fp8", 0},
// Special cases
{"none", AArch64::AEK_NONE, {}, {}, FEAT_INIT, "", ExtensionInfo::MaxFMVPriority},
};
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Analysis/ScalarEvolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13437,9 +13437,8 @@ static void PrintLoopInfo(raw_ostream &OS, ScalarEvolution *SE,
for (const auto *P : Preds)
P->print(OS, 4);
} else {
OS << "Unpredictable predicated backedge-taken count. ";
OS << "Unpredictable predicated backedge-taken count.\n";
}
OS << "\n";

if (SE->hasLoopInvariantBackedgeTakenCount(L)) {
OS << "Loop ";
Expand Down
13 changes: 12 additions & 1 deletion llvm/lib/CodeGen/CalcSpillWeights.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,17 @@ void VirtRegAuxInfo::calculateSpillWeightAndHint(LiveInterval &LI) {
LI.setWeight(Weight);
}

static bool canMemFoldInlineAsm(LiveInterval &LI,
const MachineRegisterInfo &MRI) {
for (const MachineOperand &MO : MRI.reg_operands(LI.reg())) {
const MachineInstr *MI = MO.getParent();
if (MI->isInlineAsm() && MI->mayFoldInlineAsmRegOp(MI->getOperandNo(&MO)))
return true;
}

return false;
}

float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
SlotIndex *End) {
MachineRegisterInfo &MRI = MF.getRegInfo();
Expand Down Expand Up @@ -315,7 +326,7 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
// into instruction itself makes perfect sense.
if (ShouldUpdateLI && LI.isZeroLength(LIS.getSlotIndexes()) &&
!LI.isLiveAtIndexes(LIS.getRegMaskSlots()) &&
!isLiveAtStatepointVarArg(LI)) {
!isLiveAtStatepointVarArg(LI) && !canMemFoldInlineAsm(LI, MRI)) {
LI.markNotSpillable();
return -1.0;
}
Expand Down
23 changes: 23 additions & 0 deletions llvm/lib/CodeGen/MachineInstr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1792,6 +1792,12 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
if (F.isUseOperandTiedToDef(TiedTo))
OS << " tiedto:$" << TiedTo;

if ((F.isRegDefKind() || F.isRegDefEarlyClobberKind() ||
F.isRegUseKind()) &&
F.getRegMayBeFolded()) {
OS << " foldable";
}

OS << ']';

// Compute the index of the next operand descriptor.
Expand Down Expand Up @@ -2526,3 +2532,20 @@ void MachineInstr::insert(mop_iterator InsertBefore,
tieOperands(Tie1, Tie2);
}
}

bool MachineInstr::mayFoldInlineAsmRegOp(unsigned OpId) const {
assert(OpId && "expected non-zero operand id");
assert(isInlineAsm() && "should only be used on inline asm");

if (!getOperand(OpId).isReg())
return false;

const MachineOperand &MD = getOperand(OpId - 1);
if (!MD.isImm())
return false;

InlineAsm::Flag F(MD.getImm());
if (F.isRegUseKind() || F.isRegDefKind() || F.isRegDefEarlyClobberKind())
return F.getRegMayBeFolded();
return false;
}
7 changes: 5 additions & 2 deletions llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13484,8 +13484,11 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
// fold (sext x) -> (zext x) if the sign bit is known zero.
if (!TLI.isSExtCheaperThanZExt(N0.getValueType(), VT) &&
(!LegalOperations || TLI.isOperationLegal(ISD::ZERO_EXTEND, VT)) &&
DAG.SignBitIsZero(N0))
return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, N0);
DAG.SignBitIsZero(N0)) {
SDNodeFlags Flags;
Flags.setNonNeg(true);
return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, N0, Flags);
}

if (SDValue NewVSel = matchVSelectOpSizesWithSetCC(N))
return NewVSel;
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5027,7 +5027,6 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
case ISD::BITREVERSE:
case ISD::PARITY:
case ISD::SIGN_EXTEND:
case ISD::ZERO_EXTEND:
case ISD::TRUNCATE:
case ISD::SIGN_EXTEND_INREG:
case ISD::SIGN_EXTEND_VECTOR_INREG:
Expand All @@ -5037,6 +5036,10 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
case ISD::BUILD_PAIR:
return false;

// Matches hasPoisonGeneratingFlags().
case ISD::ZERO_EXTEND:
return ConsiderFlags && Op->getFlags().hasNonNeg();

case ISD::ADD:
case ISD::SUB:
case ISD::MUL:
Expand Down
16 changes: 9 additions & 7 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3527,18 +3527,20 @@ void SelectionDAGBuilder::visitZExt(const User &I) {
auto &TLI = DAG.getTargetLoweringInfo();
EVT DestVT = TLI.getValueType(DAG.getDataLayout(), I.getType());

// Since we don't yet have a representation of zext nneg in SDAG or MI,
// eagerly use the information to canonicalize towards sign_extend if
// that is the target's preference. TODO: Add nneg support to the
// SDAG and MI representations.
if (auto *PNI = dyn_cast<PossiblyNonNegInst>(&I);
PNI && PNI->hasNonNeg() &&
SDNodeFlags Flags;
if (auto *PNI = dyn_cast<PossiblyNonNegInst>(&I))
Flags.setNonNeg(PNI->hasNonNeg());

// Eagerly use nonneg information to canonicalize towards sign_extend if
// that is the target's preference.
// TODO: Let the target do this later.
if (Flags.hasNonNeg() &&
TLI.isSExtCheaperThanZExt(N.getValueType(), DestVT)) {
setValue(&I, DAG.getNode(ISD::SIGN_EXTEND, getCurSDLoc(), DestVT, N));
return;
}

setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, getCurSDLoc(), DestVT, N));
setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, getCurSDLoc(), DestVT, N, Flags));
}

void SelectionDAGBuilder::visitSExt(const User &I) {
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,9 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
if (getFlags().hasExact())
OS << " exact";

if (getFlags().hasNonNeg())
OS << " nneg";

if (getFlags().hasNoNaNs())
OS << " nnan";

Expand Down
8 changes: 7 additions & 1 deletion llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2402,11 +2402,17 @@ bool TargetLowering::SimplifyDemandedBits(
return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, dl, VT, Src));
}

SDNodeFlags Flags = Op->getFlags();
APInt InDemandedBits = DemandedBits.trunc(InBits);
APInt InDemandedElts = DemandedElts.zext(InElts);
if (SimplifyDemandedBits(Src, InDemandedBits, InDemandedElts, Known, TLO,
Depth + 1))
Depth + 1)) {
if (Flags.hasNonNeg()) {
Flags.setNonNeg(false);
Op->setFlags(Flags);
}
return true;
}
assert(!Known.hasConflict() && "Bits known to be one AND zero?");
assert(Known.getBitWidth() == InBits && "Src width has changed?");
Known = Known.zext(BitWidth);
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/CodeGen/TargetInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1639,6 +1639,10 @@ std::string TargetInstrInfo::createMIROperandComment(
if (F.isUseOperandTiedToDef(TiedTo))
OS << " tiedto:$" << TiedTo;

if ((F.isRegDefKind() || F.isRegDefEarlyClobberKind() || F.isRegUseKind()) &&
F.getRegMayBeFolded())
OS << " foldable";

return OS.str();
}

Expand Down
19 changes: 19 additions & 0 deletions llvm/lib/DWARFLinker/DWARFLinker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,20 @@ static void resolveRelativeObjectPath(SmallVectorImpl<char> &Buf, DWARFDie CU) {
sys::path::append(Buf, dwarf::toString(CU.find(dwarf::DW_AT_comp_dir), ""));
}

/// Make a best effort to guess the
/// Xcode.app/Contents/Developer/Toolchains/ path from an SDK path.
static SmallString<128> guessToolchainBaseDir(StringRef SysRoot) {
SmallString<128> Result;
// Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
StringRef Base = sys::path::parent_path(SysRoot);
if (sys::path::filename(Base) != "SDKs")
return Result;
Base = sys::path::parent_path(Base);
Result = Base;
sys::path::append(Result, "Toolchains");
return Result;
}

/// Collect references to parseable Swift interfaces in imported
/// DW_TAG_module blocks.
static void analyzeImportedModule(
Expand All @@ -198,6 +212,11 @@ static void analyzeImportedModule(
SysRoot = CU.getSysRoot();
if (!SysRoot.empty() && Path.startswith(SysRoot))
return;
// Don't track interfaces that are part of the toolchain.
// For example: Swift, _Concurrency, ...
SmallString<128> Toolchain = guessToolchainBaseDir(SysRoot);
if (!Toolchain.empty() && Path.startswith(Toolchain))
return;
std::optional<const char *> Name =
dwarf::toString(DIE.find(dwarf::DW_AT_name));
if (!Name)
Expand Down
19 changes: 19 additions & 0 deletions llvm/lib/DWARFLinkerParallel/DWARFLinkerCompileUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,20 @@ void CompileUnit::cleanupDataAfterClonning() {
getOrigUnit().clear();
}

/// Make a best effort to guess the
/// Xcode.app/Contents/Developer/Toolchains/ path from an SDK path.
static SmallString<128> guessToolchainBaseDir(StringRef SysRoot) {
SmallString<128> Result;
// Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
StringRef Base = sys::path::parent_path(SysRoot);
if (sys::path::filename(Base) != "SDKs")
return Result;
Base = sys::path::parent_path(Base);
Result = Base;
sys::path::append(Result, "Toolchains");
return Result;
}

/// Collect references to parseable Swift interfaces in imported
/// DW_TAG_module blocks.
void CompileUnit::analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry) {
Expand All @@ -187,6 +201,11 @@ void CompileUnit::analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry) {
SysRoot = getSysRoot();
if (!SysRoot.empty() && Path.startswith(SysRoot))
return;
// Don't track interfaces that are part of the toolchain.
// For example: Swift, _Concurrency, ...
SmallString<128> Toolchain = guessToolchainBaseDir(SysRoot);
if (!Toolchain.empty() && Path.startswith(Toolchain))
return;
if (std::optional<DWARFFormValue> Val = find(DieEntry, dwarf::DW_AT_name)) {
Expected<const char *> Name = Val->getAsCString();
if (!Name) {
Expand Down
111 changes: 107 additions & 4 deletions llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,33 @@ static StringRef ObjCRuntimeObjectSectionName =
static StringRef ObjCImageInfoSymbolName =
"__llvm_jitlink_macho_objc_imageinfo";

struct ObjCImageInfoFlags {
uint16_t SwiftABIVersion;
uint16_t SwiftVersion;
bool HasCategoryClassProperties;
bool HasSignedObjCClassROs;

static constexpr uint32_t SIGNED_CLASS_RO = (1 << 4);
static constexpr uint32_t HAS_CATEGORY_CLASS_PROPERTIES = (1 << 6);

explicit ObjCImageInfoFlags(uint32_t RawFlags) {
HasSignedObjCClassROs = RawFlags & SIGNED_CLASS_RO;
HasCategoryClassProperties = RawFlags & HAS_CATEGORY_CLASS_PROPERTIES;
SwiftABIVersion = (RawFlags >> 8) & 0xFF;
SwiftVersion = (RawFlags >> 16) & 0xFFFF;
}

uint32_t rawFlags() const {
uint32_t Result = 0;
if (HasCategoryClassProperties)
Result |= HAS_CATEGORY_CLASS_PROPERTIES;
if (HasSignedObjCClassROs)
Result |= SIGNED_CLASS_RO;
Result |= (SwiftABIVersion << 8);
Result |= (SwiftVersion << 16);
return Result;
}
};
} // end anonymous namespace

namespace llvm {
Expand Down Expand Up @@ -1029,15 +1056,19 @@ Error MachOPlatform::MachOPlatformPlugin::processObjCImageInfo(
" does not match first registered version",
inconvertibleErrorCode());
if (ObjCImageInfoItr->second.Flags != Flags)
return make_error<StringError>("ObjC flags in " + G.getName() +
" do not match first registered flags",
inconvertibleErrorCode());
if (Error E = mergeImageInfoFlags(G, MR, ObjCImageInfoItr->second, Flags))
return E;

// __objc_imageinfo is valid. Delete the block.
for (auto *S : ObjCImageInfo->symbols())
G.removeDefinedSymbol(*S);
G.removeBlock(ObjCImageInfoBlock);
} else {
LLVM_DEBUG({
dbgs() << "MachOPlatform: Registered __objc_imageinfo for "
<< MR.getTargetJITDylib().getName() << " in " << G.getName()
<< "; flags = " << formatv("{0:x4}", Flags) << "\n";
});
// We haven't registered an __objc_imageinfo section yet. Register and
// move on. The section should already be marked no-dead-strip.
G.addDefinedSymbol(ObjCImageInfoBlock, 0, ObjCImageInfoSymbolName,
Expand All @@ -1047,12 +1078,66 @@ Error MachOPlatform::MachOPlatformPlugin::processObjCImageInfo(
{{MR.getExecutionSession().intern(ObjCImageInfoSymbolName),
JITSymbolFlags()}}))
return Err;
ObjCImageInfos[&MR.getTargetJITDylib()] = {Version, Flags};
ObjCImageInfos[&MR.getTargetJITDylib()] = {Version, Flags, false};
}

return Error::success();
}

Error MachOPlatform::MachOPlatformPlugin::mergeImageInfoFlags(
jitlink::LinkGraph &G, MaterializationResponsibility &MR,
ObjCImageInfo &Info, uint32_t NewFlags) {
if (Info.Flags == NewFlags)
return Error::success();

ObjCImageInfoFlags Old(Info.Flags);
ObjCImageInfoFlags New(NewFlags);

// Check for incompatible flags.
if (Old.SwiftABIVersion && New.SwiftABIVersion &&
Old.SwiftABIVersion != New.SwiftABIVersion)
return make_error<StringError>("Swift ABI version in " + G.getName() +
" does not match first registered flags",
inconvertibleErrorCode());

if (Old.HasCategoryClassProperties != New.HasCategoryClassProperties)
return make_error<StringError>("ObjC category class property support in " +
G.getName() +
" does not match first registered flags",
inconvertibleErrorCode());
if (Old.HasSignedObjCClassROs != New.HasSignedObjCClassROs)
return make_error<StringError>("ObjC class_ro_t pointer signing in " +
G.getName() +
" does not match first registered flags",
inconvertibleErrorCode());

// If we cannot change the flags, ignore any remaining differences. Adding
// Swift or changing its version are unlikely to cause problems in practice.
if (Info.Finalized)
return Error::success();

// Use the minimum Swift version.
if (Old.SwiftVersion && New.SwiftVersion)
New.SwiftVersion = std::min(Old.SwiftVersion, New.SwiftVersion);
else if (Old.SwiftVersion)
New.SwiftVersion = Old.SwiftVersion;
// Add a Swift ABI version if it was pure objc before.
if (!New.SwiftABIVersion)
New.SwiftABIVersion = Old.SwiftABIVersion;

LLVM_DEBUG({
dbgs() << "MachOPlatform: Merging __objc_imageinfo flags for "
<< MR.getTargetJITDylib().getName() << " (was "
<< formatv("{0:x4}", Old.rawFlags()) << ")"
<< " with " << G.getName() << " (" << formatv("{0:x4}", NewFlags)
<< ")"
<< " -> " << formatv("{0:x4}", New.rawFlags()) << "\n";
});

Info.Flags = New.rawFlags();
return Error::success();
}

Error MachOPlatform::MachOPlatformPlugin::fixTLVSectionsAndEdges(
jitlink::LinkGraph &G, JITDylib &JD) {

Expand Down Expand Up @@ -1403,6 +1488,24 @@ Error MachOPlatform::MachOPlatformPlugin::populateObjCRuntimeObject(
for (auto *Sym : G.defined_symbols())
if (Sym->hasName() && Sym->getName() == ObjCImageInfoSymbolName) {
ObjCImageInfoSym = Sym;
std::optional<uint32_t> Flags;
{
std::lock_guard<std::mutex> Lock(PluginMutex);
auto It = ObjCImageInfos.find(&MR.getTargetJITDylib());
if (It != ObjCImageInfos.end()) {
It->second.Finalized = true;
Flags = It->second.Flags;
}
}

if (Flags) {
// We own the definition of __objc_image_info; write the final
// merged flags value.
auto Content = Sym->getBlock().getMutableContent(G);
assert(Content.size() == 8 &&
"__objc_image_info size should have been verified already");
support::endian::write32(&Content[4], *Flags, G.getEndianness());
}
break;
}
if (!ObjCImageInfoSym)
Expand Down
Loading