Add elementtype attributes for llvm.arm.ldrex/strex intrinsics
These intrinsics (and a few more, but there are the only ones exposed by stdarch) require an elementtype attribute in LLVM 15.
This commit is contained in:
parent
ff693dc7b8
commit
f653d3ab30
@ -569,6 +569,22 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
||||
&[cmse_nonsecure_call],
|
||||
);
|
||||
}
|
||||
|
||||
// Some intrinsics require that an elementtype attribute (with the pointee type of a
|
||||
// pointer argument) is added to the callsite.
|
||||
let element_type_index = unsafe { llvm::LLVMRustGetElementTypeArgIndex(callsite) };
|
||||
if element_type_index >= 0 {
|
||||
let arg_ty = self.args[element_type_index as usize].layout.ty;
|
||||
let pointee_ty = arg_ty.builtin_deref(true).expect("Must be pointer argument").ty;
|
||||
let element_type_attr = unsafe {
|
||||
llvm::LLVMRustCreateElementTypeAttr(bx.llcx, bx.layout_of(pointee_ty).llvm_type(bx))
|
||||
};
|
||||
attributes::apply_to_callsite(
|
||||
callsite,
|
||||
llvm::AttributePlace::Argument(element_type_index as u32),
|
||||
&[element_type_attr],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1192,6 +1192,7 @@ extern "C" {
|
||||
pub fn LLVMRustCreateDereferenceableOrNullAttr(C: &Context, bytes: u64) -> &Attribute;
|
||||
pub fn LLVMRustCreateByValAttr<'a>(C: &'a Context, ty: &'a Type) -> &'a Attribute;
|
||||
pub fn LLVMRustCreateStructRetAttr<'a>(C: &'a Context, ty: &'a Type) -> &'a Attribute;
|
||||
pub fn LLVMRustCreateElementTypeAttr<'a>(C: &'a Context, ty: &'a Type) -> &'a Attribute;
|
||||
pub fn LLVMRustCreateUWTableAttr(C: &Context, async_: bool) -> &Attribute;
|
||||
pub fn LLVMRustCreateAllocSizeAttr(C: &Context, size_arg: u32) -> &Attribute;
|
||||
pub fn LLVMRustCreateAllocKindAttr(C: &Context, size_arg: u64) -> &Attribute;
|
||||
@ -2541,4 +2542,6 @@ extern "C" {
|
||||
|
||||
#[allow(improper_ctypes)]
|
||||
pub fn LLVMRustGetMangledName(V: &Value, out: &RustString);
|
||||
|
||||
pub fn LLVMRustGetElementTypeArgIndex(CallSite: &Value) -> i32;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "llvm/IR/GlobalVariable.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/IntrinsicsARM.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#include "llvm/Object/Archive.h"
|
||||
#include "llvm/Object/COFFImportFile.h"
|
||||
@ -300,6 +301,14 @@ extern "C" LLVMAttributeRef LLVMRustCreateStructRetAttr(LLVMContextRef C, LLVMTy
|
||||
return wrap(Attribute::getWithStructRetType(*unwrap(C), unwrap(Ty)));
|
||||
}
|
||||
|
||||
extern "C" LLVMAttributeRef LLVMRustCreateElementTypeAttr(LLVMContextRef C, LLVMTypeRef Ty) {
|
||||
#if LLVM_VERSION_GE(15, 0)
|
||||
return wrap(Attribute::get(*unwrap(C), Attribute::ElementType, unwrap(Ty)));
|
||||
#else
|
||||
report_fatal_error("Should not be needed on LLVM < 15");
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" LLVMAttributeRef LLVMRustCreateUWTableAttr(LLVMContextRef C, bool Async) {
|
||||
#if LLVM_VERSION_LT(15, 0)
|
||||
return wrap(Attribute::get(*unwrap(C), Attribute::UWTable));
|
||||
@ -1943,3 +1952,16 @@ extern "C" LLVMValueRef LLVMGetAggregateElement(LLVMValueRef C, unsigned Idx) {
|
||||
return wrap(unwrap<Constant>(C)->getAggregateElement(Idx));
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" int32_t LLVMRustGetElementTypeArgIndex(LLVMValueRef CallSite) {
|
||||
#if LLVM_VERSION_GE(15, 0)
|
||||
auto *CB = unwrap<CallBase>(CallSite);
|
||||
switch (CB->getIntrinsicID()) {
|
||||
case Intrinsic::arm_ldrex:
|
||||
return 0;
|
||||
case Intrinsic::arm_strex:
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user