1 //===- llvm/unittest/IR/AttributesTest.cpp - Attributes unit tests --------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/IR/Attributes.h"
10 #include "llvm/IR/LLVMContext.h"
11 #include "llvm/IR/DerivedTypes.h"
12 #include "gtest/gtest.h"
17 TEST(Attributes
, Uniquing
) {
20 Attribute AttrA
= Attribute::get(C
, Attribute::AlwaysInline
);
21 Attribute AttrB
= Attribute::get(C
, Attribute::AlwaysInline
);
22 EXPECT_EQ(AttrA
, AttrB
);
24 AttributeList ASs
[] = {AttributeList::get(C
, 1, Attribute::ZExt
),
25 AttributeList::get(C
, 2, Attribute::SExt
)};
27 AttributeList SetA
= AttributeList::get(C
, ASs
);
28 AttributeList SetB
= AttributeList::get(C
, ASs
);
29 EXPECT_EQ(SetA
, SetB
);
32 TEST(Attributes
, Ordering
) {
35 Attribute Align4
= Attribute::get(C
, Attribute::Alignment
, 4);
36 Attribute Align5
= Attribute::get(C
, Attribute::Alignment
, 5);
37 Attribute Deref4
= Attribute::get(C
, Attribute::Dereferenceable
, 4);
38 Attribute Deref5
= Attribute::get(C
, Attribute::Dereferenceable
, 5);
39 EXPECT_TRUE(Align4
< Align5
);
40 EXPECT_TRUE(Align4
< Deref4
);
41 EXPECT_TRUE(Align4
< Deref5
);
42 EXPECT_TRUE(Align5
< Deref4
);
44 Attribute ByVal
= Attribute::get(C
, Attribute::ByVal
, Type::getInt32Ty(C
));
45 EXPECT_FALSE(ByVal
< Attribute::get(C
, Attribute::ZExt
));
46 EXPECT_TRUE(ByVal
< Align4
);
48 AttributeList ASs
[] = {AttributeList::get(C
, 2, Attribute::ZExt
),
49 AttributeList::get(C
, 1, Attribute::SExt
)};
51 AttributeList SetA
= AttributeList::get(C
, ASs
);
52 AttributeList SetB
= SetA
.removeAttributes(C
, 1, ASs
[1].getAttributes(1));
53 EXPECT_NE(SetA
, SetB
);
56 TEST(Attributes
, AddAttributes
) {
60 B
.addAttribute(Attribute::NoReturn
);
61 AL
= AL
.addAttributes(C
, AttributeList::FunctionIndex
, AttributeSet::get(C
, B
));
62 EXPECT_TRUE(AL
.hasFnAttribute(Attribute::NoReturn
));
64 B
.addAttribute(Attribute::SExt
);
65 AL
= AL
.addAttributes(C
, AttributeList::ReturnIndex
, B
);
66 EXPECT_TRUE(AL
.hasAttribute(AttributeList::ReturnIndex
, Attribute::SExt
));
67 EXPECT_TRUE(AL
.hasFnAttribute(Attribute::NoReturn
));
70 TEST(Attributes
, RemoveAlign
) {
73 Attribute AlignAttr
= Attribute::getWithAlignment(C
, 8);
74 Attribute StackAlignAttr
= Attribute::getWithStackAlignment(C
, 32);
75 AttrBuilder B_align_readonly
;
76 B_align_readonly
.addAttribute(AlignAttr
);
77 B_align_readonly
.addAttribute(Attribute::ReadOnly
);
79 B_align
.addAttribute(AlignAttr
);
80 AttrBuilder B_stackalign_optnone
;
81 B_stackalign_optnone
.addAttribute(StackAlignAttr
);
82 B_stackalign_optnone
.addAttribute(Attribute::OptimizeNone
);
83 AttrBuilder B_stackalign
;
84 B_stackalign
.addAttribute(StackAlignAttr
);
86 AttributeSet AS
= AttributeSet::get(C
, B_align_readonly
);
87 EXPECT_TRUE(AS
.getAlignment() == 8);
88 EXPECT_TRUE(AS
.hasAttribute(Attribute::ReadOnly
));
89 AS
= AS
.removeAttribute(C
, Attribute::Alignment
);
90 EXPECT_FALSE(AS
.hasAttribute(Attribute::Alignment
));
91 EXPECT_TRUE(AS
.hasAttribute(Attribute::ReadOnly
));
92 AS
= AttributeSet::get(C
, B_align_readonly
);
93 AS
= AS
.removeAttributes(C
, B_align
);
94 EXPECT_TRUE(AS
.getAlignment() == 0);
95 EXPECT_TRUE(AS
.hasAttribute(Attribute::ReadOnly
));
98 AL
= AL
.addParamAttributes(C
, 0, B_align_readonly
);
99 AL
= AL
.addAttributes(C
, 0, B_stackalign_optnone
);
100 EXPECT_TRUE(AL
.hasAttributes(0));
101 EXPECT_TRUE(AL
.hasAttribute(0, Attribute::StackAlignment
));
102 EXPECT_TRUE(AL
.hasAttribute(0, Attribute::OptimizeNone
));
103 EXPECT_TRUE(AL
.getStackAlignment(0) == 32);
104 EXPECT_TRUE(AL
.hasParamAttrs(0));
105 EXPECT_TRUE(AL
.hasParamAttr(0, Attribute::Alignment
));
106 EXPECT_TRUE(AL
.hasParamAttr(0, Attribute::ReadOnly
));
107 EXPECT_TRUE(AL
.getParamAlignment(0) == 8);
109 AL
= AL
.removeParamAttribute(C
, 0, Attribute::Alignment
);
110 EXPECT_FALSE(AL
.hasParamAttr(0, Attribute::Alignment
));
111 EXPECT_TRUE(AL
.hasParamAttr(0, Attribute::ReadOnly
));
112 EXPECT_TRUE(AL
.hasAttribute(0, Attribute::StackAlignment
));
113 EXPECT_TRUE(AL
.hasAttribute(0, Attribute::OptimizeNone
));
114 EXPECT_TRUE(AL
.getStackAlignment(0) == 32);
116 AL
= AL
.removeAttribute(C
, 0, Attribute::StackAlignment
);
117 EXPECT_FALSE(AL
.hasParamAttr(0, Attribute::Alignment
));
118 EXPECT_TRUE(AL
.hasParamAttr(0, Attribute::ReadOnly
));
119 EXPECT_FALSE(AL
.hasAttribute(0, Attribute::StackAlignment
));
120 EXPECT_TRUE(AL
.hasAttribute(0, Attribute::OptimizeNone
));
123 AL2
= AL2
.addParamAttributes(C
, 0, B_align_readonly
);
124 AL2
= AL2
.addAttributes(C
, 0, B_stackalign_optnone
);
126 AL2
= AL2
.removeParamAttributes(C
, 0, B_align
);
127 EXPECT_FALSE(AL2
.hasParamAttr(0, Attribute::Alignment
));
128 EXPECT_TRUE(AL2
.hasParamAttr(0, Attribute::ReadOnly
));
129 EXPECT_TRUE(AL2
.hasAttribute(0, Attribute::StackAlignment
));
130 EXPECT_TRUE(AL2
.hasAttribute(0, Attribute::OptimizeNone
));
131 EXPECT_TRUE(AL2
.getStackAlignment(0) == 32);
133 AL2
= AL2
.removeAttributes(C
, 0, B_stackalign
);
134 EXPECT_FALSE(AL2
.hasParamAttr(0, Attribute::Alignment
));
135 EXPECT_TRUE(AL2
.hasParamAttr(0, Attribute::ReadOnly
));
136 EXPECT_FALSE(AL2
.hasAttribute(0, Attribute::StackAlignment
));
137 EXPECT_TRUE(AL2
.hasAttribute(0, Attribute::OptimizeNone
));
140 TEST(Attributes
, AddMatchingAlignAttr
) {
143 AL
= AL
.addAttribute(C
, AttributeList::FirstArgIndex
,
144 Attribute::getWithAlignment(C
, 8));
145 AL
= AL
.addAttribute(C
, AttributeList::FirstArgIndex
+ 1,
146 Attribute::getWithAlignment(C
, 32));
147 EXPECT_EQ(8U, AL
.getParamAlignment(0));
148 EXPECT_EQ(32U, AL
.getParamAlignment(1));
151 B
.addAttribute(Attribute::NonNull
);
152 B
.addAlignmentAttr(8);
153 AL
= AL
.addAttributes(C
, AttributeList::FirstArgIndex
, B
);
154 EXPECT_EQ(8U, AL
.getParamAlignment(0));
155 EXPECT_EQ(32U, AL
.getParamAlignment(1));
156 EXPECT_TRUE(AL
.hasParamAttribute(0, Attribute::NonNull
));
159 TEST(Attributes
, EmptyGet
) {
161 AttributeList EmptyLists
[] = {AttributeList(), AttributeList()};
162 AttributeList AL
= AttributeList::get(C
, EmptyLists
);
163 EXPECT_TRUE(AL
.isEmpty());
166 TEST(Attributes
, OverflowGet
) {
168 std::pair
<unsigned, Attribute
> Attrs
[] = { { AttributeList::ReturnIndex
, Attribute::get(C
, Attribute::SExt
) },
169 { AttributeList::FunctionIndex
, Attribute::get(C
, Attribute::ReadOnly
) } };
170 AttributeList AL
= AttributeList::get(C
, Attrs
);
171 EXPECT_EQ(2U, AL
.getNumAttrSets());
174 TEST(Attributes
, StringRepresentation
) {
176 StructType
*Ty
= StructType::create(Type::getInt32Ty(C
), "mystruct");
178 // Insufficiently careful printing can result in byval(%mystruct = { i32 })
179 Attribute A
= Attribute::getWithByValType(C
, Ty
);
180 EXPECT_EQ(A
.getAsString(), "byval(%mystruct)");
182 A
= Attribute::getWithByValType(C
, nullptr);
183 EXPECT_EQ(A
.getAsString(), "byval");
185 A
= Attribute::getWithByValType(C
, Type::getInt32Ty(C
));
186 EXPECT_EQ(A
.getAsString(), "byval(i32)");
189 } // end anonymous namespace