mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-03 19:02:35 +00:00
Teach lint about address spaces
llvm-svn: 203132
This commit is contained in:
parent
7d4ecf1273
commit
1c2aa9b94e
@ -582,6 +582,11 @@ public:
|
|||||||
Type *IntPtrTy ///< Integer type corresponding to pointer
|
Type *IntPtrTy ///< Integer type corresponding to pointer
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
/// @brief Determine if this cast is a no-op cast.
|
||||||
|
bool isNoopCast(
|
||||||
|
const DataLayout *DL ///< DataLayout to get the Int Ptr type from.
|
||||||
|
) const;
|
||||||
|
|
||||||
/// Determine how a pair of casts can be eliminated, if they can be at all.
|
/// Determine how a pair of casts can be eliminated, if they can be at all.
|
||||||
/// This is a helper function for both CastInst and ConstantExpr.
|
/// This is a helper function for both CastInst and ConstantExpr.
|
||||||
/// @returns 0 if the CastInst pair can't be eliminated, otherwise
|
/// @returns 0 if the CastInst pair can't be eliminated, otherwise
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
// those aren't comprehensive either. Second, many conditions cannot be
|
// those aren't comprehensive either. Second, many conditions cannot be
|
||||||
// checked statically. This pass does no dynamic instrumentation, so it
|
// checked statically. This pass does no dynamic instrumentation, so it
|
||||||
// can't check for all possible problems.
|
// can't check for all possible problems.
|
||||||
//
|
//
|
||||||
// Another limitation is that it assumes all code will be executed. A store
|
// Another limitation is that it assumes all code will be executed. A store
|
||||||
// through a null pointer in a basic block which is never reached is harmless,
|
// through a null pointer in a basic block which is never reached is harmless,
|
||||||
// but this pass will warn about it anyway. This is the main reason why most
|
// but this pass will warn about it anyway. This is the main reason why most
|
||||||
@ -26,12 +26,12 @@
|
|||||||
// less obvious. If an optimization pass appears to be introducing a warning,
|
// less obvious. If an optimization pass appears to be introducing a warning,
|
||||||
// it may be that the optimization pass is merely exposing an existing
|
// it may be that the optimization pass is merely exposing an existing
|
||||||
// condition in the code.
|
// condition in the code.
|
||||||
//
|
//
|
||||||
// This code may be run before instcombine. In many cases, instcombine checks
|
// This code may be run before instcombine. In many cases, instcombine checks
|
||||||
// for the same kinds of things and turns instructions with undefined behavior
|
// for the same kinds of things and turns instructions with undefined behavior
|
||||||
// into unreachable (or equivalent). Because of this, this pass makes some
|
// into unreachable (or equivalent). Because of this, this pass makes some
|
||||||
// effort to look through bitcasts and so on.
|
// effort to look through bitcasts and so on.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/Analysis/Lint.h"
|
#include "llvm/Analysis/Lint.h"
|
||||||
@ -652,8 +652,7 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk,
|
|||||||
if (W != V)
|
if (W != V)
|
||||||
return findValueImpl(W, OffsetOk, Visited);
|
return findValueImpl(W, OffsetOk, Visited);
|
||||||
} else if (CastInst *CI = dyn_cast<CastInst>(V)) {
|
} else if (CastInst *CI = dyn_cast<CastInst>(V)) {
|
||||||
if (CI->isNoopCast(DL ? DL->getIntPtrType(V->getContext()) :
|
if (CI->isNoopCast(DL))
|
||||||
Type::getInt64Ty(V->getContext())))
|
|
||||||
return findValueImpl(CI->getOperand(0), OffsetOk, Visited);
|
return findValueImpl(CI->getOperand(0), OffsetOk, Visited);
|
||||||
} else if (ExtractValueInst *Ex = dyn_cast<ExtractValueInst>(V)) {
|
} else if (ExtractValueInst *Ex = dyn_cast<ExtractValueInst>(V)) {
|
||||||
if (Value *W = FindInsertedValue(Ex->getAggregateOperand(),
|
if (Value *W = FindInsertedValue(Ex->getAggregateOperand(),
|
||||||
@ -666,7 +665,7 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk,
|
|||||||
if (CastInst::isNoopCast(Instruction::CastOps(CE->getOpcode()),
|
if (CastInst::isNoopCast(Instruction::CastOps(CE->getOpcode()),
|
||||||
CE->getOperand(0)->getType(),
|
CE->getOperand(0)->getType(),
|
||||||
CE->getType(),
|
CE->getType(),
|
||||||
DL ? DL->getIntPtrType(V->getContext()) :
|
DL ? DL->getIntPtrType(V->getType()) :
|
||||||
Type::getInt64Ty(V->getContext())))
|
Type::getInt64Ty(V->getContext())))
|
||||||
return findValueImpl(CE->getOperand(0), OffsetOk, Visited);
|
return findValueImpl(CE->getOperand(0), OffsetOk, Visited);
|
||||||
} else if (CE->getOpcode() == Instruction::ExtractValue) {
|
} else if (CE->getOpcode() == Instruction::ExtractValue) {
|
||||||
|
@ -2115,8 +2115,27 @@ bool CastInst::isNoopCast(Type *IntPtrTy) const {
|
|||||||
return isNoopCast(getOpcode(), getOperand(0)->getType(), getType(), IntPtrTy);
|
return isNoopCast(getOpcode(), getOperand(0)->getType(), getType(), IntPtrTy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function determines if a pair of casts can be eliminated and what
|
bool CastInst::isNoopCast(const DataLayout *DL) const {
|
||||||
/// opcode should be used in the elimination. This assumes that there are two
|
if (!DL) {
|
||||||
|
// Assume maximum pointer size.
|
||||||
|
return isNoopCast(Type::getInt64Ty(getContext()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Type *PtrOpTy = 0;
|
||||||
|
if (getOpcode() == Instruction::PtrToInt)
|
||||||
|
PtrOpTy = getOperand(0)->getType();
|
||||||
|
else if (getOpcode() == Instruction::IntToPtr)
|
||||||
|
PtrOpTy = getType();
|
||||||
|
|
||||||
|
Type *IntPtrTy = PtrOpTy
|
||||||
|
? DL->getIntPtrType(PtrOpTy)
|
||||||
|
: DL->getIntPtrType(getContext(), 0);
|
||||||
|
|
||||||
|
return isNoopCast(getOpcode(), getOperand(0)->getType(), getType(), IntPtrTy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This function determines if a pair of casts can be eliminated and what
|
||||||
|
/// opcode should be used in the elimination. This assumes that there are two
|
||||||
/// instructions like this:
|
/// instructions like this:
|
||||||
/// * %F = firstOpcode SrcTy %x to MidTy
|
/// * %F = firstOpcode SrcTy %x to MidTy
|
||||||
/// * %S = secondOpcode MidTy %F to DstTy
|
/// * %S = secondOpcode MidTy %F to DstTy
|
||||||
|
25
test/Analysis/Lint/address-spaces.ll
Normal file
25
test/Analysis/Lint/address-spaces.ll
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
; RUN: opt -lint < %s
|
||||||
|
|
||||||
|
target datalayout = "p32:32:32-p1:16:16:16-n16:32"
|
||||||
|
|
||||||
|
declare void @foo(i64) nounwind
|
||||||
|
|
||||||
|
define i64 @test1(i32 addrspace(1)* %x) nounwind {
|
||||||
|
%y = ptrtoint i32 addrspace(1)* %x to i64
|
||||||
|
ret i64 %y
|
||||||
|
}
|
||||||
|
|
||||||
|
define <4 x i64> @test1_vector(<4 x i32 addrspace(1)*> %x) nounwind {
|
||||||
|
%y = ptrtoint <4 x i32 addrspace(1)*> %x to <4 x i64>
|
||||||
|
ret <4 x i64> %y
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 addrspace(1)* @test2(i64 %x) nounwind {
|
||||||
|
%y = inttoptr i64 %x to i32 addrspace(1)*
|
||||||
|
ret i32 addrspace(1)* %y
|
||||||
|
}
|
||||||
|
|
||||||
|
define <4 x i32 addrspace(1)*> @test2_vector(<4 x i64> %x) nounwind {
|
||||||
|
%y = inttoptr <4 x i64> %x to <4 x i32 addrspace(1)*>
|
||||||
|
ret <4 x i32 addrspace(1)*> %y
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user