[LLVMdev] load widening conflicts with AddressSanitizer

John Criswell criswell at illinois.edu
Fri Dec 16 14:41:27 PST 2011


On 12/16/11 4:14 PM, Chris Lattner wrote:
> On Dec 16, 2011, at 12:39 PM, Kostya Serebryany wrote:
>>
>>     > Do we consider the above transformation legal?
>>
>
> Yes, the transformation is perfectly legal for the normal compiler.

So how do you guarantee that the behavior is predictable regardless of 
hardware platform if you don't define what the behavior should be?

>
>>     > I would argue that it should not be legal.  We don't actually
>>     know what
>>     > comes after the 22 byte object.  Is it another memory object?  A
>>     > memory-mapped I/O device?  Unmapped memory?  Padded junk
>>     space?  Reading
>>     > memory-mapped I/O could have nasty side effects, and accessing
>>     unmapped
>>     > memory could cause the program to fault even though it was
>>     written correctly
>>     > as the source-language level.
>>
>
> Device memory accesses need to be done with volatile.  This can't 
> cause a paging problem (e.g. causing an additional page fault where 
> none existed before) on systems that use power-of-two sized pages.

I think people are misunderstanding my point about I/O memory.  I wasn't 
saying that the alloca is supposed to access I/O memory; I was saying 
that it is possible for I/O memory to be located contiguously after the 
memory object should the memory object be the last object on its memory 
page.

Now, after thinking about it, I realize why that can't happen if the 
memory is aligned to a 16-byte boundary on most architectures.  However, 
does load-widening actually check that the memory is 16-byte aligned?  
If not, then I don't see why this can't be a problem with memory 
allocated at arbitrary alignments.  Furthermore, you're making 
assumptions about the underlying MMU.  What if you have a funky 
architecture that someone is porting LLVM to, or someone is using x86-32 
segments in an interesting way?

If load-widening searches back through the def-use chains to check that 
the memory is aligned, then fixing the transform to always perform 
defined behavior seems easy enough: we check that the alloca is of the 
right alignment, and then we boost the allocated size if necessary.  
Since we'll never increase the size by more than 8 bytes, this seems 
reasonable.

Moreover, I don't really understand the rationale for allowing a 
transform to introduce undefined behavior into programs that exhibit no 
undefined behavior.  It's a source of subtle problems in the future when 
architectures change or someone does something unconventional, and it 
trips up memory safety tools and static analysis tools that are working 
correctly.  The only reason I see for tolerating it is if fixing the 
problem would be detrimental to performance.  If Kostya or I or someone 
else fixes load-widening so that it doesn't introduce undefined 
behavior, is it going to really hurt performance?

-- John T.

>
>>     Having the load hit unmapped memory is impossible on common
>>     architectures given the alignment we're talking about here.  And if
>>     memory-mapped IO comes after the memory object, the object itself
>>     also
>>     has some sort of unusual semantics, so it should be using volatile
>>     loads anyway.
>>
>>
>> Would would be the right way to disable load widening when 
>> AddressSanitizer (or SAFECode) is enabled?
>
> This is a good question.  Would it be possible for ASan to do its 
> instrumentation earlier?  I supposed we could add a "do not widen" 
> metadata hint on load instructions or something like that.
>
> -Chris
>
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20111216/e0f11222/attachment.html>


More information about the llvm-dev mailing list