1 ; RUN: opt -S -basicaa -licm < %s | FileCheck %s 2 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 3 target triple = "x86_64-unknown-linux-gnu" 4 5 ; This test represents the following function: 6 ; void test1(int * __restrict__ a, int * __restrict__ b, int &c, int n) { 7 ; for (int i = 0; i < n; ++i) 8 ; if (a[i] > 0) 9 ; a[i] = c*b[i]; 10 ; } 11 ; and we want to hoist the load of %c out of the loop. This can be done only 12 ; because the dereferenceable attribute is on %c. 13 14 ; CHECK-LABEL: @test1 15 ; CHECK: load i32, i32* %c, align 4 16 ; CHECK: for.body: 17 18 define void @test1(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull dereferenceable(4) %c, i32 %n) #0 { 19 entry: 20 %cmp11 = icmp sgt i32 %n, 0 21 br i1 %cmp11, label %for.body, label %for.end 22 23 for.body: ; preds = %entry, %for.inc 24 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 25 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 26 %0 = load i32, i32* %arrayidx, align 4 27 %cmp1 = icmp sgt i32 %0, 0 28 br i1 %cmp1, label %if.then, label %for.inc 29 30 if.then: ; preds = %for.body 31 %1 = load i32, i32* %c, align 4 32 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 33 %2 = load i32, i32* %arrayidx3, align 4 34 %mul = mul nsw i32 %2, %1 35 store i32 %mul, i32* %arrayidx, align 4 36 br label %for.inc 37 38 for.inc: ; preds = %for.body, %if.then 39 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 40 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 41 %exitcond = icmp eq i32 %lftr.wideiv, %n 42 br i1 %exitcond, label %for.end, label %for.body 43 44 for.end: ; preds = %for.inc, %entry 45 ret void 46 } 47 48 ; This is the same as @test1, but without the dereferenceable attribute on %c. 49 ; Without this attribute, we should not hoist the load of %c. 50 51 ; CHECK-LABEL: @test2 52 ; CHECK: if.then: 53 ; CHECK: load i32, i32* %c, align 4 54 55 define void @test2(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull %c, i32 %n) #0 { 56 entry: 57 %cmp11 = icmp sgt i32 %n, 0 58 br i1 %cmp11, label %for.body, label %for.end 59 60 for.body: ; preds = %entry, %for.inc 61 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 62 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 63 %0 = load i32, i32* %arrayidx, align 4 64 %cmp1 = icmp sgt i32 %0, 0 65 br i1 %cmp1, label %if.then, label %for.inc 66 67 if.then: ; preds = %for.body 68 %1 = load i32, i32* %c, align 4 69 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 70 %2 = load i32, i32* %arrayidx3, align 4 71 %mul = mul nsw i32 %2, %1 72 store i32 %mul, i32* %arrayidx, align 4 73 br label %for.inc 74 75 for.inc: ; preds = %for.body, %if.then 76 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 77 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 78 %exitcond = icmp eq i32 %lftr.wideiv, %n 79 br i1 %exitcond, label %for.end, label %for.body 80 81 for.end: ; preds = %for.inc, %entry 82 ret void 83 } 84 85 ; This test represents the following function: 86 ; void test3(int * restrict a, int * restrict b, int c[static 3], int n) { 87 ; for (int i = 0; i < n; ++i) 88 ; if (a[i] > 0) 89 ; a[i] = c[2]*b[i]; 90 ; } 91 ; and we want to hoist the load of c[2] out of the loop. This can be done only 92 ; because the dereferenceable attribute is on %c. 93 94 ; CHECK-LABEL: @test3 95 ; CHECK: load i32, i32* %c2, align 4 96 ; CHECK: for.body: 97 98 define void @test3(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(12) %c, i32 %n) #0 { 99 entry: 100 %cmp11 = icmp sgt i32 %n, 0 101 br i1 %cmp11, label %for.body, label %for.end 102 103 for.body: ; preds = %entry, %for.inc 104 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 105 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 106 %0 = load i32, i32* %arrayidx, align 4 107 %cmp1 = icmp sgt i32 %0, 0 108 br i1 %cmp1, label %if.then, label %for.inc 109 110 if.then: ; preds = %for.body 111 %c2 = getelementptr inbounds i32, i32* %c, i64 2 112 %1 = load i32, i32* %c2, align 4 113 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 114 %2 = load i32, i32* %arrayidx3, align 4 115 %mul = mul nsw i32 %2, %1 116 store i32 %mul, i32* %arrayidx, align 4 117 br label %for.inc 118 119 for.inc: ; preds = %for.body, %if.then 120 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 121 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 122 %exitcond = icmp eq i32 %lftr.wideiv, %n 123 br i1 %exitcond, label %for.end, label %for.body 124 125 for.end: ; preds = %for.inc, %entry 126 ret void 127 } 128 129 ; This is the same as @test3, but with a dereferenceable attribute on %c with a 130 ; size too small to cover c[2] (and so we should not hoist it). 131 132 ; CHECK-LABEL: @test4 133 ; CHECK: if.then: 134 ; CHECK: load i32, i32* %c2, align 4 135 136 define void @test4(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(11) %c, i32 %n) #0 { 137 entry: 138 %cmp11 = icmp sgt i32 %n, 0 139 br i1 %cmp11, label %for.body, label %for.end 140 141 for.body: ; preds = %entry, %for.inc 142 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 143 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 144 %0 = load i32, i32* %arrayidx, align 4 145 %cmp1 = icmp sgt i32 %0, 0 146 br i1 %cmp1, label %if.then, label %for.inc 147 148 if.then: ; preds = %for.body 149 %c2 = getelementptr inbounds i32, i32* %c, i64 2 150 %1 = load i32, i32* %c2, align 4 151 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 152 %2 = load i32, i32* %arrayidx3, align 4 153 %mul = mul nsw i32 %2, %1 154 store i32 %mul, i32* %arrayidx, align 4 155 br label %for.inc 156 157 for.inc: ; preds = %for.body, %if.then 158 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 159 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 160 %exitcond = icmp eq i32 %lftr.wideiv, %n 161 br i1 %exitcond, label %for.end, label %for.body 162 163 for.end: ; preds = %for.inc, %entry 164 ret void 165 } 166 167 ; This test represents the following function: 168 ; void test1(int * __restrict__ a, int *b, int &c, int n) { 169 ; if (c != null) 170 ; for (int i = 0; i < n; ++i) 171 ; if (a[i] > 0) 172 ; a[i] = c*b[i]; 173 ; } 174 ; and we want to hoist the load of %c out of the loop. This can be done only 175 ; because the dereferenceable_or_null attribute is on %c and there is a null 176 ; check on %c. 177 178 ; CHECK-LABEL: @test5 179 ; CHECK: load i32, i32* %c, align 4 180 ; CHECK: for.body: 181 182 define void @test5(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 { 183 entry: 184 %not_null = icmp ne i32* %c, null 185 br i1 %not_null, label %not.null, label %for.end 186 187 not.null: 188 %cmp11 = icmp sgt i32 %n, 0 189 br i1 %cmp11, label %for.body, label %for.end 190 191 for.body: ; preds = %not.null, %for.inc 192 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ] 193 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 194 %0 = load i32, i32* %arrayidx, align 4 195 %cmp1 = icmp sgt i32 %0, 0 196 br i1 %cmp1, label %if.then, label %for.inc 197 198 if.then: ; preds = %for.body 199 %1 = load i32, i32* %c, align 4 200 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 201 %2 = load i32, i32* %arrayidx3, align 4 202 %mul = mul nsw i32 %2, %1 203 store i32 %mul, i32* %arrayidx, align 4 204 br label %for.inc 205 206 for.inc: ; preds = %for.body, %if.then 207 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 208 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 209 %exitcond = icmp eq i32 %lftr.wideiv, %n 210 br i1 %exitcond, label %for.end, label %for.body 211 212 for.end: ; preds = %for.inc, %entry, %not.null 213 ret void 214 } 215 216 ; This is the same as @test5, but without the null check on %c. 217 ; Without this check, we should not hoist the load of %c. 218 219 ; This test case has an icmp on c but the use of this comparison is 220 ; not a branch. 221 222 ; CHECK-LABEL: @test6 223 ; CHECK: if.then: 224 ; CHECK: load i32, i32* %c, align 4 225 226 define i1 @test6(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 { 227 entry: 228 %not_null = icmp ne i32* %c, null 229 %cmp11 = icmp sgt i32 %n, 0 230 br i1 %cmp11, label %for.body, label %for.end 231 232 for.body: ; preds = %entry, %for.inc 233 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 234 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 235 %0 = load i32, i32* %arrayidx, align 4 236 %cmp1 = icmp sgt i32 %0, 0 237 br i1 %cmp1, label %if.then, label %for.inc 238 239 if.then: ; preds = %for.body 240 %1 = load i32, i32* %c, align 4 241 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 242 %2 = load i32, i32* %arrayidx3, align 4 243 %mul = mul nsw i32 %2, %1 244 store i32 %mul, i32* %arrayidx, align 4 245 br label %for.inc 246 247 for.inc: ; preds = %for.body, %if.then 248 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 249 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 250 %exitcond = icmp eq i32 %lftr.wideiv, %n 251 br i1 %exitcond, label %for.end, label %for.body 252 253 for.end: ; preds = %for.inc, %entry 254 ret i1 %not_null 255 } 256 257 ; This test represents the following function: 258 ; void test1(int * __restrict__ a, int *b, int **cptr, int n) { 259 ; c = *cptr; 260 ; for (int i = 0; i < n; ++i) 261 ; if (a[i] > 0) 262 ; a[i] = (*c)*b[i]; 263 ; } 264 ; and we want to hoist the load of %c out of the loop. This can be done only 265 ; because the dereferenceable meatdata on the c = *cptr load. 266 267 ; CHECK-LABEL: @test7 268 ; CHECK: load i32, i32* %c, align 4 269 ; CHECK: for.body: 270 271 define void @test7(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 { 272 entry: 273 %c = load i32*, i32** %cptr, !dereferenceable !0 274 %cmp11 = icmp sgt i32 %n, 0 275 br i1 %cmp11, label %for.body, label %for.end 276 277 for.body: ; preds = %entry, %for.inc 278 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 279 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 280 %0 = load i32, i32* %arrayidx, align 4 281 %cmp1 = icmp sgt i32 %0, 0 282 br i1 %cmp1, label %if.then, label %for.inc 283 284 if.then: ; preds = %for.body 285 %1 = load i32, i32* %c, align 4 286 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 287 %2 = load i32, i32* %arrayidx3, align 4 288 %mul = mul nsw i32 %2, %1 289 store i32 %mul, i32* %arrayidx, align 4 290 br label %for.inc 291 292 for.inc: ; preds = %for.body, %if.then 293 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 294 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 295 %exitcond = icmp eq i32 %lftr.wideiv, %n 296 br i1 %exitcond, label %for.end, label %for.body 297 298 for.end: ; preds = %for.inc, %entry 299 ret void 300 } 301 302 ; This test represents the following function: 303 ; void test1(int * __restrict__ a, int *b, int **cptr, int n) { 304 ; c = *cptr; 305 ; if (c != null) 306 ; for (int i = 0; i < n; ++i) 307 ; if (a[i] > 0) 308 ; a[i] = (*c)*b[i]; 309 ; } 310 ; and we want to hoist the load of %c out of the loop. This can be done only 311 ; because the dereferenceable_or_null meatdata on the c = *cptr load and there 312 ; is a null check on %c. 313 314 ; CHECK-LABEL: @test8 315 ; CHECK: load i32, i32* %c, align 4 316 ; CHECK: for.body: 317 318 define void @test8(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 { 319 entry: 320 %c = load i32*, i32** %cptr, !dereferenceable_or_null !0 321 %not_null = icmp ne i32* %c, null 322 br i1 %not_null, label %not.null, label %for.end 323 324 not.null: 325 %cmp11 = icmp sgt i32 %n, 0 326 br i1 %cmp11, label %for.body, label %for.end 327 328 for.body: ; preds = %not.null, %for.inc 329 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ] 330 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 331 %0 = load i32, i32* %arrayidx, align 4 332 %cmp1 = icmp sgt i32 %0, 0 333 br i1 %cmp1, label %if.then, label %for.inc 334 335 if.then: ; preds = %for.body 336 %1 = load i32, i32* %c, align 4 337 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 338 %2 = load i32, i32* %arrayidx3, align 4 339 %mul = mul nsw i32 %2, %1 340 store i32 %mul, i32* %arrayidx, align 4 341 br label %for.inc 342 343 for.inc: ; preds = %for.body, %if.then 344 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 345 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 346 %exitcond = icmp eq i32 %lftr.wideiv, %n 347 br i1 %exitcond, label %for.end, label %for.body 348 349 for.end: ; preds = %for.inc, %entry, %not.null 350 ret void 351 } 352 353 ; This is the same as @test8, but without the null check on %c. 354 ; Without this check, we should not hoist the load of %c. 355 356 ; CHECK-LABEL: @test9 357 ; CHECK: if.then: 358 ; CHECK: load i32, i32* %c, align 4 359 360 define void @test9(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 { 361 entry: 362 %c = load i32*, i32** %cptr, !dereferenceable_or_null !0 363 %cmp11 = icmp sgt i32 %n, 0 364 br i1 %cmp11, label %for.body, label %for.end 365 366 for.body: ; preds = %entry, %for.inc 367 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 368 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 369 %0 = load i32, i32* %arrayidx, align 4 370 %cmp1 = icmp sgt i32 %0, 0 371 br i1 %cmp1, label %if.then, label %for.inc 372 373 if.then: ; preds = %for.body 374 %1 = load i32, i32* %c, align 4 375 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 376 %2 = load i32, i32* %arrayidx3, align 4 377 %mul = mul nsw i32 %2, %1 378 store i32 %mul, i32* %arrayidx, align 4 379 br label %for.inc 380 381 for.inc: ; preds = %for.body, %if.then 382 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 383 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 384 %exitcond = icmp eq i32 %lftr.wideiv, %n 385 br i1 %exitcond, label %for.end, label %for.body 386 387 for.end: ; preds = %for.inc, %entry 388 ret void 389 } 390 391 ; In this test we should be able to only hoist load from %cptr. We can't hoist 392 ; load from %c because it's dereferenceability can depend on %cmp1 condition. 393 ; By moving it out of the loop we break this dependency and can not rely 394 ; on the dereferenceability anymore. 395 ; In other words this test checks that we strip dereferenceability metadata 396 ; after hoisting an instruction. 397 398 ; CHECK-LABEL: @test10 399 ; CHECK: %c = load i32*, i32** %cptr 400 ; CHECK-NOT: dereferenceable 401 ; CHECK: if.then: 402 ; CHECK: load i32, i32* %c, align 4 403 404 define void @test10(i32* noalias %a, i32* %b, i32** dereferenceable(8) %cptr, i32 %n) #0 { 405 entry: 406 %cmp11 = icmp sgt i32 %n, 0 407 br i1 %cmp11, label %for.body, label %for.end 408 409 for.body: ; preds = %entry, %for.inc 410 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 411 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 412 %0 = load i32, i32* %arrayidx, align 4 413 %cmp1 = icmp sgt i32 %0, 0 414 br i1 %cmp1, label %if.then, label %for.inc 415 416 if.then: ; preds = %for.body 417 %c = load i32*, i32** %cptr, !dereferenceable !0 418 %1 = load i32, i32* %c, align 4 419 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 420 %2 = load i32, i32* %arrayidx3, align 4 421 %mul = mul nsw i32 %2, %1 422 store i32 %mul, i32* %arrayidx, align 4 423 br label %for.inc 424 425 for.inc: ; preds = %for.body, %if.then 426 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 427 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 428 %exitcond = icmp eq i32 %lftr.wideiv, %n 429 br i1 %exitcond, label %for.end, label %for.body 430 431 for.end: ; preds = %for.inc, %entry 432 ret void 433 } 434 435 attributes #0 = { nounwind uwtable } 436 !0 = !{i64 4} 437