summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Nemet <anemet@apple.com>2016-03-24 17:59:26 +0000
committerAdam Nemet <anemet@apple.com>2016-03-24 17:59:26 +0000
commit7aba60c853634f42988544c8150b3510cc7468fd (patch)
tree620480ea69e06b3793884e4a4c584934d3185ee2
parent107ac9e1aab2d27e6fdd2956585fbce47a03c627 (diff)
downloadbcm5719-llvm-7aba60c853634f42988544c8150b3510cc7468fd.tar.gz
bcm5719-llvm-7aba60c853634f42988544c8150b3510cc7468fd.zip
[LLE] Check for mismatching types between the store and the load earlier
isDependenceDistanceOfOne asserts that the store and the load access through the same type. This function is also used by removeDependencesFromMultipleStores so we need to make sure we filter out mismatching types before reaching this point. Now we do this when the initial candidates are gathered. This is a refinement of the fix made in r262267. Fixes PR27048. llvm-svn: 264313
-rw-r--r--llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp10
-rw-r--r--llvm/test/Transforms/LoopLoadElim/type-mismatch.ll46
2 files changed, 52 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp b/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp
index a0486901190..1a51df8a71d 100644
--- a/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp
@@ -171,6 +171,12 @@ public:
auto *Load = dyn_cast<LoadInst>(Destination);
if (!Load)
continue;
+
+ // Only progagate the value if they are of the same type.
+ if (Store->getPointerOperand()->getType() !=
+ Load->getPointerOperand()->getType())
+ continue;
+
Candidates.emplace_front(Load, Store);
}
@@ -438,10 +444,6 @@ public:
unsigned NumForwarding = 0;
for (const StoreToLoadForwardingCandidate Cand : StoreToLoadDependences) {
DEBUG(dbgs() << "Candidate " << Cand);
- // Only progagate value if they are of the same type.
- if (Cand.Store->getPointerOperand()->getType() !=
- Cand.Load->getPointerOperand()->getType())
- continue;
// Make sure that the stored values is available everywhere in the loop in
// the next iteration.
diff --git a/llvm/test/Transforms/LoopLoadElim/type-mismatch.ll b/llvm/test/Transforms/LoopLoadElim/type-mismatch.ll
index a1f790db9bb..ab8029bd35f 100644
--- a/llvm/test/Transforms/LoopLoadElim/type-mismatch.ll
+++ b/llvm/test/Transforms/LoopLoadElim/type-mismatch.ll
@@ -9,6 +9,7 @@
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+; CHECK-LABEL: @f(
define void @f(i32* noalias %A, i32* noalias %B, i32* noalias %C, i64 %N) {
entry:
@@ -41,3 +42,48 @@ for.body: ; preds = %for.body, %entry
for.end: ; preds = %for.body
ret void
}
+
+; Don't crash if the store and the load use different types.
+;
+; for (unsigned i = 0; i < 100; i++) {
+; A[i+1] = B[i] + 2;
+; A[i+1] = B[i] + 3;
+; C[i] = ((float*)A)[i] * 2;
+; }
+
+; CHECK-LABEL: @f2(
+define void @f2(i32* noalias %A, i32* noalias %B, i32* noalias %C, i64 %N) {
+
+entry:
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+
+ %Aidx_next = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
+ %Bidx = getelementptr inbounds i32, i32* %B, i64 %indvars.iv
+ %Cidx = getelementptr inbounds i32, i32* %C, i64 %indvars.iv
+ %Aidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
+ %Aidx.float = bitcast i32* %Aidx to float*
+
+ %b = load i32, i32* %Bidx, align 4
+ %a_p2 = add i32 %b, 2
+ store i32 %a_p2, i32* %Aidx_next, align 4
+
+ %a_p3 = add i32 %b, 3
+ store i32 %a_p3, i32* %Aidx_next, align 4
+
+; CHECK: %a = load float, float* %Aidx.float, align 4
+ %a = load float, float* %Aidx.float, align 4
+; CHECK-NEXT: %c = fmul float %a, 2.0
+ %c = fmul float %a, 2.0
+ %c.int = fptosi float %c to i32
+ store i32 %c.int, i32* %Cidx, align 4
+
+ %exitcond = icmp eq i64 %indvars.iv.next, %N
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ ret void
+}
OpenPOWER on IntegriCloud