summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2010-02-22 23:34:00 +0000
committerEvan Cheng <evan.cheng@apple.com>2010-02-22 23:34:00 +0000
commit6e5dfd4bf5205d5f84d958c9636bc0f57c23b96a (patch)
tree45ab0572ebd24f87e676788c693c21f9db5638f6
parent20df2420f7997cdb69c21f6bff27559cb09f7be2 (diff)
downloadllvm-6e5dfd4bf5205d5f84d958c9636bc0f57c23b96a.tar.gz
llvm-6e5dfd4bf5205d5f84d958c9636bc0f57c23b96a.tar.bz2
llvm-6e5dfd4bf5205d5f84d958c9636bc0f57c23b96a.tar.xz
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
-rw-r--r--lib/Transforms/InstCombine/InstCombineCalls.cpp13
-rw-r--r--test/CodeGen/X86/critical-edge-split.ll2
-rw-r--r--test/CodeGen/X86/ins_subreg_coalesce-3.ll2
-rw-r--r--test/CodeGen/X86/trunc-to-bool.ll21
-rw-r--r--test/CodeGen/X86/xor-icmp.ll31
-rw-r--r--test/Transforms/InstCombine/objsize.ll32
6 files changed, 86 insertions, 15 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp
index b9445040c8..835d149eab 100644
--- a/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -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);
diff --git a/test/CodeGen/X86/critical-edge-split.ll b/test/CodeGen/X86/critical-edge-split.ll
index 4fe554de75..f29cbf323e 100644
--- a/test/CodeGen/X86/critical-edge-split.ll
+++ b/test/CodeGen/X86/critical-edge-split.ll
@@ -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" }
diff --git a/test/CodeGen/X86/ins_subreg_coalesce-3.ll b/test/CodeGen/X86/ins_subreg_coalesce-3.ll
index 627edc51c1..8c1c409766 100644
--- a/test/CodeGen/X86/ins_subreg_coalesce-3.ll
+++ b/test/CodeGen/X86/ins_subreg_coalesce-3.ll
@@ -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 }
diff --git a/test/CodeGen/X86/trunc-to-bool.ll b/test/CodeGen/X86/trunc-to-bool.ll
index bfab1aef90..6062084106 100644
--- a/test/CodeGen/X86/trunc-to-bool.ll
+++ b/test/CodeGen/X86/trunc-to-bool.ll
@@ -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
diff --git a/test/CodeGen/X86/xor-icmp.ll b/test/CodeGen/X86/xor-icmp.ll
index a6bdb13ec6..2d75c5d762 100644
--- a/test/CodeGen/X86/xor-icmp.ll
+++ b/test/CodeGen/X86/xor-icmp.ll
@@ -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
+}
diff --git a/test/Transforms/InstCombine/objsize.ll b/test/Transforms/InstCombine/objsize.ll
index dbc7d31c39..43406621b8 100644
--- a/test/Transforms/InstCombine/objsize.ll
+++ b/test/Transforms/InstCombine/objsize.ll
@@ -72,4 +72,34 @@ define i32 @test2() nounwind {
ret i32 %1
}
-declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly \ No newline at end of file
+; 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