191 changes: 173 additions & 18 deletions clang/test/OpenMP/loop_bind_messages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#define NNN 50
int aaa[NNN];
int aaa2[NNN][NNN];

void parallel_loop() {
#pragma omp parallel
Expand All @@ -13,10 +14,82 @@ void parallel_loop() {
aaa[j] = j*NNN;
}
}

#pragma omp parallel for
for (int i = 0 ; i < NNN ; i++) {
#pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
for (int j = 0 ; j < NNN ; j++) {
aaa2[i][j] = i+j;
}
}

#pragma omp parallel
#pragma omp for nowait
for (int i = 0 ; i < NNN ; i++) {
#pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
for (int j = 0 ; j < NNN ; j++) {
aaa2[i][j] = i+j;
}
}

#pragma omp parallel for
for (int i = 0 ; i < NNN ; i++) {
#pragma omp nothing
#pragma omp loop
for (int j = 0 ; j < NNN ; j++) {
aaa2[i][j] = i+j;
}
}

#pragma omp target teams distribute parallel for
for (int i = 0 ; i < NNN ; i++) {
#pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
for (int j = 0 ; j < NNN ; j++) {
aaa2[i][j] = i+j;
}
}

#pragma omp target parallel
for (int i = 0 ; i < NNN ; i++) {
#pragma omp loop bind(parallel)
for (int j = 0 ; j < NNN ; j++) {
aaa2[i][j] = i+j;
}
}

#pragma omp parallel for
for (int i = 0; i < 100; ++i) {
#pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
for (int i = 0 ; i < NNN ; i++) {
#pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'loop' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
for (int j = 0 ; j < NNN ; j++) {
aaa[j] = j*NNN;
}
}
}

#pragma omp parallel
{
#pragma omp sections
{
for (int i = 0 ; i < NNN ; i++) {
#pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
for (int j = 0 ; j < NNN ; j++) {
aaa2[i][j] = i+j;
}
}

#pragma omp section
{
aaa[NNN-1] = NNN;
}
}
}
}

void teams_loop() {
int var1, var2;
int var1;
int total = 0;

#pragma omp teams
{
Expand All @@ -32,24 +105,22 @@ void teams_loop() {
}
}
}
}

