llvm-project/polly/test/Isl/CodeGen/reduction_2.ll
Tobias Grosser 8bd7f3c0a5 [ScopDetect/Info] Allow unconditional hoisting of loads from dereferenceable ptrs
In case LLVM pointers are annotated with !dereferencable attributes/metadata
or LLVM can look at the allocation from which a pointer is derived, we can know
that dereferencing pointers is safe and can be done unconditionally. We use this
information to proof certain pointers as save to hoist and then hoist them
unconditionally.

llvm-svn: 297375
2017-03-09 11:36:00 +00:00

102 lines
4.6 KiB
LLVM

; RUN: opt %loadPolly -basicaa -polly-ast -analyze \
; RUN: -polly-invariant-load-hoisting=true < %s | FileCheck %s
;#include <string.h>
;#include <stdio.h>
;#define N 1021
;
;int main () {
; int i;
; int A[N];
; int RED[1];
;
; memset(A, 0, sizeof(int) * N);
;
; A[0] = 1;
; A[1] = 1;
; RED[0] = 0;
;
; for (i = 2; i < N; i++) {
; A[i] = A[i-1] + A[i-2];
; RED[0] += A[i-2];
; }
;
; if (RED[0] != 382399368)
; return 1;
;}
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-n8:16:32:64"
define i32 @main() nounwind {
entry:
%A = alloca [1021 x i32], align 4 ; <[1021 x i32]*> [#uses=6]
%RED = alloca [1 x i32], align 4 ; <[1 x i32]*> [#uses=3]
%arraydecay = getelementptr inbounds [1021 x i32], [1021 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
%conv = bitcast i32* %arraydecay to i8* ; <i8*> [#uses=1]
call void @llvm.memset.p0i8.i64(i8* %conv, i8 0, i64 4084, i32 1, i1 false)
%arraydecay1 = getelementptr inbounds [1021 x i32], [1021 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
%arrayidx = getelementptr inbounds i32, i32* %arraydecay1, i64 0 ; <i32*> [#uses=1]
store i32 1, i32* %arrayidx
%arraydecay2 = getelementptr inbounds [1021 x i32], [1021 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
%arrayidx3 = getelementptr inbounds i32, i32* %arraydecay2, i64 1 ; <i32*> [#uses=1]
store i32 1, i32* %arrayidx3
%arraydecay4 = getelementptr inbounds [1 x i32], [1 x i32]* %RED, i32 0, i32 0 ; <i32*> [#uses=1]
%arrayidx5 = getelementptr inbounds i32, i32* %arraydecay4, i64 0 ; <i32*> [#uses=1]
store i32 0, i32* %arrayidx5
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ] ; <i64> [#uses=5]
%arrayidx15 = getelementptr [1021 x i32], [1021 x i32]* %A, i64 0, i64 %indvar ; <i32*> [#uses=2]
%tmp = add i64 %indvar, 2 ; <i64> [#uses=1]
%arrayidx20 = getelementptr [1021 x i32], [1021 x i32]* %A, i64 0, i64 %tmp ; <i32*> [#uses=1]
%tmp1 = add i64 %indvar, 1 ; <i64> [#uses=1]
%arrayidx9 = getelementptr [1021 x i32], [1021 x i32]* %A, i64 0, i64 %tmp1 ; <i32*> [#uses=1]
%exitcond = icmp ne i64 %indvar, 1019 ; <i1> [#uses=1]
br i1 %exitcond, label %for.body, label %for.end
for.body: ; preds = %for.cond
%tmp10 = load i32, i32* %arrayidx9 ; <i32> [#uses=1]
%tmp16 = load i32, i32* %arrayidx15 ; <i32> [#uses=1]
%add = add nsw i32 %tmp10, %tmp16 ; <i32> [#uses=1]
store i32 %add, i32* %arrayidx20
%tmp26 = load i32, i32* %arrayidx15 ; <i32> [#uses=1]
%arraydecay27 = getelementptr inbounds [1 x i32], [1 x i32]* %RED, i32 0, i32 0 ; <i32*> [#uses=1]
%arrayidx28 = getelementptr inbounds i32, i32* %arraydecay27, i64 0 ; <i32*> [#uses=2]
%tmp29 = load i32, i32* %arrayidx28 ; <i32> [#uses=1]
%add30 = add nsw i32 %tmp29, %tmp26 ; <i32> [#uses=1]
store i32 %add30, i32* %arrayidx28
br label %for.inc
for.inc: ; preds = %for.body
%indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
br label %for.cond
for.end: ; preds = %for.cond
%arraydecay32 = getelementptr inbounds [1 x i32], [1 x i32]* %RED, i32 0, i32 0 ; <i32*> [#uses=1]
%arrayidx33 = getelementptr inbounds i32, i32* %arraydecay32, i64 0 ; <i32*> [#uses=1]
%tmp34 = load i32, i32* %arrayidx33 ; <i32> [#uses=1]
%cmp35 = icmp ne i32 %tmp34, 382399368 ; <i1> [#uses=1]
br i1 %cmp35, label %if.then, label %if.end
if.then: ; preds = %for.end
br label %if.end
if.end: ; preds = %if.then, %for.end
%retval.0 = phi i32 [ 1, %if.then ], [ 0, %for.end ] ; <i32> [#uses=1]
ret i32 %retval.0
}
declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
; At some point this was a negative test, where we optimistically assumed RED[0]
; in the conditional after the loop is invariant and expanded the SCoP from
; the loop to include the conditional. However, during SCoP generation we
; realized that RED[0] is in fact not invariant and bailed.
;
; Today, LLVM can derive that the load is indeed invariant and Polly uses this
; information to unconditionally invariant load hoist RED[0].
;
; CHECK: for (int c0 = 0; c0 <= 1018; c0 += 1)
; CHECK-NEXT: Stmt_for_body(c0);