Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[LICM & MSSA] Limit unsafe sinking and hoisting.
Summary: The getClobberingMemoryAccess API checks for clobbering accesses in a loop by walking the backedge. This may check if a memory access is being clobbered by the loop in a previous iteration, depending how smart AA got over the course of the updates in MemorySSA (it does not occur when built from scratch). If no clobbering access is found inside the loop, it will optimize to an access outside the loop. This however does not mean that access is safe to sink. Given: ``` for i load a[i] store a[i] ``` The access corresponding to the load can be optimized to outside the loop, and the load can be hoisted. But it is incorrect to sink it. In order to sink the load, we'd need to check no Def clobbers the Use in the same iteration. With this patch we currently restrict sinking to either Defs not existing in the loop, or Defs preceding the load in the same block. An easy extension is to ensure the load (Use) post-dominates all Defs. Caught by PR42294. This issue also shed light on the converse problem: hoisting stores in this same scenario would be illegal. With this patch we restrict hoisting of stores to the case when their corresponding Defs are dominating all Uses in the loop. Reviewers: george.burgess.iv Subscribers: jlebar, Prazek, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D63582 llvm-svn: 363982
- Loading branch information
Showing
4 changed files
with
104 additions
and
12 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,48 @@ | ||
; RUN: opt -loop-rotate -licm %s -disable-output -enable-mssa-loop-dependency=true -debug-only=licm 2>&1 | FileCheck %s -check-prefix=LICM | ||
; RUN: opt -loop-rotate -licm %s -disable-output -enable-mssa-loop-dependency=false -debug-only=licm 2>&1 | FileCheck %s -check-prefix=LICM | ||
; RUN: opt -loop-rotate -licm %s -S -enable-mssa-loop-dependency=true | FileCheck %s | ||
; RUN: opt -loop-rotate -licm %s -S -enable-mssa-loop-dependency=false | FileCheck %s | ||
|
||
; LICM: Using | ||
; LICM-NOT: LICM sinking instruction: %.pre = load i8, i8* %arrayidx.phi.trans.insert | ||
|
||
; CHECK-LABEL: @fn1 | ||
; CHECK-LABEL: entry: | ||
; CHECK: br i1 true, label %[[END:.*]], label %[[PH:.*]] | ||
; CHECK: [[PH]]: | ||
; CHECK: br label %[[CRIT:.*]] | ||
; CHECK: [[CRIT]]: | ||
; CHECK: load i8 | ||
; CHECK: store i8 | ||
; CHECK: br i1 true, label %[[ENDCRIT:.*]], label %[[CRIT]] | ||
; CHECK: [[ENDCRIT]]: | ||
; CHECK-NOT: load i8 | ||
; CHECK: br label %[[END]] | ||
|
||
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64" | ||
target triple = "s390x-unknown-linux-gnu" | ||
|
||
define void @fn1() { | ||
entry: | ||
%g = alloca [9 x i8], align 1 | ||
br label %for.body | ||
|
||
for.body: ; preds = %for.body.for.body_crit_edge, %entry | ||
%0 = phi i64 [ 0, %entry ], [ %phitmp, %for.body.for.body_crit_edge ] | ||
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body.for.body_crit_edge ] | ||
%arrayidx = getelementptr inbounds [9 x i8], [9 x i8]* %g, i64 0, i64 %indvars.iv | ||
store i8 2, i8* %arrayidx, align 1 | ||
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 | ||
br i1 undef, label %for.end18, label %for.body.for.body_crit_edge | ||
|
||
for.body.for.body_crit_edge: ; preds = %for.body | ||
%arrayidx.phi.trans.insert = getelementptr inbounds [9 x i8], [9 x i8]* %g, i64 0, i64 %indvars.iv.next | ||
%.pre = load i8, i8* %arrayidx.phi.trans.insert, align 1 | ||
%phitmp = zext i8 %.pre to i64 | ||
br label %for.body | ||
|
||
for.end18: ; preds = %for.body | ||
store i64 %0, i64* undef, align 8 | ||
ret void | ||
} | ||
|
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