1 ; RUN: opt -S -basicaa -licm < %s | FileCheck %s 2 ; RUN: opt -aa-pipeline=basic-aa -passes='loop-simplify,require<aa>,require<targetir>,require<scalar-evolution>,loop(simplify-cfg,licm)' -S < %s | FileCheck %s 3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 4 target triple = "x86_64-unknown-linux-gnu" 5 6 ; This test represents the following function: 7 ; void test1(int * __restrict__ a, int * __restrict__ b, int &c, int n) { 8 ; for (int i = 0; i < n; ++i) 9 ; if (a[i] > 0) 10 ; a[i] = c*b[i]; 11 ; } 12 ; and we want to hoist the load of %c out of the loop. This can be done only 13 ; because the dereferenceable attribute is on %c. 14 15 ; CHECK-LABEL: @test1 16 ; CHECK: load i32, i32* %c, align 4 17 ; CHECK: for.body: 18 19 define void @test1(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull dereferenceable(4) %c, i32 %n) #0 { 20 entry: 21 %cmp11 = icmp sgt i32 %n, 0 22 br i1 %cmp11, label %for.body, label %for.end 23 24 for.body: ; preds = %entry, %for.inc 25 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 26 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 27 %0 = load i32, i32* %arrayidx, align 4 28 %cmp1 = icmp sgt i32 %0, 0 29 br i1 %cmp1, label %if.then, label %for.inc 30 31 if.then: ; preds = %for.body 32 %1 = load i32, i32* %c, align 4 33 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 34 %2 = load i32, i32* %arrayidx3, align 4 35 %mul = mul nsw i32 %2, %1 36 store i32 %mul, i32* %arrayidx, align 4 37 br label %for.inc 38 39 for.inc: ; preds = %for.body, %if.then 40 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 41 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 42 %exitcond = icmp eq i32 %lftr.wideiv, %n 43 br i1 %exitcond, label %for.end, label %for.body 44 45 for.end: ; preds = %for.inc, %entry 46 ret void 47 } 48 49 ; This is the same as @test1, but without the dereferenceable attribute on %c. 50 ; Without this attribute, we should not hoist the load of %c. 51 52 ; CHECK-LABEL: @test2 53 ; CHECK: if.then: 54 ; CHECK: load i32, i32* %c, align 4 55 56 define void @test2(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull %c, i32 %n) #0 { 57 entry: 58 %cmp11 = icmp sgt i32 %n, 0 59 br i1 %cmp11, label %for.body, label %for.end 60 61 for.body: ; preds = %entry, %for.inc 62 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 63 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 64 %0 = load i32, i32* %arrayidx, align 4 65 %cmp1 = icmp sgt i32 %0, 0 66 br i1 %cmp1, label %if.then, label %for.inc 67 68 if.then: ; preds = %for.body 69 %1 = load i32, i32* %c, align 4 70 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 71 %2 = load i32, i32* %arrayidx3, align 4 72 %mul = mul nsw i32 %2, %1 73 store i32 %mul, i32* %arrayidx, align 4 74 br label %for.inc 75 76 for.inc: ; preds = %for.body, %if.then 77 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 78 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 79 %exitcond = icmp eq i32 %lftr.wideiv, %n 80 br i1 %exitcond, label %for.end, label %for.body 81 82 for.end: ; preds = %for.inc, %entry 83 ret void 84 } 85 86 ; This test represents the following function: 87 ; void test3(int * restrict a, int * restrict b, int c[static 3], int n) { 88 ; for (int i = 0; i < n; ++i) 89 ; if (a[i] > 0) 90 ; a[i] = c[2]*b[i]; 91 ; } 92 ; and we want to hoist the load of c[2] out of the loop. This can be done only 93 ; because the dereferenceable attribute is on %c. 94 95 ; CHECK-LABEL: @test3 96 ; CHECK: load i32, i32* %c2, align 4 97 ; CHECK: for.body: 98 99 define void @test3(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(12) %c, i32 %n) #0 { 100 entry: 101 %cmp11 = icmp sgt i32 %n, 0 102 br i1 %cmp11, label %for.body, label %for.end 103 104 for.body: ; preds = %entry, %for.inc 105 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 106 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 107 %0 = load i32, i32* %arrayidx, align 4 108 %cmp1 = icmp sgt i32 %0, 0 109 br i1 %cmp1, label %if.then, label %for.inc 110 111 if.then: ; preds = %for.body 112 %c2 = getelementptr inbounds i32, i32* %c, i64 2 113 %1 = load i32, i32* %c2, align 4 114 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 115 %2 = load i32, i32* %arrayidx3, align 4 116 %mul = mul nsw i32 %2, %1 117 store i32 %mul, i32* %arrayidx, align 4 118 br label %for.inc 119 120 for.inc: ; preds = %for.body, %if.then 121 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 122 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 123 %exitcond = icmp eq i32 %lftr.wideiv, %n 124 br i1 %exitcond, label %for.end, label %for.body 125 126 for.end: ; preds = %for.inc, %entry 127 ret void 128 } 129 130 ; This is the same as @test3, but with a dereferenceable attribute on %c with a 131 ; size too small to cover c[2] (and so we should not hoist it). 132 133 ; CHECK-LABEL: @test4 134 ; CHECK: if.then: 135 ; CHECK: load i32, i32* %c2, align 4 136 137 define void @test4(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(11) %c, i32 %n) #0 { 138 entry: 139 %cmp11 = icmp sgt i32 %n, 0 140 br i1 %cmp11, label %for.body, label %for.end 141 142 for.body: ; preds = %entry, %for.inc 143 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 144 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 145 %0 = load i32, i32* %arrayidx, align 4 146 %cmp1 = icmp sgt i32 %0, 0 147 br i1 %cmp1, label %if.then, label %for.inc 148 149 if.then: ; preds = %for.body 150 %c2 = getelementptr inbounds i32, i32* %c, i64 2 151 %1 = load i32, i32* %c2, align 4 152 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 153 %2 = load i32, i32* %arrayidx3, align 4 154 %mul = mul nsw i32 %2, %1 155 store i32 %mul, i32* %arrayidx, align 4 156 br label %for.inc 157 158 for.inc: ; preds = %for.body, %if.then 159 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 160 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 161 %exitcond = icmp eq i32 %lftr.wideiv, %n 162 br i1 %exitcond, label %for.end, label %for.body 163 164 for.end: ; preds = %for.inc, %entry 165 ret void 166 } 167 168 ; This test represents the following function: 169 ; void test1(int * __restrict__ a, int *b, int &c, int n) { 170 ; if (c != null) 171 ; for (int i = 0; i < n; ++i) 172 ; if (a[i] > 0) 173 ; a[i] = c*b[i]; 174 ; } 175 ; and we want to hoist the load of %c out of the loop. This can be done only 176 ; because the dereferenceable_or_null attribute is on %c and there is a null 177 ; check on %c. 178 179 ; CHECK-LABEL: @test5 180 ; CHECK: load i32, i32* %c, align 4 181 ; CHECK: for.body: 182 183 define void @test5(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 { 184 entry: 185 %not_null = icmp ne i32* %c, null 186 br i1 %not_null, label %not.null, label %for.end 187 188 not.null: 189 %cmp11 = icmp sgt i32 %n, 0 190 br i1 %cmp11, label %for.body, label %for.end 191 192 for.body: ; preds = %not.null, %for.inc 193 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ] 194 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 195 %0 = load i32, i32* %arrayidx, align 4 196 %cmp1 = icmp sgt i32 %0, 0 197 br i1 %cmp1, label %if.then, label %for.inc 198 199 if.then: ; preds = %for.body 200 %1 = load i32, i32* %c, align 4 201 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 202 %2 = load i32, i32* %arrayidx3, align 4 203 %mul = mul nsw i32 %2, %1 204 store i32 %mul, i32* %arrayidx, align 4 205 br label %for.inc 206 207 for.inc: ; preds = %for.body, %if.then 208 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 209 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 210 %exitcond = icmp eq i32 %lftr.wideiv, %n 211 br i1 %exitcond, label %for.end, label %for.body 212 213 for.end: ; preds = %for.inc, %entry, %not.null 214 ret void 215 } 216 217 ; This is the same as @test5, but without the null check on %c. 218 ; Without this check, we should not hoist the load of %c. 219 220 ; This test case has an icmp on c but the use of this comparison is 221 ; not a branch. 222 223 ; CHECK-LABEL: @test6 224 ; CHECK: if.then: 225 ; CHECK: load i32, i32* %c, align 4 226 227 define i1 @test6(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 { 228 entry: 229 %not_null = icmp ne i32* %c, null 230 %cmp11 = icmp sgt i32 %n, 0 231 br i1 %cmp11, label %for.body, label %for.end 232 233 for.body: ; preds = %entry, %for.inc 234 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 235 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 236 %0 = load i32, i32* %arrayidx, align 4 237 %cmp1 = icmp sgt i32 %0, 0 238 br i1 %cmp1, label %if.then, label %for.inc 239 240 if.then: ; preds = %for.body 241 %1 = load i32, i32* %c, align 4 242 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 243 %2 = load i32, i32* %arrayidx3, align 4 244 %mul = mul nsw i32 %2, %1 245 store i32 %mul, i32* %arrayidx, align 4 246 br label %for.inc 247 248 for.inc: ; preds = %for.body, %if.then 249 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 250 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 251 %exitcond = icmp eq i32 %lftr.wideiv, %n 252 br i1 %exitcond, label %for.end, label %for.body 253 254 for.end: ; preds = %for.inc, %entry 255 ret i1 %not_null 256 } 257 258 ; This test represents the following function: 259 ; void test1(int * __restrict__ a, int *b, int **cptr, int n) { 260 ; c = *cptr; 261 ; for (int i = 0; i < n; ++i) 262 ; if (a[i] > 0) 263 ; a[i] = (*c)*b[i]; 264 ; } 265 ; and we want to hoist the load of %c out of the loop. This can be done only 266 ; because the dereferenceable meatdata on the c = *cptr load. 267 268 ; CHECK-LABEL: @test7 269 ; CHECK: load i32, i32* %c, align 4 270 ; CHECK: for.body: 271 272 define void @test7(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 { 273 entry: 274 %c = load i32*, i32** %cptr, !dereferenceable !0 275 %cmp11 = icmp sgt i32 %n, 0 276 br i1 %cmp11, label %for.body, label %for.end 277 278 for.body: ; preds = %entry, %for.inc 279 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 280 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 281 %0 = load i32, i32* %arrayidx, align 4 282 %cmp1 = icmp sgt i32 %0, 0 283 br i1 %cmp1, label %if.then, label %for.inc 284 285 if.then: ; preds = %for.body 286 %1 = load i32, i32* %c, align 4 287 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 288 %2 = load i32, i32* %arrayidx3, align 4 289 %mul = mul nsw i32 %2, %1 290 store i32 %mul, i32* %arrayidx, align 4 291 br label %for.inc 292 293 for.inc: ; preds = %for.body, %if.then 294 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 295 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 296 %exitcond = icmp eq i32 %lftr.wideiv, %n 297 br i1 %exitcond, label %for.end, label %for.body 298 299 for.end: ; preds = %for.inc, %entry 300 ret void 301 } 302 303 ; This test represents the following function: 304 ; void test1(int * __restrict__ a, int *b, int **cptr, int n) { 305 ; c = *cptr; 306 ; if (c != null) 307 ; for (int i = 0; i < n; ++i) 308 ; if (a[i] > 0) 309 ; a[i] = (*c)*b[i]; 310 ; } 311 ; and we want to hoist the load of %c out of the loop. This can be done only 312 ; because the dereferenceable_or_null meatdata on the c = *cptr load and there 313 ; is a null check on %c. 314 315 ; CHECK-LABEL: @test8 316 ; CHECK: load i32, i32* %c, align 4 317 ; CHECK: for.body: 318 319 define void @test8(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 { 320 entry: 321 %c = load i32*, i32** %cptr, !dereferenceable_or_null !0 322 %not_null = icmp ne i32* %c, null 323 br i1 %not_null, label %not.null, label %for.end 324 325 not.null: 326 %cmp11 = icmp sgt i32 %n, 0 327 br i1 %cmp11, label %for.body, label %for.end 328 329 for.body: ; preds = %not.null, %for.inc 330 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ] 331 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 332 %0 = load i32, i32* %arrayidx, align 4 333 %cmp1 = icmp sgt i32 %0, 0 334 br i1 %cmp1, label %if.then, label %for.inc 335 336 if.then: ; preds = %for.body 337 %1 = load i32, i32* %c, align 4 338 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 339 %2 = load i32, i32* %arrayidx3, align 4 340 %mul = mul nsw i32 %2, %1 341 store i32 %mul, i32* %arrayidx, align 4 342 br label %for.inc 343 344 for.inc: ; preds = %for.body, %if.then 345 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 346 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 347 %exitcond = icmp eq i32 %lftr.wideiv, %n 348 br i1 %exitcond, label %for.end, label %for.body 349 350 for.end: ; preds = %for.inc, %entry, %not.null 351 ret void 352 } 353 354 ; This is the same as @test8, but without the null check on %c. 355 ; Without this check, we should not hoist the load of %c. 356 357 ; CHECK-LABEL: @test9 358 ; CHECK: if.then: 359 ; CHECK: load i32, i32* %c, align 4 360 361 define void @test9(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 { 362 entry: 363 %c = load i32*, i32** %cptr, !dereferenceable_or_null !0 364 %cmp11 = icmp sgt i32 %n, 0 365 br i1 %cmp11, label %for.body, label %for.end 366 367 for.body: ; preds = %entry, %for.inc 368 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 369 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 370 %0 = load i32, i32* %arrayidx, align 4 371 %cmp1 = icmp sgt i32 %0, 0 372 br i1 %cmp1, label %if.then, label %for.inc 373 374 if.then: ; preds = %for.body 375 %1 = load i32, i32* %c, align 4 376 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 377 %2 = load i32, i32* %arrayidx3, align 4 378 %mul = mul nsw i32 %2, %1 379 store i32 %mul, i32* %arrayidx, align 4 380 br label %for.inc 381 382 for.inc: ; preds = %for.body, %if.then 383 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 384 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 385 %exitcond = icmp eq i32 %lftr.wideiv, %n 386 br i1 %exitcond, label %for.end, label %for.body 387 388 for.end: ; preds = %for.inc, %entry 389 ret void 390 } 391 392 ; In this test we should be able to only hoist load from %cptr. We can't hoist 393 ; load from %c because it's dereferenceability can depend on %cmp1 condition. 394 ; By moving it out of the loop we break this dependency and can not rely 395 ; on the dereferenceability anymore. 396 ; In other words this test checks that we strip dereferenceability metadata 397 ; after hoisting an instruction. 398 399 ; CHECK-LABEL: @test10 400 ; CHECK: %c = load i32*, i32** %cptr 401 ; CHECK-NOT: dereferenceable 402 ; CHECK: if.then: 403 ; CHECK: load i32, i32* %c, align 4 404 405 define void @test10(i32* noalias %a, i32* %b, i32** dereferenceable(8) %cptr, i32 %n) #0 { 406 entry: 407 %cmp11 = icmp sgt i32 %n, 0 408 br i1 %cmp11, label %for.body, label %for.end 409 410 for.body: ; preds = %entry, %for.inc 411 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 412 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 413 %0 = load i32, i32* %arrayidx, align 4 414 %cmp1 = icmp sgt i32 %0, 0 415 br i1 %cmp1, label %if.then, label %for.inc 416 417 if.then: ; preds = %for.body 418 %c = load i32*, i32** %cptr, !dereferenceable !0 419 %1 = load i32, i32* %c, align 4 420 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 421 %2 = load i32, i32* %arrayidx3, align 4 422 %mul = mul nsw i32 %2, %1 423 store i32 %mul, i32* %arrayidx, align 4 424 br label %for.inc 425 426 for.inc: ; preds = %for.body, %if.then 427 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 428 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 429 %exitcond = icmp eq i32 %lftr.wideiv, %n 430 br i1 %exitcond, label %for.end, label %for.body 431 432 for.end: ; preds = %for.inc, %entry 433 ret void 434 } 435 436 define void @test11(i32* noalias %a, i32* %b, i32** dereferenceable(8) %cptr, i32 %n) #0 { 437 ; CHECK-LABEL: @test11( 438 entry: 439 %cmp11 = icmp sgt i32 %n, 0 440 br i1 %cmp11, label %for.body, label %for.end 441 442 ; CHECK: for.body.preheader: 443 ; CHECK: %c = load i32*, i32** %cptr, !dereferenceable !0 444 ; CHECK: %d = load i32, i32* %c, align 4 445 446 447 for.body: ; preds = %entry, %for.inc 448 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 449 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 450 %0 = load i32, i32* %arrayidx, align 4 451 %cmp1 = icmp sgt i32 %0, 0 452 %c = load i32*, i32** %cptr, !dereferenceable !0 453 br i1 %cmp1, label %if.then, label %for.inc 454 455 if.then: ; preds = %for.body 456 %d = load i32, i32* %c, align 4 457 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 458 %e = load i32, i32* %arrayidx3, align 4 459 %mul = mul nsw i32 %e, %d 460 store i32 %mul, i32* %arrayidx, align 4 461 br label %for.inc 462 463 for.inc: ; preds = %for.body, %if.then 464 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 465 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 466 %exitcond = icmp eq i32 %lftr.wideiv, %n 467 br i1 %exitcond, label %for.end, label %for.body 468 469 for.end: ; preds = %for.inc, %entry 470 ret void 471 } 472 473 declare void @llvm.experimental.guard(i1, ...) 474 475 define void @test12(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 { 476 ; Prove non-null ness of %c via a guard, not a branch. 477 478 ; CHECK-LABEL: @test12( 479 entry: 480 %not_null = icmp ne i32* %c, null 481 call void(i1, ...) @llvm.experimental.guard(i1 %not_null) [ "deopt"() ] 482 %cmp11 = icmp sgt i32 %n, 0 483 br i1 %cmp11, label %for.body, label %for.end 484 485 ; CHECK: for.body.preheader: 486 ; CHECK-NEXT: [[VAL:%[^ ]]] = load i32, i32* %c, align 4 487 ; CHECK-NEXT: br label %for.body 488 489 490 for.body: ; preds = %entry, %for.inc 491 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 492 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 493 %0 = load i32, i32* %arrayidx, align 4 494 %cmp1 = icmp sgt i32 %0, 0 495 br i1 %cmp1, label %if.then, label %for.inc 496 497 if.then: ; preds = %for.body 498 %1 = load i32, i32* %c, align 4 499 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 500 %2 = load i32, i32* %arrayidx3, align 4 501 %mul = mul nsw i32 %2, %1 502 store i32 %mul, i32* %arrayidx, align 4 503 br label %for.inc 504 505 for.inc: ; preds = %for.body, %if.then 506 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 507 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 508 %exitcond = icmp eq i32 %lftr.wideiv, %n 509 br i1 %exitcond, label %for.end, label %for.body 510 511 for.end: ; preds = %for.inc, %entry, %entry 512 ret void 513 } 514 515 define void @test13(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 { 516 ; Like @test12, but has a post-dominating guard, which cannot be used 517 ; to prove %c is nonnull at the point of the load. 518 519 ; CHECK-LABEL: @test13( 520 entry: 521 %not_null = icmp ne i32* %c, null 522 %cmp11 = icmp sgt i32 %n, 0 523 br i1 %cmp11, label %for.body, label %for.end 524 525 ; CHECK: for.body.preheader: 526 ; CHECK-NOT: load i32, i32* %c 527 ; CHECK: br label %for.body 528 529 for.body: ; preds = %entry, %for.inc 530 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 531 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 532 %0 = load i32, i32* %arrayidx, align 4 533 %cmp1 = icmp sgt i32 %0, 0 534 br i1 %cmp1, label %if.then, label %for.inc 535 536 if.then: ; preds = %for.body 537 ; CHECK: if.then: 538 ; CHECK: load i32, i32* %c 539 ; CHECK: br label %for.inc 540 %1 = load i32, i32* %c, align 4 541 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 542 %2 = load i32, i32* %arrayidx3, align 4 543 %mul = mul nsw i32 %2, %1 544 store i32 %mul, i32* %arrayidx, align 4 545 br label %for.inc 546 547 for.inc: ; preds = %for.body, %if.then 548 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 549 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 550 %exitcond = icmp eq i32 %lftr.wideiv, %n 551 br i1 %exitcond, label %for.end, label %for.body 552 553 for.end: ; preds = %for.inc, %entry, %entry 554 call void(i1, ...) @llvm.experimental.guard(i1 %not_null) [ "deopt"() ] 555 ret void 556 } 557 558 attributes #0 = { nounwind uwtable } 559 !0 = !{i64 4} 560