1; RUN: opt -S -basicaa -licm < %s | FileCheck %s 2target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 3target 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 18define void @test1(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull dereferenceable(4) %c, i32 %n) #0 { 19entry: 20 %cmp11 = icmp sgt i32 %n, 0 21 br i1 %cmp11, label %for.body, label %for.end 22 23for.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 30if.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 38for.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 44for.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 55define void @test2(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull %c, i32 %n) #0 { 56entry: 57 %cmp11 = icmp sgt i32 %n, 0 58 br i1 %cmp11, label %for.body, label %for.end 59 60for.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 67if.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 75for.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 81for.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 98define void @test3(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(12) %c, i32 %n) #0 { 99entry: 100 %cmp11 = icmp sgt i32 %n, 0 101 br i1 %cmp11, label %for.body, label %for.end 102 103for.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 110if.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 119for.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 125for.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 136define void @test4(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly dereferenceable(11) %c, i32 %n) #0 { 137entry: 138 %cmp11 = icmp sgt i32 %n, 0 139 br i1 %cmp11, label %for.body, label %for.end 140 141for.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 148if.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 157for.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 163for.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 182define void @test5(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 { 183entry: 184 %not_null = icmp ne i32* %c, null 185 br i1 %not_null, label %not.null, label %for.end 186 187not.null: 188 %cmp11 = icmp sgt i32 %n, 0 189 br i1 %cmp11, label %for.body, label %for.end 190 191for.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 198if.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 206for.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 212for.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 226define i1 @test6(i32* noalias %a, i32* %b, i32* dereferenceable_or_null(4) %c, i32 %n) #0 { 227entry: 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 232for.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 239if.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 247for.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 253for.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 271define void @test7(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 { 272entry: 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 277for.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 284if.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 292for.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 298for.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 318define void @test8(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 { 319entry: 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 324not.null: 325 %cmp11 = icmp sgt i32 %n, 0 326 br i1 %cmp11, label %for.body, label %for.end 327 328for.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 335if.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 343for.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 349for.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 360define void @test9(i32* noalias %a, i32* %b, i32** %cptr, i32 %n) #0 { 361entry: 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 366for.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 373if.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 381for.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 387for.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 404define void @test10(i32* noalias %a, i32* %b, i32** dereferenceable(8) %cptr, i32 %n) #0 { 405entry: 406 %cmp11 = icmp sgt i32 %n, 0 407 br i1 %cmp11, label %for.body, label %for.end 408 409for.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 416if.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 425for.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 431for.end: ; preds = %for.inc, %entry 432 ret void 433} 434 435attributes #0 = { nounwind uwtable } 436!0 = !{i64 4} 437