authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-07 16:48:37-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-07 16:52:19-07:00
loga028488384c599aa997ba04bbd5ed98f2172630c
treed61c60e53f167ecb3c5b24235f5fa30f01fd8c23
parent722d4a11bbba4052558f6f69b7e710d1206f3355

Sema: clean up zirUnaryMath

* pass air_tag instead of zir_tag * also pass eval function so that the branch only happens once and the body of zirUnaryMath is simplified * Value.sqrt: update to handle f80 and f128 in the normalized way that includes handling c_longdouble. Semi-related change: fix incorrect sqrt builtin name for f80 in stage1.

3 files changed, 44 insertions(+), 67 deletions(-)

src/Sema.zig+24-57
...@@ -745,19 +745,19 @@ fn analyzeBodyInner(...@@ -745,19 +745,19 @@ fn analyzeBodyInner(
745 .clz => try sema.zirClzCtz(block, inst, .clz, Value.clz),745 .clz => try sema.zirClzCtz(block, inst, .clz, Value.clz),
746 .ctz => try sema.zirClzCtz(block, inst, .ctz, Value.ctz),746 .ctz => try sema.zirClzCtz(block, inst, .ctz, Value.ctz),
747747
748 .sqrt => try sema.zirUnaryMath(block, inst, .sqrt),748 .sqrt => try sema.zirUnaryMath(block, inst, .sqrt, Value.sqrt),
749 .sin => try sema.zirUnaryMath(block, inst, .sin),749 .sin => @panic("TODO"),
750 .cos => try sema.zirUnaryMath(block, inst, .cos),750 .cos => @panic("TODO"),
751 .exp => try sema.zirUnaryMath(block, inst, .exp),751 .exp => @panic("TODO"),
752 .exp2 => try sema.zirUnaryMath(block, inst, .exp2),752 .exp2 => @panic("TODO"),
753 .log => try sema.zirUnaryMath(block, inst, .log),753 .log => @panic("TODO"),
754 .log2 => try sema.zirUnaryMath(block, inst, .log2),754 .log2 => @panic("TODO"),
755 .log10 => try sema.zirUnaryMath(block, inst, .log10),755 .log10 => @panic("TODO"),
756 .fabs => try sema.zirUnaryMath(block, inst, .fabs),756 .fabs => @panic("TODO"),
757 .floor => try sema.zirUnaryMath(block, inst, .floor),757 .floor => @panic("TODO"),
758 .ceil => try sema.zirUnaryMath(block, inst, .ceil),758 .ceil => @panic("TODO"),
759 .trunc => try sema.zirUnaryMath(block, inst, .trunc),759 .trunc => @panic("TODO"),
760 .round => try sema.zirUnaryMath(block, inst, .round),760 .round => @panic("TODO"),
761761
762 .error_set_decl => try sema.zirErrorSetDecl(block, inst, .parent),762 .error_set_decl => try sema.zirErrorSetDecl(block, inst, .parent),
763 .error_set_decl_anon => try sema.zirErrorSetDecl(block, inst, .anon),763 .error_set_decl_anon => try sema.zirErrorSetDecl(block, inst, .anon),
...@@ -11014,60 +11014,27 @@ fn zirUnaryMath(...@@ -11014,60 +11014,27 @@ fn zirUnaryMath(
11014 sema: *Sema,11014 sema: *Sema,
11015 block: *Block,11015 block: *Block,
11016 inst: Zir.Inst.Index,11016 inst: Zir.Inst.Index,
11017 zir_tag: Zir.Inst.Tag,11017 air_tag: Air.Inst.Tag,
11018 eval: fn (Value, Type, Allocator, std.Target) Allocator.Error!Value,
11018) CompileError!Air.Inst.Ref {11019) CompileError!Air.Inst.Ref {
11019 const tracy = trace(@src());11020 const tracy = trace(@src());
11020 defer tracy.end();11021 defer tracy.end();
1102111022
11022 const inst_data = sema.code.instructions.items(.data)[inst].un_node;11023 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
11023 const src = inst_data.src();
11024 const operand = sema.resolveInst(inst_data.operand);11024 const operand = sema.resolveInst(inst_data.operand);
11025 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
11025 const operand_ty = sema.typeOf(operand);11026 const operand_ty = sema.typeOf(operand);
11026 const operand_zig_ty_tag = operand_ty.zigTypeTag();11027 try sema.checkFloatType(block, operand_src, operand_ty);
1102711028
11028 const is_float = operand_zig_ty_tag == .Float or operand_zig_ty_tag == .ComptimeFloat;11029 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |operand_val| {
11029 if (!is_float) {11030 if (operand_val.isUndef()) return sema.addConstUndef(operand_ty);
11030 return sema.fail(block, src, "expected float type, found '{s}'", .{@tagName(operand_zig_ty_tag)});11031 const target = sema.mod.getTarget();
11032 const result_val = try eval(operand_val, operand_ty, sema.arena, target);
11033 return sema.addConstant(operand_ty, result_val);
11031 }11034 }
1103211035
11033 switch (zir_tag) {11036 try sema.requireRuntimeBlock(block, operand_src);
11034 .sqrt => {11037 return block.addUnOp(air_tag, operand);
11035 switch (operand_ty.tag()) {
11036 .f128,
11037 .comptime_float,
11038 .c_longdouble,
11039 => |t| return sema.fail(block, src, "TODO implement @sqrt for type '{s}'", .{@tagName(t)}),
11040 else => {},
11041 }
11042
11043 const maybe_operand_val = try sema.resolveMaybeUndefVal(block, src, operand);
11044 if (maybe_operand_val) |val| {
11045 if (val.isUndef())
11046 return sema.addConstUndef(operand_ty);
11047 const result_val = try val.sqrt(operand_ty, sema.arena);
11048 return sema.addConstant(operand_ty, result_val);
11049 }
11050
11051 try sema.requireRuntimeBlock(block, src);
11052 return block.addUnOp(.sqrt, operand);
11053 },
11054
11055 .sin,
11056 .cos,
11057 .exp,
11058 .exp2,
11059 .log,
11060 .log2,
11061 .log10,
11062 .fabs,
11063 .floor,
11064 .ceil,
11065 .trunc,
11066 .round,
11067 => return sema.fail(block, src, "TODO: implement zirUnaryMath for ZIR tag '{s}'", .{@tagName(zir_tag)}),
11068
11069 else => unreachable,
11070 }
11071}11038}
1107211039
11073fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {11040fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
src/stage1/codegen.cpp+1-1
...@@ -6996,7 +6996,7 @@ static LLVMValueRef ir_render_soft_f80_float_op(CodeGen *g, Stage1Air *executabl...@@ -6996,7 +6996,7 @@ static LLVMValueRef ir_render_soft_f80_float_op(CodeGen *g, Stage1Air *executabl
6996 const char *func_name;6996 const char *func_name;
6997 switch (instruction->fn_id) {6997 switch (instruction->fn_id) {
6998 case BuiltinFnIdSqrt:6998 case BuiltinFnIdSqrt:
6999 func_name = "__sqrt";6999 func_name = "__sqrtx";
7000 break;7000 break;
7001 case BuiltinFnIdSin:7001 case BuiltinFnIdSin:
7002 func_name = "__sinx";7002 func_name = "__sinx";
src/value.zig+19-9
...@@ -3265,24 +3265,34 @@ pub const Value = extern union {...@@ -3265,24 +3265,34 @@ pub const Value = extern union {
3265 }3265 }
3266 }3266 }
32673267
3268 pub fn sqrt(val: Value, float_type: Type, arena: Allocator) !Value {3268 pub fn sqrt(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value {
3269 switch (float_type.tag()) {3269 switch (float_type.floatBits(target)) {
3270 .f16 => {3270 16 => {
3271 const f = val.toFloat(f16);3271 const f = val.toFloat(f16);
3272 return Value.Tag.float_16.create(arena, @sqrt(f));3272 return Value.Tag.float_16.create(arena, @sqrt(f));
3273 },3273 },
3274 .f32 => {3274 32 => {
3275 const f = val.toFloat(f32);3275 const f = val.toFloat(f32);
3276 return Value.Tag.float_32.create(arena, @sqrt(f));3276 return Value.Tag.float_32.create(arena, @sqrt(f));
3277 },3277 },
3278 .f64 => {3278 64 => {
3279 const f = val.toFloat(f64);3279 const f = val.toFloat(f64);
3280 return Value.Tag.float_64.create(arena, @sqrt(f));3280 return Value.Tag.float_64.create(arena, @sqrt(f));
3281 },3281 },
32823282 80 => {
3283 // TODO: implement @sqrt for these types3283 if (true) {
3284 .f128, .comptime_float, .c_longdouble => unreachable,3284 @panic("TODO implement compiler_rt __sqrtx");
32853285 }
3286 const f = val.toFloat(f80);
3287 return Value.Tag.float_80.create(arena, @sqrt(f));
3288 },
3289 128 => {
3290 if (true) {
3291 @panic("TODO implement compiler_rt sqrtq");
3292 }
3293 const f = val.toFloat(f128);
3294 return Value.Tag.float_128.create(arena, @sqrt(f));
3295 },
3286 else => unreachable,3296 else => unreachable,
3287 }3297 }
3288 }3298 }