Skip to content

Commit f6ca5aa

Browse files
authored
Rollup merge of #103977 - TimNN:memory-effects, r=nikic
LLVM 16: Switch to using MemoryEffects This adapts the compiler to the changes required by llvm/llvm-project@304f1d5. AFAICT, `WriteOnly` isn't used by the compiler, all `ReadNone` uses were migrated and the remaining use of `ReadOnly` is only for function parameters. To simplify the FFI, this PR uses an enum to represent `MemoryEffects` across the FFI boundary, which then gets mapped to the matching static factory method when constructing the attribute. Fixes #103961. `@rustbot` label +llvm-main r? `@nikic`
2 parents b1a47d2 + c15cfc9 commit f6ca5aa

File tree

8 files changed

+67
-12
lines changed

8 files changed

+67
-12
lines changed

compiler/rustc_codegen_llvm/src/asm.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -285,13 +285,13 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
285285
let mut attrs = SmallVec::<[_; 2]>::new();
286286
if options.contains(InlineAsmOptions::PURE) {
287287
if options.contains(InlineAsmOptions::NOMEM) {
288-
attrs.push(llvm::AttributeKind::ReadNone.create_attr(self.cx.llcx));
288+
attrs.push(llvm::MemoryEffects::None.create_attr(self.cx.llcx));
289289
} else if options.contains(InlineAsmOptions::READONLY) {
290-
attrs.push(llvm::AttributeKind::ReadOnly.create_attr(self.cx.llcx));
290+
attrs.push(llvm::MemoryEffects::ReadOnly.create_attr(self.cx.llcx));
291291
}
292292
attrs.push(llvm::AttributeKind::WillReturn.create_attr(self.cx.llcx));
293293
} else if options.contains(InlineAsmOptions::NOMEM) {
294-
attrs.push(llvm::AttributeKind::InaccessibleMemOnly.create_attr(self.cx.llcx));
294+
attrs.push(llvm::MemoryEffects::InaccessibleMemOnly.create_attr(self.cx.llcx));
295295
} else {
296296
// LLVM doesn't have an attribute to represent ReadOnly + SideEffect
297297
}

compiler/rustc_codegen_llvm/src/attributes.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use smallvec::SmallVec;
1313

1414
use crate::attributes;
1515
use crate::llvm::AttributePlace::Function;
16-
use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace};
16+
use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace, MemoryEffects};
1717
use crate::llvm_util;
1818
pub use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr};
1919

