[LLVMdev] LTO "bug" and Clang warnings

Duncan Sands baldrick at free.fr
Tue Jan 8 08:20:00 PST 2013


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;
> }
>




More information about the llvm-dev mailing list