Skip to content

[x86] Undefined temporary symbol .Ltmp0 created by blockaddress #161164

@tetzank

Description

@tetzank

The backend pass codegenprepare eliminates a basic block from which the address was taken in another function. There seems to be some mechanism in place to prevent this as a second symbol is kept alive even though the basic block it refers to got removed. It gets the following comment in the assembly output:

.Ltmp1:                                 # Address of block that was removed by CodeGen

Unfortunately, the definition of the first temporary symbol .Ltmp0 is lost. At least two blockaddress expressions are required to trigger the issue.

Reproducer:

target datalayout = "i64:64:64-i128:128:128-a0:8:8"
target triple = "x86_64-unknown-linux-gnu"

define void @foo0(ptr %jumpAddr) {
  store ptr blockaddress(@main, %scope2_exit), ptr %jumpAddr, align 8   ; uses .Ltmp0
  ret void
}

define void @foo1(ptr %jumpAddr) {
  store ptr blockaddress(@main, %scope1_exit), ptr %jumpAddr, align 8   ; uses .Ltmp1
  ret void
}

define i64 @main(ptr %p, i1 %c1) {
first:
  br label %loop_head

loop_head:                                        ; preds = %loop_end, %first
  br i1 %c1, label %scope0, label %scope1

scope1:                                           ; preds = %loop_head
  br i1 %c1, label %scope1_exit, label %scope2

scope2:                                           ; preds = %scope1
  br i1 %c1, label %scope2_exit, label %inner

inner:                                            ; preds = %scope2
  br label %scope2_exit

scope2_exit:                                      ; preds = %inner, %scope2
  %phi2 = phi ptr [ %p, %inner ], [ null, %scope2 ]
  br label %scope1_exit

scope1_exit:                                      ; preds = %scope2_exit, %scope1
  %phi1 = phi ptr [ %phi2, %scope2_exit ], [ null, %scope1 ]
  %val1 = load i128, ptr %phi1, align 16
  br label %loop_end

scope0:                                           ; preds = %loop_head
  %ptr0 = select i1 %c1, ptr null, ptr %p
  %val0 = load i128, ptr %ptr0, align 16
  br label %loop_end

loop_end:                                         ; preds = %scope0, %scope1_exit
  %storemerge = phi i128 [ %val1, %scope1_exit ], [ %val0, %scope0 ]
  store i128 %storemerge, ptr %p, align 16
  br label %loop_head
}

The undefined symbol is detected when writing the ELF file.

$ llc --filetype=obj -o out.o minimal.ll
<unknown>:0: error: Undefined temporary symbol .Ltmp0

I was not able to run codegenprepare as a single pass. opt --passes=codegenprepare crashes and llc --passes only works on .mir files.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions