about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs22
-rw-r--r--tests/codegen/is_val_statically_known.rs81
3 files changed, 96 insertions, 9 deletions
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index dd3f39ecead..1fd9f9e8116 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -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);
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index f5558723d11..abfe38d4c0c 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -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
diff --git a/tests/codegen/is_val_statically_known.rs b/tests/codegen/is_val_statically_known.rs
index 6af4f353a48..fe432d3bcc4 100644
--- a/tests/codegen/is_val_statically_known.rs
+++ b/tests/codegen/is_val_statically_known.rs
@@ -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;
 
@@ -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(
@@ -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(
@@ -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)
+}