LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 44880 - Debug invariance in GlobalOpt
Summary: Debug invariance in GlobalOpt
Status: NEW
Alias: None
Product: libraries
Classification: Unclassified
Component: DebugInfo (show other bugs)
Version: trunk
Hardware: PC Linux
: P enhancement
Assignee: Unassigned LLVM Bugs
URL:
Keywords:
Depends on:
Blocks: 37728
  Show dependency tree
 
Reported: 2020-02-12 02:49 PST by David Stenberg
Modified: 2021-06-22 00:59 PDT (History)
7 users (show)

See Also:
Fixed By Commit(s):


Attachments
IR reproducer. (5.02 KB, text/plain)
2020-02-12 02:49 PST, David Stenberg
Details

Note You need to log in before you can comment on or make changes to this bug.
Description David Stenberg 2020-02-12 02:49:39 PST
Created attachment 23121 [details]
IR reproducer.

After the introduction of "[InstCombine][DebugInfo] Fold constants wrapped in metadata", some debug invariance started appearing.

Please note that that commit was reverted in 982944525c7706c4dee00042d5b7cf2f0d87804f due to this issue.

C reproducer:

    int a, b, c;
    static int arr[4];
    
    void foo() {
      const int *e[] = {&arr[2]};
      const int **f = &e[0];
      c = f != foo;
    }
    
    int main() {
      for (b = 0; b < 4; b++)
        a = a ^ arr[b];
      return 0;
    }

Commands:

    $ clang -O3 -g globalopt.c -S -o - -mllvm -disable-debug-info-print -o with-debug.s
    $ clang -O3 globalopt.c -S -o - -mllvm -disable-debug-info-print -o without-debug.s
    $ diff -u without-debug.s with-debug.s
    [...]
    +	movl	arr(%rip), %eax
    +	xorl	a(%rip), %eax
    +	xorl	arr+4(%rip), %eax
    +	xorl	arr+8(%rip), %eax
    +	xorl	arr+12(%rip), %eax
    +	movl	%eax, a(%rip)
     	movl	$4, b(%rip)
     	xorl	%eax, %eax
     	retq

That commit appears to have exposed a pre-existing debug invariance issue in GlobalOpt.

This can also be reproduced by just running GlobalOpt on the attached IR reproducer.

    $ opt -strip-debug globalopt.ll | opt -S -globalopt -o without-debug.ll
    $ opt globalopt.ll | opt -S -globalopt -strip-debug -o with-debug.ll
    $ diff without-debug.ll with-debug.ll
    [...]
    -  %xor = xor i32 0, %a.promoted
    -  %xor.1 = xor i32 0, %xor
    -  %xor.2 = xor i32 0, %xor.1
    -  %xor.3 = xor i32 0, %xor.2
    +  %0 = load i32, i32* getelementptr inbounds ([4 x i32], [4 x i32]* @arr, i64 0, i64 0), align 16
    +  %xor = xor i32 %0, %a.promoted
    +  %1 = load i32, i32* getelementptr inbounds ([4 x i32], [4 x i32]* @arr, i64 0, i64 1), align 4
    +  %xor.1 = xor i32 %1, %xor
    +  %2 = load i32, i32* getelementptr inbounds ([4 x i32], [4 x i32]* @arr, i64 0, i64 2), align 8
    +  %xor.2 = xor i32 %2, %xor.1
    +  %3 = load i32, i32* getelementptr inbounds ([4 x i32], [4 x i32]* @arr, i64 0, i64 3), align 4
    +  %xor.3 = xor i32 %3, %xor.2

The issue seems to be that the dbg.value intrinsic:

  call void @llvm.dbg.value(metadata i64 ptrtoint (i32* getelementptr inbounds ([4 x i32], [4 x i32]* @arr, i64 0, i64 2) to i64), metadata !24, metadata !DIExpression()), !dbg !32

seems to lead to GlobalStatus::analyzeGlobal() returning true that @arr has its address taken. This seems to have to do with the analysis bailing out due to the ptrtoint use of the GEP:

      // If the result of the constantexpr isn't pointer type, then we won't
      // know to expect it in various places.  Just reject early.
      if (!isa<PointerType>(CE->getType()))
        return true;
Comment 1 Markus Lavin 2021-06-22 00:59:13 PDT
Trying to address this in https://reviews.llvm.org/D104628