22 changes: 22 additions & 0 deletions libc/test/src/math/smoke/atan2_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//===-- Unittests for atan2 -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/math/atan2.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"

using LlvmLibcAtan2Test = LIBC_NAMESPACE::testing::FPTest<double>;

TEST_F(LlvmLibcAtan2Test, SpecialNumbers) {
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atan2(aNaN, zero));
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atan2(1.0, aNaN));
EXPECT_FP_EQ_ALL_ROUNDING(0.0, LIBC_NAMESPACE::atan2(zero, zero));
EXPECT_FP_EQ_ALL_ROUNDING(-0.0, LIBC_NAMESPACE::atan2(-0.0, zero));
EXPECT_FP_EQ_ALL_ROUNDING(0.0, LIBC_NAMESPACE::atan2(1.0, inf));
EXPECT_FP_EQ_ALL_ROUNDING(-0.0, LIBC_NAMESPACE::atan2(-1.0, inf));
}
16 changes: 0 additions & 16 deletions libcxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -310,10 +310,6 @@ endif()
option(LIBCXX_ENABLE_PEDANTIC "Compile with pedantic enabled." OFF)
option(LIBCXX_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)

option(LIBCXX_GENERATE_COVERAGE "Enable generating code coverage." OFF)
set(LIBCXX_COVERAGE_LIBRARY "" CACHE STRING
"The Profile-rt library used to build with code coverage")

set(LIBCXX_HERMETIC_STATIC_LIBRARY_DEFAULT OFF)
if (WIN32)
set(LIBCXX_HERMETIC_STATIC_LIBRARY_DEFAULT ON)
Expand Down Expand Up @@ -376,12 +372,6 @@ if (NOT LIBCXX_ENABLE_RTTI AND LIBCXX_ENABLE_EXCEPTIONS)
" for details.")
endif()

# Ensure LLVM_USE_SANITIZER is not specified when LIBCXX_GENERATE_COVERAGE
# is ON.
if (LLVM_USE_SANITIZER AND LIBCXX_GENERATE_COVERAGE)
message(FATAL_ERROR "LLVM_USE_SANITIZER cannot be used with LIBCXX_GENERATE_COVERAGE")
endif()

if (LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
if (APPLE)
message(FATAL_ERROR "LIBCXX_ENABLE_ABI_LINKER_SCRIPT cannot be used on APPLE targets")
Expand Down Expand Up @@ -490,12 +480,6 @@ endif()
# Configure compiler.
include(config-ix)

# Configure coverage options.
if (LIBCXX_GENERATE_COVERAGE)
include(CodeCoverage)
set(CMAKE_BUILD_TYPE "COVERAGE" CACHE STRING "" FORCE)
endif()

#===============================================================================
# Setup Compiler Flags
#===============================================================================
Expand Down
50 changes: 0 additions & 50 deletions libcxx/cmake/Modules/CodeCoverage.cmake

This file was deleted.

4 changes: 4 additions & 0 deletions libcxx/cmake/caches/Generic-no-exceptions.cmake
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
set(LIBCXXABI_ENABLE_EXCEPTIONS OFF CACHE BOOL "")

# Speed up the CI
set(LIBCXX_TEST_PARAMS "enable_modules=clang" CACHE STRING "")
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
4 changes: 4 additions & 0 deletions libcxx/cmake/caches/Generic-no-experimental.cmake
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
set(LIBCXX_TEST_PARAMS "enable_experimental=False" CACHE STRING "")
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")

# Speed up the CI
set(LIBCXX_TEST_PARAMS "enable_modules=clang" CACHE STRING "")
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
4 changes: 4 additions & 0 deletions libcxx/cmake/caches/Generic-no-filesystem.cmake
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
set(LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "")

# Speed up the CI
set(LIBCXX_TEST_PARAMS "enable_modules=clang" CACHE STRING "")
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
4 changes: 4 additions & 0 deletions libcxx/cmake/caches/Generic-no-localization.cmake
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
set(LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "")

# Speed up the CI
set(LIBCXX_TEST_PARAMS "enable_modules=clang" CACHE STRING "")
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
4 changes: 4 additions & 0 deletions libcxx/cmake/caches/Generic-no-random_device.cmake
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
set(LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "")

# Speed up the CI
set(LIBCXX_TEST_PARAMS "enable_modules=clang" CACHE STRING "")
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
4 changes: 4 additions & 0 deletions libcxx/cmake/caches/Generic-no-rtti.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@ set(LIBCXX_ENABLE_RTTI OFF CACHE BOOL "")
set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
set(LIBCXXABI_ENABLE_RTTI OFF CACHE BOOL "")
set(LIBCXXABI_ENABLE_EXCEPTIONS OFF CACHE BOOL "")

# Speed up the CI
set(LIBCXX_TEST_PARAMS "enable_modules=clang" CACHE STRING "")
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
4 changes: 4 additions & 0 deletions libcxx/cmake/caches/Generic-no-threads.cmake
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
set(LIBCXX_ENABLE_THREADS OFF CACHE BOOL "")
set(LIBCXXABI_ENABLE_THREADS OFF CACHE BOOL "")
set(LIBCXX_ENABLE_MONOTONIC_CLOCK OFF CACHE BOOL "")

# Speed up the CI
set(LIBCXX_TEST_PARAMS "enable_modules=clang" CACHE STRING "")
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
4 changes: 4 additions & 0 deletions libcxx/cmake/caches/Generic-no-tzdb.cmake
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
set(LIBCXX_ENABLE_TIME_ZONE_DATABASE OFF CACHE BOOL "")

# Speed up the CI
set(LIBCXX_TEST_PARAMS "enable_modules=clang" CACHE STRING "")
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
4 changes: 4 additions & 0 deletions libcxx/cmake/caches/Generic-no-unicode.cmake
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
set(LIBCXX_ENABLE_UNICODE OFF CACHE BOOL "")

# Speed up the CI
set(LIBCXX_TEST_PARAMS "enable_modules=clang" CACHE STRING "")
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
4 changes: 4 additions & 0 deletions libcxx/cmake/caches/Generic-no-wide-characters.cmake
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
set(LIBCXX_ENABLE_WIDE_CHARACTERS OFF CACHE BOOL "")

# Speed up the CI
set(LIBCXX_TEST_PARAMS "enable_modules=clang" CACHE STRING "")
set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "")
1 change: 1 addition & 0 deletions libcxx/include/__thread/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#ifndef _LIBCPP___THREAD_THREAD_H
#define _LIBCPP___THREAD_THREAD_H

#include <__assert>
#include <__condition_variable/condition_variable.h>
#include <__config>
#include <__exception/terminate.h>
Expand Down
5 changes: 0 additions & 5 deletions libcxx/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,6 @@ if(NOT LIBCXX_INSTALL_LIBRARY)
set(exclude_from_all EXCLUDE_FROM_ALL)
endif()

if (LIBCXX_GENERATE_COVERAGE AND NOT LIBCXX_COVERAGE_LIBRARY)
find_compiler_rt_library(profile LIBCXX_COVERAGE_LIBRARY)
endif()
add_library_flags_if(LIBCXX_COVERAGE_LIBRARY "${LIBCXX_COVERAGE_LIBRARY}")

