Merge remote-tracking branch 'origin/master' into pre-monorepo

Conflicts:
	runtime/druntime
This commit is contained in:
Martin Kinkelin 2022-11-19 19:08:06 +01:00
commit 1e9f3a7be7
45 changed files with 3089 additions and 111 deletions

View file

@ -31,6 +31,10 @@ runs:
for mode in thin full; do
installed/bin/ldc2 hello.d -of=hello_$mode -flto=$mode -defaultlib=phobos2-ldc-lto,druntime-ldc-lto
./hello_$mode
if [[ '${{ runner.os }}' == Linux ]]; then
installed/bin/ldc2 hello.d -m32 -of=hello_$mode-32 -flto=$mode -defaultlib=phobos2-ldc-lto,druntime-ldc-lto
./hello_$mode-32
fi
done
- name: Run dynamic-compile integration test

View file

@ -34,7 +34,7 @@ find_package(LLVM 9.0 REQUIRED
instcombine ipo instrumentation irreader libdriver linker lto mc
mcdisassembler mcparser objcarcopts object option profiledata scalaropts
selectiondag support tablegen target transformutils vectorize
windowsmanifest ${EXTRA_LLVM_MODULES})
windowsdriver windowsmanifest ${EXTRA_LLVM_MODULES})
math(EXPR LDC_LLVM_VER ${LLVM_VERSION_MAJOR}*100+${LLVM_VERSION_MINOR})
message(STATUS "Using LLVM Version ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}")
# Remove LLVMTableGen library from list of libraries

View file

@ -32,7 +32,8 @@
# We also want an user-specified LLVM_ROOT_DIR to take precedence over the
# system default locations such as /usr/local/bin. Executing find_program()
# multiples times is the approach recommended in the docs.
set(llvm_config_names llvm-config-14.0 llvm-config140 llvm-config-14
set(llvm_config_names llvm-config-15.0 llvm-config150 llvm-config-15
llvm-config-14.0 llvm-config140 llvm-config-14
llvm-config-13.0 llvm-config130 llvm-config-13
llvm-config-12.0 llvm-config120 llvm-config-12
llvm-config-11.0 llvm-config110 llvm-config-11
@ -48,9 +49,11 @@ if(APPLE)
# extra fallbacks for MacPorts & Homebrew
find_program(LLVM_CONFIG
NAMES ${llvm_config_names}
PATHS /opt/local/libexec/llvm-14/bin /opt/local/libexec/llvm-13/bin /opt/local/libexec/llvm-12/bin
PATHS /opt/local/libexec/llvm-15/bin
/opt/local/libexec/llvm-14/bin /opt/local/libexec/llvm-13/bin /opt/local/libexec/llvm-12/bin
/opt/local/libexec/llvm-11/bin /opt/local/libexec/llvm-10/bin /opt/local/libexec/llvm-9.0/bin
/opt/local/libexec/llvm/bin
/usr/local/opt/llvm@15/bin
/usr/local/opt/llvm@14/bin /usr/local/opt/llvm@13/bin /usr/local/opt/llvm@12/bin
/usr/local/opt/llvm@11/bin /usr/local/opt/llvm@10/bin /usr/local/opt/llvm@9/bin
/usr/local/opt/llvm/bin
@ -123,6 +126,8 @@ else()
# The LLVM version string _may_ contain a git/svn suffix, so match only the x.y.z part
string(REGEX MATCH "^[0-9]+[.][0-9]+[.][0-9]+" LLVM_VERSION_BASE_STRING "${LLVM_VERSION_STRING}")
string(REGEX REPLACE "([0-9]+).*" "\\1" LLVM_VERSION_MAJOR "${LLVM_VERSION_STRING}" )
string(REGEX REPLACE "[0-9]+\\.([0-9]+).*[A-Za-z]*" "\\1" LLVM_VERSION_MINOR "${LLVM_VERSION_STRING}" )
llvm_set(SHARED_MODE shared-mode)
if(LLVM_SHARED_MODE STREQUAL "shared")
@ -138,6 +143,11 @@ else()
string(REPLACE "-llibxml2.tbd" "-lxml2" LLVM_LDFLAGS ${LLVM_LDFLAGS})
endif()
if(${LLVM_VERSION_MAJOR} LESS "15")
# Versions below 15.0 do not support component windowsdriver
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "windowsdriver")
endif()
llvm_set(LIBRARY_DIRS libdir true)
llvm_set_libs(LIBRARIES libs "${LLVM_FIND_COMPONENTS}")
# LLVM bug: llvm-config --libs tablegen returns -lLLVM-3.8.0
@ -181,9 +191,6 @@ else()
string(REPLACE "-Wno-maybe-uninitialized " "" LLVM_CXXFLAGS ${LLVM_CXXFLAGS})
endif()
string(REGEX REPLACE "([0-9]+).*" "\\1" LLVM_VERSION_MAJOR "${LLVM_VERSION_STRING}" )
string(REGEX REPLACE "[0-9]+\\.([0-9]+).*[A-Za-z]*" "\\1" LLVM_VERSION_MINOR "${LLVM_VERSION_STRING}" )
if (${LLVM_VERSION_STRING} VERSION_LESS ${LLVM_FIND_VERSION})
_LLVM_FAIL("Unsupported LLVM version ${LLVM_VERSION_STRING} found (${LLVM_CONFIG}). At least version ${LLVM_FIND_VERSION} is required. You can also set variables 'LLVM_ROOT_DIR' or 'LLVM_CONFIG' to use a different LLVM installation.")
endif()

View file

@ -528,6 +528,18 @@ cl::opt<bool> noPLT(
"fno-plt", cl::ZeroOrMore,
cl::desc("Do not use the PLT to make function calls"));
static cl::opt<signed char> passmanager("passmanager",
cl::desc("Setting the passmanager (new,legacy):"), cl::ZeroOrMore,
#if LDC_LLVM_VER < 1500
cl::init(0),
#else
cl::init(1),
#endif
cl::values(
clEnumValN(0, "legacy", "Use the legacy passmanager (available for LLVM14 and below) "),
clEnumValN(1, "new", "Use the new passmanager (available for LLVM14 and above)")));
bool isUsingLegacyPassManager() { return passmanager == 0; }
// Math options
bool fFastMath; // Storage for the dynamically created ffast-math option.
llvm::FastMathFlags defaultFMF;

View file

@ -90,6 +90,8 @@ extern cl::opt<bool> noPLT;
extern cl::opt<bool> useDIP25;
extern cl::opt<bool> useDIP1000;
bool isUsingLegacyPassManager();
// Math options
extern bool fFastMath;
extern llvm::FastMathFlags defaultFMF;

View file

@ -546,6 +546,20 @@ void parseCommandLine(Strings &sourceFiles) {
global.params.dihdr.fullOutput = opts::hdrKeepAllBodies;
global.params.disableRedZone = opts::disableRedZone();
// Passmanager selection options depend on LLVM version
#if LDC_LLVM_VER < 1400
// LLVM < 14 only supports the legacy passmanager
if (!opts::isUsingLegacyPassManager()) {
error(Loc(), "LLVM version 13 or below only supports --passmanager=legacy");
}
#endif
#if LDC_LLVM_VER >= 1500
// LLVM >= 15 only supports the new passmanager
if (opts::isUsingLegacyPassManager()) {
error(Loc(), "LLVM version 15 or above only supports --passmanager=new");
}
#endif
}
void initializePasses() {
@ -555,11 +569,16 @@ void initializePasses() {
initializeCore(Registry);
initializeTransformUtils(Registry);
initializeScalarOpts(Registry);
#if LDC_LLVM_VER < 1600
initializeObjCARCOpts(Registry);
#endif
initializeVectorization(Registry);
initializeInstCombine(Registry);
initializeAggressiveInstCombine(Registry);
initializeIPO(Registry);
#if LDC_LLVM_VER < 1600
initializeInstrumentation(Registry);
#endif
initializeAnalysis(Registry);
initializeCodeGen(Registry);
initializeGlobalISel(Registry);
@ -974,6 +993,13 @@ void registerPredefinedVersions() {
VersionCondition::addPredefinedGlobalIdent("LDC_ThreadSanitizer");
}
#if LDC_LLVM_VER >= 1400
// A version identifier for whether opaque pointers are enabled or not. (needed e.g. for intrinsic mangling)
if (!getGlobalContext().supportsTypedPointers()) {
VersionCondition::addPredefinedGlobalIdent("LDC_LLVM_OpaquePointers");
}
#endif
// Expose LLVM version to runtime
#define STR(x) #x
#define XSTR(x) STR(x)

View file

@ -17,21 +17,57 @@
#include "dmd/errors.h"
#include "dmd/globals.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/DynamicLibrary.h"
#if LDC_LLVM_VER >= 1400
#include "llvm/ADT/SmallVector.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Support/Error.h"
#include "driver/cl_options.h"
#endif
namespace {
namespace cl = llvm::cl;
cl::list<std::string>
pluginFiles("plugin", cl::CommaSeparated, cl::desc("Plugins to load."),
cl::list<std::string> pluginFiles("plugin", cl::CommaSeparated,
cl::desc("Pass plugins to load."),
cl::value_desc("dynamic_library.so,lib2.so"));
} // anonymous namespace
/// Loads all plugins. The static constructor of each plugin should take care of
/// the plugins registering themself with the rest of LDC/LLVM.
void loadAllPlugins() {
#if LDC_LLVM_VER >= 1400
namespace {
llvm::SmallVector<llvm::PassPlugin, 1> plugins;
}
/// Loads all plugins for the new pass manager. These plugins will need to be
/// added When building the optimization pipeline.
void loadAllPluginsNewPM() {
for (auto &filename : pluginFiles) {
auto plugin = llvm::PassPlugin::Load(filename);
if (!plugin) {
error(Loc(), "Error loading plugin '%s': %s", filename.c_str(),
llvm::toString(plugin.takeError()).c_str());
continue;
}
plugins.emplace_back(plugin.get());
}
}
void registerAllPluginsWithPassBuilder(llvm::PassBuilder &PB) {
for (auto &plugin : plugins) {
plugin.registerPassBuilderCallbacks(PB);
}
}
#endif // LDC_LLVM_VER >= 1400
/// Loads all plugins for the legacy pass manaager. The static constructor of
/// each plugin should take care of the plugins registering themself with the
/// rest of LDC/LLVM.
void loadAllPluginsLegacyPM() {
for (auto &filename : pluginFiles) {
std::string errorString;
if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(filename.c_str(),
@ -42,8 +78,21 @@ void loadAllPlugins() {
}
}
#if LDC_LLVM_VER >= 1400
void loadAllPlugins() {
if (opts::isUsingLegacyPassManager())
loadAllPluginsLegacyPM();
else
loadAllPluginsNewPM();
}
#else
void loadAllPlugins() { loadAllPluginsLegacyPM(); }
void registerAllPluginsWithPassBuilder(llvm::PassBuilder &) {}
#endif
#else // #if LDC_ENABLE_PLUGINS
void loadAllPlugins() {}
void registerAllPluginsWithPassBuilder(llvm::PassBuilder &) {}
#endif // LDC_ENABLE_PLUGINS

View file

@ -9,4 +9,7 @@
#pragma once
#include "llvm/Passes/PassBuilder.h"
void loadAllPlugins();
void registerAllPluginsWithPassBuilder(llvm::PassBuilder &PB);

View file

@ -16,8 +16,9 @@
struct NVPTXTargetABI : TargetABI {
DComputePointerRewrite pointerRewite;
llvm::CallingConv::ID callingConv(LINK) override {
llvm_unreachable("expected FuncDeclaration overload to be used");
llvm::CallingConv::ID callingConv(LINK l) override {
assert(l == LINK::c);
return llvm::CallingConv::PTX_Device;
}
llvm::CallingConv::ID callingConv(FuncDeclaration *fdecl) override {
return hasKernelAttr(fdecl) ? llvm::CallingConv::PTX_Kernel

View file

@ -16,8 +16,9 @@
struct SPIRVTargetABI : TargetABI {
DComputePointerRewrite pointerRewite;
llvm::CallingConv::ID callingConv(LINK) override {
llvm_unreachable("expected FuncDeclaration overload to be used");
llvm::CallingConv::ID callingConv(LINK l) override {
assert(l == LINK::c);
return llvm::CallingConv::SPIR_FUNC;
}
llvm::CallingConv::ID callingConv(FuncDeclaration *fdecl) override {
return hasKernelAttr(fdecl) ? llvm::CallingConv::SPIR_KERNEL

View file

@ -229,7 +229,7 @@ void DtoArrayAssign(const Loc &loc, DValue *lhs, DValue *rhs, EXP op,
LLValue *realRhsArrayPtr = (t2->ty == TY::Tarray || t2->ty == TY::Tsarray)
? DtoArrayPtr(rhs)
: nullptr;
if (realRhsArrayPtr && realRhsArrayPtr->getType() == realLhsPtr->getType()) {
if (realRhsArrayPtr && DtoMemType(t2->nextOf()) == DtoMemType(t->nextOf())) {
// T[] = T[] T[] = T[n]
// T[n] = T[n] T[n] = T[]
LLValue *rhsPtr = DtoBitCast(realRhsArrayPtr, getVoidPtrType());

View file

@ -1215,9 +1215,10 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
// function attributes
if (gABI->needsUnwindTables()) {
func->addFnAttr(LLAttribute::UWTable);
#if LDC_LLVM_VER >= 1500
func->setUWTableKind(llvm::UWTableKind::Default);
#else
func->addFnAttr(LLAttribute::UWTable);
#endif
}
if (opts::isAnySanitizerEnabled() &&

View file

@ -228,7 +228,11 @@ void DtoResolveNestedContext(const Loc &loc, AggregateDeclaration *decl,
unsigned idx = getVthisIdx(decl);
llvm::StructType *st = getIrAggr(decl, true)->getLLStructType();
LLValue *gep = DtoGEP(st, value, 0, idx, ".vthis");
#if LDC_LLVM_VER >= 1500
DtoStore(nest, gep);
#else
DtoStore(DtoBitCast(nest, gep->getType()->getContainedType(0)), gep);
#endif
}
}

View file

@ -18,6 +18,7 @@
#include "driver/cl_options.h"
#include "driver/cl_options_instrumentation.h"
#include "driver/cl_options_sanitizers.h"
#include "driver/plugins.h"
#include "driver/targetmachine.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/InlineCost.h"
@ -123,12 +124,6 @@ static cl::opt<int> fSanitizeMemoryTrackOrigins(
cl::desc(
"Enable origins tracking in MemorySanitizer (0=disabled, default)"));
static cl::opt<signed char> passmanager("passmanager",
cl::desc("Setting the passmanager (new,legacy):"), cl::ZeroOrMore, cl::init(0),
cl::values(
clEnumValN(0, "legacy", "Use the legacy passmanager (available for LLVM14 and below) "),
clEnumValN(1, "new", "Use the new passmanager (available for LLVM14 and above)")));
unsigned optLevel() {
// Use -O2 as a base for the size-optimization levels.
return optimizeLevel >= 0 ? optimizeLevel : 2;
@ -731,6 +726,8 @@ void runOptimizationPasses(llvm::Module *M) {
addStripExternalsPass(mpm, level);
});
registerAllPluginsWithPassBuilder(pb);
pb.registerModuleAnalyses(mam);
pb.registerCGSCCAnalyses(cgam);
pb.registerFunctionAnalyses(fam);
@ -839,7 +836,7 @@ bool ldc_optimize_module(llvm::Module *M) {
#if LDC_LLVM_VER < 1400
return legacy_ldc_optimize_module(M);
#elif LDC_LLVM_VER < 1500
return passmanager==0 ? legacy_ldc_optimize_module(M)
return opts::isUsingLegacyPassManager() ? legacy_ldc_optimize_module(M)
: new_ldc_optimize_module(M);
#else
return new_ldc_optimize_module(M);

View file

@ -32,6 +32,9 @@
#include "ir/irtypefunction.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/IR/Attributes.h"
#if LDC_LLVM_VER >= 1600
#include "llvm/IR/ModRef.h"
#endif
#include "llvm/IR/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MemoryBuffer.h"
@ -272,9 +275,10 @@ struct LazyFunctionDeclarer {
// FIXME: Move to better place (abi-x86-64.cpp?)
// NOTE: There are several occurances if this line.
if (global.params.targetTriple->getArch() == llvm::Triple::x86_64) {
fn->addFnAttr(LLAttribute::UWTable);
#if LDC_LLVM_VER >= 1500
fn->setUWTableKind(llvm::UWTableKind::Default);
#else
fn->addFnAttr(LLAttribute::UWTable);
#endif
}
@ -467,7 +471,8 @@ static Type *rt_dg2() {
static void buildRuntimeModule() {
Logger::println("building runtime module");
M = new llvm::Module("ldc internal runtime", gIR->context());
auto &context = gIR->context();
M = new llvm::Module("ldc internal runtime", context);
Type *voidTy = Type::tvoid;
Type *boolTy = Type::tbool;
@ -496,8 +501,14 @@ static void buildRuntimeModule() {
AttrSet NoAttrs,
Attr_NoUnwind(NoAttrs, LLAttributeList::FunctionIndex,
llvm::Attribute::NoUnwind),
#if LDC_LLVM_VER >= 1600
Attr_ReadOnly(llvm::AttributeList().addFnAttribute(
context, llvm::Attribute::getWithMemoryEffects(
context, llvm::MemoryEffects::readOnly()))),
#else
Attr_ReadOnly(NoAttrs, LLAttributeList::FunctionIndex,
llvm::Attribute::ReadOnly),
#endif
Attr_Cold(NoAttrs, LLAttributeList::FunctionIndex, llvm::Attribute::Cold),
Attr_Cold_NoReturn(Attr_Cold, LLAttributeList::FunctionIndex,
llvm::Attribute::NoReturn),

View file

@ -799,6 +799,9 @@ build_jit_runtime("${D_FLAGS};${D_FLAGS_RELEASE}" "${RT_CFLAGS}" "${LD_FLAGS}" "
# Add the (static- and release-only) bitcode libraries.
if(BUILD_LTO_LIBS AND (NOT ${BUILD_SHARED_LIBS} STREQUAL "ON"))
list(APPEND libs_to_install druntime-ldc-lto phobos2-ldc-lto)
if(MULTILIB)
list(APPEND libs_to_install druntime-ldc-lto_${MULTILIB_SUFFIX} phobos2-ldc-lto_${MULTILIB_SUFFIX})
endif()
endif()
foreach(libname ${libs_to_install})

@ -1 +1 @@
Subproject commit d7fae40096ab85fb4cd7202c5f466deb83aeaa83
Subproject commit f8163d1e6b6327bd2364d2f4c989b04a864031f0

View file

@ -28,7 +28,7 @@ extern(C): // simplify name mangling for simpler string matching
// PROFGEN-LABEL: @for_loop()
// PROFUSE-LABEL: @for_loop()
// PROFGEN: store {{.*}} @[[FL]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[FL]]
// PROFUSE-SAME: !prof ![[FL0:[0-9]+]]
void for_loop() {
uint i;
@ -63,7 +63,7 @@ void for_loop() {
// PROFGEN-LABEL: @foreach_loop()
// PROFUSE-LABEL: @foreach_loop()
// PROFGEN: store {{.*}} @[[FEL]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[FEL]]
// PROFUSE-SAME: !prof ![[FEL0:[0-9]+]]
void foreach_loop() {
// PROFGEN: store {{.*}} @[[FEL]], i{{32|64}} 0, i{{32|64}} 1
@ -88,7 +88,7 @@ void foreach_loop() {
// PROFGEN-LABEL: @foreachrange_loop()
// PROFUSE-LABEL: @foreachrange_loop()
// PROFGEN: store {{.*}} @[[FERL]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[FERL]]
// PROFUSE-SAME: !prof ![[FERL0:[0-9]+]]
void foreachrange_loop() {
import std.range : iota;
@ -118,7 +118,7 @@ void foreachrange_loop() {
// PROFGEN-LABEL: @label_goto()
// PROFUSE-LABEL: @label_goto()
// PROFGEN: store {{.*}} @[[LG]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[LG]]
// PROFUSE-SAME: !prof ![[LG0:[0-9]+]]
void label_goto() {
int i = 0; // 1x
@ -149,7 +149,7 @@ emptylabel: // 1x
// PROFGEN-LABEL: @c_switches()
// PROFUSE-LABEL: @c_switches()
// PROFGEN: store {{.*}} @[[SWC]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[SWC]]
// PROFUSE-SAME: !prof ![[SW0:[0-9]+]]
void c_switches() {
static int[] weights = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5];
@ -238,7 +238,7 @@ void c_switches() {
// test the particulars of switches using D features
// PROFGEN-LABEL: @d_switches()
// PROFUSE-LABEL: @d_switches()
// PROFGEN: store {{.*}} @[[DSW]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[DSW]]
// PROFUSE-SAME: !prof ![[DSW0:[0-9]+]]
void d_switches() {
uint i;
@ -297,7 +297,7 @@ void d_switches() {
// PROFGEN-LABEL: @booleanlogic()
// PROFUSE-LABEL: @booleanlogic()
// PROFGEN: store {{.*}} @[[BOOL]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[BOOL]]
// PROFUSE-SAME: !prof ![[BOOL0:[0-9]+]]
void booleanlogic() {
bool t = true, f = false;
@ -335,7 +335,7 @@ void booleanlogic() {
// PROFGEN-LABEL: @do_while()
// PROFUSE-LABEL: @do_while()
// PROFGEN: store {{.*}} @[[DW]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[DW]]
// PROFUSE-SAME: !prof ![[DW0:[0-9]+]]
void do_while() {
int i;

View file

@ -18,7 +18,7 @@
// PROFGEN: @[[MAIN:__(llvm_profile_counters|profc)__Dmain]] ={{.*}} global [1 x i64] zeroinitializer
// PROFGEN-LABEL: @_Dmain(
// PROFGEN: store {{.*}} @[[MAIN]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[MAIN]]
@safe:
void main() {
int[] array = [1,2,3];

View file

@ -16,7 +16,7 @@ extern(C): // simplify name mangling for simpler string matching
// PROFGEN-LABEL: @bunch_of_branches(i32
// PROFUSE-LABEL: @bunch_of_branches(i32
// PROFGEN: store {{.*}} @[[BoB]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[BoB]]
// PROFUSE-SAME: !prof ![[BoB0:[0-9]+]]
void bunch_of_branches(const uint two) {
uint i;

View file

@ -17,7 +17,7 @@ extern(C): // simplify name mangling for simpler string matching
// PROFGEN-LABEL: @testbreak({{.*}})
// PROFUSE-LABEL: @testbreak({{.*}})
// PROFGEN: store {{.*}} @[[BREAK]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[BREAK]]
// PROFUSE-SAME: !prof ![[BREAK0:[0-9]+]]
void testbreak(bool a) {
@ -51,7 +51,7 @@ outer:
// PROFGEN-LABEL: @testcontinue({{.*}})
// PROFUSE-LABEL: @testcontinue({{.*}})
// PROFGEN: store {{.*}} @[[CONT]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[CONT]]
// PROFUSE-SAME: !prof ![[CONT0:[0-9]+]]
void testcontinue(bool a) {

View file

@ -28,7 +28,7 @@ class ExceptionThree : Exception {
// PROFGEN-LABEL: @scope_stmts(
// PROFUSE-LABEL: @scope_stmts(
// PROFGEN: store {{.*}} @[[SCP]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[SCP]]
// PROFUSE-SAME: !prof ![[SCP0:[0-9]+]]
void scope_stmts(bool fail) {
int i;
@ -50,7 +50,7 @@ void scope_stmts(bool fail) {
// PROFGEN-LABEL: @try_catch()
// PROFUSE-LABEL: @try_catch()
// PROFGEN: store {{.*}} @[[TC]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[TC]]
// PROFUSE-SAME: !prof ![[TC0:[0-9]+]]
void try_catch() {
// PROFGEN: store {{.*}} @[[TC]], i{{32|64}} 0, i{{32|64}} 1
@ -110,7 +110,7 @@ void try_catch() {
// PROFGEN-LABEL: @try_finally()
// PROFUSE-LABEL: @try_finally()
// PROFGEN: store {{.*}} @[[TF]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[TF]]
// PROFUSE-SAME: !prof ![[TF0:[0-9]+]]
void try_finally() {
int i;

View file

@ -32,7 +32,7 @@
// PROFGEN-LABEL: define {{.*}} @{{.*}}simplefunction{{.*}}(
// PROFUSE-LABEL: define {{.*}} @{{.*}}simplefunction{{.*}}(
// PROFGEN: store {{.*}} @[[SMPL]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[SMPL]]
// PROFUSE-SAME: !prof ![[SMPL0:[0-9]+]]
void simplefunction(int i) {
// PROFGEN: store {{.*}} @[[SMPL]], i{{32|64}} 0, i{{32|64}} 1
@ -43,7 +43,7 @@ void simplefunction(int i) {
// PROFGEN-LABEL: define {{.*}} @{{.*}}templatefunc{{.*}}(
// PROFUSE-LABEL: define {{.*}} @{{.*}}templatefunc{{.*}}(
// PROFGEN: store {{.*}} @[[TMPL]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[TMPL]]
// PROFUSE-SAME: !prof ![[TMPL0:[0-9]+]]
void templatefunc(T)(T i) {
// PROFGEN: store {{.*}} @[[TMPL]], i{{32|64}} 0, i{{32|64}} 1
@ -59,13 +59,13 @@ void call_templatefunc(int i) {
// PROFGEN-LABEL: define {{.*}} @{{.*}}outerfunc{{.*}}(
// PROFUSE-LABEL: define {{.*}} @{{.*}}outerfunc{{.*}}(
// PROFGEN: store {{.*}} @[[OUTR]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[OUTR]]
// PROFUSE-SAME: !prof ![[OUTR0:[0-9]+]]
// PROFGEN: store {{.*}} @[[OUTR]], i{{32|64}} 0, i{{32|64}} 1
// PROFUSE: br {{.*}} !prof ![[OUTR1:[0-9]+]]
// PROFGEN-LABEL: define {{.*}} @{{.*}}nestedfunc{{.*}}(
// PROFUSE-LABEL: define {{.*}} @{{.*}}nestedfunc{{.*}}(
// PROFGEN: store {{.*}} @[[NEST]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[NEST]]
// PROFUSE-SAME: !prof ![[NEST0:[0-9]+]]
// PROFGEN: store {{.*}} @[[NEST]], i{{32|64}} 0, i{{32|64}} 1
// PROFUSE: br {{.*}} !prof ![[NEST1:[0-9]+]]
@ -83,7 +83,7 @@ void takedelegate(int i, int delegate(int) fd) {
}
// PROFGEN-LABEL: define {{.*}} @{{.*}}testanonymous{{.*}}lambda{{.*}}(
// PROFUSE-LABEL: define {{.*}} @{{.*}}testanonymous{{.*}}lambda{{.*}}(
// PROFGEN: store {{.*}} @[[LMBD]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[LMBD]]
// PROFUSE-SAME: !prof ![[LMBD0:[0-9]+]]
// PROFGEN: store {{.*}} @[[LMBD]], i{{32|64}} 0, i{{32|64}} 1
// PROFUSE: br {{.*}} !prof ![[LMBD1:[0-9]+]]
@ -97,7 +97,7 @@ class Klass {
// PROFGEN-LABEL: define {{.*}} @{{.*}}Klass{{.*}}__ctor{{.*}}(
// PROFUSE-LABEL: define {{.*}} @{{.*}}Klass{{.*}}__ctor{{.*}}(
// PROFGEN: store {{.*}} @[[KCTR]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[KCTR]]
// PROFUSE-SAME: !prof ![[KCTR0:[0-9]+]]
// PROFGEN: store {{.*}} @[[KCTR]], i{{32|64}} 0, i{{32|64}} 1
// PROFUSE: br {{.*}} !prof ![[KCTR1:[0-9]+]]
@ -108,7 +108,7 @@ class Klass {
// PROFGEN-LABEL: define {{.*}} @{{.*}}Klass{{.*}}__dtor{{.*}}(
// PROFUSE-LABEL: define {{.*}} @{{.*}}Klass{{.*}}__dtor{{.*}}(
// PROFGEN: store {{.*}} @[[KDTR]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[KDTR]]
// PROFUSE-SAME: !prof ![[KDTR0:[0-9]+]]
// PROFGEN: store {{.*}} @[[KDTR]], i{{32|64}} 0, i{{32|64}} 1
// PROFUSE: br {{.*}} !prof ![[KDTR1:[0-9]+]]
@ -118,7 +118,7 @@ class Klass {
// PROFGEN-LABEL: define {{.*}} @{{.*}}Klass{{.*}}stdmethod{{.*}}(
// PROFUSE-LABEL: define {{.*}} @{{.*}}Klass{{.*}}stdmethod{{.*}}(
// PROFGEN: store {{.*}} @[[KMTH]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[KMTH]]
// PROFUSE-SAME: !prof ![[KMTH0:[0-9]+]]
// PROFGEN: store {{.*}} @[[KMTH]], i{{32|64}} 0, i{{32|64}} 1
// PROFUSE: br {{.*}} !prof ![[KMTH1:[0-9]+]]
@ -128,7 +128,7 @@ class Klass {
// PROFGEN-LABEL: define {{.*}} @{{.*}}Klass{{.*}}staticmethod{{.*}}(
// PROFUSE-LABEL: define {{.*}} @{{.*}}Klass{{.*}}staticmethod{{.*}}(
// PROFGEN: store {{.*}} @[[KSTC]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[KSTC]]
// PROFUSE-SAME: !prof ![[KSTC0:[0-9]+]]
// PROFGEN: store {{.*}} @[[KSTC]], i{{32|64}} 0, i{{32|64}} 1
// PROFUSE: br {{.*}} !prof ![[KSTC1:[0-9]+]]
@ -143,7 +143,7 @@ struct Strukt {
// PROFGEN-LABEL: define {{.*}} @{{.*}}Strukt{{.*}}__ctor{{.*}}(
// PROFUSE-LABEL: define {{.*}} @{{.*}}Strukt{{.*}}__ctor{{.*}}(
// PROFGEN: store {{.*}} @[[SCTR]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[SCTR]]
// PROFUSE-SAME: !prof ![[SCTR0:[0-9]+]]
// PROFGEN: store {{.*}} @[[SCTR]], i{{32|64}} 0, i{{32|64}} 1
// PROFUSE: br {{.*}} !prof ![[SCTR1:[0-9]+]]
@ -154,7 +154,7 @@ struct Strukt {
// PROFGEN-LABEL: define {{.*}} @{{.*}}Strukt{{.*}}stdmethod{{.*}}(
// PROFUSE-LABEL: define {{.*}} @{{.*}}Strukt{{.*}}stdmethod{{.*}}(
// PROFGEN: store {{.*}} @[[SMTH]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[SMTH]]
// PROFUSE-SAME: !prof ![[SMTH0:[0-9]+]]
// PROFGEN: store {{.*}} @[[SMTH]], i{{32|64}} 0, i{{32|64}} 1
// PROFUSE: br {{.*}} !prof ![[SMTH1:[0-9]+]]
@ -164,7 +164,7 @@ struct Strukt {
// PROFGEN-LABEL: define {{.*}} @{{.*}}Strukt{{.*}}__dtor{{.*}}(
// PROFUSE-LABEL: define {{.*}} @{{.*}}Strukt{{.*}}__dtor{{.*}}(
// PROFGEN: store {{.*}} @[[SDTR]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[SDTR]]
// PROFUSE-SAME: !prof ![[SDTR0:[0-9]+]]
// PROFGEN: store {{.*}} @[[SDTR]], i{{32|64}} 0, i{{32|64}} 1
// PROFUSE: br {{.*}} !prof ![[SDTR1:[0-9]+]]
@ -175,7 +175,7 @@ struct Strukt {
// PROFGEN-LABEL: define {{.*}} @{{.*}}contractprog{{.*}}(
// PROFUSE-LABEL: define {{.*}} @{{.*}}contractprog{{.*}}(
// PROFGEN: store {{.*}} @[[CNTR]], i{{32|64}} 0, i{{32|64}} 0
// PROFGEN: store {{.*}} @[[CNTR]]
// PROFUSE-SAME: !prof ![[CNTR0:[0-9]+]]
void contractprog(int i)
in {

View file

@ -50,8 +50,8 @@ int main()
{
select_func(i);
// PROFUSE: [[REG1:%[0-9]+]] = load void ()*, void ()** @foo
// PROFUSE: [[REG2:%[0-9]+]] = icmp eq void ()* [[REG1]], @hot
// PROFUSE: [[REG1:%[0-9]+]] = load {{void \(\)\*, void \(\)\*\*|ptr, ptr}} @foo
// PROFUSE: [[REG2:%[0-9]+]] = icmp eq {{void \(\)\*|ptr}} [[REG1]], @hot
// PROFUSE: call void @hot()
// PROFUSE: call void [[REG1]]()

View file

@ -42,7 +42,7 @@ void indirectOutput(uint eax)
uint[4] r = void;
// CHECK-NEXT: %1 = load i32, {{i32\*|ptr}} %eax
// CHECK-NEXT: call void asm sideeffect "cpuid
// CHECK-SAME: "=*m,{eax},~{eax},~{ebx},~{ecx},~{edx}"([4 x i32]* {{(elementtype\(\[4 x i32\]\) )?}}%r, i32 %1), !srcloc
// CHECK-SAME: "=*m,{eax},~{eax},~{ebx},~{ecx},~{edx}"({{\[4 x i32\]\*|ptr}} {{(elementtype\(\[4 x i32\]\) )?}}%r, i32 %1), !srcloc
asm
{
`cpuid

View file

@ -83,7 +83,7 @@ void tupleassignByVal()
// CHECK: alloca %assign_struct_init_without_stack.OpAssignStruct
// CHECK: call void @llvm.memcpy
// CHECK-NOT: memcpy
// CHECK: call{{.*}} %assign_struct_init_without_stack.OpAssignStruct* @{{.*}}_D32assign_struct_init_without_stack14OpAssignStruct__T8opAssignTSQCmQBhZQsMFNaNbNcNiNjNfQyZQBb
// CHECK: call{{.*}} {{%assign_struct_init_without_stack\.OpAssignStruct\*|ptr}} @{{.*}}_D32assign_struct_init_without_stack14OpAssignStruct__T8opAssignTSQCmQBhZQsMFNaNbNcNiNjNfQyZQBb
// CHECK-NEXT: ret void
}
@ -93,7 +93,7 @@ void tupleassignByRef()
globalOpAssignStruct = globalOpAssignStruct2;
// There should not be a memcpy.
// CHECK-NOT: memcpy
// CHECK: call{{.*}} %assign_struct_init_without_stack.OpAssignStruct* @{{.*}}_D32assign_struct_init_without_stack14OpAssignStruct__T8opAssignTSQCmQBhZQsMFNaNbNcNiNjNfKQzZQBc
// CHECK: call{{.*}} {{%assign_struct_init_without_stack\.OpAssignStruct\*|ptr}} @{{.*}}_D32assign_struct_init_without_stack14OpAssignStruct__T8opAssignTSQCmQBhZQsMFNaNbNcNiNjNfKQzZQBc
// CHECK-NEXT: ret void
}

View file

@ -2,7 +2,7 @@
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// CHECK: @llvm.used = appending global {{.*}} @some_function {{.*}} @some_variable
// CHECK: @llvm.used = appending global {{.*}} @some_function{{.*}} @some_variable
static import ldc.attributes;

View file

@ -3,34 +3,34 @@
@compute(CompileFor.deviceOnly) module dcompute_cu_addrspaces;
import ldc.dcompute;
// LL: %"ldc.dcompute.Pointer!(AddrSpace.Private, float).Pointer" = type { float addrspace(5)* }
// LL: %"ldc.dcompute.Pointer!(AddrSpace.Global, float).Pointer" = type { float addrspace(1)* }
// LL: %"ldc.dcompute.Pointer!(AddrSpace.Shared, float).Pointer" = type { float addrspace(3)* }
// LL: %"ldc.dcompute.Pointer!(AddrSpace.Constant, immutable(float)).Pointer" = type { float addrspace(4)* }
// LL: %"ldc.dcompute.Pointer!(AddrSpace.Generic, float).Pointer" = type { float* }
// LL: %"ldc.dcompute.Pointer!(AddrSpace.Private, float).Pointer" = type { {{float addrspace\(5\)\*|ptr addrspace\(5\)}} }
// LL: %"ldc.dcompute.Pointer!(AddrSpace.Global, float).Pointer" = type { {{float addrspace\(1\)\*|ptr addrspace\(1\)}} }
// LL: %"ldc.dcompute.Pointer!(AddrSpace.Shared, float).Pointer" = type { {{float addrspace\(3\)\*|ptr addrspace\(3\)}} }
// LL: %"ldc.dcompute.Pointer!(AddrSpace.Constant, immutable(float)).Pointer" = type { {{float addrspace\(4\)\*|ptr addrspace\(4\)}} }
// LL: %"ldc.dcompute.Pointer!(AddrSpace.Generic, float).Pointer" = type { {{float\*|ptr}} }
void foo(PrivatePointer!float f) {
// LL: load float, float addrspace(5)*
// LL: load float, {{float addrspace\(5\)\*|ptr addrspace\(5\)}}
// PTX: ld.local.f32
float g = *f;
}
void foo(GlobalPointer!float f) {
// LL: load float, float addrspace(1)*
// LL: load float, {{float addrspace\(1\)\*|ptr addrspace\(1\)}}
// PTX: ld.global.f32
float g = *f;
}
void foo(SharedPointer!float f) {
// LL: load float, float addrspace(3)*
// LL: load float, {{float addrspace\(3\)\*|ptr addrspace\(3\)}}
// PTX: ld.shared.f32
float g = *f;
}
void foo(ConstantPointer!float f) {
// LL: load float, float addrspace(4)*
// LL: load float, {{float addrspace\(4\)\*|ptr addrspace\(4\)}}
// PTX: ld.const.f32
float g = *f;
}
void foo(GenericPointer!float f) {
// LL: load float, float*
// LL: load float, {{float\*|ptr}}
// PTX: ld.f32
float g = *f;
}

View file

@ -28,34 +28,34 @@ void foo(GlobalPointer!float x_in) {
PrivatePointer!float private_x;
ConstantPointer!float const_x;
// LL: [[s_load_reg:%[0-9]*]] = load float*, float** {{%[0-9]*}}
// LL: [[s_addr_reg:%[0-9]*]] = load float*, float** {{%[0-9]*}}
// LL: [[s_store_reg:%[0-9]*]] = load float, float* [[s_addr_reg]]
// LL: store float [[s_store_reg]], float* [[s_load_reg]]
// LL: [[s_load_reg:%[0-9]*]] = load {{float\*|ptr}}, {{float\*\*|ptr}} {{%[0-9]*}}
// LL: [[s_addr_reg:%[0-9]*]] = load {{float\*|ptr}}, {{float\*\*|ptr}} {{%[0-9]*}}
// LL: [[s_store_reg:%[0-9]*]] = load float, {{float\*|ptr}} [[s_addr_reg]]
// LL: store float [[s_store_reg]], {{float\*|ptr}} [[s_load_reg]]
*shared_x = *x_in;
// LL: [[p_load_reg:%[0-9]*]] = load float*, float** {{%[0-9]*}}
// LL: [[p_addr_reg:%[0-9]*]] = load float*, float** {{%[0-9]*}}
// LL: [[p_store_reg:%[0-9]*]] = load float, float* [[p_addr_reg]]
// LL: store float [[p_store_reg]], float* [[p_load_reg]]
// LL: [[p_load_reg:%[0-9]*]] = load {{float\*|ptr}}, {{float\*\*|ptr}} {{%[0-9]*}}
// LL: [[p_addr_reg:%[0-9]*]] = load {{float\*|ptr}}, {{float\*\*|ptr}} {{%[0-9]*}}
// LL: [[p_store_reg:%[0-9]*]] = load float, {{float\*|ptr}} [[p_addr_reg]]
// LL: store float [[p_store_reg]], {{float\*|ptr}} [[p_load_reg]]
*private_x = *x_in;
// LL: [[c_load_reg:%[0-9]*]] = load float*, float** {{%[0-9]*}}
// LL: [[c_addr_reg:%[0-9]*]] = load float*, float** {{%[0-9]*}}
// LL: [[c_store_reg:%[0-9]*]] = load float, float* [[c_addr_reg]]
// LL: store float [[c_store_reg]], float* [[c_load_reg]]
// LL: [[c_load_reg:%[0-9]*]] = load {{float\*|ptr}}, {{float\*\*|ptr}} {{%[0-9]*}}
// LL: [[c_addr_reg:%[0-9]*]] = load {{float\*|ptr}}, {{float\*\*|ptr}} {{%[0-9]*}}
// LL: [[c_store_reg:%[0-9]*]] = load float, {{float\*|ptr}} [[c_addr_reg]]
// LL: store float [[c_store_reg]], {{float\*|ptr}} [[c_load_reg]]
*x_in = *const_x;
// LL: [[g1_load_reg:%[0-9]*]] = load float*, float** {{%[0-9]*}}
// LL: [[g1_addr_reg:%[0-9]*]] = load float*, float** {{%[0-9]*}}
// LL: [[g1_store_reg:%[0-9]*]] = load float, float* [[g1_addr_reg]]
// LL: store float [[g1_store_reg]], float* [[g1_load_reg]]
// LL: [[g1_load_reg:%[0-9]*]] = load {{float\*|ptr}}, {{float\*\*|ptr}} {{%[0-9]*}}
// LL: [[g1_addr_reg:%[0-9]*]] = load {{float\*|ptr}}, {{float\*\*|ptr}} {{%[0-9]*}}
// LL: [[g1_store_reg:%[0-9]*]] = load float, {{float\*|ptr}} [[g1_addr_reg]]
// LL: store float [[g1_store_reg]], {{float\*|ptr}} [[g1_load_reg]]
*x_in = *shared_x;
// LL: [[g2_load_reg:%[0-9]*]] = load float*, float** {{%[0-9]*}}
// LL: [[g2_addr_reg:%[0-9]*]] = load float*, float** {{%[0-9]*}}
// LL: [[g2_store_reg:%[0-9]*]] = load float, float* [[g2_addr_reg]]
// LL: store float [[g2_store_reg]], float* [[g2_load_reg]]
// LL: [[g2_load_reg:%[0-9]*]] = load {{float\*|ptr}}, {{float\*\*|ptr}} {{%[0-9]*}}
// LL: [[g2_addr_reg:%[0-9]*]] = load {{float\*|ptr}}, {{float\*\*|ptr}} {{%[0-9]*}}
// LL: [[g2_store_reg:%[0-9]*]] = load float, {{float\*|ptr}} [[g2_addr_reg]]
// LL: store float [[g2_store_reg]], {{float\*|ptr}} [[g2_load_reg]]
*x_in = *private_x;
}

View file

@ -2,7 +2,7 @@
void foo()
{
// CHECK: %1 = getelementptr {{.*}}_D6gh28653fooFZv{{.*}} to i8*), i32 -10
// CHECK-NEXT: %2 = ptrtoint i8* %1 to i{{32|64}}
// CHECK: %1 = getelementptr inbounds i8,{{.*}}_D6gh28653fooFZv{{.*}}, i32 -10
// CHECK-NEXT: %2 = ptrtoint {{i8\*|ptr}} %1 to i{{32|64}}
auto addr = (cast(size_t) &foo) - 10;
}

View file

@ -1,6 +1,7 @@
// https://github.com/ldc-developers/ldc/issues/3692
// REQUIRES: target_X86
// REQUIRES: atmost_llvm1409
// RUN: %ldc -mtriple=x86_64-linux-gnu -output-ll -of=%t.ll %s
// RUN: FileCheck %s < %t.ll

View file

@ -0,0 +1,46 @@
// https://github.com/ldc-developers/ldc/issues/3692
// REQUIRES: target_X86
// REQUIRES: atleast_llvm1500
// RUN: %ldc -mtriple=x86_64-linux-gnu -output-ll -of=%t.ll %s
// RUN: FileCheck %s < %t.ll
// D `int[3]` rewritten to LL `{ i64, i32 }` for SysV ABI - mismatching size and alignment
// CHECK: define void @_D13gh3692_llvm154takeFG3iZv({ i64, i32 } %a_arg)
void take(int[3] a)
{
// the `{ i64, i32 }` size is 16 bytes, so we need a padded alloca (with 8-bytes alignment)
// CHECK-NEXT: %a = alloca { i64, i32 }, align 8
// CHECK-NEXT: store { i64, i32 } %a_arg, ptr %a
}
// CHECK: define void @_D13gh3692_llvm154passFZv()
void pass()
{
// CHECK-NEXT: %arrayliteral = alloca [3 x i32], align 4
// we need an extra padded alloca with proper alignment
// CHECK-NEXT: %.BaseBitcastABIRewrite_padded_arg_storage = alloca { i64, i32 }, align 8
// CHECK: %.BaseBitcastABIRewrite_arg = load { i64, i32 }, ptr %.BaseBitcastABIRewrite_padded_arg_storage
take([1, 2, 3]);
}
// D `int[4]` rewritten to LL `{ i64, i64 }` for SysV ABI - mismatching alignment only
// CHECK: define void @_D13gh3692_llvm155take4FG4iZv({ i64, i64 } %a_arg)
void take4(int[4] a)
{
// the alloca should have 8-bytes alignment, even though a.alignof == 4
// CHECK-NEXT: %a = alloca [4 x i32], align 8
// CHECK-NEXT: store { i64, i64 } %a_arg, ptr %a
}
// CHECK: define void @_D13gh3692_llvm155pass4FZv()
void pass4()
{
// CHECK-NEXT: %arrayliteral = alloca [4 x i32], align 4
// we need an extra alloca with 8-bytes alignment
// CHECK-NEXT: %.BaseBitcastABIRewrite_padded_arg_storage = alloca { i64, i64 }, align 8
// CHECK: %.BaseBitcastABIRewrite_arg = load { i64, i64 }, ptr %.BaseBitcastABIRewrite_padded_arg_storage
take4([1, 2, 3, 4]);
}

View file

@ -2,14 +2,15 @@
import ldc.llvmasm;
import ldc.intrinsics;
static if (LLVM_atleast!1500)
static if (LLVM_atleast!15)
{
alias __irEx!("", "store i32 %1, ptr %0, !nontemporal !0", "!0 = !{i32 1}", void, int*, int) nontemporalStore;
alias __irEx!("!0 = !{i32 1}", "%i = load i32, ptr %0, !nontemporal !0\nret i32 %i", "", int, const int*) nontemporalLoad;
}
else {
alias __irEx!("", "store i32 %1, i32* %0, !nontemporal !0", "!0 = !{i32 1}", void, int*, int) nontemporalStore;
alias __irEx!("!0 = !{i32 1}", "%i = load i32, i32* %0, !nontemporal !0\nret i32 %i", "", int, const int*) nontemporalLoad;
else
{
alias __irEx!("", "store i32 %1, i32* %0, !nontemporal !0", "!0 = !{i32 1}", void, int*, int) nontemporalStore;
alias __irEx!("!0 = !{i32 1}", "%i = load i32, i32* %0, !nontemporal !0\nret i32 %i", "", int, const int*) nontemporalLoad;
}
int foo(const int* src)
{

View file

@ -10,7 +10,7 @@
// There was a bug where llvm.used was emitted more than once, whose symptom was that suffixed versions would appear: e.g. `@llvm.used.3`.
// Expect 2 llvm.used entries, for both ModuleInfo refs.
// LLVM-NOT: @llvm.used.
// LLVM: @llvm.used = appending global [2 x i8*]
// LLVM: @llvm.used = appending global [2 x {{i8\*|ptr}}]
// LLVM-NOT: @llvm.used.
// EXECUTE: ctor

View file

@ -12,7 +12,7 @@ module mod;
// OPT3-LABEL: define {{.*}} @{{.*}}void_three_return_paths
void void_three_return_paths(int a, ...)
{
// OPT3: call void @llvm.va_start({{.*}} %[[VA:[0-9]+]])
// OPT3: call void @llvm.va_start({{.*}} %[[VA:[_0-9a-zA-Z]+]])
// OPT3-NOT: return_two
return_two();

View file

@ -21,8 +21,8 @@ extern int declaredGlobal;
// make sure the ModuleInfo ref is emitted into the __minfo section:
// CHECK: @_D4wasi11__moduleRefZ = linkonce_odr hidden global %object.ModuleInfo* {{.*}}, section "__minfo"
// CHECK: @llvm.used = appending global [1 x {{i8\*|ptr}}] [{{i8\*|ptr}} {{.*}} @_D4wasi11__moduleRefZ
// CHECK: @_D4wasi11__moduleRefZ = linkonce_odr hidden global {{%object\.ModuleInfo\*|ptr}} {{.*}}, section "__minfo"
// CHECK: @llvm.used = appending global [1 x {{i8\*|ptr}}] [{{i8\*|ptr}} {{.*}}@_D4wasi11__moduleRefZ
// test the magic linker symbols via linkability of the following:

12
tests/compilable/gh4266.d Normal file
View file

@ -0,0 +1,12 @@
// REQUIRES: target_NVPTX
// RUN: %ldc -c -mdcompute-targets=cuda-350 %s
@compute(CompileFor.deviceOnly) module gh4266;
import ldc.dcompute;
pragma(LDC_intrinsic, "llvm.nvvm.barrier0")
void barrier0();
void callbarrier() {
barrier0();
}

View file

@ -2,9 +2,9 @@
void fun0 () {
// CHECK-LABEL: define{{.*}} @{{.*}}4fun0FZv
// CHECK: [[RET1:%[0-9]]] = call i8* @llvm.returnaddress(i32 0)
// CHECK: [[RET1:%[0-9]]] = call {{i8\*|ptr}} @llvm.returnaddress(i32 0)
// CHECK: call void @__cyg_profile_func_enter{{.*}}4fun0FZv{{.*}}[[RET1]]
// CHECK: [[RET2:%[0-9]]] = call i8* @llvm.returnaddress(i32 0)
// CHECK: [[RET2:%[0-9]]] = call {{i8\*|ptr}} @llvm.returnaddress(i32 0)
// CHECK: call void @__cyg_profile_func_exit{{.*}}4fun0FZv{{.*}}[[RET2]]
// CHECK-NEXT: ret
return;

View file

@ -4,7 +4,7 @@
// https://github.com/llvm/llvm-test-suite/commit/2c3c4a6286d453f763c0245c6536ddd368f0db99
// XFAIL: Darwin && atleast_llvm1100
// RUN: %ldc -fxray-instrument -fxray-instruction-threshold=1 -of=%t%exe %s -vv | FileCheck %s
// RUN: %ldc -fxray-instrument -fxray-instruction-threshold=1 -of=%t%exe %s -vv 2>&1 | FileCheck %s
void foo()
{
@ -15,5 +15,6 @@ void main()
foo();
}
// CHECK-NOT: error
// CHECK: Linking with:
// CHECK-NEXT: rt.xray

View file

@ -85,7 +85,7 @@ config.available_features.add("llvm%d" % config.llvm_version)
plusoneable_llvmversion = config.llvm_version // 10 + config.llvm_version%10
for version in range(60, plusoneable_llvmversion+1):
config.available_features.add("atleast_llvm%d0%d" % (version//10, version%10))
for version in range(plusoneable_llvmversion, 141):
for version in range(plusoneable_llvmversion, 201):
config.available_features.add("atmost_llvm%d0%d" % (version//10, version%10))
# Define OS as available feature (Windows, Darwin, Linux, FreeBSD...)

View file

@ -66,3 +66,53 @@ static void addFuncEntryCallPass(const PassManagerBuilder &,
static RegisterStandardPasses
RegisterFuncEntryCallPass0(PassManagerBuilder::EP_EnabledOnOptLevel0,
addFuncEntryCallPass);
#if LLVM_VERSION >= 1400
// Implementation of plugin for the new passmanager
#include "llvm/IR/PassManager.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Passes/PassPlugin.h"
namespace {
struct MyPass : public PassInfoMixin<MyPass> {
// The first argument of the run() function defines on what level
// of granularity your pass will run (e.g. Module, Function).
// The second argument is the corresponding AnalysisManager
// (e.g ModuleAnalysisManager, FunctionAnalysisManager)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM) {
FuncEntryCallPass pass;
pass.doInitialization(M);
for (Function &F : M.functions()) {
if (!F.isDeclaration())
pass.runOnFunction(F);
}
return PreservedAnalyses::none();
}
};
}
// This part is the new way of registering your pass
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo() {
return {
LLVM_PLUGIN_API_VERSION, "MyPass", "v0.1",
[](PassBuilder &PB) {
PB.registerPipelineStartEPCallback(
[](ModulePassManager &mpm, OptimizationLevel) {
mpm.addPass(MyPass());
}
);
}
};
}
#endif

View file

@ -1,7 +1,8 @@
// REQUIRES: Plugins
// REQUIRES: atleast_llvm1400
// RUN: %gnu_make -f %S/Makefile
// RUN: %ldc -passmanager=legacy -c -output-ll -plugin=./addFuncEntryCallPass.so -of=%t.ll %s
// RUN: %ldc --passmanager=new -c -output-ll -plugin=./addFuncEntryCallPass.so -of=%t.ll %s
// RUN: FileCheck %s < %t.ll
// CHECK: define {{.*}}testfunction

View file

@ -0,0 +1,15 @@
// REQUIRES: Plugins
// REQUIRES: atmost_llvm1409
// RUN: %gnu_make -f %S/Makefile
// RUN: %ldc --passmanager=legacy -c -output-ll -plugin=./addFuncEntryCallPass.so -of=%t.ll %s
// RUN: FileCheck %s < %t.ll
// CHECK: define {{.*}}testfunction
int testfunction(int i)
{
// CHECK-NEXT: call {{.*}}__test_funcentrycall
return i * 2;
}
// CHECK-DAG: declare {{.*}}__test_funcentrycall

View file

@ -36,4 +36,6 @@ if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LDCPROFDATA_SRC})
)
target_link_libraries(ldc-profdata ${LLVM_LIBRARIES} ${CMAKE_DL_LIBS} ${LLVM_LDFLAGS})
install(TARGETS ldc-profdata DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
else()
message(WARNING "ldc-profdata source (${LDCPROFDATA_SRC}) not found")
endif()

File diff suppressed because it is too large Load diff