diff options
-rw-r--r-- | llvm/lib/Analysis/ConstantFolding.cpp | 11 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/getelementptr.ll | 8 |
2 files changed, 9 insertions, 10 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index bf0cb3e1a18..20370d23b7c 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -845,15 +845,18 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP, // Determine which element of the array the offset points into. APInt ElemSize(BitWidth, DL.getTypeAllocSize(Ty)); - if (ElemSize == 0) + if (ElemSize == 0) { // The element size is 0. This may be [0 x Ty]*, so just use a zero // index for this level and proceed to the next level to see if it can // accommodate the offset. NewIdxs.push_back(ConstantInt::get(IntPtrTy, 0)); - else { + } else if (ElemSize.isAllOnesValue()) { + // Avoid signed overflow. + break; + } else { // The element size is non-zero divide the offset by the element // size (rounding down), to compute the index at this level. - APInt NewIdx = Offset.udiv(ElemSize); + APInt NewIdx = Offset.sdiv(ElemSize); Offset -= NewIdx * ElemSize; NewIdxs.push_back(ConstantInt::get(IntPtrTy, NewIdx)); } @@ -864,7 +867,7 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP, // operand likely went through casts that are necessary to make the GEP // sensible. const StructLayout &SL = *DL.getStructLayout(STy); - if (Offset.uge(SL.getSizeInBytes())) + if (Offset.isNegative() || Offset.uge(SL.getSizeInBytes())) break; // Determine which field of the struct the offset points into. The diff --git a/llvm/test/Transforms/InstCombine/getelementptr.ll b/llvm/test/Transforms/InstCombine/getelementptr.ll index 276ada91f3c..7446734e210 100644 --- a/llvm/test/Transforms/InstCombine/getelementptr.ll +++ b/llvm/test/Transforms/InstCombine/getelementptr.ll @@ -624,15 +624,11 @@ define i32 @test35() nounwind { ; CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @"\01LC8", i64 0, i64 0), i8* getelementptr inbounds (%t0, %t0* @s, i64 0, i32 1, i64 0)) [[NUW:#[0-9]+]] } -; Instcombine should constant-fold the GEP so that indices that have -; static array extents are within bounds of those array extents. -; In the below, -1 is not in the range [0,11). After the transformation, -; the same address is computed, but 3 is in the range of [0,11). - +; Don't treat signed offsets as unsigned. define i8* @test36() nounwind { ret i8* getelementptr ([11 x i8], [11 x i8]* @array, i32 0, i64 -1) ; CHECK-LABEL: @test36( -; CHECK: ret i8* getelementptr ([11 x i8], [11 x i8]* @array, i64 1676976733973595601, i64 4) +; CHECK: ret i8* getelementptr ([11 x i8], [11 x i8]* @array, i64 0, i64 -1) } ; Instcombine shouldn't assume that gep(A,0,1) != gep(A,1,0). |