Skip to content

Debug invariance in GlobalOpt #44225

Closed
Closed
@dstenb

Description

@dstenb
mannequin
Bugzilla Link 44880
Version trunk
OS Linux
Blocks #37076
Attachments IR reproducer.
CC @JDevlieghere,@jmorse,@walkerkd,@elavkje,@pogo59

Extended Description

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

Please note that that commit was reverted in 9829445 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]* @&#8203;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]* @&#8203;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]* @&#8203;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]* @&#8203;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;

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions