You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.167
Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
parent
e19d552987
commit
b084638f15
@ -1,33 +0,0 @@
|
||||
; RUN: opt -loop-load-elim -S < %s | FileCheck %s
|
||||
; RUN: opt -passes=loop-load-elim -S < %s | FileCheck %s
|
||||
|
||||
; Simple st->ld forwarding derived from a lexical backward dep.
|
||||
;
|
||||
; for (unsigned i = 0; i < 100; i++)
|
||||
; A[i+1] = A[i] + B[i];
|
||||
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
define void @f(i32* noalias nocapture %A, i32* noalias nocapture readonly %B, i64 %N) {
|
||||
entry:
|
||||
; CHECK: %load_initial = load i32, i32* %A
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body, %entry
|
||||
; CHECK: %store_forwarded = phi i32 [ %load_initial, %entry ], [ %add, %for.body ]
|
||||
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
|
||||
%load = load i32, i32* %arrayidx, align 4
|
||||
%arrayidx2 = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
|
||||
%load_1 = load i32, i32* %arrayidx2, align 4
|
||||
; CHECK: %add = add i32 %load_1, %store_forwarded
|
||||
%add = add i32 %load_1, %load
|
||||
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
||||
%arrayidx_next = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
|
||||
store i32 %add, i32* %arrayidx_next, align 4
|
||||
%exitcond = icmp eq i64 %indvars.iv.next, %N
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
for.end: ; preds = %for.body
|
||||
ret void
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
; RUN: opt -S -loop-load-elim < %s | FileCheck %s
|
||||
|
||||
; We can't hoist conditional loads to the preheader for the initial value.
|
||||
; E.g. in the loop below we'd access array[-1] if we did:
|
||||
;
|
||||
; for(int i = 0 ; i < n ; i++ )
|
||||
; array[i] = ( i > 0 ? array[i - 1] : 0 ) + 4;
|
||||
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-apple-macosx10.11.0"
|
||||
|
||||
define void @f(i32* %array, i32 %n) {
|
||||
entry:
|
||||
%cmp10 = icmp sgt i32 %n, 0
|
||||
br i1 %cmp10, label %for.body, label %for.cond.cleanup
|
||||
|
||||
for.cond.cleanup: ; preds = %cond.end, %entry
|
||||
ret void
|
||||
|
||||
for.body: ; preds = %entry, %cond.end
|
||||
%indvars.iv = phi i64 [ %indvars.iv.next, %cond.end ], [ 0, %entry ]
|
||||
; CHECK-NOT: %store_forwarded = phi
|
||||
%cmp1 = icmp sgt i64 %indvars.iv, 0
|
||||
br i1 %cmp1, label %cond.true, label %cond.end
|
||||
|
||||
cond.true: ; preds = %for.body
|
||||
%0 = add nsw i64 %indvars.iv, -1
|
||||
%arrayidx = getelementptr inbounds i32, i32* %array, i64 %0
|
||||
%1 = load i32, i32* %arrayidx, align 4
|
||||
br label %cond.end
|
||||
|
||||
cond.end: ; preds = %for.body, %cond.true
|
||||
%cond = phi i32 [ %1, %cond.true ], [ 0, %for.body ]
|
||||
; CHECK: %cond = phi i32 [ %1, %cond.true ], [ 0, %for.body ]
|
||||
%add = add nsw i32 %cond, 4
|
||||
%arrayidx3 = getelementptr inbounds i32, i32* %array, i64 %indvars.iv
|
||||
store i32 %add, i32* %arrayidx3, align 4
|
||||
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
||||
%lftr.wideiv = trunc i64 %indvars.iv.next to i32
|
||||
%exitcond = icmp eq i32 %lftr.wideiv, %n
|
||||
br i1 %exitcond, label %for.cond.cleanup, label %for.body
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
; RUN: opt -loop-load-elim -S < %s | FileCheck %s
|
||||
|
||||
; No loop-carried forwarding: The intervening store to A[i] kills the stored
|
||||
; value from the previous iteration.
|
||||
;
|
||||
; for (unsigned i = 0; i < 100; i++) {
|
||||
; A[i] = 1;
|
||||
; A[i+1] = A[i] + B[i];
|
||||
; }
|
||||
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
define void @f(i32* noalias nocapture %A, i32* noalias nocapture readonly %B, i64 %N) {
|
||||
entry:
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body, %entry
|
||||
; CHECK-NOT: %store_forwarded
|
||||
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
|
||||
store i32 1, i32* %arrayidx, align 4
|
||||
%a = load i32, i32* %arrayidx, align 4
|
||||
%arrayidxB = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
|
||||
%b = load i32, i32* %arrayidxB, align 4
|
||||
; CHECK: %add = add i32 %b, %a
|
||||
%add = add i32 %b, %a
|
||||
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
||||
%arrayidx_next = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
|
||||
store i32 %add, i32* %arrayidx_next, align 4
|
||||
%exitcond = icmp eq i64 %indvars.iv.next, %N
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
for.end: ; preds = %for.body
|
||||
ret void
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
; RUN: opt -loop-load-elim -S < %s | FileCheck %s
|
||||
; RUN: opt -passes=loop-load-elim -S < %s | FileCheck %s
|
||||
|
||||
; Simple st->ld forwarding derived from a lexical forward dep.
|
||||
;
|
||||
; for (unsigned i = 0; i < 100; i++) {
|
||||
; A[i+1] = B[i] + 2;
|
||||
; C[i] = A[i] * 2;
|
||||
; }
|
||||
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
define void @f(i32* %A, i32* %B, i32* %C, i64 %N) {
|
||||
|
||||
; CHECK: for.body.lver.check:
|
||||
; CHECK: %found.conflict{{.*}} =
|
||||
; CHECK-NOT: %found.conflict{{.*}} =
|
||||
|
||||
entry:
|
||||
; Make sure the hoisted load keeps the alignment
|
||||
; CHECK: %load_initial = load i32, i32* %A, align 1
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body, %entry
|
||||
; CHECK: %store_forwarded = phi i32 [ %load_initial, %for.body.ph ], [ %a_p1, %for.body ]
|
||||
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
|
||||
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
||||
|
||||
%Aidx_next = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
|
||||
%Bidx = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
|
||||
%Cidx = getelementptr inbounds i32, i32* %C, i64 %indvars.iv
|
||||
%Aidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
|
||||
|
||||
%b = load i32, i32* %Bidx, align 4
|
||||
%a_p1 = add i32 %b, 2
|
||||
store i32 %a_p1, i32* %Aidx_next, align 4
|
||||
|
||||
%a = load i32, i32* %Aidx, align 1
|
||||
; CHECK: %c = mul i32 %store_forwarded, 2
|
||||
%c = mul i32 %a, 2
|
||||
store i32 %c, i32* %Cidx, align 4
|
||||
|
||||
%exitcond = icmp eq i64 %indvars.iv.next, %N
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
for.end: ; preds = %for.body
|
||||
ret void
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
; RUN: opt -loop-load-elim -S < %s | FileCheck %s
|
||||
|
||||
; Make sure we create a preheader if we dont' have one.
|
||||
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
define void @f(i32* noalias nocapture %A, i32* noalias nocapture readonly %B, i64 %N, i1 %C) {
|
||||
entry:
|
||||
br i1 %C, label %for.body, label %for.end
|
||||
|
||||
; CHECK: for.body.preheader:
|
||||
; CHECK-NEXT: %load_initial = load i32, i32* %A
|
||||
; CHECK-NEXT: br label %for.body
|
||||
|
||||
; CHECK: for.body:
|
||||
for.body:
|
||||
; CHECK-NEXT: %store_forwarded = phi i32 [ %load_initial, %for.body.preheader ], [ %add, %for.body ]
|
||||
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
|
||||
%load = load i32, i32* %arrayidx, align 4
|
||||
%arrayidx2 = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
|
||||
%load_1 = load i32, i32* %arrayidx2, align 4
|
||||
; CHECK: %add = add i32 %load_1, %store_forwarded
|
||||
%add = add i32 %load_1, %load
|
||||
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
||||
%arrayidx_next = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
|
||||
store i32 %add, i32* %arrayidx_next, align 4
|
||||
%exitcond = icmp eq i64 %indvars.iv.next, %N
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
for.end:
|
||||
ret void
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
; RUN: opt -loop-load-elim -S < %s | FileCheck %s
|
||||
; RUN: opt -loop-load-elim -S -runtime-check-per-loop-load-elim=2 < %s | FileCheck %s --check-prefix=AGGRESSIVE
|
||||
|
||||
; This needs two pairs of memchecks (A * { C, D }) for a single load
|
||||
; elimination which is considered to expansive by default.
|
||||
;
|
||||
; for (unsigned i = 0; i < 100; i++) {
|
||||
; A[i+1] = B[i] + 2;
|
||||
; C[i] = A[i] * 2;
|
||||
; D[i] = 2;
|
||||
; }
|
||||
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
define void @f(i32* %A, i32* %B, i32* %C, i64 %N, i32* %D) {
|
||||
entry:
|
||||
br label %for.body
|
||||
|
||||
; AGGRESSIVE: for.body.lver.check:
|
||||
; AGGRESSIVE: %found.conflict{{.*}} =
|
||||
; AGGRESSIVE: %found.conflict{{.*}} =
|
||||
; AGGRESSIVE-NOT: %found.conflict{{.*}} =
|
||||
|
||||
for.body: ; preds = %for.body, %entry
|
||||
; CHECK-NOT: %store_forwarded =
|
||||
; AGGRESSIVE: %store_forwarded =
|
||||
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
|
||||
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
||||
|
||||
%Aidx_next = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
|
||||
%Bidx = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
|
||||
%Cidx = getelementptr inbounds i32, i32* %C, i64 %indvars.iv
|
||||
%Aidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
|
||||
%Didx = getelementptr inbounds i32, i32* %D, i64 %indvars.iv
|
||||
|
||||
%b = load i32, i32* %Bidx, align 4
|
||||
%a_p1 = add i32 %b, 2
|
||||
store i32 %a_p1, i32* %Aidx_next, align 4
|
||||
|
||||
%a = load i32, i32* %Aidx, align 4
|
||||
; CHECK: %c = mul i32 %a, 2
|
||||
; AGGRESSIVE: %c = mul i32 %store_forwarded, 2
|
||||
%c = mul i32 %a, 2
|
||||
store i32 %c, i32* %Cidx, align 4
|
||||
store i32 2, i32* %Didx, align 4
|
||||
|
||||
%exitcond = icmp eq i64 %indvars.iv.next, %N
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
for.end: ; preds = %for.body
|
||||
ret void
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
; RUN: opt -basicaa -loop-load-elim -S < %s | FileCheck %s
|
||||
|
||||
; In this case the later store forward to the load:
|
||||
;
|
||||
; for (unsigned i = 0; i < 100; i++) {
|
||||
; B[i] = A[i] + 1;
|
||||
; A[i+1] = C[i] + 2;
|
||||
; A[i+1] = D[i] + 3;
|
||||
; }
|
||||
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
define void @f(i32* noalias nocapture %A, i32* noalias nocapture readonly %B,
|
||||
i32* noalias nocapture %C, i32* noalias nocapture readonly %D,
|
||||
i64 %N) {
|
||||
entry:
|
||||
; CHECK: %load_initial = load i32, i32* %A
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body, %entry
|
||||
; CHECK: %store_forwarded = phi i32 [ %load_initial, %entry ], [ %addD, %for.body ]
|
||||
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
|
||||
%arrayidxA = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
|
||||
%loadA = load i32, i32* %arrayidxA, align 4
|
||||
; CHECK: %addA = add i32 %store_forwarded, 1
|
||||
%addA = add i32 %loadA, 1
|
||||
|
||||
%arrayidxB = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
|
||||
store i32 %addA, i32* %arrayidxB, align 4
|
||||
|
||||
%arrayidxC = getelementptr inbounds i32, i32* %C, i64 %indvars.iv
|
||||
%loadC = load i32, i32* %arrayidxC, align 4
|
||||
%addC = add i32 %loadC, 2
|
||||
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
||||
%arrayidxA_next = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
|
||||
store i32 %addC, i32* %arrayidxA_next, align 4
|
||||
|
||||
%arrayidxD = getelementptr inbounds i32, i32* %D, i64 %indvars.iv
|
||||
%loadD = load i32, i32* %arrayidxD, align 4
|
||||
%addD = add i32 %loadD, 3
|
||||
store i32 %addD, i32* %arrayidxA_next, align 4
|
||||
|
||||
%exitcond = icmp eq i64 %indvars.iv.next, %N
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
for.end: ; preds = %for.body
|
||||
ret void
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
; RUN: opt -loop-load-elim -S < %s | FileCheck %s
|
||||
|
||||
; The accesses to A are independent here but LAA reports it as a loop-carried
|
||||
; forward dependence. Check that we don't perform st->ld forwarding between
|
||||
; them.
|
||||
;
|
||||
; for (unsigned i = 0; i < 100; i++) {
|
||||
; A[i][1] = B[i] + 2;
|
||||
; C[i] = A[i][0] * 2;
|
||||
; }
|
||||
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
define void @f([2 x i32]* noalias %A, i32* noalias %B, i32* noalias %C, i64 %N) {
|
||||
|
||||
entry:
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body, %entry
|
||||
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
|
||||
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
||||
|
||||
%A1idx = getelementptr inbounds [2 x i32], [2 x i32]* %A, i64 %indvars.iv, i32 1
|
||||
%Bidx = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
|
||||
%Cidx = getelementptr inbounds i32, i32* %C, i64 %indvars.iv
|
||||
%A0idx = getelementptr inbounds [2 x i32], [2 x i32]* %A, i64 %indvars.iv, i32 0
|
||||
|
||||
%b = load i32, i32* %Bidx, align 4
|
||||
%a_p1 = add i32 %b, 2
|
||||
store i32 %a_p1, i32* %A1idx, align 4
|
||||
|
||||
; CHECK: %a = load i32, i32* %A0idx, align 4
|
||||
%a = load i32, i32* %A0idx, align 4
|
||||
; CHECK: %c = mul i32 %a, 2
|
||||
%c = mul i32 %a, 2
|
||||
store i32 %c, i32* %Cidx, align 4
|
||||
|
||||
%exitcond = icmp eq i64 %indvars.iv.next, %N
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
for.end: ; preds = %for.body
|
||||
ret void
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
; RUN: opt -basicaa -loop-load-elim -S < %s | FileCheck %s
|
||||
|
||||
; When optimizing for size don't eliminate in this loop because the loop would
|
||||
; have to be versioned first because A and C may alias.
|
||||
;
|
||||
; for (unsigned i = 0; i < 100; i++) {
|
||||
; A[i+1] = B[i] + 2;
|
||||
; C[i] = A[i] * 2;
|
||||
; }
|
||||
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
; CHECK-LABEL: @f(
|
||||
define void @f(i32* %A, i32* %B, i32* %C, i64 %N) optsize {
|
||||
|
||||
entry:
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body, %entry
|
||||
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
|
||||
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
||||
|
||||
%Aidx_next = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
|
||||
%Bidx = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
|
||||
%Cidx = getelementptr inbounds i32, i32* %C, i64 %indvars.iv
|
||||
%Aidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
|
||||
|
||||
%b = load i32, i32* %Bidx, align 4
|
||||
%a_p1 = add i32 %b, 2
|
||||
store i32 %a_p1, i32* %Aidx_next, align 4
|
||||
|
||||
%a = load i32, i32* %Aidx, align 4
|
||||
; CHECK: %c = mul i32 %a, 2
|
||||
%c = mul i32 %a, 2
|
||||
store i32 %c, i32* %Cidx, align 4
|
||||
|
||||
%exitcond = icmp eq i64 %indvars.iv.next, %N
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
for.end: ; preds = %for.body
|
||||
ret void
|
||||
}
|
||||
|
||||
; Same loop but with noalias on %A and %C. In this case load-eliminate even
|
||||
; with -Os.
|
||||
|
||||
; CHECK-LABEL: @g(
|
||||
define void @g(i32* noalias %A, i32* %B, i32* noalias %C, i64 %N) optsize {
|
||||
|
||||
entry:
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body, %entry
|
||||
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
|
||||
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
||||
|
||||
%Aidx_next = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
|
||||
%Bidx = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
|
||||
%Cidx = getelementptr inbounds i32, i32* %C, i64 %indvars.iv
|
||||
%Aidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
|
||||
|
||||
%b = load i32, i32* %Bidx, align 4
|
||||
%a_p1 = add i32 %b, 2
|
||||
store i32 %a_p1, i32* %Aidx_next, align 4
|
||||
|
||||
%a = load i32, i32* %Aidx, align 4
|
||||
; CHECK: %c = mul i32 %store_forwarded, 2
|
||||
%c = mul i32 %a, 2
|
||||
store i32 %c, i32* %Cidx, align 4
|
||||
|
||||
%exitcond = icmp eq i64 %indvars.iv.next, %N
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
for.end: ; preds = %for.body
|
||||
ret void
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
; RUN: opt -loop-load-elim -S < %s | \
|
||||
; RUN: FileCheck %s -check-prefix=ALL -check-prefix=ONE_STRIDE_SPEC \
|
||||
; RUN: -check-prefix=TWO_STRIDE_SPEC
|
||||
|
||||
; RUN: opt -loop-load-elim -S -enable-mem-access-versioning=0 < %s | \
|
||||
; RUN: FileCheck %s -check-prefix=ALL -check-prefix=NO_ONE_STRIDE_SPEC \
|
||||
; RUN: -check-prefix=NO_TWO_STRIDE_SPEC
|
||||
|
||||
; RUN: opt -loop-load-elim -S -loop-load-elimination-scev-check-threshold=1 < %s | \
|
||||
; RUN: FileCheck %s -check-prefix=ALL -check-prefix=ONE_STRIDE_SPEC \
|
||||
; RUN: -check-prefix=NO_TWO_STRIDE_SPEC
|
||||
|
||||
; Forwarding in the presence of symbolic strides:
|
||||
;
|
||||
; for (unsigned i = 0; i < 100; i++)
|
||||
; A[i + 1] = A[Stride * i] + B[i];
|
||||
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
; ALL-LABEL: @f(
|
||||
define void @f(i32* noalias nocapture %A, i32* noalias nocapture readonly %B, i64 %N,
|
||||
i64 %stride) {
|
||||
|
||||
; ONE_STRIDE_SPEC: %ident.check = icmp ne i64 %stride, 1
|
||||
|
||||
entry:
|
||||
; NO_ONE_STRIDE_SPEC-NOT: %load_initial = load i32, i32* %A
|
||||
; ONE_STRIDE_SPEC: %load_initial = load i32, i32* %A
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body, %entry
|
||||
; NO_ONE_STRIDE_SPEC-NOT: %store_forwarded = phi i32 [ %load_initial, {{.*}} ], [ %add, %for.body ]
|
||||
; ONE_STRIDE_SPEC: %store_forwarded = phi i32 [ %load_initial, {{.*}} ], [ %add, %for.body ]
|
||||
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
|
||||
%mul = mul i64 %indvars.iv, %stride
|
||||
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %mul
|
||||
%load = load i32, i32* %arrayidx, align 4
|
||||
%arrayidx2 = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
|
||||
%load_1 = load i32, i32* %arrayidx2, align 4
|
||||
; NO_ONE_STRIDE_SPEC-NOT: %add = add i32 %load_1, %store_forwarded
|
||||
; ONE_STRIDE_SPEC: %add = add i32 %load_1, %store_forwarded
|
||||
%add = add i32 %load_1, %load
|
||||
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
||||
%arrayidx_next = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
|
||||
store i32 %add, i32* %arrayidx_next, align 4
|
||||
%exitcond = icmp eq i64 %indvars.iv.next, %N
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
for.end: ; preds = %for.body
|
||||
ret void
|
||||
}
|
||||
|
||||
; With two symbolic strides:
|
||||
;
|
||||
; for (unsigned i = 0; i < 100; i++)
|
||||
; A[Stride2 * (i + 1)] = A[Stride1 * i] + B[i];
|
||||
|
||||
; ALL-LABEL: @two_strides(
|
||||
define void @two_strides(i32* noalias nocapture %A, i32* noalias nocapture readonly %B, i64 %N,
|
||||
i64 %stride.1, i64 %stride.2) {
|
||||
|
||||
; TWO_STRIDE_SPEC: %ident.check = icmp ne i64 %stride.2, 1
|
||||
; TWO_STRIDE_SPEC: %ident.check1 = icmp ne i64 %stride.1, 1
|
||||
; NO_TWO_STRIDE_SPEC-NOT: %ident.check{{.*}} = icmp ne i64 %stride{{.*}}, 1
|
||||
|
||||
entry:
|
||||
; NO_TWO_STRIDE_SPEC-NOT: %load_initial = load i32, i32* %A
|
||||
; TWO_STRIDE_SPEC: %load_initial = load i32, i32* %A
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body, %entry
|
||||
; NO_TWO_STRIDE_SPEC-NOT: %store_forwarded = phi i32 [ %load_initial, {{.*}} ], [ %add, %for.body ]
|
||||
; TWO_STRIDE_SPEC: %store_forwarded = phi i32 [ %load_initial, {{.*}} ], [ %add, %for.body ]
|
||||
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
|
||||
%mul = mul i64 %indvars.iv, %stride.1
|
||||
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %mul
|
||||
%load = load i32, i32* %arrayidx, align 4
|
||||
%arrayidx2 = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
|
||||
%load_1 = load i32, i32* %arrayidx2, align 4
|
||||
; NO_TWO_STRIDE_SPEC-NOT: %add = add i32 %load_1, %store_forwarded
|
||||
; TWO_STRIDE_SPEC: %add = add i32 %load_1, %store_forwarded
|
||||
%add = add i32 %load_1, %load
|
||||
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
||||
%mul.2 = mul i64 %indvars.iv.next, %stride.2
|
||||
%arrayidx_next = getelementptr inbounds i32, i32* %A, i64 %mul.2
|
||||
store i32 %add, i32* %arrayidx_next, align 4
|
||||
%exitcond = icmp eq i64 %indvars.iv.next, %N
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
for.end: ; preds = %for.body
|
||||
ret void
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
; RUN: opt -loop-load-elim -S < %s | FileCheck %s
|
||||
|
||||
; Don't crash if the store and the load use different types.
|
||||
;
|
||||
; for (unsigned i = 0; i < 100; i++) {
|
||||
; A[i+1] = B[i] + 2;
|
||||
; C[i] = ((float*)A)[i] * 2;
|
||||
; }
|
||||
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
; CHECK-LABEL: @f(
|
||||
define void @f(i32* noalias %A, i32* noalias %B, i32* noalias %C, i64 %N) {
|
||||
|
||||
entry:
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body, %entry
|
||||
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
|
||||
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
||||
|
||||
%Aidx_next = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
|
||||
%Bidx = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
|
||||
%Cidx = getelementptr inbounds i32, i32* %C, i64 %indvars.iv
|
||||
%Aidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
|
||||
%Aidx.float = bitcast i32* %Aidx to float*
|
||||
|
||||
%b = load i32, i32* %Bidx, align 4
|
||||
%a_p1 = add i32 %b, 2
|
||||
store i32 %a_p1, i32* %Aidx_next, align 4
|
||||
|
||||
; CHECK: %a = load float, float* %Aidx.float, align 4
|
||||
%a = load float, float* %Aidx.float, align 4
|
||||
; CHECK-NEXT: %c = fmul float %a, 2.0
|
||||
%c = fmul float %a, 2.0
|
||||
%c.int = fptosi float %c to i32
|
||||
store i32 %c.int, i32* %Cidx, align 4
|
||||
|
||||
%exitcond = icmp eq i64 %indvars.iv.next, %N
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
for.end: ; preds = %for.body
|
||||
ret void
|
||||
}
|
||||
|
||||
; Don't crash if the store and the load use different types.
|
||||
;
|
||||
; for (unsigned i = 0; i < 100; i++) {
|
||||
; A[i+1] = B[i] + 2;
|
||||
; A[i+1] = B[i] + 3;
|
||||
; C[i] = ((float*)A)[i] * 2;
|
||||
; }
|
||||
|
||||
; CHECK-LABEL: @f2(
|
||||
define void @f2(i32* noalias %A, i32* noalias %B, i32* noalias %C, i64 %N) {
|
||||
|
||||
entry:
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body, %entry
|
||||
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
|
||||
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
||||
|
||||
%Aidx_next = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
|
||||
%Bidx = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
|
||||
%Cidx = getelementptr inbounds i32, i32* %C, i64 %indvars.iv
|
||||
%Aidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
|
||||
%Aidx.float = bitcast i32* %Aidx to float*
|
||||
|
||||
%b = load i32, i32* %Bidx, align 4
|
||||
%a_p2 = add i32 %b, 2
|
||||
store i32 %a_p2, i32* %Aidx_next, align 4
|
||||
|
||||
%a_p3 = add i32 %b, 3
|
||||
store i32 %a_p3, i32* %Aidx_next, align 4
|
||||
|
||||
; CHECK: %a = load float, float* %Aidx.float, align 4
|
||||
%a = load float, float* %Aidx.float, align 4
|
||||
; CHECK-NEXT: %c = fmul float %a, 2.0
|
||||
%c = fmul float %a, 2.0
|
||||
%c.int = fptosi float %c to i32
|
||||
store i32 %c.int, i32* %Cidx, align 4
|
||||
|
||||
%exitcond = icmp eq i64 %indvars.iv.next, %N
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
for.end: ; preds = %for.body
|
||||
ret void
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
; RUN: opt -basicaa -loop-load-elim -S < %s | FileCheck %s
|
||||
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
; Give up in the presence of unknown deps. Here, the different strides result
|
||||
; in unknown dependence:
|
||||
;
|
||||
; for (unsigned i = 0; i < 100; i++) {
|
||||
; A[i+1] = B[i] + 2;
|
||||
; A[2*i] = C[i] + 2;
|
||||
; D[i] = A[i] + 2;
|
||||
; }
|
||||
|
||||
define void @f(i32* noalias %A, i32* noalias %B, i32* noalias %C,
|
||||
i32* noalias %D, i64 %N) {
|
||||
|
||||
entry:
|
||||
; for.body.ph:
|
||||
; CHECK-NOT: %load_initial =
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body, %entry
|
||||
; CHECK-NOT: %store_forwarded =
|
||||
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
|
||||
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
||||
|
||||
%Aidx_next = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
|
||||
%Bidx = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
|
||||
%Cidx = getelementptr inbounds i32, i32* %C, i64 %indvars.iv
|
||||
%Didx = getelementptr inbounds i32, i32* %D, i64 %indvars.iv
|
||||
%Aidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
|
||||
%indvars.m2 = mul nuw nsw i64 %indvars.iv, 2
|
||||
%A2idx = getelementptr inbounds i32, i32* %A, i64 %indvars.m2
|
||||
|
||||
%b = load i32, i32* %Bidx, align 4
|
||||
%a_p1 = add i32 %b, 2
|
||||
store i32 %a_p1, i32* %Aidx_next, align 4
|
||||
|
||||
%c = load i32, i32* %Cidx, align 4
|
||||
%a_m2 = add i32 %c, 2
|
||||
store i32 %a_m2, i32* %A2idx, align 4
|
||||
|
||||
%a = load i32, i32* %Aidx, align 4
|
||||
; CHECK-NOT: %d = add i32 %store_forwarded, 2
|
||||
; CHECK: %d = add i32 %a, 2
|
||||
%d = add i32 %a, 2
|
||||
store i32 %d, i32* %Didx, align 4
|
||||
|
||||
%exitcond = icmp eq i64 %indvars.iv.next, %N
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
for.end: ; preds = %for.body
|
||||
ret void
|
||||
}
|
Reference in New Issue
Block a user