1 ; RUN: opt -O2 -S < %s | FileCheck %s 2 3 @data = common global i32* null, align 8 4 5 define i32 @fct1(i32 %a) nounwind uwtable ssp { 6 entry: 7 %a.addr = alloca i32, align 4 8 %res = alloca i32, align 4 9 %i = alloca i32, align 4 10 store i32 %a, i32* %a.addr, align 4 11 %tmp = load i32* %a.addr, align 4 12 %idxprom = sext i32 %tmp to i64 13 %tmp1 = load i32** @data, align 8 14 %arrayidx = getelementptr inbounds i32* %tmp1, i64 %idxprom 15 %tmp2 = load i32* %arrayidx, align 4 16 %tmp3 = load i32* %a.addr, align 4 17 %add = add nsw i32 %tmp3, 1 18 %idxprom1 = sext i32 %add to i64 19 %tmp4 = load i32** @data, align 8 20 %arrayidx2 = getelementptr inbounds i32* %tmp4, i64 %idxprom1 21 %tmp5 = load i32* %arrayidx2, align 4 22 %mul = mul nsw i32 %tmp2, %tmp5 23 store i32 %mul, i32* %res, align 4 24 store i32 0, i32* %i, align 4 25 store i32 0, i32* %i, align 4 26 br label %for.cond 27 28 for.cond: ; preds = %for.inc, %entry 29 %tmp6 = load i32* %i, align 4 30 %tmp7 = load i32* %res, align 4 31 %cmp = icmp slt i32 %tmp6, %tmp7 32 br i1 %cmp, label %for.body, label %for.end 33 34 for.body: ; preds = %for.cond 35 %tmp8 = load i32* %i, align 4 36 %idxprom3 = sext i32 %tmp8 to i64 37 %tmp9 = load i32** @data, align 8 38 %arrayidx4 = getelementptr inbounds i32* %tmp9, i64 %idxprom3 39 call void @fct0(i32* %arrayidx4) 40 br label %for.inc 41 42 for.inc: ; preds = %for.body 43 %tmp10 = load i32* %i, align 4 44 %inc = add nsw i32 %tmp10, 1 45 store i32 %inc, i32* %i, align 4 46 br label %for.cond 47 48 for.end: ; preds = %for.cond 49 store i32 0, i32* %i, align 4 50 br label %for.cond5 51 52 for.cond5: ; preds = %for.inc10, %for.end 53 %tmp11 = load i32* %i, align 4 54 %tmp12 = load i32* %res, align 4 55 %cmp6 = icmp slt i32 %tmp11, %tmp12 56 br i1 %cmp6, label %for.body7, label %for.end12 57 58 for.body7: ; preds = %for.cond5 59 %tmp13 = load i32* %i, align 4 60 %idxprom8 = sext i32 %tmp13 to i64 61 %tmp14 = load i32** @data, align 8 62 %arrayidx9 = getelementptr inbounds i32* %tmp14, i64 %idxprom8 63 call void @fct0(i32* %arrayidx9) 64 br label %for.inc10 65 66 for.inc10: ; preds = %for.body7 67 %tmp15 = load i32* %i, align 4 68 %inc11 = add nsw i32 %tmp15, 1 69 store i32 %inc11, i32* %i, align 4 70 br label %for.cond5 71 72 for.end12: ; preds = %for.cond5 73 store i32 0, i32* %i, align 4 74 br label %for.cond13 75 76 for.cond13: ; preds = %for.inc18, %for.end12 77 %tmp16 = load i32* %i, align 4 78 %tmp17 = load i32* %res, align 4 79 %cmp14 = icmp slt i32 %tmp16, %tmp17 80 br i1 %cmp14, label %for.body15, label %for.end20 81 82 for.body15: ; preds = %for.cond13 83 %tmp18 = load i32* %i, align 4 84 %idxprom16 = sext i32 %tmp18 to i64 85 %tmp19 = load i32** @data, align 8 86 %arrayidx17 = getelementptr inbounds i32* %tmp19, i64 %idxprom16 87 call void @fct0(i32* %arrayidx17) 88 br label %for.inc18 89 90 for.inc18: ; preds = %for.body15 91 %tmp20 = load i32* %i, align 4 92 %inc19 = add nsw i32 %tmp20, 1 93 store i32 %inc19, i32* %i, align 4 94 br label %for.cond13 95 96 for.end20: ; preds = %for.cond13 97 %tmp21 = load i32* %res, align 4 98 ret i32 %tmp21 99 } 100 101 declare void @fct0(i32*) 102 103 define i32 @fct2(i32 %a) nounwind uwtable inlinehint ssp { 104 entry: 105 %a.addr = alloca i32, align 4 106 %res = alloca i32, align 4 107 %i = alloca i32, align 4 108 store i32 %a, i32* %a.addr, align 4 109 %tmp = load i32* %a.addr, align 4 110 %shl = shl i32 %tmp, 1 111 %idxprom = sext i32 %shl to i64 112 %tmp1 = load i32** @data, align 8 113 %arrayidx = getelementptr inbounds i32* %tmp1, i64 %idxprom 114 %tmp2 = load i32* %arrayidx, align 4 115 %tmp3 = load i32* %a.addr, align 4 116 %shl1 = shl i32 %tmp3, 1 117 %add = add nsw i32 %shl1, 13 118 %idxprom2 = sext i32 %add to i64 119 %tmp4 = load i32** @data, align 8 120 %arrayidx3 = getelementptr inbounds i32* %tmp4, i64 %idxprom2 121 %tmp5 = load i32* %arrayidx3, align 4 122 %mul = mul nsw i32 %tmp2, %tmp5 123 store i32 %mul, i32* %res, align 4 124 store i32 0, i32* %i, align 4 125 store i32 0, i32* %i, align 4 126 br label %for.cond 127 128 for.cond: ; preds = %for.inc, %entry 129 %tmp6 = load i32* %i, align 4 130 %tmp7 = load i32* %res, align 4 131 %cmp = icmp slt i32 %tmp6, %tmp7 132 br i1 %cmp, label %for.body, label %for.end 133 134 for.body: ; preds = %for.cond 135 %tmp8 = load i32* %i, align 4 136 %idxprom4 = sext i32 %tmp8 to i64 137 %tmp9 = load i32** @data, align 8 138 %arrayidx5 = getelementptr inbounds i32* %tmp9, i64 %idxprom4 139 call void @fct0(i32* %arrayidx5) 140 br label %for.inc 141 142 for.inc: ; preds = %for.body 143 %tmp10 = load i32* %i, align 4 144 %inc = add nsw i32 %tmp10, 1 145 store i32 %inc, i32* %i, align 4 146 br label %for.cond 147 148 for.end: ; preds = %for.cond 149 store i32 0, i32* %i, align 4 150 br label %for.cond6 151 152 for.cond6: ; preds = %for.inc11, %for.end 153 %tmp11 = load i32* %i, align 4 154 %tmp12 = load i32* %res, align 4 155 %cmp7 = icmp slt i32 %tmp11, %tmp12 156 br i1 %cmp7, label %for.body8, label %for.end13 157 158 for.body8: ; preds = %for.cond6 159 %tmp13 = load i32* %i, align 4 160 %idxprom9 = sext i32 %tmp13 to i64 161 %tmp14 = load i32** @data, align 8 162 %arrayidx10 = getelementptr inbounds i32* %tmp14, i64 %idxprom9 163 call void @fct0(i32* %arrayidx10) 164 br label %for.inc11 165 166 for.inc11: ; preds = %for.body8 167 %tmp15 = load i32* %i, align 4 168 %inc12 = add nsw i32 %tmp15, 1 169 store i32 %inc12, i32* %i, align 4 170 br label %for.cond6 171 172 for.end13: ; preds = %for.cond6 173 store i32 0, i32* %i, align 4 174 br label %for.cond14 175 176 for.cond14: ; preds = %for.inc19, %for.end13 177 %tmp16 = load i32* %i, align 4 178 %tmp17 = load i32* %res, align 4 179 %cmp15 = icmp slt i32 %tmp16, %tmp17 180 br i1 %cmp15, label %for.body16, label %for.end21 181 182 for.body16: ; preds = %for.cond14 183 %tmp18 = load i32* %i, align 4 184 %idxprom17 = sext i32 %tmp18 to i64 185 %tmp19 = load i32** @data, align 8 186 %arrayidx18 = getelementptr inbounds i32* %tmp19, i64 %idxprom17 187 call void @fct0(i32* %arrayidx18) 188 br label %for.inc19 189 190 for.inc19: ; preds = %for.body16 191 %tmp20 = load i32* %i, align 4 192 %inc20 = add nsw i32 %tmp20, 1 193 store i32 %inc20, i32* %i, align 4 194 br label %for.cond14 195 196 for.end21: ; preds = %for.cond14 197 %tmp21 = load i32* %res, align 4 198 ret i32 %tmp21 199 } 200 201 define i32 @fct3(i32 %c) nounwind uwtable ssp { 202 entry: 203 ;CHECK-LABEL: @fct3( 204 ;CHECK: call i32 @fct1 205 ; The inline keyword gives a sufficient benefits to inline fct2 206 ;CHECK-NOT: call i32 @fct2 207 %c.addr = alloca i32, align 4 208 store i32 %c, i32* %c.addr, align 4 209 %tmp = load i32* %c.addr, align 4 210 %call = call i32 @fct1(i32 %tmp) 211 %tmp1 = load i32* %c.addr, align 4 212 %call1 = call i32 @fct2(i32 %tmp1) 213 %add = add nsw i32 %call, %call1 214 ret i32 %add 215 } 216 217 define i32 @fct4(i32 %c) minsize nounwind uwtable ssp { 218 entry: 219 ;CHECK-LABEL: @fct4( 220 ;CHECK: call i32 @fct1 221 ; With Oz (minsize attribute), the benefit of inlining fct2 222 ; is the same as fct1, thus no inlining for fct2 223 ;CHECK: call i32 @fct2 224 %c.addr = alloca i32, align 4 225 store i32 %c, i32* %c.addr, align 4 226 %tmp = load i32* %c.addr, align 4 227 %call = call i32 @fct1(i32 %tmp) 228 %tmp1 = load i32* %c.addr, align 4 229 %call1 = call i32 @fct2(i32 %tmp1) 230 %add = add nsw i32 %call, %call1 231 ret i32 %add 232 } 233