1; RUN: opt -inline < %s -S -o - -inline-threshold=3 | FileCheck %s 2 3target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 4target triple = "x86_64-unknown-linux-gnu" 5 6declare void @pad() readnone 7 8define void @outer1(i32* %a) { 9; CHECK-LABEL: @outer1( 10; CHECK-NOT: call void @inner1 11 %b = alloca i32 12 call void @inner1(i32* %a, i32* %b) 13 ret void 14} 15 16define void @inner1(i32* %a, i32* %b) { 17 %1 = load i32, i32* %a 18 store i32 %1, i32 * %b ; This store does not clobber the first load. 19 %2 = load i32, i32* %a 20 call void @pad() 21 %3 = load i32, i32* %a 22 ret void 23} 24 25 26define void @outer2(i32* %a, i32* %b) { 27; CHECK-LABEL: @outer2( 28; CHECK: call void @inner2 29 call void @inner2(i32* %a, i32* %b) 30 ret void 31} 32 33define void @inner2(i32* %a, i32* %b) { 34 %1 = load i32, i32* %a 35 store i32 %1, i32 * %b ; This store clobbers the first load. 36 %2 = load i32, i32* %a 37 call void @pad() 38 ret void 39} 40 41 42define void @outer3(i32* %a) { 43; CHECK-LABEL: @outer3( 44; CHECK: call void @inner3 45 call void @inner3(i32* %a) 46 ret void 47} 48 49declare void @ext() 50 51define void @inner3(i32* %a) { 52 %1 = load i32, i32* %a 53 call void @ext() ; This call clobbers the first load. 54 %2 = load i32, i32* %a 55 ret void 56} 57 58 59define void @outer4(i32* %a, i32* %b, i32* %c) { 60; CHECK-LABEL: @outer4( 61; CHECK-NOT: call void @inner4 62 call void @inner4(i32* %a, i32* %b, i1 false) 63 ret void 64} 65 66define void @inner4(i32* %a, i32* %b, i1 %pred) { 67 %1 = load i32, i32* %a 68 br i1 %pred, label %cond_true, label %cond_false 69 70cond_true: 71 store i32 %1, i32 * %b ; This store does not clobber the first load. 72 br label %cond_false 73 74cond_false: 75 %2 = load i32, i32* %a 76 call void @pad() 77 %3 = load i32, i32* %a 78 %4 = load i32, i32* %a 79 ret void 80} 81 82 83define void @outer5(i32* %a, double %b) { 84; CHECK-LABEL: @outer5( 85; CHECK-NOT: call void @inner5 86 call void @inner5(i32* %a, double %b) 87 ret void 88} 89 90declare double @llvm.fabs.f64(double) nounwind readnone 91 92define void @inner5(i32* %a, double %b) { 93 %1 = load i32, i32* %a 94 %2 = call double @llvm.fabs.f64(double %b) ; This intrinsic does not clobber the first load. 95 %3 = load i32, i32* %a 96 call void @pad() 97 ret void 98} 99 100define void @outer6(i32* %a, i8* %ptr) { 101; CHECK-LABEL: @outer6( 102; CHECK-NOT: call void @inner6 103 call void @inner6(i32* %a, i8* %ptr) 104 ret void 105} 106 107declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) argmemonly nounwind 108 109define void @inner6(i32* %a, i8* %ptr) { 110 %1 = load i32, i32* %a 111 call void @llvm.lifetime.start.p0i8(i64 32, i8* %ptr) ; This intrinsic does not clobber the first load. 112 %2 = load i32, i32* %a 113 call void @pad() 114 %3 = load i32, i32* %a 115 ret void 116} 117 118define void @outer7(i32* %a) { 119; CHECK-LABEL: @outer7( 120; CHECK-NOT: call void @inner7 121 call void @inner7(i32* %a) 122 ret void 123} 124 125declare void @ext2() readnone 126 127define void @inner7(i32* %a) { 128 %1 = load i32, i32* %a 129 call void @ext2() ; This call does not clobber the first load. 130 %2 = load i32, i32* %a 131 ret void 132} 133 134 135define void @outer8(i32* %a) { 136; CHECK-LABEL: @outer8( 137; CHECK-NOT: call void @inner8 138 call void @inner8(i32* %a, void ()* @ext2) 139 ret void 140} 141 142define void @inner8(i32* %a, void ()* %f) { 143 %1 = load i32, i32* %a 144 call void %f() ; This indirect call does not clobber the first load. 145 %2 = load i32, i32* %a 146 call void @pad() 147 call void @pad() 148 call void @pad() 149 call void @pad() 150 call void @pad() 151 call void @pad() 152 call void @pad() 153 call void @pad() 154 call void @pad() 155 call void @pad() 156 call void @pad() 157 call void @pad() 158 ret void 159} 160 161 162define void @outer9(i32* %a) { 163; CHECK-LABEL: @outer9( 164; CHECK: call void @inner9 165 call void @inner9(i32* %a, void ()* @ext) 166 ret void 167} 168 169define void @inner9(i32* %a, void ()* %f) { 170 %1 = load i32, i32* %a 171 call void %f() ; This indirect call clobbers the first load. 172 %2 = load i32, i32* %a 173 call void @pad() 174 call void @pad() 175 call void @pad() 176 call void @pad() 177 call void @pad() 178 call void @pad() 179 call void @pad() 180 call void @pad() 181 call void @pad() 182 call void @pad() 183 call void @pad() 184 call void @pad() 185 ret void 186} 187 188 189define void @outer10(i32* %a) { 190; CHECK-LABEL: @outer10( 191; CHECK: call void @inner10 192 %b = alloca i32 193 call void @inner10(i32* %a, i32* %b) 194 ret void 195} 196 197define void @inner10(i32* %a, i32* %b) { 198 %1 = load i32, i32* %a 199 store i32 %1, i32 * %b 200 %2 = load volatile i32, i32* %a ; volatile load should be kept. 201 call void @pad() 202 %3 = load volatile i32, i32* %a ; Same as the above. 203 ret void 204} 205