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