Skip to content

Commit 64023da

Browse files
committed
Check for AutoUpgraded intrinsics, and emit a hard error for unknown intrinsics
1 parent 3e4faa5 commit 64023da

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

compiler/rustc_codegen_llvm/src/declare.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,27 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
177177
fn_abi.apply_attrs_llfn(self, llfn, instance);
178178
}
179179

180-
// todo: check for upgrades, and emit error if not upgradable
180+
if let FunctionSignature::MaybeInvalidIntrinsic(..) = signature {
181+
let mut new_llfn = None;
182+
let can_upgrade =
183+
unsafe { llvm::LLVMRustUpgradeIntrinsicFunction(llfn, &mut new_llfn, false) };
184+
185+
if can_upgrade {
186+
// not all intrinsics are upgraded to some other intrinsics, most are upgraded to instruction sequences
187+
if let Some(new_llfn) = new_llfn {
188+
self.tcx.dcx().note(format!(
189+
"Using deprecated intrinsic `{name}`, `{}` can be used instead",
190+
str::from_utf8(llvm::get_value_name(new_llfn)).unwrap()
191+
));
192+
} else if self.tcx.sess.opts.verbose {
193+
self.tcx.dcx().note(format!(
194+
"Using deprecated intrinsic `{name}`, consider using other intrinsics/instructions"
195+
));
196+
}
197+
} else {
198+
self.tcx.dcx().fatal(format!("Invalid LLVM intrinsic: `{name}`"))
199+
}
200+
}
181201

182202
if self.tcx.sess.is_sanitizer_cfi_enabled() {
183203
if let Some(instance) = instance {

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,6 +1213,11 @@ unsafe extern "C" {
12131213
ParamTypes: *const &'a Type,
12141214
ParamCount: size_t,
12151215
) -> &'a Type;
1216+
pub(crate) fn LLVMRustUpgradeIntrinsicFunction<'a>(
1217+
Fn: &'a Value,
1218+
NewFn: &mut Option<&'a Value>,
1219+
CanUpgradeDebugIntrinsicsToRecords: bool,
1220+
) -> bool;
12161221

12171222
// Operations on parameters
12181223
pub(crate) fn LLVMIsAArgument(Val: &Value) -> Option<&Value>;

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "llvm/ADT/StringRef.h"
1010
#include "llvm/BinaryFormat/Magic.h"
1111
#include "llvm/Bitcode/BitcodeWriter.h"
12+
#include "llvm/IR/AutoUpgrade.h"
1213
#include "llvm/IR/DIBuilder.h"
1314
#include "llvm/IR/DebugInfoMetadata.h"
1415
#include "llvm/IR/DiagnosticHandler.h"
@@ -1901,6 +1902,17 @@ extern "C" void LLVMRustGetMangledName(LLVMValueRef V, RustStringRef Str) {
19011902
Mangler().getNameWithPrefix(OS, GV, true);
19021903
}
19031904

1905+
extern "C" bool
1906+
LLVMRustUpgradeIntrinsicFunction(LLVMValueRef Fn, LLVMValueRef *NewFn,
1907+
bool canUpgradeDebugIntrinsicsToRecords) {
1908+
Function *F = unwrap<Function>(Fn);
1909+
Function *NewF = nullptr;
1910+
bool CanUpgrade =
1911+
UpgradeIntrinsicFunction(F, NewF, canUpgradeDebugIntrinsicsToRecords);
1912+
*NewFn = wrap(NewF);
1913+
return CanUpgrade;
1914+
}
1915+
19041916
extern "C" int32_t LLVMRustGetElementTypeArgIndex(LLVMValueRef CallSite) {
19051917
auto *CB = unwrap<CallBase>(CallSite);
19061918
switch (CB->getIntrinsicID()) {

0 commit comments

Comments
 (0)