brintos

brintos / llvm-project-archived public Read only

0
0
Text · 26.0 KiB · 0e2a08f Raw
748 lines · plain
1; REQUIRES: aarch64-registered-target2 3; RUN: llvm-as %s -o %t0.bc4; RUN: llvm-as %S/Inputs/ipa.ll -o %t1.bc5; RUN: llvm-link -disable-lazy-loading %t0.bc %t1.bc -o %t.combined.bc6 7; RUN: opt -S -passes="print<stack-safety-local>" -disable-output %t.combined.bc 2>&1 | FileCheck %s --check-prefixes=CHECK,LOCAL8 9; RUN: opt -S -passes="print-stack-safety" -disable-output %t.combined.bc 2>&1 | FileCheck %s --check-prefixes=CHECK,GLOBAL,NOLTO10 11; Do an end-to-test using the new LTO API12; TODO: Hideous llvm-lto2 invocation, add a --default-symbol-resolution to llvm-lto2?13; RUN: opt -module-summary %s -o %t.summ0.bc14; RUN: opt -module-summary %S/Inputs/ipa.ll -o %t.summ1.bc15 16; RUN: llvm-dis %t.summ0.bc -o - > %t.ids.txt17; RUN: llvm-dis %t.summ1.bc -o - >> %t.ids.txt18 19; DEFINE: %{res} = \20; DEFINE:  -r %t.summ0.bc,ExternalCall, \21; DEFINE:  -r %t.summ0.bc,f1,px \22; DEFINE:  -r %t.summ0.bc,f2,px \23; DEFINE:  -r %t.summ0.bc,f3,px \24; DEFINE:  -r %t.summ0.bc,f4,px \25; DEFINE:  -r %t.summ0.bc,f5,px \26; DEFINE:  -r %t.summ0.bc,f6,px \27; DEFINE:  -r %t.summ0.bc,f7,px \28; DEFINE:  -r %t.summ0.bc,f8left,px \29; DEFINE:  -r %t.summ0.bc,f8oobleft,px \30; DEFINE:  -r %t.summ0.bc,f8oobright,px \31; DEFINE:  -r %t.summ0.bc,f8right,px \32; DEFINE:  -r %t.summ0.bc,InterposableCall,px \33; DEFINE:  -r %t.summ0.bc,InterposableWrite1, \34; DEFINE:  -r %t.summ0.bc,PreemptableCall,px \35; DEFINE:  -r %t.summ0.bc,PreemptableWrite1, \36; DEFINE:  -r %t.summ0.bc,PrivateCall,px \37; DEFINE:  -r %t.summ0.bc,Rec2, \38; DEFINE:  -r %t.summ0.bc,RecursiveNoOffset, \39; DEFINE:  -r %t.summ0.bc,RecursiveWithOffset, \40; DEFINE:  -r %t.summ0.bc,ReturnDependent, \41; DEFINE:  -r %t.summ0.bc,TestCrossModuleConflict,px \42; DEFINE:  -r %t.summ0.bc,TestCrossModuleOnce,px \43; DEFINE:  -r %t.summ0.bc,TestCrossModuleTwice,px \44; DEFINE:  -r %t.summ0.bc,TestCrossModuleWeak,px \45; DEFINE:  -r %t.summ0.bc,TestRecursiveNoOffset,px \46; DEFINE:  -r %t.summ0.bc,TestRecursiveWithOffset,px \47; DEFINE:  -r %t.summ0.bc,TestUpdateArg,px \48; DEFINE:  -r %t.summ0.bc,TwoArguments,px \49; DEFINE:  -r %t.summ0.bc,TwoArgumentsOOBBoth,px \50; DEFINE:  -r %t.summ0.bc,TwoArgumentsOOBOne,px \51; DEFINE:  -r %t.summ0.bc,TwoArgumentsOOBOther,px \52; DEFINE:  -r %t.summ0.bc,Weak,x \53; DEFINE:  -r %t.summ0.bc,Write1, \54; DEFINE:  -r %t.summ0.bc,Write1DiffModule,x \55; DEFINE:  -r %t.summ0.bc,Write1Module0,px \56; DEFINE:  -r %t.summ0.bc,Write1Private,x \57; DEFINE:  -r %t.summ0.bc,Write1SameModule,x \58; DEFINE:  -r %t.summ0.bc,Write1Weak,x \59; DEFINE:  -r %t.summ0.bc,Write4_2, \60; DEFINE:  -r %t.summ0.bc,Write4, \61; DEFINE:  -r %t.summ0.bc,Write8, \62; DEFINE:  -r %t.summ0.bc,WriteAndReturn8, \63; DEFINE:  -r %t.summ1.bc,ExternalCall,px \64; DEFINE:  -r %t.summ1.bc,InterposableWrite1,px \65; DEFINE:  -r %t.summ1.bc,PreemptableWrite1,px \66; DEFINE:  -r %t.summ1.bc,Rec0,px \67; DEFINE:  -r %t.summ1.bc,Rec1,px \68; DEFINE:  -r %t.summ1.bc,Rec2,px \69; DEFINE:  -r %t.summ1.bc,RecursiveNoOffset,px \70; DEFINE:  -r %t.summ1.bc,RecursiveWithOffset,px \71; DEFINE:  -r %t.summ1.bc,ReturnAlloca,px \72; DEFINE:  -r %t.summ1.bc,ReturnDependent,px \73; DEFINE:  -r %t.summ1.bc,Weak,x \74; DEFINE:  -r %t.summ1.bc,Write1,px \75; DEFINE:  -r %t.summ1.bc,Write1DiffModule,px \76; DEFINE:  -r %t.summ1.bc,Write1Module0,x \77; DEFINE:  -r %t.summ1.bc,Write1Private,px \78; DEFINE:  -r %t.summ1.bc,Write1SameModule,px \79; DEFINE:  -r %t.summ1.bc,Write1Weak,px \80; DEFINE:  -r %t.summ1.bc,Write4_2,px \81; DEFINE:  -r %t.summ1.bc,Write4,px \82; DEFINE:  -r %t.summ1.bc,Write8,px \83; DEFINE:  -r %t.summ1.bc,WriteAndReturn8,px84 85; 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 \86; RUN:  %{res} \87; RUN:    2>&1 | FileCheck %s --check-prefixes=CHECK,GLOBAL,LTO88 89; RUN: llvm-lto2 run %t.summ0.bc %t.summ1.bc -o %t.lto -stack-safety-run -thinlto-distributed-indexes -thinlto-threads 1 -O0 %{res}90; RUN: llvm-dis %t.summ1.bc.thinlto.bc -o - >> %t.ids.txt91; RUN: FileCheck --check-prefixes=INDEX %s < %t.ids.txt92 93target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"94target triple = "aarch64-unknown-linux"95 96attributes #0 = { noinline sanitize_memtag "target-features"="+mte,+neon" }97 98declare void @Write1(ptr %p)99declare void @Write4(ptr %p)100declare void @Write4_2(ptr %p, ptr %q)101declare void @Write8(ptr %p)102declare dso_local ptr @WriteAndReturn8(ptr %p)103declare dso_local void @ExternalCall(ptr %p)104declare void @PreemptableWrite1(ptr %p)105declare void @InterposableWrite1(ptr %p)106declare ptr @ReturnDependent(ptr %p)107declare void @Rec2(ptr %p)108declare void @RecursiveNoOffset(ptr %p, i32 %size, ptr %acc)109declare void @RecursiveWithOffset(i32 %size, ptr %acc)110declare void @Write1SameModule(ptr %p)111declare void @Write1DiffModule(ptr %p)112declare void @Write1Private(ptr %p)113declare void @Write1Weak(ptr %p)114 115; Basic out-of-bounds.116define void @f1() #0 {117; CHECK-LABEL: @f1 dso_preemptable{{$}}118; CHECK-NEXT: args uses:119; CHECK-NEXT: allocas uses:120; LOCAL-NEXT: x[4]: empty-set, @Write8(arg0, [0,1)){{$}}121; GLOBAL-NEXT: x[4]: [0,8), @Write8(arg0, [0,1)){{$}}122; GLOBAL-NEXT: safe accesses:123; CHECK-EMPTY:124entry:125  %x = alloca i32, align 4126  call void @Write8(ptr %x)127  ret void128}129 130; Basic in-bounds.131define void @f2() #0 {132; CHECK-LABEL: @f2 dso_preemptable{{$}}133; CHECK-NEXT: args uses:134; CHECK-NEXT: allocas uses:135; LOCAL-NEXT: x[4]: empty-set, @Write1(arg0, [0,1)){{$}}136; GLOBAL-NEXT: x[4]: [0,1), @Write1(arg0, [0,1)){{$}}137; GLOBAL-NEXT: safe accesses:138; CHECK-EMPTY:139entry:140  %x = alloca i32, align 4141  call void @Write1(ptr %x)142  ret void143}144 145; Another basic in-bounds.146define void @f3() #0 {147; CHECK-LABEL: @f3 dso_preemptable{{$}}148; CHECK-NEXT: args uses:149; CHECK-NEXT: allocas uses:150; LOCAL-NEXT: x[4]: empty-set, @Write4(arg0, [0,1)){{$}}151; GLOBAL-NEXT: x[4]: [0,4), @Write4(arg0, [0,1)){{$}}152; GLOBAL-NEXT: safe accesses:153; CHECK-EMPTY:154entry:155  %x = alloca i32, align 4156  call void @Write4(ptr %x)157  ret void158}159 160; In-bounds with offset.161define void @f4() #0 {162; CHECK-LABEL: @f4 dso_preemptable{{$}}163; CHECK-NEXT: args uses:164; CHECK-NEXT: allocas uses:165; LOCAL-NEXT: x[4]: empty-set, @Write1(arg0, [1,2)){{$}}166; GLOBAL-NEXT: x[4]: [1,2), @Write1(arg0, [1,2)){{$}}167; GLOBAL-NEXT: safe accesses:168; CHECK-EMPTY:169entry:170  %x = alloca i32, align 4171  %x2 = getelementptr i8, ptr %x, i64 1172  call void @Write1(ptr %x2)173  ret void174}175 176; Out-of-bounds with offset.177define void @f5() #0 {178; CHECK-LABEL: @f5 dso_preemptable{{$}}179; CHECK-NEXT: args uses:180; CHECK-NEXT: allocas uses:181; LOCAL-NEXT: empty-set, @Write4(arg0, [1,2)){{$}}182; GLOBAL-NEXT: [1,5), @Write4(arg0, [1,2)){{$}}183; GLOBAL-NEXT: safe accesses:184; CHECK-EMPTY:185entry:186  %x = alloca i32, align 4187  %x2 = getelementptr i8, ptr %x, i64 1188  call void @Write4(ptr %x2)189  ret void190}191 192; External call.193define void @f6() #0 {194; CHECK-LABEL: @f6 dso_preemptable{{$}}195; CHECK-NEXT: args uses:196; CHECK-NEXT: allocas uses:197; LOCAL-NEXT: x[4]: empty-set, @ExternalCall(arg0, [0,1)){{$}}198; GLOBAL-NEXT: x[4]: full-set, @ExternalCall(arg0, [0,1)){{$}}199; GLOBAL-NEXT: safe accesses:200; CHECK-EMPTY:201entry:202  %x = alloca i32, align 4203  call void @ExternalCall(ptr %x)204  ret void205}206 207; Call to dso_preemptable function208define void @PreemptableCall() #0 {209; CHECK-LABEL: @PreemptableCall dso_preemptable{{$}}210; CHECK-NEXT: args uses:211; CHECK-NEXT: allocas uses:212; LOCAL-NEXT: x[4]: empty-set, @PreemptableWrite1(arg0, [0,1)){{$}}213; GLOBAL-NEXT: x[4]: full-set, @PreemptableWrite1(arg0, [0,1)){{$}}214; GLOBAL-NEXT: safe accesses:215; CHECK-EMPTY:216entry:217  %x = alloca i32, align 4218  call void @PreemptableWrite1(ptr %x)219  ret void220}221 222; Call to function with interposable linkage223define void @InterposableCall() #0 {224; CHECK-LABEL: @InterposableCall dso_preemptable{{$}}225; CHECK-NEXT: args uses:226; CHECK-NEXT: allocas uses:227; LOCAL-NEXT: x[4]: empty-set, @InterposableWrite1(arg0, [0,1)){{$}}228; NOLTO-NEXT: x[4]: full-set, @InterposableWrite1(arg0, [0,1)){{$}}229; LTO-NEXT: x[4]: [0,1), @InterposableWrite1(arg0, [0,1)){{$}}230; GLOBAL-NEXT: safe accesses:231; CHECK-EMPTY:232entry:233  %x = alloca i32, align 4234  call void @InterposableWrite1(ptr %x)235  ret void236}237 238; Call to function with private linkage239define void @PrivateCall() #0 {240; CHECK-LABEL: @PrivateCall dso_preemptable{{$}}241; CHECK-NEXT: args uses:242; CHECK-NEXT: allocas uses:243; LOCAL-NEXT: x[4]: empty-set, @PrivateWrite1(arg0, [0,1)){{$}}244; GLOBAL-NEXT: x[4]: [0,1), @PrivateWrite1(arg0, [0,1)){{$}}245; GLOBAL-NEXT: safe accesses:246; CHECK-EMPTY:247entry:248  %x = alloca i32, align 4249  call void @PrivateWrite1(ptr %x)250  ret void251}252 253define private void @PrivateWrite1(ptr %p) #0 {254; CHECK-LABEL: @PrivateWrite1{{$}}255; CHECK-NEXT: args uses:256; CHECK-NEXT: p[]: [0,1){{$}}257; CHECK-NEXT: allocas uses:258; GLOBAL-NEXT: safe accesses:259; GLOBAL-NEXT: store i8 0, ptr %p, align 1260; CHECK-EMPTY:261entry:262  store i8 0, ptr %p, align 1263  ret void264}265 266; Caller returns a dependent value.267; FIXME: alloca considered unsafe even if the return value is unused.268define void @f7() #0 {269; CHECK-LABEL: @f7 dso_preemptable{{$}}270; CHECK-NEXT: args uses:271; CHECK-NEXT: allocas uses:272; LOCAL-NEXT: x[4]: empty-set, @ReturnDependent(arg0, [0,1)){{$}}273; GLOBAL-NEXT: x[4]: full-set, @ReturnDependent(arg0, [0,1)){{$}}274; GLOBAL-NEXT: safe accesses:275; CHECK-EMPTY:276entry:277  %x = alloca i32, align 4278  %x2 = call ptr @ReturnDependent(ptr %x)279  ret void280}281 282define void @f8left() #0 {283; CHECK-LABEL: @f8left dso_preemptable{{$}}284; CHECK-NEXT: args uses:285; CHECK-NEXT: allocas uses:286; LOCAL-NEXT: x[8]: empty-set, @Rec2(arg0, [2,3)){{$}}287; GLOBAL-NEXT: x[8]: [0,4), @Rec2(arg0, [2,3)){{$}}288; GLOBAL-NEXT: safe accesses:289; CHECK-EMPTY:290entry:291  %x = alloca i64, align 4292  %x2 = getelementptr i8, ptr %x, i64 2293; 2 + [-2, 2) = [0, 4) => OK294  call void @Rec2(ptr %x2)295  ret void296}297 298define void @f8right() #0 {299; CHECK-LABEL: @f8right dso_preemptable{{$}}300; CHECK-NEXT: args uses:301; CHECK-NEXT: allocas uses:302; LOCAL-NEXT: x[8]: empty-set, @Rec2(arg0, [6,7)){{$}}303; GLOBAL-NEXT: x[8]: [4,8), @Rec2(arg0, [6,7)){{$}}304; GLOBAL-NEXT: safe accesses:305; CHECK-EMPTY:306entry:307  %x = alloca i64, align 4308  %x2 = getelementptr i8, ptr %x, i64 6309; 6 + [-2, 2) = [4, 8) => OK310  call void @Rec2(ptr %x2)311  ret void312}313 314define void @f8oobleft() #0 {315; CHECK-LABEL: @f8oobleft dso_preemptable{{$}}316; CHECK-NEXT: args uses:317; CHECK-NEXT: allocas uses:318; LOCAL-NEXT: x[8]: empty-set, @Rec2(arg0, [1,2)){{$}}319; GLOBAL-NEXT: x[8]: [-1,3), @Rec2(arg0, [1,2)){{$}}320; GLOBAL-NEXT: safe accesses:321; CHECK-EMPTY:322entry:323  %x = alloca i64, align 4324  %x2 = getelementptr i8, ptr %x, i64 1325; 1 + [-2, 2) = [-1, 3) => NOT OK326  call void @Rec2(ptr %x2)327  ret void328}329 330define void @f8oobright() #0 {331; CHECK-LABEL: @f8oobright dso_preemptable{{$}}332; CHECK-NEXT: args uses:333; CHECK-NEXT: allocas uses:334; LOCAL-NEXT: x[8]: empty-set, @Rec2(arg0, [7,8)){{$}}335; GLOBAL-NEXT: x[8]: [5,9), @Rec2(arg0, [7,8)){{$}}336; GLOBAL-NEXT: safe accesses:337; CHECK-EMPTY:338entry:339  %x = alloca i64, align 4340  %x2 = getelementptr i8, ptr %x, i64 7341; 7 + [-2, 2) = [5, 9) => NOT OK342  call void @Rec2(ptr %x2)343  ret void344}345 346define void @TwoArguments() #0 {347; CHECK-LABEL: @TwoArguments dso_preemptable{{$}}348; CHECK-NEXT: args uses:349; CHECK-NEXT: allocas uses:350; LOCAL-NEXT: x[8]: empty-set, @Write4_2(arg0, [4,5)), @Write4_2(arg1, [0,1)){{$}}351; GLOBAL-NEXT: x[8]: [0,8), @Write4_2(arg0, [4,5)), @Write4_2(arg1, [0,1)){{$}}352; GLOBAL-NEXT: safe accesses:353; CHECK-EMPTY:354entry:355  %x = alloca i64, align 4356  %x2 = getelementptr i8, ptr %x, i64 4357  call void @Write4_2(ptr %x2, ptr %x)358  ret void359}360 361define void @TwoArgumentsOOBOne() #0 {362; CHECK-LABEL: @TwoArgumentsOOBOne dso_preemptable{{$}}363; CHECK-NEXT: args uses:364; CHECK-NEXT: allocas uses:365; LOCAL-NEXT: x[8]: empty-set, @Write4_2(arg0, [5,6)), @Write4_2(arg1, [0,1)){{$}}366; GLOBAL-NEXT: x[8]: [0,9), @Write4_2(arg0, [5,6)), @Write4_2(arg1, [0,1)){{$}}367; GLOBAL-NEXT: safe accesses:368; CHECK-EMPTY:369entry:370  %x = alloca i64, align 4371  %x2 = getelementptr i8, ptr %x, i64 5372  call void @Write4_2(ptr %x2, ptr %x)373  ret void374}375 376define void @TwoArgumentsOOBOther() #0 {377; CHECK-LABEL: @TwoArgumentsOOBOther dso_preemptable{{$}}378; CHECK-NEXT: args uses:379; CHECK-NEXT: allocas uses:380; LOCAL-NEXT: x[8]: empty-set, @Write4_2(arg0, [4,5)), @Write4_2(arg1, [-1,0)){{$}}381; GLOBAL-NEXT: x[8]: [-1,8), @Write4_2(arg0, [4,5)), @Write4_2(arg1, [-1,0)){{$}}382; GLOBAL-NEXT: safe accesses:383; CHECK-EMPTY:384entry:385  %x = alloca i64, align 4386  %x1 = getelementptr i8, ptr %x, i64 -1387  %x2 = getelementptr i8, ptr %x, i64 4388  call void @Write4_2(ptr %x2, ptr %x1)389  ret void390}391 392define void @TwoArgumentsOOBBoth() #0 {393; CHECK-LABEL: @TwoArgumentsOOBBoth dso_preemptable{{$}}394; CHECK-NEXT: args uses:395; CHECK-NEXT: allocas uses:396; LOCAL-NEXT: x[8]: empty-set, @Write4_2(arg0, [5,6)), @Write4_2(arg1, [-1,0)){{$}}397; GLOBAL-NEXT: x[8]: [-1,9), @Write4_2(arg0, [5,6)), @Write4_2(arg1, [-1,0)){{$}}398; GLOBAL-NEXT: safe accesses:399; CHECK-EMPTY:400entry:401  %x = alloca i64, align 4402  %x1 = getelementptr i8, ptr %x, i64 -1403  %x2 = getelementptr i8, ptr %x, i64 5404  call void @Write4_2(ptr %x2, ptr %x1)405  ret void406}407 408define i32 @TestRecursiveNoOffset(ptr %p, i32 %size) #0 {409; CHECK-LABEL: @TestRecursiveNoOffset dso_preemptable{{$}}410; CHECK-NEXT: args uses:411; LOCAL-NEXT: p[]: empty-set, @RecursiveNoOffset(arg0, [0,1)){{$}}412; GLOBAL-NEXT: p[]: full-set, @RecursiveNoOffset(arg0, [0,1)){{$}}413; CHECK-NEXT: allocas uses:414; CHECK-NEXT: sum[4]: [0,4), @RecursiveNoOffset(arg2, [0,1)){{$}}415; GLOBAL-NEXT: safe accesses:416; GLOBAL-NEXT: store i32 0, ptr %sum, align 4417; GLOBAL-NEXT: %load = load i32, ptr %sum, align 4418; CHECK-EMPTY:419entry:420  %sum = alloca i32, align 4421  store i32 0, ptr %sum, align 4422  call void @RecursiveNoOffset(ptr %p, i32 %size, ptr %sum)423  %load = load i32, ptr %sum, align 4424  ret i32 %load425}426 427define void @TestRecursiveWithOffset(i32 %size) #0 {428; CHECK-LABEL: @TestRecursiveWithOffset dso_preemptable{{$}}429; CHECK-NEXT: args uses:430; CHECK-NEXT: allocas uses:431; LOCAL-NEXT: sum[64]: empty-set, @RecursiveWithOffset(arg1, [0,1)){{$}}432; GLOBAL-NEXT: sum[64]: full-set, @RecursiveWithOffset(arg1, [0,1)){{$}}433; GLOBAL-NEXT: safe accesses:434; CHECK-EMPTY:435entry:436  %sum = alloca i32, i64 16, align 4437  call void @RecursiveWithOffset(i32 %size, ptr %sum)438  ret void439}440 441; FIXME: IPA should detect that access is safe442define void @TestUpdateArg() #0 {443; CHECK-LABEL: @TestUpdateArg dso_preemptable{{$}}444; CHECK-NEXT: args uses:445; CHECK-NEXT: allocas uses:446; LOCAL-NEXT: x[16]: empty-set, @WriteAndReturn8(arg0, [0,1)){{$}}447; GLOBAL-NEXT: x[16]: full-set, @WriteAndReturn8(arg0, [0,1)){{$}}448; GLOBAL-NEXT: safe accesses:449; CHECK-EMPTY:450entry:451  %x = alloca i8, i64 16, align 4452  %0 = call ptr @WriteAndReturn8(ptr %x)453  ret void454}455 456define void @TestCrossModuleOnce() #0 {457; CHECK-DAG: @TestCrossModuleOnce dso_preemptable{{$}}458; CHECK-NEXT: args uses:459; CHECK-NEXT: allocas uses:460; LOCAL-NEXT: y[1]: empty-set, @Write1SameModule(arg0, [0,1)){{$}}461; GLOBAL-NEXT: y[1]: [0,1), @Write1SameModule(arg0, [0,1)){{$}}462; GLOBAL-NEXT: safe accesses:463; CHECK-EMPTY:464entry:465  %y = alloca i8, align 4466  call void @Write1SameModule(ptr %y)467  ret void468}469 470define void @TestCrossModuleTwice() #0 {471; CHECK-DAG: @TestCrossModuleTwice dso_preemptable{{$}}472; CHECK-NEXT: args uses:473; CHECK-NEXT: allocas uses:474; LOCAL-NEXT: z[1]: empty-set, @Write1DiffModule(arg0, [0,1)){{$}}475; GLOBAL-NEXT: z[1]: [0,1), @Write1DiffModule(arg0, [0,1)){{$}}476; GLOBAL-NEXT: safe accesses:477; CHECK-EMPTY:478entry:479  %z = alloca i8, align 4480  call void @Write1DiffModule(ptr %z)481  ret void482}483 484define void @TestCrossModuleConflict() #0 {485; CHECK-DAG: @TestCrossModuleConflict dso_preemptable{{$}}486; CHECK-NEXT: args uses:487; CHECK-NEXT: allocas uses:488; LOCAL-NEXT: x[1]: empty-set, @Write1Private(arg0, [0,1)){{$}}489; GLOBAL-NEXT: x[1]: [-1,0), @Write1Private(arg0, [0,1)){{$}}490; GLOBAL-NEXT: safe accesses:491; CHECK-EMPTY:492entry:493  %x = alloca i8, align 4494  call void @Write1Private(ptr %x)495  ret void496}497 498; FIXME: LTO should match NOLTO499define void @TestCrossModuleWeak() #0 {500; CHECK-DAG: @TestCrossModuleWeak dso_preemptable{{$}}501; CHECK-NEXT: args uses:502; CHECK-NEXT: allocas uses:503; LOCAL-NEXT: x[1]: empty-set, @Write1Weak(arg0, [0,1)){{$}}504; NOLTO-NEXT: x[1]: [1,2), @Write1Weak(arg0, [0,1)){{$}}505; LTO-NEXT: x[1]: full-set, @Write1Weak(arg0, [0,1)){{$}}506; GLOBAL-NEXT: safe accesses:507; CHECK-EMPTY:508entry:509  %x = alloca i8, align 4510  call void @Write1Weak(ptr %x)511  ret void512}513 514define private dso_local void @Private(ptr %p) #0 {515entry:516  %p1 = getelementptr i8, ptr %p, i64 1517  store i8 0, ptr %p1, align 1518  ret void519}520 521define dso_local void @Write1Module0(ptr %p) #0 {522entry:523  store i8 0, ptr %p, align 1524  ret void525}526 527define dso_local void @Weak(ptr %p) #0 {528entry:529  %p1 = getelementptr i8, ptr %p, i64 1530  store i8 0, ptr %p1, align 1531  ret void532}533 534; The rest is from Inputs/ipa.ll535 536; CHECK-LABEL: @Write1{{$}}537; CHECK-NEXT: args uses:538; CHECK-NEXT: p[]: [0,1){{$}}539; CHECK-NEXT: allocas uses:540; GLOBAL-NEXT: safe accesses:541; GLOBAL-NEXT: store i8 0, ptr %p, align 1542; CHECK-EMPTY:543 544; CHECK-LABEL: @Write4{{$}}545; CHECK-NEXT: args uses:546; CHECK-NEXT: p[]: [0,4){{$}}547; CHECK-NEXT: allocas uses:548; GLOBAL-NEXT: safe accesses:549; GLOBAL-NEXT: store i32 0, ptr %p, align 1550; CHECK-EMPTY:551 552; CHECK-LABEL: @Write4_2{{$}}553; CHECK-NEXT: args uses:554; CHECK-NEXT: p[]: [0,4){{$}}555; CHECK-NEXT: q[]: [0,4){{$}}556; CHECK-NEXT: allocas uses:557; GLOBAL-NEXT: safe accesses:558; GLOBAL-NEXT: store i32 0, ptr %p, align 1559; GLOBAL-NEXT: store i32 0, ptr %q, align 1560; CHECK-EMPTY:561 562; CHECK-LABEL: @Write8{{$}}563; CHECK-NEXT: args uses:564; CHECK-NEXT: p[]: [0,8){{$}}565; CHECK-NEXT: allocas uses:566; GLOBAL-NEXT: safe accesses:567; GLOBAL-NEXT: store i64 0, ptr %p, align 1568; CHECK-EMPTY:569 570; CHECK-LABEL: @WriteAndReturn8{{$}}571; CHECK-NEXT: args uses:572; CHECK-NEXT: p[]: full-set{{$}}573; CHECK-NEXT: allocas uses:574; GLOBAL-NEXT: safe accesses:575; GLOBAL-NEXT: store i8 0, ptr %p, align 1576; CHECK-EMPTY:577 578; CHECK-LABEL: @PreemptableWrite1 dso_preemptable{{$}}579; CHECK-NEXT: args uses:580; CHECK-NEXT: p[]: [0,1){{$}}581; CHECK-NEXT: allocas uses:582; GLOBAL-NEXT: safe accesses:583; GLOBAL-NEXT: store i8 0, ptr %p, align 1584; CHECK-EMPTY:585 586; CHECK-LABEL: @InterposableWrite1 interposable{{$}}587; CHECK-NEXT: args uses:588; CHECK-NEXT: p[]: [0,1){{$}}589; CHECK-NEXT: allocas uses:590; GLOBAL-NEXT: safe accesses:591; GLOBAL-NEXT: store i8 0, ptr %p, align 1592; CHECK-EMPTY:593 594; CHECK-LABEL: @ReturnDependent{{$}}595; CHECK-NEXT: args uses:596; CHECK-NEXT: p[]: full-set{{$}}597; CHECK-NEXT: allocas uses:598; GLOBAL-NEXT: safe accesses:599; CHECK-EMPTY:600 601; CHECK-LABEL: @Rec0{{$}}602; CHECK-NEXT: args uses:603; LOCAL-NEXT: p[]: empty-set, @Write4(arg0, [2,3)){{$}}604; GLOBAL-NEXT: p[]: [2,6)605; CHECK-NEXT: allocas uses:606; GLOBAL-NEXT: safe accesses:607; CHECK-EMPTY:608 609; CHECK-LABEL: @Rec1{{$}}610; CHECK-NEXT: args uses:611; LOCAL-NEXT: p[]: empty-set, @Rec0(arg0, [1,2)){{$}}612; GLOBAL-NEXT: p[]: [3,7)613; CHECK-NEXT: allocas uses:614; GLOBAL-NEXT: safe accesses:615; CHECK-EMPTY:616 617; CHECK-LABEL: @Rec2{{$}}618; CHECK-NEXT: args uses:619; LOCAL-NEXT: p[]: empty-set, @Rec1(arg0, [-5,-4)){{$}}620; GLOBAL-NEXT: p[]: [-2,2)621; CHECK-NEXT: allocas uses:622; GLOBAL-NEXT: safe accesses:623; CHECK-EMPTY:624 625; CHECK-LABEL: @RecursiveNoOffset{{$}}626; CHECK-NEXT: args uses:627; LOCAL-NEXT: p[]: [0,4), @RecursiveNoOffset(arg0, [4,5)){{$}}628; GLOBAL-NEXT: p[]: full-set, @RecursiveNoOffset(arg0, [4,5)){{$}}629; CHECK-NEXT: acc[]: [0,4), @RecursiveNoOffset(arg2, [0,1)){{$}}630; CHECK-NEXT: allocas uses:631; GLOBAL-NEXT: safe accesses:632; GLOBAL-NEXT: %load0 = load i32, ptr %p, align 4633; GLOBAL-NEXT: %load1 = load i32, ptr %acc, align 4634; GLOBAL-NEXT: store i32 %add, ptr %acc, align 4635; CHECK-EMPTY:636 637; CHECK-LABEL: @RecursiveWithOffset{{$}}638; CHECK-NEXT: args uses:639; LOCAL-NEXT: acc[]: [0,4), @RecursiveWithOffset(arg1, [4,5)){{$}}640; GLOBAL-NEXT: acc[]: full-set, @RecursiveWithOffset(arg1, [4,5)){{$}}641; CHECK-NEXT: allocas uses:642; GLOBAL-NEXT: safe accesses:643; GLOBAL-NEXT: store i32 0, ptr %acc, align 4644; CHECK-EMPTY:645 646; CHECK-LABEL: @ReturnAlloca647; CHECK-NEXT: args uses:648; CHECK-NEXT: allocas uses:649; CHECK-NEXT: x[8]: full-set650; GLOBAL-NEXT: safe accesses:651; CHECK-EMPTY:652 653; INDEX-LABEL: ^0 = module:654; INDEX-DAG: name: "ReturnDependent"{{.*}} guid = [[ReturnDependent:[-0-9]+]]655; INDEX-DAG: name: "Private"{{.*}} guid = [[Private:[-0-9]+]]656; INDEX-DAG: name: "TwoArgumentsOOBOther"{{.*}} guid = [[TwoArgumentsOOBOther:[-0-9]+]]657; INDEX-DAG: name: "Rec2"{{.*}} guid = [[Rec2:[-0-9]+]]658; INDEX-DAG: name: "f1"{{.*}} guid = [[f1:[-0-9]+]]659; INDEX-DAG: name: "PrivateWrite1"{{.*}} guid = [[PrivateWrite1:[-0-9]+]]660; INDEX-DAG: name: "TestRecursiveNoOffset"{{.*}} guid = [[TestRecursiveNoOffset:[-0-9]+]]661; INDEX-DAG: name: "f8left"{{.*}} guid = [[f8left:[-0-9]+]]662; INDEX-DAG: name: "Write4"{{.*}} guid = [[Write4:[-0-9]+]]663; INDEX-DAG: name: "f7"{{.*}} guid = [[f7:[-0-9]+]]664; INDEX-DAG: name: "Write1SameModule"{{.*}} guid = [[Write1SameModule:[-0-9]+]]665; INDEX-DAG: name: "Write8"{{.*}} guid = [[Write8:[-0-9]+]]666; INDEX-DAG: name: "TwoArgumentsOOBOne"{{.*}} guid = [[TwoArgumentsOOBOne:[-0-9]+]]667; INDEX-DAG: name: "f3"{{.*}} guid = [[f3:[-0-9]+]]668; INDEX-DAG: name: "f8right"{{.*}} guid = [[f8right:[-0-9]+]]669; INDEX-DAG: name: "Write4_2"{{.*}} guid = [[Write4_2:[-0-9]+]]670; INDEX-DAG: name: "RecursiveWithOffset"{{.*}} guid = [[RecursiveWithOffset:[-0-9]+]]671; INDEX-DAG: name: "Weak"{{.*}} guid = [[Weak:[-0-9]+]]672; INDEX-DAG: name: "Write1Private"{{.*}} guid = [[Write1Private:[-0-9]+]]673; INDEX-DAG: name: "TestUpdateArg"{{.*}} guid = [[TestUpdateArg:[-0-9]+]]674; INDEX-DAG: name: "TestCrossModuleTwice"{{.*}} guid = [[TestCrossModuleTwice:[-0-9]+]]675; INDEX-DAG: name: "TestCrossModuleWeak"{{.*}} guid = [[TestCrossModuleWeak:[-0-9]+]]676; INDEX-DAG: name: "f2"{{.*}} guid = [[f2:[-0-9]+]]677; INDEX-DAG: name: "PrivateCall"{{.*}} guid = [[PrivateCall:[-0-9]+]]678; INDEX-DAG: name: "TestRecursiveWithOffset"{{.*}} guid = [[TestRecursiveWithOffset:[-0-9]+]]679; INDEX-DAG: name: "f8oobleft"{{.*}} guid = [[f8oobleft:[-0-9]+]]680; INDEX-DAG: name: "InterposableWrite1"{{.*}} guid = [[InterposableWrite1:[-0-9]+]]681; INDEX-DAG: name: "f4"{{.*}} guid = [[f4:[-0-9]+]]682; INDEX-DAG: name: "TestCrossModuleConflict"{{.*}} guid = [[TestCrossModuleConflict:[-0-9]+]]683; INDEX-DAG: name: "RecursiveNoOffset"{{.*}} guid = [[RecursiveNoOffset:[-0-9]+]]684; INDEX-DAG: name: "TwoArgumentsOOBBoth"{{.*}} guid = [[TwoArgumentsOOBBoth:[-0-9]+]]685; INDEX-DAG: name: "f5"{{.*}} guid = [[f5:[-0-9]+]]686; INDEX-DAG: name: "f6"{{.*}} guid = [[f6:[-0-9]+]]687; INDEX-DAG: name: "Write1Weak"{{.*}} guid = [[Write1Weak:[-0-9]+]]688; INDEX-DAG: name: "Write1"{{.*}} guid = [[Write1:[-0-9]+]]689; INDEX-DAG: name: "PreemptableWrite1"{{.*}} guid = [[PreemptableWrite1:[-0-9]+]]690; INDEX-DAG: name: "f8oobright"{{.*}} guid = [[f8oobright:[-0-9]+]]691; INDEX-DAG: name: "InterposableCall"{{.*}} guid = [[InterposableCall:[-0-9]+]]692; INDEX-DAG: name: "TestCrossModuleOnce"{{.*}} guid = [[TestCrossModuleOnce:[-0-9]+]]693; INDEX-DAG: name: "WriteAndReturn8"{{.*}} guid = [[WriteAndReturn8:[-0-9]+]]694; INDEX-DAG: name: "TwoArguments"{{.*}} guid = [[TwoArguments:[-0-9]+]]695; INDEX-DAG: name: "Write1Module0"{{.*}} guid = [[Write1Module0:[-0-9]+]]696; INDEX-DAG: name: "PreemptableCall"{{.*}} guid = [[PreemptableCall:[-0-9]+]]697; INDEX-DAG: name: "Write1DiffModule"{{.*}} guid = [[Write1DiffModule:[-0-9]+]]698; INDEX-DAG: name: "ExternalCall"{{.*}} guid = [[ExternalCall:[-0-9]+]]699; INDEX-LABEL: = blockcount:700 701; INDEX-LABEL: ^0 = module:702; INDEX-DAG: name: "ReturnDependent"{{.*}} guid = [[ReturnDependent:[-0-9]+]]703; INDEX-DAG: name: "Rec0"{{.*}} guid = [[Rec0:[-0-9]+]]704; INDEX-DAG: name: "Rec2"{{.*}} guid = [[Rec2:[-0-9]+]]705; INDEX-DAG: name: "Write4"{{.*}} guid = [[Write4:[-0-9]+]]706; INDEX-DAG: name: "Write1SameModule"{{.*}} guid = [[Write1SameModule:[-0-9]+]]707; INDEX-DAG: name: "Write8"{{.*}} guid = [[Write8:[-0-9]+]]708; INDEX-DAG: name: "Write4_2"{{.*}} guid = [[Write4_2:[-0-9]+]]709; INDEX-DAG: name: "RecursiveWithOffset"{{.*}} guid = [[RecursiveWithOffset:[-0-9]+]]710; INDEX-DAG: name: "Weak"{{.*}} guid = [[Weak:[-0-9]+]]711; INDEX-DAG: name: "Write1Private"{{.*}} guid = [[Write1Private:[-0-9]+]]712; INDEX-DAG: name: "InterposableWrite1"{{.*}} guid = [[InterposableWrite1:[-0-9]+]]713; INDEX-DAG: name: "Private"{{.*}} guid = [[Private:[-0-9]+]]714; INDEX-DAG: name: "Rec1"{{.*}} guid = [[Rec1:[-0-9]+]]715; INDEX-DAG: name: "RecursiveNoOffset"{{.*}} guid = [[RecursiveNoOffset:[-0-9]+]]716; INDEX-DAG: name: "Write1Weak"{{.*}} guid = [[Write1Weak:[-0-9]+]]717; INDEX-DAG: name: "Write1"{{.*}} guid = [[Write1:[-0-9]+]]718; INDEX-DAG: name: "PreemptableWrite1"{{.*}} guid = [[PreemptableWrite1:[-0-9]+]]719; INDEX-DAG: name: "WriteAndReturn8"{{.*}} guid = [[WriteAndReturn8:[-0-9]+]]720; INDEX-DAG: name: "Write1Module0"{{.*}} guid = [[Write1Module0:[-0-9]+]]721; INDEX-DAG: name: "Write1DiffModule"{{.*}} guid = [[Write1DiffModule:[-0-9]+]]722; INDEX-DAG: name: "ExternalCall"{{.*}} guid = [[ExternalCall:[-0-9]+]]723; INDEX-DAG: name: "ReturnAlloca"{{.*}} guid = [[ReturnAlloca:[-0-9]+]]724; INDEX-LABEL: = blockcount:725 726; INDEX-LABEL: ^0 = module:727; INDEX-DAG: guid: [[ReturnDependent]], {{.*}}, funcFlags: ({{.*}}))))728; INDEX-DAG: guid: [[Rec0]], {{.*}}, params: ((param: 0, offset: [2, 5])))))729; INDEX-DAG: guid: [[Rec2]], {{.*}}, params: ((param: 0, offset: [-2, 1])))))730; INDEX-DAG: guid: [[Write4]], {{.*}}, params: ((param: 0, offset: [0, 3])))))731; INDEX-DAG: guid: [[Write1SameModule]], {{.*}}, params: ((param: 0, offset: [0, 0])))))732; INDEX-DAG: guid: [[Write8]], {{.*}}, params: ((param: 0, offset: [0, 7])))))733; INDEX-DAG: guid: [[Write4_2]], {{.*}}, params: ((param: 0, offset: [0, 3]), (param: 1, offset: [0, 3])))))734; INDEX-DAG: guid: [[RecursiveWithOffset]], {{.*}}, calls: ((callee: ^{{[0-9]+}}, tail: 1)))))735; INDEX-DAG: guid: [[Weak]], {{.*}}, funcFlags: ({{.*}}))))736; INDEX-DAG: guid: [[Write1Private]], {{.*}}, params: ((param: 0, offset: [-1, -1])))))737; INDEX-DAG: guid: [[InterposableWrite1]], {{.*}}, params: ((param: 0, offset: [0, 0])))))738; INDEX-DAG: guid: [[Private]], {{.*}}, params: ((param: 0, offset: [-1, -1])))))739; INDEX-DAG: guid: [[Rec1]], {{.*}}, params: ((param: 0, offset: [3, 6])))))740; INDEX-DAG: guid: [[RecursiveNoOffset]], {{.*}}, params: ((param: 2, offset: [0, 3])))))741; INDEX-DAG: guid: [[Write1Weak]], {{.*}}, calls: ((callee: ^{{[0-9]+}})))))742; INDEX-DAG: guid: [[Write1]], {{.*}}, params: ((param: 0, offset: [0, 0])))))743; INDEX-DAG: guid: [[PreemptableWrite1]], {{.*}}, funcFlags: ({{.*}}))))744; INDEX-DAG: guid: [[WriteAndReturn8]], {{.*}}, funcFlags: ({{.*}}))))745; INDEX-DAG: guid: [[Write1DiffModule]], {{.*}}, funcFlags: ({{.*}}))))746; INDEX-DAG: guid: [[ReturnAlloca]], {{.*}}, insts: 2)))747; INDEX-LABEL: blockcount:748