mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-29 13:24:25 +00:00
Revert "Teach the load analysis to allow finding available values which require" (r220277)
This seems to have caused PR21330. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220349 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -1246,18 +1246,6 @@ public:
|
|||||||
return Insert(Folder.CreateIntCast(VC, DestTy, isSigned), Name);
|
return Insert(Folder.CreateIntCast(VC, DestTy, isSigned), Name);
|
||||||
return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name);
|
return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *CreateBitOrPointerCast(Value *V, Type *DestTy,
|
|
||||||
const Twine &Name = "") {
|
|
||||||
if (V->getType() == DestTy)
|
|
||||||
return V;
|
|
||||||
if (V->getType()->isPointerTy() && DestTy->isIntegerTy())
|
|
||||||
return CreatePtrToInt(V, DestTy, Name);
|
|
||||||
if (V->getType()->isIntegerTy() && DestTy->isPointerTy())
|
|
||||||
return CreateIntToPtr(V, DestTy, Name);
|
|
||||||
|
|
||||||
return CreateBitCast(V, DestTy, Name);
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
// \brief Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a
|
// \brief Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a
|
||||||
// compile time error, instead of converting the string to bool for the
|
// compile time error, instead of converting the string to bool for the
|
||||||
|
@ -490,19 +490,6 @@ public:
|
|||||||
Instruction *InsertBefore = 0 ///< Place to insert the instruction
|
Instruction *InsertBefore = 0 ///< Place to insert the instruction
|
||||||
);
|
);
|
||||||
|
|
||||||
/// @brief Create a BitCast, a PtrToInt, or an IntToPTr cast instruction.
|
|
||||||
///
|
|
||||||
/// If the value is a pointer type and the destination an integer type,
|
|
||||||
/// creates a PtrToInt cast. If the value is an integer type and the
|
|
||||||
/// destination a pointer type, creates an IntToPtr cast. Otherwise, creates
|
|
||||||
/// a bitcast.
|
|
||||||
static CastInst *CreateBitOrPointerCast(
|
|
||||||
Value *S, ///< The pointer value to be casted (operand 0)
|
|
||||||
Type *Ty, ///< The type to which cast should be made
|
|
||||||
const Twine &Name = "", ///< Name for the instruction
|
|
||||||
Instruction *InsertBefore = 0 ///< Place to insert the instruction
|
|
||||||
);
|
|
||||||
|
|
||||||
/// @brief Create a ZExt, BitCast, or Trunc for int -> int casts.
|
/// @brief Create a ZExt, BitCast, or Trunc for int -> int casts.
|
||||||
static CastInst *CreateIntegerCast(
|
static CastInst *CreateIntegerCast(
|
||||||
Value *S, ///< The pointer value to be casted (operand 0)
|
Value *S, ///< The pointer value to be casted (operand 0)
|
||||||
@ -565,17 +552,6 @@ public:
|
|||||||
Type *DestTy ///< The Type to which the value should be cast.
|
Type *DestTy ///< The Type to which the value should be cast.
|
||||||
);
|
);
|
||||||
|
|
||||||
/// @brief Check whether a bitcast, inttoptr, or ptrtoint cast between these
|
|
||||||
/// types is valid and a no-op.
|
|
||||||
///
|
|
||||||
/// This ensures that any pointer<->integer cast has enough bits in the
|
|
||||||
/// integer and any other cast is a bitcast.
|
|
||||||
static bool isBitOrNoopPointerCastable(
|
|
||||||
Type *SrcTy, ///< The Type from which the value should be cast.
|
|
||||||
Type *DestTy, ///< The Type to which the value should be cast.
|
|
||||||
const DataLayout *Layout = 0 ///< Optional DataLayout.
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Returns the opcode necessary to cast Val into Ty using usual casting
|
/// Returns the opcode necessary to cast Val into Ty using usual casting
|
||||||
/// rules.
|
/// rules.
|
||||||
/// @brief Infer the opcode for cast operand and type
|
/// @brief Infer the opcode for cast operand and type
|
||||||
|
@ -176,13 +176,8 @@ Value *llvm::FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB,
|
|||||||
|
|
||||||
Type *AccessTy = cast<PointerType>(Ptr->getType())->getElementType();
|
Type *AccessTy = cast<PointerType>(Ptr->getType())->getElementType();
|
||||||
|
|
||||||
// Try to get the DataLayout for this module. This may be null, in which case
|
// If we're using alias analysis to disambiguate get the size of *Ptr.
|
||||||
// the optimizations will be limited.
|
uint64_t AccessSize = AA ? AA->getTypeStoreSize(AccessTy) : 0;
|
||||||
const DataLayout *DL = ScanBB->getDataLayout();
|
|
||||||
|
|
||||||
// Try to get the store size for the type.
|
|
||||||
uint64_t AccessSize = DL ? DL->getTypeStoreSize(AccessTy)
|
|
||||||
: AA ? AA->getTypeStoreSize(AccessTy) : 0;
|
|
||||||
|
|
||||||
Value *StrippedPtr = Ptr->stripPointerCasts();
|
Value *StrippedPtr = Ptr->stripPointerCasts();
|
||||||
|
|
||||||
@ -207,7 +202,7 @@ Value *llvm::FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB,
|
|||||||
if (LoadInst *LI = dyn_cast<LoadInst>(Inst))
|
if (LoadInst *LI = dyn_cast<LoadInst>(Inst))
|
||||||
if (AreEquivalentAddressValues(
|
if (AreEquivalentAddressValues(
|
||||||
LI->getPointerOperand()->stripPointerCasts(), StrippedPtr) &&
|
LI->getPointerOperand()->stripPointerCasts(), StrippedPtr) &&
|
||||||
CastInst::isBitOrNoopPointerCastable(LI->getType(), AccessTy, DL)) {
|
CastInst::isBitCastable(LI->getType(), AccessTy)) {
|
||||||
if (AATags)
|
if (AATags)
|
||||||
LI->getAAMetadata(*AATags);
|
LI->getAAMetadata(*AATags);
|
||||||
return LI;
|
return LI;
|
||||||
@ -219,8 +214,7 @@ Value *llvm::FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB,
|
|||||||
// (This is true even if the store is volatile or atomic, although
|
// (This is true even if the store is volatile or atomic, although
|
||||||
// those cases are unlikely.)
|
// those cases are unlikely.)
|
||||||
if (AreEquivalentAddressValues(StorePtr, StrippedPtr) &&
|
if (AreEquivalentAddressValues(StorePtr, StrippedPtr) &&
|
||||||
CastInst::isBitOrNoopPointerCastable(SI->getValueOperand()->getType(),
|
CastInst::isBitCastable(SI->getValueOperand()->getType(), AccessTy)) {
|
||||||
AccessTy, DL)) {
|
|
||||||
if (AATags)
|
if (AATags)
|
||||||
SI->getAAMetadata(*AATags);
|
SI->getAAMetadata(*AATags);
|
||||||
return SI->getOperand(0);
|
return SI->getOperand(0);
|
||||||
|
@ -2559,17 +2559,6 @@ CastInst *CastInst::CreatePointerBitCastOrAddrSpaceCast(
|
|||||||
return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
|
return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
|
||||||
}
|
}
|
||||||
|
|
||||||
CastInst *CastInst::CreateBitOrPointerCast(Value *S, Type *Ty,
|
|
||||||
const Twine &Name,
|
|
||||||
Instruction *InsertBefore) {
|
|
||||||
if (S->getType()->isPointerTy() && Ty->isIntegerTy())
|
|
||||||
return Create(Instruction::PtrToInt, S, Ty, Name, InsertBefore);
|
|
||||||
if (S->getType()->isIntegerTy() && Ty->isPointerTy())
|
|
||||||
return Create(Instruction::IntToPtr, S, Ty, Name, InsertBefore);
|
|
||||||
|
|
||||||
return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
|
|
||||||
}
|
|
||||||
|
|
||||||
CastInst *CastInst::CreateIntegerCast(Value *C, Type *Ty,
|
CastInst *CastInst::CreateIntegerCast(Value *C, Type *Ty,
|
||||||
bool isSigned, const Twine &Name,
|
bool isSigned, const Twine &Name,
|
||||||
Instruction *InsertBefore) {
|
Instruction *InsertBefore) {
|
||||||
@ -2727,18 +2716,6 @@ bool CastInst::isBitCastable(Type *SrcTy, Type *DestTy) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CastInst::isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy,
|
|
||||||
const DataLayout *DL) {
|
|
||||||
if (auto *PtrTy = dyn_cast<PointerType>(SrcTy))
|
|
||||||
if (auto *IntTy = dyn_cast<IntegerType>(DestTy))
|
|
||||||
return DL && IntTy->getBitWidth() >= DL->getPointerTypeSizeInBits(PtrTy);
|
|
||||||
if (auto *PtrTy = dyn_cast<PointerType>(DestTy))
|
|
||||||
if (auto *IntTy = dyn_cast<IntegerType>(SrcTy))
|
|
||||||
return DL && IntTy->getBitWidth() >= DL->getPointerTypeSizeInBits(PtrTy);
|
|
||||||
|
|
||||||
return isBitCastable(SrcTy, DestTy);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provide a way to get a "cast" where the cast opcode is inferred from the
|
// Provide a way to get a "cast" where the cast opcode is inferred from the
|
||||||
// types and size of the operand. This, basically, is a parallel of the
|
// types and size of the operand. This, basically, is a parallel of the
|
||||||
// logic in the castIsValid function below. This axiom should hold:
|
// logic in the castIsValid function below. This axiom should hold:
|
||||||
|
@ -418,8 +418,7 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
|
|||||||
BasicBlock::iterator BBI = &LI;
|
BasicBlock::iterator BBI = &LI;
|
||||||
if (Value *AvailableVal = FindAvailableLoadedValue(Op, LI.getParent(), BBI,6))
|
if (Value *AvailableVal = FindAvailableLoadedValue(Op, LI.getParent(), BBI,6))
|
||||||
return ReplaceInstUsesWith(
|
return ReplaceInstUsesWith(
|
||||||
LI, Builder->CreateBitOrPointerCast(AvailableVal, LI.getType(),
|
LI, Builder->CreateBitCast(AvailableVal, LI.getType()));
|
||||||
LI.getName() + ".cast"));
|
|
||||||
|
|
||||||
// load(gep null, ...) -> unreachable
|
// load(gep null, ...) -> unreachable
|
||||||
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(Op)) {
|
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(Op)) {
|
||||||
|
@ -902,8 +902,8 @@ bool JumpThreading::SimplifyPartiallyRedundantLoad(LoadInst *LI) {
|
|||||||
// only happen in dead loops.
|
// only happen in dead loops.
|
||||||
if (AvailableVal == LI) AvailableVal = UndefValue::get(LI->getType());
|
if (AvailableVal == LI) AvailableVal = UndefValue::get(LI->getType());
|
||||||
if (AvailableVal->getType() != LI->getType())
|
if (AvailableVal->getType() != LI->getType())
|
||||||
AvailableVal =
|
AvailableVal = CastInst::Create(CastInst::BitCast, AvailableVal,
|
||||||
CastInst::CreateBitOrPointerCast(AvailableVal, LI->getType(), "", LI);
|
LI->getType(), "", LI);
|
||||||
LI->replaceAllUsesWith(AvailableVal);
|
LI->replaceAllUsesWith(AvailableVal);
|
||||||
LI->eraseFromParent();
|
LI->eraseFromParent();
|
||||||
return true;
|
return true;
|
||||||
@ -1040,7 +1040,7 @@ bool JumpThreading::SimplifyPartiallyRedundantLoad(LoadInst *LI) {
|
|||||||
// predecessor use the same bitcast.
|
// predecessor use the same bitcast.
|
||||||
Value *&PredV = I->second;
|
Value *&PredV = I->second;
|
||||||
if (PredV->getType() != LI->getType())
|
if (PredV->getType() != LI->getType())
|
||||||
PredV = CastInst::CreateBitOrPointerCast(PredV, LI->getType(), "",
|
PredV = CastInst::Create(CastInst::BitCast, PredV, LI->getType(), "",
|
||||||
P->getTerminator());
|
P->getTerminator());
|
||||||
|
|
||||||
PN->addIncoming(PredV, I->first);
|
PN->addIncoming(PredV, I->first);
|
||||||
|
@ -1256,7 +1256,7 @@ define i32 @test76(i1 %flag, i32* %x) {
|
|||||||
ret i32 %v
|
ret i32 %v
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @scribble_on_i32(i32*)
|
declare void @scribble_on_memory(i32*)
|
||||||
|
|
||||||
define i32 @test77(i1 %flag, i32* %x) {
|
define i32 @test77(i1 %flag, i32* %x) {
|
||||||
; The load here must not be speculated around the select. One side of the
|
; The load here must not be speculated around the select. One side of the
|
||||||
@ -1264,13 +1264,13 @@ define i32 @test77(i1 %flag, i32* %x) {
|
|||||||
; load does.
|
; load does.
|
||||||
; CHECK-LABEL: @test77(
|
; CHECK-LABEL: @test77(
|
||||||
; CHECK: %[[A:.*]] = alloca i32, align 1
|
; CHECK: %[[A:.*]] = alloca i32, align 1
|
||||||
; CHECK: call void @scribble_on_i32(i32* %[[A]])
|
; CHECK: call void @scribble_on_memory(i32* %[[A]])
|
||||||
; CHECK: store i32 0, i32* %x
|
; CHECK: store i32 0, i32* %x
|
||||||
; CHECK: %[[P:.*]] = select i1 %flag, i32* %[[A]], i32* %x
|
; CHECK: %[[P:.*]] = select i1 %flag, i32* %[[A]], i32* %x
|
||||||
; CHECK: load i32* %[[P]]
|
; CHECK: load i32* %[[P]]
|
||||||
|
|
||||||
%under_aligned = alloca i32, align 1
|
%under_aligned = alloca i32, align 1
|
||||||
call void @scribble_on_i32(i32* %under_aligned)
|
call void @scribble_on_memory(i32* %under_aligned)
|
||||||
store i32 0, i32* %x
|
store i32 0, i32* %x
|
||||||
%p = select i1 %flag, i32* %under_aligned, i32* %x
|
%p = select i1 %flag, i32* %under_aligned, i32* %x
|
||||||
%v = load i32* %p
|
%v = load i32* %p
|
||||||
@ -1327,8 +1327,8 @@ define i32 @test80(i1 %flag) {
|
|||||||
entry:
|
entry:
|
||||||
%x = alloca i32
|
%x = alloca i32
|
||||||
%y = alloca i32
|
%y = alloca i32
|
||||||
call void @scribble_on_i32(i32* %x)
|
call void @scribble_on_memory(i32* %x)
|
||||||
call void @scribble_on_i32(i32* %y)
|
call void @scribble_on_memory(i32* %y)
|
||||||
%tmp = load i32* %x
|
%tmp = load i32* %x
|
||||||
store i32 %tmp, i32* %y
|
store i32 %tmp, i32* %y
|
||||||
%p = select i1 %flag, i32* %x, i32* %y
|
%p = select i1 %flag, i32* %x, i32* %y
|
||||||
@ -1351,8 +1351,8 @@ entry:
|
|||||||
%y = alloca i32
|
%y = alloca i32
|
||||||
%x1 = bitcast float* %x to i32*
|
%x1 = bitcast float* %x to i32*
|
||||||
%y1 = bitcast i32* %y to float*
|
%y1 = bitcast i32* %y to float*
|
||||||
call void @scribble_on_i32(i32* %x1)
|
call void @scribble_on_memory(i32* %x1)
|
||||||
call void @scribble_on_i32(i32* %y)
|
call void @scribble_on_memory(i32* %y)
|
||||||
%tmp = load i32* %x1
|
%tmp = load i32* %x1
|
||||||
store i32 %tmp, i32* %y
|
store i32 %tmp, i32* %y
|
||||||
%p = select i1 %flag, float* %x, float* %y1
|
%p = select i1 %flag, float* %x, float* %y1
|
||||||
@ -1377,63 +1377,11 @@ entry:
|
|||||||
%y = alloca i32
|
%y = alloca i32
|
||||||
%x1 = bitcast float* %x to i32*
|
%x1 = bitcast float* %x to i32*
|
||||||
%y1 = bitcast i32* %y to float*
|
%y1 = bitcast i32* %y to float*
|
||||||
call void @scribble_on_i32(i32* %x1)
|
call void @scribble_on_memory(i32* %x1)
|
||||||
call void @scribble_on_i32(i32* %y)
|
call void @scribble_on_memory(i32* %y)
|
||||||
%tmp = load float* %x
|
%tmp = load float* %x
|
||||||
store float %tmp, float* %y1
|
store float %tmp, float* %y1
|
||||||
%p = select i1 %flag, i32* %x1, i32* %y
|
%p = select i1 %flag, i32* %x1, i32* %y
|
||||||
%v = load i32* %p
|
%v = load i32* %p
|
||||||
ret i32 %v
|
ret i32 %v
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @scribble_on_i64(i64*)
|
|
||||||
|
|
||||||
define i8* @test83(i1 %flag) {
|
|
||||||
; Test that we can speculate the load around the select even though they use
|
|
||||||
; differently typed pointers and requires inttoptr casts.
|
|
||||||
; CHECK-LABEL: @test83(
|
|
||||||
; CHECK: %[[X:.*]] = alloca i8*
|
|
||||||
; CHECK-NEXT: %[[Y:.*]] = alloca i8*
|
|
||||||
; CHECK: %[[V:.*]] = load i64* %[[X]]
|
|
||||||
; CHECK-NEXT: %[[C1:.*]] = inttoptr i64 %[[V]] to i8*
|
|
||||||
; CHECK-NEXT: store i8* %[[C1]], i8** %[[Y]]
|
|
||||||
; CHECK-NEXT: %[[C2:.*]] = inttoptr i64 %[[V]] to i8*
|
|
||||||
; CHECK-NEXT: %[[S:.*]] = select i1 %flag, i8* %[[C2]], i8* %[[C1]]
|
|
||||||
; CHECK-NEXT: ret i8* %[[S]]
|
|
||||||
entry:
|
|
||||||
%x = alloca i8*
|
|
||||||
%y = alloca i64
|
|
||||||
%x1 = bitcast i8** %x to i64*
|
|
||||||
%y1 = bitcast i64* %y to i8**
|
|
||||||
call void @scribble_on_i64(i64* %x1)
|
|
||||||
call void @scribble_on_i64(i64* %y)
|
|
||||||
%tmp = load i64* %x1
|
|
||||||
store i64 %tmp, i64* %y
|
|
||||||
%p = select i1 %flag, i8** %x, i8** %y1
|
|
||||||
%v = load i8** %p
|
|
||||||
ret i8* %v
|
|
||||||
}
|
|
||||||
|
|
||||||
define i64 @test84(i1 %flag) {
|
|
||||||
; Test that we can speculate the load around the select even though they use
|
|
||||||
; differently typed pointers and requires a ptrtoint cast.
|
|
||||||
; CHECK-LABEL: @test84(
|
|
||||||
; CHECK: %[[X:.*]] = alloca i8*
|
|
||||||
; CHECK-NEXT: %[[Y:.*]] = alloca i8*
|
|
||||||
; CHECK: %[[V:.*]] = load i8** %[[X]]
|
|
||||||
; CHECK-NEXT: store i8* %[[V]], i8** %[[Y]]
|
|
||||||
; CHECK-NEXT: %[[C:.*]] = ptrtoint i8* %[[V]] to i64
|
|
||||||
; CHECK-NEXT: ret i64 %[[C]]
|
|
||||||
entry:
|
|
||||||
%x = alloca i8*
|
|
||||||
%y = alloca i64
|
|
||||||
%x1 = bitcast i8** %x to i64*
|
|
||||||
%y1 = bitcast i64* %y to i8**
|
|
||||||
call void @scribble_on_i64(i64* %x1)
|
|
||||||
call void @scribble_on_i64(i64* %y)
|
|
||||||
%tmp = load i8** %x
|
|
||||||
store i8* %tmp, i8** %y1
|
|
||||||
%p = select i1 %flag, i64* %x1, i64* %y
|
|
||||||
%v = load i64* %p
|
|
||||||
ret i64 %v
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user