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