1; Test IPA over a single combined file 2; RUN: llvm-as %s -o %t0.bc 3; RUN: llvm-as %S/Inputs/ipa-alias.ll -o %t1.bc 4; RUN: llvm-link %t0.bc %t1.bc -o %t.combined.bc 5; RUN: opt -S -analyze -stack-safety-local %t.combined.bc | FileCheck %s --check-prefixes=CHECK,LOCAL 6; RUN: opt -S -passes="print<stack-safety-local>" -disable-output %t.combined.bc 2>&1 | FileCheck %s --check-prefixes=CHECK,LOCAL 7; RUN: opt -S -analyze -stack-safety %t.combined.bc | FileCheck %s --check-prefixes=CHECK,GLOBAL 8; RUN: opt -S -passes="print-stack-safety" -disable-output %t.combined.bc 2>&1 | FileCheck %s --check-prefixes=CHECK,GLOBAL 9 10target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 11target triple = "x86_64-unknown-linux-gnu" 12 13declare void @PreemptableAliasWrite1(i8* %p) 14declare void @AliasToPreemptableAliasWrite1(i8* %p) 15 16declare void @InterposableAliasWrite1(i8* %p) 17; Aliases to interposable aliases are not allowed 18 19declare void @AliasWrite1(i8* %p) 20 21declare void @BitcastAliasWrite1(i32* %p) 22declare void @AliasToBitcastAliasWrite1(i8* %p) 23 24; Call to dso_preemptable alias to a dso_local aliasee 25define void @PreemptableAliasCall() { 26; CHECK-LABEL: @PreemptableAliasCall dso_preemptable{{$}} 27; CHECK-NEXT: args uses: 28; CHECK-NEXT: allocas uses: 29; LOCAL-NEXT: x1[1]: empty-set, @PreemptableAliasWrite1(arg0, [0,1)){{$}} 30; GLOBAL-NEXT: x1[1]: full-set, @PreemptableAliasWrite1(arg0, [0,1)){{$}} 31; LOCAL-NEXT: x2[1]: empty-set, @AliasToPreemptableAliasWrite1(arg0, [0,1)){{$}} 32; GLOBAL-NEXT: x2[1]: [0,1), @AliasToPreemptableAliasWrite1(arg0, [0,1)){{$}} 33; CHECK-NOT: ]: 34entry: 35 %x1 = alloca i8 36 call void @PreemptableAliasWrite1(i8* %x1) 37 38 %x2 = alloca i8 39; Alias to a preemptable alias is not preemptable 40 call void @AliasToPreemptableAliasWrite1(i8* %x2) 41 ret void 42} 43 44; Call to an interposable alias to a non-interposable aliasee 45define void @InterposableAliasCall() { 46; CHECK-LABEL: @InterposableAliasCall dso_preemptable{{$}} 47; CHECK-NEXT: args uses: 48; CHECK-NEXT: allocas uses: 49; LOCAL-NEXT: x[1]: empty-set, @InterposableAliasWrite1(arg0, [0,1)){{$}} 50; GLOBAL-NEXT: x[1]: full-set, @InterposableAliasWrite1(arg0, [0,1)){{$}} 51; CHECK-NOT: ]: 52entry: 53 %x = alloca i8 54; ThinLTO can resolve the prevailing implementation for interposable definitions. 55 call void @InterposableAliasWrite1(i8* %x) 56 ret void 57} 58 59; Call to a dso_local/non-interposable alias/aliasee 60define void @AliasCall() { 61; CHECK-LABEL: @AliasCall dso_preemptable{{$}} 62; CHECK-NEXT: args uses: 63; CHECK-NEXT: allocas uses: 64; LOCAL-NEXT: x[1]: empty-set, @AliasWrite1(arg0, [0,1)){{$}} 65; GLOBAL-NEXT: x[1]: [0,1), @AliasWrite1(arg0, [0,1)){{$}} 66; CHECK-NOT: ]: 67entry: 68 %x = alloca i8 69 call void @AliasWrite1(i8* %x) 70 ret void 71} 72 73; Call to a bitcasted dso_local/non-interposable alias/aliasee 74define void @BitcastAliasCall() { 75; CHECK-LABEL: @BitcastAliasCall dso_preemptable{{$}} 76; CHECK-NEXT: args uses: 77; CHECK-NEXT: allocas uses: 78; LOCAL-NEXT: x1[4]: empty-set, @BitcastAliasWrite1(arg0, [0,1)){{$}} 79; GLOBAL-NEXT: x1[4]: [0,1), @BitcastAliasWrite1(arg0, [0,1)){{$}} 80; LOCAL-NEXT: x2[1]: empty-set, @AliasToBitcastAliasWrite1(arg0, [0,1)){{$}} 81; GLOBAL-NEXT: x2[1]: [0,1), @AliasToBitcastAliasWrite1(arg0, [0,1)){{$}} 82; CHECK-NOT: ]: 83entry: 84 %x1 = alloca i32 85 call void @BitcastAliasWrite1(i32* %x1) 86 %x2 = alloca i8 87 call void @AliasToBitcastAliasWrite1(i8* %x2) 88 ret void 89} 90 91; The rest is from Inputs/ipa-alias.ll 92 93; CHECK-LABEL: @Write1{{$}} 94; CHECK-NEXT: args uses: 95; CHECK-NEXT: p[]: [0,1){{$}} 96; CHECK-NEXT: allocas uses: 97; CHECK-NOT: ]: 98 99; GLOBAL-LABEL: @InterposableAliasWrite1 interposable{{$}} 100; GLOBAL-NEXT: args uses: 101; GLOBAL-NEXT: <N/A>[]: [0,1), @Write1(arg0, [0,1)){{$}} 102; GLOBAL-NEXT: allocas uses: 103; GLOBAL-NOT: ]: 104 105; GLOBAL-LABEL: @PreemptableAliasWrite1 dso_preemptable{{$}} 106; GLOBAL-NEXT: args uses: 107; GLOBAL-NEXT: <N/A>[]: [0,1), @Write1(arg0, [0,1)){{$}} 108; GLOBAL-NEXT: allocas uses: 109; GLOBAL-NOT: ]: 110 111; GLOBAL-LABEL: @AliasToPreemptableAliasWrite1{{$}} 112; GLOBAL-NEXT: args uses: 113; GLOBAL-NEXT: <N/A>[]: [0,1), @Write1(arg0, [0,1)){{$}} 114; GLOBAL-NEXT: allocas uses: 115; GLOBAL-NOT: ]: 116 117; GLOBAL-LABEL: @AliasWrite1{{$}} 118; GLOBAL-NEXT: args uses: 119; GLOBAL-NEXT: <N/A>[]: [0,1), @Write1(arg0, [0,1)){{$}} 120; GLOBAL-NEXT: allocas uses: 121; GLOBAL-NOT: ]: 122 123; GLOBAL-LABEL: @BitcastAliasWrite1{{$}} 124; GLOBAL-NEXT: args uses: 125; GLOBAL-NEXT: <N/A>[]: [0,1), @Write1(arg0, [0,1)){{$}} 126; GLOBAL-NEXT: allocas uses: 127; GLOBAL-NOT: ]: 128 129; GLOBAL-LABEL: @AliasToBitcastAliasWrite1{{$}} 130; GLOBAL-NEXT: args uses: 131; GLOBAL-NEXT: <N/A>[]: [0,1), @Write1(arg0, [0,1)){{$}} 132; GLOBAL-NEXT: allocas uses: 133; GLOBAL-NOT: ]: 134