How to track down a bad llvm optimization pass

Joakim via digitalmars-d-ldc digitalmars-d-ldc at puremagic.com
Thu Jun 30 04:50:15 PDT 2016


On Wednesday, 29 June 2016 at 15:09:33 UTC, Johan Engelen wrote:
> On Wednesday, 29 June 2016 at 08:18:46 UTC, Joakim wrote:
>> On Wednesday, 22 June 2016 at 16:06:13 UTC, Dan Olson wrote:
>>> Joakim <dlang at joakim.fea.st> writes:
>>>> shift.d(5): Error: shift by -4 is outside the range 0..31
>>>
>>> Agree, should be explored more to understand why that error 
>>> message didn't appear in this case.
>>
>> I looked into this and it appears that dmd doesn't do the 
>> static analysis necessary to catch such bugs nor insert the 
>> runtime checks that could bail out with an exact error:
>>
>> https://issues.dlang.org/show_bug.cgi?id=7604
>> https://issues.dlang.org/show_bug.cgi?id=4835
>>
>> Walter says he doesn't want runtime checks for performance 
>> reasons (comment 11 in the second linked bug), which is 
>> understandable.  I'm not sure we can do anything but be more 
>> careful about such bugs in our D code.
>
> This is LDC, not DMD, so for this it doesn't matter what Walter 
> says :-)
> If you can implement a runtime check (default off) for 
> undefined shifts, how is that bad? Clang's -fsanitize flags 
> look great. 
> http://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html

I'll look into what clang's doing there.

Speaking of shift errors, I took a look at why even ldc 1.0.0 
fails for that undefined shift optimization bug I just reported 
for dmd and it does the same thing, simply removes the test block 
after inlining and optimization.

Here's the relevant IR before and after inlining with -O1 
-enable-inlining on linux/x64:

*** IR Dump Before Function Integration/Inlining ***
; Function Attrs: uwtable
define void @_D5shift14__unittestL2_1FZv() #1 comdat {
   %1 = call i32 @_D5shift11check_shiftFiZi(i32 3) #1
   %2 = icmp eq i32 %1, 16
   br i1 %2, label %assertPassed, label %assertFailed

*** IR Dump After Function Integration/Inlining ***
; Function Attrs: uwtable
define void @_D5shift14__unittestL2_1FZv() #1 comdat {
%1 = icmp eq i32 undef, 16
br i1 %1, label %assertPassed, label %assertFailed

Eventually that gets optimized away to nothing, just like with 
dmd.

Would this be considered an llvm bug or the expected result from 
passing an undefined right shift to llvm?  It should at least 
warn about that undef after inlining, shouldn't it?


More information about the digitalmars-d-ldc mailing list