brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.4 KiB · e0f12fb Raw
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