Skip to content

Commit aa2dcbe

Browse files
authored
Rollup merge of #145420 - Zalathar:llvm-c, r=WaffleLapkin
cg_llvm: Use LLVM-C bindings for `LLVMSetTailCallKind`, `LLVMGetTypeKind` This PR replaces two existing `LLVMRust` bindings with equivalent calls to the LLVM-C API. For `LLVMGetTypeKind`, we avoid the UB hazard by declaring the foreign function to return `RawEnum<TypeKind>` (which is a wrapper around `u32`), and then perform checked conversion from `u32` to `TypeKind`.
2 parents 3a694c7 + e193b53 commit aa2dcbe

File tree

4 files changed

+14
-89
lines changed

4 files changed

+14
-89
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1453,7 +1453,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
14531453
instance: Option<Instance<'tcx>>,
14541454
) {
14551455
let call = self.call(llty, fn_attrs, Some(fn_abi), llfn, args, funclet, instance);
1456-
llvm::LLVMRustSetTailCallKind(call, llvm::TailCallKind::MustTail);
1456+
llvm::LLVMSetTailCallKind(call, llvm::TailCallKind::MustTail);
14571457

14581458
match &fn_abi.ret.mode {
14591459
PassMode::Ignore | PassMode::Indirect { .. } => self.ret_void(),

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ pub(crate) enum ModuleFlagMergeBehavior {
9797

9898
// Consts for the LLVM CallConv type, pre-cast to usize.
9999

100+
/// Must match the layout of `LLVMTailCallKind`.
100101
#[derive(Copy, Clone, PartialEq, Debug)]
101102
#[repr(C)]
102103
#[allow(dead_code)]
@@ -332,10 +333,15 @@ impl RealPredicate {
332333
}
333334
}
334335

335-
/// LLVMTypeKind
336-
#[derive(Copy, Clone, PartialEq, Debug)]
336+
/// Must match the layout of `LLVMTypeKind`.
337+
///
338+
/// Use [`RawEnum<TypeKind>`] for values of `LLVMTypeKind` returned from LLVM,
339+
/// to avoid risk of UB if LLVM adds new enum values.
340+
///
341+
/// All of LLVM's variants should be declared here, even if no Rust-side code refers
342+
/// to them, because unknown variants will cause [`RawEnum::to_rust`] to panic.
343+
#[derive(Copy, Clone, PartialEq, Debug, TryFromU32)]
337344
#[repr(C)]
338-
#[expect(dead_code, reason = "Some variants are unused, but are kept to match LLVM-C")]
339345
pub(crate) enum TypeKind {
340346
Void = 0,
341347
Half = 1,
@@ -1046,6 +1052,8 @@ unsafe extern "C" {
10461052
CanThrow: llvm::Bool,
10471053
) -> &'ll Value;
10481054

1055+
pub(crate) safe fn LLVMGetTypeKind(Ty: &Type) -> RawEnum<TypeKind>;
1056+
10491057
// Operations on integer types
10501058
pub(crate) fn LLVMInt1TypeInContext(C: &Context) -> &Type;
10511059
pub(crate) fn LLVMInt8TypeInContext(C: &Context) -> &Type;
@@ -1197,7 +1205,7 @@ unsafe extern "C" {
11971205
pub(crate) safe fn LLVMIsGlobalConstant(GlobalVar: &Value) -> Bool;
11981206
pub(crate) safe fn LLVMSetGlobalConstant(GlobalVar: &Value, IsConstant: Bool);
11991207
pub(crate) safe fn LLVMSetTailCall(CallInst: &Value, IsTailCall: Bool);
1200-
pub(crate) safe fn LLVMRustSetTailCallKind(CallInst: &Value, Kind: TailCallKind);
1208+
pub(crate) safe fn LLVMSetTailCallKind(CallInst: &Value, kind: TailCallKind);
12011209

12021210
// Operations on attributes
12031211
pub(crate) fn LLVMCreateStringAttribute(
@@ -1841,9 +1849,6 @@ unsafe extern "C" {
18411849
// Create and destroy contexts.
18421850
pub(crate) fn LLVMRustContextCreate(shouldDiscardNames: bool) -> &'static mut Context;
18431851

1844-
/// See llvm::LLVMTypeKind::getTypeID.
1845-
pub(crate) fn LLVMRustGetTypeKind(Ty: &Type) -> TypeKind;
1846-
18471852
// Operations on all values
18481853
pub(crate) fn LLVMRustGlobalAddMetadata<'a>(
18491854
Val: &'a Value,

compiler/rustc_codegen_llvm/src/type_.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ impl<'ll, CX: Borrow<SCx<'ll>>> BaseTypeCodegenMethods for GenericCx<'ll, CX> {
204204
}
205205

206206
fn type_kind(&self, ty: &'ll Type) -> TypeKind {
207-
unsafe { llvm::LLVMRustGetTypeKind(ty).to_generic() }
207+
llvm::LLVMGetTypeKind(ty).to_rust().to_generic()
208208
}
209209

210210
fn type_ptr(&self) -> &'ll Type {

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

Lines changed: 0 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,60 +1460,6 @@ LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef DI) {
14601460
return toRust((DiagnosticKind)unwrap(DI)->getKind());
14611461
}
14621462

1463-
// This is kept distinct from LLVMGetTypeKind, because when
1464-
// a new type kind is added, the Rust-side enum must be
1465-
// updated or UB will result.
1466-
extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
1467-
switch (unwrap(Ty)->getTypeID()) {
1468-
case Type::VoidTyID:
1469-
return LLVMVoidTypeKind;
1470-
case Type::HalfTyID:
1471-
return LLVMHalfTypeKind;
1472-
case Type::FloatTyID:
1473-
return LLVMFloatTypeKind;
1474-
case Type::DoubleTyID:
1475-
return LLVMDoubleTypeKind;
1476-
case Type::X86_FP80TyID:
1477-
return LLVMX86_FP80TypeKind;
1478-
case Type::FP128TyID:
1479-
return LLVMFP128TypeKind;
1480-
case Type::PPC_FP128TyID:
1481-
return LLVMPPC_FP128TypeKind;
1482-
case Type::LabelTyID:
1483-
return LLVMLabelTypeKind;
1484-
case Type::MetadataTyID:
1485-
return LLVMMetadataTypeKind;
1486-
case Type::IntegerTyID:
1487-
return LLVMIntegerTypeKind;
1488-
case Type::FunctionTyID:
1489-
return LLVMFunctionTypeKind;
1490-
case Type::StructTyID:
1491-
return LLVMStructTypeKind;
1492-
case Type::ArrayTyID:
1493-
return LLVMArrayTypeKind;
1494-
case Type::PointerTyID:
1495-
return LLVMPointerTypeKind;
1496-
case Type::FixedVectorTyID:
1497-
return LLVMVectorTypeKind;
1498-
case Type::TokenTyID:
1499-
return LLVMTokenTypeKind;
1500-
case Type::ScalableVectorTyID:
1501-
return LLVMScalableVectorTypeKind;
1502-
case Type::BFloatTyID:
1503-
return LLVMBFloatTypeKind;
1504-
case Type::X86_AMXTyID:
1505-
return LLVMX86_AMXTypeKind;
1506-
default: {
1507-
std::string error;
1508-
auto stream = llvm::raw_string_ostream(error);
1509-
stream << "Rust does not support the TypeID: " << unwrap(Ty)->getTypeID()
1510-
<< " for the type: " << *unwrap(Ty);
1511-
stream.flush();
1512-
report_fatal_error(error.c_str());
1513-
}
1514-
}
1515-
}
1516-
15171463
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
15181464

15191465
extern "C" LLVMSMDiagnosticRef LLVMRustGetSMDiagnostic(LLVMDiagnosticInfoRef DI,
@@ -1993,29 +1939,3 @@ extern "C" void LLVMRustSetNoSanitizeHWAddress(LLVMValueRef Global) {
19931939
MD.NoHWAddress = true;
19941940
GV.setSanitizerMetadata(MD);
19951941
}
1996-
1997-
enum class LLVMRustTailCallKind {
1998-
None = 0,
1999-
Tail = 1,
2000-
MustTail = 2,
2001-
NoTail = 3
2002-
};
2003-
2004-
extern "C" void LLVMRustSetTailCallKind(LLVMValueRef Call,
2005-
LLVMRustTailCallKind Kind) {
2006-
CallInst *CI = unwrap<CallInst>(Call);
2007-
switch (Kind) {
2008-
case LLVMRustTailCallKind::None:
2009-
CI->setTailCallKind(CallInst::TCK_None);
2010-
break;
2011-
case LLVMRustTailCallKind::Tail:
2012-
CI->setTailCallKind(CallInst::TCK_Tail);
2013-
break;
2014-
case LLVMRustTailCallKind::MustTail:
2015-
CI->setTailCallKind(CallInst::TCK_MustTail);
2016-
break;
2017-
case LLVMRustTailCallKind::NoTail:
2018-
CI->setTailCallKind(CallInst::TCK_NoTail);
2019-
break;
2020-
}
2021-
}

0 commit comments

Comments
 (0)