mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-06 06:33:24 +00:00
Teach InstCombine visitGetElementPtr about address spaces
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188721 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c4ad982f0b
commit
8e3367ea36
@ -212,8 +212,8 @@ private:
|
||||
bool ShouldChangeType(Type *From, Type *To) const;
|
||||
Value *dyn_castNegVal(Value *V) const;
|
||||
Value *dyn_castFNegVal(Value *V, bool NoSignedZero=false) const;
|
||||
Type *FindElementAtOffset(Type *Ty, int64_t Offset,
|
||||
SmallVectorImpl<Value*> &NewIndices);
|
||||
Type *FindElementAtOffset(Type *PtrTy, int64_t Offset,
|
||||
SmallVectorImpl<Value*> &NewIndices);
|
||||
Instruction *FoldOpIntoSelect(Instruction &Op, SelectInst *SI);
|
||||
|
||||
/// ShouldOptimizeCast - Return true if the cast from "V to Ty" actually
|
||||
|
@ -1385,9 +1385,10 @@ Instruction *InstCombiner::commonPointerCastTransforms(CastInst &CI) {
|
||||
GEP->accumulateConstantOffset(*TD, Offset)) {
|
||||
// Get the base pointer input of the bitcast, and the type it points to.
|
||||
Value *OrigBase = BCI->getOperand(0);
|
||||
Type *GEPIdxTy = OrigBase->getType()->getPointerElementType();
|
||||
SmallVector<Value*, 8> NewIndices;
|
||||
if (FindElementAtOffset(GEPIdxTy, Offset.getSExtValue(), NewIndices)) {
|
||||
if (FindElementAtOffset(OrigBase->getType(),
|
||||
Offset.getSExtValue(),
|
||||
NewIndices)) {
|
||||
// If we were able to index down into an element, create the GEP
|
||||
// and bitcast the result. This eliminates one bitcast, potentially
|
||||
// two.
|
||||
|
@ -755,19 +755,25 @@ Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) {
|
||||
return ReplaceInstUsesWith(I, NewPN);
|
||||
}
|
||||
|
||||
/// FindElementAtOffset - Given a type and a constant offset, determine whether
|
||||
/// or not there is a sequence of GEP indices into the type that will land us at
|
||||
/// the specified offset. If so, fill them into NewIndices and return the
|
||||
/// resultant element type, otherwise return null.
|
||||
Type *InstCombiner::FindElementAtOffset(Type *Ty, int64_t Offset,
|
||||
SmallVectorImpl<Value*> &NewIndices) {
|
||||
if (!TD) return 0;
|
||||
if (!Ty->isSized()) return 0;
|
||||
/// FindElementAtOffset - Given a pointer type and a constant offset, determine
|
||||
/// whether or not there is a sequence of GEP indices into the pointed type that
|
||||
/// will land us at the specified offset. If so, fill them into NewIndices and
|
||||
/// return the resultant element type, otherwise return null.
|
||||
Type *InstCombiner::FindElementAtOffset(Type *PtrTy, int64_t Offset,
|
||||
SmallVectorImpl<Value*> &NewIndices) {
|
||||
assert(PtrTy->isPtrOrPtrVectorTy());
|
||||
|
||||
if (!TD)
|
||||
return 0;
|
||||
|
||||
Type *Ty = PtrTy->getPointerElementType();
|
||||
if (!Ty->isSized())
|
||||
return 0;
|
||||
|
||||
// Start with the index over the outer type. Note that the type size
|
||||
// might be zero (even if the offset isn't zero) if the indexed type
|
||||
// is something like [0 x {int, int}]
|
||||
Type *IntPtrTy = TD->getIntPtrType(Ty->getContext());
|
||||
Type *IntPtrTy = TD->getIntPtrType(PtrTy);
|
||||
int64_t FirstIdx = 0;
|
||||
if (int64_t TySize = TD->getTypeAllocSize(Ty)) {
|
||||
FirstIdx = Offset/TySize;
|
||||
@ -1235,7 +1241,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
||||
if (TD && SrcElTy->isArrayTy() &&
|
||||
TD->getTypeAllocSize(SrcElTy->getArrayElementType()) ==
|
||||
TD->getTypeAllocSize(ResElTy)) {
|
||||
Type *IdxType = TD->getIntPtrType(GEP.getContext());
|
||||
Type *IdxType = TD->getIntPtrType(GEP.getType());
|
||||
Value *Idx[2] = { Constant::getNullValue(IdxType), GEP.getOperand(1) };
|
||||
Value *NewGEP = GEP.isInBounds() ?
|
||||
Builder->CreateInBoundsGEP(StrippedPtr, Idx, GEP.getName()) :
|
||||
@ -1260,7 +1266,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
||||
|
||||
// Earlier transforms ensure that the index has type IntPtrType, which
|
||||
// considerably simplifies the logic by eliminating implicit casts.
|
||||
assert(Idx->getType() == TD->getIntPtrType(GEP.getContext()) &&
|
||||
assert(Idx->getType() == TD->getIntPtrType(GEP.getType()) &&
|
||||
"Index not cast to pointer width?");
|
||||
|
||||
bool NSW;
|
||||
@ -1295,7 +1301,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
||||
|
||||
// Earlier transforms ensure that the index has type IntPtrType, which
|
||||
// considerably simplifies the logic by eliminating implicit casts.
|
||||
assert(Idx->getType() == TD->getIntPtrType(GEP.getContext()) &&
|
||||
assert(Idx->getType() == TD->getIntPtrType(GEP.getType()) &&
|
||||
"Index not cast to pointer width?");
|
||||
|
||||
bool NSW;
|
||||
@ -1304,7 +1310,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
||||
// If the multiplication NewIdx * Scale may overflow then the new
|
||||
// GEP may not be "inbounds".
|
||||
Value *Off[2] = {
|
||||
Constant::getNullValue(TD->getIntPtrType(GEP.getContext())),
|
||||
Constant::getNullValue(TD->getIntPtrType(GEP.getType())),
|
||||
NewIdx
|
||||
};
|
||||
|
||||
@ -1330,7 +1336,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
||||
if (BitCastInst *BCI = dyn_cast<BitCastInst>(PtrOp)) {
|
||||
Value *Operand = BCI->getOperand(0);
|
||||
PointerType *OpType = cast<PointerType>(Operand->getType());
|
||||
unsigned OffsetBits = TD->getPointerSizeInBits();
|
||||
unsigned OffsetBits = TD->getPointerTypeSizeInBits(OpType);
|
||||
APInt Offset(OffsetBits, 0);
|
||||
if (!isa<BitCastInst>(Operand) &&
|
||||
GEP.accumulateConstantOffset(*TD, Offset) &&
|
||||
@ -1359,8 +1365,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
||||
// field at Offset in 'A's type. If so, we can pull the cast through the
|
||||
// GEP.
|
||||
SmallVector<Value*, 8> NewIndices;
|
||||
Type *InTy = OpType->getElementType();
|
||||
if (FindElementAtOffset(InTy, Offset.getSExtValue(), NewIndices)) {
|
||||
if (FindElementAtOffset(OpType, Offset.getSExtValue(), NewIndices)) {
|
||||
Value *NGEP = GEP.isInBounds() ?
|
||||
Builder->CreateInBoundsGEP(Operand, NewIndices) :
|
||||
Builder->CreateGEP(Operand, NewIndices);
|
||||
|
@ -1,6 +1,6 @@
|
||||
; Tests to make sure elimination of casts is working correctly
|
||||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64"
|
||||
target datalayout = "E-p:64:64:64-p1:32:32:32-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n8:16:32:64"
|
||||
|
||||
@inbuf = external global [32832 x i8] ; <[32832 x i8]*> [#uses=1]
|
||||
|
||||
@ -708,6 +708,19 @@ define %s @test68(%s *%p, i64 %i) {
|
||||
; CHECK-NEXT: ret %s
|
||||
}
|
||||
|
||||
define %s @test68_as1(%s addrspace(1)* %p, i32 %i) {
|
||||
; CHECK-LABEL: @test68_as1(
|
||||
%o = mul i32 %i, 12
|
||||
%q = bitcast %s addrspace(1)* %p to i8 addrspace(1)*
|
||||
%pp = getelementptr inbounds i8 addrspace(1)* %q, i32 %o
|
||||
; CHECK-NEXT: getelementptr %s addrspace(1)*
|
||||
%r = bitcast i8 addrspace(1)* %pp to %s addrspace(1)*
|
||||
%l = load %s addrspace(1)* %r
|
||||
; CHECK-NEXT: load %s addrspace(1)*
|
||||
ret %s %l
|
||||
; CHECK-NEXT: ret %s
|
||||
}
|
||||
|
||||
define double @test69(double *%p, i64 %i) {
|
||||
; CHECK-LABEL: @test69(
|
||||
%o = shl nsw i64 %i, 3
|
||||
@ -890,6 +903,20 @@ define double @test80([100 x double]* %p, i32 %i) {
|
||||
; CHECK-NEXT: ret double
|
||||
}
|
||||
|
||||
define double @test80_as1([100 x double] addrspace(1)* %p, i16 %i) {
|
||||
; CHECK-LABEL: @test80_as1(
|
||||
%tmp = mul nsw i16 %i, 8
|
||||
; CHECK-NEXT: sext i16 %i to i32
|
||||
%q = bitcast [100 x double] addrspace(1)* %p to i8 addrspace(1)*
|
||||
%pp = getelementptr i8 addrspace(1)* %q, i16 %tmp
|
||||
; CHECK-NEXT: getelementptr [100 x double] addrspace(1)*
|
||||
%r = bitcast i8 addrspace(1)* %pp to double addrspace(1)*
|
||||
%l = load double addrspace(1)* %r
|
||||
; CHECK-NEXT: load double addrspace(1)*
|
||||
ret double %l
|
||||
; CHECK-NEXT: ret double
|
||||
}
|
||||
|
||||
define double @test81(double *%p, float %f) {
|
||||
%i = fptosi float %f to i64
|
||||
%q = bitcast double* %p to i8*
|
||||
|
Loading…
x
Reference in New Issue
Block a user