@@ -303,10 +303,10 @@ pub fn from_fn_attrs<'ll, 'tcx>(
303303
to_add.push(AttributeKind::ReturnsTwice.create_attr(cx.llcx));
304304
}
305305
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::FFI_PURE) {
306-
to_add.push(AttributeKind::ReadOnly.create_attr(cx.llcx));
306+
to_add.push(MemoryEffects::ReadOnly.create_attr(cx.llcx));
307307
}
308308
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::FFI_CONST) {
309-
to_add.push(AttributeKind::ReadNone.create_attr(cx.llcx));
309+
to_add.push(MemoryEffects::None.create_attr(cx.llcx));
310310
}
311311
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
312312
to_add.push(AttributeKind::Naked.create_attr(cx.llcx));

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,6 @@ pub enum AttributeKind {
183183
OptimizeNone = 24,
184184
ReturnsTwice = 25,
185185
ReadNone = 26,
186-
InaccessibleMemOnly = 27,
187186
SanitizeHWAddress = 28,
188187
WillReturn = 29,
189188
StackProtectReq = 30,
@@ -590,6 +589,15 @@ pub enum ChecksumKind {
590589
SHA256,
591590
}
592591

592+
/// LLVMRustMemoryEffects
593+
#[derive(Copy, Clone)]
594+
#[repr(C)]
595+
pub enum MemoryEffects {
596+
None,
597+
ReadOnly,
598+
InaccessibleMemOnly,
599+
}
600+
593601
extern "C" {
594602
type Opaque;
595603
}
@@ -1175,6 +1183,7 @@ extern "C" {
11751183
pub fn LLVMRustCreateUWTableAttr(C: &Context, async_: bool) -> &Attribute;
11761184
pub fn LLVMRustCreateAllocSizeAttr(C: &Context, size_arg: u32) -> &Attribute;
11771185
pub fn LLVMRustCreateAllocKindAttr(C: &Context, size_arg: u64) -> &Attribute;
1186+
pub fn LLVMRustCreateMemoryEffectsAttr(C: &Context, effects: MemoryEffects) -> &Attribute;
11781187

11791188
// Operations on functions
11801189
pub fn LLVMRustGetOrInsertFunction<'a>(

compiler/rustc_codegen_llvm/src/llvm/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,13 @@ impl AttributeKind {
185185
}
186186
}
187187

188+
impl MemoryEffects {
189+
/// Create an LLVM Attribute with these memory effects.
190+
pub fn create_attr(self, llcx: &Context) -> &Attribute {
191+
unsafe { LLVMRustCreateMemoryEffectsAttr(llcx, self) }
192+
}
193+
}
194+
188195
pub fn set_section(llglobal: &Value, section_name: &str) {
189196
let section_name_cstr = CString::new(section_name).expect("unexpected CString error");
190197
unsafe {

compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h

-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ enum LLVMRustAttribute {
7676
OptimizeNone = 24,
7777
ReturnsTwice = 25,
7878
ReadNone = 26,
79-
InaccessibleMemOnly = 27,
8079
SanitizeHWAddress = 28,
8180
WillReturn = 29,
8281
StackProtectReq = 30,

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+40-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
#include "llvm/IR/Intrinsics.h"
99
#include "llvm/IR/IntrinsicsARM.h"
1010
#include "llvm/IR/Mangler.h"
11+
#if LLVM_VERSION_GE(16, 0)
12+
#include "llvm/IR/ModRef.h"
13+
#endif
1114
#include "llvm/Object/Archive.h"
1215
#include "llvm/Object/COFFImportFile.h"
1316
#include "llvm/Object/ObjectFile.h"
@@ -213,8 +216,6 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
213216
return Attribute::ReturnsTwice;
214217
case ReadNone:
215218
return Attribute::ReadNone;
216-
case InaccessibleMemOnly:
217-
return Attribute::InaccessibleMemOnly;
218219
case SanitizeHWAddress:
219220
return Attribute::SanitizeHWAddress;
220221
case WillReturn:
@@ -379,6 +380,43 @@ extern "C" LLVMAttributeRef LLVMRustCreateAllocKindAttr(LLVMContextRef C, uint64
379380
#endif
380381
}
381382

383+
// Simplified representation of `MemoryEffects` across the FFI boundary.
384+
//
385+
// Each variant corresponds to one of the static factory methods on `MemoryEffects`.
386+
enum class LLVMRustMemoryEffects {
387+
None,
388+
ReadOnly,
389+
InaccessibleMemOnly,
390+
};
391+
392+
extern "C" LLVMAttributeRef LLVMRustCreateMemoryEffectsAttr(LLVMContextRef C,
393+
LLVMRustMemoryEffects Effects) {
394+
#if LLVM_VERSION_GE(16, 0)
395+
switch (Effects) {
396+
case LLVMRustMemoryEffects::None:
397+
return wrap(Attribute::getWithMemoryEffects(*unwrap(C), MemoryEffects::none()));
398+
case LLVMRustMemoryEffects::ReadOnly:
399+
return wrap(Attribute::getWithMemoryEffects(*unwrap(C), MemoryEffects::readOnly()));
400+
case LLVMRustMemoryEffects::InaccessibleMemOnly:
401+
return wrap(Attribute::getWithMemoryEffects(*unwrap(C),
402+
MemoryEffects::inaccessibleMemOnly()));
403+
default:
404+
report_fatal_error("bad MemoryEffects.");
405+
}
406+
#else
407+
switch (Effects) {
408+
case LLVMRustMemoryEffects::None:
409+
return wrap(Attribute::get(*unwrap(C), Attribute::ReadNone));
410+
case LLVMRustMemoryEffects::ReadOnly:
411+
return wrap(Attribute::get(*unwrap(C), Attribute::ReadOnly));
412+
case LLVMRustMemoryEffects::InaccessibleMemOnly:
413+
return wrap(Attribute::get(*unwrap(C), Attribute::InaccessibleMemOnly));
414+
default:
415+
report_fatal_error("bad MemoryEffects.");
416+
}
417+
#endif
418+
}
419+
382420
// Enable a fast-math flag
383421
//
384422
// https://llvm.org/docs/LangRef.html#fast-math-flags

src/test/codegen/ffi-const.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub fn bar() { unsafe { foo() } }
77
extern "C" {
88
// CHECK-LABEL: declare{{.*}}void @foo()
99
// CHECK-SAME: [[ATTRS:#[0-9]+]]
10-
// CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readnone{{.*}} }
10+
// The attribute changed from `readnone` to `memory(none)` with LLVM 16.0.
11+
// CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readnone|memory\(none\)}}{{.*}} }
1112
#[ffi_const] pub fn foo();
1213
}

src/test/codegen/ffi-pure.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub fn bar() { unsafe { foo() } }
77
extern "C" {
88
// CHECK-LABEL: declare{{.*}}void @foo()
99
// CHECK-SAME: [[ATTRS:#[0-9]+]]
10-
// CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readonly{{.*}} }
10+
// The attribute changed from `readonly` to `memory(read)` with LLVM 16.0.
11+
// CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readonly|memory\(read\)}}{{.*}} }
1112
#[ffi_pure] pub fn foo();
1213
}

0 commit comments

Comments
 (0)