mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-25 00:29:20 +00:00
InstSimplify: Fold gep X, (sub 0, ptrtoint(X)) to null
Save InstCombine some work if we can perform this fold during InstSimplify. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216441 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
594e4a1dd3
commit
8058ffeb18
@ -2789,14 +2789,14 @@ static Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const Query &Q, unsigned) {
|
|||||||
if (Ops.size() == 1)
|
if (Ops.size() == 1)
|
||||||
return Ops[0];
|
return Ops[0];
|
||||||
|
|
||||||
if (isa<UndefValue>(Ops[0])) {
|
// Compute the (pointer) type returned by the GEP instruction.
|
||||||
// Compute the (pointer) type returned by the GEP instruction.
|
Type *LastType = GetElementPtrInst::getIndexedType(PtrTy, Ops.slice(1));
|
||||||
Type *LastType = GetElementPtrInst::getIndexedType(PtrTy, Ops.slice(1));
|
Type *GEPTy = PointerType::get(LastType, AS);
|
||||||
Type *GEPTy = PointerType::get(LastType, AS);
|
if (VectorType *VT = dyn_cast<VectorType>(Ops[0]->getType()))
|
||||||
if (VectorType *VT = dyn_cast<VectorType>(Ops[0]->getType()))
|
GEPTy = VectorType::get(GEPTy, VT->getNumElements());
|
||||||
GEPTy = VectorType::get(GEPTy, VT->getNumElements());
|
|
||||||
|
if (isa<UndefValue>(Ops[0]))
|
||||||
return UndefValue::get(GEPTy);
|
return UndefValue::get(GEPTy);
|
||||||
}
|
|
||||||
|
|
||||||
if (Ops.size() == 2) {
|
if (Ops.size() == 2) {
|
||||||
// getelementptr P, 0 -> P.
|
// getelementptr P, 0 -> P.
|
||||||
@ -2816,26 +2816,37 @@ static Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const Query &Q, unsigned) {
|
|||||||
// doesn't truncate the pointers.
|
// doesn't truncate the pointers.
|
||||||
if (Ops[1]->getType()->getScalarSizeInBits() ==
|
if (Ops[1]->getType()->getScalarSizeInBits() ==
|
||||||
Q.DL->getPointerSizeInBits(AS)) {
|
Q.DL->getPointerSizeInBits(AS)) {
|
||||||
// getelementptr P, (sub Q, P) -> Q if P points to a type of size 1.
|
auto PtrToIntOrZero = [GEPTy](Value *P) -> Value * {
|
||||||
|
if (match(P, m_Zero()))
|
||||||
|
return Constant::getNullValue(GEPTy);
|
||||||
|
Value *Temp;
|
||||||
|
if (match(P, m_PtrToInt(m_Value(Temp))))
|
||||||
|
return Temp;
|
||||||
|
return nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
// getelementptr V, (sub P, V) -> P if P points to a type of size 1.
|
||||||
if (TyAllocSize == 1 &&
|
if (TyAllocSize == 1 &&
|
||||||
match(Ops[1], m_Sub(m_PtrToInt(m_Value(P)),
|
match(Ops[1], m_Sub(m_Value(P), m_PtrToInt(m_Specific(Ops[0])))))
|
||||||
m_PtrToInt(m_Specific(Ops[0])))))
|
if (Value *R = PtrToIntOrZero(P))
|
||||||
return P;
|
return R;
|
||||||
|
|
||||||
// getelementptr P, (ashr (sub Q, P), C) -> Q
|
// getelementptr V, (ashr (sub P, V), C) -> Q
|
||||||
// if P points to a type of size 1 << C.
|
// if P points to a type of size 1 << C.
|
||||||
if (match(Ops[1], m_AShr(m_Sub(m_PtrToInt(m_Value(P)),
|
if (match(Ops[1],
|
||||||
m_PtrToInt(m_Specific(Ops[0]))),
|
m_AShr(m_Sub(m_Value(P), m_PtrToInt(m_Specific(Ops[0]))),
|
||||||
m_ConstantInt(C))) &&
|
m_ConstantInt(C))) &&
|
||||||
TyAllocSize == 1ULL << C)
|
TyAllocSize == 1ULL << C)
|
||||||
return P;
|
if (Value *R = PtrToIntOrZero(P))
|
||||||
|
return R;
|
||||||
|
|
||||||
// getelementptr P, (sdiv (sub Q, P), C) -> Q
|
// getelementptr V, (sdiv (sub P, V), C) -> Q
|
||||||
// if P points to a type of size C.
|
// if P points to a type of size C.
|
||||||
if (match(Ops[1], m_SDiv(m_Sub(m_PtrToInt(m_Value(P)),
|
if (match(Ops[1],
|
||||||
m_PtrToInt(m_Specific(Ops[0]))),
|
m_SDiv(m_Sub(m_Value(P), m_PtrToInt(m_Specific(Ops[0]))),
|
||||||
m_SpecificInt(TyAllocSize))))
|
m_SpecificInt(TyAllocSize))))
|
||||||
return P;
|
if (Value *R = PtrToIntOrZero(P))
|
||||||
|
return R;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,3 +35,32 @@ define i64* @test3(i64* %b, i64* %e) {
|
|||||||
; CHECK-LABEL: @test3
|
; CHECK-LABEL: @test3
|
||||||
; CHECK-NEXT: ret i64* %e
|
; CHECK-NEXT: ret i64* %e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define %struct.A* @test4(%struct.A* %b) {
|
||||||
|
%b_ptr = ptrtoint %struct.A* %b to i64
|
||||||
|
%sub = sub i64 0, %b_ptr
|
||||||
|
%sdiv = sdiv exact i64 %sub, 7
|
||||||
|
%gep = getelementptr inbounds %struct.A* %b, i64 %sdiv
|
||||||
|
ret %struct.A* %gep
|
||||||
|
; CHECK-LABEL: @test4
|
||||||
|
; CHECK-NEXT: ret %struct.A* null
|
||||||
|
}
|
||||||
|
|
||||||
|
define i8* @test5(i8* %b) {
|
||||||
|
%b_ptr = ptrtoint i8* %b to i64
|
||||||
|
%sub = sub i64 0, %b_ptr
|
||||||
|
%gep = getelementptr inbounds i8* %b, i64 %sub
|
||||||
|
ret i8* %gep
|
||||||
|
; CHECK-LABEL: @test5
|
||||||
|
; CHECK-NEXT: ret i8* null
|
||||||
|
}
|
||||||
|
|
||||||
|
define i64* @test6(i64* %b) {
|
||||||
|
%b_ptr = ptrtoint i64* %b to i64
|
||||||
|
%sub = sub i64 0, %b_ptr
|
||||||
|
%ashr = ashr exact i64 %sub, 3
|
||||||
|
%gep = getelementptr inbounds i64* %b, i64 %ashr
|
||||||
|
ret i64* %gep
|
||||||
|
; CHECK-LABEL: @test6
|
||||||
|
; CHECK-NEXT: ret i64* null
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user