[llvm-commits] [llvm] r97875 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombine.h lib/Transforms/InstCombine/InstCombineCalls.cpp lib/Transforms/Scalar/SimplifyLibCalls.cpp test/Transforms/InstCombine/memset_chk.ll test/Transforms/InstCombine/objsize.ll test/Transforms/InstCombine/strcpy_chk.ll test/Transforms/SimplifyLibCalls/memset_chk.ll test/Transforms/SimplifyLibCalls/strcpy_chk.ll

Eric Christopher echristo at apple.com
Sat Mar 6 02:50:38 PST 2010


Author: echristo
Date: Sat Mar  6 04:50:38 2010
New Revision: 97875

URL: http://llvm.org/viewvc/llvm-project?rev=97875&view=rev
Log:
Migrate _chk call lowering from SimplifyLibCalls to InstCombine. Stub
out the remainder of the calls that we should lower in some way and
move the tests to the new correct directory. Fix up tests that are now
optimized more than they were before by -instcombine.

Added:
    llvm/trunk/test/Transforms/InstCombine/memset_chk.ll
      - copied, changed from r97869, llvm/trunk/test/Transforms/SimplifyLibCalls/memset_chk.ll
    llvm/trunk/test/Transforms/InstCombine/strcpy_chk.ll
      - copied, changed from r97869, llvm/trunk/test/Transforms/SimplifyLibCalls/strcpy_chk.ll
Removed:
    llvm/trunk/test/Transforms/SimplifyLibCalls/memset_chk.ll
    llvm/trunk/test/Transforms/SimplifyLibCalls/strcpy_chk.ll
Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombine.h
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
    llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp
    llvm/trunk/test/Transforms/InstCombine/objsize.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombine.h?rev=97875&r1=97874&r2=97875&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombine.h (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombine.h Sat Mar  6 04:50:38 2010
@@ -207,6 +207,7 @@
                           const Type *Ty);
 
   Instruction *visitCallSite(CallSite CS);
+  Instruction *tryOptimizeCall(CallInst *CI, const TargetData *TD);
   bool transformConstExprCastCall(CallSite CS);
   Instruction *transformCallThroughTrampoline(CallSite CS);
   Instruction *transformZExtICmp(ICmpInst *ICI, Instruction &CI,

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=97875&r1=97874&r2=97875&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Sat Mar  6 04:50:38 2010
@@ -16,6 +16,7 @@
 #include "llvm/Support/CallSite.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Analysis/MemoryBuiltins.h"
+#include "llvm/Transforms/Utils/BuildLibCalls.h"
 using namespace llvm;
 
 /// getPromotedType - Return the specified type promoted as it would be to pass
@@ -347,7 +348,7 @@
       Operand = Operand->stripPointerCasts();
       if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Operand))
         if (!GV->hasDefinitiveInitializer()) break;
-      
+        
       // Get what we're pointing to and its size. 
       const PointerType *BaseType = 
         cast<PointerType>(Operand->getType());
@@ -370,7 +371,7 @@
       Constant *RetVal = ConstantInt::get(ReturnTy, Size-Offset);
       return ReplaceInstUsesWith(CI, RetVal);
       
-    }
+    } 
 
     // Do not return "I don't know" here. Later optimization passes could
     // make it possible to evaluate objectsize to a constant.
@@ -740,6 +741,122 @@
   return true;
 }
 
+// Try to fold some different type of calls here.
+// Currently we're only working with the checking functions, memcpy_chk, 
+// mempcpy_chk, memmove_chk, memset_chk, strcpy_chk, stpcpy_chk, strncpy_chk,
+// strcat_chk and strncat_chk.
+Instruction *InstCombiner::tryOptimizeCall(CallInst *CI, const TargetData *TD) {
+  if (CI->getCalledFunction() == 0) return 0;
+  
+  StringRef Name = CI->getCalledFunction()->getName();
+  BasicBlock *BB = CI->getParent();
+  IRBuilder<> B(CI->getParent()->getContext());
+  
+  // Set the builder to the instruction after the call.
+  B.SetInsertPoint(BB, CI);
+
+  if (Name == "__memcpy_chk") {
+    ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
+    if (!SizeCI)
+      return 0;
+    ConstantInt *SizeArg = dyn_cast<ConstantInt>(CI->getOperand(3));
+    if (!SizeArg)
+      return 0;
+    if (SizeCI->isAllOnesValue() ||
+        SizeCI->getZExtValue() <= SizeArg->getZExtValue()) {
+      EmitMemCpy(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3),
+                 1, B, TD);
+      return ReplaceInstUsesWith(*CI, CI->getOperand(1));
+    }
+    return 0;
+  }
+
+  // Should be similar to memcpy.
+  if (Name == "__mempcpy_chk") {
+    return 0;
+  }
+
+  if (Name == "__memmove_chk") {
+    ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
+    if (!SizeCI)
+      return 0;
+    ConstantInt *SizeArg = dyn_cast<ConstantInt>(CI->getOperand(3));
+    if (!SizeArg)
+      return 0;
+    if (SizeCI->isAllOnesValue() ||
+        SizeCI->getZExtValue() <= SizeArg->getZExtValue()) {
+      EmitMemMove(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3),
+                  1, B, TD);
+      return ReplaceInstUsesWith(*CI, CI->getOperand(1));
+    }
+    return 0;
+  }
+
+  if (Name == "__memset_chk") {
+    ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
+    if (!SizeCI)
+      return 0;
+    ConstantInt *SizeArg = dyn_cast<ConstantInt>(CI->getOperand(3));
+    if (!SizeArg)
+      return 0;
+    if (SizeCI->isAllOnesValue() ||
+        SizeCI->getZExtValue() <= SizeArg->getZExtValue()) {
+      Value *Val = B.CreateIntCast(CI->getOperand(2), B.getInt8Ty(),
+                                   false);
+      EmitMemSet(CI->getOperand(1), Val,  CI->getOperand(3), B, TD);
+      return ReplaceInstUsesWith(*CI, CI->getOperand(1));
+    }
+    return 0;
+  }
+
+  if (Name == "__strcpy_chk") {
+    ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(3));
+    if (!SizeCI)
+      return 0;
+    // If a) we don't have any length information, or b) we know this will
+    // fit then just lower to a plain strcpy. Otherwise we'll keep our
+    // strcpy_chk call which may fail at runtime if the size is too long.
+    // TODO: It might be nice to get a maximum length out of the possible
+    // string lengths for varying.
+    if (SizeCI->isAllOnesValue() ||
+      SizeCI->getZExtValue() >= GetStringLength(CI->getOperand(2))) {
+      Value *Ret = EmitStrCpy(CI->getOperand(1), CI->getOperand(2), B, TD);
+      return ReplaceInstUsesWith(*CI, Ret);
+    }
+    return 0;
+  }
+
+  // Should be similar to strcpy.
+  if (Name == "__stpcpy_chk") {
+    return 0;
+  }
+
+  if (Name == "__strncpy_chk") {
+    ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
+    if (!SizeCI)
+      return 0;
+    ConstantInt *SizeArg = dyn_cast<ConstantInt>(CI->getOperand(3));
+    if (!SizeArg)
+      return 0;
+    if (SizeCI->isAllOnesValue() ||
+        SizeCI->getZExtValue() <= SizeArg->getZExtValue()) {
+      Value *Ret = EmitStrCpy(CI->getOperand(1), CI->getOperand(2), B, TD);
+      return ReplaceInstUsesWith(*CI, Ret);
+    }
+    return 0; 
+  }
+
+  if (Name == "__strcat_chk") {
+    return 0;
+  }
+
+  if (Name == "__strncat_chk") {
+    return 0;
+  }
+
+  return 0;
+}
+
 // visitCallSite - Improvements for call and invoke instructions.
 //
 Instruction *InstCombiner::visitCallSite(CallSite CS) {
@@ -826,6 +943,14 @@
     Changed = true;
   }
 
+  // Try to optimize the call if possible, we require TargetData for most of
+  // this.  None of these calls are seen as possibly dead so go ahead and
+  // delete the instruction now.
+  if (CallInst *CI = dyn_cast<CallInst>(CS.getInstruction())) {
+    Instruction *I = tryOptimizeCall(CI, TD);
+    return I ? EraseInstFromFunction(*I): 0;
+  }
+
   return Changed ? CS.getInstruction() : 0;
 }
 

Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp?rev=97875&r1=97874&r2=97875&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Sat Mar  6 04:50:38 2010
@@ -633,130 +633,6 @@
 };
 
 //===----------------------------------------------------------------------===//
