Support for float <-> float conversions. (#7279)

Implement support for floating-point <-> floating-point type conversions
as described in https://github.com/carbon-language/carbon-lang/pull/820
and https://github.com/carbon-language/carbon-lang/pull/845.
Value-preserving conversions are implicit; narrowing conversions require
explicit `as`.

Assisted-by: Gemini via Antigravity
This commit is contained in:
Richard Smith
2026-06-04 00:33:33 +00:00
committed by GitHub
parent 7fe3e35aec
commit 88c191146d
15 changed files with 976 additions and 11 deletions
+1
View File
@@ -74,3 +74,4 @@ impl FloatLiteral() as UnsafeAs(IntLiteral()) {
}
interface IntFitsIn(Dest:! type) {}
interface FloatFitsIn(Src:! type) {}
+39 -2
View File
@@ -27,8 +27,8 @@ impl forall [N:! IntLiteral()] Float(N) as Copy {
fn Op[self: Self]() -> Self = "primitive_copy";
}
// Conversions between floating-point types.
// TODO: Support mixed-size conversions.
// Conversions between floating-point types. Implicit if all the source values
// can be represented exactly in the target type, otherwise explicit.
impl forall [N:! IntLiteral()] FloatLiteral() as ImplicitAs(Float(N)) {
fn Convert[self: Self]() -> Float(N) = "float.convert_checked";
}
@@ -38,6 +38,43 @@ impl forall [N:! IntLiteral()] FloatLiteral() as As(Float(N)) {
fn Convert[self: Self]() -> Float(N) = "float.convert_checked";
}
final impl forall [From:! IntLiteral(), To:! IntLiteral()]
Float(From) as As(Float(To)) {
fn Convert[self: Self]() -> Float(To) = "float.convert";
}
// AnyFloat exists to work around the inability to apply constraints to an impl
// that is only parameterized by integers.
// TODO: Remove these once possible.
private interface AnyFloat {
let Width:! IntLiteral();
fn AsFloat[self: Self]() -> Float(Width);
fn Make(src: Float(Width)) -> Self;
}
impl forall [N:! IntLiteral()] Float(N) as AnyFloat where .Width = N {
fn AsFloat[self: Self]() -> Self { return self; }
fn Make(src: Self) -> Self { return src; }
}
// Use `Float(?) as ImplicitAs(?)` to avoid a collision with the
// `? as ImplicitAs(Float(?))` type structure used by int -> float conversion.
// TODO: Use `match_first` to resolve this instead once it is available.
impl forall [From:! IntLiteral(), To:! AnyFloat where Float(From) impls FloatFitsIn(.Self)]
Float(From) as ImplicitAs(To) {
fn Convert[self: Self]() -> To {
fn Impl(src: Float(From)) -> Float(To.Width) = "float.convert";
return To.Make(Impl(self));
}
}
// Desired workaround-free version of the above:
// impl forall [From:! IntLiteral(), To:! IntLiteral()
// where Float(From) impls FloatFitsIn(Float(To))]
// Float(From) as ImplicitAs(Float(To)) {
// fn Convert[self: Self]() -> Float(To) = "float.convert";
// }
// Conversions from floating-point to integer type. Always unsafe: not all
// source values fit in the target type.
final impl forall [From:! IntLiteral(), To:! IntLiteral()]
+1
View File
@@ -44,6 +44,7 @@ CARBON_CORE_IDENTIFIER(DivWith)
CARBON_CORE_IDENTIFIER(EqWith)
CARBON_CORE_IDENTIFIER(Equal)
CARBON_CORE_IDENTIFIER(Float)
CARBON_CORE_IDENTIFIER(FloatFitsIn)
CARBON_CORE_IDENTIFIER(Get)
CARBON_CORE_IDENTIFIER(Greater)
CARBON_CORE_IDENTIFIER(GreaterOrEquivalent)
+2 -1
View File
@@ -606,8 +606,9 @@ auto LookupCppImpl(Context& context, SemIR::LocId loc_id,
return BuildCppRangeForIterateWitness(
context, loc_id, query_self_const_id, query_specific_interface_id);
// IntFitsIn is for Carbon integer types only.
// *FitsIn are implemented only by Carbon primitive types.
case SemIR::CoreInterface::IntFitsIn:
case SemIR::CoreInterface::FloatFitsIn:
return SemIR::InstId::None;
case SemIR::CoreInterface::Unknown:
+75
View File
@@ -740,6 +740,78 @@ static auto MakeIntFitsInWitness(
query_specific_interface_id, {});
}
static auto MakeFloatFitsInWitness(
Context& context, SemIR::LocId loc_id,
SemIR::ConstantId query_self_const_id,
SemIR::SpecificInterfaceId query_specific_interface_id, bool build_witness)
-> std::optional<SemIR::InstId> {
auto query_specific_interface =
context.specific_interfaces().Get(query_specific_interface_id);
auto args_id = query_specific_interface.specific_id;
if (!args_id.has_value()) {
return std::nullopt;
}
auto args_block_id = context.specifics().Get(args_id).args_id;
auto args_block = context.inst_blocks().Get(args_block_id);
if (args_block.size() != 1) {
return std::nullopt;
}
auto dest_const_id = context.constant_values().Get(args_block[0]);
if (!dest_const_id.is_constant()) {
return std::nullopt;
}
auto src_type_id = GetFacetAsType(context, query_self_const_id);
auto dest_type_id = GetFacetAsType(context, dest_const_id);
auto context_fn = [](DiagnosticContextBuilder& /*builder*/) -> void {};
if (!RequireCompleteType(context, src_type_id, loc_id, context_fn) ||
!RequireCompleteType(context, dest_type_id, loc_id, context_fn)) {
return std::nullopt;
}
// Ensure both are actually floating-point types.
auto src_object_rep_id = context.types().GetObjectRepr(src_type_id);
auto src_float_type =
context.types().TryGetAs<SemIR::FloatType>(src_object_rep_id);
if (!src_float_type) {
return std::nullopt;
}
auto dest_object_rep_id = context.types().GetObjectRepr(dest_type_id);
auto dest_float_type =
context.types().TryGetAs<SemIR::FloatType>(dest_object_rep_id);
if (!dest_float_type) {
return std::nullopt;
}
// Get their bit widths.
auto src_width_opt =
context.sem_ir().GetZExtIntValue(src_float_type->bit_width_id);
auto dest_width_opt =
context.sem_ir().GetZExtIntValue(dest_float_type->bit_width_id);
if (!src_width_opt || !dest_width_opt) {
// If the bit width is unknown (e.g. symbolic), we can't decide yet.
return std::nullopt;
}
const auto& src_semantics = src_float_type->float_kind.Semantics();
const auto& dest_semantics = dest_float_type->float_kind.Semantics();
if (!llvm::APFloat::isRepresentableBy(src_semantics, dest_semantics)) {
return std::nullopt;
}
if (!build_witness) {
return SemIR::InstId::None;
}
return BuildCustomWitness(context, loc_id, query_self_const_id,
query_specific_interface_id, {});
}
auto LookupCustomWitness(Context& context, SemIR::LocId loc_id,
SemIR::CoreInterface core_interface,
SemIR::ConstantId query_self_const_id,
@@ -749,6 +821,9 @@ auto LookupCustomWitness(Context& context, SemIR::LocId loc_id,
case SemIR::CoreInterface::Destroy:
return LookupDestroyWitness(context, loc_id, query_self_const_id,
query_specific_interface_id, build_witness);
case SemIR::CoreInterface::FloatFitsIn:
return MakeFloatFitsInWitness(context, loc_id, query_self_const_id,
query_specific_interface_id, build_witness);
case SemIR::CoreInterface::IntFitsIn:
return MakeIntFitsInWitness(context, loc_id, query_self_const_id,
query_specific_interface_id, build_witness);
+15 -8
View File
@@ -1282,10 +1282,10 @@ static auto RealToAPFloat(Context& context, RealId real_id,
}
// Performs a conversion between floating-point types, diagnosing if the value
// doesn't fit in the destination type.
static auto PerformCheckedFloatConvert(Context& context, SemIR::LocId loc_id,
SemIR::InstId arg_id,
SemIR::TypeId dest_type_id)
// doesn't fit in the destination type when check_overflow is true.
static auto PerformFloatConvert(Context& context, SemIR::LocId loc_id,
SemIR::InstId arg_id,
SemIR::TypeId dest_type_id, bool check_overflow)
-> SemIR::ConstantId {
auto dest_type_object_rep_id = context.types().GetObjectRepr(dest_type_id);
CARBON_CHECK(dest_type_object_rep_id.has_value(),
@@ -1316,7 +1316,7 @@ static auto PerformCheckedFloatConvert(Context& context, SemIR::LocId loc_id,
llvm::APFloat result =
RealToAPFloat(context, literal->real_id,
dest_float_type->float_kind.Semantics(), &status);
if (status & llvm::APFloat::opOverflow) {
if (check_overflow && (status & llvm::APFloat::opOverflow)) {
CARBON_DIAGNOSTIC(FloatLiteralTooLargeForType, Error,
"value {0} too large for floating-point type {1}",
RealId, SemIR::TypeId);
@@ -1338,7 +1338,7 @@ static auto PerformCheckedFloatConvert(Context& context, SemIR::LocId loc_id,
bool loses_info;
auto status = result.convert(dest_float_type->float_kind.Semantics(),
llvm::APFloat::rmNearestTiesToEven, &loses_info);
if (status & llvm::APFloat::opOverflow) {
if (check_overflow && (status & llvm::APFloat::opOverflow)) {
CARBON_DIAGNOSTIC(FloatTooLargeForType, Error,
"value {0} too large for floating-point type {1}",
llvm::APFloat, SemIR::TypeId);
@@ -2390,12 +2390,19 @@ static auto MakeConstantForBuiltinCall(EvalContext& eval_context,
}
// Floating-point conversions.
case SemIR::BuiltinFunctionKind::FloatConvert: {
if (phase != Phase::Concrete) {
return MakeConstantResult(context, call, phase);
}
return PerformFloatConvert(context, loc_id, arg_ids[0], call.type_id,
/*check_overflow=*/false);
}
case SemIR::BuiltinFunctionKind::FloatConvertChecked: {
if (phase != Phase::Concrete) {
return MakeConstantResult(context, call, phase);
}
return PerformCheckedFloatConvert(context, loc_id, arg_ids[0],
call.type_id);
return PerformFloatConvert(context, loc_id, arg_ids[0], call.type_id,
/*check_overflow=*/true);
}
case SemIR::BuiltinFunctionKind::FloatConvertInt: {
if (phase != Phase::Concrete) {
+657
View File
@@ -0,0 +1,657 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/primitives.carbon
//
// AUTOUPDATE
// TIP: To test this file alone, run:
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/builtins/float/convert.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/builtins/float/convert.carbon
// --- literal.carbon
library "literal";
fn FloatLiteral() -> type = "float_literal.make_type";
fn FloatLiteralToFloatLiteral(a: FloatLiteral()) -> FloatLiteral() =
"float.convert";
// --- identity_literal.carbon
library "identity_literal";
import library "literal";
//@dump-sem-ir-begin
let f: FloatLiteral() = FloatLiteralToFloatLiteral(1.0);
//@dump-sem-ir-end
// --- f64.carbon
library "f64";
export import library "literal";
fn Float64ToFloat64(a: f64) -> f64 = "float.convert";
fn FloatLiteralToFloat64(a: FloatLiteral()) -> f64 = "float.convert";
// --- f32.carbon
library "f32";
export import library "literal";
fn Float32ToFloat32(a: f32) -> f32 = "float.convert";
fn FloatLiteralToFloat32(a: FloatLiteral()) -> f32 = "float.convert";
fn Float32ToFloat64(a: f32) -> f64 = "float.convert";
fn Float64ToFloat32(a: f64) -> f32 = "float.convert";
// --- literal_f64.carbon
library "literal_f64";
import library "f64";
//@dump-sem-ir-begin
let a: f64 = FloatLiteralToFloat64(0.0);
let b: f64 = FloatLiteralToFloat64(1.0);
let c: f64 = FloatLiteralToFloat64(1.0e308);
// Large value that overflows is allowed in unchecked convert (rounds to infinity)
let d: f64 = FloatLiteralToFloat64(1.0e309);
//@dump-sem-ir-end
// --- literal_f32.carbon
library "literal_f32";
import library "f32";
//@dump-sem-ir-begin
let a: f32 = FloatLiteralToFloat32(0.0);
let b: f32 = FloatLiteralToFloat32(1.0);
let c: f32 = FloatLiteralToFloat32(1.0e38);
// Large value that overflows is allowed in unchecked convert (rounds to infinity)
let d: f32 = FloatLiteralToFloat32(1.0e39);
//@dump-sem-ir-end
// --- identity_f64.carbon
library "identity_f64";
import library "f64";
//@dump-sem-ir-begin
let a: f64 = Float64ToFloat64(0.0);
let b: f64 = Float64ToFloat64(1.0);
let c: f64 = Float64ToFloat64(1.0e308);
//@dump-sem-ir-end
// --- identity_f32.carbon
library "identity_f32";
import library "f32";
//@dump-sem-ir-begin
let a: f32 = Float32ToFloat32(0.0);
let b: f32 = Float32ToFloat32(1.0);
let c: f32 = Float32ToFloat32(1.0e38);
//@dump-sem-ir-end
// --- truncate.carbon
library "truncate";
import library "f32";
import library "f64";
//@dump-sem-ir-begin
let a: f32 = Float64ToFloat32(1.0);
// Narrowing with overflow is allowed in unchecked convert (rounds to infinity)
let b: f32 = Float64ToFloat32(1.0e39);
//@dump-sem-ir-end
// --- extend.carbon
library "extend";
import library "f32";
import library "f64";
//@dump-sem-ir-begin
let a: f64 = Float32ToFloat64(1.0);
let b: f64 = Float32ToFloat64(1.0e30);
//@dump-sem-ir-end
// CHECK:STDOUT: --- identity_literal.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %FloatLiteral.type: type = fn_type @FloatLiteral [concrete]
// CHECK:STDOUT: %FloatLiteral: %FloatLiteral.type = struct_value () [concrete]
// CHECK:STDOUT: %pattern_type.dab: type = pattern_type Core.FloatLiteral [concrete]
// CHECK:STDOUT: %FloatLiteralToFloatLiteral.type: type = fn_type @FloatLiteralToFloatLiteral [concrete]
// CHECK:STDOUT: %FloatLiteralToFloatLiteral: %FloatLiteralToFloatLiteral.type = struct_value () [concrete]
// CHECK:STDOUT: %float: Core.FloatLiteral = float_literal_value 10e-1 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Main.FloatLiteral: %FloatLiteral.type = import_ref Main//literal, FloatLiteral, loaded [concrete = constants.%FloatLiteral]
// CHECK:STDOUT: %Main.FloatLiteralToFloatLiteral: %FloatLiteralToFloatLiteral.type = import_ref Main//literal, FloatLiteralToFloatLiteral, loaded [concrete = constants.%FloatLiteralToFloatLiteral]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %f.patt: %pattern_type.dab = value_binding_pattern f [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc6_21.1: type = splice_block %.loc6_21.3 [concrete = Core.FloatLiteral] {
// CHECK:STDOUT: %FloatLiteral.ref: %FloatLiteral.type = name_ref FloatLiteral, imports.%Main.FloatLiteral [concrete = constants.%FloatLiteral]
// CHECK:STDOUT: %FloatLiteral.call: init type = call %FloatLiteral.ref() [concrete = Core.FloatLiteral]
// CHECK:STDOUT: %.loc6_21.2: type = value_of_initializer %FloatLiteral.call [concrete = Core.FloatLiteral]
// CHECK:STDOUT: %.loc6_21.3: type = converted %FloatLiteral.call, %.loc6_21.2 [concrete = Core.FloatLiteral]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc6_55.1: Core.FloatLiteral = value_of_initializer @__global_init.%FloatLiteralToFloatLiteral.call [concrete = constants.%float]
// CHECK:STDOUT: %.loc6_55.2: Core.FloatLiteral = converted @__global_init.%FloatLiteralToFloatLiteral.call, %.loc6_55.1 [concrete = constants.%float]
// CHECK:STDOUT: %f: Core.FloatLiteral = value_binding f, %.loc6_55.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %FloatLiteralToFloatLiteral.ref: %FloatLiteralToFloatLiteral.type = name_ref FloatLiteralToFloatLiteral, imports.%Main.FloatLiteralToFloatLiteral [concrete = constants.%FloatLiteralToFloatLiteral]
// CHECK:STDOUT: %float: Core.FloatLiteral = float_literal_value 10e-1 [concrete = constants.%float]
// CHECK:STDOUT: %FloatLiteralToFloatLiteral.call: init Core.FloatLiteral = call %FloatLiteralToFloatLiteral.ref(%float) [concrete = constants.%float]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- literal_f64.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete]
// CHECK:STDOUT: %f64.b55: type = class_type @Float, @Float(%int_64) [concrete]
// CHECK:STDOUT: %pattern_type.f3c: type = pattern_type %f64.b55 [concrete]
// CHECK:STDOUT: %FloatLiteralToFloat64.type: type = fn_type @FloatLiteralToFloat64 [concrete]
// CHECK:STDOUT: %FloatLiteralToFloat64: %FloatLiteralToFloat64.type = struct_value () [concrete]
// CHECK:STDOUT: %float.1f7: Core.FloatLiteral = float_literal_value 0e-1 [concrete]
// CHECK:STDOUT: %float.1af: %f64.b55 = float_value 0 [concrete]
// CHECK:STDOUT: %float.6da: Core.FloatLiteral = float_literal_value 10e-1 [concrete]
// CHECK:STDOUT: %float.642: %f64.b55 = float_value 1 [concrete]
// CHECK:STDOUT: %float.12a: Core.FloatLiteral = float_literal_value 10e307 [concrete]
// CHECK:STDOUT: %float.3b9: %f64.b55 = float_value 1.0E+308 [concrete]
// CHECK:STDOUT: %float.82f: Core.FloatLiteral = float_literal_value 10e308 [concrete]
// CHECK:STDOUT: %float.f70: %f64.b55 = float_value +Inf [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Main.FloatLiteralToFloat64: %FloatLiteralToFloat64.type = import_ref Main//f64, FloatLiteralToFloat64, loaded [concrete = constants.%FloatLiteralToFloat64]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %a.patt: %pattern_type.f3c = value_binding_pattern a [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f64.loc6: type = type_literal constants.%f64.b55 [concrete = constants.%f64.b55]
// CHECK:STDOUT: %.loc6_39.1: %f64.b55 = value_of_initializer @__global_init.%FloatLiteralToFloat64.call.loc6 [concrete = constants.%float.1af]
// CHECK:STDOUT: %.loc6_39.2: %f64.b55 = converted @__global_init.%FloatLiteralToFloat64.call.loc6, %.loc6_39.1 [concrete = constants.%float.1af]
// CHECK:STDOUT: %a: %f64.b55 = value_binding a, %.loc6_39.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %pattern_type.f3c = value_binding_pattern b [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f64.loc7: type = type_literal constants.%f64.b55 [concrete = constants.%f64.b55]
// CHECK:STDOUT: %.loc7_39.1: %f64.b55 = value_of_initializer @__global_init.%FloatLiteralToFloat64.call.loc7 [concrete = constants.%float.642]
// CHECK:STDOUT: %.loc7_39.2: %f64.b55 = converted @__global_init.%FloatLiteralToFloat64.call.loc7, %.loc7_39.1 [concrete = constants.%float.642]
// CHECK:STDOUT: %b: %f64.b55 = value_binding b, %.loc7_39.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %c.patt: %pattern_type.f3c = value_binding_pattern c [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f64.loc8: type = type_literal constants.%f64.b55 [concrete = constants.%f64.b55]
// CHECK:STDOUT: %.loc8_43.1: %f64.b55 = value_of_initializer @__global_init.%FloatLiteralToFloat64.call.loc8 [concrete = constants.%float.3b9]
// CHECK:STDOUT: %.loc8_43.2: %f64.b55 = converted @__global_init.%FloatLiteralToFloat64.call.loc8, %.loc8_43.1 [concrete = constants.%float.3b9]
// CHECK:STDOUT: %c: %f64.b55 = value_binding c, %.loc8_43.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %d.patt: %pattern_type.f3c = value_binding_pattern d [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f64.loc10: type = type_literal constants.%f64.b55 [concrete = constants.%f64.b55]
// CHECK:STDOUT: %.loc10_43.1: %f64.b55 = value_of_initializer @__global_init.%FloatLiteralToFloat64.call.loc10 [concrete = constants.%float.f70]
// CHECK:STDOUT: %.loc10_43.2: %f64.b55 = converted @__global_init.%FloatLiteralToFloat64.call.loc10, %.loc10_43.1 [concrete = constants.%float.f70]
// CHECK:STDOUT: %d: %f64.b55 = value_binding d, %.loc10_43.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %FloatLiteralToFloat64.ref.loc6: %FloatLiteralToFloat64.type = name_ref FloatLiteralToFloat64, imports.%Main.FloatLiteralToFloat64 [concrete = constants.%FloatLiteralToFloat64]
// CHECK:STDOUT: %float.loc6: Core.FloatLiteral = float_literal_value 0e-1 [concrete = constants.%float.1f7]
// CHECK:STDOUT: %FloatLiteralToFloat64.call.loc6: init %f64.b55 = call %FloatLiteralToFloat64.ref.loc6(%float.loc6) [concrete = constants.%float.1af]
// CHECK:STDOUT: %FloatLiteralToFloat64.ref.loc7: %FloatLiteralToFloat64.type = name_ref FloatLiteralToFloat64, imports.%Main.FloatLiteralToFloat64 [concrete = constants.%FloatLiteralToFloat64]
// CHECK:STDOUT: %float.loc7: Core.FloatLiteral = float_literal_value 10e-1 [concrete = constants.%float.6da]
// CHECK:STDOUT: %FloatLiteralToFloat64.call.loc7: init %f64.b55 = call %FloatLiteralToFloat64.ref.loc7(%float.loc7) [concrete = constants.%float.642]
// CHECK:STDOUT: %FloatLiteralToFloat64.ref.loc8: %FloatLiteralToFloat64.type = name_ref FloatLiteralToFloat64, imports.%Main.FloatLiteralToFloat64 [concrete = constants.%FloatLiteralToFloat64]
// CHECK:STDOUT: %float.loc8: Core.FloatLiteral = float_literal_value 10e307 [concrete = constants.%float.12a]
// CHECK:STDOUT: %FloatLiteralToFloat64.call.loc8: init %f64.b55 = call %FloatLiteralToFloat64.ref.loc8(%float.loc8) [concrete = constants.%float.3b9]
// CHECK:STDOUT: %FloatLiteralToFloat64.ref.loc10: %FloatLiteralToFloat64.type = name_ref FloatLiteralToFloat64, imports.%Main.FloatLiteralToFloat64 [concrete = constants.%FloatLiteralToFloat64]
// CHECK:STDOUT: %float.loc10: Core.FloatLiteral = float_literal_value 10e308 [concrete = constants.%float.82f]
// CHECK:STDOUT: %FloatLiteralToFloat64.call.loc10: init %f64.b55 = call %FloatLiteralToFloat64.ref.loc10(%float.loc10) [concrete = constants.%float.f70]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- literal_f32.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %f32.a26: type = class_type @Float, @Float(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.f3b: type = pattern_type %f32.a26 [concrete]
// CHECK:STDOUT: %FloatLiteralToFloat32.type: type = fn_type @FloatLiteralToFloat32 [concrete]
// CHECK:STDOUT: %FloatLiteralToFloat32: %FloatLiteralToFloat32.type = struct_value () [concrete]
// CHECK:STDOUT: %float.1f7: Core.FloatLiteral = float_literal_value 0e-1 [concrete]
// CHECK:STDOUT: %float.e89: %f32.a26 = float_value 0 [concrete]
// CHECK:STDOUT: %float.6da: Core.FloatLiteral = float_literal_value 10e-1 [concrete]
// CHECK:STDOUT: %float.2ec: %f32.a26 = float_value 1 [concrete]
// CHECK:STDOUT: %float.8d2: Core.FloatLiteral = float_literal_value 10e37 [concrete]
// CHECK:STDOUT: %float.16a: %f32.a26 = float_value 9.99999968E+37 [concrete]
// CHECK:STDOUT: %float.cfc: Core.FloatLiteral = float_literal_value 10e38 [concrete]
// CHECK:STDOUT: %float.81c: %f32.a26 = float_value +Inf [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Main.FloatLiteralToFloat32: %FloatLiteralToFloat32.type = import_ref Main//f32, FloatLiteralToFloat32, loaded [concrete = constants.%FloatLiteralToFloat32]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %a.patt: %pattern_type.f3b = value_binding_pattern a [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f32.loc6: type = type_literal constants.%f32.a26 [concrete = constants.%f32.a26]
// CHECK:STDOUT: %.loc6_39.1: %f32.a26 = value_of_initializer @__global_init.%FloatLiteralToFloat32.call.loc6 [concrete = constants.%float.e89]
// CHECK:STDOUT: %.loc6_39.2: %f32.a26 = converted @__global_init.%FloatLiteralToFloat32.call.loc6, %.loc6_39.1 [concrete = constants.%float.e89]
// CHECK:STDOUT: %a: %f32.a26 = value_binding a, %.loc6_39.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %pattern_type.f3b = value_binding_pattern b [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f32.loc7: type = type_literal constants.%f32.a26 [concrete = constants.%f32.a26]
// CHECK:STDOUT: %.loc7_39.1: %f32.a26 = value_of_initializer @__global_init.%FloatLiteralToFloat32.call.loc7 [concrete = constants.%float.2ec]
// CHECK:STDOUT: %.loc7_39.2: %f32.a26 = converted @__global_init.%FloatLiteralToFloat32.call.loc7, %.loc7_39.1 [concrete = constants.%float.2ec]
// CHECK:STDOUT: %b: %f32.a26 = value_binding b, %.loc7_39.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %c.patt: %pattern_type.f3b = value_binding_pattern c [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f32.loc8: type = type_literal constants.%f32.a26 [concrete = constants.%f32.a26]
// CHECK:STDOUT: %.loc8_42.1: %f32.a26 = value_of_initializer @__global_init.%FloatLiteralToFloat32.call.loc8 [concrete = constants.%float.16a]
// CHECK:STDOUT: %.loc8_42.2: %f32.a26 = converted @__global_init.%FloatLiteralToFloat32.call.loc8, %.loc8_42.1 [concrete = constants.%float.16a]
// CHECK:STDOUT: %c: %f32.a26 = value_binding c, %.loc8_42.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %d.patt: %pattern_type.f3b = value_binding_pattern d [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f32.loc10: type = type_literal constants.%f32.a26 [concrete = constants.%f32.a26]
// CHECK:STDOUT: %.loc10_42.1: %f32.a26 = value_of_initializer @__global_init.%FloatLiteralToFloat32.call.loc10 [concrete = constants.%float.81c]
// CHECK:STDOUT: %.loc10_42.2: %f32.a26 = converted @__global_init.%FloatLiteralToFloat32.call.loc10, %.loc10_42.1 [concrete = constants.%float.81c]
// CHECK:STDOUT: %d: %f32.a26 = value_binding d, %.loc10_42.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %FloatLiteralToFloat32.ref.loc6: %FloatLiteralToFloat32.type = name_ref FloatLiteralToFloat32, imports.%Main.FloatLiteralToFloat32 [concrete = constants.%FloatLiteralToFloat32]
// CHECK:STDOUT: %float.loc6: Core.FloatLiteral = float_literal_value 0e-1 [concrete = constants.%float.1f7]
// CHECK:STDOUT: %FloatLiteralToFloat32.call.loc6: init %f32.a26 = call %FloatLiteralToFloat32.ref.loc6(%float.loc6) [concrete = constants.%float.e89]
// CHECK:STDOUT: %FloatLiteralToFloat32.ref.loc7: %FloatLiteralToFloat32.type = name_ref FloatLiteralToFloat32, imports.%Main.FloatLiteralToFloat32 [concrete = constants.%FloatLiteralToFloat32]
// CHECK:STDOUT: %float.loc7: Core.FloatLiteral = float_literal_value 10e-1 [concrete = constants.%float.6da]
// CHECK:STDOUT: %FloatLiteralToFloat32.call.loc7: init %f32.a26 = call %FloatLiteralToFloat32.ref.loc7(%float.loc7) [concrete = constants.%float.2ec]
// CHECK:STDOUT: %FloatLiteralToFloat32.ref.loc8: %FloatLiteralToFloat32.type = name_ref FloatLiteralToFloat32, imports.%Main.FloatLiteralToFloat32 [concrete = constants.%FloatLiteralToFloat32]
// CHECK:STDOUT: %float.loc8: Core.FloatLiteral = float_literal_value 10e37 [concrete = constants.%float.8d2]
// CHECK:STDOUT: %FloatLiteralToFloat32.call.loc8: init %f32.a26 = call %FloatLiteralToFloat32.ref.loc8(%float.loc8) [concrete = constants.%float.16a]
// CHECK:STDOUT: %FloatLiteralToFloat32.ref.loc10: %FloatLiteralToFloat32.type = name_ref FloatLiteralToFloat32, imports.%Main.FloatLiteralToFloat32 [concrete = constants.%FloatLiteralToFloat32]
// CHECK:STDOUT: %float.loc10: Core.FloatLiteral = float_literal_value 10e38 [concrete = constants.%float.cfc]
// CHECK:STDOUT: %FloatLiteralToFloat32.call.loc10: init %f32.a26 = call %FloatLiteralToFloat32.ref.loc10(%float.loc10) [concrete = constants.%float.81c]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- identity_f64.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete]
// CHECK:STDOUT: %f64.b55: type = class_type @Float, @Float(%int_64) [concrete]
// CHECK:STDOUT: %pattern_type.f3c: type = pattern_type %f64.b55 [concrete]
// CHECK:STDOUT: %Float64ToFloat64.type: type = fn_type @Float64ToFloat64 [concrete]
// CHECK:STDOUT: %Float64ToFloat64: %Float64ToFloat64.type = struct_value () [concrete]
// CHECK:STDOUT: %float.1f7: Core.FloatLiteral = float_literal_value 0e-1 [concrete]
// CHECK:STDOUT: %ImplicitAs.type.857: type = facet_type <@ImplicitAs, @ImplicitAs(%f64.b55)> [concrete]
// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.5e6: type = fn_type @Core.FloatLiteral.as.ImplicitAs.impl.Convert, @Core.FloatLiteral.as.ImplicitAs.impl(%To) [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.539: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.5e6 = struct_value () [symbolic]
// CHECK:STDOUT: %ImplicitAs.impl_witness.83f: <witness> = impl_witness imports.%ImplicitAs.impl_witness_table, @Core.FloatLiteral.as.ImplicitAs.impl(%int_64) [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.5c5: type = fn_type @Core.FloatLiteral.as.ImplicitAs.impl.Convert, @Core.FloatLiteral.as.ImplicitAs.impl(%int_64) [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.881: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.5c5 = struct_value () [concrete]
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.857 = facet_value Core.FloatLiteral, (%ImplicitAs.impl_witness.83f) [concrete]
// CHECK:STDOUT: %ImplicitAs.WithSelf.Convert.type.096: type = fn_type @ImplicitAs.WithSelf.Convert, @ImplicitAs.WithSelf(%f64.b55, %ImplicitAs.facet) [concrete]
// CHECK:STDOUT: %.119: type = fn_type_with_self_type %ImplicitAs.WithSelf.Convert.type.096, %ImplicitAs.facet [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.4d4: <bound method> = bound_method %float.1f7, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.881 [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %Core.FloatLiteral.as.ImplicitAs.impl.Convert.881, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(%int_64) [concrete]
// CHECK:STDOUT: %bound_method.a29: <bound method> = bound_method %float.1f7, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.1af: %f64.b55 = float_value 0 [concrete]
// CHECK:STDOUT: %float.6da: Core.FloatLiteral = float_literal_value 10e-1 [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.bef: <bound method> = bound_method %float.6da, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.881 [concrete]
// CHECK:STDOUT: %bound_method.c5a: <bound method> = bound_method %float.6da, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.642: %f64.b55 = float_value 1 [concrete]
// CHECK:STDOUT: %float.12a: Core.FloatLiteral = float_literal_value 10e307 [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.72f: <bound method> = bound_method %float.12a, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.881 [concrete]
// CHECK:STDOUT: %bound_method.b4f: <bound method> = bound_method %float.12a, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.3b9: %f64.b55 = float_value 1.0E+308 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Main.Float64ToFloat64: %Float64ToFloat64.type = import_ref Main//f64, Float64ToFloat64, loaded [concrete = constants.%Float64ToFloat64]
// CHECK:STDOUT: %Core.import_ref.63c: @Core.FloatLiteral.as.ImplicitAs.impl.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.type (%Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.5e6) = import_ref Core//prelude/parts/float, loc{{\d+_\d+}}, loaded [symbolic = @Core.FloatLiteral.as.ImplicitAs.impl.%Core.FloatLiteral.as.ImplicitAs.impl.Convert (constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.539)]
// CHECK:STDOUT: %ImplicitAs.impl_witness_table = impl_witness_table (%Core.import_ref.63c), @Core.FloatLiteral.as.ImplicitAs.impl [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %a.patt: %pattern_type.f3c = value_binding_pattern a [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f64.loc6: type = type_literal constants.%f64.b55 [concrete = constants.%f64.b55]
// CHECK:STDOUT: %.loc6_34.1: %f64.b55 = value_of_initializer @__global_init.%Float64ToFloat64.call.loc6 [concrete = constants.%float.1af]
// CHECK:STDOUT: %.loc6_34.2: %f64.b55 = converted @__global_init.%Float64ToFloat64.call.loc6, %.loc6_34.1 [concrete = constants.%float.1af]
// CHECK:STDOUT: %a: %f64.b55 = value_binding a, %.loc6_34.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %pattern_type.f3c = value_binding_pattern b [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f64.loc7: type = type_literal constants.%f64.b55 [concrete = constants.%f64.b55]
// CHECK:STDOUT: %.loc7_34.1: %f64.b55 = value_of_initializer @__global_init.%Float64ToFloat64.call.loc7 [concrete = constants.%float.642]
// CHECK:STDOUT: %.loc7_34.2: %f64.b55 = converted @__global_init.%Float64ToFloat64.call.loc7, %.loc7_34.1 [concrete = constants.%float.642]
// CHECK:STDOUT: %b: %f64.b55 = value_binding b, %.loc7_34.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %c.patt: %pattern_type.f3c = value_binding_pattern c [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f64.loc8: type = type_literal constants.%f64.b55 [concrete = constants.%f64.b55]
// CHECK:STDOUT: %.loc8_38.1: %f64.b55 = value_of_initializer @__global_init.%Float64ToFloat64.call.loc8 [concrete = constants.%float.3b9]
// CHECK:STDOUT: %.loc8_38.2: %f64.b55 = converted @__global_init.%Float64ToFloat64.call.loc8, %.loc8_38.1 [concrete = constants.%float.3b9]
// CHECK:STDOUT: %c: %f64.b55 = value_binding c, %.loc8_38.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Float64ToFloat64.ref.loc6: %Float64ToFloat64.type = name_ref Float64ToFloat64, imports.%Main.Float64ToFloat64 [concrete = constants.%Float64ToFloat64]
// CHECK:STDOUT: %float.loc6: Core.FloatLiteral = float_literal_value 0e-1 [concrete = constants.%float.1f7]
// CHECK:STDOUT: %impl.elem0.loc6: %.119 = impl_witness_access constants.%ImplicitAs.impl_witness.83f, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.881]
// CHECK:STDOUT: %bound_method.loc6_31.1: <bound method> = bound_method %float.loc6, %impl.elem0.loc6 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.4d4]
// CHECK:STDOUT: %specific_fn.loc6: <specific function> = specific_function %impl.elem0.loc6, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(constants.%int_64) [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc6_31.2: <bound method> = bound_method %float.loc6, %specific_fn.loc6 [concrete = constants.%bound_method.a29]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc6: init %f64.b55 = call %bound_method.loc6_31.2(%float.loc6) [concrete = constants.%float.1af]
// CHECK:STDOUT: %.loc6_31.1: %f64.b55 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc6 [concrete = constants.%float.1af]
// CHECK:STDOUT: %.loc6_31.2: %f64.b55 = converted %float.loc6, %.loc6_31.1 [concrete = constants.%float.1af]
// CHECK:STDOUT: %Float64ToFloat64.call.loc6: init %f64.b55 = call %Float64ToFloat64.ref.loc6(%.loc6_31.2) [concrete = constants.%float.1af]
// CHECK:STDOUT: %Float64ToFloat64.ref.loc7: %Float64ToFloat64.type = name_ref Float64ToFloat64, imports.%Main.Float64ToFloat64 [concrete = constants.%Float64ToFloat64]
// CHECK:STDOUT: %float.loc7: Core.FloatLiteral = float_literal_value 10e-1 [concrete = constants.%float.6da]
// CHECK:STDOUT: %impl.elem0.loc7: %.119 = impl_witness_access constants.%ImplicitAs.impl_witness.83f, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.881]
// CHECK:STDOUT: %bound_method.loc7_31.1: <bound method> = bound_method %float.loc7, %impl.elem0.loc7 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.bef]
// CHECK:STDOUT: %specific_fn.loc7: <specific function> = specific_function %impl.elem0.loc7, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(constants.%int_64) [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc7_31.2: <bound method> = bound_method %float.loc7, %specific_fn.loc7 [concrete = constants.%bound_method.c5a]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc7: init %f64.b55 = call %bound_method.loc7_31.2(%float.loc7) [concrete = constants.%float.642]
// CHECK:STDOUT: %.loc7_31.1: %f64.b55 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc7 [concrete = constants.%float.642]
// CHECK:STDOUT: %.loc7_31.2: %f64.b55 = converted %float.loc7, %.loc7_31.1 [concrete = constants.%float.642]
// CHECK:STDOUT: %Float64ToFloat64.call.loc7: init %f64.b55 = call %Float64ToFloat64.ref.loc7(%.loc7_31.2) [concrete = constants.%float.642]
// CHECK:STDOUT: %Float64ToFloat64.ref.loc8: %Float64ToFloat64.type = name_ref Float64ToFloat64, imports.%Main.Float64ToFloat64 [concrete = constants.%Float64ToFloat64]
// CHECK:STDOUT: %float.loc8: Core.FloatLiteral = float_literal_value 10e307 [concrete = constants.%float.12a]
// CHECK:STDOUT: %impl.elem0.loc8: %.119 = impl_witness_access constants.%ImplicitAs.impl_witness.83f, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.881]
// CHECK:STDOUT: %bound_method.loc8_31.1: <bound method> = bound_method %float.loc8, %impl.elem0.loc8 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.72f]
// CHECK:STDOUT: %specific_fn.loc8: <specific function> = specific_function %impl.elem0.loc8, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(constants.%int_64) [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc8_31.2: <bound method> = bound_method %float.loc8, %specific_fn.loc8 [concrete = constants.%bound_method.b4f]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc8: init %f64.b55 = call %bound_method.loc8_31.2(%float.loc8) [concrete = constants.%float.3b9]
// CHECK:STDOUT: %.loc8_31.1: %f64.b55 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc8 [concrete = constants.%float.3b9]
// CHECK:STDOUT: %.loc8_31.2: %f64.b55 = converted %float.loc8, %.loc8_31.1 [concrete = constants.%float.3b9]
// CHECK:STDOUT: %Float64ToFloat64.call.loc8: init %f64.b55 = call %Float64ToFloat64.ref.loc8(%.loc8_31.2) [concrete = constants.%float.3b9]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- identity_f32.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %f32.a26: type = class_type @Float, @Float(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.f3b: type = pattern_type %f32.a26 [concrete]
// CHECK:STDOUT: %Float32ToFloat32.type: type = fn_type @Float32ToFloat32 [concrete]
// CHECK:STDOUT: %Float32ToFloat32: %Float32ToFloat32.type = struct_value () [concrete]
// CHECK:STDOUT: %float.1f7: Core.FloatLiteral = float_literal_value 0e-1 [concrete]
// CHECK:STDOUT: %ImplicitAs.type.d0d: type = facet_type <@ImplicitAs, @ImplicitAs(%f32.a26)> [concrete]
// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.5e6: type = fn_type @Core.FloatLiteral.as.ImplicitAs.impl.Convert, @Core.FloatLiteral.as.ImplicitAs.impl(%To) [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.539: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.5e6 = struct_value () [symbolic]
// CHECK:STDOUT: %ImplicitAs.impl_witness.65d: <witness> = impl_witness imports.%ImplicitAs.impl_witness_table, @Core.FloatLiteral.as.ImplicitAs.impl(%int_32) [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.f03: type = fn_type @Core.FloatLiteral.as.ImplicitAs.impl.Convert, @Core.FloatLiteral.as.ImplicitAs.impl(%int_32) [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.2cd: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.f03 = struct_value () [concrete]
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.d0d = facet_value Core.FloatLiteral, (%ImplicitAs.impl_witness.65d) [concrete]
// CHECK:STDOUT: %ImplicitAs.WithSelf.Convert.type.c87: type = fn_type @ImplicitAs.WithSelf.Convert, @ImplicitAs.WithSelf(%f32.a26, %ImplicitAs.facet) [concrete]
// CHECK:STDOUT: %.3a8: type = fn_type_with_self_type %ImplicitAs.WithSelf.Convert.type.c87, %ImplicitAs.facet [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.3a0: <bound method> = bound_method %float.1f7, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.2cd [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %Core.FloatLiteral.as.ImplicitAs.impl.Convert.2cd, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete]
// CHECK:STDOUT: %bound_method.7ae: <bound method> = bound_method %float.1f7, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.e89: %f32.a26 = float_value 0 [concrete]
// CHECK:STDOUT: %float.6da: Core.FloatLiteral = float_literal_value 10e-1 [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.1ac: <bound method> = bound_method %float.6da, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.2cd [concrete]
// CHECK:STDOUT: %bound_method.aaa: <bound method> = bound_method %float.6da, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.2ec: %f32.a26 = float_value 1 [concrete]
// CHECK:STDOUT: %float.8d2: Core.FloatLiteral = float_literal_value 10e37 [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.f18: <bound method> = bound_method %float.8d2, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.2cd [concrete]
// CHECK:STDOUT: %bound_method.137: <bound method> = bound_method %float.8d2, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.16a: %f32.a26 = float_value 9.99999968E+37 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Main.Float32ToFloat32: %Float32ToFloat32.type = import_ref Main//f32, Float32ToFloat32, loaded [concrete = constants.%Float32ToFloat32]
// CHECK:STDOUT: %Core.import_ref.63c: @Core.FloatLiteral.as.ImplicitAs.impl.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.type (%Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.5e6) = import_ref Core//prelude/parts/float, loc{{\d+_\d+}}, loaded [symbolic = @Core.FloatLiteral.as.ImplicitAs.impl.%Core.FloatLiteral.as.ImplicitAs.impl.Convert (constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.539)]
// CHECK:STDOUT: %ImplicitAs.impl_witness_table = impl_witness_table (%Core.import_ref.63c), @Core.FloatLiteral.as.ImplicitAs.impl [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %a.patt: %pattern_type.f3b = value_binding_pattern a [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f32.loc6: type = type_literal constants.%f32.a26 [concrete = constants.%f32.a26]
// CHECK:STDOUT: %.loc6_34.1: %f32.a26 = value_of_initializer @__global_init.%Float32ToFloat32.call.loc6 [concrete = constants.%float.e89]
// CHECK:STDOUT: %.loc6_34.2: %f32.a26 = converted @__global_init.%Float32ToFloat32.call.loc6, %.loc6_34.1 [concrete = constants.%float.e89]
// CHECK:STDOUT: %a: %f32.a26 = value_binding a, %.loc6_34.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %pattern_type.f3b = value_binding_pattern b [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f32.loc7: type = type_literal constants.%f32.a26 [concrete = constants.%f32.a26]
// CHECK:STDOUT: %.loc7_34.1: %f32.a26 = value_of_initializer @__global_init.%Float32ToFloat32.call.loc7 [concrete = constants.%float.2ec]
// CHECK:STDOUT: %.loc7_34.2: %f32.a26 = converted @__global_init.%Float32ToFloat32.call.loc7, %.loc7_34.1 [concrete = constants.%float.2ec]
// CHECK:STDOUT: %b: %f32.a26 = value_binding b, %.loc7_34.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %c.patt: %pattern_type.f3b = value_binding_pattern c [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f32.loc8: type = type_literal constants.%f32.a26 [concrete = constants.%f32.a26]
// CHECK:STDOUT: %.loc8_37.1: %f32.a26 = value_of_initializer @__global_init.%Float32ToFloat32.call.loc8 [concrete = constants.%float.16a]
// CHECK:STDOUT: %.loc8_37.2: %f32.a26 = converted @__global_init.%Float32ToFloat32.call.loc8, %.loc8_37.1 [concrete = constants.%float.16a]
// CHECK:STDOUT: %c: %f32.a26 = value_binding c, %.loc8_37.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Float32ToFloat32.ref.loc6: %Float32ToFloat32.type = name_ref Float32ToFloat32, imports.%Main.Float32ToFloat32 [concrete = constants.%Float32ToFloat32]
// CHECK:STDOUT: %float.loc6: Core.FloatLiteral = float_literal_value 0e-1 [concrete = constants.%float.1f7]
// CHECK:STDOUT: %impl.elem0.loc6: %.3a8 = impl_witness_access constants.%ImplicitAs.impl_witness.65d, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.2cd]
// CHECK:STDOUT: %bound_method.loc6_31.1: <bound method> = bound_method %float.loc6, %impl.elem0.loc6 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.3a0]
// CHECK:STDOUT: %specific_fn.loc6: <specific function> = specific_function %impl.elem0.loc6, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc6_31.2: <bound method> = bound_method %float.loc6, %specific_fn.loc6 [concrete = constants.%bound_method.7ae]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc6: init %f32.a26 = call %bound_method.loc6_31.2(%float.loc6) [concrete = constants.%float.e89]
// CHECK:STDOUT: %.loc6_31.1: %f32.a26 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc6 [concrete = constants.%float.e89]
// CHECK:STDOUT: %.loc6_31.2: %f32.a26 = converted %float.loc6, %.loc6_31.1 [concrete = constants.%float.e89]
// CHECK:STDOUT: %Float32ToFloat32.call.loc6: init %f32.a26 = call %Float32ToFloat32.ref.loc6(%.loc6_31.2) [concrete = constants.%float.e89]
// CHECK:STDOUT: %Float32ToFloat32.ref.loc7: %Float32ToFloat32.type = name_ref Float32ToFloat32, imports.%Main.Float32ToFloat32 [concrete = constants.%Float32ToFloat32]
// CHECK:STDOUT: %float.loc7: Core.FloatLiteral = float_literal_value 10e-1 [concrete = constants.%float.6da]
// CHECK:STDOUT: %impl.elem0.loc7: %.3a8 = impl_witness_access constants.%ImplicitAs.impl_witness.65d, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.2cd]
// CHECK:STDOUT: %bound_method.loc7_31.1: <bound method> = bound_method %float.loc7, %impl.elem0.loc7 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.1ac]
// CHECK:STDOUT: %specific_fn.loc7: <specific function> = specific_function %impl.elem0.loc7, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc7_31.2: <bound method> = bound_method %float.loc7, %specific_fn.loc7 [concrete = constants.%bound_method.aaa]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc7: init %f32.a26 = call %bound_method.loc7_31.2(%float.loc7) [concrete = constants.%float.2ec]
// CHECK:STDOUT: %.loc7_31.1: %f32.a26 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc7 [concrete = constants.%float.2ec]
// CHECK:STDOUT: %.loc7_31.2: %f32.a26 = converted %float.loc7, %.loc7_31.1 [concrete = constants.%float.2ec]
// CHECK:STDOUT: %Float32ToFloat32.call.loc7: init %f32.a26 = call %Float32ToFloat32.ref.loc7(%.loc7_31.2) [concrete = constants.%float.2ec]
// CHECK:STDOUT: %Float32ToFloat32.ref.loc8: %Float32ToFloat32.type = name_ref Float32ToFloat32, imports.%Main.Float32ToFloat32 [concrete = constants.%Float32ToFloat32]
// CHECK:STDOUT: %float.loc8: Core.FloatLiteral = float_literal_value 10e37 [concrete = constants.%float.8d2]
// CHECK:STDOUT: %impl.elem0.loc8: %.3a8 = impl_witness_access constants.%ImplicitAs.impl_witness.65d, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.2cd]
// CHECK:STDOUT: %bound_method.loc8_31.1: <bound method> = bound_method %float.loc8, %impl.elem0.loc8 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.f18]
// CHECK:STDOUT: %specific_fn.loc8: <specific function> = specific_function %impl.elem0.loc8, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc8_31.2: <bound method> = bound_method %float.loc8, %specific_fn.loc8 [concrete = constants.%bound_method.137]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc8: init %f32.a26 = call %bound_method.loc8_31.2(%float.loc8) [concrete = constants.%float.16a]
// CHECK:STDOUT: %.loc8_31.1: %f32.a26 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc8 [concrete = constants.%float.16a]
// CHECK:STDOUT: %.loc8_31.2: %f32.a26 = converted %float.loc8, %.loc8_31.1 [concrete = constants.%float.16a]
// CHECK:STDOUT: %Float32ToFloat32.call.loc8: init %f32.a26 = call %Float32ToFloat32.ref.loc8(%.loc8_31.2) [concrete = constants.%float.16a]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- truncate.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %f32.a26: type = class_type @Float, @Float(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.f3b: type = pattern_type %f32.a26 [concrete]
// CHECK:STDOUT: %Float64ToFloat32.type: type = fn_type @Float64ToFloat32 [concrete]
// CHECK:STDOUT: %Float64ToFloat32: %Float64ToFloat32.type = struct_value () [concrete]
// CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete]
// CHECK:STDOUT: %f64.b55: type = class_type @Float, @Float(%int_64) [concrete]
// CHECK:STDOUT: %float.6da: Core.FloatLiteral = float_literal_value 10e-1 [concrete]
// CHECK:STDOUT: %ImplicitAs.type.857: type = facet_type <@ImplicitAs, @ImplicitAs(%f64.b55)> [concrete]
// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.5e6: type = fn_type @Core.FloatLiteral.as.ImplicitAs.impl.Convert, @Core.FloatLiteral.as.ImplicitAs.impl(%To) [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.539: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.5e6 = struct_value () [symbolic]
// CHECK:STDOUT: %ImplicitAs.impl_witness.83f: <witness> = impl_witness imports.%ImplicitAs.impl_witness_table, @Core.FloatLiteral.as.ImplicitAs.impl(%int_64) [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.5c5: type = fn_type @Core.FloatLiteral.as.ImplicitAs.impl.Convert, @Core.FloatLiteral.as.ImplicitAs.impl(%int_64) [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.881: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.5c5 = struct_value () [concrete]
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.857 = facet_value Core.FloatLiteral, (%ImplicitAs.impl_witness.83f) [concrete]
// CHECK:STDOUT: %ImplicitAs.WithSelf.Convert.type.096: type = fn_type @ImplicitAs.WithSelf.Convert, @ImplicitAs.WithSelf(%f64.b55, %ImplicitAs.facet) [concrete]
// CHECK:STDOUT: %.119: type = fn_type_with_self_type %ImplicitAs.WithSelf.Convert.type.096, %ImplicitAs.facet [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.bef: <bound method> = bound_method %float.6da, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.881 [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %Core.FloatLiteral.as.ImplicitAs.impl.Convert.881, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(%int_64) [concrete]
// CHECK:STDOUT: %bound_method.c5a: <bound method> = bound_method %float.6da, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.642: %f64.b55 = float_value 1 [concrete]
// CHECK:STDOUT: %float.2ec: %f32.a26 = float_value 1 [concrete]
// CHECK:STDOUT: %float.cfc: Core.FloatLiteral = float_literal_value 10e38 [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.af3: <bound method> = bound_method %float.cfc, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.881 [concrete]
// CHECK:STDOUT: %bound_method.8d2: <bound method> = bound_method %float.cfc, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.dae: %f64.b55 = float_value 9.9999999999999994E+38 [concrete]
// CHECK:STDOUT: %float.81c: %f32.a26 = float_value +Inf [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Main.Float64ToFloat32: %Float64ToFloat32.type = import_ref Main//f32, Float64ToFloat32, loaded [concrete = constants.%Float64ToFloat32]
// CHECK:STDOUT: %Core.import_ref.63c: @Core.FloatLiteral.as.ImplicitAs.impl.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.type (%Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.5e6) = import_ref Core//prelude/parts/float, loc{{\d+_\d+}}, loaded [symbolic = @Core.FloatLiteral.as.ImplicitAs.impl.%Core.FloatLiteral.as.ImplicitAs.impl.Convert (constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.539)]
// CHECK:STDOUT: %ImplicitAs.impl_witness_table = impl_witness_table (%Core.import_ref.63c), @Core.FloatLiteral.as.ImplicitAs.impl [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %a.patt: %pattern_type.f3b = value_binding_pattern a [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f32.loc7: type = type_literal constants.%f32.a26 [concrete = constants.%f32.a26]
// CHECK:STDOUT: %.loc7_34.1: %f32.a26 = value_of_initializer @__global_init.%Float64ToFloat32.call.loc7 [concrete = constants.%float.2ec]
// CHECK:STDOUT: %.loc7_34.2: %f32.a26 = converted @__global_init.%Float64ToFloat32.call.loc7, %.loc7_34.1 [concrete = constants.%float.2ec]
// CHECK:STDOUT: %a: %f32.a26 = value_binding a, %.loc7_34.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %pattern_type.f3b = value_binding_pattern b [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f32.loc9: type = type_literal constants.%f32.a26 [concrete = constants.%f32.a26]
// CHECK:STDOUT: %.loc9_37.1: %f32.a26 = value_of_initializer @__global_init.%Float64ToFloat32.call.loc9 [concrete = constants.%float.81c]
// CHECK:STDOUT: %.loc9_37.2: %f32.a26 = converted @__global_init.%Float64ToFloat32.call.loc9, %.loc9_37.1 [concrete = constants.%float.81c]
// CHECK:STDOUT: %b: %f32.a26 = value_binding b, %.loc9_37.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Float64ToFloat32.ref.loc7: %Float64ToFloat32.type = name_ref Float64ToFloat32, imports.%Main.Float64ToFloat32 [concrete = constants.%Float64ToFloat32]
// CHECK:STDOUT: %float.loc7: Core.FloatLiteral = float_literal_value 10e-1 [concrete = constants.%float.6da]
// CHECK:STDOUT: %impl.elem0.loc7: %.119 = impl_witness_access constants.%ImplicitAs.impl_witness.83f, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.881]
// CHECK:STDOUT: %bound_method.loc7_31.1: <bound method> = bound_method %float.loc7, %impl.elem0.loc7 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.bef]
// CHECK:STDOUT: %specific_fn.loc7: <specific function> = specific_function %impl.elem0.loc7, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(constants.%int_64) [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc7_31.2: <bound method> = bound_method %float.loc7, %specific_fn.loc7 [concrete = constants.%bound_method.c5a]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc7: init %f64.b55 = call %bound_method.loc7_31.2(%float.loc7) [concrete = constants.%float.642]
// CHECK:STDOUT: %.loc7_31.1: %f64.b55 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc7 [concrete = constants.%float.642]
// CHECK:STDOUT: %.loc7_31.2: %f64.b55 = converted %float.loc7, %.loc7_31.1 [concrete = constants.%float.642]
// CHECK:STDOUT: %Float64ToFloat32.call.loc7: init %f32.a26 = call %Float64ToFloat32.ref.loc7(%.loc7_31.2) [concrete = constants.%float.2ec]
// CHECK:STDOUT: %Float64ToFloat32.ref.loc9: %Float64ToFloat32.type = name_ref Float64ToFloat32, imports.%Main.Float64ToFloat32 [concrete = constants.%Float64ToFloat32]
// CHECK:STDOUT: %float.loc9: Core.FloatLiteral = float_literal_value 10e38 [concrete = constants.%float.cfc]
// CHECK:STDOUT: %impl.elem0.loc9: %.119 = impl_witness_access constants.%ImplicitAs.impl_witness.83f, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.881]
// CHECK:STDOUT: %bound_method.loc9_31.1: <bound method> = bound_method %float.loc9, %impl.elem0.loc9 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.af3]
// CHECK:STDOUT: %specific_fn.loc9: <specific function> = specific_function %impl.elem0.loc9, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(constants.%int_64) [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc9_31.2: <bound method> = bound_method %float.loc9, %specific_fn.loc9 [concrete = constants.%bound_method.8d2]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc9: init %f64.b55 = call %bound_method.loc9_31.2(%float.loc9) [concrete = constants.%float.dae]
// CHECK:STDOUT: %.loc9_31.1: %f64.b55 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc9 [concrete = constants.%float.dae]
// CHECK:STDOUT: %.loc9_31.2: %f64.b55 = converted %float.loc9, %.loc9_31.1 [concrete = constants.%float.dae]
// CHECK:STDOUT: %Float64ToFloat32.call.loc9: init %f32.a26 = call %Float64ToFloat32.ref.loc9(%.loc9_31.2) [concrete = constants.%float.81c]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- extend.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete]
// CHECK:STDOUT: %f64.b55: type = class_type @Float, @Float(%int_64) [concrete]
// CHECK:STDOUT: %pattern_type.f3c: type = pattern_type %f64.b55 [concrete]
// CHECK:STDOUT: %Float32ToFloat64.type: type = fn_type @Float32ToFloat64 [concrete]
// CHECK:STDOUT: %Float32ToFloat64: %Float32ToFloat64.type = struct_value () [concrete]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %f32.a26: type = class_type @Float, @Float(%int_32) [concrete]
// CHECK:STDOUT: %float.6da: Core.FloatLiteral = float_literal_value 10e-1 [concrete]
// CHECK:STDOUT: %ImplicitAs.type.d0d: type = facet_type <@ImplicitAs, @ImplicitAs(%f32.a26)> [concrete]
// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.5e6: type = fn_type @Core.FloatLiteral.as.ImplicitAs.impl.Convert, @Core.FloatLiteral.as.ImplicitAs.impl(%To) [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.539: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.5e6 = struct_value () [symbolic]
// CHECK:STDOUT: %ImplicitAs.impl_witness.65d: <witness> = impl_witness imports.%ImplicitAs.impl_witness_table, @Core.FloatLiteral.as.ImplicitAs.impl(%int_32) [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.f03: type = fn_type @Core.FloatLiteral.as.ImplicitAs.impl.Convert, @Core.FloatLiteral.as.ImplicitAs.impl(%int_32) [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.2cd: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.f03 = struct_value () [concrete]
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.d0d = facet_value Core.FloatLiteral, (%ImplicitAs.impl_witness.65d) [concrete]
// CHECK:STDOUT: %ImplicitAs.WithSelf.Convert.type.c87: type = fn_type @ImplicitAs.WithSelf.Convert, @ImplicitAs.WithSelf(%f32.a26, %ImplicitAs.facet) [concrete]
// CHECK:STDOUT: %.3a8: type = fn_type_with_self_type %ImplicitAs.WithSelf.Convert.type.c87, %ImplicitAs.facet [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.1ac: <bound method> = bound_method %float.6da, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.2cd [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %Core.FloatLiteral.as.ImplicitAs.impl.Convert.2cd, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete]
// CHECK:STDOUT: %bound_method.aaa: <bound method> = bound_method %float.6da, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.2ec: %f32.a26 = float_value 1 [concrete]
// CHECK:STDOUT: %float.642: %f64.b55 = float_value 1 [concrete]
// CHECK:STDOUT: %float.c02: Core.FloatLiteral = float_literal_value 10e29 [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.1c5: <bound method> = bound_method %float.c02, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.2cd [concrete]
// CHECK:STDOUT: %bound_method.dc8: <bound method> = bound_method %float.c02, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.419: %f32.a26 = float_value 1.00000002E+30 [concrete]
// CHECK:STDOUT: %float.e6a: %f64.b55 = float_value 1.0000000150474662E+30 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Main.Float32ToFloat64: %Float32ToFloat64.type = import_ref Main//f32, Float32ToFloat64, loaded [concrete = constants.%Float32ToFloat64]
// CHECK:STDOUT: %Core.import_ref.63c: @Core.FloatLiteral.as.ImplicitAs.impl.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.type (%Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.5e6) = import_ref Core//prelude/parts/float, loc{{\d+_\d+}}, loaded [symbolic = @Core.FloatLiteral.as.ImplicitAs.impl.%Core.FloatLiteral.as.ImplicitAs.impl.Convert (constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.539)]
// CHECK:STDOUT: %ImplicitAs.impl_witness_table = impl_witness_table (%Core.import_ref.63c), @Core.FloatLiteral.as.ImplicitAs.impl [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %a.patt: %pattern_type.f3c = value_binding_pattern a [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f64.loc7: type = type_literal constants.%f64.b55 [concrete = constants.%f64.b55]
// CHECK:STDOUT: %.loc7_34.1: %f64.b55 = value_of_initializer @__global_init.%Float32ToFloat64.call.loc7 [concrete = constants.%float.642]
// CHECK:STDOUT: %.loc7_34.2: %f64.b55 = converted @__global_init.%Float32ToFloat64.call.loc7, %.loc7_34.1 [concrete = constants.%float.642]
// CHECK:STDOUT: %a: %f64.b55 = value_binding a, %.loc7_34.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %pattern_type.f3c = value_binding_pattern b [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %f64.loc8: type = type_literal constants.%f64.b55 [concrete = constants.%f64.b55]
// CHECK:STDOUT: %.loc8_37.1: %f64.b55 = value_of_initializer @__global_init.%Float32ToFloat64.call.loc8 [concrete = constants.%float.e6a]
// CHECK:STDOUT: %.loc8_37.2: %f64.b55 = converted @__global_init.%Float32ToFloat64.call.loc8, %.loc8_37.1 [concrete = constants.%float.e6a]
// CHECK:STDOUT: %b: %f64.b55 = value_binding b, %.loc8_37.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Float32ToFloat64.ref.loc7: %Float32ToFloat64.type = name_ref Float32ToFloat64, imports.%Main.Float32ToFloat64 [concrete = constants.%Float32ToFloat64]
// CHECK:STDOUT: %float.loc7: Core.FloatLiteral = float_literal_value 10e-1 [concrete = constants.%float.6da]
// CHECK:STDOUT: %impl.elem0.loc7: %.3a8 = impl_witness_access constants.%ImplicitAs.impl_witness.65d, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.2cd]
// CHECK:STDOUT: %bound_method.loc7_31.1: <bound method> = bound_method %float.loc7, %impl.elem0.loc7 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.1ac]
// CHECK:STDOUT: %specific_fn.loc7: <specific function> = specific_function %impl.elem0.loc7, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc7_31.2: <bound method> = bound_method %float.loc7, %specific_fn.loc7 [concrete = constants.%bound_method.aaa]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc7: init %f32.a26 = call %bound_method.loc7_31.2(%float.loc7) [concrete = constants.%float.2ec]
// CHECK:STDOUT: %.loc7_31.1: %f32.a26 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc7 [concrete = constants.%float.2ec]
// CHECK:STDOUT: %.loc7_31.2: %f32.a26 = converted %float.loc7, %.loc7_31.1 [concrete = constants.%float.2ec]
// CHECK:STDOUT: %Float32ToFloat64.call.loc7: init %f64.b55 = call %Float32ToFloat64.ref.loc7(%.loc7_31.2) [concrete = constants.%float.642]
// CHECK:STDOUT: %Float32ToFloat64.ref.loc8: %Float32ToFloat64.type = name_ref Float32ToFloat64, imports.%Main.Float32ToFloat64 [concrete = constants.%Float32ToFloat64]
// CHECK:STDOUT: %float.loc8: Core.FloatLiteral = float_literal_value 10e29 [concrete = constants.%float.c02]
// CHECK:STDOUT: %impl.elem0.loc8: %.3a8 = impl_witness_access constants.%ImplicitAs.impl_witness.65d, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.2cd]
// CHECK:STDOUT: %bound_method.loc8_31.1: <bound method> = bound_method %float.loc8, %impl.elem0.loc8 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.1c5]
// CHECK:STDOUT: %specific_fn.loc8: <specific function> = specific_function %impl.elem0.loc8, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc8_31.2: <bound method> = bound_method %float.loc8, %specific_fn.loc8 [concrete = constants.%bound_method.dc8]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc8: init %f32.a26 = call %bound_method.loc8_31.2(%float.loc8) [concrete = constants.%float.419]
// CHECK:STDOUT: %.loc8_31.1: %f32.a26 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc8 [concrete = constants.%float.419]
// CHECK:STDOUT: %.loc8_31.2: %f32.a26 = converted %float.loc8, %.loc8_31.1 [concrete = constants.%float.419]
// CHECK:STDOUT: %Float32ToFloat64.call.loc8: init %f64.b55 = call %Float32ToFloat64.ref.loc8(%.loc8_31.2) [concrete = constants.%float.e6a]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -0,0 +1,61 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/primitives.carbon
//
// AUTOUPDATE
// TIP: To test this file alone, run:
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/impl/custom_witness/float_fits_in.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/custom_witness/float_fits_in.carbon
// --- core.carbon
package Core;
interface FloatFitsIn(Dest:! type) {}
fn CheckFitsIn[U:! type, T:! FloatFitsIn(U)](unused t: T, unused u: U) {}
// --- valid.carbon
library "[[@TEST_NAME]]";
import Core;
fn CheckSameSize() {
Core.CheckFitsIn(1.0 as f32, 2.0 as f32);
Core.CheckFitsIn(1.0 as f64, 2.0 as f64);
}
fn CheckOk() {
Core.CheckFitsIn(1.0 as f16, 2.0 as f32);
Core.CheckFitsIn(1.0 as f16, 2.0 as f64);
Core.CheckFitsIn(1.0 as f32, 2.0 as f64);
}
// --- fail_narrowing.carbon
library "[[@TEST_NAME]]";
import Core;
fn CheckFail() {
// CHECK:STDERR: fail_narrowing.carbon:[[@LINE+7]]:3: error: cannot convert type `f64` into type implementing `Core.FloatFitsIn(f32)` [ConversionFailureTypeToFacet]
// CHECK:STDERR: Core.CheckFitsIn(1.0 as f64, 2.0 as f32);
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR: core.carbon:6:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
// CHECK:STDERR: fn CheckFitsIn[U:! type, T:! FloatFitsIn(U)](unused t: T, unused u: U) {}
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
Core.CheckFitsIn(1.0 as f64, 2.0 as f32);
// CHECK:STDERR: fail_narrowing.carbon:[[@LINE+7]]:3: error: cannot convert type `f32` into type implementing `Core.FloatFitsIn(f16)` [ConversionFailureTypeToFacet]
// CHECK:STDERR: Core.CheckFitsIn(1.0 as f32, 2.0 as f16);
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR: core.carbon:6:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
// CHECK:STDERR: fn CheckFitsIn[U:! type, T:! FloatFitsIn(U)](unused t: T, unused u: U) {}
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
Core.CheckFitsIn(1.0 as f32, 2.0 as f16);
}
@@ -24,6 +24,11 @@ library "[[@TEST_NAME]]";
import Core;
fn CheckSameSize() {
Core.CheckFitsIn(1 as i32, 2 as i32);
Core.CheckFitsIn(1 as u32, 2 as u32);
}
fn CheckOk() {
Core.CheckFitsIn(1 as i32, 2 as i64);
Core.CheckFitsIn(1 as u32, 2 as u64);
@@ -111,3 +111,34 @@ fn F(f: f32) {
// CHECK:STDERR:
let _: i32 = f as i32;
}
// --- float_to_float.carbon
library "[[@TEST_NAME]]";
import library "test_helpers";
fn F(x: f32) {
// Implicit conversion (widening f32 -> f64)
let y: f64 = x;
// Explicit conversion (widening f32 -> f64)
let _: f64 = x as f64;
// Explicit conversion (narrowing f64 -> f32)
let _: f32 = y as f32;
}
// --- fail_float_to_float_narrowing.carbon
library "[[@TEST_NAME]]";
fn F(x: f64) {
// Implicit narrowing conversion (f64 -> f32) is not permitted.
// CHECK:STDERR: fail_float_to_float_narrowing.carbon:[[@LINE+7]]:16: error: cannot implicitly convert expression of type `f64` to `f32` [ConversionFailure]
// CHECK:STDERR: let _: f32 = x;
// CHECK:STDERR: ^
// CHECK:STDERR: fail_float_to_float_narrowing.carbon:[[@LINE+4]]:16: note: type `f64` does not implement interface `Core.ImplicitAs(f32)` [MissingImplInMemberAccessInContext]
// CHECK:STDERR: let _: f32 = x;
// CHECK:STDERR: ^
// CHECK:STDERR:
let _: f32 = x;
}
+7
View File
@@ -441,6 +441,13 @@ static auto HandleBuiltinCall(FunctionContext& context, SemIR::InstId inst_id,
: context.builder().CreateUIToFP(operand, dest_type));
return;
}
case SemIR::BuiltinFunctionKind::FloatConvert: {
auto* operand = context.GetValue(arg_ids[0]);
auto* dest_type = context.GetTypeOfInst(inst_id);
context.SetLocal(inst_id,
context.builder().CreateFPCast(operand, dest_type));
return;
}
case SemIR::BuiltinFunctionKind::FloatConvertInt: {
auto* operand = context.GetValue(arg_ids[0]);
auto* dest_type = context.GetTypeOfInst(inst_id);
+75
View File
@@ -0,0 +1,75 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/primitives.carbon
//
// AUTOUPDATE
// TIP: To test this file alone, run:
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lower/testdata/builtins/float_to_float.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/builtins/float_to_float.carbon
// --- float_to_float.carbon
library "[[@TEST_NAME]]";
fn ConvertF32ToF64(a: f32) -> f64 = "float.convert";
fn TestConvertF32ToF64(a: f32) -> f64 { return ConvertF32ToF64(a); }
fn ConvertF64ToF32(a: f64) -> f32 = "float.convert";
fn TestConvertF64ToF32(a: f64) -> f32 { return ConvertF64ToF32(a); }
fn ConvertF16ToF128(a: f16) -> f128 = "float.convert";
fn TestConvertF16ToF128(a: f16) -> f128 { return ConvertF16ToF128(a); }
// CHECK:STDOUT: ; ModuleID = 'float_to_float.carbon'
// CHECK:STDOUT: source_filename = "float_to_float.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define double @_CTestConvertF32ToF64.Main(float %a) #0 !dbg !4 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %ConvertF32ToF64.call = fpext float %a to double, !dbg !10
// CHECK:STDOUT: ret double %ConvertF32ToF64.call, !dbg !11
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define float @_CTestConvertF64ToF32.Main(double %a) #0 !dbg !12 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %ConvertF64ToF32.call = fptrunc double %a to float, !dbg !15
// CHECK:STDOUT: ret float %ConvertF64ToF32.call, !dbg !16
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nounwind
// CHECK:STDOUT: define fp128 @_CTestConvertF16ToF128.Main(half %a) #0 !dbg !17 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %ConvertF16ToF128.call = fpext half %a to fp128, !dbg !20
// CHECK:STDOUT: ret fp128 %ConvertF16ToF128.call, !dbg !21
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: attributes #0 = { nounwind }
// CHECK:STDOUT:
// CHECK:STDOUT: !llvm.module.flags = !{!0, !1}
// CHECK:STDOUT: !llvm.dbg.cu = !{!2}
// CHECK:STDOUT:
// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
// CHECK:STDOUT: !3 = !DIFile(filename: "float_to_float.carbon", directory: "")
// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "TestConvertF32ToF64", linkageName: "_CTestConvertF32ToF64.Main", scope: null, file: !3, line: 4, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !8)
// CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
// CHECK:STDOUT: !6 = !{!7, !7}
// CHECK:STDOUT: !7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
// CHECK:STDOUT: !8 = !{!9}
// CHECK:STDOUT: !9 = !DILocalVariable(arg: 1, scope: !4, type: !7)
// CHECK:STDOUT: !10 = !DILocation(line: 4, column: 48, scope: !4)
// CHECK:STDOUT: !11 = !DILocation(line: 4, column: 41, scope: !4)
// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "TestConvertF64ToF32", linkageName: "_CTestConvertF64ToF32.Main", scope: null, file: !3, line: 7, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !13)
// CHECK:STDOUT: !13 = !{!14}
// CHECK:STDOUT: !14 = !DILocalVariable(arg: 1, scope: !12, type: !7)
// CHECK:STDOUT: !15 = !DILocation(line: 7, column: 48, scope: !12)
// CHECK:STDOUT: !16 = !DILocation(line: 7, column: 41, scope: !12)
// CHECK:STDOUT: !17 = distinct !DISubprogram(name: "TestConvertF16ToF128", linkageName: "_CTestConvertF16ToF128.Main", scope: null, file: !3, line: 10, type: !5, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !18)
// CHECK:STDOUT: !18 = !{!19}
// CHECK:STDOUT: !19 = !DILocalVariable(arg: 1, scope: !17, type: !7)
// CHECK:STDOUT: !20 = !DILocation(line: 10, column: 50, scope: !17)
// CHECK:STDOUT: !21 = !DILocation(line: 10, column: 43, scope: !17)
@@ -702,6 +702,10 @@ constexpr BuiltinInfo FloatDivAssign = {
"float.div_assign",
ValidateSignature<auto(ByRef<SizedFloatT>, SizedFloatT)->NoReturn>};
// Converts between floating-point types, without checking.
constexpr BuiltinInfo FloatConvert = {"float.convert",
ValidateSignature<auto(FloatT)->FloatU>};
// Converts between floating-point types, with a diagnostic if the value doesn't
// fit.
constexpr BuiltinInfo FloatConvertChecked = {
@@ -859,6 +863,7 @@ auto BuiltinFunctionKind::IsCompTimeOnly(const File& sem_ir,
// Checked conversions are compile-time only.
return true;
case FloatConvert:
case FloatConvertInt:
case IntConvert:
case IntConvertChar:
@@ -117,6 +117,7 @@ CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(FloatMulAssign)
CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(FloatDivAssign)
// Float conversion.
CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(FloatConvert)
CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(FloatConvertChecked)
CARBON_SEM_IR_BUILTIN_FUNCTION_KIND(FloatConvertInt)
+1
View File
@@ -24,6 +24,7 @@ CARBON_SEM_IR_CORE_INTERFACE_KIND(CppUnsafeDeref)
CARBON_SEM_IR_CORE_INTERFACE_KIND(Dec)
CARBON_SEM_IR_CORE_INTERFACE_KIND(Default)
CARBON_SEM_IR_CORE_INTERFACE_KIND(Destroy)
CARBON_SEM_IR_CORE_INTERFACE_KIND(FloatFitsIn)
CARBON_SEM_IR_CORE_INTERFACE_KIND(DivAssignWith)
CARBON_SEM_IR_CORE_INTERFACE_KIND(DivWith)
CARBON_SEM_IR_CORE_INTERFACE_KIND(EqWith)