<div dir="ltr">Thanks Tim, that's actually a very useful guide, and debugging this is going to be much easier with that knowledge.<br><br>First step: rebuild Clang.</div><br><div class="gmail_quote"><div dir="ltr">On Mon, 3 Sep 2018 at 13:31, Tim Northover <<a href="mailto:t.p.northover@gmail.com">t.p.northover@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Dan,<br>
<br>
On Sun, 2 Sep 2018 at 22:14, Dan Ravensloft via llvm-dev<br>
<<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br>
> I then tried to compile newlib 3.0.0-20180802, as newlib is used as the standard C library for the PS2, and hit multiple asserts, which I have attached below.<br>
<br>
After a quick look, three of the issues seem to be related to "long<br>
double", which is translated to fp128:<br>
<br>
vfprintf: invalid bitcast from f128 to f64. Part of some call, maybe?<br>
ldtoa: obviously a function taking "long double".<br>
vfscanf: Mishandling return of f128 from a libcall.<br>
<br>
Now, mapping long double to fp128 is actually a choice you have as an<br>
ABI creator. It's possible you feel constrained to follow GCC here and<br>
so need that, but if not the simplest fix might well be to just<br>
declare long double is the same as double. PS2 doesn't strike me as a<br>
system where you'd often want a 128-bit float. You'd do that by<br>
modifying tools/clang/lib/Basic/Targets/Mips.h (the setN32N64ABITypes<br>
function, notice FreeBSD has already done this).<br>
<br>
If you do have to support f128, you'd probably start by focusing on<br>
MipsISelLowering.cpp. Specifically the functions named things like<br>
LowerFormalArguments, LowerCall, LowerReturn. I'm not sure what the<br>
ABI is likely to be there, but I suspect you'll end up assigning an<br>
fp128 to 2 64-bit integer registers. If needed I'm sure me or a Mips<br>
expert could provide more details.<br>
<br>
The other problem (lrintfp) seems to involve an invalid truncation<br>
from f32 to f64, possibly inserted by code unaware of the single-float<br>
option. Nothing looks obviously wrong, so it's the usual debugging<br>
procedure:<br>
<br>
1. Try to produce a reduced test-case<br>
2. gdb/lldb it, since not many places produce the Mips-specific<br>
TruncIntFP node that's causing the problem.<br>
<br>
For 1, I've actually already got one for you:<br>
<br>
void foo(float *in, long long *out) {<br>
  *out = *in;<br>
}<br>
<br>
In brief, how I got it was:<br>
1. Run lldb on the crashing Clang command. Go up the backtrace until I<br>
got usable C++ code. DAG.viewGraph() produces a very nice pictorial<br>
representation of the code being selected, it had load(f32) -><br>
MipsISD::TruncIntFP (f64) -> store. That middle trunc is obviously<br>
really dodgy.<br>
2. From there you could try to write IR that did the same thing.<br>
Instead I printed "BlockName" that was available in one of the frames.<br>
Then I dumped the IR from Clang (-emit-llvm) and just looked at that<br>
IR snippet:<br>
<br>
  %23 = load float, float* %x.addr, align 4<br>
  %conv33 = fptosi float %23 to i64<br>
  store i64 %conv33, i64* %retval, align 8<br>
  br label %return<br>
<br>
>From there it's a lot easier to write down the C function I gave,<br>
which is what I did.<br>
<br>
So the next step is to debug where Mips is producing those TruncIntFP<br>
nodes. There'll be some constraint it's not checking or an unexpected<br>
node type, probably related to -msingle-float. I'm afraid I'm not sure<br>
what yet.<br>
<br>
Cheers.<br>
<br>
Tim.<br>
</blockquote></div>