summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2014-03-06 17:33:55 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2014-03-06 17:33:55 +0000
commit38c18efe4137fb97464c7bc3428a5da19874a578 (patch)
tree79e07769533fec4d3bf69112f5b08e652b1141ad
parentd530a9670113a18fdd6fa39c15b294d9b5fb7080 (diff)
downloadllvm-38c18efe4137fb97464c7bc3428a5da19874a578.tar.gz
llvm-38c18efe4137fb97464c7bc3428a5da19874a578.tar.bz2
llvm-38c18efe4137fb97464c7bc3428a5da19874a578.tar.xz
Teach lint about address spaces
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203132 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/IR/InstrTypes.h5
-rw-r--r--lib/Analysis/Lint.cpp11
-rw-r--r--lib/IR/Instructions.cpp23
-rw-r--r--test/Analysis/Lint/address-spaces.ll25
4 files changed, 56 insertions, 8 deletions
diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h
index 4e247e9c9c..35357b1458 100644
--- a/include/llvm/IR/InstrTypes.h
+++ b/include/llvm/IR/InstrTypes.h
@@ -582,6 +582,11 @@ public:
Type *IntPtrTy ///< Integer type corresponding to pointer
) 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.
/// This is a helper function for both CastInst and ConstantExpr.
/// @returns 0 if the CastInst pair can't be eliminated, otherwise
diff --git a/lib/Analysis/Lint.cpp b/lib/Analysis/Lint.cpp
index 5c44638fbb..b2182b146d 100644
--- a/lib/Analysis/Lint.cpp
+++ b/lib/Analysis/Lint.cpp
@@ -16,7 +16,7 @@
// those aren't comprehensive either. Second, many conditions cannot be
// checked statically. This pass does no dynamic instrumentation, so it
// can't check for all possible problems.
-//
+//
// 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,
// 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,
// it may be that the optimization pass is merely exposing an existing
// condition in the code.
-//
+//
// This code may be run before instcombine. In many cases, instcombine checks
// for the same kinds of things and turns instructions with undefined behavior
// into unreachable (or equivalent). Because of this, this pass makes some
// effort to look through bitcasts and so on.
-//
+//
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/Lint.h"
@@ -652,8 +652,7 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk,
if (W != V)
return findValueImpl(W, OffsetOk, Visited);
} else if (CastInst *CI = dyn_cast<CastInst>(V)) {
- if (CI->isNoopCast(DL ? DL->getIntPtrType(V->getContext()) :
- Type::getInt64Ty(V->getContext())))
+ if (CI->isNoopCast(DL))
return findValueImpl(CI->getOperand(0), OffsetOk, Visited);
} else if (ExtractValueInst *Ex = dyn_cast<ExtractValueInst>(V)) {
if (Value *W = FindInsertedValue(Ex->getAggregateOperand(),
@@ -666,7 +665,7 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk,
if (CastInst::isNoopCast(Instruction::CastOps(CE->getOpcode()),
CE->getOperand(0)->getType(),
CE->getType(),
- DL ? DL->getIntPtrType(V->getContext()) :
+ DL ? DL->getIntPtrType(V->getType()) :
Type::getInt64Ty(V->getContext())))
return findValueImpl(CE->getOperand(0), OffsetOk, Visited);
} else if (CE->getOpcode() == Instruction::ExtractValue) {
diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp
index c89365fcda..c3a34a2ccd 100644
--- a/lib/IR/Instructions.cpp
+++ b/lib/IR/Instructions.cpp
@@ -2115,8 +2115,27 @@ bool CastInst::isNoopCast(Type *IntPtrTy) const {
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
+bool CastInst::isNoopCast(const DataLayout *DL) const {
+ 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:
/// * %F = firstOpcode SrcTy %x to MidTy
/// * %S = secondOpcode MidTy %F to DstTy
diff --git a/test/Analysis/Lint/address-spaces.ll b/test/Analysis/Lint/address-spaces.ll
new file mode 100644
index 0000000000..46ee1d734b
--- /dev/null
+++ b/test/Analysis/Lint/address-spaces.ll
@@ -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
+} \ No newline at end of file