forked from OSchip/llvm-project
Add more test cases to check loop invariance of the base pointer.
llvm-svn: 200305
This commit is contained in:
parent
7c9621c0be
commit
5b5daab9f1
|
@ -0,0 +1,236 @@
|
|||
; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
|
||||
; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
|
||||
|
||||
|
||||
target 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"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
define void @base_pointer_in_condition(i64** noalias %A_ptr, i64 %N) nounwind {
|
||||
entry:
|
||||
fence seq_cst
|
||||
br label %pre
|
||||
|
||||
pre:
|
||||
%A = load i64** %A_ptr
|
||||
br i1 true, label %for.i, label %then
|
||||
|
||||
for.i:
|
||||
%indvar = phi i64 [ 0, %pre ], [ %indvar.next, %for.i ]
|
||||
%scevgep = getelementptr i64* %A, i64 %indvar
|
||||
store i64 %indvar, i64* %scevgep
|
||||
%indvar.next = add nsw i64 %indvar, 1
|
||||
%exitcond = icmp eq i64 %indvar.next, %N
|
||||
br i1 %exitcond, label %then, label %for.i
|
||||
|
||||
then:
|
||||
br label %return
|
||||
|
||||
return:
|
||||
fence seq_cst
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: base_pointer_in_condition
|
||||
; CHECK: Valid Region for Scop: for.i => then
|
||||
|
||||
define void @base_pointer_is_argument(float* %A, i64 %n) {
|
||||
entry:
|
||||
br label %for.i
|
||||
|
||||
for.i:
|
||||
%indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
|
||||
br label %S1
|
||||
|
||||
S1:
|
||||
%conv = sitofp i64 %indvar.i to float
|
||||
%arrayidx5 = getelementptr float* %A, i64 %indvar.i
|
||||
store float %conv, float* %arrayidx5, align 4
|
||||
br label %for.i.inc
|
||||
|
||||
for.i.inc:
|
||||
%indvar.i.next = add i64 %indvar.i, 1
|
||||
%exitcond.i = icmp ne i64 %indvar.i.next, %n
|
||||
br i1 %exitcond.i, label %for.i, label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: base_pointer_is_argument
|
||||
; CHECK: Valid Region for Scop: for.i => exit
|
||||
|
||||
define void @base_pointer_is_const_expr(i64 %n) {
|
||||
entry:
|
||||
br label %for.i
|
||||
|
||||
for.i:
|
||||
%indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
|
||||
br label %S1
|
||||
|
||||
S1:
|
||||
%conv = sitofp i64 %indvar.i to float
|
||||
%arrayidx5 = getelementptr float* inttoptr (i64 100 to float*), i64 %indvar.i
|
||||
store float %conv, float* %arrayidx5, align 4
|
||||
br label %for.i.inc
|
||||
|
||||
for.i.inc:
|
||||
%indvar.i.next = add i64 %indvar.i, 1
|
||||
%exitcond.i = icmp ne i64 %indvar.i.next, %n
|
||||
br i1 %exitcond.i, label %for.i, label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: base_pointer_is_const_expr
|
||||
; CHECK-LABEL: Valid Region for Scop: for.i => exit
|
||||
|
||||
@A = external global float
|
||||
|
||||
define void @base_pointer_is_global(i64 %n) {
|
||||
entry:
|
||||
br label %for.i
|
||||
|
||||
for.i:
|
||||
%indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
|
||||
br label %S1
|
||||
|
||||
S1:
|
||||
%conv = sitofp i64 %indvar.i to float
|
||||
%arrayidx5 = getelementptr float* @A, i64 %indvar.i
|
||||
store float %conv, float* %arrayidx5, align 4
|
||||
br label %for.i.inc
|
||||
|
||||
for.i.inc:
|
||||
%indvar.i.next = add i64 %indvar.i, 1
|
||||
%exitcond.i = icmp ne i64 %indvar.i.next, %n
|
||||
br i1 %exitcond.i, label %for.i, label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: base_pointer_is_global
|
||||
; CHECK: Valid Region for Scop: for.i => exit
|
||||
|
||||
declare float *@foo()
|
||||
|
||||
define void @base_pointer_is_inst_outside(i64 %n) {
|
||||
entry:
|
||||
%A = call float *@foo()
|
||||
br label %for.i
|
||||
|
||||
for.i:
|
||||
%indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
|
||||
br label %S1
|
||||
|
||||
S1:
|
||||
%conv = sitofp i64 %indvar.i to float
|
||||
%arrayidx5 = getelementptr float* %A, i64 %indvar.i
|
||||
store float %conv, float* %arrayidx5, align 4
|
||||
br label %for.i.inc
|
||||
|
||||
for.i.inc:
|
||||
%indvar.i.next = add i64 %indvar.i, 1
|
||||
%exitcond.i = icmp ne i64 %indvar.i.next, %n
|
||||
br i1 %exitcond.i, label %for.i, label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: base_pointer_is_inst_outside
|
||||
; CHECK: Valid Region for Scop: for.i => exit
|
||||
|
||||
declare float* @getNextBasePtr(float*) readnone nounwind
|
||||
|
||||
define void @base_pointer_is_phi_node(i64 %n, float* %A) {
|
||||
entry:
|
||||
br label %for.i
|
||||
|
||||
for.i:
|
||||
%indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
|
||||
%ptr = phi float* [ %ptr.next, %for.i.inc ], [ %A, %entry ]
|
||||
; To get a PHI node inside a SCoP, that can not be analyzed but
|
||||
; for which the surrounding scop is normally still valid we use a function
|
||||
; without any sideeffects.
|
||||
%ptr.next = call float* @getNextBasePtr(float* %ptr)
|
||||
br label %S1
|
||||
|
||||
S1:
|
||||
%conv = sitofp i64 %indvar.i to float
|
||||
%arrayidx5 = getelementptr float* %ptr, i64 %indvar.i
|
||||
store float %conv, float* %arrayidx5, align 4
|
||||
br label %for.i.inc
|
||||
|
||||
for.i.inc:
|
||||
%indvar.i.next = add i64 %indvar.i, 1
|
||||
%exitcond.i = icmp ne i64 %indvar.i.next, %n
|
||||
br i1 %exitcond.i, label %for.i, label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: base_pointer_is_phi_node
|
||||
; CHECK-NOT: Valid Region for Scop
|
||||
|
||||
define void @base_pointer_is_inst_inside_invariant_1(i64 %n, float* %A) {
|
||||
entry:
|
||||
br label %for.i
|
||||
|
||||
for.i:
|
||||
%indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
|
||||
; To get an instruction inside a region, we use a function without side
|
||||
; effects on which SCEV blocks, but for which still is clear that the return
|
||||
; value remains invariant throughout the whole loop.
|
||||
%ptr = call float* @getNextBasePtr(float* %A)
|
||||
br label %S1
|
||||
|
||||
S1:
|
||||
%conv = sitofp i64 %indvar.i to float
|
||||
%arrayidx5 = getelementptr float* %ptr, i64 %indvar.i
|
||||
store float %conv, float* %arrayidx5, align 4
|
||||
br label %for.i.inc
|
||||
|
||||
for.i.inc:
|
||||
%indvar.i.next = add i64 %indvar.i, 1
|
||||
%exitcond.i = icmp ne i64 %indvar.i.next, %n
|
||||
br i1 %exitcond.i, label %for.i, label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: base_pointer_is_inst_inside_invariant_1
|
||||
; CHECK: Valid Region for Scop: for.i => exit
|
||||
|
||||
declare float* @getNextBasePtr2(float*) readnone nounwind
|
||||
|
||||
define void @base_pointer_is_inst_inside_invariant_2(i64 %n, float* %A) {
|
||||
entry:
|
||||
br label %for.i
|
||||
|
||||
for.i:
|
||||
%indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
|
||||
%ptr = call float* @getNextBasePtr2(float* %A)
|
||||
%ptr2 = call float* @getNextBasePtr(float* %ptr)
|
||||
br label %S1
|
||||
|
||||
S1:
|
||||
%conv = sitofp i64 %indvar.i to float
|
||||
%arrayidx5 = getelementptr float* %ptr2, i64 %indvar.i
|
||||
store float %conv, float* %arrayidx5, align 4
|
||||
br label %for.i.inc
|
||||
|
||||
for.i.inc:
|
||||
%indvar.i.next = add i64 %indvar.i, 1
|
||||
%exitcond.i = icmp ne i64 %indvar.i.next, %n
|
||||
br i1 %exitcond.i, label %for.i, label %exit
|
||||
|
||||
exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: base_pointer_is_inst_inside_invariant_2
|
||||
; CHECK: Valid Region for Scop: for.i => exit
|
|
@ -1,45 +0,0 @@
|
|||
; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
|
||||
; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
|
||||
|
||||
; void f(long **A_ptr, long N) {
|
||||
; long i;
|
||||
; long *A;
|
||||
;
|
||||
; if (true) {
|
||||
; A = *A_ptr;
|
||||
; for (i = 0; i < N; ++i)
|
||||
; A[i] = i;
|
||||
; }
|
||||
; }
|
||||
|
||||
; We verify that a base pointer is always loop invariant.
|
||||
|
||||
target 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"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
define void @f(i64** noalias %A_ptr, i64 %N) nounwind {
|
||||
entry:
|
||||
fence seq_cst
|
||||
br label %pre
|
||||
|
||||
pre:
|
||||
%A = load i64** %A_ptr
|
||||
br i1 true, label %for.i, label %then
|
||||
|
||||
for.i:
|
||||
%indvar = phi i64 [ 0, %pre ], [ %indvar.next, %for.i ]
|
||||
%scevgep = getelementptr i64* %A, i64 %indvar
|
||||
store i64 %indvar, i64* %scevgep
|
||||
%indvar.next = add nsw i64 %indvar, 1
|
||||
%exitcond = icmp eq i64 %indvar.next, %N
|
||||
br i1 %exitcond, label %then, label %for.i
|
||||
|
||||
then:
|
||||
br label %return
|
||||
|
||||
return:
|
||||
fence seq_cst
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: Valid Region for Scop: for.i => then
|
Loading…
Reference in New Issue