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:
@@ -569,6 +569,22 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
|||||||
&[cmse_nonsecure_call],
|
&[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 LLVMRustCreateDereferenceableOrNullAttr(C: &Context, bytes: u64) -> &Attribute;
|
||||||
pub fn LLVMRustCreateByValAttr<'a>(C: &'a Context, ty: &'a Type) -> &'a 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 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 LLVMRustCreateUWTableAttr(C: &Context, async_: bool) -> &Attribute;
|
||||||
pub fn LLVMRustCreateAllocSizeAttr(C: &Context, size_arg: u32) -> &Attribute;
|
pub fn LLVMRustCreateAllocSizeAttr(C: &Context, size_arg: u32) -> &Attribute;
|
||||||
pub fn LLVMRustCreateAllocKindAttr(C: &Context, size_arg: u64) -> &Attribute;
|
pub fn LLVMRustCreateAllocKindAttr(C: &Context, size_arg: u64) -> &Attribute;
|
||||||
@@ -2541,4 +2542,6 @@ extern "C" {
|
|||||||
|
|
||||||
#[allow(improper_ctypes)]
|
#[allow(improper_ctypes)]
|
||||||
pub fn LLVMRustGetMangledName(V: &Value, out: &RustString);
|
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/GlobalVariable.h"
|
||||||
#include "llvm/IR/Instructions.h"
|
#include "llvm/IR/Instructions.h"
|
||||||
#include "llvm/IR/Intrinsics.h"
|
#include "llvm/IR/Intrinsics.h"
|
||||||
|
#include "llvm/IR/IntrinsicsARM.h"
|
||||||
#include "llvm/IR/Mangler.h"
|
#include "llvm/IR/Mangler.h"
|
||||||
#include "llvm/Object/Archive.h"
|
#include "llvm/Object/Archive.h"
|
||||||
#include "llvm/Object/COFFImportFile.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)));
|
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) {
|
extern "C" LLVMAttributeRef LLVMRustCreateUWTableAttr(LLVMContextRef C, bool Async) {
|
||||||
#if LLVM_VERSION_LT(15, 0)
|
#if LLVM_VERSION_LT(15, 0)
|
||||||
return wrap(Attribute::get(*unwrap(C), Attribute::UWTable));
|
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));
|
return wrap(unwrap<Constant>(C)->getAggregateElement(Idx));
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user