Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FIX] Adjust execution context of hoisted loads wrt. error domains
If we build the domains for error blocks and later remove them we lose the information that they are not executed. Thus, in the SCoP it looks like the control will always reach the statement S: for (i = 0 ... N) if (*valid == 0) doSth(&ptr); S: A[i] = *ptr; Consequently, we would have assumed "ptr" to be always accessed and preloaded it unconditionally. However, only if "*valid != 0" we would execute the optimized version of the SCoP. Nevertheless, we would have hoisted and accessed "ptr"regardless of "*valid". This changes the semantic of the program as the value of "*valid" can cause a change of "ptr" and control if it is executed or not. To fix this problem we adjust the execution context of hoisted loads wrt. error domains. To this end we introduce an ErrorDomainCtxMap that maps each basic block to the error context under which it might be executed. Thus, to the context under which it is executed but an error block would have been executed to. To fill this map one traversal of the blocks in the SCoP suffices. During this traversal we do also "remove" error statements and those that are only reachable via error statements. This was previously done by the removeErrorBlockDomains function which is therefor not needed anymore. This fixes bug PR26683 and thereby several SPEC miscompiles. Differential Revision: http://reviews.llvm.org/D18822 llvm-svn: 265778
- Loading branch information
Johannes Doerfert
committed
Apr 8, 2016
1 parent
b47cbe1
commit 3ef78d6
Showing
3 changed files
with
171 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s | ||
; | ||
; CHECK: Invariant Accesses: { | ||
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] | ||
; CHECK-NEXT: [N, valid_val] -> { Stmt_for_body[i0] -> MemRef_valid[0] }; | ||
; CHECK-NEXT: Execution Context: [N, valid_val] -> { : N > 0 } | ||
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] | ||
; CHECK-NEXT: [N, valid_val] -> { Stmt_S[i0] -> MemRef_ptr_addr[0] }; | ||
; CHECK-NEXT: Execution Context: [N, valid_val] -> { : N > 0 and (valid_val < 0 or valid_val > 0) } | ||
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] | ||
; CHECK-NEXT: [N, valid_val] -> { Stmt_S[i0] -> MemRef_tmp2[0] }; | ||
; CHECK-NEXT: Execution Context: [N, valid_val] -> { : N > 0 and (valid_val < 0 or valid_val > 0) } | ||
; CHECK-NEXT: } | ||
; CHECK-NEXT: Context: | ||
; CHECK-NEXT: [N, valid_val] -> { : -2147483648 <= N <= 2147483647 and -2147483648 <= valid_val <= 2147483647 } | ||
; CHECK-NEXT: Assumed Context: | ||
; CHECK-NEXT: [N, valid_val] -> { : } | ||
; CHECK-NEXT: Invalid Context: | ||
; CHECK-NEXT: [N, valid_val] -> { : valid_val = 0 and N > 0 } | ||
; | ||
; CHECK: Statements { | ||
; CHECK-NEXT: Stmt_S | ||
; CHECK-NEXT: Domain := | ||
; CHECK-NEXT: [N, valid_val] -> { Stmt_S[i0] : 0 <= i0 < N }; | ||
; CHECK-NEXT: Schedule := | ||
; CHECK-NEXT: [N, valid_val] -> { Stmt_S[i0] -> [i0] }; | ||
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] | ||
; CHECK-NEXT: [N, valid_val] -> { Stmt_S[i0] -> MemRef_A[i0] }; | ||
; CHECK-NEXT: } | ||
; | ||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
|
||
define void @f(i32 %N, i32* noalias %valid, i32* noalias %ptr, i32* noalias %A) { | ||
entry: | ||
%ptr.addr = alloca i32*, align 8 | ||
store i32* %ptr, i32** %ptr.addr, align 8 | ||
%tmp = sext i32 %N to i64 | ||
br label %for.cond | ||
|
||
for.cond: ; preds = %for.inc, %entry | ||
%indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] | ||
%cmp = icmp slt i64 %indvars.iv, %tmp | ||
br i1 %cmp, label %for.body, label %for.end | ||
|
||
for.body: ; preds = %for.cond | ||
%valid_val = load i32, i32* %valid, align 4 | ||
%cmp1 = icmp eq i32 %valid_val, 0 | ||
br i1 %cmp1, label %if.then, label %if.end | ||
|
||
if.then: ; preds = %for.body | ||
call void @doSth(i32** nonnull %ptr.addr) | ||
br label %if.end | ||
|
||
if.end: ; preds = %if.then, %for.body | ||
br label %S | ||
|
||
S: ; preds = %if.end | ||
%tmp2 = load i32*, i32** %ptr.addr, align 8 | ||
%tmp3 = load i32, i32* %tmp2, align 4 | ||
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv | ||
store i32 %tmp3, i32* %arrayidx, align 4 | ||
br label %for.inc | ||
|
||
for.inc: ; preds = %S | ||
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 | ||
br label %for.cond | ||
|
||
for.end: ; preds = %for.cond | ||
ret void | ||
} | ||
|
||
declare void @doSth(i32**) |