1; RUN: split-file %s %t 2; RUN: opt -module-summary %t/a.ll -o %t/a.bc 3; RUN: opt -module-summary %t/b.ll -o %t/b.bc 4; RUN: opt -module-summary %t/c.ll -o %t/c.bc 5 6;; ThinLTO Function attribute propagation uses the prevailing symbol to propagate attributes to its callers. 7;; Interposable (linkonce and weak) linkages are fair game given we know the prevailing copy will be used in the final binary. 8; RUN: llvm-lto2 run -disable-thinlto-funcattrs=0 %t/a.bc %t/b.bc %t/c.bc -o %t1 -save-temps \ 9; RUN: -r=%t/a.bc,call_extern,plx -r=%t/a.bc,call_linkonceodr,plx -r=%t/a.bc,call_weakodr,plx -r=%t/a.bc,call_linkonce,plx -r=%t/a.bc,call_weak,plx -r=%t/a.bc,call_linkonce_may_unwind,plx -r=%t/a.bc,call_weak_may_unwind,plx \ 10; RUN: -r=%t/a.bc,extern, -r=%t/a.bc,linkonceodr, -r=%t/a.bc,weakodr, -r=%t/a.bc,linkonce, -r=%t/a.bc,weak, -r=%t/a.bc,linkonce_may_unwind, -r=%t/a.bc,weak_may_unwind, \ 11; RUN: -r=%t/b.bc,extern,p -r=%t/b.bc,linkonceodr,p -r=%t/b.bc,weakodr,p -r=%t/b.bc,linkonce,p -r=%t/b.bc,weak,p -r=%t/b.bc,linkonce_may_unwind,p -r=%t/b.bc,weak_may_unwind, \ 12; RUN: -r=%t/c.bc,extern, -r=%t/c.bc,linkonceodr, -r=%t/c.bc,weakodr, -r=%t/c.bc,linkonce, -r=%t/c.bc,weak, -r=%t/c.bc,linkonce_may_unwind, -r=%t/c.bc,weak_may_unwind,p -r=%t/c.bc,may_throw, 13 14; RUN: llvm-dis %t1.1.3.import.bc -o - | FileCheck %s 15 16;--- a.ll 17target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 18target triple = "x86_64-unknown-linux-gnu" 19 20;; These functions are identical between b.ll and c.ll 21declare void @extern() 22declare void @linkonceodr() 23declare void @weakodr() 24 25declare void @linkonce() 26declare void @weak() 27 28;; b.ll contains non-throwing copies of these functions 29;; c.ll contains throwing copies of these functions 30declare void @linkonce_may_unwind() 31declare void @weak_may_unwind() 32 33; CHECK: define dso_local void @call_extern() [[ATTR_NOUNWIND:#[0-9]+]] 34define void @call_extern() { 35 call void @extern() 36 ret void 37} 38 39; CHECK: define dso_local void @call_linkonceodr() [[ATTR_NOUNWIND:#[0-9]+]] 40define void @call_linkonceodr() { 41 call void @linkonceodr() 42 ret void 43} 44 45; CHECK: define dso_local void @call_weakodr() [[ATTR_NOUNWIND:#[0-9]+]] 46define void @call_weakodr() { 47 call void @weakodr() 48 ret void 49} 50 51; CHECK: define dso_local void @call_linkonce() [[ATTR_NOUNWIND:#[0-9]+]] 52define void @call_linkonce() { 53 call void @linkonce() 54 ret void 55} 56 57; CHECK: define dso_local void @call_weak() [[ATTR_NOUNWIND:#[0-9]+]] 58define void @call_weak() { 59 call void @weak() 60 ret void 61} 62 63; CHECK: define dso_local void @call_linkonce_may_unwind() [[ATTR_NOUNWIND:#[0-9]+]] 64;; The prevailing copy here comes from b.ll, which contains nounwind and norecurse 65define void @call_linkonce_may_unwind() { 66 call void @linkonce_may_unwind() 67 ret void 68} 69 70; CHECK: define dso_local void @call_weak_may_unwind() [[ATTR_MAYTHROW:#[0-9]+]] 71;; The prevailing copy hree comes from c.ll, which only contains norecurse 72define void @call_weak_may_unwind() { 73 call void @weak_may_unwind() 74 ret void 75} 76 77; CHECK-DAG: attributes [[ATTR_NOUNWIND]] = { norecurse nounwind } 78; CHECK-DAG: attributes [[ATTR_MAYTHROW]] = { norecurse } 79 80;--- b.ll 81target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 82target triple = "x86_64-unknown-linux-gnu" 83 84attributes #0 = { nounwind norecurse } 85 86define void @extern() #0 { 87 ret void 88} 89 90define linkonce_odr void @linkonceodr() #0 { 91 ret void 92} 93 94define weak_odr void @weakodr() #0 { 95 ret void 96} 97 98define linkonce void @linkonce() #0 { 99 ret void 100} 101 102define weak void @weak() #0 { 103 ret void 104} 105 106define linkonce void @linkonce_may_unwind() #0 { 107 ret void 108} 109 110define weak void @weak_may_unwind() #0 { 111 ret void 112} 113 114;--- c.ll 115target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 116target triple = "x86_64-unknown-linux-gnu" 117 118attributes #0 = { nounwind norecurse } 119attributes #1 = { norecurse } 120 121define void @extern() #0 { 122 ret void 123} 124 125define linkonce_odr void @linkonceodr() #0 { 126 ret void 127} 128 129define weak_odr void @weakodr() #0 { 130 ret void 131} 132 133define linkonce void @linkonce() #0 { 134 ret void 135} 136 137define weak void @weak() #0 { 138 ret void 139} 140 141declare void @may_throw() 142 143define linkonce void @linkonce_may_unwind() #1 { 144 call void @may_throw() 145 ret void 146} 147 148define weak void @weak_may_unwind() #1 { 149 call void @may_throw() 150 ret void 151} 152