if (APPLE AND LLVM_USE_SANITIZER)
if (("${LLVM_USE_SANITIZER}" STREQUAL "Address") OR
("${LLVM_USE_SANITIZER}" STREQUAL "Address;Undefined") OR
Expand Down
18 changes: 0 additions & 18 deletions libcxx/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
include(HandleLitArguments)
add_subdirectory(tools)

# By default, libcxx and libcxxabi share a library directory.
if (NOT LIBCXX_CXX_ABI_LIBRARY_PATH)
set(LIBCXX_CXX_ABI_LIBRARY_PATH "${LIBCXX_LIBRARY_DIR}" CACHE PATH
"The path to libc++abi library.")
endif()

set(AUTO_GEN_COMMENT "## Autogenerated by libcxx configuration.\n# Do not edit!")
set(SERIALIZED_LIT_PARAMS "# Lit parameters serialized here for llvm-lit to pick them up\n")

Expand Down Expand Up @@ -49,15 +43,3 @@ add_lit_testsuite(check-cxx
"Running libcxx tests"
${CMAKE_CURRENT_BINARY_DIR}
DEPENDS cxx-test-depends)

if (LIBCXX_GENERATE_COVERAGE)
include(CodeCoverage)
set(output_dir "${CMAKE_CURRENT_BINARY_DIR}/coverage")
set(capture_dirs
"${LIBCXX_LIB_CMAKEFILES_DIR}/cxx_objects.dir/"
"${LIBCXX_LIB_CMAKEFILES_DIR}/cxx.dir/"
"${LIBCXX_LIB_CMAKEFILES_DIR}/cxx_experimental.dir/"
"${CMAKE_CURRENT_BINARY_DIR}")
set(extract_dirs "${LIBCXX_SOURCE_DIR}/include;${LIBCXX_SOURCE_DIR}/src")
setup_lcov_test_target_coverage("cxx" "${output_dir}" "${capture_dirs}" "${extract_dirs}")
endif()
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <atomic>
#include <cassert>
#include <concepts>
#include <cstddef>

template <typename T>
constexpr void check_required_alignment() {
Expand Down
10 changes: 10 additions & 0 deletions lld/ELF/Arch/LoongArch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,12 @@ RelExpr LoongArch::getRelExpr(const RelType type, const Symbol &s,
return R_TLSDESC;
case R_LARCH_TLS_DESC_CALL:
return R_TLSDESC_CALL;
case R_LARCH_TLS_LD_PCREL20_S2:
return R_TLSLD_PC;
case R_LARCH_TLS_GD_PCREL20_S2:
return R_TLSGD_PC;
case R_LARCH_TLS_DESC_PCREL20_S2:
return R_TLSDESC_PC;

// Other known relocs that are explicitly unimplemented:
//
Expand Down Expand Up @@ -557,7 +563,11 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel,
write64le(loc, val);
return;

// Relocs intended for `pcaddi`.
case R_LARCH_PCREL20_S2:
case R_LARCH_TLS_LD_PCREL20_S2:
case R_LARCH_TLS_GD_PCREL20_S2:
case R_LARCH_TLS_DESC_PCREL20_S2:
checkInt(loc, val, 22, rel);
checkAlignment(loc, val, 4, rel);
write32le(loc, setJ20(read32le(loc), val >> 2));
Expand Down
3 changes: 2 additions & 1 deletion lld/ELF/Relocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1308,7 +1308,8 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
// LoongArch does not yet implement transition from TLSDESC to LE/IE, so
// generate TLSDESC dynamic relocation for the dynamic linker to handle.
if (config->emachine == EM_LOONGARCH &&
oneof<R_LOONGARCH_TLSDESC_PAGE_PC, R_TLSDESC, R_TLSDESC_CALL>(expr)) {
oneof<R_LOONGARCH_TLSDESC_PAGE_PC, R_TLSDESC, R_TLSDESC_PC,
R_TLSDESC_CALL>(expr)) {
if (expr != R_TLSDESC_CALL) {
sym.setFlags(NEEDS_TLSDESC);
c.addReloc({expr, type, offset, addend, &sym});
Expand Down
2 changes: 0 additions & 2 deletions lld/ELF/ScriptLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,6 @@ static bool encloses(StringRef s, StringRef t) {
MemoryBufferRef ScriptLexer::getCurrentMB() {
// Find input buffer containing the current token.
assert(!mbs.empty());
if (prevTok.empty())
return mbs.back();
for (MemoryBufferRef mb : mbs)
if (encloses(mb.getBuffer(), curBuf.s))
return mb;
Expand Down
16 changes: 4 additions & 12 deletions lld/ELF/ScriptParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1116,19 +1116,11 @@ SymbolAssignment *ScriptParser::readProvideHidden(bool provide, bool hidden) {
// Replace whitespace sequence (including \n) with one single space. The output
// is used by -Map.
static void squeezeSpaces(std::string &str) {
std::string ret;
bool flag = false;
char prev = '\0';
auto it = str.begin();
for (char c : str) {
if (isSpace(c)) {
if (!flag)
*it++ = ' ';
flag = true;
} else {
*it++ = c;
flag = false;
}
}
for (char c : str)
if (!isSpace(c) || (c = ' ') != prev)
*it++ = prev = c;
str.erase(it, str.end());
}

Expand Down
2 changes: 1 addition & 1 deletion lld/test/ELF/linkerscript/map-file.test
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# RUN: FileCheck -strict-whitespace %s < %t.map

SECTIONS {
. = 0x1000;
. = 0x1000; # tabs
.foo : {
BYTE ( 0x11 )
SHORT (0x1122)
Expand Down
129 changes: 129 additions & 0 deletions lld/test/ELF/loongarch-tls-gd-pcrel20-s2.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# REQUIRES: loongarch
# RUN: rm -rf %t && split-file %s %t

# RUN: llvm-mc --filetype=obj --triple=loongarch32 %t/a.s -o %t/a.32.o
# RUN: llvm-mc --filetype=obj --triple=loongarch32 %t/bc.s -o %t/bc.32.o
# RUN: ld.lld -shared -soname=bc.so %t/bc.32.o -o %t/bc.32.so
# RUN: llvm-mc --filetype=obj --triple=loongarch32 %t/tga.s -o %t/tga.32.o
# RUN: llvm-mc --filetype=obj --triple=loongarch64 %t/a.s -o %t/a.64.o
# RUN: llvm-mc --filetype=obj --triple=loongarch64 %t/bc.s -o %t/bc.64.o
# RUN: ld.lld -shared -soname=bc.so %t/bc.64.o -o %t/bc.64.so
# RUN: llvm-mc --filetype=obj --triple=loongarch64 %t/tga.s -o %t/tga.64.o

## LA32 GD
# RUN: ld.lld -shared %t/a.32.o %t/bc.32.o -o %t/gd.32.so
# RUN: llvm-readobj -r %t/gd.32.so | FileCheck --check-prefix=GD32-REL %s
# RUN: llvm-objdump -d --no-show-raw-insn %t/gd.32.so | FileCheck --check-prefix=GD32 %s

## LA32 GD -> LE
# RUN: ld.lld %t/a.32.o %t/bc.32.o %t/tga.32.o -o %t/le.32
# RUN: llvm-readelf -r %t/le.32 | FileCheck --check-prefix=NOREL %s
# RUN: llvm-readelf -x .got %t/le.32 | FileCheck --check-prefix=LE32-GOT %s
# RUN: ld.lld -pie %t/a.32.o %t/bc.32.o %t/tga.32.o -o %t/le-pie.32
# RUN: llvm-readelf -r %t/le-pie.32 | FileCheck --check-prefix=NOREL %s
# RUN: llvm-readelf -x .got %t/le-pie.32 | FileCheck --check-prefix=LE32-GOT %s

## LA32 GD -> IE
# RUN: ld.lld %t/a.32.o %t/bc.32.so %t/tga.32.o -o %t/ie.32
# RUN: llvm-readobj -r %t/ie.32 | FileCheck --check-prefix=IE32-REL %s
# RUN: llvm-readelf -x .got %t/ie.32 | FileCheck --check-prefix=IE32-GOT %s

## LA64 GD
# RUN: ld.lld -shared %t/a.64.o %t/bc.64.o -o %t/gd.64.so
# RUN: llvm-readobj -r %t/gd.64.so | FileCheck --check-prefix=GD64-REL %s
# RUN: llvm-objdump -d --no-show-raw-insn %t/gd.64.so | FileCheck --check-prefix=GD64 %s

## LA64 GD -> LE
# RUN: ld.lld %t/a.64.o %t/bc.64.o %t/tga.64.o -o %t/le.64
# RUN: llvm-readelf -r %t/le.64 | FileCheck --check-prefix=NOREL %s
# RUN: llvm-readelf -x .got %t/le.64 | FileCheck --check-prefix=LE64-GOT %s
# RUN: ld.lld -pie %t/a.64.o %t/bc.64.o %t/tga.64.o -o %t/le-pie.64
# RUN: llvm-readelf -r %t/le-pie.64 | FileCheck --check-prefix=NOREL %s
# RUN: llvm-readelf -x .got %t/le-pie.64 | FileCheck --check-prefix=LE64-GOT %s

## LA64 GD -> IE
# RUN: ld.lld %t/a.64.o %t/bc.64.so %t/tga.64.o -o %t/ie.64
# RUN: llvm-readobj -r %t/ie.64 | FileCheck --check-prefix=IE64-REL %s
# RUN: llvm-readelf -x .got %t/ie.64 | FileCheck --check-prefix=IE64-GOT %s

# GD32-REL: .rela.dyn {
# GD32-REL-NEXT: 0x20300 R_LARCH_TLS_DTPMOD32 a 0x0
# GD32-REL-NEXT: 0x20304 R_LARCH_TLS_DTPREL32 a 0x0
# GD32-REL-NEXT: 0x20308 R_LARCH_TLS_DTPMOD32 b 0x0
# GD32-REL-NEXT: 0x2030C R_LARCH_TLS_DTPREL32 b 0x0
# GD32-REL-NEXT: }

## &DTPMOD(a) - . = 0x20300 - 0x10250 = 16428<<2
# GD32: 10250: pcaddi $a0, 16428
# GD32-NEXT: bl 44

## &DTPMOD(b) - . = 0x20308 - 0x10258 = 16428<<2
# GD32: 10258: pcaddi $a0, 16428
# GD32-NEXT: bl 36

# GD64-REL: .rela.dyn {
# GD64-REL-NEXT: 0x204C0 R_LARCH_TLS_DTPMOD64 a 0x0
# GD64-REL-NEXT: 0x204C8 R_LARCH_TLS_DTPREL64 a 0x0
# GD64-REL-NEXT: 0x204D0 R_LARCH_TLS_DTPMOD64 b 0x0
# GD64-REL-NEXT: 0x204D8 R_LARCH_TLS_DTPREL64 b 0x0
# GD64-REL-NEXT: }

## &DTPMOD(a) - . = 0x204c0 - 0x10398 = 16458<<2
# GD64: 10398: pcaddi $a0, 16458
# GD64-NEXT: bl 52

## &DTPMOD(b) - . = 0x204d0 - 0x103a4 = 16460<<2
# GD64: 103a0: pcaddi $a0, 16460
# GD64-NEXT: bl 44

# NOREL: no relocations

## .got contains pre-populated values: [a@dtpmod, a@dtprel, b@dtpmod, b@dtprel]
## a@dtprel = st_value(a) = 0x8
## b@dtprel = st_value(b) = 0xc
# LE32-GOT: section '.got':
# LE32-GOT-NEXT: 0x[[#%x,A:]] 01000000 08000000 01000000 0c000000
# LE64-GOT: section '.got':
# LE64-GOT-NEXT: 0x[[#%x,A:]] 01000000 00000000 08000000 00000000
# LE64-GOT-NEXT: 0x[[#%x,A:]] 01000000 00000000 0c000000 00000000

## a is local - relaxed to LE - its DTPMOD/DTPREL slots are link-time constants.
## b is external - DTPMOD/DTPREL dynamic relocations are required.
# IE32-REL: .rela.dyn {
# IE32-REL-NEXT: 0x30220 R_LARCH_TLS_DTPMOD32 b 0x0
# IE32-REL-NEXT: 0x30224 R_LARCH_TLS_DTPREL32 b 0x0
# IE32-REL-NEXT: }
# IE32-GOT: section '.got':
# IE32-GOT-NEXT: 0x00030218 01000000 08000000 00000000 00000000

# IE64-REL: .rela.dyn {
# IE64-REL-NEXT: 0x30380 R_LARCH_TLS_DTPMOD64 b 0x0
# IE64-REL-NEXT: 0x30388 R_LARCH_TLS_DTPREL64 b 0x0
# IE64-REL-NEXT: }
# IE64-GOT: section '.got':
# IE64-GOT-NEXT: 0x00030370 01000000 00000000 08000000 00000000
# IE64-GOT-NEXT: 0x00030380 00000000 00000000 00000000 00000000

#--- a.s
pcaddi $a0, %gd_pcrel_20(a)
bl %plt(__tls_get_addr)

pcaddi $a0, %gd_pcrel_20(b)
bl %plt(__tls_get_addr)

.section .tbss,"awT",@nobits
.globl a
.zero 8
a:
.zero 4

#--- bc.s
.section .tbss,"awT",@nobits
.globl b, c
b:
.zero 4
c:

#--- tga.s
.globl __tls_get_addr
__tls_get_addr:
82 changes: 82 additions & 0 deletions lld/test/ELF/loongarch-tls-ld-pcrel20-s2.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# REQUIRES: loongarch
# RUN: rm -rf %t && split-file %s %t

# RUN: llvm-mc --filetype=obj --triple=loongarch32 --position-independent %t/a.s -o %t/a.32.o
# RUN: llvm-mc --filetype=obj --triple=loongarch32 %t/tga.s -o %t/tga.32.o
# RUN: llvm-mc --filetype=obj --triple=loongarch64 --position-independent %t/a.s -o %t/a.64.o
# RUN: llvm-mc --filetype=obj --triple=loongarch64 %t/tga.s -o %t/tga.64.o

## LA32 LD
# RUN: ld.lld -shared %t/a.32.o -o %t/ld.32.so
# RUN: llvm-readobj -r %t/ld.32.so | FileCheck --check-prefix=LD32-REL %s
# RUN: llvm-readelf -x .got %t/ld.32.so | FileCheck --check-prefix=LD32-GOT %s
# RUN: llvm-objdump -d --no-show-raw-insn %t/ld.32.so | FileCheck --check-prefixes=LD32 %s

## LA32 LD -> LE
# RUN: ld.lld %t/a.32.o %t/tga.32.o -o %t/le.32
# RUN: llvm-readelf -r %t/le.32 | FileCheck --check-prefix=NOREL %s
# RUN: llvm-readelf -x .got %t/le.32 | FileCheck --check-prefix=LE32-GOT %s
# RUN: llvm-objdump -d --no-show-raw-insn %t/le.32 | FileCheck --check-prefixes=LE32 %s

## LA64 LD
# RUN: ld.lld -shared %t/a.64.o -o %t/ld.64.so
# RUN: llvm-readobj -r %t/ld.64.so | FileCheck --check-prefix=LD64-REL %s
# RUN: llvm-readelf -x .got %t/ld.64.so | FileCheck --check-prefix=LD64-GOT %s
# RUN: llvm-objdump -d --no-show-raw-insn %t/ld.64.so | FileCheck --check-prefixes=LD64 %s

## LA64 LD -> LE
# RUN: ld.lld %t/a.64.o %t/tga.64.o -o %t/le.64
# RUN: llvm-readelf -r %t/le.64 | FileCheck --check-prefix=NOREL %s
# RUN: llvm-readelf -x .got %t/le.64 | FileCheck --check-prefix=LE64-GOT %s
# RUN: llvm-objdump -d --no-show-raw-insn %t/le.64 | FileCheck --check-prefixes=LE64 %s

## a@dtprel = st_value(a) = 0 is a link-time constant.
# LD32-REL: .rela.dyn {
# LD32-REL-NEXT: 0x20280 R_LARCH_TLS_DTPMOD32 - 0x0
# LD32-REL-NEXT: }
# LD32-GOT: section '.got':
# LD32-GOT-NEXT: 0x00020280 00000000 00000000

# LD64-REL: .rela.dyn {
# LD64-REL-NEXT: 0x20400 R_LARCH_TLS_DTPMOD64 - 0x0
# LD64-REL-NEXT: }
# LD64-GOT: section '.got':
# LD64-GOT-NEXT: 0x00020400 00000000 00000000 00000000 00000000

## LA32: &DTPMOD(a) - . = 0x20280 - 0x101cc = 16429<<2
# LD32: 101cc: pcaddi $a0, 16429
# LD32-NEXT: bl 48

## LA64: &DTPMOD(a) - . = 0x20400 - 0x102e0 = 16456<<2
# LD64: 102e0: pcaddi $a0, 16456
# LD64-NEXT: bl 44

# NOREL: no relocations

## a is local - its DTPMOD/DTPREL slots are link-time constants.
## a@dtpmod = 1 (main module)
# LE32-GOT: section '.got':
# LE32-GOT-NEXT: 0x0003011c 01000000 00000000

# LE64-GOT: section '.got':
# LE64-GOT-NEXT: 0x000301d0 01000000 00000000 00000000 00000000

## LA32: DTPMOD(.LANCHOR0) - . = 0x3011c - 0x20114 = 16386<<2
# LE32: 20114: pcaddi $a0, 16386
# LE32-NEXT: bl 4

## LA64: DTPMOD(.LANCHOR0) - . = 0x301d0 - 0x201c8 = 16386<<2
# LE64: 201c8: pcaddi $a0, 16386
# LE64-NEXT: bl 4

#--- a.s
pcaddi $a0, %ld_pcrel_20(.LANCHOR0)
bl %plt(__tls_get_addr)

.section .tbss,"awT",@nobits
.set .LANCHOR0, . + 0
.zero 8

#--- tga.s
.globl __tls_get_addr
__tls_get_addr:
142 changes: 142 additions & 0 deletions lld/test/ELF/loongarch-tlsdesc-pcrel20-s2.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# REQUIRES: loongarch
# RUN: rm -rf %t && split-file %s %t && cd %t
# RUN: llvm-mc -filetype=obj -triple=loongarch64 a.s -o a.64.o
# RUN: llvm-mc -filetype=obj -triple=loongarch64 c.s -o c.64.o
# RUN: ld.lld -shared -soname=c.64.so c.64.o -o c.64.so
# RUN: llvm-mc -filetype=obj -triple=loongarch32 --defsym ELF32=1 a.s -o a.32.o
# RUN: llvm-mc -filetype=obj -triple=loongarch32 --defsym ELF32=1 c.s -o c.32.o
# RUN: ld.lld -shared -soname=c.32.so c.32.o -o c.32.so

# RUN: ld.lld -shared -z now a.64.o c.64.o -o a.64.so
# RUN: llvm-readobj -r -x .got a.64.so | FileCheck --check-prefix=GD64-RELA %s
# RUN: llvm-objdump --no-show-raw-insn -h -d a.64.so | FileCheck %s --check-prefix=GD64

# RUN: ld.lld -shared -z now a.64.o c.64.o -o rel.64.so -z rel
# RUN: llvm-readobj -r -x .got rel.64.so | FileCheck --check-prefix=GD64-REL %s

## FIXME: The transition frome TLSDESC to IE/LE has not yet been implemented.
## Keep the dynamic relocations and hand them over to dynamic linker.

# RUN: ld.lld -e 0 -z now a.64.o c.64.o -o a.64.le
# RUN: llvm-readobj -r -x .got a.64.le | FileCheck --check-prefix=LE64-RELA %s

# RUN: ld.lld -e 0 -z now a.64.o c.64.so -o a.64.ie
# RUN: llvm-readobj -r -x .got a.64.ie | FileCheck --check-prefix=IE64-RELA %s

## 32-bit code is mostly the same. We only test a few variants.

# RUN: ld.lld -shared -z now a.32.o c.32.o -o rel.32.so -z rel
# RUN: llvm-readobj -r -x .got rel.32.so | FileCheck --check-prefix=GD32-REL %s

# GD64-RELA: .rela.dyn {
# GD64-RELA-NEXT: 0x203F0 R_LARCH_TLS_DESC64 - 0x7FF
# GD64-RELA-NEXT: 0x203D0 R_LARCH_TLS_DESC64 a 0x0
# GD64-RELA-NEXT: 0x203E0 R_LARCH_TLS_DESC64 c 0x0
# GD64-RELA-NEXT: }
# GD64-RELA: Hex dump of section '.got':
# GD64-RELA-NEXT: 0x000203d0 00000000 00000000 00000000 00000000 .
# GD64-RELA-NEXT: 0x000203e0 00000000 00000000 00000000 00000000 .
# GD64-RELA-NEXT: 0x000203f0 00000000 00000000 00000000 00000000 .

# GD64-REL: .rel.dyn {
# GD64-REL-NEXT: 0x203D8 R_LARCH_TLS_DESC64 -
# GD64-REL-NEXT: 0x203B8 R_LARCH_TLS_DESC64 a
# GD64-REL-NEXT: 0x203C8 R_LARCH_TLS_DESC64 c
# GD64-REL-NEXT: }
# GD64-REL: Hex dump of section '.got':
# GD64-REL-NEXT: 0x000203b8 00000000 00000000 00000000 00000000 .
# GD64-REL-NEXT: 0x000203c8 00000000 00000000 00000000 00000000 .
# GD64-REL-NEXT: 0x000203d8 00000000 00000000 ff070000 00000000 .

# GD64: .got 00000030 00000000000203d0

## &.got[a]-. = 0x203d0 - 0x102e0 = 16444<<2
# GD64: 102e0: pcaddi $a0, 16444
# GD64-NEXT: ld.d $ra, $a0, 0
# GD64-NEXT: jirl $ra, $ra, 0
# GD64-NEXT: add.d $a1, $a0, $tp

## &.got[b]-. = 0x203d0+32 - 0x102f0 = 16448<<2
# GD64: 102f0: pcaddi $a0, 16448
# GD64-NEXT: ld.d $ra, $a0, 0
# GD64-NEXT: jirl $ra, $ra, 0
# GD64-NEXT: add.d $a2, $a0, $tp

## &.got[c]-. = 0x203d0+16 - 0x10300 = 16440<<2
# GD64: 10300: pcaddi $a0, 16440
# GD64-NEXT: ld.d $ra, $a0, 0
# GD64-NEXT: jirl $ra, $ra, 0
# GD64-NEXT: add.d $a3, $a0, $tp

# LE64-RELA: .rela.dyn {
# LE64-RELA-NEXT: 0x30240 R_LARCH_TLS_DESC64 - 0x8
# LE64-RELA-NEXT: 0x30250 R_LARCH_TLS_DESC64 - 0x800
# LE64-RELA-NEXT: 0x30260 R_LARCH_TLS_DESC64 - 0x7FF
# LE64-RELA-NEXT: }
# LE64-RELA: Hex dump of section '.got':
# LE64-RELA-NEXT: 0x00030240 00000000 00000000 00000000 00000000 .
# LE64-RELA-NEXT: 0x00030250 00000000 00000000 00000000 00000000 .
# LE64-RELA-NEXT: 0x00030260 00000000 00000000 00000000 00000000 .

# IE64-RELA: .rela.dyn {
# IE64-RELA-NEXT: 0x303C8 R_LARCH_TLS_DESC64 - 0x8
# IE64-RELA-NEXT: 0x303E8 R_LARCH_TLS_DESC64 - 0x7FF
# IE64-RELA-NEXT: 0x303D8 R_LARCH_TLS_DESC64 c 0x0
# IE64-RELA-NEXT: }
# IE64-RELA: Hex dump of section '.got':
# IE64-RELA-NEXT: 0x000303c8 00000000 00000000 00000000 00000000 .
# IE64-RELA-NEXT: 0x000303d8 00000000 00000000 00000000 00000000 .
# IE64-RELA-NEXT: 0x000303e8 00000000 00000000 00000000 00000000 .

# GD32-REL: .rel.dyn {
# GD32-REL-NEXT: 0x20264 R_LARCH_TLS_DESC32 -
# GD32-REL-NEXT: 0x20254 R_LARCH_TLS_DESC32 a
# GD32-REL-NEXT: 0x2025C R_LARCH_TLS_DESC32 c
# GD32-REL-NEXT: }
# GD32-REL: Hex dump of section '.got':
# GD32-REL-NEXT: 0x00020254 00000000 00000000 00000000 00000000 .
# GD32-REL-NEXT: 0x00020264 00000000 ff070000 .

#--- a.s
.macro add dst, src1, src2
.ifdef ELF32
add.w \dst, \src1, \src2
.else
add.d \dst, \src1, \src2
.endif
.endm
.macro load dst, src1, src2
.ifdef ELF32
ld.w \dst, \src1, \src2
.else
ld.d \dst, \src1, \src2
.endif
.endm

pcaddi $a0, %desc_pcrel_20(a)
load $ra, $a0, %desc_ld(a)
jirl $ra, $ra, %desc_call(a)
add $a1, $a0, $tp

pcaddi $a0, %desc_pcrel_20(b)
load $ra, $a0, %desc_ld(b)
jirl $ra, $ra, %desc_call(b)
add $a2, $a0, $tp

pcaddi $a0, %desc_pcrel_20(c)
load $ra, $a0, %desc_ld(c)
jirl $ra, $ra, %desc_call(c)
add $a3, $a0, $tp

.section .tbss,"awT",@nobits
.globl a
.zero 8
a:
.zero 2039 ## Place b at 0x7ff
b:
.zero 1

#--- c.s
.section .tbss,"awT",@nobits
.globl c
c: .zero 4
Original file line number Diff line number Diff line change
Expand Up @@ -1145,8 +1145,8 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
if (socket_pipe.CanWrite())
socket_pipe.CloseWriteFileDescriptor();
if (socket_pipe.CanRead()) {
char port_cstr[PATH_MAX] = {0};
port_cstr[0] = '\0';
// The port number may be up to "65535\0".
char port_cstr[6] = {0};
size_t num_bytes = sizeof(port_cstr);
// Read port from pipe with 10 second timeout.
error = socket_pipe.ReadWithTimeout(
Expand Down
113 changes: 57 additions & 56 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4725,67 +4725,68 @@ TypeSystemClang::GetFloatTypeSemantics(size_t byte_size) {
return llvm::APFloatBase::Bogus();
}

std::optional<uint64_t>
TypeSystemClang::GetObjCBitSize(QualType qual_type,
ExecutionContextScope *exe_scope) {
assert(qual_type->isObjCObjectOrInterfaceType());
ExecutionContext exe_ctx(exe_scope);
if (Process *process = exe_ctx.GetProcessPtr()) {
if (ObjCLanguageRuntime *objc_runtime =
ObjCLanguageRuntime::Get(*process)) {
if (std::optional<uint64_t> bit_size =
objc_runtime->GetTypeBitSize(GetType(qual_type)))
return *bit_size;
}
} else {
static bool g_printed = false;
if (!g_printed) {
StreamString s;
DumpTypeDescription(qual_type.getAsOpaquePtr(), s);

llvm::outs() << "warning: trying to determine the size of type ";
llvm::outs() << s.GetString() << "\n";
llvm::outs() << "without a valid ExecutionContext. this is not "
"reliable. please file a bug against LLDB.\n";
llvm::outs() << "backtrace:\n";
llvm::sys::PrintStackTrace(llvm::outs());
llvm::outs() << "\n";
g_printed = true;
}
}

return getASTContext().getTypeSize(qual_type) +
getASTContext().getTypeSize(getASTContext().ObjCBuiltinClassTy);
}

std::optional<uint64_t>
TypeSystemClang::GetBitSize(lldb::opaque_compiler_type_t type,
ExecutionContextScope *exe_scope) {
if (GetCompleteType(type)) {
clang::QualType qual_type(GetCanonicalQualType(type));
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
switch (type_class) {
case clang::Type::Record:
if (GetCompleteType(type))
return getASTContext().getTypeSize(qual_type);
else
return std::nullopt;
break;
if (!GetCompleteType(type))
return std::nullopt;

case clang::Type::ObjCInterface:
case clang::Type::ObjCObject: {
ExecutionContext exe_ctx(exe_scope);
Process *process = exe_ctx.GetProcessPtr();
if (process) {
if (ObjCLanguageRuntime *objc_runtime =
ObjCLanguageRuntime::Get(*process)) {
if (std::optional<uint64_t> bit_size =
objc_runtime->GetTypeBitSize(GetType(qual_type)))
return *bit_size;
}
} else {
static bool g_printed = false;
if (!g_printed) {
StreamString s;
DumpTypeDescription(type, s);

llvm::outs() << "warning: trying to determine the size of type ";
llvm::outs() << s.GetString() << "\n";
llvm::outs() << "without a valid ExecutionContext. this is not "
"reliable. please file a bug against LLDB.\n";
llvm::outs() << "backtrace:\n";
llvm::sys::PrintStackTrace(llvm::outs());
llvm::outs() << "\n";
g_printed = true;
}
}
}
[[fallthrough]];
default:
const uint32_t bit_size = getASTContext().getTypeSize(qual_type);
if (bit_size == 0) {
if (qual_type->isIncompleteArrayType())
return getASTContext().getTypeSize(
qual_type->getArrayElementTypeNoTypeQual()
->getCanonicalTypeUnqualified());
}
if (qual_type->isObjCObjectOrInterfaceType())
return bit_size +
getASTContext().getTypeSize(getASTContext().ObjCBuiltinClassTy);
// Function types actually have a size of 0, that's not an error.
if (qual_type->isFunctionProtoType())
return bit_size;
if (bit_size)
return bit_size;
}
clang::QualType qual_type(GetCanonicalQualType(type));
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
switch (type_class) {
case clang::Type::FunctionProto:
case clang::Type::Record:
return getASTContext().getTypeSize(qual_type);
case clang::Type::ObjCInterface:
case clang::Type::ObjCObject:
return GetObjCBitSize(qual_type, exe_scope);
case clang::Type::IncompleteArray: {
const uint64_t bit_size = getASTContext().getTypeSize(qual_type);
if (bit_size == 0)
return getASTContext().getTypeSize(
qual_type->getArrayElementTypeNoTypeQual()
->getCanonicalTypeUnqualified());

return bit_size;
}
default:
if (const uint64_t bit_size = getASTContext().getTypeSize(qual_type))
return bit_size;
}

return std::nullopt;
}

Expand Down
3 changes: 3 additions & 0 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
Original file line number Diff line number Diff line change
Expand Up @@ -1172,6 +1172,9 @@ class TypeSystemClang : public TypeSystem {
/// on creation of a new instance.
void LogCreation() const;

std::optional<uint64_t> GetObjCBitSize(clang::QualType qual_type,
ExecutionContextScope *exe_scope);

// Classes that inherit from TypeSystemClang can see and modify these
std::string m_target_triple;
std::unique_ptr<clang::ASTContext> m_ast_up;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@


class TestCaseClassTemplateNonTypeParameterPack(TestBase):
@expectedFailureAll(
oslist=["windows"], archs=["i[3-6]86", "x86_64"]
) # Fails to read memory from target.
@no_debug_info_test
def test(self):
self.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@


class TestCaseClassTemplateTypeParameterPack(TestBase):
@expectedFailureAll(
oslist=["windows"], archs=["i[3-6]86", "x86_64"]
) # Fails to read memory from target.
@no_debug_info_test
def test(self):
self.build()
Expand Down
31 changes: 31 additions & 0 deletions lldb/tools/lldb-dap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,20 @@ locally on port `2345`.
}
```

You can also use the `gdb-remote-port` parameter to send an attach request
to a debug server running on the current machine,
instead of using the custom command `attachCommands`.

```javascript
{
"name": "Local Debug Server",
"type": "lldb-dap",
"request": "attach",
"program": "/tmp/a.out",
"gdb-remote-port": 2345,
}
```

#### Connect to a Debug Server on Another Machine

This connects to a debug server running on another machine with hostname
Expand All @@ -173,6 +187,23 @@ port `5678` of that other machine.
}
```

You can also use the `gdb-remote-hostname` and `gdb-remote-port` parameters
to send an attach request to a debug server running on a different machine,
instead of custom command `attachCommands`.
The default hostname being used `localhost`.


```javascript
{
"name": "Local Debug Server",
"type": "lldb-dap",
"request": "attach",
"program": "/tmp/a.out",
"gdb-remote-port": 5678,
"gdb-remote-hostname": "hostname",
}
```

## Custom debugger commands

The `lldb-dap` tool includes additional custom commands to support the Debug
Expand Down
4 changes: 2 additions & 2 deletions lldb/tools/lldb-dap/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "lldb-dap",
"displayName": "LLDB DAP",
"version": "0.2.2",
"version": "0.2.3",
"publisher": "llvm-vs-code-extensions",
"homepage": "https://lldb.llvm.org",
"description": "LLDB debugging from VSCode",
Expand Down Expand Up @@ -353,7 +353,7 @@
"number",
"string"
],
"description": "TCP/IP port to attach to. Specifying both pid and port is an error."
"description": "TCP/IP port to attach to a remote system. Specifying both pid and port is an error."
},
"gdb-remote-hostname": {
"type": "string",
Expand Down
1 change: 0 additions & 1 deletion llvm/bindings/ocaml/llvm/llvm.ml
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,6 @@ external vector_size : lltype -> int = "llvm_vector_size"
(*--... Operations on other types ..........................................--*)
external void_type : llcontext -> lltype = "llvm_void_type"
external label_type : llcontext -> lltype = "llvm_label_type"
external x86_mmx_type : llcontext -> lltype = "llvm_x86_mmx_type"
external type_by_name : llmodule -> string -> lltype option = "llvm_type_by_name"

external classify_value : llvalue -> ValueKind.t = "llvm_classify_value"
Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/ADT/DenseMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,13 @@ class DenseMapBase : public DebugEpochBase {
return;
}

const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
const KeyT EmptyKey = getEmptyKey();
if (std::is_trivially_destructible<ValueT>::value) {
// Use a simpler loop when values don't need destruction.
for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P)
P->getFirst() = EmptyKey;
} else {
const KeyT TombstoneKey = getTombstoneKey();
unsigned NumEntries = getNumEntries();
for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey)) {
Expand Down
22 changes: 8 additions & 14 deletions llvm/include/llvm/Analysis/LoopAccessAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,7 @@ class MemoryDepChecker {
///
/// Only checks sets with elements in \p CheckDeps.
bool areDepsSafe(const DepCandidates &AccessSets,
const MemAccessInfoList &CheckDeps,
const DenseMap<Value *, SmallVector<const Value *, 16>>
&UnderlyingObjects);
const MemAccessInfoList &CheckDeps);

/// No memory dependence was encountered that would inhibit
/// vectorization.
Expand Down Expand Up @@ -352,11 +350,8 @@ class MemoryDepChecker {
/// element access it records this distance in \p MinDepDistBytes (if this
/// distance is smaller than any other distance encountered so far).
/// Otherwise, this function returns true signaling a possible dependence.
Dependence::DepType
isDependent(const MemAccessInfo &A, unsigned AIdx, const MemAccessInfo &B,
unsigned BIdx,
const DenseMap<Value *, SmallVector<const Value *, 16>>
&UnderlyingObjects);
Dependence::DepType isDependent(const MemAccessInfo &A, unsigned AIdx,
const MemAccessInfo &B, unsigned BIdx);

/// Check whether the data dependence could prevent store-load
/// forwarding.
Expand Down Expand Up @@ -393,11 +388,9 @@ class MemoryDepChecker {
/// determined, or a struct containing (Distance, Stride, TypeSize, AIsWrite,
/// BIsWrite).
std::variant<Dependence::DepType, DepDistanceStrideAndSizeInfo>
getDependenceDistanceStrideAndSize(
const MemAccessInfo &A, Instruction *AInst, const MemAccessInfo &B,
Instruction *BInst,
const DenseMap<Value *, SmallVector<const Value *, 16>>
&UnderlyingObjects);
getDependenceDistanceStrideAndSize(const MemAccessInfo &A, Instruction *AInst,
const MemAccessInfo &B,
Instruction *BInst);
};

class RuntimePointerChecking;
Expand Down Expand Up @@ -799,7 +792,8 @@ replaceSymbolicStrideSCEV(PredicatedScalarEvolution &PSE,
Value *Ptr);

/// If the pointer has a constant stride return it in units of the access type
/// size. Otherwise return std::nullopt.
/// size. If the pointer is loop-invariant, return 0. Otherwise return
/// std::nullopt.
///
/// Ensure that it does not wrap in the address space, assuming the predicate
/// associated with \p PSE is true.
Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/CodeGen/AsmPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@ class AsmPrinter : public MachineFunctionPass {
/// split stack prologue.
bool HasNoSplitStack = false;

/// True if debugging information is available in this module.
bool DbgInfoAvailable = false;

protected:
explicit AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer);

Expand Down Expand Up @@ -430,6 +433,9 @@ class AsmPrinter : public MachineFunctionPass {
/// Get the CFISection type for the module.
CFISection getModuleCFISectionType() const { return ModuleCFISection; }

/// Returns true if valid debug info is present.
bool hasDebugInfo() const { return DbgInfoAvailable; }

bool needsSEHMoves();

/// Since emitting CFI unwind information is entangled with supporting the
Expand Down
9 changes: 9 additions & 0 deletions llvm/include/llvm/CodeGen/FunctionLoweringInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ class FunctionLoweringInfo {
/// SelectionDAGISel::PrepareEHLandingPad().
unsigned ExceptionPointerVirtReg, ExceptionSelectorVirtReg;

/// The current call site index being processed, if any. 0 if none.
unsigned CurCallSite = 0;

/// Collection of dbg.declare instructions handled after argument
/// lowering and before ISel proper.
SmallPtrSet<const DbgDeclareInst *, 8> PreprocessedDbgDeclares;
Expand Down Expand Up @@ -281,6 +284,12 @@ class FunctionLoweringInfo {
Register getCatchPadExceptionPointerVReg(const Value *CPI,
const TargetRegisterClass *RC);

/// Set the call site currently being processed.
void setCurrentCallSite(unsigned Site) { CurCallSite = Site; }

/// Get the call site currently being processed, if any. Return zero if none.
unsigned getCurrentCallSite() { return CurCallSite; }

private:
/// LiveOutRegInfo - Information about live out vregs.
IndexedMap<LiveOutInfo, VirtReg2IndexFunctor> LiveOutRegInfo;
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/CodeGen/MIRPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace llvm {

class MachineBasicBlock;
class MachineFunction;
class MachineModuleInfo;
class Module;
template <typename T> class SmallVectorImpl;

Expand Down
19 changes: 8 additions & 11 deletions llvm/include/llvm/CodeGen/MachineFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ class MachineConstantPool;
class MachineFrameInfo;
class MachineFunction;
class MachineJumpTableInfo;
class MachineModuleInfo;
class MachineRegisterInfo;
class MCContext;
class MCInstrDesc;
Expand Down Expand Up @@ -260,7 +259,6 @@ class LLVM_EXTERNAL_VISIBILITY MachineFunction {
const LLVMTargetMachine &Target;
const TargetSubtargetInfo *STI;
MCContext &Ctx;
MachineModuleInfo &MMI;

// RegInfo - Information about each register in use in the function.
MachineRegisterInfo *RegInfo;
Expand Down Expand Up @@ -395,15 +393,15 @@ class LLVM_EXTERNAL_VISIBILITY MachineFunction {

/// \}

/// Clear all the members of this MachineFunction, but the ones used
/// to initialize again the MachineFunction.
/// More specifically, this deallocates all the dynamically allocated
/// objects and get rid of all the XXXInfo data structure, but keep
/// unchanged the references to Fn, Target, MMI, and FunctionNumber.
/// Clear all the members of this MachineFunction, but the ones used to
/// initialize again the MachineFunction. More specifically, this deallocates
/// all the dynamically allocated objects and get rids of all the XXXInfo data
/// structure, but keeps unchanged the references to Fn, Target, and
/// FunctionNumber.
void clear();
/// Allocate and initialize the different members.
/// In particular, the XXXInfo data structure.
/// \pre Fn, Target, MMI, and FunctionNumber are properly set.
/// \pre Fn, Target, and FunctionNumber are properly set.
void init();

public:
Expand Down Expand Up @@ -632,8 +630,8 @@ class LLVM_EXTERNAL_VISIBILITY MachineFunction {
const static unsigned int DebugOperandMemNumber;

MachineFunction(Function &F, const LLVMTargetMachine &Target,
const TargetSubtargetInfo &STI, unsigned FunctionNum,
MachineModuleInfo &MMI);
const TargetSubtargetInfo &STI, MCContext &Ctx,
unsigned FunctionNum);
MachineFunction(const MachineFunction &) = delete;
MachineFunction &operator=(const MachineFunction &) = delete;
~MachineFunction();
Expand Down Expand Up @@ -665,7 +663,6 @@ class LLVM_EXTERNAL_VISIBILITY MachineFunction {

GISelChangeObserver *getObserver() const { return Observer; }

MachineModuleInfo &getMMI() const { return MMI; }
MCContext &getContext() const { return Ctx; }

/// Returns the Section this function belongs to.
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/MachineInstr.h
Original file line number Diff line number Diff line change
Expand Up @@ -1723,7 +1723,7 @@ class MachineInstr
/// Return true if it is safe to move this instruction. If
/// SawStore is set to true, it means that there is a store (or call) between
/// the instruction's location and its intended destination.
bool isSafeToMove(AAResults *AA, bool &SawStore) const;
bool isSafeToMove(bool &SawStore) const;

/// Returns true if this instruction's memory access aliases the memory
/// access of Other.
Expand Down
38 changes: 0 additions & 38 deletions llvm/include/llvm/CodeGen/MachineModuleInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,27 +99,6 @@ class MachineModuleInfo {
/// want.
MachineModuleInfoImpl *ObjFileMMI;

/// \name Exception Handling
/// \{

/// The current call site index being processed, if any. 0 if none.
unsigned CurCallSite = 0;

/// \}

// TODO: Ideally, what we'd like is to have a switch that allows emitting
// synchronous (precise at call-sites only) CFA into .eh_frame. However,
// even under this switch, we'd like .debug_frame to be precise when using
// -g. At this moment, there's no way to specify that some CFI directives
// go into .eh_frame only, while others go into .debug_frame only.

/// True if debugging information is available in this module.
bool DbgInfoAvailable = false;

/// True if this module is being built for windows/msvc, and uses floating
/// point. This is used to emit an undefined reference to _fltused.
bool UsesMSVCFloatingPoint = false;

/// Maps IR Functions to their corresponding MachineFunctions.
DenseMap<const Function*, std::unique_ptr<MachineFunction>> MachineFunctions;
/// Next unique number available for a MachineFunction.
Expand Down Expand Up @@ -186,23 +165,6 @@ class MachineModuleInfo {
return const_cast<MachineModuleInfo*>(this)->getObjFileInfo<Ty>();
}

/// Returns true if valid debug info is present.
bool hasDebugInfo() const { return DbgInfoAvailable; }

bool usesMSVCFloatingPoint() const { return UsesMSVCFloatingPoint; }

void setUsesMSVCFloatingPoint(bool b) { UsesMSVCFloatingPoint = b; }

/// \name Exception Handling
/// \{

/// Set the call site currently being processed.
void setCurrentCallSite(unsigned Site) { CurCallSite = Site; }

/// Get the call site currently being processed, if any. return zero if
/// none.
unsigned getCurrentCallSite() { return CurCallSite; }

/// \}
}; // End class MachineModuleInfo

Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/CodeGen/SDPatternMatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,12 @@ m_c_SetCC(const T0_P &LHS, const T1_P &RHS, const T2_P &CC) {
CC);
}

template <typename T0_P, typename T1_P, typename T2_P>
inline TernaryOpc_match<T0_P, T1_P, T2_P>
m_Select(const T0_P &Cond, const T1_P &T, const T2_P &F) {
return TernaryOpc_match<T0_P, T1_P, T2_P>(ISD::SELECT, Cond, T, F);
}

// === Binary operations ===
template <typename LHS_P, typename RHS_P, bool Commutable = false,
bool ExcludeChain = false>
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/CodeGen/SelectionDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ struct KnownBits;
class LLVMContext;
class MachineBasicBlock;
class MachineConstantPoolValue;
class MachineModuleInfo;
class MCSymbol;
class OptimizationRemarkEmitter;
class ProfileSummaryInfo;
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/CodeGen/TargetInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class LiveIntervals;
class LiveVariables;
class MachineLoop;
class MachineMemOperand;
class MachineModuleInfo;
class MachineRegisterInfo;
class MCAsmInfo;
class MCInst;
Expand Down
119 changes: 55 additions & 64 deletions llvm/lib/Analysis/LoopAccessAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -725,11 +725,6 @@ class AccessAnalysis {

const MemAccessInfoList &getDependenciesToCheck() const { return CheckDeps; }

const DenseMap<Value *, SmallVector<const Value *, 16>> &
getUnderlyingObjects() const {
return UnderlyingObjects;
}

private:
typedef MapVector<MemAccessInfo, SmallSetVector<Type *, 1>> PtrAccessMap;

Expand Down Expand Up @@ -1455,22 +1450,23 @@ static bool isNoWrapAddRec(Value *Ptr, const SCEVAddRecExpr *AR,
}

/// Check whether the access through \p Ptr has a constant stride.
std::optional<int64_t> llvm::getPtrStride(PredicatedScalarEvolution &PSE,
Type *AccessTy, Value *Ptr,
const Loop *Lp,
const DenseMap<Value *, const SCEV *> &StridesMap,
bool Assume, bool ShouldCheckWrap) {
std::optional<int64_t>
llvm::getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr,
const Loop *Lp,
const DenseMap<Value *, const SCEV *> &StridesMap,
bool Assume, bool ShouldCheckWrap) {
const SCEV *PtrScev = replaceSymbolicStrideSCEV(PSE, StridesMap, Ptr);
if (PSE.getSE()->isLoopInvariant(PtrScev, Lp))
return {0};

Type *Ty = Ptr->getType();
assert(Ty->isPointerTy() && "Unexpected non-ptr");

if (isa<ScalableVectorType>(AccessTy)) {
LLVM_DEBUG(dbgs() << "LAA: Bad stride - Scalable object: " << *AccessTy
<< "\n");
return std::nullopt;
}

const SCEV *PtrScev = replaceSymbolicStrideSCEV(PSE, StridesMap, Ptr);

const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(PtrScev);
if (Assume && !AR)
AR = PSE.getAsAddRec(Ptr);
Expand Down Expand Up @@ -1897,23 +1893,11 @@ static bool areStridedAccessesIndependent(uint64_t Distance, uint64_t Stride,
return ScaledDist % Stride;
}

/// Returns true if any of the underlying objects has a loop varying address,
/// i.e. may change in \p L.
static bool
isLoopVariantIndirectAddress(ArrayRef<const Value *> UnderlyingObjects,
ScalarEvolution &SE, const Loop *L) {
return any_of(UnderlyingObjects, [&SE, L](const Value *UO) {
return !SE.isLoopInvariant(SE.getSCEV(const_cast<Value *>(UO)), L);
});
}

std::variant<MemoryDepChecker::Dependence::DepType,
MemoryDepChecker::DepDistanceStrideAndSizeInfo>
MemoryDepChecker::getDependenceDistanceStrideAndSize(
const AccessAnalysis::MemAccessInfo &A, Instruction *AInst,
const AccessAnalysis::MemAccessInfo &B, Instruction *BInst,
const DenseMap<Value *, SmallVector<const Value *, 16>>
&UnderlyingObjects) {
const AccessAnalysis::MemAccessInfo &B, Instruction *BInst) {
const auto &DL = InnermostLoop->getHeader()->getDataLayout();
auto &SE = *PSE.getSE();
const auto &[APtr, AIsWrite] = A;
Expand All @@ -1931,39 +1915,30 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
BPtr->getType()->getPointerAddressSpace())
return MemoryDepChecker::Dependence::Unknown;

int64_t StrideAPtr =
getPtrStride(PSE, ATy, APtr, InnermostLoop, SymbolicStrides, true)
.value_or(0);
int64_t StrideBPtr =
getPtrStride(PSE, BTy, BPtr, InnermostLoop, SymbolicStrides, true)
.value_or(0);
std::optional<int64_t> StrideAPtr =
getPtrStride(PSE, ATy, APtr, InnermostLoop, SymbolicStrides, true, true);
std::optional<int64_t> StrideBPtr =
getPtrStride(PSE, BTy, BPtr, InnermostLoop, SymbolicStrides, true, true);

const SCEV *Src = PSE.getSCEV(APtr);
const SCEV *Sink = PSE.getSCEV(BPtr);

// If the induction step is negative we have to invert source and sink of the
// dependence when measuring the distance between them. We should not swap
// AIsWrite with BIsWrite, as their uses expect them in program order.
if (StrideAPtr < 0) {
if (StrideAPtr && *StrideAPtr < 0) {
std::swap(Src, Sink);
std::swap(AInst, BInst);
std::swap(StrideAPtr, StrideBPtr);
}

const SCEV *Dist = SE.getMinusSCEV(Sink, Src);

LLVM_DEBUG(dbgs() << "LAA: Src Scev: " << *Src << "Sink Scev: " << *Sink
<< "(Induction step: " << StrideAPtr << ")\n");
<< "\n");
LLVM_DEBUG(dbgs() << "LAA: Distance for " << *AInst << " to " << *BInst
<< ": " << *Dist << "\n");

// Needs accesses where the addresses of the accessed underlying objects do
// not change within the loop.
if (isLoopVariantIndirectAddress(UnderlyingObjects.find(APtr)->second, SE,
InnermostLoop) ||
isLoopVariantIndirectAddress(UnderlyingObjects.find(BPtr)->second, SE,
InnermostLoop))
return MemoryDepChecker::Dependence::IndirectUnsafe;

// Check if we can prove that Sink only accesses memory after Src's end or
// vice versa. At the moment this is limited to cases where either source or
// sink are loop invariant to avoid compile-time increases. This is not
Expand All @@ -1985,12 +1960,33 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
}
}

// Need accesses with constant strides and the same direction. We don't want
// to vectorize "A[B[i]] += ..." and similar code or pointer arithmetic that
// could wrap in the address space.
if (!StrideAPtr || !StrideBPtr || (StrideAPtr > 0 && StrideBPtr < 0) ||
(StrideAPtr < 0 && StrideBPtr > 0)) {
// Need accesses with constant strides and the same direction for further
// dependence analysis. We don't want to vectorize "A[B[i]] += ..." and
// similar code or pointer arithmetic that could wrap in the address space.

// If either Src or Sink are not strided (i.e. not a non-wrapping AddRec) and
// not loop-invariant (stride will be 0 in that case), we cannot analyze the
// dependence further and also cannot generate runtime checks.
if (!StrideAPtr || !StrideBPtr) {
LLVM_DEBUG(dbgs() << "Pointer access with non-constant stride\n");
return MemoryDepChecker::Dependence::IndirectUnsafe;
}

int64_t StrideAPtrInt = *StrideAPtr;
int64_t StrideBPtrInt = *StrideBPtr;
LLVM_DEBUG(dbgs() << "LAA: Src induction step: " << StrideAPtrInt
<< " Sink induction step: " << StrideBPtrInt << "\n");
// At least Src or Sink are loop invariant and the other is strided or
// invariant. We can generate a runtime check to disambiguate the accesses.
if (StrideAPtrInt == 0 || StrideBPtrInt == 0)
return MemoryDepChecker::Dependence::Unknown;

// Both Src and Sink have a constant stride, check if they are in the same
// direction.
if ((StrideAPtrInt > 0 && StrideBPtrInt < 0) ||
(StrideAPtrInt < 0 && StrideBPtrInt > 0)) {
LLVM_DEBUG(
dbgs() << "Pointer access with strides in different directions\n");
return MemoryDepChecker::Dependence::Unknown;
}

Expand All @@ -1999,22 +1995,20 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
DL.getTypeStoreSizeInBits(ATy) == DL.getTypeStoreSizeInBits(BTy);
if (!HasSameSize)
TypeByteSize = 0;
return DepDistanceStrideAndSizeInfo(Dist, std::abs(StrideAPtr),
std::abs(StrideBPtr), TypeByteSize,
return DepDistanceStrideAndSizeInfo(Dist, std::abs(StrideAPtrInt),
std::abs(StrideBPtrInt), TypeByteSize,
AIsWrite, BIsWrite);
}

MemoryDepChecker::Dependence::DepType MemoryDepChecker::isDependent(
const MemAccessInfo &A, unsigned AIdx, const MemAccessInfo &B,
unsigned BIdx,
const DenseMap<Value *, SmallVector<const Value *, 16>>
&UnderlyingObjects) {
MemoryDepChecker::Dependence::DepType
MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
const MemAccessInfo &B, unsigned BIdx) {
assert(AIdx < BIdx && "Must pass arguments in program order");

// Get the dependence distance, stride, type size and what access writes for
// the dependence between A and B.
auto Res = getDependenceDistanceStrideAndSize(
A, InstMap[AIdx], B, InstMap[BIdx], UnderlyingObjects);
auto Res =
getDependenceDistanceStrideAndSize(A, InstMap[AIdx], B, InstMap[BIdx]);
if (std::holds_alternative<Dependence::DepType>(Res))
return std::get<Dependence::DepType>(Res);

Expand Down Expand Up @@ -2248,10 +2242,8 @@ MemoryDepChecker::Dependence::DepType MemoryDepChecker::isDependent(
return Dependence::BackwardVectorizable;
}

bool MemoryDepChecker::areDepsSafe(
const DepCandidates &AccessSets, const MemAccessInfoList &CheckDeps,
const DenseMap<Value *, SmallVector<const Value *, 16>>
&UnderlyingObjects) {
bool MemoryDepChecker::areDepsSafe(const DepCandidates &AccessSets,
const MemAccessInfoList &CheckDeps) {

MinDepDistBytes = -1;
SmallPtrSet<MemAccessInfo, 8> Visited;
Expand Down Expand Up @@ -2294,8 +2286,8 @@ bool MemoryDepChecker::areDepsSafe(
if (*I1 > *I2)
std::swap(A, B);

Dependence::DepType Type = isDependent(*A.first, A.second, *B.first,
B.second, UnderlyingObjects);
Dependence::DepType Type =
isDependent(*A.first, A.second, *B.first, B.second);
mergeInStatus(Dependence::isSafeForVectorization(Type));

// Gather dependences unless we accumulated MaxDependences
Expand Down Expand Up @@ -2650,8 +2642,7 @@ bool LoopAccessInfo::analyzeLoop(AAResults *AA, const LoopInfo *LI,
if (Accesses.isDependencyCheckNeeded()) {
LLVM_DEBUG(dbgs() << "LAA: Checking memory dependencies\n");
DepsAreSafe = DepChecker->areDepsSafe(DependentAccesses,
Accesses.getDependenciesToCheck(),
Accesses.getUnderlyingObjects());
Accesses.getDependenciesToCheck());

if (!DepsAreSafe && DepChecker->shouldRetryWithRuntimeCheck()) {
LLVM_DEBUG(dbgs() << "LAA: Retrying with memory checks\n");
Expand Down
18 changes: 8 additions & 10 deletions llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ bool AsmPrinter::doInitialization(Module &M) {
MMI = MMIWP ? &MMIWP->getMMI() : nullptr;
HasSplitStack = false;
HasNoSplitStack = false;
DbgInfoAvailable = !M.debug_compile_units().empty();

AddrLabelSymbols = nullptr;

Expand Down Expand Up @@ -541,8 +542,7 @@ bool AsmPrinter::doInitialization(Module &M) {
if (EmitCodeView && TM.getTargetTriple().isOSWindows())
DebugHandlers.push_back(std::make_unique<CodeViewDebug>(this));
if (!EmitCodeView || M.getDwarfVersion()) {
assert(MMI && "MMI could not be nullptr here!");
if (MMI->hasDebugInfo()) {
if (hasDebugInfo()) {
DD = new DwarfDebug(this);
DebugHandlers.push_back(std::unique_ptr<DwarfDebug>(DD));
}
Expand Down Expand Up @@ -1277,8 +1277,7 @@ AsmPrinter::getFunctionCFISectionType(const Function &F) const {
if (MAI->usesCFIWithoutEH() && F.hasUWTable())
return CFISection::EH;

assert(MMI != nullptr && "Invalid machine module info");
if (MMI->hasDebugInfo() || TM.Options.ForceDwarfFrameSection)
if (hasDebugInfo() || TM.Options.ForceDwarfFrameSection)
return CFISection::Debug;

return CFISection::None;
Expand Down Expand Up @@ -1669,10 +1668,9 @@ void AsmPrinter::emitPCSections(const MachineFunction &MF) {
}

/// Returns true if function begin and end labels should be emitted.
static bool needFuncLabels(const MachineFunction &MF,
const MachineModuleInfo &MMI) {
if (!MF.getLandingPads().empty() || MF.hasEHFunclets() ||
MMI.hasDebugInfo() ||
static bool needFuncLabels(const MachineFunction &MF, const AsmPrinter &Asm) {
if (Asm.hasDebugInfo() || !MF.getLandingPads().empty() ||
MF.hasEHFunclets() ||
MF.getFunction().hasMetadata(LLVMContext::MD_pcsections))
return true;

Expand Down Expand Up @@ -1944,7 +1942,7 @@ void AsmPrinter::emitFunctionBody() {
// are automatically sized.
bool EmitFunctionSize = MAI->hasDotTypeDotSizeDirective() && !TT.isWasm();

if (needFuncLabels(*MF, *MMI) || EmitFunctionSize) {
if (EmitFunctionSize || needFuncLabels(*MF, *this)) {
// Create a symbol for the end of function.
CurrentFnEnd = createTempSymbol("func_end");
OutStreamer->emitLabel(CurrentFnEnd);
Expand Down Expand Up @@ -2588,7 +2586,7 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
if (F.hasFnAttribute("patchable-function-entry") ||
F.hasFnAttribute("function-instrument") ||
F.hasFnAttribute("xray-instruction-threshold") ||
needFuncLabels(MF, *MMI) || NeedsLocalForSize ||
needFuncLabels(MF, *this) || NeedsLocalForSize ||
MF.getTarget().Options.EmitStackSizeSection ||
MF.getTarget().Options.BBAddrMap || MF.hasBBLabels()) {
CurrentFnBegin = createTempSymbol("func_begin");
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ static SourceLanguage MapDWLangToCVLang(unsigned DWLang) {
void CodeViewDebug::beginModule(Module *M) {
// If module doesn't have named metadata anchors or COFF debug section
// is not available, skip any debug info related stuff.
if (!MMI->hasDebugInfo() ||
if (!Asm->hasDebugInfo() ||
!Asm->getObjFileLowering().getCOFFDebugSymbolsSection()) {
Asm = nullptr;
return;
Expand All @@ -636,7 +636,7 @@ void CodeViewDebug::beginModule(Module *M) {
}

void CodeViewDebug::endModule() {
if (!Asm || !MMI->hasDebugInfo())
if (!Asm || !Asm->hasDebugInfo())
return;

// The COFF .debug$S section consists of several subsections, each starting
Expand Down
13 changes: 5 additions & 8 deletions llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,7 @@ bool DebugHandlerBase::isUnsignedDIType(const DIType *Ty) {
Ty->getTag() == dwarf::DW_TAG_unspecified_type;
}

static bool hasDebugInfo(const MachineModuleInfo *MMI,
const MachineFunction *MF) {
if (!MMI->hasDebugInfo())
return false;
static bool hasDebugInfo(const MachineFunction *MF) {
auto *SP = MF->getFunction().getSubprogram();
if (!SP)
return false;
Expand All @@ -258,7 +255,7 @@ static bool hasDebugInfo(const MachineModuleInfo *MMI,
void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
PrevInstBB = nullptr;

if (!Asm || !hasDebugInfo(MMI, MF)) {
if (!Asm || !hasDebugInfo(MF)) {
skippedNonDebugFunction();
return;
}
Expand Down Expand Up @@ -354,7 +351,7 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
}

void DebugHandlerBase::beginInstruction(const MachineInstr *MI) {
if (!Asm || !MMI->hasDebugInfo())
if (!Asm || !Asm->hasDebugInfo())
return;

assert(CurMI == nullptr);
Expand All @@ -380,7 +377,7 @@ void DebugHandlerBase::beginInstruction(const MachineInstr *MI) {
}

void DebugHandlerBase::endInstruction() {
if (!Asm || !MMI->hasDebugInfo())
if (!Asm || !Asm->hasDebugInfo())
return;

assert(CurMI != nullptr);
Expand Down Expand Up @@ -415,7 +412,7 @@ void DebugHandlerBase::endInstruction() {
}

void DebugHandlerBase::endFunction(const MachineFunction *MF) {
if (Asm && hasDebugInfo(MMI, MF))
if (Asm && hasDebugInfo(MF))
endFunctionImpl(MF);
DbgValues.clear();
DbgLabels.clear();
Expand Down
9 changes: 5 additions & 4 deletions llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1148,14 +1148,15 @@ sortGlobalExprs(SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &GVEs) {
void DwarfDebug::beginModule(Module *M) {
DebugHandlerBase::beginModule(M);

if (!Asm || !MMI->hasDebugInfo())
if (!Asm)
return;

unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
M->debug_compile_units_end());
if (NumDebugCUs == 0)
return;

assert(NumDebugCUs > 0 && "Asm unexpectedly initialized");
assert(MMI->hasDebugInfo() &&
"DebugInfoAvailabilty unexpectedly not initialized");
SingleCU = NumDebugCUs == 1;
DenseMap<DIGlobalVariable *, SmallVector<DwarfCompileUnit::GlobalExpr, 1>>
GVMap;
Expand Down Expand Up @@ -1433,7 +1434,7 @@ void DwarfDebug::endModule() {

// If we aren't actually generating debug info (check beginModule -
// conditionalized on the presence of the llvm.dbg.cu metadata node)
if (!Asm || !MMI->hasDebugInfo())
if (!Asm || !Asm->hasDebugInfo())
return;

// Finalize the debug info for the module.
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/BranchFolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1891,7 +1891,7 @@ MachineBasicBlock::iterator findHoistingInsertPosAndDeps(MachineBasicBlock *MBB,
// Also avoid moving code above predicated instruction since it's hard to
// reason about register liveness with predicated instruction.
bool DontMoveAcrossStore = true;
if (!PI->isSafeToMove(nullptr, DontMoveAcrossStore) || TII->isPredicated(*PI))
if (!PI->isSafeToMove(DontMoveAcrossStore) || TII->isPredicated(*PI))
return MBB->end();

// Find out what registers are live. Note this routine is ignoring other live
Expand Down Expand Up @@ -2015,7 +2015,7 @@ bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB) {
break;

bool DontMoveAcrossStore = true;
if (!TIB->isSafeToMove(nullptr, DontMoveAcrossStore))
if (!TIB->isSafeToMove(DontMoveAcrossStore))
break;

// Remove kills from ActiveDefsSet, these registers had short live ranges.
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/DeadMachineInstructionElim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ bool DeadMachineInstructionElimImpl::isDead(const MachineInstr *MI) const {

// Don't delete instructions with side effects.
bool SawStore = false;
if (!MI->isSafeToMove(nullptr, SawStore) && !MI->isPHI())
if (!MI->isSafeToMove(SawStore) && !MI->isPHI())
return false;

// Examine each operand.
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/EarlyIfConversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ bool SSAIfConv::canSpeculateInstrs(MachineBasicBlock *MBB) {

// We never speculate stores, so an AA pointer isn't necessary.
bool DontMoveAcrossStore = true;
if (!MI.isSafeToMove(nullptr, DontMoveAcrossStore)) {
if (!MI.isSafeToMove(DontMoveAcrossStore)) {
LLVM_DEBUG(dbgs() << "Can't speculate: " << MI);
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/GlobalISel/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ bool llvm::isTriviallyDead(const MachineInstr &MI,
// If we can move an instruction, we can remove it. Otherwise, it has
// a side-effect of some sort.
bool SawStore = false;
if (!MI.isSafeToMove(/*AA=*/nullptr, SawStore) && !MI.isPHI())
if (!MI.isSafeToMove(SawStore) && !MI.isPHI())
return false;

// Instructions without side-effects are dead iff they only define dead vregs.
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/IfConversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2097,7 +2097,7 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
static bool MaySpeculate(const MachineInstr &MI,
SmallSet<MCPhysReg, 4> &LaterRedefs) {
bool SawStore = true;
if (!MI.isSafeToMove(nullptr, SawStore))
if (!MI.isSafeToMove(SawStore))
return false;

for (const MachineOperand &MO : MI.operands()) {
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/LiveRangeEdit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ bool LiveRangeEdit::foldAsLoad(LiveInterval *LI,
// We also need to make sure it is safe to move the load.
// Assume there are stores between DefMI and UseMI.
bool SawStore = true;
if (!DefMI->isSafeToMove(nullptr, SawStore))
if (!DefMI->isSafeToMove(SawStore))
return false;

LLVM_DEBUG(dbgs() << "Try to fold single def: " << *DefMI
Expand Down Expand Up @@ -300,7 +300,7 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) {

// Use the same criteria as DeadMachineInstructionElim.
bool SawStore = false;
if (!MI->isSafeToMove(nullptr, SawStore)) {
if (!MI->isSafeToMove(SawStore)) {
LLVM_DEBUG(dbgs() << "Can't delete: " << Idx << '\t' << *MI);
return;
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/LiveRangeShrink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ bool LiveRangeShrink::runOnMachineFunction(MachineFunction &MF) {
}
}

if (!MI.isSafeToMove(nullptr, SawStore)) {
if (!MI.isSafeToMove(SawStore)) {
// If MI has side effects, it should become a barrier for code motion.
// IOM is rebuild from the next instruction to prevent later
// instructions from being moved before this MI.
Expand Down
17 changes: 11 additions & 6 deletions llvm/lib/CodeGen/MachineFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,9 @@ static inline Align getFnStackAlignment(const TargetSubtargetInfo *STI,
}

MachineFunction::MachineFunction(Function &F, const LLVMTargetMachine &Target,
const TargetSubtargetInfo &STI,
unsigned FunctionNum, MachineModuleInfo &mmi)
: F(F), Target(Target), STI(&STI), Ctx(mmi.getContext()), MMI(mmi) {
const TargetSubtargetInfo &STI, MCContext &Ctx,
unsigned FunctionNum)
: F(F), Target(Target), STI(&STI), Ctx(Ctx) {
FunctionNumber = FunctionNum;
init();
}
Expand Down Expand Up @@ -654,9 +654,14 @@ void MachineFunction::print(raw_ostream &OS, const SlotIndexes *Indexes) const {

/// True if this function needs frame moves for debug or exceptions.
bool MachineFunction::needsFrameMoves() const {
return getMMI().hasDebugInfo() ||
getTarget().Options.ForceDwarfFrameSection ||
F.needsUnwindTableEntry();
// TODO: Ideally, what we'd like is to have a switch that allows emitting
// synchronous (precise at call-sites only) CFA into .eh_frame. However, even
// under this switch, we'd like .debug_frame to be precise when using -g. At
// this moment, there's no way to specify that some CFI directives go into
// .eh_frame only, while others go into .debug_frame only.
return getTarget().Options.ForceDwarfFrameSection ||
F.needsUnwindTableEntry() ||
!F.getParent()->debug_compile_units().empty();
}

namespace llvm {
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/MachineFunctionAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ MachineFunctionAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
.getCachedResult<MachineModuleAnalysis>(*F.getParent())
->getMMI();
auto MF = std::make_unique<MachineFunction>(
F, *TM, STI, Context.generateMachineFunctionNum(F), MMI);
F, *TM, STI, MMI.getContext(), Context.generateMachineFunctionNum(F));
MF->initTargetMachineFunctionInfo(STI);

// MRI callback for target specific initializations.
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/MachineInstr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1293,7 +1293,7 @@ void MachineInstr::substituteRegister(Register FromReg, Register ToReg,
/// isSafeToMove - Return true if it is safe to move this instruction. If
/// SawStore is set to true, it means that there is a store (or call) between
/// the instruction's location and its intended destination.
bool MachineInstr::isSafeToMove(AAResults *AA, bool &SawStore) const {
bool MachineInstr::isSafeToMove(bool &SawStore) const {
// Ignore stuff that we obviously can't move.
//
// Treat volatile loads as stores. This is not strictly necessary for
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/MachineLICM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1075,7 +1075,7 @@ static bool isCopyFeedingInvariantStore(const MachineInstr &MI,
bool MachineLICMBase::IsLICMCandidate(MachineInstr &I, MachineLoop *CurLoop) {
// Check if it's safe to move the instruction.
bool DontMoveAcrossStore = !HoistConstLoads || !AllowedToHoistLoads[CurLoop];
if ((!I.isSafeToMove(AA, DontMoveAcrossStore)) &&
if ((!I.isSafeToMove(DontMoveAcrossStore)) &&
!(HoistConstStores && isInvariantStore(I, TRI, MRI))) {
LLVM_DEBUG(dbgs() << "LICM: Instruction not safe to move.\n");
return false;
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/CodeGen/MachineLateInstrsCleanup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,7 @@ static bool isCandidate(const MachineInstr *MI, Register &DefedReg,
Register FrameReg) {
DefedReg = MCRegister::NoRegister;
bool SawStore = true;
if (!MI->isSafeToMove(nullptr, SawStore) || MI->isImplicitDef() ||
MI->isInlineAsm())
if (!MI->isSafeToMove(SawStore) || MI->isImplicitDef() || MI->isInlineAsm())
return false;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
Expand Down
8 changes: 1 addition & 7 deletions llvm/lib/CodeGen/MachineModuleInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@ MachineModuleInfoImpl::~MachineModuleInfoImpl() = default;

void MachineModuleInfo::initialize() {
ObjFileMMI = nullptr;
CurCallSite = 0;
NextFnNum = 0;
UsesMSVCFloatingPoint = false;
DbgInfoAvailable = false;
}

void MachineModuleInfo::finalize() {
Expand All @@ -47,7 +44,6 @@ MachineModuleInfo::MachineModuleInfo(MachineModuleInfo &&MMI)
MachineFunctions(std::move(MMI.MachineFunctions)) {
Context.setObjectFileInfo(TM.getObjFileLowering());
ObjFileMMI = MMI.ObjFileMMI;
CurCallSite = MMI.CurCallSite;
ExternalContext = MMI.ExternalContext;
TheModule = MMI.TheModule;
}
Expand Down Expand Up @@ -90,7 +86,7 @@ MachineFunction &MachineModuleInfo::getOrCreateMachineFunction(Function &F) {
if (I.second) {
// No pre-existing machine function, create a new one.
const TargetSubtargetInfo &STI = *TM.getSubtargetImpl(F);
MF = new MachineFunction(F, TM, STI, NextFnNum++, *this);
MF = new MachineFunction(F, TM, STI, getContext(), NextFnNum++);
MF->initTargetMachineFunctionInfo(STI);

// MRI callback for target specific initializations.
Expand Down Expand Up @@ -210,7 +206,6 @@ bool MachineModuleInfoWrapperPass::doInitialization(Module &M) {
Ctx.diagnose(
DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie));
});
MMI.DbgInfoAvailable = !M.debug_compile_units().empty();
return false;
}

Expand All @@ -235,6 +230,5 @@ MachineModuleAnalysis::run(Module &M, ModuleAnalysisManager &) {
Ctx.diagnose(
DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie));
});
MMI.DbgInfoAvailable = !M.debug_compile_units().empty();
return Result(MMI);
}
8 changes: 4 additions & 4 deletions llvm/lib/CodeGen/MachineSink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ bool MachineSinking::PerformSinkAndFold(MachineInstr &MI,

// Check if it's safe to move the instruction.
bool SawStore = true;
if (!MI.isSafeToMove(AA, SawStore))
if (!MI.isSafeToMove(SawStore))
return false;

// Convergent operations may not be made control-dependent on additional
Expand Down Expand Up @@ -687,7 +687,7 @@ void MachineSinking::FindCycleSinkCandidates(
continue;
}
bool DontMoveAcrossStore = true;
if (!MI.isSafeToMove(AA, DontMoveAcrossStore)) {
if (!MI.isSafeToMove(DontMoveAcrossStore)) {
LLVM_DEBUG(dbgs() << "CycleSink: Instruction not safe to move.\n");
continue;
}
Expand Down Expand Up @@ -1654,7 +1654,7 @@ bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,
return false;

// Check if it's safe to move the instruction.
if (!MI.isSafeToMove(AA, SawStore))
if (!MI.isSafeToMove(SawStore))
return false;

// Convergent operations may not be made control-dependent on additional
Expand Down Expand Up @@ -1705,7 +1705,7 @@ bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,
bool TryBreak = false;
bool Store =
MI.mayLoad() ? hasStoreBetween(ParentBlock, SuccToSinkTo, MI) : true;
if (!MI.isSafeToMove(AA, Store)) {
if (!MI.isSafeToMove(Store)) {
LLVM_DEBUG(dbgs() << " *** NOTE: Won't sink load along critical edge.\n");
TryBreak = true;
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/ModuloSchedule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ void ModuloScheduleExpander::removeDeadInstructions(MachineBasicBlock *KernelBB,
bool SawStore = false;
// Check if it's safe to remove the instruction due to side effects.
// We can, and want to, remove Phis here.
if (!MI->isSafeToMove(nullptr, SawStore) && !MI->isPHI()) {
if (!MI->isSafeToMove(SawStore) && !MI->isPHI()) {
++MI;
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/RegisterCoalescer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1320,7 +1320,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
if (!definesFullReg(*DefMI, SrcReg))
return false;
bool SawStore = false;
if (!DefMI->isSafeToMove(AA, SawStore))
if (!DefMI->isSafeToMove(SawStore))
return false;
const MCInstrDesc &MCID = DefMI->getDesc();
if (MCID.getNumDefs() != 1)
Expand Down
16 changes: 0 additions & 16 deletions llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1203,11 +1203,6 @@ void FastISel::handleDbgInfo(const Instruction *II) {

if (DbgLabelRecord *DLR = dyn_cast<DbgLabelRecord>(&DR)) {
assert(DLR->getLabel() && "Missing label");
if (!FuncInfo.MF->getMMI().hasDebugInfo()) {
LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DLR << "\n");
continue;
}

BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DLR->getDebugLoc(),
TII.get(TargetOpcode::DBG_LABEL))
.addMetadata(DLR->getLabel());
Expand Down Expand Up @@ -1402,12 +1397,6 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {
case Intrinsic::dbg_declare: {
const DbgDeclareInst *DI = cast<DbgDeclareInst>(II);
assert(DI->getVariable() && "Missing variable");
if (!FuncInfo.MF->getMMI().hasDebugInfo()) {
LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI
<< " (!hasDebugInfo)\n");
return true;
}

if (FuncInfo.PreprocessedDbgDeclares.contains(DI))
return true;

Expand Down Expand Up @@ -1446,11 +1435,6 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {
case Intrinsic::dbg_label: {
const DbgLabelInst *DI = cast<DbgLabelInst>(II);
assert(DI->getLabel() && "Missing label");
if (!FuncInfo.MF->getMMI().hasDebugInfo()) {
LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n");
return true;
}

BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
TII.get(TargetOpcode::DBG_LABEL)).addMetadata(DI->getLabel());
return true;
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3395,13 +3395,13 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N,
Lo = DAG.getNode(ISD::UADDO, dl, VTList, LoOps);
HiOps[2] = Lo.getValue(1);
Hi = DAG.computeKnownBits(HiOps[2]).isZero()
? DAG.getNode(ISD::UADDO, dl, VTList, ArrayRef(HiOps, 2))
? DAG.getNode(ISD::ADD, dl, NVT, ArrayRef(HiOps, 2))
: DAG.getNode(ISD::UADDO_CARRY, dl, VTList, HiOps);
} else {
Lo = DAG.getNode(ISD::USUBO, dl, VTList, LoOps);
HiOps[2] = Lo.getValue(1);
Hi = DAG.computeKnownBits(HiOps[2]).isZero()
? DAG.getNode(ISD::USUBO, dl, VTList, ArrayRef(HiOps, 2))
? DAG.getNode(ISD::SUB, dl, NVT, ArrayRef(HiOps, 2))
: DAG.getNode(ISD::USUBO_CARRY, dl, VTList, HiOps);
}
return;
Expand Down
10 changes: 4 additions & 6 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6708,10 +6708,9 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
return;
case Intrinsic::eh_sjlj_callsite: {
ConstantInt *CI = cast<ConstantInt>(I.getArgOperand(0));
assert(DAG.getMMI()->getCurrentCallSite() == 0 &&
"Overlapping call sites!");
assert(FuncInfo.getCurrentCallSite() == 0 && "Overlapping call sites!");

DAG.getMMI()->setCurrentCallSite(CI->getZExtValue());
FuncInfo.setCurrentCallSite(CI->getZExtValue());
return;
}
case Intrinsic::eh_sjlj_functioncontext: {
Expand Down Expand Up @@ -8619,21 +8618,20 @@ SDValue SelectionDAGBuilder::lowerStartEH(SDValue Chain,
const BasicBlock *EHPadBB,
MCSymbol *&BeginLabel) {
MachineFunction &MF = DAG.getMachineFunction();
MachineModuleInfo &MMI = MF.getMMI();

// Insert a label before the invoke call to mark the try range. This can be
// used to detect deletion of the invoke via the MachineModuleInfo.
BeginLabel = MF.getContext().createTempSymbol();

// For SjLj, keep track of which landing pads go with which invokes
// so as to maintain the ordering of pads in the LSDA.
unsigned CallSiteIndex = MMI.getCurrentCallSite();
unsigned CallSiteIndex = FuncInfo.getCurrentCallSite();
if (CallSiteIndex) {
MF.setCallSiteBeginLabel(BeginLabel, CallSiteIndex);
LPadToCallSiteMap[FuncInfo.MBBMap[EHPadBB]].push_back(CallSiteIndex);

// Now that the call site is handled, stop tracking it.
MMI.setCurrentCallSite(0);
FuncInfo.setCurrentCallSite(0);
}

return DAG.getEHLabel(getCurSDLoc(), Chain, BeginLabel);
Expand Down
27 changes: 0 additions & 27 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -417,30 +417,6 @@ void SelectionDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
MachineFunctionPass::getAnalysisUsage(AU);
}

static void computeUsesMSVCFloatingPoint(const Triple &TT, const Function &F,
MachineModuleInfo &MMI) {
// Only needed for MSVC
if (!TT.isWindowsMSVCEnvironment())
return;

// If it's already set, nothing to do.
if (MMI.usesMSVCFloatingPoint())
return;

for (const Instruction &I : instructions(F)) {
if (I.getType()->isFPOrFPVectorTy()) {
MMI.setUsesMSVCFloatingPoint(true);
return;
}
for (const auto &Op : I.operands()) {
if (Op->getType()->isFPOrFPVectorTy()) {
MMI.setUsesMSVCFloatingPoint(true);
return;
}
}
}
}

PreservedAnalyses
SelectionDAGISelPass::run(MachineFunction &MF,
MachineFunctionAnalysisManager &MFAM) {
Expand Down Expand Up @@ -802,9 +778,6 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
}
}

// Determine if floating point is used for msvc
computeUsesMSVCFloatingPoint(TM.getTargetTriple(), Fn, *CurDAG->getMMI());

// Release function-specific state. SDB and CurDAG are already cleared
// at this point.
FuncInfo->clear();
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,7 @@ bool TwoAddressInstructionImpl::rescheduleMIBelowKill(
return false;

bool SeenStore = true;
if (!MI->isSafeToMove(AA, SeenStore))
if (!MI->isSafeToMove(SeenStore))
return false;

if (TII->getInstrLatency(InstrItins, *MI) > 1)
Expand Down Expand Up @@ -1131,7 +1131,7 @@ bool TwoAddressInstructionImpl::rescheduleKillAboveMI(
return false;

bool SeenStore = true;
if (!KillMI->isSafeToMove(AA, SeenStore))
if (!KillMI->isSafeToMove(SeenStore))
return false;

SmallVector<Register, 2> Uses;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/AArch64/AArch64ConditionalCompares.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ bool SSACCmpConv::canSpeculateInstrs(MachineBasicBlock *MBB,

// We never speculate stores, so an AA pointer isn't necessary.
bool DontMoveAcrossStore = true;
if (!I.isSafeToMove(nullptr, DontMoveAcrossStore)) {
if (!I.isSafeToMove(DontMoveAcrossStore)) {
LLVM_DEBUG(dbgs() << "Can't speculate: " << I);
return false;
}
Expand Down
26 changes: 3 additions & 23 deletions llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2169,27 +2169,6 @@ bool AMDGPUInstructionSelector::selectG_SELECT(MachineInstr &I) const {
return Ret;
}

static int sizeToSubRegIndex(unsigned Size) {
switch (Size) {
case 32:
return AMDGPU::sub0;
case 64:
return AMDGPU::sub0_sub1;
case 96:
return AMDGPU::sub0_sub1_sub2;
case 128:
return AMDGPU::sub0_sub1_sub2_sub3;
case 256:
return AMDGPU::sub0_sub1_sub2_sub3_sub4_sub5_sub6_sub7;
default:
if (Size < 32)
return AMDGPU::sub0;
if (Size > 256)
return -1;
return sizeToSubRegIndex(llvm::bit_ceil(Size));
}
}

bool AMDGPUInstructionSelector::selectG_TRUNC(MachineInstr &I) const {
Register DstReg = I.getOperand(0).getReg();
Register SrcReg = I.getOperand(1).getReg();
Expand Down Expand Up @@ -2293,8 +2272,9 @@ bool AMDGPUInstructionSelector::selectG_TRUNC(MachineInstr &I) const {
return false;

if (SrcSize > 32) {
int SubRegIdx = sizeToSubRegIndex(DstSize);
if (SubRegIdx == -1)
unsigned SubRegIdx =
DstSize < 32 ? AMDGPU::sub0 : TRI.getSubRegFromChannel(0, DstSize / 32);
if (SubRegIdx == AMDGPU::NoSubRegister)
return false;

// Deal with weird cases where the class only partially supports the subreg
Expand Down
31 changes: 9 additions & 22 deletions llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,6 @@ void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
printU32ImmOperand(MI, OpNo, STI, O);
}

void AMDGPUInstPrinter::printU4ImmDecOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
O << formatDec(MI->getOperand(OpNo).getImm() & 0xf);
}

void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);
Expand Down Expand Up @@ -719,29 +714,25 @@ void AMDGPUInstPrinter::printDefaultVccOperand(bool FirstOperand,
void AMDGPUInstPrinter::printWaitVDST(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
O << " wait_vdst:";
printU4ImmDecOperand(MI, OpNo, O);
O << " wait_vdst:" << formatDec(MI->getOperand(OpNo).getImm());
}

void AMDGPUInstPrinter::printWaitVAVDst(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
O << " wait_va_vdst:";
printU4ImmDecOperand(MI, OpNo, O);
O << " wait_va_vdst:" << formatDec(MI->getOperand(OpNo).getImm());
}

void AMDGPUInstPrinter::printWaitVMVSrc(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
O << " wait_vm_vsrc:";
printU4ImmDecOperand(MI, OpNo, O);
O << " wait_vm_vsrc:" << formatDec(MI->getOperand(OpNo).getImm());
}

void AMDGPUInstPrinter::printWaitEXP(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
O << " wait_exp:";
printU4ImmDecOperand(MI, OpNo, O);
O << " wait_exp:" << formatDec(MI->getOperand(OpNo).getImm());
}

bool AMDGPUInstPrinter::needsImpliedVcc(const MCInstrDesc &Desc,
Expand Down Expand Up @@ -1065,16 +1056,13 @@ void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
O << formatDec((Imm & 0xc0) >> 6) << ']';
} else if ((Imm >= DppCtrl::ROW_SHL_FIRST) &&
(Imm <= DppCtrl::ROW_SHL_LAST)) {
O << "row_shl:";
printU4ImmDecOperand(MI, OpNo, O);
O << "row_shl:" << formatDec(Imm - DppCtrl::ROW_SHL0);
} else if ((Imm >= DppCtrl::ROW_SHR_FIRST) &&
(Imm <= DppCtrl::ROW_SHR_LAST)) {
O << "row_shr:";
printU4ImmDecOperand(MI, OpNo, O);
O << "row_shr:" << formatDec(Imm - DppCtrl::ROW_SHR0);
} else if ((Imm >= DppCtrl::ROW_ROR_FIRST) &&
(Imm <= DppCtrl::ROW_ROR_LAST)) {
O << "row_ror:";
printU4ImmDecOperand(MI, OpNo, O);
O << "row_ror:" << formatDec(Imm - DppCtrl::ROW_ROR0);
} else if (Imm == DppCtrl::WAVE_SHL1) {
if (AMDGPU::isGFX10Plus(STI)) {
O << "/* wave_shl is not supported starting from GFX10 */";
Expand Down Expand Up @@ -1126,15 +1114,14 @@ void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
"than GFX90A/GFX10 */";
return;
}
printU4ImmDecOperand(MI, OpNo, O);
O << formatDec(Imm - DppCtrl::ROW_SHARE_FIRST);
} else if ((Imm >= DppCtrl::ROW_XMASK_FIRST) &&
(Imm <= DppCtrl::ROW_XMASK_LAST)) {
if (!AMDGPU::isGFX10Plus(STI)) {
O << "/* row_xmask is not supported on ASICs earlier than GFX10 */";
return;
}
O << "row_xmask:";
printU4ImmDecOperand(MI, OpNo, O);
O << "row_xmask:" << formatDec(Imm - DppCtrl::ROW_XMASK_FIRST);
} else {
O << "/* Invalid dpp_ctrl value */";
}
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ class AMDGPUInstPrinter : public MCInstPrinter {
private:
void printU16ImmOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
void printU4ImmDecOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
void printU16ImmDecOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
void printU32ImmOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
Expand Down
22 changes: 11 additions & 11 deletions llvm/lib/Target/AMDGPU/SMInstructions.td
Original file line number Diff line number Diff line change
Expand Up @@ -950,20 +950,20 @@ multiclass SMLoad_Pattern <string Instr, ValueType vt, bit immci = true> {
(vt (SIsbuffer_load v4i32:$sbase, (SMRDBufferImm32 i32:$offset), timm:$cachepolicy)),
(!cast<InstSI>(Instr#"_IMM_ci") SReg_128:$sbase, smrd_literal_offset:$offset,
(extract_cpol $cachepolicy))> {
let OtherPredicates = [isGFX7Only];
let SubtargetPredicate = isGFX7Only;
let AddedComplexity = 1;
}

// 3. Offset loaded in an 32bit SGPR
def : GCNPat <
(SIsbuffer_load v4i32:$sbase, i32:$soffset, timm:$cachepolicy),
(vt (!cast<SM_Pseudo>(Instr#"_SGPR") SReg_128:$sbase, SReg_32:$soffset, (extract_cpol $cachepolicy)))> {
let OtherPredicates = [isNotGFX9Plus];
let SubtargetPredicate = isNotGFX9Plus;
}
def : GCNPat <
(SIsbuffer_load v4i32:$sbase, i32:$soffset, timm:$cachepolicy),
(vt (!cast<SM_Pseudo>(Instr#"_SGPR_IMM") SReg_128:$sbase, SReg_32:$soffset, 0, (extract_cpol $cachepolicy)))> {
let OtherPredicates = [isGFX9Plus];
let SubtargetPredicate = isGFX9Plus;
}

// 4. Offset as an 32-bit SGPR + immediate
Expand All @@ -972,7 +972,7 @@ multiclass SMLoad_Pattern <string Instr, ValueType vt, bit immci = true> {
timm:$cachepolicy),
(vt (!cast<SM_Pseudo>(Instr#"_SGPR_IMM") SReg_128:$sbase, SReg_32:$soffset, i32imm:$offset,
(extract_cpol $cachepolicy)))> {
let OtherPredicates = [isGFX9Plus];
let SubtargetPredicate = isGFX9Plus;
}
}

Expand All @@ -981,28 +981,28 @@ multiclass ScalarLoadWithExtensionPat <string Instr, SDPatternOperator node, Val
def : GCNPat <
(node (SMRDImm i64:$sbase, i32:$offset)),
(vt (!cast<SM_Pseudo>(Instr#"_IMM") $sbase, $offset, 0))>{
let OtherPredicates = [isGFX12Plus];
let SubtargetPredicate = isGFX12Plus;
}

// 2. SGPR offset
def : GCNPat <
(node (SMRDSgpr i64:$sbase, i32:$soffset)),
(vt (!cast<SM_Pseudo>(Instr#"_SGPR_IMM") $sbase, $soffset, 0, 0))>{
let OtherPredicates = [isGFX12Plus];
let SubtargetPredicate = isGFX12Plus;
}

// 3. SGPR+IMM offset
def : GCNPat <
(node (SMRDSgprImm i64:$sbase, i32:$soffset, i32:$offset)),
(vt (!cast<SM_Pseudo>(Instr#"_SGPR_IMM") $sbase, $soffset, $offset, 0))>{
let OtherPredicates = [isGFX12Plus];
let SubtargetPredicate = isGFX12Plus;
}

// 4. No offset
def : GCNPat <
(vt (node (i64 SReg_64:$sbase))),
(vt (!cast<SM_Pseudo>(Instr#"_IMM") i64:$sbase, 0, 0))>{
let OtherPredicates = [isGFX12Plus];
let SubtargetPredicate = isGFX12Plus;
}
}

Expand All @@ -1012,14 +1012,14 @@ multiclass ScalarBufferLoadIntrinsicPat <SDPatternOperator name, string Instr> {
def : GCNPat <
(name v4i32:$sbase, (SMRDBufferImm i32:$offset), timm:$cachepolicy),
(i32 (!cast<SM_Pseudo>(Instr#"_IMM") SReg_128:$sbase, i32imm:$offset, (extract_cpol $cachepolicy)))> {
let OtherPredicates = [isGFX12Plus];
let SubtargetPredicate = isGFX12Plus;
}

// 2. Offset as an 32-bit SGPR
def : GCNPat <
(name v4i32:$sbase, i32:$soffset, timm:$cachepolicy),
(i32 (!cast<SM_Pseudo>(Instr#"_SGPR_IMM") SReg_128:$sbase, SReg_32:$soffset, 0, (extract_cpol $cachepolicy)))> {
let OtherPredicates = [isGFX12Plus];
let SubtargetPredicate = isGFX12Plus;
}

// 3. Offset as an 32-bit SGPR + immediate
Expand All @@ -1028,7 +1028,7 @@ multiclass ScalarBufferLoadIntrinsicPat <SDPatternOperator name, string Instr> {
timm:$cachepolicy),
(i32 (!cast<SM_Pseudo>(Instr#"_SGPR_IMM") SReg_128:$sbase, SReg_32:$soffset, i32imm:$offset,
(extract_cpol $cachepolicy)))> {
let OtherPredicates = [isGFX12Plus];
let SubtargetPredicate = isGFX12Plus;
}
}

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2311,7 +2311,7 @@ ARMBaseInstrInfo::canFoldIntoMOVCC(Register Reg, const MachineRegisterInfo &MRI,
return nullptr;
}
bool DontMoveAcrossStores = true;
if (!MI->isSafeToMove(/* AliasAnalysis = */ nullptr, DontMoveAcrossStores))
if (!MI->isSafeToMove(DontMoveAcrossStores))
return nullptr;
return MI;
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ bool DeadCodeElimination::runOnNode(MachineDomTreeNode *N) {
if (MI->isInlineAsm())
continue;
// Delete PHIs if possible.
if (!MI->isPHI() && !MI->isSafeToMove(nullptr, Store))
if (!MI->isPHI() && !MI->isSafeToMove(Store))
continue;

bool AllDead = true;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/Hexagon/HexagonGenInsert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1451,7 +1451,7 @@ bool HexagonGenInsert::removeDeadCode(MachineDomTreeNode *N) {
Opc == TargetOpcode::LIFETIME_END)
continue;
bool Store = false;
if (MI->isInlineAsm() || !MI->isSafeToMove(nullptr, Store))
if (MI->isInlineAsm() || !MI->isSafeToMove(Store))
continue;

bool AllDead = true;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/Lanai/LanaiInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ static MachineInstr *canFoldIntoSelect(Register Reg,
return nullptr;
}
bool DontMoveAcrossStores = true;
if (!MI->isSafeToMove(/*AliasAnalysis=*/nullptr, DontMoveAcrossStores))
if (!MI->isSafeToMove(DontMoveAcrossStores))
return nullptr;
return MI;
}
Expand Down
24 changes: 24 additions & 0 deletions llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,24 @@ class LoongArchOperand : public MCParsedAsmOperand {
IsValidKind;
}

bool isSImm20pcaddi() const {
if (!isImm())
return false;

int64_t Imm;
LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None;
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
bool IsValidKind = VK == LoongArchMCExpr::VK_LoongArch_None ||
VK == LoongArchMCExpr::VK_LoongArch_PCREL20_S2 ||
VK == LoongArchMCExpr::VK_LoongArch_TLS_LD_PCREL20_S2 ||
VK == LoongArchMCExpr::VK_LoongArch_TLS_GD_PCREL20_S2 ||
VK == LoongArchMCExpr::VK_LoongArch_TLS_DESC_PCREL20_S2;
return IsConstantImm
? isInt<20>(Imm) && IsValidKind
: LoongArchAsmParser::classifySymbolRef(getImm(), VK) &&
IsValidKind;
}

bool isSImm21lsl2() const {
if (!isImm())
return false;
Expand Down Expand Up @@ -1676,6 +1694,12 @@ bool LoongArchAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
/*Upper=*/(1 << 19) - 1,
"operand must be a symbol with modifier (e.g. %call36) or an integer "
"in the range");
case Match_InvalidSImm20pcaddi:
return generateImmOutOfRangeError(
Operands, ErrorInfo, /*Lower=*/-(1 << 19),
/*Upper=*/(1 << 19) - 1,
"operand must be a symbol with modifier (e.g. %pcrel_20) or an integer "
"in the range");
case Match_InvalidSImm21lsl2:
return generateImmOutOfRangeError(
Operands, ErrorInfo, /*Lower=*/-(1 << 22), /*Upper=*/(1 << 22) - 4,
Expand Down
6 changes: 5 additions & 1 deletion llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,10 @@ def simm20_pcaddu18i : SImm20Operand {
let ParserMatchClass = SImmAsmOperand<20, "pcaddu18i">;
}

def simm20_pcaddi : SImm20Operand {
let ParserMatchClass = SImmAsmOperand<20, "pcaddi">;
}

def simm21_lsl2 : Operand<OtherVT> {
let ParserMatchClass = SImmAsmOperand<21, "lsl2">;
let EncoderMethod = "getImmOpValueAsr<2>";
Expand Down Expand Up @@ -754,7 +758,7 @@ def SLT : ALU_3R<0x00120000>;
def SLTU : ALU_3R<0x00128000>;
def SLTI : ALU_2RI12<0x02000000, simm12>;
def SLTUI : ALU_2RI12<0x02400000, simm12>;
def PCADDI : ALU_1RI20<0x18000000, simm20>;
def PCADDI : ALU_1RI20<0x18000000, simm20_pcaddi>;
def PCADDU12I : ALU_1RI20<0x1c000000, simm20>;
def PCALAU12I : ALU_1RI20<0x1a000000, simm20_pcalau12i>;
def AND : ALU_3R<0x00148000>;
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchFixupKinds.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ enum Fixups {
fixup_loongarch_relax = FirstLiteralRelocationKind + ELF::R_LARCH_RELAX,
// Generate an R_LARCH_ALIGN which indicates the linker may fixup align here.
fixup_loongarch_align = FirstLiteralRelocationKind + ELF::R_LARCH_ALIGN,
// 20-bit fixup corresponding to %pcrel_20(foo) for instruction pcaddi.
fixup_loongarch_pcrel20_s2,
// 36-bit fixup corresponding to %call36(foo) for a pair instructions:
// pcaddu18i+jirl.
fixup_loongarch_call36 = FirstLiteralRelocationKind + ELF::R_LARCH_CALL36,
Expand Down Expand Up @@ -142,6 +144,12 @@ enum Fixups {
fixup_loongarch_tls_le_add_r,
// 12-bit fixup corresponding to %le_lo12_r(foo) for instruction addi.w/d.
fixup_loongarch_tls_le_lo12_r,
// 20-bit fixup corresponding to %ld_pcrel_20(foo) for instruction pcaddi.
fixup_loongarch_tls_ld_pcrel20_s2,
// 20-bit fixup corresponding to %gd_pcrel_20(foo) for instruction pcaddi.
fixup_loongarch_tls_gd_pcrel20_s2,
// 20-bit fixup corresponding to %desc_pcrel_20(foo) for instruction pcaddi.
fixup_loongarch_tls_desc_pcrel20_s2,
};
} // end namespace LoongArch
} // end namespace llvm
Expand Down
12 changes: 12 additions & 0 deletions llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,18 @@ LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO,
case LoongArchMCExpr::VK_LoongArch_TLS_LE_LO12_R:
FixupKind = LoongArch::fixup_loongarch_tls_le_lo12_r;
break;
case LoongArchMCExpr::VK_LoongArch_PCREL20_S2:
FixupKind = LoongArch::fixup_loongarch_pcrel20_s2;
break;
case LoongArchMCExpr::VK_LoongArch_TLS_LD_PCREL20_S2:
FixupKind = LoongArch::fixup_loongarch_tls_ld_pcrel20_s2;
break;
case LoongArchMCExpr::VK_LoongArch_TLS_GD_PCREL20_S2:
FixupKind = LoongArch::fixup_loongarch_tls_gd_pcrel20_s2;
break;
case LoongArchMCExpr::VK_LoongArch_TLS_DESC_PCREL20_S2:
FixupKind = LoongArch::fixup_loongarch_tls_desc_pcrel20_s2;
break;
}
} else if (Kind == MCExpr::SymbolRef &&
cast<MCSymbolRefExpr>(Expr)->getKind() ==
Expand Down
15 changes: 15 additions & 0 deletions llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,14 @@ StringRef LoongArchMCExpr::getVariantKindName(VariantKind Kind) {
return "le_add_r";
case VK_LoongArch_TLS_LE_LO12_R:
return "le_lo12_r";
case VK_LoongArch_PCREL20_S2:
return "pcrel_20";
case VK_LoongArch_TLS_LD_PCREL20_S2:
return "ld_pcrel_20";
case VK_LoongArch_TLS_GD_PCREL20_S2:
return "gd_pcrel_20";
case VK_LoongArch_TLS_DESC_PCREL20_S2:
return "desc_pcrel_20";
}
}

Expand Down Expand Up @@ -222,6 +230,10 @@ LoongArchMCExpr::getVariantKindForName(StringRef name) {
.Case("le_hi20_r", VK_LoongArch_TLS_LE_HI20_R)
.Case("le_add_r", VK_LoongArch_TLS_LE_ADD_R)
.Case("le_lo12_r", VK_LoongArch_TLS_LE_LO12_R)
.Case("pcrel_20", VK_LoongArch_PCREL20_S2)
.Case("ld_pcrel_20", VK_LoongArch_TLS_LD_PCREL20_S2)
.Case("gd_pcrel_20", VK_LoongArch_TLS_GD_PCREL20_S2)
.Case("desc_pcrel_20", VK_LoongArch_TLS_DESC_PCREL20_S2)
.Default(VK_LoongArch_Invalid);
}

Expand Down Expand Up @@ -264,6 +276,9 @@ void LoongArchMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
case VK_LoongArch_TLS_GD_HI20:
case VK_LoongArch_TLS_DESC_PC_HI20:
case VK_LoongArch_TLS_DESC_HI20:
case VK_LoongArch_TLS_LD_PCREL20_S2:
case VK_LoongArch_TLS_GD_PCREL20_S2:
case VK_LoongArch_TLS_DESC_PCREL20_S2:
break;
}
fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ class LoongArchMCExpr : public MCTargetExpr {
VK_LoongArch_TLS_LE_HI20_R,
VK_LoongArch_TLS_LE_ADD_R,
VK_LoongArch_TLS_LE_LO12_R,
VK_LoongArch_PCREL20_S2,
VK_LoongArch_TLS_LD_PCREL20_S2,
VK_LoongArch_TLS_GD_PCREL20_S2,
VK_LoongArch_TLS_DESC_PCREL20_S2,
VK_LoongArch_Invalid // Must be the last item.
};

Expand Down
8 changes: 3 additions & 5 deletions llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ void NVPTXAsmPrinter::emitFunctionEntryLabel() {
// Emit initial .loc debug directive for correct relocation symbol data.
if (const DISubprogram *SP = MF->getFunction().getSubprogram()) {
assert(SP->getUnit());
if (!SP->getUnit()->isDebugDirectivesOnly() && MMI && MMI->hasDebugInfo())
if (!SP->getUnit()->isDebugDirectivesOnly())
emitInitialRawDwarfLocDirective(*MF);
}
}
Expand Down Expand Up @@ -912,7 +912,7 @@ void NVPTXAsmPrinter::emitHeader(Module &M, raw_ostream &O,
if (HasFullDebugInfo)
break;
}
if (MMI && MMI->hasDebugInfo() && HasFullDebugInfo)
if (HasFullDebugInfo)
O << ", debug";

O << "\n";
Expand All @@ -928,8 +928,6 @@ void NVPTXAsmPrinter::emitHeader(Module &M, raw_ostream &O,
}

bool NVPTXAsmPrinter::doFinalization(Module &M) {
bool HasDebugInfo = MMI && MMI->hasDebugInfo();

// If we did not emit any functions, then the global declarations have not
// yet been emitted.
if (!GlobalsEmitted) {
Expand All @@ -945,7 +943,7 @@ bool NVPTXAsmPrinter::doFinalization(Module &M) {
auto *TS =
static_cast<NVPTXTargetStreamer *>(OutStreamer->getTargetStreamer());
// Close the last emitted section
if (HasDebugInfo) {
if (hasDebugInfo()) {
TS->closeLastSection();
// Emit empty .debug_loc section for better support of the empty files.
OutStreamer->emitRawText("\t.section\t.debug_loc\t{\t}");
Expand Down
12 changes: 6 additions & 6 deletions llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3137,11 +3137,11 @@ void PPCAIXAsmPrinter::emitInstruction(const MachineInstr *MI) {
break;
MCSymbol *TempSym = OutContext.createNamedTempSymbol();
OutStreamer->emitLabel(TempSym);
OutStreamer->emitXCOFFExceptDirective(CurrentFnSym, TempSym,
LangMO.getImm(), ReasonMO.getImm(),
Subtarget->isPPC64() ? MI->getMF()->getInstructionCount() * 8 :
MI->getMF()->getInstructionCount() * 4,
MMI->hasDebugInfo());
OutStreamer->emitXCOFFExceptDirective(
CurrentFnSym, TempSym, LangMO.getImm(), ReasonMO.getImm(),
Subtarget->isPPC64() ? MI->getMF()->getInstructionCount() * 8
: MI->getMF()->getInstructionCount() * 4,
hasDebugInfo());
break;
}
case PPC::GETtlsMOD32AIX:
Expand Down Expand Up @@ -3199,7 +3199,7 @@ void PPCAIXAsmPrinter::emitInstruction(const MachineInstr *MI) {

bool PPCAIXAsmPrinter::doFinalization(Module &M) {
// Do streamer related finalization for DWARF.
if (!MAI->usesDwarfFileAndLocDirectives() && MMI->hasDebugInfo())
if (!MAI->usesDwarfFileAndLocDirectives() && hasDebugInfo())
OutStreamer->doFinalizationAtSectionEnd(
OutStreamer->getContext().getObjectFileInfo()->getTextSection());

Expand Down
4 changes: 1 addition & 3 deletions llvm/lib/Target/RISCV/RISCVFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -1370,9 +1370,7 @@ def HasConditionalMoveFusion : Predicate<"Subtarget->hasConditionalMoveFusion()"
def NoConditionalMoveFusion : Predicate<"!Subtarget->hasConditionalMoveFusion()">;

def TuneSiFive7 : SubtargetFeature<"sifive7", "RISCVProcFamily", "SiFive7",
"SiFive 7-Series processors",
[TuneNoDefaultUnroll,
TuneShortForwardBranchOpt]>;
"SiFive 7-Series processors">;

def TuneVentanaVeyron : SubtargetFeature<"ventana-veyron", "RISCVProcFamily", "VentanaVeyron",
"Ventana Veyron-Series processors">;
Expand Down
Loading