1 ; RUN: opt < %s -O1 -loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -dce -instcombine -S | FileCheck %s 2 3 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:64-n32-S64" 4 5 %struct.anon = type { [100 x i32], i32, [100 x i32] } 6 %struct.anon.0 = type { [100 x [100 x i32]], i32, [100 x [100 x i32]] } 7 8 @Foo = common global %struct.anon zeroinitializer, align 4 9 @Bar = common global %struct.anon.0 zeroinitializer, align 4 10 11 @PB = external global i32* 12 @PA = external global i32* 13 14 15 ;; === First, the tests that should always vectorize, wither statically or by adding run-time checks === 16 17 18 ; /// Different objects, positive induction, constant distance 19 ; int noAlias01 (int a) { 20 ; int i; 21 ; for (i=0; i<SIZE; i++) 22 ; Foo.A[i] = Foo.B[i] + a; 23 ; return Foo.A[a]; 24 ; } 25 ; CHECK-LABEL: define i32 @noAlias01( 26 ; CHECK: add nsw <4 x i32> 27 ; CHECK: ret 28 29 define i32 @noAlias01(i32 %a) nounwind { 30 entry: 31 %a.addr = alloca i32, align 4 32 %i = alloca i32, align 4 33 store i32 %a, i32* %a.addr, align 4 34 store i32 0, i32* %i, align 4 35 br label %for.cond 36 37 for.cond: ; preds = %for.inc, %entry 38 %0 = load i32, i32* %i, align 4 39 %cmp = icmp slt i32 %0, 100 40 br i1 %cmp, label %for.body, label %for.end 41 42 for.body: ; preds = %for.cond 43 %1 = load i32, i32* %i, align 4 44 %arrayidx = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %1 45 %2 = load i32, i32* %arrayidx, align 4 46 %3 = load i32, i32* %a.addr, align 4 47 %add = add nsw i32 %2, %3 48 %4 = load i32, i32* %i, align 4 49 %arrayidx1 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %4 50 store i32 %add, i32* %arrayidx1, align 4 51 br label %for.inc 52 53 for.inc: ; preds = %for.body 54 %5 = load i32, i32* %i, align 4 55 %inc = add nsw i32 %5, 1 56 store i32 %inc, i32* %i, align 4 57 br label %for.cond 58 59 for.end: ; preds = %for.cond 60 %6 = load i32, i32* %a.addr, align 4 61 %arrayidx2 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6 62 %7 = load i32, i32* %arrayidx2, align 4 63 ret i32 %7 64 } 65 66 ; /// Different objects, positive induction with widening slide 67 ; int noAlias02 (int a) { 68 ; int i; 69 ; for (i=0; i<SIZE-10; i++) 70 ; Foo.A[i] = Foo.B[i+10] + a; 71 ; return Foo.A[a]; 72 ; } 73 ; CHECK-LABEL: define i32 @noAlias02( 74 ; CHECK: add nsw <4 x i32> 75 ; CHECK: ret 76 77 define i32 @noAlias02(i32 %a) { 78 entry: 79 %a.addr = alloca i32, align 4 80 %i = alloca i32, align 4 81 store i32 %a, i32* %a.addr, align 4 82 store i32 0, i32* %i, align 4 83 br label %for.cond 84 85 for.cond: ; preds = %for.inc, %entry 86 %0 = load i32, i32* %i, align 4 87 %cmp = icmp slt i32 %0, 90 88 br i1 %cmp, label %for.body, label %for.end 89 90 for.body: ; preds = %for.cond 91 %1 = load i32, i32* %i, align 4 92 %add = add nsw i32 %1, 10 93 %arrayidx = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %add 94 %2 = load i32, i32* %arrayidx, align 4 95 %3 = load i32, i32* %a.addr, align 4 96 %add1 = add nsw i32 %2, %3 97 %4 = load i32, i32* %i, align 4 98 %arrayidx2 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %4 99 store i32 %add1, i32* %arrayidx2, align 4 100 br label %for.inc 101 102 for.inc: ; preds = %for.body 103 %5 = load i32, i32* %i, align 4 104 %inc = add nsw i32 %5, 1 105 store i32 %inc, i32* %i, align 4 106 br label %for.cond 107 108 for.end: ; preds = %for.cond 109 %6 = load i32, i32* %a.addr, align 4 110 %arrayidx3 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6 111 %7 = load i32, i32* %arrayidx3, align 4 112 ret i32 %7 113 } 114 115 ; /// Different objects, positive induction with shortening slide 116 ; int noAlias03 (int a) { 117 ; int i; 118 ; for (i=0; i<SIZE; i++) 119 ; Foo.A[i+10] = Foo.B[i] + a; 120 ; return Foo.A[a]; 121 ; } 122 ; CHECK-LABEL: define i32 @noAlias03( 123 ; CHECK: add nsw <4 x i32> 124 ; CHECK: ret 125 126 define i32 @noAlias03(i32 %a) { 127 entry: 128 %a.addr = alloca i32, align 4 129 %i = alloca i32, align 4 130 store i32 %a, i32* %a.addr, align 4 131 store i32 0, i32* %i, align 4 132 br label %for.cond 133 134 for.cond: ; preds = %for.inc, %entry 135 %0 = load i32, i32* %i, align 4 136 %cmp = icmp slt i32 %0, 100 137 br i1 %cmp, label %for.body, label %for.end 138 139 for.body: ; preds = %for.cond 140 %1 = load i32, i32* %i, align 4 141 %arrayidx = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %1 142 %2 = load i32, i32* %arrayidx, align 4 143 %3 = load i32, i32* %a.addr, align 4 144 %add = add nsw i32 %2, %3 145 %4 = load i32, i32* %i, align 4 146 %add1 = add nsw i32 %4, 10 147 %arrayidx2 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %add1 148 store i32 %add, i32* %arrayidx2, align 4 149 br label %for.inc 150 151 for.inc: ; preds = %for.body 152 %5 = load i32, i32* %i, align 4 153 %inc = add nsw i32 %5, 1 154 store i32 %inc, i32* %i, align 4 155 br label %for.cond 156 157 for.end: ; preds = %for.cond 158 %6 = load i32, i32* %a.addr, align 4 159 %arrayidx3 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6 160 %7 = load i32, i32* %arrayidx3, align 4 161 ret i32 %7 162 } 163 164 ; /// Pointer access, positive stride, run-time check added 165 ; int noAlias04 (int a) { 166 ; int i; 167 ; for (i=0; i<SIZE; i++) 168 ; *(PA+i) = *(PB+i) + a; 169 ; return *(PA+a); 170 ; } 171 ; CHECK-LABEL: define i32 @noAlias04( 172 ; CHECK-NOT: add nsw <4 x i32> 173 ; CHECK: ret 174 ; 175 ; TODO: This test vectorizes (with run-time check) on real targets with -O3) 176 ; Check why it's not being vectorized even when forcing vectorization 177 178 define i32 @noAlias04(i32 %a) #0 { 179 entry: 180 %a.addr = alloca i32, align 4 181 %i = alloca i32, align 4 182 store i32 %a, i32* %a.addr, align 4 183 store i32 0, i32* %i, align 4 184 br label %for.cond 185 186 for.cond: ; preds = %for.inc, %entry 187 %0 = load i32, i32* %i, align 4 188 %cmp = icmp slt i32 %0, 100 189 br i1 %cmp, label %for.body, label %for.end 190 191 for.body: ; preds = %for.cond 192 %1 = load i32*, i32** @PB, align 4 193 %2 = load i32, i32* %i, align 4 194 %add.ptr = getelementptr inbounds i32, i32* %1, i32 %2 195 %3 = load i32, i32* %add.ptr, align 4 196 %4 = load i32, i32* %a.addr, align 4 197 %add = add nsw i32 %3, %4 198 %5 = load i32*, i32** @PA, align 4 199 %6 = load i32, i32* %i, align 4 200 %add.ptr1 = getelementptr inbounds i32, i32* %5, i32 %6 201 store i32 %add, i32* %add.ptr1, align 4 202 br label %for.inc 203 204 for.inc: ; preds = %for.body 205 %7 = load i32, i32* %i, align 4 206 %inc = add nsw i32 %7, 1 207 store i32 %inc, i32* %i, align 4 208 br label %for.cond 209 210 for.end: ; preds = %for.cond 211 %8 = load i32*, i32** @PA, align 4 212 %9 = load i32, i32* %a.addr, align 4 213 %add.ptr2 = getelementptr inbounds i32, i32* %8, i32 %9 214 %10 = load i32, i32* %add.ptr2, align 4 215 ret i32 %10 216 } 217 218 ; /// Different objects, positive induction, multi-array 219 ; int noAlias05 (int a) { 220 ; int i, N=10; 221 ; for (i=0; i<SIZE; i++) 222 ; Bar.A[N][i] = Bar.B[N][i] + a; 223 ; return Bar.A[N][a]; 224 ; } 225 ; CHECK-LABEL: define i32 @noAlias05( 226 ; CHECK: add nsw <4 x i32> 227 ; CHECK: ret 228 229 define i32 @noAlias05(i32 %a) #0 { 230 entry: 231 %a.addr = alloca i32, align 4 232 %i = alloca i32, align 4 233 %N = alloca i32, align 4 234 store i32 %a, i32* %a.addr, align 4 235 store i32 10, i32* %N, align 4 236 store i32 0, i32* %i, align 4 237 br label %for.cond 238 239 for.cond: ; preds = %for.inc, %entry 240 %0 = load i32, i32* %i, align 4 241 %cmp = icmp slt i32 %0, 100 242 br i1 %cmp, label %for.body, label %for.end 243 244 for.body: ; preds = %for.cond 245 %1 = load i32, i32* %i, align 4 246 %2 = load i32, i32* %N, align 4 247 %arrayidx = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* getelementptr inbounds (%struct.anon.0, %struct.anon.0* @Bar, i32 0, i32 2), i32 0, i32 %2 248 %arrayidx1 = getelementptr inbounds [100 x i32], [100 x i32]* %arrayidx, i32 0, i32 %1 249 %3 = load i32, i32* %arrayidx1, align 4 250 %4 = load i32, i32* %a.addr, align 4 251 %add = add nsw i32 %3, %4 252 %5 = load i32, i32* %i, align 4 253 %6 = load i32, i32* %N, align 4 254 %arrayidx2 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* getelementptr inbounds (%struct.anon.0, %struct.anon.0* @Bar, i32 0, i32 0), i32 0, i32 %6 255 %arrayidx3 = getelementptr inbounds [100 x i32], [100 x i32]* %arrayidx2, i32 0, i32 %5 256 store i32 %add, i32* %arrayidx3, align 4 257 br label %for.inc 258 259 for.inc: ; preds = %for.body 260 %7 = load i32, i32* %i, align 4 261 %inc = add nsw i32 %7, 1 262 store i32 %inc, i32* %i, align 4 263 br label %for.cond 264 265 for.end: ; preds = %for.cond 266 %8 = load i32, i32* %a.addr, align 4 267 %9 = load i32, i32* %N, align 4 268 %arrayidx4 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* getelementptr inbounds (%struct.anon.0, %struct.anon.0* @Bar, i32 0, i32 0), i32 0, i32 %9 269 %arrayidx5 = getelementptr inbounds [100 x i32], [100 x i32]* %arrayidx4, i32 0, i32 %8 270 %10 = load i32, i32* %arrayidx5, align 4 271 ret i32 %10 272 } 273 274 ; /// Same objects, positive induction, multi-array, different sub-elements 275 ; int noAlias06 (int a) { 276 ; int i, N=10; 277 ; for (i=0; i<SIZE; i++) 278 ; Bar.A[N][i] = Bar.A[N+1][i] + a; 279 ; return Bar.A[N][a]; 280 ; } 281 ; CHECK-LABEL: define i32 @noAlias06( 282 ; CHECK: add nsw <4 x i32> 283 ; CHECK: ret 284 285 define i32 @noAlias06(i32 %a) #0 { 286 entry: 287 %a.addr = alloca i32, align 4 288 %i = alloca i32, align 4 289 %N = alloca i32, align 4 290 store i32 %a, i32* %a.addr, align 4 291 store i32 10, i32* %N, align 4 292 store i32 0, i32* %i, align 4 293 br label %for.cond 294 295 for.cond: ; preds = %for.inc, %entry 296 %0 = load i32, i32* %i, align 4 297 %cmp = icmp slt i32 %0, 100 298 br i1 %cmp, label %for.body, label %for.end 299 300 for.body: ; preds = %for.cond 301 %1 = load i32, i32* %i, align 4 302 %2 = load i32, i32* %N, align 4 303 %add = add nsw i32 %2, 1 304 %arrayidx = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* getelementptr inbounds (%struct.anon.0, %struct.anon.0* @Bar, i32 0, i32 0), i32 0, i32 %add 305 %arrayidx1 = getelementptr inbounds [100 x i32], [100 x i32]* %arrayidx, i32 0, i32 %1 306 %3 = load i32, i32* %arrayidx1, align 4 307 %4 = load i32, i32* %a.addr, align 4 308 %add2 = add nsw i32 %3, %4 309 %5 = load i32, i32* %i, align 4 310 %6 = load i32, i32* %N, align 4 311 %arrayidx3 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* getelementptr inbounds (%struct.anon.0, %struct.anon.0* @Bar, i32 0, i32 0), i32 0, i32 %6 312 %arrayidx4 = getelementptr inbounds [100 x i32], [100 x i32]* %arrayidx3, i32 0, i32 %5 313 store i32 %add2, i32* %arrayidx4, align 4 314 br label %for.inc 315 316 for.inc: ; preds = %for.body 317 %7 = load i32, i32* %i, align 4 318 %inc = add nsw i32 %7, 1 319 store i32 %inc, i32* %i, align 4 320 br label %for.cond 321 322 for.end: ; preds = %for.cond 323 %8 = load i32, i32* %a.addr, align 4 324 %9 = load i32, i32* %N, align 4 325 %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* getelementptr inbounds (%struct.anon.0, %struct.anon.0* @Bar, i32 0, i32 0), i32 0, i32 %9 326 %arrayidx6 = getelementptr inbounds [100 x i32], [100 x i32]* %arrayidx5, i32 0, i32 %8 327 %10 = load i32, i32* %arrayidx6, align 4 328 ret i32 %10 329 } 330 331 ; /// Different objects, negative induction, constant distance 332 ; int noAlias07 (int a) { 333 ; int i; 334 ; for (i=0; i<SIZE; i++) 335 ; Foo.A[SIZE-i-1] = Foo.B[SIZE-i-1] + a; 336 ; return Foo.A[a]; 337 ; } 338 ; CHECK-LABEL: define i32 @noAlias07( 339 ; CHECK: store <4 x i32> 340 ; CHECK: ret 341 define i32 @noAlias07(i32 %a) #0 { 342 entry: 343 %a.addr = alloca i32, align 4 344 %i = alloca i32, align 4 345 store i32 %a, i32* %a.addr, align 4 346 store i32 0, i32* %i, align 4 347 br label %for.cond 348 349 for.cond: ; preds = %for.inc, %entry 350 %0 = load i32, i32* %i, align 4 351 %cmp = icmp slt i32 %0, 100 352 br i1 %cmp, label %for.body, label %for.end 353 354 for.body: ; preds = %for.cond 355 %1 = load i32, i32* %i, align 4 356 %sub = sub nsw i32 100, %1 357 %sub1 = sub nsw i32 %sub, 1 358 %arrayidx = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %sub1 359 %2 = load i32, i32* %arrayidx, align 4 360 %3 = load i32, i32* %a.addr, align 4 361 %add = add nsw i32 %2, %3 362 %4 = load i32, i32* %i, align 4 363 %sub2 = sub nsw i32 100, %4 364 %sub3 = sub nsw i32 %sub2, 1 365 %arrayidx4 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %sub3 366 store i32 %add, i32* %arrayidx4, align 4 367 br label %for.inc 368 369 for.inc: ; preds = %for.body 370 %5 = load i32, i32* %i, align 4 371 %inc = add nsw i32 %5, 1 372 store i32 %inc, i32* %i, align 4 373 br label %for.cond 374 375 for.end: ; preds = %for.cond 376 %6 = load i32, i32* %a.addr, align 4 377 %arrayidx5 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6 378 %7 = load i32, i32* %arrayidx5, align 4 379 ret i32 %7 380 } 381 382 ; /// Different objects, negative induction, shortening slide 383 ; int noAlias08 (int a) { 384 ; int i; 385 ; for (i=0; i<SIZE-10; i++) 386 ; Foo.A[SIZE-i-1] = Foo.B[SIZE-i-10] + a; 387 ; return Foo.A[a]; 388 ; } 389 ; CHECK-LABEL: define i32 @noAlias08( 390 ; CHECK: sub <4 x i32> 391 ; CHECK: ret 392 393 define i32 @noAlias08(i32 %a) #0 { 394 entry: 395 %a.addr = alloca i32, align 4 396 %i = alloca i32, align 4 397 store i32 %a, i32* %a.addr, align 4 398 store i32 0, i32* %i, align 4 399 br label %for.cond 400 401 for.cond: ; preds = %for.inc, %entry 402 %0 = load i32, i32* %i, align 4 403 %cmp = icmp slt i32 %0, 90 404 br i1 %cmp, label %for.body, label %for.end 405 406 for.body: ; preds = %for.cond 407 %1 = load i32, i32* %i, align 4 408 %sub = sub nsw i32 100, %1 409 %sub1 = sub nsw i32 %sub, 10 410 %arrayidx = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %sub1 411 %2 = load i32, i32* %arrayidx, align 4 412 %3 = load i32, i32* %a.addr, align 4 413 %add = add nsw i32 %2, %3 414 %4 = load i32, i32* %i, align 4 415 %sub2 = sub nsw i32 100, %4 416 %sub3 = sub nsw i32 %sub2, 1 417 %arrayidx4 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %sub3 418 store i32 %add, i32* %arrayidx4, align 4 419 br label %for.inc 420 421 for.inc: ; preds = %for.body 422 %5 = load i32, i32* %i, align 4 423 %inc = add nsw i32 %5, 1 424 store i32 %inc, i32* %i, align 4 425 br label %for.cond 426 427 for.end: ; preds = %for.cond 428 %6 = load i32, i32* %a.addr, align 4 429 %arrayidx5 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6 430 %7 = load i32, i32* %arrayidx5, align 4 431 ret i32 %7 432 } 433 434 ; /// Different objects, negative induction, widening slide 435 ; int noAlias09 (int a) { 436 ; int i; 437 ; for (i=0; i<SIZE; i++) 438 ; Foo.A[SIZE-i-10] = Foo.B[SIZE-i-1] + a; 439 ; return Foo.A[a]; 440 ; } 441 ; CHECK-LABEL: define i32 @noAlias09( 442 ; CHECK: sub <4 x i32> 443 ; CHECK: ret 444 445 define i32 @noAlias09(i32 %a) #0 { 446 entry: 447 %a.addr = alloca i32, align 4 448 %i = alloca i32, align 4 449 store i32 %a, i32* %a.addr, align 4 450 store i32 0, i32* %i, align 4 451 br label %for.cond 452 453 for.cond: ; preds = %for.inc, %entry 454 %0 = load i32, i32* %i, align 4 455 %cmp = icmp slt i32 %0, 100 456 br i1 %cmp, label %for.body, label %for.end 457 458 for.body: ; preds = %for.cond 459 %1 = load i32, i32* %i, align 4 460 %sub = sub nsw i32 100, %1 461 %sub1 = sub nsw i32 %sub, 1 462 %arrayidx = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %sub1 463 %2 = load i32, i32* %arrayidx, align 4 464 %3 = load i32, i32* %a.addr, align 4 465 %add = add nsw i32 %2, %3 466 %4 = load i32, i32* %i, align 4 467 %sub2 = sub nsw i32 100, %4 468 %sub3 = sub nsw i32 %sub2, 10 469 %arrayidx4 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %sub3 470 store i32 %add, i32* %arrayidx4, align 4 471 br label %for.inc 472 473 for.inc: ; preds = %for.body 474 %5 = load i32, i32* %i, align 4 475 %inc = add nsw i32 %5, 1 476 store i32 %inc, i32* %i, align 4 477 br label %for.cond 478 479 for.end: ; preds = %for.cond 480 %6 = load i32, i32* %a.addr, align 4 481 %arrayidx5 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6 482 %7 = load i32, i32* %arrayidx5, align 4 483 ret i32 %7 484 } 485 486 ; /// Pointer access, negative stride, run-time check added 487 ; int noAlias10 (int a) { 488 ; int i; 489 ; for (i=0; i<SIZE; i++) 490 ; *(PA+SIZE-i-1) = *(PB+SIZE-i-1) + a; 491 ; return *(PA+a); 492 ; } 493 ; CHECK-LABEL: define i32 @noAlias10( 494 ; CHECK-NOT: sub {{.*}} <4 x i32> 495 ; CHECK: ret 496 ; 497 ; TODO: This test vectorizes (with run-time check) on real targets with -O3) 498 ; Check why it's not being vectorized even when forcing vectorization 499 500 define i32 @noAlias10(i32 %a) #0 { 501 entry: 502 %a.addr = alloca i32, align 4 503 %i = alloca i32, align 4 504 store i32 %a, i32* %a.addr, align 4 505 store i32 0, i32* %i, align 4 506 br label %for.cond 507 508 for.cond: ; preds = %for.inc, %entry 509 %0 = load i32, i32* %i, align 4 510 %cmp = icmp slt i32 %0, 100 511 br i1 %cmp, label %for.body, label %for.end 512 513 for.body: ; preds = %for.cond 514 %1 = load i32*, i32** @PB, align 4 515 %add.ptr = getelementptr inbounds i32, i32* %1, i32 100 516 %2 = load i32, i32* %i, align 4 517 %idx.neg = sub i32 0, %2 518 %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %idx.neg 519 %add.ptr2 = getelementptr inbounds i32, i32* %add.ptr1, i32 -1 520 %3 = load i32, i32* %add.ptr2, align 4 521 %4 = load i32, i32* %a.addr, align 4 522 %add = add nsw i32 %3, %4 523 %5 = load i32*, i32** @PA, align 4 524 %add.ptr3 = getelementptr inbounds i32, i32* %5, i32 100 525 %6 = load i32, i32* %i, align 4 526 %idx.neg4 = sub i32 0, %6 527 %add.ptr5 = getelementptr inbounds i32, i32* %add.ptr3, i32 %idx.neg4 528 %add.ptr6 = getelementptr inbounds i32, i32* %add.ptr5, i32 -1 529 store i32 %add, i32* %add.ptr6, align 4 530 br label %for.inc 531 532 for.inc: ; preds = %for.body 533 %7 = load i32, i32* %i, align 4 534 %inc = add nsw i32 %7, 1 535 store i32 %inc, i32* %i, align 4 536 br label %for.cond 537 538 for.end: ; preds = %for.cond 539 %8 = load i32*, i32** @PA, align 4 540 %9 = load i32, i32* %a.addr, align 4 541 %add.ptr7 = getelementptr inbounds i32, i32* %8, i32 %9 542 %10 = load i32, i32* %add.ptr7, align 4 543 ret i32 %10 544 } 545 546 ; /// Different objects, negative induction, multi-array 547 ; int noAlias11 (int a) { 548 ; int i, N=10; 549 ; for (i=0; i<SIZE; i++) 550 ; Bar.A[N][SIZE-i-1] = Bar.B[N][SIZE-i-1] + a; 551 ; return Bar.A[N][a]; 552 ; } 553 ; CHECK-LABEL: define i32 @noAlias11( 554 ; CHECK: store <4 x i32> 555 ; CHECK: ret 556 557 define i32 @noAlias11(i32 %a) #0 { 558 entry: 559 %a.addr = alloca i32, align 4 560 %i = alloca i32, align 4 561 %N = alloca i32, align 4 562 store i32 %a, i32* %a.addr, align 4 563 store i32 10, i32* %N, align 4 564 store i32 0, i32* %i, align 4 565 br label %for.cond 566 567 for.cond: ; preds = %for.inc, %entry 568 %0 = load i32, i32* %i, align 4 569 %cmp = icmp slt i32 %0, 100 570 br i1 %cmp, label %for.body, label %for.end 571 572 for.body: ; preds = %for.cond 573 %1 = load i32, i32* %i, align 4 574 %sub = sub nsw i32 100, %1 575 %sub1 = sub nsw i32 %sub, 1 576 %2 = load i32, i32* %N, align 4 577 %arrayidx = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* getelementptr inbounds (%struct.anon.0, %struct.anon.0* @Bar, i32 0, i32 2), i32 0, i32 %2 578 %arrayidx2 = getelementptr inbounds [100 x i32], [100 x i32]* %arrayidx, i32 0, i32 %sub1 579 %3 = load i32, i32* %arrayidx2, align 4 580 %4 = load i32, i32* %a.addr, align 4 581 %add = add nsw i32 %3, %4 582 %5 = load i32, i32* %i, align 4 583 %sub3 = sub nsw i32 100, %5 584 %sub4 = sub nsw i32 %sub3, 1 585 %6 = load i32, i32* %N, align 4 586 %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* getelementptr inbounds (%struct.anon.0, %struct.anon.0* @Bar, i32 0, i32 0), i32 0, i32 %6 587 %arrayidx6 = getelementptr inbounds [100 x i32], [100 x i32]* %arrayidx5, i32 0, i32 %sub4 588 store i32 %add, i32* %arrayidx6, align 4 589 br label %for.inc 590 591 for.inc: ; preds = %for.body 592 %7 = load i32, i32* %i, align 4 593 %inc = add nsw i32 %7, 1 594 store i32 %inc, i32* %i, align 4 595 br label %for.cond 596 597 for.end: ; preds = %for.cond 598 %8 = load i32, i32* %a.addr, align 4 599 %9 = load i32, i32* %N, align 4 600 %arrayidx7 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* getelementptr inbounds (%struct.anon.0, %struct.anon.0* @Bar, i32 0, i32 0), i32 0, i32 %9 601 %arrayidx8 = getelementptr inbounds [100 x i32], [100 x i32]* %arrayidx7, i32 0, i32 %8 602 %10 = load i32, i32* %arrayidx8, align 4 603 ret i32 %10 604 } 605 606 ; /// Same objects, negative induction, multi-array, different sub-elements 607 ; int noAlias12 (int a) { 608 ; int i, N=10; 609 ; for (i=0; i<SIZE; i++) 610 ; Bar.A[N][SIZE-i-1] = Bar.A[N+1][SIZE-i-1] + a; 611 ; return Bar.A[N][a]; 612 ; } 613 ; CHECK-LABEL: define i32 @noAlias12( 614 ; CHECK: store <4 x i32> 615 ; CHECK: ret 616 617 define i32 @noAlias12(i32 %a) #0 { 618 entry: 619 %a.addr = alloca i32, align 4 620 %i = alloca i32, align 4 621 %N = alloca i32, align 4 622 store i32 %a, i32* %a.addr, align 4 623 store i32 10, i32* %N, align 4 624 store i32 0, i32* %i, align 4 625 br label %for.cond 626 627 for.cond: ; preds = %for.inc, %entry 628 %0 = load i32, i32* %i, align 4 629 %cmp = icmp slt i32 %0, 100 630 br i1 %cmp, label %for.body, label %for.end 631 632 for.body: ; preds = %for.cond 633 %1 = load i32, i32* %i, align 4 634 %sub = sub nsw i32 100, %1 635 %sub1 = sub nsw i32 %sub, 1 636 %2 = load i32, i32* %N, align 4 637 %add = add nsw i32 %2, 1 638 %arrayidx = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* getelementptr inbounds (%struct.anon.0, %struct.anon.0* @Bar, i32 0, i32 0), i32 0, i32 %add 639 %arrayidx2 = getelementptr inbounds [100 x i32], [100 x i32]* %arrayidx, i32 0, i32 %sub1 640 %3 = load i32, i32* %arrayidx2, align 4 641 %4 = load i32, i32* %a.addr, align 4 642 %add3 = add nsw i32 %3, %4 643 %5 = load i32, i32* %i, align 4 644 %sub4 = sub nsw i32 100, %5 645 %sub5 = sub nsw i32 %sub4, 1 646 %6 = load i32, i32* %N, align 4 647 %arrayidx6 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* getelementptr inbounds (%struct.anon.0, %struct.anon.0* @Bar, i32 0, i32 0), i32 0, i32 %6 648 %arrayidx7 = getelementptr inbounds [100 x i32], [100 x i32]* %arrayidx6, i32 0, i32 %sub5 649 store i32 %add3, i32* %arrayidx7, align 4 650 br label %for.inc 651 652 for.inc: ; preds = %for.body 653 %7 = load i32, i32* %i, align 4 654 %inc = add nsw i32 %7, 1 655 store i32 %inc, i32* %i, align 4 656 br label %for.cond 657 658 for.end: ; preds = %for.cond 659 %8 = load i32, i32* %a.addr, align 4 660 %9 = load i32, i32* %N, align 4 661 %arrayidx8 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* getelementptr inbounds (%struct.anon.0, %struct.anon.0* @Bar, i32 0, i32 0), i32 0, i32 %9 662 %arrayidx9 = getelementptr inbounds [100 x i32], [100 x i32]* %arrayidx8, i32 0, i32 %8 663 %10 = load i32, i32* %arrayidx9, align 4 664 ret i32 %10 665 } 666 667 ; /// Same objects, positive induction, constant distance, just enough for vector size 668 ; int noAlias13 (int a) { 669 ; int i; 670 ; for (i=0; i<SIZE; i++) 671 ; Foo.A[i] = Foo.A[i+4] + a; 672 ; return Foo.A[a]; 673 ; } 674 ; CHECK-LABEL: define i32 @noAlias13( 675 ; CHECK: add nsw <4 x i32> 676 ; CHECK: ret 677 678 define i32 @noAlias13(i32 %a) #0 { 679 entry: 680 %a.addr = alloca i32, align 4 681 %i = alloca i32, align 4 682 store i32 %a, i32* %a.addr, align 4 683 store i32 0, i32* %i, align 4 684 br label %for.cond 685 686 for.cond: ; preds = %for.inc, %entry 687 %0 = load i32, i32* %i, align 4 688 %cmp = icmp slt i32 %0, 100 689 br i1 %cmp, label %for.body, label %for.end 690 691 for.body: ; preds = %for.cond 692 %1 = load i32, i32* %i, align 4 693 %add = add nsw i32 %1, 4 694 %arrayidx = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %add 695 %2 = load i32, i32* %arrayidx, align 4 696 %3 = load i32, i32* %a.addr, align 4 697 %add1 = add nsw i32 %2, %3 698 %4 = load i32, i32* %i, align 4 699 %arrayidx2 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %4 700 store i32 %add1, i32* %arrayidx2, align 4 701 br label %for.inc 702 703 for.inc: ; preds = %for.body 704 %5 = load i32, i32* %i, align 4 705 %inc = add nsw i32 %5, 1 706 store i32 %inc, i32* %i, align 4 707 br label %for.cond 708 709 for.end: ; preds = %for.cond 710 %6 = load i32, i32* %a.addr, align 4 711 %arrayidx3 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6 712 %7 = load i32, i32* %arrayidx3, align 4 713 ret i32 %7 714 } 715 716 ; /// Same objects, negative induction, constant distance, just enough for vector size 717 ; int noAlias14 (int a) { 718 ; int i; 719 ; for (i=0; i<SIZE; i++) 720 ; Foo.A[SIZE-i-1] = Foo.A[SIZE-i-5] + a; 721 ; return Foo.A[a]; 722 ; } 723 ; CHECK-LABEL: define i32 @noAlias14( 724 ; CHECK: sub <4 x i32> 725 ; CHECK: ret 726 727 define i32 @noAlias14(i32 %a) #0 { 728 entry: 729 %a.addr = alloca i32, align 4 730 %i = alloca i32, align 4 731 store i32 %a, i32* %a.addr, align 4 732 store i32 0, i32* %i, align 4 733 br label %for.cond 734 735 for.cond: ; preds = %for.inc, %entry 736 %0 = load i32, i32* %i, align 4 737 %cmp = icmp slt i32 %0, 100 738 br i1 %cmp, label %for.body, label %for.end 739 740 for.body: ; preds = %for.cond 741 %1 = load i32, i32* %i, align 4 742 %sub = sub nsw i32 100, %1 743 %sub1 = sub nsw i32 %sub, 5 744 %arrayidx = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %sub1 745 %2 = load i32, i32* %arrayidx, align 4 746 %3 = load i32, i32* %a.addr, align 4 747 %add = add nsw i32 %2, %3 748 %4 = load i32, i32* %i, align 4 749 %sub2 = sub nsw i32 100, %4 750 %sub3 = sub nsw i32 %sub2, 1 751 %arrayidx4 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %sub3 752 store i32 %add, i32* %arrayidx4, align 4 753 br label %for.inc 754 755 for.inc: ; preds = %for.body 756 %5 = load i32, i32* %i, align 4 757 %inc = add nsw i32 %5, 1 758 store i32 %inc, i32* %i, align 4 759 br label %for.cond 760 761 for.end: ; preds = %for.cond 762 %6 = load i32, i32* %a.addr, align 4 763 %arrayidx5 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6 764 %7 = load i32, i32* %arrayidx5, align 4 765 ret i32 %7 766 } 767 768 769 ;; === Now, the tests that we could vectorize with induction changes or run-time checks === 770 771 772 ; /// Different objects, swapped induction, alias at the end 773 ; int mayAlias01 (int a) { 774 ; int i; 775 ; for (i=0; i<SIZE; i++) 776 ; Foo.A[i] = Foo.B[SIZE-i-1] + a; 777 ; return Foo.A[a]; 778 ; } 779 ; CHECK-LABEL: define i32 @mayAlias01( 780 ; CHECK-NOT: add nsw <4 x i32> 781 ; CHECK: ret 782 783 define i32 @mayAlias01(i32 %a) nounwind { 784 entry: 785 %a.addr = alloca i32, align 4 786 %i = alloca i32, align 4 787 store i32 %a, i32* %a.addr, align 4 788 store i32 0, i32* %i, align 4 789 br label %for.cond 790 791 for.cond: ; preds = %for.inc, %entry 792 %0 = load i32, i32* %i, align 4 793 %cmp = icmp slt i32 %0, 100 794 br i1 %cmp, label %for.body, label %for.end 795 796 for.body: ; preds = %for.cond 797 %1 = load i32, i32* %i, align 4 798 %sub = sub nsw i32 100, %1 799 %sub1 = sub nsw i32 %sub, 1 800 %arrayidx = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %sub1 801 %2 = load i32, i32* %arrayidx, align 4 802 %3 = load i32, i32* %a.addr, align 4 803 %add = add nsw i32 %2, %3 804 %4 = load i32, i32* %i, align 4 805 %arrayidx2 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %4 806 store i32 %add, i32* %arrayidx2, align 4 807 br label %for.inc 808 809 for.inc: ; preds = %for.body 810 %5 = load i32, i32* %i, align 4 811 %inc = add nsw i32 %5, 1 812 store i32 %inc, i32* %i, align 4 813 br label %for.cond 814 815 for.end: ; preds = %for.cond 816 %6 = load i32, i32* %a.addr, align 4 817 %arrayidx3 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6 818 %7 = load i32, i32* %arrayidx3, align 4 819 ret i32 %7 820 } 821 822 ; /// Different objects, swapped induction, alias at the beginning 823 ; int mayAlias02 (int a) { 824 ; int i; 825 ; for (i=0; i<SIZE; i++) 826 ; Foo.A[SIZE-i-1] = Foo.B[i] + a; 827 ; return Foo.A[a]; 828 ; } 829 ; CHECK-LABEL: define i32 @mayAlias02( 830 ; CHECK-NOT: add nsw <4 x i32> 831 ; CHECK: ret 832 833 define i32 @mayAlias02(i32 %a) nounwind { 834 entry: 835 %a.addr = alloca i32, align 4 836 %i = alloca i32, align 4 837 store i32 %a, i32* %a.addr, align 4 838 store i32 0, i32* %i, align 4 839 br label %for.cond 840 841 for.cond: ; preds = %for.inc, %entry 842 %0 = load i32, i32* %i, align 4 843 %cmp = icmp slt i32 %0, 100 844 br i1 %cmp, label %for.body, label %for.end 845 846 for.body: ; preds = %for.cond 847 %1 = load i32, i32* %i, align 4 848 %arrayidx = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %1 849 %2 = load i32, i32* %arrayidx, align 4 850 %3 = load i32, i32* %a.addr, align 4 851 %add = add nsw i32 %2, %3 852 %4 = load i32, i32* %i, align 4 853 %sub = sub nsw i32 100, %4 854 %sub1 = sub nsw i32 %sub, 1 855 %arrayidx2 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %sub1 856 store i32 %add, i32* %arrayidx2, align 4 857 br label %for.inc 858 859 for.inc: ; preds = %for.body 860 %5 = load i32, i32* %i, align 4 861 %inc = add nsw i32 %5, 1 862 store i32 %inc, i32* %i, align 4 863 br label %for.cond 864 865 for.end: ; preds = %for.cond 866 %6 = load i32, i32* %a.addr, align 4 867 %arrayidx3 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6 868 %7 = load i32, i32* %arrayidx3, align 4 869 ret i32 %7 870 } 871 872 ; /// Pointer access, run-time check added 873 ; int mayAlias03 (int a) { 874 ; int i; 875 ; for (i=0; i<SIZE; i++) 876 ; *(PA+i) = *(PB+SIZE-i-1) + a; 877 ; return *(PA+a); 878 ; } 879 ; CHECK-LABEL: define i32 @mayAlias03( 880 ; CHECK-NOT: add nsw <4 x i32> 881 ; CHECK: ret 882 883 define i32 @mayAlias03(i32 %a) nounwind { 884 entry: 885 %a.addr = alloca i32, align 4 886 %i = alloca i32, align 4 887 store i32 %a, i32* %a.addr, align 4 888 store i32 0, i32* %i, align 4 889 br label %for.cond 890 891 for.cond: ; preds = %for.inc, %entry 892 %0 = load i32, i32* %i, align 4 893 %cmp = icmp slt i32 %0, 100 894 br i1 %cmp, label %for.body, label %for.end 895 896 for.body: ; preds = %for.cond 897 %1 = load i32*, i32** @PB, align 4 898 %add.ptr = getelementptr inbounds i32, i32* %1, i32 100 899 %2 = load i32, i32* %i, align 4 900 %idx.neg = sub i32 0, %2 901 %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %idx.neg 902 %add.ptr2 = getelementptr inbounds i32, i32* %add.ptr1, i32 -1 903 %3 = load i32, i32* %add.ptr2, align 4 904 %4 = load i32, i32* %a.addr, align 4 905 %add = add nsw i32 %3, %4 906 %5 = load i32*, i32** @PA, align 4 907 %6 = load i32, i32* %i, align 4 908 %add.ptr3 = getelementptr inbounds i32, i32* %5, i32 %6 909 store i32 %add, i32* %add.ptr3, align 4 910 br label %for.inc 911 912 for.inc: ; preds = %for.body 913 %7 = load i32, i32* %i, align 4 914 %inc = add nsw i32 %7, 1 915 store i32 %inc, i32* %i, align 4 916 br label %for.cond 917 918 for.end: ; preds = %for.cond 919 %8 = load i32*, i32** @PA, align 4 920 %9 = load i32, i32* %a.addr, align 4 921 %add.ptr4 = getelementptr inbounds i32, i32* %8, i32 %9 922 %10 = load i32, i32* %add.ptr4, align 4 923 ret i32 %10 924 } 925 926 927 ;; === Finally, the tests that should only vectorize with care (or if we ignore undefined behaviour at all) === 928 929 930 ; int mustAlias01 (int a) { 931 ; int i; 932 ; for (i=0; i<SIZE; i++) 933 ; Foo.A[i+10] = Foo.B[SIZE-i-1] + a; 934 ; return Foo.A[a]; 935 ; } 936 ; CHECK-LABEL: define i32 @mustAlias01( 937 ; CHECK-NOT: add nsw <4 x i32> 938 ; CHECK: ret 939 940 define i32 @mustAlias01(i32 %a) nounwind { 941 entry: 942 %a.addr = alloca i32, align 4 943 %i = alloca i32, align 4 944 store i32 %a, i32* %a.addr, align 4 945 store i32 0, i32* %i, align 4 946 br label %for.cond 947 948 for.cond: ; preds = %for.inc, %entry 949 %0 = load i32, i32* %i, align 4 950 %cmp = icmp slt i32 %0, 100 951 br i1 %cmp, label %for.body, label %for.end 952 953 for.body: ; preds = %for.cond 954 %1 = load i32, i32* %i, align 4 955 %sub = sub nsw i32 100, %1 956 %sub1 = sub nsw i32 %sub, 1 957 %arrayidx = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %sub1 958 %2 = load i32, i32* %arrayidx, align 4 959 %3 = load i32, i32* %a.addr, align 4 960 %add = add nsw i32 %2, %3 961 %4 = load i32, i32* %i, align 4 962 %add2 = add nsw i32 %4, 10 963 %arrayidx3 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %add2 964 store i32 %add, i32* %arrayidx3, align 4 965 br label %for.inc 966 967 for.inc: ; preds = %for.body 968 %5 = load i32, i32* %i, align 4 969 %inc = add nsw i32 %5, 1 970 store i32 %inc, i32* %i, align 4 971 br label %for.cond 972 973 for.end: ; preds = %for.cond 974 %6 = load i32, i32* %a.addr, align 4 975 %arrayidx4 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6 976 %7 = load i32, i32* %arrayidx4, align 4 977 ret i32 %7 978 } 979 980 ; int mustAlias02 (int a) { 981 ; int i; 982 ; for (i=0; i<SIZE; i++) 983 ; Foo.A[i] = Foo.B[SIZE-i-10] + a; 984 ; return Foo.A[a]; 985 ; } 986 ; CHECK-LABEL: define i32 @mustAlias02( 987 ; CHECK-NOT: add nsw <4 x i32> 988 ; CHECK: ret 989 990 define i32 @mustAlias02(i32 %a) nounwind { 991 entry: 992 %a.addr = alloca i32, align 4 993 %i = alloca i32, align 4 994 store i32 %a, i32* %a.addr, align 4 995 store i32 0, i32* %i, align 4 996 br label %for.cond 997 998 for.cond: ; preds = %for.inc, %entry 999 %0 = load i32, i32* %i, align 4 1000 %cmp = icmp slt i32 %0, 100 1001 br i1 %cmp, label %for.body, label %for.end 1002 1003 for.body: ; preds = %for.cond 1004 %1 = load i32, i32* %i, align 4 1005 %sub = sub nsw i32 100, %1 1006 %sub1 = sub nsw i32 %sub, 10 1007 %arrayidx = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %sub1 1008 %2 = load i32, i32* %arrayidx, align 4 1009 %3 = load i32, i32* %a.addr, align 4 1010 %add = add nsw i32 %2, %3 1011 %4 = load i32, i32* %i, align 4 1012 %arrayidx2 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %4 1013 store i32 %add, i32* %arrayidx2, align 4 1014 br label %for.inc 1015 1016 for.inc: ; preds = %for.body 1017 %5 = load i32, i32* %i, align 4 1018 %inc = add nsw i32 %5, 1 1019 store i32 %inc, i32* %i, align 4 1020 br label %for.cond 1021 1022 for.end: ; preds = %for.cond 1023 %6 = load i32, i32* %a.addr, align 4 1024 %arrayidx3 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6 1025 %7 = load i32, i32* %arrayidx3, align 4 1026 ret i32 %7 1027 } 1028 1029 ; int mustAlias03 (int a) { 1030 ; int i; 1031 ; for (i=0; i<SIZE; i++) 1032 ; Foo.A[i+10] = Foo.B[SIZE-i-10] + a; 1033 ; return Foo.A[a]; 1034 ; } 1035 ; CHECK-LABEL: define i32 @mustAlias03( 1036 ; CHECK-NOT: add nsw <4 x i32> 1037 ; CHECK: ret 1038 1039 define i32 @mustAlias03(i32 %a) nounwind { 1040 entry: 1041 %a.addr = alloca i32, align 4 1042 %i = alloca i32, align 4 1043 store i32 %a, i32* %a.addr, align 4 1044 store i32 0, i32* %i, align 4 1045 br label %for.cond 1046 1047 for.cond: ; preds = %for.inc, %entry 1048 %0 = load i32, i32* %i, align 4 1049 %cmp = icmp slt i32 %0, 100 1050 br i1 %cmp, label %for.body, label %for.end 1051 1052 for.body: ; preds = %for.cond 1053 %1 = load i32, i32* %i, align 4 1054 %sub = sub nsw i32 100, %1 1055 %sub1 = sub nsw i32 %sub, 10 1056 %arrayidx = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %sub1 1057 %2 = load i32, i32* %arrayidx, align 4 1058 %3 = load i32, i32* %a.addr, align 4 1059 %add = add nsw i32 %2, %3 1060 %4 = load i32, i32* %i, align 4 1061 %add2 = add nsw i32 %4, 10 1062 %arrayidx3 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %add2 1063 store i32 %add, i32* %arrayidx3, align 4 1064 br label %for.inc 1065 1066 for.inc: ; preds = %for.body 1067 %5 = load i32, i32* %i, align 4 1068 %inc = add nsw i32 %5, 1 1069 store i32 %inc, i32* %i, align 4 1070 br label %for.cond 1071 1072 for.end: ; preds = %for.cond 1073 %6 = load i32, i32* %a.addr, align 4 1074 %arrayidx4 = getelementptr inbounds [100 x i32], [100 x i32]* getelementptr inbounds (%struct.anon, %struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6 1075 %7 = load i32, i32* %arrayidx4, align 4 1076 ret i32 %7 1077 } 1078