Auto merge of #114148 - cuviper:drop-llvm-14, r=nikic
Update the minimum external LLVM to 15 With this change, we'll have stable support for LLVM 15 through 17 (pending release). For reference, the previous increase to LLVM 14 was #107573.
This commit is contained in:
commit
4c96822796
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
@ -55,7 +55,7 @@ jobs:
|
||||
- name: mingw-check-tidy
|
||||
os: ubuntu-20.04-16core-64gb
|
||||
env: {}
|
||||
- name: x86_64-gnu-llvm-14
|
||||
- name: x86_64-gnu-llvm-15
|
||||
os: ubuntu-20.04-16core-64gb
|
||||
env: {}
|
||||
- name: x86_64-gnu-tools
|
||||
@ -293,10 +293,6 @@ jobs:
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
- name: x86_64-gnu-llvm-14
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
os: ubuntu-20.04-8core-32gb
|
||||
- name: x86_64-gnu-nopt
|
||||
os: ubuntu-20.04-4core-16gb
|
||||
env: {}
|
||||
|
@ -363,50 +363,44 @@ pub fn from_fn_attrs<'ll, 'tcx>(
|
||||
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR)
|
||||
|| codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR_ZEROED)
|
||||
{
|
||||
if llvm_util::get_version() >= (15, 0, 0) {
|
||||
to_add.push(create_alloc_family_attr(cx.llcx));
|
||||
// apply to argument place instead of function
|
||||
let alloc_align = AttributeKind::AllocAlign.create_attr(cx.llcx);
|
||||
attributes::apply_to_llfn(llfn, AttributePlace::Argument(1), &[alloc_align]);
|
||||
to_add.push(llvm::CreateAllocSizeAttr(cx.llcx, 0));
|
||||
let mut flags = AllocKindFlags::Alloc | AllocKindFlags::Aligned;
|
||||
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR) {
|
||||
flags |= AllocKindFlags::Uninitialized;
|
||||
} else {
|
||||
flags |= AllocKindFlags::Zeroed;
|
||||
}
|
||||
to_add.push(llvm::CreateAllocKindAttr(cx.llcx, flags));
|
||||
to_add.push(create_alloc_family_attr(cx.llcx));
|
||||
// apply to argument place instead of function
|
||||
let alloc_align = AttributeKind::AllocAlign.create_attr(cx.llcx);
|
||||
attributes::apply_to_llfn(llfn, AttributePlace::Argument(1), &[alloc_align]);
|
||||
to_add.push(llvm::CreateAllocSizeAttr(cx.llcx, 0));
|
||||
let mut flags = AllocKindFlags::Alloc | AllocKindFlags::Aligned;
|
||||
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR) {
|
||||
flags |= AllocKindFlags::Uninitialized;
|
||||
} else {
|
||||
flags |= AllocKindFlags::Zeroed;
|
||||
}
|
||||
to_add.push(llvm::CreateAllocKindAttr(cx.llcx, flags));
|
||||
// apply to return place instead of function (unlike all other attributes applied in this function)
|
||||
let no_alias = AttributeKind::NoAlias.create_attr(cx.llcx);
|
||||
attributes::apply_to_llfn(llfn, AttributePlace::ReturnValue, &[no_alias]);
|
||||
}
|
||||
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::REALLOCATOR) {
|
||||
if llvm_util::get_version() >= (15, 0, 0) {
|
||||
to_add.push(create_alloc_family_attr(cx.llcx));
|
||||
to_add.push(llvm::CreateAllocKindAttr(
|
||||
cx.llcx,
|
||||
AllocKindFlags::Realloc | AllocKindFlags::Aligned,
|
||||
));
|
||||
// applies to argument place instead of function place
|
||||
let allocated_pointer = AttributeKind::AllocatedPointer.create_attr(cx.llcx);
|
||||
attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), &[allocated_pointer]);
|
||||
// apply to argument place instead of function
|
||||
let alloc_align = AttributeKind::AllocAlign.create_attr(cx.llcx);
|
||||
attributes::apply_to_llfn(llfn, AttributePlace::Argument(2), &[alloc_align]);
|
||||
to_add.push(llvm::CreateAllocSizeAttr(cx.llcx, 3));
|
||||
}
|
||||
to_add.push(create_alloc_family_attr(cx.llcx));
|
||||
to_add.push(llvm::CreateAllocKindAttr(
|
||||
cx.llcx,
|
||||
AllocKindFlags::Realloc | AllocKindFlags::Aligned,
|
||||
));
|
||||
// applies to argument place instead of function place
|
||||
let allocated_pointer = AttributeKind::AllocatedPointer.create_attr(cx.llcx);
|
||||
attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), &[allocated_pointer]);
|
||||
// apply to argument place instead of function
|
||||
let alloc_align = AttributeKind::AllocAlign.create_attr(cx.llcx);
|
||||
attributes::apply_to_llfn(llfn, AttributePlace::Argument(2), &[alloc_align]);
|
||||
to_add.push(llvm::CreateAllocSizeAttr(cx.llcx, 3));
|
||||
let no_alias = AttributeKind::NoAlias.create_attr(cx.llcx);
|
||||
attributes::apply_to_llfn(llfn, AttributePlace::ReturnValue, &[no_alias]);
|
||||
}
|
||||
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::DEALLOCATOR) {
|
||||
if llvm_util::get_version() >= (15, 0, 0) {
|
||||
to_add.push(create_alloc_family_attr(cx.llcx));
|
||||
to_add.push(llvm::CreateAllocKindAttr(cx.llcx, AllocKindFlags::Free));
|
||||
// applies to argument place instead of function place
|
||||
let allocated_pointer = AttributeKind::AllocatedPointer.create_attr(cx.llcx);
|
||||
attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), &[allocated_pointer]);
|
||||
}
|
||||
to_add.push(create_alloc_family_attr(cx.llcx));
|
||||
to_add.push(llvm::CreateAllocKindAttr(cx.llcx, AllocKindFlags::Free));
|
||||
// applies to argument place instead of function place
|
||||
let allocated_pointer = AttributeKind::AllocatedPointer.create_attr(cx.llcx);
|
||||
attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), &[allocated_pointer]);
|
||||
}
|
||||
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY) {
|
||||
to_add.push(llvm::CreateAttrString(cx.llcx, "cmse_nonsecure_entry"));
|
||||
|
@ -507,8 +507,6 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
|
||||
.features
|
||||
.split(',')
|
||||
.filter(|v| !v.is_empty() && backend_feature_name(v).is_some())
|
||||
// Drop +atomics-32 feature introduced in LLVM 15.
|
||||
.filter(|v| *v != "+atomics-32" || get_version() >= (15, 0, 0))
|
||||
.map(String::from),
|
||||
);
|
||||
|
||||
|
@ -92,10 +92,8 @@ enum LLVMRustAttribute {
|
||||
NoCfCheck = 35,
|
||||
ShadowCallStack = 36,
|
||||
AllocSize = 37,
|
||||
#if LLVM_VERSION_GE(15, 0)
|
||||
AllocatedPointer = 38,
|
||||
AllocAlign = 39,
|
||||
#endif
|
||||
SanitizeSafeStack = 40,
|
||||
};
|
||||
|
||||
|
@ -801,9 +801,6 @@ LLVMRustOptimize(
|
||||
OptimizerLastEPCallbacks.push_back(
|
||||
[SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) {
|
||||
auto CompileKernel = SanitizerOptions->SanitizeKernelAddress;
|
||||
#if LLVM_VERSION_LT(15, 0)
|
||||
MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
|
||||
#endif
|
||||
AddressSanitizerOptions opts = AddressSanitizerOptions{
|
||||
CompileKernel,
|
||||
SanitizerOptions->SanitizeAddressRecover
|
||||
|
@ -277,12 +277,10 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
|
||||
return Attribute::ShadowCallStack;
|
||||
case AllocSize:
|
||||
return Attribute::AllocSize;
|
||||
#if LLVM_VERSION_GE(15, 0)
|
||||
case AllocatedPointer:
|
||||
return Attribute::AllocatedPointer;
|
||||
case AllocAlign:
|
||||
return Attribute::AllocAlign;
|
||||
#endif
|
||||
case SanitizeSafeStack:
|
||||
return Attribute::SafeStack;
|
||||
}
|
||||
@ -340,20 +338,12 @@ extern "C" LLVMAttributeRef LLVMRustCreateStructRetAttr(LLVMContextRef C, LLVMTy
|
||||
}
|
||||
|
||||
extern "C" LLVMAttributeRef LLVMRustCreateElementTypeAttr(LLVMContextRef C, LLVMTypeRef Ty) {
|
||||
#if LLVM_VERSION_GE(15, 0)
|
||||
return wrap(Attribute::get(*unwrap(C), Attribute::ElementType, unwrap(Ty)));
|
||||
#else
|
||||
report_fatal_error("Should not be needed on LLVM < 15");
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" LLVMAttributeRef LLVMRustCreateUWTableAttr(LLVMContextRef C, bool Async) {
|
||||
#if LLVM_VERSION_LT(15, 0)
|
||||
return wrap(Attribute::get(*unwrap(C), Attribute::UWTable));
|
||||
#else
|
||||
return wrap(Attribute::getWithUWTableKind(
|
||||
*unwrap(C), Async ? UWTableKind::Async : UWTableKind::Sync));
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" LLVMAttributeRef LLVMRustCreateAllocSizeAttr(LLVMContextRef C, uint32_t ElementSizeArg) {
|
||||
@ -366,8 +356,6 @@ extern "C" LLVMAttributeRef LLVMRustCreateAllocSizeAttr(LLVMContextRef C, uint32
|
||||
));
|
||||
}
|
||||
|
||||
#if LLVM_VERSION_GE(15, 0)
|
||||
|
||||
// These values **must** match ffi::AllocKindFlags.
|
||||
// It _happens_ to match the LLVM values of llvm::AllocFnKind,
|
||||
// but that's happenstance and we do explicit conversions before
|
||||
@ -411,16 +399,10 @@ static llvm::AllocFnKind allocKindFromRust(LLVMRustAllocKindFlags F) {
|
||||
}
|
||||
return AFK;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" LLVMAttributeRef LLVMRustCreateAllocKindAttr(LLVMContextRef C, uint64_t AllocKindArg) {
|
||||
#if LLVM_VERSION_GE(15, 0)
|
||||
return wrap(Attribute::get(*unwrap(C), Attribute::AllocKind,
|
||||
static_cast<uint64_t>(allocKindFromRust(static_cast<LLVMRustAllocKindFlags>(AllocKindArg)))));
|
||||
#else
|
||||
report_fatal_error(
|
||||
"allockind attributes are new in LLVM 15 and should not be used on older LLVMs");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Simplified representation of `MemoryEffects` across the FFI boundary.
|
||||
@ -517,14 +499,9 @@ LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen,
|
||||
|
||||
extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
|
||||
size_t ConstraintsLen) {
|
||||
#if LLVM_VERSION_LT(15, 0)
|
||||
return InlineAsm::Verify(unwrap<FunctionType>(Ty),
|
||||
StringRef(Constraints, ConstraintsLen));
|
||||
#else
|
||||
// llvm::Error converts to true if it is an error.
|
||||
return !llvm::errorToBool(InlineAsm::verify(
|
||||
unwrap<FunctionType>(Ty), StringRef(Constraints, ConstraintsLen)));
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef DIBuilder *LLVMRustDIBuilderRef;
|
||||
@ -1649,19 +1626,11 @@ extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *hig
|
||||
auto C = unwrap<llvm::ConstantInt>(CV);
|
||||
if (C->getBitWidth() > 128) { return false; }
|
||||
APInt AP;
|
||||
#if LLVM_VERSION_GE(15, 0)
|
||||
if (sext) {
|
||||
AP = C->getValue().sext(128);
|
||||
} else {
|
||||
AP = C->getValue().zext(128);
|
||||
}
|
||||
#else
|
||||
if (sext) {
|
||||
AP = C->getValue().sextOrSelf(128);
|
||||
} else {
|
||||
AP = C->getValue().zextOrSelf(128);
|
||||
}
|
||||
#endif
|
||||
*low = AP.getLoBits(64).getZExtValue();
|
||||
*high = AP.getHiBits(64).getZExtValue();
|
||||
return true;
|
||||
@ -2037,16 +2006,7 @@ extern "C" void LLVMRustGetMangledName(LLVMValueRef V, RustStringRef Str) {
|
||||
Mangler().getNameWithPrefix(OS, GV, true);
|
||||
}
|
||||
|
||||
// LLVMGetAggregateElement was added in LLVM 15. For earlier LLVM versions just
|
||||
// use its implementation.
|
||||
#if LLVM_VERSION_LT(15, 0)
|
||||
extern "C" LLVMValueRef LLVMGetAggregateElement(LLVMValueRef C, unsigned Idx) {
|
||||
return wrap(unwrap<Constant>(C)->getAggregateElement(Idx));
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" int32_t LLVMRustGetElementTypeArgIndex(LLVMValueRef CallSite) {
|
||||
#if LLVM_VERSION_GE(15, 0)
|
||||
auto *CB = unwrap<CallBase>(CallSite);
|
||||
switch (CB->getIntrinsicID()) {
|
||||
case Intrinsic::arm_ldrex:
|
||||
@ -2054,7 +2014,6 @@ extern "C" int32_t LLVMRustGetElementTypeArgIndex(LLVMValueRef CallSite) {
|
||||
case Intrinsic::arm_strex:
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -525,11 +525,11 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) {
|
||||
let version = output(cmd.arg("--version"));
|
||||
let mut parts = version.split('.').take(2).filter_map(|s| s.parse::<u32>().ok());
|
||||
if let (Some(major), Some(_minor)) = (parts.next(), parts.next()) {
|
||||
if major >= 14 {
|
||||
if major >= 15 {
|
||||
return;
|
||||
}
|
||||
}
|
||||
panic!("\n\nbad LLVM version: {}, need >=14.0\n\n", version)
|
||||
panic!("\n\nbad LLVM version: {}, need >=15.0\n\n", version)
|
||||
}
|
||||
|
||||
fn configure_cmake(
|
||||
|
@ -1,54 +0,0 @@
|
||||
FROM ubuntu:22.04
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
g++ \
|
||||
gcc-multilib \
|
||||
make \
|
||||
ninja-build \
|
||||
file \
|
||||
curl \
|
||||
ca-certificates \
|
||||
python3.11 \
|
||||
git \
|
||||
cmake \
|
||||
sudo \
|
||||
gdb \
|
||||
llvm-14-tools \
|
||||
llvm-14-dev \
|
||||
libedit-dev \
|
||||
libssl-dev \
|
||||
pkg-config \
|
||||
zlib1g-dev \
|
||||
xz-utils \
|
||||
nodejs \
|
||||
mingw-w64 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install powershell (universal package) so we can test x.ps1 on Linux
|
||||
RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/powershell_7.3.1-1.deb_amd64.deb" > powershell.deb && \
|
||||
dpkg -i powershell.deb && \
|
||||
rm -f powershell.deb
|
||||
|
||||
COPY scripts/sccache.sh /scripts/
|
||||
RUN sh /scripts/sccache.sh
|
||||
|
||||
# We are disabling CI LLVM since this builder is intentionally using a host
|
||||
# LLVM, rather than the typical src/llvm-project LLVM.
|
||||
ENV NO_DOWNLOAD_CI_LLVM 1
|
||||
|
||||
# This is not the latest LLVM version, so some components required by tests may
|
||||
# be missing.
|
||||
ENV IS_NOT_LATEST_LLVM 1
|
||||
|
||||
# Using llvm-link-shared due to libffi issues -- see #34486
|
||||
ENV RUST_CONFIGURE_ARGS \
|
||||
--build=x86_64-unknown-linux-gnu \
|
||||
--llvm-root=/usr/lib/llvm-14 \
|
||||
--enable-llvm-link-shared \
|
||||
--set rust.thin-lto-import-instr-limit=10
|
||||
|
||||
COPY host-x86_64/x86_64-gnu-llvm-14/script.sh /tmp/
|
||||
|
||||
ENV SCRIPT /tmp/script.sh
|
@ -1,4 +1,4 @@
|
||||
FROM ubuntu:22.10
|
||||
FROM ubuntu:22.04
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
@ -10,7 +10,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
file \
|
||||
curl \
|
||||
ca-certificates \
|
||||
python3 \
|
||||
python3.11 \
|
||||
git \
|
||||
cmake \
|
||||
sudo \
|
||||
@ -49,20 +49,6 @@ ENV RUST_CONFIGURE_ARGS \
|
||||
--enable-llvm-link-shared \
|
||||
--set rust.thin-lto-import-instr-limit=10
|
||||
|
||||
# NOTE: intentionally uses all of `x.py`, `x`, and `x.ps1` to make sure they all work on Linux.
|
||||
ENV SCRIPT ../x.py --stage 2 test --exclude src/tools/tidy && \
|
||||
# Run the `mir-opt` tests again but this time for a 32-bit target.
|
||||
# This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have
|
||||
# both 32-bit and 64-bit outputs updated by the PR author, before
|
||||
# the PR is approved and tested for merging.
|
||||
# It will also detect tests lacking `// EMIT_MIR_FOR_EACH_BIT_WIDTH`,
|
||||
# despite having different output on 32-bit vs 64-bit targets.
|
||||
../x --stage 2 test tests/mir-opt \
|
||||
--host='' --target=i686-unknown-linux-gnu && \
|
||||
# Run the UI test suite again, but in `--pass=check` mode
|
||||
#
|
||||
# This is intended to make sure that both `--pass=check` continues to
|
||||
# work.
|
||||
#
|
||||
../x.ps1 --stage 2 test tests/ui --pass=check \
|
||||
--host='' --target=i686-unknown-linux-gnu
|
||||
COPY host-x86_64/x86_64-gnu-llvm-15/script.sh /tmp/
|
||||
|
||||
ENV SCRIPT /tmp/script.sh
|
||||
|
@ -45,20 +45,6 @@ ENV RUST_CONFIGURE_ARGS \
|
||||
--enable-llvm-link-shared \
|
||||
--set rust.thin-lto-import-instr-limit=10
|
||||
|
||||
# NOTE: intentionally uses all of `x.py`, `x`, and `x.ps1` to make sure they all work on Linux.
|
||||
ENV SCRIPT ../x.py --stage 2 test --exclude src/tools/tidy && \
|
||||
# Run the `mir-opt` tests again but this time for a 32-bit target.
|
||||
# This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have
|
||||
# both 32-bit and 64-bit outputs updated by the PR author, before
|
||||
# the PR is approved and tested for merging.
|
||||
# It will also detect tests lacking `// EMIT_MIR_FOR_EACH_BIT_WIDTH`,
|
||||
# despite having different output on 32-bit vs 64-bit targets.
|
||||
../x --stage 2 test tests/mir-opt \
|
||||
--host='' --target=i686-unknown-linux-gnu && \
|
||||
# Run the UI test suite again, but in `--pass=check` mode
|
||||
#
|
||||
# This is intended to make sure that both `--pass=check` continues to
|
||||
# work.
|
||||
#
|
||||
../x.ps1 --stage 2 test tests/ui --pass=check \
|
||||
--host='' --target=i686-unknown-linux-gnu
|
||||
COPY host-x86_64/x86_64-gnu-llvm-15/script.sh /tmp/
|
||||
|
||||
ENV SCRIPT /tmp/script.sh
|
||||
|
@ -323,7 +323,7 @@ jobs:
|
||||
- name: mingw-check-tidy
|
||||
<<: *job-linux-16c
|
||||
|
||||
- name: x86_64-gnu-llvm-14
|
||||
- name: x86_64-gnu-llvm-15
|
||||
<<: *job-linux-16c
|
||||
|
||||
- name: x86_64-gnu-tools
|
||||
@ -469,11 +469,6 @@ jobs:
|
||||
RUST_BACKTRACE: 1
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: x86_64-gnu-llvm-14
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
<<: *job-linux-8c
|
||||
|
||||
- name: x86_64-gnu-nopt
|
||||
<<: *job-linux-4c
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
// assembly-output: emit-asm
|
||||
// min-llvm-version: 15.0
|
||||
// only-x86_64
|
||||
// ignore-sgx
|
||||
// revisions: opt-speed opt-size
|
||||
|
@ -3,7 +3,6 @@
|
||||
// [LIN] only-linux
|
||||
// assembly-output: emit-asm
|
||||
// compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel
|
||||
// min-llvm-version: 14
|
||||
// only-x86_64
|
||||
// ignore-sgx
|
||||
// ignore-debug
|
||||
|
@ -2,7 +2,6 @@
|
||||
// compile-flags: -Copt-level=1
|
||||
// only-x86_64
|
||||
// ignore-sgx
|
||||
// min-llvm-version: 15.0
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
// CHECK-LABEL: old_style
|
||||
|
@ -7,4 +7,4 @@
|
||||
fn main() {
|
||||
}
|
||||
|
||||
// CHECK: define{{( hidden)?}} i32 @main(i32{{( %0)?}}, {{i8\*\*|ptr}}{{( %1)?}})
|
||||
// CHECK: define{{( hidden)?}} i32 @main(i32{{( %0)?}}, ptr{{( %1)?}})
|
||||
|
@ -1,5 +1,4 @@
|
||||
// compile-flags: -C opt-level=3 -C no-prepopulate-passes
|
||||
// min-llvm-version: 15.0 (for opaque pointers)
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
@ -13,9 +13,9 @@ pub fn helper(_: usize) {
|
||||
pub fn no_op_slice_adjustment(x: &[u8]) -> &[u8] {
|
||||
// We used to generate an extra alloca and memcpy for the block's trailing expression value, so
|
||||
// check that we copy directly to the return value slot
|
||||
// CHECK: %0 = insertvalue { {{\[0 x i8\]\*|ptr}}, [[USIZE]] } poison, {{\[0 x i8\]\*|ptr}} %x.0, 0
|
||||
// CHECK: %1 = insertvalue { {{\[0 x i8\]\*|ptr}}, [[USIZE]] } %0, [[USIZE]] %x.1, 1
|
||||
// CHECK: ret { {{\[0 x i8\]\*|ptr}}, [[USIZE]] } %1
|
||||
// CHECK: %0 = insertvalue { ptr, [[USIZE]] } poison, ptr %x.0, 0
|
||||
// CHECK: %1 = insertvalue { ptr, [[USIZE]] } %0, [[USIZE]] %x.1, 1
|
||||
// CHECK: ret { ptr, [[USIZE]] } %1
|
||||
{ x }
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ pub struct Nested64 {
|
||||
#[no_mangle]
|
||||
pub fn align64(a: u32) -> Align64 {
|
||||
// CHECK: %a64 = alloca %Align64, align 64
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 64 %{{.*}}, {{i8\*|ptr}} align 64 %{{.*}}, i{{[0-9]+}} 64, i1 false)
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 64 %{{.*}}, ptr align 64 %{{.*}}, i{{[0-9]+}} 64, i1 false)
|
||||
let a64 = Align64::A(a);
|
||||
a64
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
// compile-flags: -O
|
||||
// min-llvm-version: 15.0 (because we're using opaque pointers)
|
||||
// ignore-debug (debug assertions in `slice::from_raw_parts` block optimizations)
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
@ -32,7 +32,7 @@ pub enum Enum64 {
|
||||
#[no_mangle]
|
||||
pub fn align64(i : i32) -> Align64 {
|
||||
// CHECK: %a64 = alloca %Align64, align 64
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 64 %{{.*}}, {{i8\*|ptr}} align 64 %{{.*}}, i{{[0-9]+}} 64, i1 false)
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 64 %{{.*}}, ptr align 64 %{{.*}}, i{{[0-9]+}} 64, i1 false)
|
||||
let a64 = Align64(i);
|
||||
a64
|
||||
}
|
||||
@ -42,7 +42,7 @@ pub fn align64(i : i32) -> Align64 {
|
||||
// CHECK-LABEL: @align64_load
|
||||
#[no_mangle]
|
||||
pub fn align64_load(a: Align64) -> i32 {
|
||||
// CHECK: {{%.*}} = load i32, {{i32\*|ptr}} {{%.*}}, align 64
|
||||
// CHECK: {{%.*}} = load i32, ptr {{%.*}}, align 64
|
||||
a.0
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
// compile-flags: -O -C no-prepopulate-passes
|
||||
// min-llvm-version: 15.0 (for opaque pointers)
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
@ -16,8 +16,8 @@
|
||||
#[no_mangle]
|
||||
pub fn array_eq_ref(a: &[u16; 3], b: &[u16; 3]) -> bool {
|
||||
// CHECK: start:
|
||||
// CHECK: load i48, {{i48\*|ptr}} %{{.+}}, align 2
|
||||
// CHECK: load i48, {{i48\*|ptr}} %{{.+}}, align 2
|
||||
// CHECK: load i48, ptr %{{.+}}, align 2
|
||||
// CHECK: load i48, ptr %{{.+}}, align 2
|
||||
// CHECK: icmp eq i48
|
||||
// CHECK-NEXT: ret
|
||||
a == b
|
||||
@ -27,7 +27,7 @@
|
||||
#[no_mangle]
|
||||
pub fn array_eq_value_still_passed_by_pointer(a: [u16; 9], b: [u16; 9]) -> bool {
|
||||
// CHECK-NEXT: start:
|
||||
// CHECK: %[[CMP:.+]] = tail call i32 @{{bcmp|memcmp}}({{i8\*|ptr}} {{.*}} dereferenceable(18) %{{.+}}, {{i8\*|ptr}} {{.*}} dereferenceable(18) %{{.+}}, i64 18)
|
||||
// CHECK: %[[CMP:.+]] = tail call i32 @{{bcmp|memcmp}}(ptr {{.*}} dereferenceable(18) %{{.+}}, ptr {{.*}} dereferenceable(18) %{{.+}}, i64 18)
|
||||
// CHECK-NEXT: %[[EQ:.+]] = icmp eq i32 %[[CMP]], 0
|
||||
// CHECK-NEXT: ret i1 %[[EQ]]
|
||||
a == b
|
||||
@ -37,7 +37,7 @@
|
||||
#[no_mangle]
|
||||
pub fn array_eq_long(a: &[u16; 1234], b: &[u16; 1234]) -> bool {
|
||||
// CHECK-NEXT: start:
|
||||
// CHECK: %[[CMP:.+]] = tail call i32 @{{bcmp|memcmp}}({{i8\*|ptr}} {{.*}} dereferenceable(2468) %{{.+}}, {{i8\*|ptr}} {{.*}} dereferenceable(2468) %{{.+}}, i64 2468)
|
||||
// CHECK: %[[CMP:.+]] = tail call i32 @{{bcmp|memcmp}}(ptr {{.*}} dereferenceable(2468) %{{.+}}, ptr {{.*}} dereferenceable(2468) %{{.+}}, i64 2468)
|
||||
// CHECK-NEXT: %[[EQ:.+]] = icmp eq i32 %[[CMP]], 0
|
||||
// CHECK-NEXT: ret i1 %[[EQ]]
|
||||
a == b
|
||||
|
@ -7,37 +7,37 @@
|
||||
// CHECK-LABEL: @compare_exchange
|
||||
#[no_mangle]
|
||||
pub fn compare_exchange(a: &AtomicI32) {
|
||||
// CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 10 monotonic monotonic
|
||||
// CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 11 monotonic acquire
|
||||
// CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 12 monotonic seq_cst
|
||||
// CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 10 monotonic monotonic
|
||||
// CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 11 monotonic acquire
|
||||
// CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 12 monotonic seq_cst
|
||||
let _ = a.compare_exchange(0, 10, Relaxed, Relaxed);
|
||||
let _ = a.compare_exchange(0, 11, Relaxed, Acquire);
|
||||
let _ = a.compare_exchange(0, 12, Relaxed, SeqCst);
|
||||
|
||||
// CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 20 release monotonic
|
||||
// CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 21 release acquire
|
||||
// CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 22 release seq_cst
|
||||
// CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 20 release monotonic
|
||||
// CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 21 release acquire
|
||||
// CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 22 release seq_cst
|
||||
let _ = a.compare_exchange(0, 20, Release, Relaxed);
|
||||
let _ = a.compare_exchange(0, 21, Release, Acquire);
|
||||
let _ = a.compare_exchange(0, 22, Release, SeqCst);
|
||||
|
||||
// CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 30 acquire monotonic
|
||||
// CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 31 acquire acquire
|
||||
// CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 32 acquire seq_cst
|
||||
// CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 30 acquire monotonic
|
||||
// CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 31 acquire acquire
|
||||
// CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 32 acquire seq_cst
|
||||
let _ = a.compare_exchange(0, 30, Acquire, Relaxed);
|
||||
let _ = a.compare_exchange(0, 31, Acquire, Acquire);
|
||||
let _ = a.compare_exchange(0, 32, Acquire, SeqCst);
|
||||
|
||||
// CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 40 acq_rel monotonic
|
||||
// CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 41 acq_rel acquire
|
||||
// CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 42 acq_rel seq_cst
|
||||
// CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 40 acq_rel monotonic
|
||||
// CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 41 acq_rel acquire
|
||||
// CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 42 acq_rel seq_cst
|
||||
let _ = a.compare_exchange(0, 40, AcqRel, Relaxed);
|
||||
let _ = a.compare_exchange(0, 41, AcqRel, Acquire);
|
||||
let _ = a.compare_exchange(0, 42, AcqRel, SeqCst);
|
||||
|
||||
// CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 50 seq_cst monotonic
|
||||
// CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 51 seq_cst acquire
|
||||
// CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 52 seq_cst seq_cst
|
||||
// CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 50 seq_cst monotonic
|
||||
// CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 51 seq_cst acquire
|
||||
// CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 52 seq_cst seq_cst
|
||||
let _ = a.compare_exchange(0, 50, SeqCst, Relaxed);
|
||||
let _ = a.compare_exchange(0, 51, SeqCst, Acquire);
|
||||
let _ = a.compare_exchange(0, 52, SeqCst, SeqCst);
|
||||
@ -46,37 +46,37 @@ pub fn compare_exchange(a: &AtomicI32) {
|
||||
// CHECK-LABEL: @compare_exchange_weak
|
||||
#[no_mangle]
|
||||
pub fn compare_exchange_weak(w: &AtomicI32) {
|
||||
// CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 10 monotonic monotonic
|
||||
// CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 11 monotonic acquire
|
||||
// CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 12 monotonic seq_cst
|
||||
// CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 10 monotonic monotonic
|
||||
// CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 11 monotonic acquire
|
||||
// CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 12 monotonic seq_cst
|
||||
let _ = w.compare_exchange_weak(1, 10, Relaxed, Relaxed);
|
||||
let _ = w.compare_exchange_weak(1, 11, Relaxed, Acquire);
|
||||
let _ = w.compare_exchange_weak(1, 12, Relaxed, SeqCst);
|
||||
|
||||
// CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 20 release monotonic
|
||||
// CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 21 release acquire
|
||||
// CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 22 release seq_cst
|
||||
// CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 20 release monotonic
|
||||
// CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 21 release acquire
|
||||
// CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 22 release seq_cst
|
||||
let _ = w.compare_exchange_weak(1, 20, Release, Relaxed);
|
||||
let _ = w.compare_exchange_weak(1, 21, Release, Acquire);
|
||||
let _ = w.compare_exchange_weak(1, 22, Release, SeqCst);
|
||||
|
||||
// CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 30 acquire monotonic
|
||||
// CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 31 acquire acquire
|
||||
// CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 32 acquire seq_cst
|
||||
// CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 30 acquire monotonic
|
||||
// CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 31 acquire acquire
|
||||
// CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 32 acquire seq_cst
|
||||
let _ = w.compare_exchange_weak(1, 30, Acquire, Relaxed);
|
||||
let _ = w.compare_exchange_weak(1, 31, Acquire, Acquire);
|
||||
let _ = w.compare_exchange_weak(1, 32, Acquire, SeqCst);
|
||||
|
||||
// CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 40 acq_rel monotonic
|
||||
// CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 41 acq_rel acquire
|
||||
// CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 42 acq_rel seq_cst
|
||||
// CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 40 acq_rel monotonic
|
||||
// CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 41 acq_rel acquire
|
||||
// CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 42 acq_rel seq_cst
|
||||
let _ = w.compare_exchange_weak(1, 40, AcqRel, Relaxed);
|
||||
let _ = w.compare_exchange_weak(1, 41, AcqRel, Acquire);
|
||||
let _ = w.compare_exchange_weak(1, 42, AcqRel, SeqCst);
|
||||
|
||||
// CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 50 seq_cst monotonic
|
||||
// CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 51 seq_cst acquire
|
||||
// CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 52 seq_cst seq_cst
|
||||
// CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 50 seq_cst monotonic
|
||||
// CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 51 seq_cst acquire
|
||||
// CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 52 seq_cst seq_cst
|
||||
let _ = w.compare_exchange_weak(1, 50, SeqCst, Relaxed);
|
||||
let _ = w.compare_exchange_weak(1, 51, SeqCst, Acquire);
|
||||
let _ = w.compare_exchange_weak(1, 52, SeqCst, SeqCst);
|
||||
|
@ -94,7 +94,7 @@ pub extern "C" fn test() {
|
||||
|
||||
// Validate that we can codegen transmutes between data ptrs and fn ptrs.
|
||||
|
||||
// CHECK: define{{.+}}{{void \(\) addrspace\(1\)\*|ptr addrspace\(1\)}} @transmute_data_ptr_to_fn({{\{\}\*|ptr}}{{.*}} %x)
|
||||
// CHECK: define{{.+}}ptr addrspace(1) @transmute_data_ptr_to_fn(ptr{{.*}} %x)
|
||||
#[no_mangle]
|
||||
pub unsafe fn transmute_data_ptr_to_fn(x: *const ()) -> fn() {
|
||||
// It doesn't matter precisely how this is codegenned (through memory or an addrspacecast),
|
||||
@ -102,7 +102,7 @@ pub unsafe fn transmute_data_ptr_to_fn(x: *const ()) -> fn() {
|
||||
transmute(x)
|
||||
}
|
||||
|
||||
// CHECK: define{{.+}}{{\{\}\*|ptr}} @transmute_fn_ptr_to_data({{void \(\) addrspace\(1\)\*|ptr addrspace\(1\)}}{{.*}} %x)
|
||||
// CHECK: define{{.+}}ptr @transmute_fn_ptr_to_data(ptr addrspace(1){{.*}} %x)
|
||||
#[no_mangle]
|
||||
pub unsafe fn transmute_fn_ptr_to_data(x: fn()) -> *const () {
|
||||
// It doesn't matter precisely how this is codegenned (through memory or an addrspacecast),
|
||||
@ -116,7 +116,7 @@ pub enum Either<T, U> { A(T), B(U) }
|
||||
// with the `ptr` field representing both `&i32` and `fn()` depending on the variant.
|
||||
// This is incorrect, because `fn()` should be `ptr addrspace(1)`, not `ptr`.
|
||||
|
||||
// CHECK: define{{.+}}void @should_not_combine_addrspace({{.+\*|ptr}}{{.+}}sret{{.+}}%_0, {{.+\*|ptr}}{{.+}}%x)
|
||||
// CHECK: define{{.+}}void @should_not_combine_addrspace(ptr{{.+}}sret{{.+}}%_0, ptr{{.+}}%x)
|
||||
#[no_mangle]
|
||||
#[inline(never)]
|
||||
pub fn should_not_combine_addrspace(x: Either<&i32, fn()>) -> Either<&i32, fn()> {
|
||||
|
@ -1,5 +1,4 @@
|
||||
// compile-flags: -O
|
||||
// min-llvm-version: 15.0
|
||||
#![crate_type = "lib"]
|
||||
|
||||
use std::mem::MaybeUninit;
|
||||
|
@ -1,5 +1,4 @@
|
||||
// compile-flags: -C opt-level=1 -Z merge-functions=disabled
|
||||
// min-llvm-version: 15.0
|
||||
// only-x86_64
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
@ -3,7 +3,6 @@
|
||||
// in the operators for such a type all optimize away.
|
||||
|
||||
// compile-flags: -C opt-level=1
|
||||
// min-llvm-version: 15.0
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
// compile-flags: -C no-prepopulate-passes
|
||||
// min-llvm-version: 15.0 (for opaque pointers)
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
@ -7,9 +7,9 @@
|
||||
|
||||
use std::marker::PhantomPinned;
|
||||
|
||||
// CHECK: define internal void @{{.*}}core{{.*}}ptr{{.*}}drop_in_place{{.*}}StructUnpin{{.*}}({{.*\*|ptr}} noalias noundef align 4 dereferenceable(12) %{{.+}})
|
||||
// CHECK: define internal void @{{.*}}core{{.*}}ptr{{.*}}drop_in_place{{.*}}StructUnpin{{.*}}(ptr noalias noundef align 4 dereferenceable(12) %{{.+}})
|
||||
|
||||
// CHECK: define internal void @{{.*}}core{{.*}}ptr{{.*}}drop_in_place{{.*}}StructNotUnpin{{.*}}({{.*\*|ptr}} noundef nonnull align 4 %{{.+}})
|
||||
// CHECK: define internal void @{{.*}}core{{.*}}ptr{{.*}}drop_in_place{{.*}}StructNotUnpin{{.*}}(ptr noundef nonnull align 4 %{{.+}})
|
||||
|
||||
pub struct StructUnpin {
|
||||
a: i32,
|
||||
|
@ -19,7 +19,7 @@ pub mod tests {
|
||||
#[no_mangle]
|
||||
pub extern "fastcall" fn f1(_: i32, _: i32, _: i32) {}
|
||||
|
||||
// CHECK: @f2({{i32\*|ptr}} inreg noundef %_1, {{i32\*|ptr}} inreg noundef %_2, {{i32\*|ptr}} noundef %_3)
|
||||
// CHECK: @f2(ptr inreg noundef %_1, ptr inreg noundef %_2, ptr noundef %_3)
|
||||
#[no_mangle]
|
||||
pub extern "fastcall" fn f2(_: *const i32, _: *const i32, _: *const i32) {}
|
||||
|
||||
|
@ -23,13 +23,13 @@ pub fn boolean_call(x: bool, f: fn(bool) -> bool) -> bool {
|
||||
f(x)
|
||||
}
|
||||
|
||||
// CHECK: align 4 {{i32\*|ptr}} @borrow({{i32\*|ptr}} align 4 %x)
|
||||
// CHECK: align 4 ptr @borrow(ptr align 4 %x)
|
||||
#[no_mangle]
|
||||
pub fn borrow(x: &i32) -> &i32 {
|
||||
x
|
||||
}
|
||||
|
||||
// CHECK: align 4 {{i32\*|ptr}} @borrow_mut({{i32\*|ptr}} align 4 %x)
|
||||
// CHECK: align 4 ptr @borrow_mut(ptr align 4 %x)
|
||||
#[no_mangle]
|
||||
pub fn borrow_mut(x: &mut i32) -> &mut i32 {
|
||||
x
|
||||
@ -38,11 +38,11 @@ pub fn borrow_mut(x: &mut i32) -> &mut i32 {
|
||||
// CHECK-LABEL: @borrow_call
|
||||
#[no_mangle]
|
||||
pub fn borrow_call(x: &i32, f: fn(&i32) -> &i32) -> &i32 {
|
||||
// CHECK: call align 4 {{i32\*|ptr}} %f({{i32\*|ptr}} align 4 %x)
|
||||
// CHECK: call align 4 ptr %f(ptr align 4 %x)
|
||||
f(x)
|
||||
}
|
||||
|
||||
// CHECK: void @struct_({{%S\*|ptr}} sret(%S) align 4{{( %_0)?}}, {{%S\*|ptr}} align 4 %x)
|
||||
// CHECK: void @struct_(ptr sret(%S) align 4{{( %_0)?}}, ptr align 4 %x)
|
||||
#[no_mangle]
|
||||
pub fn struct_(x: S) -> S {
|
||||
x
|
||||
@ -51,7 +51,7 @@ pub fn struct_(x: S) -> S {
|
||||
// CHECK-LABEL: @struct_call
|
||||
#[no_mangle]
|
||||
pub fn struct_call(x: S, f: fn(S) -> S) -> S {
|
||||
// CHECK: call void %f({{%S\*|ptr}} sret(%S) align 4{{( %_0)?}}, {{%S\*|ptr}} align 4 %{{.+}})
|
||||
// CHECK: call void %f(ptr sret(%S) align 4{{( %_0)?}}, ptr align 4 %{{.+}})
|
||||
f(x)
|
||||
}
|
||||
|
||||
|
@ -80,95 +80,95 @@ pub fn option_nonzero_int(x: Option<NonZeroU64>) -> Option<NonZeroU64> {
|
||||
x
|
||||
}
|
||||
|
||||
// CHECK: @readonly_borrow({{i32\*|ptr}} noalias noundef readonly align 4 dereferenceable(4) %_1)
|
||||
// CHECK: @readonly_borrow(ptr noalias noundef readonly align 4 dereferenceable(4) %_1)
|
||||
// FIXME #25759 This should also have `nocapture`
|
||||
#[no_mangle]
|
||||
pub fn readonly_borrow(_: &i32) {
|
||||
}
|
||||
|
||||
// CHECK: noundef align 4 dereferenceable(4) {{i32\*|ptr}} @readonly_borrow_ret()
|
||||
// CHECK: noundef align 4 dereferenceable(4) ptr @readonly_borrow_ret()
|
||||
#[no_mangle]
|
||||
pub fn readonly_borrow_ret() -> &'static i32 {
|
||||
loop {}
|
||||
}
|
||||
|
||||
// CHECK: @static_borrow({{i32\*|ptr}} noalias noundef readonly align 4 dereferenceable(4) %_1)
|
||||
// CHECK: @static_borrow(ptr noalias noundef readonly align 4 dereferenceable(4) %_1)
|
||||
// static borrow may be captured
|
||||
#[no_mangle]
|
||||
pub fn static_borrow(_: &'static i32) {
|
||||
}
|
||||
|
||||
// CHECK: @named_borrow({{i32\*|ptr}} noalias noundef readonly align 4 dereferenceable(4) %_1)
|
||||
// CHECK: @named_borrow(ptr noalias noundef readonly align 4 dereferenceable(4) %_1)
|
||||
// borrow with named lifetime may be captured
|
||||
#[no_mangle]
|
||||
pub fn named_borrow<'r>(_: &'r i32) {
|
||||
}
|
||||
|
||||
// CHECK: @unsafe_borrow({{i16\*|ptr}} noundef nonnull align 2 %_1)
|
||||
// CHECK: @unsafe_borrow(ptr noundef nonnull align 2 %_1)
|
||||
// unsafe interior means this isn't actually readonly and there may be aliases ...
|
||||
#[no_mangle]
|
||||
pub fn unsafe_borrow(_: &UnsafeInner) {
|
||||
}
|
||||
|
||||
// CHECK: @mutable_unsafe_borrow({{i16\*|ptr}} noalias noundef align 2 dereferenceable(2) %_1)
|
||||
// CHECK: @mutable_unsafe_borrow(ptr noalias noundef align 2 dereferenceable(2) %_1)
|
||||
// ... unless this is a mutable borrow, those never alias
|
||||
#[no_mangle]
|
||||
pub fn mutable_unsafe_borrow(_: &mut UnsafeInner) {
|
||||
}
|
||||
|
||||
// CHECK: @mutable_borrow({{i32\*|ptr}} noalias noundef align 4 dereferenceable(4) %_1)
|
||||
// CHECK: @mutable_borrow(ptr noalias noundef align 4 dereferenceable(4) %_1)
|
||||
// FIXME #25759 This should also have `nocapture`
|
||||
#[no_mangle]
|
||||
pub fn mutable_borrow(_: &mut i32) {
|
||||
}
|
||||
|
||||
// CHECK: noundef align 4 dereferenceable(4) {{i32\*|ptr}} @mutable_borrow_ret()
|
||||
// CHECK: noundef align 4 dereferenceable(4) ptr @mutable_borrow_ret()
|
||||
#[no_mangle]
|
||||
pub fn mutable_borrow_ret() -> &'static mut i32 {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
// CHECK: @mutable_notunpin_borrow({{i32\*|ptr}} noundef nonnull align 4 %_1)
|
||||
// CHECK: @mutable_notunpin_borrow(ptr noundef nonnull align 4 %_1)
|
||||
// This one is *not* `noalias` because it might be self-referential.
|
||||
// It is also not `dereferenceable` due to
|
||||
// <https://github.com/rust-lang/unsafe-code-guidelines/issues/381>.
|
||||
pub fn mutable_notunpin_borrow(_: &mut NotUnpin) {
|
||||
}
|
||||
|
||||
// CHECK: @notunpin_borrow({{i32\*|ptr}} noalias noundef readonly align 4 dereferenceable(4) %_1)
|
||||
// CHECK: @notunpin_borrow(ptr noalias noundef readonly align 4 dereferenceable(4) %_1)
|
||||
// But `&NotUnpin` behaves perfectly normal.
|
||||
#[no_mangle]
|
||||
pub fn notunpin_borrow(_: &NotUnpin) {
|
||||
}
|
||||
|
||||
// CHECK: @indirect_struct({{%S\*|ptr}} noalias nocapture noundef readonly align 4 dereferenceable(32) %_1)
|
||||
// CHECK: @indirect_struct(ptr noalias nocapture noundef readonly align 4 dereferenceable(32) %_1)
|
||||
#[no_mangle]
|
||||
pub fn indirect_struct(_: S) {
|
||||
}
|
||||
|
||||
// CHECK: @borrowed_struct({{%S\*|ptr}} noalias noundef readonly align 4 dereferenceable(32) %_1)
|
||||
// CHECK: @borrowed_struct(ptr noalias noundef readonly align 4 dereferenceable(32) %_1)
|
||||
// FIXME #25759 This should also have `nocapture`
|
||||
#[no_mangle]
|
||||
pub fn borrowed_struct(_: &S) {
|
||||
}
|
||||
|
||||
// CHECK: @option_borrow({{i32\*|ptr}} noalias noundef readonly align 4 dereferenceable_or_null(4) %x)
|
||||
// CHECK: @option_borrow(ptr noalias noundef readonly align 4 dereferenceable_or_null(4) %x)
|
||||
#[no_mangle]
|
||||
pub fn option_borrow(x: Option<&i32>) {
|
||||
}
|
||||
|
||||
// CHECK: @option_borrow_mut({{i32\*|ptr}} noalias noundef align 4 dereferenceable_or_null(4) %x)
|
||||
// CHECK: @option_borrow_mut(ptr noalias noundef align 4 dereferenceable_or_null(4) %x)
|
||||
#[no_mangle]
|
||||
pub fn option_borrow_mut(x: Option<&mut i32>) {
|
||||
}
|
||||
|
||||
// CHECK: @raw_struct({{%S\*|ptr}} noundef %_1)
|
||||
// CHECK: @raw_struct(ptr noundef %_1)
|
||||
#[no_mangle]
|
||||
pub fn raw_struct(_: *const S) {
|
||||
}
|
||||
|
||||
// CHECK: @raw_option_nonnull_struct({{i32\*|ptr}} noundef %_1)
|
||||
// CHECK: @raw_option_nonnull_struct(ptr noundef %_1)
|
||||
#[no_mangle]
|
||||
pub fn raw_option_nonnull_struct(_: Option<NonNull<S>>) {
|
||||
}
|
||||
@ -176,19 +176,19 @@ pub fn raw_option_nonnull_struct(_: Option<NonNull<S>>) {
|
||||
|
||||
// `Box` can get deallocated during execution of the function, so it should
|
||||
// not get `dereferenceable`.
|
||||
// CHECK: noundef nonnull align 4 {{i32\*|ptr}} @_box({{i32\*|ptr}} noalias noundef nonnull align 4 %x)
|
||||
// CHECK: noundef nonnull align 4 ptr @_box(ptr noalias noundef nonnull align 4 %x)
|
||||
#[no_mangle]
|
||||
pub fn _box(x: Box<i32>) -> Box<i32> {
|
||||
x
|
||||
}
|
||||
|
||||
// CHECK: noundef nonnull align 4 {{i32\*|ptr}} @notunpin_box({{i32\*|ptr}} noundef nonnull align 4 %x)
|
||||
// CHECK: noundef nonnull align 4 ptr @notunpin_box(ptr noundef nonnull align 4 %x)
|
||||
#[no_mangle]
|
||||
pub fn notunpin_box(x: Box<NotUnpin>) -> Box<NotUnpin> {
|
||||
x
|
||||
}
|
||||
|
||||
// CHECK: @struct_return({{%S\*|ptr}} noalias nocapture noundef sret(%S) align 4 dereferenceable(32){{( %_0)?}})
|
||||
// CHECK: @struct_return(ptr noalias nocapture noundef sret(%S) align 4 dereferenceable(32){{( %_0)?}})
|
||||
#[no_mangle]
|
||||
pub fn struct_return() -> S {
|
||||
S {
|
||||
@ -202,68 +202,68 @@ pub fn struct_return() -> S {
|
||||
pub fn helper(_: usize) {
|
||||
}
|
||||
|
||||
// CHECK: @slice({{\[0 x i8\]\*|ptr}} noalias noundef nonnull readonly align 1 %_1.0, [[USIZE]] noundef %_1.1)
|
||||
// CHECK: @slice(ptr noalias noundef nonnull readonly align 1 %_1.0, [[USIZE]] noundef %_1.1)
|
||||
// FIXME #25759 This should also have `nocapture`
|
||||
#[no_mangle]
|
||||
pub fn slice(_: &[u8]) {
|
||||
}
|
||||
|
||||
// CHECK: @mutable_slice({{\[0 x i8\]\*|ptr}} noalias noundef nonnull align 1 %_1.0, [[USIZE]] noundef %_1.1)
|
||||
// CHECK: @mutable_slice(ptr noalias noundef nonnull align 1 %_1.0, [[USIZE]] noundef %_1.1)
|
||||
// FIXME #25759 This should also have `nocapture`
|
||||
#[no_mangle]
|
||||
pub fn mutable_slice(_: &mut [u8]) {
|
||||
}
|
||||
|
||||
// CHECK: @unsafe_slice({{\[0 x i16\]\*|ptr}} noundef nonnull align 2 %_1.0, [[USIZE]] noundef %_1.1)
|
||||
// CHECK: @unsafe_slice(ptr noundef nonnull align 2 %_1.0, [[USIZE]] noundef %_1.1)
|
||||
// unsafe interior means this isn't actually readonly and there may be aliases ...
|
||||
#[no_mangle]
|
||||
pub fn unsafe_slice(_: &[UnsafeInner]) {
|
||||
}
|
||||
|
||||
// CHECK: @raw_slice({{\[0 x i8\]\*|ptr}} noundef %_1.0, [[USIZE]] noundef %_1.1)
|
||||
// CHECK: @raw_slice(ptr noundef %_1.0, [[USIZE]] noundef %_1.1)
|
||||
#[no_mangle]
|
||||
pub fn raw_slice(_: *const [u8]) {
|
||||
}
|
||||
|
||||
// CHECK: @str({{\[0 x i8\]\*|ptr}} noalias noundef nonnull readonly align 1 %_1.0, [[USIZE]] noundef %_1.1)
|
||||
// CHECK: @str(ptr noalias noundef nonnull readonly align 1 %_1.0, [[USIZE]] noundef %_1.1)
|
||||
// FIXME #25759 This should also have `nocapture`
|
||||
#[no_mangle]
|
||||
pub fn str(_: &[u8]) {
|
||||
}
|
||||
|
||||
// CHECK: @trait_borrow({{\{\}\*|ptr}} noundef nonnull align 1 %_1.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %_1.1)
|
||||
// CHECK: @trait_borrow(ptr noundef nonnull align 1 %_1.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %_1.1)
|
||||
// FIXME #25759 This should also have `nocapture`
|
||||
#[no_mangle]
|
||||
pub fn trait_borrow(_: &dyn Drop) {
|
||||
}
|
||||
|
||||
// CHECK: @option_trait_borrow({{i8\*|ptr}} noundef align 1 %x.0, {{i8\*|ptr}} %x.1)
|
||||
// CHECK: @option_trait_borrow(ptr noundef align 1 %x.0, ptr %x.1)
|
||||
#[no_mangle]
|
||||
pub fn option_trait_borrow(x: Option<&dyn Drop>) {
|
||||
}
|
||||
|
||||
// CHECK: @option_trait_borrow_mut({{i8\*|ptr}} noundef align 1 %x.0, {{i8\*|ptr}} %x.1)
|
||||
// CHECK: @option_trait_borrow_mut(ptr noundef align 1 %x.0, ptr %x.1)
|
||||
#[no_mangle]
|
||||
pub fn option_trait_borrow_mut(x: Option<&mut dyn Drop>) {
|
||||
}
|
||||
|
||||
// CHECK: @trait_raw({{\{\}\*|ptr}} noundef %_1.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %_1.1)
|
||||
// CHECK: @trait_raw(ptr noundef %_1.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %_1.1)
|
||||
#[no_mangle]
|
||||
pub fn trait_raw(_: *const dyn Drop) {
|
||||
}
|
||||
|
||||
// CHECK: @trait_box({{\{\}\*|ptr}} noalias noundef nonnull align 1{{( %0)?}}, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}){{( %1)?}})
|
||||
// CHECK: @trait_box(ptr noalias noundef nonnull align 1{{( %0)?}}, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}){{( %1)?}})
|
||||
#[no_mangle]
|
||||
pub fn trait_box(_: Box<dyn Drop + Unpin>) {
|
||||
}
|
||||
|
||||
// CHECK: { {{i8\*|ptr}}, {{i8\*|ptr}} } @trait_option({{i8\*|ptr}} noalias noundef align 1 %x.0, {{i8\*|ptr}} %x.1)
|
||||
// CHECK: { ptr, ptr } @trait_option(ptr noalias noundef align 1 %x.0, ptr %x.1)
|
||||
#[no_mangle]
|
||||
pub fn trait_option(x: Option<Box<dyn Drop + Unpin>>) -> Option<Box<dyn Drop + Unpin>> {
|
||||
x
|
||||
}
|
||||
|
||||
// CHECK: { {{\[0 x i16\]\*|ptr}}, [[USIZE]] } @return_slice({{\[0 x i16\]\*|ptr}} noalias noundef nonnull readonly align 2 %x.0, [[USIZE]] noundef %x.1)
|
||||
// CHECK: { ptr, [[USIZE]] } @return_slice(ptr noalias noundef nonnull readonly align 2 %x.0, [[USIZE]] noundef %x.1)
|
||||
#[no_mangle]
|
||||
pub fn return_slice(x: &[u16]) -> &[u16] {
|
||||
x
|
||||
@ -281,7 +281,7 @@ pub fn enum_id_2(x: Option<u8>) -> Option<u8> {
|
||||
x
|
||||
}
|
||||
|
||||
// CHECK: { {{\{\}\*|ptr}}, {{.+}} } @dyn_star({{\{\}\*|ptr}} noundef %x.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %x.1)
|
||||
// CHECK: { ptr, {{.+}} } @dyn_star(ptr noundef %x.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %x.1)
|
||||
// Expect an ABI something like `{ {}*, [3 x i64]* }`, but that's hard to match on generically,
|
||||
// so do like the `trait_box` test and just match on `{{.+}}` for the vtable.
|
||||
#[no_mangle]
|
||||
|
@ -7,6 +7,6 @@
|
||||
#[no_mangle]
|
||||
pub fn mask_ptr(ptr: *const u16, mask: usize) -> *const u16 {
|
||||
// CHECK: call
|
||||
// CHECK-SAME: @llvm.ptrmask.{{p0|p0i8}}.[[WORD]]({{ptr|i8\*}} {{%ptr|%1}}, [[WORD]] %mask)
|
||||
// CHECK-SAME: @llvm.ptrmask.{{p0|p0i8}}.[[WORD]](ptr {{%ptr|%1}}, [[WORD]] %mask)
|
||||
core::intrinsics::ptr_mask(ptr, mask)
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
#[no_mangle]
|
||||
pub fn a(a: &mut u32, b: u32) {
|
||||
// CHECK-LABEL: define{{.*}}void @a
|
||||
// CHECK: store i32 %b, {{i32\*|ptr}} %a, align 4, !nontemporal
|
||||
// CHECK: store i32 %b, ptr %a, align 4, !nontemporal
|
||||
unsafe {
|
||||
std::intrinsics::nontemporal_store(a, b);
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
// compile-flags: -O -C no-prepopulate-passes
|
||||
// min-llvm-version: 15.0 (because we're using opaque pointers)
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(core_intrinsics)]
|
||||
|
@ -2,7 +2,6 @@
|
||||
// [OPT] compile-flags: -C opt-level=3 -C no-prepopulate-passes
|
||||
// [DBG] compile-flags: -C opt-level=0 -C no-prepopulate-passes
|
||||
// only-64bit (so I don't need to worry about usize)
|
||||
// min-llvm-version: 15.0 # this test assumes `ptr`s
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
// compile-flags: -O -C no-prepopulate-passes
|
||||
// only-x86_64 (it's using arch-specific types)
|
||||
// min-llvm-version: 15.0 # this test assumes `ptr`s
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
// compile-flags: -O -C no-prepopulate-passes
|
||||
// only-64bit (so I don't need to worry about usize)
|
||||
// min-llvm-version: 15.0 # this test assumes `ptr`s
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(core_intrinsics)]
|
||||
|
@ -1,6 +1,5 @@
|
||||
// compile-flags: --crate-type=lib -O -Cdebuginfo=2 -Cno-prepopulate-passes -Zmir-enable-passes=-ScalarReplacementOfAggregates
|
||||
// MIR SROA will decompose the closure
|
||||
// min-llvm-version: 15.0 # this test uses opaque pointer notation
|
||||
#![feature(stmt_expr_attributes)]
|
||||
|
||||
pub struct S([usize; 8]);
|
||||
@ -16,8 +15,8 @@ pub fn outer_function(x: S, y: S) -> usize {
|
||||
// Check that we do not attempt to load from the spilled arg before it is assigned to
|
||||
// when generating debuginfo.
|
||||
// CHECK-LABEL: @outer_function
|
||||
// CHECK: [[spill:%.*]] = alloca %"[closure@{{.*.rs}}:10:23: 10:25]"
|
||||
// CHECK-NOT: [[ptr_tmp:%.*]] = getelementptr inbounds %"[closure@{{.*.rs}}:10:23: 10:25]", ptr [[spill]]
|
||||
// CHECK: [[spill:%.*]] = alloca %"[closure@{{.*.rs}}:9:23: 9:25]"
|
||||
// CHECK-NOT: [[ptr_tmp:%.*]] = getelementptr inbounds %"[closure@{{.*.rs}}:9:23: 9:25]", ptr [[spill]]
|
||||
// CHECK-NOT: [[load:%.*]] = load ptr, ptr
|
||||
// CHECK: call void @llvm.lifetime.start{{.*}}({{.*}}, ptr [[spill]])
|
||||
// CHECK: [[inner:%.*]] = getelementptr inbounds %"{{.*}}", ptr [[spill]]
|
||||
|
@ -12,11 +12,11 @@
|
||||
pub fn is_empty_1(xs: Iter<f32>) -> bool {
|
||||
// CHECK-LABEL: @is_empty_1(
|
||||
// CHECK-NEXT: start:
|
||||
// CHECK-NEXT: [[A:%.*]] = icmp ne {{i32\*|ptr}} {{%xs.0|%xs.1}}, null
|
||||
// CHECK-NEXT: [[A:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null
|
||||
// CHECK-NEXT: tail call void @llvm.assume(i1 [[A]])
|
||||
// The order between %xs.0 and %xs.1 on the next line doesn't matter
|
||||
// and different LLVM versions produce different order.
|
||||
// CHECK-NEXT: [[B:%.*]] = icmp eq {{i32\*|ptr}} {{%xs.0, %xs.1|%xs.1, %xs.0}}
|
||||
// CHECK-NEXT: [[B:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}}
|
||||
// CHECK-NEXT: ret i1 [[B:%.*]]
|
||||
{xs}.next().is_none()
|
||||
}
|
||||
@ -25,11 +25,11 @@ pub fn is_empty_1(xs: Iter<f32>) -> bool {
|
||||
pub fn is_empty_2(xs: Iter<f32>) -> bool {
|
||||
// CHECK-LABEL: @is_empty_2
|
||||
// CHECK-NEXT: start:
|
||||
// CHECK-NEXT: [[C:%.*]] = icmp ne {{i32\*|ptr}} {{%xs.0|%xs.1}}, null
|
||||
// CHECK-NEXT: [[C:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null
|
||||
// CHECK-NEXT: tail call void @llvm.assume(i1 [[C]])
|
||||
// The order between %xs.0 and %xs.1 on the next line doesn't matter
|
||||
// and different LLVM versions produce different order.
|
||||
// CHECK-NEXT: [[D:%.*]] = icmp eq {{i32\*|ptr}} {{%xs.0, %xs.1|%xs.1, %xs.0}}
|
||||
// CHECK-NEXT: [[D:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}}
|
||||
// CHECK-NEXT: ret i1 [[D:%.*]]
|
||||
xs.map(|&x| x).next().is_none()
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ pub struct Foo<T> {
|
||||
// The load from bar.1 should have alignment 4. Not checking
|
||||
// other loads here, as the alignment will be platform-dependent.
|
||||
|
||||
// CHECK: %{{.+}} = load i32, {{i32\*|ptr}} %{{.+}}, align 4
|
||||
// CHECK: %{{.+}} = load i32, ptr %{{.+}}, align 4
|
||||
#[no_mangle]
|
||||
pub fn test(x: Foo<(i32, i32)>) -> (i32, i32) {
|
||||
x.bar
|
||||
|
@ -11,7 +11,7 @@ pub struct Foo<T> {
|
||||
// The store writing to bar.1 should have alignment 4. Not checking
|
||||
// other stores here, as the alignment will be platform-dependent.
|
||||
|
||||
// CHECK: store i32 [[TMP1:%.+]], {{i32\*|ptr}} [[TMP2:%.+]], align 4
|
||||
// CHECK: store i32 [[TMP1:%.+]], ptr [[TMP2:%.+]], align 4
|
||||
#[no_mangle]
|
||||
pub fn test(x: (i32, i32)) -> Foo<(i32, i32)> {
|
||||
Foo { foo: 0, bar: x }
|
||||
|
@ -8,10 +8,10 @@ pub struct S {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @test1
|
||||
// CHECK: store i32 0, {{i32\*|ptr}} %{{.+}}, align 16
|
||||
// CHECK: store i32 1, {{i32\*|ptr}} %{{.+}}, align 4
|
||||
// CHECK: store i32 2, {{i32\*|ptr}} %{{.+}}, align 8
|
||||
// CHECK: store i32 3, {{i32\*|ptr}} %{{.+}}, align 4
|
||||
// CHECK: store i32 0, ptr %{{.+}}, align 16
|
||||
// CHECK: store i32 1, ptr %{{.+}}, align 4
|
||||
// CHECK: store i32 2, ptr %{{.+}}, align 8
|
||||
// CHECK: store i32 3, ptr %{{.+}}, align 4
|
||||
#[no_mangle]
|
||||
pub fn test1(s: &mut S) {
|
||||
s.arr[0] = 0;
|
||||
@ -21,7 +21,7 @@ pub fn test1(s: &mut S) {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @test2
|
||||
// CHECK: store i32 4, {{i32\*|ptr}} %{{.+}}, align 4
|
||||
// CHECK: store i32 4, ptr %{{.+}}, align 4
|
||||
#[allow(unconditional_panic)]
|
||||
#[no_mangle]
|
||||
pub fn test2(s: &mut S) {
|
||||
@ -29,14 +29,14 @@ pub fn test2(s: &mut S) {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @test3
|
||||
// CHECK: store i32 5, {{i32\*|ptr}} %{{.+}}, align 4
|
||||
// CHECK: store i32 5, ptr %{{.+}}, align 4
|
||||
#[no_mangle]
|
||||
pub fn test3(s: &mut S, i: usize) {
|
||||
s.arr[i] = 5;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @test4
|
||||
// CHECK: store i32 6, {{i32\*|ptr}} %{{.+}}, align 4
|
||||
// CHECK: store i32 6, ptr %{{.+}}, align 4
|
||||
#[no_mangle]
|
||||
pub fn test4(s: &mut S) {
|
||||
s.arr = [6; 4];
|
||||
|
@ -16,6 +16,6 @@
|
||||
|
||||
// Ensure that emit arguments of the correct type.
|
||||
pub unsafe fn test_call_variadic() {
|
||||
// CHECK: call void (i32, ...) @variadic_fn(i32 0, i8 {{.*}}, {{%Bar\*|ptr}} {{.*}})
|
||||
// CHECK: call void (i32, ...) @variadic_fn(i32 0, i8 {{.*}}, ptr {{.*}})
|
||||
variadic_fn(0, Foo(0), Bar(0, 0, 0))
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
// min-llvm-version: 15.0.0
|
||||
// compile-flags: -O
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
@ -1,4 +1,3 @@
|
||||
// min-llvm-version: 15.0
|
||||
// only-64bit llvm appears to use stores instead of memset on 32bit
|
||||
// compile-flags: -C opt-level=3 -Z merge-functions=disabled
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
// min-llvm-version: 15.0
|
||||
// compile-flags: -O
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
@ -3,7 +3,6 @@
|
||||
// in some situations, see https://github.com/rust-lang/rust/issues/96497#issuecomment-1112865218
|
||||
|
||||
// compile-flags: -O
|
||||
// min-llvm-version: 15.0
|
||||
|
||||
#![crate_type="lib"]
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
// min-llvm-version: 15.0.0
|
||||
// ignore-debug: The debug assertions get in the way
|
||||
// compile-flags: -O
|
||||
|
||||
|
@ -8,7 +8,7 @@ pub fn test() {
|
||||
let a = 0u8;
|
||||
&a; // keep variable in an alloca
|
||||
|
||||
// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, {{i8\*|ptr}} %a)
|
||||
// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, ptr %a)
|
||||
|
||||
{
|
||||
let b = &Some(a);
|
||||
@ -26,9 +26,9 @@ pub fn test() {
|
||||
let c = 1u8;
|
||||
&c; // keep variable in an alloca
|
||||
|
||||
// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, {{i8\*|ptr}} %c)
|
||||
// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, ptr %c)
|
||||
|
||||
// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, {{i8\*|ptr}} %c)
|
||||
// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, ptr %c)
|
||||
|
||||
// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, {{i8\*|ptr}} %a)
|
||||
// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, ptr %a)
|
||||
}
|
||||
|
@ -28,22 +28,22 @@ pub fn ptr_alignment_helper(x: &&()) {}
|
||||
// CHECK-LABEL: @load_ref
|
||||
#[no_mangle]
|
||||
pub fn load_ref<'a>(x: &&'a i32) -> &'a i32 {
|
||||
// CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META:[0-9]+]], !noundef !{{[0-9]+}}
|
||||
// CHECK: load ptr, ptr %x, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META:[0-9]+]], !noundef !{{[0-9]+}}
|
||||
*x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @load_ref_higher_alignment
|
||||
#[no_mangle]
|
||||
pub fn load_ref_higher_alignment<'a>(x: &&'a Align16) -> &'a Align16 {
|
||||
// CHECK: load {{%Align16\*|i128\*|ptr}}, {{%Align16\*\*|i128\*\*|ptr}} %x, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_16_META:[0-9]+]], !noundef !{{[0-9]+}}
|
||||
// CHECK: load ptr, ptr %x, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_16_META:[0-9]+]], !noundef !{{[0-9]+}}
|
||||
*x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @load_scalar_pair
|
||||
#[no_mangle]
|
||||
pub fn load_scalar_pair<'a>(x: &(&'a i32, &'a Align16)) -> (&'a i32, &'a Align16) {
|
||||
// CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %{{.+}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META]], !noundef !{{[0-9]+}}
|
||||
// CHECK: load {{i64\*|ptr}}, {{i64\*\*|ptr}} %{{.+}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_16_META]], !noundef !{{[0-9]+}}
|
||||
// CHECK: load ptr, ptr %{{.+}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META]], !noundef !{{[0-9]+}}
|
||||
// CHECK: load ptr, ptr %{{.+}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_16_META]], !noundef !{{[0-9]+}}
|
||||
*x
|
||||
}
|
||||
|
||||
@ -51,70 +51,70 @@ pub fn load_scalar_pair<'a>(x: &(&'a i32, &'a Align16)) -> (&'a i32, &'a Align16
|
||||
#[no_mangle]
|
||||
pub fn load_raw_pointer<'a>(x: &*const i32) -> *const i32 {
|
||||
// loaded raw pointer should not have !nonnull or !align metadata
|
||||
// CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x, align [[PTR_ALIGNMENT]], !noundef ![[NOUNDEF:[0-9]+]]{{$}}
|
||||
// CHECK: load ptr, ptr %x, align [[PTR_ALIGNMENT]], !noundef ![[NOUNDEF:[0-9]+]]{{$}}
|
||||
*x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @load_box
|
||||
#[no_mangle]
|
||||
pub fn load_box<'a>(x: Box<Box<i32>>) -> Box<i32> {
|
||||
// CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %{{.*}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META]], !noundef !{{[0-9]+}}
|
||||
// CHECK: load ptr, ptr %{{.*}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META]], !noundef !{{[0-9]+}}
|
||||
*x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @load_bool
|
||||
#[no_mangle]
|
||||
pub fn load_bool(x: &bool) -> bool {
|
||||
// CHECK: load i8, {{i8\*|ptr}} %x, align 1, !range ![[BOOL_RANGE:[0-9]+]], !noundef !{{[0-9]+}}
|
||||
// CHECK: load i8, ptr %x, align 1, !range ![[BOOL_RANGE:[0-9]+]], !noundef !{{[0-9]+}}
|
||||
*x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @load_maybeuninit_bool
|
||||
#[no_mangle]
|
||||
pub fn load_maybeuninit_bool(x: &MaybeUninit<bool>) -> MaybeUninit<bool> {
|
||||
// CHECK: load i8, {{i8\*|ptr}} %x, align 1{{$}}
|
||||
// CHECK: load i8, ptr %x, align 1{{$}}
|
||||
*x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @load_enum_bool
|
||||
#[no_mangle]
|
||||
pub fn load_enum_bool(x: &MyBool) -> MyBool {
|
||||
// CHECK: load i8, {{i8\*|ptr}} %x, align 1, !range ![[BOOL_RANGE]], !noundef !{{[0-9]+}}
|
||||
// CHECK: load i8, ptr %x, align 1, !range ![[BOOL_RANGE]], !noundef !{{[0-9]+}}
|
||||
*x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @load_maybeuninit_enum_bool
|
||||
#[no_mangle]
|
||||
pub fn load_maybeuninit_enum_bool(x: &MaybeUninit<MyBool>) -> MaybeUninit<MyBool> {
|
||||
// CHECK: load i8, {{i8\*|ptr}} %x, align 1{{$}}
|
||||
// CHECK: load i8, ptr %x, align 1{{$}}
|
||||
*x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @load_int
|
||||
#[no_mangle]
|
||||
pub fn load_int(x: &u16) -> u16 {
|
||||
// CHECK: load i16, {{i16\*|ptr}} %x, align 2, !noundef ![[NOUNDEF]]{{$}}
|
||||
// CHECK: load i16, ptr %x, align 2, !noundef ![[NOUNDEF]]{{$}}
|
||||
*x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @load_nonzero_int
|
||||
#[no_mangle]
|
||||
pub fn load_nonzero_int(x: &NonZeroU16) -> NonZeroU16 {
|
||||
// CHECK: load i16, {{i16\*|ptr}} %x, align 2, !range ![[NONZEROU16_RANGE:[0-9]+]], !noundef !{{[0-9]+}}
|
||||
// CHECK: load i16, ptr %x, align 2, !range ![[NONZEROU16_RANGE:[0-9]+]], !noundef !{{[0-9]+}}
|
||||
*x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @load_option_nonzero_int
|
||||
#[no_mangle]
|
||||
pub fn load_option_nonzero_int(x: &Option<NonZeroU16>) -> Option<NonZeroU16> {
|
||||
// CHECK: load i16, {{i16\*|ptr}} %x, align 2, !noundef ![[NOUNDEF]]{{$}}
|
||||
// CHECK: load i16, ptr %x, align 2, !noundef ![[NOUNDEF]]{{$}}
|
||||
*x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @borrow
|
||||
#[no_mangle]
|
||||
pub fn borrow(x: &i32) -> &i32 {
|
||||
// CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x{{.*}}, !nonnull
|
||||
// CHECK: load ptr, ptr %x{{.*}}, !nonnull
|
||||
&x; // keep variable in an alloca
|
||||
x
|
||||
}
|
||||
@ -122,7 +122,7 @@ pub fn borrow(x: &i32) -> &i32 {
|
||||
// CHECK-LABEL: @_box
|
||||
#[no_mangle]
|
||||
pub fn _box(x: Box<i32>) -> i32 {
|
||||
// CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x{{.*}}, align [[PTR_ALIGNMENT]]
|
||||
// CHECK: load ptr, ptr %x{{.*}}, align [[PTR_ALIGNMENT]]
|
||||
*x
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ pub fn _box(x: Box<i32>) -> i32 {
|
||||
// dependent alignment
|
||||
#[no_mangle]
|
||||
pub fn small_array_alignment(x: [i8; 4]) -> [i8; 4] {
|
||||
// CHECK: [[VAR:%[0-9]+]] = load i32, {{i32\*|ptr}} %{{.*}}, align 1
|
||||
// CHECK: [[VAR:%[0-9]+]] = load i32, ptr %{{.*}}, align 1
|
||||
// CHECK: ret i32 [[VAR]]
|
||||
x
|
||||
}
|
||||
@ -141,7 +141,7 @@ pub fn _box(x: Box<i32>) -> i32 {
|
||||
// dependent alignment
|
||||
#[no_mangle]
|
||||
pub fn small_struct_alignment(x: Bytes) -> Bytes {
|
||||
// CHECK: [[VAR:%[0-9]+]] = load i32, {{i32\*|ptr}} %{{.*}}, align 1
|
||||
// CHECK: [[VAR:%[0-9]+]] = load i32, ptr %{{.*}}, align 1
|
||||
// CHECK: ret i32 [[VAR]]
|
||||
x
|
||||
}
|
||||
|
@ -20,13 +20,13 @@ pub fn exhaustive_match(e: E) -> u8 {
|
||||
// CHECK-NEXT: unreachable
|
||||
//
|
||||
// CHECK: [[A]]:
|
||||
// CHECK-NEXT: store i8 0, {{i8\*|ptr}} %_0, align 1
|
||||
// CHECK-NEXT: store i8 0, ptr %_0, align 1
|
||||
// CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
|
||||
// CHECK: [[B]]:
|
||||
// CHECK-NEXT: store i8 1, {{i8\*|ptr}} %_0, align 1
|
||||
// CHECK-NEXT: store i8 1, ptr %_0, align 1
|
||||
// CHECK-NEXT: br label %[[EXIT]]
|
||||
// CHECK: [[C]]:
|
||||
// CHECK-NEXT: store i8 2, {{i8\*|ptr}} %_0, align 1
|
||||
// CHECK-NEXT: store i8 2, ptr %_0, align 1
|
||||
// CHECK-NEXT: br label %[[EXIT]]
|
||||
match e {
|
||||
E::A => 0,
|
||||
|
@ -25,9 +25,9 @@ pub fn replace_big(dst: &mut Big, src: Big) -> Big {
|
||||
// For a large type, we expect exactly three `memcpy`s
|
||||
// CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}sret(%Big)
|
||||
// CHECK-NOT: call void @llvm.memcpy
|
||||
// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %result, {{i8\*|ptr}} align 8 %dest, i{{.*}} 56, i1 false)
|
||||
// CHECK: call void @llvm.memcpy.{{.+}}(ptr align 8 %result, ptr align 8 %dest, i{{.*}} 56, i1 false)
|
||||
// CHECK-NOT: call void @llvm.memcpy
|
||||
// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %dest, {{i8\*|ptr}} align 8 %src, i{{.*}} 56, i1 false)
|
||||
// CHECK: call void @llvm.memcpy.{{.+}}(ptr align 8 %dest, ptr align 8 %src, i{{.*}} 56, i1 false)
|
||||
// CHECK-NOT: call void @llvm.memcpy
|
||||
|
||||
// CHECK-NOT: call void @llvm.memcpy
|
||||
|
@ -1,5 +1,4 @@
|
||||
// compile-flags: -O -C no-prepopulate-passes
|
||||
// min-llvm-version: 15.0 (for opaque pointers)
|
||||
// only-x86_64 (to not worry about usize differing)
|
||||
// ignore-debug (the debug assertions get in the way)
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#[no_mangle]
|
||||
pub fn f(a: T, b: fn(_: T, _: T)) {
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, {{.*}} 256, i1 false)
|
||||
// CHECK-NOT: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, {{.*}} 256, i1 false)
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 1 %{{.*}}, {{.*}} 256, i1 false)
|
||||
// CHECK-NOT: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 1 %{{.*}}, {{.*}} 256, i1 false)
|
||||
b(a, a)
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ pub fn non_zero_signed_eq(l: Option<NonZeroI64>, r: Option<NonZeroI64>) -> bool
|
||||
#[no_mangle]
|
||||
pub fn non_null_eq(l: Option<NonNull<u8>>, r: Option<NonNull<u8>>) -> bool {
|
||||
// CHECK: start:
|
||||
// CHECK-NEXT: icmp eq {{(i8\*|ptr)}}
|
||||
// CHECK-NEXT: icmp eq ptr
|
||||
// CHECK-NEXT: ret i1
|
||||
l == r
|
||||
}
|
||||
|
@ -18,8 +18,8 @@ pub struct Packed2 {
|
||||
// CHECK-LABEL: @write_pkd1
|
||||
#[no_mangle]
|
||||
pub fn write_pkd1(pkd: &mut Packed1) -> u32 {
|
||||
// CHECK: %{{.*}} = load i32, {{i32\*|ptr}} %{{.*}}, align 1
|
||||
// CHECK: store i32 42, {{i32\*|ptr}} %{{.*}}, align 1
|
||||
// CHECK: %{{.*}} = load i32, ptr %{{.*}}, align 1
|
||||
// CHECK: store i32 42, ptr %{{.*}}, align 1
|
||||
let result = pkd.data;
|
||||
pkd.data = 42;
|
||||
result
|
||||
@ -28,8 +28,8 @@ pub fn write_pkd1(pkd: &mut Packed1) -> u32 {
|
||||
// CHECK-LABEL: @write_pkd2
|
||||
#[no_mangle]
|
||||
pub fn write_pkd2(pkd: &mut Packed2) -> u32 {
|
||||
// CHECK: %{{.*}} = load i32, {{i32\*|ptr}} %{{.*}}, align 2
|
||||
// CHECK: store i32 42, {{i32\*|ptr}} %{{.*}}, align 2
|
||||
// CHECK: %{{.*}} = load i32, ptr %{{.*}}, align 2
|
||||
// CHECK: store i32 42, ptr %{{.*}}, align 2
|
||||
let result = pkd.data;
|
||||
pkd.data = 42;
|
||||
result
|
||||
@ -52,8 +52,8 @@ pub struct BigPacked2 {
|
||||
#[no_mangle]
|
||||
pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 {
|
||||
// CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
|
||||
// CHECK: call void %{{.*}}({{%Array\*|ptr}} noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]])
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
|
||||
// CHECK: call void %{{.*}}(ptr noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]])
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
|
||||
// check that calls whose destination is a field of a packed struct
|
||||
// go through an alloca rather than calling the function with an
|
||||
// unaligned destination.
|
||||
@ -64,8 +64,8 @@ pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 {
|
||||
#[no_mangle]
|
||||
pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 {
|
||||
// CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
|
||||
// CHECK: call void %{{.*}}({{%Array\*|ptr}} noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]])
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 2 %{{.*}}, {{i8\*|ptr}} align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
|
||||
// CHECK: call void %{{.*}}(ptr noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]])
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 2 %{{.*}}, ptr align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
|
||||
// check that calls whose destination is a field of a packed struct
|
||||
// go through an alloca rather than calling the function with an
|
||||
// unaligned destination.
|
||||
@ -73,9 +73,9 @@ pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @write_packed_array1
|
||||
// CHECK: store i32 0, {{i32\*|ptr}} %{{.+}}, align 1
|
||||
// CHECK: store i32 1, {{i32\*|ptr}} %{{.+}}, align 1
|
||||
// CHECK: store i32 2, {{i32\*|ptr}} %{{.+}}, align 1
|
||||
// CHECK: store i32 0, ptr %{{.+}}, align 1
|
||||
// CHECK: store i32 1, ptr %{{.+}}, align 1
|
||||
// CHECK: store i32 2, ptr %{{.+}}, align 1
|
||||
#[no_mangle]
|
||||
pub fn write_packed_array1(p: &mut BigPacked1) {
|
||||
p.data.0[0] = 0;
|
||||
@ -84,9 +84,9 @@ pub fn write_packed_array1(p: &mut BigPacked1) {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @write_packed_array2
|
||||
// CHECK: store i32 0, {{i32\*|ptr}} %{{.+}}, align 2
|
||||
// CHECK: store i32 1, {{i32\*|ptr}} %{{.+}}, align 2
|
||||
// CHECK: store i32 2, {{i32\*|ptr}} %{{.+}}, align 2
|
||||
// CHECK: store i32 0, ptr %{{.+}}, align 2
|
||||
// CHECK: store i32 1, ptr %{{.+}}, align 2
|
||||
// CHECK: store i32 2, ptr %{{.+}}, align 2
|
||||
#[no_mangle]
|
||||
pub fn write_packed_array2(p: &mut BigPacked2) {
|
||||
p.data.0[0] = 0;
|
||||
@ -95,14 +95,14 @@ pub fn write_packed_array2(p: &mut BigPacked2) {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @repeat_packed_array1
|
||||
// CHECK: store i32 42, {{i32\*|ptr}} %{{.+}}, align 1
|
||||
// CHECK: store i32 42, ptr %{{.+}}, align 1
|
||||
#[no_mangle]
|
||||
pub fn repeat_packed_array1(p: &mut BigPacked1) {
|
||||
p.data.0 = [42; 8];
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @repeat_packed_array2
|
||||
// CHECK: store i32 42, {{i32\*|ptr}} %{{.+}}, align 2
|
||||
// CHECK: store i32 42, ptr %{{.+}}, align 2
|
||||
#[no_mangle]
|
||||
pub fn repeat_packed_array2(p: &mut BigPacked2) {
|
||||
p.data.0 = [42; 8];
|
||||
@ -119,14 +119,14 @@ pub fn repeat_packed_array2(p: &mut BigPacked2) {
|
||||
// CHECK-LABEL: @pkd1_pair
|
||||
#[no_mangle]
|
||||
pub fn pkd1_pair(pair1: &mut Packed1Pair, pair2: &mut Packed1Pair) {
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, i{{[0-9]+}} 5, i1 false)
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 1 %{{.*}}, i{{[0-9]+}} 5, i1 false)
|
||||
*pair2 = *pair1;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @pkd2_pair
|
||||
#[no_mangle]
|
||||
pub fn pkd2_pair(pair1: &mut Packed2Pair, pair2: &mut Packed2Pair) {
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 2 %{{.*}}, {{i8\*|ptr}} align 2 %{{.*}}, i{{[0-9]+}} 6, i1 false)
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 2 %{{.*}}, ptr align 2 %{{.*}}, i{{[0-9]+}} 6, i1 false)
|
||||
*pair2 = *pair1;
|
||||
}
|
||||
|
||||
@ -141,13 +141,13 @@ pub fn pkd2_pair(pair1: &mut Packed2Pair, pair2: &mut Packed2Pair) {
|
||||
// CHECK-LABEL: @pkd1_nested_pair
|
||||
#[no_mangle]
|
||||
pub fn pkd1_nested_pair(pair1: &mut Packed1NestedPair, pair2: &mut Packed1NestedPair) {
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, i{{[0-9]+}} 8, i1 false)
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 1 %{{.*}}, i{{[0-9]+}} 8, i1 false)
|
||||
*pair2 = *pair1;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @pkd2_nested_pair
|
||||
#[no_mangle]
|
||||
pub fn pkd2_nested_pair(pair1: &mut Packed2NestedPair, pair2: &mut Packed2NestedPair) {
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 2 %{{.*}}, {{i8\*|ptr}} align 2 %{{.*}}, i{{[0-9]+}} 8, i1 false)
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 2 %{{.*}}, ptr align 2 %{{.*}}, i{{[0-9]+}} 8, i1 false)
|
||||
*pair2 = *pair1;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ pub fn test() {
|
||||
let _s = S;
|
||||
// Check that the personality slot alloca gets a lifetime start in each cleanup block, not just
|
||||
// in the first one.
|
||||
// CHECK: [[SLOT:%[0-9]+]] = alloca { {{i8\*|ptr}}, i32 }
|
||||
// CHECK: [[SLOT:%[0-9]+]] = alloca { ptr, i32 }
|
||||
// CHECK-LABEL: cleanup:
|
||||
// CHECK: call void @llvm.lifetime.start.{{.*}}({{.*}})
|
||||
// CHECK-LABEL: cleanup1:
|
||||
|
@ -13,9 +13,9 @@ pub fn helper(_: usize) {
|
||||
pub fn ref_dst(s: &[u8]) {
|
||||
// We used to generate an extra alloca and memcpy to ref the dst, so check that we copy
|
||||
// directly to the alloca for "x"
|
||||
// CHECK: [[X0:%[0-9]+]] = getelementptr inbounds { {{\[0 x i8\]\*|ptr}}, [[USIZE]] }, {{.*}} %x, i32 0, i32 0
|
||||
// CHECK: store {{\[0 x i8\]\*|ptr}} %s.0, {{.*}} [[X0]]
|
||||
// CHECK: [[X1:%[0-9]+]] = getelementptr inbounds { {{\[0 x i8\]\*|ptr}}, [[USIZE]] }, {{.*}} %x, i32 0, i32 1
|
||||
// CHECK: [[X0:%[0-9]+]] = getelementptr inbounds { ptr, [[USIZE]] }, {{.*}} %x, i32 0, i32 0
|
||||
// CHECK: store ptr %s.0, {{.*}} [[X0]]
|
||||
// CHECK: [[X1:%[0-9]+]] = getelementptr inbounds { ptr, [[USIZE]] }, {{.*}} %x, i32 0, i32 1
|
||||
// CHECK: store [[USIZE]] %s.1, {{.*}} [[X1]]
|
||||
|
||||
let x = &*s;
|
||||
|
@ -8,13 +8,13 @@
|
||||
// CHECK-LABEL: @repeat_take_collect
|
||||
#[no_mangle]
|
||||
pub fn repeat_take_collect() -> Vec<u8> {
|
||||
// CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}align 1{{.*}} %{{.*}}, i8 42, i{{[0-9]+}} 100000, i1 false)
|
||||
// CHECK: call void @llvm.memset.{{.+}}(ptr {{.*}}align 1{{.*}} %{{.*}}, i8 42, i{{[0-9]+}} 100000, i1 false)
|
||||
iter::repeat(42).take(100000).collect()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @repeat_with_take_collect
|
||||
#[no_mangle]
|
||||
pub fn repeat_with_take_collect() -> Vec<u8> {
|
||||
// CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}align 1{{.*}} %{{.*}}, i8 13, i{{[0-9]+}} 12345, i1 false)
|
||||
// CHECK: call void @llvm.memset.{{.+}}(ptr {{.*}}align 1{{.*}} %{{.*}}, i8 13, i{{[0-9]+}} 12345, i1 false)
|
||||
iter::repeat_with(|| 13).take(12345).collect()
|
||||
}
|
||||
|
@ -36,19 +36,19 @@ pub enum TeBigS {
|
||||
Variant(BigS),
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}}void @test_BigS({{%BigS\*|ptr}} [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], {{%BigS\*|ptr}} [[BIGS_ARG_ATTRS1:.*]] byval(%BigS) [[BIGS_ARG_ATTRS2:.*]])
|
||||
// CHECK: define{{.*}}void @test_BigS(ptr [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], ptr [[BIGS_ARG_ATTRS1:.*]] byval(%BigS) [[BIGS_ARG_ATTRS2:.*]])
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_BigS(_: BigS) -> BigS { loop {} }
|
||||
|
||||
// CHECK: define{{.*}}void @test_TsBigS({{%TsBigS\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], {{%TsBigS\*|ptr}} [[BIGS_ARG_ATTRS1]] byval(%TsBigS) [[BIGS_ARG_ATTRS2:.*]])
|
||||
// CHECK: define{{.*}}void @test_TsBigS(ptr [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]] byval(%TsBigS) [[BIGS_ARG_ATTRS2:.*]])
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
|
||||
|
||||
// CHECK: define{{.*}}void @test_TuBigS({{%TuBigS\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], {{%TuBigS\*|ptr}} [[BIGS_ARG_ATTRS1]] byval(%TuBigS) [[BIGS_ARG_ATTRS2:.*]])
|
||||
// CHECK: define{{.*}}void @test_TuBigS(ptr [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]] byval(%TuBigS) [[BIGS_ARG_ATTRS2:.*]])
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
|
||||
|
||||
// CHECK: define{{.*}}void @test_TeBigS({{%"TeBigS::Variant"\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], {{%"TeBigS::Variant"\*|ptr}} [[BIGS_ARG_ATTRS1]] byval(%"TeBigS::Variant") [[BIGS_ARG_ATTRS2]])
|
||||
// CHECK: define{{.*}}void @test_TeBigS(ptr [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]] byval(%"TeBigS::Variant") [[BIGS_ARG_ATTRS2]])
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
|
||||
|
||||
@ -72,18 +72,18 @@ pub enum TeBigU {
|
||||
Variant(BigU),
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}}void @test_BigU({{%BigU\*|ptr}} [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], {{%BigU\*|ptr}} [[BIGU_ARG_ATTRS1:.*]] byval(%BigU) [[BIGU_ARG_ATTRS2:.*]])
|
||||
// CHECK: define{{.*}}void @test_BigU(ptr [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1:.*]] byval(%BigU) [[BIGU_ARG_ATTRS2:.*]])
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_BigU(_: BigU) -> BigU { loop {} }
|
||||
|
||||
// CHECK: define{{.*}}void @test_TsBigU({{%TsBigU\*|ptr}} [[BIGU_RET_ATTRS1:.*]] sret(%TsBigU) [[BIGU_RET_ATTRS2:.*]], {{%TsBigU\*|ptr}} [[BIGU_ARG_ATTRS1]] byval(%TsBigU) [[BIGU_ARG_ATTRS2]])
|
||||
// CHECK: define{{.*}}void @test_TsBigU(ptr [[BIGU_RET_ATTRS1:.*]] sret(%TsBigU) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]] byval(%TsBigU) [[BIGU_ARG_ATTRS2]])
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
|
||||
|
||||
// CHECK: define{{.*}}void @test_TuBigU({{%TuBigU\*|ptr}} [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2:.*]], {{%TuBigU\*|ptr}} [[BIGU_ARG_ATTRS1]] byval(%TuBigU) [[BIGU_ARG_ATTRS2]])
|
||||
// CHECK: define{{.*}}void @test_TuBigU(ptr [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]] byval(%TuBigU) [[BIGU_ARG_ATTRS2]])
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
|
||||
|
||||
// CHECK: define{{.*}}void @test_TeBigU({{%"TeBigU::Variant"\*|ptr}} [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2:.*]], {{%"TeBigU::Variant"\*|ptr}} [[BIGU_ARG_ATTRS1]] byval(%"TeBigU::Variant") [[BIGU_ARG_ATTRS2]])
|
||||
// CHECK: define{{.*}}void @test_TeBigU(ptr [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]] byval(%"TeBigU::Variant") [[BIGU_ARG_ATTRS2]])
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }
|
||||
|
@ -37,19 +37,19 @@ pub enum TeBigS {
|
||||
Variant(BigS),
|
||||
}
|
||||
|
||||
// CHECK: define void @test_BigS({{%BigS\*|ptr}} [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], [16 x i32]
|
||||
// CHECK: define void @test_BigS(ptr [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], [16 x i32]
|
||||
#[no_mangle]
|
||||
pub extern fn test_BigS(_: BigS) -> BigS { loop {} }
|
||||
|
||||
// CHECK: define void @test_TsBigS({{%TsBigS\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], [16 x i32]
|
||||
// CHECK: define void @test_TsBigS(ptr [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], [16 x i32]
|
||||
#[no_mangle]
|
||||
pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
|
||||
|
||||
// CHECK: define void @test_TuBigS({{%TuBigS\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], [16 x i32]
|
||||
// CHECK: define void @test_TuBigS(ptr [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], [16 x i32]
|
||||
#[no_mangle]
|
||||
pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
|
||||
|
||||
// CHECK: define void @test_TeBigS({{%"TeBigS::Variant"\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], [16 x i32]
|
||||
// CHECK: define void @test_TeBigS(ptr [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], [16 x i32]
|
||||
#[no_mangle]
|
||||
pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
|
||||
|
||||
@ -73,18 +73,18 @@ pub enum TeBigU {
|
||||
Variant(BigU),
|
||||
}
|
||||
|
||||
// CHECK: define void @test_BigU({{%BigU\*|ptr}} [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], [16 x i32]
|
||||
// CHECK: define void @test_BigU(ptr [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], [16 x i32]
|
||||
#[no_mangle]
|
||||
pub extern fn test_BigU(_: BigU) -> BigU { loop {} }
|
||||
|
||||
// CHECK: define void @test_TsBigU({{%TsBigU\*|ptr}} [[BIGU_RET_ATTRS1]] sret(%TsBigU) [[BIGU_RET_ATTRS2]], [16 x i32]
|
||||
// CHECK: define void @test_TsBigU(ptr [[BIGU_RET_ATTRS1]] sret(%TsBigU) [[BIGU_RET_ATTRS2]], [16 x i32]
|
||||
#[no_mangle]
|
||||
pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
|
||||
|
||||
// CHECK: define void @test_TuBigU({{%TuBigU\*|ptr}} [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2]], [16 x i32]
|
||||
// CHECK: define void @test_TuBigU(ptr [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2]], [16 x i32]
|
||||
#[no_mangle]
|
||||
pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
|
||||
|
||||
// CHECK: define void @test_TeBigU({{%"TeBigU::Variant"\*|ptr}} [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2]], [16 x i32]
|
||||
// CHECK: define void @test_TeBigU(ptr [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2]], [16 x i32]
|
||||
#[no_mangle]
|
||||
pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }
|
||||
|
@ -26,7 +26,7 @@ pub extern "C" fn test_F32(_: F32) -> F32 { loop {} }
|
||||
#[repr(transparent)]
|
||||
pub struct Ptr(*mut u8);
|
||||
|
||||
// CHECK: define{{.*}}{{i8\*|ptr}} @test_Ptr({{i8\*|ptr}} noundef %_1)
|
||||
// CHECK: define{{.*}}ptr @test_Ptr(ptr noundef %_1)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_Ptr(_: Ptr) -> Ptr { loop {} }
|
||||
|
||||
@ -41,7 +41,7 @@ pub extern "C" fn test_WithZst(_: WithZst) -> WithZst { loop {} }
|
||||
pub struct WithZeroSizedArray(*const f32, [i8; 0]);
|
||||
|
||||
// Apparently we use i32* when newtype-unwrapping f32 pointers. Whatever.
|
||||
// CHECK: define{{.*}}{{i32\*|ptr}} @test_WithZeroSizedArray({{i32\*|ptr}} noundef %_1)
|
||||
// CHECK: define{{.*}}ptr @test_WithZeroSizedArray(ptr noundef %_1)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} }
|
||||
|
||||
@ -65,7 +65,7 @@ pub extern "C" fn test_Gpz(_: GenericPlusZst<Bool>) -> GenericPlusZst<Bool> { lo
|
||||
#[repr(transparent)]
|
||||
pub struct LifetimePhantom<'a, T: 'a>(*const T, PhantomData<&'a T>);
|
||||
|
||||
// CHECK: define{{.*}}{{i16\*|ptr}} @test_LifetimePhantom({{i16\*|ptr}} noundef %_1)
|
||||
// CHECK: define{{.*}}ptr @test_LifetimePhantom(ptr noundef %_1)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_LifetimePhantom(_: LifetimePhantom<i16>) -> LifetimePhantom<i16> { loop {} }
|
||||
|
||||
|
@ -127,18 +127,18 @@ pub struct Large {
|
||||
d: i64,
|
||||
}
|
||||
|
||||
// CHECK: define void @f_agg_large({{%Large\*|ptr}} {{.*}}%x)
|
||||
// CHECK: define void @f_agg_large(ptr {{.*}}%x)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_agg_large(mut x: Large) {
|
||||
}
|
||||
|
||||
// CHECK: define void @f_agg_large_ret({{%Large\*|ptr}} {{.*}}sret{{.*}}, i32 noundef signext %i, i8 noundef signext %j)
|
||||
// CHECK: define void @f_agg_large_ret(ptr {{.*}}sret{{.*}}, i32 noundef signext %i, i8 noundef signext %j)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_agg_large_ret(i: i32, j: i8) -> Large {
|
||||
Large { a: 1, b: 2, c: 3, d: 4 }
|
||||
}
|
||||
|
||||
// CHECK: define void @f_scalar_stack_1(i64 %0, [2 x i64] %1, i128 %2, {{%Large\*|ptr}} {{.*}}%d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef %g, i8 noundef %h)
|
||||
// CHECK: define void @f_scalar_stack_1(i64 %0, [2 x i64] %1, i128 %2, ptr {{.*}}%d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef %g, i8 noundef %h)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_scalar_stack_1(
|
||||
a: Tiny,
|
||||
@ -152,7 +152,7 @@ pub extern "C" fn f_scalar_stack_1(
|
||||
) {
|
||||
}
|
||||
|
||||
// CHECK: define void @f_scalar_stack_2({{%Large\*|ptr}} {{.*}}sret{{.*}} %_0, i64 noundef %a, i128 %0, i128 %1, i64 noundef %d, i8 noundef zeroext %e, i8 noundef %f, i8 noundef %g)
|
||||
// CHECK: define void @f_scalar_stack_2(ptr {{.*}}sret{{.*}} %_0, i64 noundef %a, i128 %0, i128 %1, i64 noundef %d, i8 noundef zeroext %e, i8 noundef %f, i8 noundef %g)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_scalar_stack_2(
|
||||
a: u64,
|
||||
@ -172,7 +172,7 @@ pub extern "C" fn f_scalar_stack_2(
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_va_caller() {
|
||||
// CHECK: call noundef signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i64 noundef 3, double {{.*}}, double {{.*}}, i64 {{.*}}, [2 x i64] {{.*}}, i128 {{.*}}, {{%Large\*|ptr}} {{.*}})
|
||||
// CHECK: call noundef signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i64 noundef 3, double {{.*}}, double {{.*}}, i64 {{.*}}, [2 x i64] {{.*}}, i128 {{.*}}, ptr {{.*}})
|
||||
f_va_callee(
|
||||
1,
|
||||
2i32,
|
||||
|
@ -8,7 +8,7 @@
|
||||
pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}}foo{{.*}}!type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||
// CHECK: start:
|
||||
// CHECK: [[TT:%.+]] = call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"{{[[:print:]]+}}")
|
||||
// CHECK: [[TT:%.+]] = call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"{{[[:print:]]+}}")
|
||||
// CHECK-NEXT: br i1 [[TT]], label %type_test.pass, label %type_test.fail
|
||||
// CHECK: type_test.pass:
|
||||
// CHECK-NEXT: {{%.+}} = call i32 %f(i32 %arg)
|
||||
|
@ -8,21 +8,21 @@
|
||||
pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}}foo
|
||||
// CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_E.generalized")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_E.generalized")
|
||||
f(arg)
|
||||
}
|
||||
|
||||
pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}}bar
|
||||
// CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E.generalized")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E.generalized")
|
||||
f(arg1, arg2)
|
||||
}
|
||||
|
||||
pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}}baz
|
||||
// CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E.generalized")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E.generalized")
|
||||
f(arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
|
@ -8,21 +8,21 @@
|
||||
pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}}foo
|
||||
// CHECK-SAME: {{.*}}![[TYPE1:[0-9]+]]
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_E.normalized.generalized")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_E.normalized.generalized")
|
||||
f(arg)
|
||||
}
|
||||
|
||||
pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}}bar
|
||||
// CHECK-SAME: {{.*}}![[TYPE2:[0-9]+]]
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E.normalized.generalized")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E.normalized.generalized")
|
||||
f(arg1, arg2)
|
||||
}
|
||||
|
||||
pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}}baz
|
||||
// CHECK-SAME: {{.*}}![[TYPE3:[0-9]+]]
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E.normalized.generalized")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E.normalized.generalized")
|
||||
f(arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
|
@ -8,21 +8,21 @@
|
||||
pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}}foo
|
||||
// CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_E.normalized")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_E.normalized")
|
||||
f(arg)
|
||||
}
|
||||
|
||||
pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}}bar
|
||||
// CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E.normalized")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E.normalized")
|
||||
f(arg1, arg2)
|
||||
}
|
||||
|
||||
pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}}baz
|
||||
// CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E.normalized")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E.normalized")
|
||||
f(arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
|
@ -8,21 +8,21 @@
|
||||
pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}}foo
|
||||
// CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_E")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_E")
|
||||
f(arg)
|
||||
}
|
||||
|
||||
pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}}bar
|
||||
// CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E")
|
||||
f(arg1, arg2)
|
||||
}
|
||||
|
||||
pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}}baz
|
||||
// CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E")
|
||||
f(arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ impl<T, U, const N: usize> Trait5<U, N> for T {
|
||||
pub fn foo1(a: &dyn Trait1) {
|
||||
a.foo();
|
||||
// CHECK-LABEL: define{{.*}}4foo1{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE1:[[:print:]]+]]")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE1:[[:print:]]+]]")
|
||||
}
|
||||
|
||||
pub fn bar1() {
|
||||
@ -76,13 +76,13 @@ pub fn bar1() {
|
||||
let b = &a as &dyn Trait1;
|
||||
b.foo();
|
||||
// CHECK-LABEL: define{{.*}}4bar1{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE2:[[:print:]]+]]")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE2:[[:print:]]+]]")
|
||||
}
|
||||
|
||||
pub fn foo2<T>(a: &dyn Trait2<T>) {
|
||||
a.bar();
|
||||
// CHECK-LABEL: define{{.*}}4foo2{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE2:[[:print:]]+]]")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE2:[[:print:]]+]]")
|
||||
}
|
||||
|
||||
pub fn bar2() {
|
||||
@ -91,14 +91,14 @@ pub fn bar2() {
|
||||
let b = &a as &dyn Trait2<i32>;
|
||||
b.bar();
|
||||
// CHECK-LABEL: define{{.*}}4bar2{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE2:[[:print:]]+]]")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE2:[[:print:]]+]]")
|
||||
}
|
||||
|
||||
pub fn foo3(a: &dyn Trait3<Type3>) {
|
||||
let b = Type3;
|
||||
a.baz(&b);
|
||||
// CHECK-LABEL: define{{.*}}4foo3{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE3:[[:print:]]+]]")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE3:[[:print:]]+]]")
|
||||
}
|
||||
|
||||
pub fn bar3() {
|
||||
@ -107,14 +107,14 @@ pub fn bar3() {
|
||||
let b = &a as &dyn Trait3<Type3>;
|
||||
b.baz(&a);
|
||||
// CHECK-LABEL: define{{.*}}4bar3{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE3:[[:print:]]+]]")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE3:[[:print:]]+]]")
|
||||
}
|
||||
|
||||
pub fn foo4<'a>(a: &dyn Trait4<'a, Type4, Output = &'a i32>) {
|
||||
let b = Type4;
|
||||
a.qux(&b);
|
||||
// CHECK-LABEL: define{{.*}}4foo4{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE4:[[:print:]]+]]")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE4:[[:print:]]+]]")
|
||||
}
|
||||
|
||||
pub fn bar4<'a>() {
|
||||
@ -123,14 +123,14 @@ pub fn bar4<'a>() {
|
||||
let b = &a as &dyn Trait4<'a, Type4, Output = &'a i32>;
|
||||
b.qux(&a);
|
||||
// CHECK-LABEL: define{{.*}}4bar4{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE4:[[:print:]]+]]")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE4:[[:print:]]+]]")
|
||||
}
|
||||
|
||||
pub fn foo5(a: &dyn Trait5<Type5, 32>) {
|
||||
let b = &[Type5; 32];
|
||||
a.quux(&b);
|
||||
// CHECK-LABEL: define{{.*}}4foo5{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE5:[[:print:]]+]]")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE5:[[:print:]]+]]")
|
||||
}
|
||||
|
||||
pub fn bar5() {
|
||||
@ -139,7 +139,7 @@ pub fn bar5() {
|
||||
let b = &a as &dyn Trait5<Type5, 32>;
|
||||
b.quux(&a);
|
||||
// CHECK-LABEL: define{{.*}}4bar5{{.*}}!type !{{[0-9]+}}
|
||||
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE5:[[:print:]]+]]")
|
||||
// CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE5:[[:print:]]+]]")
|
||||
}
|
||||
|
||||
// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE1]]"}
|
||||
|
@ -93,7 +93,7 @@ impl<T, U, const N: usize> Trait5<U, N> for T {
|
||||
pub fn foo1(a: &dyn Trait1) {
|
||||
a.foo();
|
||||
// CHECK-LABEL: define{{.*}}4foo1{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE1:[[:print:]]+]]) ]
|
||||
// CHECK: call void %{{[0-9]}}(ptr align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE1:[[:print:]]+]]) ]
|
||||
}
|
||||
|
||||
pub fn bar1() {
|
||||
@ -101,13 +101,13 @@ pub fn bar1() {
|
||||
let b = &a as &dyn Trait1;
|
||||
b.foo();
|
||||
// CHECK-LABEL: define{{.*}}4bar1{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE1:[[:print:]]+]]) ]
|
||||
// CHECK: call void %{{[0-9]}}(ptr align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE1:[[:print:]]+]]) ]
|
||||
}
|
||||
|
||||
pub fn foo2<T>(a: &dyn Trait2<T>) {
|
||||
a.bar();
|
||||
// CHECK-LABEL: define{{.*}}4foo2{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE2:[[:print:]]+]]) ]
|
||||
// CHECK: call void %{{[0-9]}}(ptr align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE2:[[:print:]]+]]) ]
|
||||
}
|
||||
|
||||
pub fn bar2() {
|
||||
@ -116,14 +116,14 @@ pub fn bar2() {
|
||||
let b = &a as &dyn Trait2<i32>;
|
||||
b.bar();
|
||||
// CHECK-LABEL: define{{.*}}4bar2{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE2:[[:print:]]+]]) ]
|
||||
// CHECK: call void %{{[0-9]}}(ptr align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE2:[[:print:]]+]]) ]
|
||||
}
|
||||
|
||||
pub fn foo3(a: &dyn Trait3<Type3>) {
|
||||
let b = Type3;
|
||||
a.baz(&b);
|
||||
// CHECK-LABEL: define{{.*}}4foo3{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}, {{\{\}\*|ptr|%Type3\*}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE3:[[:print:]]+]]) ]
|
||||
// CHECK: call void %{{[0-9]}}(ptr align 1 {{%[a-z]\.0|%_[0-9]}}, ptr align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE3:[[:print:]]+]]) ]
|
||||
}
|
||||
|
||||
pub fn bar3() {
|
||||
@ -132,14 +132,14 @@ pub fn bar3() {
|
||||
let b = &a as &dyn Trait3<Type3>;
|
||||
b.baz(&a);
|
||||
// CHECK-LABEL: define{{.*}}4bar3{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}, {{\{\}\*|ptr|%Type3\*}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE3:[[:print:]]+]]) ]
|
||||
// CHECK: call void %{{[0-9]}}(ptr align 1 {{%[a-z]\.0|%_[0-9]}}, ptr align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE3:[[:print:]]+]]) ]
|
||||
}
|
||||
|
||||
pub fn foo4<'a>(a: &dyn Trait4<'a, Type4, Output = &'a i32>) {
|
||||
let b = Type4;
|
||||
a.qux(&b);
|
||||
// CHECK-LABEL: define{{.*}}4foo4{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call align 4 {{ptr|i32\*}} %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}, {{\{\}\*|ptr|%Type4\*}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE4:[[:print:]]+]]) ]
|
||||
// CHECK: call align 4 ptr %{{[0-9]}}(ptr align 1 {{%[a-z]\.0|%_[0-9]}}, ptr align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE4:[[:print:]]+]]) ]
|
||||
}
|
||||
|
||||
pub fn bar4<'a>() {
|
||||
@ -148,14 +148,14 @@ pub fn bar4<'a>() {
|
||||
let b = &a as &dyn Trait4<'a, Type4, Output = &'a i32>;
|
||||
b.qux(&a);
|
||||
// CHECK-LABEL: define{{.*}}4bar4{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call align 4 {{ptr|i32\*}} %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}, {{\{\}\*|ptr|%Type4\*}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE4:[[:print:]]+]]) ]
|
||||
// CHECK: call align 4 ptr %{{[0-9]}}(ptr align 1 {{%[a-z]\.0|%_[0-9]}}, ptr align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE4:[[:print:]]+]]) ]
|
||||
}
|
||||
|
||||
pub fn foo5(a: &dyn Trait5<Type5, 32>) {
|
||||
let b = &[Type5; 32];
|
||||
a.quux(&b);
|
||||
// CHECK-LABEL: define{{.*}}4foo5{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z](\.0)*|%_[0-9]+]}}, {{\{\}\*|ptr|\[32 x %Type5\]\*}} align 1 {{%[a-z](\.0)*|%_[0-9]+}}){{.*}}[ "kcfi"(i32 [[TYPE5:[[:print:]]+]]) ]
|
||||
// CHECK: call void %{{[0-9]}}(ptr align 1 {{%[a-z](\.0)*|%_[0-9]+]}}, ptr align 1 {{%[a-z](\.0)*|%_[0-9]+}}){{.*}}[ "kcfi"(i32 [[TYPE5:[[:print:]]+]]) ]
|
||||
}
|
||||
|
||||
pub fn bar5() {
|
||||
@ -164,7 +164,7 @@ pub fn bar5() {
|
||||
let b = &a as &dyn Trait5<Type5, 32>;
|
||||
b.quux(&a);
|
||||
// CHECK-LABEL: define{{.*}}4bar5{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}}
|
||||
// CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z](\.0)*|%_[0-9]+]}}, {{\{\}\*|ptr|\[32 x %Type5\]\*}} align 1 {{%[a-z](\.0)*|%_[0-9]+}}){{.*}}[ "kcfi"(i32 [[TYPE5:[[:print:]]+]]) ]
|
||||
// CHECK: call void %{{[0-9]}}(ptr align 1 {{%[a-z](\.0)*|%_[0-9]+]}}, ptr align 1 {{%[a-z](\.0)*|%_[0-9]+}}){{.*}}[ "kcfi"(i32 [[TYPE5:[[:print:]]+]]) ]
|
||||
}
|
||||
|
||||
// CHECK: !{{[0-9]+}} = !{i32 [[TYPE1]]}
|
||||
|
@ -23,7 +23,7 @@
|
||||
#[no_mangle]
|
||||
pub unsafe fn gather_f32x2(pointers: Vec2<*const f32>, mask: Vec2<i32>,
|
||||
values: Vec2<f32>) -> Vec2<f32> {
|
||||
// CHECK: call <2 x float> @llvm.masked.gather.v2f32.{{.+}}(<2 x {{float\*|ptr}}> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}, <2 x float> {{.*}})
|
||||
// CHECK: call <2 x float> @llvm.masked.gather.v2f32.{{.+}}(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}, <2 x float> {{.*}})
|
||||
simd_gather(values, pointers, mask)
|
||||
}
|
||||
|
||||
@ -31,6 +31,6 @@ pub unsafe fn gather_f32x2(pointers: Vec2<*const f32>, mask: Vec2<i32>,
|
||||
#[no_mangle]
|
||||
pub unsafe fn gather_pf32x2(pointers: Vec2<*const *const f32>, mask: Vec2<i32>,
|
||||
values: Vec2<*const f32>) -> Vec2<*const f32> {
|
||||
// CHECK: call <2 x {{float\*|ptr}}> @llvm.masked.gather.{{.+}}(<2 x {{float\*\*|ptr}}> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}, <2 x {{float\*|ptr}}> {{.*}})
|
||||
// CHECK: call <2 x ptr> @llvm.masked.gather.{{.+}}(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}, <2 x ptr> {{.*}})
|
||||
simd_gather(values, pointers, mask)
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
#[no_mangle]
|
||||
pub unsafe fn scatter_f32x2(pointers: Vec2<*mut f32>, mask: Vec2<i32>,
|
||||
values: Vec2<f32>) {
|
||||
// CHECK: call void @llvm.masked.scatter.v2f32.v2p0{{.*}}(<2 x float> {{.*}}, <2 x {{float\*|ptr}}> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}})
|
||||
// CHECK: call void @llvm.masked.scatter.v2f32.v2p0{{.*}}(<2 x float> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}})
|
||||
simd_scatter(values, pointers, mask)
|
||||
}
|
||||
|
||||
@ -32,6 +32,6 @@ pub unsafe fn scatter_f32x2(pointers: Vec2<*mut f32>, mask: Vec2<i32>,
|
||||
#[no_mangle]
|
||||
pub unsafe fn scatter_pf32x2(pointers: Vec2<*mut *const f32>, mask: Vec2<i32>,
|
||||
values: Vec2<*const f32>) {
|
||||
// CHECK: call void @llvm.masked.scatter.v2p0{{.*}}.v2p0{{.*}}(<2 x {{float\*|ptr}}> {{.*}}, <2 x {{float\*\*|ptr}}> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}})
|
||||
// CHECK: call void @llvm.masked.scatter.v2p0{{.*}}.v2p0{{.*}}(<2 x ptr> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}})
|
||||
simd_scatter(values, pointers, mask)
|
||||
}
|
||||
|
@ -42,8 +42,8 @@ pub fn vector_align() -> usize {
|
||||
// CHECK-LABEL: @build_array_transmute_s
|
||||
#[no_mangle]
|
||||
pub fn build_array_transmute_s(x: [f32; 4]) -> S<4> {
|
||||
// CHECK: %[[VAL:.+]] = load <4 x float>, {{ptr %x|.+>\* %.+}}, align [[ARRAY_ALIGN]]
|
||||
// CHECK: store <4 x float> %[[VAL:.+]], {{ptr %_0|.+>\* %.+}}, align [[VECTOR_ALIGN]]
|
||||
// CHECK: %[[VAL:.+]] = load <4 x float>, ptr %x, align [[ARRAY_ALIGN]]
|
||||
// CHECK: store <4 x float> %[[VAL:.+]], ptr %_0, align [[VECTOR_ALIGN]]
|
||||
unsafe { std::mem::transmute(x) }
|
||||
}
|
||||
|
||||
@ -57,8 +57,8 @@ pub fn vector_align() -> usize {
|
||||
// CHECK-LABEL: @build_array_transmute_t
|
||||
#[no_mangle]
|
||||
pub fn build_array_transmute_t(x: [f32; 4]) -> T {
|
||||
// CHECK: %[[VAL:.+]] = load <4 x float>, {{ptr %x|.+>\* %.+}}, align [[ARRAY_ALIGN]]
|
||||
// CHECK: store <4 x float> %[[VAL:.+]], {{ptr %_0|.+>\* %.+}}, align [[VECTOR_ALIGN]]
|
||||
// CHECK: %[[VAL:.+]] = load <4 x float>, ptr %x, align [[ARRAY_ALIGN]]
|
||||
// CHECK: store <4 x float> %[[VAL:.+]], ptr %_0, align [[VECTOR_ALIGN]]
|
||||
unsafe { std::mem::transmute(x) }
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ pub fn vector_align() -> usize {
|
||||
// CHECK-LABEL: @build_array_transmute_u
|
||||
#[no_mangle]
|
||||
pub fn build_array_transmute_u(x: [f32; 4]) -> U {
|
||||
// CHECK: %[[VAL:.+]] = load <4 x float>, {{ptr %x|.+>\* %.+}}, align [[ARRAY_ALIGN]]
|
||||
// CHECK: store <4 x float> %[[VAL:.+]], {{ptr %_0|.+>\* %.+}}, align [[VECTOR_ALIGN]]
|
||||
// CHECK: %[[VAL:.+]] = load <4 x float>, ptr %x, align [[ARRAY_ALIGN]]
|
||||
// CHECK: store <4 x float> %[[VAL:.+]], ptr %_0, align [[VECTOR_ALIGN]]
|
||||
unsafe { std::mem::transmute(x) }
|
||||
}
|
||||
|
@ -21,6 +21,6 @@
|
||||
// CHECK-LABEL: smoke
|
||||
#[no_mangle]
|
||||
pub fn smoke(ptrs: SimdConstPtr<u8, 8>, offsets: Simd<usize, 8>) -> SimdConstPtr<u8, 8> {
|
||||
// CHECK: getelementptr i8, <8 x {{i8\*|ptr}}> %0, <8 x i64> %1
|
||||
// CHECK: getelementptr i8, <8 x ptr> %0, <8 x i64> %1
|
||||
unsafe { simd_arith_offset(ptrs, offsets) }
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ pub fn zero_len_array() {
|
||||
// CHECK-LABEL: @byte_array
|
||||
#[no_mangle]
|
||||
pub fn byte_array() {
|
||||
// CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}, i8 7, i{{[0-9]+}} 4
|
||||
// CHECK: call void @llvm.memset.{{.+}}(ptr {{.*}}, i8 7, i{{[0-9]+}} 4
|
||||
// CHECK-NOT: br label %repeat_loop_header{{.*}}
|
||||
let x = [7u8; 4];
|
||||
opaque(&x);
|
||||
@ -39,7 +39,7 @@ enum Init {
|
||||
// CHECK-LABEL: @byte_enum_array
|
||||
#[no_mangle]
|
||||
pub fn byte_enum_array() {
|
||||
// CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}, i8 {{.*}}, i{{[0-9]+}} 4
|
||||
// CHECK: call void @llvm.memset.{{.+}}(ptr {{.*}}, i8 {{.*}}, i{{[0-9]+}} 4
|
||||
// CHECK-NOT: br label %repeat_loop_header{{.*}}
|
||||
let x = [Init::Memset; 4];
|
||||
opaque(&x);
|
||||
@ -48,7 +48,7 @@ pub fn byte_enum_array() {
|
||||
// CHECK-LABEL: @zeroed_integer_array
|
||||
#[no_mangle]
|
||||
pub fn zeroed_integer_array() {
|
||||
// CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}, i8 0, i{{[0-9]+}} 16
|
||||
// CHECK: call void @llvm.memset.{{.+}}(ptr {{.*}}, i8 0, i{{[0-9]+}} 16
|
||||
// CHECK-NOT: br label %repeat_loop_header{{.*}}
|
||||
let x = [0u32; 4];
|
||||
opaque(&x);
|
||||
|
@ -9,7 +9,7 @@
|
||||
#[no_mangle]
|
||||
pub fn slice_iter_len_eq_zero(y: std::slice::Iter<'_, Demo>) -> bool {
|
||||
// CHECK-NOT: sub
|
||||
// CHECK: %[[RET:.+]] = icmp eq {{i8\*|ptr}} {{%1|%0}}, {{%1|%0}}
|
||||
// CHECK: %[[RET:.+]] = icmp eq ptr {{%1|%0}}, {{%1|%0}}
|
||||
// CHECK: ret i1 %[[RET]]
|
||||
y.len() == 0
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
// CHECK-LABEL: @is_zero_slice_short
|
||||
#[no_mangle]
|
||||
pub fn is_zero_slice_short(data: &[u8; 4]) -> bool {
|
||||
// CHECK: %[[LOAD:.+]] = load i32, {{i32\*|ptr}} %{{.+}}, align 1
|
||||
// CHECK: %[[LOAD:.+]] = load i32, ptr %{{.+}}, align 1
|
||||
// CHECK-NEXT: %[[EQ:.+]] = icmp eq i32 %[[LOAD]], 0
|
||||
// CHECK-NEXT: ret i1 %[[EQ]]
|
||||
&data[..] == [0; 4]
|
||||
@ -34,7 +34,7 @@
|
||||
// CHECK-LABEL: @is_zero_array
|
||||
#[no_mangle]
|
||||
pub fn is_zero_array(data: &[u8; 4]) -> bool {
|
||||
// CHECK: %[[LOAD:.+]] = load i32, {{i32\*|ptr}} %{{.+}}, align 1
|
||||
// CHECK: %[[LOAD:.+]] = load i32, ptr %{{.+}}, align 1
|
||||
// CHECK-NEXT: %[[EQ:.+]] = icmp eq i32 %[[LOAD]], 0
|
||||
// CHECK-NEXT: ret i1 %[[EQ]]
|
||||
*data == [0; 4]
|
||||
@ -50,7 +50,7 @@
|
||||
fn eq_slice_of_nested_u8(x: &[[u8; 3]], y: &[[u8; 3]]) -> bool {
|
||||
// CHECK: icmp eq [[USIZE]] %x.1, %y.1
|
||||
// CHECK: %[[BYTES:.+]] = mul nsw [[USIZE]] %x.1, 3
|
||||
// CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}({{i8\*|ptr}}
|
||||
// CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}(ptr
|
||||
// CHECK-SAME: , [[USIZE]]{{( noundef)?}} %[[BYTES]])
|
||||
x == y
|
||||
}
|
||||
@ -62,7 +62,7 @@
|
||||
fn eq_slice_of_i32(x: &[i32], y: &[i32]) -> bool {
|
||||
// CHECK: icmp eq [[USIZE]] %x.1, %y.1
|
||||
// CHECK: %[[BYTES:.+]] = shl nsw [[USIZE]] %x.1, 2
|
||||
// CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}({{i32\*|ptr}}
|
||||
// CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}(ptr
|
||||
// CHECK-SAME: , [[USIZE]]{{( noundef)?}} %[[BYTES]])
|
||||
x == y
|
||||
}
|
||||
@ -74,7 +74,7 @@ fn eq_slice_of_i32(x: &[i32], y: &[i32]) -> bool {
|
||||
fn eq_slice_of_nonzero(x: &[NonZeroU32], y: &[NonZeroU32]) -> bool {
|
||||
// CHECK: icmp eq [[USIZE]] %x.1, %y.1
|
||||
// CHECK: %[[BYTES:.+]] = shl nsw [[USIZE]] %x.1, 2
|
||||
// CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}({{i32\*|ptr}}
|
||||
// CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}(ptr
|
||||
// CHECK-SAME: , [[USIZE]]{{( noundef)?}} %[[BYTES]])
|
||||
x == y
|
||||
}
|
||||
@ -86,7 +86,7 @@ fn eq_slice_of_nonzero(x: &[NonZeroU32], y: &[NonZeroU32]) -> bool {
|
||||
fn eq_slice_of_option_of_nonzero(x: &[Option<NonZeroI16>], y: &[Option<NonZeroI16>]) -> bool {
|
||||
// CHECK: icmp eq [[USIZE]] %x.1, %y.1
|
||||
// CHECK: %[[BYTES:.+]] = shl nsw [[USIZE]] %x.1, 1
|
||||
// CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}({{i16\*|ptr}}
|
||||
// CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}(ptr
|
||||
// CHECK-SAME: , [[USIZE]]{{( noundef)?}} %[[BYTES]])
|
||||
x == y
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
// compile-flags: -O
|
||||
// only-64bit (because we're using [ui]size)
|
||||
// ignore-debug (because the assertions get in the way)
|
||||
// min-llvm-version: 15.0 (because this is a relatively new instcombine)
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(slice_from_ptr_range)]
|
||||
|
@ -17,8 +17,8 @@ pub struct Bytes {
|
||||
pub fn small_array_alignment(x: &mut [i8; 4], y: [i8; 4]) {
|
||||
// CHECK: [[TMP:%.+]] = alloca i32
|
||||
// CHECK: %y = alloca [4 x i8]
|
||||
// CHECK: store i32 %0, {{i32\*|ptr}} [[TMP]]
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 1 {{.+}}, {{i8\*|ptr}} align 4 {{.+}}, i{{[0-9]+}} 4, i1 false)
|
||||
// CHECK: store i32 %0, ptr [[TMP]]
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 {{.+}}, ptr align 4 {{.+}}, i{{[0-9]+}} 4, i1 false)
|
||||
*x = y;
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ pub struct Bytes {
|
||||
pub fn small_struct_alignment(x: &mut Bytes, y: Bytes) {
|
||||
// CHECK: [[TMP:%.+]] = alloca i32
|
||||
// CHECK: %y = alloca %Bytes
|
||||
// CHECK: store i32 %0, {{i32\*|ptr}} [[TMP]]
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 1 {{.+}}, {{i8\*|ptr}} align 4 {{.+}}, i{{[0-9]+}} 4, i1 false)
|
||||
// CHECK: store i32 %0, ptr [[TMP]]
|
||||
// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 {{.+}}, ptr align 4 {{.+}}, i{{[0-9]+}} 4, i1 false)
|
||||
*x = y;
|
||||
}
|
||||
|
@ -83,9 +83,9 @@ pub fn swap_1kb_slices(x: &mut [OneKilobyteBuffer], y: &mut [OneKilobyteBuffer])
|
||||
#[no_mangle]
|
||||
pub fn swap_big_aligned(x: &mut BigButHighlyAligned, y: &mut BigButHighlyAligned) {
|
||||
// CHECK-NOT: call void @llvm.memcpy
|
||||
// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} noundef nonnull align 64 dereferenceable(192)
|
||||
// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} noundef nonnull align 64 dereferenceable(192)
|
||||
// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} noundef nonnull align 64 dereferenceable(192)
|
||||
// CHECK: call void @llvm.memcpy.{{.+}}(ptr noundef nonnull align 64 dereferenceable(192)
|
||||
// CHECK: call void @llvm.memcpy.{{.+}}(ptr noundef nonnull align 64 dereferenceable(192)
|
||||
// CHECK: call void @llvm.memcpy.{{.+}}(ptr noundef nonnull align 64 dereferenceable(192)
|
||||
// CHECK-NOT: call void @llvm.memcpy
|
||||
swap(x, y)
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
// compile-flags: -O -Z merge-functions=disabled
|
||||
// min-llvm-version: 15.0 # this test uses `ptr`s
|
||||
// ignore-debug
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
@ -1,5 +1,4 @@
|
||||
// compile-flags: -C opt-level=0 -C no-prepopulate-passes
|
||||
// min-llvm-version: 15.0 # this test assumes `ptr`s and thus no `pointercast`s
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
// min-llvm-version: 15.0
|
||||
// compile-flags: -O -Z merge-functions=disabled --edition=2021
|
||||
// only-x86_64
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
// compile-flags: -O
|
||||
// min-llvm-version: 15.0 (LLVM 13 in CI does this differently from submodule LLVM)
|
||||
// ignore-debug (because unchecked is checked in debug)
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
@ -1,5 +1,4 @@
|
||||
// compile-flags: -C no-prepopulate-passes
|
||||
// min-llvm-version: 15.0 (for opaque pointers)
|
||||
|
||||
// Check that we use undef (and not zero) for uninitialized bytes in constants.
|
||||
|
||||
|
@ -17,25 +17,25 @@ pub enum Unhab {}
|
||||
#[derive(Copy, Clone)]
|
||||
pub union UnionI64x4{ a:(), b: i64x4 }
|
||||
|
||||
// CHECK: define {{(dso_local )?}}void @test_UnionI64x4({{<4 x i64>\*|ptr}} {{.*}} %_1)
|
||||
// CHECK: define {{(dso_local )?}}void @test_UnionI64x4(ptr {{.*}} %_1)
|
||||
#[no_mangle]
|
||||
pub fn test_UnionI64x4(_: UnionI64x4) { loop {} }
|
||||
|
||||
pub union UnionI64x4_{ a: i64x4, b: (), c:i64x4, d: Unhab, e: ((),()), f: UnionI64x4 }
|
||||
|
||||
// CHECK: define {{(dso_local )?}}void @test_UnionI64x4_({{<4 x i64>\*|ptr}} {{.*}} %_1)
|
||||
// CHECK: define {{(dso_local )?}}void @test_UnionI64x4_(ptr {{.*}} %_1)
|
||||
#[no_mangle]
|
||||
pub fn test_UnionI64x4_(_: UnionI64x4_) { loop {} }
|
||||
|
||||
pub union UnionI64x4I64{ a: i64x4, b: i64 }
|
||||
|
||||
// CHECK: define {{(dso_local )?}}void @test_UnionI64x4I64({{%UnionI64x4I64\*|ptr}} {{.*}} %_1)
|
||||
// CHECK: define {{(dso_local )?}}void @test_UnionI64x4I64(ptr {{.*}} %_1)
|
||||
#[no_mangle]
|
||||
pub fn test_UnionI64x4I64(_: UnionI64x4I64) { loop {} }
|
||||
|
||||
pub union UnionI64x4Tuple{ a: i64x4, b: (i64, i64, i64, i64) }
|
||||
|
||||
// CHECK: define {{(dso_local )?}}void @test_UnionI64x4Tuple({{%UnionI64x4Tuple\*|ptr}} {{.*}} %_1)
|
||||
// CHECK: define {{(dso_local )?}}void @test_UnionI64x4Tuple(ptr {{.*}} %_1)
|
||||
#[no_mangle]
|
||||
pub fn test_UnionI64x4Tuple(_: UnionI64x4Tuple) { loop {} }
|
||||
|
||||
@ -65,7 +65,7 @@ pub fn test_UnionU128(_: UnionU128) -> UnionU128 { loop {} }
|
||||
|
||||
#[repr(C)]
|
||||
pub union CUnionU128{a:u128}
|
||||
// CHECK: define {{(dso_local )?}}void @test_CUnionU128({{%CUnionU128\*|ptr}} {{.*}} %_1)
|
||||
// CHECK: define {{(dso_local )?}}void @test_CUnionU128(ptr {{.*}} %_1)
|
||||
#[no_mangle]
|
||||
pub fn test_CUnionU128(_: CUnionU128) { loop {} }
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
// Test that even though we return a *const u8 not a &[u8] or a NonNull<u8>, LLVM knows that this
|
||||
// pointer is nonnull.
|
||||
// CHECK: nonnull {{i8\*|ptr}} @vec_as_ptr
|
||||
// CHECK: nonnull ptr @vec_as_ptr
|
||||
#[no_mangle]
|
||||
pub fn vec_as_ptr(v: &Vec<u8>) -> *const u8 {
|
||||
v.as_ptr()
|
||||
@ -12,7 +12,7 @@ pub fn vec_as_ptr(v: &Vec<u8>) -> *const u8 {
|
||||
|
||||
// Test that even though we return a *const u8 not a &[u8] or a NonNull<u8>, LLVM knows that this
|
||||
// pointer is nonnull.
|
||||
// CHECK: nonnull {{i8\*|ptr}} @vec_as_mut_ptr
|
||||
// CHECK: nonnull ptr @vec_as_mut_ptr
|
||||
#[no_mangle]
|
||||
pub fn vec_as_mut_ptr(v: &mut Vec<u8>) -> *mut u8 {
|
||||
v.as_mut_ptr()
|
||||
|
@ -1,7 +1,6 @@
|
||||
// compile-flags: -O -Z merge-functions=disabled
|
||||
// only-x86_64
|
||||
// ignore-debug
|
||||
// min-llvm-version: 15.0
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
@ -39,10 +39,10 @@ CHECK-NOT: [[DEFINE_INTERNAL]]
|
||||
CHECK: atomicrmw add ptr
|
||||
CHECK-SAME: @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called,
|
||||
|
||||
CHECK: declare void @llvm.instrprof.increment({{i8\*|ptr}}, i64, i32, i32) #[[LLVM_INSTRPROF_INCREMENT_ATTR:[0-9]+]]
|
||||
CHECK: declare void @llvm.instrprof.increment(ptr, i64, i32, i32) #[[LLVM_INSTRPROF_INCREMENT_ATTR:[0-9]+]]
|
||||
|
||||
WINDOWS: define linkonce_odr hidden i32 @__llvm_profile_runtime_user() #[[LLVM_PROFILE_RUNTIME_USER_ATTR:[0-9]+]] comdat {
|
||||
WINDOWS-NEXT: %1 = load i32, {{i32\*|ptr}} @__llvm_profile_runtime
|
||||
WINDOWS-NEXT: %1 = load i32, ptr @__llvm_profile_runtime
|
||||
WINDOWS-NEXT: ret i32 %1
|
||||
WINDOWS-NEXT: }
|
||||
|
||||
|
@ -2,7 +2,7 @@ CHECK: define void @call_a_bunch_of_functions({{.*}} {
|
||||
|
||||
# Make sure that indirect call promotion inserted a check against the most
|
||||
# frequently called function.
|
||||
CHECK: %{{.*}} = icmp eq {{void \(\)\*|ptr}} %{{.*}}, @function_called_always
|
||||
CHECK: %{{.*}} = icmp eq ptr %{{.*}}, @function_called_always
|
||||
|
||||
# Check that the call to `function_called_always` was inlined, so that we
|
||||
# directly call `opaque_f1` from the upstream crate.
|
||||
@ -12,5 +12,5 @@ CHECK: call void @opaque_f1()
|
||||
# Same checks as above, repeated for the trait object case
|
||||
|
||||
CHECK: define void @call_a_bunch_of_trait_methods({{.*}}
|
||||
CHECK: %{{.*}} = icmp eq {{void \(\{\}\*\)\*|ptr}} %{{.*}}, {{.*}}@foo
|
||||
CHECK: %{{.*}} = icmp eq ptr %{{.*}}, {{.*}}@foo
|
||||
CHECK: tail call void @opaque_f2()
|
||||
|
@ -1,6 +1,5 @@
|
||||
// build-pass
|
||||
// compile-flags: -O
|
||||
// min-llvm-version: 14.0.5
|
||||
// needs-asm-support
|
||||
// only-x86_64
|
||||
// only-linux
|
||||
|
@ -1,7 +1,5 @@
|
||||
// run-pass
|
||||
// ^-- The above is needed as this issue is related to LLVM/codegen.
|
||||
// min-llvm-version:15.0.0
|
||||
// ^-- The above is needed as this issue is fixed by the opaque pointers.
|
||||
|
||||
fn main() {
|
||||
type_error(|x| &x);
|
||||
|
@ -1,8 +1,6 @@
|
||||
// run-pass
|
||||
// compile-flags: -Copt-level=0 -Cllvm-args=-opaque-pointers=0
|
||||
|
||||
// (opaque-pointers flag is called force-opaque-pointers in LLVM 13...)
|
||||
// min-llvm-version: 14.0
|
||||
// (the ability to disable opaque pointers has been removed in LLVM 17)
|
||||
// ignore-llvm-version: 17 - 99
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
// run-pass
|
||||
// regression test for issue #94923
|
||||
// min-llvm-version: 15.0.0
|
||||
// compile-flags: -C opt-level=3
|
||||
|
||||
fn f0<T>(mut x: usize) -> usize {
|
||||
|
Loading…
Reference in New Issue
Block a user