Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit ef0538f

Browse files
committed
[LICM] Hoist an invariant_start out of loops if there are no stores executed before it
Once the invariant_start is reached, we know that no instruction *after* it can modify the memory. So, if we can prove the location isn't read *between entry into the loop and the execution of the invariant_start*, we can execute the invariant_start before entering the loop. Differential Revision: https://reviews.llvm.org/D51181 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340617 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 64e272c commit ef0538f

File tree

2 files changed

+9
-8
lines changed

2 files changed

+9
-8
lines changed

lib/Transforms/Scalar/LICM.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,9 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI,
525525
}
526526

527527
using namespace PatternMatch;
528-
if (match(&I, m_Intrinsic<Intrinsic::experimental_guard>()) &&
528+
if (((I.use_empty() &&
529+
match(&I, m_Intrinsic<Intrinsic::invariant_start>())) ||
530+
match(&I, m_Intrinsic<Intrinsic::experimental_guard>())) &&
529531
IsMustExecute && IsMemoryNotModified &&
530532
CurLoop->hasLoopInvariantOperands(&I)) {
531533
hoist(I, DT, CurLoop, SafetyInfo, ORE);

test/Transforms/LICM/invariant.start.ll

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,18 @@
33
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=0 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
44
; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=200 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s --check-prefix=ALIAS-N2
55

6-
; TODO: By default (without the -licm-n2-threshold value), we should be able to hoist both load and invariant.start
76
define void @test1(i1 %cond, i32* %ptr) {
87
; CHECK-LABEL: @test1(
98
; CHECK-LABEL: entry:
9+
; CHECK: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
1010
; CHECK: %val = load i32, i32* %ptr
1111
; CHECK-LABEL: loop:
12-
; CHECK: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
1312

1413
; ALIAS-N2-LABEL: @test1(
1514
; ALIAS-N2-LABEL: entry:
16-
; ALIAS-N2: %val = load i32, i32* %ptr
17-
; ALIAS-N2-LABEL: loop:
1815
; ALIAS-N2: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
16+
; ALIAS-N2: %val = load i32, i32* %ptr
17+
; ALIAS-N2-LABEL: loop:
1918

2019
entry:
2120
br label %loop
@@ -57,15 +56,15 @@ loop:
5756
define void @test3(i1 %cond, i32* %ptr) {
5857
; CHECK-LABEL: @test3(
5958
; CHECK-LABEL: entry:
59+
; CHECK: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
6060
; CHECK: %val = load i32, i32* %ptr
6161
; CHECK-LABEL: loop:
62-
; CHECK: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
6362

6463
; ALIAS-N2-LABEL: @test3(
6564
; ALIAS-N2-LABEL: entry:
66-
; ALIAS-N2: %val = load i32, i32* %ptr
65+
; ALIAS-N2: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
66+
; ALIAS-N2: %val = load i32, i32* %ptr
6767
; ALIAS-N2-LABEL: loop:
68-
; ALIAS-N2: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
6968
entry:
7069
br label %loop
7170

0 commit comments

Comments
 (0)