diff options
author | Chris Lattner <sabre@nondot.org> | 2010-07-29 06:26:06 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-07-29 06:26:06 +0000 |
commit | 800588fd230d2c37ddce8fbf4a3881352715d700 (patch) | |
tree | 4e080d2e6f3a76307af7d5f51dc7301b3bc2c6a6 /lib/CodeGen/ABIInfo.h | |
parent | 15842bd05bd6d3b7450385ac8f73aaee5f807e19 (diff) |
Kill off the 'coerce' ABI passing form. Now 'direct' and 'extend' always
have a "coerce to" type which often matches the default lowering of Clang
type to LLVM IR type, but the coerce case can be handled by making them
not be the same.
This simplifies things and fixes issues where X86-64 abi lowering would
return coerce after making preferred types exactly match up. This caused
us to compile:
typedef float v4f32 __attribute__((__vector_size__(16)));
v4f32 foo(v4f32 X) {
return X+X;
}
into this code at -O0:
define <4 x float> @foo(<4 x float> %X.coerce) nounwind {
entry:
%retval = alloca <4 x float>, align 16 ; <<4 x float>*> [#uses=2]
%coerce = alloca <4 x float>, align 16 ; <<4 x float>*> [#uses=2]
%X.addr = alloca <4 x float>, align 16 ; <<4 x float>*> [#uses=3]
store <4 x float> %X.coerce, <4 x float>* %coerce
%X = load <4 x float>* %coerce ; <<4 x float>> [#uses=1]
store <4 x float> %X, <4 x float>* %X.addr
%tmp = load <4 x float>* %X.addr ; <<4 x float>> [#uses=1]
%tmp1 = load <4 x float>* %X.addr ; <<4 x float>> [#uses=1]
%add = fadd <4 x float> %tmp, %tmp1 ; <<4 x float>> [#uses=1]
store <4 x float> %add, <4 x float>* %retval
%0 = load <4 x float>* %retval ; <<4 x float>> [#uses=1]
ret <4 x float> %0
}
Now we get:
define <4 x float> @foo(<4 x float> %X) nounwind {
entry:
%X.addr = alloca <4 x float>, align 16 ; <<4 x float>*> [#uses=3]
store <4 x float> %X, <4 x float>* %X.addr
%tmp = load <4 x float>* %X.addr ; <<4 x float>> [#uses=1]
%tmp1 = load <4 x float>* %X.addr ; <<4 x float>> [#uses=1]
%add = fadd <4 x float> %tmp, %tmp1 ; <<4 x float>> [#uses=1]
ret <4 x float> %add
}
This implements rdar://8248065
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109733 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/ABIInfo.h')
-rw-r--r-- | lib/CodeGen/ABIInfo.h | 32 |
1 files changed, 16 insertions, 16 deletions
diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h index 30f99c31e3..642fddb5c8 100644 --- a/lib/CodeGen/ABIInfo.h +++ b/lib/CodeGen/ABIInfo.h @@ -38,17 +38,13 @@ namespace clang { class ABIArgInfo { public: enum Kind { - Direct, /// Pass the argument directly using the normal - /// converted LLVM type. Complex and structure types - /// are passed using first class aggregates. + Direct, /// Pass the argument directly using the normal converted LLVM + /// type, or by coercing to another specified type + /// (stored in 'CoerceToType'). Extend, /// Valid only for integer argument types. Same as 'direct' /// but also emit a zero/sign extension attribute. - Coerce, /// Only valid for aggregate return types, the argument - /// should be accessed by coercion to a provided type. - - Indirect, /// Pass the argument indirectly via a hidden pointer /// with the specified alignment (0 indicates default /// alignment). @@ -79,8 +75,8 @@ namespace clang { public: ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {} - static ABIArgInfo getDirect() { - return ABIArgInfo(Direct); + static ABIArgInfo getDirect(const llvm::Type *T = 0) { + return ABIArgInfo(Direct, T); } static ABIArgInfo getExtend() { return ABIArgInfo(Extend); @@ -88,9 +84,6 @@ namespace clang { static ABIArgInfo getIgnore() { return ABIArgInfo(Ignore); } - static ABIArgInfo getCoerce(const llvm::Type *T) { - return ABIArgInfo(Coerce, T); - } static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true) { return ABIArgInfo(Indirect, 0, Alignment, ByVal); } @@ -102,16 +95,23 @@ namespace clang { bool isDirect() const { return TheKind == Direct; } bool isExtend() const { return TheKind == Extend; } bool isIgnore() const { return TheKind == Ignore; } - bool isCoerce() const { return TheKind == Coerce; } bool isIndirect() const { return TheKind == Indirect; } bool isExpand() const { return TheKind == Expand; } - // Coerce accessors + bool canHaveCoerceToType() const { + return TheKind == Direct || TheKind == Extend; + } + + // Direct/Extend accessors const llvm::Type *getCoerceToType() const { - assert(TheKind == Coerce && "Invalid kind!"); + assert(canHaveCoerceToType() && "Invalid kind!"); return TypeData; } - + + void setCoerceToType(const llvm::Type *T) { + assert(canHaveCoerceToType() && "Invalid kind!"); + TypeData = T; + } // Indirect accessors unsigned getIndirectAlign() const { assert(TheKind == Indirect && "Invalid kind!"); |