Add support for f16, f64, f128. (#5952)

Generalize the f64 support to support other sizes. Also provide interop
support for `float`, `_Float16`, and `__float128`.

Also lay some groundwork for non-standard floating-point types, though
we don't have any syntax to name them yet.
This commit is contained in:
Richard Smith
2025-08-14 01:14:40 +00:00
committed by GitHub
parent cfe5599144
commit b851e8c423
27 changed files with 826 additions and 379 deletions
+32 -14
View File
@@ -1005,8 +1005,9 @@ static auto MakeFloatTypeResult(Context& context, SemIR::LocId loc_id,
-> SemIR::ConstantId {
auto result = SemIR::FloatType{
.type_id = GetSingletonType(context, SemIR::TypeType::TypeInstId),
.bit_width_id = width_id};
if (!ValidateFloatType(context, loc_id, result)) {
.bit_width_id = width_id,
.float_kind = SemIR::FloatKind::None};
if (!ValidateFloatTypeAndSetKind(context, loc_id, result)) {
return SemIR::ErrorInst::ConstantId;
}
return MakeConstantResult(context, result, phase);
@@ -1078,9 +1079,17 @@ static auto PerformCheckedFloatConvert(Context& context, SemIR::LocId loc_id,
SemIR::InstId arg_id,
SemIR::TypeId dest_type_id)
-> SemIR::ConstantId {
auto dest_type_object_rep_id = context.types().GetObjectRepr(dest_type_id);
CARBON_CHECK(dest_type_object_rep_id.has_value(),
"Conversion to incomplete type");
auto dest_float_type =
context.types().TryGetAs<SemIR::FloatType>(dest_type_object_rep_id);
CARBON_CHECK(dest_float_type || context.types().Is<SemIR::FloatLiteralType>(
dest_type_object_rep_id));
if (auto literal =
context.insts().TryGetAs<SemIR::FloatLiteralValue>(arg_id)) {
if (context.types().Is<SemIR::FloatLiteralType>(dest_type_id)) {
if (!dest_float_type) {
return MakeConstantResult(
context,
SemIR::FloatLiteralValue{.type_id = dest_type_id,
@@ -1105,8 +1114,7 @@ static auto PerformCheckedFloatConvert(Context& context, SemIR::LocId loc_id,
real_value.exponent.toStringSigned(str);
// Convert the string to an APFloat.
// TODO: Compute the fltSemantics from the type.
llvm::APFloat result(llvm::APFloat::IEEEdouble());
llvm::APFloat result(dest_float_type->float_kind.Semantics());
// TODO: The implementation of this conversion effectively converts back to
// APInts, but unfortunately the conversion from integer mantissa and
// exponent in IEEEFloat::roundSignificandWithExponent is not part of the
@@ -1119,27 +1127,37 @@ static auto PerformCheckedFloatConvert(Context& context, SemIR::LocId loc_id,
toString(std::move(error)));
}
if (status.get() & llvm::APFloat::opOverflow) {
CARBON_DIAGNOSTIC(FloatTooLargeForType, Error,
CARBON_DIAGNOSTIC(FloatLiteralTooLargeForType, Error,
"value {0} too large for floating-point type {1}",
RealId, SemIR::TypeId);
context.emitter().Emit(loc_id, FloatTooLargeForType, literal->real_id,
dest_type_id);
context.emitter().Emit(loc_id, FloatLiteralTooLargeForType,
literal->real_id, dest_type_id);
return SemIR::ErrorInst::ConstantId;
}
return MakeFloatResult(context, dest_type_id, std::move(result));
}
// TODO: Perform a conversion if necessary.
if (context.types().Is<SemIR::FloatLiteralType>(dest_type_id)) {
if (!dest_float_type) {
context.TODO(loc_id, "conversion from float to float literal");
return SemIR::ErrorInst::ConstantId;
}
// Convert to the destination float semantics.
auto arg = context.insts().GetAs<SemIR::FloatValue>(arg_id);
return MakeConstantResult(
context,
SemIR::FloatValue{.type_id = dest_type_id, .float_id = arg.float_id},
Phase::Concrete);
llvm::APFloat result = context.floats().Get(arg.float_id);
bool loses_info;
auto status = result.convert(dest_float_type->float_kind.Semantics(),
llvm::APFloat::rmNearestTiesToEven, &loses_info);
if (status & llvm::APFloat::opOverflow) {
CARBON_DIAGNOSTIC(FloatTooLargeForType, Error,
"value {0} too large for floating-point type {1}",
llvm::APFloat, SemIR::TypeId);
context.emitter().Emit(loc_id, FloatTooLargeForType,
context.floats().Get(arg.float_id), dest_type_id);
return SemIR::ErrorInst::ConstantId;
}
return MakeFloatResult(context, dest_type_id, std::move(result));
}
// Issues a diagnostic for a compile-time division by zero.
+1 -1
View File
@@ -205,7 +205,7 @@ auto EvalConstantInst(Context& context, SemIR::FacetAccessType inst)
auto EvalConstantInst(Context& context, SemIR::InstId inst_id,
SemIR::FloatType inst) -> ConstantEvalResult {
return ValidateFloatType(context, SemIR::LocId(inst_id), inst)
return ValidateFloatTypeAndSetKind(context, SemIR::LocId(inst_id), inst)
? ConstantEvalResult::NewSamePhase(inst)
: ConstantEvalResult::Error;
}
+1 -2
View File
@@ -121,8 +121,7 @@ auto HandleParseNode(Context& context, Parse::FloatTypeLiteralId node_id)
-> bool {
auto tok_id = context.parse_tree().node_token(node_id);
auto size_id = context.tokens().GetTypeLiteralSize(tok_id);
auto type_inst_id =
MakeFloatTypeLiteral(context, node_id, SemIR::FloatKind::None, size_id);
auto type_inst_id = MakeFloatTypeLiteral(context, node_id, size_id);
context.node_stack().Push(node_id, type_inst_id);
return true;
}
+10 -9
View File
@@ -1071,15 +1071,16 @@ static auto MapBuiltinType(Context& context, SemIR::LocId loc_id,
return type_expr;
}
// TODO: Handle integer types that map to named aliases.
} else if (type.isDoubleType()) {
// TODO: Handle other floating point types when Carbon supports fN where N
// != 64.
CARBON_CHECK(ast_context.getTypeSize(qual_type) == 64);
CARBON_CHECK(ast_context.hasSameType(qual_type, ast_context.DoubleTy));
return ExprAsType(
context, Parse::NodeId::None,
MakeFloatTypeLiteral(context, Parse::NodeId::None,
SemIR::FloatKind::None, context.ints().Add(64)));
} else if (type.isFloatingPoint()) {
if (type.isFloat16Type() || type.isFloat32Type() || type.isDoubleType() ||
type.isFloat128Type()) {
return ExprAsType(
context, Parse::NodeId::None,
MakeFloatTypeLiteral(
context, Parse::NodeId::None,
context.ints().Add(ast_context.getTypeSize(qual_type))));
}
// TODO: Handle floating-point types that map to named aliases.
}
return {.inst_id = SemIR::TypeInstId::None, .type_id = SemIR::TypeId::None};
+3 -2
View File
@@ -1882,8 +1882,9 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
}
return ResolveAsDeduplicated<SemIR::FloatType>(
resolver,
{.type_id = SemIR::TypeType::TypeId, .bit_width_id = bit_width_id});
resolver, {.type_id = SemIR::TypeType::TypeId,
.bit_width_id = bit_width_id,
.float_kind = inst.float_kind});
}
static auto TryResolveTypedInst(ImportRefResolver& resolver,
+1 -3
View File
@@ -38,9 +38,7 @@ auto MakeIntType(Context& context, Parse::NodeId node_id,
}
auto MakeFloatTypeLiteral(Context& context, Parse::NodeId node_id,
SemIR::FloatKind float_kind, IntId size_id)
-> SemIR::InstId {
CARBON_CHECK(float_kind == SemIR::FloatKind::None);
IntId size_id) -> SemIR::InstId {
auto width_id = MakeIntLiteral(context, node_id, size_id);
auto fn_inst_id = LookupNameInCore(context, node_id, "Float");
return PerformCall(context, node_id, fn_inst_id, {width_id});
+1 -2
View File
@@ -27,8 +27,7 @@ auto MakeIntType(Context& context, Parse::NodeId node_id,
// Forms a floating point type expression for `fN` literal.
auto MakeFloatTypeLiteral(Context& context, Parse::NodeId node_id,
SemIR::FloatKind float_kind, IntId size_id)
-> SemIR::InstId;
IntId size_id) -> SemIR::InstId;
} // namespace Carbon::Check
@@ -30,13 +30,6 @@ library "[[@TEST_NAME]]";
// CHECK:STDERR:
fn NotPtr(a: f64, b: f64) = "float.add_assign";
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: bit width must be 64 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+8]]:24: note: in `f32` used here [ResolvingSpecificHere]
// CHECK:STDERR: fn MixedTypes(a: f64*, b: f32) = "float.add_assign";
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "float.add_assign" [InvalidBuiltinSignature]
// CHECK:STDERR: fn MixedTypes(a: f64*, b: f32) = "float.add_assign";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+163 -206
View File
@@ -37,43 +37,16 @@ fn Float64ToFloat64(a: f64) -> f64 = "float.convert_checked";
fn Float64ToFloatLiteral(a: f64) -> FloatLiteral() = "float.convert_checked";
fn FloatLiteralToFloat64(a: FloatLiteral()) -> f64 = "float.convert_checked";
// --- fail_todo_f32.carbon
// --- f32.carbon
library "[[@TEST_NAME]]";
export import library "literal";
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: bit width must be 64 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_todo_f32.carbon:[[@LINE+8]]:29: note: in `f32` used here [ResolvingSpecificHere]
// CHECK:STDERR: fn Float32ToFloat32(a: f32) -> f32 = "float.convert_checked";
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_todo_f32.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "float.convert_checked" [InvalidBuiltinSignature]
// CHECK:STDERR: fn Float32ToFloat32(a: f32) -> f32 = "float.convert_checked";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
fn Float32ToFloat32(a: f32) -> f32 = "float.convert_checked";
// CHECK:STDERR: fail_todo_f32.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "float.convert_checked" [InvalidBuiltinSignature]
// CHECK:STDERR: fn Float32ToFloatLiteral(a: f32) -> FloatLiteral() = "float.convert_checked";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
fn Float32ToFloatLiteral(a: f32) -> FloatLiteral() = "float.convert_checked";
// CHECK:STDERR: fail_todo_f32.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "float.convert_checked" [InvalidBuiltinSignature]
// CHECK:STDERR: fn FloatLiteralToFloat32(a: FloatLiteral()) -> f32 = "float.convert_checked";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
fn FloatLiteralToFloat32(a: FloatLiteral()) -> f32 = "float.convert_checked";
// CHECK:STDERR: fail_todo_f32.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "float.convert_checked" [InvalidBuiltinSignature]
// CHECK:STDERR: fn Float32ToFloat64(a: f32) -> f64 = "float.convert_checked";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
fn Float32ToFloat64(a: f32) -> f64 = "float.convert_checked";
// CHECK:STDERR: fail_todo_f32.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "float.convert_checked" [InvalidBuiltinSignature]
// CHECK:STDERR: fn Float64ToFloat32(a: f64) -> f32 = "float.convert_checked";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
fn Float64ToFloat32(a: f64) -> f32 = "float.convert_checked";
// --- literal_f64.carbon
@@ -87,19 +60,12 @@ let b: f64 = FloatLiteralToFloat64(1.0);
let c: f64 = FloatLiteralToFloat64(1.0e308);
//@dump-sem-ir-end
// --- fail_todo_literal_f32.carbon
// --- literal_f32.carbon
library "[[@TEST_NAME]]";
import library "f32";
//@dump-sem-ir-begin
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: bit width must be 64 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_todo_literal_f32.carbon:[[@LINE+4]]:8: note: in `f32` used here [ResolvingSpecificHere]
// CHECK:STDERR: let a: f32 = FloatLiteralToFloat32(0.0);
// CHECK:STDERR: ^~~
// CHECK:STDERR:
let a: f32 = FloatLiteralToFloat32(0.0);
let b: f32 = FloatLiteralToFloat32(1.0);
let c: f32 = FloatLiteralToFloat32(1.0e38);
@@ -116,37 +82,23 @@ let b: f64 = Float64ToFloat64(1.0);
let c: f64 = Float64ToFloat64(1.0e308);
//@dump-sem-ir-end
// --- fail_todo_identity_f32.carbon
// --- identity_f32.carbon
library "[[@TEST_NAME]]";
import library "f32";
//@dump-sem-ir-begin
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: bit width must be 64 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_todo_identity_f32.carbon:[[@LINE+4]]:8: note: in `f32` used here [ResolvingSpecificHere]
// CHECK:STDERR: let a: f32 = Float32ToFloat32(0.0);
// CHECK:STDERR: ^~~
// CHECK:STDERR:
let a: f32 = Float32ToFloat32(0.0);
let b: f32 = Float32ToFloat32(1.0);
let c: f32 = Float32ToFloat32(1.0e38);
//@dump-sem-ir-end
// --- fail_todo_truncate.carbon
// --- truncate.carbon
library "[[@TEST_NAME]]";
import library "f32";
//@dump-sem-ir-begin
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: bit width must be 64 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_todo_truncate.carbon:[[@LINE+4]]:8: note: in `f32` used here [ResolvingSpecificHere]
// CHECK:STDERR: let a: f32 = Float64ToFloat32(1.0);
// CHECK:STDERR: ^~~
// CHECK:STDERR:
let a: f32 = Float64ToFloat32(1.0);
//@dump-sem-ir-end
@@ -157,18 +109,17 @@ import library "f32";
import library "f64";
//@dump-sem-ir-begin
// TODO: These should all produce an error that the source value doesn't fit in
// the destination type.
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: bit width must be 64 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_truncate_overflow.carbon:[[@LINE+4]]:8: note: in `f32` used here [ResolvingSpecificHere]
// CHECK:STDERR: fail_truncate_overflow.carbon:[[@LINE+4]]:14: error: value 9.9999999999999994E+38 too large for floating-point type `f32` [FloatTooLargeForType]
// CHECK:STDERR: let a: f32 = Float64ToFloat32(1.0e39);
// CHECK:STDERR: ^~~
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
let a: f32 = Float64ToFloat32(1.0e39);
// CHECK:STDERR: fail_truncate_overflow.carbon:[[@LINE+4]]:14: error: value 10*10^38 too large for floating-point type `f32` [FloatLiteralTooLargeForType]
// CHECK:STDERR: let b: f32 = FloatLiteralToFloat32(1.0e39);
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
let b: f32 = FloatLiteralToFloat32(1.0e39);
// CHECK:STDERR: fail_truncate_overflow.carbon:[[@LINE+4]]:14: error: value 10*10^308 too large for floating-point type `f64` [FloatTooLargeForType]
// CHECK:STDERR: fail_truncate_overflow.carbon:[[@LINE+4]]:14: error: value 10*10^308 too large for floating-point type `f64` [FloatLiteralTooLargeForType]
// CHECK:STDERR: let c: f64 = FloatLiteralToFloat64(1.0e309);
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
@@ -309,17 +260,20 @@ let convert_not_constant: f64 = Float64ToFloat64(not_constant_64);
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_literal_f32.carbon
// CHECK:STDOUT: --- literal_f32.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %f32: type = class_type @Float, @Float(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.201: type = pattern_type %f32 [concrete]
// CHECK:STDOUT: %f32.97e: type = class_type @Float, @Float(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.201: type = pattern_type %f32.97e [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.4db: %f32.97e = float_value 0 [concrete]
// CHECK:STDOUT: %float.674: Core.FloatLiteral = float_literal_value 10e-1 [concrete]
// CHECK:STDOUT: %float.e3b: %f32.97e = float_value 1 [concrete]
// CHECK:STDOUT: %float.516: Core.FloatLiteral = float_literal_value 10e37 [concrete]
// CHECK:STDOUT: %float.520: %f32.97e = float_value 9.99999968E+37 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -330,46 +284,46 @@ let convert_not_constant: f64 = Float64ToFloat64(not_constant_64);
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %a.patt: %pattern_type.201 = binding_pattern a [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc13_8: type = splice_block %f32.loc13 [concrete = constants.%f32] {
// CHECK:STDOUT: %int_32.loc13: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32.loc13: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32]
// CHECK:STDOUT: %.loc6_8: type = splice_block %f32.loc6 [concrete = constants.%f32.97e] {
// CHECK:STDOUT: %int_32.loc6: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32.loc6: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32.97e]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc13_39.1: %f32 = value_of_initializer @__global_init.%FloatLiteralToFloat32.call.loc13
// CHECK:STDOUT: %.loc13_39.2: %f32 = converted @__global_init.%FloatLiteralToFloat32.call.loc13, %.loc13_39.1
// CHECK:STDOUT: %a: %f32 = bind_name a, %.loc13_39.2
// CHECK:STDOUT: %.loc6_39.1: %f32.97e = value_of_initializer @__global_init.%FloatLiteralToFloat32.call.loc6 [concrete = constants.%float.4db]
// CHECK:STDOUT: %.loc6_39.2: %f32.97e = converted @__global_init.%FloatLiteralToFloat32.call.loc6, %.loc6_39.1 [concrete = constants.%float.4db]
// CHECK:STDOUT: %a: %f32.97e = bind_name a, %.loc6_39.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %pattern_type.201 = binding_pattern b [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc14_8: type = splice_block %f32.loc14 [concrete = constants.%f32] {
// CHECK:STDOUT: %int_32.loc14: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32.loc14: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32]
// CHECK:STDOUT: %.loc7_8: type = splice_block %f32.loc7 [concrete = constants.%f32.97e] {
// CHECK:STDOUT: %int_32.loc7: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32.loc7: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32.97e]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc14_39.1: %f32 = value_of_initializer @__global_init.%FloatLiteralToFloat32.call.loc14
// CHECK:STDOUT: %.loc14_39.2: %f32 = converted @__global_init.%FloatLiteralToFloat32.call.loc14, %.loc14_39.1
// CHECK:STDOUT: %b: %f32 = bind_name b, %.loc14_39.2
// CHECK:STDOUT: %.loc7_39.1: %f32.97e = value_of_initializer @__global_init.%FloatLiteralToFloat32.call.loc7 [concrete = constants.%float.e3b]
// CHECK:STDOUT: %.loc7_39.2: %f32.97e = converted @__global_init.%FloatLiteralToFloat32.call.loc7, %.loc7_39.1 [concrete = constants.%float.e3b]
// CHECK:STDOUT: %b: %f32.97e = bind_name b, %.loc7_39.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %c.patt: %pattern_type.201 = binding_pattern c [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc15_8: type = splice_block %f32.loc15 [concrete = constants.%f32] {
// CHECK:STDOUT: %int_32.loc15: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32.loc15: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32]
// CHECK:STDOUT: %.loc8_8: type = splice_block %f32.loc8 [concrete = constants.%f32.97e] {
// CHECK:STDOUT: %int_32.loc8: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32.loc8: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32.97e]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc15_42.1: %f32 = value_of_initializer @__global_init.%FloatLiteralToFloat32.call.loc15
// CHECK:STDOUT: %.loc15_42.2: %f32 = converted @__global_init.%FloatLiteralToFloat32.call.loc15, %.loc15_42.1
// CHECK:STDOUT: %c: %f32 = bind_name c, %.loc15_42.2
// CHECK:STDOUT: %.loc8_42.1: %f32.97e = value_of_initializer @__global_init.%FloatLiteralToFloat32.call.loc8 [concrete = constants.%float.520]
// CHECK:STDOUT: %.loc8_42.2: %f32.97e = converted @__global_init.%FloatLiteralToFloat32.call.loc8, %.loc8_42.1 [concrete = constants.%float.520]
// CHECK:STDOUT: %c: %f32.97e = bind_name c, %.loc8_42.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %FloatLiteralToFloat32.ref.loc13: %FloatLiteralToFloat32.type = name_ref FloatLiteralToFloat32, imports.%Main.FloatLiteralToFloat32 [concrete = constants.%FloatLiteralToFloat32]
// CHECK:STDOUT: %float.loc13: Core.FloatLiteral = float_literal_value 0e-1 [concrete = constants.%float.1f7]
// CHECK:STDOUT: %FloatLiteralToFloat32.call.loc13: init %f32 = call %FloatLiteralToFloat32.ref.loc13(%float.loc13)
// CHECK:STDOUT: %FloatLiteralToFloat32.ref.loc14: %FloatLiteralToFloat32.type = name_ref FloatLiteralToFloat32, imports.%Main.FloatLiteralToFloat32 [concrete = constants.%FloatLiteralToFloat32]
// CHECK:STDOUT: %float.loc14: Core.FloatLiteral = float_literal_value 10e-1 [concrete = constants.%float.674]
// CHECK:STDOUT: %FloatLiteralToFloat32.call.loc14: init %f32 = call %FloatLiteralToFloat32.ref.loc14(%float.loc14)
// CHECK:STDOUT: %FloatLiteralToFloat32.ref.loc15: %FloatLiteralToFloat32.type = name_ref FloatLiteralToFloat32, imports.%Main.FloatLiteralToFloat32 [concrete = constants.%FloatLiteralToFloat32]
// CHECK:STDOUT: %float.loc15: Core.FloatLiteral = float_literal_value 10e37 [concrete = constants.%float.516]
// CHECK:STDOUT: %FloatLiteralToFloat32.call.loc15: init %f32 = call %FloatLiteralToFloat32.ref.loc15(%float.loc15)
// 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.97e = call %FloatLiteralToFloat32.ref.loc6(%float.loc6) [concrete = constants.%float.4db]
// 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.674]
// CHECK:STDOUT: %FloatLiteralToFloat32.call.loc7: init %f32.97e = call %FloatLiteralToFloat32.ref.loc7(%float.loc7) [concrete = constants.%float.e3b]
// 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.516]
// CHECK:STDOUT: %FloatLiteralToFloat32.call.loc8: init %f32.97e = call %FloatLiteralToFloat32.ref.loc8(%float.loc8) [concrete = constants.%float.520]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -480,17 +434,17 @@ let convert_not_constant: f64 = Float64ToFloat64(not_constant_64);
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_identity_f32.carbon
// CHECK:STDOUT: --- identity_f32.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %f32: type = class_type @Float, @Float(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.201: type = pattern_type %f32 [concrete]
// CHECK:STDOUT: %f32.97e: type = class_type @Float, @Float(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.201: type = pattern_type %f32.97e [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.31d: type = facet_type <@ImplicitAs, @ImplicitAs(%f32)> [concrete]
// CHECK:STDOUT: %ImplicitAs.Convert.type.b8c: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%f32) [concrete]
// CHECK:STDOUT: %ImplicitAs.type.31d: type = facet_type <@ImplicitAs, @ImplicitAs(%f32.97e)> [concrete]
// CHECK:STDOUT: %ImplicitAs.Convert.type.b8c: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%f32.97e) [concrete]
// CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.644: type = fn_type @Core.FloatLiteral.as.ImplicitAs.impl.Convert, @Core.FloatLiteral.as.ImplicitAs.impl(%To) [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.b45: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.644 = struct_value () [symbolic]
@@ -502,15 +456,15 @@ let convert_not_constant: f64 = Float64ToFloat64(not_constant_64);
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.b37: <bound method> = bound_method %float.1f7, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.1a3 [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %Core.FloatLiteral.as.ImplicitAs.impl.Convert.1a3, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete]
// CHECK:STDOUT: %bound_method.91e: <bound method> = bound_method %float.1f7, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.540: %f32 = float_value 0 [concrete]
// CHECK:STDOUT: %float.4db: %f32.97e = float_value 0 [concrete]
// CHECK:STDOUT: %float.674: Core.FloatLiteral = float_literal_value 10e-1 [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.6d0: <bound method> = bound_method %float.674, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.1a3 [concrete]
// CHECK:STDOUT: %bound_method.6b4: <bound method> = bound_method %float.674, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.3b9: %f32 = float_value 1 [concrete]
// CHECK:STDOUT: %float.e3b: %f32.97e = float_value 1 [concrete]
// CHECK:STDOUT: %float.516: Core.FloatLiteral = float_literal_value 10e37 [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.dc9: <bound method> = bound_method %float.516, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.1a3 [concrete]
// CHECK:STDOUT: %bound_method.3b8: <bound method> = bound_method %float.516, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.a77: %f32 = float_value 9.9999999999999997E+37 [concrete]
// CHECK:STDOUT: %float.520: %f32.97e = float_value 9.99999968E+37 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -523,76 +477,76 @@ let convert_not_constant: f64 = Float64ToFloat64(not_constant_64);
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %a.patt: %pattern_type.201 = binding_pattern a [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc13_8: type = splice_block %f32.loc13 [concrete = constants.%f32] {
// CHECK:STDOUT: %int_32.loc13: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32.loc13: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32]
// CHECK:STDOUT: %.loc6_8: type = splice_block %f32.loc6 [concrete = constants.%f32.97e] {
// CHECK:STDOUT: %int_32.loc6: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32.loc6: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32.97e]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc13_34.1: %f32 = value_of_initializer @__global_init.%Float32ToFloat32.call.loc13
// CHECK:STDOUT: %.loc13_34.2: %f32 = converted @__global_init.%Float32ToFloat32.call.loc13, %.loc13_34.1
// CHECK:STDOUT: %a: %f32 = bind_name a, %.loc13_34.2
// CHECK:STDOUT: %.loc6_34.1: %f32.97e = value_of_initializer @__global_init.%Float32ToFloat32.call.loc6 [concrete = constants.%float.4db]
// CHECK:STDOUT: %.loc6_34.2: %f32.97e = converted @__global_init.%Float32ToFloat32.call.loc6, %.loc6_34.1 [concrete = constants.%float.4db]
// CHECK:STDOUT: %a: %f32.97e = bind_name a, %.loc6_34.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %pattern_type.201 = binding_pattern b [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc14_8: type = splice_block %f32.loc14 [concrete = constants.%f32] {
// CHECK:STDOUT: %int_32.loc14: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32.loc14: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32]
// CHECK:STDOUT: %.loc7_8: type = splice_block %f32.loc7 [concrete = constants.%f32.97e] {
// CHECK:STDOUT: %int_32.loc7: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32.loc7: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32.97e]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc14_34.1: %f32 = value_of_initializer @__global_init.%Float32ToFloat32.call.loc14
// CHECK:STDOUT: %.loc14_34.2: %f32 = converted @__global_init.%Float32ToFloat32.call.loc14, %.loc14_34.1
// CHECK:STDOUT: %b: %f32 = bind_name b, %.loc14_34.2
// CHECK:STDOUT: %.loc7_34.1: %f32.97e = value_of_initializer @__global_init.%Float32ToFloat32.call.loc7 [concrete = constants.%float.e3b]
// CHECK:STDOUT: %.loc7_34.2: %f32.97e = converted @__global_init.%Float32ToFloat32.call.loc7, %.loc7_34.1 [concrete = constants.%float.e3b]
// CHECK:STDOUT: %b: %f32.97e = bind_name b, %.loc7_34.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %c.patt: %pattern_type.201 = binding_pattern c [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc15_8: type = splice_block %f32.loc15 [concrete = constants.%f32] {
// CHECK:STDOUT: %int_32.loc15: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32.loc15: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32]
// CHECK:STDOUT: %.loc8_8: type = splice_block %f32.loc8 [concrete = constants.%f32.97e] {
// CHECK:STDOUT: %int_32.loc8: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32.loc8: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32.97e]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc15_37.1: %f32 = value_of_initializer @__global_init.%Float32ToFloat32.call.loc15
// CHECK:STDOUT: %.loc15_37.2: %f32 = converted @__global_init.%Float32ToFloat32.call.loc15, %.loc15_37.1
// CHECK:STDOUT: %c: %f32 = bind_name c, %.loc15_37.2
// CHECK:STDOUT: %.loc8_37.1: %f32.97e = value_of_initializer @__global_init.%Float32ToFloat32.call.loc8 [concrete = constants.%float.520]
// CHECK:STDOUT: %.loc8_37.2: %f32.97e = converted @__global_init.%Float32ToFloat32.call.loc8, %.loc8_37.1 [concrete = constants.%float.520]
// CHECK:STDOUT: %c: %f32.97e = bind_name c, %.loc8_37.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Float32ToFloat32.ref.loc13: %Float32ToFloat32.type = name_ref Float32ToFloat32, imports.%Main.Float32ToFloat32 [concrete = constants.%Float32ToFloat32]
// CHECK:STDOUT: %float.loc13: Core.FloatLiteral = float_literal_value 0e-1 [concrete = constants.%float.1f7]
// CHECK:STDOUT: %impl.elem0.loc13: %.a5d = impl_witness_access constants.%ImplicitAs.impl_witness.e3f, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.1a3]
// CHECK:STDOUT: %bound_method.loc13_31.1: <bound method> = bound_method %float.loc13, %impl.elem0.loc13 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.b37]
// CHECK:STDOUT: %specific_fn.loc13: <specific function> = specific_function %impl.elem0.loc13, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc13_31.2: <bound method> = bound_method %float.loc13, %specific_fn.loc13 [concrete = constants.%bound_method.91e]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc13: init %f32 = call %bound_method.loc13_31.2(%float.loc13) [concrete = constants.%float.540]
// CHECK:STDOUT: %.loc13_31.1: %f32 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc13 [concrete = constants.%float.540]
// CHECK:STDOUT: %.loc13_31.2: %f32 = converted %float.loc13, %.loc13_31.1 [concrete = constants.%float.540]
// CHECK:STDOUT: %Float32ToFloat32.call.loc13: init %f32 = call %Float32ToFloat32.ref.loc13(%.loc13_31.2)
// CHECK:STDOUT: %Float32ToFloat32.ref.loc14: %Float32ToFloat32.type = name_ref Float32ToFloat32, imports.%Main.Float32ToFloat32 [concrete = constants.%Float32ToFloat32]
// CHECK:STDOUT: %float.loc14: Core.FloatLiteral = float_literal_value 10e-1 [concrete = constants.%float.674]
// CHECK:STDOUT: %impl.elem0.loc14: %.a5d = impl_witness_access constants.%ImplicitAs.impl_witness.e3f, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.1a3]
// CHECK:STDOUT: %bound_method.loc14_31.1: <bound method> = bound_method %float.loc14, %impl.elem0.loc14 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.6d0]
// CHECK:STDOUT: %specific_fn.loc14: <specific function> = specific_function %impl.elem0.loc14, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc14_31.2: <bound method> = bound_method %float.loc14, %specific_fn.loc14 [concrete = constants.%bound_method.6b4]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc14: init %f32 = call %bound_method.loc14_31.2(%float.loc14) [concrete = constants.%float.3b9]
// CHECK:STDOUT: %.loc14_31.1: %f32 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc14 [concrete = constants.%float.3b9]
// CHECK:STDOUT: %.loc14_31.2: %f32 = converted %float.loc14, %.loc14_31.1 [concrete = constants.%float.3b9]
// CHECK:STDOUT: %Float32ToFloat32.call.loc14: init %f32 = call %Float32ToFloat32.ref.loc14(%.loc14_31.2)
// CHECK:STDOUT: %Float32ToFloat32.ref.loc15: %Float32ToFloat32.type = name_ref Float32ToFloat32, imports.%Main.Float32ToFloat32 [concrete = constants.%Float32ToFloat32]
// CHECK:STDOUT: %float.loc15: Core.FloatLiteral = float_literal_value 10e37 [concrete = constants.%float.516]
// CHECK:STDOUT: %impl.elem0.loc15: %.a5d = impl_witness_access constants.%ImplicitAs.impl_witness.e3f, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.1a3]
// CHECK:STDOUT: %bound_method.loc15_31.1: <bound method> = bound_method %float.loc15, %impl.elem0.loc15 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.dc9]
// CHECK:STDOUT: %specific_fn.loc15: <specific function> = specific_function %impl.elem0.loc15, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc15_31.2: <bound method> = bound_method %float.loc15, %specific_fn.loc15 [concrete = constants.%bound_method.3b8]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc15: init %f32 = call %bound_method.loc15_31.2(%float.loc15) [concrete = constants.%float.a77]
// CHECK:STDOUT: %.loc15_31.1: %f32 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc15 [concrete = constants.%float.a77]
// CHECK:STDOUT: %.loc15_31.2: %f32 = converted %float.loc15, %.loc15_31.1 [concrete = constants.%float.a77]
// CHECK:STDOUT: %Float32ToFloat32.call.loc15: init %f32 = call %Float32ToFloat32.ref.loc15(%.loc15_31.2)
// 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: %.a5d = impl_witness_access constants.%ImplicitAs.impl_witness.e3f, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.1a3]
// 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.b37]
// 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.91e]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc6: init %f32.97e = call %bound_method.loc6_31.2(%float.loc6) [concrete = constants.%float.4db]
// CHECK:STDOUT: %.loc6_31.1: %f32.97e = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc6 [concrete = constants.%float.4db]
// CHECK:STDOUT: %.loc6_31.2: %f32.97e = converted %float.loc6, %.loc6_31.1 [concrete = constants.%float.4db]
// CHECK:STDOUT: %Float32ToFloat32.call.loc6: init %f32.97e = call %Float32ToFloat32.ref.loc6(%.loc6_31.2) [concrete = constants.%float.4db]
// 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.674]
// CHECK:STDOUT: %impl.elem0.loc7: %.a5d = impl_witness_access constants.%ImplicitAs.impl_witness.e3f, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.1a3]
// 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.6d0]
// 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.6b4]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc7: init %f32.97e = call %bound_method.loc7_31.2(%float.loc7) [concrete = constants.%float.e3b]
// CHECK:STDOUT: %.loc7_31.1: %f32.97e = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc7 [concrete = constants.%float.e3b]
// CHECK:STDOUT: %.loc7_31.2: %f32.97e = converted %float.loc7, %.loc7_31.1 [concrete = constants.%float.e3b]
// CHECK:STDOUT: %Float32ToFloat32.call.loc7: init %f32.97e = call %Float32ToFloat32.ref.loc7(%.loc7_31.2) [concrete = constants.%float.e3b]
// 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.516]
// CHECK:STDOUT: %impl.elem0.loc8: %.a5d = impl_witness_access constants.%ImplicitAs.impl_witness.e3f, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.1a3]
// 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.dc9]
// 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.3b8]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc8: init %f32.97e = call %bound_method.loc8_31.2(%float.loc8) [concrete = constants.%float.520]
// CHECK:STDOUT: %.loc8_31.1: %f32.97e = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc8 [concrete = constants.%float.520]
// CHECK:STDOUT: %.loc8_31.2: %f32.97e = converted %float.loc8, %.loc8_31.1 [concrete = constants.%float.520]
// CHECK:STDOUT: %Float32ToFloat32.call.loc8: init %f32.97e = call %Float32ToFloat32.ref.loc8(%.loc8_31.2) [concrete = constants.%float.520]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_truncate.carbon
// CHECK:STDOUT: --- truncate.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %f32: type = class_type @Float, @Float(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.201: type = pattern_type %f32 [concrete]
// CHECK:STDOUT: %f32.97e: type = class_type @Float, @Float(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.201: type = pattern_type %f32.97e [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]
@@ -612,6 +566,7 @@ let convert_not_constant: f64 = Float64ToFloat64(not_constant_64);
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %Core.FloatLiteral.as.ImplicitAs.impl.Convert.a03, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(%int_64) [concrete]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %float.674, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.d20: %f64.d77 = float_value 1 [concrete]
// CHECK:STDOUT: %float.e3b: %f32.97e = float_value 1 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -624,13 +579,13 @@ let convert_not_constant: f64 = Float64ToFloat64(not_constant_64);
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %a.patt: %pattern_type.201 = binding_pattern a [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc13_8: type = splice_block %f32 [concrete = constants.%f32] {
// CHECK:STDOUT: %.loc6_8: type = splice_block %f32 [concrete = constants.%f32.97e] {
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32]
// CHECK:STDOUT: %f32: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32.97e]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc13_34.1: %f32 = value_of_initializer @__global_init.%Float64ToFloat32.call
// CHECK:STDOUT: %.loc13_34.2: %f32 = converted @__global_init.%Float64ToFloat32.call, %.loc13_34.1
// CHECK:STDOUT: %a: %f32 = bind_name a, %.loc13_34.2
// CHECK:STDOUT: %.loc6_34.1: %f32.97e = value_of_initializer @__global_init.%Float64ToFloat32.call [concrete = constants.%float.e3b]
// CHECK:STDOUT: %.loc6_34.2: %f32.97e = converted @__global_init.%Float64ToFloat32.call, %.loc6_34.1 [concrete = constants.%float.e3b]
// CHECK:STDOUT: %a: %f32.97e = bind_name a, %.loc6_34.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
@@ -638,13 +593,13 @@ let convert_not_constant: f64 = Float64ToFloat64(not_constant_64);
// CHECK:STDOUT: %Float64ToFloat32.ref: %Float64ToFloat32.type = name_ref Float64ToFloat32, imports.%Main.Float64ToFloat32 [concrete = constants.%Float64ToFloat32]
// CHECK:STDOUT: %float: Core.FloatLiteral = float_literal_value 10e-1 [concrete = constants.%float.674]
// CHECK:STDOUT: %impl.elem0: %.678 = impl_witness_access constants.%ImplicitAs.impl_witness.857, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.a03]
// CHECK:STDOUT: %bound_method.loc13_31.1: <bound method> = bound_method %float, %impl.elem0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound]
// CHECK:STDOUT: %bound_method.loc6_31.1: <bound method> = bound_method %float, %impl.elem0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(constants.%int_64) [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc13_31.2: <bound method> = bound_method %float, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call: init %f64.d77 = call %bound_method.loc13_31.2(%float) [concrete = constants.%float.d20]
// CHECK:STDOUT: %.loc13_31.1: %f64.d77 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%float.d20]
// CHECK:STDOUT: %.loc13_31.2: %f64.d77 = converted %float, %.loc13_31.1 [concrete = constants.%float.d20]
// CHECK:STDOUT: %Float64ToFloat32.call: init %f32 = call %Float64ToFloat32.ref(%.loc13_31.2)
// CHECK:STDOUT: %bound_method.loc6_31.2: <bound method> = bound_method %float, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call: init %f64.d77 = call %bound_method.loc6_31.2(%float) [concrete = constants.%float.d20]
// CHECK:STDOUT: %.loc6_31.1: %f64.d77 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%float.d20]
// CHECK:STDOUT: %.loc6_31.2: %f64.d77 = converted %float, %.loc6_31.1 [concrete = constants.%float.d20]
// CHECK:STDOUT: %Float64ToFloat32.call: init %f32.97e = call %Float64ToFloat32.ref(%.loc6_31.2) [concrete = constants.%float.e3b]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -652,8 +607,8 @@ let convert_not_constant: f64 = Float64ToFloat64(not_constant_64);
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %f32: type = class_type @Float, @Float(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.201: type = pattern_type %f32 [concrete]
// CHECK:STDOUT: %f32.97e: type = class_type @Float, @Float(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.201: type = pattern_type %f32.97e [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]
@@ -694,53 +649,53 @@ let convert_not_constant: f64 = Float64ToFloat64(not_constant_64);
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %a.patt: %pattern_type.201 = binding_pattern a [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc16_8: type = splice_block %f32.loc16 [concrete = constants.%f32] {
// CHECK:STDOUT: %int_32.loc16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32.loc16: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32]
// CHECK:STDOUT: %.loc11_8: type = splice_block %f32.loc11 [concrete = constants.%f32.97e] {
// CHECK:STDOUT: %int_32.loc11: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32.loc11: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32.97e]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc16_37.1: %f32 = value_of_initializer @__global_init.%Float64ToFloat32.call
// CHECK:STDOUT: %.loc16_37.2: %f32 = converted @__global_init.%Float64ToFloat32.call, %.loc16_37.1
// CHECK:STDOUT: %a: %f32 = bind_name a, %.loc16_37.2
// CHECK:STDOUT: %.loc11_37.1: %f32.97e = value_of_initializer @__global_init.%Float64ToFloat32.call [concrete = <error>]
// CHECK:STDOUT: %.loc11_37.2: %f32.97e = converted @__global_init.%Float64ToFloat32.call, %.loc11_37.1 [concrete = <error>]
// CHECK:STDOUT: %a: %f32.97e = bind_name a, %.loc11_37.2 [concrete = <error>]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %pattern_type.201 = binding_pattern b [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc17_8: type = splice_block %f32.loc17 [concrete = constants.%f32] {
// CHECK:STDOUT: %int_32.loc17: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32.loc17: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32]
// CHECK:STDOUT: %.loc16_8: type = splice_block %f32.loc16 [concrete = constants.%f32.97e] {
// CHECK:STDOUT: %int_32.loc16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32.loc16: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32.97e]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc17_42.1: %f32 = value_of_initializer @__global_init.%FloatLiteralToFloat32.call
// CHECK:STDOUT: %.loc17_42.2: %f32 = converted @__global_init.%FloatLiteralToFloat32.call, %.loc17_42.1
// CHECK:STDOUT: %b: %f32 = bind_name b, %.loc17_42.2
// CHECK:STDOUT: %.loc16_42.1: %f32.97e = value_of_initializer @__global_init.%FloatLiteralToFloat32.call [concrete = <error>]
// CHECK:STDOUT: %.loc16_42.2: %f32.97e = converted @__global_init.%FloatLiteralToFloat32.call, %.loc16_42.1 [concrete = <error>]
// CHECK:STDOUT: %b: %f32.97e = bind_name b, %.loc16_42.2 [concrete = <error>]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %c.patt: %pattern_type.0ae = binding_pattern c [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc22_8: type = splice_block %f64 [concrete = constants.%f64.d77] {
// CHECK:STDOUT: %.loc21_8: type = splice_block %f64 [concrete = constants.%f64.d77] {
// CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete = constants.%int_64]
// CHECK:STDOUT: %f64: type = class_type @Float, @Float(constants.%int_64) [concrete = constants.%f64.d77]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc22_43.1: %f64.d77 = value_of_initializer @__global_init.%FloatLiteralToFloat64.call [concrete = <error>]
// CHECK:STDOUT: %.loc22_43.2: %f64.d77 = converted @__global_init.%FloatLiteralToFloat64.call, %.loc22_43.1 [concrete = <error>]
// CHECK:STDOUT: %c: %f64.d77 = bind_name c, %.loc22_43.2 [concrete = <error>]
// CHECK:STDOUT: %.loc21_43.1: %f64.d77 = value_of_initializer @__global_init.%FloatLiteralToFloat64.call [concrete = <error>]
// CHECK:STDOUT: %.loc21_43.2: %f64.d77 = converted @__global_init.%FloatLiteralToFloat64.call, %.loc21_43.1 [concrete = <error>]
// CHECK:STDOUT: %c: %f64.d77 = bind_name c, %.loc21_43.2 [concrete = <error>]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @__global_init() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Float64ToFloat32.ref: %Float64ToFloat32.type = name_ref Float64ToFloat32, imports.%Main.Float64ToFloat32 [concrete = constants.%Float64ToFloat32]
// CHECK:STDOUT: %float.loc16: Core.FloatLiteral = float_literal_value 10e38 [concrete = constants.%float.bfd691.1]
// CHECK:STDOUT: %float.loc11: Core.FloatLiteral = float_literal_value 10e38 [concrete = constants.%float.bfd691.1]
// CHECK:STDOUT: %impl.elem0: %.678 = impl_witness_access constants.%ImplicitAs.impl_witness.857, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.a03]
// CHECK:STDOUT: %bound_method.loc16_31.1: <bound method> = bound_method %float.loc16, %impl.elem0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound]
// CHECK:STDOUT: %bound_method.loc11_31.1: <bound method> = bound_method %float.loc11, %impl.elem0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(constants.%int_64) [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc16_31.2: <bound method> = bound_method %float.loc16, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call: init %f64.d77 = call %bound_method.loc16_31.2(%float.loc16) [concrete = constants.%float.c37]
// CHECK:STDOUT: %.loc16_31.1: %f64.d77 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%float.c37]
// CHECK:STDOUT: %.loc16_31.2: %f64.d77 = converted %float.loc16, %.loc16_31.1 [concrete = constants.%float.c37]
// CHECK:STDOUT: %Float64ToFloat32.call: init %f32 = call %Float64ToFloat32.ref(%.loc16_31.2)
// CHECK:STDOUT: %bound_method.loc11_31.2: <bound method> = bound_method %float.loc11, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call: init %f64.d77 = call %bound_method.loc11_31.2(%float.loc11) [concrete = constants.%float.c37]
// CHECK:STDOUT: %.loc11_31.1: %f64.d77 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%float.c37]
// CHECK:STDOUT: %.loc11_31.2: %f64.d77 = converted %float.loc11, %.loc11_31.1 [concrete = constants.%float.c37]
// CHECK:STDOUT: %Float64ToFloat32.call: init %f32.97e = call %Float64ToFloat32.ref(%.loc11_31.2) [concrete = <error>]
// CHECK:STDOUT: %FloatLiteralToFloat32.ref: %FloatLiteralToFloat32.type = name_ref FloatLiteralToFloat32, imports.%Main.FloatLiteralToFloat32 [concrete = constants.%FloatLiteralToFloat32]
// CHECK:STDOUT: %float.loc17: Core.FloatLiteral = float_literal_value 10e38 [concrete = constants.%float.bfd691.2]
// CHECK:STDOUT: %FloatLiteralToFloat32.call: init %f32 = call %FloatLiteralToFloat32.ref(%float.loc17)
// CHECK:STDOUT: %float.loc16: Core.FloatLiteral = float_literal_value 10e38 [concrete = constants.%float.bfd691.2]
// CHECK:STDOUT: %FloatLiteralToFloat32.call: init %f32.97e = call %FloatLiteralToFloat32.ref(%float.loc16) [concrete = <error>]
// CHECK:STDOUT: %FloatLiteralToFloat64.ref: %FloatLiteralToFloat64.type = name_ref FloatLiteralToFloat64, imports.%Main.FloatLiteralToFloat64 [concrete = constants.%FloatLiteralToFloat64]
// CHECK:STDOUT: %float.loc22: Core.FloatLiteral = float_literal_value 10e308 [concrete = constants.%float.bb5]
// CHECK:STDOUT: %FloatLiteralToFloat64.call: init %f64.d77 = call %FloatLiteralToFloat64.ref(%float.loc22) [concrete = <error>]
// CHECK:STDOUT: %float.loc21: Core.FloatLiteral = float_literal_value 10e308 [concrete = constants.%float.bb5]
// CHECK:STDOUT: %FloatLiteralToFloat64.call: init %f64.d77 = call %FloatLiteralToFloat64.ref(%float.loc21) [concrete = <error>]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -753,10 +708,10 @@ let convert_not_constant: f64 = Float64ToFloat64(not_constant_64);
// 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: type = class_type @Float, @Float(%int_32) [concrete]
// CHECK:STDOUT: %f32.97e: type = class_type @Float, @Float(%int_32) [concrete]
// CHECK:STDOUT: %float.674: Core.FloatLiteral = float_literal_value 10e-1 [concrete]
// CHECK:STDOUT: %ImplicitAs.type.31d: type = facet_type <@ImplicitAs, @ImplicitAs(%f32)> [concrete]
// CHECK:STDOUT: %ImplicitAs.Convert.type.b8c: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%f32) [concrete]
// CHECK:STDOUT: %ImplicitAs.type.31d: type = facet_type <@ImplicitAs, @ImplicitAs(%f32.97e)> [concrete]
// CHECK:STDOUT: %ImplicitAs.Convert.type.b8c: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%f32.97e) [concrete]
// CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.644: type = fn_type @Core.FloatLiteral.as.ImplicitAs.impl.Convert, @Core.FloatLiteral.as.ImplicitAs.impl(%To) [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.b45: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.644 = struct_value () [symbolic]
@@ -768,11 +723,13 @@ let convert_not_constant: f64 = Float64ToFloat64(not_constant_64);
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.6d0: <bound method> = bound_method %float.674, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.1a3 [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %Core.FloatLiteral.as.ImplicitAs.impl.Convert.1a3, @Core.FloatLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete]
// CHECK:STDOUT: %bound_method.6b4: <bound method> = bound_method %float.674, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.3b9: %f32 = float_value 1 [concrete]
// CHECK:STDOUT: %float.e3b: %f32.97e = float_value 1 [concrete]
// CHECK:STDOUT: %float.d20: %f64.d77 = float_value 1 [concrete]
// CHECK:STDOUT: %float.9bd: Core.FloatLiteral = float_literal_value 10e29 [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.bound.a5c: <bound method> = bound_method %float.9bd, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.1a3 [concrete]
// CHECK:STDOUT: %bound_method.3e4: <bound method> = bound_method %float.9bd, %Core.FloatLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.82f: %f32 = float_value 1.0E+30 [concrete]
// CHECK:STDOUT: %float.7d4: %f32.97e = float_value 1.00000002E+30 [concrete]
// CHECK:STDOUT: %float.6a7: %f64.d77 = float_value 1.0000000150474662E+30 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -789,8 +746,8 @@ let convert_not_constant: f64 = Float64ToFloat64(not_constant_64);
// CHECK:STDOUT: %int_64.loc6: Core.IntLiteral = int_value 64 [concrete = constants.%int_64]
// CHECK:STDOUT: %f64.loc6: type = class_type @Float, @Float(constants.%int_64) [concrete = constants.%f64.d77]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc6_34.1: %f64.d77 = value_of_initializer @__global_init.%Float32ToFloat64.call.loc6
// CHECK:STDOUT: %.loc6_34.2: %f64.d77 = converted @__global_init.%Float32ToFloat64.call.loc6, %.loc6_34.1
// CHECK:STDOUT: %.loc6_34.1: %f64.d77 = value_of_initializer @__global_init.%Float32ToFloat64.call.loc6 [concrete = constants.%float.d20]
// CHECK:STDOUT: %.loc6_34.2: %f64.d77 = converted @__global_init.%Float32ToFloat64.call.loc6, %.loc6_34.1 [concrete = constants.%float.d20]
// CHECK:STDOUT: %a: %f64.d77 = bind_name a, %.loc6_34.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %pattern_type.0ae = binding_pattern b [concrete]
@@ -799,8 +756,8 @@ let convert_not_constant: f64 = Float64ToFloat64(not_constant_64);
// CHECK:STDOUT: %int_64.loc7: Core.IntLiteral = int_value 64 [concrete = constants.%int_64]
// CHECK:STDOUT: %f64.loc7: type = class_type @Float, @Float(constants.%int_64) [concrete = constants.%f64.d77]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc7_37.1: %f64.d77 = value_of_initializer @__global_init.%Float32ToFloat64.call.loc7
// CHECK:STDOUT: %.loc7_37.2: %f64.d77 = converted @__global_init.%Float32ToFloat64.call.loc7, %.loc7_37.1
// CHECK:STDOUT: %.loc7_37.1: %f64.d77 = value_of_initializer @__global_init.%Float32ToFloat64.call.loc7 [concrete = constants.%float.6a7]
// CHECK:STDOUT: %.loc7_37.2: %f64.d77 = converted @__global_init.%Float32ToFloat64.call.loc7, %.loc7_37.1 [concrete = constants.%float.6a7]
// CHECK:STDOUT: %b: %f64.d77 = bind_name b, %.loc7_37.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -812,20 +769,20 @@ let convert_not_constant: f64 = Float64ToFloat64(not_constant_64);
// 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.6d0]
// 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.6b4]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc6: init %f32 = call %bound_method.loc6_31.2(%float.loc6) [concrete = constants.%float.3b9]
// CHECK:STDOUT: %.loc6_31.1: %f32 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc6 [concrete = constants.%float.3b9]
// CHECK:STDOUT: %.loc6_31.2: %f32 = converted %float.loc6, %.loc6_31.1 [concrete = constants.%float.3b9]
// CHECK:STDOUT: %Float32ToFloat64.call.loc6: init %f64.d77 = call %Float32ToFloat64.ref.loc6(%.loc6_31.2)
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc6: init %f32.97e = call %bound_method.loc6_31.2(%float.loc6) [concrete = constants.%float.e3b]
// CHECK:STDOUT: %.loc6_31.1: %f32.97e = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc6 [concrete = constants.%float.e3b]
// CHECK:STDOUT: %.loc6_31.2: %f32.97e = converted %float.loc6, %.loc6_31.1 [concrete = constants.%float.e3b]
// CHECK:STDOUT: %Float32ToFloat64.call.loc6: init %f64.d77 = call %Float32ToFloat64.ref.loc6(%.loc6_31.2) [concrete = constants.%float.d20]
// 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 10e29 [concrete = constants.%float.9bd]
// CHECK:STDOUT: %impl.elem0.loc7: %.a5d = impl_witness_access constants.%ImplicitAs.impl_witness.e3f, element0 [concrete = constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.1a3]
// 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.a5c]
// 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.3e4]
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc7: init %f32 = call %bound_method.loc7_31.2(%float.loc7) [concrete = constants.%float.82f]
// CHECK:STDOUT: %.loc7_31.1: %f32 = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc7 [concrete = constants.%float.82f]
// CHECK:STDOUT: %.loc7_31.2: %f32 = converted %float.loc7, %.loc7_31.1 [concrete = constants.%float.82f]
// CHECK:STDOUT: %Float32ToFloat64.call.loc7: init %f64.d77 = call %Float32ToFloat64.ref.loc7(%.loc7_31.2)
// CHECK:STDOUT: %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc7: init %f32.97e = call %bound_method.loc7_31.2(%float.loc7) [concrete = constants.%float.7d4]
// CHECK:STDOUT: %.loc7_31.1: %f32.97e = value_of_initializer %Core.FloatLiteral.as.ImplicitAs.impl.Convert.call.loc7 [concrete = constants.%float.7d4]
// CHECK:STDOUT: %.loc7_31.2: %f32.97e = converted %float.loc7, %.loc7_31.1 [concrete = constants.%float.7d4]
// CHECK:STDOUT: %Float32ToFloat64.call.loc7: init %f64.d77 = call %Float32ToFloat64.ref.loc7(%.loc7_31.2) [concrete = constants.%float.6a7]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -30,13 +30,6 @@ library "[[@TEST_NAME]]";
// CHECK:STDERR:
fn NotPtr(a: f64, b: f64) = "float.div_assign";
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: bit width must be 64 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+8]]:24: note: in `f32` used here [ResolvingSpecificHere]
// CHECK:STDERR: fn MixedTypes(a: f64*, b: f32) = "float.div_assign";
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "float.div_assign" [InvalidBuiltinSignature]
// CHECK:STDERR: fn MixedTypes(a: f64*, b: f32) = "float.div_assign";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+10 -7
View File
@@ -22,7 +22,10 @@ library "[[@TEST_NAME]]";
import library "types";
var f: Float(64);
var a: Float(16);
var b: Float(32);
var c: Float(64);
var d: Float(128);
fn GetFloat(dyn_size: i32) -> type {
//@dump-sem-ir-begin
@@ -36,7 +39,7 @@ library "[[@TEST_NAME]]";
import library "types";
// CHECK:STDERR: fail_invalid_size.carbon:[[@LINE+4]]:20: error: bit width must be 64 [CompileTimeFloatBitWidth]
// CHECK:STDERR: fail_invalid_size.carbon:[[@LINE+4]]:20: error: unsupported floating-point bit width 931 [CompileTimeFloatBitWidth]
// CHECK:STDERR: var invalid_float: Float(931);
// CHECK:STDERR: ^~~~~~~~~~
// CHECK:STDERR:
@@ -60,8 +63,8 @@ var dyn: Float(dyn_size);
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %Float.type: type = fn_type @Float [concrete]
// CHECK:STDOUT: %Float: %Float.type = struct_value () [concrete]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
// CHECK:STDOUT: %int_32.be0: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32.be0) [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -73,8 +76,8 @@ var dyn: Float(dyn_size);
// CHECK:STDOUT: %Float.ref: %Float.type = name_ref Float, imports.%Main.Float [concrete = constants.%Float]
// CHECK:STDOUT: %dyn_size.ref: %i32 = name_ref dyn_size, %dyn_size
// CHECK:STDOUT: %Float.call: init type = call %Float.ref(%dyn_size.ref)
// CHECK:STDOUT: %.loc10_25.1: type = value_of_initializer %Float.call
// CHECK:STDOUT: %.loc10_25.2: type = converted %Float.call, %.loc10_25.1
// CHECK:STDOUT: return %.loc10_25.2
// CHECK:STDOUT: %.loc13_25.1: type = value_of_initializer %Float.call
// CHECK:STDOUT: %.loc13_25.2: type = converted %Float.call, %.loc13_25.1
// CHECK:STDOUT: return %.loc13_25.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -30,13 +30,6 @@ library "[[@TEST_NAME]]";
// CHECK:STDERR:
fn NotPtr(a: f64, b: f64) = "float.mul_assign";
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: bit width must be 64 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+8]]:24: note: in `f32` used here [ResolvingSpecificHere]
// CHECK:STDERR: fn MixedTypes(a: f64*, b: f32) = "float.mul_assign";
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "float.mul_assign" [InvalidBuiltinSignature]
// CHECK:STDERR: fn MixedTypes(a: f64*, b: f32) = "float.mul_assign";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -30,13 +30,6 @@ library "[[@TEST_NAME]]";
// CHECK:STDERR:
fn NotPtr(a: f64, b: f64) = "float.sub_assign";
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: bit width must be 64 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+8]]:24: note: in `f32` used here [ResolvingSpecificHere]
// CHECK:STDERR: fn MixedTypes(a: f64*, b: f32) = "float.sub_assign";
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_bad_decl.carbon:[[@LINE+4]]:1: error: invalid signature for builtin function "float.sub_assign" [InvalidBuiltinSignature]
// CHECK:STDERR: fn MixedTypes(a: f64*, b: f32) = "float.sub_assign";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+3 -3
View File
@@ -194,8 +194,8 @@ fn G(a: f64) -> Core.IntLiteral() {
// CHECK:STDOUT: %pattern_type.0ae: type = pattern_type %f64.d77 [concrete]
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
// CHECK:STDOUT: %f64.cae: type = float_type %int_64 [concrete]
// CHECK:STDOUT: %complete_type.3f9: <witness> = complete_type_witness %f64.cae [concrete]
// CHECK:STDOUT: %f64.794: type = float_type %int_64, f64 [concrete]
// CHECK:STDOUT: %complete_type.7b9: <witness> = complete_type_witness %f64.794 [concrete]
// CHECK:STDOUT: %F.specific_fn: <specific function> = specific_function %F, @F(%int_64) [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -309,6 +309,6 @@ fn G(a: f64) -> Core.IntLiteral() {
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.0ae
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete => constants.%complete_type.3f9
// CHECK:STDOUT: %require_complete => constants.%complete_type.7b9
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/primitives.carbon
// EXTRA-ARGS: --target=x86_64-linux-gnu
//
// AUTOUPDATE
// TIP: To test this file alone, run:
@@ -357,6 +358,46 @@ fn F() {
//@dump-sem-ir-end
}
// ============================================================================
// _Float16 param
// ============================================================================
// --- float16_param.h
auto foo(_Float16 a) -> void;
// --- import_float16_param.carbon
library "[[@TEST_NAME]]";
import Cpp library "float16_param.h";
fn F() {
//@dump-sem-ir-begin
Cpp.foo(0.8 as f16);
//@dump-sem-ir-end
}
// ============================================================================
// float param
// ============================================================================
// --- float_param.h
auto foo(float a) -> void;
// --- import_float_param.carbon
library "[[@TEST_NAME]]";
import Cpp library "float_param.h";
fn F() {
//@dump-sem-ir-begin
Cpp.foo(0.8 as f32);
//@dump-sem-ir-end
}
// ============================================================================
// double param
// ============================================================================
@@ -377,6 +418,26 @@ fn F() {
//@dump-sem-ir-end
}
// ============================================================================
// __float128 param
// ============================================================================
// --- float128_param.h
auto foo(__float128 a) -> void;
// --- import_float128_param.carbon
library "[[@TEST_NAME]]";
import Cpp library "float128_param.h";
fn F() {
//@dump-sem-ir-begin
Cpp.foo(0.8 as f128);
//@dump-sem-ir-end
}
// ============================================================================
// bool return
// ============================================================================
@@ -1331,6 +1392,156 @@ fn F() {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- import_float16_param.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %int_16: Core.IntLiteral = int_value 16 [concrete]
// CHECK:STDOUT: %f16.a6a: type = class_type @Float, @Float(%int_16) [concrete]
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: %ptr.823: type = ptr_type %f16.a6a [concrete]
// CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete]
// CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete]
// CHECK:STDOUT: %float.c64: Core.FloatLiteral = float_literal_value 8e-1 [concrete]
// CHECK:STDOUT: %As.type.c58: type = facet_type <@As, @As(%f16.a6a)> [concrete]
// CHECK:STDOUT: %As.Convert.type.c23: type = fn_type @As.Convert, @As(%f16.a6a) [concrete]
// CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.type.6a5: type = fn_type @Core.FloatLiteral.as.As.impl.Convert, @Core.FloatLiteral.as.As.impl(%To) [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.6af: %Core.FloatLiteral.as.As.impl.Convert.type.6a5 = struct_value () [symbolic]
// CHECK:STDOUT: %As.impl_witness.bc0: <witness> = impl_witness imports.%As.impl_witness_table, @Core.FloatLiteral.as.As.impl(%int_16) [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.type.f15: type = fn_type @Core.FloatLiteral.as.As.impl.Convert, @Core.FloatLiteral.as.As.impl(%int_16) [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.e2a: %Core.FloatLiteral.as.As.impl.Convert.type.f15 = struct_value () [concrete]
// CHECK:STDOUT: %As.facet: %As.type.c58 = facet_value Core.FloatLiteral, (%As.impl_witness.bc0) [concrete]
// CHECK:STDOUT: %.178: type = fn_type_with_self_type %As.Convert.type.c23, %As.facet [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.bound: <bound method> = bound_method %float.c64, %Core.FloatLiteral.as.As.impl.Convert.e2a [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.specific_fn: <specific function> = specific_function %Core.FloatLiteral.as.As.impl.Convert.e2a, @Core.FloatLiteral.as.As.impl.Convert(%int_16) [concrete]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %float.c64, %Core.FloatLiteral.as.As.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.032: %f16.a6a = float_value 0.7998 [concrete]
// CHECK:STDOUT: %Float.as.Destroy.impl.Op.type.cf1: type = fn_type @Float.as.Destroy.impl.Op, @Float.as.Destroy.impl(%int_16) [concrete]
// CHECK:STDOUT: %Float.as.Destroy.impl.Op.85f: %Float.as.Destroy.impl.Op.type.cf1 = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .foo = %foo.decl
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: %Core.import_ref.2c9: @Core.FloatLiteral.as.As.impl.%Core.FloatLiteral.as.As.impl.Convert.type (%Core.FloatLiteral.as.As.impl.Convert.type.6a5) = import_ref Core//prelude/parts/float, loc20_41, loaded [symbolic = @Core.FloatLiteral.as.As.impl.%Core.FloatLiteral.as.As.impl.Convert (constants.%Core.FloatLiteral.as.As.impl.Convert.6af)]
// CHECK:STDOUT: %As.impl_witness_table = impl_witness_table (%Core.import_ref.2c9), @Core.FloatLiteral.as.As.impl [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
// CHECK:STDOUT: %float: Core.FloatLiteral = float_literal_value 8e-1 [concrete = constants.%float.c64]
// CHECK:STDOUT: %int_16: Core.IntLiteral = int_value 16 [concrete = constants.%int_16]
// CHECK:STDOUT: %f16: type = class_type @Float, @Float(constants.%int_16) [concrete = constants.%f16.a6a]
// CHECK:STDOUT: %impl.elem0: %.178 = impl_witness_access constants.%As.impl_witness.bc0, element0 [concrete = constants.%Core.FloatLiteral.as.As.impl.Convert.e2a]
// CHECK:STDOUT: %bound_method.loc8_15.1: <bound method> = bound_method %float, %impl.elem0 [concrete = constants.%Core.FloatLiteral.as.As.impl.Convert.bound]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Core.FloatLiteral.as.As.impl.Convert(constants.%int_16) [concrete = constants.%Core.FloatLiteral.as.As.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc8_15.2: <bound method> = bound_method %float, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.call: init %f16.a6a = call %bound_method.loc8_15.2(%float) [concrete = constants.%float.032]
// CHECK:STDOUT: %.loc8_15.1: %f16.a6a = value_of_initializer %Core.FloatLiteral.as.As.impl.Convert.call [concrete = constants.%float.032]
// CHECK:STDOUT: %.loc8_15.2: %f16.a6a = converted %float, %.loc8_15.1 [concrete = constants.%float.032]
// CHECK:STDOUT: %.loc8_15.3: ref %f16.a6a = temporary_storage
// CHECK:STDOUT: %.loc8_15.4: ref %f16.a6a = temporary %.loc8_15.3, %.loc8_15.2
// CHECK:STDOUT: %addr.loc8_21: %ptr.823 = addr_of %.loc8_15.4
// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr.loc8_21)
// CHECK:STDOUT: %Float.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc8_15.3, constants.%Float.as.Destroy.impl.Op.85f
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method.loc8_15.3: <bound method> = bound_method %.loc8_15.3, %Float.as.Destroy.impl.Op.specific_fn
// CHECK:STDOUT: %addr.loc8_15: %ptr.823 = addr_of %.loc8_15.3
// CHECK:STDOUT: %Float.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc8_15.3(%addr.loc8_15)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- import_float_param.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %f32.97e: type = class_type @Float, @Float(%int_32) [concrete]
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: %ptr.0bc: type = ptr_type %f32.97e [concrete]
// CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete]
// CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete]
// CHECK:STDOUT: %float.c64: Core.FloatLiteral = float_literal_value 8e-1 [concrete]
// CHECK:STDOUT: %As.type.114: type = facet_type <@As, @As(%f32.97e)> [concrete]
// CHECK:STDOUT: %As.Convert.type.f5e: type = fn_type @As.Convert, @As(%f32.97e) [concrete]
// CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.type.6a5: type = fn_type @Core.FloatLiteral.as.As.impl.Convert, @Core.FloatLiteral.as.As.impl(%To) [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.6af: %Core.FloatLiteral.as.As.impl.Convert.type.6a5 = struct_value () [symbolic]
// CHECK:STDOUT: %As.impl_witness.1e4: <witness> = impl_witness imports.%As.impl_witness_table, @Core.FloatLiteral.as.As.impl(%int_32) [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.type.73e: type = fn_type @Core.FloatLiteral.as.As.impl.Convert, @Core.FloatLiteral.as.As.impl(%int_32) [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.7b2: %Core.FloatLiteral.as.As.impl.Convert.type.73e = struct_value () [concrete]
// CHECK:STDOUT: %As.facet: %As.type.114 = facet_value Core.FloatLiteral, (%As.impl_witness.1e4) [concrete]
// CHECK:STDOUT: %.b33: type = fn_type_with_self_type %As.Convert.type.f5e, %As.facet [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.bound: <bound method> = bound_method %float.c64, %Core.FloatLiteral.as.As.impl.Convert.7b2 [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.specific_fn: <specific function> = specific_function %Core.FloatLiteral.as.As.impl.Convert.7b2, @Core.FloatLiteral.as.As.impl.Convert(%int_32) [concrete]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %float.c64, %Core.FloatLiteral.as.As.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.4cb: %f32.97e = float_value 0.800000011 [concrete]
// CHECK:STDOUT: %Float.as.Destroy.impl.Op.type.1b1: type = fn_type @Float.as.Destroy.impl.Op, @Float.as.Destroy.impl(%int_32) [concrete]
// CHECK:STDOUT: %Float.as.Destroy.impl.Op.199: %Float.as.Destroy.impl.Op.type.1b1 = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .foo = %foo.decl
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: %Core.import_ref.2c9: @Core.FloatLiteral.as.As.impl.%Core.FloatLiteral.as.As.impl.Convert.type (%Core.FloatLiteral.as.As.impl.Convert.type.6a5) = import_ref Core//prelude/parts/float, loc20_41, loaded [symbolic = @Core.FloatLiteral.as.As.impl.%Core.FloatLiteral.as.As.impl.Convert (constants.%Core.FloatLiteral.as.As.impl.Convert.6af)]
// CHECK:STDOUT: %As.impl_witness_table = impl_witness_table (%Core.import_ref.2c9), @Core.FloatLiteral.as.As.impl [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
// CHECK:STDOUT: %float: Core.FloatLiteral = float_literal_value 8e-1 [concrete = constants.%float.c64]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32.97e]
// CHECK:STDOUT: %impl.elem0: %.b33 = impl_witness_access constants.%As.impl_witness.1e4, element0 [concrete = constants.%Core.FloatLiteral.as.As.impl.Convert.7b2]
// CHECK:STDOUT: %bound_method.loc8_15.1: <bound method> = bound_method %float, %impl.elem0 [concrete = constants.%Core.FloatLiteral.as.As.impl.Convert.bound]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Core.FloatLiteral.as.As.impl.Convert(constants.%int_32) [concrete = constants.%Core.FloatLiteral.as.As.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc8_15.2: <bound method> = bound_method %float, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.call: init %f32.97e = call %bound_method.loc8_15.2(%float) [concrete = constants.%float.4cb]
// CHECK:STDOUT: %.loc8_15.1: %f32.97e = value_of_initializer %Core.FloatLiteral.as.As.impl.Convert.call [concrete = constants.%float.4cb]
// CHECK:STDOUT: %.loc8_15.2: %f32.97e = converted %float, %.loc8_15.1 [concrete = constants.%float.4cb]
// CHECK:STDOUT: %.loc8_15.3: ref %f32.97e = temporary_storage
// CHECK:STDOUT: %.loc8_15.4: ref %f32.97e = temporary %.loc8_15.3, %.loc8_15.2
// CHECK:STDOUT: %addr.loc8_21: %ptr.0bc = addr_of %.loc8_15.4
// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr.loc8_21)
// CHECK:STDOUT: %Float.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc8_15.3, constants.%Float.as.Destroy.impl.Op.199
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method.loc8_15.3: <bound method> = bound_method %.loc8_15.3, %Float.as.Destroy.impl.Op.specific_fn
// CHECK:STDOUT: %addr.loc8_15: %ptr.0bc = addr_of %.loc8_15.3
// CHECK:STDOUT: %Float.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc8_15.3(%addr.loc8_15)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- import_double_param.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
@@ -1406,6 +1617,81 @@ fn F() {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- import_float128_param.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %int_128: Core.IntLiteral = int_value 128 [concrete]
// CHECK:STDOUT: %f128.b8c: type = class_type @Float, @Float(%int_128) [concrete]
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: %ptr.402: type = ptr_type %f128.b8c [concrete]
// CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete]
// CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete]
// CHECK:STDOUT: %float.c64: Core.FloatLiteral = float_literal_value 8e-1 [concrete]
// CHECK:STDOUT: %As.type.d2d: type = facet_type <@As, @As(%f128.b8c)> [concrete]
// CHECK:STDOUT: %As.Convert.type.3bf: type = fn_type @As.Convert, @As(%f128.b8c) [concrete]
// CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.type.6a5: type = fn_type @Core.FloatLiteral.as.As.impl.Convert, @Core.FloatLiteral.as.As.impl(%To) [symbolic]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.6af: %Core.FloatLiteral.as.As.impl.Convert.type.6a5 = struct_value () [symbolic]
// CHECK:STDOUT: %As.impl_witness.8a8: <witness> = impl_witness imports.%As.impl_witness_table, @Core.FloatLiteral.as.As.impl(%int_128) [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.type.22a: type = fn_type @Core.FloatLiteral.as.As.impl.Convert, @Core.FloatLiteral.as.As.impl(%int_128) [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.e57: %Core.FloatLiteral.as.As.impl.Convert.type.22a = struct_value () [concrete]
// CHECK:STDOUT: %As.facet: %As.type.d2d = facet_value Core.FloatLiteral, (%As.impl_witness.8a8) [concrete]
// CHECK:STDOUT: %.df5: type = fn_type_with_self_type %As.Convert.type.3bf, %As.facet [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.bound: <bound method> = bound_method %float.c64, %Core.FloatLiteral.as.As.impl.Convert.e57 [concrete]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.specific_fn: <specific function> = specific_function %Core.FloatLiteral.as.As.impl.Convert.e57, @Core.FloatLiteral.as.As.impl.Convert(%int_128) [concrete]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %float.c64, %Core.FloatLiteral.as.As.impl.Convert.specific_fn [concrete]
// CHECK:STDOUT: %float.709: %f128.b8c = float_value 0.800000000000000000000000000000000039 [concrete]
// CHECK:STDOUT: %Float.as.Destroy.impl.Op.type.0e0: type = fn_type @Float.as.Destroy.impl.Op, @Float.as.Destroy.impl(%int_128) [concrete]
// CHECK:STDOUT: %Float.as.Destroy.impl.Op.052: %Float.as.Destroy.impl.Op.type.0e0 = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .foo = %foo.decl
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: %Core.import_ref.2c9: @Core.FloatLiteral.as.As.impl.%Core.FloatLiteral.as.As.impl.Convert.type (%Core.FloatLiteral.as.As.impl.Convert.type.6a5) = import_ref Core//prelude/parts/float, loc20_41, loaded [symbolic = @Core.FloatLiteral.as.As.impl.%Core.FloatLiteral.as.As.impl.Convert (constants.%Core.FloatLiteral.as.As.impl.Convert.6af)]
// CHECK:STDOUT: %As.impl_witness_table = impl_witness_table (%Core.import_ref.2c9), @Core.FloatLiteral.as.As.impl [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
// CHECK:STDOUT: %float: Core.FloatLiteral = float_literal_value 8e-1 [concrete = constants.%float.c64]
// CHECK:STDOUT: %int_128: Core.IntLiteral = int_value 128 [concrete = constants.%int_128]
// CHECK:STDOUT: %f128: type = class_type @Float, @Float(constants.%int_128) [concrete = constants.%f128.b8c]
// CHECK:STDOUT: %impl.elem0: %.df5 = impl_witness_access constants.%As.impl_witness.8a8, element0 [concrete = constants.%Core.FloatLiteral.as.As.impl.Convert.e57]
// CHECK:STDOUT: %bound_method.loc8_15.1: <bound method> = bound_method %float, %impl.elem0 [concrete = constants.%Core.FloatLiteral.as.As.impl.Convert.bound]
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Core.FloatLiteral.as.As.impl.Convert(constants.%int_128) [concrete = constants.%Core.FloatLiteral.as.As.impl.Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc8_15.2: <bound method> = bound_method %float, %specific_fn [concrete = constants.%bound_method]
// CHECK:STDOUT: %Core.FloatLiteral.as.As.impl.Convert.call: init %f128.b8c = call %bound_method.loc8_15.2(%float) [concrete = constants.%float.709]
// CHECK:STDOUT: %.loc8_15.1: %f128.b8c = value_of_initializer %Core.FloatLiteral.as.As.impl.Convert.call [concrete = constants.%float.709]
// CHECK:STDOUT: %.loc8_15.2: %f128.b8c = converted %float, %.loc8_15.1 [concrete = constants.%float.709]
// CHECK:STDOUT: %.loc8_15.3: ref %f128.b8c = temporary_storage
// CHECK:STDOUT: %.loc8_15.4: ref %f128.b8c = temporary %.loc8_15.3, %.loc8_15.2
// CHECK:STDOUT: %addr.loc8_22: %ptr.402 = addr_of %.loc8_15.4
// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr.loc8_22)
// CHECK:STDOUT: %Float.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc8_15.3, constants.%Float.as.Destroy.impl.Op.052
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method.loc8_15.3: <bound method> = bound_method %.loc8_15.3, %Float.as.Destroy.impl.Op.specific_fn
// CHECK:STDOUT: %addr.loc8_15: %ptr.402 = addr_of %.loc8_15.3
// CHECK:STDOUT: %Float.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc8_15.3(%addr.loc8_15)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- import_bool_return.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
@@ -16,7 +16,7 @@
// --- unsupported_primitive_type.h
auto foo(float a) -> void;
auto foo(_BitInt(23) a) -> void;
// --- fail_todo_import_unsupported_primitive_type.carbon
@@ -26,14 +26,14 @@ import Cpp library "unsupported_primitive_type.h";
fn F() {
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_import_unsupported_primitive_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: parameter type: float` [SemanticsTodo]
// CHECK:STDERR: Cpp.foo(1.1);
// CHECK:STDERR: fail_todo_import_unsupported_primitive_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: parameter type: _BitInt(23)` [SemanticsTodo]
// CHECK:STDERR: Cpp.foo(11);
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR: fail_todo_import_unsupported_primitive_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
// CHECK:STDERR: Cpp.foo(1.1);
// CHECK:STDERR: Cpp.foo(11);
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
Cpp.foo(1.1);
Cpp.foo(11);
//@dump-sem-ir-end
}
@@ -43,7 +43,7 @@ fn F() {
// --- unsupported_primitive_type_among_params.h
auto foo(int a, float b) -> void;
auto foo(int a, _BitInt(23) b) -> void;
// --- fail_todo_import_unsupported_primitive_type_among_params.carbon
@@ -53,21 +53,21 @@ import Cpp library "unsupported_primitive_type_among_params.h";
fn F() {
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_import_unsupported_primitive_type_among_params.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: parameter type: float` [SemanticsTodo]
// CHECK:STDERR: Cpp.foo(1, 2.0);
// CHECK:STDERR: fail_todo_import_unsupported_primitive_type_among_params.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: parameter type: _BitInt(23)` [SemanticsTodo]
// CHECK:STDERR: Cpp.foo(1, 20);
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR: fail_todo_import_unsupported_primitive_type_among_params.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
// CHECK:STDERR: Cpp.foo(1, 2.0);
// CHECK:STDERR: Cpp.foo(1, 20);
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
Cpp.foo(1, 2.0);
Cpp.foo(1, 20);
//@dump-sem-ir-end
}
// CHECK:STDOUT: --- fail_todo_import_unsupported_primitive_type.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %float: Core.FloatLiteral = float_literal_value 11e-1 [concrete]
// CHECK:STDOUT: %int_11: Core.IntLiteral = int_value 11 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -81,7 +81,7 @@ fn F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %foo.ref: <error> = name_ref foo, <error> [concrete = <error>]
// CHECK:STDOUT: %float: Core.FloatLiteral = float_literal_value 11e-1 [concrete = constants.%float]
// CHECK:STDOUT: %int_11: Core.IntLiteral = int_value 11 [concrete = constants.%int_11]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -89,7 +89,7 @@ fn F() {
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete]
// CHECK:STDOUT: %float: Core.FloatLiteral = float_literal_value 20e-1 [concrete]
// CHECK:STDOUT: %int_20: Core.IntLiteral = int_value 20 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -104,7 +104,7 @@ fn F() {
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %foo.ref: <error> = name_ref foo, <error> [concrete = <error>]
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1]
// CHECK:STDOUT: %float: Core.FloatLiteral = float_literal_value 20e-1 [concrete = constants.%float]
// CHECK:STDOUT: %int_20: Core.IntLiteral = int_value 20 [concrete = constants.%int_20]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -92,7 +92,7 @@ let max_rounds_down_hex: f64 = 0x1.FFFFFFFFFFFFF7FFFFFFFFFFp+1023;
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_overflow_very_large_mantissa.carbon:[[@LINE+4]]:22: error: value 399999999999999999999999999999999999999999999999999999999999999999999990*10^237 too large for floating-point type `f64` [FloatTooLargeForType]
// CHECK:STDERR: fail_overflow_very_large_mantissa.carbon:[[@LINE+4]]:22: error: value 399999999999999999999999999999999999999999999999999999999999999999999990*10^237 too large for floating-point type `f64` [FloatLiteralTooLargeForType]
// CHECK:STDERR: let too_large: f64 = 39999999999999999999999999999999999999999999999999999999999999999999999.0e238;
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
@@ -105,19 +105,19 @@ let max_plus_one: f64 = 17976931348623157081452742373170435679807056752584499659
let max_plus_a_bit_hex: f64 = 0x1.FFFFFFFFFFFFF00000000000000000000001p+1023;
// The smallest number that would round to having an over-large exponent.
// CHECK:STDERR: fail_overflow_very_large_mantissa.carbon:[[@LINE+4]]:30: error: value 1797693134862315807937289714053034150799341327100378269361737789804449682927647509466490179775872070963302864166928879109465555478519404026306574886715058206819089020007083836762738548458177115317644757302700698555713669596228429148198608349364752927190741684443655107043427115596995080930428801779041744977920*10^-1 too large for floating-point type `f64` [FloatTooLargeForType]
// CHECK:STDERR: fail_overflow_very_large_mantissa.carbon:[[@LINE+4]]:30: error: value 1797693134862315807937289714053034150799341327100378269361737789804449682927647509466490179775872070963302864166928879109465555478519404026306574886715058206819089020007083836762738548458177115317644757302700698555713669596228429148198608349364752927190741684443655107043427115596995080930428801779041744977920*10^-1 too large for floating-point type `f64` [FloatLiteralTooLargeForType]
// CHECK:STDERR: let min_rounds_to_inf: f64 = 179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497792.0;
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
let min_rounds_to_inf: f64 = 179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497792.0;
// CHECK:STDERR: fail_overflow_very_large_mantissa.carbon:[[@LINE+4]]:41: error: value 179769313486231580793728971405303415079934132710037826936173778980444969*10^237 too large for floating-point type `f64` [FloatTooLargeForType]
// CHECK:STDERR: fail_overflow_very_large_mantissa.carbon:[[@LINE+4]]:41: error: value 179769313486231580793728971405303415079934132710037826936173778980444969*10^237 too large for floating-point type `f64` [FloatLiteralTooLargeForType]
// CHECK:STDERR: let min_rounds_to_inf_rounded_up: f64 = 17976931348623158079372897140530341507993413271003782693617377898044496.9e238;
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
let min_rounds_to_inf_rounded_up: f64 = 17976931348623158079372897140530341507993413271003782693617377898044496.9e238;
// CHECK:STDERR: fail_overflow_very_large_mantissa.carbon:[[@LINE+4]]:34: error: value 144115188075855864*2^967 too large for floating-point type `f64` [FloatTooLargeForType]
// CHECK:STDERR: fail_overflow_very_large_mantissa.carbon:[[@LINE+4]]:34: error: value 144115188075855864*2^967 too large for floating-point type `f64` [FloatLiteralTooLargeForType]
// CHECK:STDERR: let min_rounds_to_inf_hex: f64 = 0x1.FFFFFFFFFFFFF8p+1023;
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
@@ -127,7 +127,7 @@ let min_rounds_to_inf_hex: f64 = 0x1.FFFFFFFFFFFFF8p+1023;
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_overflow_very_large_exponent.carbon:[[@LINE+4]]:14: error: value 50*10^39999999999999999992 too large for floating-point type `f64` [FloatTooLargeForType]
// CHECK:STDERR: fail_overflow_very_large_exponent.carbon:[[@LINE+4]]:14: error: value 50*10^39999999999999999992 too large for floating-point type `f64` [FloatLiteralTooLargeForType]
// CHECK:STDERR: let e: f64 = 5.0e39999999999999999993;
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
+56 -34
View File
@@ -34,37 +34,11 @@ var test_u64: u64;
library "[[@TEST_NAME]]";
//@dump-sem-ir-begin
var test_f64: f64;
//@dump-sem-ir-end
// --- fail_todo_fN_unsupported.carbon
library "[[@TEST_NAME]]";
// TODO: Some or all of these should eventually work.
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: bit width must be 64 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_todo_fN_unsupported.carbon:[[@LINE+4]]:15: note: in `f16` used here [ResolvingSpecificHere]
// CHECK:STDERR: var test_f16: f16;
// CHECK:STDERR: ^~~
// CHECK:STDERR:
var test_f16: f16;
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: bit width must be 64 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_todo_fN_unsupported.carbon:[[@LINE+4]]:15: note: in `f32` used here [ResolvingSpecificHere]
// CHECK:STDERR: var test_f32: f32;
// CHECK:STDERR: ^~~
// CHECK:STDERR:
var test_f32: f32;
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: bit width must be 64 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_todo_fN_unsupported.carbon:[[@LINE+4]]:16: note: in `f128` used here [ResolvingSpecificHere]
// CHECK:STDERR: var test_f128: f128;
// CHECK:STDERR: ^~~~
// CHECK:STDERR:
var test_f64: f64;
var test_f128: f128;
//@dump-sem-ir-end
// --- string.carbon
@@ -164,7 +138,7 @@ library "[[@TEST_NAME]]";
// CHECK:STDERR: ^~
// CHECK:STDERR:
var test_f0: f0;
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: bit width must be 64 [CompileTimeFloatBitWidth]
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: unsupported floating-point bit width 1 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_fN_bad_width.carbon:[[@LINE+4]]:14: note: in `f1` used here [ResolvingSpecificHere]
@@ -172,7 +146,7 @@ var test_f0: f0;
// CHECK:STDERR: ^~
// CHECK:STDERR:
var test_f1: f1;
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: bit width must be 64 [CompileTimeFloatBitWidth]
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: unsupported floating-point bit width 15 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_fN_bad_width.carbon:[[@LINE+4]]:15: note: in `f15` used here [ResolvingSpecificHere]
@@ -180,7 +154,16 @@ var test_f1: f1;
// CHECK:STDERR: ^~~
// CHECK:STDERR:
var test_f15: f15;
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: bit width must be 64 [CompileTimeFloatBitWidth]
// TODO: Decide if we want to expose the x87 80-bit floating point type this way.
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: unsupported floating-point bit width 80 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_fN_bad_width.carbon:[[@LINE+4]]:15: note: in `f80` used here [ResolvingSpecificHere]
// CHECK:STDERR: var test_f80: f80;
// CHECK:STDERR: ^~~
// CHECK:STDERR:
var test_f80: f80;
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: unsupported floating-point bit width 100 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_fN_bad_width.carbon:[[@LINE+4]]:16: note: in `f100` used here [ResolvingSpecificHere]
@@ -188,7 +171,7 @@ var test_f15: f15;
// CHECK:STDERR: ^~~~
// CHECK:STDERR:
var test_f100: f100;
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: bit width must be 64 [CompileTimeFloatBitWidth]
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: unsupported floating-point bit width 1000000000 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_fN_bad_width.carbon:[[@LINE+4]]:23: note: in `f1000000000` used here [ResolvingSpecificHere]
@@ -196,7 +179,7 @@ var test_f100: f100;
// CHECK:STDERR: ^~~~~~~~~~~
// CHECK:STDERR:
var test_f1000000000: f1000000000;
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: bit width must be 64 [CompileTimeFloatBitWidth]
// CHECK:STDERR: min_prelude/parts/float.carbon:11:9: error: unsupported floating-point bit width 1000000000000 [CompileTimeFloatBitWidth]
// CHECK:STDERR: adapt MakeFloat(N);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_fN_bad_width.carbon:[[@LINE+4]]:26: note: in `f1000000000000` used here [ResolvingSpecificHere]
@@ -347,9 +330,18 @@ var x: type = 42;
// CHECK:STDOUT: --- fN.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %int_16: Core.IntLiteral = int_value 16 [concrete]
// CHECK:STDOUT: %f16.a6a: type = class_type @Float, @Float(%int_16) [concrete]
// CHECK:STDOUT: %pattern_type.cd1: type = pattern_type %f16.a6a [concrete]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %f32.97e: type = class_type @Float, @Float(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.201: type = pattern_type %f32.97e [concrete]
// CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete]
// CHECK:STDOUT: %f64.d77: type = class_type @Float, @Float(%int_64) [concrete]
// CHECK:STDOUT: %pattern_type.0ae: type = pattern_type %f64.d77 [concrete]
// CHECK:STDOUT: %int_128: Core.IntLiteral = int_value 128 [concrete]
// CHECK:STDOUT: %f128.b8c: type = class_type @Float, @Float(%int_128) [concrete]
// CHECK:STDOUT: %pattern_type.22c: type = pattern_type %f128.b8c [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -357,15 +349,45 @@ var x: type = 42;
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %test_f16.patt: %pattern_type.cd1 = binding_pattern test_f16 [concrete]
// CHECK:STDOUT: %test_f16.var_patt: %pattern_type.cd1 = var_pattern %test_f16.patt [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %test_f16.var: ref %f16.a6a = var %test_f16.var_patt [concrete]
// CHECK:STDOUT: %.loc4: type = splice_block %f16 [concrete = constants.%f16.a6a] {
// CHECK:STDOUT: %int_16: Core.IntLiteral = int_value 16 [concrete = constants.%int_16]
// CHECK:STDOUT: %f16: type = class_type @Float, @Float(constants.%int_16) [concrete = constants.%f16.a6a]
// CHECK:STDOUT: }
// CHECK:STDOUT: %test_f16: ref %f16.a6a = bind_name test_f16, %test_f16.var [concrete = %test_f16.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %test_f32.patt: %pattern_type.201 = binding_pattern test_f32 [concrete]
// CHECK:STDOUT: %test_f32.var_patt: %pattern_type.201 = var_pattern %test_f32.patt [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %test_f32.var: ref %f32.97e = var %test_f32.var_patt [concrete]
// CHECK:STDOUT: %.loc5: type = splice_block %f32 [concrete = constants.%f32.97e] {
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %f32: type = class_type @Float, @Float(constants.%int_32) [concrete = constants.%f32.97e]
// CHECK:STDOUT: }
// CHECK:STDOUT: %test_f32: ref %f32.97e = bind_name test_f32, %test_f32.var [concrete = %test_f32.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %test_f64.patt: %pattern_type.0ae = binding_pattern test_f64 [concrete]
// CHECK:STDOUT: %test_f64.var_patt: %pattern_type.0ae = var_pattern %test_f64.patt [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %test_f64.var: ref %f64.d77 = var %test_f64.var_patt [concrete]
// CHECK:STDOUT: %.loc4: type = splice_block %f64 [concrete = constants.%f64.d77] {
// CHECK:STDOUT: %.loc6: type = splice_block %f64 [concrete = constants.%f64.d77] {
// CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete = constants.%int_64]
// CHECK:STDOUT: %f64: type = class_type @Float, @Float(constants.%int_64) [concrete = constants.%f64.d77]
// CHECK:STDOUT: }
// CHECK:STDOUT: %test_f64: ref %f64.d77 = bind_name test_f64, %test_f64.var [concrete = %test_f64.var]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %test_f128.patt: %pattern_type.22c = binding_pattern test_f128 [concrete]
// CHECK:STDOUT: %test_f128.var_patt: %pattern_type.22c = var_pattern %test_f128.patt [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %test_f128.var: ref %f128.b8c = var %test_f128.var_patt [concrete]
// CHECK:STDOUT: %.loc7: type = splice_block %f128 [concrete = constants.%f128.b8c] {
// CHECK:STDOUT: %int_128: Core.IntLiteral = int_value 128 [concrete = constants.%int_128]
// CHECK:STDOUT: %f128: type = class_type @Float, @Float(constants.%int_128) [concrete = constants.%f128.b8c]
// CHECK:STDOUT: }
// CHECK:STDOUT: %test_f128: ref %f128.b8c = bind_name test_f128, %test_f128.var [concrete = %test_f128.var]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- string.carbon
+46 -21
View File
@@ -8,10 +8,10 @@
#include "toolchain/check/facet_type.h"
#include "toolchain/check/type_completion.h"
#include "toolchain/sem_ir/facet_type_info.h"
#include "toolchain/sem_ir/ids.h"
namespace Carbon::Check {
// Enforces that an integer type has a valid bit width.
auto ValidateIntType(Context& context, SemIR::LocId loc_id,
SemIR::IntType result) -> bool {
auto bit_width =
@@ -44,29 +44,54 @@ auto ValidateIntType(Context& context, SemIR::LocId loc_id,
return true;
}
// Enforces that the bit width is 64 for a float.
auto ValidateFloatBitWidth(Context& context, SemIR::LocId loc_id,
SemIR::InstId inst_id) -> bool {
auto inst = context.insts().GetAs<SemIR::IntValue>(inst_id);
if (context.ints().Get(inst.int_id) == 64) {
return true;
}
CARBON_DIAGNOSTIC(CompileTimeFloatBitWidth, Error, "bit width must be 64");
context.emitter().Emit(loc_id, CompileTimeFloatBitWidth);
return false;
}
// Enforces that a float type has a valid bit width.
auto ValidateFloatType(Context& context, SemIR::LocId loc_id,
SemIR::FloatType result) -> bool {
auto bit_width =
auto ValidateFloatTypeAndSetKind(Context& context, SemIR::LocId loc_id,
SemIR::FloatType& result) -> bool {
// Get the bit width value.
auto bit_width_inst =
context.insts().TryGetAs<SemIR::IntValue>(result.bit_width_id);
if (!bit_width) {
// Symbolic bit width.
if (!bit_width_inst) {
// Symbolic bit width. Defer checking until we have a concrete value.
return true;
}
return ValidateFloatBitWidth(context, loc_id, result.bit_width_id);
auto bit_width = context.ints().Get(bit_width_inst->int_id);
// If no kind is specified, infer kind from width.
if (!result.float_kind.has_value()) {
switch (bit_width.getLimitedValue()) {
case 16:
result.float_kind = SemIR::FloatKind::Binary16;
break;
case 32:
result.float_kind = SemIR::FloatKind::Binary32;
break;
case 64:
result.float_kind = SemIR::FloatKind::Binary64;
break;
case 128:
result.float_kind = SemIR::FloatKind::Binary128;
break;
default:
CARBON_DIAGNOSTIC(CompileTimeFloatBitWidth, Error,
"unsupported floating-point bit width {0}", TypedInt);
context.emitter().Emit(loc_id, CompileTimeFloatBitWidth,
TypedInt(bit_width_inst->type_id, bit_width));
return false;
}
}
if (llvm::APFloat::semanticsSizeInBits(result.float_kind.Semantics()) !=
bit_width) {
// This can't currently happen because we don't provide any way to set the
// float kind other than through the bit width.
// TODO: Add a float_type.make builtin that takes a float kind, and add a
// diagnostic here if the size is wrong.
context.TODO(loc_id, "wrong size for float type");
return false;
}
// TODO: Diagnose if the floating-point type is not supported on this target?
return true;
}
// Gets or forms a type_id for a type, given the instruction kind and arguments.
+4 -7
View File
@@ -15,13 +15,10 @@ namespace Carbon::Check {
auto ValidateIntType(Context& context, SemIR::LocId loc_id,
SemIR::IntType result) -> bool;
// Enforces that the bit width is 64 for a float.
auto ValidateFloatBitWidth(Context& context, SemIR::LocId loc_id,
SemIR::InstId inst_id) -> bool;
// Enforces that a float type has a valid bit width.
auto ValidateFloatType(Context& context, SemIR::LocId loc_id,
SemIR::FloatType result) -> bool;
// Enforces that a float type has a valid bit width. If the `float_kind` field
// is `None`, sets it to a suitable kind for the bit width.
auto ValidateFloatTypeAndSetKind(Context& context, SemIR::LocId loc_id,
SemIR::FloatType& result) -> bool;
// Gets the type to use for an unbound associated entity declared in this
// interface. For example, this is the type of `I.T` after
@@ -423,6 +423,7 @@ CARBON_DIAGNOSTIC_KIND(IncompleteTypeInValueConversion)
CARBON_DIAGNOSTIC_KIND(InCopy)
CARBON_DIAGNOSTIC_KIND(CharTooLargeForType)
CARBON_DIAGNOSTIC_KIND(IntTooLargeForType)
CARBON_DIAGNOSTIC_KIND(FloatLiteralTooLargeForType)
CARBON_DIAGNOSTIC_KIND(FloatTooLargeForType)
CARBON_DIAGNOSTIC_KIND(IntWidthNotMultipleOf8)
CARBON_DIAGNOSTIC_KIND(IntWidthNotPositive)
+3 -3
View File
@@ -794,10 +794,10 @@ static auto BuildTypeForInst(FileContext& /*context*/,
return nullptr;
}
static auto BuildTypeForInst(FileContext& context, SemIR::FloatType /*inst*/)
static auto BuildTypeForInst(FileContext& context, SemIR::FloatType inst)
-> llvm::Type* {
// TODO: Handle different sizes.
return llvm::Type::getDoubleTy(context.llvm_context());
return llvm::Type::getFloatingPointTy(context.llvm_context(),
inst.float_kind.Semantics());
}
static auto BuildTypeForInst(FileContext& context, SemIR::IntType inst)
+64
View File
@@ -63,6 +63,22 @@ fn TestMul(a: f64*, b: f64) { Mul(a, b); }
fn Div(a: f64*, b: f64) = "float.div_assign";
fn TestDiv(a: f64*, b: f64) { Div(a, b); }
// --- types.carbon
library "[[@TEST_NAME]]";
fn F16(a: f16, b: f16) -> f16 = "float.add";
fn TestF16(a: f16, b: f16) -> f16 { return F16(a, b); }
fn F32(a: f32, b: f32) -> f32 = "float.add";
fn TestF32(a: f32, b: f32) -> f32 { return F32(a, b); }
fn F64(a: f64, b: f64) -> f64 = "float.add";
fn TestF64(a: f64, b: f64) -> f64 { return F64(a, b); }
fn F128(a: f128, b: f128) -> f128 = "float.add";
fn TestF128(a: f128, b: f128) -> f128 { return F128(a, b); }
// CHECK:STDOUT: ; ModuleID = 'basic.carbon'
// CHECK:STDOUT: source_filename = "basic.carbon"
// CHECK:STDOUT:
@@ -230,3 +246,51 @@ fn TestDiv(a: f64*, b: f64) { Div(a, b); }
// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "TestDiv", linkageName: "_CTestDiv.Main", scope: null, file: !3, line: 14, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !16 = !DILocation(line: 14, column: 31, scope: !15)
// CHECK:STDOUT: !17 = !DILocation(line: 14, column: 1, scope: !15)
// CHECK:STDOUT: ; ModuleID = 'types.carbon'
// CHECK:STDOUT: source_filename = "types.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: define half @_CTestF16.Main(half %a, half %b) !dbg !4 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %F16.call = fadd half %a, %b, !dbg !7
// CHECK:STDOUT: ret half %F16.call, !dbg !8
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: define float @_CTestF32.Main(float %a, float %b) !dbg !9 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %F32.call = fadd float %a, %b, !dbg !10
// CHECK:STDOUT: ret float %F32.call, !dbg !11
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: define double @_CTestF64.Main(double %a, double %b) !dbg !12 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %F64.call = fadd double %a, %b, !dbg !13
// CHECK:STDOUT: ret double %F64.call, !dbg !14
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: define fp128 @_CTestF128.Main(fp128 %a, fp128 %b) !dbg !15 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %F128.call = fadd fp128 %a, %b, !dbg !16
// CHECK:STDOUT: ret fp128 %F128.call, !dbg !17
// CHECK:STDOUT: }
// 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, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
// CHECK:STDOUT: !3 = !DIFile(filename: "types.carbon", directory: "")
// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "TestF16", linkageName: "_CTestF16.Main", scope: null, file: !3, line: 5, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
// CHECK:STDOUT: !6 = !{}
// CHECK:STDOUT: !7 = !DILocation(line: 5, column: 44, scope: !4)
// CHECK:STDOUT: !8 = !DILocation(line: 5, column: 37, scope: !4)
// CHECK:STDOUT: !9 = distinct !DISubprogram(name: "TestF32", linkageName: "_CTestF32.Main", scope: null, file: !3, line: 8, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !10 = !DILocation(line: 8, column: 44, scope: !9)
// CHECK:STDOUT: !11 = !DILocation(line: 8, column: 37, scope: !9)
// CHECK:STDOUT: !12 = distinct !DISubprogram(name: "TestF64", linkageName: "_CTestF64.Main", scope: null, file: !3, line: 11, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !13 = !DILocation(line: 11, column: 44, scope: !12)
// CHECK:STDOUT: !14 = !DILocation(line: 11, column: 37, scope: !12)
// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "TestF128", linkageName: "_CTestF128.Main", scope: null, file: !3, line: 14, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !16 = !DILocation(line: 14, column: 48, scope: !15)
// CHECK:STDOUT: !17 = !DILocation(line: 14, column: 41, scope: !15)
+34 -16
View File
@@ -16,11 +16,17 @@ fn Int(size: IntLiteral()) -> type = "int.make_type_signed";
fn Float(size: IntLiteral()) -> type = "float.make_type";
fn Bool() -> type = "bool.make_type";
fn AsI32(n: IntLiteral()) -> Int(32) = "int.convert_checked";
fn AsF16(f: FloatLiteral()) -> Float(16) = "float.convert_checked";
fn AsF32(f: FloatLiteral()) -> Float(32) = "float.convert_checked";
fn AsF64(f: FloatLiteral()) -> Float(64) = "float.convert_checked";
fn AsF128(f: FloatLiteral()) -> Float(128) = "float.convert_checked";
fn F() {
var i: Int(32) = AsI32(0);
var f: Float(64) = AsF64(0.0);
var i: Int(32) = AsI32(1);
var e: Float(16) = AsF16(1.0);
var f: Float(32) = AsF32(1.0);
var g: Float(64) = AsF64(1.0);
var h: Float(128) = AsF128(1.0);
var b: Bool() = false;
}
@@ -30,22 +36,31 @@ fn F() {
// CHECK:STDOUT: define void @_CF.Main() !dbg !4 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT: %i.var = alloca i32, align 4, !dbg !7
// CHECK:STDOUT: %f.var = alloca double, align 8, !dbg !8
// CHECK:STDOUT: %b.var = alloca i1, align 1, !dbg !9
// CHECK:STDOUT: %e.var = alloca half, align 2, !dbg !8
// CHECK:STDOUT: %f.var = alloca float, align 4, !dbg !9
// CHECK:STDOUT: %g.var = alloca double, align 8, !dbg !10
// CHECK:STDOUT: %h.var = alloca fp128, align 16, !dbg !11
// CHECK:STDOUT: %b.var = alloca i1, align 1, !dbg !12
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %i.var), !dbg !7
// CHECK:STDOUT: store i32 0, ptr %i.var, align 4, !dbg !7
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %f.var), !dbg !8
// CHECK:STDOUT: store double 0.000000e+00, ptr %f.var, align 8, !dbg !8
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 1, ptr %b.var), !dbg !9
// CHECK:STDOUT: store i1 false, ptr %b.var, align 1, !dbg !9
// CHECK:STDOUT: ret void, !dbg !10
// CHECK:STDOUT: store i32 1, ptr %i.var, align 4, !dbg !7
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 2, ptr %e.var), !dbg !8
// CHECK:STDOUT: store half 0xH3C00, ptr %e.var, align 2, !dbg !8
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %f.var), !dbg !9
// CHECK:STDOUT: store float 1.000000e+00, ptr %f.var, align 4, !dbg !9
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %g.var), !dbg !10
// CHECK:STDOUT: store double 1.000000e+00, ptr %g.var, align 8, !dbg !10
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 16, ptr %h.var), !dbg !11
// CHECK:STDOUT: store fp128 0xL00000000000000003FFF000000000000, ptr %h.var, align 16, !dbg !11
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 1, ptr %b.var), !dbg !12
// CHECK:STDOUT: store i1 false, ptr %b.var, align 1, !dbg !12
// CHECK:STDOUT: ret void, !dbg !13
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #0
// CHECK:STDOUT:
// CHECK:STDOUT: ; uselistorder directives
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 2, 1, 0 }
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 5, 4, 3, 2, 1, 0 }
// CHECK:STDOUT:
// CHECK:STDOUT: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
// CHECK:STDOUT:
@@ -56,10 +71,13 @@ fn F() {
// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
// CHECK:STDOUT: !3 = !DIFile(filename: "types.carbon", directory: "")
// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main", scope: null, file: !3, line: 21, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main", scope: null, file: !3, line: 24, type: !5, spFlags: DISPFlagDefinition, unit: !2)
// CHECK:STDOUT: !5 = !DISubroutineType(types: !6)
// CHECK:STDOUT: !6 = !{}
// CHECK:STDOUT: !7 = !DILocation(line: 22, column: 3, scope: !4)
// CHECK:STDOUT: !8 = !DILocation(line: 23, column: 3, scope: !4)
// CHECK:STDOUT: !9 = !DILocation(line: 24, column: 3, scope: !4)
// CHECK:STDOUT: !10 = !DILocation(line: 21, column: 1, scope: !4)
// CHECK:STDOUT: !7 = !DILocation(line: 25, column: 3, scope: !4)
// CHECK:STDOUT: !8 = !DILocation(line: 26, column: 3, scope: !4)
// CHECK:STDOUT: !9 = !DILocation(line: 27, column: 3, scope: !4)
// CHECK:STDOUT: !10 = !DILocation(line: 28, column: 3, scope: !4)
// CHECK:STDOUT: !11 = !DILocation(line: 29, column: 3, scope: !4)
// CHECK:STDOUT: !12 = !DILocation(line: 30, column: 3, scope: !4)
// CHECK:STDOUT: !13 = !DILocation(line: 24, column: 1, scope: !4)
+48
View File
@@ -78,6 +78,54 @@ auto IntKind::Print(llvm::raw_ostream& out) const -> void {
}
}
static auto FloatKindToStringLiteral(FloatKind kind) -> llvm::StringLiteral {
switch (kind.index) {
case FloatKind::None.index:
return "<none>";
case FloatKind::Binary16.index:
return "f16";
case FloatKind::Binary32.index:
return "f32";
case FloatKind::Binary64.index:
return "f64";
case FloatKind::Binary128.index:
return "f128";
case FloatKind::BFloat16.index:
return "f16_brain";
case FloatKind::X87Float80.index:
return "f80_x87";
case FloatKind::PPCFloat128.index:
return "f128_ppc";
default:
return "<invalid>";
}
}
auto FloatKind::Print(llvm::raw_ostream& out) const -> void {
out << FloatKindToStringLiteral(*this);
}
auto FloatKind::Semantics() const -> const llvm::fltSemantics& {
switch (this->index) {
case Binary16.index:
return llvm::APFloat::IEEEhalf();
case Binary32.index:
return llvm::APFloat::IEEEsingle();
case Binary64.index:
return llvm::APFloat::IEEEdouble();
case Binary128.index:
return llvm::APFloat::IEEEquad();
case BFloat16.index:
return llvm::APFloat::BFloat();
case X87Float80.index:
return llvm::APFloat::x87DoubleExtended();
case PPCFloat128.index:
return llvm::APFloat::PPCDoubleDouble();
default:
CARBON_FATAL("Unexpected float kind {0}", *this);
}
}
// Double-check the special value mapping and constexpr evaluation.
static_assert(NameId::SpecialNameId::Vptr == *NameId::Vptr.AsSpecialNameId());
+39 -2
View File
@@ -9,6 +9,7 @@
#include "common/check.h"
#include "common/ostream.h"
#include "llvm/ADT/APFloat.h"
#include "toolchain/base/index_base.h"
#include "toolchain/base/value_ids.h"
#include "toolchain/diagnostics/diagnostic_emitter.h"
@@ -503,16 +504,52 @@ struct IntKind : public IdBase<IntKind> {
constexpr IntKind IntKind::Unsigned = IntKind(0);
constexpr IntKind IntKind::Signed = IntKind(1);
// A float kind value.
// A float kind value. This describes the semantics of the floating-point type.
// This represents very similar information to the bit-width, but is more
// precise. In particular, there is in general more than one floating-point type
// with a given bit-width, and while only one such type can be named with the
// `fN` notation, the others should still be modeled as `FloatType`s.
struct FloatKind : public IdBase<FloatKind> {
// Not used by `Print`, but for `IdKind`.
static constexpr llvm::StringLiteral Label = "float_kind";
// An explicitly absent kind. Used when the kind has not been determined.
static const FloatKind None;
// Supported IEEE-754 interchange formats. These correspond to Carbon `fN`
// type literal syntax.
static const FloatKind Binary16;
static const FloatKind Binary32;
static const FloatKind Binary64;
static const FloatKind Binary128;
// Note, binary256 is not supported by LLVM and hence not by us.
// Other formats supported by LLVM. Support for these may be
// target-dependent.
// TODO: Add a mechanism to use these types from Carbon code.
static const FloatKind BFloat16;
static const FloatKind X87Float80;
static const FloatKind PPCFloat128;
using IdBase::IdBase;
auto Print(llvm::raw_ostream& out) const -> void { out << "float"; }
auto Print(llvm::raw_ostream& out) const -> void;
// Query the LLVM semantics model associated with this kind of floating-point
// type. This kind must be concrete.
auto Semantics() const -> const llvm::fltSemantics&;
};
constexpr FloatKind FloatKind::None = FloatKind(NoneIndex);
constexpr FloatKind FloatKind::Binary16 = FloatKind(0);
constexpr FloatKind FloatKind::Binary32 = FloatKind(1);
constexpr FloatKind FloatKind::Binary64 = FloatKind(2);
constexpr FloatKind FloatKind::Binary128 = FloatKind(3);
constexpr FloatKind FloatKind::BFloat16 = FloatKind(4);
constexpr FloatKind FloatKind::X87Float80 = FloatKind(5);
constexpr FloatKind FloatKind::PPCFloat128 = FloatKind(6);
// An X-macro for special names. Uses should look like:
//
// #define CARBON_SPECIAL_NAME_ID_FOR_XYZ(Name) ...
+1
View File
@@ -734,6 +734,7 @@ struct FloatType {
// TODO: Consider adding a more compact way of representing either a small
// float bit width or an inst_id.
InstId bit_width_id;
FloatKind float_kind;
};
// A floating point value.