Skip to content
Open
Show file tree
Hide file tree
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
9 changes: 9 additions & 0 deletions compiler/rustc_codegen_llvm/src/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,15 @@ fn create_wrapper_function(
None
};

if tcx.sess.target.is_like_gpu {
// Conservatively apply convergent to all functions
attributes::apply_to_llfn(
llfn,
llvm::AttributePlace::Function,
&[llvm::AttributeKind::Convergent.create_attr(cx.llcx)],
);
}

let llbb = unsafe { llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, c"entry".as_ptr()) };
let mut bx = SBuilder::build(&cx, llbb);

Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_codegen_llvm/src/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use std::borrow::Borrow;

use itertools::Itertools;
use rustc_codegen_ssa::traits::TypeMembershipCodegenMethods;
use rustc_codegen_ssa::traits::{MiscCodegenMethods, TypeMembershipCodegenMethods};
use rustc_data_structures::fx::FxIndexSet;
use rustc_middle::ty::{Instance, Ty};
use rustc_sanitizers::{cfi, kcfi};
Expand Down Expand Up @@ -70,6 +70,11 @@ pub(crate) fn declare_raw_fn<'ll, 'tcx>(

let mut attrs = SmallVec::<[_; 4]>::new();

if cx.sess().target.is_like_gpu {
// Conservatively apply convergent to all functions
attrs.push(llvm::AttributeKind::Convergent.create_attr(cx.llcx));
}

if cx.tcx.sess.opts.cg.no_redzone.unwrap_or(cx.tcx.sess.target.disable_redzone) {
attrs.push(llvm::AttributeKind::NoRedZone.create_attr(cx.llcx));
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ pub(crate) enum AttributeKind {
CapturesNone = 46,
SanitizeRealtimeNonblocking = 47,
SanitizeRealtimeBlocking = 48,
Convergent = 49,
}

/// LLVMIntPredicate
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ enum class LLVMRustAttributeKind {
CapturesNone = 46,
SanitizeRealtimeNonblocking = 47,
SanitizeRealtimeBlocking = 48,
Convergent = 49,
};

static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) {
Expand Down Expand Up @@ -428,6 +429,8 @@ static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) {
return Attribute::SanitizeRealtime;
case LLVMRustAttributeKind::SanitizeRealtimeBlocking:
return Attribute::SanitizeRealtimeBlocking;
case LLVMRustAttributeKind::Convergent:
return Attribute::Convergent;
}
report_fatal_error("bad LLVMRustAttributeKind");
}
Expand Down
14 changes: 10 additions & 4 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -586,10 +586,16 @@ impl Session {
}

pub fn mir_opt_level(&self) -> usize {
self.opts
.unstable_opts
.mir_opt_level
.unwrap_or_else(|| if self.opts.optimize != OptLevel::No { 2 } else { 1 })
if self.target.is_like_gpu {
// Special care needs to be taken for convergent operations (i.e. not duplicating them).
// We do not want to handle these, so do not run any optimizations.
0
} else {
self.opts
.unstable_opts
.mir_opt_level
.unwrap_or_else(|| if self.opts.optimize != OptLevel::No { 2 } else { 1 })
}
}

/// Calculates the flavor of LTO to use for this compilation.
Expand Down
28 changes: 28 additions & 0 deletions tests/codegen-llvm/gpu-convergent.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Checks that when compiling for GPU targets, the convergent attribute
// is added to function declarations and definitions.

//@ add-minicore
//@ revisions: amdgpu nvptx
//@ [amdgpu] compile-flags: --crate-type=rlib --target=amdgcn-amd-amdhsa -Ctarget-cpu=gfx900
//@ [amdgpu] needs-llvm-components: amdgpu
//@ [nvptx] compile-flags: --crate-type=rlib --target=nvptx64-nvidia-cuda
//@ [nvptx] needs-llvm-components: nvptx
#![feature(no_core, lang_items, abi_gpu_kernel)]
#![no_core]

extern crate minicore;
use minicore::*;

extern "C" {
fn ext();
}

// CHECK: define {{.*}}_kernel void @fun(i32{{.*}}) unnamed_addr #[[ATTR:[0-9]+]] {
// CHECK: declare void @ext() unnamed_addr #[[ATTR]]
// CHECK: attributes #[[ATTR]] = {{.*}} convergent
#[no_mangle]
pub extern "gpu-kernel" fn fun(_: i32) {
unsafe {
ext();
}
}
Loading