diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index b8be612fbe69..b8ba6db9aa80 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -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 => {