reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
; Test IPA over a single combined file
; RUN: llvm-as %s -o %t0.bc
; RUN: llvm-as %S/Inputs/ipa-alias.ll -o %t1.bc
; RUN: llvm-link %t0.bc %t1.bc -o %t.combined.bc
; RUN: opt -S -analyze -stack-safety-local %t.combined.bc | FileCheck %s --check-prefixes=CHECK,LOCAL
; RUN: opt -S -passes="print<stack-safety-local>" -disable-output %t.combined.bc 2>&1 | FileCheck %s --check-prefixes=CHECK,LOCAL
; RUN: opt -S -analyze -stack-safety %t.combined.bc | FileCheck %s --check-prefixes=CHECK,GLOBAL
; RUN: opt -S -passes="print-stack-safety" -disable-output %t.combined.bc 2>&1 | FileCheck %s --check-prefixes=CHECK,GLOBAL

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

declare void @PreemptableAliasWrite1(i8* %p)
declare void @AliasToPreemptableAliasWrite1(i8* %p)

declare void @InterposableAliasWrite1(i8* %p)
; Aliases to interposable aliases are not allowed

declare void @AliasWrite1(i8* %p)

declare void @BitcastAliasWrite1(i32* %p)
declare void @AliasToBitcastAliasWrite1(i8* %p)

; Call to dso_preemptable alias to a dso_local aliasee
define void @PreemptableAliasCall() {
; CHECK-LABEL: @PreemptableAliasCall dso_preemptable{{$}}
; CHECK-NEXT: args uses:
; CHECK-NEXT: allocas uses:
; LOCAL-NEXT: x1[1]: empty-set, @PreemptableAliasWrite1(arg0, [0,1)){{$}}
; GLOBAL-NEXT: x1[1]: full-set, @PreemptableAliasWrite1(arg0, [0,1)){{$}}
; LOCAL-NEXT: x2[1]: empty-set, @AliasToPreemptableAliasWrite1(arg0, [0,1)){{$}}
; GLOBAL-NEXT: x2[1]: [0,1), @AliasToPreemptableAliasWrite1(arg0, [0,1)){{$}}
; CHECK-NOT: ]:
entry:
  %x1 = alloca i8
  call void @PreemptableAliasWrite1(i8* %x1)

  %x2 = alloca i8
; Alias to a preemptable alias is not preemptable
  call void @AliasToPreemptableAliasWrite1(i8* %x2)
  ret void
}

; Call to an interposable alias to a non-interposable aliasee
define void @InterposableAliasCall() {
; CHECK-LABEL: @InterposableAliasCall dso_preemptable{{$}}
; CHECK-NEXT: args uses:
; CHECK-NEXT: allocas uses:
; LOCAL-NEXT: x[1]: empty-set, @InterposableAliasWrite1(arg0, [0,1)){{$}}
; GLOBAL-NEXT: x[1]: full-set, @InterposableAliasWrite1(arg0, [0,1)){{$}}
; CHECK-NOT: ]:
entry:
  %x = alloca i8
; ThinLTO can resolve the prevailing implementation for interposable definitions.
  call void @InterposableAliasWrite1(i8* %x)
  ret void
}

; Call to a dso_local/non-interposable alias/aliasee
define void @AliasCall() {
; CHECK-LABEL: @AliasCall dso_preemptable{{$}}
; CHECK-NEXT: args uses:
; CHECK-NEXT: allocas uses:
; LOCAL-NEXT: x[1]: empty-set, @AliasWrite1(arg0, [0,1)){{$}}
; GLOBAL-NEXT: x[1]: [0,1), @AliasWrite1(arg0, [0,1)){{$}}
; CHECK-NOT: ]:
entry:
  %x = alloca i8
  call void @AliasWrite1(i8* %x)
  ret void
}

; Call to a bitcasted dso_local/non-interposable alias/aliasee
define void @BitcastAliasCall() {
; CHECK-LABEL: @BitcastAliasCall dso_preemptable{{$}}
; CHECK-NEXT: args uses:
; CHECK-NEXT: allocas uses:
; LOCAL-NEXT: x1[4]: empty-set, @BitcastAliasWrite1(arg0, [0,1)){{$}}
; GLOBAL-NEXT: x1[4]: [0,1), @BitcastAliasWrite1(arg0, [0,1)){{$}}
; LOCAL-NEXT: x2[1]: empty-set, @AliasToBitcastAliasWrite1(arg0, [0,1)){{$}}
; GLOBAL-NEXT: x2[1]: [0,1), @AliasToBitcastAliasWrite1(arg0, [0,1)){{$}}
; CHECK-NOT: ]:
entry:
  %x1 = alloca i32
  call void @BitcastAliasWrite1(i32* %x1)
  %x2 = alloca i8
  call void @AliasToBitcastAliasWrite1(i8* %x2)
  ret void
}

; The rest is from Inputs/ipa-alias.ll

; CHECK-LABEL: @Write1{{$}}
; CHECK-NEXT: args uses:
; CHECK-NEXT: p[]: [0,1){{$}}
; CHECK-NEXT: allocas uses:
; CHECK-NOT: ]:

; GLOBAL-LABEL: @InterposableAliasWrite1 interposable{{$}}
; GLOBAL-NEXT: args uses:
; GLOBAL-NEXT: <N/A>[]: [0,1), @Write1(arg0, [0,1)){{$}}
; GLOBAL-NEXT: allocas uses:
; GLOBAL-NOT: ]:

; GLOBAL-LABEL: @PreemptableAliasWrite1 dso_preemptable{{$}}
; GLOBAL-NEXT: args uses:
; GLOBAL-NEXT: <N/A>[]: [0,1), @Write1(arg0, [0,1)){{$}}
; GLOBAL-NEXT: allocas uses:
; GLOBAL-NOT: ]:

; GLOBAL-LABEL: @AliasToPreemptableAliasWrite1{{$}}
; GLOBAL-NEXT: args uses:
; GLOBAL-NEXT: <N/A>[]: [0,1), @Write1(arg0, [0,1)){{$}}
; GLOBAL-NEXT: allocas uses:
; GLOBAL-NOT: ]:

; GLOBAL-LABEL: @AliasWrite1{{$}}
; GLOBAL-NEXT: args uses:
; GLOBAL-NEXT: <N/A>[]: [0,1), @Write1(arg0, [0,1)){{$}}
; GLOBAL-NEXT: allocas uses:
; GLOBAL-NOT: ]:

; GLOBAL-LABEL: @BitcastAliasWrite1{{$}}
; GLOBAL-NEXT: args uses:
; GLOBAL-NEXT: <N/A>[]: [0,1), @Write1(arg0, [0,1)){{$}}
; GLOBAL-NEXT: allocas uses:
; GLOBAL-NOT: ]:

; GLOBAL-LABEL: @AliasToBitcastAliasWrite1{{$}}
; GLOBAL-NEXT: args uses:
; GLOBAL-NEXT: <N/A>[]: [0,1), @Write1(arg0, [0,1)){{$}}
; GLOBAL-NEXT: allocas uses:
; GLOBAL-NOT: ]: