authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-30 11:48:37-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-30 11:48:37-07:00
logb3b96b5e288ddf3694b4a0d203c684b9b8f6b49f
tree93ec35c7630bdfe44eb3cf4f27e9db286d1e2b32
parentc8531faaf56612773ef860d341f8eebb36af4bf3

LLVM: lower float negation with xor a constant

Rather than a compiler-rt call in the case that LLVM does not support lowering the fneg instruction.

1 files changed, 10 insertions(+), 4 deletions(-)

src/codegen/llvm.zig+10-4
...@@ -6598,10 +6598,16 @@ pub const FuncGen = struct {...@@ -6598,10 +6598,16 @@ pub const FuncGen = struct {
6598 } else b: {6598 } else b: {
6599 const float_bits = scalar_ty.floatBits(target);6599 const float_bits = scalar_ty.floatBits(target);
6600 break :b switch (op) {6600 break :b switch (op) {
6601 .neg => FloatOpStrat{6601 .neg => {
6602 .libc = std.fmt.bufPrintZ(&fn_name_buf, "__neg{s}f2", .{6602 // In this case we can generate a softfloat negation by XORing the
6603 compilerRtFloatAbbrev(float_bits),6603 // bits with a constant.
6604 }) catch unreachable,6604 const int_llvm_ty = self.dg.context.intType(float_bits);
6605 const one = int_llvm_ty.constInt(1, .False);
6606 const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False);
6607 const sign_mask = one.constShl(shift_amt);
6608 const bitcasted_operand = self.builder.buildBitCast(params[0], int_llvm_ty, "");
6609 const result = self.builder.buildXor(bitcasted_operand, sign_mask, "");
6610 return self.builder.buildBitCast(result, llvm_ty, "");
6605 },6611 },
6606 .add, .sub, .div, .mul => FloatOpStrat{6612 .add, .sub, .div, .mul => FloatOpStrat{
6607 .libc = std.fmt.bufPrintZ(&fn_name_buf, "__{s}{s}f3", .{6613 .libc = std.fmt.bufPrintZ(&fn_name_buf, "__{s}{s}f3", .{