forked from OSchip/llvm-project
Remove the AttrBuilder form of the Attribute::get creators.
The AttrBuilder is for building a collection of attributes. The Attribute object holds only one attribute. So it's not really useful for the Attribute object to have a creator which takes an AttrBuilder. This has two fallouts: 1. The AttrBuilder no longer holds its internal attributes in a bit-mask form. 2. The attributes are now ordered alphabetically (hence why the tests have changed). llvm-svn: 174110
This commit is contained in:
parent
1a0cf80533
commit
1c7cc8ae90
|
@ -105,8 +105,6 @@ public:
|
||||||
private:
|
private:
|
||||||
AttributeImpl *pImpl;
|
AttributeImpl *pImpl;
|
||||||
Attribute(AttributeImpl *A) : pImpl(A) {}
|
Attribute(AttributeImpl *A) : pImpl(A) {}
|
||||||
|
|
||||||
static Attribute get(LLVMContext &Context, AttrBuilder &B);
|
|
||||||
public:
|
public:
|
||||||
Attribute() : pImpl(0) {}
|
Attribute() : pImpl(0) {}
|
||||||
|
|
||||||
|
@ -115,7 +113,8 @@ public:
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// \brief Return a uniquified Attribute object.
|
/// \brief Return a uniquified Attribute object.
|
||||||
static Attribute get(LLVMContext &Context, AttrKind Kind);
|
static Attribute get(LLVMContext &Context, AttrKind Kind, Constant *Val = 0);
|
||||||
|
static Attribute get(LLVMContext &Context, Constant *Kind, Constant *Val = 0);
|
||||||
|
|
||||||
/// \brief Return a uniquified Attribute object that has the specific
|
/// \brief Return a uniquified Attribute object that has the specific
|
||||||
/// alignment set.
|
/// alignment set.
|
||||||
|
|
|
@ -40,6 +40,8 @@ class AttributeImpl : public FoldingSetNode {
|
||||||
public:
|
public:
|
||||||
AttributeImpl(LLVMContext &C, Constant *Kind)
|
AttributeImpl(LLVMContext &C, Constant *Kind)
|
||||||
: Context(C), Kind(Kind) {}
|
: Context(C), Kind(Kind) {}
|
||||||
|
AttributeImpl(LLVMContext &C, Constant *Kind, ArrayRef<Constant*> Vals)
|
||||||
|
: Context(C), Kind(Kind), Vals(Vals.begin(), Vals.end()) {}
|
||||||
explicit AttributeImpl(LLVMContext &C, Attribute::AttrKind data);
|
explicit AttributeImpl(LLVMContext &C, Attribute::AttrKind data);
|
||||||
AttributeImpl(LLVMContext &C, Attribute::AttrKind data,
|
AttributeImpl(LLVMContext &C, Attribute::AttrKind data,
|
||||||
ArrayRef<Constant*> values);
|
ArrayRef<Constant*> values);
|
||||||
|
|
|
@ -30,24 +30,11 @@ using namespace llvm;
|
||||||
// Attribute Construction Methods
|
// Attribute Construction Methods
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
Attribute Attribute::get(LLVMContext &Context, AttrKind Kind) {
|
Attribute Attribute::get(LLVMContext &Context, Constant *Kind, Constant *Val) {
|
||||||
AttrBuilder B;
|
|
||||||
return Attribute::get(Context, B.addAttribute(Kind));
|
|
||||||
}
|
|
||||||
|
|
||||||
Attribute Attribute::get(LLVMContext &Context, AttrBuilder &B) {
|
|
||||||
// If there are no attributes, return an empty Attribute class.
|
|
||||||
if (!B.hasAttributes())
|
|
||||||
return Attribute();
|
|
||||||
|
|
||||||
assert(std::distance(B.begin(), B.end()) == 1 &&
|
|
||||||
"The Attribute object should represent one attribute only!");
|
|
||||||
|
|
||||||
// Otherwise, build a key to look up the existing attributes.
|
|
||||||
LLVMContextImpl *pImpl = Context.pImpl;
|
LLVMContextImpl *pImpl = Context.pImpl;
|
||||||
FoldingSetNodeID ID;
|
FoldingSetNodeID ID;
|
||||||
ConstantInt *CI = ConstantInt::get(Type::getInt64Ty(Context), B.Raw());
|
ID.AddPointer(Kind);
|
||||||
ID.AddPointer(CI);
|
if (Val) ID.AddPointer(Val);
|
||||||
|
|
||||||
void *InsertPoint;
|
void *InsertPoint;
|
||||||
AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
|
AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
|
||||||
|
@ -55,7 +42,9 @@ Attribute Attribute::get(LLVMContext &Context, AttrBuilder &B) {
|
||||||
if (!PA) {
|
if (!PA) {
|
||||||
// If we didn't find any existing attributes of the same shape then create a
|
// If we didn't find any existing attributes of the same shape then create a
|
||||||
// new one and insert it.
|
// new one and insert it.
|
||||||
PA = new AttributeImpl(Context, CI);
|
PA = (!Val) ?
|
||||||
|
new AttributeImpl(Context, Kind) :
|
||||||
|
new AttributeImpl(Context, Kind, Val);
|
||||||
pImpl->AttrsSet.InsertNode(PA, InsertPoint);
|
pImpl->AttrsSet.InsertNode(PA, InsertPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,15 +52,24 @@ Attribute Attribute::get(LLVMContext &Context, AttrBuilder &B) {
|
||||||
return Attribute(PA);
|
return Attribute(PA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Attribute Attribute::get(LLVMContext &Context, AttrKind Kind, Constant *Val) {
|
||||||
|
ConstantInt *KindVal = ConstantInt::get(Type::getInt64Ty(Context), Kind);
|
||||||
|
return get(Context, KindVal, Val);
|
||||||
|
}
|
||||||
|
|
||||||
Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) {
|
Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) {
|
||||||
AttrBuilder B;
|
assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
|
||||||
return get(Context, B.addAlignmentAttr(Align));
|
assert(Align <= 0x40000000 && "Alignment too large.");
|
||||||
|
return get(Context, Alignment,
|
||||||
|
ConstantInt::get(Type::getInt64Ty(Context), Align));
|
||||||
}
|
}
|
||||||
|
|
||||||
Attribute Attribute::getWithStackAlignment(LLVMContext &Context,
|
Attribute Attribute::getWithStackAlignment(LLVMContext &Context,
|
||||||
uint64_t Align) {
|
uint64_t Align) {
|
||||||
AttrBuilder B;
|
assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
|
||||||
return get(Context, B.addStackAlignmentAttr(Align));
|
assert(Align <= 0x100 && "Alignment too large.");
|
||||||
|
return get(Context, StackAlignment,
|
||||||
|
ConstantInt::get(Type::getInt64Ty(Context), Align));
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -250,17 +248,21 @@ AttributeImpl::AttributeImpl(LLVMContext &C, StringRef kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
|
bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
|
||||||
return (Raw() & getAttrMask(A)) != 0;
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(Kind))
|
||||||
|
return CI->getZExtValue() == A;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t AttributeImpl::getAlignment() const {
|
uint64_t AttributeImpl::getAlignment() const {
|
||||||
uint64_t Mask = Raw() & getAttrMask(Attribute::Alignment);
|
assert(hasAttribute(Attribute::Alignment) &&
|
||||||
return 1ULL << ((Mask >> 16) - 1);
|
"Trying to retrieve the alignment from a non-alignment attr!");
|
||||||
|
return cast<ConstantInt>(Vals[0])->getZExtValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t AttributeImpl::getStackAlignment() const {
|
uint64_t AttributeImpl::getStackAlignment() const {
|
||||||
uint64_t Mask = Raw() & getAttrMask(Attribute::StackAlignment);
|
assert(hasAttribute(Attribute::StackAlignment) &&
|
||||||
return 1ULL << ((Mask >> 26) - 1);
|
"Trying to retrieve the stack alignment from a non-alignment attr!");
|
||||||
|
return cast<ConstantInt>(Vals[0])->getZExtValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AttributeImpl::operator==(Attribute::AttrKind kind) const {
|
bool AttributeImpl::operator==(Attribute::AttrKind kind) const {
|
||||||
|
@ -808,12 +810,15 @@ void AttrBuilder::clear() {
|
||||||
}
|
}
|
||||||
|
|
||||||
AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) {
|
AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) {
|
||||||
|
assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment &&
|
||||||
|
"Adding alignment attribute without adding alignment value!");
|
||||||
Attrs.insert(Val);
|
Attrs.insert(Val);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
|
AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
|
||||||
Attrs.erase(Val);
|
Attrs.erase(Val);
|
||||||
|
|
||||||
if (Val == Attribute::Alignment)
|
if (Val == Attribute::Alignment)
|
||||||
Alignment = 0;
|
Alignment = 0;
|
||||||
else if (Val == Attribute::StackAlignment)
|
else if (Val == Attribute::StackAlignment)
|
||||||
|
@ -823,16 +828,13 @@ AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AttrBuilder &AttrBuilder::addAttributes(Attribute Attr) {
|
AttrBuilder &AttrBuilder::addAttributes(Attribute Attr) {
|
||||||
uint64_t Mask = Attr.Raw();
|
ConstantInt *Kind = cast<ConstantInt>(Attr.getAttributeKind());
|
||||||
|
Attribute::AttrKind KindVal = Attribute::AttrKind(Kind->getZExtValue());
|
||||||
|
Attrs.insert(KindVal);
|
||||||
|
|
||||||
for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds;
|
if (KindVal == Attribute::Alignment)
|
||||||
I = Attribute::AttrKind(I + 1))
|
|
||||||
if ((Mask & AttributeImpl::getAttrMask(I)) != 0)
|
|
||||||
Attrs.insert(I);
|
|
||||||
|
|
||||||
if (Attr.getAlignment())
|
|
||||||
Alignment = Attr.getAlignment();
|
Alignment = Attr.getAlignment();
|
||||||
if (Attr.getStackAlignment())
|
else if (KindVal == Attribute::StackAlignment)
|
||||||
StackAlignment = Attr.getStackAlignment();
|
StackAlignment = Attr.getStackAlignment();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,19 +11,19 @@
|
||||||
; propagated correctly. The caller should have its SSP attribute set as:
|
; propagated correctly. The caller should have its SSP attribute set as:
|
||||||
; strictest(caller-ssp-attr, callee-ssp-attr), where strictness is ordered as:
|
; strictest(caller-ssp-attr, callee-ssp-attr), where strictness is ordered as:
|
||||||
; sspreq > sspstrong > ssp > [no ssp]
|
; sspreq > sspstrong > ssp > [no ssp]
|
||||||
define internal void @fun_sspreq() nounwind uwtable sspreq {
|
define internal void @fun_sspreq() nounwind sspreq uwtable {
|
||||||
entry:
|
entry:
|
||||||
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str3, i32 0, i32 0))
|
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str3, i32 0, i32 0))
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define internal void @fun_sspstrong() nounwind uwtable sspstrong {
|
define internal void @fun_sspstrong() nounwind sspstrong uwtable {
|
||||||
entry:
|
entry:
|
||||||
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str2, i32 0, i32 0))
|
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str2, i32 0, i32 0))
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define internal void @fun_ssp() nounwind uwtable ssp {
|
define internal void @fun_ssp() nounwind ssp uwtable {
|
||||||
entry:
|
entry:
|
||||||
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([9 x i8]* @.str1, i32 0, i32 0))
|
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([9 x i8]* @.str1, i32 0, i32 0))
|
||||||
ret void
|
ret void
|
||||||
|
@ -37,21 +37,21 @@ entry:
|
||||||
|
|
||||||
; Tests start below
|
; Tests start below
|
||||||
|
|
||||||
define void @inline_req_req() nounwind uwtable sspreq {
|
define void @inline_req_req() nounwind sspreq uwtable {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: @inline_req_req() nounwind sspreq uwtable
|
; CHECK: @inline_req_req() nounwind sspreq uwtable
|
||||||
call void @fun_sspreq()
|
call void @fun_sspreq()
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @inline_req_strong() nounwind uwtable sspstrong {
|
define void @inline_req_strong() nounwind sspstrong uwtable {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: @inline_req_strong() nounwind sspreq uwtable
|
; CHECK: @inline_req_strong() nounwind sspreq uwtable
|
||||||
call void @fun_sspreq()
|
call void @fun_sspreq()
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @inline_req_ssp() nounwind uwtable ssp {
|
define void @inline_req_ssp() nounwind ssp uwtable {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: @inline_req_ssp() nounwind sspreq uwtable
|
; CHECK: @inline_req_ssp() nounwind sspreq uwtable
|
||||||
call void @fun_sspreq()
|
call void @fun_sspreq()
|
||||||
|
@ -65,7 +65,7 @@ entry:
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @inline_strong_req() nounwind uwtable sspreq {
|
define void @inline_strong_req() nounwind sspreq uwtable {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: @inline_strong_req() nounwind sspreq uwtable
|
; CHECK: @inline_strong_req() nounwind sspreq uwtable
|
||||||
call void @fun_sspstrong()
|
call void @fun_sspstrong()
|
||||||
|
@ -73,28 +73,28 @@ entry:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
define void @inline_strong_strong() nounwind uwtable sspstrong {
|
define void @inline_strong_strong() nounwind sspstrong uwtable {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: @inline_strong_strong() nounwind uwtable sspstrong
|
; CHECK: @inline_strong_strong() nounwind sspstrong uwtable
|
||||||
call void @fun_sspstrong()
|
call void @fun_sspstrong()
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @inline_strong_ssp() nounwind uwtable ssp {
|
define void @inline_strong_ssp() nounwind ssp uwtable {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: @inline_strong_ssp() nounwind uwtable sspstrong
|
; CHECK: @inline_strong_ssp() nounwind sspstrong uwtable
|
||||||
call void @fun_sspstrong()
|
call void @fun_sspstrong()
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @inline_strong_nossp() nounwind uwtable {
|
define void @inline_strong_nossp() nounwind uwtable {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: @inline_strong_nossp() nounwind uwtable sspstrong
|
; CHECK: @inline_strong_nossp() nounwind sspstrong uwtable
|
||||||
call void @fun_sspstrong()
|
call void @fun_sspstrong()
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @inline_ssp_req() nounwind uwtable sspreq {
|
define void @inline_ssp_req() nounwind sspreq uwtable {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: @inline_ssp_req() nounwind sspreq uwtable
|
; CHECK: @inline_ssp_req() nounwind sspreq uwtable
|
||||||
call void @fun_ssp()
|
call void @fun_ssp()
|
||||||
|
@ -102,14 +102,14 @@ entry:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
define void @inline_ssp_strong() nounwind uwtable sspstrong {
|
define void @inline_ssp_strong() nounwind sspstrong uwtable {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: @inline_ssp_strong() nounwind uwtable sspstrong
|
; CHECK: @inline_ssp_strong() nounwind sspstrong uwtable
|
||||||
call void @fun_ssp()
|
call void @fun_ssp()
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @inline_ssp_ssp() nounwind uwtable ssp {
|
define void @inline_ssp_ssp() nounwind ssp uwtable {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: @inline_ssp_ssp() nounwind ssp uwtable
|
; CHECK: @inline_ssp_ssp() nounwind ssp uwtable
|
||||||
call void @fun_ssp()
|
call void @fun_ssp()
|
||||||
|
@ -131,14 +131,14 @@ entry:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
define void @inline_nossp_strong() nounwind uwtable sspstrong {
|
define void @inline_nossp_strong() nounwind sspstrong uwtable {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: @inline_nossp_strong() nounwind uwtable sspstrong
|
; CHECK: @inline_nossp_strong() nounwind sspstrong uwtable
|
||||||
call void @fun_nossp()
|
call void @fun_nossp()
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @inline_nossp_ssp() nounwind uwtable ssp {
|
define void @inline_nossp_ssp() nounwind ssp uwtable {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: @inline_nossp_ssp() nounwind ssp uwtable
|
; CHECK: @inline_nossp_ssp() nounwind ssp uwtable
|
||||||
call void @fun_nossp()
|
call void @fun_nossp()
|
||||||
|
|
|
@ -70,20 +70,20 @@ define void @test4(i8 *%P) {
|
||||||
%A = alloca %1
|
%A = alloca %1
|
||||||
%a = bitcast %1* %A to i8*
|
%a = bitcast %1* %A to i8*
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %P, i64 8, i32 4, i1 false)
|
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %P, i64 8, i32 4, i1 false)
|
||||||
call void @test4a(i8* byval align 1 %a)
|
call void @test4a(i8* align 1 byval %a)
|
||||||
ret void
|
ret void
|
||||||
; CHECK: @test4
|
; CHECK: @test4
|
||||||
; CHECK-NEXT: call void @test4a(
|
; CHECK-NEXT: call void @test4a(
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @test4a(i8* byval align 1)
|
declare void @test4a(i8* align 1 byval)
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
|
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
|
||||||
|
|
||||||
%struct.S = type { i128, [4 x i8]}
|
%struct.S = type { i128, [4 x i8]}
|
||||||
|
|
||||||
@sS = external global %struct.S, align 16
|
@sS = external global %struct.S, align 16
|
||||||
|
|
||||||
declare void @test5a(%struct.S* byval align 16) nounwind ssp
|
declare void @test5a(%struct.S* align 16 byval) nounwind ssp
|
||||||
|
|
||||||
|
|
||||||
; rdar://8713376 - This memcpy can't be eliminated.
|
; rdar://8713376 - This memcpy can't be eliminated.
|
||||||
|
@ -94,11 +94,11 @@ entry:
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp, i8* bitcast (%struct.S* @sS to i8*), i64 32, i32 16, i1 false)
|
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp, i8* bitcast (%struct.S* @sS to i8*), i64 32, i32 16, i1 false)
|
||||||
%a = getelementptr %struct.S* %y, i64 0, i32 1, i64 0
|
%a = getelementptr %struct.S* %y, i64 0, i32 1, i64 0
|
||||||
store i8 4, i8* %a
|
store i8 4, i8* %a
|
||||||
call void @test5a(%struct.S* byval align 16 %y)
|
call void @test5a(%struct.S* align 16 byval %y)
|
||||||
ret i32 0
|
ret i32 0
|
||||||
; CHECK: @test5(
|
; CHECK: @test5(
|
||||||
; CHECK: store i8 4
|
; CHECK: store i8 4
|
||||||
; CHECK: call void @test5a(%struct.S* byval align 16 %y)
|
; CHECK: call void @test5a(%struct.S* align 16 byval %y)
|
||||||
}
|
}
|
||||||
|
|
||||||
;; Noop memcpy should be zapped.
|
;; Noop memcpy should be zapped.
|
||||||
|
@ -114,19 +114,19 @@ define void @test6(i8 *%P) {
|
||||||
; isn't itself 8 byte aligned.
|
; isn't itself 8 byte aligned.
|
||||||
%struct.p = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 }
|
%struct.p = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 }
|
||||||
|
|
||||||
define i32 @test7(%struct.p* nocapture byval align 8 %q) nounwind ssp {
|
define i32 @test7(%struct.p* nocapture align 8 byval %q) nounwind ssp {
|
||||||
entry:
|
entry:
|
||||||
%agg.tmp = alloca %struct.p, align 4
|
%agg.tmp = alloca %struct.p, align 4
|
||||||
%tmp = bitcast %struct.p* %agg.tmp to i8*
|
%tmp = bitcast %struct.p* %agg.tmp to i8*
|
||||||
%tmp1 = bitcast %struct.p* %q to i8*
|
%tmp1 = bitcast %struct.p* %q to i8*
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp, i8* %tmp1, i64 48, i32 4, i1 false)
|
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp, i8* %tmp1, i64 48, i32 4, i1 false)
|
||||||
%call = call i32 @g(%struct.p* byval align 8 %agg.tmp) nounwind
|
%call = call i32 @g(%struct.p* align 8 byval %agg.tmp) nounwind
|
||||||
ret i32 %call
|
ret i32 %call
|
||||||
; CHECK: @test7
|
; CHECK: @test7
|
||||||
; CHECK: call i32 @g(%struct.p* byval align 8 %q) nounwind
|
; CHECK: call i32 @g(%struct.p* align 8 byval %q) nounwind
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i32 @g(%struct.p* byval align 8)
|
declare i32 @g(%struct.p* align 8 byval)
|
||||||
|
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
|
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ declare noalias i8* @malloc(i32)
|
||||||
; rdar://11341081
|
; rdar://11341081
|
||||||
%struct.big = type { [50 x i32] }
|
%struct.big = type { [50 x i32] }
|
||||||
|
|
||||||
define void @test9() nounwind uwtable ssp {
|
define void @test9() nounwind ssp uwtable {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: test9
|
; CHECK: test9
|
||||||
; CHECK: f1
|
; CHECK: f1
|
||||||
|
|
Loading…
Reference in New Issue