summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/Scalar/GVN.cpp6
-rw-r--r--llvm/test/Transforms/GVN/condprop.ll72
2 files changed, 78 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index c48e766c797..95c35adb8f5 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -1736,6 +1736,9 @@ bool GVN::propagateEquality(Value *LHS, Value *RHS, const BasicBlockEdge &Root,
Changed |= NumReplacements > 0;
NumGVNEqProp += NumReplacements;
+ // Cached information for anything that uses LHS will be invalid.
+ if (MD)
+ MD->invalidateCachedPointerInfo(LHS);
}
// Now try to deduce additional equalities from this one. For example, if
@@ -1811,6 +1814,9 @@ bool GVN::propagateEquality(Value *LHS, Value *RHS, const BasicBlockEdge &Root,
Root.getStart());
Changed |= NumReplacements > 0;
NumGVNEqProp += NumReplacements;
+ // Cached information for anything that uses NotCmp will be invalid.
+ if (MD)
+ MD->invalidateCachedPointerInfo(NotCmp);
}
}
// Ensure that any instruction in scope that gets the "A < B" value number
diff --git a/llvm/test/Transforms/GVN/condprop.ll b/llvm/test/Transforms/GVN/condprop.ll
index 6aa3cb86250..949fdd0c0c9 100644
--- a/llvm/test/Transforms/GVN/condprop.ll
+++ b/llvm/test/Transforms/GVN/condprop.ll
@@ -297,3 +297,75 @@ ret:
; CHECK: %res = phi i32 [ 0, %cond_true ], [ %x, %cond_false ]
ret i32 %res
}
+
+; On the path from entry->if->end we know that ptr1==ptr2, so we can determine
+; that gep2 does not alias ptr1 on that path (as it would require that
+; ptr2==ptr2+2), so we can perform PRE of the load.
+; CHECK-LABEL: @test13
+define i32 @test13(i32* %ptr1, i32* %ptr2) {
+; CHECK-LABEL: entry:
+entry:
+ %gep1 = getelementptr i32, i32* %ptr2, i32 1
+ %gep2 = getelementptr i32, i32* %ptr2, i32 2
+ %cmp = icmp eq i32* %ptr1, %ptr2
+ br i1 %cmp, label %if, label %end
+
+; CHECK: [[CRIT_EDGE:.*]]:
+; CHECK: %[[PRE:.*]] = load i32, i32* %gep2, align 4
+
+; CHECK-LABEL: if:
+if:
+ %val1 = load i32, i32* %gep2, align 4
+ br label %end
+
+; CHECK-LABEL: end:
+; CHECK: %val2 = phi i32 [ %val1, %if ], [ %[[PRE]], %[[CRIT_EDGE]] ]
+; CHECK-NOT: load
+end:
+ %phi1 = phi i32* [ %ptr1, %if ], [ %gep1, %entry ]
+ %phi2 = phi i32 [ %val1, %if ], [ 0, %entry ]
+ store i32 0, i32* %phi1, align 4
+ %val2 = load i32, i32* %gep2, align 4
+ %ret = add i32 %phi2, %val2
+ ret i32 %ret
+}
+
+; CHECK-LABEL: @test14
+define void @test14(i32* %ptr1, i32* noalias %ptr2) {
+entry:
+ %gep1 = getelementptr inbounds i32, i32* %ptr1, i32 1
+ %gep2 = getelementptr inbounds i32, i32* %ptr1, i32 2
+ br label %loop
+
+; CHECK-LABEL: loop:
+loop:
+ %phi1 = phi i32* [ %gep3, %loop.end ], [ %gep1, %entry ]
+ br i1 undef, label %if1, label %then
+
+; CHECK: [[CRIT_EDGE:.*]]:
+; CHECK: %[[PRE:.*]] = load i32, i32* %gep2, align 4
+
+; CHECK-LABEL: if1:
+; CHECK: %val2 = phi i32 [ %[[PRE]], %[[CRIT_EDGE]] ], [ %val3, %loop.end ]
+; CHECK-NOT: load
+if1:
+ %val2 = load i32, i32* %gep2, align 4
+ store i32 %val2, i32* %gep2, align 4
+ store i32 0, i32* %phi1, align 4
+ br label %then
+
+; CHECK-LABEL: then:
+then:
+ %cmp = icmp eq i32* %gep2, %ptr2
+ br i1 %cmp, label %loop.end, label %if2
+
+if2:
+ br label %loop.end
+
+loop.end:
+ %phi3 = phi i32* [ %gep2, %then ], [ %ptr1, %if2 ]
+ %val3 = load i32, i32* %gep2, align 4
+ store i32 %val3, i32* %phi3, align 4
+ %gep3 = getelementptr inbounds i32, i32* %ptr1, i32 1
+ br i1 undef, label %loop, label %if1
+}
OpenPOWER on IntegriCloud