diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-03-06 15:23:21 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-03-06 16:11:39 -0700 |
| commit | 71b8760d3b145c92dc6e331aefff7dac5cabebeb (patch) | |
| tree | 66b92748616634b689eb5c984f143042132d5e6c /src/Sema.zig | |
| parent | 6637335981f7179b449fced78cfd4052b1618051 (diff) | |
| download | zig-71b8760d3b145c92dc6e331aefff7dac5cabebeb.tar.gz zig-71b8760d3b145c92dc6e331aefff7dac5cabebeb.zip | |
stage2: rework `@mulAdd`
* mul_add AIR instruction: use `pl_op` instead of `ty_pl`. The type is
always the same as the operand; no need to waste bytes redundantly
storing the type.
* AstGen: use coerced_ty for all the operands except for one which we
use to communicate the type.
* Sema: use the correct source location for requireRuntimeBlock in
handling of `@mulAdd`.
* native backends: handle liveness even for the functions that are
TODO.
* C backend: implement `@mulAdd`. It lowers to libc calls.
* LLVM backend: make `@mulAdd` handle all float types.
- improved fptrunc and fpext to handle f80 with compiler-rt calls.
* Value.mulAdd: handle all float types and use the `@mulAdd` builtin.
* behavior tests: revert the changes to testing `@mulAdd`. These
changes broke the test coverage, making it only tested at
compile-time.
Improved f80 support:
* std.math.fma handles f80
* move fma functions from freestanding libc to compiler-rt
- add __fmax and fmal
- make __fmax and fmaq only exported when they don't alias fmal.
- make their linkage weak just like the rest of compiler-rt symbols.
* removed `longDoubleIsF128` and replaced it with `longDoubleIs` which
takes a type as a parameter. The implementation is now more accurate
and handles more targets. Similarly, in stage2 the function
CTypes.sizeInBits is more accurate for long double for more targets.
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 81 |
1 files changed, 40 insertions, 41 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 4ef20a99ba..019a635123 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -13525,48 +13525,26 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. const mulend2_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node }; const addend_src: LazySrcLoc = .{ .node_offset_builtin_call_arg3 = inst_data.src_node }; - const mulend1 = sema.resolveInst(extra.mulend1); - const mulend2 = sema.resolveInst(extra.mulend2); const addend = sema.resolveInst(extra.addend); - // All args have the same type - const ty = sema.typeOf(mulend1); - switch (ty.zigTypeTag()) { - .ComptimeFloat, .Float => {}, - .Vector => { - const scalar_ty = ty.scalarType(); - switch (scalar_ty.zigTypeTag()) { - .ComptimeFloat, .Float => {}, - else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{scalar_ty}), - } - }, - else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty}), - } + const ty = sema.typeOf(addend); + const mulend1 = try sema.coerce(block, ty, sema.resolveInst(extra.mulend1), mulend1_src); + const mulend2 = try sema.coerce(block, ty, sema.resolveInst(extra.mulend2), mulend2_src); const target = sema.mod.getTarget(); + switch (ty.zigTypeTag()) { .ComptimeFloat, .Float => { const maybe_mulend1 = try sema.resolveMaybeUndefVal(block, mulend1_src, mulend1); const maybe_mulend2 = try sema.resolveMaybeUndefVal(block, mulend2_src, mulend2); const maybe_addend = try sema.resolveMaybeUndefVal(block, addend_src, addend); - if (maybe_mulend1) |mulend1_val| { - if (mulend1_val.isUndef()) - return sema.addConstUndef(ty); - } - - if (maybe_mulend2) |mulend2_val| { - if (mulend2_val.isUndef()) - return sema.addConstUndef(ty); - } - - if (maybe_addend) |addend_val| { - if (addend_val.isUndef()) - return sema.addConstUndef(ty); - } - - if (maybe_mulend1) |mulend1_val| { + const runtime_src = if (maybe_mulend1) |mulend1_val| rs: { if (maybe_mulend2) |mulend2_val| { + if (mulend2_val.isUndef()) return sema.addConstUndef(ty); + if (maybe_addend) |addend_val| { + if (addend_val.isUndef()) return sema.addConstUndef(ty); + const result_val = try Value.mulAdd( ty, mulend1_val, @@ -13576,25 +13554,46 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. target, ); return sema.addConstant(ty, result_val); + } else { + break :rs addend_src; } + } else { + if (maybe_addend) |addend_val| { + if (addend_val.isUndef()) return sema.addConstUndef(ty); + } + break :rs mulend2_src; } - } + } else rs: { + if (maybe_mulend2) |mulend2_val| { + if (mulend2_val.isUndef()) return sema.addConstUndef(ty); + } + if (maybe_addend) |addend_val| { + if (addend_val.isUndef()) return sema.addConstUndef(ty); + } + break :rs mulend1_src; + }; - try sema.requireRuntimeBlock(block, src); + try sema.requireRuntimeBlock(block, runtime_src); return block.addInst(.{ .tag = .mul_add, - .data = .{ .ty_pl = .{ - .ty = try sema.addType(ty), - .payload = try sema.addExtra(Air.MulAdd{ - .mulend1 = mulend1, - .mulend2 = mulend2, - .addend = addend, + .data = .{ .pl_op = .{ + .operand = addend, + .payload = try sema.addExtra(Air.Bin{ + .lhs = mulend1, + .rhs = mulend2, }), } }, }); }, - .Vector => return sema.fail(block, src, "TODO: implement @mulAdd for vectors", .{}), - else => unreachable, + .Vector => { + const scalar_ty = ty.scalarType(); + switch (scalar_ty.zigTypeTag()) { + .ComptimeFloat, .Float => {}, + else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{scalar_ty}), + } + return sema.fail(block, src, "TODO: implement @mulAdd for vectors", .{}); + }, + else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty}), } } |
