diff options
| author | Chris Lattner <sabre@nondot.org> | 2010-06-29 06:01:59 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2010-06-29 06:01:59 +0000 |
| commit | 22a931e3bb03210d147b39124d656975cd0d267f (patch) | |
| tree | f5de398c79a844b24fc401cc148b73847a02b2ec /clang/test | |
| parent | b59dd8f10af7ac5005e20e42ef0aa6da4eab69f9 (diff) | |
| download | bcm5719-llvm-22a931e3bb03210d147b39124d656975cd0d267f.tar.gz bcm5719-llvm-22a931e3bb03210d147b39124d656975cd0d267f.zip | |
Change X86_64ABIInfo to have ASTContext and TargetData ivars to
avoid passing ASTContext down through all the methods it has.
When classifying an argument, or argument piece, as INTEGER, check
to see if we have a pointer at exactly the same offset in the
preferred type. If so, use that pointer type instead of i64. This
allows us to compile A function taking a stringref into something
like this:
define i8* @foo(i64 %D.coerce0, i8* %D.coerce1) nounwind ssp {
entry:
%D = alloca %struct.DeclGroup, align 8 ; <%struct.DeclGroup*> [#uses=4]
%0 = getelementptr %struct.DeclGroup* %D, i32 0, i32 0 ; <i64*> [#uses=1]
store i64 %D.coerce0, i64* %0
%1 = getelementptr %struct.DeclGroup* %D, i32 0, i32 1 ; <i8**> [#uses=1]
store i8* %D.coerce1, i8** %1
%tmp = getelementptr inbounds %struct.DeclGroup* %D, i32 0, i32 0 ; <i64*> [#uses=1]
%tmp1 = load i64* %tmp ; <i64> [#uses=1]
%tmp2 = getelementptr inbounds %struct.DeclGroup* %D, i32 0, i32 1 ; <i8**> [#uses=1]
%tmp3 = load i8** %tmp2 ; <i8*> [#uses=1]
%add.ptr = getelementptr inbounds i8* %tmp3, i64 %tmp1 ; <i8*> [#uses=1]
ret i8* %add.ptr
}
instead of this:
define i8* @foo(i64 %D.coerce0, i64 %D.coerce1) nounwind ssp {
entry:
%D = alloca %struct.DeclGroup, align 8 ; <%struct.DeclGroup*> [#uses=3]
%0 = insertvalue %0 undef, i64 %D.coerce0, 0 ; <%0> [#uses=1]
%1 = insertvalue %0 %0, i64 %D.coerce1, 1 ; <%0> [#uses=1]
%2 = bitcast %struct.DeclGroup* %D to %0* ; <%0*> [#uses=1]
store %0 %1, %0* %2, align 1
%tmp = getelementptr inbounds %struct.DeclGroup* %D, i32 0, i32 0 ; <i64*> [#uses=1]
%tmp1 = load i64* %tmp ; <i64> [#uses=1]
%tmp2 = getelementptr inbounds %struct.DeclGroup* %D, i32 0, i32 1 ; <i8**> [#uses=1]
%tmp3 = load i8** %tmp2 ; <i8*> [#uses=1]
%add.ptr = getelementptr inbounds i8* %tmp3, i64 %tmp1 ; <i8*> [#uses=1]
ret i8* %add.ptr
}
This implements rdar://7375902 - [codegen quality] clang x86-64 ABI lowering code punishing StringRef
llvm-svn: 107123
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/CodeGen/x86_64-arguments.c | 10 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/x86_64-arguments.cpp | 7 |
2 files changed, 12 insertions, 5 deletions
diff --git a/clang/test/CodeGen/x86_64-arguments.c b/clang/test/CodeGen/x86_64-arguments.c index 595f2a816d6..ba9045a1f48 100644 --- a/clang/test/CodeGen/x86_64-arguments.c +++ b/clang/test/CodeGen/x86_64-arguments.c @@ -113,3 +113,13 @@ struct __attribute__((aligned(32))) s20 { int y; }; void f20(struct s20 x) {} + +struct StringRef { + long x; + const char *Ptr; +}; + +// rdar://7375902 +// CHECK: define i8* @f21(i64 %S.coerce0, i8* %S.coerce1) +const char *f21(struct StringRef S) { return S.x+S.Ptr; } + diff --git a/clang/test/CodeGenCXX/x86_64-arguments.cpp b/clang/test/CodeGenCXX/x86_64-arguments.cpp index 2c7e5b80d93..8a21fddec4b 100644 --- a/clang/test/CodeGenCXX/x86_64-arguments.cpp +++ b/clang/test/CodeGenCXX/x86_64-arguments.cpp @@ -1,12 +1,9 @@ // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s -// CHECK: [[i64_i64_ty:%.*]] = type { i64, i64 } -// CHECK: [[i64_double_ty:%.*]] = type { i64, double } - // Basic base class test. struct f0_s0 { unsigned a; }; struct f0_s1 : public f0_s0 { void *b; }; -// CHECK: define void @_Z2f05f0_s1(i64 %a0.coerce0, i64 %a0.coerce1) +// CHECK: define void @_Z2f05f0_s1(i64 %a0.coerce0, i8* %a0.coerce1) void f0(f0_s1 a0) { } // Check with two eight-bytes in base class. @@ -27,7 +24,7 @@ struct s3_1 { struct s3_0 a; long b; }; void f3(struct s3_1 x) {} // CHECK: define i64 @_Z4f4_0M2s4i(i64 %a.coerce) -// CHECK: define [[i64_i64_ty]] @_Z4f4_1M2s4FivE(i64 %a.coerce0, i64 %a.coerce1) +// CHECK: define {{.*}} @_Z4f4_1M2s4FivE(i64 %a.coerce0, i64 %a.coerce1) struct s4 {}; typedef int s4::* s4_mdp; typedef int (s4::*s4_mfp)(); |

