Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Precision loss during round-trip of ppc_fp128 hexadecimal floating-point constants (double-double arithmetic) #124

Open
mewmew opened this issue Dec 28, 2019 · 2 comments

Comments

@mewmew
Copy link
Member

mewmew commented Dec 28, 2019

There is a known precision loss when parsing and printing LLVM IR assembly containing ppc_fp128 hexadecimal floating-point constants. This issue was identified by @dannypsnl, and the cause has been researched by @dannypsnl (see #31 (comment)) and @scottshotgg (see #31 (comment)).

Below follows a proof of concept illustrating the precision loss for the ppc_fp128 constant 0xM400C0000000000300000000010000000. From #31 (comment)

The problem happened, in this case, was because the sum of high and low is not exact, I create an example for it:

package main

import (
	"fmt"
	"math/big"
	"math"
)

func main() {
	precision := uint(106)
	// Operate on numbers of different precision.
	var z big.Float
	x := big.NewFloat(math.Float64frombits(0x0000000010000000)).SetPrec(precision)
	y := big.NewFloat(math.Float64frombits(0x400C000000000030)).SetPrec(precision)
	z.SetPrec(precision)
	z.Add(x, y)
	fmt.Printf("x = %.10g (%s, prec = %d, acc = %s)\n", x, x.Text('p', 0), x.Prec(), x.Acc())
	fmt.Printf("y = %.10g (%s, prec = %d, acc = %s)\n", y, y.Text('p', 0), y.Prec(), y.Acc())
	fmt.Printf("z = %.10g (%s, prec = %d, acc = %s)\n", &z, z.Text('p', 0), z.Prec(), z.Acc())
}
// Result:
// x = 1.326247369e-315 (0x.8p-1045, prec = 106, acc = Exact)
// y = 3.5 (0x.e000000000018p+2, prec = 106, acc = Exact)
// z = 3.5 (0x.e000000000018p+2, prec = 106, acc = Below)

Link to failing test case:

"0xM400C0000000000300000000010000000",

go test github.com/llir/llvm/ir/constant -run TestNewFloatFromStringForPPCFP128

Changing the precision of the math/big.Float from 106 (which is the precision of double-double arithmetic) to 1048 fixes this issue and resolves the loss of precision (see #31 (comment)). However, simply changing the precision to 1048 does not seem like the right fix, since it will affect the results of future arithmetic on these constants and may result in more memory usage and loss of performance.

Leaving this issue open in the hopes that someone has the expertise needed to figure out what is going wrong, and come up with a solution.

ref to sister issue #31.

@scottshotgg
Copy link

Here is another bug that someone has reported in the Haskell LLVM bindings. He mentions 'roundtrip' but it sounds like LLVM is not outputting it correctly. Either way, if someone anyone here can actually read Haskell, here's the issue: llvm-hs/llvm-hs#4

@mewmew mewmew added this to the future milestone Dec 28, 2019
@mewmew
Copy link
Member Author

mewmew commented Dec 28, 2019

Test case disabled in rev a353c6c.

From a353c6c#diff-296597e1a91f88998cc9640e7b83fcf5

//"0xM400C0000000000300000000010000000", // see issue https://github.com/llir/llvm/issues/124

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants