[cfe-commits] r129651 - in /cfe/trunk: lib/CodeGen/CGBuiltin.cpp test/CodeGen/builtin-memfns.c test/CodeGen/builtinmemcpy.c

Chris Lattner sabre at nondot.org
Sat Apr 16 17:40:25 PDT 2011


Author: lattner
Date: Sat Apr 16 19:40:24 2011
New Revision: 129651

URL: http://llvm.org/viewvc/llvm-project?rev=129651&view=rev
Log:
fold memcpy/set/move_chk to llvm.memcpy/set/move when the sizes
are trivial.  This exposes opportunities earlier, and allows fastisel
to do good things with these at -O0.

This addresses rdar://9289468 - clang doesn't fold memset_chk at -O0

Removed:
    cfe/trunk/test/CodeGen/builtinmemcpy.c
Modified:
    cfe/trunk/lib/CodeGen/CGBuiltin.cpp
    cfe/trunk/test/CodeGen/builtin-memfns.c

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=129651&r1=129650&r2=129651&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Sat Apr 16 19:40:24 2011
@@ -543,6 +543,22 @@
     return RValue::get(Address);
   }
       
+  case Builtin::BI__builtin___memcpy_chk: {
+    // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memset iff cst1<=cst2.
+    if (!E->getArg(2)->isEvaluatable(CGM.getContext()) ||
+        !E->getArg(3)->isEvaluatable(CGM.getContext()))
+      break;
+    llvm::APSInt Size = E->getArg(2)->EvaluateAsInt(CGM.getContext());
+    llvm::APSInt DstSize = E->getArg(3)->EvaluateAsInt(CGM.getContext());
+    if (Size.ugt(DstSize))
+      break;
+    Value *Dest = EmitScalarExpr(E->getArg(0));
+    Value *Src = EmitScalarExpr(E->getArg(1));
+    Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
+    Builder.CreateMemCpy(Dest, Src, SizeVal, 1, false);
+    return RValue::get(0);
+  }
+      
   case Builtin::BI__builtin_objc_memmove_collectable: {
     Value *Address = EmitScalarExpr(E->getArg(0));
     Value *SrcAddr = EmitScalarExpr(E->getArg(1));
@@ -551,7 +567,23 @@
                                                   Address, SrcAddr, SizeVal);
     return RValue::get(Address);
   }
-      
+
+  case Builtin::BI__builtin___memmove_chk: {
+    // fold __builtin_memmove_chk(x, y, cst1, cst2) to memset iff cst1<=cst2.
+    if (!E->getArg(2)->isEvaluatable(CGM.getContext()) ||
+        !E->getArg(3)->isEvaluatable(CGM.getContext()))
+      break;
+    llvm::APSInt Size = E->getArg(2)->EvaluateAsInt(CGM.getContext());
+    llvm::APSInt DstSize = E->getArg(3)->EvaluateAsInt(CGM.getContext());
+    if (Size.ugt(DstSize))
+      break;
+    Value *Dest = EmitScalarExpr(E->getArg(0));
+    Value *Src = EmitScalarExpr(E->getArg(1));
+    Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
+    Builder.CreateMemMove(Dest, Src, SizeVal, 1, false);
+    return RValue::get(0);
+  }
+
   case Builtin::BImemmove:
   case Builtin::BI__builtin_memmove: {
     Value *Address = EmitScalarExpr(E->getArg(0));
@@ -569,6 +601,23 @@
     Builder.CreateMemSet(Address, ByteVal, SizeVal, 1, false);
     return RValue::get(Address);
   }
+  case Builtin::BI__builtin___memset_chk: {
+    // fold __builtin_memset_chk(x, y, cst1, cst2) to memset iff cst1<=cst2.
+    if (!E->getArg(2)->isEvaluatable(CGM.getContext()) ||
+        !E->getArg(3)->isEvaluatable(CGM.getContext()))
+      break;
+    llvm::APSInt Size = E->getArg(2)->EvaluateAsInt(CGM.getContext());
+    llvm::APSInt DstSize = E->getArg(3)->EvaluateAsInt(CGM.getContext());
+    if (Size.ugt(DstSize))
+      break;
+    Value *Address = EmitScalarExpr(E->getArg(0));
+    Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
+                                         Builder.getInt8Ty());
+    Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
+    Builder.CreateMemSet(Address, ByteVal, SizeVal, 1, false);
+    
+    return RValue::get(0);
+  }
   case Builtin::BI__builtin_dwarf_cfa: {
     // The offset in bytes from the first argument to the CFA.
     //

Modified: cfe/trunk/test/CodeGen/builtin-memfns.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtin-memfns.c?rev=129651&r1=129650&r2=129651&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/builtin-memfns.c (original)
+++ cfe/trunk/test/CodeGen/builtin-memfns.c Sat Apr 16 19:40:24 2011
@@ -1,12 +1,13 @@
 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm < %s| FileCheck %s
 
+// CHECK: @test1
 // CHECK: call void @llvm.memset.p0i8.i32
 // CHECK: call void @llvm.memset.p0i8.i32
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32
 // CHECK: call void @llvm.memmove.p0i8.p0i8.i32
 // CHECK-NOT: __builtin
 // CHECK: ret
-int main(int argc, char **argv) {
+int test1(int argc, char **argv) {
   unsigned char a = 0x11223344;
   unsigned char b = 0x11223344;
   __builtin_bzero(&a, sizeof(a));
@@ -15,3 +16,29 @@
   __builtin_memmove(&a, &b, sizeof(a));
   return 0;
 }
+
+// rdar://9289468
+
+// CHECK: @test2
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i32
+char* test2(char* a, char* b) {
+  return __builtin_memcpy(a, b, 4);
+}
+
+// CHECK: @test3
+// CHECK: call void @llvm.memset
+void test3(char *P) {
+  __builtin___memset_chk(P, 42, 128, 128);
+}
+
+// CHECK: @test4
+// CHECK: call void @llvm.memcpy
+void test4(char *P, char *Q) {
+  __builtin___memcpy_chk(P, Q, 128, 128);
+}
+
+// CHECK: @test5
+// CHECK: call void @llvm.memmove
+void test5(char *P, char *Q) {
+  __builtin___memmove_chk(P, Q, 128, 128);
+}

Removed: cfe/trunk/test/CodeGen/builtinmemcpy.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtinmemcpy.c?rev=129650&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/builtinmemcpy.c (original)
+++ cfe/trunk/test/CodeGen/builtinmemcpy.c (removed)
@@ -1,3 +0,0 @@
-// RUN: %clang_cc1 -emit-llvm < %s -o - | grep "llvm.memcpy"
-
-char* x(char* a, char* b) {return __builtin_memcpy(a, b, 4);}





More information about the cfe-commits mailing list