mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
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
This commit is contained in:
parent
af1caad2cb
commit
eac3a6d03c
@ -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;
|
||||
|
@ -34,10 +34,14 @@ while.body.i.preheader:
|
||||
while.body.i:
|
||||
; CHECK: phi
|
||||
; CHECK-NEXT: phi
|
||||
; CHECK-NEXT: phi
|
||||
; CHECK: trap
|
||||
; CHECK-NOT: phi
|
||||
%c.addr.02.i = phi i8* [ %incdec.ptr.i, %while.body.i ], [ %addr, %while.body.i.preheader ]
|
||||
%incdec.ptr.i = getelementptr inbounds i8* %c.addr.02.i, i64 -1
|
||||
; CHECK: sub i64 10, %0
|
||||
; CHECK-NEXT: icmp ult i64 10, %0
|
||||
; CHECK-NEXT: icmp ult i64 {{.*}}, 1
|
||||
; CHECK-NEXT: or i1
|
||||
; CHECK-NEXT: br {{.*}}, label %trap
|
||||
store i8 100, i8* %c.addr.02.i, align 1
|
||||
%0 = load i8* %incdec.ptr.i, align 1
|
||||
%tobool.i = icmp eq i8 %0, 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user