1; RUN: opt -passes=inline < %s -S -o - -inline-threshold=10 | FileCheck %s 2 3target datalayout = "p:32:32-p1:64:64-p2:16:16-n16:32:64" 4 5define i32 @outer1() { 6; CHECK-LABEL: @outer1( 7; CHECK-NOT: call i32 8; CHECK: ret i32 9 10 %ptr = alloca i32 11 %ptr2 = getelementptr inbounds i32, ptr %ptr, i32 42 12 %result = call i32 @inner1(ptr %ptr, ptr %ptr2) 13 ret i32 %result 14} 15 16define i32 @inner1(ptr %begin, ptr %end) { 17 call void @extern() 18 %begin.i = ptrtoint ptr %begin to i32 19 %end.i = ptrtoint ptr %end to i32 20 %distance = sub i32 %end.i, %begin.i 21 %icmp = icmp sle i32 %distance, 42 22 br i1 %icmp, label %then, label %else 23 24then: 25 ret i32 3 26 27else: 28 %t = load i32, ptr %begin 29 ret i32 %t 30} 31 32define i32 @outer1_as1(ptr addrspace(1) %ptr) { 33; CHECK-LABEL: @outer1_as1( 34; CHECK-NOT: call 35; CHECK: ret i32 36 %ptr2 = getelementptr inbounds i32, ptr addrspace(1) %ptr, i32 42 37 %result = call i32 @inner1_as1(ptr addrspace(1) %ptr, ptr addrspace(1) %ptr2) 38 ret i32 %result 39} 40 41; Make sure that the address space's larger size makes the ptrtoints 42; not no-ops preventing inlining 43define i32 @inner1_as1(ptr addrspace(1) %begin, ptr addrspace(1) %end) { 44 %begin.i = ptrtoint ptr addrspace(1) %begin to i32 45 %end.i = ptrtoint ptr addrspace(1) %end to i32 46 %distance = sub i32 %end.i, %begin.i 47 %icmp = icmp sle i32 %distance, 42 48 br i1 %icmp, label %then, label %else 49 50then: 51 ret i32 3 52 53else: 54 %t = load i32, ptr addrspace(1) %begin 55 ret i32 %t 56} 57 58define i32 @outer2(ptr %ptr) { 59; Test that an inbounds GEP disables this -- it isn't safe in general as 60; wrapping changes the behavior of lessthan and greaterthan comparisons. 61; CHECK-LABEL: @outer2( 62; CHECK: call i32 @inner2 63; CHECK: ret i32 64 65 %ptr2 = getelementptr i32, ptr %ptr, i32 42 66 %result = call i32 @inner2(ptr %ptr, ptr %ptr2) 67 ret i32 %result 68} 69 70define i32 @inner2(ptr %begin, ptr %end) { 71 call void @extern() 72 %begin.i = ptrtoint ptr %begin to i32 73 %end.i = ptrtoint ptr %end to i32 74 %distance = sub i32 %end.i, %begin.i 75 %icmp = icmp sle i32 %distance, 42 76 br i1 %icmp, label %then, label %else 77 78then: 79 ret i32 3 80 81else: 82 %t = load i32, ptr %begin 83 ret i32 %t 84} 85 86define i32 @outer3(ptr addrspace(1) %ptr) { 87; CHECK-LABEL: @outer3( 88; CHECK-NOT: call i32 89; CHECK: ret i32 3 90; CHECK-LABEL: @inner3( 91 %result = call i32 @inner3(ptr addrspace(1) %ptr) 92 ret i32 %result 93} 94 95define i32 @inner3(ptr addrspace(1) %ptr) { 96 call void @extern() 97 %ptr.i = ptrtoint ptr addrspace(1) %ptr to i64 98 %distance = sub i64 %ptr.i, %ptr.i 99 %icmp = icmp eq i64 %distance, 0 100 br i1 %icmp, label %then, label %else 101 102then: 103 ret i32 3 104 105else: 106 ret i32 5 107} 108 109 110; The inttoptrs are free since it is a smaller integer to a larger 111; pointer size 112define i32 @inttoptr_free_cost(i32 %a, i32 %b, i32 %c) { 113 call void @extern() 114 %p1 = inttoptr i32 %a to ptr addrspace(1) 115 %p2 = inttoptr i32 %b to ptr addrspace(1) 116 %p3 = inttoptr i32 %c to ptr addrspace(1) 117 %t1 = load i32, ptr addrspace(1) %p1 118 %t2 = load i32, ptr addrspace(1) %p2 119 %t3 = load i32, ptr addrspace(1) %p3 120 %s = add i32 %t1, %t2 121 %s1 = add i32 %s, %t3 122 ret i32 %s1 123} 124 125define i32 @inttoptr_free_cost_user(i32 %begin, i32 %end) { 126; CHECK-LABEL: @inttoptr_free_cost_user( 127; CHECK-NOT: call i32 128 %x = call i32 @inttoptr_free_cost(i32 %begin, i32 %end, i32 9) 129 ret i32 %x 130} 131 132; The inttoptrs have a cost since it is a larger integer to a smaller 133; pointer size 134define i32 @inttoptr_cost_smaller_ptr(i32 %a, i32 %b, i32 %c) { 135 call void @extern() 136 %p1 = inttoptr i32 %a to ptr addrspace(2) 137 %p2 = inttoptr i32 %b to ptr addrspace(2) 138 %p3 = inttoptr i32 %c to ptr addrspace(2) 139 %t1 = load i32, ptr addrspace(2) %p1 140 %t2 = load i32, ptr addrspace(2) %p2 141 %t3 = load i32, ptr addrspace(2) %p3 142 %s = add i32 %t1, %t2 143 %s1 = add i32 %s, %t3 144 ret i32 %s1 145} 146 147define i32 @inttoptr_cost_smaller_ptr_user(i32 %begin, i32 %end) { 148; CHECK-LABEL: @inttoptr_cost_smaller_ptr_user( 149; CHECK: call i32 150 %x = call i32 @inttoptr_cost_smaller_ptr(i32 %begin, i32 %end, i32 9) 151 ret i32 %x 152} 153 154declare void @extern() 155