void orphan_loop_with_bind() {
#pragma omp loop bind(parallel)
for (int j = 0 ; j < NNN ; j++) {
aaa[j] = j*NNN;
#pragma omp target teams
for (int i = 0 ; i < NNN ; i++) {
#pragma omp loop bind(teams)
for (int j = 0 ; j < NNN ; j++) {
aaa2[i][j] = i+j;
}
}
}

void orphan_loop_no_bind() {
#pragma omp loop // expected-error{{expected 'bind' clause for 'loop' construct without an enclosing OpenMP construct}}
for (int j = 0 ; j < NNN ; j++) {
aaa[j] = j*NNN;
#pragma omp target teams distribute parallel for
for (int i = 0 ; i < NNN ; i++) {
#pragma omp loop bind(teams) // expected-error{{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp loop' directive into a teams region?}}
for (int j = 0 ; j < NNN ; j++) {
aaa2[i][j] = i+j;
}
}
}

void teams_loop_reduction() {
int total = 0;

#pragma omp teams
{
Expand All @@ -63,14 +134,98 @@ void teams_loop_reduction() {
total+=aaa[j];
}
}

#pragma omp teams num_teams(8) thread_limit(256)
#pragma omp distribute parallel for dist_schedule(static, 1024) \
schedule(static, 64)
for (int i = 0; i < NNN; i++) {
#pragma omp loop bind(teams) // expected-error{{'distribute parallel for' region; perhaps you forget to enclose 'omp loop' directive into a teams region?}}
for (int j = 0; j < NNN; j++) {
aaa2[i][j] = i+j;
}
}

#pragma omp teams
for (int i = 0; i < NNN; i++) {
#pragma omp loop bind(thread)
for (int j = 0 ; j < NNN ; j++) {
aaa[i] = i+i*NNN;
}
}

#pragma omp teams loop
for (int i = 0; i < NNN; i++) {
#pragma omp loop
for (int j = 0 ; j < NNN ; j++) {
aaa[i] = i+i*NNN;
}
}

#pragma omp teams loop
for (int i = 0; i < NNN; i++) {
#pragma omp loop bind(teams) // expected-error{{region cannot be closely nested inside 'teams loop' region; perhaps you forget to enclose 'omp loop' directive into a teams region?}}
for (int j = 0 ; j < NNN ; j++) {
aaa[i] = i+i*NNN;
}
}
}

void thread_loop() {
#pragma omp parallel
for (int i = 0; i < NNN; i++) {
#pragma omp loop bind(thread)
for (int j = 0 ; j < NNN ; j++) {
aaa[i] = i+i*NNN;
}
}

#pragma omp teams
for (int i = 0; i < NNN; i++) {
#pragma omp loop bind(thread)
for (int j = 0 ; j < NNN ; j++) {
aaa[i] = i+i*NNN;
}
}
}

void parallel_for_with_loop_teams_bind(){
#pragma omp parallel for
for (int i = 0; i < NNN; i++) {
#pragma omp loop bind(teams) // expected-error{{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp loop' directive into a teams region?}}
for (int j = 0 ; j < NNN ; j++) {
aaa[i] = i+i*NNN;
}
}
}

void orphan_loops() {
#pragma omp loop // expected-error{{expected 'bind' clause for 'loop' construct without an enclosing OpenMP construct}}
for (int j = 0 ; j < NNN ; j++) {
aaa[j] = j*NNN;
}

#pragma omp loop bind(parallel)
for (int j = 0 ; j < NNN ; j++) {
aaa[j] = j*NNN;
}

#pragma omp loop bind(teams)
for (int i = 0; i < NNN; i++) {
aaa[i] = i+i*NNN;
}

#pragma omp loop bind(thread)
for (int i = 0; i < NNN; i++) {
aaa[i] = i+i*NNN;
}
}

int main(int argc, char *argv[]) {
parallel_loop();
teams_loop();
orphan_loop_with_bind();
orphan_loop_no_bind();
teams_loop_reduction();
thread_loop();
parallel_for_with_loop_teams_bind();
orphan_loops();
}

#endif
8 changes: 6 additions & 2 deletions clang/test/PCH/pragma-loop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,13 @@ class pragma_test {

inline void run10(int *List, int Length) {
int i = 0;
#pragma omp loop bind(teams)
int j = 0;
#pragma omp teams
for (int i = 0; i < Length; i++) {
List[i] = i;
#pragma omp loop bind(teams)
for (int j = 0; j < Length; j++) {
List[i] = i+j;
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion clang/tools/clang-shlib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ add_clang_library(clang-cpp
${_DEPS})
# Optimize function calls for default visibility definitions to avoid PLT and
# reduce dynamic relocations.
if (NOT APPLE AND NOT MINGW)
if (NOT APPLE AND NOT MINGW AND NOT LLVM_LINKER_IS_SOLARISLD_ILLUMOS)
target_link_options(clang-cpp PRIVATE LINKER:-Bsymbolic-functions)
endif()
if (MINGW OR CYGWIN)
Expand Down
19 changes: 15 additions & 4 deletions clang/tools/libclang/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,22 @@ if(ENABLE_SHARED)
endif()
endif()
if (USE_VERSION_SCRIPT)
target_link_options(libclang PRIVATE "-Wl,--version-script,${CMAKE_CURRENT_SOURCE_DIR}/libclang.map")
# The Solaris 11.4 linker supports a subset of GNU ld version scripts,
# but requires a special option to enable it.
if (${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
target_link_options(libclang PRIVATE "-Wl,-z,gnu-version-script-compat")
include(CheckLinkerFlag)
# The Solaris 11.4 linker supports a subset of GNU ld version scripts,
# but requires a special option to enable it.
llvm_check_linker_flag(CXX "-Wl,-z,gnu-version-script-compat"
LINKER_SUPPORTS_Z_GNU_VERSION_SCRIPT_COMPAT)
# Older Solaris (and illumos) linker does not support GNU ld version scripts
# and does not support GNU version script compat.
if (LINKER_SUPPORTS_Z_GNU_VERSION_SCRIPT_COMPAT)
target_link_options(libclang PRIVATE "-Wl,--version-script,${CMAKE_CURRENT_SOURCE_DIR}/libclang.map")
target_link_options(libclang PRIVATE "-Wl,-z,gnu-version-script-compat")
else()
target_link_options(libclang PRIVATE "-Wl,-M,${CMAKE_CURRENT_SOURCE_DIR}/libclang.map")
endif()
else()
target_link_options(libclang PRIVATE "-Wl,--version-script,${CMAKE_CURRENT_SOURCE_DIR}/libclang.map")
endif()
# Ensure that libclang.so gets rebuilt when the linker script changes.
set_property(SOURCE ARCMigrate.cpp APPEND PROPERTY
Expand Down
42 changes: 42 additions & 0 deletions lld/ELF/Arch/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class RISCV final : public TargetInfo {
const uint8_t *loc) const override;
void relocate(uint8_t *loc, const Relocation &rel,
uint64_t val) const override;
void relocateAlloc(InputSectionBase &sec, uint8_t *buf) const override;
bool relaxOnce(int pass) const override;
};

Expand Down Expand Up @@ -307,6 +308,7 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
case R_RISCV_RELAX:
return config->relax ? R_RELAX_HINT : R_NONE;
case R_RISCV_SET_ULEB128:
case R_RISCV_SUB_ULEB128:
return R_RISCV_LEB128;
default:
error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
Expand Down Expand Up @@ -515,6 +517,46 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
}
}

void RISCV::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
uint64_t secAddr = sec.getOutputSection()->addr;
if (auto *s = dyn_cast<InputSection>(&sec))
secAddr += s->outSecOff;
else if (auto *ehIn = dyn_cast<EhInputSection>(&sec))
secAddr += ehIn->getParent()->outSecOff;
for (size_t i = 0, size = sec.relocs().size(); i != size; ++i) {
const Relocation &rel = sec.relocs()[i];
uint8_t *loc = buf + rel.offset;
const uint64_t val =
sec.getRelocTargetVA(sec.file, rel.type, rel.addend,
secAddr + rel.offset, *rel.sym, rel.expr);

switch (rel.expr) {
case R_RELAX_HINT:
break;
case R_RISCV_LEB128:
if (i + 1 < size) {
const Relocation &rel1 = sec.relocs()[i + 1];
if (rel.type == R_RISCV_SET_ULEB128 &&
rel1.type == R_RISCV_SUB_ULEB128 && rel.offset == rel1.offset) {
auto val = rel.sym->getVA(rel.addend) - rel1.sym->getVA(rel1.addend);
if (overwriteULEB128(loc, val) >= 0x80)
errorOrWarn(sec.getLocation(rel.offset) + ": ULEB128 value " +
Twine(val) + " exceeds available space; references '" +
lld::toString(*rel.sym) + "'");
++i;
continue;
}
}
errorOrWarn(sec.getLocation(rel.offset) +
": R_RISCV_SET_ULEB128 not paired with R_RISCV_SUB_SET128");
return;
default:
relocate(loc, rel, val);
break;
}
}
}

namespace {
struct SymbolAnchor {
uint64_t offset;
Expand Down
11 changes: 1 addition & 10 deletions lld/ELF/InputSection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type,
case R_RELAX_TLS_LD_TO_LE_ABS:
case R_RELAX_GOT_PC_NOPIC:
case R_RISCV_ADD:
case R_RISCV_LEB128:
return sym.getVA(a);
case R_ADDEND:
return a;
Expand Down Expand Up @@ -875,16 +876,6 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type,
}
}

// Overwrite a ULEB128 value and keep the original length.
static uint64_t overwriteULEB128(uint8_t *bufLoc, uint64_t val) {
while (*bufLoc & 0x80) {
*bufLoc++ = 0x80 | (val & 0x7f);
val >>= 7;
}
*bufLoc = val;
return val;
}

// This function applies relocations to sections without SHF_ALLOC bit.
// Such sections are never mapped to memory at runtime. Debug sections are
// an example. Relocations in non-alloc sections are much easier to
Expand Down
4 changes: 4 additions & 0 deletions lld/ELF/LinkerScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ static StringRef getOutputSectionName(const InputSectionBase *s) {
if (auto *isec = dyn_cast<InputSection>(s)) {
if (InputSectionBase *rel = isec->getRelocatedSection()) {
OutputSection *out = rel->getOutputSection();
if (!out) {
assert(config->relocatable && (rel->flags & SHF_LINK_ORDER));
return s->name;
}
if (s->type == SHT_RELA)
return saver().save(".rela" + out->name);
return saver().save(".rel" + out->name);
Expand Down
4 changes: 2 additions & 2 deletions lld/ELF/Relocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -988,8 +988,8 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
if (!config->isPic)
return true;

// The size of a non preemptible symbol is a constant.
if (e == R_SIZE)
// Constant when referencing a non-preemptible symbol.
if (e == R_SIZE || e == R_RISCV_LEB128)
return true;

// For the target and the relocation, we want to know if they are
Expand Down
10 changes: 10 additions & 0 deletions lld/ELF/Target.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,16 @@ inline void write32(void *p, uint32_t v) {
inline void write64(void *p, uint64_t v) {
llvm::support::endian::write64(p, v, config->endianness);
}

// Overwrite a ULEB128 value and keep the original length.
inline uint64_t overwriteULEB128(uint8_t *bufLoc, uint64_t val) {
while (*bufLoc & 0x80) {
*bufLoc++ = 0x80 | (val & 0x7f);
val >>= 7;
}
*bufLoc = val;
return val;
}
} // namespace elf
} // namespace lld

Expand Down
58 changes: 58 additions & 0 deletions lld/test/ELF/linkorder-group.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# REQUIRES: x86
## Test SHF_LINK_ORDER when the linked-to section has a larger index.
# RUN: yaml2obj %s -o %t.o
# RUN: ld.lld -r %t.o -o %t.ro
# RUN: llvm-readelf -x asan_globals %t.ro | FileCheck %s

# CHECK: Hex dump of section 'asan_globals':
# CHECK-NEXT: 0x00000000 00 .

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_X86_64
SectionHeaderStringTable: .strtab
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- Name: .bss
Type: SHT_NOBITS
Flags: [ SHF_WRITE, SHF_ALLOC, SHF_GROUP ]
Size: 0x1
- Name: asan_globals
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_LINK_ORDER, SHF_GROUP ]
Link: .bss
Content: '00'
- Name: .group
Type: SHT_GROUP
Link: .symtab
Info: foo
Members:
- SectionOrType: GRP_COMDAT
- SectionOrType: .bss
- SectionOrType: asan_globals
- SectionOrType: .relaasan_globals
- Name: .relaasan_globals
Type: SHT_RELA
Flags: [ SHF_GROUP ]
Link: .symtab
Info: asan_globals
Relocations:
- Type: R_X86_64_NONE
- Type: SectionHeaderTable
Sections:
- Name: .strtab
- Name: .text
- Name: .group
- Name: asan_globals
- Name: .relaasan_globals
- Name: .bss
- Name: .symtab
Symbols:
- Name: foo
Section: .bss
Binding: STB_WEAK
80 changes: 69 additions & 11 deletions lld/test/ELF/riscv-reloc-leb128.s
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# REQUIRES: riscv
# RUN: rm -rf %t && split-file %s %t && cd %t
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax a.s -o a.o
# RUN: llvm-readobj -r -x .debug_rnglists -x .debug_loclists a.o | FileCheck %s --check-prefix=REL
# RUN: ld.lld -shared --gc-sections a.o -o a.so
# RUN: llvm-readelf -x .debug_rnglists -x .debug_loclists a.so | FileCheck %s
# RUN: llvm-readobj -r -x .gcc_except_table -x .debug_rnglists -x .debug_loclists a.o | FileCheck %s --check-prefix=REL
# RUN: ld.lld -shared --gc-sections --noinhibit-exec a.o -o a.so
# RUN: llvm-readelf -x .gcc_except_table -x .debug_rnglists -x .debug_loclists a.so | FileCheck %s

# REL: .rela.debug_rnglists {
# REL-NEXT: 0x0 R_RISCV_SET_ULEB128 w1 0x83
# REL-NEXT: 0x0 R_RISCV_SUB_ULEB128 w2 0x0
# REL-NEXT: 0x0 R_RISCV_SET_ULEB128 w1 0x82
# REL-NEXT: 0x0 R_RISCV_SUB_ULEB128 w2 0xFFFFFFFFFFFFFFFF
# REL-NEXT: 0x1 R_RISCV_SET_ULEB128 w2 0x78
# REL-NEXT: 0x1 R_RISCV_SUB_ULEB128 w1 0x0
# REL-NEXT: 0x3 R_RISCV_SET_ULEB128 w1 0x89
Expand All @@ -28,12 +28,18 @@
# REL-NEXT: 0x1 R_RISCV_SUB_ULEB128 x1 0x0
# REL-NEXT: }

# REL: Hex dump of section '.gcc_except_table':
# REL-NEXT: 0x00000000 7b800181 01808001 81800180 80800181 {
# REL-NEXT: 0x00000010 808001 .
# REL: Hex dump of section '.debug_rnglists':
# REL-NEXT: 0x00000000 7b800181 01808001 81800180 80800181 {
# REL-NEXT: 0x00000010 808001 .
# REL: Hex dump of section '.debug_loclists':
# REL-NEXT: 0x00000000 0008 .

# CHECK: Hex dump of section '.gcc_except_table':
# CHECK-NEXT: 0x[[#%x,]] 7ffc0085 01fcff00 858001fc ffff0085 .
# CHECK-NEXT: 0x[[#%x,]] 808001 .
# CHECK: Hex dump of section '.debug_rnglists':
# CHECK-NEXT: 0x00000000 7ffc0085 01fcff00 858001fc ffff0085 .
# CHECK-NEXT: 0x00000010 808001 .
Expand All @@ -50,21 +56,32 @@

# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax sub.s -o sub.o
# RUN: not ld.lld -shared sub.o 2>&1 | FileCheck %s --check-prefix=SUB
# SUB: error: sub.o:(.debug_rnglists+0x8): unknown relocation (61) against symbol w2
# SUB: error: sub.o:(.debug_rnglists+0x8): has non-ABS relocation R_RISCV_SUB_ULEB128 against symbol 'w2'

# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax unpaired1.s -o unpaired1.o
# RUN: not ld.lld -shared unpaired1.o 2>&1 | FileCheck %s --check-prefix=UNPAIRED
# RUN: not ld.lld -shared --threads=1 unpaired1.o 2>&1 | FileCheck %s --check-prefix=UNPAIRED
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax unpaired2.s -o unpaired2.o
# RUN: not ld.lld -shared unpaired2.o 2>&1 | FileCheck %s --check-prefix=UNPAIRED
# RUN: not ld.lld -shared --threads=1 unpaired2.o 2>&1 | FileCheck %s --check-prefix=UNPAIRED
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax unpaired3.s -o unpaired3.o
# RUN: not ld.lld -shared unpaired3.o 2>&1 | FileCheck %s --check-prefix=UNPAIRED
# RUN: not ld.lld -shared --threads=1 unpaired3.o 2>&1 | FileCheck %s --check-prefix=UNPAIRED
# UNPAIRED: error: {{.*}}.o:(.alloc+0x8): R_RISCV_SET_ULEB128 not paired with R_RISCV_SUB_SET128
# UNPAIRED: error: {{.*}}.o:(.debug_rnglists+0x8): R_RISCV_SET_ULEB128 not paired with R_RISCV_SUB_SET128

# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax overflow.s -o overflow.o
# RUN: not ld.lld -shared overflow.o 2>&1 | FileCheck %s --check-prefix=OVERFLOW
# RUN: not ld.lld -shared --threads=1 overflow.o 2>&1 | FileCheck %s --check-prefix=OVERFLOW
# OVERFLOW: error: overflow.o:(.alloc+0x8): ULEB128 value 128 exceeds available space; references 'w2'
# OVERFLOW: error: overflow.o:(.debug_rnglists+0x8): ULEB128 value 128 exceeds available space; references 'w2'

# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax preemptable.s -o preemptable.o
# RUN: not ld.lld -shared --threads=1 preemptable.o 2>&1 | FileCheck %s --check-prefix=PREEMPTABLE --implicit-check-not=error:
# PREEMPTABLE: error: relocation R_RISCV_SET_ULEB128 cannot be used against symbol 'w2'; recompile with -fPIC
# PREEMPTABLE: error: relocation R_RISCV_SUB_ULEB128 cannot be used against symbol 'w1'; recompile with -fPIC

#--- a.s
.cfi_startproc
.cfi_lsda 0x1b,.LLSDA0
.cfi_endproc

.section .text.w,"axR"
w1:
call foo # 4 bytes after relaxation
Expand All @@ -75,8 +92,22 @@ x1:
call foo # 4 bytes after relaxation
x2:

.section .gcc_except_table,"a"
.LLSDA0:
.reloc ., R_RISCV_SET_ULEB128, w1+130
.reloc ., R_RISCV_SUB_ULEB128, w2-1 # non-zero addend for SUB
.byte 0x7b
.uleb128 w2-w1+120 # initial value: 0x0180
.uleb128 w1-w2+137 # initial value: 0x0181
.uleb128 w2-w1+16376 # initial value: 0x018080
.uleb128 w1-w2+16393 # initial value: 0x018081
.uleb128 w2-w1+2097144 # initial value: 0x01808080
.uleb128 w1-w2+2097161 # initial value: 0x01808081

.section .debug_rnglists
.uleb128 w1-w2+131 # initial value: 0x7b
.reloc ., R_RISCV_SET_ULEB128, w1+130
.reloc ., R_RISCV_SUB_ULEB128, w2-1 # non-zero addend for SUB
.byte 0x7b
.uleb128 w2-w1+120 # initial value: 0x0180
.uleb128 w1-w2+137 # initial value: 0x0181
.uleb128 w2-w1+16376 # initial value: 0x018080
Expand All @@ -99,13 +130,22 @@ w1: call foo; w2:

#--- unpaired1.s
w1: call foo; w2:
.section .alloc,"a"
.quad 0
.reloc ., R_RISCV_SET_ULEB128, w2+120
.byte 0x7f
.section .debug_rnglists
.quad 0;
.reloc ., R_RISCV_SET_ULEB128, w2+120
.byte 0x7f

#--- unpaired2.s
w1: call foo; w2:
.section .alloc,"a"
.quad 0
.reloc ., R_RISCV_SET_ULEB128, w2+120
.reloc .+1, R_RISCV_SUB_ULEB128, w1
.byte 0x7f
.section .debug_rnglists
.quad 0
.reloc ., R_RISCV_SET_ULEB128, w2+120
Expand All @@ -114,6 +154,11 @@ w1: call foo; w2:

#--- unpaired3.s
w1: call foo; w2:
.section .alloc,"a"
.quad 0
.reloc ., R_RISCV_SET_ULEB128, w2+120
.reloc ., R_RISCV_SUB64, w1
.byte 0x7f
.section .debug_rnglists
.quad 0
.reloc ., R_RISCV_SET_ULEB128, w2+120
Expand All @@ -122,8 +167,21 @@ w1: call foo; w2:

#--- overflow.s
w1: call foo; w2:
.section .alloc,"a"
.quad 0
.reloc ., R_RISCV_SET_ULEB128, w2+124
.reloc ., R_RISCV_SUB_ULEB128, w1
.byte 0x7f
.section .debug_rnglists
.quad 0
.reloc ., R_RISCV_SET_ULEB128, w2+124
.reloc ., R_RISCV_SUB_ULEB128, w1
.byte 0x7f

#--- preemptable.s
.globl w1, w2
w1: call foo; w2:
.section .alloc,"a"
.uleb128 w2-w1
.section .debug_rnglists
.uleb128 w2-w1
6 changes: 6 additions & 0 deletions llvm/cmake/modules/AddLLVM.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,12 @@ if (NOT DEFINED LLVM_LINKER_DETECTED AND NOT WIN32)
set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
set(LLVM_LINKER_IS_GNULD YES CACHE INTERNAL "")
message(STATUS "Linker detection: GNU ld")
elseif("${stderr}" MATCHES "(illumos)" OR
"${stdout}" MATCHES "(illumos)")
set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
set(LLVM_LINKER_IS_SOLARISLD YES CACHE INTERNAL "")
set(LLVM_LINKER_IS_SOLARISLD_ILLUMOS YES CACHE INTERNAL "")
message(STATUS "Linker detection: Solaris ld (illumos)")
elseif("${stderr}" MATCHES "Solaris Link Editors" OR
"${stdout}" MATCHES "Solaris Link Editors")
set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/TargetParser/Triple.h
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,12 @@ class Triple {
/// string (separated by a '-' if the environment component is present).
StringRef getOSAndEnvironmentName() const;

/// Get the version component of the environment component as a single
/// string (the version after the environment).
///
/// For example, "fooos1.2.3" would return "1.2.3".
StringRef getEnvironmentVersionString() const;

/// @}
/// @name Convenience Predicates
/// @{
Expand Down
7 changes: 5 additions & 2 deletions llvm/lib/TargetParser/Triple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1206,11 +1206,14 @@ static VersionTuple parseVersionFromName(StringRef Name) {
}

VersionTuple Triple::getEnvironmentVersion() const {
return parseVersionFromName(getEnvironmentVersionString());
}

StringRef Triple::getEnvironmentVersionString() const {
StringRef EnvironmentName = getEnvironmentName();
StringRef EnvironmentTypeName = getEnvironmentTypeName(getEnvironment());
EnvironmentName.consume_front(EnvironmentTypeName);

return parseVersionFromName(EnvironmentName);
return EnvironmentName;
}

VersionTuple Triple::getOSVersion() const {
Expand Down
51 changes: 18 additions & 33 deletions llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,10 +330,6 @@ extern cl::opt<std::string> ViewBlockFreqFuncName;
extern cl::opt<InstrProfCorrelator::ProfCorrelatorKind> ProfileCorrelate;
} // namespace llvm

static cl::opt<bool>
PGOOldCFGHashing("pgo-instr-old-cfg-hashing", cl::init(false), cl::Hidden,
cl::desc("Use the old CFG function hashing"));

// Return a string describing the branch condition that can be
// used in static branch probability heuristics:
static std::string getBranchCondString(Instruction *TI) {
Expand Down Expand Up @@ -635,34 +631,25 @@ void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() {
JC.update(Indexes);

JamCRC JCH;
if (PGOOldCFGHashing) {
// Hash format for context sensitive profile. Reserve 4 bits for other
// information.
FunctionHash = (uint64_t)SIVisitor.getNumOfSelectInsts() << 56 |
(uint64_t)ValueSites[IPVK_IndirectCallTarget].size() << 48 |
//(uint64_t)ValueSites[IPVK_MemOPSize].size() << 40 |
(uint64_t)MST.numEdges() << 32 | JC.getCRC();
// The higher 32 bits.
auto updateJCH = [&JCH](uint64_t Num) {
uint8_t Data[8];
support::endian::write64le(Data, Num);
JCH.update(Data);
};
updateJCH((uint64_t)SIVisitor.getNumOfSelectInsts());
updateJCH((uint64_t)ValueSites[IPVK_IndirectCallTarget].size());
updateJCH((uint64_t)ValueSites[IPVK_MemOPSize].size());
if (BCI) {
updateJCH(BCI->getInstrumentedBlocksHash());
} else {
// The higher 32 bits.
auto updateJCH = [&JCH](uint64_t Num) {
uint8_t Data[8];
support::endian::write64le(Data, Num);
JCH.update(Data);
};
updateJCH((uint64_t)SIVisitor.getNumOfSelectInsts());
updateJCH((uint64_t)ValueSites[IPVK_IndirectCallTarget].size());
updateJCH((uint64_t)ValueSites[IPVK_MemOPSize].size());
if (BCI) {
updateJCH(BCI->getInstrumentedBlocksHash());
} else {
updateJCH((uint64_t)MST.numEdges());
}

// Hash format for context sensitive profile. Reserve 4 bits for other
// information.
FunctionHash = (((uint64_t)JCH.getCRC()) << 28) + JC.getCRC();
updateJCH((uint64_t)MST.numEdges());
}

// Hash format for context sensitive profile. Reserve 4 bits for other
// information.
FunctionHash = (((uint64_t)JCH.getCRC()) << 28) + JC.getCRC();

// Reserve bit 60-63 for other information purpose.
FunctionHash &= 0x0FFFFFFFFFFFFFFF;
if (IsCS)
Expand All @@ -672,10 +659,8 @@ void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() {
<< ", Selects = " << SIVisitor.getNumOfSelectInsts()
<< ", Edges = " << MST.numEdges() << ", ICSites = "
<< ValueSites[IPVK_IndirectCallTarget].size());
if (!PGOOldCFGHashing) {
LLVM_DEBUG(dbgs() << ", Memops = " << ValueSites[IPVK_MemOPSize].size()
<< ", High32 CRC = " << JCH.getCRC());
}
LLVM_DEBUG(dbgs() << ", Memops = " << ValueSites[IPVK_MemOPSize].size()
<< ", High32 CRC = " << JCH.getCRC());
LLVM_DEBUG(dbgs() << ", Hash = " << FunctionHash << "\n";);

if (PGOTraceFuncHash != "-" && F.getName().contains(PGOTraceFuncHash))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,6 @@ _Z3fooi
18
12

# For -pgo-instr-old-cfg-hashing=true
_Z3fooi
# Func Hash:
72057606922829823
# Num Counters:
2
# Counter Values:
18
6

_Z3fooi
# Func Hash:
12884901887
Expand All @@ -36,29 +26,10 @@ _Z3bari
0
0

# For -pgo-instr-old-cfg-hashing=true
_Z3bari
# Func Hash:
72057606922829823
# Num Counters:
2
# Counter Values:
0
0

_Z4m2f1v
# Func Hash:
742261418966908927
# Num Counters:
1
# Counter Values:
1

# For -pgo-instr-old-cfg-hashing=true
_Z4m2f1v
# Func Hash:
12884901887
# Num Counters:
1
# Counter Values:
1
4 changes: 0 additions & 4 deletions llvm/test/Transforms/PGOProfile/multiple_hash_profile.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
; RUN: llvm-profdata merge %S/Inputs/multiple_hash_profile.proftext -o %t.profdata
; RUN: opt < %s -passes=pgo-instr-use -pgo-test-profile-file=%t.profdata -S | FileCheck %s
; RUN: opt < %s -passes=pgo-instr-use -pgo-test-profile-file=%t.profdata -pgo-instr-old-cfg-hashing=true -S | FileCheck -check-prefix=CHECKOLDHASH %s
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

Expand Down Expand Up @@ -29,9 +28,6 @@ entry:
; CHECK: %mul.i = select i1 %cmp.i, i32 1, i32 %i
; CHECK-SAME: !prof ![[BW:[0-9]+]]
; CHECK: ![[BW]] = !{!"branch_weights", i32 12, i32 6}
; CHECKOLDHASH: %mul.i = select i1 %cmp.i, i32 1, i32 %i
; CHECKOLDHASH-SAME: !prof ![[BW:[0-9]+]]
; CHECKOLDHASH: ![[BW]] = !{!"branch_weights", i32 6, i32 12}
%retval.0.i = mul nsw i32 %mul.i, %i
ret i32 %retval.0.i
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/tools/llvm-shlib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ if(LLVM_BUILD_LLVM_DYLIB)
# Solaris ld does not accept global: *; so there is no way to version *all* global symbols
set(LIB_NAMES -Wl,--version-script,${LLVM_LIBRARY_DIR}/tools/llvm-shlib/simple_version_script.map ${LIB_NAMES})
endif()
if (NOT MINGW)
if (NOT MINGW AND NOT LLVM_LINKER_IS_SOLARISLD_ILLUMOS)
# Optimize function calls for default visibility definitions to avoid PLT and
# reduce dynamic relocations.
# Note: for -fno-pic default, the address of a function may be different from
Expand Down
2 changes: 2 additions & 0 deletions mlir/lib/Dialect/Arith/IR/ArithDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//

#include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/UB/IR/UBOps.h"
#include "mlir/IR/Builders.h"
Expand Down Expand Up @@ -44,6 +45,7 @@ void arith::ArithDialect::initialize() {
#include "mlir/Dialect/Arith/IR/ArithOpsAttributes.cpp.inc"
>();
addInterfaces<ArithInlinerInterface>();
declarePromisedInterface<ArithDialect, ConvertToLLVMPatternInterface>();
}

/// Materialize an integer or floating point constant.
Expand Down
2 changes: 2 additions & 0 deletions mlir/lib/Dialect/Complex/IR/ComplexDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//

#include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/Complex/IR/Complex.h"
#include "mlir/IR/Builders.h"
Expand All @@ -26,6 +27,7 @@ void complex::ComplexDialect::initialize() {
#define GET_ATTRDEF_LIST
#include "mlir/Dialect/Complex/IR/ComplexAttributes.cpp.inc"
>();
declarePromisedInterface<ComplexDialect, ConvertToLLVMPatternInterface>();
}

Operation *complex::ComplexDialect::materializeConstant(OpBuilder &builder,
Expand Down
2 changes: 2 additions & 0 deletions mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"

#include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/IR/AffineExpr.h"
#include "mlir/IR/AffineMap.h"
Expand Down Expand Up @@ -67,6 +68,7 @@ void ControlFlowDialect::initialize() {
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.cpp.inc"
>();
addInterfaces<ControlFlowInlinerInterface>();
declarePromisedInterface<ControlFlowDialect, ConvertToLLVMPatternInterface>();
}

//===----------------------------------------------------------------------===//
Expand Down
2 changes: 2 additions & 0 deletions mlir/lib/Dialect/Func/IR/FuncOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "mlir/Dialect/Func/IR/FuncOps.h"

#include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/IRMapping.h"
Expand Down Expand Up @@ -41,6 +42,7 @@ void FuncDialect::initialize() {
#include "mlir/Dialect/Func/IR/FuncOps.cpp.inc"
>();
declarePromisedInterface<FuncDialect, DialectInlinerInterface>();
declarePromisedInterface<FuncDialect, ConvertToLLVMPatternInterface>();
}

/// Materialize a single constant operation from a given attribute value with
Expand Down
2 changes: 2 additions & 0 deletions mlir/lib/Dialect/Index/IR/IndexDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "mlir/Dialect/Index/IR/IndexDialect.h"
#include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"

using namespace mlir;
using namespace mlir::index;
Expand All @@ -18,6 +19,7 @@ using namespace mlir::index;
void IndexDialect::initialize() {
registerAttributes();
registerOperations();
declarePromisedInterface<IndexDialect, ConvertToLLVMPatternInterface>();
}

//===----------------------------------------------------------------------===//
Expand Down
2 changes: 2 additions & 0 deletions mlir/lib/Dialect/Math/IR/MathDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//

#include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
#include "mlir/Dialect/Math/IR/Math.h"
#include "mlir/Dialect/UB/IR/UBOps.h"
#include "mlir/Transforms/InliningUtils.h"
Expand Down Expand Up @@ -34,4 +35,5 @@ void mlir::math::MathDialect::initialize() {
#include "mlir/Dialect/Math/IR/MathOps.cpp.inc"
>();
addInterfaces<MathInlinerInterface>();
declarePromisedInterface<MathDialect, ConvertToLLVMPatternInterface>();
}
2 changes: 2 additions & 0 deletions mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//

#include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/MemRef/IR/MemRef.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
Expand Down Expand Up @@ -41,6 +42,7 @@ void mlir::memref::MemRefDialect::initialize() {
#include "mlir/Dialect/MemRef/IR/MemRefOps.cpp.inc"
>();
addInterfaces<MemRefInlinerInterface>();
declarePromisedInterface<MemRefDialect, ConvertToLLVMPatternInterface>();
}

/// Finds the unique dealloc operation (if one exists) for `allocValue`.
Expand Down
2 changes: 2 additions & 0 deletions mlir/lib/Dialect/UB/IR/UBOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "mlir/Dialect/UB/IR/UBOps.h"
#include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
#include "mlir/Transforms/InliningUtils.h"

#include "mlir/IR/Builders.h"
Expand Down Expand Up @@ -45,6 +46,7 @@ void UBDialect::initialize() {
#include "mlir/Dialect/UB/IR/UBOpsAttributes.cpp.inc"
>();
addInterfaces<UBInlinerInterface>();
declarePromisedInterface<UBDialect, ConvertToLLVMPatternInterface>();
}

Operation *UBDialect::materializeConstant(OpBuilder &builder, Attribute value,
Expand Down
5 changes: 1 addition & 4 deletions mlir/lib/Query/Matcher/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,7 @@ class Parser::CodeTokenizer {
}

// Consume all leading whitespace from code, except newlines
void consumeWhitespace() {
code = code.drop_while(
[](char c) { return llvm::StringRef(" \t\v\f\r").contains(c); });
}
void consumeWhitespace() { code = code.ltrim(" \t\v\f\r"); }

// Returns the current location in the source code
SourceLocation currentLocation() {
Expand Down
9 changes: 3 additions & 6 deletions mlir/lib/Query/QueryParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ namespace mlir::query {
// is found before end, return StringRef(). begin is adjusted to exclude the
// lexed region.
llvm::StringRef QueryParser::lexWord() {
line = line.drop_while([](char c) {
// Don't trim newlines.
return llvm::StringRef(" \t\v\f\r").contains(c);
});
// Don't trim newlines.
line = line.ltrim(" \t\v\f\r");

if (line.empty())
// Even though the line is empty, it contains a pointer and
Expand Down Expand Up @@ -91,8 +89,7 @@ struct QueryParser::LexOrCompleteWord {

QueryRef QueryParser::endQuery(QueryRef queryRef) {
llvm::StringRef extra = line;
llvm::StringRef extraTrimmed = extra.drop_while(
[](char c) { return llvm::StringRef(" \t\v\f\r").contains(c); });
llvm::StringRef extraTrimmed = extra.ltrim(" \t\v\f\r");

if ((!extraTrimmed.empty() && extraTrimmed[0] == '\n') ||
(extraTrimmed.size() >= 2 && extraTrimmed[0] == '\r' &&
Expand Down
2 changes: 1 addition & 1 deletion mlir/lib/TableGen/Class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ MethodBody::MethodBody(bool declOnly)
: declOnly(declOnly), stringOs(body), os(stringOs) {}

void MethodBody::writeTo(raw_indented_ostream &os) const {
auto bodyRef = StringRef(body).drop_while([](char c) { return c == '\n'; });
auto bodyRef = StringRef(body).ltrim('\n');
os << bodyRef;
if (bodyRef.empty())
return;
Expand Down
2 changes: 1 addition & 1 deletion mlir/lib/Tools/lsp-server-support/SourceMgrUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ lsp::extractSourceDocComment(llvm::SourceMgr &sourceMgr, SMLoc loc) {
break;

// Extract the document string from the comment.
commentLines.push_back(line->drop_while([](char c) { return c == '/'; }));
commentLines.push_back(line->ltrim('/'));
}

if (commentLines.empty())
Expand Down