summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/BoundsChecking.cpp
diff options
context:
space:
mode:
authorNuno Lopes <nunoplopes@sapo.pt>2012-07-03 17:30:18 +0000
committerNuno Lopes <nunoplopes@sapo.pt>2012-07-03 17:30:18 +0000
commit1e8dffdf270e0e2a513df4219fd3a6194894760a (patch)
treeb38431cc8a3298df849046ff5544ebf6ac6f833b /llvm/lib/Transforms/Scalar/BoundsChecking.cpp
parent9291ff4078e57f3b09d76bd2148814b259fb5638 (diff)
downloadbcm5719-llvm-1e8dffdf270e0e2a513df4219fd3a6194894760a.tar.gz
bcm5719-llvm-1e8dffdf270e0e2a513df4219fd3a6194894760a.zip
BoundsChecking: optimize out the check for offset < 0 if size is known to be >= 0 (signed).
(LLVM optimizers cannot do this optimization by themselves) llvm-svn: 159668
Diffstat (limited to 'llvm/lib/Transforms/Scalar/BoundsChecking.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/BoundsChecking.cpp17
1 files changed, 10 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/Scalar/BoundsChecking.cpp b/llvm/lib/Transforms/Scalar/BoundsChecking.cpp
index 0690d76e7b5..ef2f39d8583 100644
--- a/llvm/lib/Transforms/Scalar/BoundsChecking.cpp
+++ b/llvm/lib/Transforms/Scalar/BoundsChecking.cpp
@@ -67,11 +67,8 @@ namespace {
}
char BoundsChecking::ID = 0;
-INITIALIZE_PASS_BEGIN(BoundsChecking, "bounds-checking",
- "Run-time bounds checking", false, false)
-INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
-INITIALIZE_PASS_END(BoundsChecking, "bounds-checking",
- "Run-time bounds checking", false, false)
+INITIALIZE_PASS(BoundsChecking, "bounds-checking", "Run-time bounds checking",
+ false, false)
/// getTrapBB - create a basic block that traps. All overflowing conditions
@@ -141,6 +138,7 @@ bool BoundsChecking::instrument(Value *Ptr, Value *InstVal) {
Value *Size = SizeOffset.first;
Value *Offset = SizeOffset.second;
+ ConstantInt *SizeCI = dyn_cast<ConstantInt>(Size);
IntegerType *IntTy = TD->getIntPtrType(Inst->getContext());
Value *NeededSizeVal = ConstantInt::get(IntTy, NeededSize);
@@ -149,12 +147,17 @@ bool BoundsChecking::instrument(Value *Ptr, Value *InstVal) {
// . Offset >= 0 (since the offset is given from the base ptr)
// . Size >= Offset (unsigned)
// . Size - Offset >= NeededSize (unsigned)
+ //
+ // optimization: if Size >= 0 (signed), skip 1st check
// FIXME: add NSW/NUW here? -- we dont care if the subtraction overflows
Value *ObjSize = Builder->CreateSub(Size, Offset);
- Value *Cmp1 = Builder->CreateICmpSLT(Offset, ConstantInt::get(IntTy, 0));
Value *Cmp2 = Builder->CreateICmpULT(Size, Offset);
Value *Cmp3 = Builder->CreateICmpULT(ObjSize, NeededSizeVal);
- Value *Or = Builder->CreateOr(Cmp1, Builder->CreateOr(Cmp2, Cmp3));
+ Value *Or = Builder->CreateOr(Cmp2, Cmp3);
+ if (!SizeCI || SizeCI->getValue().slt(0)) {
+ Value *Cmp1 = Builder->CreateICmpSLT(Offset, ConstantInt::get(IntTy, 0));
+ Or = Builder->CreateOr(Cmp1, Or);
+ }
emitBranchToTrap(Or);
++ChecksAdded;
OpenPOWER on IntegriCloud