[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