1; RUN: opt < %s -inline -inline-threshold=20 -S | FileCheck %s 2 3define internal i32 @callee1(i32 %A, i32 %B) { 4 %C = sdiv i32 %A, %B 5 ret i32 %C 6} 7 8define i32 @caller1() { 9; CHECK-LABEL: define i32 @caller1( 10; CHECK-NEXT: ret i32 3 11 12 %X = call i32 @callee1( i32 10, i32 3 ) 13 ret i32 %X 14} 15 16define i32 @caller2() { 17; Check that we can constant-prop through instructions after inlining callee21 18; to get constants in the inlined callsite to callee22. 19; FIXME: Currently, the threshold is fixed at 20 because we don't perform 20; *recursive* cost analysis to realize that the nested call site will definitely 21; inline and be cheap. We should eventually do that and lower the threshold here 22; to 1. 23; 24; CHECK-LABEL: @caller2( 25; CHECK-NOT: call void @callee2 26; CHECK: ret 27 28 %x = call i32 @callee21(i32 42, i32 48) 29 ret i32 %x 30} 31 32define i32 @callee21(i32 %x, i32 %y) { 33 %sub = sub i32 %y, %x 34 %result = call i32 @callee22(i32 %sub) 35 ret i32 %result 36} 37 38declare i8* @getptr() 39 40define i32 @callee22(i32 %x) { 41 %icmp = icmp ugt i32 %x, 42 42 br i1 %icmp, label %bb.true, label %bb.false 43bb.true: 44 ; This block musn't be counted in the inline cost. 45 %x1 = add i32 %x, 1 46 %x2 = add i32 %x1, 1 47 %x3 = add i32 %x2, 1 48 %x4 = add i32 %x3, 1 49 %x5 = add i32 %x4, 1 50 %x6 = add i32 %x5, 1 51 %x7 = add i32 %x6, 1 52 %x8 = add i32 %x7, 1 53 54 ret i32 %x8 55bb.false: 56 ret i32 %x 57} 58 59define i32 @caller3() { 60; Check that even if the expensive path is hidden behind several basic blocks, 61; it doesn't count toward the inline cost when constant-prop proves those paths 62; dead. 63; 64; CHECK-LABEL: @caller3( 65; CHECK-NOT: call 66; CHECK: ret i32 6 67 68entry: 69 %x = call i32 @callee3(i32 42, i32 48) 70 ret i32 %x 71} 72 73define i32 @callee3(i32 %x, i32 %y) { 74 %sub = sub i32 %y, %x 75 %icmp = icmp ugt i32 %sub, 42 76 br i1 %icmp, label %bb.true, label %bb.false 77 78bb.true: 79 %icmp2 = icmp ult i32 %sub, 64 80 br i1 %icmp2, label %bb.true.true, label %bb.true.false 81 82bb.true.true: 83 ; This block musn't be counted in the inline cost. 84 %x1 = add i32 %x, 1 85 %x2 = add i32 %x1, 1 86 %x3 = add i32 %x2, 1 87 %x4 = add i32 %x3, 1 88 %x5 = add i32 %x4, 1 89 %x6 = add i32 %x5, 1 90 %x7 = add i32 %x6, 1 91 %x8 = add i32 %x7, 1 92 br label %bb.merge 93 94bb.true.false: 95 ; This block musn't be counted in the inline cost. 96 %y1 = add i32 %y, 1 97 %y2 = add i32 %y1, 1 98 %y3 = add i32 %y2, 1 99 %y4 = add i32 %y3, 1 100 %y5 = add i32 %y4, 1 101 %y6 = add i32 %y5, 1 102 %y7 = add i32 %y6, 1 103 %y8 = add i32 %y7, 1 104 br label %bb.merge 105 106bb.merge: 107 %result = phi i32 [ %x8, %bb.true.true ], [ %y8, %bb.true.false ] 108 ret i32 %result 109 110bb.false: 111 ret i32 %sub 112} 113 114declare {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a, i8 %b) 115 116define i8 @caller4(i8 %z) { 117; Check that we can constant fold through intrinsics such as the 118; overflow-detecting arithmetic instrinsics. These are particularly important 119; as they are used heavily in standard library code and generic C++ code where 120; the arguments are oftent constant but complete generality is required. 121; 122; CHECK-LABEL: @caller4( 123; CHECK-NOT: call 124; CHECK: ret i8 -1 125 126entry: 127 %x = call i8 @callee4(i8 254, i8 14, i8 %z) 128 ret i8 %x 129} 130 131define i8 @callee4(i8 %x, i8 %y, i8 %z) { 132 %uadd = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %x, i8 %y) 133 %o = extractvalue {i8, i1} %uadd, 1 134 br i1 %o, label %bb.true, label %bb.false 135 136bb.true: 137 ret i8 -1 138 139bb.false: 140 ; This block musn't be counted in the inline cost. 141 %z1 = add i8 %z, 1 142 %z2 = add i8 %z1, 1 143 %z3 = add i8 %z2, 1 144 %z4 = add i8 %z3, 1 145 %z5 = add i8 %z4, 1 146 %z6 = add i8 %z5, 1 147 %z7 = add i8 %z6, 1 148 %z8 = add i8 %z7, 1 149 ret i8 %z8 150} 151 152define i64 @caller5(i64 %y) { 153; Check that we can round trip constants through various kinds of casts etc w/o 154; losing track of the constant prop in the inline cost analysis. 155; 156; CHECK-LABEL: @caller5( 157; CHECK-NOT: call 158; CHECK: ret i64 -1 159 160entry: 161 %x = call i64 @callee5(i64 42, i64 %y) 162 ret i64 %x 163} 164 165define i64 @callee5(i64 %x, i64 %y) { 166 %inttoptr = inttoptr i64 %x to i8* 167 %bitcast = bitcast i8* %inttoptr to i32* 168 %ptrtoint = ptrtoint i32* %bitcast to i64 169 %trunc = trunc i64 %ptrtoint to i32 170 %zext = zext i32 %trunc to i64 171 %cmp = icmp eq i64 %zext, 42 172 br i1 %cmp, label %bb.true, label %bb.false 173 174bb.true: 175 ret i64 -1 176 177bb.false: 178 ; This block musn't be counted in the inline cost. 179 %y1 = add i64 %y, 1 180 %y2 = add i64 %y1, 1 181 %y3 = add i64 %y2, 1 182 %y4 = add i64 %y3, 1 183 %y5 = add i64 %y4, 1 184 %y6 = add i64 %y5, 1 185 %y7 = add i64 %y6, 1 186 %y8 = add i64 %y7, 1 187 ret i64 %y8 188} 189 190define float @caller6() { 191; Check that we can constant-prop through fcmp instructions 192; 193; CHECK-LABEL: @caller6( 194; CHECK-NOT: call 195; CHECK: ret 196 %x = call float @callee6(float 42.0) 197 ret float %x 198} 199 200define float @callee6(float %x) { 201 %icmp = fcmp ugt float %x, 42.0 202 br i1 %icmp, label %bb.true, label %bb.false 203 204bb.true: 205 ; This block musn't be counted in the inline cost. 206 %x1 = fadd float %x, 1.0 207 %x2 = fadd float %x1, 1.0 208 %x3 = fadd float %x2, 1.0 209 %x4 = fadd float %x3, 1.0 210 %x5 = fadd float %x4, 1.0 211 %x6 = fadd float %x5, 1.0 212 %x7 = fadd float %x6, 1.0 213 %x8 = fadd float %x7, 1.0 214 ret float %x8 215 216bb.false: 217 ret float %x 218} 219 220 221 222define i32 @PR13412.main() { 223; This is a somewhat complicated three layer subprogram that was reported to 224; compute the wrong value for a branch due to assuming that an argument 225; mid-inline couldn't be equal to another pointer. 226; 227; After inlining, the branch should point directly to the exit block, not to 228; the intermediate block. 229; CHECK: @PR13412.main 230; CHECK: br i1 true, label %[[TRUE_DEST:.*]], label %[[FALSE_DEST:.*]] 231; CHECK: [[FALSE_DEST]]: 232; CHECK-NEXT: call void @PR13412.fail() 233; CHECK: [[TRUE_DEST]]: 234; CHECK-NEXT: ret i32 0 235 236entry: 237 %i1 = alloca i64 238 store i64 0, i64* %i1 239 %arraydecay = bitcast i64* %i1 to i32* 240 %call = call i1 @PR13412.first(i32* %arraydecay, i32* %arraydecay) 241 br i1 %call, label %cond.end, label %cond.false 242 243cond.false: 244 call void @PR13412.fail() 245 br label %cond.end 246 247cond.end: 248 ret i32 0 249} 250 251define internal i1 @PR13412.first(i32* %a, i32* %b) { 252entry: 253 %call = call i32* @PR13412.second(i32* %a, i32* %b) 254 %cmp = icmp eq i32* %call, %b 255 ret i1 %cmp 256} 257 258declare void @PR13412.fail() 259 260define internal i32* @PR13412.second(i32* %a, i32* %b) { 261entry: 262 %sub.ptr.lhs.cast = ptrtoint i32* %b to i64 263 %sub.ptr.rhs.cast = ptrtoint i32* %a to i64 264 %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast 265 %sub.ptr.div = ashr exact i64 %sub.ptr.sub, 2 266 %cmp = icmp ugt i64 %sub.ptr.div, 1 267 br i1 %cmp, label %if.then, label %if.end3 268 269if.then: 270 %0 = load i32, i32* %a 271 %1 = load i32, i32* %b 272 %cmp1 = icmp eq i32 %0, %1 273 br i1 %cmp1, label %return, label %if.end3 274 275if.end3: 276 br label %return 277 278return: 279 %retval.0 = phi i32* [ %b, %if.end3 ], [ %a, %if.then ] 280 ret i32* %retval.0 281} 282