Skip to content

X86 MachineVerifier error from TLS_base_addr64 #45574

@jyknight

Description

@jyknight
Bugzilla Link 46229
Version trunk
OS All
CC @topperc,@RKSimon,@rotateright

Extended Description

TLS access can occur within a call sequence, which ends up generating a ADJCALLSTACK sequence nested within another ADJCALLSTACK sequence. Which, at least according to the MachineVerifier, is illegal.

Run: llc -verify-machineinstrs -relocation-model=pic -o - test.ll

test.ll

target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@TLS = internal thread_local global i64 zeroinitializer, align 8
declare void @bar(i64*)
define internal void @foo() {
  call void @bar(i64* @TLS)
  call void @bar(i64* @TLS)
  ret void
}

Results in:

*** Bad machine code: FrameSetup is after another FrameSetup ***
- function:    foo
- basic block: %bb.0  (0x8e98c48)
- instruction: ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp

*** Bad machine code: FrameDestroy is not after a FrameSetup ***
- function:    foo
- basic block: %bb.0  (0x8e98c48)
- instruction: ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp

The result of ISel is like this -- with the TLS access within the call-sequence:

 ADJCALLSTACKDOWN64
 TLS_base_addr64
 ...
 CALL64pcrel32
 ADJCALLSTACKUP64

And then in expand-pseudos, the TLS_base_addr64 pseudo surrounds itself with another set of ADJCALLSTACK.

So, you end up with:

 ADJCALLSTACKDOWN64
 ADJCALLSTACKDOWN64
 TLS_base_addr64
 ADJCALLSTACKUP64
 ...
 CALL64pcrel32
 ADJCALLSTACKUP64

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions