diff options
| author | Jingyue Wu <jingyue@google.com> | 2016-07-09 19:13:18 +0000 | 
|---|---|---|
| committer | Jingyue Wu <jingyue@google.com> | 2016-07-09 19:13:18 +0000 | 
| commit | debce55ac3048eda31c2e97ab9eefc0d10c45fd2 (patch) | |
| tree | 2a69b2b84b0a3276a6c16d82e11bfba498a8081a | |
| parent | 6170b4bebdcf3c9eae3eb0d88dbe855c98977a08 (diff) | |
| download | bcm5719-llvm-debce55ac3048eda31c2e97ab9eefc0d10c45fd2.tar.gz bcm5719-llvm-debce55ac3048eda31c2e97ab9eefc0d10c45fd2.zip | |
[SLSR] Fix crash on handling 128-bit integers.
    
ConstantInt::getSExtValue may fail on >64-bit integers. Add checks to call
getSExtValue only on narrow integers.
As a minor aside, simplify slsr-gep.ll to remove unnecessary load instructions.
llvm-svn: 274982
3 files changed, 73 insertions, 39 deletions
| diff --git a/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp index 411033bd583..77f0a78b928 100644 --- a/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp +++ b/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp @@ -246,7 +246,9 @@ static bool isGEPFoldable(GetElementPtrInst *GEP,  // Returns whether (Base + Index * Stride) can be folded to an addressing mode.  static bool isAddFoldable(const SCEV *Base, ConstantInt *Index, Value *Stride,                            TargetTransformInfo *TTI) { -  return TTI->isLegalAddressingMode(Base->getType(), nullptr, 0, true, +  // Index->getSExtValue() may crash if Index is wider than 64-bit. +  return Index->getBitWidth() <= 64 && +         TTI->isLegalAddressingMode(Base->getType(), nullptr, 0, true,                                      Index->getSExtValue(), UnknownAddressSpace);  } @@ -502,13 +504,23 @@ void StraightLineStrengthReduce::allocateCandidatesAndFindBasisForGEP(                                            IndexExprs, GEP->isInBounds());      Value *ArrayIdx = GEP->getOperand(I);      uint64_t ElementSize = DL->getTypeAllocSize(*GTI); -    factorArrayIndex(ArrayIdx, BaseExpr, ElementSize, GEP); +    if (ArrayIdx->getType()->getIntegerBitWidth() <= +        DL->getPointerSizeInBits()) { +      // Skip factoring if ArrayIdx is wider than the pointer size, because +      // ArrayIdx is implicitly truncated to the pointer size. +      factorArrayIndex(ArrayIdx, BaseExpr, ElementSize, GEP); +    }      // When ArrayIdx is the sext of a value, we try to factor that value as      // well.  Handling this case is important because array indices are      // typically sign-extended to the pointer size.      Value *TruncatedArrayIdx = nullptr; -    if (match(ArrayIdx, m_SExt(m_Value(TruncatedArrayIdx)))) +    if (match(ArrayIdx, m_SExt(m_Value(TruncatedArrayIdx))) && +        TruncatedArrayIdx->getType()->getIntegerBitWidth() <= +            DL->getPointerSizeInBits()) { +      // Skip factoring if TruncatedArrayIdx is wider than the pointer size, +      // because TruncatedArrayIdx is implicitly truncated to the pointer size.        factorArrayIndex(TruncatedArrayIdx, BaseExpr, ElementSize, GEP); +    }      IndexExprs[I - 1] = OrigIndexExpr;    } @@ -535,10 +547,11 @@ Value *StraightLineStrengthReduce::emitBump(const Candidate &Basis,    if (Basis.CandidateKind == Candidate::GEP) {      APInt ElementSize(          IndexOffset.getBitWidth(), -        DL->getTypeAllocSize(cast<GetElementPtrInst>(Basis.Ins)->getResultElementType())); +        DL->getTypeAllocSize( +            cast<GetElementPtrInst>(Basis.Ins)->getResultElementType()));      APInt Q, R;      APInt::sdivrem(IndexOffset, ElementSize, Q, R); -    if (R.getSExtValue() == 0) +    if (R == 0)        IndexOffset = Q;      else        BumpWithUglyGEP = true; @@ -546,10 +559,10 @@ Value *StraightLineStrengthReduce::emitBump(const Candidate &Basis,    // Compute Bump = C - Basis = (i' - i) * S.    // Common case 1: if (i' - i) is 1, Bump = S. -  if (IndexOffset.getSExtValue() == 1) +  if (IndexOffset == 1)      return C.Stride;    // Common case 2: if (i' - i) is -1, Bump = -S. -  if (IndexOffset.getSExtValue() == -1) +  if (IndexOffset.isAllOnesValue())      return Builder.CreateNeg(C.Stride);    // Otherwise, Bump = (i' - i) * sext/trunc(S). Note that (i' - i) and S may diff --git a/llvm/test/Transforms/StraightLineStrengthReduce/slsr-add.ll b/llvm/test/Transforms/StraightLineStrengthReduce/slsr-add.ll index e25ddc2888a..b4f448ace2a 100644 --- a/llvm/test/Transforms/StraightLineStrengthReduce/slsr-add.ll +++ b/llvm/test/Transforms/StraightLineStrengthReduce/slsr-add.ll @@ -98,4 +98,19 @@ define void @simple_enough(i32 %b, i32 %s) {    ret void  } +define void @slsr_strided_add_128bit(i128 %b, i128 %s) { +; CHECK-LABEL: @slsr_strided_add_128bit( +  %s125 = shl i128 %s, 125 +  %s126 = shl i128 %s, 126 +  %1 = add i128 %b, %s125 +; CHECK: [[t1:%[a-zA-Z0-9]+]] = add i128 %b, %s125 +  call void @bar(i128 %1) +  %2 = add i128 %b, %s126 +; CHECK: [[t2:%[a-zA-Z0-9]+]] = add i128 [[t1]], %s125 +  call void @bar(i128 %2) +; CHECK: call void @bar(i128 [[t2]]) +  ret void +} +  declare void @foo(i32) +declare void @bar(i128) diff --git a/llvm/test/Transforms/StraightLineStrengthReduce/slsr-gep.ll b/llvm/test/Transforms/StraightLineStrengthReduce/slsr-gep.ll index bd92780a036..573c33cb858 100644 --- a/llvm/test/Transforms/StraightLineStrengthReduce/slsr-gep.ll +++ b/llvm/test/Transforms/StraightLineStrengthReduce/slsr-gep.ll @@ -16,21 +16,18 @@ define void @slsr_gep(i32* %input, i64 %s) {  ; CHECK-LABEL: @slsr_gep(    ; v0 = input[0];    %p0 = getelementptr inbounds i32, i32* %input, i64 0 -  %v0 = load i32, i32* %p0 -  call void @foo(i32 %v0) +  call void @foo(i32* %p0)    ; v1 = input[s];    %p1 = getelementptr inbounds i32, i32* %input, i64 %s  ; CHECK: %p1 = getelementptr inbounds i32, i32* %input, i64 %s -  %v1 = load i32, i32* %p1 -  call void @foo(i32 %v1) +  call void @foo(i32* %p1)    ; v2 = input[s * 2];    %s2 = shl nsw i64 %s, 1    %p2 = getelementptr inbounds i32, i32* %input, i64 %s2  ; CHECK: %p2 = getelementptr inbounds i32, i32* %p1, i64 %s -  %v2 = load i32, i32* %p2 -  call void @foo(i32 %v2) +  call void @foo(i32* %p2)    ret void  } @@ -49,23 +46,20 @@ define void @slsr_gep_sext(i32* %input, i32 %s) {  ; CHECK-LABEL: @slsr_gep_sext(    ; v0 = input[0];    %p0 = getelementptr inbounds i32, i32* %input, i64 0 -  %v0 = load i32, i32* %p0 -  call void @foo(i32 %v0) +  call void @foo(i32* %p0)    ; v1 = input[s];    %t = sext i32 %s to i64    %p1 = getelementptr inbounds i32, i32* %input, i64 %t  ; CHECK: %p1 = getelementptr inbounds i32, i32* %input, i64 %t -  %v1 = load i32, i32* %p1 -  call void @foo(i32 %v1) +  call void @foo(i32* %p1)    ; v2 = input[s * 2];    %s2 = shl nsw i32 %s, 1    %t2 = sext i32 %s2 to i64    %p2 = getelementptr inbounds i32, i32* %input, i64 %t2  ; CHECK: %p2 = getelementptr inbounds i32, i32* %p1, i64 %t -  %v2 = load i32, i32* %p2 -  call void @foo(i32 %v2) +  call void @foo(i32* %p2)    ret void  } @@ -85,23 +79,20 @@ define void @slsr_gep_2d([10 x [5 x i32]]* %input, i64 %s, i64 %t) {  ; CHECK-LABEL: @slsr_gep_2d(    ; v0 = input[s][t];    %p0 = getelementptr inbounds [10 x [5 x i32]], [10 x [5 x i32]]* %input, i64 0, i64 %s, i64 %t -  %v0 = load i32, i32* %p0 -  call void @foo(i32 %v0) +  call void @foo(i32* %p0)    ; v1 = input[s * 2][t];    %s2 = shl nsw i64 %s, 1  ; CHECK: [[BUMP:%[a-zA-Z0-9]+]] = mul i64 %s, 5    %p1 = getelementptr inbounds [10 x [5 x i32]], [10 x [5 x i32]]* %input, i64 0, i64 %s2, i64 %t  ; CHECK: %p1 = getelementptr inbounds i32, i32* %p0, i64 [[BUMP]] -  %v1 = load i32, i32* %p1 -  call void @foo(i32 %v1) +  call void @foo(i32* %p1)    ; v3 = input[s * 3][t];    %s3 = mul nsw i64 %s, 3    %p2 = getelementptr inbounds [10 x [5 x i32]], [10 x [5 x i32]]* %input, i64 0, i64 %s3, i64 %t  ; CHECK: %p2 = getelementptr inbounds i32, i32* %p1, i64 [[BUMP]] -  %v2 = load i32, i32* %p2 -  call void @foo(i32 %v2) +  call void @foo(i32* %p2)    ret void  } @@ -118,23 +109,20 @@ define void @slsr_gep_uglygep([10 x [5 x %struct.S]]* %input, i64 %s, i64 %t) {  ; CHECK-LABEL: @slsr_gep_uglygep(    ; v0 = input[s][t].f1;    %p0 = getelementptr inbounds [10 x [5 x %struct.S]], [10 x [5 x %struct.S]]* %input, i64 0, i64 %s, i64 %t, i32 0 -  %v0 = load i64, i64* %p0 -  call void @bar(i64 %v0) +  call void @bar(i64* %p0)    ; v1 = input[s * 2][t].f1;    %s2 = shl nsw i64 %s, 1  ; CHECK: [[BUMP:%[a-zA-Z0-9]+]] = mul i64 %s, 60    %p1 = getelementptr inbounds [10 x [5 x %struct.S]], [10 x [5 x %struct.S]]* %input, i64 0, i64 %s2, i64 %t, i32 0  ; CHECK: getelementptr inbounds i8, i8* %{{[0-9]+}}, i64 [[BUMP]] -  %v1 = load i64, i64* %p1 -  call void @bar(i64 %v1) +  call void @bar(i64* %p1)    ; v2 = input[s * 3][t].f1;    %s3 = mul nsw i64 %s, 3    %p2 = getelementptr inbounds [10 x [5 x %struct.S]], [10 x [5 x %struct.S]]* %input, i64 0, i64 %s3, i64 %t, i32 0  ; CHECK: getelementptr inbounds i8, i8* %{{[0-9]+}}, i64 [[BUMP]] -  %v2 = load i64, i64* %p2 -  call void @bar(i64 %v2) +  call void @bar(i64* %p2)    ret void  } @@ -143,26 +131,44 @@ define void @slsr_out_of_bounds_gep(i32* %input, i32 %s) {  ; CHECK-LABEL: @slsr_out_of_bounds_gep(    ; v0 = input[0];    %p0 = getelementptr i32, i32* %input, i64 0 -  %v0 = load i32, i32* %p0 -  call void @foo(i32 %v0) +  call void @foo(i32* %p0)    ; v1 = input[(long)s];    %t = sext i32 %s to i64    %p1 = getelementptr i32, i32* %input, i64 %t  ; CHECK: %p1 = getelementptr i32, i32* %input, i64 %t -  %v1 = load i32, i32* %p1 -  call void @foo(i32 %v1) +  call void @foo(i32* %p1)    ; v2 = input[(long)(s * 2)];    %s2 = shl nsw i32 %s, 1    %t2 = sext i32 %s2 to i64    %p2 = getelementptr i32, i32* %input, i64 %t2  ; CHECK: %p2 = getelementptr i32, i32* %p1, i64 %t -  %v2 = load i32, i32* %p2 -  call void @foo(i32 %v2) +  call void @foo(i32* %p2)    ret void  } -declare void @foo(i32) -declare void @bar(i64) +define void @slsr_gep_128bit(i32* %input, i128 %s) { +; CHECK-LABEL: @slsr_gep_128bit( +  ; p0 = &input[0] +  %p0 = getelementptr inbounds i32, i32* %input, i128 0 +  call void @foo(i32* %p0) + +  ; p1 = &input[s << 125] +  %s125 = shl nsw i128 %s, 125 +  %p1 = getelementptr inbounds i32, i32* %input, i128 %s125 +; CHECK: %p1 = getelementptr inbounds i32, i32* %input, i128 %s125 +  call void @foo(i32* %p1) + +  ; p2 = &input[s << 126] +  %s126 = shl nsw i128 %s, 126 +  %p2 = getelementptr inbounds i32, i32* %input, i128 %s126 +; CHECK: %p2 = getelementptr inbounds i32, i32* %input, i128 %s126 +  call void @foo(i32* %p2) + +  ret void +} + +declare void @foo(i32*) +declare void @bar(i64*) | 

