Instcombine constant folding can normalize gep with negative index to index with large offset. When instcombine objsize checking transformation sees these geps where the offset seemingly point out of bound, it should just return "i don't know" rather than asserting.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96825 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2010-02-22 23:34:00 +00:00
parent 20df2420f7
commit 6e5dfd4bf5
6 changed files with 86 additions and 15 deletions

View File

@ -319,7 +319,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op1)) {
if (GV->hasDefinitiveInitializer()) {
Constant *C = GV->getInitializer();
size_t globalSize = TD->getTypeAllocSize(C->getType());
uint64_t globalSize = TD->getTypeAllocSize(C->getType());
return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, globalSize));
} else {
Constant *RetVal = ConstantInt::get(ReturnTy, Min ? 0 : -1ULL);
@ -341,16 +341,21 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
// Get what we're pointing to and its size.
const PointerType *BaseType =
cast<PointerType>(Operand->getType());
size_t Size = TD->getTypeAllocSize(BaseType->getElementType());
uint64_t Size = TD->getTypeAllocSize(BaseType->getElementType());
// Get the current byte offset into the thing. Use the original
// operand in case we're looking through a bitcast.
SmallVector<Value*, 8> Ops(CE->op_begin()+1, CE->op_end());
const PointerType *OffsetType =
cast<PointerType>(GEP->getPointerOperand()->getType());
size_t Offset = TD->getIndexedOffset(OffsetType, &Ops[0], Ops.size());
uint64_t Offset = TD->getIndexedOffset(OffsetType, &Ops[0], Ops.size());
assert(Size >= Offset);
if (Size < Offset) {
// Out of bound reference? Negative index normalized to large
// index? Just return "I don't know".
Constant *RetVal = ConstantInt::get(ReturnTy, Min ? 0 : -1ULL);
return ReplaceInstUsesWith(CI, RetVal);
}
Constant *RetVal = ConstantInt::get(ReturnTy, Size-Offset);
return ReplaceInstUsesWith(CI, RetVal);

View File

@ -1,4 +1,4 @@
; RUN: llc < %s -mtriple=i386-apple-darwin -tailcallopt=false -stats -info-output-file - | grep asm-printer | grep 31
; RUN: llc < %s -mtriple=i386-apple-darwin -stats -info-output-file - | grep asm-printer | grep 29
%CC = type { %Register }
%II = type { %"struct.XX::II::$_74" }

View File

@ -1,4 +1,4 @@
; RUN: llc < %s -march=x86-64 | grep mov | count 5
; RUN: llc < %s -march=x86-64 | grep mov | count 3
%struct.COMPOSITE = type { i8, i16, i16 }
%struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }

View File

@ -3,13 +3,14 @@
; value and as the operand of a branch.
; RUN: llc < %s -march=x86 | FileCheck %s
define i1 @test1(i32 %X) zeroext {
define i1 @test1(i32 %X) zeroext nounwind {
%Y = trunc i32 %X to i1
ret i1 %Y
}
; CHECK: test1:
; CHECK: andl $1, %eax
define i1 @test2(i32 %val, i32 %mask) {
define i1 @test2(i32 %val, i32 %mask) nounwind {
entry:
%shifted = ashr i32 %val, %mask
%anded = and i32 %shifted, 1
@ -20,9 +21,10 @@ ret_true:
ret_false:
ret i1 false
}
; CHECK: testb $1, %al
; CHECK: test2:
; CHECK: btl %eax
define i32 @test3(i8* %ptr) {
define i32 @test3(i8* %ptr) nounwind {
%val = load i8* %ptr
%tmp = trunc i8 %val to i1
br i1 %tmp, label %cond_true, label %cond_false
@ -31,9 +33,10 @@ cond_true:
cond_false:
ret i32 42
}
; CHECK: testb $1, %al
; CHECK: test3:
; CHECK: testb $1, (%eax)
define i32 @test4(i8* %ptr) {
define i32 @test4(i8* %ptr) nounwind {
%tmp = ptrtoint i8* %ptr to i1
br i1 %tmp, label %cond_true, label %cond_false
cond_true:
@ -41,9 +44,10 @@ cond_true:
cond_false:
ret i32 42
}
; CHECK: testb $1, %al
; CHECK: test4:
; CHECK: testb $1, 4(%esp)
define i32 @test6(double %d) {
define i32 @test5(double %d) nounwind {
%tmp = fptosi double %d to i1
br i1 %tmp, label %cond_true, label %cond_false
cond_true:
@ -51,4 +55,5 @@ cond_true:
cond_false:
ret i32 42
}
; CHECK: test5:
; CHECK: testb $1

View File

@ -1,5 +1,6 @@
; RUN: llc < %s -march=x86 | FileCheck %s -check-prefix=X32
; RUN: llc < %s -march=x86-64 | FileCheck %s -check-prefix=X64
; rdar://7367229
define i32 @t(i32 %a, i32 %b) nounwind ssp {
entry:
@ -34,3 +35,33 @@ bb1: ; preds = %entry
declare i32 @foo(...)
declare i32 @bar(...)
define i32 @t2(i32 %x, i32 %y) nounwind ssp {
; X32: t2:
; X32: cmpl
; X32: sete
; X32: cmpl
; X32: sete
; X32-NOT: xor
; X32: je
; X64: t2:
; X64: testl
; X64: sete
; X64: testl
; X64: sete
; X64-NOT: xor
; X64: je
entry:
%0 = icmp eq i32 %x, 0 ; <i1> [#uses=1]
%1 = icmp eq i32 %y, 0 ; <i1> [#uses=1]
%2 = xor i1 %1, %0 ; <i1> [#uses=1]
br i1 %2, label %bb, label %return
bb: ; preds = %entry
%3 = tail call i32 (...)* @foo() nounwind ; <i32> [#uses=0]
ret i32 undef
return: ; preds = %entry
ret i32 undef
}

View File

@ -72,4 +72,34 @@ define i32 @test2() nounwind {
ret i32 %1
}
; rdar://7674946
@array = internal global [480 x float] zeroinitializer ; <[480 x float]*> [#uses=1]
declare i8* @__memcpy_chk(i8*, i8*, i32, i32) nounwind
declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly
declare i8* @__inline_memcpy_chk(i8*, i8*, i32) nounwind inlinehint
define void @test3() nounwind {
; CHECK: @test3
entry:
br i1 undef, label %bb11, label %bb12
bb11:
%0 = getelementptr inbounds float* getelementptr inbounds ([480 x float]* @array, i32 0, i32 128), i32 -127 ; <float*> [#uses=1]
%1 = bitcast float* %0 to i8* ; <i8*> [#uses=1]
%2 = call i32 @llvm.objectsize.i32(i8* %1, i1 false) ; <i32> [#uses=1]
%3 = call i8* @__memcpy_chk(i8* undef, i8* undef, i32 512, i32 %2) nounwind ; <i8*> [#uses=0]
; CHECK: @__memcpy_chk
unreachable
bb12:
%4 = getelementptr inbounds float* getelementptr inbounds ([480 x float]* @array, i32 0, i32 128), i32 -127 ; <float*> [#uses=1]
%5 = bitcast float* %4 to i8* ; <i8*> [#uses=1]
%6 = call i8* @__inline_memcpy_chk(i8* %5, i8* undef, i32 512) nounwind inlinehint ; <i8*> [#uses=0]
; CHECK: @__inline_memcpy_chk
unreachable
}
declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly