Instcombine constant folding can normalize gep with negative index to index with...
authorEvan Cheng <evan.cheng@apple.com>
Mon, 22 Feb 2010 23:34:00 +0000 (23:34 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Mon, 22 Feb 2010 23:34:00 +0000 (23:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96825 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineCalls.cpp
test/CodeGen/X86/critical-edge-split.ll
test/CodeGen/X86/ins_subreg_coalesce-3.ll
test/CodeGen/X86/trunc-to-bool.ll
test/CodeGen/X86/xor-icmp.ll
test/Transforms/InstCombine/objsize.ll

index b9445040c84d50aba9881f1899d122f30c0b6ea5..835d149eab4820e5f904c23a31320b231645d845 100644 (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);
index 4fe554de75a027f95f3852d6b7eae0a7dc7d63b7..f29cbf323e376b5d9957c22a02e27ebed0074d29 100644 (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" }
index 627edc51c18d761a25e981974a48425e422951ee..8c1c40976605a568d891a180d83e7704b3288c3e 100644 (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 }
index bfab1aef901431f2a48b47c65ddd700836e7815d..60620841064f68f6c1b5cb46043cd2a033f1d3d7 100644 (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
index a6bdb13ec6b41213e5205fcc587e6efd9c9b11ad..2d75c5d762010d77f64b82717688f6559067b334 100644 (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
+}
index dbc7d31c3925ed2982d6439cd3141a7d188b0548..43406621b81da8c3ee808cacaa81482f1a462853 100644 (file)
@@ -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