1; RUN: opt -S -basic-aa -licm < %s | FileCheck %s 2; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(loop-simplifycfg,licm)' -S < %s | FileCheck %s 3; RUN: opt -S -basic-aa -licm -enable-mssa-loop-dependency=true -verify-memoryssa < %s | FileCheck %s 4; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(loop-simplifycfg,licm)' -verify-memoryssa -S < %s | FileCheck %s 5 6target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 7target triple = "x86_64-unknown-linux-gnu" 8 9; This test represents the following function: 10; void test1(int * __restrict__ a, int * __restrict__ b, int &c, int n) { 11; for (int i = 0; i < n; ++i) 12; if (a[i] > 0) 13; a[i] = c*b[i]; 14; } 15; and we want to hoist the load of %c out of the loop. This can be done only 16; because the dereferenceable attribute is on %c. 17 18; CHECK-LABEL: @test1 19; CHECK: load i32, i32* %c, align 4 20; CHECK: for.body: 21 22define void @test1(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull dereferenceable(4) align 4 %c, i32 %n) #0 { 23entry: 24 %cmp11 = icmp sgt i32 %n, 0 25 br i1 %cmp11, label %for.body, label %for.end 26 27for.body: ; preds = %entry, %for.inc 28 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 29 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 30 %0 = load i32, i32* %arrayidx, align 4 31 %cmp1 = icmp sgt i32 %0, 0 32 br i1 %cmp1, label %if.then, label %for.inc 33 34if.then: ; preds = %for.body 35 %1 = load i32, i32* %c, align 4 36 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 37 %2 = load i32, i32* %arrayidx3, align 4 38 %mul = mul nsw i32 %2, %1 39 store i32 %mul, i32* %arrayidx, align 4 40 br label %for.inc 41 42for.inc: ; preds = %for.body, %if.then 43 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 44 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 45 %exitcond = icmp eq i32 %lftr.wideiv, %n 46 br i1 %exitcond, label %for.end, label %for.body 47 48for.end: ; preds = %for.inc, %entry 49 ret void 50} 51 52; This is the same as @test1, but without the dereferenceable attribute on %c. 53; Without this attribute, we should not hoist the load of %c. 54 55; CHECK-LABEL: @test2 56; CHECK: if.then: 57; CHECK: load i32, i32* %c, align 4 58 59define void @test2(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull %c, i32 %n) #0 { 60entry: 61 %cmp11 = icmp sgt i32 %n, 0 62 br i1 %cmp11, label %for.body, label %for.end 63 64for.body: ; preds = %entry, %for.inc 65 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 66 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 67 %0 = load i32, i32* %arrayidx, align 4 68 %cmp1 = icmp sgt i32 %0, 0 69 br i1 %cmp1, label %if.then, label %for.inc 70 71if.then: ; preds = %for.body 72 %1 = load i32, i32* %c, align 4 73 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 74 %2 = load i32, i32* %arrayidx3, align 4 75 %mul = mul nsw i32 %2, %1 76 store i32 %mul, i32* %arrayidx, align 4 77 br label %for.inc 78 79for.inc: ; preds = %for.body, %if.then 80 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 81 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 82 %exitcond = icmp eq i32 %lftr.wideiv, %n 83 br i1 %exitcond, label %for.end, label %for.body 84 85for.end: ; preds = %for.inc, %entry 86 ret void 87} 88 89; This test represents the following function: 90; void test3(int * restrict a, int * restrict b, int c[static 3], int n) { 91; for (int i = 0; i < n; ++i) 92; if (a[i] > 0) 93; a[i] = c[2]*b[i]; 94; } 95; and we want to hoist the load of c[2] out of the loop. This can be done only 96; because the dereferenceable attribute is on %c. 97 98; CHECK-LABEL: @test3 99; CHECK: load i32, i32* %c2, align 4 100; CHECK: for.body: 101 102define void @test3(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(12) align 4 %c, i32 %n) #0 { 103entry: 104 %cmp11 = icmp sgt i32 %n, 0 105 br i1 %cmp11, label %for.body, label %for.end 106 107for.body: ; preds = %entry, %for.inc 108 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 109 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 110 %0 = load i32, i32* %arrayidx, align 4 111 %cmp1 = icmp sgt i32 %0, 0 112 br i1 %cmp1, label %if.then, label %for.inc 113 114if.then: ; preds = %for.body 115 %c2 = getelementptr inbounds i32, i32* %c, i64 2 116 %1 = load i32, i32* %c2, align 4 117 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 118 %2 = load i32, i32* %arrayidx3, align 4 119 %mul = mul nsw i32 %2, %1 120 store i32 %mul, i32* %arrayidx, align 4 121 br label %for.inc 122 123for.inc: ; preds = %for.body, %if.then 124 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 125 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 126 %exitcond = icmp eq i32 %lftr.wideiv, %n 127 br i1 %exitcond, label %for.end, label %for.body 128 129for.end: ; preds = %for.inc, %entry 130 ret void 131} 132 133; This is the same as @test3, but with a dereferenceable attribute on %c with a 134; size too small to cover c[2] (and so we should not hoist it). 135 136; CHECK-LABEL: @test4 137; CHECK: if.then: 138; CHECK: load i32, i32* %c2, align 4 139 140define void @test4(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(11) %c, i32 %n) #0 { 141entry: 142 %cmp11 = icmp sgt i32 %n, 0 143 br i1 %cmp11, label %for.body, label %for.end 144 145for.body: ; preds = %entry, %for.inc 146 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 147 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 148 %0 = load i32, i32* %arrayidx, align 4 149 %cmp1 = icmp sgt i32 %0, 0 150 br i1 %cmp1, label %if.then, label %for.inc 151 152if.then: ; preds = %for.body 153 %c2 = getelementptr inbounds i32, i32* %c, i64 2 154 %1 = load i32, i32* %c2, align 4 155 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 156 %2 = load i32, i32* %arrayidx3, align 4 157 %mul = mul nsw i32 %2, %1 158 store i32 %mul, i32* %arrayidx, align 4 159 br label %for.inc 160 161for.inc: ; preds = %for.body, %if.then 162 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 163 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 164 %exitcond = icmp eq i32 %lftr.wideiv, %n 165 br i1 %exitcond, label %for.end, label %for.body 166 167for.end: ; preds = %for.inc, %entry 168 ret void 169} 170 171; This test represents the following function: 172; void test1(int * __restrict__ a, int *b, int &c, int n) { 173; if (c != null) 174; for (int i = 0; i < n; ++i) 175; if (a[i] > 0) 176; a[i] = c*b[i]; 177; } 178; and we want to hoist the load of %c out of the loop. This can be done only 179; because the dereferenceable_or_null attribute is on %c and there is a null 180; check on %c. 181 182; CHECK-LABEL: @test5 183; CHECK: load i32, i32* %c, align 4 184; CHECK: for.body: 185 186define void @test5(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) align 4 %c, i32 %n) #0 { 187entry: 188 %not_null = icmp ne i32* %c, null 189 br i1 %not_null, label %not.null, label %for.end 190 191not.null: 192 %cmp11 = icmp sgt i32 %n, 0 193 br i1 %cmp11, label %for.body, label %for.end 194 195for.body: ; preds = %not.null, %for.inc 196 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ] 197 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 198 %0 = load i32, i32* %arrayidx, align 4 199 %cmp1 = icmp sgt i32 %0, 0 200 br i1 %cmp1, label %if.then, label %for.inc 201 202if.then: ; preds = %for.body 203 %1 = load i32, i32* %c, align 4 204 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 205 %2 = load i32, i32* %arrayidx3, align 4 206 %mul = mul nsw i32 %2, %1 207 store i32 %mul, i32* %arrayidx, align 4 208 br label %for.inc 209 210for.inc: ; preds = %for.body, %if.then 211 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 212 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 213 %exitcond = icmp eq i32 %lftr.wideiv, %n 214 br i1 %exitcond, label %for.end, label %for.body 215 216for.end: ; preds = %for.inc, %entry, %not.null 217 ret void 218} 219 220; This is the same as @test5, but without the null check on %c. 221; Without this check, we should not hoist the load of %c. 222 223; This test case has an icmp on c but the use of this comparison is 224; not a branch. 225 226; CHECK-LABEL: @test6 227; CHECK: if.then: 228; CHECK: load i32, i32* %c, align 4 229 230define i1 @test6(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 { 231entry: 232 %not_null = icmp ne i32* %c, null 233 %cmp11 = icmp sgt i32 %n, 0 234 br i1 %cmp11, label %for.body, label %for.end 235 236for.body: ; preds = %entry, %for.inc 237 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 238 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 239 %0 = load i32, i32* %arrayidx, align 4 240 %cmp1 = icmp sgt i32 %0, 0 241 br i1 %cmp1, label %if.then, label %for.inc 242 243if.then: ; preds = %for.body 244 %1 = load i32, i32* %c, align 4 245 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 246 %2 = load i32, i32* %arrayidx3, align 4 247 %mul = mul nsw i32 %2, %1 248 store i32 %mul, i32* %arrayidx, align 4 249 br label %for.inc 250 251for.inc: ; preds = %for.body, %if.then 252 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 253 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 254 %exitcond = icmp eq i32 %lftr.wideiv, %n 255 br i1 %exitcond, label %for.end, label %for.body 256 257for.end: ; preds = %for.inc, %entry 258 ret i1 %not_null 259} 260 261; This test represents the following function: 262; void test1(int * __restrict__ a, int *b, int **cptr, int n) { 263; c = *cptr; 264; for (int i = 0; i < n; ++i) 265; if (a[i] > 0) 266; a[i] = (*c)*b[i]; 267; } 268; and we want to hoist the load of %c out of the loop. This can be done only 269; because the dereferenceable meatdata on the c = *cptr load. 270 271; CHECK-LABEL: @test7 272; CHECK: load i32, i32* %c, align 4 273; CHECK: for.body: 274 275define void @test7(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 { 276entry: 277 %c = load i32*, i32** %cptr, !dereferenceable !0, !align !{i64 4} 278 %cmp11 = icmp sgt i32 %n, 0 279 br i1 %cmp11, label %for.body, label %for.end 280 281for.body: ; preds = %entry, %for.inc 282 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 283 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 284 %0 = load i32, i32* %arrayidx, align 4 285 %cmp1 = icmp sgt i32 %0, 0 286 br i1 %cmp1, label %if.then, label %for.inc 287 288if.then: ; preds = %for.body 289 %1 = load i32, i32* %c, align 4 290 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 291 %2 = load i32, i32* %arrayidx3, align 4 292 %mul = mul nsw i32 %2, %1 293 store i32 %mul, i32* %arrayidx, align 4 294 br label %for.inc 295 296for.inc: ; preds = %for.body, %if.then 297 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 298 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 299 %exitcond = icmp eq i32 %lftr.wideiv, %n 300 br i1 %exitcond, label %for.end, label %for.body 301 302for.end: ; preds = %for.inc, %entry 303 ret void 304} 305 306; This test represents the following function: 307; void test1(int * __restrict__ a, int *b, int **cptr, int n) { 308; c = *cptr; 309; if (c != null) 310; for (int i = 0; i < n; ++i) 311; if (a[i] > 0) 312; a[i] = (*c)*b[i]; 313; } 314; and we want to hoist the load of %c out of the loop. This can be done only 315; because the dereferenceable_or_null meatdata on the c = *cptr load and there 316; is a null check on %c. 317 318; CHECK-LABEL: @test8 319; CHECK: load i32, i32* %c, align 4 320; CHECK: for.body: 321 322define void @test8(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 { 323entry: 324 %c = load i32*, i32** %cptr, !dereferenceable_or_null !0, !align !{i64 4} 325 %not_null = icmp ne i32* %c, null 326 br i1 %not_null, label %not.null, label %for.end 327 328not.null: 329 %cmp11 = icmp sgt i32 %n, 0 330 br i1 %cmp11, label %for.body, label %for.end 331 332for.body: ; preds = %not.null, %for.inc 333 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ] 334 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 335 %0 = load i32, i32* %arrayidx, align 4 336 %cmp1 = icmp sgt i32 %0, 0 337 br i1 %cmp1, label %if.then, label %for.inc 338 339if.then: ; preds = %for.body 340 %1 = load i32, i32* %c, align 4 341 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 342 %2 = load i32, i32* %arrayidx3, align 4 343 %mul = mul nsw i32 %2, %1 344 store i32 %mul, i32* %arrayidx, align 4 345 br label %for.inc 346 347for.inc: ; preds = %for.body, %if.then 348 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 349 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 350 %exitcond = icmp eq i32 %lftr.wideiv, %n 351 br i1 %exitcond, label %for.end, label %for.body 352 353for.end: ; preds = %for.inc, %entry, %not.null 354 ret void 355} 356 357; This is the same as @test8, but without the null check on %c. 358; Without this check, we should not hoist the load of %c. 359 360; CHECK-LABEL: @test9 361; CHECK: if.then: 362; CHECK: load i32, i32* %c, align 4 363 364define void @test9(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 { 365entry: 366 %c = load i32*, i32** %cptr, !dereferenceable_or_null !0 367 %cmp11 = icmp sgt i32 %n, 0 368 br i1 %cmp11, label %for.body, label %for.end 369 370for.body: ; preds = %entry, %for.inc 371 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 372 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 373 %0 = load i32, i32* %arrayidx, align 4 374 %cmp1 = icmp sgt i32 %0, 0 375 br i1 %cmp1, label %if.then, label %for.inc 376 377if.then: ; preds = %for.body 378 %1 = load i32, i32* %c, align 4 379 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 380 %2 = load i32, i32* %arrayidx3, align 4 381 %mul = mul nsw i32 %2, %1 382 store i32 %mul, i32* %arrayidx, align 4 383 br label %for.inc 384 385for.inc: ; preds = %for.body, %if.then 386 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 387 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 388 %exitcond = icmp eq i32 %lftr.wideiv, %n 389 br i1 %exitcond, label %for.end, label %for.body 390 391for.end: ; preds = %for.inc, %entry 392 ret void 393} 394 395; In this test we should be able to only hoist load from %cptr. We can't hoist 396; load from %c because it's dereferenceability can depend on %cmp1 condition. 397; By moving it out of the loop we break this dependency and can not rely 398; on the dereferenceability anymore. 399; In other words this test checks that we strip dereferenceability metadata 400; after hoisting an instruction. 401 402; CHECK-LABEL: @test10 403; CHECK: %c = load i32*, i32** %cptr 404; CHECK-NOT: dereferenceable 405; CHECK: if.then: 406; CHECK: load i32, i32* %c, align 4 407 408define void @test10(i32* noalias %a, i32* %b, i32** dereferenceable(8) align 8 %cptr, i32 %n) #0 { 409entry: 410 %cmp11 = icmp sgt i32 %n, 0 411 br i1 %cmp11, label %for.body, label %for.end 412 413for.body: ; preds = %entry, %for.inc 414 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 415 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 416 %0 = load i32, i32* %arrayidx, align 4 417 %cmp1 = icmp sgt i32 %0, 0 418 br i1 %cmp1, label %if.then, label %for.inc 419 420if.then: ; preds = %for.body 421 %c = load i32*, i32** %cptr, !dereferenceable !0 422 %1 = load i32, i32* %c, align 4 423 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 424 %2 = load i32, i32* %arrayidx3, align 4 425 %mul = mul nsw i32 %2, %1 426 store i32 %mul, i32* %arrayidx, align 4 427 br label %for.inc 428 429for.inc: ; preds = %for.body, %if.then 430 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 431 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 432 %exitcond = icmp eq i32 %lftr.wideiv, %n 433 br i1 %exitcond, label %for.end, label %for.body 434 435for.end: ; preds = %for.inc, %entry 436 ret void 437} 438 439define void @test11(i32* noalias %a, i32* %b, i32** dereferenceable(8) %cptr, i32 %n) #0 { 440; CHECK-LABEL: @test11( 441entry: 442 %cmp11 = icmp sgt i32 %n, 0 443 br i1 %cmp11, label %for.body, label %for.end 444 445; CHECK: for.body.preheader: 446; CHECK: %c = load i32*, i32** %cptr, align 8, !dereferenceable !0 447; CHECK: %d = load i32, i32* %c, align 4 448 449 450for.body: ; preds = %entry, %for.inc 451 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 452 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 453 %0 = load i32, i32* %arrayidx, align 4 454 %cmp1 = icmp sgt i32 %0, 0 455 %c = load i32*, i32** %cptr, !dereferenceable !0 456 br i1 %cmp1, label %if.then, label %for.inc 457 458if.then: ; preds = %for.body 459 %d = load i32, i32* %c, align 4 460 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 461 %e = load i32, i32* %arrayidx3, align 4 462 %mul = mul nsw i32 %e, %d 463 store i32 %mul, i32* %arrayidx, align 4 464 br label %for.inc 465 466for.inc: ; preds = %for.body, %if.then 467 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 468 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 469 %exitcond = icmp eq i32 %lftr.wideiv, %n 470 br i1 %exitcond, label %for.end, label %for.body 471 472for.end: ; preds = %for.inc, %entry 473 ret void 474} 475 476declare void @llvm.experimental.guard(i1, ...) 477 478define void @test12(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) align 4 %c, i32 %n) #0 { 479; Prove non-null ness of %c via a guard, not a branch. 480 481; CHECK-LABEL: @test12( 482entry: 483 %not_null = icmp ne i32* %c, null 484 call void(i1, ...) @llvm.experimental.guard(i1 %not_null) [ "deopt"() ] 485 %cmp11 = icmp sgt i32 %n, 0 486 br i1 %cmp11, label %for.body, label %for.end 487 488; CHECK: for.body.preheader: 489; CHECK-NEXT: [[VAL:%[^ ]]] = load i32, i32* %c, align 4 490; CHECK-NEXT: br label %for.body 491 492 493for.body: ; preds = %entry, %for.inc 494 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 495 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 496 %0 = load i32, i32* %arrayidx, align 4 497 %cmp1 = icmp sgt i32 %0, 0 498 br i1 %cmp1, label %if.then, label %for.inc 499 500if.then: ; preds = %for.body 501 %1 = load i32, i32* %c, align 4 502 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 503 %2 = load i32, i32* %arrayidx3, align 4 504 %mul = mul nsw i32 %2, %1 505 store i32 %mul, i32* %arrayidx, align 4 506 br label %for.inc 507 508for.inc: ; preds = %for.body, %if.then 509 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 510 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 511 %exitcond = icmp eq i32 %lftr.wideiv, %n 512 br i1 %exitcond, label %for.end, label %for.body 513 514for.end: ; preds = %for.inc, %entry, %entry 515 ret void 516} 517 518define void @test13(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 { 519; Like @test12, but has a post-dominating guard, which cannot be used 520; to prove %c is nonnull at the point of the load. 521 522; CHECK-LABEL: @test13( 523entry: 524 %not_null = icmp ne i32* %c, null 525 %cmp11 = icmp sgt i32 %n, 0 526 br i1 %cmp11, label %for.body, label %for.end 527 528; CHECK: for.body.preheader: 529; CHECK-NOT: load i32, i32* %c 530; CHECK: br label %for.body 531 532for.body: ; preds = %entry, %for.inc 533 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 534 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 535 %0 = load i32, i32* %arrayidx, align 4 536 %cmp1 = icmp sgt i32 %0, 0 537 br i1 %cmp1, label %if.then, label %for.inc 538 539if.then: ; preds = %for.body 540; CHECK: if.then: 541; CHECK: load i32, i32* %c 542; CHECK: br label %for.inc 543 %1 = load i32, i32* %c, align 4 544 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 545 %2 = load i32, i32* %arrayidx3, align 4 546 %mul = mul nsw i32 %2, %1 547 store i32 %mul, i32* %arrayidx, align 4 548 br label %for.inc 549 550for.inc: ; preds = %for.body, %if.then 551 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 552 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 553 %exitcond = icmp eq i32 %lftr.wideiv, %n 554 br i1 %exitcond, label %for.end, label %for.body 555 556for.end: ; preds = %for.inc, %entry, %entry 557 call void(i1, ...) @llvm.experimental.guard(i1 %not_null) [ "deopt"() ] 558 ret void 559} 560 561; Check that branch by condition "null check AND something" allows to hoist the 562; load. 563define void @test14(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) align 4 %c, i32 %n, i1 %dummy_cond) #0 { 564 565; CHECK-LABEL: @test14 566; CHECK: load i32, i32* %c, align 4 567; CHECK: for.body: 568 569entry: 570 %not_null = icmp ne i32* %c, null 571 %dummy_and = and i1 %not_null, %dummy_cond 572 br i1 %dummy_and, label %not.null, label %for.end 573 574not.null: 575 %cmp11 = icmp sgt i32 %n, 0 576 br i1 %cmp11, label %for.body, label %for.end 577 578for.body: ; preds = %not.null, %for.inc 579 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ] 580 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 581 %0 = load i32, i32* %arrayidx, align 4 582 %cmp1 = icmp sgt i32 %0, 0 583 br i1 %cmp1, label %if.then, label %for.inc 584 585if.then: ; preds = %for.body 586 %1 = load i32, i32* %c, align 4 587 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 588 %2 = load i32, i32* %arrayidx3, align 4 589 %mul = mul nsw i32 %2, %1 590 store i32 %mul, i32* %arrayidx, align 4 591 br label %for.inc 592 593for.inc: ; preds = %for.body, %if.then 594 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 595 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 596 %exitcond = icmp eq i32 %lftr.wideiv, %n 597 br i1 %exitcond, label %for.end, label %for.body 598 599for.end: ; preds = %for.inc, %entry, %not.null 600 ret void 601} 602 603; Check that guard by condition "null check AND something" allows to hoist the 604; load. 605define void @test15(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) align 4 %c, i32 %n, i1 %dummy_cond) #0 { 606 607; CHECK-LABEL: @test15 608; CHECK: load i32, i32* %c, align 4 609; CHECK: for.body: 610 611entry: 612 %not_null = icmp ne i32* %c, null 613 %dummy_and = and i1 %not_null, %dummy_cond 614 call void(i1, ...) @llvm.experimental.guard(i1 %dummy_and) [ "deopt"() ] 615 %cmp11 = icmp sgt i32 %n, 0 616 br i1 %cmp11, label %for.body, label %for.end 617 618for.body: ; preds = %entry, %for.inc 619 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 620 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 621 %0 = load i32, i32* %arrayidx, align 4 622 %cmp1 = icmp sgt i32 %0, 0 623 br i1 %cmp1, label %if.then, label %for.inc 624 625if.then: ; preds = %for.body 626 %1 = load i32, i32* %c, align 4 627 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 628 %2 = load i32, i32* %arrayidx3, align 4 629 %mul = mul nsw i32 %2, %1 630 store i32 %mul, i32* %arrayidx, align 4 631 br label %for.inc 632 633for.inc: ; preds = %for.body, %if.then 634 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 635 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 636 %exitcond = icmp eq i32 %lftr.wideiv, %n 637 br i1 %exitcond, label %for.end, label %for.body 638 639for.end: ; preds = %for.inc, %entry 640 ret void 641} 642 643; Ensure that (c == null && other_cond) does not automatically mean that c is 644; non-null in false branch. So the condition ((c == null && other_cond) == false) 645; is not sufficient to conclude that c != null. 646define void @test16(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n, i1 %dummy_cond) #0 { 647 648; CHECK-LABEL: @test16 649; CHECK: for.body: 650; CHECK: load i32, i32* %c, align 4 651 652entry: 653 %not_null = icmp eq i32* %c, null 654 %dummy_and = and i1 %not_null, %dummy_cond 655 br i1 %dummy_and, label %for.end, label %not.null 656 657not.null: 658 %cmp11 = icmp sgt i32 %n, 0 659 br i1 %cmp11, label %for.body, label %for.end 660 661for.body: ; preds = %not.null, %for.inc 662 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %not.null ] 663 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 664 %0 = load i32, i32* %arrayidx, align 4 665 %cmp1 = icmp sgt i32 %0, 0 666 br i1 %cmp1, label %if.then, label %for.inc 667 668if.then: ; preds = %for.body 669 %1 = load i32, i32* %c, align 4 670 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 671 %2 = load i32, i32* %arrayidx3, align 4 672 %mul = mul nsw i32 %2, %1 673 store i32 %mul, i32* %arrayidx, align 4 674 br label %for.inc 675 676for.inc: ; preds = %for.body, %if.then 677 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 678 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 679 %exitcond = icmp eq i32 %lftr.wideiv, %n 680 br i1 %exitcond, label %for.end, label %for.body 681 682for.end: ; preds = %for.inc, %entry, %not.null 683 ret void 684} 685 686; Ensure that (c == null && other_cond) does not automatically mean that c is 687; non-null in false branch. So the condition ((c == null && other_cond) == false) 688; is not sufficient to conclude that c != null. 689define void @test17(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n, i1 %dummy_cond) #0 { 690 691; CHECK-LABEL: @test17 692; CHECK: for.body: 693; CHECK: load i32, i32* %c, align 4 694 695entry: 696 %not_null = icmp eq i32* %c, null 697 %dummy_and = and i1 %not_null, %dummy_cond 698 call void(i1, ...) @llvm.experimental.guard(i1 %dummy_and) [ "deopt"() ] 699 %cmp11 = icmp sgt i32 %n, 0 700 br i1 %cmp11, label %for.end, label %for.body 701 702for.body: ; preds = %entry, %for.inc 703 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 704 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 705 %0 = load i32, i32* %arrayidx, align 4 706 %cmp1 = icmp sgt i32 %0, 0 707 br i1 %cmp1, label %if.then, label %for.inc 708 709if.then: ; preds = %for.body 710 %1 = load i32, i32* %c, align 4 711 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 712 %2 = load i32, i32* %arrayidx3, align 4 713 %mul = mul nsw i32 %2, %1 714 store i32 %mul, i32* %arrayidx, align 4 715 br label %for.inc 716 717for.inc: ; preds = %for.body, %if.then 718 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 719 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 720 %exitcond = icmp eq i32 %lftr.wideiv, %n 721 br i1 %exitcond, label %for.end, label %for.body 722 723for.end: ; preds = %for.inc, %entry 724 ret void 725} 726 727attributes #0 = { nounwind uwtable } 728!0 = !{i64 4} 729