nontemporal_store: make sure that the intrinsic is truly just a hint
This commit is contained in:
parent
29e924841f
commit
28e0907111
5 changed files with 49 additions and 15 deletions
|
@ -727,13 +727,29 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
llvm::LLVMSetVolatile(store, llvm::True);
|
||||
}
|
||||
if flags.contains(MemFlags::NONTEMPORAL) {
|
||||
// According to LLVM [1] building a nontemporal store must
|
||||
// *always* point to a metadata value of the integer 1.
|
||||
//
|
||||
// [1]: https://llvm.org/docs/LangRef.html#store-instruction
|
||||
let one = self.cx.const_i32(1);
|
||||
let node = llvm::LLVMMDNodeInContext(self.cx.llcx, &one, 1);
|
||||
llvm::LLVMSetMetadata(store, llvm::MD_nontemporal as c_uint, node);
|
||||
// Make sure that the current target architectures supports "sane" non-temporal
|
||||
// stores, i.e., non-temporal stores that are equivalent to regular stores except
|
||||
// for performance. LLVM doesn't seem to care about this, and will happily treat
|
||||
// `!nontemporal` stores as-if they were normal stores (for reordering optimizations
|
||||
// etc) even on x86, despite later lowering them to MOVNT which do *not* behave like
|
||||
// regular stores but require special fences.
|
||||
// So we keep a list of architectures where `!nontemporal` is known to be truly just
|
||||
// a hint, and use regular stores everywhere else.
|
||||
// (In the future, we could alternatively ensure that an sfence gets emitted after a sequence of movnt
|
||||
// before any kind of synchronizing operation. But it's not clear how to do that with LLVM.)
|
||||
const WELL_BEHAVED_NONTEMPORAL_ARCHS: &[&str] = &["aarch64", "arm"];
|
||||
|
||||
let use_nontemporal =
|
||||
WELL_BEHAVED_NONTEMPORAL_ARCHS.contains(&&*self.cx.tcx.sess.target.arch);
|
||||
if use_nontemporal {
|
||||
// According to LLVM [1] building a nontemporal store must
|
||||
// *always* point to a metadata value of the integer 1.
|
||||
//
|
||||
// [1]: https://llvm.org/docs/LangRef.html#store-instruction
|
||||
let one = self.cx.const_i32(1);
|
||||
let node = llvm::LLVMMDNodeInContext(self.cx.llcx, &one, 1);
|
||||
llvm::LLVMSetMetadata(store, llvm::MD_nontemporal as c_uint, node);
|
||||
}
|
||||
}
|
||||
store
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue