Skip to content

Commit 240af05

Browse files
committed
Overhaul FFI for creation of LLVM range attributes
1 parent f6ddd99 commit 240af05

File tree

3 files changed

+33
-20
lines changed

3 files changed

+33
-20
lines changed

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1881,12 +1881,15 @@ unsafe extern "C" {
18811881
C: &Context,
18821882
effects: MemoryEffects,
18831883
) -> &Attribute;
1884-
pub(crate) fn LLVMRustCreateRangeAttribute(
1885-
C: &Context,
1886-
num_bits: c_uint,
1887-
lower_words: *const u64,
1888-
upper_words: *const u64,
1889-
) -> &Attribute;
1884+
/// Lower and upper bounds are each passed as a `u128` broken into low and high 64-bit parts.
1885+
pub(crate) safe fn LLVMRustCreateRangeAttribute<'ll>(
1886+
C: &'ll Context,
1887+
NumBits: c_uint,
1888+
LowerBoundLo: u64,
1889+
LowerBoundHi: u64,
1890+
UpperBoundLo: u64,
1891+
UpperBoundHi: u64,
1892+
) -> &'ll Attribute;
18901893

18911894
// Operations on functions
18921895
pub(crate) fn LLVMRustGetOrInsertFunction<'a>(

compiler/rustc_codegen_llvm/src/llvm/mod.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -112,17 +112,22 @@ pub(crate) fn CreateAllocKindAttr(llcx: &Context, kind_arg: AllocKindFlags) -> &
112112

113113
pub(crate) fn CreateRangeAttr(llcx: &Context, size: Size, range: WrappingRange) -> &Attribute {
114114
let lower = range.start;
115+
// LLVM treats the upper bound as exclusive, but allows wrapping.
115116
let upper = range.end.wrapping_add(1);
116-
let lower_words = [lower as u64, (lower >> 64) as u64];
117-
let upper_words = [upper as u64, (upper >> 64) as u64];
118-
unsafe {
119-
LLVMRustCreateRangeAttribute(
120-
llcx,
121-
size.bits().try_into().unwrap(),
122-
lower_words.as_ptr(),
123-
upper_words.as_ptr(),
124-
)
125-
}
117+
118+
// Split each endpoint into a pair of u64 values to make FFI easier.
119+
let as_lo_hi_pair = |x: u128| (x as u64, (x >> 64) as u64);
120+
let (lower_bound_lo, lower_bound_hi) = as_lo_hi_pair(lower);
121+
let (upper_bound_lo, upper_bound_hi) = as_lo_hi_pair(upper);
122+
123+
LLVMRustCreateRangeAttribute(
124+
llcx,
125+
size.bits().try_into().unwrap(),
126+
lower_bound_lo,
127+
lower_bound_hi,
128+
upper_bound_lo,
129+
upper_bound_hi,
130+
)
126131
}
127132

128133
#[derive(Copy, Clone)]

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -486,10 +486,15 @@ LLVMRustCreateAllocSizeAttr(LLVMContextRef C, uint32_t ElementSizeArg) {
486486

487487
extern "C" LLVMAttributeRef
488488
LLVMRustCreateRangeAttribute(LLVMContextRef C, unsigned NumBits,
489-
const uint64_t LowerWords[],
490-
const uint64_t UpperWords[]) {
491-
return LLVMCreateConstantRangeAttribute(C, Attribute::Range, NumBits,
492-
LowerWords, UpperWords);
489+
uint64_t LowerBoundLo, uint64_t LowerBoundHi,
490+
uint64_t UpperBoundLo, uint64_t UpperBoundHi) {
491+
// For both endpoints, reassemble the lo/hi parts into into APInt values.
492+
// APInt will automatically discard any excess bits.
493+
ConstantRange RangeValue = {
494+
APInt(NumBits, ArrayRef{LowerBoundLo, LowerBoundHi}),
495+
APInt(NumBits, ArrayRef{UpperBoundLo, UpperBoundHi}),
496+
};
497+
return wrap(Attribute::get(*unwrap(C), llvm::Attribute::Range, RangeValue));
493498
}
494499

495500
// These values **must** match ffi::AllocKindFlags.

0 commit comments

Comments
 (0)