refactor llvm va_arg intrinsic validation logic

This commit is contained in:
Folkert de Vries
2026-04-19 12:54:43 +02:00
parent a852582b35
commit fa740c7255
+15 -8
View File
@@ -3,7 +3,8 @@
use std::{assert_matches, iter, ptr};
use rustc_abi::{
Align, BackendRepr, Float, HasDataLayout, NumScalableVectors, Primitive, Size, WrappingRange,
Align, BackendRepr, Float, HasDataLayout, Integer, NumScalableVectors, Primitive, Size,
WrappingRange,
};
use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh};
use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
@@ -288,10 +289,17 @@ fn codegen_intrinsic_call(
bug!("the va_arg intrinsic does not support non-scalar types")
};
// We reject types that would never be passed as varargs in C because
// they get promoted to a larger type, specifically integers smaller than
// c_int and float type smaller than c_double.
match scalar.primitive() {
Primitive::Pointer(_) => {
// Pointers are always OK.
emit_va_arg(self, args[0], result.layout.ty)
}
Primitive::Int(Integer::I128, _) => {
// FIXME: maybe we should support these? At least on 32-bit powerpc
// the logic in LLVM does not handle i128 correctly though.
bug!("the va_arg intrinsic does not support `i128`/`u128`")
}
Primitive::Int(..) => {
let int_width = self.cx().size_of(result.layout.ty).bits();
@@ -305,27 +313,26 @@ fn codegen_intrinsic_call(
target_c_int_width
);
}
emit_va_arg(self, args[0], result.layout.ty)
}
Primitive::Float(Float::F16) => {
bug!("the va_arg intrinsic does not support `f16`")
}
Primitive::Float(Float::F32) => {
if self.cx().sess().target.arch == Arch::Avr {
// c_double is actually f32 on avr.
emit_va_arg(self, args[0], result.layout.ty)
} else {
// c_double is actually f32 on avr.
if self.cx().sess().target.arch != Arch::Avr {
bug!("the va_arg intrinsic does not support `f32` on this target")
}
}
Primitive::Float(Float::F64) => {
// 64-bit floats are always OK.
emit_va_arg(self, args[0], result.layout.ty)
}
Primitive::Float(Float::F128) => {
// FIXME(f128) figure out whether we should support this.
bug!("the va_arg intrinsic does not support `f128`")
}
}
emit_va_arg(self, args[0], result.layout.ty)
}
sym::volatile_load | sym::unaligned_volatile_load => {