702 lines · plain
1; RUN: opt -passes='loop-vectorize,dce,instcombine' -force-vector-interleave=1 -force-vector-width=4 -S %s | FileCheck %s2 3target 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 49@Bar = common global %struct.anon.0 zeroinitializer, align 410 11@PB = external global ptr12@PA = external global ptr13 14 15;; === First, the tests that should always vectorize, whether statically or by adding run-time checks ===16 17 18; /// Different objects, positive induction, constant distance19; 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: ret28 29define i32 @noAlias01(i32 %a) nounwind {30entry:31 br label %for.body32 33for.body: ; preds = %entry, %for.body34 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]35 %arrayidx = getelementptr inbounds %struct.anon, ptr @Foo, i32 0, i32 2, i32 %i.0536 %0 = load i32, ptr %arrayidx, align 437 %add = add nsw i32 %0, %a38 %arrayidx1 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %i.0539 store i32 %add, ptr %arrayidx1, align 440 %inc = add nuw nsw i32 %i.05, 141 %exitcond.not = icmp eq i32 %inc, 10042 br i1 %exitcond.not, label %for.end, label %for.body43 44for.end: ; preds = %for.body45 %arrayidx2 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %a46 %1 = load i32, ptr %arrayidx2, align 447 ret i32 %148}49 50; /// Different objects, positive induction with widening slide51; int noAlias02 (int a) {52; int i;53; for (i=0; i<SIZE-10; i++)54; Foo.A[i] = Foo.B[i+10] + a;55; return Foo.A[a];56; }57; CHECK-LABEL: define i32 @noAlias02(58; CHECK: add nsw <4 x i32>59; CHECK: ret60 61define i32 @noAlias02(i32 %a) {62entry:63 br label %for.body64 65for.body: ; preds = %entry, %for.body66 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]67 %add = add nuw nsw i32 %i.05, 1068 %arrayidx = getelementptr inbounds %struct.anon, ptr @Foo, i32 0, i32 2, i32 %add69 %0 = load i32, ptr %arrayidx, align 470 %add1 = add nsw i32 %0, %a71 %arrayidx2 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %i.0572 store i32 %add1, ptr %arrayidx2, align 473 %inc = add nuw nsw i32 %i.05, 174 %exitcond.not = icmp eq i32 %inc, 9075 br i1 %exitcond.not, label %for.end, label %for.body76 77for.end: ; preds = %for.body78 %arrayidx3 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %a79 %1 = load i32, ptr %arrayidx3, align 480 ret i32 %181}82 83; /// Different objects, positive induction with shortening slide84; int noAlias03 (int a) {85; int i;86; for (i=0; i<SIZE; i++)87; Foo.A[i+10] = Foo.B[i] + a;88; return Foo.A[a];89; }90; CHECK-LABEL: define i32 @noAlias03(91; CHECK: add nsw <4 x i32>92; CHECK: ret93 94define i32 @noAlias03(i32 %a) {95entry:96 br label %for.body97 98for.body: ; preds = %entry, %for.body99 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]100 %arrayidx = getelementptr inbounds %struct.anon, ptr @Foo, i32 0, i32 2, i32 %i.05101 %0 = load i32, ptr %arrayidx, align 4102 %add = add nsw i32 %0, %a103 %add1 = add nuw nsw i32 %i.05, 10104 %arrayidx2 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %add1105 store i32 %add, ptr %arrayidx2, align 4106 %inc = add nuw nsw i32 %i.05, 1107 %exitcond.not = icmp eq i32 %inc, 100108 br i1 %exitcond.not, label %for.end, label %for.body109 110for.end: ; preds = %for.body111 %arrayidx3 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %a112 %1 = load i32, ptr %arrayidx3, align 4113 ret i32 %1114}115 116; /// Pointer access, positive stride, run-time check added117; int noAlias04 (int a) {118; int i;119; for (i=0; i<SIZE; i++)120; *(PA+i) = *(PB+i) + a;121; return *(PA+a);122; }123; CHECK-LABEL: define i32 @noAlias04(124; CHECK-NOT: add nsw <4 x i32>125; CHECK: ret126;127; TODO: This test vectorizes (with run-time check) on real targets with -O3)128; Check why it's not being vectorized even when forcing vectorization129 130define i32 @noAlias04(i32 %a) #0 {131entry:132 br label %for.body133 134for.body: ; preds = %entry, %for.body135 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]136 %0 = load ptr, ptr @PB, align 4137 %add.ptr = getelementptr inbounds i32, ptr %0, i32 %i.05138 %1 = load i32, ptr %add.ptr, align 4139 %add = add nsw i32 %1, %a140 %2 = load ptr, ptr @PA, align 4141 %add.ptr1 = getelementptr inbounds i32, ptr %2, i32 %i.05142 store i32 %add, ptr %add.ptr1, align 4143 %inc = add nuw nsw i32 %i.05, 1144 %exitcond.not = icmp eq i32 %inc, 100145 br i1 %exitcond.not, label %for.end, label %for.body146 147for.end: ; preds = %for.body148 %3 = load ptr, ptr @PA, align 4149 %add.ptr2 = getelementptr inbounds i32, ptr %3, i32 %a150 %4 = load i32, ptr %add.ptr2, align 4151 ret i32 %4152}153 154; /// Different objects, positive induction, multi-array155; int noAlias05 (int a) {156; int i, N=10;157; for (i=0; i<SIZE; i++)158; Bar.A[N][i] = Bar.B[N][i] + a;159; return Bar.A[N][a];160; }161; CHECK-LABEL: define i32 @noAlias05(162; CHECK: add nsw <4 x i32>163; CHECK: ret164 165define i32 @noAlias05(i32 %a) #0 {166entry:167 br label %for.body168 169for.body: ; preds = %entry, %for.body170 %i.07 = phi i32 [ 0, %entry ], [ %inc, %for.body ]171 %arrayidx1 = getelementptr inbounds %struct.anon.0, ptr @Bar, i32 0, i32 2, i32 10, i32 %i.07172 %0 = load i32, ptr %arrayidx1, align 4173 %add = add nsw i32 %0, %a174 %arrayidx3 = getelementptr inbounds %struct.anon.0, ptr @Bar, i32 0, i32 0, i32 10, i32 %i.07175 store i32 %add, ptr %arrayidx3, align 4176 %inc = add nuw nsw i32 %i.07, 1177 %exitcond.not = icmp eq i32 %inc, 100178 br i1 %exitcond.not, label %for.end, label %for.body179 180for.end: ; preds = %for.body181 %arrayidx5 = getelementptr inbounds %struct.anon.0, ptr @Bar, i32 0, i32 0, i32 10, i32 %a182 %1 = load i32, ptr %arrayidx5, align 4183 ret i32 %1184}185 186; /// Same objects, positive induction, multi-array, different sub-elements187; int noAlias06 (int a) {188; int i, N=10;189; for (i=0; i<SIZE; i++)190; Bar.A[N][i] = Bar.A[N+1][i] + a;191; return Bar.A[N][a];192; }193; CHECK-LABEL: define i32 @noAlias06(194; CHECK: add nsw <4 x i32>195; CHECK: ret196 197define i32 @noAlias06(i32 %a) #0 {198entry:199 br label %for.body200 201for.body: ; preds = %entry, %for.body202 %i.07 = phi i32 [ 0, %entry ], [ %inc, %for.body ]203 %arrayidx1 = getelementptr inbounds %struct.anon.0, ptr @Bar, i32 0, i32 0, i32 11, i32 %i.07204 %0 = load i32, ptr %arrayidx1, align 4205 %add2 = add nsw i32 %0, %a206 %arrayidx4 = getelementptr inbounds %struct.anon.0, ptr @Bar, i32 0, i32 0, i32 10, i32 %i.07207 store i32 %add2, ptr %arrayidx4, align 4208 %inc = add nuw nsw i32 %i.07, 1209 %exitcond.not = icmp eq i32 %inc, 100210 br i1 %exitcond.not, label %for.end, label %for.body211 212for.end: ; preds = %for.body213 %arrayidx6 = getelementptr inbounds %struct.anon.0, ptr @Bar, i32 0, i32 0, i32 10, i32 %a214 %1 = load i32, ptr %arrayidx6, align 4215 ret i32 %1216}217 218; /// Different objects, negative induction, constant distance219; int noAlias07 (int a) {220; int i;221; for (i=0; i<SIZE; i++)222; Foo.A[SIZE-i-1] = Foo.B[SIZE-i-1] + a;223; return Foo.A[a];224; }225; CHECK-LABEL: define i32 @noAlias07(226; CHECK: store <4 x i32>227; CHECK: ret228define i32 @noAlias07(i32 %a) #0 {229entry:230 br label %for.body231 232for.body: ; preds = %entry, %for.body233 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]234 %sub1 = sub nuw nsw i32 99, %i.05235 %arrayidx = getelementptr inbounds %struct.anon, ptr @Foo, i32 0, i32 2, i32 %sub1236 %0 = load i32, ptr %arrayidx, align 4237 %add = add nsw i32 %0, %a238 %arrayidx4 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %sub1239 store i32 %add, ptr %arrayidx4, align 4240 %inc = add nuw nsw i32 %i.05, 1241 %exitcond.not = icmp eq i32 %inc, 100242 br i1 %exitcond.not, label %for.end, label %for.body243 244for.end: ; preds = %for.body245 %arrayidx5 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %a246 %1 = load i32, ptr %arrayidx5, align 4247 ret i32 %1248}249 250; /// Different objects, negative induction, shortening slide251; int noAlias08 (int a) {252; int i;253; for (i=0; i<SIZE-10; i++)254; Foo.A[SIZE-i-1] = Foo.B[SIZE-i-10] + a;255; return Foo.A[a];256; }257; CHECK-LABEL: define i32 @noAlias08(258; CHECK: load <4 x i32>259; CHECK: ret260 261define i32 @noAlias08(i32 %a) #0 {262entry:263 br label %for.body264 265for.body: ; preds = %entry, %for.body266 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]267 %sub1 = sub nuw nsw i32 90, %i.05268 %arrayidx = getelementptr inbounds %struct.anon, ptr @Foo, i32 0, i32 2, i32 %sub1269 %0 = load i32, ptr %arrayidx, align 4270 %add = add nsw i32 %0, %a271 %sub3 = sub nuw nsw i32 99, %i.05272 %arrayidx4 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %sub3273 store i32 %add, ptr %arrayidx4, align 4274 %inc = add nuw nsw i32 %i.05, 1275 %exitcond.not = icmp eq i32 %inc, 90276 br i1 %exitcond.not, label %for.end, label %for.body277 278for.end: ; preds = %for.body279 %arrayidx5 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %a280 %1 = load i32, ptr %arrayidx5, align 4281 ret i32 %1282}283 284; /// Different objects, negative induction, widening slide285; int noAlias09 (int a) {286; int i;287; for (i=0; i<SIZE; i++)288; Foo.A[SIZE-i-10] = Foo.B[SIZE-i-1] + a;289; return Foo.A[a];290; }291; CHECK-LABEL: define i32 @noAlias09(292; CHECK: load <4 x i32>293; CHECK: ret294 295define i32 @noAlias09(i32 %a) #0 {296entry:297 br label %for.body298 299for.body: ; preds = %entry, %for.body300 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]301 %sub1 = sub nuw nsw i32 99, %i.05302 %arrayidx = getelementptr inbounds %struct.anon, ptr @Foo, i32 0, i32 2, i32 %sub1303 %0 = load i32, ptr %arrayidx, align 4304 %add = add nsw i32 %0, %a305 %sub3 = sub nsw i32 90, %i.05306 %arrayidx4 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %sub3307 store i32 %add, ptr %arrayidx4, align 4308 %inc = add nuw nsw i32 %i.05, 1309 %exitcond.not = icmp eq i32 %inc, 100310 br i1 %exitcond.not, label %for.end, label %for.body311 312for.end: ; preds = %for.body313 %arrayidx5 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %a314 %1 = load i32, ptr %arrayidx5, align 4315 ret i32 %1316}317 318; /// Pointer access, negative stride, run-time check added319; int noAlias10 (int a) {320; int i;321; for (i=0; i<SIZE; i++)322; *(PA+SIZE-i-1) = *(PB+SIZE-i-1) + a;323; return *(PA+a);324; }325; CHECK-LABEL: define i32 @noAlias10(326; CHECK-NOT: sub {{.*}} <4 x i32>327; CHECK: ret328;329; TODO: This test vectorizes (with run-time check) on real targets with -O3)330; Check why it's not being vectorized even when forcing vectorization331 332define i32 @noAlias10(i32 %a) #0 {333entry:334 br label %for.body335 336for.body: ; preds = %entry, %for.body337 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]338 %0 = load ptr, ptr @PB, align 4339 %add.ptr = getelementptr inbounds i8, ptr %0, i32 400340 %idx.neg = sub nsw i32 0, %i.05341 %add.ptr1 = getelementptr inbounds i32, ptr %add.ptr, i32 %idx.neg342 %add.ptr2 = getelementptr inbounds i8, ptr %add.ptr1, i32 -4343 %1 = load i32, ptr %add.ptr2, align 4344 %add = add nsw i32 %1, %a345 %2 = load ptr, ptr @PA, align 4346 %add.ptr3 = getelementptr inbounds i8, ptr %2, i32 400347 %add.ptr5 = getelementptr inbounds i32, ptr %add.ptr3, i32 %idx.neg348 %add.ptr6 = getelementptr inbounds i8, ptr %add.ptr5, i32 -4349 store i32 %add, ptr %add.ptr6, align 4350 %inc = add nuw nsw i32 %i.05, 1351 %exitcond.not = icmp eq i32 %inc, 100352 br i1 %exitcond.not, label %for.end, label %for.body353 354for.end: ; preds = %for.body355 %3 = load ptr, ptr @PA, align 4356 %add.ptr7 = getelementptr inbounds i32, ptr %3, i32 %a357 %4 = load i32, ptr %add.ptr7, align 4358 ret i32 %4359}360 361; /// Different objects, negative induction, multi-array362; int noAlias11 (int a) {363; int i, N=10;364; for (i=0; i<SIZE; i++)365; Bar.A[N][SIZE-i-1] = Bar.B[N][SIZE-i-1] + a;366; return Bar.A[N][a];367; }368; CHECK-LABEL: define i32 @noAlias11(369; CHECK: store <4 x i32>370; CHECK: ret371 372define i32 @noAlias11(i32 %a) #0 {373entry:374 br label %for.body375 376for.body: ; preds = %entry, %for.body377 %i.07 = phi i32 [ 0, %entry ], [ %inc, %for.body ]378 %sub1 = sub nuw nsw i32 99, %i.07379 %arrayidx2 = getelementptr inbounds %struct.anon.0, ptr @Bar, i32 0, i32 2, i32 10, i32 %sub1380 %0 = load i32, ptr %arrayidx2, align 4381 %add = add nsw i32 %0, %a382 %arrayidx6 = getelementptr inbounds %struct.anon.0, ptr @Bar, i32 0, i32 0, i32 10, i32 %sub1383 store i32 %add, ptr %arrayidx6, align 4384 %inc = add nuw nsw i32 %i.07, 1385 %exitcond.not = icmp eq i32 %inc, 100386 br i1 %exitcond.not, label %for.end, label %for.body387 388for.end: ; preds = %for.body389 %arrayidx8 = getelementptr inbounds %struct.anon.0, ptr @Bar, i32 0, i32 0, i32 10, i32 %a390 %1 = load i32, ptr %arrayidx8, align 4391 ret i32 %1392}393 394; /// Same objects, negative induction, multi-array, different sub-elements395; int noAlias12 (int a) {396; int i, N=10;397; for (i=0; i<SIZE; i++)398; Bar.A[N][SIZE-i-1] = Bar.A[N+1][SIZE-i-1] + a;399; return Bar.A[N][a];400; }401; CHECK-LABEL: define i32 @noAlias12(402; CHECK: store <4 x i32>403; CHECK: ret404 405define i32 @noAlias12(i32 %a) #0 {406entry:407 br label %for.body408 409for.body: ; preds = %entry, %for.body410 %i.07 = phi i32 [ 0, %entry ], [ %inc, %for.body ]411 %sub1 = sub nuw nsw i32 99, %i.07412 %arrayidx2 = getelementptr inbounds %struct.anon.0, ptr @Bar, i32 0, i32 0, i32 11, i32 %sub1413 %0 = load i32, ptr %arrayidx2, align 4414 %add3 = add nsw i32 %0, %a415 %arrayidx7 = getelementptr inbounds %struct.anon.0, ptr @Bar, i32 0, i32 0, i32 10, i32 %sub1416 store i32 %add3, ptr %arrayidx7, align 4417 %inc = add nuw nsw i32 %i.07, 1418 %exitcond.not = icmp eq i32 %inc, 100419 br i1 %exitcond.not, label %for.end, label %for.body420 421for.end: ; preds = %for.body422 %arrayidx9 = getelementptr inbounds %struct.anon.0, ptr @Bar, i32 0, i32 0, i32 10, i32 %a423 %1 = load i32, ptr %arrayidx9, align 4424 ret i32 %1425}426 427; /// Same objects, positive induction, constant distance, just enough for vector size428; int noAlias13 (int a) {429; int i;430; for (i=0; i<SIZE; i++)431; Foo.A[i] = Foo.A[i+4] + a;432; return Foo.A[a];433; }434; CHECK-LABEL: define i32 @noAlias13(435; CHECK: add nsw <4 x i32>436; CHECK: ret437 438define i32 @noAlias13(i32 %a) #0 {439entry:440 br label %for.body441 442for.body: ; preds = %entry, %for.body443 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]444 %add = add nuw nsw i32 %i.05, 4445 %arrayidx = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %add446 %0 = load i32, ptr %arrayidx, align 4447 %add1 = add nsw i32 %0, %a448 %arrayidx2 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %i.05449 store i32 %add1, ptr %arrayidx2, align 4450 %inc = add nuw nsw i32 %i.05, 1451 %exitcond.not = icmp eq i32 %inc, 100452 br i1 %exitcond.not, label %for.end, label %for.body453 454for.end: ; preds = %for.body455 %arrayidx3 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %a456 %1 = load i32, ptr %arrayidx3, align 4457 ret i32 %1458}459 460; /// Same objects, negative induction, constant distance, just enough for vector size461; int noAlias14 (int a) {462; int i;463; for (i=0; i<SIZE; i++)464; Foo.A[SIZE-i-1] = Foo.A[SIZE-i-5] + a;465; return Foo.A[a];466; }467; CHECK-LABEL: define i32 @noAlias14(468; CHECK: load <4 x i32>469; CHECK: ret470 471define i32 @noAlias14(i32 %a) #0 {472entry:473 br label %for.body474 475for.body: ; preds = %entry, %for.body476 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]477 %sub1 = sub nsw i32 95, %i.05478 %arrayidx = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %sub1479 %0 = load i32, ptr %arrayidx, align 4480 %add = add nsw i32 %0, %a481 %sub3 = sub nuw nsw i32 99, %i.05482 %arrayidx4 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %sub3483 store i32 %add, ptr %arrayidx4, align 4484 %inc = add nuw nsw i32 %i.05, 1485 %exitcond.not = icmp eq i32 %inc, 100486 br i1 %exitcond.not, label %for.end, label %for.body487 488for.end: ; preds = %for.body489 %arrayidx5 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %a490 %1 = load i32, ptr %arrayidx5, align 4491 ret i32 %1492}493 494 495;; === Now, the tests that we could vectorize with induction changes or run-time checks ===496 497 498; /// Different objects, swapped induction, alias at the end499; int mayAlias01 (int a) {500; int i;501; for (i=0; i<SIZE; i++)502; Foo.A[i] = Foo.B[SIZE-i-1] + a;503; return Foo.A[a];504; }505; CHECK-LABEL: define i32 @mayAlias01(506; CHECK: add nsw <4 x i32>507; CHECK: ret508 509define i32 @mayAlias01(i32 %a) nounwind {510entry:511 br label %for.body512 513for.body: ; preds = %entry, %for.body514 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]515 %sub1 = sub nuw nsw i32 99, %i.05516 %arrayidx = getelementptr inbounds %struct.anon, ptr @Foo, i32 0, i32 2, i32 %sub1517 %0 = load i32, ptr %arrayidx, align 4518 %add = add nsw i32 %0, %a519 %arrayidx2 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %i.05520 store i32 %add, ptr %arrayidx2, align 4521 %inc = add nuw nsw i32 %i.05, 1522 %exitcond.not = icmp eq i32 %inc, 100523 br i1 %exitcond.not, label %for.end, label %for.body524 525for.end: ; preds = %for.body526 %arrayidx3 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %a527 %1 = load i32, ptr %arrayidx3, align 4528 ret i32 %1529}530 531; /// Different objects, swapped induction, alias at the beginning532; int mayAlias02 (int a) {533; int i;534; for (i=0; i<SIZE; i++)535; Foo.A[SIZE-i-1] = Foo.B[i] + a;536; return Foo.A[a];537; }538; CHECK-LABEL: define i32 @mayAlias02(539; CHECK: add nsw <4 x i32>540; CHECK: ret541 542define i32 @mayAlias02(i32 %a) nounwind {543entry:544 br label %for.body545 546for.body: ; preds = %entry, %for.body547 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]548 %arrayidx = getelementptr inbounds %struct.anon, ptr @Foo, i32 0, i32 2, i32 %i.05549 %0 = load i32, ptr %arrayidx, align 4550 %add = add nsw i32 %0, %a551 %sub1 = sub nuw nsw i32 99, %i.05552 %arrayidx2 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %sub1553 store i32 %add, ptr %arrayidx2, align 4554 %inc = add nuw nsw i32 %i.05, 1555 %exitcond.not = icmp eq i32 %inc, 100556 br i1 %exitcond.not, label %for.end, label %for.body557 558for.end: ; preds = %for.body559 %arrayidx3 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %a560 %1 = load i32, ptr %arrayidx3, align 4561 ret i32 %1562}563 564; /// Pointer access, run-time check added565; int mayAlias03 (int a) {566; int i;567; for (i=0; i<SIZE; i++)568; *(PA+i) = *(PB+SIZE-i-1) + a;569; return *(PA+a);570; }571; CHECK-LABEL: define i32 @mayAlias03(572; CHECK-NOT: add nsw <4 x i32>573; CHECK: ret574 575define i32 @mayAlias03(i32 %a) nounwind {576entry:577 br label %for.body578 579for.body: ; preds = %entry, %for.body580 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]581 %0 = load ptr, ptr @PB, align 4582 %add.ptr = getelementptr inbounds i8, ptr %0, i32 400583 %idx.neg = sub nsw i32 0, %i.05584 %add.ptr1 = getelementptr inbounds i32, ptr %add.ptr, i32 %idx.neg585 %add.ptr2 = getelementptr inbounds i8, ptr %add.ptr1, i32 -4586 %1 = load i32, ptr %add.ptr2, align 4587 %add = add nsw i32 %1, %a588 %2 = load ptr, ptr @PA, align 4589 %add.ptr3 = getelementptr inbounds i32, ptr %2, i32 %i.05590 store i32 %add, ptr %add.ptr3, align 4591 %inc = add nuw nsw i32 %i.05, 1592 %exitcond.not = icmp eq i32 %inc, 100593 br i1 %exitcond.not, label %for.end, label %for.body594 595for.end: ; preds = %for.body596 %3 = load ptr, ptr @PA, align 4597 %add.ptr4 = getelementptr inbounds i32, ptr %3, i32 %a598 %4 = load i32, ptr %add.ptr4, align 4599 ret i32 %4600}601 602;; === Finally, the tests that should only vectorize with care (or if we ignore undefined behaviour at all) ===603 604 605; int mustAlias01 (int a) {606; int i;607; for (i=0; i<SIZE; i++)608; Foo.A[i+10] = Foo.B[SIZE-i-1] + a;609; return Foo.A[a];610; }611; CHECK-LABEL: define i32 @mustAlias01(612; CHECK-NOT: add nsw <4 x i32>613; CHECK: ret614 615define i32 @mustAlias01(i32 %a) nounwind {616entry:617 br label %for.body618 619for.body: ; preds = %entry, %for.body620 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]621 %sub1 = sub nuw nsw i32 99, %i.05622 %arrayidx = getelementptr inbounds %struct.anon, ptr @Foo, i32 0, i32 2, i32 %sub1623 %0 = load i32, ptr %arrayidx, align 4624 %add = add nsw i32 %0, %a625 %add2 = add nuw nsw i32 %i.05, 10626 %arrayidx3 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %add2627 store i32 %add, ptr %arrayidx3, align 4628 %inc = add nuw nsw i32 %i.05, 1629 %exitcond.not = icmp eq i32 %inc, 100630 br i1 %exitcond.not, label %for.end, label %for.body631 632for.end: ; preds = %for.body633 %arrayidx4 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %a634 %1 = load i32, ptr %arrayidx4, align 4635 ret i32 %1636}637 638; int mustAlias02 (int a) {639; int i;640; for (i=0; i<SIZE; i++)641; Foo.A[i] = Foo.B[SIZE-i-10] + a;642; return Foo.A[a];643; }644; CHECK-LABEL: define i32 @mustAlias02(645; CHECK-NOT: add nsw <4 x i32>646; CHECK: ret647 648define i32 @mustAlias02(i32 %a) nounwind {649entry:650 br label %for.body651 652for.body: ; preds = %entry, %for.body653 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]654 %sub1 = sub nsw i32 90, %i.05655 %arrayidx = getelementptr inbounds %struct.anon, ptr @Foo, i32 0, i32 2, i32 %sub1656 %0 = load i32, ptr %arrayidx, align 4657 %add = add nsw i32 %0, %a658 %arrayidx2 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %i.05659 store i32 %add, ptr %arrayidx2, align 4660 %inc = add nuw nsw i32 %i.05, 1661 %exitcond.not = icmp eq i32 %inc, 100662 br i1 %exitcond.not, label %for.end, label %for.body663 664for.end: ; preds = %for.body665 %arrayidx3 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %a666 %1 = load i32, ptr %arrayidx3, align 4667 ret i32 %1668}669 670; int mustAlias03 (int a) {671; int i;672; for (i=0; i<SIZE; i++)673; Foo.A[i+10] = Foo.B[SIZE-i-10] + a;674; return Foo.A[a];675; }676; CHECK-LABEL: define i32 @mustAlias03(677; CHECK-NOT: add nsw <4 x i32>678; CHECK: ret679 680define i32 @mustAlias03(i32 %a) nounwind {681entry:682 br label %for.body683 684for.body: ; preds = %entry, %for.body685 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.body ]686 %sub1 = sub nsw i32 90, %i.05687 %arrayidx = getelementptr inbounds %struct.anon, ptr @Foo, i32 0, i32 2, i32 %sub1688 %0 = load i32, ptr %arrayidx, align 4689 %add = add nsw i32 %0, %a690 %add2 = add nuw nsw i32 %i.05, 10691 %arrayidx3 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %add2692 store i32 %add, ptr %arrayidx3, align 4693 %inc = add nuw nsw i32 %i.05, 1694 %exitcond.not = icmp eq i32 %inc, 100695 br i1 %exitcond.not, label %for.end, label %for.body696 697for.end: ; preds = %for.body698 %arrayidx4 = getelementptr inbounds [100 x i32], ptr @Foo, i32 0, i32 %a699 %1 = load i32, ptr %arrayidx4, align 4700 ret i32 %1701}702