diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index b9445040c84..835d149eab4 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(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(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 Ops(CE->op_begin()+1, CE->op_end()); const PointerType *OffsetType = cast(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 4fe554de75a..f29cbf323e3 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 627edc51c18..8c1c4097660 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 bfab1aef901..60620841064 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 a6bdb13ec6b..2d75c5d7620 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 ; [#uses=1] + %1 = icmp eq i32 %y, 0 ; [#uses=1] + %2 = xor i1 %1, %0 ; [#uses=1] + br i1 %2, label %bb, label %return + +bb: ; preds = %entry + %3 = tail call i32 (...)* @foo() nounwind ; [#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 dbc7d31c392..43406621b81 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 ; [#uses=1] + %1 = bitcast float* %0 to i8* ; [#uses=1] + %2 = call i32 @llvm.objectsize.i32(i8* %1, i1 false) ; [#uses=1] + %3 = call i8* @__memcpy_chk(i8* undef, i8* undef, i32 512, i32 %2) nounwind ; [#uses=0] +; CHECK: @__memcpy_chk + unreachable + +bb12: + %4 = getelementptr inbounds float* getelementptr inbounds ([480 x float]* @array, i32 0, i32 128), i32 -127 ; [#uses=1] + %5 = bitcast float* %4 to i8* ; [#uses=1] + %6 = call i8* @__inline_memcpy_chk(i8* %5, i8* undef, i32 512) nounwind inlinehint ; [#uses=0] +; CHECK: @__inline_memcpy_chk + unreachable +} + +declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly