stage2: implement @setFloatMode

This commit is contained in:
Veikka Tuominen
2022-07-21 14:40:00 +03:00
parent 585c160c20
commit d75fa86d70
14 changed files with 494 additions and 122 deletions

View File

@@ -1928,6 +1928,30 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
.wasm_memory_size => try airWasmMemorySize(f, inst),
.wasm_memory_grow => try airWasmMemoryGrow(f, inst),
.add_optimized,
.addwrap_optimized,
.sub_optimized,
.subwrap_optimized,
.mul_optimized,
.mulwrap_optimized,
.div_float_optimized,
.div_trunc_optimized,
.div_floor_optimized,
.div_exact_optimized,
.rem_optimized,
.mod_optimized,
.neg_optimized,
.cmp_lt_optimized,
.cmp_lte_optimized,
.cmp_eq_optimized,
.cmp_gte_optimized,
.cmp_gt_optimized,
.cmp_neq_optimized,
.cmp_vector_optimized,
.reduce_optimized,
.float_to_int_optimized,
=> return f.fail("TODO implement optimized float mode", .{}),
// zig fmt: on
};
switch (result_value) {

View File

@@ -3984,21 +3984,21 @@ pub const FuncGen = struct {
for (body) |inst, i| {
const opt_value: ?*const llvm.Value = switch (air_tags[inst]) {
// zig fmt: off
.add => try self.airAdd(inst),
.addwrap => try self.airAddWrap(inst),
.add => try self.airAdd(inst, false),
.addwrap => try self.airAddWrap(inst, false),
.add_sat => try self.airAddSat(inst),
.sub => try self.airSub(inst),
.subwrap => try self.airSubWrap(inst),
.sub => try self.airSub(inst, false),
.subwrap => try self.airSubWrap(inst, false),
.sub_sat => try self.airSubSat(inst),
.mul => try self.airMul(inst),
.mulwrap => try self.airMulWrap(inst),
.mul => try self.airMul(inst, false),
.mulwrap => try self.airMulWrap(inst, false),
.mul_sat => try self.airMulSat(inst),
.div_float => try self.airDivFloat(inst),
.div_trunc => try self.airDivTrunc(inst),
.div_floor => try self.airDivFloor(inst),
.div_exact => try self.airDivExact(inst),
.rem => try self.airRem(inst),
.mod => try self.airMod(inst),
.div_float => try self.airDivFloat(inst, false),
.div_trunc => try self.airDivTrunc(inst, false),
.div_floor => try self.airDivFloor(inst, false),
.div_exact => try self.airDivExact(inst, false),
.rem => try self.airRem(inst, false),
.mod => try self.airMod(inst, false),
.ptr_add => try self.airPtrAdd(inst),
.ptr_sub => try self.airPtrSub(inst),
.shl => try self.airShl(inst),
@@ -4009,6 +4009,19 @@ pub const FuncGen = struct {
.slice => try self.airSlice(inst),
.mul_add => try self.airMulAdd(inst),
.add_optimized => try self.airAdd(inst, true),
.addwrap_optimized => try self.airAddWrap(inst, true),
.sub_optimized => try self.airSub(inst, true),
.subwrap_optimized => try self.airSubWrap(inst, true),
.mul_optimized => try self.airMul(inst, true),
.mulwrap_optimized => try self.airMulWrap(inst, true),
.div_float_optimized => try self.airDivFloat(inst, true),
.div_trunc_optimized => try self.airDivTrunc(inst, true),
.div_floor_optimized => try self.airDivFloor(inst, true),
.div_exact_optimized => try self.airDivExact(inst, true),
.rem_optimized => try self.airRem(inst, true),
.mod_optimized => try self.airMod(inst, true),
.add_with_overflow => try self.airOverflow(inst, "llvm.sadd.with.overflow", "llvm.uadd.with.overflow"),
.sub_with_overflow => try self.airOverflow(inst, "llvm.ssub.with.overflow", "llvm.usub.with.overflow"),
.mul_with_overflow => try self.airOverflow(inst, "llvm.smul.with.overflow", "llvm.umul.with.overflow"),
@@ -4034,17 +4047,27 @@ pub const FuncGen = struct {
.ceil => try self.airUnaryOp(inst, .ceil),
.round => try self.airUnaryOp(inst, .round),
.trunc_float => try self.airUnaryOp(inst, .trunc),
.neg => try self.airUnaryOp(inst, .neg),
.cmp_eq => try self.airCmp(inst, .eq),
.cmp_gt => try self.airCmp(inst, .gt),
.cmp_gte => try self.airCmp(inst, .gte),
.cmp_lt => try self.airCmp(inst, .lt),
.cmp_lte => try self.airCmp(inst, .lte),
.cmp_neq => try self.airCmp(inst, .neq),
.neg => try self.airNeg(inst, false),
.neg_optimized => try self.airNeg(inst, true),
.cmp_vector => try self.airCmpVector(inst),
.cmp_lt_errors_len => try self.airCmpLtErrorsLen(inst),
.cmp_eq => try self.airCmp(inst, .eq, false),
.cmp_gt => try self.airCmp(inst, .gt, false),
.cmp_gte => try self.airCmp(inst, .gte, false),
.cmp_lt => try self.airCmp(inst, .lt, false),
.cmp_lte => try self.airCmp(inst, .lte, false),
.cmp_neq => try self.airCmp(inst, .neq, false),
.cmp_eq_optimized => try self.airCmp(inst, .eq, true),
.cmp_gt_optimized => try self.airCmp(inst, .gt, true),
.cmp_gte_optimized => try self.airCmp(inst, .gte, true),
.cmp_lt_optimized => try self.airCmp(inst, .lt, true),
.cmp_lte_optimized => try self.airCmp(inst, .lte, true),
.cmp_neq_optimized => try self.airCmp(inst, .neq, true),
.cmp_vector => try self.airCmpVector(inst, false),
.cmp_vector_optimized => try self.airCmpVector(inst, true),
.cmp_lt_errors_len => try self.airCmpLtErrorsLen(inst),
.is_non_null => try self.airIsNonNull(inst, false, .NE),
.is_non_null_ptr => try self.airIsNonNull(inst, true , .NE),
@@ -4093,8 +4116,10 @@ pub const FuncGen = struct {
.ptr_slice_ptr_ptr => try self.airPtrSliceFieldPtr(inst, 0),
.ptr_slice_len_ptr => try self.airPtrSliceFieldPtr(inst, 1),
.float_to_int => try self.airFloatToInt(inst, false),
.float_to_int_optimized => try self.airFloatToInt(inst, true),
.array_to_slice => try self.airArrayToSlice(inst),
.float_to_int => try self.airFloatToInt(inst),
.int_to_float => try self.airIntToFloat(inst),
.cmpxchg_weak => try self.airCmpxchg(inst, true),
.cmpxchg_strong => try self.airCmpxchg(inst, false),
@@ -4115,11 +4140,13 @@ pub const FuncGen = struct {
.splat => try self.airSplat(inst),
.select => try self.airSelect(inst),
.shuffle => try self.airShuffle(inst),
.reduce => try self.airReduce(inst),
.aggregate_init => try self.airAggregateInit(inst),
.union_init => try self.airUnionInit(inst),
.prefetch => try self.airPrefetch(inst),
.reduce => try self.airReduce(inst, false),
.reduce_optimized => try self.airReduce(inst, true),
.atomic_store_unordered => try self.airAtomicStore(inst, .Unordered),
.atomic_store_monotonic => try self.airAtomicStore(inst, .Monotonic),
.atomic_store_release => try self.airAtomicStore(inst, .Release),
@@ -4485,8 +4512,9 @@ pub const FuncGen = struct {
return null;
}
fn airCmp(self: *FuncGen, inst: Air.Inst.Index, op: math.CompareOperator) !?*const llvm.Value {
fn airCmp(self: *FuncGen, inst: Air.Inst.Index, op: math.CompareOperator, want_fast_math: bool) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
self.builder.setFastMath(want_fast_math);
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
@@ -4496,8 +4524,9 @@ pub const FuncGen = struct {
return self.cmp(lhs, rhs, operand_ty, op);
}
fn airCmpVector(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
fn airCmpVector(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
self.builder.setFastMath(want_fast_math);
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const extra = self.air.extraData(Air.VectorCmp, ty_pl.payload).data;
@@ -4943,10 +4972,12 @@ pub const FuncGen = struct {
return self.builder.buildCall(libc_fn, &params, params.len, .C, .Auto, "");
}
fn airFloatToInt(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
fn airFloatToInt(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
if (self.liveness.isUnused(inst))
return null;
self.builder.setFastMath(want_fast_math);
const target = self.dg.module.getTarget();
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
@@ -6095,8 +6126,9 @@ pub const FuncGen = struct {
return self.builder.buildInsertValue(partial, len, 1, "");
}
fn airAdd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
fn airAdd(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
self.builder.setFastMath(want_fast_math);
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
@@ -6109,8 +6141,9 @@ pub const FuncGen = struct {
return self.builder.buildNUWAdd(lhs, rhs, "");
}
fn airAddWrap(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
fn airAddWrap(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
self.builder.setFastMath(want_fast_math);
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
@@ -6134,8 +6167,9 @@ pub const FuncGen = struct {
return self.builder.buildUAddSat(lhs, rhs, "");
}
fn airSub(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
fn airSub(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
self.builder.setFastMath(want_fast_math);
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
@@ -6148,8 +6182,9 @@ pub const FuncGen = struct {
return self.builder.buildNUWSub(lhs, rhs, "");
}
fn airSubWrap(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
fn airSubWrap(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
self.builder.setFastMath(want_fast_math);
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
@@ -6172,8 +6207,9 @@ pub const FuncGen = struct {
return self.builder.buildUSubSat(lhs, rhs, "");
}
fn airMul(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
fn airMul(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
self.builder.setFastMath(want_fast_math);
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
@@ -6186,8 +6222,9 @@ pub const FuncGen = struct {
return self.builder.buildNUWMul(lhs, rhs, "");
}
fn airMulWrap(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
fn airMulWrap(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
self.builder.setFastMath(want_fast_math);
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
@@ -6210,8 +6247,9 @@ pub const FuncGen = struct {
return self.builder.buildUMulFixSat(lhs, rhs, "");
}
fn airDivFloat(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
fn airDivFloat(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
self.builder.setFastMath(want_fast_math);
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
@@ -6221,8 +6259,9 @@ pub const FuncGen = struct {
return self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs });
}
fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
self.builder.setFastMath(want_fast_math);
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
@@ -6238,8 +6277,9 @@ pub const FuncGen = struct {
return self.builder.buildUDiv(lhs, rhs, "");
}
fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
self.builder.setFastMath(want_fast_math);
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
@@ -6270,8 +6310,9 @@ pub const FuncGen = struct {
return self.builder.buildUDiv(lhs, rhs, "");
}
fn airDivExact(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
self.builder.setFastMath(want_fast_math);
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
@@ -6284,8 +6325,9 @@ pub const FuncGen = struct {
return self.builder.buildExactUDiv(lhs, rhs, "");
}
fn airRem(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
fn airRem(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
self.builder.setFastMath(want_fast_math);
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
@@ -6298,8 +6340,9 @@ pub const FuncGen = struct {
return self.builder.buildURem(lhs, rhs, "");
}
fn airMod(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
fn airMod(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
self.builder.setFastMath(want_fast_math);
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
@@ -7613,6 +7656,17 @@ pub const FuncGen = struct {
return self.buildFloatOp(op, operand_ty, 1, .{operand});
}
fn airNeg(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
self.builder.setFastMath(want_fast_math);
const un_op = self.air.instructions.items(.data)[inst].un_op;
const operand = try self.resolveInst(un_op);
const operand_ty = self.air.typeOf(un_op);
return self.buildFloatOp(.neg, operand_ty, 1, .{operand});
}
fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
@@ -7927,8 +7981,9 @@ pub const FuncGen = struct {
return self.builder.buildShuffleVector(a, b, llvm_mask_value, "");
}
fn airReduce(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
fn airReduce(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
self.builder.setFastMath(want_fast_math);
const reduce = self.air.instructions.items(.data)[inst].reduce;
const operand = try self.resolveInst(reduce.operand);

View File

@@ -941,6 +941,9 @@ pub const Builder = opaque {
pub const buildFPMulReduce = ZigLLVMBuildFPMulReduce;
extern fn ZigLLVMBuildFPMulReduce(B: *const Builder, Acc: *const Value, Val: *const Value) *const Value;
pub const setFastMath = ZigLLVMSetFastMath;
extern fn ZigLLVMSetFastMath(B: *const Builder, on_state: bool) void;
};
pub const MDString = opaque {