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(
745745 .clz => try sema.zirClzCtz(block, inst, .clz, Value.clz),
746746 .ctz => try sema.zirClzCtz(block, inst, .ctz, Value.ctz),
747747
748 .sqrt => try sema.zirUnaryMath(block, inst, .sqrt),
749 .sin => try sema.zirUnaryMath(block, inst, .sin),
750 .cos => try sema.zirUnaryMath(block, inst, .cos),
751 .exp => try sema.zirUnaryMath(block, inst, .exp),
752 .exp2 => try sema.zirUnaryMath(block, inst, .exp2),
753 .log => try sema.zirUnaryMath(block, inst, .log),
754 .log2 => try sema.zirUnaryMath(block, inst, .log2),
755 .log10 => try sema.zirUnaryMath(block, inst, .log10),
756 .fabs => try sema.zirUnaryMath(block, inst, .fabs),
757 .floor => try sema.zirUnaryMath(block, inst, .floor),
758 .ceil => try sema.zirUnaryMath(block, inst, .ceil),
759 .trunc => try sema.zirUnaryMath(block, inst, .trunc),
760 .round => try sema.zirUnaryMath(block, inst, .round),
748 .sqrt => try sema.zirUnaryMath(block, inst, .sqrt, Value.sqrt),
749 .sin => @panic("TODO"),
750 .cos => @panic("TODO"),
751 .exp => @panic("TODO"),
752 .exp2 => @panic("TODO"),
753 .log => @panic("TODO"),
754 .log2 => @panic("TODO"),
755 .log10 => @panic("TODO"),
756 .fabs => @panic("TODO"),
757 .floor => @panic("TODO"),
758 .ceil => @panic("TODO"),
759 .trunc => @panic("TODO"),
760 .round => @panic("TODO"),
761761
762762 .error_set_decl => try sema.zirErrorSetDecl(block, inst, .parent),
763763 .error_set_decl_anon => try sema.zirErrorSetDecl(block, inst, .anon),
......@@ -11014,60 +11014,27 @@ fn zirUnaryMath(
1101411014 sema: *Sema,
1101511015 block: *Block,
1101611016 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,
1101811019) CompileError!Air.Inst.Ref {
1101911020 const tracy = trace(@src());
1102011021 defer tracy.end();
1102111022
1102211023 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
11023 const src = inst_data.src();
1102411024 const operand = sema.resolveInst(inst_data.operand);
11025 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1102511026 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 (!is_float) {
11030 return sema.fail(block, src, "expected float type, found '{s}'", .{@tagName(operand_zig_ty_tag)});
11029 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |operand_val| {
11030 if (operand_val.isUndef()) return sema.addConstUndef(operand_ty);
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);
1103111034 }
1103211035
11033 switch (zir_tag) {
11034 .sqrt => {
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 }
11036 try sema.requireRuntimeBlock(block, operand_src);
11037 return block.addUnOp(air_tag, operand);
1107111038}
1107211039
1107311040fn 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
69966996 const char *func_name;
69976997 switch (instruction->fn_id) {
69986998 case BuiltinFnIdSqrt:
6999 func_name = "__sqrt";
6999 func_name = "__sqrtx";
70007000 break;
70017001 case BuiltinFnIdSin:
70027002 func_name = "__sinx";
src/value.zig+19-9
......@@ -3265,24 +3265,34 @@ pub const Value = extern union {
32653265 }
32663266 }
32673267
3268 pub fn sqrt(val: Value, float_type: Type, arena: Allocator) !Value {
3269 switch (float_type.tag()) {
3270 .f16 => {
3268 pub fn sqrt(val: Value, float_type: Type, arena: Allocator, target: Target) Allocator.Error!Value {
3269 switch (float_type.floatBits(target)) {
3270 16 => {
32713271 const f = val.toFloat(f16);
32723272 return Value.Tag.float_16.create(arena, @sqrt(f));
32733273 },
3274 .f32 => {
3274 32 => {
32753275 const f = val.toFloat(f32);
32763276 return Value.Tag.float_32.create(arena, @sqrt(f));
32773277 },
3278 .f64 => {
3278 64 => {
32793279 const f = val.toFloat(f64);
32803280 return Value.Tag.float_64.create(arena, @sqrt(f));
32813281 },
3282
3283 // TODO: implement @sqrt for these types
3284 .f128, .comptime_float, .c_longdouble => unreachable,
3285
3282 80 => {
3283 if (true) {
3284 @panic("TODO implement compiler_rt __sqrtx");
3285 }
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 },
32863296 else => unreachable,
32873297 }
32883298 }