brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.5 KiB · 66aa1e7 Raw
377 lines · plain
1; RUN: opt < %s -passes=inline -inline-threshold=20 -S | FileCheck %s2; RUN: opt < %s -passes='cgscc(inline)' -inline-threshold=20 -S | FileCheck %s3 4define internal i32 @callee1(i32 %A, i32 %B) {5  %C = sdiv i32 %A, %B6  ret i32 %C7}8 9define i32 @caller1() {10; CHECK-LABEL: define i32 @caller1(11; CHECK-NEXT: ret i32 312 13  %X = call i32 @callee1( i32 10, i32 3 )14  ret i32 %X15}16 17define i32 @caller2() {18; Check that we can constant-prop through instructions after inlining callee2119; to get constants in the inlined callsite to callee22.20; FIXME: Currently, the threshold is fixed at 20 because we don't perform21; *recursive* cost analysis to realize that the nested call site will definitely22; inline and be cheap. We should eventually do that and lower the threshold here23; to 1.24;25; CHECK-LABEL: @caller2(26; CHECK-NOT: call void @callee227; CHECK: ret28 29  %x = call i32 @callee21(i32 42, i32 48)30  ret i32 %x31}32 33define i32 @callee21(i32 %x, i32 %y) {34  %sub = sub i32 %y, %x35  %result = call i32 @callee22(i32 %sub)36  ret i32 %result37}38 39declare ptr @getptr()40 41define i32 @callee22(i32 %x) {42  %icmp = icmp ugt i32 %x, 4243  br i1 %icmp, label %bb.true, label %bb.false44bb.true:45  ; This block musn't be counted in the inline cost.46  %x1 = add i32 %x, 147  %x2 = add i32 %x1, 148  %x3 = add i32 %x2, 149  %x4 = add i32 %x3, 150  %x5 = add i32 %x4, 151  %x6 = add i32 %x5, 152  %x7 = add i32 %x6, 153  %x8 = add i32 %x7, 154 55  ret i32 %x856bb.false:57  ret i32 %x58}59 60define i32 @caller3() {61; Check that even if the expensive path is hidden behind several basic blocks,62; it doesn't count toward the inline cost when constant-prop proves those paths63; dead.64;65; CHECK-LABEL: @caller3(66; CHECK-NOT: call67; CHECK: ret i32 668 69entry:70  %x = call i32 @callee3(i32 42, i32 48)71  ret i32 %x72}73 74define i32 @callee3(i32 %x, i32 %y) {75  %sub = sub i32 %y, %x76  %icmp = icmp ugt i32 %sub, 4277  br i1 %icmp, label %bb.true, label %bb.false78 79bb.true:80  %icmp2 = icmp ult i32 %sub, 6481  br i1 %icmp2, label %bb.true.true, label %bb.true.false82 83bb.true.true:84  ; This block musn't be counted in the inline cost.85  %x1 = add i32 %x, 186  %x2 = add i32 %x1, 187  %x3 = add i32 %x2, 188  %x4 = add i32 %x3, 189  %x5 = add i32 %x4, 190  %x6 = add i32 %x5, 191  %x7 = add i32 %x6, 192  %x8 = add i32 %x7, 193  br label %bb.merge94 95bb.true.false:96  ; This block musn't be counted in the inline cost.97  %y1 = add i32 %y, 198  %y2 = add i32 %y1, 199  %y3 = add i32 %y2, 1100  %y4 = add i32 %y3, 1101  %y5 = add i32 %y4, 1102  %y6 = add i32 %y5, 1103  %y7 = add i32 %y6, 1104  %y8 = add i32 %y7, 1105  br label %bb.merge106 107bb.merge:108  %result = phi i32 [ %x8, %bb.true.true ], [ %y8, %bb.true.false ]109  ret i32 %result110 111bb.false:112  ret i32 %sub113}114 115declare {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a, i8 %b)116 117define i8 @caller4(i8 %z) {118; Check that we can constant fold through intrinsics such as the119; overflow-detecting arithmetic intrinsics. These are particularly important120; as they are used heavily in standard library code and generic C++ code where121; the arguments are oftent constant but complete generality is required.122;123; CHECK-LABEL: @caller4(124; CHECK-NOT: call125; CHECK: ret i8 -1126 127entry:128  %x = call i8 @callee4(i8 254, i8 14, i8 %z)129  ret i8 %x130}131 132define i8 @callee4(i8 %x, i8 %y, i8 %z) {133  %uadd = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %x, i8 %y)134  %o = extractvalue {i8, i1} %uadd, 1135  br i1 %o, label %bb.true, label %bb.false136 137bb.true:138  ret i8 -1139 140bb.false:141  ; This block musn't be counted in the inline cost.142  %z1 = add i8 %z, 1143  %z2 = add i8 %z1, 1144  %z3 = add i8 %z2, 1145  %z4 = add i8 %z3, 1146  %z5 = add i8 %z4, 1147  %z6 = add i8 %z5, 1148  %z7 = add i8 %z6, 1149  %z8 = add i8 %z7, 1150  ret i8 %z8151}152 153define i64 @caller5(i64 %y) {154; Check that we can round trip constants through various kinds of casts etc w/o155; losing track of the constant prop in the inline cost analysis.156;157; CHECK-LABEL: @caller5(158; CHECK-NOT: call159; CHECK: ret i64 -1160 161entry:162  %x = call i64 @callee5(i64 42, i64 %y)163  ret i64 %x164}165 166define i64 @callee5(i64 %x, i64 %y) {167  %inttoptr = inttoptr i64 %x to ptr168  %ptrtoint = ptrtoint ptr %inttoptr to i64169  %trunc = trunc i64 %ptrtoint to i32170  %zext = zext i32 %trunc to i64171  %cmp = icmp eq i64 %zext, 42172  br i1 %cmp, label %bb.true, label %bb.false173 174bb.true:175  ret i64 -1176 177bb.false:178  ; This block musn't be counted in the inline cost.179  %y1 = add i64 %y, 1180  %y2 = add i64 %y1, 1181  %y3 = add i64 %y2, 1182  %y4 = add i64 %y3, 1183  %y5 = add i64 %y4, 1184  %y6 = add i64 %y5, 1185  %y7 = add i64 %y6, 1186  %y8 = add i64 %y7, 1187  ret i64 %y8188}189 190define float @caller6() {191; Check that we can constant-prop through fcmp instructions192;193; CHECK-LABEL: @caller6(194; CHECK-NOT: call195; CHECK: ret196  %x = call float @callee6(float 42.0)197  ret float %x198}199 200define float @callee6(float %x) {201  %icmp = fcmp ugt float %x, 42.0202  br i1 %icmp, label %bb.true, label %bb.false203 204bb.true:205  ; This block musn't be counted in the inline cost.206  %x1 = fadd float %x, 1.0207  %x2 = fadd float %x1, 1.0208  %x3 = fadd float %x2, 1.0209  %x4 = fadd float %x3, 1.0210  %x5 = fadd float %x4, 1.0211  %x6 = fadd float %x5, 1.0212  %x7 = fadd float %x6, 1.0213  %x8 = fadd float %x7, 1.0214  ret float %x8215 216bb.false:217  ret float %x218}219 220 221 222define i32 @PR13412.main() {223; This is a somewhat complicated three layer subprogram that was reported to224; compute the wrong value for a branch due to assuming that an argument225; mid-inline couldn't be equal to another pointer.226;227; After inlining, the branch should point directly to the exit block, not to228; the intermediate block.229; CHECK: @PR13412.main230; 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 0235 236entry:237  %i1 = alloca i64238  store i64 0, ptr %i1239  %call = call i1 @PR13412.first(ptr %i1, ptr %i1)240  br i1 %call, label %cond.end, label %cond.false241 242cond.false:243  call void @PR13412.fail()244  br label %cond.end245 246cond.end:247  ret i32 0248}249 250define internal i1 @PR13412.first(ptr %a, ptr %b) {251entry:252  %call = call ptr @PR13412.second(ptr %a, ptr %b)253  %cmp = icmp eq ptr %call, %b254  ret i1 %cmp255}256 257declare void @PR13412.fail()258 259define internal ptr @PR13412.second(ptr %a, ptr %b) {260entry:261  %sub.ptr.lhs.cast = ptrtoint ptr %b to i64262  %sub.ptr.rhs.cast = ptrtoint ptr %a to i64263  %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast264  %sub.ptr.div = ashr exact i64 %sub.ptr.sub, 2265  %cmp = icmp ugt i64 %sub.ptr.div, 1266  br i1 %cmp, label %if.then, label %if.end3267 268if.then:269  %0 = load i32, ptr %a270  %1 = load i32, ptr %b271  %cmp1 = icmp eq i32 %0, %1272  br i1 %cmp1, label %return, label %if.end3273 274if.end3:275  br label %return276 277return:278  %retval.0 = phi ptr [ %b, %if.end3 ], [ %a, %if.then ]279  ret ptr %retval.0280}281 282declare i32 @PR28802.external(i32 returned %p1)283 284define internal i32 @PR28802.callee() {285entry:286  br label %cont287 288cont:289  %0 = phi i32 [ 0, %entry ]290  %call = call i32 @PR28802.external(i32 %0)291  ret i32 %call292}293 294define i32 @PR28802() {295entry:296  %call = call i32 @PR28802.callee()297  ret i32 %call298}299 300; CHECK-LABEL: define i32 @PR28802(301; CHECK: %[[call:.*]] = call i32 @PR28802.external(i32 0)302; CHECK: ret i32 %[[call]]303 304define internal i32 @PR28848.callee(i32 %p2, i1 %c) {305entry:306  br i1 %c, label %cond.end, label %cond.true307 308cond.true:309  br label %cond.end310 311cond.end:312  %cond = phi i32 [ 0, %cond.true ], [ %p2, %entry ]313  %or = or i32 %cond, %p2314  ret i32 %or315}316 317define i32 @PR28848() {318entry:319  %call = call i32 @PR28848.callee(i32 0, i1 false)320  ret i32 %call321}322; CHECK-LABEL: define i32 @PR28848(323; CHECK: ret i32 0324 325define internal void @callee7(i16 %param1, i16 %param2) {326entry:327  br label %bb328 329bb:330  %phi = phi i16 [ %param2, %entry ]331  %add = add i16 %phi, %param1332  ret void333}334 335declare i16 @caller7.external(i16 returned)336 337define void @caller7() {338bb1:339  %call = call i16 @caller7.external(i16 1)340  call void @callee7(i16 0, i16 %call)341  ret void342}343; CHECK-LABEL: define void @caller7(344; CHECK: %call = call i16 @caller7.external(i16 1)345; CHECK-NEXT: ret void346 347define float @caller8(float %y) {348; Check that we can constant-prop through fneg instructions349;350; CHECK-LABEL: @caller8(351; CHECK-NOT: call352; CHECK: ret353  %x = call float @callee8(float -42.0, float %y)354  ret float %x355}356 357define float @callee8(float %x, float %y) {358  %neg = fneg float %x359  %icmp = fcmp ugt float %neg, 42.0360  br i1 %icmp, label %bb.true, label %bb.false361 362bb.true:363  ; This block musn't be counted in the inline cost.364  %y1 = fadd float %y, 1.0365  %y2 = fadd float %y1, 1.0366  %y3 = fadd float %y2, 1.0367  %y4 = fadd float %y3, 1.0368  %y5 = fadd float %y4, 1.0369  %y6 = fadd float %y5, 1.0370  %y7 = fadd float %y6, 1.0371  %y8 = fadd float %y7, 1.0372  ret float %y8373 374bb.false:375  ret float %x376}377