Skip to content

Commit

Permalink
Rollup merge of rust-lang#129173 - beetrees:statically-known-float, r…
Browse files Browse the repository at this point in the history
…=compiler-errors

Fix `is_val_statically_known` for floats

The LLVM intrinsic name for floats differs from the LLVM type name, so handle them explicitly. Also adds support for `f16` and `f128`.

`f16`/`f128` tracking issue: rust-lang#116909
  • Loading branch information
tgross35 authored Aug 17, 2024
2 parents 8438d1d + 9bc7cea commit 8f916ca
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 9 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1000,8 +1000,10 @@ impl<'ll> CodegenCx<'ll, '_> {
ifn!("llvm.is.constant.i64", fn(t_i64) -> i1);
ifn!("llvm.is.constant.i128", fn(t_i128) -> i1);
ifn!("llvm.is.constant.isize", fn(t_isize) -> i1);
ifn!("llvm.is.constant.f16", fn(t_f16) -> i1);
ifn!("llvm.is.constant.f32", fn(t_f32) -> i1);
ifn!("llvm.is.constant.f64", fn(t_f64) -> i1);
ifn!("llvm.is.constant.f128", fn(t_f128) -> i1);
ifn!("llvm.is.constant.ptr", fn(ptr) -> i1);

ifn!("llvm.expect.i1", fn(i1, i1) -> i1);
Expand Down
22 changes: 15 additions & 7 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,22 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
}
sym::is_val_statically_known => {
let intrinsic_type = args[0].layout.immediate_llvm_type(self.cx);
match self.type_kind(intrinsic_type) {
TypeKind::Pointer | TypeKind::Integer | TypeKind::Float | TypeKind::Double => {
self.call_intrinsic(
&format!("llvm.is.constant.{:?}", intrinsic_type),
&[args[0].immediate()],
)
let kind = self.type_kind(intrinsic_type);
let intrinsic_name = match kind {
TypeKind::Pointer | TypeKind::Integer => {
Some(format!("llvm.is.constant.{intrinsic_type:?}"))
}
_ => self.const_bool(false),
// LLVM float types' intrinsic names differ from their type names.
TypeKind::Half => Some(format!("llvm.is.constant.f16")),
TypeKind::Float => Some(format!("llvm.is.constant.f32")),
TypeKind::Double => Some(format!("llvm.is.constant.f64")),
TypeKind::FP128 => Some(format!("llvm.is.constant.f128")),
_ => None,
};
if let Some(intrinsic_name) = intrinsic_name {
self.call_intrinsic(&intrinsic_name, &[args[0].immediate()])
} else {
self.const_bool(false)
}
}
sym::unlikely => self
Expand Down
81 changes: 79 additions & 2 deletions tests/codegen/is_val_statically_known.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//@ compile-flags: --crate-type=lib -Zmerge-functions=disabled -O

#![feature(core_intrinsics)]
#![feature(f16, f128)]

use std::intrinsics::is_val_statically_known;

Expand Down Expand Up @@ -49,7 +50,7 @@ pub fn _bool_false(b: bool) -> i32 {

#[inline]
pub fn _iref(a: &u8) -> i32 {
if unsafe { is_val_statically_known(a) } { 5 } else { 4 }
if is_val_statically_known(a) { 5 } else { 4 }
}

// CHECK-LABEL: @_iref_borrow(
Expand All @@ -68,7 +69,7 @@ pub fn _iref_arg(a: &u8) -> i32 {

#[inline]
pub fn _slice_ref(a: &[u8]) -> i32 {
if unsafe { is_val_statically_known(a) } { 7 } else { 6 }
if is_val_statically_known(a) { 7 } else { 6 }
}

// CHECK-LABEL: @_slice_ref_borrow(
Expand All @@ -84,3 +85,79 @@ pub fn _slice_ref_arg(a: &[u8]) -> i32 {
// CHECK: ret i32 6
_slice_ref(a)
}

#[inline]
pub fn _f16(a: f16) -> i32 {
if is_val_statically_known(a) { 1 } else { 0 }
}

// CHECK-LABEL: @_f16_true(
#[no_mangle]
pub fn _f16_true() -> i32 {
// CHECK: ret i32 1
_f16(1.0)
}

// CHECK-LABEL: @_f16_false(
#[no_mangle]
pub fn _f16_false(a: f16) -> i32 {
// CHECK: ret i32 0
_f16(a)
}

#[inline]
pub fn _f32(a: f32) -> i32 {
if is_val_statically_known(a) { 1 } else { 0 }
}

// CHECK-LABEL: @_f32_true(
#[no_mangle]
pub fn _f32_true() -> i32 {
// CHECK: ret i32 1
_f32(1.0)
}

// CHECK-LABEL: @_f32_false(
#[no_mangle]
pub fn _f32_false(a: f32) -> i32 {
// CHECK: ret i32 0
_f32(a)
}

#[inline]
pub fn _f64(a: f64) -> i32 {
if is_val_statically_known(a) { 1 } else { 0 }
}

// CHECK-LABEL: @_f64_true(
#[no_mangle]
pub fn _f64_true() -> i32 {
// CHECK: ret i32 1
_f64(1.0)
}

// CHECK-LABEL: @_f64_false(
#[no_mangle]
pub fn _f64_false(a: f64) -> i32 {
// CHECK: ret i32 0
_f64(a)
}

#[inline]
pub fn _f128(a: f128) -> i32 {
if is_val_statically_known(a) { 1 } else { 0 }
}

// CHECK-LABEL: @_f128_true(
#[no_mangle]
pub fn _f128_true() -> i32 {
// CHECK: ret i32 1
_f128(1.0)
}

// CHECK-LABEL: @_f128_false(
#[no_mangle]
pub fn _f128_false(a: f128) -> i32 {
// CHECK: ret i32 0
_f128(a)
}

0 comments on commit 8f916ca

Please sign in to comment.