How to track down a bad llvm optimization pass
Joakim via digitalmars-d-ldc
digitalmars-d-ldc at puremagic.com
Wed Jun 22 02:44:46 PDT 2016
On Wednesday, 22 June 2016 at 08:54:22 UTC, Joakim wrote:
> On Tuesday, 21 June 2016 at 19:41:59 UTC, Dan Olson wrote:
>> On Tuesday, 21 June 2016 at 07:00:35 UTC, Joakim wrote:
>>> On Tuesday, 21 June 2016 at 05:51:56 UTC, Joakim wrote:
>>>> On Monday, 20 June 2016 at 20:15:52 UTC, Rainer Schuetze
>>>> wrote:
>>>>>
>>>>>
>>>>> On 19.06.2016 08:58, Joakim wrote:
>>>>>> [...]
>>>>>
>>>>> If it fails in a specific optimization pass, it has already
>>>>> passed a number of verification passes. When I posted some
>>>>> bug reports, the LLVM people (who have been very helpful)
>>>>> considered it an LLVM bug if an invalid IR passes the
>>>>> verifier. So even if some assumptions are broken, I would
>>>>> suggest to report to the LLVM bug tracker.
>>>>
>>>> OK, will do. I think the fact that the exact same ldc
>>>> frontend linked with llvm 3.7.1 doesn't have this problem,
>>>> only when linked against llvm 3.8.0, indicates this most
>>>> likely isn't a problem on our end.
>>>
>>> Filed: https://llvm.org/bugs/show_bug.cgi?id=28224
>>
>> Hmmm. I looked at failing code in std.conv. I think it does
>> a negative shift, which is undefined in C. It is the
>> opSlice() method.
>
> I just tried the three-line reduced test case on linux/x64 with
> the official ldc 1.0.0 release linked against 3.8.0 and it
> asserts there too. However, if I compile all of the std.conv
> unittests and run them all, they all pass.
>
> It appears that you've found a clear off-by-one bug. I didn't
> investigate our end because the tests were all passing
> otherwise- I now see that dmd doesn't assert even against the
> reduced test case- but I should have examined that code more
> closely. It would have helped if llvm and/or the ddmd frontend
> had flagged that Phobos was shifting by a negative number,
> rather than passing it through silently for either correct or
> junk codegen.
>
> I agree that the real fix for this bug should go in Phobos, but
> perhaps we can also improve the spots where this negative shift
> was most silently discarded so far, whether ddmd or llvm.
I experimented a bit with this, using the latest dmd 2.071.0
release for linux/x64 and the following test that mimics what
std.conv was doing wrong:
int check_shift(int x) { return 16 >>> ((2 - x) * 4);}
unittest
{
assert(check_shift(3) == 16);
//assert(( 16 >>> (2-3) * 4) == 16);
}
If the second assert isn't commented out, dmd always evaluates
that expression at compile-time and gives this error:
shift.d(5): Error: shift by -4 is outside the range 0..31
If it's left commented out and the file is compiled with this
command,
./2.071.0/linux/bin64/dmd -O -unittest -main shift.d
the resulting binary asserts at runtime on line 4, ie the first
assert. If I compile again with inlining,
./2.071.0/linux/bin64/dmd -O -inline -unittest -main shift.d
the test passes!
The codegen for dmd seems all over the place here.
More information about the digitalmars-d-ldc
mailing list