[LLVMdev] LTO "bug" and Clang warnings

Renato Golin renato.golin at linaro.org
Tue Jan 8 08:49:07 PST 2013


The bugs:

http://llvm.org/bugs/show_bug.cgi?id=14851

http://llvm.org/bugs/show_bug.cgi?id=14852


cheers,
--renato



On 8 January 2013 16:29, Renato Golin <renato.golin at linaro.org> wrote:

> Hi Duncan,
>
> Ok, I found that even if main() does reference foo, setup() still gets
> chopped off and the results is the unexpected:
>
> Foo: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
> Bar: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> Baz: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
>
> So, while there is the issue in LTO, I still think Clang could give a
> warning. This is a source of buffer overflow attacks...
>
> While trying to define which pass was doing this, I commented out pass by
> pass in LTO and found that commenting some of them would produce a
> seg-fault in LLVM (haven't checked further, though), but I know that is one
> of:
>
>   PM.add(createGlobalOptimizerPass());
>   PM.add(createConstantMergePass());
>   PM.add(createDeadArgEliminationPass());
>   PM.add(createInstructionCombiningPass());
>
>   // Inline small functions
>   if (RunInliner)
>     PM.add(createFunctionInliningPass());
>
>   PM.add(createPruneEHPass());   // Remove dead EH info.
>   if (RunInliner)
>     PM.add(createGlobalOptimizerPass());
>   PM.add(createGlobalDCEPass()); // Remove dead functions.
>
> Then I looped over all LTO passes in the populateLTOPassManager() but
> adding them manually (incrementally, until I passed them all) didn't allow
> me to reproduce the error.
>
> I'll create a bugzilla for this, and the Clang warning. If Clang folks
> think it's worth, they can start from there.
>
> --renato
>
>
> On 8 January 2013 16:20, Duncan Sands <baldrick at free.fr> wrote:
>
>> Hi Renato,
>>
>>
>> On 08/01/13 17:16, Renato Golin wrote:
>>
>>> After looking at the Livermore for a while, we found the issue that was
>>> causing
>>> LTO to produce a different result.
>>>
>>> Consider the code below [1]. setup() doesn't touch bar/baz, main()
>>> doesn't
>>> reference foo. LTO finds, correctly,
>>>
>>
>> I don't think this is correct.  At the LLVM IR level it is valid to write
>> into
>> bar and baz by accessing off the end of foo.  GlobalOpt is wrong to think
>> that
>> an inbounds GEP into foo cannot be referencing bar/baz; the inbounds
>> rules only
>> say it can't access memory outside of S.  So I think this is an optimizer
>> bug.
>>
>> Ciao, Duncan.
>>
>>
>>  that it can remove the setup(), but the
>>
>>> result is different.
>>>
>>> The code is clearly wrong, but the compiler has no right to fix user's
>>> stupidity, even at that level. The only think I can think that would
>>> mitigate
>>> the problem would be to have a warning or out-of-bounds access when it's
>>> that
>>> obvious.
>>>
>>> Clang folks,
>>>
>>> Correct me it I'm wrong, but I humbly think this should be done in the
>>> front-end, so it's easy to print out line information without requiring
>>> debug
>>> symbols to be present. How easy would be to do that in Clang's AST?
>>>
>>> I assume it's only a matter of checking the stride against the bounds of
>>> the
>>> array, if all is knowns at compile time. That would also help against
>>> segmentation fault.
>>>
>>> It wouldn't, however, work with variable length arrays, but VLA tend to
>>> segfault
>>> more often than silently overwrite other global variables.
>>>
>>> cheers,
>>> --renato
>>>
>>> [1]
>>> #include <stdio.h>
>>>
>>> struct {
>>>    int foo[20];
>>>    int bar[20];
>>>    int baz[20];
>>> } S;
>>>
>>> void setup() {
>>>    int i;
>>>    // OVERWRITES ALL THREE ARRAYS
>>>    for (i=0; i<60; i++)
>>>      S.foo[i] = i; // ONLY REFERENCES FOO
>>> }
>>>
>>> // DOESN'T USE FOO
>>> int main() {
>>>    int i;
>>>    setup();
>>>    printf("Bar: ");
>>>    for (i=0; i<20; i++)
>>>      printf("%d ", S.bar[i]);
>>>    printf("\nBaz: ");
>>>    for (i=0; i<20; i++)
>>>      printf("%d ", S.baz[i]);
>>>    puts("");
>>>
>>>    return 0;
>>> }
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130108/c218f786/attachment.html>


More information about the llvm-dev mailing list