Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InstCombine drops debug value info towards end of function #61153

Open
jryans opened this issue Mar 3, 2023 · 4 comments
Open

InstCombine drops debug value info towards end of function #61153

jryans opened this issue Mar 3, 2023 · 4 comments

Comments

@jryans
Copy link
Member

jryans commented Mar 3, 2023

The InstCombine pass removes debug value info for is_annotated towards the
end of the function, and this is then propagated throughout the whole function.

Versions

Compiler Explorer

Program source

int get_name_prio;
int b(void);
int main(void) {
  int is_annotated;
  if (b())
    is_annotated = 0;
  else
    is_annotated = 4;
  if (is_annotated)
    get_name_prio = 2;
  return 0;
}

Debug info view

$ clang -fno-discard-value-names -fno-inline -g -O1 -c -o example-O1.o
$ llvm-dwarfdump -n is_annotated example-O1.o
0x00000067: DW_TAG_variable
              DW_AT_name        ("is_annotated")
              DW_AT_decl_line   (4)
              DW_AT_type        (0x00000047 "int")

Location for is_annotated is missing throughout the function.

IR before InstCombine

define dso_local i32 @main() local_unnamed_addr #0 {
entry:
  %call = call i32 @b()
  %tobool = icmp ne i32 %call, 0
  br i1 %tobool, label %if.then, label %if.else

if.then:                                          ; preds = %entry
  call void @llvm.dbg.value(metadata i32 0, "is_annotated", metadata !DIExpression())
  br label %if.end

if.else:                                          ; preds = %entry
  call void @llvm.dbg.value(metadata i32 4, "is_annotated", metadata !DIExpression())
  br label %if.end

if.end:                                           ; preds = %if.else, %if.then
  %is_annotated.0 = phi i32 [ 0, %if.then ], [ 4, %if.else ]
  call void @llvm.dbg.value(metadata i32 %is_annotated.0, "is_annotated", metadata !DIExpression())
  %tobool1 = icmp ne i32 %is_annotated.0, 0
  br i1 %tobool1, label %if.then2, label %if.end3

if.then2:                                         ; preds = %if.end
  store i32 2, ptr @get_name_prio, align 4
  br label %if.end3

if.end3:                                          ; preds = %if.then2, %if.end
  ret i32 0
}

IR after InstCombine

define dso_local i32 @main() local_unnamed_addr #0 {
entry:
  %call = call i32 @b() #3
  %tobool.not.not = icmp eq i32 %call, 0
  br i1 %tobool.not.not, label %if.else, label %if.then

if.then:                                          ; preds = %entry
  call void @llvm.dbg.value(metadata i32 0, "is_annotated", metadata !DIExpression())
  br label %if.end

if.else:                                          ; preds = %entry
  call void @llvm.dbg.value(metadata i32 4, "is_annotated", metadata !DIExpression())
  br label %if.end

if.end:                                           ; preds = %if.else, %if.then
  call void @llvm.dbg.value(metadata i32 poison, "is_annotated", metadata !DIExpression())
  br i1 %tobool.not.not, label %if.then2, label %if.end3

if.then2:                                         ; preds = %if.end
  store i32 2, ptr @get_name_prio, align 4
  br label %if.end3

if.end3:                                          ; preds = %if.then2, %if.end
  ret i32 0
}

IR diff before and after InstCombine

@@ -1,8 +1,8 @@
 define dso_local i32 @main() local_unnamed_addr #0 {
 entry:
-  %call = call i32 @b()
-  %tobool = icmp ne i32 %call, 0
-  br i1 %tobool, label %if.then, label %if.else
+  %call = call i32 @b() #3
+  %tobool.not.not = icmp eq i32 %call, 0
+  br i1 %tobool.not.not, label %if.else, label %if.then

 if.then:                                          ; preds = %entry
   call void @llvm.dbg.value(metadata i32 0, "is_annotated", metadata !DIExpression())
@@ -13,10 +13,8 @@
   br label %if.end

 if.end:                                           ; preds = %if.else, %if.then
-  %is_annotated.0 = phi i32 [ 0, %if.then ], [ 4, %if.else ]
-  call void @llvm.dbg.value(metadata i32 %is_annotated.0, "is_annotated", metadata !DIExpression())
-  %tobool1 = icmp ne i32 %is_annotated.0, 0
-  br i1 %tobool1, label %if.then2, label %if.end3
+  call void @llvm.dbg.value(metadata i32 poison, "is_annotated", metadata !DIExpression())
+  br i1 %tobool.not.not, label %if.then2, label %if.end3

 if.then2:                                         ; preds = %if.end
   store i32 2, ptr @get_name_prio, align 4
@llvmbot
Copy link
Collaborator

llvmbot commented Mar 3, 2023

@llvm/issue-subscribers-debuginfo

@jryans
Copy link
Member Author

jryans commented Mar 3, 2023

Readding debuginfo label, since it is about a debug info loss.

@llvmbot
Copy link
Collaborator

llvmbot commented Mar 3, 2023

@llvm/issue-subscribers-debuginfo

@jmorse
Copy link
Member

jmorse commented Apr 4, 2023

Hrrrrmmmm. This is certainly a dropped variable location, and the reasons are quite good: with no users there's no need to keep the PHI, and with no PHI there's no way to represent the value of ((cond) ? 4 : 0) in any LLVM Value, thus there's no way of describing it to debug-info.

On the other hand: the reason why the PHI can be dropped is because instcombine is able to express the value of %is_annotated.0 in block if.end using values computed in entry -- it's found an alternative way of representing the values with fewer dependencies. The blocks and CFG are only left there because instcombine relies on simplifycfg to clean things up later. We could choose to represent the dbg.value as being an expression using %tobool.not.not as an input.

I fear the internal representation of values being computed by instcombine might not be in a convenient format to then transform into debug-info expressions, however it's well worth examining. It might not be a cost-effective improvement to debug-info though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants