./ldc-1.20.1-src/ 0000755 0001750 0001750 00000000000 13631266752 013500 5 ustar matthias matthias ./ldc-1.20.1-src/tests/ 0000755 0001750 0001750 00000000000 13631266747 014646 5 ustar matthias matthias ./ldc-1.20.1-src/tests/compilable/ 0000755 0001750 0001750 00000000000 13631266747 016755 5 ustar matthias matthias ./ldc-1.20.1-src/tests/compilable/gh2849.d 0000644 0001750 0001750 00000000203 13631266747 020042 0 ustar matthias matthias // RUN: %ldc -c %s
extern(C++):
__gshared const int dblreg = 1;
pragma(mangle, dblreg.mangleof)
extern __gshared const int bla;
./ldc-1.20.1-src/tests/compilable/no-integrated-as.d 0000644 0001750 0001750 00000000415 13631266747 022263 0 ustar matthias matthias // RUN: %ldc -no-integrated-as %s
// We currently rely on gcc/clang; no MSVC toolchain support yet.
// UNSUPPORTED: Windows
module noIntegratedAs;
void main()
{
import std.stdio;
writeln("This object is assembled externally and linked to an executable.");
}
./ldc-1.20.1-src/tests/compilable/gh2859.d 0000644 0001750 0001750 00000000147 13631266747 020052 0 ustar matthias matthias // RUN: %ldc -c %s
void foo()
{
static struct S { int a; }
S s;
const aa = [1 : &s.a];
}
./ldc-1.20.1-src/tests/compilable/gh3250.d 0000644 0001750 0001750 00000000156 13631266747 020034 0 ustar matthias matthias // RUN: %ldc -c %s
struct Q
{
auto func(uint[3] a, uint[3] b, uint c)
{
return this;
}
}
./ldc-1.20.1-src/tests/compilable/gh2777.d 0000644 0001750 0001750 00000000152 13631266747 020045 0 ustar matthias matthias // RUN: %ldc -c -singleobj %s %S/inputs/gh2777b.d
int main(string[] args);
void reset() { main(null); }
./ldc-1.20.1-src/tests/compilable/gh1741.d 0000644 0001750 0001750 00000000305 13631266747 020033 0 ustar matthias matthias // Explicitly target Linux x86_64.
// REQUIRES: target_X86
// RUN: %ldc -mtriple=x86_64-pc-linux-gnu -c %s %S/inputs/gh1741b.d
struct S
{
C c;
}
class C
{
@property s() { return S(); }
}
./ldc-1.20.1-src/tests/compilable/gh3162.d 0000644 0001750 0001750 00000000263 13631266747 020035 0 ustar matthias matthias // RUN: %ldc -run %s
shared struct Queue
{
int[int] map;
}
void main()
{
auto queue = Queue();
( cast(int[int]) queue.map )[1] = 2;
assert(queue.map[1] == 2);
}
./ldc-1.20.1-src/tests/compilable/gh3243.d 0000644 0001750 0001750 00000000117 13631266747 020033 0 ustar matthias matthias // RUN: %ldc -c %s %S/inputs/foo/bla.di %S/inputs/bar/bla.di
import foo, bar;
./ldc-1.20.1-src/tests/compilable/objc_gh2388.d 0000644 0001750 0001750 00000000314 13631266747 021040 0 ustar matthias matthias // REQUIRES: Darwin
// RUN: %ldc -c -singleobj %s %S/objc_gh2387.d
void alloc()
{
NSObject o;
o.alloc();
}
extern (Objective-C):
interface NSObject
{
NSObject alloc() @selector("alloc");
}
./ldc-1.20.1-src/tests/compilable/gh2988.d 0000644 0001750 0001750 00000000273 13631266747 020055 0 ustar matthias matthias // RUN: %ldc -c %s
import core.simd;
float4 getVector() { return float4(1.0f); }
void foo()
{
// front-end implicitly casts from float4 to float[4]
float x = getVector()[0];
}
./ldc-1.20.1-src/tests/compilable/ctfe_math.d 0000644 0001750 0001750 00000004532 13631266747 021060 0 ustar matthias matthias // Tests CTFE-ability of some common std.math functions.
// RUN: %ldc -c %s
import std.math;
mixin template Func1(string name) {
enum r = mixin(name ~ "(0.5L)");
pragma(msg, name ~ "(0.5L) = " ~ r.stringof);
enum d = mixin(name ~ "(0.5)");
pragma(msg, name ~ "(0.5) = " ~ d.stringof);
enum f = mixin(name ~ "(0.5f)");
pragma(msg, name ~ "(0.5f) = " ~ f.stringof);
}
mixin template Func2(string name) {
enum r = mixin(name ~ "(0.5L, -2.5L)");
pragma(msg, name ~ "(0.5L, -2.5L) = " ~ r.stringof);
enum d = mixin(name ~ "(0.5, -2.5)");
pragma(msg, name ~ "(0.5, -2.5) = " ~ d.stringof);
enum f = mixin(name ~ "(0.5f, -2.5f)");
pragma(msg, name ~ "(0.5f, -2.5f) = " ~ f.stringof);
}
mixin template Func2_int(string name) {
enum r = mixin(name ~ "(0.5L, 2)");
pragma(msg, name ~ "(0.5L, 2) = " ~ r.stringof);
enum d = mixin(name ~ "(0.5, 2)");
pragma(msg, name ~ "(0.5, 2) = " ~ d.stringof);
enum f = mixin(name ~ "(0.5f, 2)");
pragma(msg, name ~ "(0.5f, 2) = " ~ f.stringof);
}
mixin template Func3(string name) {
enum r = mixin(name ~ "(0.5L, -2.5L, 6.25L)");
pragma(msg, name ~ "(0.5L, -2.5L, 6.25L) = " ~ r.stringof);
enum d = mixin(name ~ "(0.5, -2.5, 6.25)");
pragma(msg, name ~ "(0.5, -2.5, 6.25) = " ~ d.stringof);
enum f = mixin(name ~ "(0.5f, -2.5f, 6.25f)");
pragma(msg, name ~ "(0.5f, -2.5f, 6.25f) = " ~ f.stringof);
}
void main()
{
{ mixin Func1!"isNaN"; }
{ mixin Func1!"isInfinity"; }
{ mixin Func1!"isFinite"; }
{ mixin Func1!"abs"; }
{ mixin Func1!"fabs"; }
{ mixin Func1!"sqrt"; }
{ mixin Func1!"sin"; }
{ mixin Func1!"cos"; }
{ mixin Func1!"tan"; }
{ mixin Func1!"cosh"; }
{ mixin Func1!"asinh"; }
{ mixin Func1!"acosh"; }
{ mixin Func1!"atanh"; }
{ mixin Func1!"ceil"; }
{ mixin Func1!"floor"; }
{ mixin Func1!"round"; }
{ mixin Func1!"trunc"; }
{ mixin Func1!"rint"; }
{ mixin Func1!"nearbyint"; }
{ mixin Func1!"exp"; }
{ mixin Func1!"exp2"; }
{ mixin Func2_int!"ldexp"; }
{ mixin Func1!"log"; }
{ mixin Func1!"log2"; }
{ mixin Func1!"log10"; }
{ mixin Func2!"pow"; }
{ mixin Func2_int!"pow"; }
{ mixin Func2!"fmin"; }
{ mixin Func2!"fmax"; }
{ mixin Func2!"copysign"; }
{ mixin Func3!"fma"; }
static assert(2.0 ^^ 8 == 256.0);
}
./ldc-1.20.1-src/tests/compilable/gh1906.d 0000644 0001750 0001750 00000000103 13631266747 020032 0 ustar matthias matthias // RUN: %ldc -c -I%S/inputs %s
import gh1906b;
class C : Base {}
./ldc-1.20.1-src/tests/compilable/gh3194.d 0000644 0001750 0001750 00000000172 13631266747 020041 0 ustar matthias matthias // REQUIRES: target_X86
// RUN: %ldc -c %s
import ldc.gccbuiltins_x86; // should be importable by non-installed compiler
./ldc-1.20.1-src/tests/compilable/gh2458.d 0000644 0001750 0001750 00000000450 13631266747 020042 0 ustar matthias matthias // Make sure llvm_expect() is supported during CTFE.
// RUN: %ldc -c %s
import ldc.intrinsics : llvm_expect;
int notZero(int x)
{
if (llvm_expect(x == 0, false))
return 666;
return x;
}
void main()
{
static assert(notZero(0) == 666);
static assert(notZero(1) == 1);
}
./ldc-1.20.1-src/tests/compilable/gh1933.d 0000644 0001750 0001750 00000002121 13631266747 020034 0 ustar matthias matthias // See Github issue 1933.
// RUN: %ldc -c -release -g -O0 %s
// RUN: %ldc -c -release -g -O3 %s
ptrdiff_t countUntil(T, N)(T haystack, N needle)
{
ptrdiff_t result;
foreach (elem; haystack) {
if (elem == needle)
return result;
result++;
}
return -1;
}
bool foo(alias pred, N)(N haystack)
{
foreach (elem; haystack) {
if (pred(elem))
return true;
}
return false;
}
struct MatchTree
{
struct Tag
{
}
struct Terminal
{
string[] varNames;
}
Tag[] m_terminalTags;
Terminal term;
void rebuildGraph()
{
MatchGraphBuilder builder;
uint process()
{
auto aaa = m_terminalTags.length;
foreach (t; builder.m_nodes)
{
auto bbb = term.varNames.countUntil(t.var);
assert(m_terminalTags.foo!(u => t.index));
}
return 0;
}
}
}
struct MatchGraphBuilder
{
struct TerminalTag
{
size_t index;
string var;
}
TerminalTag[] m_nodes;
}
./ldc-1.20.1-src/tests/compilable/gh2033.d 0000644 0001750 0001750 00000000572 13631266747 020034 0 ustar matthias matthias // RUN: %ldc -c %s
void foo(const(uint)[4] arg)
{
// The front-end coerces the explicit and following implicit cast
// (implicit: int[4] -> const(int[4])) into a single CastExp with
// differing types CastExp::to and CastExp::type.
// Make sure the repainting code performing the implicit cast
// handles static arrays.
const copy = cast(int[4]) arg;
}
./ldc-1.20.1-src/tests/compilable/gh2415.d 0000644 0001750 0001750 00000000347 13631266747 020040 0 ustar matthias matthias // RUN: %ldc -c %s
struct Row
{
float val;
ref float opIndex(int i) { return val; }
}
struct Matrix
{
Row row;
ref Row opIndex(int i) { return row; }
}
void main()
{
Matrix matrix;
matrix[1][2] += 0.0;
}
./ldc-1.20.1-src/tests/compilable/gh2932.d 0000644 0001750 0001750 00000000626 13631266747 020044 0 ustar matthias matthias // RUN: %ldc -c -allinst %s
import std.algorithm;
extern __gshared int[] array;
void funcWithNoFrame()
{
int local;
// lambda is codegen'd
pragma(msg, typeof(array.map!(e => local)));
}
void funcWithFrame()
{
int capturedVar, local;
int nestedFunc() { return capturedVar; }
// lambda is codegen'd with `-allinst`
static assert(__traits(compiles, array.map!(e => local)));
}
./ldc-1.20.1-src/tests/compilable/objc_gh2387.d 0000644 0001750 0001750 00000000301 13631266747 021033 0 ustar matthias matthias // REQUIRES: Darwin
// RUN: %ldc -c %s
extern (Objective-C) interface NSView
{
void setWantsLayer(bool value) @selector("setWantsLayer:");
}
void foo(NSView v) { v.setWantsLayer(true); }
./ldc-1.20.1-src/tests/compilable/gh2996.d 0000644 0001750 0001750 00000000471 13631266747 020054 0 ustar matthias matthias // RUN: %ldc -c %s
struct Table
{
RCArray _elems;
void update(int x)
{
auto e = _elems[0 .. x][x == 0 ? x : $];
}
}
struct RCArray
{
int[] _arr;
inout opSlice(size_t, size_t) { return _arr; }
const length() { return _arr.length; }
const opDollar() { return length; }
}
./ldc-1.20.1-src/tests/compilable/gh2422.d 0000644 0001750 0001750 00000000134 13631266747 020030 0 ustar matthias matthias // RUN: %ldc -c -I%S/inputs %s
import gh2422a;
void main() { auto aa = ["": new Empty]; }
./ldc-1.20.1-src/tests/compilable/dcompute.d 0000644 0001750 0001750 00000002165 13631266747 020746 0 ustar matthias matthias // Tests that
// - we don't try to link with one file on the commandline that is @compute
// - turning on debugging doesn't ICE
// - don't analyse uninstantiated templates
// - typeid generated for hashing of struct (typeid(const(T))) is ignored and does not error
// - if (__ctfe) and if (!__ctfe) don't cause errors
// REQUIRES: target_NVPTX
// RUN: %ldc -mdcompute-targets=cuda-350 -g %s
@compute(CompileFor.deviceOnly) module dcompute;
import ldc.dcompute;
@kernel void foo()
{
if (__ctfe)
{
auto a = new int;
}
if (__ctfe)
{
auto a = new int;
}
else {}
if (!__ctfe)
{
}
else
{
auto a = new int;
}
}
struct AutoIndexed(T)
{
T p = void;
alias U = typeof(*T);
@property U index()
{
return p[0];
}
@property void index(U t)
{
p[0] = t;
}
@disable this();
void opAssign(U u) { index = u; }
alias index this;
}
alias aagf = AutoIndexed!(GlobalPointer!(float));
@kernel void auto_index_test(aagf a,
aagf b,
aagf c)
{
a = b + c;
}
./ldc-1.20.1-src/tests/compilable/gh2808.d 0000644 0001750 0001750 00000000571 13631266747 020045 0 ustar matthias matthias // RUN: %ldc -c %s
void gh2808()
{
extern(C) void DoubleArrayToAnyArray(void* arg0)
{
auto dg = () => { auto r = arg0; };
}
auto local = 123;
auto arg = () { return local; }();
DoubleArrayToAnyArray(null);
}
void gh3234()
{
int i;
void nested() { ++i; }
extern (C++) class Visitor
{
void visit() { nested(); }
}
}
./ldc-1.20.1-src/tests/compilable/gh2471.d 0000644 0001750 0001750 00000001266 13631266747 020043 0 ustar matthias matthias // RUN: %ldc -c %s
struct Iterator(T : T[])
{
alias ThisType = Iterator!(T[]);
alias ItemType = T;
this(T[] container, size_t index = 0)
{
container_ = container;
index_ = index;
}
U opCast(U)() const
if (is(U == ItemType))
{
return this ? container_[index_] : ItemType.init;
}
ref ThisType opUnary(string op)()
if (op == "++" || op == "--")
{
mixin(op ~ "index_;");
return this;
}
@property ItemType value() const { return container_[index_]; }
alias value this;
private T[] container_ = null;
private size_t index_ = 0;
}
void main()
{
string test = "abcde";
auto it = Iterator!string(test);
char ch = it++;
}
./ldc-1.20.1-src/tests/compilable/inputs/ 0000755 0001750 0001750 00000000000 13631266747 020277 5 ustar matthias matthias ./ldc-1.20.1-src/tests/compilable/inputs/gh1741b.d 0000644 0001750 0001750 00000000025 13631266747 021516 0 ustar matthias matthias import gh1741;
S s;
./ldc-1.20.1-src/tests/compilable/inputs/gh1906b.d 0000644 0001750 0001750 00000000107 13631266747 021522 0 ustar matthias matthias class Base
{
auto foo() { return this; }
abstract int bar();
}
./ldc-1.20.1-src/tests/compilable/inputs/gh2777b.d 0000644 0001750 0001750 00000000046 13631266747 021533 0 ustar matthias matthias int main(string[] args) { return 0; }
./ldc-1.20.1-src/tests/compilable/inputs/foo/ 0000755 0001750 0001750 00000000000 13631266747 021062 5 ustar matthias matthias ./ldc-1.20.1-src/tests/compilable/inputs/foo/bla.di 0000644 0001750 0001750 00000000014 13631266747 022131 0 ustar matthias matthias module foo;
./ldc-1.20.1-src/tests/compilable/inputs/gh2422a.d 0000644 0001750 0001750 00000000020 13631266747 021505 0 ustar matthias matthias class Empty { }
./ldc-1.20.1-src/tests/compilable/inputs/bar/ 0000755 0001750 0001750 00000000000 13631266747 021043 5 ustar matthias matthias ./ldc-1.20.1-src/tests/compilable/inputs/bar/bla.di 0000644 0001750 0001750 00000000014 13631266747 022112 0 ustar matthias matthias module bar;
./ldc-1.20.1-src/tests/plugins/ 0000755 0001750 0001750 00000000000 13631266747 016327 5 ustar matthias matthias ./ldc-1.20.1-src/tests/plugins/addFuncEntryCall/ 0000755 0001750 0001750 00000000000 13631266747 021511 5 ustar matthias matthias ./ldc-1.20.1-src/tests/plugins/addFuncEntryCall/addFuncEntryCallPass.cpp 0000644 0001750 0001750 00000003705 13631266747 026233 0 ustar matthias matthias //===-- addFuncEntryCallPass.cpp - Optimize druntime calls ----------------===//
//
// LDC – the LLVM D compiler
//
// This file is distributed under the University of Illinois Open Source
// License. See the LICENSE file for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
using namespace llvm;
namespace {
class FuncEntryCallPass : public FunctionPass {
Value *funcToCallUponEntry = nullptr;
public:
static char ID;
FuncEntryCallPass() : FunctionPass(ID) {}
bool doInitialization(Module &M) override;
bool runOnFunction(Function &F) override;
};
}
char FuncEntryCallPass::ID = 0;
bool FuncEntryCallPass::doInitialization(Module &M) {
// Add fwd declaration of the `void __test_funcentrycall(void)` function.
auto functionType = FunctionType::get(Type::getVoidTy(M.getContext()), false);
funcToCallUponEntry =
M.getOrInsertFunction("__test_funcentrycall", functionType)
#if LLVM_VERSION >= 900
.getCallee()
#endif
;
return true;
}
bool FuncEntryCallPass::runOnFunction(Function &F) {
// Add call to `__test_funcentrycall(void)` at the start of _every_ function
// (this includes e.g. `ldc.register_dso`!)
llvm::BasicBlock &block = F.getEntryBlock();
IRBuilder<> builder(&block, block.begin());
builder.CreateCall(funcToCallUponEntry);
return true;
}
static void addFuncEntryCallPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) {
PM.add(new FuncEntryCallPass());
}
// Registration of the plugin's pass is done by the plugin's static constructor.
static RegisterStandardPasses
RegisterFuncEntryCallPass0(PassManagerBuilder::EP_EnabledOnOptLevel0,
addFuncEntryCallPass);
./ldc-1.20.1-src/tests/plugins/addFuncEntryCall/testPlugin.d 0000644 0001750 0001750 00000000526 13631266747 024017 0 ustar matthias matthias // REQUIRES: Plugins
// RUN: %gnu_make -f %S/Makefile
// RUN: %ldc -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
./ldc-1.20.1-src/tests/plugins/addFuncEntryCall/Makefile 0000644 0001750 0001750 00000001344 13631266747 023153 0 ustar matthias matthias
# ROOT_DIR = directory where Makefile sits
MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
ROOT_DIR := $(dir $(MAKEFILE_PATH))
LLVM_CONFIG ?= llvm-config
CXXFLAGS ?= -O3
CXXFLAGS += $(shell $(LLVM_CONFIG) --cxxflags) -fno-rtti -fpic
CXXFLAGS += -DLLVM_VERSION=$(LLVM_VERSION)
# Remove all warning flags (they may or may not be supported by the compiler)
CXXFLAGS := $(filter-out -W%,$(CXXFLAGS))
CXXFLAGS := $(filter-out -fcolor-diagnostics,$(CXXFLAGS))
ifeq "$(shell uname)" "Darwin"
CXXFLAGS += -Wl,-flat_namespace -Wl,-undefined,suppress
endif
PASSLIB = addFuncEntryCallPass
all: $(PASSLIB)
$(PASSLIB): $(ROOT_DIR)$(PASSLIB).cpp
$(CXX) $(CXXFLAGS) -shared $< -o $@.so
.NOTPARALLEL: clean
clean:
rm -f $(PASSLIB).so
./ldc-1.20.1-src/tests/plugins/lit.local.cfg 0000644 0001750 0001750 00000000416 13631266747 020672 0 ustar matthias matthias import os
import platform
import re
if (config.plugins_supported):
config.available_features.add('Plugins')
config.environment['LLVM_CONFIG'] = os.path.join(config.llvm_tools_dir, 'llvm-config')
config.environment['LLVM_VERSION'] = str(config.llvm_version)
./ldc-1.20.1-src/tests/lit.site.cfg.in 0000644 0001750 0001750 00000022216 13631266747 017472 0 ustar matthias matthias import lit.formats
import lit.util
import os
import sys
import platform
import string
import re
import subprocess
import glob
from distutils.version import LooseVersion
# Cmake Boolean options
ON = True
OFF = False
## Auto-initialized variables by cmake:
config.ldc2_bin = "@LDC2_BIN@"
config.ldcprofdata_bin = "@LDCPROFDATA_BIN@"
config.ldcprunecache_bin = "@LDCPRUNECACHE_BIN@"
config.ldc2_bin_dir = "@LDC2_BIN_DIR@"
config.ldc2_lib_dir = "@LDC2_LIB_DIR@"
config.ldc2_runtime_dir = "@RUNTIME_DIR@"
config.test_source_root = "@TESTS_IR_DIR@"
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
config.llvm_version = @LDC_LLVM_VER@
config.llvm_targetsstr = "@LLVM_TARGETS_TO_BUILD@"
config.default_target_bits = @DEFAULT_TARGET_BITS@
config.with_PGO = True
config.dynamic_compile = @LDC_DYNAMIC_COMPILE@
config.plugins_supported = @LDC_ENABLE_PLUGINS@
config.gnu_make_bin = "@GNU_MAKE_BIN@"
config.ldc_host_arch = "@LLVM_NATIVE_ARCH@"
config.ldc_with_lld = @LDC_WITH_LLD@
config.spirv_enabled = @LLVM_SPIRV_FOUND@
config.rt_supports_sanitizers = @RT_SUPPORT_SANITIZERS@
config.name = 'LDC'
# testFormat: The test format to use to interpret tests.
config.test_format = lit.formats.ShTest(execute_external=False)
# suffixes: A list of file extensions to treat as test files. This is overriden
# by individual lit.local.cfg files in the test subdirectories.
config.suffixes = ['.d',
]
# excludes: A list of directories to exclude from the testsuite. The 'inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
config.excludes = [
'inputs',
'd2',
'CMakeLists.txt',
'runlit.py',
]
# Exclude profile test dir when PGO is disabled
if not config.with_PGO:
config.excludes.append('PGO')
# Exclude dynamic compilation tests when it's disabled
if not config.dynamic_compile:
config.excludes.append('dynamiccompile')
# Explicit forwarding of environment variables
env_cc = os.environ.get('CC', '')
if env_cc:
config.environment['CC'] = env_cc
env_cxx = os.environ.get('CXX', '')
if env_cxx:
config.environment['CXX'] = env_cxx
if (platform.system() == 'Windows'):
config.environment['VSINSTALLDIR'] = os.environ['VSINSTALLDIR']
config.environment['PATH'] = os.environ['PATH']
config.environment['LIB'] = os.environ['LIB']
# Define available features so that we can disable tests depending on LLVM version
config.available_features.add("llvm%d" % config.llvm_version)
# LLVM version history: 3.9, 4.0, 5.0, ...
# config.llvm_version: 309, 400, 500, ...
# plusoneable_llvmversion: 39, 40, 50, ...
plusoneable_llvmversion = config.llvm_version // 10 + config.llvm_version%10
for version in range(39, plusoneable_llvmversion+1):
config.available_features.add("atleast_llvm%d0%d" % (version//10, version%10))
for version in range(plusoneable_llvmversion, 91):
config.available_features.add("atmost_llvm%d0%d" % (version//10, version%10))
# Define OS as available feature (Windows, Darwin, Linux)
config.available_features.add(platform.system())
# Define available features based on what LLVM can target
# Examples: 'target_X86', 'target_ARM', 'target_PowerPC', 'target_AArch64'
for t in config.llvm_targetsstr.split(';'):
config.available_features.add('target_' + t)
if config.spirv_enabled:
config.available_features.add('target_SPIRV')
if config.rt_supports_sanitizers:
config.available_features.add('RTSupportsSanitizers')
# Add specific features for Windows x86/x64 testing
if (platform.system() == 'Windows') and (config.default_target_bits == 32):
config.available_features.add('Windows_x86')
if (platform.system() == 'Windows') and (config.default_target_bits == 64):
config.available_features.add('Windows_x64')
# Define available features based on host arch
# Examples: 'host_X86', 'host_ARM', 'host_PowerPC', 'host_AArch64'
if (config.ldc_host_arch != ''):
config.available_features.add('host_' + config.ldc_host_arch)
# Add "LTO" feature if linker support and LTO plugin are available
# (LTO is supported from LLVM 3.9)
canDoLTO = False
if (platform.system() == 'Darwin'):
command = ['ld', '-v']
p = subprocess.Popen(command, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, universal_newlines=True)
text = p.stderr.read()
if ("LTO support" in text and os.path.isfile(config.ldc2_lib_dir + '/libLTO-ldc.dylib')):
canDoLTO = True
elif (platform.system() == 'Linux'):
command = ['ld', '-plugin']
p = subprocess.Popen(command, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, universal_newlines=True)
text = p.stderr.read()
if ("plugin: missing argument" in text and os.path.isfile(config.ldc2_lib_dir + '/LLVMgold-ldc.so')):
canDoLTO = True
elif (platform.system() == 'Windows'):
try:
if (subprocess.call(["lld-link.exe", "--version"]) == 0):
canDoLTO = True
except OSError:
pass
if canDoLTO:
config.available_features.add('LTO')
if config.ldc_with_lld:
config.available_features.add('internal_lld')
config.target_triple = '(unused)'
# test_exec_root: The root path where tests should be run.
config.test_exec_root = os.path.dirname(__file__)
# add test root dir to the path (FileCheck might sit there)
path = os.path.pathsep.join( (config.test_source_root, config.environment['PATH']) )
config.environment['PATH'] = path
# Add LDC and LLVM bin dir to the path
# Give priority to LDC's version of LLVM tools (we need FileCheck with certain bug fixes)
path = os.path.pathsep.join( (config.ldc2_bin_dir, config.llvm_tools_dir, config.environment['PATH']) )
config.environment['PATH'] = path
# Add substitutions
config.substitutions.append( ('%ldc', config.ldc2_bin) )
config.substitutions.append( ('%gnu_make', config.gnu_make_bin) )
config.substitutions.append( ('%profdata', config.ldcprofdata_bin) )
config.substitutions.append( ('%prunecache', config.ldcprunecache_bin) )
config.substitutions.append( ('%llvm-spirv', os.path.join(config.llvm_tools_dir, 'llvm-spirv')) )
config.substitutions.append( ('%runtimedir', config.ldc2_runtime_dir ) )
# Add platform-dependent file extension substitutions
if (platform.system() == 'Windows'):
# add LDC lib dir to the path so app will be able to find jit.dll
# TODO: Something more robust
path = os.path.pathsep.join( (config.ldc2_lib_dir, config.environment['PATH']) )
config.environment['PATH'] = path
config.substitutions.append( ('%obj', '.obj') )
config.substitutions.append( ('%exe', '.exe') )
config.substitutions.append( ('%lib', '.lib') )
config.substitutions.append( ('%so', '.dll') )
config.substitutions.append( ('%diff_binary ', 'fc /b ') )
else:
config.substitutions.append( ('%obj', '.o') )
config.substitutions.append( ('%exe', '') )
config.substitutions.append( ('%lib', '.a') )
if (platform.system() == 'Darwin'):
config.substitutions.append( ('%so', '.dylib') )
else:
config.substitutions.append( ('%so', '.so') )
config.substitutions.append( ('%diff_binary ', 'cmp -s ') )
# Add cdb substitution
if (platform.system() == 'Windows') and (config.default_target_bits == 32):
cdb = os.environ['WindowsSDKDir'] + 'Debuggers\\x86\\cdb.exe'
config.substitutions.append( ('%arch', 'x86') )
if (platform.system() == 'Windows') and (config.default_target_bits == 64):
cdb = os.environ['WindowsSDKDir'] + 'Debuggers\\x64\\cdb.exe'
config.substitutions.append( ('%arch', 'x64') )
if (platform.system() == 'Windows') and os.path.isfile( cdb ):
config.available_features.add('cdb')
config.substitutions.append( ('%cdb', '"' + cdb.replace('\\', '\\\\') + '"') )
# Check whether GDB is present
if (platform.system() != 'Windows') and lit.util.which('gdb', config.environment['PATH']):
config.available_features.add('gdb')
gdb_dflags = ''
command = ['gdb', '--version']
p = subprocess.Popen(command, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, universal_newlines=True)
text = p.stdout.readline()
m = re.compile('[^0-9]*([0-9]+[0-9.]*).*').match(text)
if m is not None:
gdb_version = m.group(1)
if LooseVersion(gdb_version) < LooseVersion('7.8'):
gdb_dflags = '-dwarf-version=2'
elif LooseVersion(gdb_version) >= LooseVersion('8.0'):
config.available_features.add('atleast_gdb80')
config.substitutions.append( ('%_gdb_dflags', gdb_dflags) )
# Add substitutions for functionality across different LLVM versions
if config.llvm_version >= 800:
config.substitutions.append( ('%disable_fp_elim', '-frame-pointer=all') )
config.substitutions.append( ('%enable_fp_elim', '-frame-pointer=none') )
else:
config.substitutions.append( ('%disable_fp_elim', '-disable-fp-elim') )
config.substitutions.append( ('%enable_fp_elim', '-disable-fp-elim=false') )
if 'LD_LIBRARY_PATH' in os.environ:
libs = []
for lib_path in [s for s in os.environ['LD_LIBRARY_PATH'].split(':') if s]:
for pattern in ['*ldc-jit*','*druntime-ldc*','*phobos2-ldc*']:
libs += glob.glob(os.path.join(lib_path, pattern))
if libs:
print('Warning: LDC runtime libs found in LD_LIBRARY_PATH:')
for l in libs:
print(l)
./ldc-1.20.1-src/tests/instrument/ 0000755 0001750 0001750 00000000000 13631266747 017056 5 ustar matthias matthias ./ldc-1.20.1-src/tests/instrument/finstrument_functions.d 0000644 0001750 0001750 00000001632 13631266747 023673 0 ustar matthias matthias // RUN: %ldc -c -output-ll -finstrument-functions -of=%t.ll %s && FileCheck %s < %t.ll
void fun0 () {
// CHECK-LABEL: define{{.*}} @{{.*}}4fun0FZv
// CHECK: [[RET1:%[0-9]]] = call i8* @llvm.returnaddress(i32 0)
// CHECK: call void @__cyg_profile_func_enter{{.*}}4fun0FZv{{.*}}[[RET1]]
// CHECK: [[RET2:%[0-9]]] = call i8* @llvm.returnaddress(i32 0)
// CHECK: call void @__cyg_profile_func_exit{{.*}}4fun0FZv{{.*}}[[RET2]]
// CHECK-NEXT: ret
return;
}
pragma(LDC_profile_instr, false)
int fun1 (int x) {
// CHECK-LABEL: define{{.*}} @{{.*}}4fun1FiZi
// CHECK-NOT: __cyg_profile_func_enter
// CHECK-NOT: __cyg_profile_func_exit
return 42;
}
bool fun2 (int x) {
// CHECK-LABEL: define{{.*}} @{{.*}}4fun2FiZb
if (x < 10)
// CHECK: call void @__cyg_profile_func_exit
// CHECK-NEXT: ret
return true;
// CHECK: call void @__cyg_profile_func_exit
// CHECK-NEXT: ret
return false;
}
./ldc-1.20.1-src/tests/instrument/xray_check_pipeline.d 0000644 0001750 0001750 00000000537 13631266747 023235 0 ustar matthias matthias // Check that the LLVM pipeline is set up correctly to generate XRay sleds.
// If we have the XRay runtime lib for this platform, then we can also do machinecodegen:
// REQUIRES: XRay_RT
// RUN: %ldc -c -output-s -betterC -fxray-instrument -fxray-instruction-threshold=1 -of=%t.s %s && FileCheck %s < %t.s
// CHECK: xray_sled
void instrument()
{
}
./ldc-1.20.1-src/tests/instrument/xray_instrument_threshold.d 0000644 0001750 0001750 00000000512 13631266747 024550 0 ustar matthias matthias // REQUIRES: atleast_llvm500
// RUN: %ldc -c -output-ll -fxray-instrument -fxray-instruction-threshold=543 -of=%t.ll %s && FileCheck %s < %t.ll
// CHECK-LABEL: define{{.*}} @{{.*}}10instrument
// CHECK-SAME: #[[INSTR:[0-9]+]]
void instrument()
{
}
// CHECK-DAG: attributes #[[INSTR]] ={{.*}} "xray-instruction-threshold"="543"
./ldc-1.20.1-src/tests/instrument/xray_simple_execution.d 0000644 0001750 0001750 00000001020 13631266747 023633 0 ustar matthias matthias // Check basic execution of XRay to verify the basic system is working.
// REQUIRES: Linux
// REQUIRES: XRay_RT
// REQUIRES: atleast_llvm700
// RUN: %ldc -fxray-instrument -fxray-instruction-threshold=1 %s -of=%t%exe
// RUN: env XRAY_OPTIONS="patch_premain=true xray_mode=xray-basic verbosity=1" %t%exe 2>&1 | FileCheck %s
// This last command should give some output on stderr, one line of which containing:
// CHECK: XRay: Log file
// If stderr is empty, things are not working.
void foo()
{
}
void main()
{
foo();
}
./ldc-1.20.1-src/tests/instrument/xray_instrument.d 0000644 0001750 0001750 00000001056 13631266747 022500 0 ustar matthias matthias // REQUIRES: atleast_llvm500
// RUN: %ldc -c -output-ll -fxray-instrument -of=%t.ll %s && FileCheck %s < %t.ll
import ldc.attributes;
// CHECK-LABEL: define{{.*}} @{{.*}}10instrument
// CHECK-SAME: #[[INSTR:[0-9]+]]
void instrument()
{
}
// CHECK-LABEL: define{{.*}} @{{.*}}15dont_instrument
// CHECK-SAME: #[[DONT_INSTR:[0-9]+]]
void dont_instrument()
{
pragma(LDC_profile_instr, false);
}
// CHECK-DAG: attributes #[[INSTR]] ={{.*}} "xray-instruction-threshold"=
// CHECK-DAG: attributes #[[DONT_INSTR]] ={{.*}} "function-instrument"="xray-never"
./ldc-1.20.1-src/tests/instrument/coverage_cycle_gh2177.d 0000644 0001750 0001750 00000000467 13631266747 023203 0 ustar matthias matthias // Test that `-cov` does not lead to harmless import cycle errors.
// Github issue 2177
// RUN: %ldc -cov=100 -Iinputs %s %S/inputs/coverage_cycle_input.d -of=%t%exe
// RUN: %t%exe
module coverage_cycle_gh2177;
import inputs.coverage_cycle_input;
static this() {
int i;
}
int main () {
return 0;
}
./ldc-1.20.1-src/tests/instrument/coverage_main_gh2163.d 0000644 0001750 0001750 00000000033 13631266747 023010 0 ustar matthias matthias // RUN: %ldc -main -cov %s
./ldc-1.20.1-src/tests/instrument/lit.local.cfg 0000644 0001750 0001750 00000000411 13631266747 021414 0 ustar matthias matthias import os
import platform
import re
# Add "XRay_RT" feature if the runtime library is available
for file in os.listdir(config.ldc2_lib_dir):
m = re.match('.*xray.*', file)
if m is not None:
config.available_features.add('XRay_RT')
continue
./ldc-1.20.1-src/tests/instrument/xray_link.d 0000644 0001750 0001750 00000000321 13631266747 021217 0 ustar matthias matthias // REQUIRES: XRay_RT
// RUN: %ldc -fxray-instrument -fxray-instruction-threshold=1 -of=%t%exe %s -vv | FileCheck %s
void foo()
{
}
void main()
{
foo();
}
// CHECK: Linking with:
// CHECK-NEXT: rt.xray
./ldc-1.20.1-src/tests/instrument/inputs/ 0000755 0001750 0001750 00000000000 13631266747 020400 5 ustar matthias matthias ./ldc-1.20.1-src/tests/instrument/inputs/coverage_cycle_input.d 0000644 0001750 0001750 00000000103 13631266747 024730 0 ustar matthias matthias module inputs.coverage_cycle_input;
import coverage_cycle_gh2177;
./ldc-1.20.1-src/tests/codegen/ 0000755 0001750 0001750 00000000000 13631266747 016252 5 ustar matthias matthias ./ldc-1.20.1-src/tests/codegen/inlineIR_math.d 0000644 0001750 0001750 00000006642 13631266747 021151 0 ustar matthias matthias // Tests inline IR + math optimizations
// REQUIRES: target_X86
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s --check-prefix LLVM < %t.ll
// RUN: %ldc -mtriple=x86_64-linux-gnu -mattr=+fma -O3 -release -c -output-s -of=%t.s %s && FileCheck %s --check-prefix ASM < %t.s
import ldc.attributes;
import ldc.llvmasm;
// Test that internal @inline.ir.*" functions for the inlined IR pieces are always inlined and are not present as a global symbol
// LLVM-NOT: @inline.ir.
// LLVM-NOT: alwaysinline
// __ir should inherit the enclosing function attributes, thus preserving the enclosing function attributes after inlining.
// LLVM-LABEL: define{{.*}} @dot
// LLVM-SAME: #[[UNSAFEFPMATH:[0-9]+]]
// ASM-LABEL: dot:
@llvmAttr("unsafe-fp-math", "true")
extern (C) double dot(double[] a, double[] b)
{
double s = 0;
// ASM: vfmadd{{[123][123][123]}}pd
foreach (size_t i; 0 .. a.length)
{
s = __ir!(`%p = fmul fast double %0, %1
%r = fadd fast double %p, %2
ret double %r`, double)(a[i], b[i], s);
}
return s;
}
// LLVM-LABEL: define{{.*}} @features
// LLVM-SAME: #[[FEAT:[0-9]+]]
@target("fma")
extern (C) double features(double[] a, double[] b)
{
double s = 0;
foreach (size_t i; 0 .. a.length)
{
s = __ir!(`%p = fmul fast double %0, %1
%r = fadd fast double %p, %2
ret double %r`, double)(a[i], b[i], s);
}
return s;
}
// Test that inline IR works when calling function has special attributes defined for its parameters
// LLVM-LABEL: define{{.*}} @dot160
// ASM-LABEL: dot160:
extern (C) double dot160(double[160] a, double[160] b)
{
double s = 0;
// ASM-NOT: vfmadd
foreach (size_t i; 0 .. a.length)
{
s = __ir!(`%p = fmul double %0, %1
%r = fadd double %p, %2
ret double %r`, double)(a[i], b[i], s);
}
return s;
}
// Test inline IR alias defined outside any function
alias __ir!(`%p = fmul fast double %0, %1
%r = fadd fast double %p, %2
ret double %r`,
double, double, double, double) muladdFast;
alias __ir!(`%p = fmul double %0, %1
%r = fadd double %p, %2
ret double %r`,
double, double, double, double) muladd;
// LLVM-LABEL: define{{.*}} @aliasInlineUnsafe
// LLVM-SAME: #[[UNSAFEFPMATH]]
// ASM-LABEL: aliasInlineUnsafe:
@llvmAttr("unsafe-fp-math", "true")
extern (C) double aliasInlineUnsafe(double[] a, double[] b)
{
double s = 0;
// ASM: vfmadd{{[123][123][123]}}pd
foreach (size_t i; 0 .. a.length)
{
s = muladdFast(a[i], b[i], s);
}
return s;
}
// LLVM-LABEL: define{{.*}} @aliasInlineSafe
// LLVM-SAME: #[[UNSAFEFPMATH2:[0-9]+]]
// ASM-LABEL: aliasInlineSafe:
extern (C) double aliasInlineSafe(double[] a, double[] b)
{
double s = 0;
// ASM-NOT: vfmadd{{[123][123][123]}}pd
foreach (size_t i; 0 .. a.length)
{
s = muladd(a[i], b[i], s);
}
return s;
}
// Make sure an enclosing function's 'noinline' attribute isn't copied to
// the inlined IR function (having 'alwaysinline') (issue #1711).
double neverInlinedEnclosingFunction()
{
pragma(inline, false);
return muladd(1.0, 2.0, 3.0);
}
// LLVM-DAG: attributes #[[UNSAFEFPMATH]] ={{.*}} "unsafe-fp-math"="true"
// LLVM-DAG: attributes #[[UNSAFEFPMATH2]] ={{.*}} "unsafe-fp-math"="false"
// LLVM-DAG: attributes #[[FEAT]] ={{.*}} "target-features"="{{.*}}+fma{{.*}}"
./ldc-1.20.1-src/tests/codegen/attr_targetoptions.d 0000644 0001750 0001750 00000002054 13631266747 022354 0 ustar matthias matthias // REQUIRES: atleast_llvm800
// Tests that our TargetMachine options are added as function attributes
// RUN: %ldc -c -output-ll -of=%t.ll %s
// RUN: FileCheck %s --check-prefix=COMMON --check-prefix=WITH_FP < %t.ll
// RUN: %ldc -c -output-ll -of=%t.ll %s -O2
// RUN: FileCheck %s --check-prefix=COMMON --check-prefix=NO_FP < %t.ll
// RUN: %ldc -c -output-ll -of=%t.ll %s -O2 %disable_fp_elim
// RUN: FileCheck %s --check-prefix=COMMON --check-prefix=WITH_FP < %t.ll
// RUN: %ldc -c -output-ll -of=%t.ll %s %enable_fp_elim -mattr=test
// RUN: FileCheck %s --check-prefix=COMMON --check-prefix=NO_FP --check-prefix=ATTR < %t.ll
// COMMON: define{{.*}} @{{.*}}3fooFZv{{.*}} #[[KEYVALUE:[0-9]+]]
void foo()
{
}
// COMMON: attributes #[[KEYVALUE]]
// COMMON-DAG: "target-cpu"=
// COMMON-DAG: "unsafe-fp-math"="false"
// COMMON-DAG: "less-precise-fpmad"="false"
// COMMON-DAG: "no-infs-fp-math"="false"
// COMMON-DAG: "no-nans-fp-math"="false"
// WITH_FP-DAG: "frame-pointer"="all"
// NO_FP-DAG: "frame-pointer"="none"
// ATTR-DAG: "target-features"="{{[^"]*}}+test
./ldc-1.20.1-src/tests/codegen/attr_target_x86.d 0000644 0001750 0001750 00000003670 13631266747 021452 0 ustar matthias matthias // Tests @target attribute for x86
// REQUIRES: target_X86
// RUN: %ldc -O -c -mcpu=i386 -mtriple=i386-linux-gnu -output-ll -of=%t.ll %s && FileCheck %s --check-prefix LLVM < %t.ll
// RUN: %ldc -O -c -mcpu=i386 -mtriple=i386-linux-gnu -output-s -of=%t.s %s && FileCheck %s --check-prefix ASM < %t.s
import ldc.attributes;
// LLVM-LABEL: define{{.*}} void @{{.*}}foo
// ASM-LABEL: _D15attr_target_x863fooFPfQcfZv:
void foo(float *A, float* B, float K) {
for (int i = 0; i < 128; ++i)
A[i] *= B[i] + K;
// ASM-NOT: addps
}
// LLVM-LABEL: define{{.*}} void @{{.*}}foo_sse
// LLVM-SAME: #[[SSE:[0-9]+]]
// ASM-LABEL: _D15attr_target_x867foo_sseFPfQcfZv:
@(target("sse"))
void foo_sse(float *A, float* B, float K) {
for (int i = 0; i < 128; ++i)
A[i] *= B[i] + K;
// ASM: addps
}
// Make sure that no-sse overrides sse (attribute sorting). Also tests multiple @target attribs.
// LLVM-LABEL: define{{.*}} void @{{.*}}foo_nosse
// LLVM-SAME: #[[NOSSE:[0-9]+]]
// ASM-LABEL: _D15attr_target_x869foo_nosseFPfQcfZv:
@(target("no-sse\n , \tsse "))
void foo_nosse(float *A, float* B, float K) {
for (int i = 0; i < 128; ++i)
A[i] *= B[i] + K;
// ASM-NOT: addps
}
// LLVM-LABEL: define{{.*}} void @{{.*}}bar_nosse
// LLVM-SAME: #[[NOSSE]]
// ASM-LABEL: _D15attr_target_x869bar_nosseFPfQcfZv:
@(target("sse"))
@(target(" no-sse"))
void bar_nosse(float *A, float* B, float K) {
for (int i = 0; i < 128; ++i)
A[i] *= B[i] + K;
// ASM-NOT: addps
}
// LLVM-LABEL: define{{.*}} void @{{.*}}haswell
// LLVM-SAME: #[[HSW:[0-9]+]]
// ASM-LABEL: _D15attr_target_x867haswellFPfQcfZv:
@(target("arch=haswell "))
void haswell(float *A, float* B, float K) {
for (int i = 0; i < 128; ++i)
A[i] *= B[i] + K;
// ASM: vaddps
}
// LLVM-DAG: attributes #[[SSE]] = {{.*}} "target-features"="+sse"
// LLVM-DAG: attributes #[[NOSSE]] = {{.*}} "target-features"="+sse,-sse"
// LLVM-DAG: attributes #[[HSW]] = {{.*}} "target-cpu"="haswell"
./ldc-1.20.1-src/tests/codegen/attr_allocsize_diag.d 0000644 0001750 0001750 00000002315 13631266747 022423 0 ustar matthias matthias // Test ldc.attributes.allocSize diagnostics
// Although @allocSize is only effective for LLVM>=3.9, diagnostics should work for all LLVM versions
// RUN: not %ldc -d-version=NORMAL %s 2>&1 | FileCheck %s --check-prefix=NORMAL
// RUN: not %ldc -d-version=THIS %s 2>&1 | FileCheck %s --check-prefix=THIS
import ldc.attributes;
version(NORMAL)
{
// NORMAL: attr_allocsize_diag.d([[@LINE+2]]): Error: `@ldc.attributes.allocSize.sizeArgIdx=2` too large for function `my_calloc` with 2 arguments.
// NORMAL: attr_allocsize_diag.d([[@LINE+1]]): Error: `@ldc.attributes.allocSize.numArgIdx=2` too large for function `my_calloc` with 2 arguments.
extern (C) void* my_calloc(size_t num, size_t size) @allocSize(2, 2)
{
return null;
}
}
version(THIS)
{
// Test function type with hidden `this` argument
class A
{
// THIS: attr_allocsize_diag.d([[@LINE+2]]): Error: `@ldc.attributes.allocSize.sizeArgIdx=4` too large for function `this_calloc` with 4 arguments.
// THIS: attr_allocsize_diag.d([[@LINE+1]]): Error: `@ldc.attributes.allocSize.numArgIdx=4` too large for function `this_calloc` with 4 arguments.
void* this_calloc(int size, int b, size_t num, int c) @allocSize(4, 4)
{
return null;
}
}
}
./ldc-1.20.1-src/tests/codegen/align_class.d 0000644 0001750 0001750 00000002525 13631266747 020702 0 ustar matthias matthias // RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// RUN: %ldc -run %s
struct S16 { align(16) int a; }
class D { align(32) int d = 0xDD; }
// CHECK: %align_class.D = type { [5 x i8*]*, i8*, [{{(16|24)}} x i8], i32 }
class E : D { S16 s16 = S16(0xEE); }
// CHECK: %align_class.E = type { [5 x i8*]*, i8*, [{{(16|24)}} x i8], i32, [12 x i8], %align_class.S16 }
class F : D { align(64) int f = 0xFF; }
// CHECK: %align_class.F = type { [5 x i8*]*, i8*, [{{(16|24)}} x i8], i32, [28 x i8], i32 }
extern(C++) class CppClass { align(32) int a = 0xAA; }
// CHECK: %align_class.CppClass = type { [0 x i8*]*, [{{(24|28)}} x i8], i32 }
void main()
{
scope d = new D;
// CHECK: = alloca %align_class.D, align 32
static assert(D.d.offsetof == 32);
assert(d.d == 0xDD);
scope e = new E;
// CHECK: = alloca %align_class.E, align 32
static assert(E.d.offsetof == 32);
assert(e.d == 0xDD);
static assert(E.s16.offsetof == 48);
assert(e.s16.a == 0xEE);
scope f = new F;
// CHECK: = alloca %align_class.F, align 64
static assert(F.d.offsetof == 32);
assert(f.d == 0xDD);
static assert(F.f.offsetof == 64);
assert(f.f == 0xFF);
scope cppClass = new CppClass;
// CHECK: = alloca %align_class.CppClass, align 32
static assert(CppClass.a.offsetof == 32);
assert(cppClass.a == 0xAA);
}
./ldc-1.20.1-src/tests/codegen/gh2346.d 0000644 0001750 0001750 00000004314 13631266747 017336 0 ustar matthias matthias // RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// Make sure the LL struct is packed due to an unnatural overall alignment of 1.
// CHECK-DAG: %gh2346.UnalignedUInt = type <{ i32 }>
struct UnalignedUInt {
align(1) uint a;
}
static assert(UnalignedUInt.alignof == 1);
static assert(UnalignedUInt.sizeof == 4);
// Then there's no need to pack naturally aligned containers.
// CHECK-DAG: %gh2346.Container = type { i8, %gh2346.UnalignedUInt }
struct Container {
ubyte one;
UnalignedUInt two;
}
static assert(Container.alignof == 1);
static assert(Container.sizeof == 5);
static assert(Container.two.offsetof == 1);
// CHECK-DAG: %gh2346.UnalignedUInt2 = type <{ i32 }>
struct UnalignedUInt2 {
align(2) uint a;
}
static assert(UnalignedUInt2.alignof == 2);
static assert(UnalignedUInt2.sizeof == 4);
// CHECK-DAG: %gh2346.Container2 = type { i8, [1 x i8], %gh2346.UnalignedUInt2 }
struct Container2 {
ubyte one;
UnalignedUInt2 two;
}
static assert(Container2.alignof == 2);
static assert(Container2.sizeof == 6);
static assert(Container2.two.offsetof == 2);
// CHECK-DAG: %gh2346.PackedContainer2 = type <{ i8, %gh2346.UnalignedUInt2 }>
struct PackedContainer2 {
ubyte one;
align(1) UnalignedUInt2 two;
}
static assert(PackedContainer2.alignof == 1);
static assert(PackedContainer2.sizeof == 5);
static assert(PackedContainer2.two.offsetof == 1);
// CHECK-DAG: %gh2346.WeirdContainer = type { i8, [1 x i8], %gh2346.UnalignedUInt, [2 x i8] }
align(4) struct WeirdContainer {
ubyte one;
align(2) UnalignedUInt two;
}
static assert(WeirdContainer.alignof == 4);
static assert(WeirdContainer.sizeof == 8);
static assert(WeirdContainer.two.offsetof == 2);
// CHECK-DAG: %gh2346.ExplicitlyUnalignedUInt2 = type <{ i32 }>
align(2) struct ExplicitlyUnalignedUInt2 {
uint a;
}
static assert(ExplicitlyUnalignedUInt2.alignof == 2);
static assert(ExplicitlyUnalignedUInt2.sizeof == 4);
// CHECK-DAG: %gh2346.AnotherContainer = type { i8, [1 x i8], %gh2346.ExplicitlyUnalignedUInt2 }
struct AnotherContainer {
ubyte one;
ExplicitlyUnalignedUInt2 two;
}
static assert(AnotherContainer.alignof == 2);
static assert(AnotherContainer.sizeof == 6);
static assert(AnotherContainer.two.offsetof == 2);
./ldc-1.20.1-src/tests/codegen/llvm_used_1.d 0000644 0001750 0001750 00000001613 13631266747 020632 0 ustar matthias matthias // Test that llvm.used is emitted correctly when multiple D modules are compiled into one LLVM module.
// REQUIRES: target_X86
// Explicitly use OS X triple, so that llvm.used is used for moduleinfo globals.
// RUN: %ldc -c -output-ll -O3 %S/inputs/module_ctor.d %s -of=%t.ll -mtriple=x86_64-apple-macosx && FileCheck --check-prefix=LLVM %s < %t.ll
// RUN: %ldc -O3 %S/inputs/module_ctor.d -run %s | FileCheck --check-prefix=EXECUTE %s
// 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 4 llvm.used entries - 2 ModuleInfos refs + ldc.dso_{c,d}tor refs.
// LLVM-NOT: @llvm.used.
// LLVM: @llvm.used = appending global [4 x i8*]
// LLVM-NOT: @llvm.used.
// EXECUTE: ctor
// EXECUTE: main
// EXECUTE: dtor
import core.stdc.stdio;
static ~this()
{
puts("dtor\n");
}
void main() {
puts("main\n");
} ./ldc-1.20.1-src/tests/codegen/ctor_initarray_gh2883.d 0000644 0001750 0001750 00000000427 13631266747 022456 0 ustar matthias matthias // REQUIRES: target_AArch64
// RUN: %ldc -mtriple=aarch64-unknown-linux -output-s -of=%t.s %s
// RUN: FileCheck %s < %t.s
// CHECK-NOT: .ctors
// CHECK-NOT: .dtors
// CHECK: .section .init_array
// CHECK: .section .fini_array
// No code needed to generate asm for a module.
./ldc-1.20.1-src/tests/codegen/array_equals_memcmp.d 0000644 0001750 0001750 00000006571 13631266747 022456 0 ustar matthias matthias // Tests that static array (in)equality is optimized to a memcmp call when valid.
// More importantly: test that memcmp is _not_ used when it is not valid.
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s --check-prefix=LLVM < %t.ll
// RUN: %ldc -O3 -c -output-s -of=%t.s %s && FileCheck %s --check-prefix=ASM < %t.s
// RUN: %ldc -O3 -run %s
module mod;
struct ThreeBytes
{
byte a;
byte b;
byte c;
}
align(4) struct ThreeBytesAligned
{
byte a;
byte b;
byte c;
}
struct Packed
{
byte a;
byte b;
byte c;
byte d;
}
struct PackedPacked
{
Packed a;
Packed b;
}
struct WithPadding
{
int b;
byte a;
}
// LLVM-LABEL: define{{.*}} @{{.*}}two_uints
bool two_uints(ref uint[2] a, const ref uint[2] b)
{
// LLVM: call i32 @memcmp({{.*}}, {{.*}}, i{{32|64}} 8)
return a == b;
}
// LLVM-LABEL: define{{.*}} @{{.*}}unequal_two_uints
bool unequal_two_uints(ref uint[2] a, uint[2] b)
{
// LLVM: call i32 @memcmp({{.*}}, {{.*}}, i{{32|64}} 8)
return a != b;
}
// LLVM-LABEL: define{{.*}} @{{.*}}two_floats
bool two_floats(float[2] a, float[2] b)
{
// LLVM-NOT: memcmp
return a == b;
}
// LLVM-LABEL: define{{.*}} @{{.*}}four_bools
// ASM-LABEL: four_bools{{.*}}:
bool four_bools(bool[4] a, bool[4] b)
{
// LLVM: call i32 @memcmp({{.*}}, {{.*}}, i{{32|64}} 4)
// Make sure that LLVM recognizes and optimizes-out the call to memcmp for 4 byte arrays:
// ASM-NOT: {{(mem|b)cmp}}
return a == b;
}
// LLVM-LABEL: define{{.*}} @{{.*}}array_of_array
// ASM-LABEL: array_of_array{{.*}}:
bool array_of_array(byte[3][3] a, const byte[3][3] b)
{
// LLVM: call i32 @memcmp({{.*}}, {{.*}}, i{{32|64}} 9)
return a == b;
}
// LLVM-LABEL: define{{.*}} @{{.*}}int3_short3
bool int3_short3(int[3] a, short[3] b)
{
// LLVM-NOT: memcmp
return a == b;
// LLVM-LABEL: ret i1
}
// LLVM-LABEL: define{{.*}} @{{.*}}pointer3
bool pointer3(int*[3] a, int*[3] b)
{
// LLVM: call i32 @memcmp({{.*}}, {{.*}}, i{{32|64}} {{12|24}})
return a == b;
}
// LLVM-LABEL: define{{.*}} @{{.*}}enum3
enum E : char { a, b, c, d, e, f };
bool enum3(E[3] a, E[3] b)
{
// LLVM: call i32 @memcmp({{.*}}, {{.*}}, i{{32|64}} 3)
return a == b;
}
class K {}
// LLVM-LABEL: define{{.*}} @{{.*}}klass2
bool klass2(K[2] a, K[2] b)
{
// LLVM-NOT: memcmp
return a == b;
// LLVM-LABEL: ret i1
}
void main()
{
uint[2] a = [1, 2];
uint[2] b = [1, 2];
uint[2] c = [2, 1];
assert(two_uints(a, a));
assert(two_uints(a, b));
assert(!two_uints(a, c));
assert(!unequal_two_uints(a, b));
assert(unequal_two_uints(a, c));
assert( two_floats([1.0f, 2.0f], [1.0f, 2.0f]));
assert(!two_floats([1.0f, 2.0f], [2.0f, 1.0f]));
assert( four_bools([true, false, true, false], [true, false, true, false]));
assert(!four_bools([true, false, true, false], [true, false, true, true]));
assert( array_of_array([[1,2,3],[4,5,6],[7,8,9]],[[1,2,3],[4,5,6],[7,8,9]]));
assert(!array_of_array([[1,2,3],[4,5,6],[7,8,9]],[[6,6,6],[4,5,6],[7,8,9]]));
assert( int3_short3([1, 2, 3], [1, 2, 3]));
assert(!int3_short3([1, 2, 3], [3, 2, 3]));
int aaa = 666;
int bbb = 333;
assert( pointer3([&aaa, &bbb, &aaa], [&aaa, &bbb, &aaa]));
assert(!pointer3([&aaa, &bbb, &aaa], [&bbb, &bbb, &aaa]));
assert( enum3([E.a, E.e, E.b], [E.a, E.e, E.b]));
assert(!enum3([E.a, E.e, E.b], [E.a, E.e, E.f]));
}
./ldc-1.20.1-src/tests/codegen/static_typeid_gh1540.d 0000644 0001750 0001750 00000001727 13631266747 022263 0 ustar matthias matthias // Tests correct codegen for static variables initialized with typeid(A)
// Test for Github issue 1540
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
class C
{
}
interface I
{
}
struct S
{
}
// CHECK-DAG: _D{{.*}}1C7__ClassZ{{\"?}} = global %object.TypeInfo_Class
// CHECK-DAG: _D{{.*}}classvarC14TypeInfo_Class{{\"?}} = thread_local global %object.TypeInfo_Class* {{.*}}1C7__ClassZ
auto classvar = typeid(C);
// CHECK-DAG: _D{{.*}}TypeInfo_C{{.*}}1I6__initZ{{\"?}} = linkonce_odr global %object.TypeInfo_Interface
// CHECK-DAG: _D{{.*}}interfacevarC18TypeInfo_Interface{{\"?}} = thread_local global %object.TypeInfo_Interface* {{.*}}TypeInfo_C{{.*}}1I6__initZ
auto interfacevar = typeid(I);
// CHECK-DAG: _D{{.*}}TypeInfo_S{{.*}}1S6__initZ{{\"?}} = linkonce_odr global %object.TypeInfo_Struct
// CHECK-DAG: _D{{.*}}structvarC15TypeInfo_Struct{{\"?}} = thread_local global %object.TypeInfo_Struct* {{.*}}TypeInfo_S{{.*}}1S6__initZ
auto structvar = typeid(S);
./ldc-1.20.1-src/tests/codegen/array_equals_memcmp_dyn.d 0000644 0001750 0001750 00000004037 13631266747 023323 0 ustar matthias matthias // Tests that dynamic array (in)equality is optimized to a memcmp call when valid.
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s --check-prefix=LLVM < %t.ll
// RUN: %ldc -c -output-s -O3 -of=%t.s %s && FileCheck %s --check-prefix=ASM < %t.s
// RUN: %ldc -O0 -run %s
// RUN: %ldc -O3 -run %s
module mod;
// LLVM-LABEL: define{{.*}} @{{.*}}static_dynamic
// ASM-LABEL: static_dynamic{{.*}}:
bool static_dynamic(bool[4] a, bool[] b)
{
// LLVM: call i32 @memcmp(
// Also test that LLVM recognizes and optimizes-out the call to memcmp for 4 byte arrays:
// ASM-NOT: {{(mem|b)cmp}}
return a == b;
}
// LLVM-LABEL: define{{.*}} @{{.*}}inv_dynamic_dynamic
// ASM-LABEL: inv_dynamic_dynamic{{.*}}:
bool inv_dynamic_dynamic(bool[] a, bool[] b)
{
// The front-end turns this into a call to druntime template function `object.__equals!(bool, bool).__equals(bool[], bool[])`
// After optimization (inlining), it should boil down to a length check and a call to memcmp.
// ASM: {{(mem|b)cmp}}
return a != b;
}
// LLVM-LABEL: define{{.*}} @{{.*}}_D4core8internal5array8equality__T8__equals
// ASM-LABEL: _D4core8internal5array8equality__T8__equals{{.*}}:
// LLVM-LABEL: define{{.*}} @_Dmain
// ASM-LABEL: _Dmain:
void main()
{
assert( static_dynamic([true, false, true, false], [true, false, true, false]));
assert(!static_dynamic([true, false, true, false], [true, false, true, true]));
assert(!static_dynamic([true, false, true, false], [true, false, true, false, true]));
assert(!static_dynamic([true, false, true, false], [true, false, true]));
assert(!inv_dynamic_dynamic([true, false, true, false], [true, false, true, false]));
assert( inv_dynamic_dynamic([true, false, true, false], [true, false, true, true]));
assert( inv_dynamic_dynamic([true, false], [true]));
assert( inv_dynamic_dynamic([true, false, true, false], [true, false, true]));
// Make sure that comparing zero-length arrays with ptr=null is allowed.
bool* ptr = null;
assert(!inv_dynamic_dynamic(ptr[0..0], ptr[0..0]));
}
./ldc-1.20.1-src/tests/codegen/frame_pointer_x86.d 0000644 0001750 0001750 00000001630 13631266747 021756 0 ustar matthias matthias // REQUIRES: target_X86
// RUN: %ldc -c -mtriple=x86_64 -output-s -of=%t.s %s
// RUN: FileCheck %s --check-prefixes=COMMON,FP < %t.s
// RUN: %ldc -c -mtriple=x86_64 -output-s -of=%t.s %s -O2
// RUN: FileCheck %s --check-prefixes=COMMON,NO_FP < %t.s
// RUN: %ldc -c -mtriple=x86_64 -output-s -of=%t.s %s -O2 %disable_fp_elim
// RUN: FileCheck %s --check-prefixes=COMMON,FP < %t.s
// RUN: %ldc -c -mtriple=x86_64 -output-s -of=%t.s %s %enable_fp_elim
// RUN: FileCheck %s --check-prefixes=COMMON,NO_FP < %t.s
// COMMON-LABEL: _D17frame_pointer_x8613inlineAsmLeafFZv:
// COMMON: pushq %rbp
// COMMON-LABEL: _D17frame_pointer_x8616inlineAsmNonLeafFZv:
// COMMON: pushq %rbp
// COMMON-LABEL: _D17frame_pointer_x863fooFZv:
// FP: pushq %rbp
// NO_FP-NOT: pushq %rbp
void externalFunc();
void inlineAsmLeaf() { asm { nop; } }
void inlineAsmNonLeaf() { asm { nop; } externalFunc(); }
void foo() {}
./ldc-1.20.1-src/tests/codegen/inlining_staticvar.d 0000644 0001750 0001750 00000003404 13631266747 022307 0 ustar matthias matthias // Test cross-module inlining involving static variables
// RUN: %ldc %s -I%S -c -output-ll -O3 -of=%t.O3.ll && FileCheck %s --check-prefix OPT3 < %t.O3.ll
// RUN: %ldc %s -I%S -c -output-ll -enable-inlining -O0 -of=%t.O0.ll && FileCheck %s --check-prefix OPT0 < %t.O0.ll
// RUN: %ldc -I%S -enable-inlining %S/inputs/inlinables_staticvar.d -run %s
// RUN: %ldc -I%S -O3 %S/inputs/inlinables_staticvar.d -run %s
import inputs.inlinables_staticvar;
import ldc.attributes;
extern (C): // simplify mangling for easier matching
// Functions are intentionally split and @weak to thwart LLVM constant folding.
void checkModuleScope_1() @weak
{
addToModuleScopeInline(7);
}
void checkModuleScope_2() @weak
{
addToModuleScopeOutline(101);
assert(equalModuleScope(7+101));
}
void checkInsideFunc_1() @weak
{
assert(addAndCheckInsideFunc(0, 7));
}
void checkInsideFunc_2() @weak
{
assert(addAndCheckInsideFuncIndirect(7, 101));
assert(addAndCheckInsideFunc(7+101, 9));
}
void checkInsideNestedFunc_1() @weak
{
assert(addAndCheckInsideNestedFunc(0, 7));
}
void checkInsideNestedFunc_2() @weak
{
assert(addAndCheckInsideNestedFuncIndirect(7, 101));
assert(addAndCheckInsideNestedFunc(7+101, 9));
}
void checkNestedStruct_1() @weak
{
assert(addAndCheckNestedStruct(0, 7));
}
void checkNestedStruct_2() @weak
{
assert(addAndCheckNestedStructIndirect(7, 101));
assert(addAndCheckNestedStruct(7+101, 9));
}
// OPT0-LABEL: define{{.*}} @_Dmain(
// OPT3-LABEL: define{{.*}} @_Dmain(
extern(D)
void main()
{
checkModuleScope_1();
checkModuleScope_2();
checkInsideFunc_1();
checkInsideFunc_2();
checkInsideNestedFunc_1();
checkInsideNestedFunc_2();
checkNestedStruct_1();
checkNestedStruct_2();
}
./ldc-1.20.1-src/tests/codegen/attr_fastmath.d 0000644 0001750 0001750 00000002141 13631266747 021256 0 ustar matthias matthias // Test @fastmath
// RUN: %ldc -O0 -release -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
import ldc.attributes;
// CHECK-LABEL: define{{.*}} @notfast
// CHECK-SAME: #[[ATTR_NOTFAST:[0-9]+]]
extern (C) double notfast(double a, double b)
{
@fastmath
double nested_fast(double a, double b)
{
return a * b;
}
// CHECK-NOT: fmul fast
return a * b;
}
// CHECK-LABEL: define{{.*}} @{{.*}}nested_fast
// CHECK: fmul fast
// CHECK-LABEL: define{{.*}} @fast
// CHECK-SAME: #[[ATTR_FAST:[0-9]+]]
@fastmath
extern (C) double fast(double a, double b)
{
double c;
double nested_slow(double a, double b)
{
return a * b;
}
// Also test new scopes when generating the IR.
try {
// CHECK: fmul fast
c += a * b;
}
catch (Throwable)
{
// CHECK: fmul fast
return a * b;
}
// CHECK: fmul fast
return c + a * b;
}
// CHECK-LABEL: define{{.*}} @{{.*}}nested_slow
// CHECK-NOT: fmul fast
// CHECK-DAG: attributes #[[ATTR_FAST]] ={{.*}} "unsafe-fp-math"="true"
// CHECK-NOT: attributes #[[ATTR_NOTFAST]] ={{.*}} "unsafe-fp-math"="true"
./ldc-1.20.1-src/tests/codegen/gh2729.d 0000644 0001750 0001750 00000000527 13631266747 017345 0 ustar matthias matthias // RUN: %ldc -run %s
ulong[2] foo(ulong a, ulong b) @nogc nothrow pure @safe
{
import ldc.simd;
return inlineIR!(`
%agg1 = insertvalue [2 x i64] undef, i64 %0, 0
%agg2 = insertvalue [2 x i64] %agg1, i64 %1, 1
ret [2 x i64] %agg2`, ulong[2])(a, b);
}
void main()
{
assert(foo(123, 456) == [ 123, 456 ]);
}
./ldc-1.20.1-src/tests/codegen/inlining_pragma.d 0000644 0001750 0001750 00000003135 13631266747 021557 0 ustar matthias matthias // Test inlining of functions marked with pragma(inline)
// RUN: %ldc %s -I%S -c -output-ll -O0 -of=%t.O0.ll && FileCheck %s --check-prefix OPTNONE < %t.O0.ll
// RUN: %ldc %s -I%S -c -output-ll -O3 -of=%t.O3.ll && FileCheck %s --check-prefix OPT3 < %t.O3.ll
extern (C): // simplify mangling for easier matching
int dummy;
// OPTNONE-LABEL: define{{.*}} @never_inline
// OPTNONE-SAME: #[[NEVER:[0-9]+]]
pragma(inline, false) int never_inline()
{
dummy = 111;
return 222;
}
int external();
// OPTNONE-LABEL: define{{.*}} @always_inline
// OPTNONE-SAME: #[[ALWAYS:[0-9]+]]
pragma(inline, true) int always_inline()
{
int a;
foreach (i; 1 .. 10)
{
foreach (ii; 1 .. 10)
{
foreach (iii; 1 .. 10)
{
a += i * external();
}
}
}
dummy = 444;
return a;
}
// OPTNONE-LABEL: define{{.*}} @foo
// OPTNONE-SAME: #[[FOO:[0-9]+]]
int foo()
{
return 333;
}
// OPT3-LABEL: define{{.*}} @call_always_inline
int call_always_inline()
{
// OPT3-NOT: call {{.*}} @always_inline()
// OPT3: ret
return always_inline();
}
// OPT3-LABEL: define{{.*}} @call_never_inline
int call_never_inline()
{
// OPT3: call {{.*}} @never_inline()
// OPT3: ret
return never_inline();
}
// OPTNONE-NOT: attributes #[[FOO]] ={{.*}} alwaysinline
// OPTNONE-NOT: attributes #[[FOO]] ={{.*}} noinline
// OPTNONE-NOT: attributes #[[NEVER]] ={{.*}} alwaysinline
// OPTNONE-NOT: attributes #[[ALWAYS]] ={{.*}} noinline
// OPTNONE-DAG: attributes #[[NEVER]] ={{.*}} noinline
// OPTNONE-DAG: attributes #[[ALWAYS]] ={{.*}} alwaysinline
./ldc-1.20.1-src/tests/codegen/fence_pragma.d 0000644 0001750 0001750 00000000531 13631266747 021025 0 ustar matthias matthias // RUN: %ldc %s -c -output-ll -of=%t.ll && FileCheck %s < %t.ll
// REQUIRES: atmost_llvm400
import ldc.intrinsics;
void fun0 () {
llvm_memory_fence(DefaultOrdering, SynchronizationScope.CrossThread);
// CHECK: fence seq_cst
llvm_memory_fence(DefaultOrdering, SynchronizationScope.SingleThread);
// CHECK: fence singlethread seq_cst
}
./ldc-1.20.1-src/tests/codegen/gh1843.d 0000644 0001750 0001750 00000000327 13631266747 017337 0 ustar matthias matthias // Just make sure LDC doesn't necessarily enforce the .ll extension (issue #1843).
// RUN: %ldc -output-ll -of=%t.myIR %s && FileCheck %s < %t.myIR
// CHECK: define{{.*}} void @{{.*}}_D6gh18433fooFZv
void foo() {}
./ldc-1.20.1-src/tests/codegen/inlining_invariants_gh1678.d 0000644 0001750 0001750 00000001024 13631266747 023465 0 ustar matthias matthias // RUN: %ldc --enable-inlining -of=%t%exe %s
// https://github.com/ldc-developers/ldc/issues/1678
import std.datetime;
// Extra test that fail when a simple frontend change is tried that names __invariant using the line and column number.
class A {
mixin(genInv("666")); mixin(genInv("777"));
}
string genInv(string a) {
return "invariant() { }";
}
void main()
{
auto currentTime = Clock.currTime();
auto timeString = currentTime.toISOExtString();
auto restoredTime = SysTime.fromISOExtString(timeString);
} ./ldc-1.20.1-src/tests/codegen/gh2515.d 0000644 0001750 0001750 00000003224 13631266747 017333 0 ustar matthias matthias // For scope-allocated class objects, make sure the _d_callfinalizer()
// druntime call is elided if the object has no dtors and no monitor.
// RUN: %ldc -O3 -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
import core.stdc.stdio : printf;
class Base
{
int val = 123;
void foo() { val *= 3; }
void bar() { synchronized(this) val *= 2; }
}
class WithDtor : Base
{
~this() {}
}
class WithImplicitDtor : Base
{
static struct S { int val; ~this() {} }
S s;
}
// CHECK: define{{.*}} void @{{.*}}_D6gh251516noDtor_noMonitorFZv
void noDtor_noMonitor()
{
scope b = new Base();
b.foo();
printf("%d\n", b.val);
// CHECK-NOT: _d_callfinalizer
// CHECK: ret void
}
// CHECK: define{{.*}} void @{{.*}}_D6gh251518noDtor_withMonitorFZv
void noDtor_withMonitor()
{
scope b = new Base();
b.bar();
printf("%d\n", b.val);
// CHECK: _d_callfinalizer
// CHECK: ret void
}
// CHECK: define{{.*}} void @{{.*}}_D6gh25158withDtorFZv
void withDtor()
{
scope Base b = new WithDtor();
b.foo();
printf("%d\n", b.val);
// CHECK: _d_callfinalizer
// CHECK: ret void
}
// CHECK: define{{.*}} void @{{.*}}_D6gh251516withImplicitDtorFZv
void withImplicitDtor()
{
scope Base b = new WithImplicitDtor();
b.foo();
printf("%d\n", b.val);
// CHECK: _d_callfinalizer
// CHECK: ret void
}
/* Test a C++ class as well, which as of 2.077 isn't implicitly delete()d. */
extern(C++) class CppClass
{
int val = 666;
}
// CHECK: define{{.*}} void @{{.*}}_D6gh25158cppClassFZv
void cppClass()
{
scope c = new CppClass();
printf("%d\n", c.val);
// CHECK-NOT: _d_callfinalizer
// CHECK: ret void
}
./ldc-1.20.1-src/tests/codegen/array_literal_gh1924.d 0000644 0001750 0001750 00000004143 13631266747 022251 0 ustar matthias matthias // RUN: %ldc -c -O3 -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// RUN: %ldc -d-version=RUN -run %s
// CHECK-LABEL: define{{.*}} @{{.*}}simple2d
auto simple2d()
{
// CHECK: _d_newarrayU
// CHECK: _d_newarrayU
// CHECK-NOT: _d_newarrayU
// CHECK: ret {
return [[1.0]];
}
// GitHub issue #1925
// CHECK-LABEL: define{{.*}} @{{.*}}make2d
auto make2d()
{
// CHECK: _d_newarrayU
// CHECK-NOT: _d_newarrayU
double[][1] a = [[1.0]];
// CHECK: ret
return a;
}
// CHECK-LABEL: define{{.*}} @{{.*}}make3d
auto make3d()
{
// CHECK: _d_newarrayU
// CHECK: _d_newarrayU
// CHECK-NOT: _d_newarrayU
int[][1][] a = [[[1]]];
// CHECK: ret {
return a;
}
struct S
{
auto arr = [[321]];
}
// CHECK-LABEL: define{{.*}} @{{.*}}makeS
auto makeS()
{
// CHECK: _d_newarrayU
// CHECK: _d_newarrayU
// CHECK-NOT: _d_newarrayU
// CHECK: ret
return S();
}
mixin template A()
{
auto a = [1, 2, 3];
auto b = [[1, 2, 3]];
}
version (RUN)
{
void main()
{
{
auto a = simple2d();
auto b = simple2d();
assert(a.ptr !is b.ptr);
assert(a[0].ptr !is b[0].ptr);
}
{
auto a = make2d();
auto b = make2d();
assert(a.ptr !is b.ptr);
assert(a[0].ptr !is b[0].ptr);
}
{
auto a = make3d();
auto b = make3d();
assert(a.ptr !is b.ptr);
assert(a[0].ptr !is b[0].ptr);
assert(a[0][0].ptr !is b[0][0].ptr);
}
{
enum e = [[1.0]];
auto a = e;
auto b = e;
assert(a.ptr !is b.ptr);
assert(a[0].ptr !is b[0].ptr);
}
{
auto a = makeS();
auto b = makeS();
assert(a.arr.ptr !is b.arr.ptr);
assert(a.arr[0].ptr !is b.arr[0].ptr);
}
{
mixin A!() a0;
mixin A!() a1;
assert(a0.a.ptr !is a1.a.ptr);
assert(a0.b.ptr !is a1.b.ptr);
assert(a0.b[0].ptr !is a1.b[0].ptr);
}
}
}
./ldc-1.20.1-src/tests/codegen/gc2stack.d 0000644 0001750 0001750 00000003536 13631266747 020127 0 ustar matthias matthias // RUN: %ldc -O2 -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// RUN: %ldc -O2 -disable-gc2stack -c -output-ll -of=%t.ll %s && FileCheck %s --check-prefix NOOPT < %t.ll
class Bar
{
int i;
}
// CHECK: define
int foo1()
{
// NOOPT: call{{.*}}_d_newarrayT
// CHECK-NOT: _d_newarrayT
int[] i = new int[5];
i[3] = 42;
// CHECK: ret
return i[3];
}
// CHECK: define
int foo2()
{
// NOOPT: call{{.*}}_d_allocmemoryT
// CHECK-NOT: _d_allocmemoryT
int* i = new int;
*i = 42;
// CHECK: ret
return *i;
}
// CHECK: define
int foo3()
{
// NOOPT: call{{.*}}_d_allocclass
// CHECK-NOT: _d_allocclass
Bar i = new Bar;
i.i = 42;
// CHECK: ret
return i.i;
}
int[] bar1()
{
// CHECK: _d_newarrayT
int[] i = new int[5];
// CHECK: ret
return i;
}
int* bar2()
{
// CHECK: _d_allocmemoryT
int* i = new int;
// CHECK: ret
return i;
}
Bar bar3()
{
// CHECK: _d_allocclass
Bar i = new Bar;
// CHECK: ret
return i;
}
extern void fun(int[]);
extern void fun(int*);
extern void fun(Bar);
// CHECK: define
int baz1()
{
// CHECK: _d_newarrayT
int[] i = new int[5];
fun(i);
i[3] = 42;
// CHECK: ret
return i[3];
}
// CHECK: define
int baz2()
{
// CHECK: _d_allocmemoryT
int* i = new int;
fun(i);
*i = 42;
// CHECK: ret
return *i;
}
// CHECK: define
int baz3()
{
// CHECK: _d_allocclass
Bar i = new Bar;
fun(i);
i.i = 42;
// CHECK: ret
return i.i;
}
__gshared int[] p1;
__gshared int* p2;
__gshared Bar p3;
// CHECK: define
int bzz1()
{
// CHECK: _d_newarrayT
int[] i = new int[5];
p1 = i;
i[3] = 42;
// CHECK: ret
return i[3];
}
// CHECK: define
int bzz2()
{
// CHECK: _d_allocmemoryT
int* i = new int;
p2 = i;
*i = 42;
// CHECK: ret
return *i;
}
// CHECK: define
int bzz3()
{
// CHECK: _d_allocclass
Bar i = new Bar;
p3 = i;
i.i = 42;
// CHECK: ret
return i.i;
}
./ldc-1.20.1-src/tests/codegen/dcompute_cu_addrspaces.d 0000644 0001750 0001750 00000002614 13631266747 023122 0 ustar matthias matthias // REQUIRES: target_NVPTX
// RUN: %ldc -c -mdcompute-targets=cuda-350 -m64 -mdcompute-file-prefix=addrspace -output-ll -output-o %s && FileCheck %s --check-prefix=LL < addrspace_cuda350_64.ll && FileCheck %s --check-prefix=PTX < addrspace_cuda350_64.ptx
@compute(CompileFor.deviceOnly) module dcompute_cu_addrspaces;
import ldc.dcompute;
// LL: %"ldc.dcompute.Pointer!(cast(AddrSpace)0u, float).Pointer" = type { float addrspace(5)* }
// LL: %"ldc.dcompute.Pointer!(cast(AddrSpace)1u, float).Pointer" = type { float addrspace(1)* }
// LL: %"ldc.dcompute.Pointer!(cast(AddrSpace)2u, float).Pointer" = type { float addrspace(3)* }
// LL: %"ldc.dcompute.Pointer!(cast(AddrSpace)3u, immutable(float)).Pointer" = type { float addrspace(4)* }
// LL: %"ldc.dcompute.Pointer!(cast(AddrSpace)4u, float).Pointer" = type { float* }
void foo(PrivatePointer!float f) {
// LL: load float, float addrspace(5)*
// PTX: ld.local.f32
float g = *f;
}
void foo(GlobalPointer!float f) {
// LL: load float, float addrspace(1)*
// PTX: ld.global.f32
float g = *f;
}
void foo(SharedPointer!float f) {
// LL: load float, float addrspace(3)*
// PTX: ld.shared.f32
float g = *f;
}
void foo(ConstantPointer!float f) {
// LL: load float, float addrspace(4)*
// PTX: ld.const.f32
float g = *f;
}
void foo(GenericPointer!float f) {
// LL: load float, float*
// PTX: ld.f32
float g = *f;
}
./ldc-1.20.1-src/tests/codegen/array_equals_memcmp_2.d 0000644 0001750 0001750 00000000550 13631266747 022666 0 ustar matthias matthias // Tests that static array (in)equality of unequal lengths is optimized to `false`.
// RUN: %ldc -c -O3 -output-ll -of=%t.ll %s && FileCheck %s --check-prefix=LLVM < %t.ll
// LLVM-LABEL: define{{.*}} @{{.*}}different_lengths
// ASM-LABEL: different_lengths{{.*}}:
bool different_lengths(bool[4] a, bool[3] b)
{
// LLVM: ret i1 false
return a == b;
}
./ldc-1.20.1-src/tests/codegen/nested_lazy_gh2302.d 0000644 0001750 0001750 00000000667 13631266747 021736 0 ustar matthias matthias // RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// RUN: %ldc -run %s
void foo()
{
auto impl(T)(lazy T field)
{
// Make sure `field` is a closure variable with delegate type (LL struct).
// CHECK: %nest.impl = type { { i8*, i32 (i8*)* } }
auto ff() { return field; }
auto a = field;
return ff() + a;
}
auto r = impl(123);
assert(r == 246);
}
void main() { foo(); }
./ldc-1.20.1-src/tests/codegen/dcompute_host_and_device.d 0000644 0001750 0001750 00000000606 13631266747 023437 0 ustar matthias matthias // Check that we can generate code for both the host and device in one compiler invocation
// REQUIRES: target_NVPTX
// RUN: %ldc -mdcompute-targets=cuda-350 -mdcompute-file-prefix=host_and_device -Iinputs %s %S/inputs/kernel.d
import inputs.kernel : foo;
int tlGlobal;
__gshared int gGlobal;
void main(string[] args)
{
tlGlobal = 0;
gGlobal = 0;
string s = foo.mangleof;
}
./ldc-1.20.1-src/tests/codegen/varargs.d 0000644 0001750 0001750 00000000344 13631266747 020065 0 ustar matthias matthias // RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// Make sure typesafe variadics are not lowered to LLVM variadics.
void typesafe(size_t[2] a...) {}
// CHECK: define{{.*}}typesafe
// CHECK-NOT: ...
// CHECK-SAME: {
./ldc-1.20.1-src/tests/codegen/zerolengtharray_gh1611.d 0000644 0001750 0001750 00000001502 13631266747 022624 0 ustar matthias matthias // RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
struct A0
{
ubyte[0] zerolen;
}
// CHECK-DAG: %{{.*}}.A0 = type { [1 x i8] }
struct uint_0_uint
{
uint a = 111;
ubyte[0] zerolen;
uint c = 333;
}
// CHECK-DAG: %{{.*}}.uint_0_uint = type { i32, i32 }
// No tests for codegen with e.g. uint_0_uint yet, because codegen could be much improved.
// I think codegen should be the same as for
// struct uint_uint
// {
// uint a = 111;
// uint c = 333;
// }
// CHECK-LABEL: define{{.*}}fooA0{{.*}} {
auto fooA0()
{
return A0();
// Intentionally a regexp to not match "sret"
// CHECK: {{ ret }}
}
// CHECK-LABEL: define{{.*}}foo_uint_0_uint
auto foo_uint_0_uint()
{
return uint_0_uint();
// Intentionally a regexp to not match "sret"
// CHECK: {{ ret }}
}
./ldc-1.20.1-src/tests/codegen/gh3221.d 0000644 0001750 0001750 00000000501 13631266747 017321 0 ustar matthias matthias // RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
import ldc.attributes: assumeUsed;
union U
{
ubyte a;
uint b;
}
// CHECK: @{{.*}}_D6gh32211uSQk1U{{.*}} = global { i32 } { i32 12345 }
// CHECK: @llvm.used = appending global
// CHECK-SAME: _D6gh32211uSQk1U
@assumeUsed __gshared U u = { b: 12345 };
./ldc-1.20.1-src/tests/codegen/array_catassign_gh2588.d 0000644 0001750 0001750 00000000265 13631266747 022601 0 ustar matthias matthias // RUN: %ldc -run %s
int work(ref int[] array)
{
array ~= 123;
return 456;
}
void main()
{
int[] array;
array ~= work(array);
assert(array == [ 123, 456 ]);
}
./ldc-1.20.1-src/tests/codegen/nothrow.d 0000644 0001750 0001750 00000003302 13631266747 020115 0 ustar matthias matthias // RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
struct S
{
~this() nothrow {}
void foo() nothrow { throw new Error("foo"); }
}
struct Throwing
{
~this() {}
void bar() { throw new Exception("bar"); }
}
// CHECK-LABEL: define{{.*}} @{{.*}}_D7nothrow15inTryCatchErrorFZv
void inTryCatchError()
{
try
{
// make sure the nothrow functions S.foo() and S.~this()
// are invoked in try-blocks with at least 1 catch block
S a;
// CHECK: invoke {{.*}}_D7nothrow1S3fooMFNbZv{{.*}} %a
a.foo();
// CHECK: invoke {{.*}}_D7nothrow1S6__dtorMFNbZv{{.*}} %a
}
catch (Error) {}
}
// CHECK-LABEL: define{{.*}} @{{.*}}_D7nothrow19inTryCatchExceptionFZv
void inTryCatchException()
{
// make sure the nothrow functions are never invoked
// CHECK-NOT: invoke {{.*}}_D7nothrow1S3fooMFNbZv
// CHECK-NOT: invoke {{.*}}_D7nothrow1S6__dtorMFNbZv
try
{
S a;
a.foo();
}
catch (Exception) {}
}
// CHECK-LABEL: define{{.*}} @{{.*}}_D7nothrow12inTryFinallyFZv
void inTryFinally()
{
// make sure the nothrow functions are never invoked
// CHECK-NOT: invoke {{.*}}_D7nothrow1S3fooMFNbZv
// CHECK-NOT: invoke {{.*}}_D7nothrow1S6__dtorMFNbZv
try
{
S a;
a.foo();
}
finally
{
S b;
b.foo();
}
}
// CHECK-LABEL: define{{.*}} @{{.*}}_Dmain
void main()
{
// make sure the nothrow functions are never invoked
// CHECK-NOT: invoke {{.*}}_D7nothrow1S3fooMFNbZv
// CHECK-NOT: invoke {{.*}}_D7nothrow1S6__dtorMFNbZv
Throwing t;
S a;
a.foo();
t.bar();
{
S b;
t.bar();
b.foo();
S().foo();
}
}
./ldc-1.20.1-src/tests/codegen/attr_llvmFMF_contract.d 0000644 0001750 0001750 00000001330 13631266747 022646 0 ustar matthias matthias // Tests the @ldc.attributes.llvmFastMathFlag("contract") UDA
// Also tests that adding this attribute indeed leads to LLVM optimizing it to a fused multiply-add for a simple case.
// REQUIRES: atleast_llvm500, target_X86
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s --check-prefix LLVM < %t.ll
// RUN: %ldc -betterC -mtriple=x86_64-linux-gnu -mattr=+fma -O3 -release -c -output-s -of=%t.s %s && FileCheck %s --check-prefix ASM < %t.s
import ldc.attributes;
// LLVM-LABEL: define{{.*}} @{{.*}}contract
// ASM-LABEL: contract:
@llvmFastMathFlag("contract")
extern(C) double contract(double a, double b, double c)
{
// LLVM: fmul contract double
// LLVM: fadd contract double
// ASM: vfmadd
return a * b + c;
}
./ldc-1.20.1-src/tests/codegen/static_array_huge.d 0000644 0001750 0001750 00000000453 13631266747 022116 0 ustar matthias matthias // Tests that static arrays can be large (> 16MB)
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// CHECK: Stuff = type { [209715200 x i8] }
struct Stuff
{
byte[1024*1024*200] a;
}
// CHECK: hugeArrayG209715200g{{\"?}} ={{.*}} [209715200 x i8]
byte[1024*1024*200] hugeArray;
./ldc-1.20.1-src/tests/codegen/attr_llvmattr.d 0000644 0001750 0001750 00000001043 13631266747 021314 0 ustar matthias matthias // Tests @llvmAttr attribute
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
import ldc.attributes;
extern (C): // For easier name mangling
// CHECK: define{{.*}} @keyvalue{{.*}} #[[KEYVALUE:[0-9]+]]
@(llvmAttr("key", "value"))
void keyvalue()
{
}
// CHECK: define{{.*}} @keyonly{{.*}} #[[KEYONLY:[0-9]+]]
@(llvmAttr("keyonly"))
void keyonly()
{
}
// CHECK-DAG: attributes #[[KEYVALUE]] = {{.*}} "key"="value"
// CHECK-NOT: attributes #[[KEYONLY]] = {{.*}} "keyonly"=
// CHECK-DAG: attributes #[[KEYONLY]] = {{.*}} "keyonly"
./ldc-1.20.1-src/tests/codegen/attr_weak_external.d 0000644 0001750 0001750 00000000453 13631266747 022304 0 ustar matthias matthias // Test that an imported @weak function does not result in an extern_weak reference.
// RUN: %ldc -c -I%S -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
import inputs.attr_weak_external_input: weak_definition_seven;
void foo()
{
auto a = &weak_definition_seven;
}
// CHECK-NOT: extern_weak
./ldc-1.20.1-src/tests/codegen/dmd_inline_asm_ip.d 0000644 0001750 0001750 00000000554 13631266747 022055 0 ustar matthias matthias // REQUIRES: target_X86
// RUN: %ldc -output-s -x86-asm-syntax=intel -mtriple=x86_64-linux-gnu -of=%t.s %s
// RUN: FileCheck %s < %t.s
// CHECK: _D17dmd_inline_asm_ip3fooFZm
ulong foo()
{
asm
{
// CHECK: mov eax, dword ptr [eip]
mov EAX, [EIP];
// CHECK-NEXT: mov rax, qword ptr [rip]
mov RAX, [RIP];
ret;
}
}
./ldc-1.20.1-src/tests/codegen/attr_targetoptions_fp.d 0000644 0001750 0001750 00000001056 13631266747 023042 0 ustar matthias matthias // See Github issue #1860
// RUN: %ldc -c -output-ll -of=%t.ll -float-abi=soft %s && FileCheck --check-prefix=SOFT %s < %t.ll
// RUN: %ldc -c -output-ll -of=%t.ll -float-abi=softfp %s && FileCheck --check-prefix=HARD %s < %t.ll
// SOFT: define{{.*}} @{{.*}}3fooFZv{{.*}} #[[KEYVALUE:[0-9]+]]
// HARD: define{{.*}} @{{.*}}3fooFZv{{.*}} #[[KEYVALUE:[0-9]+]]
void foo()
{
}
// SOFT: attributes #[[KEYVALUE]]
// SOFT-DAG: "target-features"="{{.*}}+soft-float{{.*}}"
// HARD: attributes #[[KEYVALUE]]
// HARD-NOT: "target-features"="{{.*}}+soft-float{{.*}}"
./ldc-1.20.1-src/tests/codegen/funcliteral_defaultarg_gh1634.d 0000644 0001750 0001750 00000001326 13631266747 024123 0 ustar matthias matthias // Test function literal as default argument
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// RUN: %ldc -run %s
module mod;
// CHECK-LABEL: define{{.*}} @{{.*}}D3mod3fooFPFZiZi
int foo(int function() d = () { return 123; })
{
return d();
}
// CHECK-LABEL: define{{.*}} @{{.*}}D3mod8call_fooFZi
int call_foo()
{
// CHECK: call {{.*}}D3mod3fooFPFZiZi{{.*}}D3mod9__lambda5FZi
return foo();
}
// The lambda is defined by the first call to foo with default arguments.
// CHECK-LABEL: define{{.*}} @{{.*}}D3mod9__lambda5FZi
// CHECK: ret i32 123
// CHECK-LABEL: define{{.*}} @{{.*}}Dmain
void main()
{
// CHECK: call {{.*}}D3mod3fooFPFZiZi{{.*}}D3mod9__lambda5FZi
assert(foo() == 123);
}
./ldc-1.20.1-src/tests/codegen/pragma_no_typeinfo.d 0000644 0001750 0001750 00000001663 13631266747 022305 0 ustar matthias matthias // Make sure the LDC_no_typeinfo pragma prevents TypeInfo emission.
// RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
pragma(LDC_no_moduleinfo); // prevent ModuleInfo from referencing class TypeInfos
// CHECK: _D50TypeInfo_S18pragma_no_typeinfo18StructWithTypeInfo6__initZ = linkonce_odr global %object.TypeInfo_Struct
struct StructWithTypeInfo {}
// CHECK: _D18pragma_no_typeinfo17ClassWithTypeInfo7__ClassZ = global %object.TypeInfo_Class
class ClassWithTypeInfo {}
// CHECK: _D18pragma_no_typeinfo21InterfaceWithTypeInfo11__InterfaceZ = global %object.TypeInfo_Class
interface InterfaceWithTypeInfo {}
pragma(LDC_no_typeinfo):
// CHECK-NOT: _D48TypeInfo_S18pragma_no_typeinfo16StructNoTypeInfo6__initZ
struct StructNoTypeInfo {}
// CHECK-NOT: _D18pragma_no_typeinfo15ClassNoTypeInfo7__ClassZ
class ClassNoTypeInfo {}
// CHECK-NOT: _D18pragma_no_typeinfo19InterfaceNoTypeInfo11__InterfaceZ
interface InterfaceNoTypeInfo {}
./ldc-1.20.1-src/tests/codegen/linker_directives_mac.d 0000644 0001750 0001750 00000000626 13631266747 022750 0 ustar matthias matthias // RUN: %ldc -mtriple=x86_64-apple-darwin -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// REQUIRES: atleast_llvm500, target_X86
// CHECK: !llvm.linker.options = !{!0, !1, !2}
// CHECK: !0 = !{!"-lmylib"}
pragma(lib, "mylib");
// CHECK: !1 = !{!"-myflag"}
pragma(linkerDirective, "-myflag");
// CHECK: !2 = !{!"-framework", !"CoreFoundation"}
pragma(linkerDirective, "-framework", "CoreFoundation");
./ldc-1.20.1-src/tests/codegen/hashed_mangling.d 0000644 0001750 0001750 00000003112 13631266747 021524 0 ustar matthias matthias // Test hashing of symbols above hash threshold
// RUN: %ldc -hash-threshold=90 -g -c -output-ll -of=%t90.ll %s && FileCheck %s --check-prefix HASH90 < %t90.ll
// RUN: %ldc -hash-threshold=90 -run %s
// Don't use Phobos functions in this test, because the test hashthreshold is too low for an unhashed libphobos.
module one.two.three;
// HASH90-DAG: define{{.*}} @externCfunctions_are_not_hashed_externCfunctions_are_not_hashed_externCfunctions_are_not_hashed
extern (C) int externCfunctions_are_not_hashed_externCfunctions_are_not_hashed_externCfunctions_are_not_hashed()
{
return 95;
}
auto s(T)(T t)
{
// HASH90-DAG: define{{.*}} @{{(\"\\01_?)?}}_D3one3two5three__T1sTiZQfFNaNbNiNfiZSQBkQBjQBi__TQBfTiZQBlFiZ__T6ResultTiZQk
// HASH90-DAG: define{{.*}} @{{(\"\\01_?)?}}_D3one3two5three3L1633_182fab6f09ff014d9f4a578edf9609981sZ
// HASH90-DAG: define{{.*}} @{{(\"\\01_?)?}}_D3one3two5three3L2333_9b5306e5c42722cd2cb93ae6beb422346Result3fooZ
struct Result(T)
{
void foo(){}
}
return Result!int();
}
auto klass(T)(T t)
{
class Result(T)
{
// HASH90-DAG: define{{.*}} @{{(\"\\01_?)?}}_D3one3two5three__T5klassTiZQjFiZ__T6ResultTiZQk3fooMFZv
// HASH90-DAG: define{{.*}} @{{(\"\\01_?)?}}_D3one3two5three3L3433_de737f3d65ae58efa925cffda52cd8da6Result3fooZ
void foo(){}
}
return new Result!int();
}
void main()
{
assert(
externCfunctions_are_not_hashed_externCfunctions_are_not_hashed_externCfunctions_are_not_hashed() == 95);
auto x = 1.s.s.s.s;
x.foo;
auto y = 1.klass.klass.klass.klass;
y.foo;
}
./ldc-1.20.1-src/tests/codegen/const_cond_labels.d 0000644 0001750 0001750 00000006352 13631266747 022100 0 ustar matthias matthias // Make sure that the dead code of an `if` (and `else if`) is elminated when the condition is constant
// _only_ if the block does not contain any labels.
// For example,
// int a = 1;
// if (false) {
// L1:
// a = 2;
// } else {
// goto L1;
// }
// assert(a == 2);
// Note that a label is conssidered anything that lets us jump inside the body
// of the statement _apart from_ the actual statement (e.g. the `if).
// That generally is a normal label, but also specific cases for switch
// statements (see last tests).
// RUN: %ldc -O0 -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
extern(C): //to avoid name mangling.
// CHECK-LABEL: @foo
void foo()
{
// CHECK: %a = alloca
// CHECK: br
int a;
if (0)
{
L1:
a = 1;
}
else
{
goto L1;
}
}
// CHECK-LABEL: @bar
void bar(int a, int b)
{
int c;
if (0)
{
switch (a) {
case 10:
while (b) {
L2:
// CHECK: store i32 10, i32* %c
c = 10;
}
default: assert(0);
}
}
else
{
goto L2;
}
}
// CHECK-LABEL: @without_goto
void without_goto(int a, int b)
{
int c;
if (0)
{
switch (a) {
case 10:
while (b) {
L2:
// CHECK: store i32 10, i32* %c
c = 10;
}
default: assert(0);
}
}
else
{
a = 2;
}
}
// CHECK-LABEL: @fourth
void fourth(int a, int b, int c)
{
int j, d;
if (a)
{
goto L3;
}
else if (false)
{
for (j = 0; j <= c; ++j)
{
// Can't `goto` in a foreach because
// it always declares a variable.
L3:
foreach (i; 0..b)
{
// CHECK: store i32 10, i32* %d
d = 10;
}
}
}
}
// If a switch is outside the body of a statement "to-be-elided"
// but a case statement of it is inside that body, then that
// case acts as a label because we can jump inside the body without
// using the statement (i.e. using the switch to jump to the case).
// CHECK-LABEL: @case_as_label
void case_as_label(int a, int b)
{
// Note the `CHECK-NOT` trickery.
// CHECK-NOT: store i32 2, i32* %c
// CHECK: store i32 3, i32* %c
// CHECK-NOT: store i32 2, i32* %c
// CHECK: store i32 4, i32* %c
// CHECK-NOT: store i32 2, i32* %c
int c;
switch (a) {
case 1:
// Can elide
if (false) {
final switch (b) {
case 2:
c = 2;
}
}
case 2:
// Can't elide
if (false) {
case 3:
c = 3;
}
// Can't elide
if (false) {
default:
c = 4;
}
}
}
// CHECK-LABEL: @case_as_label2
void case_as_label2(int a, int b)
{
// CHECK: store i32 2, i32* %c
// CHECK: store i32 3, i32* %c
int c;
final switch (a) {
// Can't elide
if (false) {
final switch (b) {
case 2:
c = 2;
}
// Test that `switch` in higher or equal nesting level
// with a `case` does not impact the handling of `case`s.
case 1:
c = 3;
}
}
}
./ldc-1.20.1-src/tests/codegen/static_array_init.d 0000644 0001750 0001750 00000007707 13631266747 022142 0 ustar matthias matthias // RUN: %ldc -output-ll %s -of=%t.ll
// RUN: FileCheck %s < %t.ll
void bytes_scalar()
{
immutable(byte)[32] myBytes = 123;
// CHECK: define {{.*}}_D17static_array_init12bytes_scalarFZv
// CHECK-NEXT: %myBytes = alloca [32 x i8], align 1
// CHECK-NEXT: %1 = bitcast [32 x i8]* %myBytes to i8*
// CHECK-NEXT: call void @llvm.memset{{.*}}(i8*{{[a-z0-9 ]*}} %1, i8 123, i{{(32|64)}} 32
}
void bytes_scalar(byte arg)
{
immutable(byte)[32] myBytes = arg;
// CHECK: define {{.*}}_D17static_array_init12bytes_scalarFgZv
// CHECK-NEXT: %arg = alloca i8, align 1
// CHECK-NEXT: %myBytes = alloca [32 x i8], align 1
// CHECK-NEXT: store i8 %arg_arg, i8* %arg
// CHECK-NEXT: %1 = bitcast [32 x i8]* %myBytes to i8*
// CHECK-NEXT: %2 = load {{.*}}i8* %arg
// CHECK-NEXT: call void @llvm.memset{{.*}}(i8*{{[a-z0-9 ]*}} %1, i8 %2, i{{(32|64)}} 32
}
void ints_scalar()
{
const(int[32]) myInts = 123;
// CHECK: define {{.*}}_D17static_array_init11ints_scalarFZv
// CHECK: arrayinit.cond:
// CHECK-NEXT: %[[I1:[0-9]+]] = load {{.*i(32|64)}}* %arrayinit.itr
// CHECK-NEXT: %arrayinit.condition = icmp ne i{{(32|64)}} %[[I1]], 32
// CHECK: store i32 123, i32* %arrayinit.arrayelem
}
void ints_scalar(int arg)
{
const(int[32]) myInts = arg;
// CHECK: define {{.*}}_D17static_array_init11ints_scalarFiZv
// CHECK: arrayinit.cond:
// CHECK-NEXT: %[[I2:[0-9]+]] = load {{.*i(32|64)}}* %arrayinit.itr
// CHECK-NEXT: %arrayinit.condition = icmp ne i{{(32|64)}} %[[I2]], 32
// CHECK: %[[E2:[0-9]+]] = load {{.*}}i32* %arg
// CHECK-NEXT: store i32 %[[E2]], i32* %arrayinit.arrayelem
}
void bytes()
{
immutable(byte[4]) myBytes = [ 1, 2, 3, 4 ];
// CHECK: define {{.*}}_D17static_array_init5bytesFZv
// CHECK-NEXT: %myBytes = alloca [4 x i8], align 1
// CHECK-NEXT: store [4 x i8] c"\01\02\03\04", [4 x i8]* %myBytes
}
void bytes(byte[] arg)
{
const(byte)[4] myBytes = arg;
// CHECK: define {{.*}}_D17static_array_init5bytesFAgZv
// CHECK: %myBytes = alloca [4 x i8], align 1
// CHECK: %1 = bitcast [4 x i8]* %myBytes to i8*
// CHECK: call void @llvm.memcpy{{.*}}(i8*{{[a-z0-9 ]*}} %1, i8*{{[a-z0-9 ]*}} %.ptr, i{{(32|64)}} 4
}
void ints()
{
immutable(int)[4] myInts = [ 1, 2, 3, 4 ];
// CHECK: define {{.*}}_D17static_array_init4intsFZv
// CHECK-NEXT: %myInts = alloca [4 x i32], align 4
// CHECK-NEXT: store [4 x i32] [i32 1, i32 2, i32 3, i32 4], [4 x i32]* %myInts
}
void ints(ref int[4] arg)
{
const(int[4]) myInts = arg;
// CHECK: define {{.*}}_D17static_array_init4intsFKG4iZv
// CHECK-NEXT: %myInts = alloca [4 x i32], align 4
// CHECK-NEXT: %1 = bitcast [4 x i32]* %myInts to i32*
// CHECK-NEXT: %2 = bitcast i32* %1 to i8*
// CHECK-NEXT: %3 = bitcast [4 x i32]* %arg to i32*
// CHECK-NEXT: %4 = bitcast i32* %3 to i8*
// CHECK-NEXT: call void @llvm.memcpy{{.*}}(i8*{{[a-z0-9 ]*}} %2, i8*{{[a-z0-9 ]*}} %4, i{{(32|64)}} 16
}
void bytes_scalar_2d()
{
immutable(byte)[4][8] myBytes = 123;
// CHECK: define {{.*}}_D17static_array_init15bytes_scalar_2dFZv
// CHECK-NEXT: %myBytes = alloca [8 x [4 x i8]], align 1
// CHECK-NEXT: %1 = bitcast [8 x [4 x i8]]* %myBytes to [32 x i8]*
// CHECK-NEXT: %2 = bitcast [32 x i8]* %1 to i8*
// CHECK-NEXT: call void @llvm.memset{{.*}}(i8*{{[a-z0-9 ]*}} %2, i8 123, i{{(32|64)}} 32
}
void ints_scalar_2d(immutable int arg)
{
const(int[4])[8] myInts = arg;
// CHECK: define {{.*}}_D17static_array_init14ints_scalar_2dFyiZv
// CHECK: arrayinit.cond:
// CHECK-NEXT: %[[I3:[0-9]+]] = load {{.*i(32|64)}}* %arrayinit.itr
// CHECK-NEXT: %arrayinit.condition = icmp ne i{{(32|64)}} %[[I3]], 32
// CHECK: %[[E3:[0-9]+]] = load {{.*}}i32* %arg
// CHECK-NEXT: store i32 %[[E3]], i32* %arrayinit.arrayelem
}
./ldc-1.20.1-src/tests/codegen/union.d 0000644 0001750 0001750 00000012222 13631266747 017546 0 ustar matthias matthias // Tests LL types and constant initializers of init symbols and globals of
// structs with and without overlapping (union) fields.
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// RUN: %ldc -run %s
struct S
{
char c; // default initializer: 0xff
uint ui;
bool[2] bools; // make sure the 2 bools are extended to 2 bytes
bool b = true; // scalar bool too
char[2][1] multidim; // multidimensional init based on a single 0xff char
}
// CHECK-DAG: %union.S = type { i8, [3 x i8], i32, [2 x i8], i8, [1 x [2 x i8]], [3 x i8] }
// CHECK-DAG: @{{.*}}_D5union1S6__initZ{{\"?}} = constant %union.S { i8 -1, [3 x i8] zeroinitializer, i32 0, [2 x i8] zeroinitializer, i8 1, [1 x [2 x i8]] {{\[}}[2 x i8] c"\FF\FF"], [3 x i8] zeroinitializer }
// CHECK-DAG: @{{.*}}_D5union8defaultSSQq1S{{\"?}} = global %union.S { i8 -1, [3 x i8] zeroinitializer, i32 0, [2 x i8] zeroinitializer, i8 1, [1 x [2 x i8]] {{\[}}[2 x i8] c"\FF\FF"], [3 x i8] zeroinitializer }
__gshared S defaultS;
// CHECK-DAG: @{{.*}}_D5union9explicitSSQr1S{{\"?}} = global %union.S { i8 3, [3 x i8] zeroinitializer, i32 56, [2 x i8] c"\00\01", i8 0, [1 x [2 x i8]] {{\[}}[2 x i8] c"\FF\FF"], [3 x i8] zeroinitializer }
__gshared S explicitS = { 3, 56, [false, true], false /* implicit multidim */ };
struct SWithUnion
{
char c;
S nested;
union
{
struct { ubyte ub = 6; ushort us = 33; align(8) ulong ul_dummy = void; ulong last = 123; }
struct { uint ui1; uint ui2 = 84; ulong ul = 666; }
}
}
// CHECK-DAG: %union.SWithUnion = type { i8, [3 x i8], %union.S, [4 x i8], i8, [1 x i8], i16, i32, i64, i64 }
// CHECK-DAG: @{{.*}}_D5union10SWithUnion6__initZ{{\"?}} = constant %union.SWithUnion { i8 -1, [3 x i8] zeroinitializer, %union.S { i8 -1, [3 x i8] zeroinitializer, i32 0, [2 x i8] zeroinitializer, i8 1, [1 x [2 x i8]] {{\[}}[2 x i8] c"\FF\FF"], [3 x i8] zeroinitializer }, [4 x i8] zeroinitializer, i8 6, [1 x i8] zeroinitializer, i16 33, i32 84, i64 666, i64 123 }
// CHECK-DAG: @{{.*}}_D5union17defaultSWithUnionSQBa10SWithUnion{{\"?}} = global %union.SWithUnion { i8 -1, [3 x i8] zeroinitializer, %union.S { i8 -1, [3 x i8] zeroinitializer, i32 0, [2 x i8] zeroinitializer, i8 1, [1 x [2 x i8]] {{\[}}[2 x i8] c"\FF\FF"], [3 x i8] zeroinitializer }, [4 x i8] zeroinitializer, i8 6, [1 x i8] zeroinitializer, i16 33, i32 84, i64 666, i64 123 }
__gshared SWithUnion defaultSWithUnion;
// CHECK-DAG: @{{.*}}_D5union28explicitCompatibleSWithUnionSQBl10SWithUnion{{\"?}} = global %union.SWithUnion { i8 -1, [3 x i8] zeroinitializer, %union.S { i8 -1, [3 x i8] zeroinitializer, i32 0, [2 x i8] zeroinitializer, i8 1, [1 x [2 x i8]] {{\[}}[2 x i8] c"\FF\FF"], [3 x i8] zeroinitializer }, [4 x i8] zeroinitializer, i8 6, [1 x i8] zeroinitializer, i16 33, i32 84, i64 53, i64 123 }
__gshared SWithUnion explicitCompatibleSWithUnion = { ul_dummy: 53 }; // ul_dummy is an alias for dominant ul
// If a dominated union field is initialized and it isn't an alias for a dominant field,
// the regular LL type cannot be used, and an anonymous one is used instead.
// CHECK-DAG: @{{.*}}_D5union30explicitIncompatibleSWithUnionSQBn10SWithUnion{{\"?}} = global { i8, [3 x i8], %union.S, [4 x i8], i32, i32, i64, i64 } { i8 -1, [3 x i8] zeroinitializer, %union.S { i8 -1, [3 x i8] zeroinitializer, i32 0, [2 x i8] zeroinitializer, i8 1, [1 x [2 x i8]] {{\[}}[2 x i8] c"\FF\FF"], [3 x i8] zeroinitializer }, [4 x i8] zeroinitializer, i32 23, i32 84, i64 666, i64 123 }
__gshared SWithUnion explicitIncompatibleSWithUnion = { ui1: 23 }; // // ui1 dominated by ub and us
struct Quat
{
static struct Vec { int x; }
union
{
Vec v;
struct { float x; }
}
static Quat identity()
{
Quat q;
q.x = 1.0f;
return q;
}
}
// T.init may feature explicit initializers for dominated members in nested unions (GitHub issue #2108).
// In that case, the init constant has an anonymous LL type as well.
// CHECK-DAG: @{{.*}}_D5union33QuatContainerWithIncompatibleInit6__initZ{{\"?}} = constant { { float } } { { float } { float 1.000000e+00 } }
struct QuatContainerWithIncompatibleInit
{
Quat q = Quat.identity;
}
void main()
{
// test dynamic literals too
{
SWithUnion s = { 'y' };
assert(s.c == 'y');
assert(s.nested == S.init);
assert(s.ub == 6);
assert(s.us == 33);
assert(s.ui2 == 84);
assert(s.ul == 666);
assert(s.last == 123);
}
{
SWithUnion s = { ul_dummy: 53 };
assert(s.c == char.init);
assert(s.nested == S.init);
assert(s.ub == 6);
assert(s.us == 33);
assert(s.ui2 == 84);
assert(s.ul_dummy == 53);
assert(s.last == 123);
}
{
SWithUnion s = { ui1: 23 };
assert(s.c == char.init);
assert(s.nested == S.init);
assert(s.ui1 == 23);
assert(s.ui2 == 84);
assert(s.ul == 666);
assert(s.last == 123);
}
{
QuatContainerWithIncompatibleInit c;
assert(c.q.x == 1.0f);
}
}
./ldc-1.20.1-src/tests/codegen/attr_fastmath_x86.d 0000644 0001750 0001750 00000000747 13631266747 021775 0 ustar matthias matthias // Test vectorized fused multiply-add in a simple dot product routine
// REQUIRES: target_X86
// RUN: %ldc -mtriple=x86_64-linux-gnu -mattr=+fma -O3 -release -c -output-s -of=%t.s %s && FileCheck %s --check-prefix ASM < %t.s
import ldc.attributes;
// ASM-LABEL: dot:
@fastmath
extern (C) double dot(double[] a, double[] b)
{
double s = 0;
// ASM: vfmadd{{[123][123][123]}}pd
foreach (size_t i; 0 .. a.length)
{
s += a[i] * b[i];
}
return s;
// ASM: ret
}
./ldc-1.20.1-src/tests/codegen/dmd_inline_asm_fp_types.d 0000644 0001750 0001750 00000001667 13631266747 023304 0 ustar matthias matthias // REQUIRES: target_X86
// RUN: %ldc -output-s -mtriple=x86_64-windows-msvc -of=%t_msvc.s %s
// RUN: FileCheck --check-prefix=COMMON --check-prefix=MSVC %s < %t_msvc.s
// RUN: %ldc -output-s -mtriple=x86_64-linux-gnu -of=%t_linux.s %s
// RUN: FileCheck --check-prefix=COMMON --check-prefix=LINUX %s < %t_linux.s
// COMMON: _D23dmd_inline_asm_fp_types3fooFfdeZv
void foo(float a, double b, real c)
{
asm
{
// COMMON: flds
fld a;
// COMMON-NEXT: fldl
fld b;
// MSVC-NEXT: fldl
// LINUX-NEXT: fldt
fld c;
ret;
}
}
// COMMON: _D23dmd_inline_asm_fp_types3barFPvZv
void bar(void* ptr)
{
asm
{
// COMMON: flds
fld float ptr [ptr];
// COMMON-NEXT: fldl
fld double ptr [ptr];
// MSVC-NEXT: fldl
// LINUX-NEXT: fldt
fld real ptr [ptr];
// COMMON-NEXT: fldt
fld extended ptr [ptr];
ret;
}
}
./ldc-1.20.1-src/tests/codegen/asm_data_directives.d 0000644 0001750 0001750 00000002636 13631266747 022420 0 ustar matthias matthias // REQUIRES: target_X86
// RUN: %ldc -mtriple=x86_64-linux-gnu -output-s -of=%t.s %s
// RUN: FileCheck %s < %t.s
// CHECK: _D19asm_data_directives14_rdrand32_stepFPkZi:
int _rdrand32_step(uint* r)
{
int ret;
asm
{
// CHECK: movl -12(%rbp), %eax
mov EAX, ret;
// CHECK-NEXT: .byte 15
// CHECK-NEXT: .byte 199
// CHECK-NEXT: .byte 240
db 0x0F, 0xC7, 0xF0; // rdrand EAX
// CHECK-NEXT: movl %eax, -12(%rbp)
mov ret, EAX;
}
if (ret != 0)
{
*r = ret;
return 1;
}
return 0;
}
// CHECK: _D19asm_data_directives3fooFZv:
void foo()
{
asm
{
// CHECK: .byte 1
// CHECK-NEXT: .byte 128
db 1, 0x80;
// CHECK-NEXT: .short 2
// CHECK-NEXT: .short 256
ds 2, 0x100;
// CHECK-NEXT: .long 3
// CHECK-NEXT: .long 65536
di 3, 0x10000;
// CHECK-NEXT: .quad 4
// CHECK-NEXT: .quad 4294967296
dl 4, 0x100000000;
// CHECK-NEXT: .long 1065353216
// CHECK-NEXT: .long 1069547520
df 1.0f, 1.5f;
// CHECK-NEXT: .quad 4607182418800017408
// CHECK-NEXT: .quad 4609434218613702656
dd 1.0, 1.5;
// CHECK-NEXT: .quad -9223372036854775808
// CHECK-NEXT: .short 16383
// CHECK-NEXT: .quad -4611686018427387904
// CHECK-NEXT: .short 16383
de 1.0L, 1.5L;
}
}
./ldc-1.20.1-src/tests/codegen/attr_llvmFMF.d 0000644 0001750 0001750 00000002507 13631266747 020760 0 ustar matthias matthias // Test @ldc.attributes.llvmFastMathFlag UDA
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s --check-prefix LLVM < %t.ll
// RUN: not %ldc -c -w -d-version=WARNING %s 2>&1 | FileCheck %s --check-prefix WARNING
import ldc.attributes;
version(WARNING)
{
// WARNING: attr_llvmFMF.d(11): Warning: ignoring unrecognized flag parameter `unrecognized` for `@ldc.attributes.llvmFastMathFlag`
@llvmFastMathFlag("unrecognized")
void foo() {}
}
// LLVM-LABEL: define{{.*}} @notfast
// LLVM-SAME: #[[ATTR_NOTFAST:[0-9]+]]
extern (C) double notfast(double a, double b)
{
@llvmFastMathFlag("fast")
double nested_fast(double a, double b)
{
return a * b;
}
// LLVM: fmul double
return a * b;
}
// LLVM-LABEL: define{{.*}} @{{.*}}nested_fast
// LLVM: fmul fast double
// LLVM-LABEL: define{{.*}} @{{.*}}nnan_arcp
@llvmFastMathFlag("nnan")
@llvmFastMathFlag("arcp")
double nnan_arcp(double a, double b)
{
// LLVM: fmul nnan arcp double
return a * b;
}
// LLVM-LABEL: define{{.*}} @{{.*}}ninf_nsz
@llvmFastMathFlag("ninf")
@llvmFastMathFlag("nsz")
double ninf_nsz(double a, double b)
{
// LLVM: fmul ninf nsz double
return a * b;
}
// LLVM-LABEL: define{{.*}} @{{.*}}cleared
@llvmFastMathFlag("ninf")
@llvmFastMathFlag("clear")
double cleared(double a, double b)
{
// LLVM: fmul double
return a * b;
}
./ldc-1.20.1-src/tests/codegen/inlining_leakdefinitions.d 0000644 0001750 0001750 00000003707 13631266747 023465 0 ustar matthias matthias // Test that inlining does not leak definitions without marking them as available_externally
// "Leaking" = symbols definitions in .o file that shouldn't be declarations instead (undefined symbols).
// RUN: %ldc %s -I%S -c -output-ll -release -O3 -enable-cross-module-inlining -of=%t.O3.ll && FileCheck %s --check-prefix OPT3 < %t.O3.ll
// RUN: %ldc %s -I%S -c -output-ll -release -enable-inlining -O0 -enable-cross-module-inlining -of=%t.O0.ll && FileCheck %s --check-prefix OPT0 < %t.O0.ll
// RUN: %ldc -I%S -enable-inlining -enable-cross-module-inlining %S/inputs/inlinables.d -run %s
// RUN: %ldc -I%S -O3 -enable-cross-module-inlining %S/inputs/inlinables.d -run %s
import inputs.inlinables;
extern (C): // simplify mangling for easier matching
// Check that the global variables that are added due to "available_externally
// inlining" do not have initializers, i.e. they are declared only and not definined.
// OPT3-DAG: @module_variable = external thread_local{{.*}} global i32, align
// OPT3-DAG: @{{.*}}write_function_static_variableUiZ15static_func_vari{{\"?}} = external thread_local{{.*}} global i32, align
// OPT0-LABEL: define{{.*}} @call_class_function(
// OPT3-LABEL: define{{.*}} @call_class_function(
int call_class_function(A a)
{
// There should be only one call to "virtual_func".
// OPT3: call
// OPT3-NOT: call
return a.final_func();
// There should be a return from an LLVM variable (not a direct value)
// OPT0: ret i32 %
// OPT3: ret i32 %
}
// OPT0-LABEL: define{{.*}} @dont_leak_module_variables(
// OPT3-LABEL: define{{.*}} @dont_leak_module_variables(
void dont_leak_module_variables()
{
write_module_variable(987);
write_function_static_variable(167);
get_typeid_A();
// OPT0: ret void
// OPT3: ret void
}
// OPT0-LABEL: define{{.*}} @main(
// OPT3-LABEL: define{{.*}} @main(
int main()
{
dont_leak_module_variables();
return 0;
// OPT0: ret i32 0
// OPT3: ret i32 0
}
./ldc-1.20.1-src/tests/codegen/gh2235.d 0000644 0001750 0001750 00000000665 13631266747 017340 0 ustar matthias matthias // RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// RUN: %ldc -run %s
// CHECK-DAG: %gh2235.Foo = type <{
align(2) struct Foo {
long y;
byte z;
}
// CHECK-DAG: %gh2235.Bar = type <{
class Bar {
union {
bool b;
Foo foo;
}
byte x;
void set(Foo f) {
x = 99;
foo = f;
}
}
void main() {
Bar bar = new Bar();
Foo f;
bar.set(f);
assert(bar.x == 99);
}
./ldc-1.20.1-src/tests/codegen/gh2131.d 0000644 0001750 0001750 00000000611 13631266747 017322 0 ustar matthias matthias // RUN: %ldc -O3 -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// CHECK: define {{.*}}zeroext {{.*}}@{{.*}}_D6gh21313foo
// CHECK-SAME: i1 zeroext %x_arg
bool foo(bool x, ref bool o)
{
// CHECK-NOT: and i8
// CHECK: load i8{{.*}}, !range ![[META:[0-9]+]]
// CHECK-NOT: and i8
o |= x;
// CHECK: ret
return o;
}
// CHECK: ![[META]] = {{.*}}!{i8 0, i8 2}
./ldc-1.20.1-src/tests/codegen/simd_unaligned.d 0000644 0001750 0001750 00000004176 13631266747 021411 0 ustar matthias matthias // Tests unaligned load and stores of SIMD types
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// RUN: %ldc -run %s
import core.simd;
import ldc.simd;
// CHECK-LABEL: define{{.*}} @{{.*}}loads
void loads(void *p)
{
// CHECK: load <4 x float>{{.*}} align 1
loadUnaligned!float4(cast(float*)p);
const float[4] f4buf = void;
immutable double[2] f8buf = void;
ubyte[16] u1buf = void;
ushort[8] u2buf = void;
uint[4] u4buf = void;
ulong[2] u8buf = void;
byte[16] i1buf = void;
short[8] i2buf = void;
int[4] i4buf = void;
long[2] i8buf = void;
// CHECK: load <4 x float>{{.*}} align 1
loadUnaligned!float4(f4buf.ptr);
// CHECK: load <2 x double>{{.*}} align 1
loadUnaligned!double2(f8buf.ptr);
// CHECK: load <16 x i8>{{.*}} align 1
loadUnaligned!ubyte16(u1buf.ptr);
// CHECK: load <8 x i16>{{.*}} align 1
loadUnaligned!ushort8(u2buf.ptr);
// CHECK: load <4 x i32>{{.*}} align 1
loadUnaligned!uint4(u4buf.ptr);
// CHECK: load <2 x i64>{{.*}} align 1
loadUnaligned!ulong2(u8buf.ptr);
// CHECK: load <16 x i8>{{.*}} align 1
loadUnaligned!byte16(i1buf.ptr);
// CHECK: load <8 x i16>{{.*}} align 1
loadUnaligned!short8(i2buf.ptr);
// CHECK: load <4 x i32>{{.*}} align 1
loadUnaligned!int4(i4buf.ptr);
// CHECK: load <2 x i64>{{.*}} align 1
loadUnaligned!long2(i8buf.ptr);
}
// CHECK-LABEL: define{{.*}} @{{.*}}stores
void stores(void *p)
{
float8 f8 = void;
int8 i8 = void;
// CHECK: store <8 x float>{{.*}} align 1
storeUnaligned!float8(f8, cast(float*)p);
// CHECK: store <8 x i32>{{.*}} align 1
storeUnaligned!int8(i8, cast(int*)p);
}
void checkStore(int *a)
{
immutable int4 v = [0, 10, 20, 30];
// CHECK: store <4 x i32>{{.*}} align 1
storeUnaligned!int4(v, a);
assert(v.array == a[0..4]);
}
void main()
{
loads(getMisalignedPtr());
stores(getMisalignedPtr());
checkStore(cast(int*)getMisalignedPtr());
}
import ldc.attributes;
align(32) char[100] dummy = void;
void* getMisalignedPtr()
@weak // disallows reasoning and inlining of this function
{
return &dummy[1];
};
./ldc-1.20.1-src/tests/codegen/gh1728.d 0000644 0001750 0001750 00000000546 13631266747 017344 0 ustar matthias matthias // RUN: %ldc -run %s
struct OpApply {
int opApply(int delegate(int) cb) {
return cb(42);
}
}
struct Bolinha {
int a;
this(ref OpApply moviadao) {
foreach(int b; moviadao) {
this.a = b;
return;
}
}
}
void main() {
OpApply range;
const s = Bolinha(range);
assert(s.a == 42);
}
./ldc-1.20.1-src/tests/codegen/gh2537.d 0000644 0001750 0001750 00000001236 13631266747 017340 0 ustar matthias matthias // RUN: %ldc -run %s
void main()
{
int[string] aa = [ "one": 123 ];
typeof(null) nul;
auto sum = nul + nul;
auto diff = nul - nul;
assert(aa + nul == aa);
assert(nul + aa == aa);
assert(aa - nul == aa);
assert(nul - aa == aa);
static assert(!__traits(compiles, nul * nul));
static assert(!__traits(compiles, aa * nul));
static assert(!__traits(compiles, nul / nul));
static assert(!__traits(compiles, aa / nul));
static assert(!__traits(compiles, nul % nul));
static assert(!__traits(compiles, aa % nul));
static assert(!__traits(compiles, nul & nul));
static assert(!__traits(compiles, aa | nul));
}
./ldc-1.20.1-src/tests/codegen/export_aggregate_symbols.d 0000644 0001750 0001750 00000004546 13631266747 023527 0 ustar matthias matthias // Tests -fvisibility={default,hidden} for special symbols generated for
// aggregates on non-Windows targets.
// UNSUPPORTED: Windows
// RUN: %ldc %s -shared -fvisibility=default -of=lib%t_default%so
// RUN: nm -g lib%t_default%so | FileCheck -check-prefix=DEFAULT -check-prefix=BOTH %s
// RUN: %ldc %s -shared -fvisibility=hidden -of=lib%t_hidden%so
// RUN: nm -g lib%t_hidden%so | FileCheck -check-prefix=HIDDEN -check-prefix=BOTH %s
// DEFAULT: _D24export_aggregate_symbols8DefaultC11__interface24export_aggregate_symbols8DefaultI{{.*}}__vtblZ
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultC11__interface24export_aggregate_symbols8DefaultI{{.*}}__vtblZ
// DEFAULT: _D24export_aggregate_symbols8DefaultC16__interfaceInfosZ
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultC16__interfaceInfosZ
// DEFAULT: _D24export_aggregate_symbols8DefaultC6__initZ
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultC6__initZ
// DEFAULT: _D24export_aggregate_symbols8DefaultC6__vtblZ
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultC6__vtblZ
// DEFAULT: _D24export_aggregate_symbols8DefaultC7__ClassZ
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultC7__ClassZ
class DefaultC : DefaultI { void foo() {} }
// DEFAULT: _D24export_aggregate_symbols8DefaultI11__InterfaceZ
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultI11__InterfaceZ
interface DefaultI { void foo(); }
// DEFAULT: _D24export_aggregate_symbols8DefaultS6__initZ
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultS6__initZ
struct DefaultS { int nonZero = 1; }
// BOTH: _D24export_aggregate_symbols9ExportedC11__interface24export_aggregate_symbols9ExportedI{{.*}}__vtblZ
// BOTH: _D24export_aggregate_symbols9ExportedC16__interfaceInfosZ
// BOTH: _D24export_aggregate_symbols9ExportedC6__initZ
// BOTH: _D24export_aggregate_symbols9ExportedC6__vtblZ
// BOTH: _D24export_aggregate_symbols9ExportedC7__ClassZ
export class ExportedC : ExportedI { void foo() {} }
// BOTH: _D24export_aggregate_symbols9ExportedI11__InterfaceZ
export interface ExportedI { void foo(); }
// BOTH: _D24export_aggregate_symbols9ExportedS6__initZ
export struct ExportedS { int nonZero = 1; }
// struct TypeInfos:
// DEFAULT: _D45TypeInfo_S24export_aggregate_symbols8DefaultS6__initZ
// HIDDEN-NOT: _D45TypeInfo_S24export_aggregate_symbols8DefaultS6__initZ
// BOTH: _D46TypeInfo_S24export_aggregate_symbols9ExportedS6__initZ
./ldc-1.20.1-src/tests/codegen/const_struct_export.d 0000644 0001750 0001750 00000001776 13631266747 022565 0 ustar matthias matthias // RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// CHECK: @.immutablearray{{.*}} = internal constant [2 x void ()*] {{.*}}exportedFunction
// CHECK-NOT: @.immutablearray{{.*}} [2 x void ()*] {{.*}}importedFunction
// CHECK: @.immutablearray{{.*}} = internal constant [2 x i32*] {{.*}}exportedVariable
// CHECK-NOT: @.immutablearray{{.*}} [2 x i32*] {{.*}}importedVariable
export void exportedFunction() {}
export void importedFunction();
export immutable int exportedVariable = 1;
export immutable int importedVariable;
void foo () {
immutable auto exportedFuncs = [ &exportedFunction, &exportedFunction ];
immutable auto importedFuncs = [ &importedFunction, &importedFunction ];
// CHECK: store void ()* @{{.*}}D19const_struct_export16importedFunctionFZv
immutable auto exportedVars = [ &exportedVariable, &exportedVariable ];
immutable auto importedVars = [ &importedVariable, &importedVariable ];
// CHECK: store i32* @{{.*}}D19const_struct_export16importedVariable
}
./ldc-1.20.1-src/tests/codegen/in_place_construct_asm.d 0000644 0001750 0001750 00000001340 13631266747 023133 0 ustar matthias matthias // Tests in-place construction of structs returned by inline assembly (issue #1823).
// Target Win64 for simplicity (e.g., 4x32-bit struct not returned in memory for non-Windows x64).
// REQUIRES: target_X86
// RUN: %ldc -mtriple=x86_64-pc-windows-msvc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
import ldc.llvmasm;
// CHECK-LABEL: define{{.*}} @{{.*}}_D22in_place_construct_asm14inlineAssemblyFkkZv
void inlineAssembly(uint eax, uint ecx)
{
// CHECK: store %"ldc.llvmasm.__asmtuple_t!(uint, uint, uint, uint).__asmtuple_t" %3, %"ldc.llvmasm.__asmtuple_t!(uint, uint, uint, uint).__asmtuple_t"* %r
auto r = __asmtuple!(uint, uint, uint, uint) ("cpuid",
"={eax},={ebx},={ecx},={edx},{eax},{ecx}", eax, ecx);
}
./ldc-1.20.1-src/tests/codegen/betterC_typeinfo.d 0000644 0001750 0001750 00000000537 13631266747 021731 0 ustar matthias matthias // Make sure the file can be compiled and linked successfully with -betterC.
// Also test that druntime and Phobos aren't in the linker command line.
// RUN: %ldc -betterC %s -v > %t.log
// RUN: FileCheck %s < %t.log
// CHECK-NOT: druntime-ldc
// CHECK-NOT: phobos2-ldc
struct MyStruct { int a; }
extern (C) void main()
{
auto s = MyStruct();
}
./ldc-1.20.1-src/tests/codegen/inferred_outputname.d 0000644 0001750 0001750 00000001217 13631266747 022477 0 ustar matthias matthias // Make sure the inferred output filename is based on the first (source or
// object) file, and independent from its module declaration.
// If it works on Windows, it will work on other platforms too, and it
// simplifies things a bit.
// REQUIRES: Windows
// 1) 2 object files compiled separately:
// RUN: %ldc -c %S/inputs/foo.d -of=%t-dir/foo%obj
// RUN: %ldc %s %t-dir/foo%obj -vv | FileCheck %s
// 2) singleObj build with external object file and 2 source files:
// RUN: %ldc %t-dir/foo%obj %s %S/inputs/attr_weak_input.d -vv | FileCheck %s
// CHECK: Linking with:
// CHECK-NEXT: '/OUT:inferred_outputname.exe'
module modulename;
void main() {}
./ldc-1.20.1-src/tests/codegen/export_marked_symbols1.d 0000644 0001750 0001750 00000001544 13631266747 023120 0 ustar matthias matthias // Tests -fvisibility={default,hidden} for function definitions and
// (non-extern) globals on non-Windows targets.
// UNSUPPORTED: Windows
// RUN: %ldc %s -betterC -shared -fvisibility=default -of=lib%t_default%so
// RUN: nm -g lib%t_default%so | FileCheck -check-prefix=DEFAULT %s
// RUN: %ldc %s -betterC -shared -fvisibility=hidden -of=lib%t_hidden%so
// RUN: nm -g lib%t_hidden%so | FileCheck -check-prefix=HIDDEN %s
extern(C) export int test__exportedFun() { return 42; }
// DEFAULT: test__exportedFun
// HIDDEN: test__exportedFun
extern(C) export int test__exportedVar;
// DEFAULT: test__exportedVar
// HIDDEN: test__exportedVar
extern(C) int test__nonExportedFun() { return 101; }
// DEFAULT: test__nonExportedFun
// HIDDEN-NOT: test__nonExportedFun
extern(C) int test__nonExportedVar;
// DEFAULT: test__nonExportedVar
// HIDDEN-NOT: test__nonExportedVar
./ldc-1.20.1-src/tests/codegen/export_marked_symbols_thin_lto.d 0000644 0001750 0001750 00000000764 13631266747 024742 0 ustar matthias matthias // Tests that mismatching symbol visibilities between declarations and definitions
// work with thin LTO.
// REQUIRES: LTO
// RUN: %ldc %S/inputs/export_marked_symbols_lib.d -c -fvisibility=hidden -flto=thin -of=%t_lib%obj
// RUN: %ldc %s -I%S/inputs -flto=thin -of=%t%exe %t_lib%obj
import export_marked_symbols_lib;
void main()
{
exportedGlobal = 1;
normalGlobal = 2; // declared in this module with default visibility, defined as hidden
exportedFoo();
normalFoo(); // ditto
}
./ldc-1.20.1-src/tests/codegen/wasi.d 0000644 0001750 0001750 00000000717 13631266747 017367 0 ustar matthias matthias // REQUIRES: atleast_llvm800, target_WebAssembly
// RUN: %ldc -mtriple=wasm32-unknown-wasi -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
version (WASI) {} else static assert(0);
version (CRuntime_WASI) {} else static assert(0);
// make sure TLS globals are emitted as regular __gshared globals:
// CHECK: @_D4wasi13definedGlobali = global i32 123
int definedGlobal = 123;
// CHECK: @_D4wasi14declaredGlobali = external global i32
extern int declaredGlobal;
./ldc-1.20.1-src/tests/codegen/attr_assumeused.d 0000644 0001750 0001750 00000000545 13631266747 021633 0 ustar matthias matthias // Tests @assumeUsed attribute
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// CHECK: @llvm.used = appending global {{.*}} @some_function {{.*}} @some_variable
static import ldc.attributes;
extern (C): // For easier name mangling
@(ldc.attributes.assumeUsed) void some_function()
{
}
@(ldc.attributes.assumeUsed) int some_variable;
./ldc-1.20.1-src/tests/codegen/complex_identity_gh2918.d 0000644 0001750 0001750 00000000526 13631266747 023004 0 ustar matthias matthias // RUN: %ldc -run %s
void main()
{
creal f1 = +0.0 + 0.0i;
creal f2 = +0.0 - 0.0i;
creal f3 = -0.0 + 0.0i;
creal f4 = +0.0 + 0.0i;
assert(f1 !is f2);
assert(f1 !is f3);
assert(f2 !is f3);
assert(f1 is f4);
assert(!(f1 is f2));
assert(!(f1 is f3));
assert(!(f2 is f3));
assert(!(f1 !is f4));
}
./ldc-1.20.1-src/tests/codegen/nested_gh2960.d 0000644 0001750 0001750 00000001226 13631266747 020701 0 ustar matthias matthias // RUN: %ldc -run %s
template listDir(alias handler)
{
struct NestedStruct
{
void callHandler() { handler(); }
}
class NestedClass
{
void callHandler() { handler(); }
}
void nestedFunc() { handler(); }
void listDir()
{
int a = 123;
void foo() { assert(a == 123); }
// pass local listDir() frame as context
foo();
// pass parent context for sibling symbols:
NestedStruct().callHandler();
(new NestedClass).callHandler();
nestedFunc();
}
}
void main()
{
int magic = 0xDEADBEEF;
listDir!(() { assert(magic == 0xDEADBEEF); })();
}
./ldc-1.20.1-src/tests/codegen/gh1433.d 0000644 0001750 0001750 00000003345 13631266747 017335 0 ustar matthias matthias // RUN: %ldc -run %s
@safe:
int step;
int[] globalArray;
void reset(int initialStep)
{
step = initialStep;
globalArray = [ -1, -2, -3, -4 ];
}
int[] getBaseSlice()
{
assert(step++ == 0);
return globalArray;
}
ref int[] getBaseSliceRef()
{
assert(step++ == 0);
return globalArray;
}
int getLowerBound(size_t dollar)
{
assert(step++ == 1);
assert(dollar == 4);
globalArray = null;
return 1;
}
int getUpperBound(size_t dollar, size_t expectedDollar)
{
assert(step++ == 2);
assert(dollar == expectedDollar);
globalArray = [ 1, 2, 3 ];
return 3;
}
// https://github.com/ldc-developers/ldc/issues/1433
void main()
{
reset(0);
auto r = getBaseSlice()[getLowerBound($) .. getUpperBound($, 4)];
assert(r == [ -2, -3 ]); // old buffer
// LDC and GDC treat $ as lvalue and load .length each time it is accessed
// DMD apparently treats it as rvalue and loads it once at the beginning (=> wrong bounds check)
version(DigitalMars)
enum expectedDollar = 4;
else
enum expectedDollar = 0;
reset(1);
r = globalArray[getLowerBound($) .. getUpperBound($, expectedDollar)];
assert(r == [ 2, 3 ]); // new buffer
reset(0);
r = getBaseSliceRef()[getLowerBound($) .. getUpperBound($, expectedDollar)];
version(DigitalMars)
assert(r == [ -2, -3 ]); // old buffer
else
assert(r == [ 2, 3 ]); // new buffer
testBoundsCheck();
}
void testBoundsCheck() @trusted // @trusted needed for catching Errors, otherwise @safe
{
import core.exception : RangeError;
reset(1);
try
{
auto r = globalArray[getLowerBound($) .. 2]; // null[1 .. 2]
assert(0); // fails for DMD
}
catch (RangeError) {}
}
./ldc-1.20.1-src/tests/codegen/inlining_stdlib.d 0000644 0001750 0001750 00000002014 13631266747 021564 0 ustar matthias matthias // Test inlining of some standard library functions
// RUN: %ldc %s -c -output-ll -release -O0 -of=%t.O0.ll && FileCheck %s --check-prefix OPT0 < %t.O0.ll
// RUN: %ldc %s -c -output-ll -release -O3 -enable-cross-module-inlining -of=%t.O3.ll && FileCheck %s --check-prefix OPT3 < %t.O3.ll
extern (C): // simplify mangling for easier matching
// OPT0-LABEL: define{{.*}} @foo(
// OPT3-LABEL: define{{.*}} @foo(
int foo(size_t i)
{
// core.bitop.bsf() is force-inlined
import core.bitop;
// OPT0: call {{.*}} @llvm.cttz
// OPT3: call {{.*}} @llvm.cttz
return bsf(i);
// OPT0: ret
// OPT3: ret
}
// OPT0-LABEL: define{{.*}} @ggg(
// OPT3-LABEL: define{{.*}} @ggg(
double ggg(double r)
{
// std.math.nextDown() is inlined when optimizing
import std.math;
// OPT0: call {{.*}} @{{.*}}D3std4math8nextDown
// OPT3: call {{.*}} @{{.*}}D3std4math6nextUp
return nextDown(r);
// OPT0: ret
// OPT3: ret
}
// OPT0: declare {{.*}}D3std4math8nextDown
// OPT3: declare {{.*}}D3std4math6nextUp
./ldc-1.20.1-src/tests/codegen/const_cond.d 0000644 0001750 0001750 00000002611 13631266747 020550 0 ustar matthias matthias // Make sure that the dead code of an `if` (and `else if`) is elminated when the condition is constant.
// If the condition value is constant, there are two cases:
// 1) It is 0 (false) -> Generate the else block (if it exists) with no branching.
// 2) It is non-0 (true) -> Generate the if block with no branching.
// Also, verify it _does_ generate correct code when it is not constant.
// RUN: %ldc -O0 -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
extern(C): //to avoid name mangling.
// CHECK-LABEL: @foo
void foo()
{
// CHECK-NOT: %a = alloca
// CHECK: %b = alloca
// CHECK-NOT: br
// CHECK-NOT: store i32 1, i32* %a
// CHECK: store i32 2, i32* %b
if (0)
{
int a = 1;
}
else
{
int b = 2;
}
}
// CHECK-LABEL: @bar
void bar()
{
// CHECK-NOT: %a = alloca
// CHECK: store i32 2, i32* %b
if (0)
{
int a = 1;
}
else if(1)
{
int b = 2;
}
}
// CHECK-LABEL: @only_ret
void only_ret()
{
// CHECK-NEXT: ret void
// CHECK-NEXT: }
if (1 && (2 - 2))
{
int a = 1;
}
}
// CHECK-LABEL: @only_ret2
void only_ret2()
{
// CHECK-NEXT: ret void
// CHECK-NEXT: }
if (0)
{
int a = 1;
}
else if(0)
{
int b = 2;
}
}
// CHECK-LABEL: @gen_br
void gen_br(immutable int a)
{
// CHECK-COUNT-1: br
if (a)
{
int b = 1;
}
}
./ldc-1.20.1-src/tests/codegen/attr_param.d 0000644 0001750 0001750 00000001117 13631266747 020551 0 ustar matthias matthias // RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
import ldc.attributes;
// CHECK: define{{.*}} @{{.*}}3foo
// CHECK-SAME: i8*{{.*}} noalias %p_arg
void foo(@llvmAttr("noalias") void* p) {}
// CHECK: define{{.*}} @{{.*}}3bar
// CHECK-SAME: [16 x float]*{{.*}} noalias dereferenceable(64) %kernel
// CHECK-SAME: float*{{.*}} noalias %data_arg
void bar(@restrict float* data, @restrict ref const float[16] kernel) {}
// CHECK: define{{.*}} @{{.*}}14classReference
// CHECK-SAME: %object.Object*{{.*}} noalias %obj_arg
void classReference(@restrict Object obj) {}
./ldc-1.20.1-src/tests/codegen/array_equals_memcmp_neverinvoke.d 0000644 0001750 0001750 00000001342 13631266747 025060 0 ustar matthias matthias // Tests that memcmp array comparisons `call` memcmp instead of `invoke`.
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s --check-prefix=LLVM < %t.ll
// When the user defines memcmp, it overrides the prototype defined by LDC.
// The user's prototype does not have the nounwind attribute, and a call to memcmp may become `invoke`.
extern(C) int memcmp(void*, void*, size_t);
void foo();
// Test that memcmp is not `invoked`
// LLVM-LABEL: define{{.*}} @{{.*}}never_invoke
void never_invoke(bool[2] a, bool[2] b)
{
try
{
// LLVM: call i32 @memcmp({{.*}}, {{.*}}, i{{32|64}} 2)
auto result = a == b;
foo(); // Compiler has to assume that this may throw
}
catch (Exception e)
{
}
}
./ldc-1.20.1-src/tests/codegen/vector_init.d 0000644 0001750 0001750 00000003031 13631266747 020741 0 ustar matthias matthias // Make sure vector initializer llvm::Constants are generated correctly (GitHub #2101).
// RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
alias D2 = __vector(double[2]);
// CHECK: @{{.*}}_D11vector_init12ImplicitInit6__initZ{{\"?}} =
// CHECK-SAME: { <2 x double> }
struct ImplicitInit { D2 a; }
// CHECK: @{{.*}}_D11vector_init12ExplicitInit6__initZ{{\"?}} =
// CHECK-SAME: { <2 x double> }
struct ExplicitInit { D2 a = D2.init; }
// CHECK: @{{.*}}_D11vector_init10SplatValue6__initZ{{\"?}} =
// CHECK-SAME: { <2 x double> }
struct SplatValue { D2 a = 1.0; }
// CHECK: @{{.*}}_D11vector_init13ElementValues6__initZ{{\"?}} =
// CHECK-SAME: { <2 x double> }
struct ElementValues { D2 a = [1.0, 2.0]; }
// CHECK: define {{.*}}_D11vector_init3foo
void foo()
{
alias void16 = __vector(void[16]);
alias short8 = __vector(short[8]);
// CHECK-NEXT: %v16 = alloca <16 x i8>
// CHECK-NEXT: %s8 = alloca <8 x i16>
// CHECK-NEXT: %d2 = alloca <2 x double>
// CHECK-NEXT: store <16 x i8> zeroinitializer, <16 x i8>* %v16
// CHECK-NEXT: store <8 x i16> , <8 x i16>* %s8
// CHECK-NEXT: store <2 x double> , <2 x double>* %d2
// CHECK-NEXT: ret void
void16 v16;
short8 s8 = [1, 2, 3, 4, 5, 6, 7, 8];
D2 d2 = 1.5;
}
./ldc-1.20.1-src/tests/codegen/cmpxchg.d 0000644 0001750 0001750 00000001300 13631266747 020042 0 ustar matthias matthias // RUN: %ldc -O -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
import core.atomic;
// CHECK: define {{.*}}_D7cmpxchg3fooFiZb
bool foo(int cmp)
{
static shared int g;
// CHECK-NEXT: %1 = cmpxchg i32*
// CHECK-NEXT: %2 = extractvalue { i32, i1 } %1, 1
// CHECK-NEXT: ret i1 %2
return cas(&g, cmp, 456);
}
// CHECK: define {{.*}}_D7cmpxchg3barFdZd
double bar(double cmp)
{
static shared double g;
// CHECK-NEXT: %1 = bitcast double %cmp_arg to i64
// CHECK-NEXT: %2 = cmpxchg weak i64*
casWeak(&g, &cmp, 456.0);
// CHECK-NEXT: %3 = extractvalue { i64, i1 } %2, 0
// CHECK-NEXT: %4 = bitcast i64 %3 to double
// CHECK-NEXT: ret double %4
return cmp;
}
./ldc-1.20.1-src/tests/codegen/mangling_real_real.d 0000644 0001750 0001750 00000001621 13631266747 022221 0 ustar matthias matthias // Tests that repeated `real` return types are treated as built-in types in C++ mangling (no substitution).
// REQUIRES: target_X86
// RUN: %ldc -mtriple=x86_64-linux -c -output-ll -of=%t.ll %s && FileCheck %s --check-prefix=LINUX < %t.ll
// RUN: %ldc -mtriple=x86_64-android -c -output-ll -of=%t.android.ll %s && FileCheck %s --check-prefix=ANDROID < %t.android.ll
// RUN: %ldc -mtriple=x86_64-windows -c -output-ll -of=%t.windows.ll %s && FileCheck %s --check-prefix=WINDOWS < %t.windows.ll
import core.stdc.config;
// LINUX: define {{.*}}Z8withrealee
// ANDROID: define {{.*}}Z8withrealgg
// WINDOWS: define {{.*}}?withreal@@YAXOO@Z
extern (C++) void withreal(real a, real b)
{
}
// LINUX: define {{.*}}Z15withclongdoubleee
// ANDROID: define {{.*}}Z15withclongdoublegg
// WINDOWS: define {{.*}}?withclongdouble@@YAXOO@Z
extern (C++) void withclongdouble(c_long_double a, c_long_double b)
{
}
./ldc-1.20.1-src/tests/codegen/vector_ops.d 0000644 0001750 0001750 00000002227 13631266747 020605 0 ustar matthias matthias // REQUIRES: atleast_llvm500
// RUN: %ldc -run %s
import core.simd;
void main()
{
static void testGenericOps(T)()
{
const T v = [ 1, -2, 3, -4 ];
assert(-v == [ -1, 2, -3, 4 ]);
assert(+v == v);
T v2 = v;
assert(v2 == v && !(v2 != v));
assert(v2 is v && !(v2 !is v));
v2[0] = 0;
assert(v2 != v && !(v2 == v));
assert(v2 !is v && !(v2 is v));
assert(v + v == [ 2, -4, 6, -8 ]);
assert(v - v == T(0));
assert(v * v == [ 1, 4, 9, 16 ]);
assert(v / v == T(1));
assert(v % T(3) == [ 1, -2, 0, -1 ]);
}
testGenericOps!float4();
testGenericOps!int4();
const float4 nan = float.nan;
assert(nan != nan && !(nan == nan));
assert(nan is nan && !(nan !is nan));
const int4 i = [ 1, 2, 3, 4 ];
assert(i << i == [ 2, 8, 24, 64 ]);
const int4 a = [ 0b1, 0b10, 0b101, 0b100011 ];
const int4 b = 0b110;
assert((a & b) == [ 0, 0b10, 0b100, 0b10 ]);
assert((a | b) == [ 0b111, 0b110, 0b111, 0b100111 ]);
assert((a ^ b) == [ 0b111, 0b100, 0b11, 0b100101 ]);
assert(~a == [ ~0b1, ~0b10, ~0b101, ~0b100011 ]);
}
./ldc-1.20.1-src/tests/codegen/simd_alignment.d 0000644 0001750 0001750 00000001107 13631266747 021410 0 ustar matthias matthias // RUN: %ldc -c -output-ll -O3 -of=%t.ll %s && FileCheck %s < %t.ll
import core.simd;
struct S17237
{
bool a;
struct
{
bool b;
int8 c;
}
}
int4 globalIntFour;
// CHECK-DAG: globalIntFour{{.*}} = {{.*}} align 16
S17237 globalStruct;
// CHECK-DAG: @{{.*}}globalStruct{{.*}}S17237{{\"?}} = {{.*}} zeroinitializer{{(, comdat)?}}, align 32
// CHECK-LABEL: define <8 x i32> @foo(
extern(C) int8 foo(S17237* s)
{
// CHECK: %[[GEP:[0-9]]] = getelementptr {{.*}}S17237* %s_arg
// CHECK: = load {{.*}}<8 x i32>* %[[GEP]], align 32
return s.c;
}
./ldc-1.20.1-src/tests/codegen/in_place_construct.d 0000644 0001750 0001750 00000010637 13631266747 022304 0 ustar matthias matthias // Tests in-place construction of variables.
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// 256 bits, returned via sret:
struct S
{
long a, b, c, d;
}
// CHECK-LABEL: define{{.*}} @{{.*}}_D18in_place_construct13returnLiteralFZSQBm1S
S returnLiteral()
{
// make sure the literal is emitted directly into the sret pointee
// CHECK: %1 = getelementptr inbounds {{.*}}%in_place_construct.S* %.sret_arg, i32 0, i32 0
// CHECK: store i64 1, i64* %1
// CHECK: %2 = getelementptr inbounds {{.*}}%in_place_construct.S* %.sret_arg, i32 0, i32 1
// CHECK: store i64 2, i64* %2
// CHECK: %3 = getelementptr inbounds {{.*}}%in_place_construct.S* %.sret_arg, i32 0, i32 2
// CHECK: store i64 3, i64* %3
// CHECK: %4 = getelementptr inbounds {{.*}}%in_place_construct.S* %.sret_arg, i32 0, i32 3
// CHECK: store i64 4, i64* %4
return S(1, 2, 3, 4);
}
// CHECK-LABEL: define{{.*}} @{{.*}}_D18in_place_construct12returnRValueFZSQBl1S
S returnRValue()
{
// make sure the sret pointer is forwarded
// CHECK: call {{.*}}_D18in_place_construct13returnLiteralFZSQBm1S
// CHECK-SAME: %in_place_construct.S* {{.*}} %.sret_arg
return returnLiteral();
}
// CHECK-LABEL: define{{.*}} @{{.*}}_D18in_place_construct10returnNRVOFZSQBj1S
S returnNRVO()
{
// make sure NRVO zero-initializes the sret pointee directly
// CHECK: %1 = bitcast %in_place_construct.S* %.sret_arg to i8*
// CHECK: call void @llvm.memset.{{.*}}(i8*{{[a-z0-9 ]*}} %1, i8 0,
const S r;
return r;
}
// CHECK-LABEL: define{{.*}} @{{.*}}_D18in_place_construct15withOutContractFZSQBo1S
S withOutContract()
out { assert(__result.a == 0); }
body
{
// make sure NRVO zero-initializes the sret pointee directly
// CHECK: %1 = bitcast %in_place_construct.S* %.sret_arg to i8*
// CHECK: call void @llvm.memset.{{.*}}(i8*{{[a-z0-9 ]*}} %1, i8 0,
const S r;
return r;
// make sure `__result` inside the out contract is just an alias to the sret pointee
// CHECK: %2 = getelementptr inbounds {{.*}}%in_place_construct.S* %.sret_arg, i32 0, i32 0
// CHECK: %3 = load {{.*}}i64* %2
// CHECK: %4 = icmp eq i64 %3, 0
}
// CHECK-LABEL: define{{.*}} @{{.*}}_D18in_place_construct7structsFZv
void structs()
{
// CHECK: %literal = alloca %in_place_construct.S
// CHECK: %a = alloca %in_place_construct.S
// CHECK: %b = alloca %in_place_construct.S
// CHECK: %c = alloca %in_place_construct.S
// make sure the literal is emitted directly into the lvalue
// CHECK: %1 = getelementptr inbounds {{.*}}%in_place_construct.S* %literal, i32 0, i32 0
// CHECK: store i64 5, i64* %1
// CHECK: %2 = getelementptr inbounds {{.*}}%in_place_construct.S* %literal, i32 0, i32 1
// CHECK: store i64 6, i64* %2
// CHECK: %3 = getelementptr inbounds {{.*}}%in_place_construct.S* %literal, i32 0, i32 2
// CHECK: store i64 7, i64* %3
// CHECK: %4 = getelementptr inbounds {{.*}}%in_place_construct.S* %literal, i32 0, i32 3
// CHECK: store i64 8, i64* %4
const literal = S(5, 6, 7, 8);
// make sure the variables are in-place constructed via sret
// CHECK: call {{.*}}_D18in_place_construct13returnLiteralFZSQBm1S
// CHECK-SAME: %in_place_construct.S* {{.*}} %a
const a = returnLiteral();
// CHECK: call {{.*}}_D18in_place_construct12returnRValueFZSQBl1S
// CHECK-SAME: %in_place_construct.S* {{.*}} %b
const b = returnRValue();
// CHECK: call {{.*}}_D18in_place_construct10returnNRVOFZSQBj1S
// CHECK-SAME: %in_place_construct.S* {{.*}} %c
const c = returnNRVO();
withOutContract();
}
// CHECK-LABEL: define{{.*}} @{{.*}}_D18in_place_construct12staticArraysFZv
void staticArrays()
{
// CHECK: %sa = alloca [2 x i32]
// make sure static array literals are in-place constructed too
// CHECK: store [2 x i32] [i32 1, i32 2], [2 x i32]* %sa
const(int[2]) sa = [ 1, 2 ];
}
struct Container { S s; }
// CHECK-LABEL: define{{.*}} @{{.*}}_D18in_place_construct19hierarchyOfLiteralsFZv
void hierarchyOfLiterals()
{
// CHECK: %sa = alloca [1 x %in_place_construct.Container]
// CHECK: store [1 x %in_place_construct.Container] [%in_place_construct.Container { %in_place_construct.S { i64 11, i64 12, i64 13, i64 14 } }], [1 x %in_place_construct.Container]* %sa
Container[1] sa = [ Container(S(11, 12, 13, 14)) ];
}
// CHECK-LABEL: define{{.*}} @{{.*}}_Dmain
void main()
{
structs();
staticArrays();
hierarchyOfLiterals();
}
./ldc-1.20.1-src/tests/codegen/vector_abi_x86.d 0000644 0001750 0001750 00000000665 13631266747 021250 0 ustar matthias matthias // Makes sure an optimized trivial function taking and returning a vector
// takes and returns it directly in XMM0, with no memory indirections.
// REQUIRES: host_X86
// RUN: %ldc -O -output-s -of=%t.s %s && FileCheck %s < %t.s
import core.simd;
// CHECK: _D14vector_abi_x863foo
int4 foo(int4 param)
{
// CHECK-NOT: mov
// CHECK: paddd
// CHECK-SAME: %xmm0
return param + 3;
// CHECK-NOT: mov
// CHECK: ret
}
./ldc-1.20.1-src/tests/codegen/discard_value_names_ir2obj_cache.d 0000644 0001750 0001750 00000001330 13631266747 024776 0 ustar matthias matthias // Test value name discarding in conjunction with the compile cache: local variable name changes should still give a cache hit.
// Create and then empty the cache for correct testing when running the test multiple times.
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir
// RUN: %prunecache -f %t-dir --max-bytes=1
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -d-version=FIRST -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -vv | FileCheck --check-prefix=MUST_HIT %s
// MUST_HIT: Cache object found!
// NO_HIT-NOT: Cache object found!
version (FIRST)
{
int foo(int a)
{
return a + 2;
}
}
else
{
int foo(int differentname)
{
return differentname + 2;
}
}
./ldc-1.20.1-src/tests/codegen/asm_constraints.d 0000644 0001750 0001750 00000000261 13631266747 021625 0 ustar matthias matthias // RUN: not %ldc -c -w %s 2>&1 | FileCheck %s
void main () {
import ldc.llvmasm : __asm;
// CHECK: Error: `__asm` constraint argument is invalid
__asm("", "][");
}
./ldc-1.20.1-src/tests/codegen/export_naked_gh2648.d 0000644 0001750 0001750 00000000451 13631266747 022104 0 ustar matthias matthias // RUN: %ldc -shared -of=%t.dll %s
// RUN: dumpbin /exports %t.dll | FileCheck %s
// REQUIRES: Windows
export
{
// CHECK-DAG: _D19export_naked_gh264812exportNormal
void exportNormal() { }
// CHECK-DAG: _D19export_naked_gh264811exportNaked
void exportNaked() { asm { naked; } }
}
./ldc-1.20.1-src/tests/codegen/pragma_LDC_extern_weak.d 0000644 0001750 0001750 00000001160 13631266747 022742 0 ustar matthias matthias // Test pragma(LDC_extern_weak) on function declarations.
// RUN: %ldc -d-version=DECLARATION -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll --check-prefix=DECLARATION
// RUN: not %ldc -d-version=DEFINITION %s 2>&1 | FileCheck %s --check-prefix=DEFINITION
version(DECLARATION)
{
// DECLARATION: declare{{.*}} extern_weak {{.*}}weakreffunction
pragma(LDC_extern_weak) extern(C) void weakreffunction();
}
version(DEFINITION)
{
// DEFINITION: Error: `LDC_extern_weak` cannot be applied to function definitions
pragma(LDC_extern_weak) extern(C) void weakreffunction() {};
}
void foo()
{
auto a = &weakreffunction;
}
./ldc-1.20.1-src/tests/codegen/inlining_disablecross.d 0000644 0001750 0001750 00000001411 13631266747 022760 0 ustar matthias matthias // Test disabling/enabling of cross-module inlining
// RUN: %ldc %s -I%S -c -output-ll -enable-cross-module-inlining -O0 -of=%t.ENA.ll && FileCheck %s --check-prefix ENABLED < %t.ENA.ll
// RUN: %ldc %s -I%S -c -output-ll -disable-cross-module-inlining -O3 -of=%t.DIS.ll && FileCheck %s --check-prefix DISABLED < %t.DIS.ll
import inputs.inlinables;
extern (C): // simplify mangling for easier matching
// DISABLED-LABEL: define{{.*}} @call_easily_inlinable(
// ENABLED-LABEL: define{{.*}} @call_easily_inlinable(
int call_easily_inlinable(int i)
{
// DISABLED: call {{.*}} @easily_inlinable(
return easily_inlinable(i);
// DISABLED: ret
// ENABLED: ret
}
// ENABLED-DAG: define {{.*}} @easily_inlinable(
// DISABLED-DAG: declare {{.*}} @easily_inlinable(
./ldc-1.20.1-src/tests/codegen/in_place_construct_temporaries.d 0000644 0001750 0001750 00000003070 13631266747 024707 0 ustar matthias matthias // from https://issues.dlang.org/show_bug.cgi?id=20321
// Restrict to x86[_64] hosts for now, as the ABI must not perform any implicit
// blits (e.g., via LLVM byval attribute) for non-PODs.
// REQUIRES: host_X86
// RUN: %ldc -run %s
version (Win32)
{
// ABI needs *a lot* of work: https://github.com/ldc-developers/ldc/pull/3204#discussion_r339300174
void main() {}
}
else:
__gshared bool success = true;
/** Container with internal pointer
*/
struct Container
{
long[3] data;
void* p;
this(int) { p = &data[0]; }
this(ref inout Container) inout { p = &data[0]; }
/** Ensure the internal pointer is correct */
void check(int line = __LINE__)
{
if (p != &data[0])
{
import core.stdc.stdio : printf;
printf("Check failed in line %d\n", line);
success = false;
}
}
}
void func(Container c) { c.check(); } // error
Container get()
{
auto a = Container(1);
auto b = a;
a.check(); // ok
b.check(); // ok
// no nrvo
if (1)
return a;
else
return b;
}
Container get2()
out(r){}
do
{
auto v = Container(1);
v.check(); // ok
return v;
}
int main()
{
Container v = Container(1);
v.check(); // ok
func(v);
auto r = get();
r.check(); // error
auto r2 = get2();
r.check(); // error
Container[1] slit = [v];
slit[0].check(); // error
Container[] dlit = [v];
dlit[0].check(); // error
auto b = B(v);
b.m.check(); // error
return success ? 0 : 1;
}
struct B
{
Container m;
}
./ldc-1.20.1-src/tests/codegen/inlining_imports.d 0000644 0001750 0001750 00000001725 13631266747 022010 0 ustar matthias matthias // Test inlining of imported functions
// RUN: %ldc %s -I%S -c -output-ll -release -O3 -enable-cross-module-inlining -of=%t.O3.ll && FileCheck %s --check-prefix OPT3 < %t.O3.ll
import inputs.inlinables;
extern (C): // simplify mangling for easier matching
// Simple functions for reference.
int foo()
{
return goo();
}
int goo()
{
return 1;
}
// OPT3-LABEL: define{{.*}} @call_easily_inlinable(
int call_easily_inlinable(int i)
{
// OPT3-NOT: call {{.*}} @easily_inlinable(
return easily_inlinable(i);
// OPT3: ret i32 2
}
// OPT3-LABEL: define{{.*}} @call_class_function(
int call_class_function(A a)
{
// OPT3-NOT: call
return a.final_class_function();
// OPT3: ret i32 12345
}
// OPT3-LABEL: define{{.*}} @call_weak_function(
int call_weak_function()
{
// OPT3: call
return weak_function();
// OPT3-NOT: 654
// Test for function end `}` to prevent matching "654" elsewhere (e.g. the LDC version git hash)
// OPT3: }
}
./ldc-1.20.1-src/tests/codegen/dcompute_cl_addrspaces.d 0000644 0001750 0001750 00000005317 13631266747 023114 0 ustar matthias matthias // See GH issue #2709
// REQUIRES: target_SPIRV
// RUN: %ldc -c -mdcompute-targets=ocl-220 -m64 -mdcompute-file-prefix=addrspace -output-ll -output-o %s && FileCheck %s --check-prefix=LL < addrspace_ocl220_64.ll \
// RUN: && %llvm-spirv -to-text addrspace_ocl220_64.spv && FileCheck %s --check-prefix=SPT < addrspace_ocl220_64.spt
@compute(CompileFor.deviceOnly) module dcompute_cl_addrspaces;
import ldc.dcompute;
// LL: %"ldc.dcompute.Pointer!(cast(AddrSpace)0u, float).Pointer" = type { float* }
// LL: %"ldc.dcompute.Pointer!(cast(AddrSpace)1u, float).Pointer" = type { float addrspace(1)* }
// LL: %"ldc.dcompute.Pointer!(cast(AddrSpace)2u, float).Pointer" = type { float addrspace(2)* }
// LL: %"ldc.dcompute.Pointer!(cast(AddrSpace)3u, immutable(float)).Pointer" = type { float addrspace(3)* }
// LL: %"ldc.dcompute.Pointer!(cast(AddrSpace)4u, float).Pointer" = type { float addrspace(4)* }
// SPT-DAG: 2 TypeVoid [[VOID_ID:[0-9]+]]
// SPT-DAG: 3 TypeFloat [[FLOAT_ID:[0-9]+]] 32
//See section 3.7 of the SPIR-V Specification for the numbers in the 4th column.
// SPT-DAG: 4 TypePointer [[SHARED_FLOAT_POINTER_ID:[0-9]+]] 4 [[FLOAT_ID]]
// SPT-DAG: 4 TypePointer [[CONSTANT_FLOAT_POINTER_ID:[0-9]+]] 0 [[FLOAT_ID]]
// SPT-DAG: 4 TypePointer [[GLOBAL_FLOAT_POINTER_ID:[0-9]+]] 5 [[FLOAT_ID]]
// SPT-DAG: 4 TypePointer [[GENERIC_FLOAT_POINTER_ID:[0-9]+]] 8 [[FLOAT_ID]]
// SPT-DAG: 4 TypePointer [[PRIVATE_FLOAT_POINTER_ID:[0-9]+]] 7 [[FLOAT_ID]]
//void function({ T addrspace(n)* })
// SPT-DAG: 4 TypeFunction [[FOO_PRIVATE:[0-9]+]] [[VOID_ID]] [[PRIVATE_FLOAT_POINTER_ID]]
// SPT-DAG: 4 TypeFunction [[FOO_GLOBAL:[0-9]+]] [[VOID_ID]] [[GLOBAL_FLOAT_POINTER_ID]]
// SPT-DAG: 4 TypeFunction [[FOO_SHARED:[0-9]+]] [[VOID_ID]] [[SHARED_FLOAT_POINTER_ID]]
// SPT-DAG: 4 TypeFunction [[FOO_CONSTANT:[0-9]+]] [[VOID_ID]] [[CONSTANT_FLOAT_POINTER_ID]]
// SPT-DAG: 4 TypeFunction [[FOO_GENERIC:[0-9]+]] [[VOID_ID]] [[GENERIC_FLOAT_POINTER_ID]]
void foo(PrivatePointer!float f) {
// LL: load float, float*
// SPT-DAG: 5 Function [[VOID_ID]] {{[0-9]+}} 0 [[FOO_PRIVATE]]
float g = *f;
}
void foo(GlobalPointer!float f) {
// LL: load float, float addrspace(1)*
// SPT-DAG: 5 Function [[VOID_ID]] {{[0-9]+}} 0 [[FOO_GLOBAL]]
float g = *f;
}
void foo(SharedPointer!float f) {
// LL: load float, float addrspace(2)*
// SPT-DAG: 5 Function [[VOID_ID]] {{[0-9]+}} 0 [[FOO_SHARED]]
float g = *f;
}
void foo(ConstantPointer!float f) {
// LL: load float, float addrspace(3)*
// SPT-DAG: 5 Function [[VOID_ID]] {{[0-9]+}} 0 [[FOO_CONSTANT]]
float g = *f;
}
void foo(GenericPointer!float f) {
// LL: load float, float addrspace(4)*
// SPT-DAG: 5 Function [[VOID_ID]] {{[0-9]+}} 0 [[FOO_GENERIC]]
float g = *f;
}
./ldc-1.20.1-src/tests/codegen/inlining_leakdefinitions_asm.d 0000644 0001750 0001750 00000002330 13631266747 024314 0 ustar matthias matthias // Test that inlining does not leak definitions without marking them as available_externally
// "Leaking" = symbols definitions in .o file that shouldn't be declarations instead (undefined symbols).
// REQUIRES: target_X86
// RUN: %ldc %s -mtriple=x86_64-linux-gnu -I%S -c -output-ll -release -O3 -enable-cross-module-inlining -of=%t.O3.ll && FileCheck %s --check-prefix OPT3 < %t.O3.ll
// RUN: %ldc %s -mtriple=x86_64-linux-gnu -I%S -c -output-ll -release -enable-inlining -O0 -enable-cross-module-inlining -of=%t.O0.ll && FileCheck %s --check-prefix OPT0 < %t.O0.ll
import inputs.inlinables_asm;
extern (C): // simplify mangling for easier matching
// Inlined naked asm func could end up as global symbols, definitely bad!
// (would give multiple definition linker error)
// OPT0-NOT: module asm {{.*}}.globl{{.*}}_naked_asm_func
// OPT3-NOT: module asm {{.*}}.globl{{.*}}_naked_asm_func
// OPT0-LABEL: define{{.*}} @asm_func(
// OPT3-LABEL: define{{.*}} @asm_func(
void asm_func()
{
naked_asm_func();
// OPT0: ret void
// OPT3: ret void
}
// OPT0-LABEL: define{{.*}} @main(
// OPT3-LABEL: define{{.*}} @main(
int main()
{
asm_func();
return 0;
// OPT0: ret i32 0
// OPT3: ret i32 0
}
./ldc-1.20.1-src/tests/codegen/vector_intrinsics_gh2962.d 0000644 0001750 0001750 00000000552 13631266747 023171 0 ustar matthias matthias // REQUIRES: atleast_llvm500
// REQUIRES: host_X86
// RUN: %ldc -run %s
import core.simd;
import ldc.intrinsics;
void main()
{
const float4 f = [ 1, -2, 3, -4 ];
const abs = llvm_fabs(f);
assert(abs == [ 1, 2, 3, 4 ]);
const int4 i = [ 0b0, 0b10, 0b101, 0b100011 ];
const numOnes = llvm_ctpop(i);
assert(numOnes == [ 0, 1, 2, 3 ]);
}
./ldc-1.20.1-src/tests/codegen/fence_pragma2.d 0000644 0001750 0001750 00000000547 13631266747 021116 0 ustar matthias matthias // RUN: %ldc %s -c -output-ll -of=%t.ll && FileCheck %s < %t.ll
// REQUIRES: atleast_llvm500
import ldc.intrinsics;
void fun0 () {
llvm_memory_fence(DefaultOrdering, SynchronizationScope.CrossThread);
// CHECK: fence seq_cst
llvm_memory_fence(DefaultOrdering, SynchronizationScope.SingleThread);
// CHECK: fence syncscope("singlethread") seq_cst
}
./ldc-1.20.1-src/tests/codegen/asm_labels.d 0000644 0001750 0001750 00000001067 13631266747 020525 0 ustar matthias matthias // REQUIRES: target_X86
// RUN: %ldc -mtriple=x86_64-linux-gnu -output-s -of=%t.s %s
// RUN: FileCheck %s < %t.s
// CHECK: _D10asm_labels3fooFiZv:
void foo(int a)
{
asm
{
// CHECK: jmp .L_D10asm_labels3fooFiZv_label
jmp label;
// CHECK-NEXT: .L_D10asm_labels3fooFiZv_label:
label:
ret;
}
}
// CHECK: _D10asm_labels3fooFkZv:
void foo(uint a)
{
asm
{
// CHECK: jmp .L_D10asm_labels3fooFkZv_label
jmp label;
// CHECK-NEXT: .L_D10asm_labels3fooFkZv_label:
label:
ret;
}
}
./ldc-1.20.1-src/tests/codegen/discard_value_names_gh1749.d 0000644 0001750 0001750 00000001536 13631266747 023417 0 ustar matthias matthias // Test value name discarding when creating non-textual IR.
// RUN: %ldc %S/inputs/input_discard_valuename.d -c -output-ll -of=%t.bar.ll && FileCheck %S/inputs/input_discard_valuename.d < %t.bar.ll
// Output a bitcode file (i.e. with discarded names) and input it into a second LDC command that outputs textual IR.
// RUN: %ldc %S/inputs/input_discard_valuename.d -g -c -output-bc -of=%t.bar.bc \
// RUN: && %ldc %s %t.bar.bc -g -c -output-ll -of=%t.ll && FileCheck %s < %t.ll
// IR imported from the bitcode file should not have local value names:
// CHECK-LABEL: define{{.*}} @foo
// CHECK: %localfoovar
// CHECK-LABEL: define{{.*}} @bar
// CHECK-NOT: %localbarvar
// But the imported IR should still have debug names:
// CHECK: DILocalVariable{{.*}}"localfoovar"
// CHECK: DILocalVariable{{.*}}"localbarvar"
extern(C) void foo()
{
int localfoovar;
}
./ldc-1.20.1-src/tests/codegen/export.d 0000644 0001750 0001750 00000001066 13631266747 017743 0 ustar matthias matthias // RUN: %ldc -output-ll -of=%t.ll %s
// RUN: FileCheck %s < %t.ll
// REQUIRES: Windows
export
{
// CHECK-DAG: @{{.*}}exportedGlobal{{.*}} = dllexport
extern(C) __gshared void* exportedGlobal;
// CHECK-DAG: @{{.*}}importedGlobal{{.*}} = external dllimport
extern(C) extern __gshared void* importedGlobal;
// CHECK-DAG: define dllexport {{.*}}_D6export11exportedFooFZv
void exportedFoo() {}
// CHECK-DAG: declare dllimport {{.*}}_D6export11importedFooFZv
void importedFoo();
}
void bar()
{
exportedFoo();
importedFoo();
}
./ldc-1.20.1-src/tests/codegen/complex_postexpr_gh1806.d 0000644 0001750 0001750 00000000632 13631266747 023030 0 ustar matthias matthias // RUN: %ldc -run %s
void runTest(T)() {
{
T v = 1.0 + 1.0i;
assert(v++ == 1.0 + 1.0i);
assert(v-- == 2.0 + 1.0i);
assert(v == 1.0 + 1.0i);
}
{
T v = 1.0 + 1.0i;
assert(++v == 2.0 + 1.0i);
assert(--v == 1.0 + 1.0i);
assert(v == 1.0 + 1.0i);
}
}
void main () {
runTest!cfloat();
runTest!cdouble();
runTest!creal();
}
./ldc-1.20.1-src/tests/codegen/inline_ir.d 0000644 0001750 0001750 00000001146 13631266747 020371 0 ustar matthias matthias // RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
import ldc.llvmasm;
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)
{
// CHECK: %{{.*}} = load i32, i32* {{.*}} !nontemporal ![[METADATA:[0-9]+]]
return nontemporalLoad(src);
}
void bar(int* dst, int val)
{
// CHECK: store i32 {{.*}} !nontemporal ![[METADATA]]
nontemporalStore(dst, val);
}
// CHECK: ![[METADATA]] = !{i32 1} ./ldc-1.20.1-src/tests/codegen/atomicrmw.d 0000644 0001750 0001750 00000001465 13631266747 020427 0 ustar matthias matthias // RUN: %ldc -c -de -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
import core.atomic;
void main() {
shared ubyte x = 3;
ubyte r;
r = atomicOp!"+="(x, uint(257));
assert(x == r);
// CHECK: = atomicrmw add i8*
r = atomicOp!"+="(x, int(-263));
assert(x == r);
// CHECK: = atomicrmw add i8*
r = atomicOp!"-="(x, ushort(257));
assert(x == r);
// CHECK: = atomicrmw sub i8*
r = atomicOp!"-="(x, short(-263));
assert(x == r);
// CHECK: = atomicrmw sub i8*
r = atomicOp!"&="(x, ubyte(255));
assert(x == r);
// CHECK: = atomicrmw and i8*
r = atomicOp!"|="(x, short(3));
assert(x == r);
// CHECK: = atomicrmw or i8*
r = atomicOp!"^="(x, int(3));
assert(x == r);
// CHECK: = atomicrmw xor i8*
r = atomicOp!"+="(x, 1.0f);
assert(x == r);
// CHECK: = cmpxchg weak i8*
}
./ldc-1.20.1-src/tests/codegen/ptr_16_bit.d 0000644 0001750 0001750 00000000301 13631266747 020362 0 ustar matthias matthias // REQUIRES: target_MSP430
// RUN: %ldc -mtriple=msp430 -o- %s
void* ptr;
static assert(ptr.sizeof == 2);
version(D_P16) {}
else static assert(0);
version(MSP430) {}
else static assert(0);
./ldc-1.20.1-src/tests/codegen/export_marked_symbols2.d 0000644 0001750 0001750 00000001355 13631266747 023121 0 ustar matthias matthias // Tests that -fvisibility=hidden doesn't affect imported and fwd declared symbols,
// so that they can still be linked in from a shared library.
// UNSUPPORTED: Windows
// RUN: %ldc %S/inputs/export_marked_symbols_lib.d -shared -of=%t_lib%so
// RUN: %ldc %s -I%S/inputs -fvisibility=hidden -of=%t%exe %t_lib%so
// RUN: %ldc %s -I%S/inputs -fvisibility=hidden -of=%t%exe %t_lib%so -d-version=DECLARE_MANUALLY
version (DECLARE_MANUALLY)
{
extern(C++):
export extern __gshared int exportedGlobal;
extern __gshared int normalGlobal;
export void exportedFoo();
void normalFoo();
}
else
{
import export_marked_symbols_lib;
}
void main()
{
exportedGlobal = 1;
normalGlobal = 2;
exportedFoo();
normalFoo();
}
./ldc-1.20.1-src/tests/codegen/linker_directives_linux.d 0000644 0001750 0001750 00000000603 13631266747 023342 0 ustar matthias matthias // RUN: %ldc -mtriple=x86_64-linux-gnu -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// REQUIRES: atleast_llvm500, target_X86
// CHECK: !llvm.dependent-libraries = !{!0}
// CHECK: !0 = !{!"mylib"}
pragma(lib, "mylib");
// silently ignored because not (yet?) embeddable in ELF object file:
pragma(linkerDirective, "-myflag");
pragma(linkerDirective, "-framework", "CoreFoundation");
./ldc-1.20.1-src/tests/codegen/gh3346.d 0000644 0001750 0001750 00000000273 13631266747 017337 0 ustar matthias matthias // RUN: %ldc -run %s
import core.thread;
void foo() {}
shared static this()
{
auto f = new Fiber(&foo); // depends on shared static this in core.thread.osthread.
}
void main() {}
./ldc-1.20.1-src/tests/codegen/cpp_interface.d 0000644 0001750 0001750 00000000164 13631266747 021222 0 ustar matthias matthias // RUN: %ldc -c %s
extern(C++) interface XUnknown {}
class ComObject : XUnknown {}
class DComObject : ComObject {}
./ldc-1.20.1-src/tests/codegen/gh1955.d 0000644 0001750 0001750 00000001650 13631266747 017343 0 ustar matthias matthias // RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// Mutex is a private alias in rt.monitor_
version (Windows)
import core.sys.windows.winbase : Mutex = CRITICAL_SECTION;
else version (Posix)
import core.sys.posix.pthread : Mutex = pthread_mutex_t;
else
static assert(0);
struct D_CRITICAL_SECTION // private symbol in rt.critical_
{
D_CRITICAL_SECTION* next;
Mutex mtx;
}
void main()
{
/* The synchronized-block uses a global buffer for the D_CRITICAL_SECTION.
* Match its size and alignment.
*/
// CHECK: __critsec{{.*}} = global {{\[}}[[SIZEOF:[0-9]+]] x i8{{\]}} zeroinitializer
// CHECK-SAME: align [[ALIGNOF:[0-9]+]]
synchronized {}
/* Verify size and alignment of the global against a manual D_CRITICAL_SECTION.
*/
// CHECK: %cs = alloca %gh1955.D_CRITICAL_SECTION, align [[ALIGNOF]]
// CHECK-SAME: size/byte = [[SIZEOF]]
D_CRITICAL_SECTION cs;
}
./ldc-1.20.1-src/tests/codegen/export_crossModuleInlining.d 0000644 0001750 0001750 00000000660 13631266747 024011 0 ustar matthias matthias // Make sure exported functions can be cross-module inlined without exporting the local function copy.
// RUN: %ldc -O -release -enable-cross-module-inlining -output-ll -of=%t.ll -I%S/inputs %s
// RUN: FileCheck %s < %t.ll
import export2;
// CHECK-NOT: _D7export23fooFZi
// CHECK: define {{.*}}_D26export_crossModuleInlining3barFZi
int bar()
{
// CHECK-NEXT: ret i32 666
return foo();
}
// CHECK-NOT: _D7export23fooFZi
./ldc-1.20.1-src/tests/codegen/attr_naked.d 0000644 0001750 0001750 00000001471 13631266747 020536 0 ustar matthias matthias // REQUIRES: target_X86
// RUN: %ldc -mtriple=x86_64-pc-linux-gnu -O -output-s -of=%t.s %s && FileCheck %s < %t.s
import ldc.attributes;
import ldc.llvmasm;
// Without -O, LLVM (6) dumps the 2 params to stack for Linux x64 (but doesn't for Win64).
// Clang is no different though.
// CHECK: withParams:
extern(C) int withParams(int param1, void* param2) @naked
{
// CHECK-NEXT: .cfi_startproc
// CHECK-NEXT: #APP
// CHECK-NEXT: xorl %eax, %eax
// CHECK-NEXT: #NO_APP
// CHECK-NEXT: retq
return __asm!int("xor %eax, %eax", "={eax}");
}
// CHECK: _D10attr_naked8noReturnFZv:
void noReturn() @naked
{
// CHECK-NEXT: .cfi_startproc
// CHECK-NEXT: #APP
// CHECK-NEXT: jmpq *%rax
// CHECK-NEXT: #NO_APP
__asm("jmp *%rax", "");
// CHECK-NOT: retq
// CHECK: .cfi_endproc
}
./ldc-1.20.1-src/tests/codegen/mangling_gh1519.d 0000644 0001750 0001750 00000001156 13631266747 021214 0 ustar matthias matthias // Test for Github issue 1519
// Check that .mangleof strings do not contain any char 0x01.
// LDC may prepend 0x01 to prevent LLVM from modifying the symbol name, but it should not appear in user code.
// RUN: %ldc -c %s
extern (C) void fooC()
{
}
extern (C++) void fooCpp()
{
}
extern (D) void fooD()
{
}
void aliasTemplate(alias F)()
{
F();
}
void main()
{
import std.algorithm;
static assert(all!"a != '\1'"(fooC.mangleof));
static assert(all!"a != '\1'"(fooCpp.mangleof));
static assert(all!"a != '\1'"(fooD.mangleof));
static assert(all!"a != '\1'"(aliasTemplate!fooCpp.mangleof));
}
./ldc-1.20.1-src/tests/codegen/vastart_vaend_gh1744.d 0000644 0001750 0001750 00000002352 13631266747 022260 0 ustar matthias matthias // Test that va_end is called when returning from a variadic function.
// Because the IR is kind of ugly, testing at -O0 is very brittle. Instead we
// test that at -O3, LLVM was able to analyse the function correctly and
// optimize-out the va_start and va_end calls and remove the call to
// return_two (Github #1744).
// RUN: %ldc %s -c -output-ll -O3 -of=%t.O3.ll \
// RUN: && FileCheck %s --check-prefix OPT3 < %t.O3.ll
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-NOT: return_two
return_two();
if (a > 0)
{
throw new Exception("");
return;
}
// There are two control paths (normal return, exception resume) that
// should call va_end.
// OPT3: call void @llvm.va_end({{.*}} %[[VA]])
// OPT3: call void @llvm.va_end({{.*}} %[[VA]])
}
// OPT3-LABEL: define {{.*}} @{{.*}}return_two
int return_two(...)
{
// OPT3-NOT: va_start
// OPT3-NOT: va_end
// OPT3: ret i32 2
return 2;
}
// Github #1744:
// OPT3-LABEL: define {{.*}} @{{.*}}two_four
int two_four()
{
// OPT3-NOT: return_two
// OPT3: ret i32 8
return return_two() * 4;
}
./ldc-1.20.1-src/tests/codegen/mangling.d 0000644 0001750 0001750 00000004736 13631266747 020225 0 ustar matthias matthias // Makes sure T.mangleof and pragma(mangle, …) are in sync.
// inputs/mangling_definitions.d features C/C++/D symbols and validates their .mangleof.
// This module forward-declares these symbols, using an identical pragma(mangle, …) string,
// and references the symbols in main().
// Compile both modules separately and make sure the 2 objects can be linked successfully.
// RUN: %ldc %S/inputs/mangling_definitions.d -c -of=%t-dir/mangling_definitions%obj
// RUN: %ldc %t-dir/mangling_definitions%obj -run %s
module mangling;
// Variables:
extern(C) pragma(mangle, "cGlobal")
extern __gshared int decl_cGlobal;
version(CRuntime_Microsoft)
enum cppGlobalMangle = "?cppGlobal@cpp_vars@@3HA";
else
enum cppGlobalMangle = "_ZN8cpp_vars9cppGlobalE";
extern(C++, decl_cpp_vars) pragma(mangle, cppGlobalMangle)
extern __gshared int decl_cppGlobal;
pragma(mangle, "_D11definitions7dGlobali")
extern __gshared int decl_dGlobal;
// Functions:
extern(C) pragma(mangle, "cFunc")
int decl_cFunc(double a);
version(CRuntime_Microsoft)
enum cppFuncMangle = "?cppFunc@cpp_funcs@@YAHN@Z";
else
enum cppFuncMangle = "_ZN9cpp_funcs7cppFuncEd";
extern(C++, decl_cpp_funcs) pragma(mangle, cppFuncMangle)
int decl_cppFunc(double a);
pragma(mangle, "_D11definitions5dFuncFdZi")
int decl_dFunc(double a);
// Naked functions:
version(D_InlineAsm_X86)
version = AsmX86;
else version(D_InlineAsm_X86_64)
version = AsmX86;
version(AsmX86)
{
extern(C) pragma(mangle, "naked_cFunc")
int decl_naked_cFunc(double a);
version(CRuntime_Microsoft)
enum nakedCppFuncMangle = "?naked_cppFunc@cpp_naked_funcs@@YAHN@Z";
else
enum nakedCppFuncMangle = "_ZN15cpp_naked_funcs13naked_cppFuncEd";
extern(C++, decl_cpp_naked_funcs) pragma(mangle, nakedCppFuncMangle)
int decl_naked_cppFunc(double a);
pragma(mangle, "_D11definitions11naked_dFuncFdZi")
int decl_naked_dFunc(double a);
}
// Interfacing with C via pragma(mangle, …), without having to take care
// of a potential target-specific C prefix (underscore on Win32 and OSX):
extern(C) pragma(mangle, "cos")
double decl_cos(double x);
void main()
{
assert(decl_cGlobal == 1);
assert(decl_cppGlobal == 2);
assert(decl_dGlobal == 3);
assert(decl_cFunc(1.0) == 1);
assert(decl_cppFunc(2.0) == 2);
assert(decl_dFunc(3.0) == 3);
version(AsmX86)
{
decl_naked_cFunc(1.0);
decl_naked_cppFunc(2.0);
decl_naked_dFunc(3.0);
}
assert(decl_cos(0.0) == 1.0);
}
./ldc-1.20.1-src/tests/codegen/indirect_byval_rewrite.d 0000644 0001750 0001750 00000002511 13631266747 023155 0 ustar matthias matthias // Ensures efficient indirect by-value passing via IndirectByvalRewrite.
// REQUIRES: target_X86
// RUN: %ldc -mtriple=x86_64-windows-msvc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
struct Big { size_t a, b; }
struct WithPostblit { Big b; this(this) {} }
Big makeBig() { return Big(123, 456); }
void foo(Big, WithPostblit, Big, WithPostblit);
// CHECK: define {{.*}}_D22indirect_byval_rewrite3bar
void bar()
{
// CHECK: %bigLValue = alloca %indirect_byval_rewrite.Big
Big bigLValue;
// CHECK-NEXT: %withPostblitLValue = alloca %indirect_byval_rewrite.WithPostblit
WithPostblit withPostblitLValue;
// * 1st arg: bigLValue bitcopy, copied by IndirectByvalRewrite
// CHECK-NEXT: %.hidden_copy_for_IndirectByvalRewrite = alloca %indirect_byval_rewrite.Big
// * 2nd arg: temporary withPostblitLValue copy (copied by frontend, incl. postblit)
// CHECK-NEXT: %__copytmp{{[0-9]*}} = alloca %indirect_byval_rewrite.WithPostblit
// * 3rd arg: sret temporary filled by makeBig()
// CHECK-NEXT: %.sret_tmp = alloca %indirect_byval_rewrite.Big
// * 4th arg: WithPostblit() literal
// CHECK-NEXT: %.structliteral = alloca %indirect_byval_rewrite.WithPostblit
foo(bigLValue, withPostblitLValue, makeBig(), WithPostblit());
// no more allocas!
// CHECK-NOT: alloca
// CHECK: ret void
}
./ldc-1.20.1-src/tests/codegen/gh2865.d 0000644 0001750 0001750 00000000374 13631266747 017346 0 ustar matthias matthias // RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
void foo()
{
// CHECK: %1 = getelementptr {{.*}}_D6gh28653fooFZv{{.*}} to i8*), i32 -10
// CHECK-NEXT: %2 = ptrtoint i8* %1 to i{{32|64}}
auto addr = (cast(size_t) &foo) - 10;
}
./ldc-1.20.1-src/tests/codegen/assign_struct_init_without_stack.d 0000644 0001750 0001750 00000010264 13631266747 025305 0 ustar matthias matthias // Tests minimal use of temporaries in non-optimized builds for struct and array assignment.
// Tests `.init` assignment in particular.
// RUN: %ldc -output-ll %s -of=%t.ll && FileCheck %s < %t.ll
void opaque();
FloatStruct opaque(FloatStruct);
FloatStruct opaqueret();
struct FloatStruct {
float[10] data;
}
FloatStruct globalStruct;
// CHECK-LABEL: define{{.*}} @{{.*}}_D32assign_struct_init_without_stack3fooFZv
void foo() {
globalStruct = FloatStruct.init;
// There should be only one memcpy.
// CHECK: call void @llvm.memcpy
// CHECK-NEXT: ret void
}
// CHECK-LABEL: define{{.*}} @{{.*}}_D32assign_struct_init_without_stack3hhhFZv
void hhh() {
globalStruct = FloatStruct([1, 0, 0, 0, 0, 0, 0, 0, 0, 42]);
// Future work: test optimized codegen (at -O0)
}
// CHECK-LABEL: define{{.*}} @{{.*}}_D32assign_struct_init_without_stack3gggFZv
void ggg() {
globalStruct = opaqueret();
// opaque() could be accessing globalStruct, in-place assignment not possible.
// CHECK: sret_tmp = alloca %assign_struct_init_without_stack.FloatStruct
// CHECK: call {{.*}}opaqueret
// CHECK: call void @llvm.memcpy
// CHECK-NEXT: ret void
}
// CHECK-LABEL: define{{.*}} @{{.*}}_D32assign_struct_init_without_stack5localFZv
void local() {
FloatStruct local;
local = opaque(local);
// Not possible to do in-place assignment, so temporary must be created.
// CHECK: local = alloca %assign_struct_init_without_stack.FloatStruct
// CHECK: sret_tmp = alloca %assign_struct_init_without_stack.FloatStruct
// CHECK: call {{.*}}opaque
// CHECK: call void @llvm.memcpy
// CHECK-NEXT: ret void
}
// CHECK-LABEL: define{{.*}} @{{.*}}_D32assign_struct_init_without_stack5arrayFZv
void array() {
int[5] arr = [0,1,2,3,4];
// Future work: test optimized codegen (at -O0)
}
// CHECK-LABEL: define{{.*}} @{{.*}}_D32assign_struct_init_without_stack6array2FKG3iZv
void array2(ref int[3] a) {
a = [4, a[0], 6];
// There should be a temporary!
// CHECK: alloca [3 x i32]
// CHECK: call void @llvm.memcpy
// CHECK-NEXT: ret void
}
struct OpAssignStruct {
float[10] data;
ubyte a;
ref OpAssignStruct opAssign(R)(auto ref R rhs) return {
return this;
}
}
OpAssignStruct globalOpAssignStruct;
OpAssignStruct globalOpAssignStruct2;
// CHECK-LABEL: define{{.*}} @{{.*}}_D32assign_struct_init_without_stack16tupleassignByValFZv
void tupleassignByVal()
{
globalOpAssignStruct = OpAssignStruct.init;
// There should be one memcpy to a temporary.
// 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-NEXT: ret void
}
// CHECK-LABEL: define{{.*}} @{{.*}}_D32assign_struct_init_without_stack16tupleassignByRefFZv
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-NEXT: ret void
}
struct DtorStruct {
float[10] data;
~this() { opaque(); }
}
struct CtorStruct {
float[10] data;
this(int i) { opaque(); }
}
DtorStruct dtorStruct;
CtorStruct ctorStruct;
// CHECK-LABEL: define{{.*}} @{{.*}}_D32assign_struct_init_without_stack4ctorFZv
void ctor() {
ctorStruct = ctorStruct.init;
// There is no dtor, so can be optimized to only a memcpy.
// CHECK-NEXT: call void @llvm.memcpy
// CHECK-NEXT: ret void
}
// CHECK-LABEL: define{{.*}} @{{.*}}_D32assign_struct_init_without_stack4dtorFZv
void dtor() {
dtorStruct = dtorStruct.init;
// There should be a temporary and a call to opAssign
// CHECK: alloca %assign_struct_init_without_stack.DtorStruct
// CHECK: call void @llvm.memcpy{{.*}}_D32assign_struct_init_without_stack10DtorStruct6__initZ
// CHECK-NEXT: call {{.*}}_D32assign_struct_init_without_stack10DtorStruct8opAssignMFNcNjSQCkQBfZQi
// CHECK-NEXT: ret void
}
./ldc-1.20.1-src/tests/codegen/exception_stack_trace.d 0000644 0001750 0001750 00000001647 13631266747 022770 0 ustar matthias matthias // RUN: %ldc -g %disable_fp_elim -link-defaultlib-debug %s -of=%t%exe
// RUN: %t%exe | FileCheck %s
void bar()
{
throw new Exception("lala");
}
void foo()
{
bar();
}
void main()
{
try
{
foo();
}
catch (Exception e)
{
import core.stdc.stdio;
auto s = e.toString();
printf("%.*s\n", s.length, s.ptr);
}
}
// CHECK: object.Exception@{{.*}}exception_stack_trace.d(6): lala
// CHECK-NEXT: ----------------
/* Hiding all frames up to and including the first _d_throw_exception()
* one doesn't work reliably on all platforms, so don't enforce
* CHECK-*NEXT* for the bar() frame.
* On Win32, the bar() frame is missing altogether.
* So be very generous and only check for 2 consecutive lines containing
* 'exception_stack_trace' each (in function name and/or source file).
*/
// CHECK: exception_stack_trace{{.*$}}
// CHECK-NEXT: exception_stack_trace{{.*$}}
./ldc-1.20.1-src/tests/codegen/attr_weak.d 0000644 0001750 0001750 00000001105 13631266747 020375 0 ustar matthias matthias // Test linking+running a program with @weak function
// RUN: %ldc -O3 %S/inputs/attr_weak_input.d -c -of=%t-dir/attr_weak_input%obj
// RUN: %ldc -O3 %t-dir/attr_weak_input%obj %s -of=%t%exe
// RUN: %t%exe
import ldc.attributes;
// Should be overridden by attr_weak_input.d (but only because its object
// file is specified before this one for the linker).
// The @weak attribute prevents the optimizer from making any assumptions
// though, so the call below is not inlined.
extern(C) @weak int return_seven() {
return 1;
}
void main() {
assert( return_seven() == 7 );
}
./ldc-1.20.1-src/tests/codegen/ffastmath.d 0000644 0001750 0001750 00000000545 13631266747 020400 0 ustar matthias matthias // Test -ffast-math
// RUN: %ldc -ffast-math -O0 -release -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
import ldc.attributes;
// CHECK-LABEL: define{{.*}} @foo
// CHECK-SAME: #[[ATTR:[0-9]+]]
extern (C) double foo(double a, double b)
{
// CHECK: fmul fast
return a * b;
}
// CHECK-DAG: attributes #[[ATTR]] ={{.*}} "unsafe-fp-math"="true"
./ldc-1.20.1-src/tests/codegen/inlining_imports_pragma.d 0000644 0001750 0001750 00000002407 13631266747 023335 0 ustar matthias matthias // Test inlining of functions marked with pragma(inline) in an imported module
// O0 and O3 should behave the same for these tests with explicit inlining directives by the user.
// RUN: %ldc %s -I%S -c -output-ll -O0 -of=%t.O0.ll && FileCheck %s --check-prefix OPTNONE < %t.O0.ll
// RUN: %ldc %s -I%S -c -output-ll -O3 -of=%t.O3.ll && FileCheck %s --check-prefix OPT3 < %t.O3.ll
import inputs.inlinables;
extern (C): // simplify mangling for easier matching
// OPTNONE-LABEL: define{{.*}} @call_never_inline(
// OPT3-LABEL: define{{.*}} @call_never_inline(
int call_never_inline()
{
// OPTNONE: call {{.*}} @never_inline()
// OPT3: call {{.*}} @never_inline()
return never_inline();
}
// OPTNONE-DAG: declare {{.*}} @never_inline()
// OPTNONE-LABEL: define{{.*}} @call_always_inline(
// OPT3-LABEL: define{{.*}} @call_always_inline(
int call_always_inline()
{
// OPTNONE-NOT: call {{.*}} @always_inline()
// OPT3-NOT: call {{.*}} @always_inline()
return always_inline();
// OPTNONE: ret
// OPT3: ret
}
// OPTNONE-LABEL: define{{.*}} @call_inline_chain(
// OPT3-LABEL: define{{.*}} @call_inline_chain(
int call_inline_chain()
{
// OPTNONE-NOT: call
// OPT3-NOT: call
return always_inline_chain0();
// OPTNONE: ret
// OPT3: ret
}
./ldc-1.20.1-src/tests/codegen/call_args_evalorder.d 0000644 0001750 0001750 00000001242 13631266747 022410 0 ustar matthias matthias // RUN: %ldc -run %s
void checkInt(int a, int b, int c)
{
assert(a == 1);
assert(b == 2);
assert(c == 3);
}
int incrementBy2AndReturn2(ref int a)
{
a += 2;
return 2;
}
// ---
struct BigStruct
{
long[33] blub;
int v;
this(int v) { this.v = v; }
}
void checkBigStruct(BigStruct a, BigStruct b, BigStruct c)
{
assert(a.v == 1);
assert(b.v == 2);
assert(c.v == 3);
}
BigStruct incrementBy2AndReturn2(ref BigStruct a)
{
a.v += 2;
return BigStruct(2);
}
// ---
void main()
{
int a = 1;
checkInt(a, incrementBy2AndReturn2(a), a);
auto s = BigStruct(1);
checkBigStruct(s, incrementBy2AndReturn2(s), s);
}
./ldc-1.20.1-src/tests/codegen/attributes.d 0000644 0001750 0001750 00000001734 13631266747 020612 0 ustar matthias matthias // Tests LDC-specific attributes
// RUN: %ldc -O -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
import ldc.attributes;
//---- @(section) -----------------------------------------------------
// CHECK-DAG: @{{.*}}mySectionedGlobali{{.*}} section ".mySection"
@(section(".mySection")) int mySectionedGlobal;
// CHECK-DAG: define{{.*}} void @{{.*}}sectionedfoo{{.*}} section "funcSection"
@(section("funcSection")) void sectionedfoo() {}
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//---- @(weak) --------------------------------------------------------
// CHECK-DAG: @{{.*}}myWeakGlobali{{\"?}} = weak
@(ldc.attributes.weak) int myWeakGlobal;
// CHECK-DAG: define{{.*}} weak {{.*}}void @{{.*}}weakFunc
@weak void weakFunc() {}
//---------------------------------------------------------------------
// CHECK-LABEL: define{{.*}} i32 @_Dmain
void main() {
sectionedfoo();
}
./ldc-1.20.1-src/tests/codegen/no_init_symbols_for_zeroinit_structs.d 0000644 0001750 0001750 00000000426 13631266747 026210 0 ustar matthias matthias // RUN: %ldc -output-ll -of=%t.ll %s
// RUN: FileCheck %s < %t.ll
module mod;
// CHECK-NOT: _D3mod5Empty6__initZ
struct Empty {}
// CHECK-NOT: _D3mod7WithInt6__initZ
struct WithInt { int a; }
// CHECK-NOT: _D3mod13WithZeroFloat6__initZ
struct WithZeroFloat { float a = 0; }
./ldc-1.20.1-src/tests/codegen/inlining_templates.d 0000644 0001750 0001750 00000003224 13631266747 022305 0 ustar matthias matthias // Test inlining of templates
// Templates that would otherwise not be codegenned, _should_ be codegenned for inlining when pragma(inline, true) is specified.
// RUN: %ldc %s -I%S -c -output-ll -release -enable-inlining -enable-cross-module-inlining -O0 -of=%t.O0.ll && FileCheck %s < %t.O0.ll
// RUN: %ldc -singleobj %S/inputs/inlinables.d %s -I%S -c -output-ll -release -enable-inlining -enable-cross-module-inlining -O0 -of=%t.singleobj.O0.ll && FileCheck %s < %t.singleobj.O0.ll
// Test linking too.
// Separate compilation
// RUN: %ldc -c -enable-inlining -enable-cross-module-inlining %S/inputs/inlinables.d -of=%t.inlinables%obj \
// RUN: && %ldc -I%S -enable-inlining -enable-cross-module-inlining %t.inlinables%obj %s -of=%t%exe
// Singleobj compilation
// RUN: %ldc -I%S -enable-inlining -enable-cross-module-inlining -singleobj %S/inputs/inlinables.d %s -of=%t2%exe
import inputs.inlinables;
int foo(int i)
{
return call_template_foo(i);
}
// Call a function calling std.exception.enforce with default __FILE__ template parameter.
// Make sure the symbol is inlined/defined and not declared (which will lead to linker errors if the location
// of the stdlib is different from where LDC was built from)
void ggg()
{
call_enforce_with_default_template_params();
}
void main()
{
}
// CHECK-NOT: declare{{.*}}_D6inputs10inlinables__T12template_fooTiZQrUNaNbNiNfiZi
// CHECK-NOT: declare{{.*}}_D3std9exception__T7enforce
// CHECK-DAG: define{{.*}}_D6inputs10inlinables__T12template_fooTiZQrUNaNbNiNfiZi{{.*}}) #[[ATTR:[0-9]+]]
// CHECK-DAG: define{{.*}}_D3std9exception__T7enforce{{.*}}) #[[ATTR]]
// CHECK-DAG: attributes #[[ATTR]] ={{.*}} alwaysinline
./ldc-1.20.1-src/tests/codegen/array_equals_null.d 0000644 0001750 0001750 00000001205 13631266747 022137 0 ustar matthias matthias // Tests that array (in)equality with null is optimized to a length check
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// RUN: %ldc -run %s
// CHECK-LABEL: define{{.*}} @{{.*}}isNull
bool isNull(int[] arg)
{
// CHECK-NOT: call
// CHECK-NOT: invoke
// CHECK: icmp eq i{{32|64}} %.len, 0
return arg == null;
}
// CHECK-LABEL: define{{.*}} @{{.*}}isNotNull
bool isNotNull(int[] arg)
{
// CHECK-NOT: call
// CHECK-NOT: invoke
// CHECK: icmp ne i{{32|64}} %.len, 0
return arg != null;
}
void main()
{
int[3] i3 = [ 0, 1, 2 ];
assert(isNull(i3[0..0]));
assert(isNotNull(i3[0..1]));
}
./ldc-1.20.1-src/tests/codegen/linker_directives_win.d 0000644 0001750 0001750 00000000651 13631266747 023003 0 ustar matthias matthias // RUN: %ldc -mtriple=x86_64-pc-windows-msvc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// REQUIRES: atleast_llvm500, target_X86
// CHECK: !llvm.linker.options = !{!0, !1, !2}
// CHECK: !0 = !{!"/DEFAULTLIB:\22mylib\22"}
pragma(lib, "mylib");
// CHECK: !1 = !{!"-myflag"}
pragma(linkerDirective, "-myflag");
// CHECK: !2 = !{!"-framework", !"CoreFoundation"}
pragma(linkerDirective, "-framework", "CoreFoundation");
./ldc-1.20.1-src/tests/codegen/variadic_thunk_gh2613.d 0000644 0001750 0001750 00000000506 13631266747 022405 0 ustar matthias matthias // RUN: %ldc -run %s
interface Stream
{
void write(...);
}
class OutputStream : Stream
{
void write(...)
{
import core.vararg;
auto arg = va_arg!string(_argptr);
assert(arg == "Hello world");
}
}
void main()
{
Stream stream = new OutputStream;
stream.write("Hello world");
}
./ldc-1.20.1-src/tests/codegen/array_alloc_gh3041.d 0000644 0001750 0001750 00000000571 13631266747 021700 0 ustar matthias matthias // RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// CHECK-LABEL: define{{.*}} @{{.*}}3foo
void[] foo()
{
// CHECK-NEXT: %.gc_mem = call {{.*}} @_d_newarrayT
// CHECK-NEXT: %.ptr = extractvalue {{.*}} %.gc_mem, 1
// CHECK-NEXT: %1 = insertvalue {{.*}} { i{{32|64}} 3, i8* undef }, i8* %.ptr, 1
// CHECK-NEXT: ret {{.*}} %1
return new void[3];
}
./ldc-1.20.1-src/tests/codegen/attr_allocsize.d 0000644 0001750 0001750 00000002301 13631266747 021432 0 ustar matthias matthias // Test ldc.attributes.allocSize
// RUN: %ldc -O3 -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
import ldc.attributes;
// CHECK-LABEL: define{{.*}}@{{.*}}my_calloc
// CHECK-SAME: #[[ATTR0:[0-9]+]]
extern (C) void* my_calloc(size_t num, size_t size) @allocSize(1, 0)
{
return null;
}
// CHECK-LABEL: define{{.*}}@{{.*}}my_malloc
// CHECK-SAME: #[[ATTR1:[0-9]+]]
extern (C) void* my_malloc(int a, int b, size_t size, int c) @allocSize(2)
{
return null;
}
// Test the reversed parameter order of D calling convention
// CHECK-LABEL: define{{.*}}@{{.*}}Dlinkage_calloc
// CHECK-SAME: #[[ATTR2:[0-9]+]]
extern (D) void* Dlinkage_calloc(int size, int b, size_t num, int c) @allocSize(0, 2)
{
return null;
}
// Test function type with hidden `this` argument
class A
{
// CHECK-LABEL: define{{.*}}@{{.*}}this_calloc
// CHECK-SAME: #[[ATTR3:[0-9]+]]
void* this_calloc(int size, int b, size_t num, int c) @allocSize(0, 2)
{
return null;
}
}
// CHECK-DAG: attributes #[[ATTR0]] ={{.*}} allocsize(1,0)
// CHECK-DAG: attributes #[[ATTR1]] ={{.*}} allocsize(2)
// CHECK-DAG: attributes #[[ATTR2]] ={{.*}} allocsize(3,1)
// CHECK-DAG: attributes #[[ATTR3]] ={{.*}} allocsize(4,2)
./ldc-1.20.1-src/tests/codegen/switch_ICE_gh1638.d 0000644 0001750 0001750 00000000470 13631266747 021401 0 ustar matthias matthias // Test for ICE bug Github issue 1638
// Don't make any changes/additions to this file without consulting GH #1638 first.
// RUN: %ldc -I%S %S/inputs/switch_ICE_gh1638_bar.d %s -c
// RUN: %ldc -I%S %s %S/inputs/switch_ICE_gh1638_bar.d -c
import switch_ICE_gh1638_bar;
int main()
{
return T().fun(123);
}
./ldc-1.20.1-src/tests/codegen/const_struct.d 0000644 0001750 0001750 00000003544 13631266747 021157 0 ustar matthias matthias // RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// RUN: %ldc -run %s
struct S0 { uint x; }
struct S1 { S0 y; this(this) { y.x = 1; } }
struct S2 { S1[3] z; }
struct C0 { int *x; }
void testNested() {
int x;
// The 'x' here is accessed via the nested context pointer
struct N1 { ~this() { ++x; } }
struct N0 { N1[3] x; }
{ N0 n; }
assert(x == 3);
}
// CHECK: @.immutablearray{{.*}} = internal constant [4 x i32]
// CHECK: @.immutablearray{{.*}} = internal constant [2 x float]
// CHECK: @.immutablearray{{.*}} = internal constant [2 x double]
// CHECK: @.immutablearray{{.*}} = internal constant [2 x { i{{32|64}}, i8* }]
// CHECK: @.immutablearray{{.*}} = internal constant [1 x %const_struct.S2]
// CHECK: @.immutablearray{{.*}} = internal constant [2 x i32*] {{.*}}globVar
// CHECK: @.immutablearray{{.*}} = internal constant [2 x void ()*] {{.*}}Dmain
void main () {
// Simple types
immutable int[] aA = [ 1, 2, 3, 4 ];
immutable float[] aB = [ 3.14, 3.33 ];
immutable double[] aC = [ 3.14, 3.33 ];
immutable string[] aD = [ "one", "two" ];
// Complex type
immutable S2[] aE = [ { [ { { 42 } }, { { 43 } }, { { 44 } } ] } ];
// Complex type with non-constant initializer
// CHECK: %.gc_mem = call { i{{32|64}}, i8* } @_d_newarrayU
// CHECK-SAME: @{{.*}}_D29TypeInfo_yAS12const_struct2C06__initZ
immutable C0[] aF = [ { new int(42) }, { new int(24) } ];
// Pointer types
static immutable int globVar;
immutable auto globalVariables = [ &globVar, &globVar ];
immutable auto functionPointers = [ &main, &main ];
// Pointer arrays with non-const initializer
immutable int localVar;
immutable auto locA = [ &localVar, &localVar ];
// CHECK: %.gc_mem{{.*}} = call { i{{32|64}}, i8* } @_d_newarrayU
// CHECK-SAME: @{{.*}}_D13TypeInfo_yAPi6__initZ
testNested();
}
./ldc-1.20.1-src/tests/codegen/inbounds.d 0000644 0001750 0001750 00000003523 13631266747 020243 0 ustar matthias matthias // RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
struct S {
float x, y;
};
extern(C): // Avoid name mangling
// IndexExp in static array with const exp
// CHECK-LABEL: @foo1
int foo1(int[3] a) {
// CHECK: getelementptr inbounds [3 x i32]
return a[1];
}
// IndexExp in static array with variable exp
// CHECK-LABEL: @foo2
int foo2(int[3] a, int i) {
// CHECK: getelementptr inbounds [3 x i32]
return a[i];
}
// IndexExp in pointer
// CHECK-LABEL: @foo3
int foo3(int* p, int i) {
// CHECK: getelementptr inbounds
return p[i];
}
// PostExp in pointer
// CHECK-LABEL: @foo4
int foo4(int* p) {
// CHECK: getelementptr inbounds
return *p++;
}
// PreExp in pointer
// CHECK-LABEL: @foo5
int foo5(int* p) {
// CHECK: getelementptr inbounds
return *++p;
}
// Add offset to pointer
// CHECK-LABEL: @foo6
int foo6(int* p, int i) {
// CHECK: getelementptr inbounds
return *(p + i);
}
// Subtract offset from pointer
// CHECK-LABEL: @foo7
int foo7(int* p, int i) {
// CHECK: getelementptr inbounds
return *(p - i);
}
// Struct field
// CHECK-LABEL: @foo8
float foo8(S s) {
// CHECK: getelementptr inbounds
return s.y;
}
// IndexExp in dynamic array with const exp
// CHECK-LABEL: @foo9
int foo9(int[] a) {
// CHECK: getelementptr inbounds i32, i32*
return a[1];
}
// IndexExp in dynamic array with variable exp
// CHECK-LABEL: @foo10
int foo10(int[] a, int i) {
// CHECK: getelementptr inbounds i32, i32*
return a[i];
}
// SliceExp for static array with const lower bound
// CHECK-LABEL: @foo11
int[] foo11(ref int[3] a) {
// CHECK: getelementptr inbounds i32, i32*
return a[1 .. $];
}
// SliceExp for dynamic array with variable lower bound
// CHECK-LABEL: @foo12
int[] foo12(int[] a, int i) {
// CHECK: getelementptr inbounds i32, i32*
return a[i .. $];
}
./ldc-1.20.1-src/tests/codegen/attr_optstrat.d 0000644 0001750 0001750 00000002525 13631266747 021335 0 ustar matthias matthias // RUN: %ldc -I%S -c -output-ll -O3 -of=%t.ll %s && FileCheck %s < %t.ll
import ldc.attributes;
extern (C): // For easier name mangling
int glob1;
int easily_inlinable(int i)
{
glob1 = i;
return 2;
}
// CHECK-LABEL: define{{.*}} @call_easily_inlinable(
// CHECK-SAME: #[[OPTNONE:[0-9]+]]
@optStrategy("none")
int call_easily_inlinable(int i)
{
// CHECK: call {{.*}} @easily_inlinable(
return easily_inlinable(i);
}
pragma(inline, true) int always_inline()
{
return 321;
}
// CHECK-LABEL: define{{.*}} @call_always_inline(
@optStrategy("none")
int call_always_inline()
{
// CHECK-NOT: call {{.*}} @always_inline()
return always_inline();
// CHECK: ret i32 321
}
// optnone functions should not be inlined.
int glob2;
@optStrategy("none") void optnone_function(int i)
{
glob2 = i;
}
// CHECK-LABEL: define{{.*}} @call_optnone(
void call_optnone()
{
// CHECK: call {{.*}} @optnone_function
optnone_function(1);
}
// CHECK-LABEL: define{{.*}} @foo(
// CHECK-SAME: #[[OPTSIZE:[0-9]+]]
@optStrategy("optsize")
void foo()
{
}
// CHECK-LABEL: define{{.*}} @foo2(
// CHECK-SAME: #[[MINSIZE:[0-9]+]]
@optStrategy("minsize")
void foo2()
{
}
// CHECK-DAG: attributes #[[OPTNONE]] = {{.*}} noinline {{.*}} optnone
// CHECK-DAG: attributes #[[OPTSIZE]] = {{.*}} optsize
// CHECK-DAG: attributes #[[MINSIZE]] = {{.*}} minsize
./ldc-1.20.1-src/tests/codegen/gh3094.d 0000644 0001750 0001750 00000000247 13631266747 017340 0 ustar matthias matthias // RUN: %ldc -run %s
void foo(void delegate() sink)
{
return (0, sink());
}
void main()
{
bool called;
foo(() { called = true; });
assert(called);
}
./ldc-1.20.1-src/tests/codegen/inputs/ 0000755 0001750 0001750 00000000000 13631266747 017574 5 ustar matthias matthias ./ldc-1.20.1-src/tests/codegen/inputs/foo.d 0000644 0001750 0001750 00000000016 13631266747 020521 0 ustar matthias matthias void bar() {}
./ldc-1.20.1-src/tests/codegen/inputs/export2.d 0000644 0001750 0001750 00000000041 13631266747 021337 0 ustar matthias matthias export int foo() { return 666; }
./ldc-1.20.1-src/tests/codegen/inputs/kernel.d 0000644 0001750 0001750 00000000142 13631266747 021216 0 ustar matthias matthias @compute(CompileFor.deviceOnly)
module inputs.kernel;
import ldc.dcompute;
@kernel void foo() {}
./ldc-1.20.1-src/tests/codegen/inputs/mangling_definitions.d 0000644 0001750 0001750 00000003064 13631266747 024133 0 ustar matthias matthias module definitions;
// variables:
extern(C) __gshared int cGlobal = 1;
static assert(cGlobal.mangleof == "cGlobal");
extern(C++, cpp_vars) __gshared int cppGlobal = 2;
version(CRuntime_Microsoft)
static assert(cppGlobal.mangleof == "?cppGlobal@cpp_vars@@3HA");
else
static assert(cppGlobal.mangleof == "_ZN8cpp_vars9cppGlobalE");
__gshared int dGlobal = 3;
static assert(dGlobal.mangleof == "_D11definitions7dGlobali");
// functions:
extern(C) int cFunc(double a) { return cGlobal; }
static assert(cFunc.mangleof == "cFunc");
extern(C++, cpp_funcs) int cppFunc(double a) { return cppGlobal; }
version(CRuntime_Microsoft)
static assert(cppFunc.mangleof == "?cppFunc@cpp_funcs@@YAHN@Z");
else
static assert(cppFunc.mangleof == "_ZN9cpp_funcs7cppFuncEd");
int dFunc(double a) { return dGlobal; }
static assert(dFunc.mangleof == "_D11definitions5dFuncFdZi");
// naked functions:
version(D_InlineAsm_X86)
version = AsmX86;
else version(D_InlineAsm_X86_64)
version = AsmX86;
version(AsmX86)
{
extern(C) int naked_cFunc(double a) { asm { naked; ret; } }
static assert(naked_cFunc.mangleof == "naked_cFunc");
extern(C++, cpp_naked_funcs) int naked_cppFunc(double a) { asm { naked; ret; } }
version(CRuntime_Microsoft)
static assert(naked_cppFunc.mangleof == "?naked_cppFunc@cpp_naked_funcs@@YAHN@Z");
else
static assert(naked_cppFunc.mangleof == "_ZN15cpp_naked_funcs13naked_cppFuncEd");
int naked_dFunc(double a) { asm { naked; ret; } }
static assert(naked_dFunc.mangleof == "_D11definitions11naked_dFuncFdZi");
}
./ldc-1.20.1-src/tests/codegen/inputs/inlinables_staticvar.d 0000644 0001750 0001750 00000004005 13631266747 024140 0 ustar matthias matthias module inputs.inlinables_staticvar;
/+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
private int atModuleScope;
pragma(inline, true) void addToModuleScopeInline(int i)
{
atModuleScope += i;
}
pragma(inline, false) void addToModuleScopeOutline(int i)
{
atModuleScope += i;
}
pragma(inline, false) bool equalModuleScope(int i)
{
return atModuleScope == i;
}
/+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
pragma(inline, true) bool addAndCheckInsideFunc(int checkbefore, int increment)
{
static int insideFunc;
if (insideFunc != checkbefore)
return false;
insideFunc += increment;
return true;
}
pragma(inline, false) bool addAndCheckInsideFuncIndirect(int checkbefore, int increment)
{
return addAndCheckInsideFunc(checkbefore, increment);
}
/+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
pragma(inline, true) bool addAndCheckInsideNestedFunc(int checkbefore, int increment)
{
pragma(inline, true)
bool addCheckNested(int checkbefore, int increment)
{
static int insideFunc;
if (insideFunc != checkbefore)
return false;
insideFunc += increment;
return true;
}
return addCheckNested(checkbefore, increment);
}
pragma(inline, false) bool addAndCheckInsideNestedFuncIndirect(int checkbefore, int increment)
{
return addAndCheckInsideNestedFunc(checkbefore, increment);
}
/+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
pragma(inline, true) bool addAndCheckNestedStruct(int checkbefore, int increment)
{
struct NestedStruct
{
static int structValue;
}
if (NestedStruct.structValue != checkbefore)
return false;
NestedStruct.structValue += increment;
return true;
}
pragma(inline, false) bool addAndCheckNestedStructIndirect(int checkbefore, int increment)
{
return addAndCheckNestedStruct(checkbefore, increment);
}
/+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/
./ldc-1.20.1-src/tests/codegen/inputs/attr_weak_input.d 0000644 0001750 0001750 00000000055 13631266747 023141 0 ustar matthias matthias extern(C) int return_seven() {
return 7;
}
./ldc-1.20.1-src/tests/codegen/inputs/switch_ICE_gh1638_bar.d 0000644 0001750 0001750 00000000617 13631266747 023552 0 ustar matthias matthias // Don't make any changes/additions to this file without consulting Github issue 1638 first.
module switch_ICE_gh1638_bar;
struct S(T)
{
auto fun = (T a) {
T r;
switch (a)
{
case 1:
r = 1;
break;
default:
return 0;
}
return r * 2;
};
}
alias T = S!int;
void f(int a)
{
int r = T().fun(a);
}
./ldc-1.20.1-src/tests/codegen/inputs/module_ctor.d 0000644 0001750 0001750 00000000077 13631266747 022261 0 ustar matthias matthias import core.stdc.stdio;
static this()
{
puts("ctor\n");
}
./ldc-1.20.1-src/tests/codegen/inputs/attr_weak_external_input.d 0000644 0001750 0001750 00000000220 13631266747 025035 0 ustar matthias matthias import ldc.attributes;
extern(C) @weak int weak_definition_four() {
return 4;
}
extern(C) @weak int weak_definition_seven() {
return 7;
}
./ldc-1.20.1-src/tests/codegen/inputs/inlinables.d 0000644 0001750 0001750 00000003271 13631266747 022064 0 ustar matthias matthias module inputs.inlinables;
import ldc.attributes;
extern (C): // simplify mangling for easier function name matching
int easily_inlinable(int i)
{
if (i > 0)
return easily_inlinable(i - 1);
return 2;
}
pragma(inline, false) int never_inline()
{
return 1;
}
@weak int external()
{
return 1;
}
pragma(inline, true) int always_inline()
{
int a;
foreach (i; 1 .. 10)
{
foreach (ii; 1 .. 10)
{
foreach (iii; 1 .. 10)
{
a += i * external();
}
}
}
return a;
}
pragma(inline, true) int always_inline_chain0()
{
return always_inline_chain1();
}
pragma(inline, true) int always_inline_chain1()
{
return always_inline_chain2();
}
pragma(inline, true) int always_inline_chain2()
{
return 345;
}
class A
{
int virtual_func()
{
return 12345;
}
pragma(inline, true) final int final_func()
{
return virtual_func();
}
final int final_class_function()
{
return 12345;
}
}
// Weak-linkage functions can not be inlined.
@weak int weak_function()
{
return 654;
}
int module_variable = 666;
pragma(inline, true) void write_module_variable(int i)
{
module_variable = i;
}
pragma(inline, true) void write_function_static_variable(int i)
{
static int static_func_var = 5;
static_func_var = i;
}
pragma(inline, true) auto get_typeid_A()
{
return typeid(A);
}
pragma(inline, true) int call_template_foo(int i)
{
return template_foo(i);
}
pragma(inline, true) T template_foo(T)(T i)
{
return i;
}
void call_enforce_with_default_template_params()
{
import std.exception;
enforce(true, { assert(0); });
}
./ldc-1.20.1-src/tests/codegen/inputs/export_marked_symbols_lib.d 0000644 0001750 0001750 00000000306 13631266747 025202 0 ustar matthias matthias extern(C++): // so that we can manually declare the symbols in another module too
export __gshared int exportedGlobal;
__gshared int normalGlobal;
export void exportedFoo() {}
void normalFoo() {}
./ldc-1.20.1-src/tests/codegen/inputs/input_discard_valuename.d 0000644 0001750 0001750 00000000444 13631266747 024630 0 ustar matthias matthias // CHECK-LABEL: define{{.*}} @bar(
extern(C) void bar()
{
// CHECK: localbarvar
int localbarvar;
}
// Make sure we can use inline IR in non-textual IR compiles:
double inlineIR(double a)
{
import ldc.llvmasm: __ir;
auto s = __ir!(`ret double %0`, double)(a);
return s;
}
./ldc-1.20.1-src/tests/codegen/inputs/inlinables_asm.d 0000644 0001750 0001750 00000000370 13631266747 022721 0 ustar matthias matthias module inputs.inlinables_asm;
import ldc.attributes;
extern (C): // simplify mangling for easier function name matching
pragma(inline, true) extern (C) void naked_asm_func()
{
asm pure nothrow @nogc
{
naked;
nop;
}
}
./ldc-1.20.1-src/tests/codegen/asm_output.d 0000644 0001750 0001750 00000000512 13631266747 020615 0 ustar matthias matthias // RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s --check-prefix LLVM < %t.ll
// RUN: %ldc -c -output-s -of=%t.s %s && FileCheck %s --check-prefix ASM < %t.s
// Try to keep these very simple checks independent of architecture.
// ASM: foofoofoofoo:
extern(C) int foofoofoofoo() {
// LLVM: ret i32 42
return 42;
}
./ldc-1.20.1-src/tests/codegen/func_contracts_gh1543.d 0000644 0001750 0001750 00000002237 13631266747 022431 0 ustar matthias matthias // Test the combination of `out` arguments with in- and out-contracts.
// Github issue #1543, https://github.com/ldc-developers/ldc/issues/1543
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// RUN: %ldc -run %s
module mod;
class Bar
{
void failMe(out int some)
in
{
assert(some == 0);
}
out
{
assert(some == 123);
}
body
{
some = 123;
}
}
// Bar.failMe codegen order = function, in-contract __require function, out-contract __ensure function
// CHECK-LABEL: define {{.*}} @{{.*}}Bar6failMe
// CHECK-SAME: i32* dereferenceable(4) %some
// CHECK: store i32 0, i32* %some
// CHECK: call {{.*}} @{{.*}}Bar6failMeMFJiZ9__require
// CHECK: call {{.*}} @{{.*}}Bar6failMeMFJiZ8__ensure
// CHECK: }
// CHECK-LABEL: define {{.*}} @{{.*}}Bar6failMeMFJiZ9__require
// CHECK-SAME: i32* dereferenceable(4) %some
// CHECK-NOT: store {{.*}} %some
// CHECK: }
// CHECK-LABEL: define {{.*}} @{{.*}}Bar6failMeMFJiZ8__ensure
// CHECK-SAME: i32* dereferenceable(4) %some
// CHECK-NOT: store {{.*}} %some
// CHECK: }
void main()
{
int some;
auto b = new Bar;
b.failMe(some);
assert(some == 123);
}
./ldc-1.20.1-src/tests/codegen/attr_weak_lto.d 0000644 0001750 0001750 00000001204 13631266747 021253 0 ustar matthias matthias // Test importing a @weak function with LTO
// REQUIRES: LTO
// RUN: %ldc -c %S/inputs/attr_weak_external_input.d -of=%t.thin%obj -flto=thin
// RUN: %ldc -I%S -of=%t.thin%exe -flto=thin %s %t.thin%obj
// RUN: %t.thin%exe
// RUN: %ldc -c %S/inputs/attr_weak_external_input.d -of=%t.full%obj -flto=full
// RUN: %ldc -I%S -of=%t.full%exe -flto=full %s %t.full%obj
// RUN: %t.full%exe
import inputs.attr_weak_external_input: weak_definition_seven;
// Forward declaration intentionally without `@weak`
extern(C) int weak_definition_four();
void main()
{
assert(&weak_definition_four != null);
assert(&weak_definition_seven != null);
}
./ldc-1.20.1-src/tests/codegen/output_s_affect_codegen.d 0000644 0001750 0001750 00000001042 13631266747 023272 0 ustar matthias matthias
// Check object files are identical regardless -output-s option
// RUN: %ldc -c -O3 -output-s -output-o -of=%t1.o %s && %ldc -c -O3 -output-o -of=%t2.o %s && %diff_binary %t1.o %t2.o
import core.simd;
import ldc.simd;
alias Vec = Vector!(float[4]);
extern void foo(float*);
// Just some random sufficiently complex code
Vec bar(Vec v)
{
float[4] val;
Vec ret;
storeUnaligned!Vec(v,val.ptr);
foo(val.ptr);
ret = loadUnaligned!Vec(val.ptr);
return ret;
}
Vec baz(Vec v)
{
return bar(bar(bar(bar(bar(bar(v))))));
}
./ldc-1.20.1-src/tests/codegen/gh3208.d 0000644 0001750 0001750 00000000643 13631266747 017335 0 ustar matthias matthias // older LLVM versions fail the test for longer vectors
// REQUIRES: atleast_llvm700
// RUN: %ldc -run %s
void test(int length)()
{
__vector(byte[length]) a = 123, b = a;
assert(a == b && !(a != b));
assert(a is b && !(a !is b));
b[0] = 0;
assert(a != b && !(a == b));
assert(a !is b && !(a is b));
}
void main()
{
static foreach (length; [16, 32, 64, 128, 256])
test!length();
}
./ldc-1.20.1-src/tests/codegen/align.d 0000644 0001750 0001750 00000006311 13631266747 017512 0 ustar matthias matthias // RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// Fails on Windows_x86, see https://github.com/ldc-developers/ldc/issues/1356
// XFAIL: Windows_x86
align(32) struct Outer { int a = 1; }
// CHECK-DAG: _D5align5Outer6__initZ = constant %align.Outer {{.*}}, align 32
struct Inner { align(32) int a = 1; }
// CHECK-DAG: _D5align5Inner6__initZ = constant %align.Inner {{.*}}, align 32
align(1) ubyte globalByte1;
// CHECK-DAG: _D5align11globalByte1h = {{.*}} align 1
static Outer globalOuter;
// CHECK-DAG: _D5align11globalOuterSQu5Outer = {{.*}} align 32
static Inner globalInner;
// CHECK-DAG: _D5align11globalInnerSQu5Inner = {{.*}} align 32
Outer passAndReturnOuterByVal(Outer arg) { return arg; }
// CHECK: define{{.*}} void @{{.*}}_D5align23passAndReturnOuterByValFSQBh5OuterZQl
/* the 32-bit x86 ABI substitutes the sret attribute by inreg */
// CHECK-SAME: %align.Outer* {{noalias sret|inreg noalias}} align 32 %.sret_arg
/* How the arg is passed by value is ABI-specific, but the pointer must be aligned.
* When the argument is passed as a byte array and copied into a stack alloc, that stack alloca must be aligned. */
// CHECK: {{(align 32 %arg|%arg = alloca %align.Outer, align 32)}}
Inner passAndReturnInnerByVal(Inner arg) { return arg; }
// CHECK: define{{.*}} void @{{.*}}_D5align23passAndReturnInnerByValFSQBh5InnerZQl
// CHECK-SAME: %align.Inner* {{noalias sret|inreg noalias}} align 32 %.sret_arg
// CHECK: {{(align 32 %arg|%arg = alloca %align.Inner, align 32)}}
void main() {
Outer outer;
// CHECK: %outer = alloca %align.Outer, align 32
Inner inner;
// CHECK: %inner = alloca %align.Inner, align 32
align(1) byte byte1;
// CHECK: %byte1 = alloca i8, align 1
align(16) byte byte16;
// CHECK: %byte16 = alloca i8, align 16
align(64) Outer outer64;
// CHECK: %outer64 = alloca %align.Outer, align 64
align(128) Inner inner128;
// CHECK: %inner128 = alloca %align.Inner, align 128
alias Byte8 = align(8) byte;
Byte8 byte8;
// Can aliases contain align(x) ?
// C HECK: %byte8 = alloca i8, align 8
// C HECK: %byte8 = alloca i8, align 1
align(16) Outer outeroverride;
// Yet undecided if align() should override type alignment:
// C HECK: %outeroverride = alloca %align.Outer, align 16
// C HECK: %outeroverride = alloca %align.Outer, align 32
// CHECK: %.sret_tmp{{.*}} = alloca %align.Outer, align 32
// CHECK: %.sret_tmp{{.*}} = alloca %align.Inner, align 32
outer = passAndReturnOuterByVal(outer);
// CHECK: call{{.*}} void @{{.*}}_D5align23passAndReturnOuterByValFSQBh5OuterZQl
// CHECK-SAME: %align.Outer* {{noalias sret|inreg noalias}} align 32 %.sret_tmp
// The argument is either passed by aligned (optimizer hint) pointer or as an array of i32/64 and copied into an aligned stack slot inside the callee.
// CHECK-SAME: {{(align 32 %|\[[0-9]+ x i..\])}}
inner = passAndReturnInnerByVal(inner);
// CHECK: call{{.*}} void @{{.*}}_D5align23passAndReturnInnerByValFSQBh5InnerZQl
// CHECK-SAME: %align.Inner* {{noalias sret|inreg noalias}} align 32 %.sret_tmp
// The argument is either passed by aligned (optimizer hint) pointer or as an array of i32/64 and copied into an aligned stack slot inside the callee.
// CHECK-SAME: {{(align 32 %|\[[0-9]+ x i..\])}}
}
./ldc-1.20.1-src/tests/runlit.py 0000755 0001750 0001750 00000001047 13631266747 016542 0 ustar matthias matthias #!/usr/bin/env python
# wrapper to run lit from commandline
from __future__ import print_function
if __name__=='__main__':
try:
import lit
except ImportError:
import sys
sys.exit('Package lit cannot be imported.\n' \
'Lit can be installed using: \'python -m pip install lit\'\n' \
'(Python versions older than 2.7.9 or 3.4 do not have pip installed, see:\n' \
'https://pip.pypa.io/en/latest/installing/)')
print("Lit version: ", lit.__version__)
lit.main()
./ldc-1.20.1-src/tests/semantic/ 0000755 0001750 0001750 00000000000 13631266747 016451 5 ustar matthias matthias ./ldc-1.20.1-src/tests/semantic/target_traits_diag.d 0000644 0001750 0001750 00000001543 13631266747 022461 0 ustar matthias matthias // Tests diagnostics of __traits(targetCPU) and __traits(targetHasFeature, ...)
// RUN: not %ldc -c -w %s 2>&1 | FileCheck %s
void main()
{
// CHECK: Warning: ignoring arguments for __traits targetCPU
enum a = __traits(targetCPU, 1);
// CHECK: Error: __traits targetHasFeature expects one argument, not 0
enum b = __traits(targetHasFeature);
// CHECK: Error: __traits targetHasFeature expects one argument, not 2
enum c = __traits(targetHasFeature, "fma", 1);
// CHECK: Error: expression expected as argument of __traits targetHasFeature
enum d = __traits(targetHasFeature, main);
// CHECK: Error: string expected as argument of __traits targetHasFeature instead of 1
enum e = __traits(targetHasFeature, 1);
// CHECK: 夜畔' is not a recognized feature for this target (ignoring feature)
enum f = __traits(targetHasFeature, "夜畔");
}
./ldc-1.20.1-src/tests/semantic/target_traits.d 0000644 0001750 0001750 00000004673 13631266747 021504 0 ustar matthias matthias // Tests LDC-specific target __traits
// REQUIRES: target_X86
// RUN: %ldc -mtriple=x86_64-apple-darwin -mcpu=nehalem -d-version=CPU_NEHALEM -c %s
// RUN: %ldc -mtriple=i686-pc-linux -mcpu=pentium -mattr=+fma -d-version=ATTR_FMA -c %s
// RUN: %ldc -mtriple=i686-pc-linux -mcpu=pentium -mattr=+fma,-sse -d-version=ATTR_FMA_MINUS_SSE -c %s
// RUN: %ldc -mtriple=x86_64-apple-darwin -mcpu=haswell -d-version=CPU_HASWELL -c %s
// Important: LLVM's default CPU selection already enables some features (like sse3)
void main()
{
version (CPU_NEHALEM)
{
static assert(__traits(targetCPU) == "nehalem");
static assert(__traits(targetHasFeature, "sse3"));
static assert(__traits(targetHasFeature, "sse4.1"));
static assert(!__traits(targetHasFeature, "avx"));
static assert(!__traits(targetHasFeature, "sse4"));
static assert(!__traits(targetHasFeature, "sse4a"));
static assert(!__traits(targetHasFeature, "unrecognized feature"));
version(D_AVX) static assert(false);
version(D_AVX2) static assert(false);
}
version (ATTR_FMA)
{
static assert(__traits(targetHasFeature, "sse"));
static assert(__traits(targetHasFeature, "sse2"));
static assert(__traits(targetHasFeature, "sse3"));
static assert(__traits(targetHasFeature, "sse4.1"));
static assert(__traits(targetHasFeature, "fma"));
static assert(__traits(targetHasFeature, "avx"));
static assert(!__traits(targetHasFeature, "avx2"));
static assert(!__traits(targetHasFeature, "unrecognized feature"));
version(D_AVX) {} else static assert(false);
version(D_AVX2) static assert(false);
}
version (ATTR_FMA_MINUS_SSE)
{
// All implied features must be enabled for targetHasFeature to return true
static assert(!__traits(targetHasFeature, "fma"));
version(D_AVX) static assert(false);
version(D_AVX2) static assert(false);
}
version (CPU_HASWELL)
{
static assert(__traits(targetHasFeature, "sse"));
static assert(__traits(targetHasFeature, "sse2"));
static assert(__traits(targetHasFeature, "sse3"));
static assert(__traits(targetHasFeature, "sse4.1"));
static assert(__traits(targetHasFeature, "avx"));
static assert(__traits(targetHasFeature, "avx2"));
version(D_AVX) {} else static assert(false);
version(D_AVX2) {} else static assert(false);
}
}
./ldc-1.20.1-src/tests/semantic/dcompute_asm.d 0000644 0001750 0001750 00000000677 13631266747 021310 0 ustar matthias matthias // Test that the "asm" statement is not allowed for DCompute code.
// "asm" is only allowed for X86, so we must explicitly target X86 in this test.
// REQUIRES: target_X86
// RUN: not %ldc -mtriple=x86_64-linux-gnu -o- %s 2>&1 | FileCheck %s
@compute(CompileFor.deviceOnly) module tests.semaintic.dcompute;
import ldc.dcompute;
void func()
{
//CHECK: dcompute_asm.d([[@LINE+1]]): Error: asm not allowed in `@compute` code
asm {ret;}
}
./ldc-1.20.1-src/tests/semantic/dcompute.d 0000644 0001750 0001750 00000005627 13631266747 020450 0 ustar matthias matthias // RUN: not %ldc -o- -verrors=0 -I%S %s 2>&1 | FileCheck %s
@compute(CompileFor.deviceOnly) module tests.semaintic.dcompute;
import ldc.dcompute;
import inputs.notatcompute : somefunc;
extern(C) bool perhaps();
//CHECK: dcompute.d([[@LINE+1]]): Error: {{.*}} interfaces and classes not allowed in `@compute` code
interface I {}
//CHECK: dcompute.d([[@LINE+1]]): Error: {{.*}} interfaces and classes not allowed in `@compute` code
class C : Throwable { this() { super(""); } }
//CHECK: dcompute.d([[@LINE+1]]): Error: {{.*}} global variables not allowed in `@compute` code
C c;
void func()
{
//CHECK: dcompute.d([[@LINE+1]]): Error: {{.*}} associative arrays not allowed in `@compute` code
int[int] foo;
//CHECK: dcompute.d([[@LINE+1]]): Error: array literal in `@compute` code not allowed
auto bar = [0, 1, 2];
//CHECK: dcompute.d([[@LINE+1]]): Error: cannot use `new` in `@compute` code
auto baz = new int;
//CHECK: dcompute.d([[@LINE+1]]): Error: cannot use `delete` in `@compute` code
delete baz;
//CHECK: dcompute.d([[@LINE+1]]): Error: {{.*}} interfaces and classes not allowed in `@compute` code
I i;
//CHECK: dcompute.d([[@LINE+1]]): Error: {{.*}} interfaces and classes not allowed in `@compute` code
C cc;
int[] quux;
//CHECK: dcompute.d([[@LINE+1]]): Error: can only call functions from other `@compute` modules in `@compute` code
quux.length = 1;
//CHECK: dcompute.d([[@LINE+1]]): Error: cannot use operator `~=` in `@compute` code
quux ~= 42;
//CHECK: dcompute.d([[@LINE+1]]): Error: cannot use operator `~` in `@compute` code
cast(void) (quux ~ 1);
//CHECK: dcompute.d([[@LINE+1]]): Error: typeinfo not available in `@compute` code
cast(void) typeid(int);
//CHECK: dcompute.d([[@LINE+1]]): Error: cannot use `synchronized` in `@compute` code
synchronized {}
//CHECK: dcompute.d([[@LINE+1]]): Error: string literals not allowed in `@compute` code
auto s = "geaxsese";
//CHECK: dcompute.d([[@LINE+1]]): Error: cannot `switch` on strings in `@compute` code
switch(s)
{
default:
break;
}
//CHECK: dcompute.d([[@LINE+1]]): Error: can only call functions from other `@compute` modules in `@compute` code
somefunc();
if (__dcompute_reflect(ReflectTarget.Host,0))
//CHECK-NOT: Error:
somefunc();
//CHECK: dcompute.d([[@LINE+1]]): Error: no exceptions in `@compute` code
try
{
func1();
}
catch(C c)
{
}
if (perhaps())
//CHECK: dcompute.d([[@LINE+1]]): Error: no exceptions in `@compute` code
throw c;
//CHECK-NOT: Error:
try
{
func1();
}
finally
{
func2();
}
//CHECK-NOT: Error:
scope(exit)
func2();
}
void func1() {}
void func2() {}
//CHECK: dcompute.d([[@LINE+1]]): Error: pragma `lib` linking additional libraries not supported in `@compute` code
pragma(lib, "bar");
./ldc-1.20.1-src/tests/semantic/target_traits_dcompute.d 0000644 0001750 0001750 00000000452 13631266747 023373 0 ustar matthias matthias // Tests LDC-specific target __traits
// RUN: %ldc -c %s -mdcompute-targets=cuda-350 -mdcompute-file-prefix=testing
// REQUIRES: target_NVPTX
static assert([ __traits(getTargetInfo, "dcomputeTargets") ] == ["cuda-350"]);
static assert(__traits(getTargetInfo, "dcomputeFilePrefix") == "testing");
./ldc-1.20.1-src/tests/semantic/inputs/ 0000755 0001750 0001750 00000000000 13631266747 017773 5 ustar matthias matthias ./ldc-1.20.1-src/tests/semantic/inputs/notatcompute.d 0000644 0001750 0001750 00000000077 13631266747 022666 0 ustar matthias matthias module tests.semantic.inputs.notatcompute;
void somefunc() {}
./ldc-1.20.1-src/tests/linking/ 0000755 0001750 0001750 00000000000 13631266747 016301 5 ustar matthias matthias ./ldc-1.20.1-src/tests/linking/fullystatic.d 0000644 0001750 0001750 00000000622 13631266747 021011 0 ustar matthias matthias /* Make sure -static overrides -link-defaultlib-shared.
* We only care about the default libs in the linker command line;
* make sure linking fails in all cases (no main()) as linking would
* fail if there are no static default libs (BUILD_SHARED_LIBS=ON).
*/
// RUN: not %ldc -v -static -link-defaultlib-shared %s | FileCheck %s
// CHECK-NOT: druntime-ldc-shared
// CHECK-NOT: phobos2-ldc-shared
./ldc-1.20.1-src/tests/linking/fulllto_1.d 0000644 0001750 0001750 00000000350 13631266747 020345 0 ustar matthias matthias // Test full LTO commandline flag
// REQUIRES: LTO
// RUN: %ldc %s -of=%t%obj -c -flto=full -vv | FileCheck %s
// RUN: %ldc -flto=full -run %s
// CHECK: Writing LLVM bitcode
// CHECK-NOT: Creating module summary
void main()
{
}
./ldc-1.20.1-src/tests/linking/linker_switches.d 0000644 0001750 0001750 00000000574 13631266747 021651 0 ustar matthias matthias // Test if global order of flags passed with -Xcc, -L and pragma(lib) is preserved
// UNSUPPORTED: Windows
// RUN: /bin/sh -c '%ldc %s -of=%t -Xcc -DOPT1,-DOPT2 -L-L/usr/lib -L--defsym -Lfoo=5 -Xcc -DOPT3 -v 2>/dev/null || true' | FileCheck %s
// CHECK: -DOPT1 -DOPT2 -L/usr/lib -Xlinker --defsym -Xlinker foo=5 -DOPT3 {{.*}}-lpthread
pragma(lib, "pthread");
void main()
{
}
./ldc-1.20.1-src/tests/linking/thinlto_1.d 0000644 0001750 0001750 00000000357 13631266747 020354 0 ustar matthias matthias // Test ThinLTO commandline flag
// REQUIRES: LTO
// RUN: %ldc %s -of=%t%obj -c -flto=thin -vv | FileCheck %s
// RUN: %ldc -flto=thin -run %s
// CHECK: Writing LLVM bitcode
// CHECK: Creating module summary for ThinLTO
void main()
{
}
./ldc-1.20.1-src/tests/linking/ir2obj_caching_flags2.d 0000644 0001750 0001750 00000002647 13631266747 022560 0 ustar matthias matthias // Test that certain cmdline flags result in different cache objects, even though the LLVM IR may be the same.
// Test a few fsanitize-coverage options.
// REQUIRES: atleast_llvm500
// Note that the NO_HIT tests should change the default setting of the tested flag.
// Create and then empty the cache for correct testing when running the test multiple times.
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir
// RUN: %prunecache -f %t-dir --max-bytes=1
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -g -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -fsanitize-coverage=trace-pc-guard -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -fsanitize-coverage=8bit-counters -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -fsanitize-coverage=trace-cmp -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -g -vv | FileCheck --check-prefix=MUST_HIT %s
// The last test is a MUST_HIT test (hits with the first compile invocation), to make sure that the cache wasn't pruned somehow which could effectively disable some NO_HIT tests.
// MUST_HIT: Cache object found!
// NO_HIT: Cache object not found.
// Could hit is used for cases where we could have a cache hit, but currently we don't: a "TODO" item.
// COULD_HIT: Cache object
void main() {}
./ldc-1.20.1-src/tests/linking/link_bitcode_libs_500.d 0000644 0001750 0001750 00000001433 13631266747 022472 0 ustar matthias matthias // Test passing of LLVM bitcode file with Linker Options set
// REQUIRES: atleast_llvm500
// Linker Options are currently only set on Windows platform, so we must (cross-)compile to Windows
// REQUIRES: target_X86
// RUN: %ldc -mtriple=x86_64-windows -c -output-bc %S/inputs/link_bitcode_libs_input.d -of=%t.bc \
// RUN: && %ldc -mtriple=x86_64-windows -c -singleobj -output-ll %t.bc %s -of=%t.ll \
// RUN: && FileCheck %s < %t.ll
pragma(lib, "library_one");
pragma(lib, "library_two");
// CHECK: !llvm.linker.options = !{![[ATTR_LIB1:[0-9]+]], ![[ATTR_LIB2:[0-9]+]], ![[ATTR_LIB3:[0-9]+]], ![[ATTR_LIB4:[0-9]+]]}
// CHECK: ![[ATTR_LIB1]]{{.*}}library_one
// CHECK: ![[ATTR_LIB2]]{{.*}}library_two
// CHECK: ![[ATTR_LIB3]]{{.*}}imported_one
// CHECK: ![[ATTR_LIB4]]{{.*}}imported_two
./ldc-1.20.1-src/tests/linking/thinlto_asm_x86.d 0000644 0001750 0001750 00000000657 13631266747 021504 0 ustar matthias matthias // ThinLTO: Test inline assembly functions with thinlto
// REQUIRES: LTO
// REQUIRES: host_X86
// Naked DMD-style asm (LLVM module-level inline assembly) with LTO on Windows
// is only supported since LLVM 9.
// REQUIRES: !Windows || atleast_llvm900
// RUN: %ldc -flto=thin %S/inputs/asm_x86.d -c -of=%t_input%obj
// RUN: %ldc -flto=thin -I%S %s %t_input%obj
import inputs.asm_x86;
int main() {
return simplefunction();
}
./ldc-1.20.1-src/tests/linking/ir2obj_cache_pruning.d 0000644 0001750 0001750 00000001041 13631266747 022516 0 ustar matthias matthias // Test recognition of -cache-prune-* commandline flags
// RUN: %ldc %s -cache=%t-dir -cache-prune
// RUN: %ldc %s -cache=%t-dir -cache-prune-interval=10 -cache-prune-maxbytes=10000
// RUN: %ldc %s -cache=%t-dir -cache-prune -cache-prune-interval=0
// RUN: %ldc %s -cache=%t-dir -cache-prune -cache-prune-maxbytes=10000
// RUN: %ldc %s -cache=%t-dir -cache-prune -cache-prune-expiration=10000
// RUN: %ldc %s -cache=%t-dir -cache-prune-maxpercentage=50
// RUN: %ldc %s -cache=%t-dir -cache-prune -cache-prune-maxpercentage=150
void main()
{
}
./ldc-1.20.1-src/tests/linking/link_bitcode.d 0000644 0001750 0001750 00000001366 13631266747 021102 0 ustar matthias matthias // Test linking with an LLVM bitcode file
// RUN: %ldc -c -output-bc -I%S %S/inputs/link_bitcode_input.d -of=%t.bc
// RUN: %ldc -c -output-bc -I%S %S/inputs/link_bitcode_import.d -of=%t2.bc
// RUN: %ldc -c -output-bc -I%S %S/inputs/link_bitcode_input3.d -of=%t3.bc
// RUN: %ldc -c -singleobj -output-bc %t.bc %t3.bc %s
// RUN: %ldc -c -singleobj -I%S %t.bc %s %S/inputs/link_bitcode_input3.d
// RUN: %ldc -c -singleobj -I%S %t.bc %S/inputs/link_bitcode_input3.d %s
// RUN: %ldc -c -I%S %t.bc %S/inputs/link_bitcode_input3.d %s
// RUN: %ldc %t.bc %t2.bc %t3.bc -run %s
// RUN: %ldc %t.bc %S/inputs/link_bitcode_import.d %t3.bc -run %s
// Defined in input/link_bitcode_input.d
extern(C) int return_seven();
void main() {
assert( return_seven() == 7 );
}
./ldc-1.20.1-src/tests/linking/ir2obj_caching.d 0000644 0001750 0001750 00000000727 13631266747 021317 0 ustar matthias matthias // Test recognition of -cache commandline flag
// RUN: %ldc -cache=%t-dir %s -vv | FileCheck --check-prefix=FIRST %s
// RUN: %ldc -cache=%t-dir %s -vv | FileCheck --check-prefix=SECOND %s
// FIRST: Use IR-to-Object cache in {{.*}}-dir
// Don't check whether the object is in the cache on the first run, because if this test is ran twice the cache will already be there.
// SECOND: Use IR-to-Object cache in {{.*}}-dir
// SECOND: Cache object found!
void main()
{
}
./ldc-1.20.1-src/tests/linking/thinlto_modulecdtors_2.d 0000644 0001750 0001750 00000000417 13631266747 023136 0 ustar matthias matthias // REQUIRES: LTO
// RUN: %ldc -flto=thin -O3 %S/inputs/thinlto_ctor.d -run %s | FileCheck --check-prefix=EXECUTE %s
// EXECUTE: ctor
// EXECUTE: main
// EXECUTE: dtor
import core.stdc.stdio;
static ~this()
{
puts("dtor\n");
}
void main() {
puts("main\n");
}
./ldc-1.20.1-src/tests/linking/link_bitcode_libs.d 0000644 0001750 0001750 00000001627 13631266747 022113 0 ustar matthias matthias // Test passing of LLVM bitcode file with Linker Options set
// LLVM >= 5.0 uses llvm.linker.options instead. See link_bitcode_libs_500.d.
// REQUIRES: atmost_llvm400
// Linker Options are currently only set on Windows platform, so we must (cross-)compile to Windows
// REQUIRES: target_X86
// RUN: %ldc -mtriple=x86_64-windows -c -output-bc %S/inputs/link_bitcode_libs_input.d -of=%t.bc \
// RUN: && %ldc -mtriple=x86_64-windows -c -singleobj -output-ll %t.bc %s -of=%t.ll \
// RUN: && FileCheck %s < %t.ll
pragma(lib, "library_one");
pragma(lib, "library_two");
// CHECK: !"Linker Options", ![[ATTR_TUPLE:[0-9]+]]
// CHECK: ![[ATTR_TUPLE]] = !{![[ATTR_LIB1:[0-9]+]], ![[ATTR_LIB2:[0-9]+]], ![[ATTR_LIB3:[0-9]+]], ![[ATTR_LIB4:[0-9]+]]}
// CHECK: ![[ATTR_LIB1]]{{.*}}library_one
// CHECK: ![[ATTR_LIB2]]{{.*}}library_two
// CHECK: ![[ATTR_LIB3]]{{.*}}imported_one
// CHECK: ![[ATTR_LIB4]]{{.*}}imported_two
./ldc-1.20.1-src/tests/linking/thinlto_modulecdtors.d 0000644 0001750 0001750 00000000522 13631266747 022712 0 ustar matthias matthias // ThinLTO: Test that module ctors/dtors are called
// REQUIRES: atleast_llvm309
// REQUIRES: LTO
// RUN: %ldc -flto=thin -O3 -run %s | FileCheck %s
// CHECK: ctor
// CHECK: main
// CHECK: dtor
import core.stdc.stdio;
static this()
{
puts("ctor\n");
}
static ~this()
{
puts("dtor\n");
}
void main() {
puts("main\n");
}
./ldc-1.20.1-src/tests/linking/betterc.d 0000644 0001750 0001750 00000000504 13631266747 020075 0 ustar matthias matthias // RUN: %ldc -betterC -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
// RUN: %ldc -betterC -run %s
// CHECK-NOT: ModuleInfoZ
// CHECK-NOT: ModuleRefZ
// CHECK-NOT: call void @ldc.register_dso
extern (C) int main(int argc, char** argv) {
assert(argc == 1); // make sure we can link against C assert
return 0;
}
./ldc-1.20.1-src/tests/linking/rt_options.d 0000644 0001750 0001750 00000000247 13631266747 020651 0 ustar matthias matthias // RUN: %ldc -run %s
extern(C) __gshared string[] rt_options = [ "key=value" ];
void main()
{
import rt.config;
assert(rt_configOption("key") == "value");
}
./ldc-1.20.1-src/tests/linking/ir2obj_caching_retrieval.d 0000644 0001750 0001750 00000001461 13631266747 023370 0 ustar matthias matthias // Test recognition of -cache-retrieval commandline flag
// RUN: %ldc -c -of=%t%obj -cache=%t-dir %s -vv | FileCheck --check-prefix=FIRST %s
// RUN: %ldc -c -of=%t%obj -cache=%t-dir %s -cache-retrieval=copy -vv | FileCheck --check-prefix=MUST_HIT %s
// RUN: %ldc %t%obj
// RUN: %ldc -c -of=%t%obj -cache=%t-dir %s -cache-retrieval=link -vv | FileCheck --check-prefix=MUST_HIT %s
// RUN: %ldc %t%obj
// RUN: %ldc -c -of=%t%obj -cache=%t-dir %s -cache-retrieval=hardlink -vv | FileCheck --check-prefix=MUST_HIT %s
// RUN: %ldc %t%obj
// FIRST: Use IR-to-Object cache in {{.*}}-dir
// Don't check whether the object is in the cache on the first run, because if this test is ran twice the cache will already be there.
// MUST_HIT: Use IR-to-Object cache in {{.*}}-dir
// MUST_HIT: Cache object found!
void main()
{
}
./ldc-1.20.1-src/tests/linking/link_internally.d 0000644 0001750 0001750 00000000231 13631266747 021640 0 ustar matthias matthias // REQUIRES: Windows
// REQUIRES: internal_lld
// RUN: %ldc -link-internally -run %s
void main()
{
import std.stdio;
writeln("Hello world");
}
./ldc-1.20.1-src/tests/linking/ir2obj_caching_flags1.d 0000644 0001750 0001750 00000007612 13631266747 022554 0 ustar matthias matthias // Test that certain cmdline flags result in different cache objects, even though the LLVM IR may be the same.
// Note that the NO_HIT tests should change the default setting of the tested flag.
// Create and then empty the cache for correct testing when running the test multiple times.
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir
// RUN: %prunecache -f %t-dir --max-bytes=1
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -g -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -O -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -O3 -vv | FileCheck --check-prefix=MUST_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -O2 -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -O4 -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc -O5 %s -c -of=%t%obj -cache=%t-dir -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -Os -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -Oz -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -disable-d-passes -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -disable-simplify-drtcalls -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -disable-simplify-libcalls -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -disable-gc2stack -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -enable-inlining -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -strip-debug -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -disable-loop-unrolling -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -disable-loop-vectorization -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -disable-slp-vectorization -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -vectorize-loops -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -v -wi -d -vv | FileCheck --check-prefix=MUST_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -D -H -I. -J. -vv | FileCheck --check-prefix=MUST_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -d-version=Irrelevant -vv | FileCheck --check-prefix=MUST_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -unittest -vv | FileCheck --check-prefix=MUST_HIT %s
// RUN: %ldc %s -cache=%t-dir -lib -vv | FileCheck --check-prefix=MUST_HIT %s
// RUN: %ldc -cache=%t-dir -vv -run %s | FileCheck --check-prefix=COULD_HIT %s
// RUN: %ldc -cache=%t-dir -vv -run %s a b | FileCheck --check-prefix=MUST_HIT %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -g -vv | FileCheck --check-prefix=MUST_HIT %s
// The last test is a MUST_HIT test (hits with the first compile invocation), to make sure that the cache wasn't pruned somehow which could effectively disable some NO_HIT tests.
// MUST_HIT: Cache object found!
// NO_HIT: Cache object not found.
// Could hit is used for cases where we could have a cache hit, but currently we don't: a "TODO" item.
// COULD_HIT: Cache object
void main() {}
./ldc-1.20.1-src/tests/linking/inputs/ 0000755 0001750 0001750 00000000000 13631266747 017623 5 ustar matthias matthias ./ldc-1.20.1-src/tests/linking/inputs/thinlto_ctor.d 0000644 0001750 0001750 00000000077 13631266747 022504 0 ustar matthias matthias import core.stdc.stdio;
static this()
{
puts("ctor\n");
}
./ldc-1.20.1-src/tests/linking/inputs/asm_x86.d 0000644 0001750 0001750 00000000147 13631266747 021257 0 ustar matthias matthias void foo()
{
asm
{
naked;
ret;
}
}
int simplefunction()
{
return 1;
}
./ldc-1.20.1-src/tests/linking/inputs/link_bitcode_input.d 0000644 0001750 0001750 00000000257 13631266747 023641 0 ustar matthias matthias module inputs.link_bitcode_input;
extern(C) int return_seven() {
return 7;
}
import inputs.link_bitcode_import;
void bar()
{
SomeStrukt r = {1};
takeStrukt(&r);
}
./ldc-1.20.1-src/tests/linking/inputs/link_bitcode_input3.d 0000644 0001750 0001750 00000000203 13631266747 023713 0 ustar matthias matthias module inputs.link_bitcode_input3;
import inputs.link_bitcode_import;
void foo()
{
SomeStrukt r = {0};
takeStrukt(&r);
}
./ldc-1.20.1-src/tests/linking/inputs/link_bitcode_import.d 0000644 0001750 0001750 00000000173 13631266747 024011 0 ustar matthias matthias module inputs.link_bitcode_import;
extern(C)
struct SomeStrukt {
int i;
}
extern(C) void takeStrukt(SomeStrukt*) {};
./ldc-1.20.1-src/tests/linking/inputs/link_bitcode_libs_input.d 0000644 0001750 0001750 00000000141 13631266747 024642 0 ustar matthias matthias module inputs.link_bitcode_libs_input;
pragma(lib, "imported_one");
pragma(lib, "imported_two"); ./ldc-1.20.1-src/tests/linking/ir2obj_cache_pruning2.d 0000644 0001750 0001750 00000003274 13631266747 022612 0 ustar matthias matthias // Test cache pruning for size
// This test assumes that the `void main(){}` object file size is below 200_000 bytes and above 200_000/2,
// such that rebuilding with version(NEW_OBJ_FILE) will clear the cache of all but the latest object file.
// RUN: %ldc %s -cache=%t-dir
// RUN: %ldc %s -cache=%t-dir -cache-prune -cache-prune-interval=0 -d-version=SLEEP
// RUN: %ldc %s -cache=%t-dir -cache-prune -cache-prune-interval=0 -vv | FileCheck --check-prefix=MUST_HIT %s
// RUN: %ldc %s -cache=%t-dir -cache-prune -cache-prune-interval=0 -vv -d-version=NEW_OBJ_FILE | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc %s -cache=%t-dir -cache-prune -cache-prune-interval=0 -vv | FileCheck --check-prefix=MUST_HIT %s
// RUN: %ldc -d-version=SLEEP -run %s
// RUN: %ldc %s -c -of=%t%obj -cache=%t-dir -cache-prune-interval=0 -cache-prune-maxbytes=200000 -vv | FileCheck --check-prefix=MUST_HIT %s
// RUN: %ldc %t%obj
// RUN: %ldc %s -cache=%t-dir -d-version=SLEEP -vv | FileCheck --check-prefix=NO_HIT %s
// RUN: %ldc -d-version=SLEEP -run %s
// RUN: %ldc %s -cache=%t-dir -cache-prune-interval=1 -cache-prune-maxbytes=200000 -d-version=NEW_OBJ_FILE
// RUN: %ldc %s -cache=%t-dir -cache-prune -cache-prune-interval=0 -vv | FileCheck --check-prefix=NO_HIT %s
// MUST_HIT: Cache object found!
// NO_HIT-NOT: Cache object found!
void main()
{
// Add non-zero static data to guarantee a binary size larger than 200_000/2.
static byte[120_000] dummy = 1;
version (NEW_OBJ_FILE)
{
auto a = __TIME__;
}
version (SLEEP)
{
// Sleep for 4 seconds, so we are sure that the cache object file timestamps are "aging".
import core.thread;
Thread.sleep( dur!"seconds"(4) );
}
}
./ldc-1.20.1-src/tests/driver/ 0000755 0001750 0001750 00000000000 13631266747 016141 5 ustar matthias matthias ./ldc-1.20.1-src/tests/driver/gh2073.d 0000644 0001750 0001750 00000000430 13631266747 017215 0 ustar matthias matthias // RUN: %ldc -mcpu=help 2>&1 | FileCheck %s
// RUN: %ldc -mattr=help 2>&1 | FileCheck %s
// RUN: %ldc -mcpu=help -mattr=help 2>&1 | FileCheck %s
// CHECK: Available CPUs for this target:
// CHECK: Available features for this target:
// CHECK-NOT: Available CPUs for this target:
./ldc-1.20.1-src/tests/driver/config_diag.d 0000644 0001750 0001750 00000000543 13631266747 020541 0 ustar matthias matthias // RUN: not %ldc -conf=%S/inputs/noswitches.conf %s 2>&1 | FileCheck %s --check-prefix=NOSWITCHES
// NOSWITCHES: Could not look up switches in {{.*}}noswitches.conf
// RUN: not %ldc -conf=%S/inputs/section_aaa.conf %s 2>&1 | FileCheck %s --check-prefix=NO_SEC
// NO_SEC: No matching section for triple '{{.*}}' in {{.*}}section_aaa.conf
void foo()
{
}
./ldc-1.20.1-src/tests/driver/drt_options_in_rsp_file.d 0000644 0001750 0001750 00000000140 13631266747 023216 0 ustar matthias matthias // RUN: %ldc -c %s @%S/inputs/drt_options_in_rsp_file.rsp | FileCheck %s
// CHECK: GC summary:
./ldc-1.20.1-src/tests/driver/gh1945.d 0000644 0001750 0001750 00000000235 13631266747 017227 0 ustar matthias matthias // REQUIRES: target_X86
// RUN: %ldc -c %s -v -march=x86 | FileCheck %s
// RUN: %ldc -c %s -v -march x86 | FileCheck %s
// CHECK: config {{.*}}.conf (i686-
./ldc-1.20.1-src/tests/driver/mscrtlib.d 0000644 0001750 0001750 00000001200 13631266747 020116 0 ustar matthias matthias // On Windows, re-test dmd-testsuite's runnable\eh.d with all 4 MS C runtime variants.
// In case of failures, it's very likely that the EH terminate hook in druntime's
// ldc.eh.msvc.msvc_eh_terminate() needs to be adapted.
// REQUIRES: Windows
// RUN: %ldc -mscrtlib=libcmt -run "%S\..\d2\dmd-testsuite\runnable\eh.d"
// RUN: %ldc -mscrtlib=libcmtd -link-defaultlib-debug -run "%S\..\d2\dmd-testsuite\runnable\eh.d"
// RUN: %ldc -mscrtlib=msvcrt -link-defaultlib-debug -run "%S\..\d2\dmd-testsuite\runnable\eh.d"
// RUN: %ldc -mscrtlib=msvcrtd -run "%S\..\d2\dmd-testsuite\runnable\eh.d"
./ldc-1.20.1-src/tests/driver/save_optimization_record.d 0000644 0001750 0001750 00000001342 13631266747 023410 0 ustar matthias matthias // REQUIRES: atleast_llvm400
// Automatic output filename generation from LL output file
// RUN: %ldc -c -betterC -O3 -g -fsave-optimization-record -output-ll -of=%t.1.ll %s \
// RUN: && FileCheck %s --check-prefix=LLVM < %t.1.ll \
// RUN: && FileCheck %s --check-prefix=YAML < %t.1.opt.yaml
// Explicit filename specified
// RUN: %ldc -c -betterC -O3 -g -fsave-optimization-record=%t.abcdefg -output-ll -of=%t.ll %s \
// RUN: && FileCheck %s --check-prefix=LLVM < %t.ll \
// RUN: && FileCheck %s --check-prefix=YAML < %t.abcdefg
int alwaysInlined(int a) { return a; }
int foo()
{
// LLVM: 8329424
// YAML: File: save_optimization_record.d, Line: [[@LINE+1]]
return 8329423 + alwaysInlined(1);
}
// LLVM: !DILocation(line
./ldc-1.20.1-src/tests/driver/post_switches.d 0000644 0001750 0001750 00000001173 13631266747 021206 0 ustar matthias matthias // RUN: not %ldc -I=%runtimedir/src -conf=%S/inputs/post_switches.conf %s -v -L-user-passed-switch | FileCheck %s
// CHECK: -normal-switch
// CHECK-SAME: -normal-two-switch
// CHECK-SAME: -user-passed-switch
// CHECK-SAME: -post-switch
// CHECK-SAME: -post-two-switch
// RUN: not %ldc -I=%runtimedir/src -conf=%S/inputs/post_switches.conf -v -L-user-passed-switch -run %s -L-after-run | FileCheck %s --check-prefix=WITHrUN
// WITHrUN: -normal-switch
// WITHrUN-SAME: -normal-two-switch
// WITHrUN-SAME: -user-passed-switch
// WITHrUN-SAME: -post-switch
// WITHrUN-SAME: -post-two-switch
// WITHrUN-NOT: -after-run
void main()
{
}
./ldc-1.20.1-src/tests/driver/gh1941.d 0000644 0001750 0001750 00000000126 13631266747 017222 0 ustar matthias matthias // RUN: %ldc -c %s @%S/gh1941.rsp 2>&1 | FileCheck %s
// CHECK: 'foo.conf' not found
./ldc-1.20.1-src/tests/driver/float_abi.d 0000644 0001750 0001750 00000002116 13631266747 020226 0 ustar matthias matthias // REQUIRES: target_ARM
// RUN: %ldc -c -o- %s -mtriple=armv7-linux-android -float-abi=soft -d-version=SOFT
// RUN: %ldc -c -o- %s -mtriple=armv7-linux-android -float-abi=softfp -d-version=SOFTFP
// RUN: %ldc -c -o- %s -mtriple=armv7-linux-gnueabihf -d-version=HARD
version (SOFT)
{
version (ARM_SoftFloat) {} else static assert(0);
version (ARM_SoftFP) static assert(0);
version (ARM_HardFloat) static assert(0);
version (D_SoftFloat) {} else static assert(0);
version (D_HardFloat) static assert(0);
}
else version (SOFTFP)
{
version (ARM_SoftFloat) static assert(0);
version (ARM_SoftFP) {} else static assert(0);
version (ARM_HardFloat) static assert(0);
version (D_SoftFloat) static assert(0);
version (D_HardFloat) {} else static assert(0);
}
else version (HARD)
{
version (ARM_SoftFloat) static assert(0);
version (ARM_SoftFP) static assert(0);
version (ARM_HardFloat) {} else static assert(0);
version (D_SoftFloat) static assert(0);
version (D_HardFloat) {} else static assert(0);
}
else
static assert(0);
./ldc-1.20.1-src/tests/driver/config_diag_x86.d 0000644 0001750 0001750 00000000345 13631266747 021246 0 ustar matthias matthias // REQUIRES: target_X86
// RUN: %ldc -conf=%S/inputs/override_default.conf -mtriple=x86-apple-windows-msvc -c -o- %s | FileCheck %s --check-prefix=OVERRIDE_DEFAULT
// OVERRIDE_DEFAULT: LDC - the LLVM D compiler
void foo()
{
}
./ldc-1.20.1-src/tests/driver/cli_preparsing.d 0000644 0001750 0001750 00000001022 13631266747 021302 0 ustar matthias matthias // REQUIRES: target_X86
// RUN: not %ldc -o- -conf= %s 2>&1 | FileCheck --check-prefix=NO_CONF %s
// RUN: not %ldc -o- --conf "" %s 2>&1 | FileCheck --check-prefix=NO_CONF %s
// NO_CONF: Error: cannot find source code for runtime library file 'object.d'
// RUN: %ldc -v -o- -mtriple x86_64-vendor-windows-msvc %s 2>&1 | FileCheck --check-prefix=TRIPLE %s
// RUN: %ldc -v -o- --mtriple=x86_64-vendor-windows-msvc %s 2>&1 | FileCheck --check-prefix=TRIPLE %s
// TRIPLE: config
// TRIPLE-SAME: (x86_64-vendor-windows-msvc)
./ldc-1.20.1-src/tests/driver/gh1941.rsp 0000644 0001750 0001750 00000000017 13631266747 017602 0 ustar matthias matthias -conf=foo.conf
./ldc-1.20.1-src/tests/driver/inputs/ 0000755 0001750 0001750 00000000000 13631266747 017463 5 ustar matthias matthias ./ldc-1.20.1-src/tests/driver/inputs/override_default.conf 0000644 0001750 0001750 00000000142 13631266747 023652 0 ustar matthias matthias default:
{
switches = [ "" ];
};
x86-apple-windows-msvc:
{
switches = [ "-version" ];
};
./ldc-1.20.1-src/tests/driver/inputs/section_aaa.conf 0000644 0001750 0001750 00000000041 13631266747 022573 0 ustar matthias matthias aaa:
{
switches = [ "" ];
};
./ldc-1.20.1-src/tests/driver/inputs/drt_options_in_rsp_file.rsp 0000644 0001750 0001750 00000000026 13631266747 025124 0 ustar matthias matthias --DRT-gcopt=profile:1
./ldc-1.20.1-src/tests/driver/inputs/noswitches.conf 0000644 0001750 0001750 00000000016 13631266747 022515 0 ustar matthias matthias default:
{
};
./ldc-1.20.1-src/tests/driver/inputs/post_switches.conf 0000644 0001750 0001750 00000000265 13631266747 023233 0 ustar matthias matthias default:
{
switches = [
"-L-normal-switch",
"-L-normal-two-switch"
];
post-switches = [
"-L-post-switch",
"-L-post-two-switch"
];
};
./ldc-1.20.1-src/tests/CMakeLists.txt 0000644 0001750 0001750 00000001263 13631266747 017410 0 ustar matthias matthias set( LDC2_BIN ${PROJECT_BINARY_DIR}/bin/${LDC_EXE} )
set( LDCPROFDATA_BIN ${PROJECT_BINARY_DIR}/bin/ldc-profdata )
set( LDCPRUNECACHE_BIN ${PROJECT_BINARY_DIR}/bin/${LDCPRUNECACHE_EXE} )
set( LLVM_TOOLS_DIR ${LLVM_ROOT_DIR}/bin )
set( LDC2_BIN_DIR ${PROJECT_BINARY_DIR}/bin )
set( LDC2_LIB_DIR ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX} )
set( TESTS_IR_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set( DEFAULT_TARGET_BITS 64 )
else()
set( DEFAULT_TARGET_BITS 32 )
endif()
configure_file(lit.site.cfg.in lit.site.cfg )
configure_file(runlit.py runlit.py COPYONLY)
add_test(NAME lit-tests
COMMAND python runlit.py -v .
)
./ldc-1.20.1-src/tests/d2/ 0000755 0001750 0001750 00000000000 13631266751 015146 5 ustar matthias matthias ./ldc-1.20.1-src/tests/d2/src/ 0000755 0001750 0001750 00000000000 13631266747 015742 5 ustar matthias matthias ./ldc-1.20.1-src/tests/d2/src/osmodel.mak 0000644 0001750 0001750 00000002706 13631266747 020103 0 ustar matthias matthias # osmodel.mak
#
# Detects and sets the macros:
#
# OS = one of {osx,linux,freebsd,openbsd,netbsd,dragonflybsd,solaris}
# MODEL = one of { 32, 64 }
# MODEL_FLAG = one of { -m32, -m64 }
#
# Note:
# Keep this file in sync between druntime, phobos, and dmd repositories!
# Source: https://github.com/dlang/dmd/blob/master/osmodel.mak
ifeq (,$(OS))
uname_S:=$(shell uname -s)
ifeq (Darwin,$(uname_S))
OS:=osx
endif
ifeq (Linux,$(uname_S))
OS:=linux
endif
ifeq (FreeBSD,$(uname_S))
OS:=freebsd
endif
ifeq (OpenBSD,$(uname_S))
OS:=openbsd
endif
ifeq (NetBSD,$(uname_S))
OS:=netbsd
endif
ifeq (DragonFly,$(uname_S))
OS:=dragonflybsd
endif
ifeq (Solaris,$(uname_S))
OS:=solaris
endif
ifeq (SunOS,$(uname_S))
OS:=solaris
endif
ifeq (,$(OS))
$(error Unrecognized or unsupported OS for uname: $(uname_S))
endif
endif
# When running make from XCode it may set environment var OS=MACOS.
# Adjust it here:
ifeq (MACOS,$(OS))
OS:=osx
endif
ifeq (,$(MODEL))
ifeq ($(OS), solaris)
uname_M:=$(shell isainfo -n)
else
uname_M:=$(shell uname -m)
endif
ifneq (,$(findstring $(uname_M),x86_64 amd64))
MODEL:=64
endif
ifneq (,$(findstring $(uname_M),i386 i586 i686))
MODEL:=32
endif
ifeq (,$(MODEL))
$(warning Cannot figure 32/64 model from uname -m: $(uname_M))
endif
endif
ifneq (,$(MODEL))
ifneq (default,$(MODEL))
MODEL_FLAG:=-m$(MODEL)
endif
endif
./ldc-1.20.1-src/tests/d2/dmd-testsuite/ 0000755 0001750 0001750 00000000000 13631266751 017741 5 ustar matthias matthias ./ldc-1.20.1-src/tests/d2/dmd-testsuite/compilable/ 0000755 0001750 0001750 00000000000 13631266747 022055 5 ustar matthias matthias ./ldc-1.20.1-src/tests/d2/dmd-testsuite/compilable/test19746.sh 0000755 0001750 0001750 00000001601 13631266747 024004 0 ustar matthias matthias #! /usr/bin/env bash
TEST_DIR=${OUTPUT_BASE}
mkdir -p ${TEST_DIR}
cat >${TEST_DIR}${SEP}test19746.d <${TEST_DIR}${SEP}test19746a.d <${TEST_DIR}${SEP}test19746b.d <${TEST_DIR}${SEP}test19746c.d <${TEST_DIR}${SEP}test19746d.d <