From 38c18efe4137fb97464c7bc3428a5da19874a578 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Thu, 6 Mar 2014 17:33:55 +0000 Subject: [PATCH] Teach lint about address spaces git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203132 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/InstrTypes.h | 5 +++++ lib/Analysis/Lint.cpp | 11 +++++------ lib/IR/Instructions.cpp | 23 +++++++++++++++++++++-- test/Analysis/Lint/address-spaces.ll | 25 +++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 test/Analysis/Lint/address-spaces.ll diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index 4e247e9c9c9..35357b14588 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 5c44638fbb0..b2182b146d7 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(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(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 c89365fcda6..c3a34a2ccd7 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 00000000000..46ee1d734ba --- /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