[llvm] r222100 - [DependenceAnalysis] Allow subscripts of different types

Jingyue Wu jingyue at google.com
Sun Nov 16 08:52:45 PST 2014


Author: jingyue
Date: Sun Nov 16 10:52:44 2014
New Revision: 222100

URL: http://llvm.org/viewvc/llvm-project?rev=222100&view=rev
Log:
[DependenceAnalysis] Allow subscripts of different types

Summary:
Several places in DependenceAnalysis assumes both SCEVs in a subscript pair
share the same integer type. For instance, isKnownPredicate calls
SE->getMinusSCEV(X, Y) which asserts X and Y share the same type. However,
DependenceAnalysis fails to ensure this assumption when producing a subscript
pair, causing tests such as NonCanonicalizedSubscript to crash. With this
patch, DependenceAnalysis runs unifySubscriptType before producing any
subscript pair, ensuring the assumption.

Test Plan:
Added NonCanonicalizedSubscript.ll on which DependenceAnalysis before the fix
crashed because subscripts have different types.

Reviewers: spop, sebpop, jingyue

Reviewed By: jingyue

Subscribers: eliben, meheff, llvm-commits

Differential Revision: http://reviews.llvm.org/D6289

Added:
    llvm/trunk/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll
Modified:
    llvm/trunk/include/llvm/Analysis/DependenceAnalysis.h
    llvm/trunk/lib/Analysis/DependenceAnalysis.cpp

Modified: llvm/trunk/include/llvm/Analysis/DependenceAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DependenceAnalysis.h?rev=222100&r1=222099&r2=222100&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/DependenceAnalysis.h (original)
+++ llvm/trunk/include/llvm/Analysis/DependenceAnalysis.h Sun Nov 16 10:52:44 2014
@@ -523,6 +523,12 @@ namespace llvm {
     /// in LoopNest.
     bool isLoopInvariant(const SCEV *Expression, const Loop *LoopNest) const;
 
+    /// Makes sure both subscripts (i.e. Pair->Src and Pair->Dst) share the same
+    /// integer type by sign-extending one of them when necessary.
+    /// Sign-extending a subscript is safe because getelementptr assumes the
+    /// array subscripts are signed.
+    void unifySubscriptType(Subscript *Pair);
+
     /// removeMatchingExtensions - Examines a subscript pair.
     /// If the source and destination are identically sign (or zero)
     /// extended, it strips off the extension in an effort to
@@ -911,7 +917,7 @@ namespace llvm {
 
     bool tryDelinearize(const SCEV *SrcSCEV, const SCEV *DstSCEV,
                         SmallVectorImpl<Subscript> &Pair,
-                        const SCEV *ElementSize) const;
+                        const SCEV *ElementSize);
 
   public:
     static char ID; // Class identification, replacement for typeinfo

Modified: llvm/trunk/lib/Analysis/DependenceAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DependenceAnalysis.cpp?rev=222100&r1=222099&r2=222100&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/DependenceAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/DependenceAnalysis.cpp Sun Nov 16 10:52:44 2014
@@ -781,6 +781,25 @@ void DependenceAnalysis::collectCommonLo
   }
 }
 
+void DependenceAnalysis::unifySubscriptType(Subscript *Pair) {
+  const SCEV *Src = Pair->Src;
+  const SCEV *Dst = Pair->Dst;
+  IntegerType *SrcTy = dyn_cast<IntegerType>(Src->getType());
+  IntegerType *DstTy = dyn_cast<IntegerType>(Dst->getType());
+  if (SrcTy == nullptr || DstTy == nullptr) {
+    assert(SrcTy == DstTy && "This function only unify integer types and "
+                             "expect Src and Dst share the same type "
+                             "otherwise.");
+    return;
+  }
+  if (SrcTy->getBitWidth() > DstTy->getBitWidth()) {
+    // Sign-extend Dst to typeof(Src) if typeof(Src) is wider than typeof(Dst).
+    Pair->Dst = SE->getSignExtendExpr(Dst, SrcTy);
+  } else if (SrcTy->getBitWidth() < DstTy->getBitWidth()) {
+    // Sign-extend Src to typeof(Dst) if typeof(Dst) is wider than typeof(Src).
+    Pair->Src = SE->getSignExtendExpr(Src, DstTy);
+  }
+}
 
 // removeMatchingExtensions - Examines a subscript pair.
 // If the source and destination are identically sign (or zero)
@@ -793,9 +812,11 @@ void DependenceAnalysis::removeMatchingE
       (isa<SCEVSignExtendExpr>(Src) && isa<SCEVSignExtendExpr>(Dst))) {
     const SCEVCastExpr *SrcCast = cast<SCEVCastExpr>(Src);
     const SCEVCastExpr *DstCast = cast<SCEVCastExpr>(Dst);
-    if (SrcCast->getType() == DstCast->getType()) {
-      Pair->Src = SrcCast->getOperand();
-      Pair->Dst = DstCast->getOperand();
+    const SCEV *SrcCastOp = SrcCast->getOperand();
+    const SCEV *DstCastOp = DstCast->getOperand();
+    if (SrcCastOp->getType() == DstCastOp->getType()) {
+      Pair->Src = SrcCastOp;
+      Pair->Dst = DstCastOp;
     }
   }
 }
@@ -3178,7 +3199,7 @@ void DependenceAnalysis::updateDirection
 bool DependenceAnalysis::tryDelinearize(const SCEV *SrcSCEV,
                                         const SCEV *DstSCEV,
                                         SmallVectorImpl<Subscript> &Pair,
-                                        const SCEV *ElementSize) const {
+                                        const SCEV *ElementSize) {
   const SCEVUnknown *SrcBase =
       dyn_cast<SCEVUnknown>(SE->getPointerBase(SrcSCEV));
   const SCEVUnknown *DstBase =
@@ -3233,6 +3254,7 @@ bool DependenceAnalysis::tryDelinearize(
   for (int i = 0; i < size; ++i) {
     Pair[i].Src = SrcSubscripts[i];
     Pair[i].Dst = DstSubscripts[i];
+    unifySubscriptType(&Pair[i]);
 
     // FIXME: we should record the bounds SrcSizes[i] and DstSizes[i] that the
     // delinearization has found, and add these constraints to the dependence
@@ -3341,6 +3363,7 @@ DependenceAnalysis::depends(Instruction
          ++SrcIdx, ++DstIdx, ++P) {
       Pair[P].Src = SE->getSCEV(*SrcIdx);
       Pair[P].Dst = SE->getSCEV(*DstIdx);
+      unifySubscriptType(&Pair[P]);
     }
   }
   else {

Added: llvm/trunk/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll?rev=222100&view=auto
==============================================================================
--- llvm/trunk/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll (added)
+++ llvm/trunk/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll Sun Nov 16 10:52:44 2014
@@ -0,0 +1,40 @@
+; RUN: opt < %s -analyze -basicaa -da -da-delinearize=false | FileCheck %s
+; RUN: opt < %s -analyze -basicaa -da -da-delinearize | FileCheck %s -check-prefix=DELIN
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.6.0"
+
+; for (int i = 0; i < 100; ++i) {
+;   int t0 = a[i][i];
+;   int t1 = t0 + 1;
+;   a[i][5] = t1;
+; }
+; The subscript 5 in a[i][5] is deliberately an i32, mismatching the types of
+; other subscript. DependenceAnalysis before the fix crashed due to this
+; mismatch.
+define void @i32_subscript([100 x [100 x i32]]* %a, i32* %b) {
+; CHECK-LABEL: 'Dependence Analysis' for function 'i32_subscript'
+; DELIN-LABEL: 'Dependence Analysis' for function 'i32_subscript'
+entry:
+  br label %for.body
+
+for.body:
+; CHECK: da analyze - none!
+; CHECK: da analyze - anti [=|<]!
+; CHECK: da analyze - none!
+; DELIN: da analyze - none!
+; DELIN: da analyze - anti [=|<]!
+; DELIN: da analyze - none!
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %for.body ]
+  %a.addr = getelementptr [100 x [100 x i32]]* %a, i64 0, i64 %i, i64 %i
+  %a.addr.2 = getelementptr [100 x [100 x i32]]* %a, i64 0, i64 %i, i32 5
+  %0 = load i32* %a.addr, align 4
+  %1 = add i32 %0, 1
+  store i32 %1, i32* %a.addr.2, align 4
+  %i.inc = add nsw i64 %i, 1
+  %exitcond = icmp ne i64 %i.inc, 100
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.end:
+  ret void
+}





More information about the llvm-commits mailing list