1*9880d681SAndroid Build Coastguard Worker; RUN: opt -loop-load-elim -S < %s | \ 2*9880d681SAndroid Build Coastguard Worker; RUN: FileCheck %s -check-prefix=ALL -check-prefix=ONE_STRIDE_SPEC \ 3*9880d681SAndroid Build Coastguard Worker; RUN: -check-prefix=TWO_STRIDE_SPEC 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Worker; RUN: opt -loop-load-elim -S -enable-mem-access-versioning=0 < %s | \ 6*9880d681SAndroid Build Coastguard Worker; RUN: FileCheck %s -check-prefix=ALL -check-prefix=NO_ONE_STRIDE_SPEC \ 7*9880d681SAndroid Build Coastguard Worker; RUN: -check-prefix=NO_TWO_STRIDE_SPEC 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Worker; RUN: opt -loop-load-elim -S -loop-load-elimination-scev-check-threshold=1 < %s | \ 10*9880d681SAndroid Build Coastguard Worker; RUN: FileCheck %s -check-prefix=ALL -check-prefix=ONE_STRIDE_SPEC \ 11*9880d681SAndroid Build Coastguard Worker; RUN: -check-prefix=NO_TWO_STRIDE_SPEC 12*9880d681SAndroid Build Coastguard Worker 13*9880d681SAndroid Build Coastguard Worker; Forwarding in the presence of symbolic strides: 14*9880d681SAndroid Build Coastguard Worker; 15*9880d681SAndroid Build Coastguard Worker; for (unsigned i = 0; i < 100; i++) 16*9880d681SAndroid Build Coastguard Worker; A[i + 1] = A[Stride * i] + B[i]; 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: @f( 21*9880d681SAndroid Build Coastguard Workerdefine void @f(i32* noalias nocapture %A, i32* noalias nocapture readonly %B, i64 %N, 22*9880d681SAndroid Build Coastguard Worker i64 %stride) { 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Worker; ONE_STRIDE_SPEC: %ident.check = icmp ne i64 %stride, 1 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Workerentry: 27*9880d681SAndroid Build Coastguard Worker; NO_ONE_STRIDE_SPEC-NOT: %load_initial = load i32, i32* %A 28*9880d681SAndroid Build Coastguard Worker; ONE_STRIDE_SPEC: %load_initial = load i32, i32* %A 29*9880d681SAndroid Build Coastguard Worker br label %for.body 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %entry 32*9880d681SAndroid Build Coastguard Worker; NO_ONE_STRIDE_SPEC-NOT: %store_forwarded = phi i32 [ %load_initial, {{.*}} ], [ %add, %for.body ] 33*9880d681SAndroid Build Coastguard Worker; ONE_STRIDE_SPEC: %store_forwarded = phi i32 [ %load_initial, {{.*}} ], [ %add, %for.body ] 34*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 35*9880d681SAndroid Build Coastguard Worker %mul = mul i64 %indvars.iv, %stride 36*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i32, i32* %A, i64 %mul 37*9880d681SAndroid Build Coastguard Worker %load = load i32, i32* %arrayidx, align 4 38*9880d681SAndroid Build Coastguard Worker %arrayidx2 = getelementptr inbounds i32, i32* %B, i64 %indvars.iv 39*9880d681SAndroid Build Coastguard Worker %load_1 = load i32, i32* %arrayidx2, align 4 40*9880d681SAndroid Build Coastguard Worker; NO_ONE_STRIDE_SPEC-NOT: %add = add i32 %load_1, %store_forwarded 41*9880d681SAndroid Build Coastguard Worker; ONE_STRIDE_SPEC: %add = add i32 %load_1, %store_forwarded 42*9880d681SAndroid Build Coastguard Worker %add = add i32 %load_1, %load 43*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 44*9880d681SAndroid Build Coastguard Worker %arrayidx_next = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next 45*9880d681SAndroid Build Coastguard Worker store i32 %add, i32* %arrayidx_next, align 4 46*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %indvars.iv.next, %N 47*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 50*9880d681SAndroid Build Coastguard Worker ret void 51*9880d681SAndroid Build Coastguard Worker} 52*9880d681SAndroid Build Coastguard Worker 53*9880d681SAndroid Build Coastguard Worker; With two symbolic strides: 54*9880d681SAndroid Build Coastguard Worker; 55*9880d681SAndroid Build Coastguard Worker; for (unsigned i = 0; i < 100; i++) 56*9880d681SAndroid Build Coastguard Worker; A[Stride2 * (i + 1)] = A[Stride1 * i] + B[i]; 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker; ALL-LABEL: @two_strides( 59*9880d681SAndroid Build Coastguard Workerdefine void @two_strides(i32* noalias nocapture %A, i32* noalias nocapture readonly %B, i64 %N, 60*9880d681SAndroid Build Coastguard Worker i64 %stride.1, i64 %stride.2) { 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker; TWO_STRIDE_SPEC: %ident.check = icmp ne i64 %stride.2, 1 63*9880d681SAndroid Build Coastguard Worker; TWO_STRIDE_SPEC: %ident.check1 = icmp ne i64 %stride.1, 1 64*9880d681SAndroid Build Coastguard Worker; NO_TWO_STRIDE_SPEC-NOT: %ident.check{{.*}} = icmp ne i64 %stride{{.*}}, 1 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Workerentry: 67*9880d681SAndroid Build Coastguard Worker; NO_TWO_STRIDE_SPEC-NOT: %load_initial = load i32, i32* %A 68*9880d681SAndroid Build Coastguard Worker; TWO_STRIDE_SPEC: %load_initial = load i32, i32* %A 69*9880d681SAndroid Build Coastguard Worker br label %for.body 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.body, %entry 72*9880d681SAndroid Build Coastguard Worker; NO_TWO_STRIDE_SPEC-NOT: %store_forwarded = phi i32 [ %load_initial, {{.*}} ], [ %add, %for.body ] 73*9880d681SAndroid Build Coastguard Worker; TWO_STRIDE_SPEC: %store_forwarded = phi i32 [ %load_initial, {{.*}} ], [ %add, %for.body ] 74*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 75*9880d681SAndroid Build Coastguard Worker %mul = mul i64 %indvars.iv, %stride.1 76*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i32, i32* %A, i64 %mul 77*9880d681SAndroid Build Coastguard Worker %load = load i32, i32* %arrayidx, align 4 78*9880d681SAndroid Build Coastguard Worker %arrayidx2 = getelementptr inbounds i32, i32* %B, i64 %indvars.iv 79*9880d681SAndroid Build Coastguard Worker %load_1 = load i32, i32* %arrayidx2, align 4 80*9880d681SAndroid Build Coastguard Worker; NO_TWO_STRIDE_SPEC-NOT: %add = add i32 %load_1, %store_forwarded 81*9880d681SAndroid Build Coastguard Worker; TWO_STRIDE_SPEC: %add = add i32 %load_1, %store_forwarded 82*9880d681SAndroid Build Coastguard Worker %add = add i32 %load_1, %load 83*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 84*9880d681SAndroid Build Coastguard Worker %mul.2 = mul i64 %indvars.iv.next, %stride.2 85*9880d681SAndroid Build Coastguard Worker %arrayidx_next = getelementptr inbounds i32, i32* %A, i64 %mul.2 86*9880d681SAndroid Build Coastguard Worker store i32 %add, i32* %arrayidx_next, align 4 87*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i64 %indvars.iv.next, %N 88*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %for.end, label %for.body 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 91*9880d681SAndroid Build Coastguard Worker ret void 92*9880d681SAndroid Build Coastguard Worker} 93