stage2: lower float negation explicitly
Rather than lowering float negation as `0.0 - x`. * Add AIR instruction for float negation. * Add compiler-rt functions for f128, f80 negation closes #11853
This commit is contained in:
@@ -1755,6 +1755,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
|
||||
.mul_sat => try airSatOp(f, inst, "muls_"),
|
||||
.shl_sat => try airSatOp(f, inst, "shls_"),
|
||||
|
||||
.neg => try airNeg(f, inst),
|
||||
|
||||
.sqrt,
|
||||
.sin,
|
||||
.cos,
|
||||
@@ -4098,6 +4100,20 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
return local;
|
||||
}
|
||||
|
||||
fn airNeg(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
if (f.liveness.isUnused(inst)) return CValue.none;
|
||||
|
||||
const un_op = f.air.instructions.items(.data)[inst].un_op;
|
||||
const writer = f.object.writer();
|
||||
const inst_ty = f.air.typeOfIndex(inst);
|
||||
const operand = try f.resolveInst(un_op);
|
||||
const local = try f.allocLocal(inst_ty, .Const);
|
||||
try writer.writeAll("-");
|
||||
try f.writeCValue(writer, operand);
|
||||
try writer.writeAll(";\n");
|
||||
return local;
|
||||
}
|
||||
|
||||
fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
if (f.liveness.isUnused(inst)) return CValue.none;
|
||||
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
|
||||
|
||||
@@ -4019,6 +4019,7 @@ 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),
|
||||
@@ -6545,13 +6546,14 @@ pub const FuncGen = struct {
|
||||
fabs,
|
||||
floor,
|
||||
fma,
|
||||
fmax,
|
||||
fmin,
|
||||
fmod,
|
||||
log,
|
||||
log10,
|
||||
log2,
|
||||
fmax,
|
||||
fmin,
|
||||
mul,
|
||||
fmod,
|
||||
neg,
|
||||
round,
|
||||
sin,
|
||||
sqrt,
|
||||
@@ -6584,6 +6586,7 @@ pub const FuncGen = struct {
|
||||
var fn_name_buf: [64]u8 = undefined;
|
||||
const strat: FloatOpStrat = if (intrinsics_allowed) switch (op) {
|
||||
// Some operations are dedicated LLVM instructions, not available as intrinsics
|
||||
.neg => return self.builder.buildFNeg(params[0], ""),
|
||||
.add => return self.builder.buildFAdd(params[0], params[1], ""),
|
||||
.sub => return self.builder.buildFSub(params[0], params[1], ""),
|
||||
.mul => return self.builder.buildFMul(params[0], params[1], ""),
|
||||
@@ -6595,6 +6598,11 @@ pub const FuncGen = struct {
|
||||
} else b: {
|
||||
const float_bits = scalar_ty.floatBits(target);
|
||||
break :b switch (op) {
|
||||
.neg => FloatOpStrat{
|
||||
.libc = std.fmt.bufPrintZ(&fn_name_buf, "__neg{s}f2", .{
|
||||
compilerRtFloatAbbrev(float_bits),
|
||||
}) catch unreachable,
|
||||
},
|
||||
.add, .sub, .div, .mul => FloatOpStrat{
|
||||
.libc = std.fmt.bufPrintZ(&fn_name_buf, "__{s}{s}f3", .{
|
||||
@tagName(op), compilerRtFloatAbbrev(float_bits),
|
||||
|
||||
@@ -549,6 +549,9 @@ pub const Builder = opaque {
|
||||
pub const buildFSub = LLVMBuildFSub;
|
||||
extern fn LLVMBuildFSub(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value;
|
||||
|
||||
pub const buildFNeg = LLVMBuildFNeg;
|
||||
extern fn LLVMBuildFNeg(*const Builder, V: *const Value, Name: [*:0]const u8) *const Value;
|
||||
|
||||
pub const buildSub = LLVMBuildSub;
|
||||
extern fn LLVMBuildSub(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user