Skip to content

Commit 3309954

Browse files
committed
Check for AutoUpgraded intrinsics, and emit a hard error for unknown intrinsics
1 parent a460e23 commit 3309954

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
@@ -1266,6 +1266,11 @@ unsafe extern "C" {
12661266
ParamTypes: *const &'a Type,
12671267
ParamCount: size_t,
12681268
) -> &'a Value;
1269+
pub(crate) fn LLVMRustUpgradeIntrinsicFunction<'a>(
1270+
Fn: &'a Value,
1271+
NewFn: &mut Option<&'a Value>,
1272+
CanUpgradeDebugIntrinsicsToRecords: bool,
1273+
) -> bool;
12691274

12701275
// Operations on parameters
12711276
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"
@@ -1902,6 +1903,17 @@ extern "C" void LLVMRustGetMangledName(LLVMValueRef V, RustStringRef Str) {
19021903
Mangler().getNameWithPrefix(OS, GV, true);
19031904
}
19041905

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

0 commit comments

Comments
 (0)