Skip to content

[DebugInfo][TailCallElim] Cloned AccRecInstrNew should drop its debugloc when being inserted into other blocks #95731

Closed
@Apochens

Description

@Apochens

TailCallElimination-L805: In optimized @test^_multiple_returns, %accumulator.ret.tr (in block %case99) and %accumulator.ret.tr2 (in block %case0) have the same debug location of %accumulate (in block %default). However, they are all in different switch cases, the debug location of % accumulate should not be propagated to the two *.ret.tr*.

Before TailCallElim optimization:

define i32 @test6_multiple_returns(i32 %x, i32 %y) local_unnamed_addr !dbg !5 {
entry:
  switch i32 %x, label %default [
    i32 0, label %case0
    i32 99, label %case99
  ], !dbg !8

case0:                                            ; preds = %entry
  %helper = call i32 @test6_helper(), !dbg !9
  ret i32 %helper, !dbg !10

case99:                                           ; preds = %entry
  %sub1 = add i32 %x, -1, !dbg !11
  %recurse1 = call i32 @test6_multiple_returns(i32 %sub1, i32 %y), !dbg !12
  ret i32 18, !dbg !13

default:                                          ; preds = %entry
  %sub2 = add i32 %x, -1, !dbg !14
  %recurse2 = call i32 @test6_multiple_returns(i32 %sub2, i32 %y), !dbg !15
->%accumulate = add i32 %recurse2, %y, !dbg !16
  ret i32 %accumulate, !dbg !17
}

!16 = !DILocation(line: 9, column: 1, scope: !5)

After TailCallElim optimization:

define i32 @test6_multiple_returns(i32 %x, i32 %y) local_unnamed_addr !dbg !5 {
entry:
  br label %tailrecurse

tailrecurse:                                      ; preds = %default, %case99, %entry
  %accumulator.tr = phi i32 [ %accumulator.tr, %case99 ], [ 0, %entry ], [ %accumulate, %default ]
  %x.tr = phi i32 [ %x, %entry ], [ %sub1, %case99 ], [ %sub2, %default ]
  %ret.tr = phi i32 [ poison, %entry ], [ %current.ret.tr, %case99 ], [ %ret.tr, %default ]
  %ret.known.tr = phi i1 [ false, %entry ], [ true, %case99 ], [ %ret.known.tr, %default ]
  switch i32 %x.tr, label %default [
    i32 0, label %case0
    i32 99, label %case99
  ], !dbg !8

case0:                                            ; preds = %tailrecurse
  %helper = tail call i32 @test6_helper(), !dbg !9
->%accumulator.ret.tr2 = add i32 %accumulator.tr, %helper, !dbg !10
  %current.ret.tr1 = select i1 %ret.known.tr, i32 %ret.tr, i32 %accumulator.ret.tr2
  ret i32 %current.ret.tr1, !dbg !11

case99:                                           ; preds = %tailrecurse
  %sub1 = add i32 %x.tr, -1, !dbg !12
->%accumulator.ret.tr = add i32 %accumulator.tr, 18, !dbg !10
  %current.ret.tr = select i1 %ret.known.tr, i32 %ret.tr, i32 %accumulator.ret.tr
  br label %tailrecurse, !dbg !13

default:                                          ; preds = %tailrecurse
  %sub2 = add i32 %x.tr, -1, !dbg !14
  %accumulate = add i32 %accumulator.tr, %y, !dbg !10
  br label %tailrecurse, !dbg !15
}

!10 = !DILocation(line: 9, column: 1, scope: !5)

TailCallElimination-L777: The same as the above error. When either %accumulator.ret.tr or %accumulator.ret.tr1 is executed, block %if.then2 would be considered being executed.

Before TailCallElim optimization:

define i32 @test7_multiple_accumulators(i32 %a) local_unnamed_addr !dbg !18 {
entry:
  %tobool = icmp eq i32 %a, 0, !dbg !19
  br i1 %tobool, label %return, label %if.end, !dbg !20

if.end:                                           ; preds = %entry
  %and = and i32 %a, 1, !dbg !21
  %tobool1 = icmp eq i32 %and, 0, !dbg !22
  %sub = add nsw i32 %a, -1, !dbg !23
  br i1 %tobool1, label %if.end3, label %if.then2, !dbg !24

if.then2:                                         ; preds = %if.end
  %recurse1 = tail call i32 @test7_multiple_accumulators(i32 %sub), !dbg !25
->%accumulate1 = add nsw i32 %recurse1, 1, !dbg !26
  br label %return, !dbg !27

if.end3:                                          ; preds = %if.end
  %recurse2 = tail call i32 @test7_multiple_accumulators(i32 %sub), !dbg !28
  %accumulate2 = mul nsw i32 %recurse2, 2, !dbg !29
  br label %return, !dbg !30

return:                                           ; preds = %if.end3, %if.then2, %entry
  %retval.0 = phi i32 [ %accumulate1, %if.then2 ], [ %accumulate2, %if.end3 ], [ 0, %entry ], !dbg !31
  ret i32 %retval.0, !dbg !32
}

!26 = !DILocation(line: 18, column: 1, scope: !18)

After TailCallElim optimization:

define i32 @test7_multiple_accumulators(i32 %a) local_unnamed_addr !dbg !16 {
entry:
  br label %tailrecurse

tailrecurse:                                      ; preds = %if.then2, %entry
  %accumulator.tr = phi i32 [ 0, %entry ], [ %accumulate1, %if.then2 ]
  %a.tr = phi i32 [ %a, %entry ], [ %sub, %if.then2 ]
  %tobool = icmp eq i32 %a.tr, 0, !dbg !17
  br i1 %tobool, label %return, label %if.end, !dbg !18

if.end:                                           ; preds = %tailrecurse
  %and = and i32 %a.tr, 1, !dbg !19
  %tobool1 = icmp eq i32 %and, 0, !dbg !20
  %sub = add nsw i32 %a.tr, -1, !dbg !21
  br i1 %tobool1, label %if.end3, label %if.then2, !dbg !22

if.then2:                                         ; preds = %if.end
  %accumulate1 = add nsw i32 %accumulator.tr, 1, !dbg !23
  br label %tailrecurse, !dbg !24

if.end3:                                          ; preds = %if.end
  %recurse2 = tail call i32 @test7_multiple_accumulators(i32 %sub), !dbg !25
  %accumulate2 = mul nsw i32 %recurse2, 2, !dbg !26
->%accumulator.ret.tr = add nsw i32 %accumulator.tr, %accumulate2, !dbg !23
  ret i32 %accumulator.ret.tr, !dbg !27

return:                                           ; preds = %tailrecurse
->%accumulator.ret.tr1 = add nsw i32 %accumulator.tr, 0, !dbg !23
  ret i32 %accumulator.ret.tr1, !dbg !27
}

!23 = !DILocation(line: 18, column: 1, scope: !16)

The two test case are in llvm/test/Transforms/TailCallElim/accum_recursion.ll.

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