Skip to content

Make i128 aligned to 16 bytes on all 64bit plats #38871

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ pub fn target() -> TargetResult {
llvm_target: "mips64-unknown-linux-gnuabi64".to_string(),
target_endian: "big".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "mips64".to_string(),
target_os: "linux".to_string(),
target_env: "gnu".to_string(),
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ pub fn target() -> TargetResult {
llvm_target: "mips64el-unknown-linux-gnuabi64".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "mips64".to_string(),
target_os: "linux".to_string(),
target_env: "gnu".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/powerpc64_unknown_linux_gnu.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ pub fn target() -> TargetResult {
llvm_target: "powerpc64-unknown-linux-gnu".to_string(),
target_endian: "big".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "E-m:e-i64:64-n32:64".to_string(),
data_layout: "E-m:e-i64:64-i128:128-n32:64".to_string(),
arch: "powerpc64".to_string(),
target_os: "linux".to_string(),
target_env: "gnu".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ pub fn target() -> TargetResult {
llvm_target: "powerpc64le-unknown-linux-gnu".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:e-i64:64-n32:64".to_string(),
data_layout: "e-m:e-i64:64-i128:128-n32:64".to_string(),
arch: "powerpc64".to_string(),
target_os: "linux".to_string(),
target_env: "gnu".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/s390x_unknown_linux_gnu.rs
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ pub fn target() -> TargetResult {
llvm_target: "s390x-unknown-linux-gnu".to_string(),
target_endian: "big".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64".to_string(),
data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-i128:128-f128:64-a:8:16-n32:64".to_string(),
arch: "s390x".to_string(),
target_os: "linux".to_string(),
target_env: "gnu".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/sparc64_unknown_linux_gnu.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ pub fn target() -> TargetResult {
llvm_target: "sparc64-unknown-linux-gnu".to_string(),
target_endian: "big".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "E-m:e-i64:64-n32:64-S128".to_string(),
data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".to_string(),
arch: "sparc64".to_string(),
target_os: "linux".to_string(),
target_env: "gnu".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/sparc64_unknown_netbsd.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ pub fn target() -> TargetResult {
llvm_target: "sparc64-unknown-netbsd".to_string(),
target_endian: "big".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "E-m:e-i64:64-n32:64-S128".to_string(),
data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".to_string(),
arch: "sparc64".to_string(),
target_os: "netbsd".to_string(),
target_env: "".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_apple_darwin.rs
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ pub fn target() -> TargetResult {
llvm_target: "x86_64-apple-darwin".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:o-i64:64-f80:128-n8:16:32:64-S128".to_string(),
data_layout: "e-m:o-i64:64-i128:128-f80:128-n8:16:32:64-S128".to_string(),
arch: "x86_64".to_string(),
target_os: "macos".to_string(),
target_env: "".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_apple_ios.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ pub fn target() -> TargetResult {
llvm_target: "x86_64-apple-ios".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:o-i64:64-f80:128-n8:16:32:64-S128".to_string(),
data_layout: "e-m:o-i64:64-i128:128-f80:128-n8:16:32:64-S128".to_string(),
arch: "x86_64".to_string(),
target_os: "ios".to_string(),
target_env: "".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_pc_windows_gnu.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ pub fn target() -> TargetResult {
llvm_target: "x86_64-pc-windows-gnu".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:w-i64:64-f80:128-n8:16:32:64-S128".to_string(),
data_layout: "e-m:w-i64:64-i128:128-f80:128-n8:16:32:64-S128".to_string(),
arch: "x86_64".to_string(),
target_os: "windows".to_string(),
target_env: "gnu".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_pc_windows_msvc.rs
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ pub fn target() -> TargetResult {
llvm_target: "x86_64-pc-windows-msvc".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:w-i64:64-f80:128-n8:16:32:64-S128".to_string(),
data_layout: "e-m:w-i64:64-i128:128-f80:128-n8:16:32:64-S128".to_string(),
arch: "x86_64".to_string(),
target_os: "windows".to_string(),
target_env: "msvc".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_rumprun_netbsd.rs
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@ pub fn target() -> TargetResult {
llvm_target: "x86_64-rumprun-netbsd".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
data_layout: "e-m:e-i64:64-i128:128-f80:128-n8:16:32:64-S128".to_string(),
arch: "x86_64".to_string(),
target_os: "netbsd".to_string(),
target_env: "".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_sun_solaris.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ pub fn target() -> TargetResult {
llvm_target: "x86_64-pc-solaris".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
data_layout: "e-m:e-i64:64-i128:128-f80:128-n8:16:32:64-S128".to_string(),
arch: "x86_64".to_string(),
target_os: "solaris".to_string(),
target_env: "".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_unknown_bitrig.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ pub fn target() -> TargetResult {
llvm_target: "x86_64-unknown-bitrig".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
data_layout: "e-m:e-i64:64-i128:128-f80:128-n8:16:32:64-S128".to_string(),
arch: "x86_64".to_string(),
target_os: "bitrig".to_string(),
target_env: "".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_unknown_dragonfly.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ pub fn target() -> TargetResult {
llvm_target: "x86_64-unknown-dragonfly".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
data_layout: "e-m:e-i64:64-i128:128-f80:128-n8:16:32:64-S128".to_string(),
arch: "x86_64".to_string(),
target_os: "dragonfly".to_string(),
target_env: "".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_unknown_freebsd.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ pub fn target() -> TargetResult {
llvm_target: "x86_64-unknown-freebsd".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
data_layout: "e-m:e-i64:64-i128:128-f80:128-n8:16:32:64-S128".to_string(),
arch: "x86_64".to_string(),
target_os: "freebsd".to_string(),
target_env: "".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_unknown_fuchsia.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ pub fn target() -> TargetResult {
llvm_target: "x86_64-unknown-fuchsia".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
data_layout: "e-m:e-i64:64-i128:128-f80:128-n8:16:32:64-S128".to_string(),
arch: "x86_64".to_string(),
target_os: "fuchsia".to_string(),
target_env: "".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_unknown_haiku.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ pub fn target() -> TargetResult {
llvm_target: "x86_64-unknown-haiku".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
data_layout: "e-m:e-i64:64-i128:128-f80:128-n8:16:32:64-S128".to_string(),
arch: "x86_64".to_string(),
target_os: "haiku".to_string(),
target_env: "".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_unknown_linux_gnu.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ pub fn target() -> TargetResult {
llvm_target: "x86_64-unknown-linux-gnu".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
data_layout: "e-m:e-i64:64-i128:128-f80:128-n8:16:32:64-S128".to_string(),
arch: "x86_64".to_string(),
target_os: "linux".to_string(),
target_env: "gnu".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_unknown_linux_musl.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ pub fn target() -> TargetResult {
llvm_target: "x86_64-unknown-linux-musl".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
data_layout: "e-m:e-i64:64-i128:128-f80:128-n8:16:32:64-S128".to_string(),
arch: "x86_64".to_string(),
target_os: "linux".to_string(),
target_env: "musl".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_unknown_netbsd.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ pub fn target() -> TargetResult {
llvm_target: "x86_64-unknown-netbsd".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
data_layout: "e-m:e-i64:64-i128:128-f80:128-n8:16:32:64-S128".to_string(),
arch: "x86_64".to_string(),
target_os: "netbsd".to_string(),
target_env: "".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_unknown_openbsd.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ pub fn target() -> TargetResult {
llvm_target: "x86_64-unknown-openbsd".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
data_layout: "e-m:e-i64:64-i128:128-f80:128-n8:16:32:64-S128".to_string(),
arch: "x86_64".to_string(),
target_os: "openbsd".to_string(),
target_env: "".to_string(),
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_unknown_redox.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ pub fn target() -> TargetResult {
llvm_target: "x86_64-unknown-redox".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
data_layout: "e-m:e-i64:64-i128:128-f80:128-n8:16:32:64-S128".to_string(),
arch: "x86_64".to_string(),
target_os: "redox".to_string(),
target_env: "".to_string(),
2 changes: 2 additions & 0 deletions src/librustc_llvm/ffi.rs
Original file line number Diff line number Diff line change
@@ -691,6 +691,7 @@ extern "C" {
-> ValueRef;
pub fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
pub fn LLVMRustAddDereferenceableAttr(Fn: ValueRef, index: c_uint, bytes: u64);
pub fn LLVMRustAddAlignAttr(Fn: ValueRef, index: c_uint, bytes: u64);
pub fn LLVMRustAddFunctionAttribute(Fn: ValueRef, index: c_uint, attr: Attribute);
pub fn LLVMRustAddFunctionAttrStringValue(Fn: ValueRef,
index: c_uint,
@@ -721,6 +722,7 @@ extern "C" {
pub fn LLVMSetInstructionCallConv(Instr: ValueRef, CC: c_uint);
pub fn LLVMRustAddCallSiteAttribute(Instr: ValueRef, index: c_uint, attr: Attribute);
pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: ValueRef, index: c_uint, bytes: u64);
pub fn LLVMRustAddAlignCallSiteAttr(Instr: ValueRef, index: c_uint, bytes: u64);

// Operations on load/store instructions (only)
pub fn LLVMSetVolatile(MemoryAccessInst: ValueRef, volatile: Bool);
12 changes: 12 additions & 0 deletions src/librustc_trans/abi.rs
Original file line number Diff line number Diff line change
@@ -96,6 +96,7 @@ impl ArgAttribute {
pub struct ArgAttributes {
regular: ArgAttribute,
dereferenceable_bytes: u64,
align: u64,
}

impl ArgAttributes {
@@ -109,6 +110,11 @@ impl ArgAttributes {
self
}

pub fn set_align(&mut self, align: u64) -> &mut Self {
self.align = align;
self
}

pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
unsafe {
self.regular.for_each_kind(|attr| attr.apply_llfn(idx, llfn));
@@ -117,6 +123,9 @@ impl ArgAttributes {
idx.as_uint(),
self.dereferenceable_bytes);
}
if self.align != 0 {
llvm::LLVMRustAddAlignAttr(llfn, idx.as_uint(), self.align);
}
}
}

@@ -128,6 +137,9 @@ impl ArgAttributes {
idx.as_uint(),
self.dereferenceable_bytes);
}
if self.align != 0 {
llvm::LLVMRustAddAlignCallSiteAttr(callsite, idx.as_uint(), self.align);
}
}
}
}
3 changes: 2 additions & 1 deletion src/librustc_trans/cabi_asmjs.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@
#![allow(non_upper_case_globals)]

use llvm::{Struct, Array};
use abi::{FnType, ArgType, ArgAttribute};
use abi::{FnType, ArgType, ArgAttribute, ty_align};
use context::CrateContext;

// Data layout: e-p:32:32-i64:64-v128:32:128-n32-S128
@@ -40,6 +40,7 @@ fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType) {
if arg.ty.is_aggregate() {
arg.make_indirect(ccx);
arg.attrs.set(ArgAttribute::ByVal);
arg.attrs.set_align(ty_align(arg.ty, 0) as u64);
}
}

3 changes: 2 additions & 1 deletion src/librustc_trans/cabi_x86.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
// except according to those terms.

use llvm::*;
use abi::{ArgAttribute, FnType};
use abi::{ArgAttribute, FnType, ty_align};
use type_::Type;
use super::common::*;
use super::machine::*;
@@ -53,6 +53,7 @@ pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType, flavor: Flavor) {
if arg.ty.kind() == Struct {
arg.make_indirect(ccx);
arg.attrs.set(ArgAttribute::ByVal);
arg.attrs.set_align(ty_align(arg.ty, 0) as u64);
} else {
arg.extend_integer_width_to(32);
}
3 changes: 2 additions & 1 deletion src/librustc_trans/cabi_x86_64.rs
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ use self::RegClass::*;

use llvm::{Integer, Pointer, Float, Double};
use llvm::{Struct, Array, Vector};
use abi::{self, ArgType, ArgAttribute, FnType};
use abi::{self, ArgType, ArgAttribute, FnType, ty_align};
use context::CrateContext;
use type_::Type;

@@ -343,6 +343,7 @@ pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) {
arg.make_indirect(ccx);
if let Some(attr) = ind_attr {
arg.attrs.set(attr);
arg.attrs.set_align(ty_align(arg.ty, 0) as u64);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this a noop? (same for all the other cabi_* changes)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #38870 for this.

}
} else {
arg.cast = Some(llreg_ty(ccx, &cls));
5 changes: 4 additions & 1 deletion src/librustc_trans/context.rs
Original file line number Diff line number Diff line change
@@ -374,8 +374,11 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR
// FIXME(#34960)
let cfg_llvm_root = option_env!("CFG_LLVM_ROOT").unwrap_or("");
let custom_llvm_used = cfg_llvm_root.trim() != "";
// Ignore any `-i128:128` that we add to our own data-layouts
let this_dl = sess.target.target.data_layout.replace("-i128:128", "");
let that_dl = data_layout.replace("-i128:128", "");

if !custom_llvm_used && sess.target.target.data_layout != data_layout {
if !custom_llvm_used && this_dl != that_dl {
bug!("data-layout for builtin `{}` target, `{}`, \
differs from LLVM default, `{}`",
sess.target.target.llvm_target,
17 changes: 14 additions & 3 deletions src/rt/rust_test_helpers.c
Original file line number Diff line number Diff line change
@@ -269,10 +269,21 @@ LARGE_INTEGER increment_all_parts(LARGE_INTEGER li) {
return li;
}

#define DO_INT128_TEST !(defined(WIN32) || defined(_WIN32) || defined(__WIN32)) && \
defined(__amd64__)
#if !(defined(WIN32) || defined(_WIN32) || defined(__WIN32)) && defined(__amd64__)

#if DO_INT128_TEST
struct Foo {
__int128 a;
int8_t b;
uint16_t c;
};

struct Foo adt_id(struct Foo foo) {
return foo;
}

struct Foo adt_clone(struct Foo *foo) {
return *foo;
}

unsigned __int128 identity(unsigned __int128 a) {
return a;
19 changes: 19 additions & 0 deletions src/rustllvm/RustWrapper.cpp
Original file line number Diff line number Diff line change
@@ -174,6 +174,17 @@ extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
AttributeSet::get(Call->getContext(), Index, B)));
}

extern "C" void LLVMRustAddAlignCallSiteAttr(LLVMValueRef Instr,
unsigned Index,
uint64_t Bytes) {
CallSite Call = CallSite(unwrap<Instruction>(Instr));
AttrBuilder B;
B.addAlignmentAttr(Bytes);
Call.setAttributes(Call.getAttributes().addAttributes(
Call->getContext(), Index,
AttributeSet::get(Call->getContext(), Index, B)));
}

extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
LLVMRustAttribute RustAttr) {
Function *A = unwrap<Function>(Fn);
@@ -190,6 +201,14 @@ extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index,
A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B));
}

extern "C" void LLVMRustAddAlignAttr(LLVMValueRef Fn, unsigned Index,
uint64_t Bytes) {
Function *A = unwrap<Function>(Fn);
AttrBuilder B;
B.addAlignmentAttr(Bytes);
A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B));
}

extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
unsigned Index,
const char *Name,
15 changes: 15 additions & 0 deletions src/test/run-pass/i128-ffi.rs
Original file line number Diff line number Diff line change
@@ -22,11 +22,21 @@

#![feature(i128_type)]

#[repr(C)]
#[derive(Copy, Clone, PartialEq, Debug)]
struct Foo {
a: i128,
b: i8,
c: u16,
}

#[link(name = "rust_test_helpers", kind = "static")]
extern "C" {
fn identity(f: u128) -> u128;
fn square(f: i128) -> i128;
fn sub(f: i128, f: i128) -> i128;
fn adt_id(f: Foo) -> Foo;
fn adt_clone(f: *const Foo) -> Foo;
}

fn main() {
@@ -41,5 +51,10 @@ fn main() {
let k_d = 0x2468_ACF1_3579_BDFF_DB97_530E_CA86_420;
let k_out = sub(k_d, k);
assert_eq!(k, k_out);
let a = Foo { a: 1, b: 2, c: 3 };
let b = adt_id(a);
assert_eq!(a, b);
let b = adt_clone(&a);
assert_eq!(a, b);
}
}