1; RUN: opt -inline < %s -S -o - -inline-threshold=8 | FileCheck %s 2 3target datalayout = "p:32:32" 4 5declare void @llvm.lifetime.start(i64 %size, i8* nocapture %ptr) 6 7@glbl = external global i32 8 9define void @outer1() { 10; CHECK: @outer1 11; CHECK-NOT: call void @inner1 12 %ptr = alloca i32 13 call void @inner1(i32* %ptr) 14 ret void 15} 16 17define void @inner1(i32 *%ptr) { 18 %A = load i32* %ptr 19 store i32 0, i32* %ptr 20 %C = getelementptr inbounds i32* %ptr, i32 0 21 %D = getelementptr inbounds i32* %ptr, i32 1 22 %E = bitcast i32* %ptr to i8* 23 %F = select i1 false, i32* %ptr, i32* @glbl 24 call void @llvm.lifetime.start(i64 0, i8* %E) 25 ret void 26} 27 28define void @outer2() { 29; CHECK: @outer2 30; CHECK: call void @inner2 31 %ptr = alloca i32 32 call void @inner2(i32* %ptr) 33 ret void 34} 35 36; %D poisons this call, scalar-repl can't handle that instruction. 37define void @inner2(i32 *%ptr) { 38 %A = load i32* %ptr 39 store i32 0, i32* %ptr 40 %C = getelementptr inbounds i32* %ptr, i32 0 41 %D = getelementptr inbounds i32* %ptr, i32 %A 42 %E = bitcast i32* %ptr to i8* 43 %F = select i1 false, i32* %ptr, i32* @glbl 44 call void @llvm.lifetime.start(i64 0, i8* %E) 45 ret void 46} 47 48define void @outer3() { 49; CHECK: @outer3 50; CHECK-NOT: call void @inner3 51 %ptr = alloca i32 52 call void @inner3(i32* %ptr, i1 undef) 53 ret void 54} 55 56define void @inner3(i32 *%ptr, i1 %x) { 57 %A = icmp eq i32* %ptr, null 58 %B = and i1 %x, %A 59 br i1 %A, label %bb.true, label %bb.false 60bb.true: 61 ; This block musn't be counted in the inline cost. 62 %t1 = load i32* %ptr 63 %t2 = add i32 %t1, 1 64 %t3 = add i32 %t2, 1 65 %t4 = add i32 %t3, 1 66 %t5 = add i32 %t4, 1 67 %t6 = add i32 %t5, 1 68 %t7 = add i32 %t6, 1 69 %t8 = add i32 %t7, 1 70 %t9 = add i32 %t8, 1 71 %t10 = add i32 %t9, 1 72 %t11 = add i32 %t10, 1 73 %t12 = add i32 %t11, 1 74 %t13 = add i32 %t12, 1 75 %t14 = add i32 %t13, 1 76 %t15 = add i32 %t14, 1 77 %t16 = add i32 %t15, 1 78 %t17 = add i32 %t16, 1 79 %t18 = add i32 %t17, 1 80 %t19 = add i32 %t18, 1 81 %t20 = add i32 %t19, 1 82 ret void 83bb.false: 84 ret void 85} 86 87define void @outer4(i32 %A) { 88; CHECK: @outer4 89; CHECK-NOT: call void @inner4 90 %ptr = alloca i32 91 call void @inner4(i32* %ptr, i32 %A) 92 ret void 93} 94 95; %B poisons this call, scalar-repl can't handle that instruction. However, we 96; still want to detect that the icmp and branch *can* be handled. 97define void @inner4(i32 *%ptr, i32 %A) { 98 %B = getelementptr inbounds i32* %ptr, i32 %A 99 %C = icmp eq i32* %ptr, null 100 br i1 %C, label %bb.true, label %bb.false 101bb.true: 102 ; This block musn't be counted in the inline cost. 103 %t1 = load i32* %ptr 104 %t2 = add i32 %t1, 1 105 %t3 = add i32 %t2, 1 106 %t4 = add i32 %t3, 1 107 %t5 = add i32 %t4, 1 108 %t6 = add i32 %t5, 1 109 %t7 = add i32 %t6, 1 110 %t8 = add i32 %t7, 1 111 %t9 = add i32 %t8, 1 112 %t10 = add i32 %t9, 1 113 %t11 = add i32 %t10, 1 114 %t12 = add i32 %t11, 1 115 %t13 = add i32 %t12, 1 116 %t14 = add i32 %t13, 1 117 %t15 = add i32 %t14, 1 118 %t16 = add i32 %t15, 1 119 %t17 = add i32 %t16, 1 120 %t18 = add i32 %t17, 1 121 %t19 = add i32 %t18, 1 122 %t20 = add i32 %t19, 1 123 ret void 124bb.false: 125 ret void 126} 127 128define void @outer5() { 129; CHECK: @outer5 130; CHECK-NOT: call void @inner5 131 %ptr = alloca i32 132 call void @inner5(i1 false, i32* %ptr) 133 ret void 134} 135 136; %D poisons this call, scalar-repl can't handle that instruction. However, if 137; the flag is set appropriately, the poisoning instruction is inside of dead 138; code, and so shouldn't be counted. 139define void @inner5(i1 %flag, i32 *%ptr) { 140 %A = load i32* %ptr 141 store i32 0, i32* %ptr 142 %C = getelementptr inbounds i32* %ptr, i32 0 143 br i1 %flag, label %if.then, label %exit 144 145if.then: 146 %D = getelementptr inbounds i32* %ptr, i32 %A 147 %E = bitcast i32* %ptr to i8* 148 %F = select i1 false, i32* %ptr, i32* @glbl 149 call void @llvm.lifetime.start(i64 0, i8* %E) 150 ret void 151 152exit: 153 ret void 154} 155 156