Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@@ -0,0 +1,154 @@
; RUN: opt %loadPolly -polly-optree-normalize-phi=true -polly-optree -analyze < %s | FileCheck %s -match-full-lines
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define internal fastcc void @kernel_atax([2100 x double]* nocapture readonly %A, double* nocapture readonly %x, double* nocapture %y, double* nocapture %tmp) unnamed_addr #0 {
entry:
br label %entry.split
entry.split: ; preds = %entry
%y15 = bitcast double* %y to i8*
call void @llvm.memset.p0i8.i64(i8* %y15, i8 0, i64 16800, i32 8, i1 false)
br label %for.body3
for.body3: ; preds = %for.inc40, %entry.split
%indvars.iv8 = phi i64 [ 0, %entry.split ], [ %indvars.iv.next9, %for.inc40 ]
%arrayidx5 = getelementptr inbounds double, double* %tmp, i64 %indvars.iv8
store double 0.000000e+00, double* %arrayidx5, align 8, !tbaa !6
br label %for.body8
for.body8: ; preds = %for.body8, %for.body3
%0 = phi double [ 0.000000e+00, %for.body3 ], [ %add, %for.body8 ]
%indvars.iv = phi i64 [ 0, %for.body3 ], [ %indvars.iv.next, %for.body8 ]
%arrayidx14 = getelementptr inbounds [2100 x double], [2100 x double]* %A, i64 %indvars.iv8, i64 %indvars.iv
%1 = load double, double* %arrayidx14, align 8, !tbaa !6
%arrayidx16 = getelementptr inbounds double, double* %x, i64 %indvars.iv
%2 = load double, double* %arrayidx16, align 8, !tbaa !6
%mul = fmul double %1, %2
%add = fadd double %0, %mul
store double %add, double* %arrayidx5, align 8, !tbaa !6
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
%exitcond = icmp eq i64 %indvars.iv.next, 2
br i1 %exitcond, label %for.end21, label %for.body8
for.end21: ; preds = %for.body8
br label %for.body24
for.body24: ; preds = %for.body24.for.body24_crit_edge, %for.end21
%3 = phi double [ %add, %for.end21 ], [ %.pre, %for.body24.for.body24_crit_edge ]
%indvars.iv5 = phi i64 [ 0, %for.end21 ], [ %indvars.iv.next6, %for.body24.for.body24_crit_edge ]
%arrayidx26 = getelementptr inbounds double, double* %y, i64 %indvars.iv5
%4 = load double, double* %arrayidx26, align 8, !tbaa !6
%arrayidx30 = getelementptr inbounds [2100 x double], [2100 x double]* %A, i64 %indvars.iv8, i64 %indvars.iv5
%5 = load double, double* %arrayidx30, align 8, !tbaa !6
%mul33 = fmul double %5, %3
%add34 = fadd double %4, %mul33
store double %add34, double* %arrayidx26, align 8, !tbaa !6
%indvars.iv.next6 = add nuw nsw i64 %indvars.iv5, 1
%exitcond7 = icmp eq i64 %indvars.iv.next6, 2
br i1 %exitcond7, label %for.inc40, label %for.body24.for.body24_crit_edge
for.body24.for.body24_crit_edge: ; preds = %for.body24
%.pre = load double, double* %arrayidx5, align 8, !tbaa !6
br label %for.body24
for.inc40: ; preds = %for.body24
%indvars.iv.next9 = add nuw nsw i64 %indvars.iv8, 1
%exitcond10 = icmp eq i64 %indvars.iv.next9, 2
br i1 %exitcond10, label %for.end42, label %for.body3
for.end42: ; preds = %for.inc40
ret void
}
; Function Attrs: argmemonly nounwind
declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i32, i1) #1
attributes #0 = { noinline norecurse nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { argmemonly nounwind }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 6.0.0 (trunk 312565) (llvm/trunk 312564)"}
!2 = !{!3, !3, i64 0}
!3 = !{!"any pointer", !4, i64 0}
!4 = !{!"omnipotent char", !5, i64 0}
!5 = !{!"Simple C/C++ TBAA"}
!6 = !{!7, !7, i64 0}
!7 = !{!"double", !4, i64 0}
; CHECK: Statistics {
; CHECK: Operand trees forwarded: 2
; CHECK: Statements with forwarded operand trees: 2
; CHECK: }
; CHECK-NEXT: After statements {
; CHECK-NEXT: Stmt_for_body3
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_for_body3[i0] -> MemRef_tmp[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: { Stmt_for_body3[i0] -> MemRef1__phi[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: store double 0.000000e+00, double* %arrayidx5, align 8, !tbaa !2
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_for_body8
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: { Stmt_for_body8[i0, i1] -> MemRef1__phi[] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: { Stmt_for_body8[i0, i1] -> MemRef1__phi[] };
; CHECK-NEXT: new: { Stmt_for_body8[i0, i1] -> MemRef_tmp[i0] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_for_body8[i0, i1] -> MemRef_A[i0, i1] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_for_body8[i0, i1] -> MemRef_x[i1] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_for_body8[i0, i1] -> MemRef_tmp[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: { Stmt_for_body8[i0, i1] -> MemRef_add[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %0 = phi double [ 0.000000e+00, %for.body3 ], [ %add, %for.body8 ]
; CHECK-NEXT: %1 = load double, double* %arrayidx14, align 8, !tbaa !2
; CHECK-NEXT: %2 = load double, double* %arrayidx16, align 8, !tbaa !2
; CHECK-NEXT: %mul = fmul double %1, %2
; CHECK-NEXT: %add = fadd double %0, %mul
; CHECK-NEXT: store double %add, double* %arrayidx5, align 8, !tbaa !2
; CHECK-NEXT: %exitcond = icmp eq i64 %indvars.iv.next, 2
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_for_end21
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: { Stmt_for_end21[i0] -> MemRef_add[] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: { Stmt_for_end21[i0] -> MemRef5__phi[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_for_body24
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: { Stmt_for_body24[i0, i1] -> MemRef5__phi[] };
; CHECK-NEXT: new: { Stmt_for_body24[i0, i1] -> MemRef_tmp[i0] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_for_body24[i0, i1] -> MemRef_y[i1] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_for_body24[i0, i1] -> MemRef_A[i0, i1] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_for_body24[i0, i1] -> MemRef_y[i1] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %3 = phi double [ %add, %for.end21 ], [ %.pre, %for.body24.for.body24_crit_edge ]
; CHECK-NEXT: %4 = load double, double* %arrayidx26, align 8, !tbaa !2
; CHECK-NEXT: %5 = load double, double* %arrayidx30, align 8, !tbaa !2
; CHECK-NEXT: %mul33 = fmul double %5, %3
; CHECK-NEXT: %add34 = fadd double %4, %mul33
; CHECK-NEXT: store double %add34, double* %arrayidx26, align 8, !tbaa !2
; CHECK-NEXT: %exitcond7 = icmp eq i64 %indvars.iv.next6, 2
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_for_body24_for_body24_crit_edge
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: { Stmt_for_body24_for_body24_crit_edge[i0, i1] -> MemRef5__phi[] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_for_body24_for_body24_crit_edge[i0, i1] -> MemRef_tmp[i0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %.pre = load double, double* %arrayidx5, align 8, !tbaa !2
; CHECK-NEXT: }
; CHECK-NEXT: }

View File

@@ -0,0 +1,78 @@
; RUN: opt %loadPolly -polly-optree -analyze < %s | FileCheck %s -match-full-lines
;
; Move instructions from region statements.
;
; for (int j = 0; j < n; j += 1) {
; bodyA:
; double val = 21.0 + 21.0;
; if (cond)
;
; bodyA_true:
; A[0] = 42;
;
; bodyB:
; A[0] = val;
; }
;
define void @func(i32 %n, double* noalias nonnull %A) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
%val = fadd double 21.0, 21.0
%cond = fcmp oeq double 21.0, 21.0
br i1 %cond, label %bodyA_true, label %bodyB
bodyA_true:
store double 42.0, double* %A
br label %bodyB
bodyB:
store double %val, double* %A
br label %bodyB_exit
bodyB_exit:
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; CHECK: Statistics {
; CHECK: Instructions copied: 1
; CHECK: Known loads forwarded: 0
; CHECK: Read-only accesses copied: 0
; CHECK: Operand trees forwarded: 1
; CHECK: Statements with forwarded operand trees: 1
; CHECK: }
; CHECK: After statements {
; CHECK: Stmt_bodyA__TO__bodyB
; CHECK: MayWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK: [n] -> { Stmt_bodyA__TO__bodyB[i0] -> MemRef_A[0] };
; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK: [n] -> { Stmt_bodyA__TO__bodyB[i0] -> MemRef_val[] };
; CHECK: Instructions {
; CHECK: %val = fadd double 2.100000e+01, 2.100000e+01
; CHECK: %cond = fcmp oeq double 2.100000e+01, 2.100000e+01
; CHECK: }
; CHECK: Stmt_bodyB
; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK: [n] -> { Stmt_bodyB[i0] -> MemRef_A[0] };
; CHECK: Instructions {
; CHECK: %val = fadd double 2.100000e+01, 2.100000e+01
; CHECK: store double %val, double* %A
; CHECK: }
; CHECK: }

View File

@@ -0,0 +1,65 @@
; RUN: opt %loadPolly -polly-invariant-load-hoisting=true -polly-optree -analyze < %s | FileCheck %s -match-full-lines
;
; Move %val to %bodyB, so %bodyA can be removed (by -polly-simplify).
; This involves making the load-hoisted %val1 to be made available in %bodyB.
;
; for (int j = 0; j < n; j += 1) {
; bodyA:
; double val = B[0] + 21.0;
;
; bodyB:
; A[0] = val;
; }
;
define void @func(i32 %n, double* noalias nonnull %A, double* noalias nonnull %B) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
%val1 = load double, double* %B
%val2 = fadd double %val1, 21.0
br label %bodyB
bodyB:
store double %val2, double* %A
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; CHECK: Statistics {
; CHECK: Instructions copied: 1
; CHECK: Operand trees forwarded: 1
; CHECK: Statements with forwarded operand trees: 1
; CHECK: }
; CHECK: After statements {
; CHECK-NEXT: Stmt_bodyA
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_val2[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val1 = load double, double* %B
; CHECK-NEXT: %val2 = fadd double %val1, 2.100000e+01
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_bodyB
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_A[0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val2 = fadd double %val1, 2.100000e+01
; CHECK-NEXT: store double %val2, double* %A
; CHECK-NEXT: }
; CHECK-NEXT: }

View File

@@ -0,0 +1,62 @@
; RUN: opt %loadPolly -polly-optree -analyze < %s | FileCheck %s -match-full-lines
;
; Move %val to %bodyB, so %bodyA can be removed (by -polly-simplify)
;
; for (int j = 0; j < n; j += 1) {
; bodyA:
; double val = 21.0 + 21.0;
;
; bodyB:
; A[0] = val;
; }
;
define void @func(i32 %n, double* noalias nonnull %A) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
%val = fadd double 21.0, 21.0
br label %bodyB
bodyB:
store double %val, double* %A
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; CHECK: Statistics {
; CHECK: Instructions copied: 1
; CHECK: Operand trees forwarded: 1
; CHECK: Statements with forwarded operand trees: 1
; CHECK: }
; CHECK: After statements {
; CHECK-NEXT: Stmt_bodyA
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_val[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = fadd double 2.100000e+01, 2.100000e+01
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_bodyB
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_A[0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = fadd double 2.100000e+01, 2.100000e+01
; CHECK-NEXT: store double %val, double* %A
; CHECK-NEXT: }
; CHECK-NEXT: }

View File

@@ -0,0 +1,72 @@
; RUN: opt %loadPolly -polly-optree -analyze < %s | FileCheck %s -match-full-lines
;
; Move instructions to region statements.
;
; for (int j = 0; j < n; j += 1) {
; bodyA:
; double val = 21.0 + 21.0;
;
; bodyB:
; if (cond)
; body_true:
; A[0] = val;
; }
;
define void @func(i32 %n, double* noalias nonnull %A) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
%val = fadd double 21.0, 21.0
br label %bodyB
bodyB:
%cond = fcmp oeq double 21.0, 21.0
br i1 %cond, label %bodyB_true, label %bodyB_exit
bodyB_true:
store double %val, double* %A
br label %bodyB_exit
bodyB_exit:
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; CHECK: Statistics {
; CHECK: Instructions copied: 1
; CHECK: Known loads forwarded: 0
; CHECK: Read-only accesses copied: 0
; CHECK: Operand trees forwarded: 1
; CHECK: Statements with forwarded operand trees: 1
; CHECK: }
; CHECK: After statements {
; CHECK-NEXT: Stmt_bodyA
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_val[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = fadd double 2.100000e+01, 2.100000e+01
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_bodyB__TO__bodyB_exit
; CHECK-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB__TO__bodyB_exit[i0] -> MemRef_A[0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = fadd double 2.100000e+01, 2.100000e+01
; CHECK-NEXT: %cond = fcmp oeq double 2.100000e+01, 2.100000e+01
; CHECK-NEXT: }
; CHECK-NEXT: }

View File

@@ -0,0 +1,57 @@
; RUN: opt %loadPolly -polly-invariant-load-hoisting=true -polly-optree -analyze < %s | FileCheck %s -match-full-lines
;
define void @foo(float* %A, i32 %p, float* %B) {
start:
br label %branch
branch:
%cmp = icmp eq i32 %p, 1024
br i1 %cmp, label %next, label %end
next:
%val = load float, float* %A
%fcmp = fcmp oeq float %val, 41.0
br label %nonaffine
nonaffine:
br i1 %fcmp, label %a, label %b
a:
store float %val, float* %A
br label %end
b:
store float 1.0, float* %A
br label %end
end:
ret void
}
; CHECK: After statements {
; CHECK-NEXT: Stmt_next
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [p] -> { Stmt_next[] -> MemRef_A[0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [p] -> { Stmt_next[] -> MemRef_fcmp[] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [p] -> { Stmt_next[] -> MemRef_val[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = load float, float* %A
; CHECK-NEXT: %fcmp = fcmp oeq float %val, 4.100000e+01
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_nonaffine__TO__end
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: ;
; CHECK-NEXT: new: [p] -> { Stmt_nonaffine__TO__end[] -> MemRef_A[0] };
; CHECK-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [p] -> { Stmt_nonaffine__TO__end[] -> MemRef_A[0] };
; CHECK-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [p] -> { Stmt_nonaffine__TO__end[] -> MemRef_A[0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = load float, float* %A
; CHECK-NEXT: %val = load float, float* %A
; CHECK-NEXT: %fcmp = fcmp oeq float %val, 4.100000e+01
; CHECK-NEXT: }
; CHECK-NEXT: }

View File

@@ -0,0 +1,59 @@
; RUN: opt %loadPolly -polly-optree -analyze < %s | FileCheck %s -match-full-lines
;
; Rematerialize a load.
;
; for (int j = 0; j < n; j += 1) {
; bodyA:
; double val = B[j];
;
; bodyB:
; A[j] = val;
; }
;
define void @func(i32 %n, double* noalias nonnull %A, double* noalias nonnull %B) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
%B_idx = getelementptr inbounds double, double* %B, i32 %j
%val = load double, double* %B_idx
br label %bodyB
bodyB:
%A_idx = getelementptr inbounds double, double* %A, i32 %j
store double %val, double* %A_idx
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; CHECK: Statistics {
; CHECK: Known loads forwarded: 1
; CHECK: Operand trees forwarded: 1
; CHECK: Statements with forwarded operand trees: 1
; CHECK: }
; CHECK: Stmt_bodyB
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: ;
; CHECK-NEXT: new: [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_A[i0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = load double, double* %B_idx
; CHECK-NEXT: store double %val, double* %A_idx
; CHECK-NEXT: }

View File

@@ -0,0 +1,93 @@
; RUN: opt %loadPolly -polly-optree -analyze < %s | FileCheck %s -match-full-lines
;
; To forward %val, B[j] cannot be reused in bodyC because it is overwritten
; between. Verify that instead the alternative C[j] is used.
;
; for (int j = 0; j < n; j += 1) {
; bodyA:
; double val = B[j];
;
; bodyB:
; B[j] = 0;
; C[j] = val;
;
; bodyC:
; A[j] = val;
; }
;
define void @func(i32 %n, double* noalias nonnull %A, double* noalias nonnull %B, double* noalias nonnull %C) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
%B_idx = getelementptr inbounds double, double* %B, i32 %j
%val = load double, double* %B_idx
br label %bodyB
bodyB:
store double 0.0, double* %B_idx
%C_idx = getelementptr inbounds double, double* %C, i32 %j
store double %val, double* %C_idx
br label %bodyC
bodyC:
%A_idx = getelementptr inbounds double, double* %A, i32 %j
store double %val, double* %A_idx
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; CHECK: Statistics {
; CHECK: Known loads forwarded: 2
; CHECK: Operand trees forwarded: 2
; CHECK: Statements with forwarded operand trees: 2
; CHECK: }
; CHECK-NEXT: After statements {
; CHECK-NEXT: Stmt_bodyA
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_B[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_val[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = load double, double* %B_idx
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_bodyB
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: ;
; CHECK-NEXT: new: [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_C[i0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = load double, double* %B_idx
; CHECK-NEXT: store double 0.000000e+00, double* %B_idx
; CHECK-NEXT: store double %val, double* %C_idx
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_bodyC
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: ;
; CHECK-NEXT: new: [n] -> { Stmt_bodyC[i0] -> MemRef_C[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyC[i0] -> MemRef_A[i0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = load double, double* %B_idx
; CHECK-NEXT: store double %val, double* %A_idx
; CHECK-NEXT: }
; CHECK-NEXT: }

View File

@@ -0,0 +1,56 @@
; RUN: opt %loadPolly -polly-optree -analyze < %s | FileCheck %s -match-full-lines
;
; Rematerialize a load even in case two writes of identical values are in
; one scop statement.
;
define void @func(i32 %n, double* noalias nonnull %A, double* noalias nonnull %B) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
%B_idx = getelementptr inbounds double, double* %B, i32 %j
%val = load double, double* %B_idx
br label %bodyB
bodyB:
%A_idx = getelementptr inbounds double, double* %A, i32 %j
store double %val, double* %A_idx
store double %val, double* %A_idx
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; CHECK: Statistics {
; CHECK: Known loads forwarded: 1
; CHECK: Operand trees forwarded: 1
; CHECK: Statements with forwarded operand trees: 1
; CHECK: }
; CHECK: Stmt_bodyB
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: ;
; CHECK-NEXT: new: [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_A[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_A[i0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = load double, double* %B_idx
; CHECK-NEXT: store double %val, double* %A_idx
; CHECK-NEXT: store double %val, double* %A_idx
; CHECK-NEXT: }

View File

@@ -0,0 +1,77 @@
; RUN: opt %loadPolly -polly-optree -analyze < %s | FileCheck %s -match-full-lines
;
; Forward a the LoadInst %val into %bodyB. %val is executed multiple times,
; we must get the last loaded values.
;
; for (int j = 0; j < n; j += 1) {
; double val;
; for (int i = 0; i < n; i += 1) {
; bodyA:
; val = B[j];
; }
;
; bodyB:
; A[j] = val;
; }
;
define void @func(i32 %n, double* noalias nonnull %A, double* noalias nonnull %B) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp sle i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
%i = phi i32 [0, %for], [%i.inc, %bodyA]
%B_idx = getelementptr inbounds double, double* %B, i32 %i
%val = load double, double* %B_idx
%i.inc = add nuw nsw i32 %i, 1
%i.cmp = icmp slt i32 %i, %n
br i1 %i.cmp, label %bodyA, label %bodyB
bodyB:
%A_idx = getelementptr inbounds double, double* %A, i32 %j
store double %val, double* %A_idx
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; CHECK: Statistics {
; CHECK: Known loads forwarded: 1
; CHECK: Operand trees forwarded: 1
; CHECK: Statements with forwarded operand trees: 1
; CHECK: }
; CHECK: After statements {
; CHECK-NEXT: Stmt_bodyA
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0, i1] -> MemRef_B[i1] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0, i1] -> MemRef_val[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = load double, double* %B_idx
; CHECK-NEXT: %i.cmp = icmp slt i32 %i, %n
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_bodyB
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: ;
; CHECK-NEXT: new: [n] -> { Stmt_bodyB[i0] -> MemRef_B[n] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_A[i0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = load double, double* %B_idx
; CHECK-NEXT: store double %val, double* %A_idx
; CHECK-NEXT: }
; CHECK-NEXT: }

View File

@@ -0,0 +1,75 @@
; RUN: opt %loadPolly -polly-optree -analyze < %s | FileCheck %s -match-full-lines
;
; Forward an operand tree consisting of a speculatable instruction (%add)
; and a load (%val).
;
; for (int j = 0; j < n; j += 1) {
; bodyA:
; double val = B[j];
; double add = val + 42.0;
;
; bodyB:
; A[j] = add;
; }
;
define void @func(i32 %n, double* noalias nonnull %A, double* noalias nonnull %B) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
%B_idx = getelementptr inbounds double, double* %B, i32 %j
%val = load double, double* %B_idx
%add = fadd double %val, 42.0
br label %bodyB
bodyB:
%A_idx = getelementptr inbounds double, double* %A, i32 %j
store double %add, double* %A_idx
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; CHECK: Statistics {
; CHECK: Instructions copied: 1
; CHECK: Known loads forwarded: 1
; CHECK: Operand trees forwarded: 1
; CHECK: Statements with forwarded operand trees: 1
; CHECK: }
; CHECK: After statements {
; CHECK-NEXT: Stmt_bodyA
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_B[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_add[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = load double, double* %B_idx
; CHECK-NEXT: %add = fadd double %val, 4.200000e+01
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_bodyB
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: ;
; CHECK-NEXT: new: [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_A[i0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = load double, double* %B_idx
; CHECK-NEXT: %add = fadd double %val, 4.200000e+01
; CHECK-NEXT: store double %add, double* %A_idx
; CHECK-NEXT: }
; CHECK-NEXT: }

View File

@@ -0,0 +1,60 @@
; RUN: opt %loadPolly -polly-optree -analyze < %s | FileCheck %s -match-full-lines
;
; Rematerialize a load in the presence of a non-store WRITE access.
;
; for (int j = 0; j < n; j += 1) {
; bodyA:
; double val = B[j];
;
; bodyB:
; A[j] = val;
;
; bodyC:
; memset(A, 0, 16);
; memset(B, 0, 16);
; }
;
declare void @llvm.memset.p0f64.i64(double* nocapture, i8, i64, i32, i1)
define void @func(i32 %n, double* noalias nonnull %A, double* noalias nonnull %B) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
%B_idx = getelementptr inbounds double, double* %B, i32 %j
%val = load double, double* %B_idx
br label %bodyB
bodyB:
%A_idx = getelementptr inbounds double, double* %A, i32 %j
store double %val, double* %A_idx
br label %bodyC
bodyC:
call void @llvm.memset.p0f64.i64(double* %A, i8 0, i64 16, i32 1, i1 false)
call void @llvm.memset.p0f64.i64(double* %B, i8 0, i64 16, i32 1, i1 false)
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; CHECK: Statistics {
; CHECK: Known loads forwarded: 1
; CHECK: Operand trees forwarded: 1
; CHECK: Statements with forwarded operand trees: 1
; CHECK: }

View File

@@ -0,0 +1,81 @@
; RUN: opt %loadPolly -polly-optree -analyze < %s | FileCheck %s -match-full-lines
;
; Rematerialize a load in the presence of a non-store WRITE access.
;
; for (int j = 0; j < n; j += 1) {
; bodyA:
; memset(A, 0, 16);
; memset(B, 0, 16);
;
; bodyB:
; double val = B[j];
;
; bodyC:
; A[j] = val;
; }
;
declare void @llvm.memset.p0f64.i64(double* nocapture, i8, i64, i32, i1)
define void @func(i32 %n, double* noalias nonnull %A, double* noalias nonnull %B) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
call void @llvm.memset.p0f64.i64(double* %A, i8 0, i64 16, i32 1, i1 false)
call void @llvm.memset.p0f64.i64(double* %B, i8 0, i64 16, i32 1, i1 false)
br label %bodyB
bodyB:
%B_idx = getelementptr inbounds double, double* %B, i32 %j
%val = load double, double* %B_idx
br label %bodyC
bodyC:
%A_idx = getelementptr inbounds double, double* %A, i32 %j
store double %val, double* %A_idx
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; CHECK: Statistics {
; CHECK: Known loads forwarded: 1
; CHECK: Operand trees forwarded: 1
; CHECK: Statements with forwarded operand trees: 1
; CHECK: }
; CHECK-NEXT: After statements {
; CHECK: Stmt_bodyB
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_B[o0] : 8i0 <= o0 <= 7 + 8i0 };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_val[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = load double, double* %B_idx
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_bodyC
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: ;
; CHECK-NEXT: new: [n] -> { Stmt_bodyC[i0] -> MemRef_B[8i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyC[i0] -> MemRef_A[o0] : 8i0 <= o0 <= 7 + 8i0 };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = load double, double* %B_idx
; CHECK-NEXT: store double %val, double* %A_idx
; CHECK-NEXT: }
; CHECK-NEXT: }

View File

@@ -0,0 +1,161 @@
; RUN: opt %loadPolly -polly-optree -polly-codegen -analyze < %s | FileCheck %s -match-full-lines
;
; %val1 is used three times: Twice by its own operand tree of %val2 and once
; more by the store in %bodyB.
; Verify that we can handle multiple uses by the same instruction and uses
; in multiple statements as well.
; The result processing may depend on the order in which the values are used,
; hence we check both orderings.
;
; for (int j = 0; j < n; j += 1) {
; bodyA:
; double val1 = A[j];
; double val2 = val1 + val1;
;
; bodyB:
; B[j] = val1;
; C[j] = val2;
; }
;
define void @func1(i32 %n, double* noalias nonnull %A, double* noalias nonnull %B, double* noalias nonnull %C) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
%A_idx = getelementptr inbounds double, double* %A, i32 %j
%val1 = load double, double* %A_idx
%val2 = fadd double %val1, %val1
br label %bodyB
bodyB:
%B_idx = getelementptr inbounds double, double* %B, i32 %j
store double %val1, double* %B_idx
%C_idx = getelementptr inbounds double, double* %C, i32 %j
store double %val2, double* %C_idx
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; CHECK: Statistics {
; CHECK: Instructions copied: 1
; CHECK: Known loads forwarded: 3
; CHECK: Operand trees forwarded: 2
; CHECK: Statements with forwarded operand trees: 1
; CHECK: }
; CHECK: After statements {
; CHECK-NEXT: Stmt_bodyA
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_A[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_val1[] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_val2[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val1 = load double, double* %A_idx
; CHECK-NEXT: %val2 = fadd double %val1, %val1
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_bodyB
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: ;
; CHECK-NEXT: new: [n] -> { Stmt_bodyB[i0] -> MemRef_A[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_C[i0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val1 = load double, double* %A_idx
; CHECK-NEXT: %val1 = load double, double* %A_idx
; CHECK-NEXT: %val2 = fadd double %val1, %val1
; CHECK-NEXT: %val1 = load double, double* %A_idx
; CHECK-NEXT: store double %val1, double* %B_idx
; CHECK-NEXT: store double %val2, double* %C_idx
; CHECK-NEXT: }
; CHECK-NEXT: }
define void @func2(i32 %n, double* noalias nonnull %A, double* noalias nonnull %B, double* noalias nonnull %C) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
%A_idx = getelementptr inbounds double, double* %A, i32 %j
%val1 = load double, double* %A_idx
%val2 = fadd double %val1, %val1
br label %bodyB
bodyB:
%B_idx = getelementptr inbounds double, double* %B, i32 %j
store double %val2, double* %B_idx
%C_idx = getelementptr inbounds double, double* %C, i32 %j
store double %val1, double* %C_idx
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; CHECK: Statistics {
; CHECK: Instructions copied: 1
; CHECK: Known loads forwarded: 3
; CHECK: Operand trees forwarded: 2
; CHECK: Statements with forwarded operand trees: 1
; CHECK: }
; CHECK: After statements {
; CHECK-NEXT: Stmt_bodyA
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_A[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_val2[] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_val1[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val1 = load double, double* %A_idx
; CHECK-NEXT: %val2 = fadd double %val1, %val1
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_bodyB
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: ;
; CHECK-NEXT: new: [n] -> { Stmt_bodyB[i0] -> MemRef_A[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_C[i0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val1 = load double, double* %A_idx
; CHECK-NEXT: %val1 = load double, double* %A_idx
; CHECK-NEXT: %val1 = load double, double* %A_idx
; CHECK-NEXT: %val2 = fadd double %val1, %val1
; CHECK-NEXT: store double %val2, double* %B_idx
; CHECK-NEXT: store double %val1, double* %C_idx
; CHECK-NEXT: }
; CHECK-NEXT: }

View File

@@ -0,0 +1,64 @@
; RUN: opt %loadPolly -polly-optree -analyze < %s | FileCheck %s -match-full-lines
;
; Rematerialize a load.
; The non-analyzable store to C[0] is unrelated and can be ignored.
;
; for (int j = 0; j < n; j += 1) {
; bodyA:
; double val = B[j];
; C[0] = 21.0;
; C[0] = 42.0;
;
; bodyB:
; A[j] = val;
; }
;
define void @func(i32 %n, double* noalias nonnull %A, double* noalias nonnull %B, double *noalias %C) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
%B_idx = getelementptr inbounds double, double* %B, i32 %j
%val = load double, double* %B_idx
store double 21.0, double* %C
store double 41.0, double* %C
br label %bodyB
bodyB:
%A_idx = getelementptr inbounds double, double* %A, i32 %j
store double %val, double* %A_idx
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; CHECK: Statistics {
; CHECK: Known loads forwarded: 1
; CHECK: Operand trees forwarded: 1
; CHECK: Statements with forwarded operand trees: 1
; CHECK: }
; CHECK: Stmt_bodyB
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: ;
; CHECK-NEXT: new: [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_A[i0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = load double, double* %B_idx
; CHECK-NEXT: store double %val, double* %A_idx
; CHECK-NEXT: }

View File

@@ -0,0 +1,82 @@
; RUN: opt %loadPolly -polly-optree-normalize-phi=true -polly-optree -analyze < %s | FileCheck %s -match-full-lines
;
; Rematerialize a load.
;
; for (int j = 0; j < n; j += 1) {
; bodyA:
; double val = B[j];
;
; bodyB:
; double phi = val;
;
; bodyC:
; A[j] = phi;
; }
;
define void @func(i32 %n, double* noalias nonnull %A, double* noalias nonnull %B) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
%B_idx = getelementptr inbounds double, double* %B, i32 %j
%val = load double, double* %B_idx
br label %bodyB
bodyB:
%phi = phi double [%val, %bodyA]
br label %bodyC
bodyC:
%A_idx = getelementptr inbounds double, double* %A, i32 %j
store double %phi, double* %A_idx
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; CHECK: Statistics {
; CHECK: Reloads: 2
; CHECK: }
; CHECK-NEXT: After statements {
; CHECK-NEXT: Stmt_bodyA
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_B[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_phi__phi[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = load double, double* %B_idx
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_bodyB
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_phi__phi[] };
; CHECK-NEXT: new: [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_phi[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %phi = phi double [ %val, %bodyA ]
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_bodyC
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyC[i0] -> MemRef_A[i0] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyC[i0] -> MemRef_phi[] };
; CHECK-NEXT: new: [n] -> { Stmt_bodyC[i0] -> MemRef_B[i0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: store double %phi, double* %A_idx
; CHECK-NEXT: }
; CHECK-NEXT: }

View File

@@ -0,0 +1,84 @@
; RUN: opt %loadPolly -polly-analyze-read-only-scalars=true -polly-optree -analyze < %s | FileCheck %s -match-full-lines -check-prefixes=STATS,MODEL
; RUN: opt %loadPolly -polly-analyze-read-only-scalars=false -polly-optree -analyze < %s | FileCheck %s -match-full-lines -check-prefixes=STATS,NOMODEL
;
; Move %val to %bodyB, so %bodyA can be removed (by -polly-simplify)
;
; for (int j = 0; j < n; j += 1) {
; bodyA:
; double val = arg + 21.0;
;
; bodyB:
; A[0] = val;
; }
;
define void @func(i32 %n, double* noalias nonnull %A, double %arg) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
%val = fadd double %arg, 21.0
br label %bodyB
bodyB:
store double %val, double* %A
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; STATS: Statistics {
; STATS: Instructions copied: 1
; STATS: Read-only accesses copied: 1
; STATS: Operand trees forwarded: 1
; STATS: Statements with forwarded operand trees: 1
; STATS: }
; MODEL: After statements {
; MODEL-NEXT: Stmt_bodyA
; MODEL-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
; MODEL-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_arg[] };
; MODEL-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; MODEL-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_val[] };
; MODEL-NEXT: Instructions {
; MODEL-NEXT: %val = fadd double %arg, 2.100000e+01
; MODEL-NEXT: }
; MODEL-NEXT: Stmt_bodyB
; MODEL-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; MODEL-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_A[0] };
; MODEL-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
; MODEL-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_arg[] };
; MODEL-NEXT: Instructions {
; MODEL-NEXT: %val = fadd double %arg, 2.100000e+01
; MODEL-NEXT: store double %val, double* %A
; MODEL-NEXT: }
; MODEL-NEXT: }
; NOMODEL: After statements {
; NOMODEL-NEXT: Stmt_bodyA
; NOMODEL-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; NOMODEL-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_val[] };
; NOMODEL-NEXT: Instructions {
; NOMODEL-NEXT: %val = fadd double %arg, 2.100000e+01
; NOMODEL-NEXT: }
; NOMODEL-NEXT: Stmt_bodyB
; NOMODEL-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; NOMODEL-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_A[0] };
; NOMODEL-NEXT: Instructions {
; NOMODEL-NEXT: %val = fadd double %arg, 2.100000e+01
; NOMODEL-NEXT: store double %val, double* %A
; NOMODEL-NEXT: }
; NOMODEL-NEXT: }

View File

@@ -0,0 +1,73 @@
; RUN: opt %loadPolly -polly-optree -analyze < %s | FileCheck %s -match-full-lines
;
; Rematerialize a load.
;
; for (int j = 0; j < n; j += 1) {
; bodyA:
; double val = B[j];
;
; bodyB:
; A[j] = val;
; }
;
declare double @f() #0
define void @func(i32 %n, double* noalias nonnull %A, double* noalias nonnull %B) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
%val = call double @f()
%A_idx = getelementptr inbounds double, double* %A, i32 %j
store double %val, double* %A_idx
br label %bodyB
bodyB:
%B_idx = getelementptr inbounds double, double* %B, i32 %j
store double %val, double* %B_idx
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
attributes #0 = { nounwind readnone }
; CHECK: Statistics {
; CHECK: Reloads: 1
; CHECK: }
; CHECK: After statements {
; CHECK-NEXT: Stmt_bodyA
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_A[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_val[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = call double @f()
; CHECK-NEXT: store double %val, double* %A_idx
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_bodyB
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_val[] };
; CHECK-NEXT: new: [n] -> { Stmt_bodyB[i0] -> MemRef_A[i0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: store double %val, double* %B_idx
; CHECK-NEXT: }
; CHECK-NEXT: }

View File

@@ -0,0 +1,80 @@
; RUN: opt %loadPolly -polly-optree -analyze < %s | FileCheck %s -match-full-lines
;
; Copy %val to bodyB, assuming the exit value of %i.
;
; for (int j = 0; j < n; j += 1) {
; double val;
; for (int i = 0; i < 128; i += 1) {
; bodyA:
; val = j;
; }
;
; bodyB:
; A[0] = val;
; }
;
define void @func(i32 %n, double* noalias nonnull %A) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %inner.for, label %exit
inner.for:
%i = phi i32 [0, %for], [%i.inc, %inner.inc]
br label %bodyA
bodyA:
%val = sitofp i32 %i to double
br label %inner.inc
inner.inc:
%i.inc = add nuw nsw i32 %i, 1
%i.cmp = icmp slt i32 %i.inc, 128
br i1 %i.cmp, label %inner.for, label %inner.exit
inner.exit:
br label %bodyB
bodyB:
store double %val, double* %A
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; CHECK: Statistics {
; CHECK: Instructions copied: 1
; CHECK: Operand trees forwarded: 1
; CHECK: Statements with forwarded operand trees: 1
; CHECK: }
; CHECK: After statements {
; CHECK-NEXT: Stmt_bodyA
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0, i1] -> MemRef_val[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = sitofp i32 %i to double
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_bodyB
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_A[0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = sitofp i32 %i to double
; CHECK-NEXT: store double %val, double* %A
; CHECK-NEXT: }
; CHECK-NEXT: }

View File

@@ -0,0 +1,62 @@
; RUN: opt %loadPolly -polly-optree -analyze < %s | FileCheck %s -match-full-lines
;
; Test support for (synthesizable) inducation variables.
;
; for (int j = 0; j < n; j += 1) {
; bodyA:
; double val = j;
;
; bodyB:
; A[0] = val;
; }
;
define void @func(i32 %n, double* noalias nonnull %A) {
entry:
br label %for
for:
%j = phi i32 [0, %entry], [%j.inc, %inc]
%j.cmp = icmp slt i32 %j, %n
br i1 %j.cmp, label %bodyA, label %exit
bodyA:
%val = sitofp i32 %j to double
br label %bodyB
bodyB:
store double %val, double* %A
br label %inc
inc:
%j.inc = add nuw nsw i32 %j, 1
br label %for
exit:
br label %return
return:
ret void
}
; CHECK: Statistics {
; CHECK: Instructions copied: 1
; CHECK: Operand trees forwarded: 1
; CHECK: Statements with forwarded operand trees: 1
; CHECK: }
; CHECK: After statements {
; CHECK-NEXT: Stmt_bodyA
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [n] -> { Stmt_bodyA[i0] -> MemRef_val[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = sitofp i32 %j to double
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_bodyB
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_A[0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %val = sitofp i32 %j to double
; CHECK-NEXT: store double %val, double* %A
; CHECK-NEXT: }
; CHECK-NEXT: }

Some files were not shown because too many files have changed in this diff Show More