1 ; RUN: opt -inline < %s -S -o - -inline-threshold=3 | FileCheck %s 2 3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 4 target triple = "x86_64-unknown-linux-gnu" 5 6 declare void @pad() readnone 7 8 define 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 16 define 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 26 define 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 33 define 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 42 define void @outer3(i32* %a) { 43 ; CHECK-LABEL: @outer3( 44 ; CHECK: call void @inner3 45 call void @inner3(i32* %a) 46 ret void 47 } 48 49 declare void @ext() 50 51 define 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 59 define 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 66 define 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 70 cond_true: 71 store i32 %1, i32 * %b ; This store does not clobber the first load. 72 br label %cond_false 73 74 cond_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 83 define 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 90 declare double @llvm.fabs.f64(double) nounwind readnone 91 92 define 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 100 define 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 107 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) argmemonly nounwind 108 109 define 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 118 define 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 125 declare void @ext2() readnone 126 127 define 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 135 define 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 142 define 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 162 define 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 169 define 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 189 define 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 197 define 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