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