-// Object Size Checking Optimizations
-//===----------------------------------------------------------------------===//
-
-//===---------------------------------------===//
-// 'memcpy_chk' Optimizations
-
-struct MemCpyChkOpt : public LibCallOptimization {
-  virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
-    // These optimizations require TargetData.
-    if (!TD) return 0;
-
-    const FunctionType *FT = Callee->getFunctionType();
-    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
-        !FT->getParamType(0)->isPointerTy() ||
-        !FT->getParamType(1)->isPointerTy() ||
-        !FT->getParamType(3)->isIntegerTy() ||
-        FT->getParamType(2) != TD->getIntPtrType(*Context))
-      return 0;
-
-    ConstantInt *ObjSizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
-    if (!ObjSizeCI)
-      return 0;
-    ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(3));
-    if (ObjSizeCI->isAllOnesValue() ||
-        (SizeCI && ObjSizeCI->getValue().uge(SizeCI->getValue()))) {
-      EmitMemCpy(CI->getOperand(1), CI->getOperand(2),
-                 CI->getOperand(3), 1, B, TD);
-      return CI->getOperand(1);
-    }
-
-    return 0;
-  }
-};
-
-//===---------------------------------------===//
-// 'memset_chk' Optimizations
-
-struct MemSetChkOpt : public LibCallOptimization {
-  virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
-    // These optimizations require TargetData.
-    if (!TD) return 0;
-
-    const FunctionType *FT = Callee->getFunctionType();
-    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
-        !FT->getParamType(0)->isPointerTy() ||
-        !FT->getParamType(1)->isIntegerTy() ||
-        !FT->getParamType(3)->isIntegerTy() ||
-        FT->getParamType(2) != TD->getIntPtrType(*Context))
-      return 0;
-
-    ConstantInt *ObjSizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
-    if (!ObjSizeCI)
-      return 0;
-    ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(3));
-    if (ObjSizeCI->isAllOnesValue() ||
-        (SizeCI && ObjSizeCI->getValue().uge(SizeCI->getValue()))) {
-      Value *Val = B.CreateIntCast(CI->getOperand(2), Type::getInt8Ty(*Context),
-				   false);
-      EmitMemSet(CI->getOperand(1), Val,  CI->getOperand(3), B, TD);
-      return CI->getOperand(1);
-    }
-
-    return 0;
-  }
-};
-
-//===---------------------------------------===//
-// 'memmove_chk' Optimizations
-
-struct MemMoveChkOpt : public LibCallOptimization {
-  virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
-    // These optimizations require TargetData.
-    if (!TD) return 0;
-
-    const FunctionType *FT = Callee->getFunctionType();
-    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
-        !FT->getParamType(0)->isPointerTy() ||
-        !FT->getParamType(1)->isPointerTy() ||
-        !FT->getParamType(3)->isIntegerTy() ||
-        FT->getParamType(2) != TD->getIntPtrType(*Context))
-      return 0;
-
-    ConstantInt *ObjSizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
-    if (!ObjSizeCI)
-      return 0;
-    ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(3));
-    if (ObjSizeCI->isAllOnesValue() ||
-        (SizeCI && ObjSizeCI->getValue().uge(SizeCI->getValue()))) {
-      EmitMemMove(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3),
-		              1, B, TD);
-      return CI->getOperand(1);
-    }
-
-    return 0;
-  }
-};
-
-struct StrCpyChkOpt : public LibCallOptimization {
-  virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
-    const FunctionType *FT = Callee->getFunctionType();
-    if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
-        !FT->getParamType(0)->isPointerTy() ||
-        !FT->getParamType(1)->isPointerTy())
-      return 0;
-
-    ConstantInt *ObjSizeCI = dyn_cast<ConstantInt>(CI->getOperand(3));
-    if (!ObjSizeCI)
-      return 0;
-    
-    // If a) we don't have any length information, or b) we know this will
-    // fit then just lower to a plain strcpy. Otherwise we'll keep our
-    // strcpy_chk call which may fail at runtime if the size is too long.
-    // TODO: It might be nice to get a maximum length out of the possible
-    // string lengths for varying.
-    if (ObjSizeCI->isAllOnesValue() ||
-        ObjSizeCI->getZExtValue() >= GetStringLength(CI->getOperand(2)))
-      return EmitStrCpy(CI->getOperand(1), CI->getOperand(2), B, TD);
-
-    return 0;
-  }
-};
-
-  
-//===----------------------------------------------------------------------===//
 // Math Library Optimizations
 //===----------------------------------------------------------------------===//
 
@@ -1298,10 +1174,6 @@
     SPrintFOpt SPrintF; PrintFOpt PrintF;
     FWriteOpt FWrite; FPutsOpt FPuts; FPrintFOpt FPrintF;
 
-    // Object Size Checking
-    MemCpyChkOpt MemCpyChk; MemSetChkOpt MemSetChk; MemMoveChkOpt MemMoveChk;
-    StrCpyChkOpt StrCpyChk;
-
     bool Modified;  // This is only used by doInitialization.
   public:
     static char ID; // Pass identification
@@ -1407,12 +1279,6 @@
   Optimizations["fwrite"] = &FWrite;
   Optimizations["fputs"] = &FPuts;
   Optimizations["fprintf"] = &FPrintF;
-
-  // Object Size Checking
-  Optimizations["__memcpy_chk"] = &MemCpyChk;
-  Optimizations["__memset_chk"] = &MemSetChk;
-  Optimizations["__memmove_chk"] = &MemMoveChk;
-  Optimizations["__strcpy_chk"] = &StrCpyChk;
 }
 
 

