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 3target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 4target 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 19define void @test1(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull dereferenceable(4) %c, i32 %n) #0 { 20entry: 21 %cmp11 = icmp sgt i32 %n, 0 22 br i1 %cmp11, label %for.body, label %for.end 23 24for.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 31if.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 39for.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 45for.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 56define void @test2(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull %c, i32 %n) #0 { 57entry: 58 %cmp11 = icmp sgt i32 %n, 0 59 br i1 %cmp11, label %for.body, label %for.end 60 61for.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 68if.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 76for.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 82for.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 99define void @test3(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(12) %c, i32 %n) #0 { 100entry: 101 %cmp11 = icmp sgt i32 %n, 0 102 br i1 %cmp11, label %for.body, label %for.end 103 104for.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 111if.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 120for.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 126for.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 137define void @test4(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(11) %c, i32 %n) #0 { 138entry: 139 %cmp11 = icmp sgt i32 %n, 0 140 br i1 %cmp11, label %for.body, label %for.end 141 142for.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 149if.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 158for.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 164for.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 183define void @test5(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 { 184entry: 185 %not_null = icmp ne i32* %c, null 186 br i1 %not_null, label %not.null, label %for.end 187 188not.null: 189 %cmp11 = icmp sgt i32 %n, 0 190 br i1 %cmp11, label %for.body, label %for.end 191 192for.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 199if.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 207for.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 213for.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 227define i1 @test6(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 { 228entry: 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 233for.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 240if.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 248for.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 254for.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 272define void @test7(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 { 273entry: 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 278for.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 285if.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 293for.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 299for.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 319define void @test8(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 { 320entry: 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 325not.null: 326 %cmp11 = icmp sgt i32 %n, 0 327 br i1 %cmp11, label %for.body, label %for.end 328 329for.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 336if.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 344for.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 350for.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 361define void @test9(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 { 362entry: 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 367for.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 374if.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 382for.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 388for.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 405define void @test10(i32* noalias %a, i32* %b, i32** dereferenceable(8) %cptr, i32 %n) #0 { 406entry: 407 %cmp11 = icmp sgt i32 %n, 0 408 br i1 %cmp11, label %for.body, label %for.end 409 410for.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 417if.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 426for.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 432for.end: ; preds = %for.inc, %entry 433 ret void 434} 435 436define void @test11(i32* noalias %a, i32* %b, i32** dereferenceable(8) %cptr, i32 %n) #0 { 437; CHECK-LABEL: @test11( 438entry: 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 447for.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 455if.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 463for.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 469for.end: ; preds = %for.inc, %entry 470 ret void 471} 472 473declare void @llvm.experimental.guard(i1, ...) 474 475define 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( 479entry: 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 490for.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 497if.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 505for.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 511for.end: ; preds = %for.inc, %entry, %entry 512 ret void 513} 514 515define 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( 520entry: 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 529for.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 536if.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 547for.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 553for.end: ; preds = %for.inc, %entry, %entry 554 call void(i1, ...) @llvm.experimental.guard(i1 %not_null) [ "deopt"() ] 555 ret void 556} 557 558attributes #0 = { nounwind uwtable } 559!0 = !{i64 4} 560