From 6ff72a1cfd9298b1e8de5fd9a8182a87fbc318fe Mon Sep 17 00:00:00 2001 From: Richard Diamond Date: Wed, 18 Jul 2018 22:01:19 -0500 Subject: [PATCH 1/4] AMDGPU call abi info. --- src/librustc_target/abi/call/amdgpu.rs | 42 ++++++++++++++++++++++++++ src/librustc_target/abi/call/mod.rs | 2 ++ 2 files changed, 44 insertions(+) create mode 100644 src/librustc_target/abi/call/amdgpu.rs diff --git a/src/librustc_target/abi/call/amdgpu.rs b/src/librustc_target/abi/call/amdgpu.rs new file mode 100644 index 0000000000000..62462f04d8f56 --- /dev/null +++ b/src/librustc_target/abi/call/amdgpu.rs @@ -0,0 +1,42 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use abi::call::{ArgType, FnType, }; +use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; + +fn classify_ret_ty<'a, Ty, C>(_tuncx: C, ret: &mut ArgType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ + ret.extend_integer_width_to(32); +} + +fn classify_arg_ty<'a, Ty, C>(_cx: C, arg: &mut ArgType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ + arg.extend_integer_width_to(32); +} + +pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>) + where Ty: TyLayoutMethods<'a, C> + Copy, + C: LayoutOf> + HasDataLayout +{ + if !fty.ret.is_ignore() { + classify_ret_ty(cx, &mut fty.ret); + } + + for arg in &mut fty.args { + if arg.is_ignore() { + continue; + } + classify_arg_ty(cx, arg); + } +} diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs index 78ed4b2d615a4..788497a378fe9 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/src/librustc_target/abi/call/mod.rs @@ -13,6 +13,7 @@ use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; use spec::HasTargetSpec; mod aarch64; +mod amdgpu; mod arm; mod asmjs; mod hexagon; @@ -503,6 +504,7 @@ impl<'a, Ty> FnType<'a, Ty> { x86_64::compute_abi_info(cx, self); }, "aarch64" => aarch64::compute_abi_info(cx, self), + "amdgpu" => amdgpu::compute_abi_info(cx, self), "arm" => arm::compute_abi_info(cx, self), "mips" => mips::compute_abi_info(cx, self), "mips64" => mips64::compute_abi_info(cx, self), From 1c0603e55fdfd17fb7960967856a89482ff7543b Mon Sep 17 00:00:00 2001 From: Richard Diamond Date: Wed, 18 Jul 2018 22:03:39 -0500 Subject: [PATCH 2/4] Actually enable the amdgpu component if present. --- src/librustc_llvm/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 4e24a26983d48..7d01ed556c8dd 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -81,7 +81,7 @@ fn main() { let is_crossed = target != host; let mut optional_components = - vec!["x86", "arm", "aarch64", "mips", "powerpc", + vec!["x86", "arm", "aarch64", "amdgpu", "mips", "powerpc", "systemz", "jsbackend", "webassembly", "msp430", "sparc", "nvptx"]; let mut version_cmd = Command::new(&llvm_config); From bfddedee37d69a4d2180f8c5e7dba000762618e9 Mon Sep 17 00:00:00 2001 From: Richard Diamond Date: Wed, 18 Jul 2018 22:04:27 -0500 Subject: [PATCH 3/4] AMDGPU ignores `noinline` when it slaps `alwaysinline` everywhere. Allow target specs to disable that attribute. --- src/librustc_codegen_llvm/attributes.rs | 11 ++++++++--- src/librustc_codegen_llvm/callee.rs | 2 +- src/librustc_codegen_llvm/mono_item.rs | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 2b64642b766ab..739acf6f5caee 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -16,6 +16,7 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::session::Session; use rustc::session::config::Sanitizer; use rustc::ty::TyCtxt; +use rustc::ty::layout::HasTyCtxt; use rustc::ty::query::Providers; use rustc_data_structures::sync::Lrc; use rustc_data_structures::fx::FxHashMap; @@ -32,12 +33,16 @@ use value::Value; /// Mark LLVM function to use provided inline heuristic. #[inline] -pub fn inline(val: &'ll Value, inline: InlineAttr) { +pub fn inline(cx: &CodegenCx<'ll, '_>, val: &'ll Value, inline: InlineAttr) { use self::InlineAttr::*; match inline { Hint => Attribute::InlineHint.apply_llfn(Function, val), Always => Attribute::AlwaysInline.apply_llfn(Function, val), - Never => Attribute::NoInline.apply_llfn(Function, val), + Never => { + if cx.tcx().sess.target.target.arch != "amdgpu" { + Attribute::NoInline.apply_llfn(Function, val); + } + }, None => { Attribute::InlineHint.unapply_llfn(Function, val); Attribute::AlwaysInline.unapply_llfn(Function, val); @@ -142,7 +147,7 @@ pub fn from_fn_attrs( let codegen_fn_attrs = id.map(|id| cx.tcx.codegen_fn_attrs(id)) .unwrap_or(CodegenFnAttrs::new()); - inline(llfn, codegen_fn_attrs.inline); + inline(cx, llfn, codegen_fn_attrs.inline); // The `uwtable` attribute according to LLVM is: // diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs index 2e90f95fa8e2d..4b4ccb3b600b3 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/src/librustc_codegen_llvm/callee.rs @@ -96,7 +96,7 @@ pub fn get_fn( debug!("get_fn: not casting pointer!"); if instance.def.is_inline(tcx) { - attributes::inline(llfn, attributes::InlineAttr::Hint); + attributes::inline(cx, llfn, attributes::InlineAttr::Hint); } attributes::from_fn_attrs(cx, llfn, Some(instance.def.def_id())); diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs index 7f25911abec35..a8502e9244768 100644 --- a/src/librustc_codegen_llvm/mono_item.rs +++ b/src/librustc_codegen_llvm/mono_item.rs @@ -180,7 +180,7 @@ fn predefine_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, debug!("predefine_fn: mono_ty = {:?} instance = {:?}", mono_ty, instance); if instance.def.is_inline(cx.tcx) { - attributes::inline(lldecl, attributes::InlineAttr::Hint); + attributes::inline(cx, lldecl, attributes::InlineAttr::Hint); } attributes::from_fn_attrs(cx, lldecl, Some(instance.def.def_id())); From 66e8e1953e25a8d9e86e2e3fef88cc178a9cea02 Mon Sep 17 00:00:00 2001 From: Richard Diamond Date: Wed, 18 Jul 2018 22:05:08 -0500 Subject: [PATCH 4/4] Fix an AMDGPU related load bit range metadata assertion. --- src/librustc_codegen_llvm/builder.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index cfbc2ab90072d..e3526a5a2eead 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -496,6 +496,14 @@ impl Builder<'a, 'll, 'tcx> { pub fn range_metadata(&self, load: &'ll Value, range: Range) { + if self.sess().target.target.arch == "amdgpu" { + // amdgpu/LLVM does something weird and thinks a i64 value is + // split into a v2i32, halving the bitwidth LLVM expects, + // tripping an assertion. So, for now, just disable this + // optimization. + return; + } + unsafe { let llty = val_ty(load); let v = [