Copied: llvm/trunk/test/Transforms/InstCombine/memset_chk.ll (from r97869, llvm/trunk/test/Transforms/SimplifyLibCalls/memset_chk.ll)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/memset_chk.ll?p2=llvm/trunk/test/Transforms/InstCombine/memset_chk.ll&p1=llvm/trunk/test/Transforms/SimplifyLibCalls/memset_chk.ll&r1=97869&r2=97875&rev=97875&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimplifyLibCalls/memset_chk.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/memset_chk.ll Sat Mar  6 04:50:38 2010
@@ -1,4 +1,4 @@
-; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
+; RUN: opt < %s -instcombine -S | FileCheck %s
 ; rdar://7719085
 
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"

Modified: llvm/trunk/test/Transforms/InstCombine/objsize.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/objsize.ll?rev=97875&r1=97874&r2=97875&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/objsize.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/objsize.ll Sat Mar  6 04:50:38 2010
@@ -91,7 +91,7 @@
   %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
+; CHECK: unreachable
   unreachable
 
 bb12:
@@ -113,7 +113,7 @@
   %1 = bitcast %struct.data* %0 to i8*
   %2 = call i64 @llvm.objectsize.i64(i8* %1, i1 false) nounwind
 ; CHECK-NOT: @llvm.objectsize
-; CHECK: @__memset_chk(i8* %1, i32 0, i64 1824, i64 1824)
+; CHECK: @llvm.memset.i64(i8* %1, i8 0, i64 1824, i32 8)
   %3 = call i8* @__memset_chk(i8* %1, i32 0, i64 1824, i64 %2) nounwind
   ret i32 0
 }

Copied: llvm/trunk/test/Transforms/InstCombine/strcpy_chk.ll (from r97869, llvm/trunk/test/Transforms/SimplifyLibCalls/strcpy_chk.ll)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/strcpy_chk.ll?p2=llvm/trunk/test/Transforms/InstCombine/strcpy_chk.ll&p1=llvm/trunk/test/Transforms/SimplifyLibCalls/strcpy_chk.ll&r1=97869&r2=97875&rev=97875&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimplifyLibCalls/strcpy_chk.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/strcpy_chk.ll Sat Mar  6 04:50:38 2010
@@ -1,4 +1,4 @@
-; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
+; RUN: opt < %s -instcombine -S | FileCheck %s
 @a = common global [60 x i8] zeroinitializer, align 1 ; <[60 x i8]*> [#uses=1]
 @.str = private constant [8 x i8] c"abcdefg\00"   ; <[8 x i8]*> [#uses=1]
 

Removed: llvm/trunk/test/Transforms/SimplifyLibCalls/memset_chk.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyLibCalls/memset_chk.ll?rev=97874&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/SimplifyLibCalls/memset_chk.ll (original)
+++ llvm/trunk/test/Transforms/SimplifyLibCalls/memset_chk.ll (removed)
@@ -1,18 +0,0 @@
-; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
-; rdar://7719085
-
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
-
-%struct.data = type { [100 x i32], [100 x i32], [1024 x i8] }
-
-define i32 @t() nounwind ssp {
-; CHECK: @t
-; CHECK: @llvm.memset.i64
-entry:
-  %0 = alloca %struct.data, align 8               ; <%struct.data*> [#uses=1]
-  %1 = bitcast %struct.data* %0 to i8*            ; <i8*> [#uses=1]
-  %2 = call i8* @__memset_chk(i8* %1, i32 0, i64 1824, i64 1824) nounwind ; <i8*> [#uses=0]
-  ret i32 0
-}
-
-declare i8* @__memset_chk(i8*, i32, i64, i64) nounwind

Removed: llvm/trunk/test/Transforms/SimplifyLibCalls/strcpy_chk.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyLibCalls/strcpy_chk.ll?rev=97874&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/SimplifyLibCalls/strcpy_chk.ll (original)
+++ llvm/trunk/test/Transforms/SimplifyLibCalls/strcpy_chk.ll (removed)
@@ -1,12 +0,0 @@
-; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
- at a = common global [60 x i8] zeroinitializer, align 1 ; <[60 x i8]*> [#uses=1]
- at .str = private constant [8 x i8] c"abcdefg\00"   ; <[8 x i8]*> [#uses=1]
-
-define i8* @foo() nounwind {
-; CHECK: @foo
-; CHECK-NEXT: call i8* @strcpy
-  %call = call i8* @__strcpy_chk(i8* getelementptr inbounds ([60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([8 x i8]* @.str, i32 0, i32 0), i32 60) ; <i8*> [#uses=1]
-  ret i8* %call
-}
-
-declare i8* @__strcpy_chk(i8*, i8*, i32) nounwind





More information about the llvm-commits mailing list