AttributesTest.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. //===- llvm/unittest/IR/AttributesTest.cpp - Attributes unit tests --------===//
  2. //
  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
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/IR/Attributes.h"
  9. #include "llvm/IR/LLVMContext.h"
  10. #include "llvm/IR/DerivedTypes.h"
  11. #include "gtest/gtest.h"
  12. using namespace llvm;
  13. namespace {
  14. TEST(Attributes, Uniquing) {
  15. LLVMContext C;
  16. Attribute AttrA = Attribute::get(C, Attribute::AlwaysInline);
  17. Attribute AttrB = Attribute::get(C, Attribute::AlwaysInline);
  18. EXPECT_EQ(AttrA, AttrB);
  19. AttributeList ASs[] = {AttributeList::get(C, 1, Attribute::ZExt),
  20. AttributeList::get(C, 2, Attribute::SExt)};
  21. AttributeList SetA = AttributeList::get(C, ASs);
  22. AttributeList SetB = AttributeList::get(C, ASs);
  23. EXPECT_EQ(SetA, SetB);
  24. }
  25. TEST(Attributes, Ordering) {
  26. LLVMContext C;
  27. Attribute Align4 = Attribute::get(C, Attribute::Alignment, 4);
  28. Attribute Align5 = Attribute::get(C, Attribute::Alignment, 5);
  29. Attribute Deref4 = Attribute::get(C, Attribute::Dereferenceable, 4);
  30. Attribute Deref5 = Attribute::get(C, Attribute::Dereferenceable, 5);
  31. EXPECT_TRUE(Align4 < Align5);
  32. EXPECT_TRUE(Align4 < Deref4);
  33. EXPECT_TRUE(Align4 < Deref5);
  34. EXPECT_TRUE(Align5 < Deref4);
  35. Attribute ByVal = Attribute::get(C, Attribute::ByVal, Type::getInt32Ty(C));
  36. EXPECT_FALSE(ByVal < Attribute::get(C, Attribute::ZExt));
  37. EXPECT_TRUE(ByVal < Align4);
  38. AttributeList ASs[] = {AttributeList::get(C, 2, Attribute::ZExt),
  39. AttributeList::get(C, 1, Attribute::SExt)};
  40. AttributeList SetA = AttributeList::get(C, ASs);
  41. AttributeList SetB = SetA.removeAttributes(C, 1, ASs[1].getAttributes(1));
  42. EXPECT_NE(SetA, SetB);
  43. }
  44. TEST(Attributes, AddAttributes) {
  45. LLVMContext C;
  46. AttributeList AL;
  47. AttrBuilder B;
  48. B.addAttribute(Attribute::NoReturn);
  49. AL = AL.addAttributes(C, AttributeList::FunctionIndex, AttributeSet::get(C, B));
  50. EXPECT_TRUE(AL.hasFnAttribute(Attribute::NoReturn));
  51. B.clear();
  52. B.addAttribute(Attribute::SExt);
  53. AL = AL.addAttributes(C, AttributeList::ReturnIndex, B);
  54. EXPECT_TRUE(AL.hasAttribute(AttributeList::ReturnIndex, Attribute::SExt));
  55. EXPECT_TRUE(AL.hasFnAttribute(Attribute::NoReturn));
  56. }
  57. TEST(Attributes, RemoveAlign) {
  58. LLVMContext C;
  59. Attribute AlignAttr = Attribute::getWithAlignment(C, Align(8));
  60. Attribute StackAlignAttr = Attribute::getWithStackAlignment(C, Align(32));
  61. AttrBuilder B_align_readonly;
  62. B_align_readonly.addAttribute(AlignAttr);
  63. B_align_readonly.addAttribute(Attribute::ReadOnly);
  64. AttrBuilder B_align;
  65. B_align.addAttribute(AlignAttr);
  66. AttrBuilder B_stackalign_optnone;
  67. B_stackalign_optnone.addAttribute(StackAlignAttr);
  68. B_stackalign_optnone.addAttribute(Attribute::OptimizeNone);
  69. AttrBuilder B_stackalign;
  70. B_stackalign.addAttribute(StackAlignAttr);
  71. AttributeSet AS = AttributeSet::get(C, B_align_readonly);
  72. EXPECT_TRUE(AS.getAlignment() == 8);
  73. EXPECT_TRUE(AS.hasAttribute(Attribute::ReadOnly));
  74. AS = AS.removeAttribute(C, Attribute::Alignment);
  75. EXPECT_FALSE(AS.hasAttribute(Attribute::Alignment));
  76. EXPECT_TRUE(AS.hasAttribute(Attribute::ReadOnly));
  77. AS = AttributeSet::get(C, B_align_readonly);
  78. AS = AS.removeAttributes(C, B_align);
  79. EXPECT_TRUE(AS.getAlignment() == 0);
  80. EXPECT_TRUE(AS.hasAttribute(Attribute::ReadOnly));
  81. AttributeList AL;
  82. AL = AL.addParamAttributes(C, 0, B_align_readonly);
  83. AL = AL.addAttributes(C, 0, B_stackalign_optnone);
  84. EXPECT_TRUE(AL.hasAttributes(0));
  85. EXPECT_TRUE(AL.hasAttribute(0, Attribute::StackAlignment));
  86. EXPECT_TRUE(AL.hasAttribute(0, Attribute::OptimizeNone));
  87. EXPECT_TRUE(AL.getStackAlignment(0) == 32);
  88. EXPECT_TRUE(AL.hasParamAttrs(0));
  89. EXPECT_TRUE(AL.hasParamAttr(0, Attribute::Alignment));
  90. EXPECT_TRUE(AL.hasParamAttr(0, Attribute::ReadOnly));
  91. EXPECT_TRUE(AL.getParamAlignment(0) == 8);
  92. AL = AL.removeParamAttribute(C, 0, Attribute::Alignment);
  93. EXPECT_FALSE(AL.hasParamAttr(0, Attribute::Alignment));
  94. EXPECT_TRUE(AL.hasParamAttr(0, Attribute::ReadOnly));
  95. EXPECT_TRUE(AL.hasAttribute(0, Attribute::StackAlignment));
  96. EXPECT_TRUE(AL.hasAttribute(0, Attribute::OptimizeNone));
  97. EXPECT_TRUE(AL.getStackAlignment(0) == 32);
  98. AL = AL.removeAttribute(C, 0, Attribute::StackAlignment);
  99. EXPECT_FALSE(AL.hasParamAttr(0, Attribute::Alignment));
  100. EXPECT_TRUE(AL.hasParamAttr(0, Attribute::ReadOnly));
  101. EXPECT_FALSE(AL.hasAttribute(0, Attribute::StackAlignment));
  102. EXPECT_TRUE(AL.hasAttribute(0, Attribute::OptimizeNone));
  103. AttributeList AL2;
  104. AL2 = AL2.addParamAttributes(C, 0, B_align_readonly);
  105. AL2 = AL2.addAttributes(C, 0, B_stackalign_optnone);
  106. AL2 = AL2.removeParamAttributes(C, 0, B_align);
  107. EXPECT_FALSE(AL2.hasParamAttr(0, Attribute::Alignment));
  108. EXPECT_TRUE(AL2.hasParamAttr(0, Attribute::ReadOnly));
  109. EXPECT_TRUE(AL2.hasAttribute(0, Attribute::StackAlignment));
  110. EXPECT_TRUE(AL2.hasAttribute(0, Attribute::OptimizeNone));
  111. EXPECT_TRUE(AL2.getStackAlignment(0) == 32);
  112. AL2 = AL2.removeAttributes(C, 0, B_stackalign);
  113. EXPECT_FALSE(AL2.hasParamAttr(0, Attribute::Alignment));
  114. EXPECT_TRUE(AL2.hasParamAttr(0, Attribute::ReadOnly));
  115. EXPECT_FALSE(AL2.hasAttribute(0, Attribute::StackAlignment));
  116. EXPECT_TRUE(AL2.hasAttribute(0, Attribute::OptimizeNone));
  117. }
  118. TEST(Attributes, AddMatchingAlignAttr) {
  119. LLVMContext C;
  120. AttributeList AL;
  121. AL = AL.addAttribute(C, AttributeList::FirstArgIndex,
  122. Attribute::getWithAlignment(C, Align(8)));
  123. AL = AL.addAttribute(C, AttributeList::FirstArgIndex + 1,
  124. Attribute::getWithAlignment(C, Align(32)));
  125. EXPECT_EQ(Align(8), AL.getParamAlignment(0));
  126. EXPECT_EQ(Align(32), AL.getParamAlignment(1));
  127. AttrBuilder B;
  128. B.addAttribute(Attribute::NonNull);
  129. B.addAlignmentAttr(8);
  130. AL = AL.addAttributes(C, AttributeList::FirstArgIndex, B);
  131. EXPECT_EQ(Align(8), AL.getParamAlignment(0));
  132. EXPECT_EQ(Align(32), AL.getParamAlignment(1));
  133. EXPECT_TRUE(AL.hasParamAttribute(0, Attribute::NonNull));
  134. }
  135. TEST(Attributes, EmptyGet) {
  136. LLVMContext C;
  137. AttributeList EmptyLists[] = {AttributeList(), AttributeList()};
  138. AttributeList AL = AttributeList::get(C, EmptyLists);
  139. EXPECT_TRUE(AL.isEmpty());
  140. }
  141. TEST(Attributes, OverflowGet) {
  142. LLVMContext C;
  143. std::pair<unsigned, Attribute> Attrs[] = { { AttributeList::ReturnIndex, Attribute::get(C, Attribute::SExt) },
  144. { AttributeList::FunctionIndex, Attribute::get(C, Attribute::ReadOnly) } };
  145. AttributeList AL = AttributeList::get(C, Attrs);
  146. EXPECT_EQ(2U, AL.getNumAttrSets());
  147. }
  148. TEST(Attributes, StringRepresentation) {
  149. LLVMContext C;
  150. StructType *Ty = StructType::create(Type::getInt32Ty(C), "mystruct");
  151. // Insufficiently careful printing can result in byval(%mystruct = { i32 })
  152. Attribute A = Attribute::getWithByValType(C, Ty);
  153. EXPECT_EQ(A.getAsString(), "byval(%mystruct)");
  154. A = Attribute::getWithByValType(C, nullptr);
  155. EXPECT_EQ(A.getAsString(), "byval");
  156. A = Attribute::getWithByValType(C, Type::getInt32Ty(C));
  157. EXPECT_EQ(A.getAsString(), "byval(i32)");
  158. }
  159. } // end anonymous namespace