[llvm] r264313 - [LLE] Check for mismatching types between the store and the load earlier

Adam Nemet via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 24 10:59:26 PDT 2016


Author: anemet
Date: Thu Mar 24 12:59:26 2016
New Revision: 264313

URL: http://llvm.org/viewvc/llvm-project?rev=264313&view=rev
Log:
[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.

Modified:
    llvm/trunk/lib/Transforms/Scalar/LoopLoadElimination.cpp
    llvm/trunk/test/Transforms/LoopLoadElim/type-mismatch.ll

Modified: llvm/trunk/lib/Transforms/Scalar/LoopLoadElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopLoadElimination.cpp?rev=264313&r1=264312&r2=264313&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopLoadElimination.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopLoadElimination.cpp Thu Mar 24 12:59:26 2016
@@ -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.

Modified: llvm/trunk/test/Transforms/LoopLoadElim/type-mismatch.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopLoadElim/type-mismatch.ll?rev=264313&r1=264312&r2=264313&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LoopLoadElim/type-mismatch.ll (original)
+++ llvm/trunk/test/Transforms/LoopLoadElim/type-mismatch.ll Thu Mar 24 12:59:26 2016
@@ -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:
@@ -30,6 +31,51 @@ for.body:
 
 ; 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
+}
+
+; 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




More information about the llvm-commits mailing list