mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-12 14:17:59 +00:00
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@274982 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ed029b06bb
commit
9dd11bf890
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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*)
|
||||
|
Loading…
Reference in New Issue
Block a user