1 //=== - llvm/unittest/Support/Alignment.cpp - Alignment utility 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 9 #include "llvm/Support/Alignment.h" 10 #include "gtest/gtest.h" 11 12 #include <vector> 13 14 using namespace llvm; 15 16 namespace { 17 18 std::vector<uint64_t> getValidAlignments() { 19 std::vector<uint64_t> Out; 20 for (size_t Shift = 0; Shift < 64; ++Shift) 21 Out.push_back(1ULL << Shift); 22 return Out; 23 } 24 25 TEST(AlignmentTest, AlignDefaultCTor) { EXPECT_EQ(Align().value(), 1ULL); } 26 27 TEST(AlignmentTest, MaybeAlignDefaultCTor) { 28 EXPECT_FALSE(MaybeAlign().hasValue()); 29 } 30 31 TEST(AlignmentTest, ValidCTors) { 32 for (uint64_t Value : getValidAlignments()) { 33 EXPECT_EQ(Align(Value).value(), Value); 34 EXPECT_EQ((*MaybeAlign(Value)).value(), Value); 35 } 36 } 37 38 TEST(AlignmentTest, CheckMaybeAlignHasValue) { 39 EXPECT_TRUE(MaybeAlign(1)); 40 EXPECT_TRUE(MaybeAlign(1).hasValue()); 41 EXPECT_FALSE(MaybeAlign(0)); 42 EXPECT_FALSE(MaybeAlign(0).hasValue()); 43 EXPECT_FALSE(MaybeAlign()); 44 EXPECT_FALSE(MaybeAlign().hasValue()); 45 } 46 47 TEST(AlignmentTest, Division) { 48 for (uint64_t Value : getValidAlignments()) { 49 if (Value > 1) { 50 EXPECT_EQ(Align(Value) / 2, Value / 2); 51 EXPECT_EQ(MaybeAlign(Value) / 2, Value / 2); 52 } 53 } 54 EXPECT_EQ(MaybeAlign(0) / 2, MaybeAlign(0)); 55 } 56 57 TEST(AlignmentTest, AlignTo) { 58 struct { 59 uint64_t alignment; 60 uint64_t offset; 61 uint64_t rounded; 62 } kTests[] = { 63 // MaybeAlign 64 {0, 0, 0}, 65 {0, 1, 1}, 66 {0, 5, 5}, 67 // MaybeAlign / Align 68 {1, 0, 0}, 69 {1, 1, 1}, 70 {1, 5, 5}, 71 {2, 0, 0}, 72 {2, 1, 2}, 73 {2, 2, 2}, 74 {2, 7, 8}, 75 {2, 16, 16}, 76 {4, 0, 0}, 77 {4, 1, 4}, 78 {4, 4, 4}, 79 {4, 6, 8}, 80 }; 81 for (const auto &T : kTests) { 82 MaybeAlign A(T.alignment); 83 // Test MaybeAlign 84 EXPECT_EQ(alignTo(T.offset, A), T.rounded); 85 // Test Align 86 if (A) 87 EXPECT_EQ(alignTo(T.offset, A.getValue()), T.rounded); 88 } 89 } 90 91 TEST(AlignmentTest, Log2) { 92 for (uint64_t Value : getValidAlignments()) { 93 EXPECT_EQ(Log2(Align(Value)), Log2_64(Value)); 94 EXPECT_EQ(Log2(MaybeAlign(Value)), Log2_64(Value)); 95 } 96 } 97 98 TEST(AlignmentTest, MinAlign) { 99 struct { 100 uint64_t A; 101 uint64_t B; 102 uint64_t MinAlign; 103 } kTests[] = { 104 // MaybeAlign 105 {0, 0, 0}, 106 {0, 8, 8}, 107 {2, 0, 2}, 108 // MaybeAlign / Align 109 {1, 2, 1}, 110 {8, 4, 4}, 111 }; 112 for (const auto &T : kTests) { 113 EXPECT_EQ(commonAlignment(MaybeAlign(T.A), MaybeAlign(T.B)), T.MinAlign); 114 EXPECT_EQ(MinAlign(T.A, T.B), T.MinAlign); 115 if (T.A) 116 EXPECT_EQ(commonAlignment(Align(T.A), MaybeAlign(T.B)), T.MinAlign); 117 if (T.B) 118 EXPECT_EQ(commonAlignment(MaybeAlign(T.A), Align(T.B)), T.MinAlign); 119 if (T.A && T.B) 120 EXPECT_EQ(commonAlignment(Align(T.A), Align(T.B)), T.MinAlign); 121 } 122 } 123 124 TEST(AlignmentTest, Encode_Decode) { 125 for (uint64_t Value : getValidAlignments()) { 126 { 127 Align Actual(Value); 128 Align Expected = decodeMaybeAlign(encode(Actual)).getValue(); 129 EXPECT_EQ(Expected, Actual); 130 } 131 { 132 MaybeAlign Actual(Value); 133 MaybeAlign Expected = decodeMaybeAlign(encode(Actual)); 134 EXPECT_EQ(Expected, Actual); 135 } 136 } 137 MaybeAlign Actual(0); 138 MaybeAlign Expected = decodeMaybeAlign(encode(Actual)); 139 EXPECT_EQ(Expected, Actual); 140 } 141 142 TEST(AlignmentTest, isAligned) { 143 struct { 144 uint64_t alignment; 145 uint64_t offset; 146 bool isAligned; 147 } kTests[] = { 148 // MaybeAlign / Align 149 {1, 0, true}, {1, 1, true}, {1, 5, true}, {2, 0, true}, 150 {2, 1, false}, {2, 2, true}, {2, 7, false}, {2, 16, true}, 151 {4, 0, true}, {4, 1, false}, {4, 4, true}, {4, 6, false}, 152 }; 153 for (const auto &T : kTests) { 154 MaybeAlign A(T.alignment); 155 // Test MaybeAlign 156 EXPECT_EQ(isAligned(A, T.offset), T.isAligned); 157 // Test Align 158 if (A) 159 EXPECT_EQ(isAligned(A.getValue(), T.offset), T.isAligned); 160 } 161 } 162 163 TEST(AlignmentTest, AlignComparisons) { 164 std::vector<uint64_t> ValidAlignments = getValidAlignments(); 165 std::sort(ValidAlignments.begin(), ValidAlignments.end()); 166 for (size_t I = 1; I < ValidAlignments.size(); ++I) { 167 assert(I >= 1); 168 const Align A(ValidAlignments[I - 1]); 169 const Align B(ValidAlignments[I]); 170 EXPECT_EQ(A, A); 171 EXPECT_NE(A, B); 172 EXPECT_LT(A, B); 173 EXPECT_GT(B, A); 174 EXPECT_LE(A, B); 175 EXPECT_GE(B, A); 176 EXPECT_LE(A, A); 177 EXPECT_GE(A, A); 178 179 EXPECT_EQ(A, A.value()); 180 EXPECT_NE(A, B.value()); 181 EXPECT_LT(A, B.value()); 182 EXPECT_GT(B, A.value()); 183 EXPECT_LE(A, B.value()); 184 EXPECT_GE(B, A.value()); 185 EXPECT_LE(A, A.value()); 186 EXPECT_GE(A, A.value()); 187 188 EXPECT_EQ(std::max(A, B), B); 189 EXPECT_EQ(std::min(A, B), A); 190 191 const MaybeAlign MA(ValidAlignments[I - 1]); 192 const MaybeAlign MB(ValidAlignments[I]); 193 EXPECT_EQ(MA, MA); 194 EXPECT_NE(MA, MB); 195 EXPECT_LT(MA, MB); 196 EXPECT_GT(MB, MA); 197 EXPECT_LE(MA, MB); 198 EXPECT_GE(MB, MA); 199 EXPECT_LE(MA, MA); 200 EXPECT_GE(MA, MA); 201 202 EXPECT_EQ(MA, MA ? (*MA).value() : 0); 203 EXPECT_NE(MA, MB ? (*MB).value() : 0); 204 EXPECT_LT(MA, MB ? (*MB).value() : 0); 205 EXPECT_GT(MB, MA ? (*MA).value() : 0); 206 EXPECT_LE(MA, MB ? (*MB).value() : 0); 207 EXPECT_GE(MB, MA ? (*MA).value() : 0); 208 EXPECT_LE(MA, MA ? (*MA).value() : 0); 209 EXPECT_GE(MA, MA ? (*MA).value() : 0); 210 211 EXPECT_EQ(std::max(A, B), B); 212 EXPECT_EQ(std::min(A, B), A); 213 } 214 } 215 216 TEST(AlignmentTest, AssumeAligned) { 217 EXPECT_EQ(assumeAligned(0), Align(1)); 218 EXPECT_EQ(assumeAligned(0), Align()); 219 EXPECT_EQ(assumeAligned(1), Align(1)); 220 EXPECT_EQ(assumeAligned(1), Align()); 221 } 222 223 // Death tests reply on assert which is disabled in release mode. 224 #ifndef NDEBUG 225 226 // We use a subset of valid alignments for DEATH_TESTs as they are particularly 227 // slow. 228 std::vector<uint64_t> getValidAlignmentsForDeathTest() { 229 return {1, 1ULL << 31, 1ULL << 63}; 230 } 231 232 std::vector<uint64_t> getNonPowerOfTwo() { return {3, 10, 15}; } 233 234 TEST(AlignmentDeathTest, Log2) { 235 EXPECT_DEATH(Log2(MaybeAlign(0)), ".* should be defined"); 236 } 237 238 TEST(AlignmentDeathTest, CantConvertUnsetMaybe) { 239 EXPECT_DEATH((MaybeAlign(0).getValue()), ".*"); 240 } 241 242 TEST(AlignmentDeathTest, Division) { 243 EXPECT_DEATH(Align(1) / 2, "Can't halve byte alignment"); 244 EXPECT_DEATH(MaybeAlign(1) / 2, "Can't halve byte alignment"); 245 246 EXPECT_DEATH(Align(8) / 0, "Divisor must be positive and a power of 2"); 247 EXPECT_DEATH(Align(8) / 3, "Divisor must be positive and a power of 2"); 248 } 249 250 TEST(AlignmentDeathTest, InvalidCTors) { 251 EXPECT_DEATH((Align(0)), "Value must not be 0"); 252 for (uint64_t Value : getNonPowerOfTwo()) { 253 EXPECT_DEATH((Align(Value)), "Alignment is not a power of 2"); 254 EXPECT_DEATH((MaybeAlign(Value)), "Alignment is not 0 or a power of 2"); 255 } 256 } 257 258 TEST(AlignmentDeathTest, ComparisonsWithZero) { 259 for (uint64_t Value : getValidAlignmentsForDeathTest()) { 260 EXPECT_DEATH((void)(Align(Value) == 0), ".* should be defined"); 261 EXPECT_DEATH((void)(Align(Value) != 0), ".* should be defined"); 262 EXPECT_DEATH((void)(Align(Value) >= 0), ".* should be defined"); 263 EXPECT_DEATH((void)(Align(Value) <= 0), ".* should be defined"); 264 EXPECT_DEATH((void)(Align(Value) > 0), ".* should be defined"); 265 EXPECT_DEATH((void)(Align(Value) < 0), ".* should be defined"); 266 } 267 } 268 269 TEST(AlignmentDeathTest, CompareMaybeAlignToZero) { 270 for (uint64_t Value : getValidAlignmentsForDeathTest()) { 271 // MaybeAlign is allowed to be == or != 0 272 (void)(MaybeAlign(Value) == 0); 273 (void)(MaybeAlign(Value) != 0); 274 EXPECT_DEATH((void)(MaybeAlign(Value) >= 0), ".* should be defined"); 275 EXPECT_DEATH((void)(MaybeAlign(Value) <= 0), ".* should be defined"); 276 EXPECT_DEATH((void)(MaybeAlign(Value) > 0), ".* should be defined"); 277 EXPECT_DEATH((void)(MaybeAlign(Value) < 0), ".* should be defined"); 278 } 279 } 280 281 TEST(AlignmentDeathTest, CompareAlignToUndefMaybeAlign) { 282 for (uint64_t Value : getValidAlignmentsForDeathTest()) { 283 EXPECT_DEATH((void)(Align(Value) == MaybeAlign(0)), ".* should be defined"); 284 EXPECT_DEATH((void)(Align(Value) != MaybeAlign(0)), ".* should be defined"); 285 EXPECT_DEATH((void)(Align(Value) >= MaybeAlign(0)), ".* should be defined"); 286 EXPECT_DEATH((void)(Align(Value) <= MaybeAlign(0)), ".* should be defined"); 287 EXPECT_DEATH((void)(Align(Value) > MaybeAlign(0)), ".* should be defined"); 288 EXPECT_DEATH((void)(Align(Value) < MaybeAlign(0)), ".* should be defined"); 289 } 290 } 291 292 #endif // NDEBUG 293 294 } // end anonymous namespace 295