brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.7 KiB · f3fdb90 Raw
182 lines · plain
1; RUN: opt < %s -passes=loop-vectorize,dce,instcombine -force-vector-width=4 -S | FileCheck %s2 3target datalayout = "e-p:64:64:64-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:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"4 5; tests skipping iterations within a VF through break/continue/gotos.6 7; The main difficulty in vectorizing these loops in test1,test2 and test3 is8; safely speculating that the widened load of A[i] should not fault if the9; scalarized loop does not fault. For example, the10; original load in the scalar loop may not fault, but the last iteration of the11; vectorized load can fault (if it crosses a page boudary for example).12; This last vector iteration is where *one* of the13; scalar iterations lead to the early exit.14 15; int test(int *A, int Length) {16;   for (int i = 0; i < Length; i++) {17;     if (A[i] > 10.0) goto end;18;     A[i] = 0;19;   }20; end:21;   return 0;22; }23; CHECK-LABEL: test1(24; CHECK-NOT: <4 x i32>25define i32 @test1(ptr nocapture %A, i32 %Length) {26entry:27  %cmp8 = icmp sgt i32 %Length, 028  br i1 %cmp8, label %for.body.preheader, label %end29 30for.body.preheader:                               ; preds = %entry31  br label %for.body32 33for.body:                                         ; preds = %for.body.preheader, %if.else34  %indvars.iv = phi i64 [ %indvars.iv.next, %if.else ], [ 0, %for.body.preheader ]35  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv36  %0 = load i32, ptr %arrayidx, align 4, !tbaa !1537  %cmp1 = icmp sgt i32 %0, 1038  br i1 %cmp1, label %end.loopexit, label %if.else39 40if.else:                                          ; preds = %for.body41  store i32 0, ptr %arrayidx, align 4, !tbaa !1542  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 143  %1 = trunc i64 %indvars.iv.next to i3244  %cmp = icmp slt i32 %1, %Length45  br i1 %cmp, label %for.body, label %end.loopexit46 47end.loopexit:                                     ; preds = %if.else, %for.body48  br label %end49 50end:                                              ; preds = %end.loopexit, %entry51  ret i32 052}53 54; We don't use anything from within the loop at the early exit path55; so we do not need to know which iteration caused the early exit path.56; bool test2(int *A, int Length, int K) {57;   for (int i = 0; i < Length; i++) {58;     if (A[i] == K) return true;59;   }60;   return false;61; }62; TODO: Today we do not vectorize this, but we could teach the vectorizer, once63; the hard part of proving/speculating A[i:VF - 1] loads does not fault is handled by the64; compiler/hardware.65 66; CHECK-LABEL: test2(67; CHECK-NOT: <4 x i32>68define i32 @test2(ptr nocapture %A, i32 %Length, i32 %K) {69entry:70  %cmp8 = icmp sgt i32 %Length, 071  br i1 %cmp8, label %for.body.preheader, label %end72 73for.body.preheader:                               ; preds = %entry74  br label %for.body75 76for.body:                                         ; preds = %for.body.preheader, %if.else77  %indvars.iv = phi i64 [ %indvars.iv.next, %if.else ], [ 0, %for.body.preheader ]78  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv79  %ld = load i32, ptr %arrayidx, align 480  %cmp1 = icmp eq i32 %ld, %K81  br i1 %cmp1, label %end.loopexit, label %if.else82 83if.else:                                          ; preds = %for.body84  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 185  %trunc = trunc i64 %indvars.iv.next to i3286  %cmp = icmp slt i32 %trunc, %Length87  br i1 %cmp, label %for.body, label %end.loopexit88 89end.loopexit:                                     ; preds = %if.else, %for.body90  %result.lcssa = phi i32 [ 1, %for.body ], [ 0, %if.else ]91  br label %end92 93end:                                              ; preds = %end.loopexit, %entry94  %result = phi i32 [ %result.lcssa, %end.loopexit ], [ 0, %entry ]95  ret i32 %result96}97 98; We use the IV in the early exit99; so we need to know which iteration caused the early exit path.100; int test3(int *A, int Length, int K) {101;   for (int i = 0; i < Length; i++) {102;     if (A[i] == K) return i;103;   }104;   return -1;105; }106; TODO: Today we do not vectorize this, but we could teach the vectorizer (once107; we handle the speculation safety of the widened load).108; CHECK-LABEL: test3(109; CHECK-NOT: <4 x i32>110define i32 @test3(ptr nocapture %A, i32 %Length, i32 %K) {111entry:112  %cmp8 = icmp sgt i32 %Length, 0113  br i1 %cmp8, label %for.body.preheader, label %end114 115for.body.preheader:                               ; preds = %entry116  br label %for.body117 118for.body:                                         ; preds = %for.body.preheader, %if.else119  %indvars.iv = phi i64 [ %indvars.iv.next, %if.else ], [ 0, %for.body.preheader ]120  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv121  %ld = load i32, ptr %arrayidx, align 4122  %cmp1 = icmp eq i32 %ld, %K123  br i1 %cmp1, label %end.loopexit, label %if.else124 125if.else:                                          ; preds = %for.body126  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1127  %trunc = trunc i64 %indvars.iv.next to i32128  %cmp = icmp slt i32 %trunc, %Length129  br i1 %cmp, label %for.body, label %end.loopexit130 131end.loopexit:                                     ; preds = %if.else, %for.body132  %result.lcssa = phi i64 [ %indvars.iv, %for.body ], [ -1, %if.else ]133  %res.trunc = trunc i64 %result.lcssa to i32134  br label %end135 136end:                                              ; preds = %end.loopexit, %entry137  %result = phi i32 [ %res.trunc, %end.loopexit ], [ -1, %entry ]138  ret i32 %result139}140 141; bool test4(int *A, int Length, int K, int J) {142;   for (int i = 0; i < Length; i++) {143;     if (A[i] == K) continue;144;     A[i] = J;145;   }146; }147; For this test, we vectorize and generate predicated stores to A[i].148; CHECK-LABEL: test4(149; CHECK: <4 x i32>150define void @test4(ptr nocapture %A, i32 %Length, i32 %K, i32 %J) {151entry:152  %cmp8 = icmp sgt i32 %Length, 0153  br i1 %cmp8, label %for.body.preheader, label %end.loopexit154 155for.body.preheader:                               ; preds = %entry156  br label %for.body157 158for.body:                                         ; preds = %for.body.preheader, %if.else159  %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %for.body.preheader ]160  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv161  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1162  %trunc = trunc i64 %indvars.iv.next to i32163  %ld = load i32, ptr %arrayidx, align 4164  %cmp1 = icmp eq i32 %ld, %K165  br i1 %cmp1, label %latch, label %if.else166 167if.else:168  store i32 %J, ptr %arrayidx, align 4169  br label %latch170 171latch:                                          ; preds = %for.body172  %cmp = icmp slt i32 %trunc, %Length173  br i1 %cmp, label %for.body, label %end.loopexit174 175end.loopexit:                                     ; preds = %if.else, %for.body176  ret void177}178!15 = !{!16, !16, i64 0}179!16 = !{!"int", !17, i64 0}180!17 = !{!"omnipotent char", !18, i64 0}181!18 = !{!"Simple C/C++ TBAA"}182