diff options
295 files changed, 6223 insertions, 2041 deletions
diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp index 8aae414..799c64b 100644 --- a/clang-tools-extra/clangd/FindTarget.cpp +++ b/clang-tools-extra/clangd/FindTarget.cpp @@ -1040,16 +1040,11 @@ private: if (auto *S = N.get<Stmt>()) return refInStmt(S, Resolver); if (auto *NNSL = N.get<NestedNameSpecifierLoc>()) { + if (auto TL = NNSL->getAsTypeLoc()) + return refInTypeLoc(NNSL->getAsTypeLoc(), Resolver); // (!) 'DeclRelation::Alias' ensures we do not lose namespace aliases. - NestedNameSpecifierLoc Qualifier; - SourceLocation NameLoc; - if (auto TL = NNSL->getAsTypeLoc()) { - Qualifier = TL.getPrefix(); - NameLoc = TL.getNonPrefixBeginLoc(); - } else { - Qualifier = NNSL->getAsNamespaceAndPrefix().Prefix; - NameLoc = NNSL->getLocalBeginLoc(); - } + NestedNameSpecifierLoc Qualifier = NNSL->getAsNamespaceAndPrefix().Prefix; + SourceLocation NameLoc = NNSL->getLocalBeginLoc(); return { ReferenceLoc{Qualifier, NameLoc, false, explicitReferenceTargets( diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-addition.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-addition.cpp index 562b513..cc41603 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-addition.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-addition.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s abseil-duration-addition %t -- -- -I%S/Inputs +// RUN: %check_clang_tidy %s abseil-duration-addition %t -- -- -I%S/Inputs #include "absl/time/time.h" @@ -8,68 +8,68 @@ void f() { i = absl::ToUnixHours(t) + 5; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixHours(t + absl::Hours(5)) + // CHECK-FIXES: i = absl::ToUnixHours(t + absl::Hours(5)); i = absl::ToUnixMinutes(t) + 5; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixMinutes(t + absl::Minutes(5)) + // CHECK-FIXES: i = absl::ToUnixMinutes(t + absl::Minutes(5)); i = absl::ToUnixSeconds(t) + 5; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5)) + // CHECK-FIXES: i = absl::ToUnixSeconds(t + absl::Seconds(5)); i = absl::ToUnixMillis(t) + 5; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixMillis(t + absl::Milliseconds(5)) + // CHECK-FIXES: i = absl::ToUnixMillis(t + absl::Milliseconds(5)); i = absl::ToUnixMicros(t) + 5; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixMicros(t + absl::Microseconds(5)) + // CHECK-FIXES: i = absl::ToUnixMicros(t + absl::Microseconds(5)); i = absl::ToUnixNanos(t) + 5; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixNanos(t + absl::Nanoseconds(5)) + // CHECK-FIXES: i = absl::ToUnixNanos(t + absl::Nanoseconds(5)); i = 3 + absl::ToUnixHours(t); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t) + // CHECK-FIXES: i = absl::ToUnixHours(absl::Hours(3) + t); i = 3 + absl::ToUnixMinutes(t); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixMinutes(absl::Minutes(3) + t) + // CHECK-FIXES: i = absl::ToUnixMinutes(absl::Minutes(3) + t); i = 3 + absl::ToUnixSeconds(t); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixSeconds(absl::Seconds(3) + t) + // CHECK-FIXES: i = absl::ToUnixSeconds(absl::Seconds(3) + t); i = 3 + absl::ToUnixMillis(t); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixMillis(absl::Milliseconds(3) + t) + // CHECK-FIXES: i = absl::ToUnixMillis(absl::Milliseconds(3) + t); i = 3 + absl::ToUnixMicros(t); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixMicros(absl::Microseconds(3) + t) + // CHECK-FIXES: i = absl::ToUnixMicros(absl::Microseconds(3) + t); i = 3 + absl::ToUnixNanos(t); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixNanos(absl::Nanoseconds(3) + t) + // CHECK-FIXES: i = absl::ToUnixNanos(absl::Nanoseconds(3) + t); // Undoing inverse conversions i = absl::ToUnixMicros(t) + absl::ToInt64Microseconds(absl::Seconds(1)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixMicros(t + absl::Seconds(1)) + // CHECK-FIXES: i = absl::ToUnixMicros(t + absl::Seconds(1)); // Parens i = 3 + (absl::ToUnixHours(t)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t) + // CHECK-FIXES: i = absl::ToUnixHours(absl::Hours(3) + t); // Float folding i = absl::ToUnixSeconds(t) + 5.0; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5)) + // CHECK-FIXES: i = absl::ToUnixSeconds(t + absl::Seconds(5)); // We can rewrite the argument of the duration conversion #define THIRTY absl::FromUnixSeconds(30) i = absl::ToUnixSeconds(THIRTY) + 1; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixSeconds(THIRTY + absl::Seconds(1)) + // CHECK-FIXES: i = absl::ToUnixSeconds(THIRTY + absl::Seconds(1)); #undef THIRTY // Some other contexts if (absl::ToUnixSeconds(t) + 1.0 > 10) {} // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(1)) + // CHECK-FIXES: if (absl::ToUnixSeconds(t + absl::Seconds(1)) > 10) {} // These should not match i = 5 + 6; @@ -88,7 +88,7 @@ template<typename T> void foo(absl::Time t) { int i = absl::ToUnixNanos(t) + T{}; // CHECK-MESSAGES: [[@LINE-1]]:11: warning: perform addition in the duration domain [abseil-duration-addition] - // CHECK-FIXES: absl::ToUnixNanos(t + absl::Nanoseconds(T{})) + // CHECK-FIXES: int i = absl::ToUnixNanos(t + absl::Nanoseconds(T{})); } void g() { diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-comparison.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-comparison.cpp index 6110dfd..8f49e71 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-comparison.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-comparison.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s abseil-duration-comparison %t -- -- -I%S/Inputs +// RUN: %check_clang_tidy %s abseil-duration-comparison %t -- -- -I%S/Inputs #include "absl/time/time.h" @@ -11,104 +11,104 @@ void f() { // Check against the RHS b = x > absl::ToDoubleSeconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Seconds(x) > d1; + // CHECK-FIXES: b = absl::Seconds(x) > d1; b = x >= absl::ToDoubleSeconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Seconds(x) >= d1; + // CHECK-FIXES: b = absl::Seconds(x) >= d1; b = x == absl::ToDoubleSeconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Seconds(x) == d1; + // CHECK-FIXES: b = absl::Seconds(x) == d1; b = x <= absl::ToDoubleSeconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Seconds(x) <= d1; + // CHECK-FIXES: b = absl::Seconds(x) <= d1; b = x < absl::ToDoubleSeconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Seconds(x) < d1; + // CHECK-FIXES: b = absl::Seconds(x) < d1; b = x == absl::ToDoubleSeconds(t1 - t2); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Seconds(x) == t1 - t2; + // CHECK-FIXES: b = absl::Seconds(x) == t1 - t2; b = absl::ToDoubleSeconds(d1) > absl::ToDoubleSeconds(d2); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: d1 > d2; + // CHECK-FIXES: b = d1 > d2; // Check against the LHS b = absl::ToDoubleSeconds(d1) < x; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: d1 < absl::Seconds(x); + // CHECK-FIXES: b = d1 < absl::Seconds(x); b = absl::ToDoubleSeconds(d1) <= x; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: d1 <= absl::Seconds(x); + // CHECK-FIXES: b = d1 <= absl::Seconds(x); b = absl::ToDoubleSeconds(d1) == x; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: d1 == absl::Seconds(x); + // CHECK-FIXES: b = d1 == absl::Seconds(x); b = absl::ToDoubleSeconds(d1) >= x; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: d1 >= absl::Seconds(x); + // CHECK-FIXES: b = d1 >= absl::Seconds(x); b = absl::ToDoubleSeconds(d1) > x; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: d1 > absl::Seconds(x); + // CHECK-FIXES: b = d1 > absl::Seconds(x); // Comparison against zero b = absl::ToDoubleSeconds(d1) < 0.0; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: d1 < absl::ZeroDuration(); + // CHECK-FIXES: b = d1 < absl::ZeroDuration(); b = absl::ToDoubleSeconds(d1) < 0; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: d1 < absl::ZeroDuration(); + // CHECK-FIXES: b = d1 < absl::ZeroDuration(); // Scales other than Seconds b = x > absl::ToDoubleMicroseconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Microseconds(x) > d1; + // CHECK-FIXES: b = absl::Microseconds(x) > d1; b = x >= absl::ToDoubleMilliseconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Milliseconds(x) >= d1; + // CHECK-FIXES: b = absl::Milliseconds(x) >= d1; b = x == absl::ToDoubleNanoseconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Nanoseconds(x) == d1; + // CHECK-FIXES: b = absl::Nanoseconds(x) == d1; b = x <= absl::ToDoubleMinutes(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Minutes(x) <= d1; + // CHECK-FIXES: b = absl::Minutes(x) <= d1; b = x < absl::ToDoubleHours(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Hours(x) < d1; + // CHECK-FIXES: b = absl::Hours(x) < d1; // Integer comparisons b = x > absl::ToInt64Microseconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Microseconds(x) > d1; + // CHECK-FIXES: b = absl::Microseconds(x) > d1; b = x >= absl::ToInt64Milliseconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Milliseconds(x) >= d1; + // CHECK-FIXES: b = absl::Milliseconds(x) >= d1; b = x == absl::ToInt64Nanoseconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Nanoseconds(x) == d1; + // CHECK-FIXES: b = absl::Nanoseconds(x) == d1; b = x == absl::ToInt64Seconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Seconds(x) == d1; + // CHECK-FIXES: b = absl::Seconds(x) == d1; b = x <= absl::ToInt64Minutes(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Minutes(x) <= d1; + // CHECK-FIXES: b = absl::Minutes(x) <= d1; b = x < absl::ToInt64Hours(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Hours(x) < d1; + // CHECK-FIXES: b = absl::Hours(x) < d1; // Other abseil-duration checks folded into this one b = static_cast<double>(5) > absl::ToDoubleSeconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Seconds(5) > d1; + // CHECK-FIXES: b = absl::Seconds(5) > d1; b = double(5) > absl::ToDoubleSeconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Seconds(5) > d1; + // CHECK-FIXES: b = absl::Seconds(5) > d1; b = float(5) > absl::ToDoubleSeconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Seconds(5) > d1; + // CHECK-FIXES: b = absl::Seconds(5) > d1; b = ((double)5) > absl::ToDoubleSeconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Seconds(5) > d1; + // CHECK-FIXES: b = absl::Seconds(5) > d1; b = 5.0 > absl::ToDoubleSeconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Seconds(5) > d1; + // CHECK-FIXES: b = absl::Seconds(5) > d1; // A long expression bool some_condition; @@ -125,20 +125,20 @@ void f() { int y; b = (y + 5) * 10 > absl::ToDoubleMilliseconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: absl::Milliseconds((y + 5) * 10) > d1; + // CHECK-FIXES: b = absl::Milliseconds((y + 5) * 10) > d1; // We should still transform the expression inside this macro invocation #define VALUE_IF(v, e) v ? (e) : 0 int a = VALUE_IF(1, 5 > absl::ToDoubleSeconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:23: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: VALUE_IF(1, absl::Seconds(5) > d1); + // CHECK-FIXES: int a = VALUE_IF(1, absl::Seconds(5) > d1); #undef VALUE_IF #define VALUE_IF_2(e) (e) #define VALUE_IF(v, e) v ? VALUE_IF_2(e) : VALUE_IF_2(0) int a2 = VALUE_IF(1, 5 > absl::ToDoubleSeconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:24: warning: perform comparison in the duration domain [abseil-duration-comparison] - // CHECK-FIXES: VALUE_IF(1, absl::Seconds(5) > d1); + // CHECK-FIXES: int a2 = VALUE_IF(1, absl::Seconds(5) > d1); #undef VALUE_IF #undef VALUE_IF_2 diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-conversion-cast.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-conversion-cast.cpp index 368b9d6..b5183a9 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-conversion-cast.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-conversion-cast.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s abseil-duration-conversion-cast %t -- -- -I%S/Inputs +// RUN: %check_clang_tidy %s abseil-duration-conversion-cast %t -- -- -I%S/Inputs #include "absl/time/time.h" @@ -9,56 +9,56 @@ void f() { i = static_cast<int>(absl::ToDoubleHours(d1)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToInt64Hours(d1); + // CHECK-FIXES: i = absl::ToInt64Hours(d1); x = static_cast<float>(absl::ToInt64Hours(d1)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToDoubleHours(d1); + // CHECK-FIXES: x = absl::ToDoubleHours(d1); i = static_cast<int>(absl::ToDoubleMinutes(d1)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToInt64Minutes(d1); + // CHECK-FIXES: i = absl::ToInt64Minutes(d1); x = static_cast<float>(absl::ToInt64Minutes(d1)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToDoubleMinutes(d1); + // CHECK-FIXES: x = absl::ToDoubleMinutes(d1); i = static_cast<int>(absl::ToDoubleSeconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToInt64Seconds(d1); + // CHECK-FIXES: i = absl::ToInt64Seconds(d1); x = static_cast<float>(absl::ToInt64Seconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToDoubleSeconds(d1); + // CHECK-FIXES: x = absl::ToDoubleSeconds(d1); i = static_cast<int>(absl::ToDoubleMilliseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToInt64Milliseconds(d1); + // CHECK-FIXES: i = absl::ToInt64Milliseconds(d1); x = static_cast<float>(absl::ToInt64Milliseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToDoubleMilliseconds(d1); + // CHECK-FIXES: x = absl::ToDoubleMilliseconds(d1); i = static_cast<int>(absl::ToDoubleMicroseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToInt64Microseconds(d1); + // CHECK-FIXES: i = absl::ToInt64Microseconds(d1); x = static_cast<float>(absl::ToInt64Microseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToDoubleMicroseconds(d1); + // CHECK-FIXES: x = absl::ToDoubleMicroseconds(d1); i = static_cast<int>(absl::ToDoubleNanoseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToInt64Nanoseconds(d1); + // CHECK-FIXES: i = absl::ToInt64Nanoseconds(d1); x = static_cast<float>(absl::ToInt64Nanoseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToDoubleNanoseconds(d1); + // CHECK-FIXES: x = absl::ToDoubleNanoseconds(d1); // Functional-style casts i = int(absl::ToDoubleHours(d1)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToInt64Hours(d1); + // CHECK-FIXES: i = absl::ToInt64Hours(d1); x = float(absl::ToInt64Microseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToDoubleMicroseconds(d1); + // CHECK-FIXES: x = absl::ToDoubleMicroseconds(d1); // C-style casts i = (int) absl::ToDoubleHours(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToInt64Hours(d1); + // CHECK-FIXES: i = absl::ToInt64Hours(d1); x = (float) absl::ToInt64Microseconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToDoubleMicroseconds(d1); + // CHECK-FIXES: x = absl::ToDoubleMicroseconds(d1); // Type aliasing typedef int FancyInt; @@ -66,17 +66,17 @@ void f() { FancyInt j = static_cast<FancyInt>(absl::ToDoubleHours(d1)); // CHECK-MESSAGES: [[@LINE-1]]:16: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToInt64Hours(d1); + // CHECK-FIXES: FancyInt j = absl::ToInt64Hours(d1); FancyFloat k = static_cast<FancyFloat>(absl::ToInt64Microseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:18: warning: duration should be converted directly to a floating-point number rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: absl::ToDoubleMicroseconds(d1); + // CHECK-FIXES: FancyFloat k = absl::ToDoubleMicroseconds(d1); // Macro handling // We want to transform things in macro arguments #define EXTERNAL(x) (x) + 5 i = EXTERNAL(static_cast<int>(absl::ToDoubleSeconds(d1))); // CHECK-MESSAGES: [[@LINE-1]]:16: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] - // CHECK-FIXES: EXTERNAL(absl::ToInt64Seconds(d1)); + // CHECK-FIXES: i = EXTERNAL(absl::ToInt64Seconds(d1)); #undef EXTERNAL // We don't want to transform this which get split across macro boundaries diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-float.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-float.cpp index 2f38dbf..9daaa72 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-float.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-float.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s abseil-duration-factory-float %t -- -- -I%S/Inputs +// RUN: %check_clang_tidy %s abseil-duration-factory-float %t -- -- -I%S/Inputs #include "absl/time/time.h" @@ -7,26 +7,26 @@ void ConvertFloatTest() { d = absl::Seconds(60.0); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float] - // CHECK-FIXES: absl::Seconds(60); + // CHECK-FIXES: d = absl::Seconds(60); d = absl::Minutes(300.0); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Minutes [abseil-duration-factory-float] - // CHECK-FIXES: absl::Minutes(300); + // CHECK-FIXES: d = absl::Minutes(300); d = absl::Milliseconds(1e2); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Milliseconds [abseil-duration-factory-float] - // CHECK-FIXES: absl::Milliseconds(100); + // CHECK-FIXES: d = absl::Milliseconds(100); d = absl::Seconds(3.0f); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float] - // CHECK-FIXES: absl::Seconds(3); + // CHECK-FIXES: d = absl::Seconds(3); d = absl::Seconds(3.); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float] - // CHECK-FIXES: absl::Seconds(3); + // CHECK-FIXES: d = absl::Seconds(3); d = absl::Seconds(0x3.p0); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float] - // CHECK-FIXES: absl::Seconds(3); + // CHECK-FIXES: d = absl::Seconds(3); d = absl::Seconds(0x3.p1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float] - // CHECK-FIXES: absl::Seconds(6); + // CHECK-FIXES: d = absl::Seconds(6); // Ignored expressions @@ -65,7 +65,7 @@ void InTemplate() { d = absl::Minutes(1.0); // 2 // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Minutes [abseil-duration-factory-float] - // CHECK-FIXES: absl::Minutes(1); // 2 + // CHECK-FIXES: d = absl::Minutes(1); // 2 } void Instantiate() { @@ -78,27 +78,27 @@ void ConvertCastTest() { d = absl::Seconds(static_cast<double>(5)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float] - // CHECK-FIXES: absl::Seconds(5); + // CHECK-FIXES: d = absl::Seconds(5); d = absl::Minutes(static_cast<float>(5)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Minutes [abseil-duration-factory-float] - // CHECK-FIXES: absl::Minutes(5); + // CHECK-FIXES: d = absl::Minutes(5); d = absl::Seconds((double) 5); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float] - // CHECK-FIXES: absl::Seconds(5); + // CHECK-FIXES: d = absl::Seconds(5); d = absl::Minutes((float) 5); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Minutes [abseil-duration-factory-float] - // CHECK-FIXES: absl::Minutes(5); + // CHECK-FIXES: d = absl::Minutes(5); d = absl::Seconds(double(5)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Seconds [abseil-duration-factory-float] - // CHECK-FIXES: absl::Seconds(5); + // CHECK-FIXES: d = absl::Seconds(5); d = absl::Minutes(float(5)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: use the integer version of absl::Minutes [abseil-duration-factory-float] - // CHECK-FIXES: absl::Minutes(5); + // CHECK-FIXES: d = absl::Minutes(5); // This should not be flagged d = absl::Seconds(static_cast<int>(5.0)); diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-scale.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-scale.cpp index dd5f808..7213f5c 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-scale.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-factory-scale.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s abseil-duration-factory-scale %t -- -- -I%S/Inputs +// RUN: %check_clang_tidy %s abseil-duration-factory-scale %t -- -- -I%S/Inputs #include "absl/time/time.h" @@ -11,87 +11,87 @@ void ScaleTest() { // Zeroes d = absl::Hours(0); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale] - // CHECK-FIXES: absl::ZeroDuration(); + // CHECK-FIXES: d = absl::ZeroDuration(); d = absl::Minutes(0); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale] - // CHECK-FIXES: absl::ZeroDuration(); + // CHECK-FIXES: d = absl::ZeroDuration(); d = absl::Seconds(0); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale] - // CHECK-FIXES: absl::ZeroDuration(); + // CHECK-FIXES: d = absl::ZeroDuration(); d = absl::Milliseconds(0); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale] - // CHECK-FIXES: absl::ZeroDuration(); + // CHECK-FIXES: d = absl::ZeroDuration(); d = absl::Microseconds(0); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale] - // CHECK-FIXES: absl::ZeroDuration(); + // CHECK-FIXES: d = absl::ZeroDuration(); d = absl::Nanoseconds(0); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale] - // CHECK-FIXES: absl::ZeroDuration(); + // CHECK-FIXES: d = absl::ZeroDuration(); d = absl::Seconds(0.0); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale] - // CHECK-FIXES: absl::ZeroDuration(); + // CHECK-FIXES: d = absl::ZeroDuration(); d = absl::Seconds(0x0.000001p-126f); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale] - // CHECK-FIXES: absl::ZeroDuration(); + // CHECK-FIXES: d = absl::ZeroDuration(); d = absl::Seconds(int{0}); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale] - // CHECK-FIXES: absl::ZeroDuration(); + // CHECK-FIXES: d = absl::ZeroDuration(); d = absl::Seconds(int64_t{0}); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale] - // CHECK-FIXES: absl::ZeroDuration(); + // CHECK-FIXES: d = absl::ZeroDuration(); d = absl::Seconds(float{0}); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use ZeroDuration() for zero-length time intervals [abseil-duration-factory-scale] - // CHECK-FIXES: absl::ZeroDuration(); + // CHECK-FIXES: d = absl::ZeroDuration(); // Fold seconds into minutes d = absl::Seconds(30 * 60); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale] - // CHECK-FIXES: absl::Minutes(30); + // CHECK-FIXES: d = absl::Minutes(30); d = absl::Seconds(60 * 30); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale] - // CHECK-FIXES: absl::Minutes(30); + // CHECK-FIXES: d = absl::Minutes(30); // Try a few more exotic multiplications d = absl::Seconds(60 * 30 * 60); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale] - // CHECK-FIXES: absl::Minutes(60 * 30); + // CHECK-FIXES: d = absl::Minutes(60 * 30); d = absl::Seconds(1e-3 * 30); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale] - // CHECK-FIXES: absl::Milliseconds(30); + // CHECK-FIXES: d = absl::Milliseconds(30); d = absl::Milliseconds(30 * 1000); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale] - // CHECK-FIXES: absl::Seconds(30); + // CHECK-FIXES: d = absl::Seconds(30); d = absl::Milliseconds(30 * 0.001); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale] - // CHECK-FIXES: absl::Microseconds(30); + // CHECK-FIXES: d = absl::Microseconds(30); // Multiple steps d = absl::Seconds(5 * 3600); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale] - // CHECK-FIXES: absl::Hours(5); + // CHECK-FIXES: d = absl::Hours(5); d = absl::Microseconds(5 * 1e6); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale] - // CHECK-FIXES: absl::Seconds(5); + // CHECK-FIXES: d = absl::Seconds(5); d = absl::Seconds(5 * 1e-6); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale] - // CHECK-FIXES: absl::Microseconds(5); + // CHECK-FIXES: d = absl::Microseconds(5); d = absl::Microseconds(5 * 1000000); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale] - // CHECK-FIXES: absl::Seconds(5); + // CHECK-FIXES: d = absl::Seconds(5); // Division d = absl::Hours(30 / 60.); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale] - // CHECK-FIXES: absl::Minutes(30); + // CHECK-FIXES: d = absl::Minutes(30); d = absl::Seconds(30 / 1000.); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale] - // CHECK-FIXES: absl::Milliseconds(30); + // CHECK-FIXES: d = absl::Milliseconds(30); d = absl::Milliseconds(30 / 1e3); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale] - // CHECK-FIXES: absl::Microseconds(30); + // CHECK-FIXES: d = absl::Microseconds(30); d = absl::Seconds(30 / 1e6); // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: internal duration scaling can be removed [abseil-duration-factory-scale] - // CHECK-FIXES: absl::Microseconds(30); + // CHECK-FIXES: d = absl::Microseconds(30); // None of these should trigger the check d = absl::Seconds(60); diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-subtraction.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-subtraction.cpp index 167258e3..53b558b 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-subtraction.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-subtraction.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s abseil-duration-subtraction %t -- -- -I %S/Inputs +// RUN: %check_clang_tidy %s abseil-duration-subtraction %t -- -- -I %S/Inputs #include "absl/time/time.h" @@ -8,34 +8,34 @@ void f() { x = absl::ToDoubleSeconds(d) - 1.0; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction] - // CHECK-FIXES: absl::ToDoubleSeconds(d - absl::Seconds(1)) + // CHECK-FIXES: x = absl::ToDoubleSeconds(d - absl::Seconds(1)); x = absl::ToDoubleSeconds(d) - absl::ToDoubleSeconds(d1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction] - // CHECK-FIXES: absl::ToDoubleSeconds(d - d1); + // CHECK-FIXES: x = absl::ToDoubleSeconds(d - d1); x = absl::ToDoubleSeconds(d) - 6.5 - 8.0; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction] - // CHECK-FIXES: absl::ToDoubleSeconds(d - absl::Seconds(6.5)) - 8.0; + // CHECK-FIXES: x = absl::ToDoubleSeconds(d - absl::Seconds(6.5)) - 8.0; x = absl::ToDoubleHours(d) - 1.0; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction] - // CHECK-FIXES: absl::ToDoubleHours(d - absl::Hours(1)) + // CHECK-FIXES: x = absl::ToDoubleHours(d - absl::Hours(1)); x = absl::ToDoubleMinutes(d) - 1; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction] - // CHECK-FIXES: absl::ToDoubleMinutes(d - absl::Minutes(1)) + // CHECK-FIXES: x = absl::ToDoubleMinutes(d - absl::Minutes(1)); x = absl::ToDoubleMilliseconds(d) - 9; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction] - // CHECK-FIXES: absl::ToDoubleMilliseconds(d - absl::Milliseconds(9)) + // CHECK-FIXES: x = absl::ToDoubleMilliseconds(d - absl::Milliseconds(9)); x = absl::ToDoubleMicroseconds(d) - 9; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction] - // CHECK-FIXES: absl::ToDoubleMicroseconds(d - absl::Microseconds(9)) + // CHECK-FIXES: x = absl::ToDoubleMicroseconds(d - absl::Microseconds(9)); x = absl::ToDoubleNanoseconds(d) - 42; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction] - // CHECK-FIXES: absl::ToDoubleNanoseconds(d - absl::Nanoseconds(42)) + // CHECK-FIXES: x = absl::ToDoubleNanoseconds(d - absl::Nanoseconds(42)); // We can rewrite the argument of the duration conversion #define THIRTY absl::Seconds(30) x = absl::ToDoubleSeconds(THIRTY) - 1.0; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction] - // CHECK-FIXES: absl::ToDoubleSeconds(THIRTY - absl::Seconds(1)) + // CHECK-FIXES: x = absl::ToDoubleSeconds(THIRTY - absl::Seconds(1)); #undef THIRTY // Some other contexts @@ -46,10 +46,10 @@ void f() { // A nested occurrence x = absl::ToDoubleSeconds(d) - absl::ToDoubleSeconds(absl::Seconds(5)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction] - // CHECK-FIXES: absl::ToDoubleSeconds(d - absl::Seconds(5)) + // CHECK-FIXES: x = absl::ToDoubleSeconds(d - absl::Seconds(5)); x = absl::ToDoubleSeconds(d) - absl::ToDoubleSeconds(absl::Seconds(absl::ToDoubleSeconds(d1))); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction] - // CHECK-FIXES: absl::ToDoubleSeconds(d - absl::Seconds(absl::ToDoubleSeconds(d1))) + // CHECK-FIXES: x = absl::ToDoubleSeconds(d - absl::Seconds(absl::ToDoubleSeconds(d1))); // These should not match x = 5 - 6; diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-unnecessary-conversion.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-unnecessary-conversion.cpp index f4c69c5..92891b6 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-unnecessary-conversion.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/duration-unnecessary-conversion.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes -std=c++11-or-later %s abseil-duration-unnecessary-conversion %t -- -- -I %S/Inputs +// RUN: %check_clang_tidy -std=c++11-or-later %s abseil-duration-unnecessary-conversion %t -- -- -I %S/Inputs #include "absl/time/time.h" @@ -8,86 +8,86 @@ void f() { // Floating point d2 = absl::Hours(absl::ToDoubleHours(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Minutes(absl::ToDoubleMinutes(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Seconds(absl::ToDoubleSeconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Milliseconds(absl::ToDoubleMilliseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Microseconds(absl::ToDoubleMicroseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Nanoseconds(absl::ToDoubleNanoseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; // Integer point d2 = absl::Hours(absl::ToInt64Hours(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Minutes(absl::ToInt64Minutes(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Seconds(absl::ToInt64Seconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Milliseconds(absl::ToInt64Milliseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Microseconds(absl::ToInt64Microseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Nanoseconds(absl::ToInt64Nanoseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Hours(d1 / absl::Hours(1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Minutes(d1 / absl::Minutes(1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Seconds(d1 / absl::Seconds(1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Milliseconds(d1 / absl::Milliseconds(1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Microseconds(d1 / absl::Microseconds(1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Nanoseconds(d1 / absl::Nanoseconds(1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Hours(absl::FDivDuration(d1, absl::Hours(1))); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Minutes(absl::FDivDuration(d1, absl::Minutes(1))); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Seconds(absl::FDivDuration(d1, absl::Seconds(1))); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Milliseconds(absl::FDivDuration(d1, absl::Milliseconds(1))); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Microseconds(absl::FDivDuration(d1, absl::Microseconds(1))); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; d2 = absl::Nanoseconds(absl::FDivDuration(d1, absl::Nanoseconds(1))); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 + // CHECK-FIXES: d2 = d1; // As macro argument #define PLUS_FIVE_S(x) x + absl::Seconds(5) d2 = PLUS_FIVE_S(absl::Seconds(absl::ToInt64Seconds(d1))); // CHECK-MESSAGES: [[@LINE-1]]:20: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: PLUS_FIVE_S(d1) + // CHECK-FIXES: d2 = PLUS_FIVE_S(d1); #undef PLUS_FIVE_S // Split by macro: should not change @@ -103,40 +103,40 @@ void f() { // Multiplication d2 = absl::Nanoseconds(absl::ToDoubleNanoseconds(d1) * 2); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 * 2 + // CHECK-FIXES: d2 = d1 * 2; d2 = absl::Microseconds(absl::ToInt64Microseconds(d1) * 2); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 * 2 + // CHECK-FIXES: d2 = d1 * 2; d2 = absl::Milliseconds(absl::ToDoubleMilliseconds(d1) * 2); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 * 2 + // CHECK-FIXES: d2 = d1 * 2; d2 = absl::Seconds(absl::ToInt64Seconds(d1) * 2); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 * 2 + // CHECK-FIXES: d2 = d1 * 2; d2 = absl::Minutes(absl::ToDoubleMinutes(d1) * 2); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 * 2 + // CHECK-FIXES: d2 = d1 * 2; d2 = absl::Hours(absl::ToInt64Hours(d1) * 2); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = d1 * 2 + // CHECK-FIXES: d2 = d1 * 2; d2 = absl::Nanoseconds(2 * absl::ToDoubleNanoseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = 2 * d1 + // CHECK-FIXES: d2 = 2 * d1; d2 = absl::Microseconds(2 * absl::ToInt64Microseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = 2 * d1 + // CHECK-FIXES: d2 = 2 * d1; d2 = absl::Milliseconds(2 * absl::ToDoubleMilliseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = 2 * d1 + // CHECK-FIXES: d2 = 2 * d1; d2 = absl::Seconds(2 * absl::ToInt64Seconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = 2 * d1 + // CHECK-FIXES: d2 = 2 * d1; d2 = absl::Minutes(2 * absl::ToDoubleMinutes(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = 2 * d1 + // CHECK-FIXES: d2 = 2 * d1; d2 = absl::Hours(2 * absl::ToInt64Hours(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d2 = 2 * d1 + // CHECK-FIXES: d2 = 2 * d1; // These should not match d2 = absl::Seconds(absl::ToDoubleMilliseconds(d1)); diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/redundant-strcat-calls.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/redundant-strcat-calls.cpp index b5e866c..8fa1b1e 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/abseil/redundant-strcat-calls.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/redundant-strcat-calls.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s abseil-redundant-strcat-calls %t -- -- -isystem %clang_tidy_headers +// RUN: %check_clang_tidy %s abseil-redundant-strcat-calls %t -- -- -isystem %clang_tidy_headers #include <string> namespace absl { @@ -69,7 +69,7 @@ using absl::StrCat; void Positives() { std::string S = StrCat(1, StrCat("A", StrCat(1.1))); // CHECK-MESSAGES: [[@LINE-1]]:19: warning: multiple calls to 'absl::StrCat' can be flattened into a single call - // CHECK-FIXES: string S = StrCat(1, "A", 1.1); + // CHECK-FIXES: std::string S = StrCat(1, "A", 1.1); S = StrCat(StrCat(StrCat(StrCat(StrCat(1))))); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: multiple calls to 'absl::StrCat' can be flattened into a single call diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/time-comparison.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/time-comparison.cpp index 4de43ec..ad3ce4c 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/abseil/time-comparison.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/time-comparison.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s abseil-time-comparison %t -- -- -I%S/Inputs +// RUN: %check_clang_tidy %s abseil-time-comparison %t -- -- -I%S/Inputs #include "absl/time/time.h" @@ -11,67 +11,67 @@ void f() { // Check against the RHS b = x > absl::ToUnixSeconds(t1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: absl::FromUnixSeconds(x) > t1; + // CHECK-FIXES: b = absl::FromUnixSeconds(x) > t1; b = x >= absl::ToUnixSeconds(t1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: absl::FromUnixSeconds(x) >= t1; + // CHECK-FIXES: b = absl::FromUnixSeconds(x) >= t1; b = x == absl::ToUnixSeconds(t1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: absl::FromUnixSeconds(x) == t1; + // CHECK-FIXES: b = absl::FromUnixSeconds(x) == t1; b = x <= absl::ToUnixSeconds(t1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: absl::FromUnixSeconds(x) <= t1; + // CHECK-FIXES: b = absl::FromUnixSeconds(x) <= t1; b = x < absl::ToUnixSeconds(t1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: absl::FromUnixSeconds(x) < t1; + // CHECK-FIXES: b = absl::FromUnixSeconds(x) < t1; b = x == absl::ToUnixSeconds(t1 - d2); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: absl::FromUnixSeconds(x) == t1 - d2; + // CHECK-FIXES: b = absl::FromUnixSeconds(x) == t1 - d2; b = absl::ToUnixSeconds(t1) > absl::ToUnixSeconds(t2); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: t1 > t2; + // CHECK-FIXES: b = t1 > t2; // Check against the LHS b = absl::ToUnixSeconds(t1) < x; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: t1 < absl::FromUnixSeconds(x); + // CHECK-FIXES: b = t1 < absl::FromUnixSeconds(x); b = absl::ToUnixSeconds(t1) <= x; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: t1 <= absl::FromUnixSeconds(x); + // CHECK-FIXES: b = t1 <= absl::FromUnixSeconds(x); b = absl::ToUnixSeconds(t1) == x; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: t1 == absl::FromUnixSeconds(x); + // CHECK-FIXES: b = t1 == absl::FromUnixSeconds(x); b = absl::ToUnixSeconds(t1) >= x; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: t1 >= absl::FromUnixSeconds(x); + // CHECK-FIXES: b = t1 >= absl::FromUnixSeconds(x); b = absl::ToUnixSeconds(t1) > x; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: t1 > absl::FromUnixSeconds(x); + // CHECK-FIXES: b = t1 > absl::FromUnixSeconds(x); // Comparison against zero b = absl::ToUnixSeconds(t1) < 0.0; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: t1 < absl::UnixEpoch(); + // CHECK-FIXES: b = t1 < absl::UnixEpoch(); b = absl::ToUnixSeconds(t1) < 0; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: t1 < absl::UnixEpoch(); + // CHECK-FIXES: b = t1 < absl::UnixEpoch(); // Scales other than Seconds b = x > absl::ToUnixMicros(t1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: absl::FromUnixMicros(x) > t1; + // CHECK-FIXES: b = absl::FromUnixMicros(x) > t1; b = x >= absl::ToUnixMillis(t1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: absl::FromUnixMillis(x) >= t1; + // CHECK-FIXES: b = absl::FromUnixMillis(x) >= t1; b = x == absl::ToUnixNanos(t1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: absl::FromUnixNanos(x) == t1; + // CHECK-FIXES: b = absl::FromUnixNanos(x) == t1; b = x <= absl::ToUnixMinutes(t1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: absl::FromUnixMinutes(x) <= t1; + // CHECK-FIXES: b = absl::FromUnixMinutes(x) <= t1; b = x < absl::ToUnixHours(t1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: absl::FromUnixHours(x) < t1; + // CHECK-FIXES: b = absl::FromUnixHours(x) < t1; // A long expression bool some_condition; @@ -88,20 +88,20 @@ void f() { int y; b = (y + 5) * 10 > absl::ToUnixMillis(t1); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: absl::FromUnixMillis((y + 5) * 10) > t1; + // CHECK-FIXES: b = absl::FromUnixMillis((y + 5) * 10) > t1; // We should still transform the expression inside this macro invocation #define VALUE_IF(v, e) v ? (e) : 0 int a = VALUE_IF(1, 5 > absl::ToUnixSeconds(t1)); // CHECK-MESSAGES: [[@LINE-1]]:23: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: VALUE_IF(1, absl::FromUnixSeconds(5) > t1); + // CHECK-FIXES: int a = VALUE_IF(1, absl::FromUnixSeconds(5) > t1); #undef VALUE_IF #define VALUE_IF_2(e) (e) #define VALUE_IF(v, e) v ? VALUE_IF_2(e) : VALUE_IF_2(0) int a2 = VALUE_IF(1, 5 > absl::ToUnixSeconds(t1)); // CHECK-MESSAGES: [[@LINE-1]]:24: warning: perform comparison in the time domain [abseil-time-comparison] - // CHECK-FIXES: VALUE_IF(1, absl::FromUnixSeconds(5) > t1); + // CHECK-FIXES: int a2 = VALUE_IF(1, absl::FromUnixSeconds(5) > t1); #undef VALUE_IF #undef VALUE_IF_2 diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/time-subtraction.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/time-subtraction.cpp index 82014e8f4..dde0681 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/abseil/time-subtraction.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/time-subtraction.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes -std=c++11-or-later %s abseil-time-subtraction %t -- -- -I %S/Inputs +// RUN: %check_clang_tidy -std=c++11-or-later %s abseil-time-subtraction %t -- -- -I %S/Inputs #include "absl/time/time.h" @@ -89,7 +89,7 @@ void f() { #define SECONDS(z) absl::Seconds(z) d = SECONDS(x - absl::ToUnixSeconds(t)); // CHECK-MESSAGES: [[@LINE-1]]:15: warning: perform subtraction in the time domain [abseil-time-subtraction] - // CHECK-FIXES: SECONDS(absl::ToInt64Seconds(absl::FromUnixSeconds(x) - t)) + // CHECK-FIXES: d = SECONDS(absl::ToInt64Seconds(absl::FromUnixSeconds(x) - t)); #undef SECONDS } diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/upgrade-duration-conversions.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/upgrade-duration-conversions.cpp index b5dfb4f..67fbe3f 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/abseil/upgrade-duration-conversions.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/upgrade-duration-conversions.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes -std=c++11-or-later %s abseil-upgrade-duration-conversions %t -- -- -I%S/Inputs +// RUN: %check_clang_tidy -std=c++11-or-later %s abseil-upgrade-duration-conversions %t -- -- -I%S/Inputs using int64_t = long long; @@ -49,22 +49,22 @@ void arithmeticOperatorBasicPositive() { ConvertibleTo<int64_t> c; d *= (c + c) * c + c; // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead - // CHECK-FIXES: d *= static_cast<int64_t>((c + c) * c + c) + // CHECK-FIXES: d *= static_cast<int64_t>((c + c) * c + c); d /= (c + c) * c + c; // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead - // CHECK-FIXES: d /= static_cast<int64_t>((c + c) * c + c) + // CHECK-FIXES: d /= static_cast<int64_t>((c + c) * c + c); d = d * c * c; // CHECK-MESSAGES: [[@LINE-1]]:11: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-MESSAGES: [[@LINE-2]]:15: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead - // CHECK-FIXES: d = d * static_cast<int64_t>(c) * static_cast<int64_t>(c) + // CHECK-FIXES: d = d * static_cast<int64_t>(c) * static_cast<int64_t>(c); d = c * d * c; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-MESSAGES: [[@LINE-2]]:15: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead - // CHECK-FIXES: d = static_cast<int64_t>(c) * d * static_cast<int64_t>(c) + // CHECK-FIXES: d = static_cast<int64_t>(c) * d * static_cast<int64_t>(c); d = d / c * c; // CHECK-MESSAGES: [[@LINE-1]]:11: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-MESSAGES: [[@LINE-2]]:15: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead - // CHECK-FIXES: d = d / static_cast<int64_t>(c) * static_cast<int64_t>(c) + // CHECK-FIXES: d = d / static_cast<int64_t>(c) * static_cast<int64_t>(c); } void arithmeticOperatorBasicNegative() { @@ -407,7 +407,7 @@ template <typename T> void factoryTemplateAndMacro() { // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead (void)absl::Nanoseconds(CONVERTIBLE_TMP); // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead - // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(CONVERTIBLE_TMP)) + // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(CONVERTIBLE_TMP)); T_CALL_FACTORTY_INSIDE_MACRO; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead } @@ -424,7 +424,7 @@ void factoryInMacros() { // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(FUNCTION_MACRO(ConvertibleTo<int>()))); (void)absl::Nanoseconds(CONVERTIBLE_TMP); // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead - // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(CONVERTIBLE_TMP)) + // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(CONVERTIBLE_TMP)); ONLY_WARN_INSIDE_MACRO_FACTORY; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead factoryTemplateAndMacro<ConvertibleTo<int>>(); diff --git a/clang-tools-extra/test/clang-tidy/checkers/altera/struct-pack-align.cpp b/clang-tools-extra/test/clang-tidy/checkers/altera/struct-pack-align.cpp index 9aaca68..6b5b946 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/altera/struct-pack-align.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/altera/struct-pack-align.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s altera-struct-pack-align %t -- -header-filter=.* +// RUN: %check_clang_tidy %s altera-struct-pack-align %t -- -header-filter=.* // Struct needs both alignment and packing struct error { @@ -10,8 +10,7 @@ struct error { // CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((packed))" to reduce the amount of padding applied to struct 'error' // CHECK-MESSAGES: :[[@LINE-7]]:8: warning: accessing fields in struct 'error' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align] // CHECK-MESSAGES: :[[@LINE-8]]:8: note: use "__attribute__((aligned(16)))" to align struct 'error' to 16 bytes -// CHECK-FIXES: __attribute__((packed)) -// CHECK-FIXES: __attribute__((aligned(16))); +// CHECK-FIXES: } __attribute__((packed)) __attribute__((aligned(16))); // Struct is explicitly packed, but needs alignment struct error_packed { @@ -21,7 +20,7 @@ struct error_packed { } __attribute__((packed)); // CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'error_packed' is inefficient due to poor alignment; currently aligned to 1 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align] // CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'error_packed' to 16 bytes -// CHECK-FIXES: __attribute__((aligned(16))) +// CHECK-FIXES: } __attribute__((aligned(16))) __attribute__((packed)); // Struct is properly packed, but needs alignment struct align_only { @@ -34,7 +33,7 @@ struct align_only { }; // CHECK-MESSAGES: :[[@LINE-8]]:8: warning: accessing fields in struct 'align_only' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align] // CHECK-MESSAGES: :[[@LINE-9]]:8: note: use "__attribute__((aligned(16)))" to align struct 'align_only' to 16 bytes -// CHECK-FIXES: __attribute__((aligned(16))); +// CHECK-FIXES: } __attribute__((aligned(16))); // Struct is perfectly packed but wrongly aligned struct bad_align { @@ -44,7 +43,7 @@ struct bad_align { } __attribute__((packed)) __attribute__((aligned(8))); // CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'bad_align' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align] // CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'bad_align' to 16 bytes -// CHECK-FIXES: __attribute__((aligned(16))); +// CHECK-FIXES: } __attribute__((packed)) __attribute__((aligned(16))); struct bad_align2 { char a; @@ -53,7 +52,7 @@ struct bad_align2 { } __attribute__((packed)) __attribute__((aligned(32))); // CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'bad_align2' is inefficient due to poor alignment; currently aligned to 32 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align] // CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'bad_align2' to 16 bytes -// CHECK-FIXES: __attribute__((aligned(16))); +// CHECK-FIXES: } __attribute__((packed)) __attribute__((aligned(16))); struct bad_align3 { char a; @@ -62,7 +61,7 @@ struct bad_align3 { } __attribute__((packed)) __attribute__((aligned(4))); // CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'bad_align3' is inefficient due to poor alignment; currently aligned to 4 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align] // CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'bad_align3' to 16 bytes -// CHECK-FIXES: __attribute__((aligned(16))); +// CHECK-FIXES: } __attribute__((packed)) __attribute__((aligned(16))); // Struct is both perfectly packed and aligned struct success { @@ -116,5 +115,4 @@ struct ContainsStructWithNoFields2 { // CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((packed))" to reduce the amount of padding applied to struct 'ContainsStructWithNoFields2' // CHECK-MESSAGES: :[[@LINE-7]]:8: warning: accessing fields in struct 'ContainsStructWithNoFields2' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align] // CHECK-MESSAGES: :[[@LINE-8]]:8: note: use "__attribute__((aligned(16)))" to align struct 'ContainsStructWithNoFields2' to 16 bytes -// CHECK-FIXES: __attribute__((packed)) -// CHECK-FIXES: __attribute__((aligned(16))); +// CHECK-FIXES: } __attribute__((packed)) __attribute__((aligned(16))); diff --git a/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-memfd-create.cpp b/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-memfd-create.cpp index b2c299b..d1d77d3 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-memfd-create.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-memfd-create.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s android-cloexec-memfd-create %t +// RUN: %check_clang_tidy %s android-cloexec-memfd-create %t #define MFD_ALLOW_SEALING 1 #define __O_CLOEXEC 3 @@ -17,19 +17,19 @@ extern "C" int memfd_create(const char *name, unsigned int flags); void a() { memfd_create(NULL, MFD_ALLOW_SEALING); // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'memfd_create' should use MFD_CLOEXEC where possible [android-cloexec-memfd-create] - // CHECK-FIXES: memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC) + // CHECK-FIXES: memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC); TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING)); // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: 'memfd_create' - // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC)) + // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC)); } void f() { memfd_create(NULL, 3); // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'memfd_create' - // CHECK-FIXES: memfd_create(NULL, 3 | MFD_CLOEXEC) + // CHECK-FIXES: memfd_create(NULL, 3 | MFD_CLOEXEC); TEMP_FAILURE_RETRY(memfd_create(NULL, 3)); // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'memfd_create' - // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, 3 | MFD_CLOEXEC)) + // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, 3 | MFD_CLOEXEC)); int flag = 3; memfd_create(NULL, flag); diff --git a/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-open.cpp b/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-open.cpp index 651e469..46e30ab 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-open.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-open.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s android-cloexec-open %t +// RUN: %check_clang_tidy %s android-cloexec-open %t #define O_RDWR 1 #define O_EXCL 2 @@ -19,67 +19,67 @@ extern "C" int openat(int dirfd, const char *pathname, int flags, ...); void a() { open("filename", O_RDWR); // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'open' should use O_CLOEXEC where possible [android-cloexec-open] - // CHECK-FIXES: O_RDWR | O_CLOEXEC + // CHECK-FIXES: open("filename", O_RDWR | O_CLOEXEC); TEMP_FAILURE_RETRY(open("filename", O_RDWR)); // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: 'open' should use O_CLOEXEC where - // CHECK-FIXES: O_RDWR | O_CLOEXEC + // CHECK-FIXES: TEMP_FAILURE_RETRY(open("filename", O_RDWR | O_CLOEXEC)); open("filename", O_RDWR | O_EXCL); // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: 'open' should use O_CLOEXEC where - // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC + // CHECK-FIXES: open("filename", O_RDWR | O_EXCL | O_CLOEXEC); TEMP_FAILURE_RETRY(open("filename", O_RDWR | O_EXCL)); // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: 'open' should use O_CLOEXEC where - // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC + // CHECK-FIXES: TEMP_FAILURE_RETRY(open("filename", O_RDWR | O_EXCL | O_CLOEXEC)); } void b() { open64("filename", O_RDWR); // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: 'open64' should use O_CLOEXEC where possible [android-cloexec-open] - // CHECK-FIXES: O_RDWR | O_CLOEXEC + // CHECK-FIXES: open64("filename", O_RDWR | O_CLOEXEC); TEMP_FAILURE_RETRY(open64("filename", O_RDWR)); // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: 'open64' should use O_CLOEXEC where - // CHECK-FIXES: O_RDWR | O_CLOEXEC + // CHECK-FIXES: TEMP_FAILURE_RETRY(open64("filename", O_RDWR | O_CLOEXEC)); open64("filename", O_RDWR | O_EXCL); // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'open64' should use O_CLOEXEC where - // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC + // CHECK-FIXES: open64("filename", O_RDWR | O_EXCL | O_CLOEXEC); TEMP_FAILURE_RETRY(open64("filename", O_RDWR | O_EXCL)); // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: 'open64' should use O_CLOEXEC where - // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC + // CHECK-FIXES: TEMP_FAILURE_RETRY(open64("filename", O_RDWR | O_EXCL | O_CLOEXEC)); } void c() { openat(0, "filename", O_RDWR); // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'openat' should use O_CLOEXEC where possible [android-cloexec-open] - // CHECK-FIXES: O_RDWR | O_CLOEXEC + // CHECK-FIXES: openat(0, "filename", O_RDWR | O_CLOEXEC); TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR)); // CHECK-MESSAGES: :[[@LINE-1]]:50: warning: 'openat' should use O_CLOEXEC where - // CHECK-FIXES: O_RDWR | O_CLOEXEC + // CHECK-FIXES: TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR | O_CLOEXEC)); openat(0, "filename", O_RDWR | O_EXCL); // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: 'openat' should use O_CLOEXEC where - // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC + // CHECK-FIXES: openat(0, "filename", O_RDWR | O_EXCL | O_CLOEXEC); TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR | O_EXCL)); // CHECK-MESSAGES: :[[@LINE-1]]:59: warning: 'openat' should use O_CLOEXEC where - // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC + // CHECK-FIXES: TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR | O_EXCL | O_CLOEXEC)); } void f() { open("filename", 3); // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'open' should use O_CLOEXEC where possible [android-cloexec-open] - // CHECK-FIXES: 3 | O_CLOEXEC + // CHECK-FIXES: open("filename", 3 | O_CLOEXEC); TEMP_FAILURE_RETRY(open("filename", 3)); // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: 'open' should use O_CLOEXEC where - // CHECK-FIXES: 3 | O_CLOEXEC + // CHECK-FIXES: TEMP_FAILURE_RETRY(open("filename", 3 | O_CLOEXEC)); open64("filename", 3); // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'open64' should use O_CLOEXEC where possible [android-cloexec-open] - // CHECK-FIXES: 3 | O_CLOEXEC + // CHECK-FIXES: open64("filename", 3 | O_CLOEXEC); TEMP_FAILURE_RETRY(open64("filename", 3)); // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'open64' should use O_CLOEXEC where - // CHECK-FIXES: 3 | O_CLOEXEC + // CHECK-FIXES: TEMP_FAILURE_RETRY(open64("filename", 3 | O_CLOEXEC)); openat(0, "filename", 3); // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'openat' should use O_CLOEXEC where possible [android-cloexec-open] - // CHECK-FIXES: 3 | O_CLOEXEC + // CHECK-FIXES: openat(0, "filename", 3 | O_CLOEXEC); TEMP_FAILURE_RETRY(openat(0, "filename", 3)); // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: 'openat' should use O_CLOEXEC where - // CHECK-FIXES: 3 | O_CLOEXEC + // CHECK-FIXES: TEMP_FAILURE_RETRY(openat(0, "filename", 3 | O_CLOEXEC)); int flag = 3; open("filename", flag); diff --git a/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-socket.cpp b/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-socket.cpp index d4d58640..3a25a93 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-socket.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/android/cloexec-socket.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s android-cloexec-socket %t +// RUN: %check_clang_tidy %s android-cloexec-socket %t #define SOCK_STREAM 1 #define SOCK_DGRAM 2 @@ -17,25 +17,25 @@ extern "C" int socket(int domain, int type, int protocol); void a() { socket(0, SOCK_STREAM, 0); // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'socket' should use SOCK_CLOEXEC where possible [android-cloexec-socket] - // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0) + // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0); TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM, 0)); // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: 'socket' - // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0)) + // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_CLOEXEC, 0)); socket(0, SOCK_STREAM | SOCK_DGRAM, 0); // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'socket' - // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC, 0) + // CHECK-FIXES: socket(0, SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC, 0); TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM, 0)); // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: 'socket' - // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC, 0)) + // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, SOCK_STREAM | SOCK_DGRAM | SOCK_CLOEXEC, 0)); } void f() { socket(0, 3, 0); // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'socket' - // CHECK-FIXES: socket(0, 3 | SOCK_CLOEXEC, 0) + // CHECK-FIXES: socket(0, 3 | SOCK_CLOEXEC, 0); TEMP_FAILURE_RETRY(socket(0, 3, 0)); // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: 'socket' - // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, 3 | SOCK_CLOEXEC, 0)) + // CHECK-FIXES: TEMP_FAILURE_RETRY(socket(0, 3 | SOCK_CLOEXEC, 0)); int flag = 3; socket(0, flag, 0); diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-shared-from-this.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-shared-from-this.cpp index 82b6ea8..81d5cc5 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-shared-from-this.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-enable-shared-from-this.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes -std=c++11-or-later %s bugprone-incorrect-enable-shared-from-this %t +// RUN: %check_clang_tidy -std=c++11-or-later %s bugprone-incorrect-enable-shared-from-this %t // NOLINTBEGIN namespace std { @@ -8,15 +8,15 @@ namespace std { class BadClassExample : std::enable_shared_from_this<BadClassExample> {}; // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'BadClassExample' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this] -// CHECK-FIXES: public std::enable_shared_from_this<BadClassExample> +// CHECK-FIXES: class BadClassExample : public std::enable_shared_from_this<BadClassExample> {}; class BadClass2Example : private std::enable_shared_from_this<BadClass2Example> {}; // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'BadClass2Example' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this] -// CHECK-FIXES: public std::enable_shared_from_this<BadClass2Example> +// CHECK-FIXES: class BadClass2Example : public std::enable_shared_from_this<BadClass2Example> {}; struct BadStructExample : private std::enable_shared_from_this<BadStructExample> {}; // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'BadStructExample' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this] -// CHECK-FIXES: public std::enable_shared_from_this<BadStructExample> +// CHECK-FIXES: struct BadStructExample : public std::enable_shared_from_this<BadStructExample> {}; class GoodClassExample : public std::enable_shared_from_this<GoodClassExample> {}; @@ -29,15 +29,15 @@ class dummy_class2 {}; class BadMultiClassExample : std::enable_shared_from_this<BadMultiClassExample>, dummy_class1 {}; // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'BadMultiClassExample' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this] -// CHECK-FIXES: public std::enable_shared_from_this<BadMultiClassExample>, dummy_class1 +// CHECK-FIXES: class BadMultiClassExample : public std::enable_shared_from_this<BadMultiClassExample>, dummy_class1 {}; class BadMultiClass2Example : dummy_class1, std::enable_shared_from_this<BadMultiClass2Example>, dummy_class2 {}; // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'BadMultiClass2Example' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this] -// CHECK-FIXES: dummy_class1, public std::enable_shared_from_this<BadMultiClass2Example>, dummy_class2 +// CHECK-FIXES: class BadMultiClass2Example : dummy_class1, public std::enable_shared_from_this<BadMultiClass2Example>, dummy_class2 {}; class BadMultiClass3Example : dummy_class1, dummy_class2, std::enable_shared_from_this<BadMultiClass3Example> {}; // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'BadMultiClass3Example' is not publicly inheriting from 'std::enable_shared_from_this', which will cause unintended behaviour when using 'shared_from_this'; make the inheritance public [bugprone-incorrect-enable-shared-from-this] -// CHECK-FIXES: dummy_class1, dummy_class2, public std::enable_shared_from_this<BadMultiClass3Example> +// CHECK-FIXES: class BadMultiClass3Example : dummy_class1, dummy_class2, public std::enable_shared_from_this<BadMultiClass3Example> {}; class ClassBase : public std::enable_shared_from_this<ClassBase> {}; class PrivateInheritClassBase : private ClassBase {}; diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/move-forwarding-reference.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/move-forwarding-reference.cpp index 66cd6ba..9f45367 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/move-forwarding-reference.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/move-forwarding-reference.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes -std=c++14-or-later %s bugprone-move-forwarding-reference %t -- -- -fno-delayed-template-parsing +// RUN: %check_clang_tidy -std=c++14-or-later %s bugprone-move-forwarding-reference %t -- -- -fno-delayed-template-parsing namespace std { template <typename> struct remove_reference; @@ -121,5 +121,5 @@ template <typename T, typename U> void f11(U &&SomeU) { template <typename T> void f12() { [] (auto&& x) { T SomeT(std::move(x)); }; // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: forwarding reference passed to - // CHECK-FIXES: [] (auto&& x) { T SomeT(std::forward<decltype(x)>(x)); } + // CHECK-FIXES: [] (auto&& x) { T SomeT(std::forward<decltype(x)>(x)); }; } diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-in-initialization-strlen.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-in-initialization-strlen.c index b241d68..99d19ec 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-in-initialization-strlen.c +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-in-initialization-strlen.c @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s bugprone-not-null-terminated-result %t -- \ +// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \ // RUN: -- -I %S/Inputs/not-null-terminated-result #include "not-null-terminated-result-c.h" @@ -40,7 +40,7 @@ int bad_strncmp_1(char *str1, const char *str2) { int length = strlen(str1) + 1; return strncmp(str1, str2, length); // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result] - // CHECK-FIXES: strncmp(str1, str2, length - 1); + // CHECK-FIXES: return strncmp(str1, str2, length - 1); } int good_strncmp_1(char *str1, const char *str2) { @@ -51,13 +51,13 @@ int good_strncmp_1(char *str1, const char *str2) { int bad_strncmp_2(char *str2) { return strncmp(str2, "foobar", (strlen("foobar") + 1)); // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result] - // CHECK-FIXES: strncmp(str2, "foobar", (strlen("foobar"))); + // CHECK-FIXES: return strncmp(str2, "foobar", (strlen("foobar"))); } int bad_strncmp_3(char *str3) { return strncmp(str3, "foobar", 1 + strlen("foobar")); // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result] - // CHECK-FIXES: strncmp(str3, "foobar", strlen("foobar")); + // CHECK-FIXES: return strncmp(str3, "foobar", strlen("foobar")); } int good_strncmp_2_3(char *str) { diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-memcpy-safe-cxx.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-memcpy-safe-cxx.cpp index 8124b3b..8465b2b 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-memcpy-safe-cxx.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-memcpy-safe-cxx.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s bugprone-not-null-terminated-result %t -- \ +// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \ // RUN: -- -std=c++11 -I %S/Inputs/not-null-terminated-result #include "not-null-terminated-result-cxx.h" @@ -27,7 +27,7 @@ void bad_memcpy_known_dest(const char *src) { char dest01[13]; memcpy(dest01, src, strlen(src)); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result] - // CHECK-FIXES: dest01[14]; + // CHECK-FIXES: char dest01[14]; // CHECK-FIXES-NEXT: strcpy_s(dest01, src); } @@ -44,7 +44,7 @@ void bad_memcpy_full_source_length(std::string src) { char *dest20 = reinterpret_cast<char *>(malloc(src.size())); memcpy(dest20, src.data(), src.size()); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'memcpy' is not null-terminated [bugprone-not-null-terminated-result] - // CHECK-FIXES: dest20 = reinterpret_cast<char *>(malloc(src.size() + 1)); + // CHECK-FIXES: char *dest20 = reinterpret_cast<char *>(malloc(src.size() + 1)); // CHECK-FIXES-NEXT: strcpy(dest20, src.data()); } diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-strlen.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-strlen.c index 366c169..dccf4ed 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-strlen.c +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-strlen.c @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s bugprone-not-null-terminated-result %t -- \ +// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \ // RUN: -- -I %S/Inputs/not-null-terminated-result // FIXME: Something wrong with the APInt un/signed conversion on Windows: @@ -70,13 +70,13 @@ void good_strerror_s(int errno) { int bad_strncmp_1(char *str0, const char *str1) { return strncmp(str0, str1, (strlen(str0) + 1)); // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result] - // CHECK-FIXES: strncmp(str0, str1, (strlen(str0))); + // CHECK-FIXES: return strncmp(str0, str1, (strlen(str0))); } int bad_strncmp_2(char *str2, const char *str3) { return strncmp(str2, str3, 1 + strlen(str2)); // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result] - // CHECK-FIXES: strncmp(str2, str3, strlen(str2)); + // CHECK-FIXES: return strncmp(str2, str3, strlen(str2)); } int good_strncmp_1_2(char *str4, const char *str5) { @@ -86,7 +86,7 @@ int good_strncmp_1_2(char *str4, const char *str5) { int bad_strncmp_3(char *str6) { return strncmp(str6, "string", 7); // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result] - // CHECK-FIXES: strncmp(str6, "string", 6); + // CHECK-FIXES: return strncmp(str6, "string", 6); } int good_strncmp_3(char *str7) { diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-wcslen.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-wcslen.cpp index 06e2db9..8047db3 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-wcslen.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-wcslen.cpp @@ -1,5 +1,5 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s bugprone-not-null-terminated-result %t -- \ -// RUN: -- -std=c++11 -I %S/Inputs/not-null-terminated-result +// RUN: %check_clang_tidy -std=c++11-or-later %s bugprone-not-null-terminated-result %t -- \ +// RUN: -- -I %S/Inputs/not-null-terminated-result // FIXME: Something wrong with the APInt un/signed conversion on Windows: // in 'wcsncmp(wcs6, L"string", 7);' it tries to inject '4294967302' as length. @@ -58,13 +58,13 @@ void good_wmemmove_s_1(wchar_t *dest, const wchar_t *src) { int bad_wcsncmp_1(wchar_t *wcs0, const wchar_t *wcs1) { return wcsncmp(wcs0, wcs1, (wcslen(wcs0) + 1)); // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result] - // CHECK-FIXES: wcsncmp(wcs0, wcs1, (wcslen(wcs0))); + // CHECK-FIXES: return wcsncmp(wcs0, wcs1, (wcslen(wcs0))); } int bad_wcsncmp_2(wchar_t *wcs2, const wchar_t *wcs3) { return wcsncmp(wcs2, wcs3, 1 + wcslen(wcs2)); // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result] - // CHECK-FIXES: wcsncmp(wcs2, wcs3, wcslen(wcs2)); + // CHECK-FIXES: return wcsncmp(wcs2, wcs3, wcslen(wcs2)); } int good_wcsncmp_1_2(wchar_t *wcs4, const wchar_t *wcs5) { @@ -74,7 +74,7 @@ int good_wcsncmp_1_2(wchar_t *wcs4, const wchar_t *wcs5) { int bad_wcsncmp_3(wchar_t *wcs6) { return wcsncmp(wcs6, L"string", 7); // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: comparison length is too long and might lead to a buffer overflow [bugprone-not-null-terminated-result] - // CHECK-FIXES: wcsncmp(wcs6, L"string", 6); + // CHECK-FIXES: return wcsncmp(wcs6, L"string", 6); } int good_wcsncmp_3(wchar_t *wcs7) { diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/posix-return.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/posix-return.cpp index 8db0536..d0dfd97 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/posix-return.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/posix-return.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s bugprone-posix-return %t +// RUN: %check_clang_tidy %s bugprone-posix-return %t #define NULL nullptr #define ZERO 0 @@ -43,40 +43,40 @@ extern "C" int pthread_yield(void); void warningLessThanZero() { if (posix_fadvise(0, 0, 0, 0) < 0) {} // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: the comparison always evaluates to false because posix_fadvise always returns non-negative values - // CHECK-FIXES: posix_fadvise(0, 0, 0, 0) > 0 + // CHECK-FIXES: if (posix_fadvise(0, 0, 0, 0) > 0) {} if (posix_fallocate(0, 0, 0) < 0) {} // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: - // CHECK-FIXES: posix_fallocate(0, 0, 0) > 0 + // CHECK-FIXES: if (posix_fallocate(0, 0, 0) > 0) {} if (posix_madvise(NULL, 0, 0) < 0) {} // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: - // CHECK-FIXES: posix_madvise(NULL, 0, 0) > 0 + // CHECK-FIXES: if (posix_madvise(NULL, 0, 0) > 0) {} if (posix_memalign(NULL, 0, 0) < 0) {} // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: - // CHECK-FIXES: posix_memalign(NULL, 0, 0) > 0 + // CHECK-FIXES: if (posix_memalign(NULL, 0, 0) > 0) {} if (posix_spawn(NULL, NULL, NULL, NULL, {NULL}, {NULL}) < 0) {} // CHECK-MESSAGES: :[[@LINE-1]]:59: warning: - // CHECK-FIXES: posix_spawn(NULL, NULL, NULL, NULL, {NULL}, {NULL}) > 0 + // CHECK-FIXES: if (posix_spawn(NULL, NULL, NULL, NULL, {NULL}, {NULL}) > 0) {} if (posix_spawnp(NULL, NULL, NULL, NULL, {NULL}, {NULL}) < 0) {} // CHECK-MESSAGES: :[[@LINE-1]]:60: warning: - // CHECK-FIXES: posix_spawnp(NULL, NULL, NULL, NULL, {NULL}, {NULL}) > 0 + // CHECK-FIXES: if (posix_spawnp(NULL, NULL, NULL, NULL, {NULL}, {NULL}) > 0) {} if (pthread_create(NULL, NULL, NULL, NULL) < 0) {} // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: the comparison always evaluates to false because pthread_create always returns non-negative values - // CHECK-FIXES: pthread_create(NULL, NULL, NULL, NULL) > 0 + // CHECK-FIXES: if (pthread_create(NULL, NULL, NULL, NULL) > 0) {} if (pthread_attr_setaffinity_np(NULL, 0, NULL) < 0) {} // CHECK-MESSAGES: :[[@LINE-1]]:50: warning: - // CHECK-FIXES: pthread_attr_setaffinity_np(NULL, 0, NULL) > 0 + // CHECK-FIXES: if (pthread_attr_setaffinity_np(NULL, 0, NULL) > 0) {} if (pthread_attr_setschedpolicy(NULL, 0) < 0) {} // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: - // CHECK-FIXES: pthread_attr_setschedpolicy(NULL, 0) > 0) + // CHECK-FIXES: if (pthread_attr_setschedpolicy(NULL, 0) > 0) {} if (pthread_attr_init(NULL) < 0) {} // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: - // CHECK-FIXES: pthread_attr_init(NULL) > 0 + // CHECK-FIXES: if (pthread_attr_init(NULL) > 0) {} if (pthread_yield() < 0) {} // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: - // CHECK-FIXES: pthread_yield() > 0 - if (0 > pthread_yield() ) {} + // CHECK-FIXES: if (pthread_yield() > 0) {} + if (0 > pthread_yield()) {} // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: - // CHECK-FIXES: 0 < pthread_yield() + // CHECK-FIXES: if (0 < pthread_yield()) {} } @@ -137,7 +137,7 @@ void warningEqualsNegative() { void WarningWithMacro() { if (posix_fadvise(0, 0, 0, 0) < ZERO) {} // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: - // CHECK-FIXES: posix_fadvise(0, 0, 0, 0) > ZERO + // CHECK-FIXES: if (posix_fadvise(0, 0, 0, 0) > ZERO) {} if (posix_fadvise(0, 0, 0, 0) >= ZERO) {} // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: if (posix_fadvise(0, 0, 0, 0) == NEGATIVE_ONE) {} @@ -150,7 +150,7 @@ void WarningWithMacro() { // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: if (pthread_create(NULL, NULL, NULL, NULL) < ZERO) {} // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: - // CHECK-FIXES: pthread_create(NULL, NULL, NULL, NULL) > ZERO + // CHECK-FIXES: if (pthread_create(NULL, NULL, NULL, NULL) > ZERO) {} if (pthread_create(NULL, NULL, NULL, NULL) >= ZERO) {} // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: if (pthread_create(NULL, NULL, NULL, NULL) == NEGATIVE_ONE) {} diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/stringview-nullptr.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/stringview-nullptr.cpp index 050e38d..b85ba02 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/stringview-nullptr.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/stringview-nullptr.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s bugprone-stringview-nullptr -std=c++17 %t +// RUN: %check_clang_tidy %s bugprone-stringview-nullptr -std=c++17 %t namespace std { @@ -148,7 +148,8 @@ void temporary_construction() /* a */ { // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default // CHECK-FIXES: (void)(std::string_view()) /* a4 */; - (void)(std::string_view({})) /* a5 */; // Default `const CharT*` + // Default `const CharT*` + (void)(std::string_view({})) /* a5 */; // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default // CHECK-FIXES: (void)(std::string_view()) /* a5 */; } @@ -171,7 +172,8 @@ void temporary_construction() /* a */ { // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default // CHECK-FIXES: (void)(std::string_view{}) /* a9 */; - (void)(std::string_view{{}}) /* a10 */; // Default `const CharT*` + // Default `const CharT*` + (void)(std::string_view{{}}) /* a10 */; // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default // CHECK-FIXES: (void)(std::string_view{}) /* a10 */; } @@ -202,7 +204,8 @@ void temporary_construction() /* a */ { // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: constructing{{.*}}default // CHECK-FIXES: (void)((std::string_view){}) /* a16 */; - (void)((std::string_view){{}}) /* a17 */; // Default `const CharT*` + // Default `const CharT*` + (void)((std::string_view){{}}) /* a17 */; // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: constructing{{.*}}default // CHECK-FIXES: (void)((std::string_view){}) /* a17 */; @@ -230,7 +233,8 @@ void temporary_construction() /* a */ { // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing{{.*}}default // CHECK-FIXES: (void)((const std::string_view){}) /* a23 */; - (void)((const std::string_view){{}}) /* a24 */; // Default `const CharT*` + // Default `const CharT*` + (void)((const std::string_view){{}}) /* a24 */; // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing{{.*}}default // CHECK-FIXES: (void)((const std::string_view){}) /* a24 */; } @@ -316,7 +320,8 @@ void stack_construction() /* b */ { // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default // CHECK-FIXES: std::string_view b13 = {}; - std::string_view b14 = {{}}; // Default `const CharT*` + // Default `const CharT*` + std::string_view b14 = {{}}; // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default // CHECK-FIXES: std::string_view b14 = {}; @@ -336,7 +341,8 @@ void stack_construction() /* b */ { // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: constructing{{.*}}default // CHECK-FIXES: const std::string_view b18 = {}; - const std::string_view b19 = {{}}; // Default `const CharT*` + // Default `const CharT*` + const std::string_view b19 = {{}}; // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: constructing{{.*}}default // CHECK-FIXES: const std::string_view b19 = {}; } @@ -382,7 +388,8 @@ void stack_construction() /* b */ { // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: constructing{{.*}}default // CHECK-FIXES: std::string_view b28; - std::string_view b29({}); // Default `const CharT*` + // Default `const CharT*` + std::string_view b29({}); // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: constructing{{.*}}default // CHECK-FIXES: std::string_view b29; @@ -402,7 +409,8 @@ void stack_construction() /* b */ { // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing{{.*}}default // CHECK-FIXES: const std::string_view b33; - const std::string_view b34({}); // Default `const CharT*` + // Default `const CharT*` + const std::string_view b34({}); // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: constructing{{.*}}default // CHECK-FIXES: const std::string_view b34; } @@ -448,7 +456,8 @@ void stack_construction() /* b */ { // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default // CHECK-FIXES: std::string_view b43{}; - std::string_view b44{{}}; // Default `const CharT*` + // Default `const CharT*` + std::string_view b44{{}}; // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default // CHECK-FIXES: std::string_view b44{}; @@ -468,7 +477,8 @@ void stack_construction() /* b */ { // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default // CHECK-FIXES: const std::string_view b48{}; - const std::string_view b49{{}}; // Default `const CharT*` + // Default `const CharT*` + const std::string_view b49{{}}; // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default // CHECK-FIXES: const std::string_view b49{}; } @@ -557,7 +567,8 @@ void field_construction() /* c */ { // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default // CHECK-FIXES: std::string_view c13 = {}; - std::string_view c14 = {{}}; // Default `const CharT*` + // Default `const CharT*` + std::string_view c14 = {{}}; // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: constructing{{.*}}default // CHECK-FIXES: std::string_view c14 = {}; @@ -577,7 +588,8 @@ void field_construction() /* c */ { // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: constructing{{.*}}default // CHECK-FIXES: const std::string_view c18 = {}; - const std::string_view c19 = {{}}; // Default `const CharT*` + // Default `const CharT*` + const std::string_view c19 = {{}}; // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: constructing{{.*}}default // CHECK-FIXES: const std::string_view c19 = {}; }; @@ -621,7 +633,8 @@ void field_construction() /* c */ { // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default // CHECK-FIXES: std::string_view c28{}; - std::string_view c29{{}}; // Default `const CharT*` + // Default `const CharT*` + std::string_view c29{{}}; // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: constructing{{.*}}default // CHECK-FIXES: std::string_view c29{}; @@ -641,7 +654,8 @@ void field_construction() /* c */ { // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default // CHECK-FIXES: const std::string_view c33{}; - const std::string_view c34{{}}; // Default `const CharT*` + // Default `const CharT*` + const std::string_view c34{{}}; // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: constructing{{.*}}default // CHECK-FIXES: const std::string_view c34{}; }; @@ -694,7 +708,8 @@ void field_construction() /* c */ { // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default // CHECK-FIXES: c43(), - c44({}) { // Default `const CharT*` + // Default `const CharT*` + c44({}) { // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default // CHECK-FIXES: c44() { } @@ -754,7 +769,8 @@ void field_construction() /* c */ { // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default // CHECK-FIXES: c53{}, - c54{{}} { // Default `const CharT*` + // Default `const CharT*` + c54{{}} { // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: constructing{{.*}}default // CHECK-FIXES: c54{} { } @@ -852,7 +868,8 @@ void default_argument_construction() /* d */ { // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing{{.*}}default // CHECK-FIXES: void d13(std::string_view sv = {}); - void d14(std::string_view sv = {{}}); // Default `const CharT*` + // Default `const CharT*` + void d14(std::string_view sv = {{}}); // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: constructing{{.*}}default // CHECK-FIXES: void d14(std::string_view sv = {}); @@ -872,7 +889,8 @@ void default_argument_construction() /* d */ { // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: constructing{{.*}}default // CHECK-FIXES: void d18(const std::string_view sv = {}); - void d19(const std::string_view sv = {{}}); // Default `const CharT*` + // Default `const CharT*` + void d19(const std::string_view sv = {{}}); // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: constructing{{.*}}default // CHECK-FIXES: void d19(const std::string_view sv = {}); } @@ -920,7 +938,8 @@ void heap_construction() /* e */ { // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default // CHECK-FIXES: (void)(new std::string_view()) /* e4 */; - (void)(new std::string_view({})) /* e5 */; // Default `const CharT*` + // Default `const CharT*` + (void)(new std::string_view({})) /* e5 */; // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default // CHECK-FIXES: (void)(new std::string_view()) /* e5 */; @@ -940,7 +959,8 @@ void heap_construction() /* e */ { // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default // CHECK-FIXES: (void)(new const std::string_view()) /* e9 */; - (void)(new const std::string_view({})) /* e10 */; // Default `const CharT*` + // Default `const CharT*` + (void)(new const std::string_view({})) /* e10 */; // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default // CHECK-FIXES: (void)(new const std::string_view()) /* e10 */; } @@ -986,7 +1006,8 @@ void heap_construction() /* e */ { // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default // CHECK-FIXES: (void)(new std::string_view{}) /* e19 */; - (void)(new std::string_view{{}}) /* e20 */; // Default `const CharT*` + // Default `const CharT*` + (void)(new std::string_view{{}}) /* e20 */; // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: constructing{{.*}}default // CHECK-FIXES: (void)(new std::string_view{}) /* e20 */; @@ -1006,7 +1027,8 @@ void heap_construction() /* e */ { // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default // CHECK-FIXES: (void)(new const std::string_view{}) /* e24 */; - (void)(new const std::string_view{{}}) /* e25 */; // Default `const CharT*` + // Default `const CharT*` + (void)(new const std::string_view{{}}) /* e25 */; // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: constructing{{.*}}default // CHECK-FIXES: (void)(new const std::string_view{}) /* e25 */; } @@ -1054,7 +1076,8 @@ void function_argument_initialization() /* f */ { // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: passing{{.*}}empty string // CHECK-FIXES: function("") /* f4 */; - function({{}}) /* f5 */; // Default `const CharT*` + // Default `const CharT*` + function({{}}) /* f5 */; // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: passing{{.*}}empty string // CHECK-FIXES: function("") /* f5 */; } @@ -1102,7 +1125,8 @@ void assignment(std::string_view sv) /* g */ { // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: assignment{{.*}}default // CHECK-FIXES: sv = {} /* g4 */; - sv = {{}} /* g5 */; // Default `const CharT*` + // Default `const CharT*` + sv = {{}} /* g5 */; // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: assignment{{.*}}default // CHECK-FIXES: sv = {} /* g5 */; } @@ -1150,7 +1174,8 @@ void pointer_assignment(std::string_view *sv_ptr) /* h */ { // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: assignment{{.*}}default // CHECK-FIXES: *sv_ptr = {} /* h4 */; - *sv_ptr = {{}} /* h5 */; // Default `const CharT*` + // Default `const CharT*` + *sv_ptr = {{}} /* h5 */; // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: assignment{{.*}}default // CHECK-FIXES: *sv_ptr = {} /* h5 */; } @@ -1566,7 +1591,8 @@ void return_statement() /* q */ { // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: constructing{{.*}}default // CHECK-FIXES: []() -> SV { return {}; } /* q6 */; - []() -> SV { return {{}}; } /* q7 */; // Default `const CharT*` + // Default `const CharT*` + []() -> SV { return {{}}; } /* q7 */; // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: constructing{{.*}}default // CHECK-FIXES: []() -> SV { return {}; } /* q7 */; } diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-string-compare.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-string-compare.cpp index d670fa9..399018e 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-string-compare.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-string-compare.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s bugprone-suspicious-string-compare %t -- \ +// RUN: %check_clang_tidy %s bugprone-suspicious-string-compare %t -- \ // RUN: -config='{CheckOptions: \ // RUN: {bugprone-suspicious-string-compare.WarnOnImplicitComparison: true, \ // RUN: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison: true}}' \ @@ -117,187 +117,187 @@ int test_implicit_compare_with_functions() { if (memcmp(A, "a", 1)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'memcmp' is called without explicitly comparing result - // CHECK-FIXES: memcmp(A, "a", 1) != 0) + // CHECK-FIXES: if (memcmp(A, "a", 1) != 0) if (wmemcmp(W, L"a", 1)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wmemcmp' is called without explicitly comparing result - // CHECK-FIXES: wmemcmp(W, L"a", 1) != 0) + // CHECK-FIXES: if (wmemcmp(W, L"a", 1) != 0) if (memicmp(A, "a", 1)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'memicmp' is called without explicitly comparing result - // CHECK-FIXES: memicmp(A, "a", 1) != 0) + // CHECK-FIXES: if (memicmp(A, "a", 1) != 0) if (_memicmp(A, "a", 1)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_memicmp' is called without explicitly comparing result - // CHECK-FIXES: _memicmp(A, "a", 1) != 0) + // CHECK-FIXES: if (_memicmp(A, "a", 1) != 0) if (_memicmp_l(A, "a", 1, locale)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_memicmp_l' is called without explicitly comparing result - // CHECK-FIXES: _memicmp_l(A, "a", 1, locale) != 0) + // CHECK-FIXES: if (_memicmp_l(A, "a", 1, locale) != 0) if (strcmp(A, "a")) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result - // CHECK-FIXES: strcmp(A, "a") != 0) + // CHECK-FIXES: if (strcmp(A, "a") != 0) if (strncmp(A, "a", 1)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strncmp' is called without explicitly comparing result - // CHECK-FIXES: strncmp(A, "a", 1) != 0) + // CHECK-FIXES: if (strncmp(A, "a", 1) != 0) if (strcasecmp(A, "a")) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcasecmp' is called without explicitly comparing result - // CHECK-FIXES: strcasecmp(A, "a") != 0) + // CHECK-FIXES: if (strcasecmp(A, "a") != 0) if (strncasecmp(A, "a", 1)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strncasecmp' is called without explicitly comparing result - // CHECK-FIXES: strncasecmp(A, "a", 1) != 0) + // CHECK-FIXES: if (strncasecmp(A, "a", 1) != 0) if (stricmp(A, "a")) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'stricmp' is called without explicitly comparing result - // CHECK-FIXES: stricmp(A, "a") != 0) + // CHECK-FIXES: if (stricmp(A, "a") != 0) if (strcmpi(A, "a")) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmpi' is called without explicitly comparing result - // CHECK-FIXES: strcmpi(A, "a") != 0) + // CHECK-FIXES: if (strcmpi(A, "a") != 0) if (_stricmp(A, "a")) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_stricmp' is called without explicitly comparing result - // CHECK-FIXES: _stricmp(A, "a") != 0) + // CHECK-FIXES: if (_stricmp(A, "a") != 0) if (strnicmp(A, "a", 1)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strnicmp' is called without explicitly comparing result - // CHECK-FIXES: strnicmp(A, "a", 1) != 0) + // CHECK-FIXES: if (strnicmp(A, "a", 1) != 0) if (_strnicmp(A, "a", 1)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_strnicmp' is called without explicitly comparing result - // CHECK-FIXES: _strnicmp(A, "a", 1) != 0) + // CHECK-FIXES: if (_strnicmp(A, "a", 1) != 0) if (_stricmp_l(A, "a", locale)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_stricmp_l' is called without explicitly comparing result - // CHECK-FIXES: _stricmp_l(A, "a", locale) != 0) + // CHECK-FIXES: if (_stricmp_l(A, "a", locale) != 0) if (_strnicmp_l(A, "a", 1, locale)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_strnicmp_l' is called without explicitly comparing result - // CHECK-FIXES: _strnicmp_l(A, "a", 1, locale) != 0) + // CHECK-FIXES: if (_strnicmp_l(A, "a", 1, locale) != 0) if (wcscmp(W, L"a")) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcscmp' is called without explicitly comparing result - // CHECK-FIXES: wcscmp(W, L"a") != 0) + // CHECK-FIXES: if (wcscmp(W, L"a") != 0) if (wcsncmp(W, L"a", 1)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcsncmp' is called without explicitly comparing result - // CHECK-FIXES: wcsncmp(W, L"a", 1) != 0) + // CHECK-FIXES: if (wcsncmp(W, L"a", 1) != 0) if (wcscasecmp(W, L"a")) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcscasecmp' is called without explicitly comparing result - // CHECK-FIXES: wcscasecmp(W, L"a") != 0) + // CHECK-FIXES: if (wcscasecmp(W, L"a") != 0) if (wcsicmp(W, L"a")) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcsicmp' is called without explicitly comparing result - // CHECK-FIXES: wcsicmp(W, L"a") != 0) + // CHECK-FIXES: if (wcsicmp(W, L"a") != 0) if (_wcsicmp(W, L"a")) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsicmp' is called without explicitly comparing result - // CHECK-FIXES: _wcsicmp(W, L"a") != 0) + // CHECK-FIXES: if (_wcsicmp(W, L"a") != 0) if (_wcsicmp_l(W, L"a", locale)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsicmp_l' is called without explicitly comparing result - // CHECK-FIXES: _wcsicmp_l(W, L"a", locale) != 0) + // CHECK-FIXES: if (_wcsicmp_l(W, L"a", locale) != 0) if (wcsnicmp(W, L"a", 1)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcsnicmp' is called without explicitly comparing result - // CHECK-FIXES: wcsnicmp(W, L"a", 1) != 0) + // CHECK-FIXES: if (wcsnicmp(W, L"a", 1) != 0) if (_wcsnicmp(W, L"a", 1)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsnicmp' is called without explicitly comparing result - // CHECK-FIXES: _wcsnicmp(W, L"a", 1) != 0) + // CHECK-FIXES: if (_wcsnicmp(W, L"a", 1) != 0) if (_wcsnicmp_l(W, L"a", 1, locale)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsnicmp_l' is called without explicitly comparing result - // CHECK-FIXES: _wcsnicmp_l(W, L"a", 1, locale) != 0) + // CHECK-FIXES: if (_wcsnicmp_l(W, L"a", 1, locale) != 0) if (_mbscmp(U, V)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbscmp' is called without explicitly comparing result - // CHECK-FIXES: _mbscmp(U, V) != 0) + // CHECK-FIXES: if (_mbscmp(U, V) != 0) if (_mbsncmp(U, V, 1)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsncmp' is called without explicitly comparing result - // CHECK-FIXES: _mbsncmp(U, V, 1) != 0) + // CHECK-FIXES: if (_mbsncmp(U, V, 1) != 0) if (_mbsnbcmp(U, V, 1)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbcmp' is called without explicitly comparing result - // CHECK-FIXES: _mbsnbcmp(U, V, 1) != 0) + // CHECK-FIXES: if (_mbsnbcmp(U, V, 1) != 0) if (_mbsnbicmp(U, V, 1)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbicmp' is called without explicitly comparing result - // CHECK-FIXES: _mbsnbicmp(U, V, 1) != 0) + // CHECK-FIXES: if (_mbsnbicmp(U, V, 1) != 0) if (_mbsicmp(U, V)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsicmp' is called without explicitly comparing result - // CHECK-FIXES: _mbsicmp(U, V) != 0) + // CHECK-FIXES: if (_mbsicmp(U, V) != 0) if (_mbsnicmp(U, V, 1)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnicmp' is called without explicitly comparing result - // CHECK-FIXES: _mbsnicmp(U, V, 1) != 0) + // CHECK-FIXES: if (_mbsnicmp(U, V, 1) != 0) if (_mbscmp_l(U, V, locale)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbscmp_l' is called without explicitly comparing result - // CHECK-FIXES: _mbscmp_l(U, V, locale) != 0) + // CHECK-FIXES: if (_mbscmp_l(U, V, locale) != 0) if (_mbsncmp_l(U, V, 1, locale)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsncmp_l' is called without explicitly comparing result - // CHECK-FIXES: _mbsncmp_l(U, V, 1, locale) != 0) + // CHECK-FIXES: if (_mbsncmp_l(U, V, 1, locale) != 0) if (_mbsicmp_l(U, V, locale)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsicmp_l' is called without explicitly comparing result - // CHECK-FIXES: _mbsicmp_l(U, V, locale) != 0) + // CHECK-FIXES: if (_mbsicmp_l(U, V, locale) != 0) if (_mbsnicmp_l(U, V, 1, locale)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnicmp_l' is called without explicitly comparing result - // CHECK-FIXES: _mbsnicmp_l(U, V, 1, locale) != 0) + // CHECK-FIXES: if (_mbsnicmp_l(U, V, 1, locale) != 0) if (_mbsnbcmp_l(U, V, 1, locale)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbcmp_l' is called without explicitly comparing result - // CHECK-FIXES: _mbsnbcmp_l(U, V, 1, locale) != 0) + // CHECK-FIXES: if (_mbsnbcmp_l(U, V, 1, locale) != 0) if (_mbsnbicmp_l(U, V, 1, locale)) return 0; // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbicmp_l' is called without explicitly comparing result - // CHECK-FIXES: _mbsnbicmp_l(U, V, 1, locale) != 0) + // CHECK-FIXES: if (_mbsnbicmp_l(U, V, 1, locale) != 0) return 1; } diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/swapped-arguments.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/swapped-arguments.cpp index 3d21396..985ebc2 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/swapped-arguments.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/swapped-arguments.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s bugprone-swapped-arguments %t +// RUN: %check_clang_tidy %s bugprone-swapped-arguments %t void F(int, double); @@ -9,7 +9,7 @@ void G(T a, U b) { F(a, b); // no-warning F(2.0, 4); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: argument with implicit conversion from 'double' to 'int' followed by argument converted from 'int' to 'double', potentially swapped arguments. -// CHECK-FIXES: F(4, 2.0) +// CHECK-FIXES: F(4, 2.0); } void funShortFloat(short, float); @@ -20,7 +20,7 @@ void funBoolFloat(bool, float); void foo() { F(1.0, 3); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: argument with implicit conversion from 'double' to 'int' followed by argument converted from 'int' to 'double', potentially swapped arguments. -// CHECK-FIXES: F(3, 1.0) +// CHECK-FIXES: F(3, 1.0); #define M(x, y) x##y() diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/prefer-member-initializer.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/prefer-member-initializer.cpp index e8d7db1..2f5e6c7 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/prefer-member-initializer.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/prefer-member-initializer.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s cppcoreguidelines-prefer-member-initializer %t -- -- -fcxx-exceptions +// RUN: %check_clang_tidy %s cppcoreguidelines-prefer-member-initializer %t -- -- -fcxx-exceptions extern void __assert_fail (__const char *__assertion, __const char *__file, unsigned int __line, __const char *__function) @@ -398,7 +398,7 @@ public: } explicit Complex19(int) { - // CHECK-FIXES: Complex19(int) : n(12) { + // CHECK-FIXES: explicit Complex19(int) : n(12) { n = 12; // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'n' should be initialized in a member initializer of the constructor [cppcoreguidelines-prefer-member-initializer] // CHECK-FIXES: {{^\ *$}} diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-constant-array-index.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-constant-array-index.cpp index 6fd5227..057ab3b 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-constant-array-index.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-constant-array-index.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s cppcoreguidelines-pro-bounds-constant-array-index %t +// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-constant-array-index %t typedef __SIZE_TYPE__ size_t; @@ -151,7 +151,6 @@ void g() { for (int i = 0; i < 10; ++i) { a[i] = i; // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use array subscript when the index is not an integer constant expression - // CHECK-FIXES: gsl::at(a, i) = i; gsl::at(a, i) = i; // OK, gsl::at() instead of [] } diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init-use-assignment.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init-use-assignment.cpp index c15d444..d1c45ec 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init-use-assignment.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init-use-assignment.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s cppcoreguidelines-pro-type-member-init %t -- -config="{CheckOptions: {cppcoreguidelines-pro-type-member-init.UseAssignment: true}}" -- -fsigned-char +// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-member-init %t -- -config="{CheckOptions: {cppcoreguidelines-pro-type-member-init.UseAssignment: true}}" -- -fsigned-char struct T { int i; @@ -30,7 +30,7 @@ struct S { double d; // CHECK-FIXES: double d = 0.0; long double ld; - // CHECK-FIXES: double ld = 0.0L; + // CHECK-FIXES: long double ld = 0.0L; int *ptr; // CHECK-FIXES: int *ptr = nullptr; T t; diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init.cpp index 8896732..890d1d2 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-member-init.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes -std=c++11,c++14,c++17 %s cppcoreguidelines-pro-type-member-init %t -- -- -fno-delayed-template-parsing +// RUN: %check_clang_tidy -std=c++11,c++14,c++17 %s cppcoreguidelines-pro-type-member-init %t -- -- -fno-delayed-template-parsing // FIXME: Fix the checker to work in C++20 mode. struct PositiveFieldBeforeConstructor { @@ -105,7 +105,7 @@ template <class T> class NegativeTemplateConstructor { int FIELD; \ }; \ // Ensure FIELD is not initialized since fixes inside of macros are disabled. -// CHECK-FIXES: int FIELD; +// CHECK-FIXES: int FIELD; {{\\}} UNINITIALIZED_FIELD_IN_MACRO_BODY(F); // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: F @@ -429,7 +429,7 @@ template struct PositiveTemplateVirtualDestructor<int>; virtual ~UninitializedFieldVirtual##FIELD() {} \ }; \ // Ensure FIELD is not initialized since fixes inside of macros are disabled. -// CHECK-FIXES: int FIELD; +// CHECK-FIXES: int FIELD; {{\\}} UNINITIALIZED_FIELD_IN_MACRO_BODY_VIRTUAL(F); // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: F diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/virtual-class-destructor.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/virtual-class-destructor.cpp index 44d0251..725a709 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/virtual-class-destructor.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/virtual-class-destructor.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s cppcoreguidelines-virtual-class-destructor %t -- --fix-notes +// RUN: %check_clang_tidy %s cppcoreguidelines-virtual-class-destructor %t -- --fix-notes // CHECK-MESSAGES: :[[@LINE+4]]:8: warning: destructor of 'PrivateVirtualBaseStruct' is private and prevents using the type [cppcoreguidelines-virtual-class-destructor] // CHECK-MESSAGES: :[[@LINE+3]]:8: note: make it public and virtual @@ -163,7 +163,7 @@ protected: // CHECK-FIXES: class OverridingDerivedClass : ProtectedNonVirtualClass { // CHECK-FIXES-NEXT: public: // CHECK-FIXES-NEXT: virtual ~OverridingDerivedClass() = default; -// CHECK-FIXES-NEXT: void f() override; +// CHECK-FIXES-NEXT: void f() override; // is implicitly virtual // CHECK-FIXES-NEXT: }; class OverridingDerivedClass : ProtectedNonVirtualClass { public: @@ -186,7 +186,7 @@ class NonOverridingDerivedClass : ProtectedNonVirtualClass { // CHECK-MESSAGES: :[[@LINE+5]]:8: note: make it public and virtual // CHECK-FIXES: struct OverridingDerivedStruct : ProtectedNonVirtualBaseStruct { // CHECK-FIXES-NEXT: virtual ~OverridingDerivedStruct() = default; -// CHECK-FIXES-NEXT: void f() override; +// CHECK-FIXES-NEXT: void f() override; // is implicitly virtual // CHECK-FIXES-NEXT: }; struct OverridingDerivedStruct : ProtectedNonVirtualBaseStruct { void f() override; // is implicitly virtual @@ -289,26 +289,18 @@ protected: virtual CONCAT(~Foo, Bar2()); // FIXME: We should have a fixit for this. }; -// CHECK-MESSAGES: :[[@LINE+6]]:7: warning: destructor of 'FooBar3' is protected and virtual [cppcoreguidelines-virtual-class-destructor] -// CHECK-MESSAGES: :[[@LINE+5]]:7: note: make it protected and non-virtual -// CHECK-FIXES: class FooBar3 { -// CHECK-FIXES-NEXT: protected: -// CHECK-FIXES-NEXT: ~FooBar3(); -// CHECK-FIXES-NEXT: }; +// CHECK-MESSAGES: :[[@LINE+2]]:7: warning: destructor of 'FooBar3' is protected and virtual [cppcoreguidelines-virtual-class-destructor] +// CHECK-MESSAGES: :[[@LINE+1]]:7: note: make it protected and non-virtual class FooBar3 { protected: - CONCAT(vir, tual) ~FooBar3(); + CONCAT(vir, tual) ~FooBar3(); // FIXME: We should have a fixit for this. }; -// CHECK-MESSAGES: :[[@LINE+6]]:7: warning: destructor of 'FooBar4' is protected and virtual [cppcoreguidelines-virtual-class-destructor] -// CHECK-MESSAGES: :[[@LINE+5]]:7: note: make it protected and non-virtual -// CHECK-FIXES: class FooBar4 { -// CHECK-FIXES-NEXT: protected: -// CHECK-FIXES-NEXT: ~CONCAT(Foo, Bar4()); -// CHECK-FIXES-NEXT: }; +// CHECK-MESSAGES: :[[@LINE+2]]:7: warning: destructor of 'FooBar4' is protected and virtual [cppcoreguidelines-virtual-class-destructor] +// CHECK-MESSAGES: :[[@LINE+1]]:7: note: make it protected and non-virtual class FooBar4 { protected: - CONCAT(vir, tual) ~CONCAT(Foo, Bar4()); + CONCAT(vir, tual) ~CONCAT(Foo, Bar4()); // FIXME: We should have a fixit for this. }; // CHECK-MESSAGES: :[[@LINE+3]]:7: warning: destructor of 'FooBar5' is protected and virtual [cppcoreguidelines-virtual-class-destructor] diff --git a/clang-tools-extra/test/clang-tidy/checkers/google/build-explicit-make-pair.cpp b/clang-tools-extra/test/clang-tidy/checkers/google/build-explicit-make-pair.cpp index 94d5462..ea77272 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/google/build-explicit-make-pair.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/google/build-explicit-make-pair.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s google-build-explicit-make-pair %t +// RUN: %check_clang_tidy %s google-build-explicit-make-pair %t namespace std { template <class T1, class T2> @@ -17,7 +17,7 @@ void templ(T a, T b) { std::make_pair<T, unsigned>(a, b); std::make_pair<int, int>(1, 2); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, omit template arguments from make_pair -// CHECK-FIXES: std::make_pair(1, 2) +// CHECK-FIXES: std::make_pair(1, 2); } template <typename T> @@ -26,15 +26,15 @@ int t(); void test(int i) { std::make_pair<int, int>(i, i); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, omit template arguments from make_pair -// CHECK-FIXES: std::make_pair(i, i) +// CHECK-FIXES: std::make_pair(i, i); std::make_pair<unsigned, int>(i, i); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, use pair directly -// CHECK-FIXES: std::pair<unsigned, int>(i, i) +// CHECK-FIXES: std::pair<unsigned, int>(i, i); std::make_pair<int, unsigned>(i, i); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, use pair directly -// CHECK-FIXES: std::pair<int, unsigned>(i, i) +// CHECK-FIXES: std::pair<int, unsigned>(i, i); #define M std::make_pair<int, unsigned>(i, i); M diff --git a/clang-tools-extra/test/clang-tidy/checkers/google/objc-avoid-nsobject-new.m b/clang-tools-extra/test/clang-tidy/checkers/google/objc-avoid-nsobject-new.m index f62af8f..9d02702 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/google/objc-avoid-nsobject-new.m +++ b/clang-tools-extra/test/clang-tidy/checkers/google/objc-avoid-nsobject-new.m @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s google-objc-avoid-nsobject-new %t +// RUN: %check_clang_tidy %s google-objc-avoid-nsobject-new %t @interface NSObject + (instancetype)new; @@ -25,18 +25,18 @@ void CheckSpecificInitRecommendations(void) { NSObject *object = [NSObject new]; // CHECK-MESSAGES: [[@LINE-1]]:22: warning: do not create objects with +new [google-objc-avoid-nsobject-new] - // CHECK-FIXES: [NSObject alloc] init]; + // CHECK-FIXES: NSObject *object = {{[[][[]}}NSObject alloc] init]; NSDate *correctDate = [NSDate date]; NSDate *incorrectDate = [NSDate new]; // CHECK-MESSAGES: [[@LINE-1]]:27: warning: do not create objects with +new [google-objc-avoid-nsobject-new] - // CHECK-FIXES: [NSDate date]; + // CHECK-FIXES: NSDate *incorrectDate = [NSDate date]; NSObject *macroCreated = ALLOCATE_OBJECT(NSObject); // Shouldn't warn on macros. NSMutableDictionary *dict = [NSMutableDictionary<NSString *, NSString *> new]; // CHECK-MESSAGES: [[@LINE-1]]:31: warning: do not create objects with +new [google-objc-avoid-nsobject-new] - // CHECK-FIXES: [NSMutableDictionary<NSString *, NSString *> alloc] init]; + // CHECK-FIXES: NSMutableDictionary *dict = {{[[][[]}}NSMutableDictionary<NSString *, NSString *> alloc] init]; } @interface Foo : NSObject diff --git a/clang-tools-extra/test/clang-tidy/checkers/google/upgrade-googletest-case.cpp b/clang-tools-extra/test/clang-tidy/checkers/google/upgrade-googletest-case.cpp index cf24d2d..edb11b9 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/google/upgrade-googletest-case.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/google/upgrade-googletest-case.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s google-upgrade-googletest-case %t -- -- -I%S/Inputs +// RUN: %check_clang_tidy %s google-upgrade-googletest-case %t -- -- -I%S/Inputs // RUN: %check_clang_tidy -check-suffix=NOSUITE %s google-upgrade-googletest-case %t -- -- -DNOSUITE -I%S/Inputs/gtest/nosuite #include "gtest/gtest.h" @@ -89,12 +89,14 @@ public: // CHECK-FIXES: static void TearDownTestSuite(); }; -template <typename T> void FooTypedTest<T>::SetUpTestCase() {} -// CHECK-MESSAGES: [[@LINE-1]]:45: warning: Google Test APIs named with 'case' +template <typename T> +void FooTypedTest<T>::SetUpTestCase() {} +// CHECK-MESSAGES: [[@LINE-1]]:23: warning: Google Test APIs named with 'case' // CHECK-FIXES: void FooTypedTest<T>::SetUpTestSuite() {} -template <typename T> void FooTypedTest<T>::TearDownTestCase() {} -// CHECK-MESSAGES: [[@LINE-1]]:45: warning: Google Test APIs named with 'case' +template <typename T> +void FooTypedTest<T>::TearDownTestCase() {} +// CHECK-MESSAGES: [[@LINE-1]]:23: warning: Google Test APIs named with 'case' // CHECK-FIXES: void FooTypedTest<T>::TearDownTestSuite() {} class BarTest : public testing::Test { diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-isa-or-dyn-cast-in-conditionals.cpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-isa-or-dyn-cast-in-conditionals.cpp index 6b4c917..4edcc05 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-isa-or-dyn-cast-in-conditionals.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-isa-or-dyn-cast-in-conditionals.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s llvm-prefer-isa-or-dyn-cast-in-conditionals %t +// RUN: %check_clang_tidy %s llvm-prefer-isa-or-dyn-cast-in-conditionals %t struct X; struct Y; @@ -79,7 +79,7 @@ bool foo(Y *y, Z *z) { break; } while (cast<X>(y)); // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: cast<> in conditional - // CHECK-FIXES: while (isa<X>(y)); + // CHECK-FIXES: } while (isa<X>(y)); if (dyn_cast<X>(y)) return true; @@ -100,7 +100,7 @@ bool foo(Y *y, Z *z) { break; } while (dyn_cast<X>(y)); // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: return value from dyn_cast<> not used - // CHECK-FIXES: while (isa<X>(y)); + // CHECK-FIXES: } while (isa<X>(y)); if (y && isa<X>(y)) return true; diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-register-over-unsigned.cpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-register-over-unsigned.cpp index 5dd3a9d..07b4f33 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-register-over-unsigned.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/llvm/prefer-register-over-unsigned.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s llvm-prefer-register-over-unsigned %t +// RUN: %check_clang_tidy %s llvm-prefer-register-over-unsigned %t namespace llvm { class Register { @@ -23,8 +23,8 @@ llvm::RegisterLike getRegLike(); void apply_1() { unsigned Reg1 = getReg(); // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'Reg1' declared as 'unsigned int'; use 'llvm::Register' instead [llvm-prefer-register-over-unsigned] - // CHECK-FIXES: apply_1() - // CHECK-FIXES-NEXT: llvm::Register Reg1 = getReg(); + // CHECK-FIXES: void apply_1() { + // CHECK-FIXES-NEXT: llvm::Register Reg1 = getReg(); } void apply_2() { @@ -34,110 +34,110 @@ void apply_2() { // DeclContext for the function so we can't elide the llvm:: in this // case. Fortunately, it doesn't actually occur in the LLVM code base. // CHECK-MESSAGES: :[[@LINE-4]]:12: warning: variable 'Reg2' declared as 'unsigned int'; use 'llvm::Register' instead [llvm-prefer-register-over-unsigned] - // CHECK-FIXES: apply_2() - // CHECK-FIXES-NEXT: using namespace llvm; - // CHECK-FIXES-NEXT: llvm::Register Reg2 = getReg(); + // CHECK-FIXES: void apply_2() { + // CHECK-FIXES-NEXT: using namespace llvm; + // CHECK-FIXES-NEXT: llvm::Register Reg2 = getReg(); } namespace llvm { void apply_3() { unsigned Reg3 = getReg(); // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'Reg3' declared as 'unsigned int'; use 'Register' instead [llvm-prefer-register-over-unsigned] - // CHECK-FIXES: apply_3() - // CHECK-FIXES-NEXT: Register Reg3 = getReg(); + // CHECK-FIXES: void apply_3() { + // CHECK-FIXES-NEXT: Register Reg3 = getReg(); } } // end namespace llvm void done_1() { llvm::Register Reg1 = getReg(); - // CHECK-FIXES: done_1() - // CHECK-FIXES-NEXT: llvm::Register Reg1 = getReg(); + // CHECK-FIXES: void done_1() { + // CHECK-FIXES-NEXT: llvm::Register Reg1 = getReg(); } void done_2() { using namespace llvm; Register Reg2 = getReg(); - // CHECK-FIXES: done_2() - // CHECK-FIXES-NEXT: using namespace llvm; - // CHECK-FIXES-NEXT: Register Reg2 = getReg(); + // CHECK-FIXES: void done_2() { + // CHECK-FIXES-NEXT: using namespace llvm; + // CHECK-FIXES-NEXT: Register Reg2 = getReg(); } namespace llvm { void done_3() { Register Reg3 = getReg(); - // CHECK-FIXES: done_3() - // CHECK-FIXES-NEXT: Register Reg3 = getReg(); + // CHECK-FIXES: void done_3() { + // CHECK-FIXES-NEXT: Register Reg3 = getReg(); } } // end namespace llvm void do_nothing_1() { unsigned Reg1 = getRegLike(); - // CHECK-FIXES: do_nothing_1() - // CHECK-FIXES-NEXT: unsigned Reg1 = getRegLike(); + // CHECK-FIXES: void do_nothing_1() { + // CHECK-FIXES-NEXT: unsigned Reg1 = getRegLike(); } void do_nothing_2() { using namespace llvm; unsigned Reg2 = getRegLike(); - // CHECK-FIXES: do_nothing_2() - // CHECK-FIXES-NEXT: using namespace llvm; - // CHECK-FIXES-NEXT: unsigned Reg2 = getRegLike(); + // CHECK-FIXES: void do_nothing_2() { + // CHECK-FIXES-NEXT: using namespace llvm; + // CHECK-FIXES-NEXT: unsigned Reg2 = getRegLike(); } namespace llvm { void do_nothing_3() { unsigned Reg3 = getRegLike(); - // CHECK-FIXES: do_nothing_3() - // CHECK-FIXES-NEXT: unsigned Reg3 = getRegLike(); + // CHECK-FIXES: void do_nothing_3() { + // CHECK-FIXES-NEXT: unsigned Reg3 = getRegLike(); } } // end namespace llvm void fn1(llvm::Register R); void do_nothing_4() { fn1(getReg()); - // CHECK-FIXES: do_nothing_4() - // CHECK-FIXES-NEXT: fn1(getReg()); + // CHECK-FIXES: void do_nothing_4() { + // CHECK-FIXES-NEXT: fn1(getReg()); } void fn2(unsigned R); void do_nothing_5() { fn2(getReg()); - // CHECK-FIXES: do_nothing_5() - // CHECK-FIXES-NEXT: fn2(getReg()); + // CHECK-FIXES: void do_nothing_5() { + // CHECK-FIXES-NEXT: fn2(getReg()); } void do_nothing_6() { using namespace llvm; Register Reg6{getReg()}; - // CHECK-FIXES: do_nothing_6() - // CHECK-FIXES-NEXT: using namespace llvm; - // CHECK-FIXES-NEXT: Register Reg6{getReg()}; + // CHECK-FIXES: void do_nothing_6() { + // CHECK-FIXES-NEXT: using namespace llvm; + // CHECK-FIXES-NEXT: Register Reg6{getReg()}; } void do_nothing_7() { using namespace llvm; Register Reg7; Reg7.Reg = getReg(); - // CHECK-FIXES: do_nothing_7() - // CHECK-FIXES-NEXT: using namespace llvm; - // CHECK-FIXES-NEXT: Register Reg7; - // CHECK-FIXES-NEXT: Reg7.Reg = getReg(); + // CHECK-FIXES: void do_nothing_7() { + // CHECK-FIXES-NEXT: using namespace llvm; + // CHECK-FIXES-NEXT: Register Reg7; + // CHECK-FIXES-NEXT: Reg7.Reg = getReg(); } void do_nothing_8() { using namespace llvm; RegisterLike Reg8{getReg()}; - // CHECK-FIXES: do_nothing_8() - // CHECK-FIXES-NEXT: using namespace llvm; - // CHECK-FIXES-NEXT: RegisterLike Reg8{getReg()}; + // CHECK-FIXES: void do_nothing_8() { + // CHECK-FIXES-NEXT: using namespace llvm; + // CHECK-FIXES-NEXT: RegisterLike Reg8{getReg()}; } void do_nothing_9() { using namespace llvm; RegisterLike Reg9; Reg9.Reg = getReg(); - // CHECK-FIXES: do_nothing_9() - // CHECK-FIXES-NEXT: using namespace llvm; - // CHECK-FIXES-NEXT: RegisterLike Reg9; - // CHECK-FIXES-NEXT: Reg9.Reg = getReg(); + // CHECK-FIXES: void do_nothing_9() { + // CHECK-FIXES-NEXT: using namespace llvm; + // CHECK-FIXES-NEXT: RegisterLike Reg9; + // CHECK-FIXES-NEXT: Reg9.Reg = getReg(); } diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/twine-local.cpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/twine-local.cpp index 05c9971..be64029 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/llvm/twine-local.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/llvm/twine-local.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s llvm-twine-local %t +// RUN: %check_clang_tidy %s llvm-twine-local %t namespace llvm { class Twine { @@ -24,7 +24,7 @@ int main() { const Twine t = Twine("a") + "b" + Twine(42); // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs // CHECK-MESSAGES: note: FIX-IT applied suggested code changes -// CHECK-FIXES: std::string t = (Twine("a") + "b" + Twine(42)).str(); +// CHECK-FIXES: const std::string t = (Twine("a") + "b" + Twine(42)).str(); foo(Twine("a") + "b"); Twine Prefix = false ? "__INT_FAST" : "__UINT_FAST"; @@ -35,31 +35,31 @@ int main() { const Twine t2 = Twine(); // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs // CHECK-MESSAGES: note: FIX-IT applied suggested code changes -// CHECK-FIXES: std::string t2 = (Twine()).str(); +// CHECK-FIXES: const std::string t2 = (Twine()).str(); foo(Twine() + "b"); const Twine t3 = Twine(42); // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs // CHECK-MESSAGES: note: FIX-IT applied suggested code changes -// CHECK-FIXES: std::string t3 = (Twine(42)).str(); +// CHECK-FIXES: const std::string t3 = (Twine(42)).str(); const Twine t4 = Twine(42) + "b"; // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs // CHECK-MESSAGES: note: FIX-IT applied suggested code changes -// CHECK-FIXES: std::string t4 = (Twine(42) + "b").str(); +// CHECK-FIXES: const std::string t4 = (Twine(42) + "b").str(); const Twine t5 = Twine() + "b"; // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs // CHECK-MESSAGES: note: FIX-IT applied suggested code changes -// CHECK-FIXES: std::string t5 = (Twine() + "b").str(); +// CHECK-FIXES: const std::string t5 = (Twine() + "b").str(); const Twine t6 = true ? Twine() : Twine(42); // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs // CHECK-MESSAGES: note: FIX-IT applied suggested code changes -// CHECK-FIXES: std::string t6 = (true ? Twine() : Twine(42)).str(); +// CHECK-FIXES: const std::string t6 = (true ? Twine() : Twine(42)).str(); const Twine t7 = false ? Twine() : Twine("b"); // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs // CHECK-MESSAGES: note: FIX-IT applied suggested code changes -// CHECK-FIXES: std::string t7 = (false ? Twine() : Twine("b")).str(); +// CHECK-FIXES: const std::string t7 = (false ? Twine() : Twine("b")).str(); } diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/use-new-mlir-op-builder.cpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/use-new-mlir-op-builder.cpp index 0971a16..b57eab0 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/llvm/use-new-mlir-op-builder.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/llvm/use-new-mlir-op-builder.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s llvm-use-new-mlir-op-builder %t +// RUN: %check_clang_tidy %s llvm-use-new-mlir-op-builder %t namespace mlir { class Location {}; @@ -36,25 +36,24 @@ struct NamedOp { template <typename T> void g(mlir::OpBuilder &b) { // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use 'OpType::create(builder, ...)' instead of 'builder.create<OpType>(...)' [llvm-use-new-mlir-op-builder] - // CHECK-FIXES: T::create(b, b.getUnknownLoc(), "gaz") + // CHECK-FIXES: T::create(b, b.getUnknownLoc(), "gaz"); b.create<T>(b.getUnknownLoc(), "gaz"); } void f() { mlir::OpBuilder builder; // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use 'OpType::create(builder, ...)' instead of 'builder.create<OpType>(...)' [llvm-use-new-mlir-op-builder] - // CHECK-FIXES: mlir:: ModuleOp::create(builder, builder.getUnknownLoc()) + // CHECK-FIXES: mlir:: ModuleOp::create(builder, builder.getUnknownLoc()); builder.create<mlir:: ModuleOp>(builder.getUnknownLoc()); using mlir::NamedOp; // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use 'OpType::create(builder, ...)' instead of 'builder.create<OpType>(...)' [llvm-use-new-mlir-op-builder] - // CHECK-FIXES: NamedOp::create(builder, builder.getUnknownLoc(), "baz") + // CHECK-FIXES: NamedOp::create(builder, builder.getUnknownLoc(), "baz"); builder.create<NamedOp>(builder.getUnknownLoc(), "baz"); - // CHECK-MESSAGES: :[[@LINE+4]]:3: warning: use 'OpType::create(builder, ...)' instead of 'builder.create<OpType>(...)' [llvm-use-new-mlir-op-builder] - // CHECK-FIXES: NamedOp::create(builder, - // CHECK-FIXES: builder.getUnknownLoc(), - // CHECK-FIXES: "caz") + // CHECK-MESSAGES: :[[@LINE+3]]:3: warning: use 'OpType::create(builder, ...)' instead of 'builder.create<OpType>(...)' [llvm-use-new-mlir-op-builder] + // CHECK-FIXES: NamedOp::create(builder, builder.getUnknownLoc(), + // CHECK-FIXES: "caz"); builder. create<NamedOp>( builder.getUnknownLoc(), @@ -67,7 +66,7 @@ void f() { mlir::ImplicitLocOpBuilder ib; // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use 'OpType::create(builder, ...)' instead of 'builder.create<OpType>(...)' [llvm-use-new-mlir-op-builder] - // CHECK-FIXES: mlir::ModuleOp::create(ib) + // CHECK-FIXES: mlir::ModuleOp::create(ib); ib.create<mlir::ModuleOp>( ); // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use 'OpType::create(builder, ...)' instead of 'builder.create<OpType>(...)' [llvm-use-new-mlir-op-builder] diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp index a44a712..e20680c 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s misc-const-correctness %t \ +// RUN: %check_clang_tidy %s misc-const-correctness %t \ // RUN: -config='{CheckOptions: {\ // RUN: misc-const-correctness.AnalyzeValues: false,\ // RUN: misc-const-correctness.AnalyzeReferences: false,\ @@ -14,7 +14,7 @@ void pointee_to_const() { int a[] = {1, 2}; int *p_local0 = &a[0]; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: pointee of variable 'p_local0' of type 'int *' can be declared 'const' - // CHECK-FIXES: int const*p_local0 + // CHECK-FIXES: int const*p_local0 = &a[0]; p_local0 = &a[1]; } @@ -22,7 +22,7 @@ void array_of_pointer_to_const() { int a[] = {1, 2}; int *p_local0[1] = {&a[0]}; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: pointee of variable 'p_local0' of type 'int *[1]' can be declared 'const' - // CHECK-FIXES: int const*p_local0[1] + // CHECK-FIXES: int const*p_local0[1] = {&a[0]}; p_local0[0] = &a[1]; } @@ -31,7 +31,7 @@ void template_fn() { T a[] = {1, 2}; T *p_local0 = &a[0]; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: pointee of variable 'p_local0' of type 'char *' can be declared 'const' - // CHECK-FIXES: T const*p_local0 + // CHECK-FIXES: T const*p_local0 = &a[0]; p_local0 = &a[1]; } diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp index 74be3dc..02d32c0 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s misc-const-correctness %t \ +// RUN: %check_clang_tidy %s misc-const-correctness %t \ // RUN: -config='{CheckOptions: \ // RUN: {misc-const-correctness.AnalyzeValues: true,\ // RUN: misc-const-correctness.WarnPointersAsValues: true,\ @@ -10,32 +10,31 @@ void potential_const_pointer() { double np_local0[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.}; double *p_local0 = &np_local0[1]; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double *' can be declared 'const' - // CHECK-FIXES: double *const p_local0 + // CHECK-FIXES: double *const p_local0 = &np_local0[1]; using doublePtr = double*; using doubleArray = double[15]; doubleArray np_local1; doublePtr p_local1 = &np_local1[0]; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'doublePtr' (aka 'double *') can be declared 'const' - // CHECK-FIXES: doublePtr const p_local1 + // CHECK-FIXES: doublePtr const p_local1 = &np_local1[0]; } void range_for() { int np_local0[2] = {1, 2}; int *p_local0[2] = {&np_local0[0], &np_local0[1]}; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int *[2]' can be declared 'const' - // CHECK-FIXES: int *const p_local0[2] + // CHECK-FIXES: int *const p_local0[2] = {&np_local0[0], &np_local0[1]}; for (const int *p_local1 : p_local0) { // CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'p_local1' of type 'const int *' can be declared 'const' - // CHECK-FIXES: for (const int *const p_local1 : p_local0) + // CHECK-FIXES: for (const int *const p_local1 : p_local0) { } int *p_local2[2] = {nullptr, nullptr}; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'int *[2]' can be declared 'const' - // CHECK-FIXES: int *const p_local2[2] + // CHECK-FIXES: int *const p_local2[2] = {nullptr, nullptr}; for (const auto *con_ptr : p_local2) { } - } template <typename T> @@ -59,7 +58,7 @@ void EmitProtocolMethodList(T &&Methods) { // some expressions are type-dependent. SmallVector<const int *> p_local0; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'SmallVector<const int *>' can be declared 'const' - // CHECK-FIXES: SmallVector<const int *> const p_local0 + // CHECK-FIXES: SmallVector<const int *> const p_local0; SmallVector<const int *> np_local0; for (const auto *I : Methods) { if (I == nullptr) @@ -70,6 +69,6 @@ void EmitProtocolMethodList(T &&Methods) { void instantiate() { int *p_local0[4] = {nullptr, nullptr, nullptr, nullptr}; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int *[4]' can be declared 'const' - // CHECK-FIXES: int *const p_local0[4] + // CHECK-FIXES: int *const p_local0[4] = {nullptr, nullptr, nullptr, nullptr}; EmitProtocolMethodList(p_local0); } diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp index 17dcf12..4cef7f4 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s misc-const-correctness %t -- \ +// RUN: %check_clang_tidy %s misc-const-correctness %t -- \ // RUN: -config="{CheckOptions: {\ // RUN: misc-const-correctness.TransformValues: true, \ // RUN: misc-const-correctness.WarnPointersAsValues: false, \ @@ -38,7 +38,7 @@ void some_function(double, wchar_t); void some_function(double np_arg0, wchar_t np_arg1) { int p_local0 = 2; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local0 + // CHECK-FIXES: int const p_local0 = 2; int np_local0; const int np_local1 = 42; @@ -60,7 +60,7 @@ void some_function(double np_arg0, wchar_t np_arg1) { int function_try_block() try { int p_local0 = 0; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local0 + // CHECK-FIXES: int const p_local0 = 0; return p_local0; } catch (...) { return 0; @@ -69,13 +69,13 @@ int function_try_block() try { void nested_scopes() { int p_local0 = 2; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local0 + // CHECK-FIXES: int const p_local0 = 2; int np_local0 = 42; { int p_local1 = 42; // CHECK-MESSAGES: [[@LINE-1]]:5: warning: variable 'p_local1' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local1 + // CHECK-FIXES: int const p_local1 = 42; np_local0 *= 2; } } @@ -89,7 +89,7 @@ void some_lambda_environment_capture_all_by_reference(double np_arg0) { int np_local0 = 0; int p_local0 = 1; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local0 + // CHECK-FIXES: int const p_local0 = 1; int np_local2; const int np_local3 = 2; @@ -99,14 +99,14 @@ void some_lambda_environment_capture_all_by_reference(double np_arg0) { int p_local1 = 0; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local1 + // CHECK-FIXES: int const p_local1 = 0; } void some_lambda_environment_capture_all_by_value(double np_arg0) { int np_local0 = 0; int p_local0 = 1; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local0 + // CHECK-FIXES: int const p_local0 = 1; int np_local1; const int np_local2 = 2; @@ -139,12 +139,12 @@ void some_pointer_taking(int *out) { int p_local1 = 42; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local1 + // CHECK-FIXES: int const p_local1 = 42; const int *const p0_p_local1 = &p_local1; int p_local2 = 42; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local2 + // CHECK-FIXES: int const p_local2 = 42; function_in_pointer(&p_local2); } @@ -163,19 +163,19 @@ void some_reference_taking() { int p_local0 = 42; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local0 + // CHECK-FIXES: int const p_local0 = 42; const int &r0_p_local0 = p_local0; int p_local1 = 42; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local1 + // CHECK-FIXES: int const p_local1 = 42; function_in_ref(p_local1); } double *non_const_pointer_return() { double p_local0 = 0.0; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double' can be declared 'const' - // CHECK-FIXES: double const p_local0 + // CHECK-FIXES: double const p_local0 = 0.0; double np_local0 = 24.4; return &np_local0; @@ -184,10 +184,10 @@ double *non_const_pointer_return() { const double *const_pointer_return() { double p_local0 = 0.0; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double' can be declared 'const' - // CHECK-FIXES: double const p_local0 + // CHECK-FIXES: double const p_local0 = 0.0; double p_local1 = 24.4; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'double' can be declared 'const' - // CHECK-FIXES: double const p_local1 + // CHECK-FIXES: double const p_local1 = 24.4; return &p_local1; } @@ -195,10 +195,10 @@ const double *const_pointer_return() { const double &const_ref_return() { double p_local0 = 0.0; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double' can be declared 'const' - // CHECK-FIXES: double const p_local0 + // CHECK-FIXES: double const p_local0 = 0.0; double p_local1 = 24.4; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'double' can be declared 'const' - // CHECK-FIXES: double const p_local1 + // CHECK-FIXES: double const p_local1 = 24.4; return p_local1; } @@ -237,7 +237,7 @@ void define_locals(T np_arg0, T &np_arg1, int np_arg2) { // non-template values are ok still. int p_local0 = 42; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local0 + // CHECK-FIXES: int const p_local0 = 42; np_local4 += p_local0; } @@ -306,19 +306,19 @@ void direct_class_access() { ConstNonConstClass p_local0; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'ConstNonConstClass' can be declared 'const' - // CHECK-FIXES: ConstNonConstClass const p_local0 + // CHECK-FIXES: ConstNonConstClass const p_local0; p_local0.constMethod(); ConstNonConstClass p_local1; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'ConstNonConstClass' can be declared 'const' - // CHECK-FIXES: ConstNonConstClass const p_local1 + // CHECK-FIXES: ConstNonConstClass const p_local1; double np_local1; p_local1.modifyingMethod(np_local1); double np_local2; ConstNonConstClass p_local2(np_local2); // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'ConstNonConstClass' can be declared 'const' - // CHECK-FIXES: ConstNonConstClass const p_local2(np_local2) + // CHECK-FIXES: ConstNonConstClass const p_local2(np_local2); ConstNonConstClass np_local3; np_local3.NonConstMember = 42.; @@ -328,14 +328,14 @@ void direct_class_access() { ConstNonConstClass p_local3; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local3' of type 'ConstNonConstClass' can be declared 'const' - // CHECK-FIXES: ConstNonConstClass const p_local3 + // CHECK-FIXES: ConstNonConstClass const p_local3; const double val0 = p_local3.NonConstMember; const double val1 = p_local3.NonConstMemberRef; const double val2 = *p_local3.NonConstMemberPtr; ConstNonConstClass p_local4; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local4' of type 'ConstNonConstClass' can be declared 'const' - // CHECK-FIXES: ConstNonConstClass const p_local4 + // CHECK-FIXES: ConstNonConstClass const p_local4; *np_local4.NonConstMemberPtr = 42.; } @@ -347,7 +347,7 @@ void class_access_array() { ConstNonConstClass p_local0[2]; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'ConstNonConstClass[2]' can be declared 'const' - // CHECK-FIXES: ConstNonConstClass const p_local0[2] + // CHECK-FIXES: ConstNonConstClass const p_local0[2]; p_local0[0].constMethod(); np_local0[1].constMethod(); } @@ -367,10 +367,10 @@ void internal_operator_calls() { OperatorsAsConstAsPossible np_local1; OperatorsAsConstAsPossible p_local0; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'OperatorsAsConstAsPossible' can be declared 'const' - // CHECK-FIXES: OperatorsAsConstAsPossible const p_local0 + // CHECK-FIXES: OperatorsAsConstAsPossible const p_local0; OperatorsAsConstAsPossible p_local1; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'OperatorsAsConstAsPossible' can be declared 'const' - // CHECK-FIXES: OperatorsAsConstAsPossible const p_local1 + // CHECK-FIXES: OperatorsAsConstAsPossible const p_local1; np_local0 += p_local0; np_local1 = p_local0 + p_local1; @@ -383,10 +383,10 @@ void internal_operator_calls() { NonConstOperators p_local2; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'NonConstOperators' can be declared 'const' - // CHECK-FIXES: NonConstOperators const p_local2 + // CHECK-FIXES: NonConstOperators const p_local2; NonConstOperators p_local3 = p_local2 - p_local2; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local3' of type 'NonConstOperators' can be declared 'const' - // CHECK-FIXES: NonConstOperators const p_local3 + // CHECK-FIXES: NonConstOperators const p_local3 = p_local2 - p_local2; } struct MyVector { @@ -411,17 +411,17 @@ void vector_usage() { double p_local0[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.}; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double[10]' can be declared 'const' - // CHECK-FIXES: double const p_local0[10] + // CHECK-FIXES: double const p_local0[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.}; double p_local1 = p_local0[5]; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'double' can be declared 'const' - // CHECK-FIXES: double const p_local1 + // CHECK-FIXES: double const p_local1 = p_local0[5]; - // The following subscript calls suprisingly choose the non-const operator + // The following subscript calls surprisingly choose the non-const operator // version. MyVector np_local2; double p_local2 = np_local2[42]; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'double' can be declared 'const' - // CHECK-FIXES: double const p_local2 + // CHECK-FIXES: double const p_local2 = np_local2[42]; MyVector np_local3; const double np_local4 = np_local3[42]; @@ -430,7 +430,7 @@ void vector_usage() { const MyVector np_local5{}; double p_local3 = np_local5[42]; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local3' of type 'double' can be declared 'const' - // CHECK-FIXES: double const p_local3 + // CHECK-FIXES: double const p_local3 = np_local5[42]; } void const_handle(const double &np_local0); @@ -460,27 +460,27 @@ void handle_from_array() { // Constant handles are ok double p_local1[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.}; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'double[10]' can be declared 'const' - // CHECK-FIXES: double const p_local1[10] + // CHECK-FIXES: double const p_local1[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.}; const double *p_local2 = &p_local1[2]; // Could be `const double *const`, but warning deactivated by default double p_local3[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.}; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local3' of type 'double[10]' can be declared 'const' - // CHECK-FIXES: double const p_local3[10] + // CHECK-FIXES: double const p_local3[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.}; const double &const_ref = p_local3[2]; double p_local4[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.}; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local4' of type 'double[10]' can be declared 'const' - // CHECK-FIXES: double const p_local4[10] + // CHECK-FIXES: double const p_local4[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.}; const double *const_ptr; const_ptr = &p_local4[2]; double p_local5[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.}; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local5' of type 'double[10]' can be declared 'const' - // CHECK-FIXES: double const p_local5[10] + // CHECK-FIXES: double const p_local5[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.}; const_handle(p_local5[2]); double p_local6[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.}; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local6' of type 'double[10]' can be declared 'const' - // CHECK-FIXES: double const p_local6[10] + // CHECK-FIXES: double const p_local6[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.}; const_handle(&p_local6[2]); } @@ -513,15 +513,15 @@ void range_for() { int p_local0[2] = {1, 2}; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int[2]' can be declared 'const' - // CHECK-FIXES: int const p_local0[2] + // CHECK-FIXES: int const p_local0[2] = {1, 2}; for (int value : p_local0) { // CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'value' of type 'int' can be declared 'const' - // CHECK-FIXES: int const value + // CHECK-FIXES: for (int const value : p_local0) { } int p_local1[2] = {1, 2}; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int[2]' can be declared 'const' - // CHECK-FIXES: int const p_local1[2] + // CHECK-FIXES: int const p_local1[2] = {1, 2}; for (const int &const_ref : p_local1) { } } @@ -552,7 +552,7 @@ void conversion_operators() { ModifyingConversion np_local0; NonModifyingConversion p_local0; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'NonModifyingConversion' can be declared 'const' - // CHECK-FIXES: NonModifyingConversion const p_local0 + // CHECK-FIXES: NonModifyingConversion const p_local0; int np_local1 = np_local0; np_local1 = p_local0; @@ -561,16 +561,16 @@ void conversion_operators() { void casts() { decltype(sizeof(void *)) p_local0 = 42; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'decltype(sizeof(void *))' - // CHECK-FIXES: decltype(sizeof(void *)) const p_local0 + // CHECK-FIXES: decltype(sizeof(void *)) const p_local0 = 42; auto np_local0 = reinterpret_cast<void *>(p_local0); np_local0 = nullptr; int p_local1 = 43; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local1 + // CHECK-FIXES: int const p_local1 = 43; short p_local2 = static_cast<short>(p_local1); // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'short' can be declared 'const' - // CHECK-FIXES: short const p_local2 + // CHECK-FIXES: short const p_local2 = static_cast<short>(p_local1); int np_local1 = p_local2; int &np_local2 = static_cast<int &>(np_local1); @@ -584,7 +584,7 @@ void ternary_operator() { int p_local0 = 3, np_local3 = 5; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const' - // CHECK-NOT-FIXES: int const p_local0 = 3 + // CHECK-NOT-FIXES: int const p_local0 = 3, np_local3 = 5; const int &np_local4 = true ? p_local0 : ++np_local3; int np_local5[3] = {1, 2, 3}; @@ -636,13 +636,13 @@ struct TMPClass { void meta_type() { TMPClass<int> p_local0; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'TMPClass<int>' can be declared 'const' - // CHECK-FIXES: TMPClass<int> const p_local0 + // CHECK-FIXES: TMPClass<int> const p_local0; p_local0.alwaysConst(); p_local0.sometimesConst(); TMPClass<double> p_local1; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'TMPClass<double>' can be declared 'const' - // CHECK-FIXES: TMPClass<double> const p_local1 + // CHECK-FIXES: TMPClass<double> const p_local1; p_local1.alwaysConst(); TMPClass<double> np_local0; @@ -659,7 +659,7 @@ template <typename T> void placement_new_in_unique_ptr() { int p_local0 = 42; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local0 + // CHECK-FIXES: int const p_local0 = 42; int np_local0 = p_local0; new to_construct<T>(np_local0); } @@ -696,7 +696,7 @@ void TestRegisters() { HardwareRegister p_reg1{3, 22}; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_reg1' of type 'HardwareRegister' can be declared 'const' - // CHECK-FIXES: HardwareRegister const p_reg1 + // CHECK-FIXES: HardwareRegister const p_reg1{3, 22}; const unsigned p_val = p_reg1.another; } @@ -745,7 +745,7 @@ struct A { void f() { int p_local0 = 42; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local0 + // CHECK-FIXES: int const p_local0 = 42; int np_local0 = 42; f_signature action = my_alloc; action(np_local0); @@ -795,7 +795,7 @@ void for_bad_iterators() { non_const_iterator np_local3; for (int p_local0 : np_local3) // CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'p_local0' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local0 + // CHECK-FIXES: for (int const p_local0 : np_local3) ; // Horrible code constructs... @@ -805,21 +805,21 @@ void for_bad_iterators() { non_const_iterator np_local5; for (int p_local1 : np_local4, np_local5) // CHECK-MESSAGES: [[@LINE-1]]:10: warning: variable 'p_local1' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local1 + // CHECK-FIXES: for (int const p_local1 : np_local4, np_local5) ; non_const_iterator np_local6; non_const_iterator np_local7; for (int p_local2 : 1 > 2 ? np_local6 : np_local7) // CHECK-MESSAGES: [[@LINE-1]]:10: warning: variable 'p_local2' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local2 + // CHECK-FIXES: for (int const p_local2 : 1 > 2 ? np_local6 : np_local7) ; non_const_iterator np_local8; non_const_iterator np_local9; for (int p_local3 : 2 > 1 ? np_local8 : (np_local8, np_local9)) // CHECK-MESSAGES: [[@LINE-1]]:10: warning: variable 'p_local3' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local3 + // CHECK-FIXES: for (int const p_local3 : 2 > 1 ? np_local8 : (np_local8, np_local9)) ; } } @@ -836,23 +836,23 @@ struct good_iterator { void good_iterators() { good_iterator p_local0; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'good_iterator' can be declared 'const' - // CHECK-FIXES: good_iterator const p_local0 + // CHECK-FIXES: good_iterator const p_local0; good_iterator &p_local1 = p_local0; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'good_iterator &' can be declared 'const' - // CHECK-FIXES: good_iterator const&p_local1 + // CHECK-FIXES: good_iterator const&p_local1 = p_local0; for (int p_local2 : p_local1) { // CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'p_local2' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local2 + // CHECK-FIXES: for (int const p_local2 : p_local1) { (void)p_local2; } good_iterator p_local3; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local3' of type 'good_iterator' can be declared 'const' - // CHECK-FIXES: good_iterator const p_local3 + // CHECK-FIXES: good_iterator const p_local3; for (int p_local4 : p_local3) // CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'p_local4' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local4 + // CHECK-FIXES: for (int const p_local4 : p_local3) ; good_iterator np_local1; for (int &np_local2 : np_local1) @@ -871,11 +871,11 @@ void for_ok_iterators_array() { int np_local0[42]; int(&p_local0)[42] = np_local0; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int (&)[42]' can be declared 'const' - // CHECK-FIXES: int const(&p_local0)[42] + // CHECK-FIXES: int const(&p_local0)[42] = np_local0; for (int p_local1 : p_local0) { // CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'p_local1' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local1 + // CHECK-FIXES: for (int const p_local1 : p_local0) { (void)p_local1; } } @@ -891,7 +891,7 @@ void complex_usage() { int np_local0 = 42; int p_local0 = 42; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const' - // CHECK-FIXES: int const p_local0 + // CHECK-FIXES: int const p_local0 = 42; int np_local1 = 42; (np_local0 == p_local0 ? np_local0 : (p_local0, np_local1))++; } @@ -920,7 +920,7 @@ void create_false_positive() { int np_local0 = 42; list_init p_local0 = {np_local0}; // CHECK-MESSAGES:[[@LINE-1]]:3: warning: variable 'p_local0' of type 'list_init' can be declared 'const' - // CHECK-FIXES: list_init const p_local0 + // CHECK-FIXES: list_init const p_local0 = {np_local0}; } struct list_init_derived { base &member; @@ -929,7 +929,7 @@ void list_init_derived_func() { derived np_local0; list_init_derived p_local0 = {np_local0}; // CHECK-MESSAGES:[[@LINE-1]]:3: warning: variable 'p_local0' of type 'list_init_derived' can be declared 'const' - // CHECK-FIXES: list_init_derived const p_local0 + // CHECK-FIXES: list_init_derived const p_local0 = {np_local0}; } template <typename L, typename R> struct ref_pair { @@ -945,7 +945,7 @@ void cast_in_class_hierarchy() { derived np_local0; base p_local1 = static_cast<base &>(np_local0); // CHECK-MESSAGES:[[@LINE-1]]:3: warning: variable 'p_local1' of type 'base' can be declared 'const' - // CHECK-FIXES: base const p_local1 + // CHECK-FIXES: base const p_local1 = static_cast<base &>(np_local0); } void function_ref_target(int); diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/definitions-in-headers.hpp b/clang-tools-extra/test/clang-tidy/checkers/misc/definitions-in-headers.hpp index c48a2ee..853ec77 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/definitions-in-headers.hpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/definitions-in-headers.hpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s misc-definitions-in-headers %t -- --fix-notes +// RUN: %check_clang_tidy %s misc-definitions-in-headers %t -- --fix-notes int f() { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f' defined in a header file; function definitions in header files can lead to ODR violations [misc-definitions-in-headers] @@ -25,7 +25,7 @@ class CA { void CA::f2() { } // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: function 'f2' defined in a header file; -// CHECK-FIXES: inline void CA::f2() { +// CHECK-FIXES: inline void CA::f2() { } template <> int CA::f3() { diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/unused-parameters.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/unused-parameters.cpp index 4baf839..f473f26 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/unused-parameters.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/unused-parameters.cpp @@ -1,7 +1,7 @@ // RUN: mkdir -p %t.dir // RUN: echo "static void staticFunctionHeader(int i) {;}" > %t.dir/header.h // RUN: echo "static void staticFunctionHeader(int /*i*/) {;}" > %t.dir/header-fixed.h -// RUN: %check_clang_tidy --match-partial-fixes -std=c++11 %s misc-unused-parameters %t.dir/code -- -header-filter='.*' -- -fno-delayed-template-parsing +// RUN: %check_clang_tidy -std=c++11 %s misc-unused-parameters %t.dir/code -- -header-filter='.*' -- -fno-delayed-template-parsing // RUN: diff %t.dir/header.h %t.dir/header-fixed.h // FIXME: Make the test work in all language modes. @@ -67,41 +67,41 @@ static void staticFunctionA(int i); // CHECK-FIXES: static void staticFunctionA(); static void staticFunctionA(int i) {;} // CHECK-MESSAGES: :[[@LINE-1]]:33: warning -// CHECK-FIXES: static void staticFunctionA() +// CHECK-FIXES: static void staticFunctionA() {;} static void staticFunctionB(int i, int j) { (void)i; } // CHECK-MESSAGES: :[[@LINE-1]]:40: warning -// CHECK-FIXES: static void staticFunctionB(int i) +// CHECK-FIXES: static void staticFunctionB(int i) { (void)i; } static void staticFunctionC(int i, int j) { (void)j; } // CHECK-MESSAGES: :[[@LINE-1]]:33: warning -// CHECK-FIXES: static void staticFunctionC(int j) +// CHECK-FIXES: static void staticFunctionC(int j) { (void)j; } static void staticFunctionD(int i, int j, int k) { (void)i; (void)k; } // CHECK-MESSAGES: :[[@LINE-1]]:40: warning -// CHECK-FIXES: static void staticFunctionD(int i, int k) +// CHECK-FIXES: static void staticFunctionD(int i, int k) { (void)i; (void)k; } static void staticFunctionE(int i = 4) {;} // CHECK-MESSAGES: :[[@LINE-1]]:33: warning -// CHECK-FIXES: static void staticFunctionE() +// CHECK-FIXES: static void staticFunctionE() {;} static void staticFunctionF(int i = 4); // CHECK-FIXES: static void staticFunctionF(); static void staticFunctionF(int i) {;} // CHECK-MESSAGES: :[[@LINE-1]]:33: warning -// CHECK-FIXES: static void staticFunctionF() +// CHECK-FIXES: static void staticFunctionF() {;} static void staticFunctionG(int i[]); // CHECK-FIXES: static void staticFunctionG(); static void staticFunctionG(int i[]) {;} // CHECK-MESSAGES: :[[@LINE-1]]:33: warning -// CHECK-FIXES: static void staticFunctionG() +// CHECK-FIXES: static void staticFunctionG() {;} static void staticFunctionH(void (*fn)()); // CHECK-FIXES: static void staticFunctionH(); static void staticFunctionH(void (*fn)()) {;} // CHECK-MESSAGES: :[[@LINE-1]]:36: warning -// CHECK-FIXES: static void staticFunctionH() +// CHECK-FIXES: static void staticFunctionH() {;} static void someCallSites() { staticFunctionA(1); @@ -298,7 +298,7 @@ using fn = void(int); void f(fn *); void test() { // CHECK-MESSAGES: :[[@LINE+2]]:12: warning: parameter 'I' is unused - // CHECK-FIXES: f([](int /*I*/) { + // CHECK-FIXES: f([](int /*I*/) { return; }); f([](int I) { return; }); } } // namespace lambda diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-bind.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-bind.cpp index 342c96a..6aa7d48 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-bind.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-bind.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes -std=c++14-or-later %s modernize-avoid-bind %t +// RUN: %check_clang_tidy -std=c++14-or-later %s modernize-avoid-bind %t namespace std { inline namespace impl { @@ -229,19 +229,19 @@ void testFunctionObjects() { D *e = nullptr; auto AAA = std::bind(d, 1, 2); // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind - // CHECK-FIXES: auto AAA = [d] { d(1, 2); } + // CHECK-FIXES: auto AAA = [d] { d(1, 2); }; auto BBB = std::bind(*e, 1, 2); // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind - // CHECK-FIXES: auto BBB = [e] { (*e)(1, 2); } + // CHECK-FIXES: auto BBB = [e] { (*e)(1, 2); }; auto CCC = std::bind(D{}, 1, 2); // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind - // CHECK-FIXES: auto CCC = [] { D{}(1, 2); } + // CHECK-FIXES: auto CCC = [] { D{}(1, 2); }; auto DDD = std::bind(D(), 1, 2); // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind - // CHECK-FIXES: auto DDD = [] { D()(1, 2); } + // CHECK-FIXES: auto DDD = [] { D()(1, 2); }; auto EEE = std::bind(*D::create(), 1, 2); // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind @@ -384,11 +384,11 @@ struct E { auto III = std::bind(&D::operator(), d, 1, 2); // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind - // CHECK-FIXES: auto III = [d] { (*d)(1, 2); } + // CHECK-FIXES: auto III = [d] { (*d)(1, 2); }; auto JJJ = std::bind(&D::operator(), &dd, 1, 2); // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind - // CHECK-FIXES: auto JJJ = [ObjectPtr = &dd] { (*ObjectPtr)(1, 2); } + // CHECK-FIXES: auto JJJ = [ObjectPtr = &dd] { (*ObjectPtr)(1, 2); }; auto KKK = std::bind(&D::operator(), _1, 1, 2); // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind @@ -396,11 +396,11 @@ struct E { auto LLL = std::bind(&D::operator bool, d); // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind - // CHECK-FIXES: auto LLL = [d] { return d->operator bool(); } + // CHECK-FIXES: auto LLL = [d] { return d->operator bool(); }; auto MMM = std::bind(&E::operator(), this, 1, 2); // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind - // CHECK-FIXES: auto MMM = [this] { return (*this)(1, 2); } + // CHECK-FIXES: auto MMM = [this] { return (*this)(1, 2); }; } }; diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp index 78adbeb..35cb550 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/concat-nested-namespaces.cpp @@ -1,10 +1,10 @@ // RUN: mkdir -p %t.dir // RUN: cp %S/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h %t.dir/modernize-concat-nested-namespaces.h -// RUN: %check_clang_tidy --match-partial-fixes -std=c++17 -check-suffix=NORMAL %s modernize-concat-nested-namespaces %t.dir/code -- -header-filter=".*" -- -I %t.dir +// RUN: %check_clang_tidy -std=c++17 -check-suffix=NORMAL %s modernize-concat-nested-namespaces %t.dir/code -- -header-filter=".*" -- -I %t.dir // RUN: FileCheck -input-file=%t.dir/modernize-concat-nested-namespaces.h %S/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h -check-prefix=CHECK-FIXES // Restore header file and re-run with c++20: // RUN: cp %S/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h %t.dir/modernize-concat-nested-namespaces.h -// RUN: %check_clang_tidy --match-partial-fixes -std=c++20 -check-suffixes=NORMAL,CPP20 %s modernize-concat-nested-namespaces %t.dir/code -- -header-filter=".*" -- -I %t.dir +// RUN: %check_clang_tidy -std=c++20 -check-suffixes=NORMAL,CPP20 %s modernize-concat-nested-namespaces %t.dir/code -- -header-filter=".*" -- -I %t.dir // RUN: FileCheck -input-file=%t.dir/modernize-concat-nested-namespaces.h %S/Inputs/concat-nested-namespaces/modernize-concat-nested-namespaces.h -check-prefix=CHECK-FIXES #include "modernize-concat-nested-namespaces.h" @@ -38,16 +38,16 @@ void t(); namespace n9 { namespace n10 { // CHECK-MESSAGES-NORMAL-DAG: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] -// CHECK-FIXES-NORMAL: namespace n9::n10 +// CHECK-FIXES-NORMAL: namespace n9::n10 { void t(); } // namespace n10 } // namespace n9 -// CHECK-FIXES-NORMAL: } +// CHECK-FIXES-NORMAL: } // namespace n9::n10 namespace n11 { namespace n12 { // CHECK-MESSAGES-NORMAL-DAG: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] -// CHECK-FIXES-NORMAL: namespace n11::n12 +// CHECK-FIXES-NORMAL: namespace n11::n12 { namespace n13 { void t(); } @@ -71,7 +71,7 @@ namespace n18 { namespace n19 { namespace n20 { // CHECK-MESSAGES-NORMAL-DAG: :[[@LINE-3]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] -// CHECK-FIXES-NORMAL: namespace n18::n19::n20 +// CHECK-FIXES-NORMAL: namespace n18::n19::n20 { void t(); } // namespace n20 } // namespace n19 @@ -94,11 +94,11 @@ namespace { namespace n24 { namespace n25 { // CHECK-MESSAGES-NORMAL-DAG: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] -// CHECK-FIXES-NORMAL: namespace n24::n25 +// CHECK-FIXES-NORMAL: namespace n24::n25 { void t(); } // namespace n25 } // namespace n24 -// CHECK-FIXES-NORMAL: } +// CHECK-FIXES-NORMAL: } // namespace n24::n25 } // namespace } // namespace n23 @@ -136,7 +136,7 @@ void t(); namespace n39 { namespace n40 { // CHECK-MESSAGES-NORMAL-DAG: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] -// CHECK-FIXES-NORMAL: namespace n39::n40 +// CHECK-FIXES-NORMAL: namespace n39::n40 { #ifdef IEXIST void t() {} #endif @@ -147,7 +147,7 @@ void t() {} namespace n41 { namespace n42 { // CHECK-MESSAGES-NORMAL-DAG: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces] -// CHECK-FIXES-NORMAL: namespace n41::n42 +// CHECK-FIXES-NORMAL: namespace n41::n42 { #ifdef IDONTEXIST void t() {} #endif diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp index 419e7f8..2f744eb 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-basic.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s modernize-loop-convert %t -- -- -I %S/Inputs/loop-convert +// RUN: %check_clang_tidy %s modernize-loop-convert %t -- -- -I %S/Inputs/loop-convert #include "structures.h" @@ -18,7 +18,7 @@ void f() { int K; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead [modernize-loop-convert] - // CHECK-FIXES: for (int I : Arr) + // CHECK-FIXES: for (int I : Arr) { // CHECK-FIXES-NEXT: Sum += I; // CHECK-FIXES-NEXT: int K; @@ -27,7 +27,7 @@ void f() { Sum += Arr[I] + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : Arr) + // CHECK-FIXES: for (int I : Arr) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); // CHECK-FIXES-NEXT: Sum += I + 2; @@ -36,7 +36,7 @@ void f() { int Y = Arr[I] + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : Arr) + // CHECK-FIXES: for (int I : Arr) { // CHECK-FIXES-NEXT: int X = I; // CHECK-FIXES-NEXT: int Y = I + 2; @@ -45,7 +45,7 @@ void f() { X = Arr[I]; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : Arr) + // CHECK-FIXES: for (int I : Arr) { // CHECK-FIXES-NEXT: int X = N; // CHECK-FIXES-NEXT: X = I; @@ -53,7 +53,7 @@ void f() { Arr[I] += 1; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & I : Arr) + // CHECK-FIXES: for (int & I : Arr) { // CHECK-FIXES-NEXT: I += 1; for (int I = 0; I < N; ++I) { @@ -61,7 +61,7 @@ void f() { Arr[I]++; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & I : Arr) + // CHECK-FIXES: for (int & I : Arr) { // CHECK-FIXES-NEXT: int X = I + 2; // CHECK-FIXES-NEXT: I++; @@ -69,14 +69,14 @@ void f() { Arr[I] = 4 + Arr[I]; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & I : Arr) + // CHECK-FIXES: for (int & I : Arr) { // CHECK-FIXES-NEXT: I = 4 + I; for (int I = 0; I < NMinusOne + 1; ++I) { Sum += Arr[I]; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : Arr) + // CHECK-FIXES: for (int I : Arr) { // CHECK-FIXES-NEXT: Sum += I; for (int I = 0; I < N; ++I) { @@ -84,7 +84,7 @@ void f() { Sum += Arr[I] + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & I : Arr) + // CHECK-FIXES: for (int & I : Arr) { // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I); // CHECK-FIXES-NEXT: Sum += I + 2; @@ -96,7 +96,7 @@ void f() { size += sizeof((Matrix[I])); } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & I : Matrix) + // CHECK-FIXES: for (auto & I : Matrix) { // CHECK-FIXES-NEXT: size += sizeof(I); // CHECK-FIXES-NEXT: size += sizeof I; // CHECK-FIXES-NEXT: size += sizeof(I); @@ -106,7 +106,7 @@ void f() { Teas[I].g(); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & Tea : Teas) + // CHECK-FIXES: for (auto & Tea : Teas) { // CHECK-FIXES-NEXT: Tea.g(); for (int I = 0; N > I; ++I) { @@ -114,7 +114,7 @@ void f() { Sum += Arr[I] + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & I : Arr) + // CHECK-FIXES: for (int & I : Arr) { // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I); // CHECK-FIXES-NEXT: Sum += I + 2; @@ -123,7 +123,7 @@ void f() { Sum += Arr[I] + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & I : Arr) + // CHECK-FIXES: for (int & I : Arr) { // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I); // CHECK-FIXES-NEXT: Sum += I + 2; @@ -132,7 +132,7 @@ void f() { Sum += Arr[I] + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & I : Arr) + // CHECK-FIXES: for (int & I : Arr) { // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I); // CHECK-FIXES-NEXT: Sum += I + 2; } @@ -142,7 +142,7 @@ const int *constArray() { printf("2 * %d = %d\n", ConstArr[I], ConstArr[I] + ConstArr[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : ConstArr) + // CHECK-FIXES: for (int I : ConstArr) { // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I, I + I); const NonTriviallyCopyable NonCopy[N]{}; @@ -150,7 +150,7 @@ const int *constArray() { printf("2 * %d = %d\n", NonCopy[I].X, NonCopy[I].X + NonCopy[I].X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (const auto & I : NonCopy) + // CHECK-FIXES: for (const auto & I : NonCopy) { // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I.X, I.X + I.X); const TriviallyCopyableButBig Big[N]{}; @@ -158,7 +158,7 @@ const int *constArray() { printf("2 * %d = %d\n", Big[I].X, Big[I].X + Big[I].X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (const auto & I : Big) + // CHECK-FIXES: for (const auto & I : Big) { // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I.X, I.X + I.X); bool Something = false; @@ -167,7 +167,7 @@ const int *constArray() { return &ConstArr[I]; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (const int & I : ConstArr) + // CHECK-FIXES: for (const int & I : ConstArr) { // CHECK-FIXES-NEXT: if (Something) // CHECK-FIXES-NEXT: return &I; @@ -182,14 +182,14 @@ struct HasArr { printf("%d", Arr[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : Arr) + // CHECK-FIXES: for (int I : Arr) { // CHECK-FIXES-NEXT: printf("%d", I); for (int I = 0; I < N; ++I) { printf("%d", ValArr[I].X); } // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & I : ValArr) + // CHECK-FIXES: for (auto & I : ValArr) { // CHECK-FIXES-NEXT: printf("%d", I.X); } @@ -198,14 +198,14 @@ struct HasArr { printf("%d", this->Arr[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : this->Arr) + // CHECK-FIXES: for (int I : this->Arr) { // CHECK-FIXES-NEXT: printf("%d", I); for (int I = 0; I < N; ++I) { printf("%d", this->ValArr[I].X); } // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & I : this->ValArr) + // CHECK-FIXES: for (auto & I : this->ValArr) { // CHECK-FIXES-NEXT: printf("%d", I.X); } }; @@ -217,14 +217,14 @@ struct HasIndirectArr { printf("%d", HA.Arr[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : HA.Arr) + // CHECK-FIXES: for (int I : HA.Arr) { // CHECK-FIXES-NEXT: printf("%d", I); for (int I = 0; I < N; ++I) { printf("%d", HA.ValArr[I].X); } // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & I : HA.ValArr) + // CHECK-FIXES: for (auto & I : HA.ValArr) { // CHECK-FIXES-NEXT: printf("%d", I.X); } @@ -233,14 +233,14 @@ struct HasIndirectArr { printf("%d", this->HA.Arr[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : this->HA.Arr) + // CHECK-FIXES: for (int I : this->HA.Arr) { // CHECK-FIXES-NEXT: printf("%d", I); for (int I = 0; I < N; ++I) { printf("%d", this->HA.ValArr[I].X); } // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & I : this->HA.ValArr) + // CHECK-FIXES: for (auto & I : this->HA.ValArr) { // CHECK-FIXES-NEXT: printf("%d", I.X); } }; @@ -285,7 +285,7 @@ void f() { printf("I found %d\n", *It); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & It : Tt) + // CHECK-FIXES: for (int & It : Tt) { // CHECK-FIXES-NEXT: printf("I found %d\n", It); // Do not crash because of Qq.begin() converting. Q::iterator converts with a @@ -295,7 +295,7 @@ void f() { printf("I found %d\n", *It); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & It : Qq) + // CHECK-FIXES: for (int & It : Qq) { // CHECK-FIXES-NEXT: printf("I found %d\n", It); T *Pt; @@ -303,7 +303,7 @@ void f() { printf("I found %d\n", *It); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & It : *Pt) + // CHECK-FIXES: for (int & It : *Pt) { // CHECK-FIXES-NEXT: printf("I found %d\n", It); S Ss; @@ -311,7 +311,7 @@ void f() { printf("s has value %d\n", (*It).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : Ss) + // CHECK-FIXES: for (auto & It : Ss) { // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); S *Ps; @@ -319,42 +319,42 @@ void f() { printf("s has value %d\n", (*It).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & P : *Ps) + // CHECK-FIXES: for (auto & P : *Ps) { // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X); for (S::const_iterator It = Ss.cbegin(), E = Ss.cend(); It != E; ++It) { printf("s has value %d\n", (*It).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto It : Ss) + // CHECK-FIXES: for (auto It : Ss) { // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { printf("s has value %d\n", It->X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : Ss) + // CHECK-FIXES: for (auto & It : Ss) { // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { It->X = 3; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : Ss) + // CHECK-FIXES: for (auto & It : Ss) { // CHECK-FIXES-NEXT: It.X = 3; for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { (*It).X = 3; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : Ss) + // CHECK-FIXES: for (auto & It : Ss) { // CHECK-FIXES-NEXT: It.X = 3; for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) { It->nonConstFun(4, 5); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : Ss) + // CHECK-FIXES: for (auto & It : Ss) { // CHECK-FIXES-NEXT: It.nonConstFun(4, 5); U Uu; @@ -362,14 +362,14 @@ void f() { printf("s has value %d\n", It->X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : Uu) + // CHECK-FIXES: for (auto & It : Uu) { // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) { printf("s has value %d\n", (*It).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : Uu) + // CHECK-FIXES: for (auto & It : Uu) { // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) { @@ -389,7 +389,7 @@ void f() { printf("Fibonacci number is %d\n", *It); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & It : V) + // CHECK-FIXES: for (int & It : V) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); for (dependent<int>::iterator It(V.begin()), E = V.end(); @@ -397,7 +397,7 @@ void f() { printf("Fibonacci number is %d\n", *It); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & It : V) + // CHECK-FIXES: for (int & It : V) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); doublyDependent<int, int> Intmap; @@ -406,7 +406,7 @@ void f() { printf("Intmap[%d] = %d", It->first, It->second); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : Intmap) + // CHECK-FIXES: for (auto & It : Intmap) { // CHECK-FIXES: printf("Intmap[%d] = %d", It.first, It.second); // PtrSet's iterator dereferences by value so auto & can't be used. @@ -418,7 +418,7 @@ void f() { (void) *I; } // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead - // CHECK-FIXES: for (auto Val_int_ptr : Val_int_ptrs) + // CHECK-FIXES: for (auto Val_int_ptr : Val_int_ptrs) { } // This container uses an iterator where the dereference type is a typedef of @@ -432,7 +432,7 @@ void f() { (void) *I; } // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead - // CHECK-FIXES: for (int & Int_ptr : Int_ptrs) + // CHECK-FIXES: for (int & Int_ptr : Int_ptrs) { } { @@ -451,49 +451,49 @@ void f() { printf("%d\n", (**I).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & I : Dpp) + // CHECK-FIXES: for (auto & I : Dpp) { // CHECK-FIXES-NEXT: printf("%d\n", (*I).X); for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) { printf("%d\n", (*I)->X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & I : Dpp) + // CHECK-FIXES: for (auto & I : Dpp) { // CHECK-FIXES-NEXT: printf("%d\n", I->X); for (S::iterator It = begin(Ss), E = end(Ss); It != E; ++It) { printf("s0 has value %d\n", (*It).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : Ss) + // CHECK-FIXES: for (auto & It : Ss) { // CHECK-FIXES-NEXT: printf("s0 has value %d\n", It.X); for (S::iterator It = std::begin(Ss), E = std::end(Ss); It != E; ++It) { printf("s1 has value %d\n", (*It).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : Ss) + // CHECK-FIXES: for (auto & It : Ss) { // CHECK-FIXES-NEXT: printf("s1 has value %d\n", It.X); for (S::iterator It = begin(*Ps), E = end(*Ps); It != E; ++It) { printf("s2 has value %d\n", (*It).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : *Ps) + // CHECK-FIXES: for (auto & It : *Ps) { // CHECK-FIXES-NEXT: printf("s2 has value %d\n", It.X); for (S::iterator It = begin(*Ps); It != end(*Ps); ++It) { printf("s3 has value %d\n", (*It).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : *Ps) + // CHECK-FIXES: for (auto & It : *Ps) { // CHECK-FIXES-NEXT: printf("s3 has value %d\n", It.X); for (S::const_iterator It = cbegin(Ss), E = cend(Ss); It != E; ++It) { printf("s4 has value %d\n", (*It).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto It : Ss) + // CHECK-FIXES: for (auto It : Ss) { // CHECK-FIXES-NEXT: printf("s4 has value %d\n", It.X); } @@ -507,7 +507,7 @@ void different_type() { printf("s has value %d\n", (*It).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto It : Ss) + // CHECK-FIXES: for (auto It : Ss) { // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); S *Ps; @@ -515,7 +515,7 @@ void different_type() { printf("s has value %d\n", (*It).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto P : *Ps) + // CHECK-FIXES: for (auto P : *Ps) { // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X); dependent<int> V; @@ -524,7 +524,7 @@ void different_type() { printf("Fibonacci number is %d\n", *It); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int It : V) + // CHECK-FIXES: for (int It : V) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); for (dependent<int>::const_iterator It(V.begin()), E = V.end(); @@ -532,7 +532,7 @@ void different_type() { printf("Fibonacci number is %d\n", *It); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int It : V) + // CHECK-FIXES: for (int It : V) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); } @@ -634,7 +634,7 @@ void f() { Sum += V[I] + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : V) + // CHECK-FIXES: for (int I : V) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); // CHECK-FIXES-NEXT: Sum += I + 2; @@ -643,7 +643,7 @@ void f() { Sum += V.at(I) + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : V) + // CHECK-FIXES: for (int I : V) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); // CHECK-FIXES-NEXT: Sum += I + 2; @@ -652,7 +652,7 @@ void f() { Sum += Pv->at(I) + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : *Pv) + // CHECK-FIXES: for (int I : *Pv) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); // CHECK-FIXES-NEXT: Sum += I + 2; @@ -665,7 +665,7 @@ void f() { Sum += (*Pv)[I] + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : *Pv) + // CHECK-FIXES: for (int I : *Pv) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); // CHECK-FIXES-NEXT: Sum += I + 2; @@ -674,7 +674,7 @@ void f() { Sum += Cv->at(I) + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : *Cv) + // CHECK-FIXES: for (int I : *Cv) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); // CHECK-FIXES-NEXT: Sum += I + 2; @@ -683,7 +683,7 @@ void f() { Sum += V[I] + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : V) + // CHECK-FIXES: for (int I : V) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); // CHECK-FIXES-NEXT: Sum += I + 2; @@ -692,7 +692,7 @@ void f() { Sum += V[I] + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : V) + // CHECK-FIXES: for (int I : V) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); // CHECK-FIXES-NEXT: Sum += I + 2; @@ -701,7 +701,7 @@ void f() { Sum += V[I] + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : V) + // CHECK-FIXES: for (int I : V) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); // CHECK-FIXES-NEXT: Sum += I + 2; @@ -710,7 +710,7 @@ void f() { Sum += VD[I] + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : VD) + // CHECK-FIXES: for (int I : VD) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); // CHECK-FIXES-NEXT: Sum += I + 2; @@ -719,7 +719,7 @@ void f() { Sum += V[I] + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : V) + // CHECK-FIXES: for (int I : V) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); // CHECK-FIXES-NEXT: Sum += I + 2; @@ -727,14 +727,14 @@ void f() { V[I] = 0; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & I : V) + // CHECK-FIXES: for (int & I : V) { // CHECK-FIXES-NEXT: I = 0; for (int I = 0, E = std::size(V); E != I; ++I) { V[I] = 0; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & I : V) + // CHECK-FIXES: for (int & I : V) { // CHECK-FIXES-NEXT: I = 0; // Although 'length' might be a valid free function, only size() is standardized @@ -748,7 +748,7 @@ void f() { Sum += Vals[I].X; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & Val : Vals) + // CHECK-FIXES: for (auto & Val : Vals) { // CHECK-FIXES-NEXT: Sum += Val.X; } @@ -760,7 +760,7 @@ void constness() { Sum += Constv[I].X + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (const auto & I : Constv) + // CHECK-FIXES: for (const auto & I : Constv) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); // CHECK-FIXES-NEXT: Sum += I.X + 2; @@ -769,7 +769,7 @@ void constness() { Sum += Constv.at(I).X + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (const auto & I : Constv) + // CHECK-FIXES: for (const auto & I : Constv) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); // CHECK-FIXES-NEXT: Sum += I.X + 2; @@ -778,7 +778,7 @@ void constness() { Sum += Pconstv->at(I).X + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (const auto & I : *Pconstv) + // CHECK-FIXES: for (const auto & I : *Pconstv) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); // CHECK-FIXES-NEXT: Sum += I.X + 2; @@ -791,7 +791,7 @@ void constness() { Sum += (*Pconstv)[I].X + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (const auto & I : *Pconstv) + // CHECK-FIXES: for (const auto & I : *Pconstv) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X); // CHECK-FIXES-NEXT: Sum += I.X + 2; } @@ -804,14 +804,14 @@ void constRef(const dependent<int>& ConstVRef) { sum += ConstVRef[I]; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : ConstVRef) + // CHECK-FIXES: for (int I : ConstVRef) { // CHECK-FIXES-NEXT: sum += I; for (auto I = ConstVRef.begin(), E = ConstVRef.end(); I != E; ++I) { sum += *I; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : ConstVRef) + // CHECK-FIXES: for (int I : ConstVRef) { // CHECK-FIXES-NEXT: sum += I; } @@ -889,7 +889,7 @@ void derefByValueTest() { printf("%d\n", DBV[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (unsigned int I : DBV) + // CHECK-FIXES: for (unsigned int I : DBV) { // CHECK-FIXES-NEXT: printf("%d\n", I); for (unsigned I = 0, E = DBV.size(); I < E; ++I) { @@ -897,7 +897,7 @@ void derefByValueTest() { printf("%d\n", DBV[I]); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (unsigned int I : DBV) + // CHECK-FIXES: for (unsigned int I : DBV) { // CHECK-FIXES-NEXT: auto f = [DBV, &I]() {}; // CHECK-FIXES-NEXT: printf("%d\n", I); } @@ -960,7 +960,7 @@ template <unsigned p> void _dependenceArrayTest() { for (unsigned j = 0; j < 3; ++j) printf("%d", test[j][i]); // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead - // CHECK-FIXES: (auto & j : test) + // CHECK-FIXES: for (auto & j : test) // CHECK-FIXES: printf("%d", j[i]); } void dependenceArrayTest() { @@ -992,13 +992,13 @@ void test() { auto V = [T = Arr[I]]() {}; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert] - // CHECK-FIXES: for (int I : Arr) + // CHECK-FIXES: for (int I : Arr) { // CHECK-FIXES-NEXT: auto V = [T = I]() {}; for (int I = 0; I < N; ++I) { auto V = [T = 10 + Arr[I]]() {}; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert] - // CHECK-FIXES: for (int I : Arr) + // CHECK-FIXES: for (int I : Arr) { // CHECK-FIXES-NEXT: auto V = [T = 10 + I]() {}; for (int I = 0; I < N; ++I) { diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-const.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-const.cpp index 6091f0a..59f472c 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-const.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-const.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s modernize-loop-convert %t +// RUN: %check_clang_tidy %s modernize-loop-convert %t struct Str { Str() = default; @@ -43,7 +43,7 @@ void memberFunctionsAndOperators() { Array[I].constMember(0); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert] - // CHECK-FIXES: for (auto I : Array) + // CHECK-FIXES: for (auto I : Array) { // CHECK-FIXES-NEXT: I.constMember(0); for (int I = 0; I < N; ++I) { @@ -51,14 +51,14 @@ void memberFunctionsAndOperators() { foo(); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop - // CHECK-FIXES: for (auto I : Array) + // CHECK-FIXES: for (auto I : Array) { // CHECK-FIXES-NEXT: if (I < OtherStr) for (int I = 0; I < N; ++I) { if (Right[I] < OtherRight) foo(); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop - // CHECK-FIXES: for (const auto & I : Right) + // CHECK-FIXES: for (const auto & I : Right) { // CHECK-FIXES-NEXT: if (I < OtherRight) // Calling non-const member functions is not. @@ -66,21 +66,21 @@ void memberFunctionsAndOperators() { Array[I].nonConstMember(0); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (auto & I : Array) + // CHECK-FIXES: for (auto & I : Array) { // CHECK-FIXES-NEXT: I.nonConstMember(0); for (int I = 0; I < N; ++I) { Array[I] = OtherStr; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (auto & I : Array) + // CHECK-FIXES: for (auto & I : Array) { // CHECK-FIXES-NEXT: I = OtherStr; for (int I = 0; I < N; ++I) { Right[I] = OtherRight; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (auto & I : Right) + // CHECK-FIXES: for (auto & I : Right) { // CHECK-FIXES-NEXT: I = OtherRight; } @@ -90,14 +90,14 @@ void usedAsParameterToFunctionOrOperator() { copyArg(Array[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (auto I : Array) + // CHECK-FIXES: for (auto I : Array) { // CHECK-FIXES-NEXT: copyArg(I); for (int I = 0; I < N; ++I) { copyArg(Right[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (auto & I : Right) + // CHECK-FIXES: for (auto & I : Right) { // CHECK-FIXES-NEXT: copyArg(I); // Using as a const reference argument is allowed. @@ -105,7 +105,7 @@ void usedAsParameterToFunctionOrOperator() { constRefArg(Array[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (auto I : Array) + // CHECK-FIXES: for (auto I : Array) { // CHECK-FIXES-NEXT: constRefArg(I); for (int I = 0; I < N; ++I) { @@ -113,14 +113,14 @@ void usedAsParameterToFunctionOrOperator() { foo(); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop - // CHECK-FIXES: for (auto I : Array) + // CHECK-FIXES: for (auto I : Array) { // CHECK-FIXES-NEXT: if (OtherStr < I) for (int I = 0; I < N; ++I) { constRefArg(Right[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (const auto & I : Right) + // CHECK-FIXES: for (const auto & I : Right) { // CHECK-FIXES-NEXT: constRefArg(I); // Using as a non-const reference is not. @@ -128,20 +128,20 @@ void usedAsParameterToFunctionOrOperator() { nonConstRefArg(Array[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (auto & I : Array) + // CHECK-FIXES: for (auto & I : Array) { // CHECK-FIXES-NEXT: nonConstRefArg(I); for (int I = 0; I < N; ++I) { nonConstRefArg(Right[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (auto & I : Right) + // CHECK-FIXES: for (auto & I : Right) { // CHECK-FIXES-NEXT: nonConstRefArg(I); for (int I = 0; I < N; ++I) { if (OtherRight < Right[I]) foo(); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop - // CHECK-FIXES: for (auto & I : Right) + // CHECK-FIXES: for (auto & I : Right) { // CHECK-FIXES-NEXT: if (OtherRight < I) } @@ -151,19 +151,19 @@ void primitiveTypes() { copyArg(Ints[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (int Int : Ints) + // CHECK-FIXES: for (int Int : Ints) { // CHECK-FIXES-NEXT: copyArg(Int); for (int I = 0; I < N; ++I) { constRefArg(Ints[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (int Int : Ints) + // CHECK-FIXES: for (int Int : Ints) { // CHECK-FIXES-NEXT: constRefArg(Int); for (int I = 0; I < N; ++I) { nonConstRefArg(Ints[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (int & Int : Ints) + // CHECK-FIXES: for (int & Int : Ints) { // CHECK-FIXES-NEXT: nonConstRefArg(Int); // Builtin operators. @@ -173,7 +173,7 @@ void primitiveTypes() { foo(); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop - // CHECK-FIXES: for (int Int : Ints) + // CHECK-FIXES: for (int Int : Ints) { // CHECK-FIXES-NEXT: if (Int < N) for (int I = 0; I < N; ++I) { @@ -181,7 +181,7 @@ void primitiveTypes() { foo(); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop - // CHECK-FIXES: for (int Int : Ints) + // CHECK-FIXES: for (int Int : Ints) { // CHECK-FIXES-NEXT: if (N == Int) // Assignment. @@ -189,21 +189,21 @@ void primitiveTypes() { Ints[I] = OtherInt; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (int & Int : Ints) + // CHECK-FIXES: for (int & Int : Ints) { // CHECK-FIXES-NEXT: Int = OtherInt; for (int I = 0; I < N; ++I) { OtherInt = Ints[I]; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (int Int : Ints) + // CHECK-FIXES: for (int Int : Ints) { // CHECK-FIXES-NEXT: OtherInt = Int; for (int I = 0; I < N; ++I) { OtherInt = Ints[I] = OtherInt; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (int & Int : Ints) + // CHECK-FIXES: for (int & Int : Ints) { // CHECK-FIXES-NEXT: OtherInt = Int = OtherInt; // Arithmetic operations. @@ -211,21 +211,21 @@ void primitiveTypes() { OtherInt += Ints[I]; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (int Int : Ints) + // CHECK-FIXES: for (int Int : Ints) { // CHECK-FIXES-NEXT: OtherInt += Int; for (int I = 0; I < N; ++I) { Ints[I] += Ints[I]; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (int & Int : Ints) + // CHECK-FIXES: for (int & Int : Ints) { // CHECK-FIXES-NEXT: Int += Int; for (int I = 0; I < N; ++I) { int Res = 5 * (Ints[I] + 1) - Ints[I]; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (int Int : Ints) + // CHECK-FIXES: for (int Int : Ints) { // CHECK-FIXES-NEXT: int Res = 5 * (Int + 1) - Int; } @@ -238,7 +238,7 @@ void takingReferences() { Str &K = Array[I]; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop - // CHECK-FIXES: for (auto & I : Array) + // CHECK-FIXES: for (auto & I : Array) { // CHECK-FIXES-NEXT: Str &J = I; // CHECK-FIXES-NEXT: Str &K = I; for (int I = 0; I < N; ++I) { @@ -246,7 +246,7 @@ void takingReferences() { const Str &K = Array[I]; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop - // CHECK-FIXES: for (auto I : Array) + // CHECK-FIXES: for (auto I : Array) { // CHECK-FIXES-NEXT: const Str &J = I; // CHECK-FIXES-NEXT: const Str &K = I; @@ -256,7 +256,7 @@ void takingReferences() { int &K = Ints[I]; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop - // CHECK-FIXES: for (int & Int : Ints) + // CHECK-FIXES: for (int & Int : Ints) { // CHECK-FIXES-NEXT: int &J = Int; // CHECK-FIXES-NEXT: int &K = Int; for (int I = 0; I < N; ++I) { @@ -264,7 +264,7 @@ void takingReferences() { const int &K = Ints[I]; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop - // CHECK-FIXES: for (int Int : Ints) + // CHECK-FIXES: for (int Int : Ints) { // CHECK-FIXES-NEXT: const int &J = Int; // CHECK-FIXES-NEXT: const int &K = Int; @@ -274,27 +274,27 @@ void takingReferences() { (void)J; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop - // CHECK-FIXES: for (auto J : Array) + // CHECK-FIXES: for (auto J : Array) { for (int I = 0; I < N; ++I) { Str &J = Array[I]; (void)J; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop - // CHECK-FIXES: for (auto & J : Array) + // CHECK-FIXES: for (auto & J : Array) { for (int I = 0; I < N; ++I) { const int &J = Ints[I]; (void)J; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop - // CHECK-FIXES: for (int J : Ints) + // CHECK-FIXES: for (int J : Ints) { for (int I = 0; I < N; ++I) { int &J = Ints[I]; (void)J; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop - // CHECK-FIXES: for (int & J : Ints) + // CHECK-FIXES: for (int & J : Ints) { } template <class T> @@ -315,7 +315,7 @@ void testContainerOfConstIents() { OtherInt -= Ints[I]; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop - // CHECK-FIXES: for (int Int : Ints) + // CHECK-FIXES: for (int Int : Ints) { vector<const Str> Strs; for (int I = 0; I < Strs.size(); ++I) { @@ -323,7 +323,7 @@ void testContainerOfConstIents() { constRefArg(Strs[I]); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop - // CHECK-FIXES: for (auto Str : Strs) + // CHECK-FIXES: for (auto Str : Strs) { } // When we are inside a const-qualified member functions, all the data members @@ -341,20 +341,20 @@ class TestInsideConstFunction { copyArg(Ints[I]); } // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop - // CHECK-FIXES: for (int Int : Ints) + // CHECK-FIXES: for (int Int : Ints) { for (int I = 0; I < N; ++I) { Array[I].constMember(0); constRefArg(Array[I]); } // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop - // CHECK-FIXES: for (auto I : Array) + // CHECK-FIXES: for (auto I : Array) { for (int I = 0; I < V.size(); ++I) { if (V[I]) copyArg(V[I]); } // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop - // CHECK-FIXES: for (int I : V) + // CHECK-FIXES: for (int I : V) { } }; diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-extra.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-extra.cpp index 1ac555f..161427c 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-extra.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/loop-convert-extra.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s modernize-loop-convert %t -- -- -I %S/Inputs/loop-convert +// RUN: %check_clang_tidy %s modernize-loop-convert %t -- -- -I %S/Inputs/loop-convert #include "structures.h" @@ -14,7 +14,7 @@ void f() { int B = Arr[I][A]; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & I : Arr) + // CHECK-FIXES: for (auto & I : Arr) { // CHECK-FIXES-NEXT: int A = 0; // CHECK-FIXES-NEXT: int B = I[A]; @@ -51,7 +51,7 @@ void aliasing() { int Y = T.X; } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & T : Arr) + // CHECK-FIXES: for (auto & T : Arr) { // CHECK-FIXES-NOT: Val &{{[a-z_]+}} = // CHECK-FIXES-NEXT: {} // CHECK-FIXES-NEXT: int Y = T.X; @@ -64,7 +64,7 @@ void aliasing() { int Z = Arr[I].X + T.X; } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & I : Arr) + // CHECK-FIXES: for (auto & I : Arr) { // CHECK-FIXES-NEXT: Val &T = I; // CHECK-FIXES-NEXT: int Y = T.X; // CHECK-FIXES-NEXT: int Z = I.X + T.X; @@ -75,7 +75,7 @@ void aliasing() { int Z = Arr[I].X + T.X; } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & I : Arr) + // CHECK-FIXES: for (auto & I : Arr) { // CHECK-FIXES-NEXT: Val T = I; // CHECK-FIXES-NEXT: int Y = T.X; // CHECK-FIXES-NEXT: int Z = I.X + T.X; @@ -88,7 +88,7 @@ void aliasing() { int Y = T.X; } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & T : V) + // CHECK-FIXES: for (auto & T : V) { // CHECK-FIXES-NEXT: {} // CHECK-FIXES-NEXT: int Y = T.X; @@ -99,7 +99,7 @@ void aliasing() { int Y = T.X; } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & T : *Pv) + // CHECK-FIXES: for (auto & T : *Pv) { // CHECK-FIXES-NEXT: {} // CHECK-FIXES-NEXT: int Y = T.X; @@ -108,7 +108,7 @@ void aliasing() { int Y = T.X; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & I : Arr) + // CHECK-FIXES: for (auto & I : Arr) { // CHECK-FIXES-NEXT: Val &T = func(I); // CHECK-FIXES-NEXT: int Y = T.X; @@ -119,8 +119,8 @@ void aliasing() { } } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int Alias : IntArr) - // CHECK-FIXES-NEXT: if (Alias) + // CHECK-FIXES: for (int Alias : IntArr) { + // CHECK-FIXES-NEXT: if (Alias) { for (unsigned I = 0; I < N; ++I) { while (int Alias = IntArr[I]) { @@ -128,8 +128,8 @@ void aliasing() { } } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int Alias : IntArr) - // CHECK-FIXES-NEXT: while (Alias) + // CHECK-FIXES: for (int Alias : IntArr) { + // CHECK-FIXES-NEXT: while (Alias) { for (unsigned I = 0; I < N; ++I) { switch (int Alias = IntArr[I]) { @@ -138,8 +138,8 @@ void aliasing() { } } // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int Alias : IntArr) - // CHECK-FIXES-NEXT: switch (Alias) + // CHECK-FIXES: for (int Alias : IntArr) { + // CHECK-FIXES-NEXT: switch (Alias) { for (unsigned I = 0; I < N; ++I) { for (int Alias = IntArr[I]; Alias < N; ++Alias) { @@ -147,8 +147,8 @@ void aliasing() { } } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int Alias : IntArr) - // CHECK-FIXES-NEXT: for (; Alias < N; ++Alias) + // CHECK-FIXES: for (int Alias : IntArr) { + // CHECK-FIXES-NEXT: for (; Alias < N; ++Alias) { for (unsigned I = 0; I < N; ++I) { for (unsigned J = 0; int Alias = IntArr[I]; ++J) { @@ -156,15 +156,15 @@ void aliasing() { } } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int Alias : IntArr) - // CHECK-FIXES-NEXT: for (unsigned J = 0; Alias; ++J) + // CHECK-FIXES: for (int Alias : IntArr) { + // CHECK-FIXES-NEXT: for (unsigned J = 0; Alias; ++J) { struct IntRef { IntRef(); IntRef(const int& i); operator int*(); }; for (int I = 0; I < N; ++I) { IntRef Int(IntArr[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : IntArr) + // CHECK-FIXES: for (int I : IntArr) { // CHECK-FIXES-NEXT: IntRef Int(I); int *PtrArr[N]; @@ -173,7 +173,7 @@ void aliasing() { printf("%d\n", *P); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto P : PtrArr) + // CHECK-FIXES: for (auto P : PtrArr) { // CHECK-FIXES-NEXT: printf("%d\n", *P); IntRef Refs[N]; @@ -182,7 +182,7 @@ void aliasing() { printf("%d\n", *P); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & Ref : Refs) + // CHECK-FIXES: for (auto & Ref : Refs) { // CHECK-FIXES-NEXT: int *P = Ref; // CHECK-FIXES-NEXT: printf("%d\n", *P); @@ -212,7 +212,7 @@ void refs_and_vals() { Alias.X = 0; } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto Alias : S_const) + // CHECK-FIXES: for (auto Alias : S_const) { // CHECK-FIXES-NOT: MutableVal {{[a-z_]+}} = // CHECK-FIXES-NEXT: {} // CHECK-FIXES-NEXT: Alias.X = 0; @@ -223,7 +223,7 @@ void refs_and_vals() { Alias.X = 0; } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto Alias : Ss) + // CHECK-FIXES: for (auto Alias : Ss) { // CHECK-FIXES-NOT: MutableVal {{[a-z_]+}} = // CHECK-FIXES-NEXT: {} // CHECK-FIXES-NEXT: Alias.X = 0; @@ -234,7 +234,7 @@ void refs_and_vals() { Alias.X = 0; } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & Alias : Ss) + // CHECK-FIXES: for (auto & Alias : Ss) { // CHECK-FIXES-NOT: MutableVal &{{[a-z_]+}} = // CHECK-FIXES-NEXT: {} // CHECK-FIXES-NEXT: Alias.X = 0; @@ -246,7 +246,7 @@ void refs_and_vals() { unsigned Othersize = Other.size(); } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & It : Dep) + // CHECK-FIXES: for (int & It : Dep) { // CHECK-FIXES-NEXT: printf("%d\n", It); // CHECK-FIXES-NEXT: const int& Idx = Other[0]; // CHECK-FIXES-NEXT: unsigned Othersize = Other.size(); @@ -255,7 +255,7 @@ void refs_and_vals() { Other.at(i); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & i : Other) + // CHECK-FIXES: for (int & i : Other) { // CHECK-FIXES: i; for (int I = 0, E = Dep.size(); I != E; ++I) { @@ -273,21 +273,21 @@ struct MemberNaming { printf("%d\n", Ints[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead - // CHECK-FIXES: for (int Int : Ints) + // CHECK-FIXES: for (int Int : Ints) { // CHECK-FIXES-NEXT: printf("%d\n", Int); for (int I = 0; I < N; ++I) { printf("%d\n", Ints_[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead - // CHECK-FIXES: for (int Int : Ints_) + // CHECK-FIXES: for (int Int : Ints_) { // CHECK-FIXES-NEXT: printf("%d\n", Int); for (int I = 0; I < DInts.size(); ++I) { printf("%d\n", DInts[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead - // CHECK-FIXES: for (int DInt : DInts) + // CHECK-FIXES: for (int DInt : DInts) { // CHECK-FIXES-NEXT: printf("%d\n", DInt); } @@ -298,14 +298,14 @@ void MemberNaming::outOfLine() { printf("%d\n", Ints[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int Int : Ints) + // CHECK-FIXES: for (int Int : Ints) { // CHECK-FIXES-NEXT: printf("%d\n", Int); for (int I = 0; I < N; ++I) { printf("%d\n", Ints_[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int Int : Ints_) + // CHECK-FIXES: for (int Int : Ints_) { // CHECK-FIXES-NEXT: printf("%d\n", Int); } @@ -334,7 +334,7 @@ void sameNames() { (void)Nums[I]; } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & I : Nums) + // CHECK-FIXES: for (int & I : Nums) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); // CHECK-FIXES-NEXT: Sum += I + 2 + Num; // CHECK-FIXES-NEXT: (void)I; @@ -346,7 +346,7 @@ void sameNames() { (void)Nums[I]; } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & I : Nums) + // CHECK-FIXES: for (int & I : Nums) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); // CHECK-FIXES-NEXT: Sum += I + 2 + Num + Elem; // CHECK-FIXES-NEXT: (void)I; @@ -357,7 +357,7 @@ void oldIndexConflict() { printf("Num: %d\n", Nums[Num]); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int Num : Nums) + // CHECK-FIXES: for (int Num : Nums) { // CHECK-FIXES-NEXT: printf("Num: %d\n", Num); S Things; @@ -365,7 +365,7 @@ void oldIndexConflict() { printf("Thing: %d %d\n", Thing->X, (*Thing).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & Thing : Things) + // CHECK-FIXES: for (auto & Thing : Things) { // CHECK-FIXES-NEXT: printf("Thing: %d %d\n", Thing.X, Thing.X); } @@ -376,7 +376,7 @@ void macroConflict() { printf("Max of 3 and 5: %d\n", MAX(3, 5)); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : MAXs) + // CHECK-FIXES: for (auto & It : MAXs) { // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); // CHECK-FIXES-NEXT: printf("Max of 3 and 5: %d\n", MAX(3, 5)); @@ -385,7 +385,7 @@ void macroConflict() { printf("Max of 3 and 5: %d\n", MAX(3, 5)); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto It : MAXs) + // CHECK-FIXES: for (auto It : MAXs) { // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); // CHECK-FIXES-NEXT: printf("Max of 3 and 5: %d\n", MAX(3, 5)); @@ -396,8 +396,8 @@ void macroConflict() { } } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & It : DEFs) - // CHECK-FIXES-NEXT: if (It == DEF) + // CHECK-FIXES: for (int & It : DEFs) { + // CHECK-FIXES-NEXT: if (It == DEF) { // CHECK-FIXES-NEXT: printf("I found %d\n", It); } @@ -407,7 +407,7 @@ void keywordConflict() { *It = 5; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & It : ints) + // CHECK-FIXES: for (int & It : ints) { // CHECK-FIXES-NEXT: It = 5; U __FUNCTION__s; @@ -416,7 +416,7 @@ void keywordConflict() { int __FUNCTION__s_It = (*It).X + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : __FUNCTION__s) + // CHECK-FIXES: for (auto & It : __FUNCTION__s) { // CHECK-FIXES-NEXT: int __FUNCTION__s_It = It.X + 2; } @@ -435,7 +435,7 @@ void typeConflict() { *It = sizeof(Val); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & It : Vals) + // CHECK-FIXES: for (int & It : Vals) { // CHECK-FIXES-NEXT: It = sizeof(Val); typedef struct Val TD; @@ -454,7 +454,7 @@ void typeConflict() { (void) *It; } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : TDs) + // CHECK-FIXES: for (auto & It : TDs) { // CHECK-FIXES-NEXT: TD V; // CHECK-FIXES-NEXT: V.X = 5; @@ -464,7 +464,7 @@ void typeConflict() { *It = sizeof(St); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & It : Sts) + // CHECK-FIXES: for (int & It : Sts) { // CHECK-FIXES-NEXT: It = sizeof(St); } @@ -528,8 +528,8 @@ void f() { } // CHECK-MESSAGES: :[[@LINE-8]]:3: warning: use range-based for loop instead // CHECK-MESSAGES: :[[@LINE-8]]:5: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & I : Arr) - // CHECK-FIXES-NEXT: for (auto & J : Arr) + // CHECK-FIXES: for (auto & I : Arr) { + // CHECK-FIXES-NEXT: for (auto & J : Arr) { // CHECK-FIXES-NEXT: int K = I.X + J.X; // CHECK-FIXES-NOT: int L = I.X + I.X; @@ -542,8 +542,8 @@ void f() { } } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & I : Nest) - // CHECK-FIXES-NEXT: for (int J = 0; J < M; ++J) + // CHECK-FIXES: for (auto & I : Nest) { + // CHECK-FIXES-NEXT: for (int J = 0; J < M; ++J) { // CHECK-FIXES-NEXT: printf("Got item %d", I[J].X); // Note that the order of M and N are switched for this test. @@ -554,8 +554,8 @@ void f() { } // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop instead // CHECK-FIXES-NOT: for (auto & {{[a-zA-Z_]+}} : Nest[I]) - // CHECK-FIXES: for (int J = 0; J < M; ++J) - // CHECK-FIXES-NEXT: for (auto & I : Nest) + // CHECK-FIXES: for (int J = 0; J < M; ++J) { + // CHECK-FIXES-NEXT: for (auto & I : Nest) { // CHECK-FIXES-NEXT: printf("Got item %d", I[J].X); // The inner loop is also convertible. @@ -566,8 +566,8 @@ void f() { } } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & I : NestT) - // CHECK-FIXES-NEXT: for (T::iterator TI = I.begin(), TE = I.end(); TI != TE; ++TI) + // CHECK-FIXES: for (auto & I : NestT) { + // CHECK-FIXES-NEXT: for (T::iterator TI = I.begin(), TE = I.end(); TI != TE; ++TI) { // CHECK-FIXES-NEXT: printf("%d", *TI); // The inner loop is also convertible. @@ -578,8 +578,8 @@ void f() { } } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto I : NestS) - // CHECK-FIXES-NEXT: for (S::const_iterator SI = I.begin(), SE = I.end(); SI != SE; ++SI) + // CHECK-FIXES: for (auto I : NestS) { + // CHECK-FIXES-NEXT: for (S::const_iterator SI = I.begin(), SE = I.end(); SI != SE; ++SI) { // CHECK-FIXES-NEXT: printf("%d", *SI); for (Nested<S>::const_iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) { @@ -590,7 +590,7 @@ void f() { } } // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto Ss : NestS) + // CHECK-FIXES: for (auto Ss : NestS) { for (Nested<S>::iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) { S &Ss = *I; @@ -600,7 +600,7 @@ void f() { } } // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & Ss : NestS) + // CHECK-FIXES: for (auto & Ss : NestS) { Foo foo; for (Nested<S>::const_iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) { @@ -611,7 +611,7 @@ void f() { } } // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto Ss : NestS) + // CHECK-FIXES: for (auto Ss : NestS) { for (Nested<S>::iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) { S &Ss = *I; @@ -621,7 +621,7 @@ void f() { } } // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & Ss : NestS) + // CHECK-FIXES: for (auto & Ss : NestS) { } @@ -638,7 +638,7 @@ void complexContainer() { MutableVal J = *I; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & I : Exes[Index].getS()) + // CHECK-FIXES: for (auto & I : Exes[Index].getS()) { // CHECK-FIXES-NEXT: MutableVal K = I; // CHECK-FIXES-NEXT: MutableVal J = I; } @@ -650,7 +650,7 @@ void f() { printf("I found %d\n", *It); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & It : Tt) + // CHECK-FIXES: for (int & It : Tt) { // CHECK-FIXES-NEXT: printf("I found %d\n", It); T *Pt; @@ -658,7 +658,7 @@ void f() { printf("I found %d\n", *It); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & It : *Pt) + // CHECK-FIXES: for (int & It : *Pt) { // CHECK-FIXES-NEXT: printf("I found %d\n", It); S Ss; @@ -666,7 +666,7 @@ void f() { printf("s has value %d\n", (*It).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : Ss) + // CHECK-FIXES: for (auto & It : Ss) { // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); S *Ps; @@ -674,35 +674,35 @@ void f() { printf("s has value %d\n", (*It).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & P : *Ps) + // CHECK-FIXES: for (auto & P : *Ps) { // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X); for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) { printf("s has value %d\n", It->X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : Ss) + // CHECK-FIXES: for (auto & It : Ss) { // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) { It->X = 3; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : Ss) + // CHECK-FIXES: for (auto & It : Ss) { // CHECK-FIXES-NEXT: It.X = 3; for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) { (*It).X = 3; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : Ss) + // CHECK-FIXES: for (auto & It : Ss) { // CHECK-FIXES-NEXT: It.X = 3; for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) { It->nonConstFun(4, 5); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : Ss) + // CHECK-FIXES: for (auto & It : Ss) { // CHECK-FIXES-NEXT: It.nonConstFun(4, 5); U Uu; @@ -710,14 +710,14 @@ void f() { printf("s has value %d\n", It->X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : Uu) + // CHECK-FIXES: for (auto & It : Uu) { // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); for (U::iterator It = Uu.begin(); It != Uu.end(); ++It) { printf("s has value %d\n", (*It).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : Uu) + // CHECK-FIXES: for (auto & It : Uu) { // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); U::iterator A; @@ -733,7 +733,7 @@ void f() { printf("Fibonacci number is %d\n", *It); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & It : V) + // CHECK-FIXES: for (int & It : V) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); for (dependent<int>::iterator It(V.begin()); @@ -741,7 +741,7 @@ void f() { printf("Fibonacci number is %d\n", *It); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & It : V) + // CHECK-FIXES: for (int & It : V) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); doublyDependent<int, int> intmap; @@ -750,7 +750,7 @@ void f() { printf("intmap[%d] = %d", It->first, It->second); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto & It : intmap) + // CHECK-FIXES: for (auto & It : intmap) { // CHECK-FIXES-NEXT: printf("intmap[%d] = %d", It.first, It.second); } @@ -765,7 +765,7 @@ void different_type() { printf("s has value %d\n", (*It).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto It : Ss) + // CHECK-FIXES: for (auto It : Ss) { // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X); S *Ps; @@ -773,7 +773,7 @@ void different_type() { printf("s has value %d\n", (*It).X); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (auto P : *Ps) + // CHECK-FIXES: for (auto P : *Ps) { // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X); dependent<int> V; @@ -781,14 +781,14 @@ void different_type() { printf("Fibonacci number is %d\n", *It); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int It : V) + // CHECK-FIXES: for (int It : V) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); for (dependent<int>::const_iterator It(V.begin()); It != V.end(); ++It) { printf("Fibonacci number is %d\n", *It); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int It : V) + // CHECK-FIXES: for (int It : V) { // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It); } @@ -808,7 +808,7 @@ void messing_with_macros() { printf("Value: %d\n", Arr[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : Arr) + // CHECK-FIXES: for (int I : Arr) { // CHECK-FIXES-NEXT: printf("Value: %d\n", I); for (int I = 0; I < N; ++I) { @@ -821,7 +821,7 @@ void messing_with_macros() { THREE_PARAM(Arr[I], Arr[I], Arr[I]); } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & I : Arr) + // CHECK-FIXES: for (int & I : Arr) { // CHECK-FIXES-NEXT: TWO_PARAM(I, I); // CHECK-FIXES-NEXT: THREE_PARAM(I, I, I); } @@ -907,10 +907,11 @@ void capturesIndex() { F(Arr[I]); } // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : Arr) - // CHECK-FIXES-NEXT: auto F = [Arr, &I](int k) - // CHECK-FIXES-NEXT: printf("%d\n", I + k); - // CHECK-FIXES: F(I); + // CHECK-FIXES: for (int I : Arr) { + // CHECK-FIXES-NEXT: auto F = [Arr, &I](int k) { + // CHECK-FIXES-NEXT: printf("%d\n", I + k); + // CHECK-FIXES-NEXT: }; + // CHECK-FIXES-NEXT: F(I); } void implicitCapture() { @@ -939,8 +940,8 @@ void implicitCapture() { }; } // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : Arr) - // CHECK-FIXES-NEXT: auto G3 = [&]() + // CHECK-FIXES: for (int I : Arr) { + // CHECK-FIXES-NEXT: auto G3 = [&]() { // CHECK-FIXES-NEXT: int R3 = I; // CHECK-FIXES-NEXT: int J3 = I + R3; @@ -950,8 +951,8 @@ void implicitCapture() { }; } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : Arr) - // CHECK-FIXES-NEXT: auto G4 = [=]() + // CHECK-FIXES: for (int I : Arr) { + // CHECK-FIXES-NEXT: auto G4 = [=]() { // CHECK-FIXES-NEXT: int R4 = I + 5; // Alias by value. @@ -962,8 +963,8 @@ void implicitCapture() { }; } // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int R5 : Arr) - // CHECK-FIXES-NEXT: auto G5 = [&]() + // CHECK-FIXES: for (int R5 : Arr) { + // CHECK-FIXES-NEXT: auto G5 = [&]() { // CHECK-FIXES-NEXT: int J5 = 8 + R5; // Alias by reference. @@ -974,8 +975,8 @@ void implicitCapture() { }; } // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int & R6 : Arr) - // CHECK-FIXES-NEXT: auto G6 = [&]() + // CHECK-FIXES: for (int & R6 : Arr) { + // CHECK-FIXES-NEXT: auto G6 = [&]() { // CHECK-FIXES-NEXT: int J6 = -1 + R6; } @@ -1029,14 +1030,14 @@ void captureByValue() { auto C1 = [&Arr, I]() { if (Arr[I] == 1); }; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : Arr) + // CHECK-FIXES: for (int I : Arr) { // CHECK-FIXES-NEXT: auto C1 = [&Arr, &I]() { if (I == 1); }; for (unsigned I = 0; I < Dep.size(); ++I) { auto C2 = [&Dep, I]() { if (Dep[I] == 2); }; } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : Dep) + // CHECK-FIXES: for (int I : Dep) { // CHECK-FIXES-NEXT: auto C2 = [&Dep, &I]() { if (I == 2); }; } @@ -1062,7 +1063,7 @@ void f() { E Ee{ { { g( { Array[I] } ) } } }; } // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int I : Array) + // CHECK-FIXES: for (int I : Array) { // CHECK-FIXES-NEXT: int A{ I }; // CHECK-FIXES-NEXT: int B{ g(I) }; // CHECK-FIXES-NEXT: int C{ g( { I } ) }; @@ -1079,7 +1080,7 @@ void bug28341() { if (value > 127) ; // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for(unsigned char value : v) + // CHECK-FIXES: for(unsigned char value : v) { // CHECK-FIXES-NEXT: if (value > 127) } } diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared.cpp index 65ece77..686b998 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s modernize-make-shared %t -- -- -I %S/Inputs/smart-ptr +// RUN: %check_clang_tidy %s modernize-make-shared %t -- -- -I %S/Inputs/smart-ptr #include "shared_ptr.h" // CHECK-FIXES: #include <memory> @@ -226,7 +226,7 @@ void initialization(int T, Base b) { // CHECK-FIXES: std::shared_ptr<APair> PAggr = std::make_shared<APair>(APair{T, 1}); PAggr.reset(new APair{T, 1}); // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead - // CHECK-FIXES: std::make_shared<APair>(APair{T, 1}); + // CHECK-FIXES: PAggr = std::make_shared<APair>(APair{T, 1}); // Test different kinds of initialization of the pointee, when the shared_ptr // is initialized with braces. diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique.cpp index 13103c7..bcdf4fb 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes -std=c++14-or-later %s modernize-make-unique %t -- -- -I %S/Inputs/smart-ptr +// RUN: %check_clang_tidy -std=c++14-or-later %s modernize-make-unique %t -- -- -I %S/Inputs/smart-ptr #include "unique_ptr.h" #include "initializer_list.h" @@ -271,7 +271,7 @@ void initialization(int T, Base b) { // CHECK-FIXES: std::unique_ptr<APair> PAggr = std::make_unique<APair>(APair{T, 1}); PAggr.reset(new APair{T, 1}); // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead - // CHECK-FIXES: std::make_unique<APair>(APair{T, 1}); + // CHECK-FIXES: PAggr = std::make_unique<APair>(APair{T, 1}); // Check aggregate init with intermediate temporaries. std::unique_ptr<APair> PAggrTemp = std::unique_ptr<APair>(new APair({T, 1})); @@ -480,7 +480,7 @@ void initialization(int T, Base b) { std::unique_ptr<int[]> FI; FI.reset(new int[5]()); // value initialization. // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: - // CHECK-FIXES: FI = std::make_unique<int[]>(5); + // CHECK-FIXES: FI = std::make_unique<int[]>(5); // value initialization. // The check doesn't give warnings and fixes for cases where the original new // expression does default initialization. diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/min-max-use-initializer-list.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/min-max-use-initializer-list.cpp index ae270dc..9dc05b9 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/min-max-use-initializer-list.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/min-max-use-initializer-list.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s modernize-min-max-use-initializer-list %t +// RUN: %check_clang_tidy %s modernize-min-max-use-initializer-list %t // CHECK-FIXES: #include <algorithm> namespace utils { @@ -206,7 +206,7 @@ int min7 = std::min(1, std::min(2, 3, fless_than), fgreater_than); // CHECK-FIXES: int min7 = std::min(1, std::min(2, 3, fless_than), fgreater_than); int max8 = std::max(1, std::max(2, 3, fless_than), less_than); -// CHECK-FIXES: int max8 = std::max(1, std::max(2, 3, fless_than), less_than) +// CHECK-FIXES: int max8 = std::max(1, std::max(2, 3, fless_than), less_than); int min8 = std::min(1, std::min(2, 3, fless_than), less_than); // CHECK-FIXES: int min8 = std::min(1, std::min(2, 3, fless_than), less_than); diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value.cpp index 7538862..cc237f4 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/pass-by-value.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s modernize-pass-by-value %t -- -- -fno-delayed-template-parsing +// RUN: %check_clang_tidy %s modernize-pass-by-value %t -- -- -fno-delayed-template-parsing namespace { // POD types are trivially move constructible. @@ -92,7 +92,7 @@ struct H { using namespace ns_H; H::H(const HMovable &M) : M(M) {} // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: pass by value and use std::move -// CHECK-FIXES: H(HMovable M) : M(std::move(M)) {} +// CHECK-FIXES: H::H(HMovable M) : M(std::move(M)) {} // Try messing up with macros. #define MOVABLE_PARAM(Name) const Movable & Name diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/redundant-void-arg.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/redundant-void-arg.cpp index 935163b..6311497 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/redundant-void-arg.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/redundant-void-arg.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s modernize-redundant-void-arg %t +// RUN: %check_clang_tidy %s modernize-redundant-void-arg %t #define NULL 0 @@ -452,22 +452,22 @@ struct DefinitionWithNoBody { #define BODY {} #define LAMBDA1 [](void){} // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg] -// CHECK-FIXES: LAMBDA1 [](){} +// CHECK-FIXES: #define LAMBDA1 [](){} #define LAMBDA2 [](void)BODY // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg] -// CHECK-FIXES: LAMBDA2 []()BODY +// CHECK-FIXES: #define LAMBDA2 []()BODY #define LAMBDA3(captures, args, body) captures args body #define WRAP(...) __VA_ARGS__ #define LAMBDA4 (void)LAMBDA3([],(void),BODY) // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg] -// CHECK-FIXES: LAMBDA4 (void)LAMBDA3([],(),BODY) +// CHECK-FIXES: #define LAMBDA4 (void)LAMBDA3([],(),BODY) #define LAMBDA5 []() -> void (*)(void) {return BODY;} // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg] -// CHECK-FIXES: LAMBDA5 []() -> void (*)() {return BODY;} +// CHECK-FIXES: #define LAMBDA5 []() -> void (*)() {return BODY;} void lambda_expression_with_macro_test(){ (void)LAMBDA1; (void)LAMBDA2; diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/replace-auto-ptr.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/replace-auto-ptr.cpp index dea0857..2281c1a 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/replace-auto-ptr.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/replace-auto-ptr.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s modernize-replace-auto-ptr %t -- -- -I %S/Inputs/replace-auto-ptr +// RUN: %check_clang_tidy %s modernize-replace-auto-ptr %t -- -- -I %S/Inputs/replace-auto-ptr // CHECK-FIXES: #include <utility> @@ -15,7 +15,7 @@ std::auto_ptr<Derived> create_derived_ptr(); // Test function return values (declaration) std::auto_ptr<char> f_5(); // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: auto_ptr is deprecated -// CHECK-FIXES: std::unique_ptr<char> f_5() +// CHECK-FIXES: std::unique_ptr<char> f_5(); // Test function parameters. diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast-remove-stars.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast-remove-stars.cpp index 5b620ad..59d6d23a 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast-remove-stars.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast-remove-stars.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s modernize-use-auto %t -- \ +// RUN: %check_clang_tidy %s modernize-use-auto %t -- \ // RUN: -config="{CheckOptions: {modernize-use-auto.RemoveStars: 'true' , modernize-use-auto.MinTypeNameLength: '0'}}" \ // RUN: -- -frtti @@ -108,7 +108,7 @@ typedef unsigned char xmlChar; do { \ xmlChar *s = (xmlChar *)(x); \ } while (false); -// CHECK-FIXES: xmlChar *s = (xmlChar *)(x); +// CHECK-FIXES: xmlChar *s = (xmlChar *)(x); {{\\}} void f_cstyle_cast() { auto *a = new A(); diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast.cpp index 3946b97..7f687ab 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-cast.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s modernize-use-auto %t -- \ +// RUN: %check_clang_tidy %s modernize-use-auto %t -- \ // RUN: -config="{CheckOptions: {modernize-use-auto.MinTypeNameLength: '0'}}" \ // RUN: -- -I %S/Inputs/use-auto -frtti @@ -108,7 +108,7 @@ typedef unsigned char xmlChar; do { \ xmlChar *s = (xmlChar *)(x); \ } while (false); -// CHECK-FIXES: xmlChar *s = (xmlChar *)(x); +// CHECK-FIXES: xmlChar *s = (xmlChar *)(x); {{\\}} void f_cstyle_cast() { auto *a = new A(); diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-for-pointer.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-for-pointer.cpp index 1fd4189..2cb0208 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-for-pointer.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-for-pointer.cpp @@ -1,20 +1,20 @@ -// RUN: %check_clang_tidy --match-partial-fixes -check-suffix=REMOVE %s modernize-use-auto %t -- \ +// RUN: %check_clang_tidy -check-suffix=REMOVE %s modernize-use-auto %t -- \ // RUN: -config="{CheckOptions: {modernize-use-auto.RemoveStars: 'true', modernize-use-auto.MinTypeNameLength: '0'}}" -// RUN: %check_clang_tidy --match-partial-fixes %s modernize-use-auto %t -- \ +// RUN: %check_clang_tidy %s modernize-use-auto %t -- \ // RUN: -config="{CheckOptions: {modernize-use-auto.RemoveStars: 'false', modernize-use-auto.MinTypeNameLength: '0'}}" void pointerToFunction() { void (*(*(f1)))() = static_cast<void (**)()>(nullptr); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing - // CHECK-FIXES-REMOVE: auto f1 = - // CHECK-FIXES: auto *f1 = + // CHECK-FIXES-REMOVE: auto f1 = static_cast<void (**)()>(nullptr); + // CHECK-FIXES: auto *f1 = static_cast<void (**)()>(nullptr); } void pointerToArray() { int(*a1)[2] = new int[10][2]; // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing - // CHECK-FIXES-REMOVE: auto a1 = - // CHECK-FIXES: auto *a1 = + // CHECK-FIXES-REMOVE: auto a1 = new int[10][2]; + // CHECK-FIXES: auto *a1 = new int[10][2]; } void memberFunctionPointer() { @@ -23,7 +23,7 @@ void memberFunctionPointer() { }; void(A::* a1)() = static_cast<void(A::*)()>(nullptr); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing - // CHECK-FIXES-REMOVE: auto a1 = - // CHECK-FIXES: auto *a1 = + // CHECK-FIXES-REMOVE: auto a1 = static_cast<void(A::*)()>(nullptr); + // CHECK-FIXES: auto *a1 = static_cast<void(A::*)()>(nullptr); } diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-iterator.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-iterator.cpp index 02fb646..a928b33 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-iterator.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-iterator.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes -std=c++11,c++14 %s modernize-use-auto %t -- -- -I %S/Inputs/use-auto +// RUN: %check_clang_tidy -std=c++11,c++14 %s modernize-use-auto %t -- -- -I %S/Inputs/use-auto // FIXME: Fix the checker to work in C++17 mode. #include "containers.h" @@ -277,18 +277,18 @@ void pointer_to_iterator() { void loop() { for (std::vector<int>::iterator I = Vec.begin(); I != Vec.end(); ++I) { // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators - // CHECK-FIXES: for (auto I = Vec.begin(); I != Vec.end(); ++I) + // CHECK-FIXES: for (auto I = Vec.begin(); I != Vec.end(); ++I) { } for (int_iterator I = Vec.begin(), E = Vec.end(); I != E; ++I) { // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators - // CHECK-FIXES: for (auto I = Vec.begin(), E = Vec.end(); I != E; ++I) + // CHECK-FIXES: for (auto I = Vec.begin(), E = Vec.end(); I != E; ++I) { } std::vector<std::vector<int>::iterator> IterVec; for (std::vector<int>::iterator I : IterVec) { // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators - // CHECK-FIXES: for (auto I : IterVec) + // CHECK-FIXES: for (auto I : IterVec) { } } diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-min-type-name-length.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-min-type-name-length.cpp index 6cea26e..e954cee 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-min-type-name-length.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-auto-min-type-name-length.cpp @@ -1,7 +1,7 @@ -// RUN: %check_clang_tidy --match-partial-fixes -check-suffix=0-0 %s modernize-use-auto %t -- -config="{CheckOptions: {modernize-use-auto.RemoveStars: false, modernize-use-auto.MinTypeNameLength: 0}}" -- -frtti -// RUN: %check_clang_tidy --match-partial-fixes -check-suffix=0-8 %s modernize-use-auto %t -- -config="{CheckOptions: {modernize-use-auto.RemoveStars: false, modernize-use-auto.MinTypeNameLength: 8}}" -- -frtti -// RUN: %check_clang_tidy --match-partial-fixes -check-suffix=1-0 %s modernize-use-auto %t -- -config="{CheckOptions: {modernize-use-auto.RemoveStars: true, modernize-use-auto.MinTypeNameLength: 0}}" -- -frtti -// RUN: %check_clang_tidy --match-partial-fixes -check-suffix=1-8 %s modernize-use-auto %t -- -config="{CheckOptions: {modernize-use-auto.RemoveStars: true, modernize-use-auto.MinTypeNameLength: 8}}" -- -frtti +// RUN: %check_clang_tidy -check-suffix=0-0 %s modernize-use-auto %t -- -config="{CheckOptions: {modernize-use-auto.RemoveStars: false, modernize-use-auto.MinTypeNameLength: 0}}" -- -frtti +// RUN: %check_clang_tidy -check-suffix=0-8 %s modernize-use-auto %t -- -config="{CheckOptions: {modernize-use-auto.RemoveStars: false, modernize-use-auto.MinTypeNameLength: 8}}" -- -frtti +// RUN: %check_clang_tidy -check-suffix=1-0 %s modernize-use-auto %t -- -config="{CheckOptions: {modernize-use-auto.RemoveStars: true, modernize-use-auto.MinTypeNameLength: 0}}" -- -frtti +// RUN: %check_clang_tidy -check-suffix=1-8 %s modernize-use-auto %t -- -config="{CheckOptions: {modernize-use-auto.RemoveStars: true, modernize-use-auto.MinTypeNameLength: 8}}" -- -frtti template <class T> extern T foo(); template <class T> struct P { explicit P(T t) : t_(t) {} T t_;}; @@ -17,10 +17,10 @@ int bar() { // CHECK-FIXES-1-0: auto i = {{.*}} // CHECK-FIXES-1-8: long i = {{.*}} const long ci = static_cast<long>(foo<const long>()); - // CHECK-FIXES-0-0: auto ci = {{.*}} - // CHECK-FIXES-0-8: long ci = {{.*}} - // CHECK-FIXES-1-0: auto ci = {{.*}} - // CHECK-FIXES-1-8: long ci = {{.*}} + // CHECK-FIXES-0-0: const auto ci = {{.*}} + // CHECK-FIXES-0-8: const long ci = {{.*}} + // CHECK-FIXES-1-0: const auto ci = {{.*}} + // CHECK-FIXES-1-8: const long ci = {{.*}} long *pi = static_cast<long *>(foo<long *>()); // CHECK-FIXES-0-0: auto *pi = {{.*}} // CHECK-FIXES-0-8: long *pi = {{.*}} diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp index 9639e0e..3afa4a4 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s modernize-use-equals-default %t -- \ +// RUN: %check_clang_tidy %s modernize-use-equals-default %t -- \ // RUN: -config="{CheckOptions: {modernize-use-equals-default.IgnoreMacros: false}}" \ // RUN: -- -fno-delayed-template-parsing -fexceptions -Wno-error=return-type @@ -35,7 +35,7 @@ struct IL { // Skip unions. union NU { NU(const NU &Other) : Field(Other.Field) {} - // CHECK-FIXES: NU(const NU &Other) : + // CHECK-FIXES: NU(const NU &Other) : Field(Other.Field) {} NU &operator=(const NU &Other) { Field = Other.Field; return *this; @@ -47,7 +47,7 @@ union NU { // Skip structs/classes containing anonymous unions. struct SU { SU(const SU &Other) : Field(Other.Field) {} - // CHECK-FIXES: SU(const SU &Other) : + // CHECK-FIXES: SU(const SU &Other) : Field(Other.Field) {} SU &operator=(const SU &Other) { Field = Other.Field; return *this; diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp index a606b84..2eefdf9 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s modernize-use-equals-default %t -- -- -fno-delayed-template-parsing -fexceptions +// RUN: %check_clang_tidy %s modernize-use-equals-default %t -- -- -fno-delayed-template-parsing -fexceptions // Out of line definition. class OL { @@ -145,7 +145,7 @@ struct ST { // CHECK-FIXES: ST() = default; ~ST() {} // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' - // CHECK-FIXES: ST() = default; + // CHECK-FIXES: ~ST() = default; }; // Deleted constructor/destructor. diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison-qt.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison-qt.cpp index 135ee27..1f26ff3 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison-qt.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison-qt.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes -std=c++17 %s modernize-use-integer-sign-comparison %t -- \ +// RUN: %check_clang_tidy -std=c++17 %s modernize-use-integer-sign-comparison %t -- \ // RUN: -config="{CheckOptions: {modernize-use-integer-sign-comparison.EnableQtSupport: true}}" // CHECK-FIXES: #include <QtCore/q20utility.h> @@ -92,7 +92,8 @@ int AllComparisons() { if (static_cast<unsigned int>(uArray[2]) < static_cast<int>(sArray[2])) return 0; // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] -// CHECK-FIXES: if (q20::cmp_less(uArray[2],sArray[2])) +// CHECK-FIXES: if (q20::cmp_less(uArray[2],sArray[2]))) +// FIXME: There should only be 2 closing braces. The fix-it inserts an unbalanced one. if ((unsigned int)uArray[3] < (int)sArray[3]) return 0; diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp index e0a84ef..628cee0 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes -std=c++20 %s modernize-use-integer-sign-comparison %t +// RUN: %check_clang_tidy -std=c++20-or-later %s modernize-use-integer-sign-comparison %t // CHECK-FIXES: #include <utility> @@ -91,7 +91,8 @@ int AllComparisons() { if (static_cast<unsigned int>(uArray[2]) < static_cast<int>(sArray[2])) return 0; // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] -// CHECK-FIXES: if (std::cmp_less(uArray[2],sArray[2])) +// CHECK-FIXES: if (std::cmp_less(uArray[2],sArray[2]))) +// FIXME: There should only be 2 closing braces. The fix-it inserts an unbalanced one. if ((unsigned int)uArray[3] < (int)sArray[3]) return 0; diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr.cpp index fe9d6de..27a9629 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s modernize-use-nullptr %t -- \ +// RUN: %check_clang_tidy %s modernize-use-nullptr %t -- \ // RUN: -config="{CheckOptions: {modernize-use-nullptr.NullMacros: 'MY_NULL,NULL'}}" #define NULL 0 @@ -91,7 +91,7 @@ template <typename T> struct pear { // it is often defined as __null and the check will catch it.) void f() { x = __null; } // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr [modernize-use-nullptr] - // CHECK-FIXES: x = nullptr; + // CHECK-FIXES: void f() { x = nullptr; } // But if you say 0, we allow the possibility that T can be used with integral // and pointer types, and "0" is an acceptable initializer (even if "{}" might @@ -118,11 +118,13 @@ void test_macro_args() { // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use nullptr // CHECK-FIXES: IS_EQ(static_cast<int*>(nullptr), Ptr); - IS_EQ(0, Ptr); // literal + // literal + IS_EQ(0, Ptr); // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr // CHECK-FIXES: IS_EQ(nullptr, Ptr); - IS_EQ(NULL, Ptr); // macro + // macro + IS_EQ(NULL, Ptr); // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr // CHECK-FIXES: IS_EQ(nullptr, Ptr); @@ -205,7 +207,7 @@ void test_macro_args() { } a[2] = {ENTRY(0), {0}}; // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: use nullptr - // CHECK-FIXES: a[2] = {ENTRY(nullptr), {nullptr}}; + // CHECK-FIXES: } a[2] = {ENTRY(nullptr), {nullptr}}; #undef ENTRY #define assert1(expr) (expr) ? 0 : 1 diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-override.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-override.cpp index 809e435..8e19fdd 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-override.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-override.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s modernize-use-override,cppcoreguidelines-explicit-virtual-functions %t -- -- -fexceptions +// RUN: %check_clang_tidy %s modernize-use-override,cppcoreguidelines-explicit-virtual-functions %t -- -- -fexceptions #define ABSTRACT = 0 @@ -96,7 +96,8 @@ public: // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using // CHECK-FIXES: void j() const override; - virtual MustUseResultObject k(); // Has an implicit attribute. + // Has an implicit attribute. + virtual MustUseResultObject k(); // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using // CHECK-FIXES: MustUseResultObject k() override; @@ -203,7 +204,8 @@ public: // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using // CHECK-FIXES: void j() const override - virtual MustUseResultObject k(); // Has an implicit attribute. + // Has an implicit attribute. + virtual MustUseResultObject k(); // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using // CHECK-FIXES: MustUseResultObject k() override; diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format.cpp index ea97d5b..6a6cb98 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-format.cpp @@ -1,11 +1,11 @@ -// RUN: %check_clang_tidy --match-partial-fixes \ -// RUN: -std=c++20 %s modernize-use-std-format %t -- \ +// RUN: %check_clang_tidy \ +// RUN: -std=c++20-or-later %s modernize-use-std-format %t -- \ // RUN: -config="{CheckOptions: {modernize-use-std-format.StrictMode: true}}" \ // RUN: -- -isystem %clang_tidy_headers \ // RUN: -DPRI_CMDLINE_MACRO="\"s\"" \ // RUN: -D__PRI_CMDLINE_MACRO="\"s\"" -// RUN: %check_clang_tidy --match-partial-fixes \ -// RUN: -std=c++20 %s modernize-use-std-format %t -- \ +// RUN: %check_clang_tidy \ +// RUN: -std=c++20-or-later %s modernize-use-std-format %t -- \ // RUN: -config="{CheckOptions: {modernize-use-std-format.StrictMode: false}}" \ // RUN: -- -isystem %clang_tidy_headers \ // RUN: -DPRI_CMDLINE_MACRO="\"s\"" \ @@ -70,32 +70,32 @@ std::string StrFormat_strict_conversion() { std::string StrFormat_field_width_and_precision() { auto s1 = absl::StrFormat("width only:%*d width and precision:%*.*f precision only:%.*f", 3, 42, 4, 2, 3.14159265358979323846, 5, 2.718); // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format] - // CHECK-FIXES: std::format("width only:{:{}} width and precision:{:{}.{}f} precision only:{:.{}f}", 42, 3, 3.14159265358979323846, 4, 2, 2.718, 5); + // CHECK-FIXES: auto s1 = std::format("width only:{:{}} width and precision:{:{}.{}f} precision only:{:.{}f}", 42, 3, 3.14159265358979323846, 4, 2, 2.718, 5); auto s2 = absl::StrFormat("width and precision positional:%1$*2$.*3$f after", 3.14159265358979323846, 4, 2); // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format] - // CHECK-FIXES: std::format("width and precision positional:{0:{1}.{2}f} after", 3.14159265358979323846, 4, 2); + // CHECK-FIXES: auto s2 = std::format("width and precision positional:{0:{1}.{2}f} after", 3.14159265358979323846, 4, 2); const int width = 10, precision = 3; const unsigned int ui1 = 42, ui2 = 43, ui3 = 44; auto s3 = absl::StrFormat("casts width only:%*d width and precision:%*.*d precision only:%.*d\n", 3, ui1, 4, 2, ui2, 5, ui3); // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format] - // CHECK-FIXES-NOTSTRICT: std::format("casts width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", ui1, 3, ui2, 4, 2, ui3, 5); - // CHECK-FIXES-STRICT: std::format("casts width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", static_cast<int>(ui1), 3, static_cast<int>(ui2), 4, 2, static_cast<int>(ui3), 5); + // CHECK-FIXES-NOTSTRICT: auto s3 = std::format("casts width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", ui1, 3, ui2, 4, 2, ui3, 5); + // CHECK-FIXES-STRICT: auto s3 = std::format("casts width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", static_cast<int>(ui1), 3, static_cast<int>(ui2), 4, 2, static_cast<int>(ui3), 5); auto s4 = absl::StrFormat("c_str removal width only:%*s width and precision:%*.*s precision only:%.*s", 3, s1.c_str(), 4, 2, s2.c_str(), 5, s3.c_str()); // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format] - // CHECK-FIXES: std::format("c_str removal width only:{:>{}} width and precision:{:>{}.{}} precision only:{:.{}}", s1, 3, s2, 4, 2, s3, 5); + // CHECK-FIXES: auto s4 = std::format("c_str removal width only:{:>{}} width and precision:{:>{}.{}} precision only:{:.{}}", s1, 3, s2, 4, 2, s3, 5); const std::string *ps1 = &s1, *ps2 = &s2, *ps3 = &s3; auto s5 = absl::StrFormat("c_str() removal pointer width only:%-*s width and precision:%-*.*s precision only:%-.*s", 3, ps1->c_str(), 4, 2, ps2->c_str(), 5, ps3->c_str()); // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format] - // CHECK-FIXES: std::format("c_str() removal pointer width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *ps1, 3, *ps2, 4, 2, *ps3, 5); + // CHECK-FIXES: auto s5 = std::format("c_str() removal pointer width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *ps1, 3, *ps2, 4, 2, *ps3, 5); iterator<std::string> is1, is2, is3; auto s6 = absl::StrFormat("c_str() removal iterator width only:%-*s width and precision:%-*.*s precision only:%-.*s", 3, is1->c_str(), 4, 2, is2->c_str(), 5, is3->c_str()); // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format] - // CHECK-FIXES: std::format("c_str() removal iterator width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *is1, 3, *is2, 4, 2, *is3, 5); + // CHECK-FIXES: auto s6 = std::format("c_str() removal iterator width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *is1, 3, *is2, 4, 2, *is3, 5); return s1 + s2 + s3 + s4 + s5 + s6; } @@ -105,7 +105,7 @@ void StrFormat_macros() { #define FORMAT absl::StrFormat auto s1 = FORMAT("Hello %d", 42); // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format] - // CHECK-FIXES: std::format("Hello {}", 42); + // CHECK-FIXES: auto s1 = std::format("Hello {}", 42); // Arguments that are macros aren't replaced with their value, even if they are rearranged. #define VALUE 3.14159265358979323846 @@ -113,7 +113,7 @@ void StrFormat_macros() { #define PRECISION 4 auto s3 = absl::StrFormat("Hello %*.*f", WIDTH, PRECISION, VALUE); // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format] - // CHECK-FIXES: std::format("Hello {:{}.{}f}", VALUE, WIDTH, PRECISION); + // CHECK-FIXES: auto s3 = std::format("Hello {:{}.{}f}", VALUE, WIDTH, PRECISION); const uint64_t u64 = 42; const uint32_t u32 = 32; @@ -121,11 +121,11 @@ void StrFormat_macros() { auto s4 = absl::StrFormat("Replaceable macro at end %" PRIu64, u64); // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format] - // CHECK-FIXES: std::format("Replaceable macro at end {}", u64); + // CHECK-FIXES: auto s4 = std::format("Replaceable macro at end {}", u64); auto s5 = absl::StrFormat("Replaceable macros in middle %" PRIu64 " %" PRIu32 "\n", u64, u32); // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'std::format' instead of 'StrFormat' [modernize-use-std-format] - // CHECK-FIXES: std::format("Replaceable macros in middle {} {}\n", u64, u32); + // CHECK-FIXES: auto s5 = std::format("Replaceable macros in middle {} {}\n", u64, u32); // These need PRI and __PRI prefixes so that the check get as far as looking for // where the macro comes from. diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp index 9bf60e7..ec37f07 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp @@ -1,11 +1,11 @@ -// RUN: %check_clang_tidy --match-partial-fixes -check-suffixes=,STRICT \ -// RUN: -std=c++23 %s modernize-use-std-print %t -- \ +// RUN: %check_clang_tidy -check-suffixes=,STRICT \ +// RUN: -std=c++23-or-later %s modernize-use-std-print %t -- \ // RUN: -config="{CheckOptions: {modernize-use-std-print.StrictMode: true}}" \ // RUN: -- -isystem %clang_tidy_headers -fexceptions \ // RUN: -DPRI_CMDLINE_MACRO="\"s\"" \ // RUN: -D__PRI_CMDLINE_MACRO="\"s\"" -// RUN: %check_clang_tidy --match-partial-fixes -check-suffixes=,NOTSTRICT \ -// RUN: -std=c++23 %s modernize-use-std-print %t -- \ +// RUN: %check_clang_tidy -check-suffixes=,NOTSTRICT \ +// RUN: -std=c++23-or-later %s modernize-use-std-print %t -- \ // RUN: -config="{CheckOptions: {modernize-use-std-print.StrictMode: false}}" \ // RUN: -- -isystem %clang_tidy_headers -fexceptions \ // RUN: -DPRI_CMDLINE_MACRO="\"s\"" \ @@ -113,7 +113,7 @@ int printf_uses_return_value(int choice) { for (printf("for init statement %d\n", i);;) // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] - // CHECK-FIXES: std::println("for init statement {}", i); + // CHECK-FIXES: for (std::println("for init statement {}", i);;) ;; for (int j = printf("for init statement %d\n", i);;) @@ -124,7 +124,7 @@ int printf_uses_return_value(int choice) { for (;; printf("for expression %d\n", i)) // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] - // CHECK-FIXES: std::println("for expression {}", i) + // CHECK-FIXES: for (;; std::println("for expression {}", i)) ;; for (auto C : "foo") @@ -228,7 +228,7 @@ int fprintf_uses_return_value(int choice) { for (fprintf(stderr, "for init statement %d\n", i);;) // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] - // CHECK-FIXES: std::println(stderr, "for init statement {}", i); + // CHECK-FIXES: for (std::println(stderr, "for init statement {}", i);;) ;; for (int j = fprintf(stderr, "for init statement %d\n", i);;) @@ -239,7 +239,7 @@ int fprintf_uses_return_value(int choice) { for (;; fprintf(stderr, "for expression %d\n", i)) // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] - // CHECK-FIXES: std::println(stderr, "for expression {}", i) + // CHECK-FIXES: for (;; std::println(stderr, "for expression {}", i)) ;; for (auto C : "foo") diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/noexcept-move-constructor-fix.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/noexcept-move-constructor-fix.cpp index 53d66ec..967fd0f 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/performance/noexcept-move-constructor-fix.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance/noexcept-move-constructor-fix.cpp @@ -1,33 +1,33 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s performance-noexcept-move-constructor %t -- -- -fexceptions +// RUN: %check_clang_tidy %s performance-noexcept-move-constructor %t -- -- -fexceptions struct C_1 { ~C_1() {} C_1(int a) {} C_1(C_1&& a) :C_1(5) {} - // CHECK-FIXES: ){{.*}}noexcept{{.*}}: + // CHECK-FIXES: C_1(C_1&& a) noexcept :C_1(5) {} C_1& operator=(C_1&&) { return *this; } - // CHECK-FIXES: ){{.*}}noexcept{{.*}} { + // CHECK-FIXES: C_1& operator=(C_1&&) noexcept { return *this; } }; struct C_2 { ~C_2() {} C_2(C_2&& a); -// CHECK-FIXES: ){{.*}}noexcept{{.*}}; +// CHECK-FIXES: C_2(C_2&& a) noexcept ; C_2& operator=(C_2&&); -// CHECK-FIXES: ){{.*}}noexcept{{.*}}; +// CHECK-FIXES: C_2& operator=(C_2&&) noexcept ; }; C_2::C_2(C_2&& a) {} -// CHECK-FIXES: ){{.*}}noexcept{{.*}} {} +// CHECK-FIXES: C_2::C_2(C_2&& a) noexcept {} C_2& C_2::operator=(C_2&&) { return *this; } -// CHECK-FIXES: ){{.*}}noexcept{{.*}} { +// CHECK-FIXES: C_2& C_2::operator=(C_2&&) noexcept { return *this; } struct C_3 { ~C_3() {} C_3(C_3&& a); -// CHECK-FIXES: ){{.*}}noexcept{{.*}}; +// CHECK-FIXES: C_3(C_3&& a) noexcept ; C_3& operator=(C_3&& a); -// CHECK-FIXES: ){{.*}}noexcept{{.*}}; +// CHECK-FIXES: C_3& operator=(C_3&& a) noexcept ; }; C_3::C_3(C_3&& a) = default; @@ -36,7 +36,7 @@ C_3& C_3::operator=(C_3&& a) = default; template <class T> struct C_4 { C_4(C_4<T>&&) {} -// CHECK-FIXES: ){{.*}}noexcept{{.*}} {} +// CHECK-FIXES: C_4(C_4<T>&&) noexcept {} ~C_4() {} C_4& operator=(C_4&& a) = default; }; @@ -44,7 +44,7 @@ struct C_4 { template <class T> struct C_5 { C_5(C_5<T>&&) {} -// CHECK-FIXES:){{.*}}noexcept{{.*}} {} +// CHECK-FIXES: C_5(C_5<T>&&) noexcept {} ~C_5() {} auto operator=(C_5&& a)->C_5<T> = default; }; @@ -52,12 +52,12 @@ struct C_5 { template <class T> struct C_6 { C_6(C_6<T>&&) {} -// CHECK-FIXES:){{.*}}noexcept{{.*}} {} +// CHECK-FIXES: C_6(C_6<T>&&) noexcept {} ~C_6() {} auto operator=(C_6&& a)->C_6<T>; -// CHECK-FIXES:){{.*}}noexcept{{.*}}; +// CHECK-FIXES: auto operator=(C_6&& a) noexcept ->C_6<T>; }; template <class T> auto C_6<T>::operator=(C_6<T>&& a) -> C_6<T> {} -// CHECK-FIXES: ){{.*}}noexcept{{.*}} {} +// CHECK-FIXES: auto C_6<T>::operator=(C_6<T>&& a) noexcept -> C_6<T> {} diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-copy-initialization.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-copy-initialization.cpp index 0168aee..4818e9d 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-copy-initialization.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-copy-initialization.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes -std=c++17-or-later %s performance-unnecessary-copy-initialization %t +// RUN: %check_clang_tidy -std=c++17-or-later %s performance-unnecessary-copy-initialization %t template <typename T> struct Iterator { @@ -469,7 +469,7 @@ struct NegativeConstructor { auto AssignedInMacro = T.reference(); \ } \ // Ensure fix is not applied. -// CHECK-FIXES: auto AssignedInMacro = T.reference(); +// CHECK-FIXES: auto AssignedInMacro = T.reference(); {{\\}} UNNECESSARY_COPY_INIT_IN_MACRO_BODY(ExpensiveToCopyType) // CHECK-MESSAGES: [[@LINE-1]]:1: warning: the variable 'AssignedInMacro' of type 'ExpensiveToCopyType' is copy-constructed @@ -480,7 +480,7 @@ void PositiveMacroArgument(const ExpensiveToCopyType &Obj) { UNNECESSARY_COPY_INIT_IN_MACRO_ARGUMENT(auto CopyInMacroArg = Obj.reference()); // CHECK-MESSAGES: [[@LINE-1]]:48: warning: the variable 'CopyInMacroArg' of type 'ExpensiveToCopyType' is copy-constructed // Ensure fix is not applied. - // CHECK-FIXES: auto CopyInMacroArg = Obj.reference() + // CHECK-FIXES: UNNECESSARY_COPY_INIT_IN_MACRO_ARGUMENT(auto CopyInMacroArg = Obj.reference()); CopyInMacroArg.constMethod(); } diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-delayed.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-delayed.cpp index 9df1d6f..42d7699 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-delayed.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-delayed.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s performance-unnecessary-value-param %t -- -- -fdelayed-template-parsing +// RUN: %check_clang_tidy %s performance-unnecessary-value-param %t -- -- -fdelayed-template-parsing struct ExpensiveToCopyType { const ExpensiveToCopyType & constReference() const { @@ -152,7 +152,7 @@ void NegativeTypedefParam(const Container<ExpensiveToCopyType>::const_reference void inMacro(const ExpensiveToCopyType T) { \ } \ // Ensure fix is not applied. -// CHECK-FIXES: void inMacro(const ExpensiveToCopyType T) { +// CHECK-FIXES: void inMacro(const ExpensiveToCopyType T) { {{\\}} UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY() // CHECK-MESSAGES: [[@LINE-1]]:1: warning: the const qualified parameter 'T' @@ -162,7 +162,7 @@ UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY() UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(void inMacroArgument(const ExpensiveToCopyType InMacroArg) {}) // CHECK-MESSAGES: [[@LINE-1]]:90: warning: the const qualified parameter 'InMacroArg' -// CHECK-FIXES: void inMacroArgument(const ExpensiveToCopyType InMacroArg) {} +// CHECK-FIXES: UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(void inMacroArgument(const ExpensiveToCopyType InMacroArg) {}) struct VirtualMethod { virtual ~VirtualMethod() {} @@ -171,7 +171,7 @@ struct VirtualMethod { struct NegativeOverriddenMethod : public VirtualMethod { void handle(ExpensiveToCopyType Overridden) const { - // CHECK-FIXES: handle(ExpensiveToCopyType Overridden) const { + // CHECK-FIXES: void handle(ExpensiveToCopyType Overridden) const { } }; diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param.cpp index f657ff5..8dc13d3 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s performance-unnecessary-value-param %t -- -- -fno-delayed-template-parsing +// RUN: %check_clang_tidy %s performance-unnecessary-value-param %t -- -- -fno-delayed-template-parsing // CHECK-FIXES: #include <utility> @@ -215,7 +215,7 @@ void NegativeTypedefParam(const Container<ExpensiveToCopyType>::const_reference void inMacro(const ExpensiveToCopyType T) { \ } \ // Ensure fix is not applied. -// CHECK-FIXES: void inMacro(const ExpensiveToCopyType T) { +// CHECK-FIXES: void inMacro(const ExpensiveToCopyType T) { {{\\}} UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY() // CHECK-MESSAGES: [[@LINE-1]]:1: warning: the const qualified parameter 'T' @@ -225,7 +225,7 @@ UNNECESSARY_VALUE_PARAM_IN_MACRO_BODY() UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(void inMacroArgument(const ExpensiveToCopyType InMacroArg) {}) // CHECK-MESSAGES: [[@LINE-1]]:90: warning: the const qualified parameter 'InMacroArg' -// CHECK-FIXES: void inMacroArgument(const ExpensiveToCopyType InMacroArg) {} +// CHECK-FIXES: UNNECESSARY_VALUE_PARAM_IN_MACRO_ARGUMENT(void inMacroArgument(const ExpensiveToCopyType InMacroArg) {}) struct VirtualMethod { virtual ~VirtualMethod() {} @@ -234,7 +234,7 @@ struct VirtualMethod { struct NegativeOverriddenMethod : public VirtualMethod { void handle(ExpensiveToCopyType Overridden) const { - // CHECK-FIXES: handle(ExpensiveToCopyType Overridden) const { + // CHECK-FIXES: void handle(ExpensiveToCopyType Overridden) const { } }; diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements.cpp index b74c4cb..f1bb4ed 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s readability-braces-around-statements %t +// RUN: %check_clang_tidy %s readability-braces-around-statements %t void do_something(const char *) {} @@ -77,9 +77,6 @@ void test() { // CHECK-FIXES-NEXT: do_something("for"); // CHECK-FIXES-NEXT: } - for (;;) { - do_something("for-ok"); - } for (;;) ; // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: statement should be inside braces @@ -87,6 +84,10 @@ void test() { // CHECK-FIXES-NEXT: ; // CHECK-FIXES-NEXT: } + for (;;) { + do_something("for-ok"); + } + int arr[4] = {1, 2, 3, 4}; for (int a : arr) do_something("for-range"); @@ -378,7 +379,7 @@ int test_macros(bool b) { #define WRAP(X) { X; } // This is to ensure no other CHECK-FIXES matches the macro definition: - // CHECK-FIXES: WRAP + // CHECK-FIXES: #define WRAP(X) { X; } // Use-case: LLVM_DEBUG({ for(...) do_something(); }); WRAP({ diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/const-return-type.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/const-return-type.cpp index 43a7ddb..d78ea34 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/const-return-type.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/const-return-type.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes -std=c++14-or-later %s readability-const-return-type %t -- -- -Wno-error=return-type +// RUN: %check_clang_tidy -std=c++14-or-later %s readability-const-return-type %t -- -- -Wno-error=return-type // p# = positive test // n# = negative test @@ -66,7 +66,7 @@ class Clazz { const Klazz<const int>* const p5() const; // CHECK-FIXES: const Klazz<const int>* p5() const; - const Clazz operator++(int x) { // p12 + const Clazz operator++(int x) { // CHECK-MESSAGES: [[@LINE-1]]:3: warning: return type 'const Clazz' is 'const // CHECK-FIXES: Clazz operator++(int x) { } diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp index 8950c72..7844275 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes -std=c++14-or-later %s readability-container-size-empty %t -- \ +// RUN: %check_clang_tidy -std=c++14-or-later %s readability-container-size-empty %t -- \ // RUN: -config="{CheckOptions: {readability-container-size-empty.ExcludedComparisonTypes: '::std::array;::IgnoredDummyType'}}" \ // RUN: -- -fno-delayed-template-parsing -isystem %clang_tidy_headers #include <string> @@ -807,7 +807,7 @@ bool testStringLiterals(const std::string& s) using namespace std::string_literals; return s == ""s; // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used - // CHECK-FIXES: return s.empty() + // CHECK-FIXES: return s.empty(); } bool testNotEmptyStringLiterals(const std::string& s) @@ -951,7 +951,7 @@ public: void doit() { if (!size()) { // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used to check for emptiness instead of 'size' - // CHECK-FIXES: if (empty()) + // CHECK-FIXES: if (empty()) { } } }; diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c index 5a4627a..7f82b95 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy -std=c23-or-later --match-partial-fixes %s readability-implicit-bool-conversion %t +// RUN: %check_clang_tidy -std=c23-or-later %s readability-implicit-bool-conversion %t // RUN: %check_clang_tidy -std=c23-or-later -check-suffix=UPPER-CASE %s readability-implicit-bool-conversion %t -- \ // RUN: -config='{CheckOptions: { \ // RUN: readability-implicit-bool-conversion.UseUpperCaseLiteralSuffix: true \ @@ -341,28 +341,28 @@ int implicitConversionReturnInt() { return true; // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int' - // CHECK-FIXES: return 1 + // CHECK-FIXES: return 1; } int implicitConversionReturnIntWithParens() { return (true); // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int' - // CHECK-FIXES: return 1 + // CHECK-FIXES: return 1; } bool implicitConversionReturnBool() { return 1; // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool' - // CHECK-FIXES: return true + // CHECK-FIXES: return true; } bool implicitConversionReturnBoolWithParens() { return (1); // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool' - // CHECK-FIXES: return true + // CHECK-FIXES: return true; } int keepCompactReturnInC_PR71848() { diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp index a0e1fd3..c3faf8a 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s readability-implicit-bool-conversion %t +// RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t // RUN: %check_clang_tidy -check-suffix=UPPER-CASE %s readability-implicit-bool-conversion %t -- \ // RUN: -config='{CheckOptions: { \ // RUN: readability-implicit-bool-conversion.UseUpperCaseLiteralSuffix: true \ @@ -490,14 +490,14 @@ int implicitConversionReturnInt() { return true; // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int' - // CHECK-FIXES: return 1 + // CHECK-FIXES: return 1; } int implicitConversionReturnIntWithParens() { return (true); // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'bool' -> 'int' - // CHECK-FIXES: return 1 + // CHECK-FIXES: return 1; } @@ -505,14 +505,14 @@ bool implicitConversionReturnBool() { return 1; // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool' - // CHECK-FIXES: return true + // CHECK-FIXES: return true; } bool implicitConversionReturnBoolWithParens() { return (1); // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: implicit conversion 'int' -> 'bool' - // CHECK-FIXES: return true + // CHECK-FIXES: return true; } diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp index 947eda0..b9f9226 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s readability-math-missing-parentheses %t +// RUN: %check_clang_tidy %s readability-math-missing-parentheses %t #define MACRO_AND & #define MACRO_ADD + @@ -123,7 +123,7 @@ void f(){ //CHECK-MESSAGES: :[[@LINE+3]]:77: warning: '-' has higher precedence than '^'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] //CHECK-MESSAGES: :[[@LINE+2]]:94: warning: '/' has higher precedence than '-'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] //CHECK-FIXES: int q = (1 MACRO_ADD (2 MACRO_MULTIPLY 3)) MACRO_OR ((4 MACRO_AND 5) MACRO_XOR (6 MACRO_SUBTRACT (7 MACRO_DIVIDE 8))); - int q = 1 MACRO_ADD 2 MACRO_MULTIPLY 3 MACRO_OR 4 MACRO_AND 5 MACRO_XOR 6 MACRO_SUBTRACT 7 MACRO_DIVIDE 8; // No warning + int q = 1 MACRO_ADD 2 MACRO_MULTIPLY 3 MACRO_OR 4 MACRO_AND 5 MACRO_XOR 6 MACRO_SUBTRACT 7 MACRO_DIVIDE 8; //CHECK-MESSAGES: :[[@LINE+1]]:21: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] int r = FUN(0 + 1 * 2); diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr-members.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr-members.cpp index 83f2fa9..89208fb 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr-members.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr-members.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s readability-simplify-boolean-expr %t +// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t class A { public: @@ -353,4 +353,4 @@ bool S::expr_with_cleanups() { return true; } // CHECK-MESSAGES: :[[@LINE-4]]:12: warning: {{.*}} in conditional return -// CHECK-FIXES: m_ar == (A)m_ar; +// CHECK-FIXES: return m_ar == (A)m_ar; diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr.cpp index ee5ff7b..0b99cb8 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/simplify-boolean-expr.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s readability-simplify-boolean-expr %t +// RUN: %check_clang_tidy %s readability-simplify-boolean-expr %t bool a1 = false; @@ -1019,7 +1019,7 @@ bool expr_with_cleanups(A &S) { return true; } // CHECK-MESSAGES: :[[@LINE-4]]:12: warning: {{.*}} in conditional return -// CHECK-FIXES: S == (A)S;{{$}} +// CHECK-FIXES: return S == (A)S;{{$}} template <bool B> void ignoreInstantiations() { diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer-custom-list.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer-custom-list.cpp index a4fcf3a..399afa5 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer-custom-list.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer-custom-list.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s readability-uppercase-literal-suffix %t -- -config="{CheckOptions: {readability-uppercase-literal-suffix.NewSuffixes: 'L;uL'}}" -- -I %clang_tidy_headers +// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -config="{CheckOptions: {readability-uppercase-literal-suffix.NewSuffixes: 'L;uL'}}" -- -I %clang_tidy_headers #include "integral_constant.h" @@ -53,7 +53,7 @@ void integer_suffix() { static_assert(is_same<decltype(v11), const unsigned long>::value, ""); static_assert(v11 == 1, ""); - static constexpr auto v12 = 1UL; // OK. + static constexpr auto v12 = 1UL; // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'UL', which is not uppercase // CHECK-FIXES: static constexpr auto v12 = 1uL; static_assert(is_same<decltype(v12), const unsigned long>::value, ""); diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/duplicate-conflicted-fixes-of-alias-checkers.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/duplicate-conflicted-fixes-of-alias-checkers.cpp index d40bb86..3659081 100644 --- a/clang-tools-extra/test/clang-tidy/infrastructure/duplicate-conflicted-fixes-of-alias-checkers.cpp +++ b/clang-tools-extra/test/clang-tidy/infrastructure/duplicate-conflicted-fixes-of-alias-checkers.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s cppcoreguidelines-pro-type-member-init,hicpp-member-init,modernize-use-emplace,hicpp-use-emplace %t -- \ +// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-member-init,hicpp-member-init,modernize-use-emplace,hicpp-use-emplace %t -- \ //// RUN: -config='{CheckOptions: { \ //// RUN: cppcoreguidelines-pro-type-member-init.UseAssignment: true, \ //// RUN: }}' @@ -19,5 +19,5 @@ public: private: int _num1; int _num2; - // CHECK-FIXES: _num2; + // CHECK-FIXES: int _num2; }; diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/duplicate-fixes-of-alias-checkers.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/duplicate-fixes-of-alias-checkers.cpp index 94cfa1a..78a903a 100644 --- a/clang-tools-extra/test/clang-tidy/infrastructure/duplicate-fixes-of-alias-checkers.cpp +++ b/clang-tools-extra/test/clang-tidy/infrastructure/duplicate-fixes-of-alias-checkers.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy --match-partial-fixes %s cppcoreguidelines-pro-type-member-init,hicpp-member-init,modernize-use-emplace,hicpp-use-emplace %t +// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-member-init,hicpp-member-init,modernize-use-emplace,hicpp-use-emplace %t namespace std { @@ -28,7 +28,7 @@ public: private: int _num1; int _num2; - // CHECK-FIXES: _num2{}; + // CHECK-FIXES: int _num2{}; }; void should_use_emplace(std::vector<Foo> &v) { diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e387d3a..1a4ec40 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -286,6 +286,7 @@ Deprecated Compiler Flags Modified Compiler Flags ----------------------- - The `-gkey-instructions` compiler flag is now enabled by default when DWARF is emitted for plain C/C++ and optimizations are enabled. (#GH149509) +- The `-fconstexpr-steps` compiler flag now accepts value `0` to opt out of this limit. (#GH160440) Removed Compiler Flags ------------------------- diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 5745e4b..2d10489 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -4036,7 +4036,7 @@ Controlling implementation limits Sets the limit for the number of full-expressions evaluated in a single constant expression evaluation. This also controls the maximum size of array and dynamic array allocation that can be constant evaluated. - The default is 1048576. + The default is 1048576, and the limit can be disabled with `-fconstexpr-steps=0`. .. option:: -ftemplate-depth=N diff --git a/clang/docs/analyzer/developer-docs/Statistics.rst b/clang/docs/analyzer/developer-docs/Statistics.rst index 4f2484a..355759d 100644 --- a/clang/docs/analyzer/developer-docs/Statistics.rst +++ b/clang/docs/analyzer/developer-docs/Statistics.rst @@ -22,7 +22,7 @@ However, note that with ``LLVM_ENABLE_STATS`` disabled, only storage of the valu If you want to define a statistic only for entry point, EntryPointStats.h has four classes at your disposal: -- ``UnsignedEPStat`` - an unsigned value assigned at most once per entry point. For example: "the number of source characters in an entry-point body". +- ``UnsignedEPStat`` - an unsigned value assigned at most once per entry point. For example: "the number of source characters in an entry-point body". If no value is assigned during analysis of an entry point, the corresponding CSV cell will be empty. - ``CounterEPStat`` - an additive statistic. It starts with 0 and you can add to it as many times as needed. For example: "the number of bugs discovered". - ``UnsignedMaxEPStat`` - a maximizing statistic. It starts with 0 and when you join it with a value, it picks the maximum of the previous value and the new one. For example, "the longest execution path of a bug". diff --git a/clang/include/clang/AST/NestedNameSpecifierBase.h b/clang/include/clang/AST/NestedNameSpecifierBase.h index 73c60ba..8f4bbe9 100644 --- a/clang/include/clang/AST/NestedNameSpecifierBase.h +++ b/clang/include/clang/AST/NestedNameSpecifierBase.h @@ -361,6 +361,9 @@ public: /// Retrieve the source range covering just the last part of /// this nested-name-specifier, not including the prefix. /// + /// Note that this is the source range of this NestedNameSpecifier chunk, + /// and for a type this includes the prefix of that type. + /// /// For example, if this instance refers to a nested-name-specifier /// \c \::std::vector<int>::, the returned source range would cover /// from "vector" to the last '::'. diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index 38e8fba..3f14ee8 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -199,11 +199,6 @@ public: NestedNameSpecifierLoc getPrefix() const; /// This returns the position of the type after any elaboration, such as the - /// 'struct' keyword, and name qualifiers. This will the 'template' keyword if - /// present, or the name location otherwise. - SourceLocation getNonPrefixBeginLoc() const; - - /// This returns the position of the type after any elaboration, such as the /// 'struct' keyword. This may be the position of the name qualifiers, /// 'template' keyword, or the name location otherwise. SourceLocation getNonElaboratedBeginLoc() const; diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 3cde249..22e60aa 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -1599,8 +1599,15 @@ def CUDAShared : InheritableAttr { } def : MutualExclusions<[CUDAConstant, CUDAShared, HIPManaged]>; +def SYCLKernel : InheritableAttr { + let Spellings = [Clang<"sycl_kernel">]; + let Subjects = SubjectList<[FunctionTmpl]>; + let LangOpts = [SYCLDevice]; + let Documentation = [SYCLKernelDocs]; +} + def DeviceKernel : DeclOrTypeAttr { - let Spellings = [Clang<"device_kernel">, Clang<"sycl_kernel">, + let Spellings = [Clang<"device_kernel">, Clang<"nvptx_kernel">, Clang<"amdgpu_kernel">, CustomKeyword<"__kernel">, CustomKeyword<"kernel">]; let Documentation = [DeviceKernelDocs]; @@ -1624,15 +1631,6 @@ def DeviceKernel : DeclOrTypeAttr { if(!A) return false; return isNVPTXSpelling(*A); } - static inline bool isSYCLSpelling(const AttributeCommonInfo& A) { - return A.getAttributeSpellingListIndex() == GNU_sycl_kernel || - A.getAttributeSpellingListIndex() == CXX11_clang_sycl_kernel || - A.getAttributeSpellingListIndex() == C23_clang_sycl_kernel; - } - static inline bool isSYCLSpelling(const AttributeCommonInfo* A) { - if(!A) return false; - return isSYCLSpelling(*A); - } static inline bool isOpenCLSpelling(const AttributeCommonInfo& A) { // Tablegen trips underscores from spellings to build the spelling // list, but here we have the same spelling with unscores and without, diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 20a52b4..e0bbda0 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -396,13 +396,10 @@ any option of a multiversioned function is undefined. }]; } -def DeviceKernelDocs : Documentation { +def SYCLKernelDocs : Documentation { let Category = DocCatFunction; - let Heading = "device_kernel, sycl_kernel, nvptx_kernel, amdgpu_kernel, " - "kernel, __kernel"; + let Heading = "sycl_kernel"; let Content = [{ -These attributes specify that the function represents a kernel for device offloading. -The specific semantics depend on the offloading language, target, and attribute spelling. The ``sycl_kernel`` attribute specifies that a function template will be used to outline device code and to generate an OpenCL kernel. Here is a code example of the SYCL program, which demonstrates the compiler's @@ -476,6 +473,21 @@ The SYCL kernel in the previous code sample meets these expectations. }]; } +def DeviceKernelDocs : Documentation { + let Category = DocCatFunction; + let Heading = "device_kernel, nvptx_kernel, amdgpu_kernel, " + "kernel, __kernel"; + let Content = [{ +These attributes specify that the function represents a kernel for device offloading. +The specific semantics depend on the offloading language, target, and attribute spelling. +Here is a code example using the attribute to mark a function as a kernel: + +.. code-block:: c++ + + [[clang::device_kernel]] int foo(int x) { return ++x; } + }]; +} + def SYCLExternalDocs : Documentation { let Category = DocCatFunction; let Heading = "sycl_external"; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index a55a523..611b68e 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2047,7 +2047,7 @@ def fconstexpr_depth_EQ : Joined<["-"], "fconstexpr-depth=">, Group<f_Group>, MarshallingInfoInt<LangOpts<"ConstexprCallDepth">, "512">; def fconstexpr_steps_EQ : Joined<["-"], "fconstexpr-steps=">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>, - HelpText<"Set the maximum number of steps in constexpr function evaluation">, + HelpText<"Set the maximum number of steps in constexpr function evaluation (0 = no limit)">, MarshallingInfoInt<LangOpts<"ConstexprStepLimit">, "1048576">; def fexperimental_new_constant_interpreter : Flag<["-"], "fexperimental-new-constant-interpreter">, Group<f_Group>, HelpText<"Enable the experimental new constant interpreter">, diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index 46b088c..f9d3a4ea 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -215,7 +215,6 @@ public: bool diagnosePositionType(QualType T, const ParsedAttr &AL); bool CanPerformScalarCast(QualType SrcTy, QualType DestTy); - bool ContainsBitField(QualType BaseTy); bool CanPerformElementwiseCast(Expr *Src, QualType DestType); bool CanPerformAggregateSplatCast(Expr *Src, QualType DestType); ExprResult ActOnOutParamExpr(ParmVarDecl *Param, Expr *Arg); diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h index 389f17d..f3c6a62 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h @@ -9,6 +9,7 @@ #ifndef CLANG_INCLUDE_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENTRYPOINTSTATS_H #define CLANG_INCLUDE_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENTRYPOINTSTATS_H +#include "clang/AST/ASTContext.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringRef.h" @@ -25,7 +26,7 @@ class EntryPointStat { public: llvm::StringLiteral name() const { return Name; } - static void lockRegistry(llvm::StringRef CPPFileName); + static void lockRegistry(llvm::StringRef CPPFileName, ASTContext &Ctx); static void takeSnapshot(const Decl *EntryPoint); static void dumpStatsAsCSV(llvm::raw_ostream &OS); @@ -85,7 +86,7 @@ class UnsignedEPStat : public EntryPointStat { public: explicit UnsignedEPStat(llvm::StringLiteral Name); - unsigned value() const { return Value.value_or(0); } + std::optional<unsigned> value() const { return Value; } void reset() { Value.reset(); } void set(unsigned V) { assert(!Value.has_value()); diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index a9c71c7..57cc705 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -3699,7 +3699,7 @@ inline bool CheckDestruction(InterpState &S, CodePtr OpPC) { inline bool CheckArraySize(InterpState &S, CodePtr OpPC, uint64_t NumElems) { uint64_t Limit = S.getLangOpts().ConstexprStepLimit; - if (NumElems > Limit) { + if (Limit != 0 && NumElems > Limit) { S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_new_exceeds_limits) << NumElems << Limit; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index a3037c3f..dfdfef2 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -990,7 +990,7 @@ namespace { // of arrays to avoid exhausting the system resources, as initialization // of each element is likely to take some number of steps anyway. uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit; - if (ElemCount > Limit) { + if (Limit != 0 && ElemCount > Limit) { if (Diag) FFDiag(Loc, diag::note_constexpr_new_exceeds_limits) << ElemCount << Limit; @@ -1016,6 +1016,9 @@ namespace { } bool nextStep(const Stmt *S) { + if (Ctx.getLangOpts().ConstexprStepLimit == 0) + return true; + if (!StepsLeft) { FFDiag(S->getBeginLoc(), diag::note_constexpr_step_limit_exceeded); return false; @@ -1186,7 +1189,8 @@ namespace { /// Should we continue evaluation as much as possible after encountering a /// construct which can't be reduced to a value? bool keepEvaluatingAfterFailure() const override { - if (!StepsLeft) + uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit; + if (Limit != 0 && !StepsLeft) return false; switch (EvalMode) { diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index 55476e2..e952e82 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -494,39 +494,6 @@ NestedNameSpecifierLoc TypeLoc::getPrefix() const { } } -SourceLocation TypeLoc::getNonPrefixBeginLoc() const { - switch (getTypeLocClass()) { - case TypeLoc::TemplateSpecialization: { - auto TL = castAs<TemplateSpecializationTypeLoc>(); - SourceLocation Loc = TL.getTemplateKeywordLoc(); - if (!Loc.isValid()) - Loc = TL.getTemplateNameLoc(); - return Loc; - } - case TypeLoc::DeducedTemplateSpecialization: { - auto TL = castAs<DeducedTemplateSpecializationTypeLoc>(); - SourceLocation Loc = TL.getTemplateKeywordLoc(); - if (!Loc.isValid()) - Loc = TL.getTemplateNameLoc(); - return Loc; - } - case TypeLoc::DependentName: - return castAs<DependentNameTypeLoc>().getNameLoc(); - case TypeLoc::Enum: - case TypeLoc::Record: - case TypeLoc::InjectedClassName: - return castAs<TagTypeLoc>().getNameLoc(); - case TypeLoc::Typedef: - return castAs<TypedefTypeLoc>().getNameLoc(); - case TypeLoc::UnresolvedUsing: - return castAs<UnresolvedUsingTypeLoc>().getNameLoc(); - case TypeLoc::Using: - return castAs<UsingTypeLoc>().getNameLoc(); - default: - return getBeginLoc(); - } -} - SourceLocation TypeLoc::getNonElaboratedBeginLoc() const { // For elaborated types (e.g. `struct a::A`) we want the portion after the // `struct` but including the namespace qualifier, `a::`. diff --git a/clang/lib/CIR/CodeGen/Address.h b/clang/lib/CIR/CodeGen/Address.h index fb74aa0..a67cbad 100644 --- a/clang/lib/CIR/CodeGen/Address.h +++ b/clang/lib/CIR/CodeGen/Address.h @@ -17,6 +17,7 @@ #include "mlir/IR/Value.h" #include "clang/AST/CharUnits.h" #include "clang/CIR/Dialect/IR/CIRTypes.h" +#include "clang/CIR/MissingFeatures.h" #include "llvm/ADT/PointerIntPair.h" namespace clang::CIRGen { @@ -90,6 +91,13 @@ public: return getPointer(); } + /// Return the pointer contained in this class after authenticating it and + /// adding offset to it if necessary. + mlir::Value emitRawPointer() const { + assert(!cir::MissingFeatures::addressPointerAuthInfo()); + return getBasePointer(); + } + mlir::Type getType() const { assert(mlir::cast<cir::PointerType>( pointerAndKnownNonNull.getPointer().getType()) diff --git a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h index 06f41cd..6d3741c4 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h +++ b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h @@ -191,6 +191,15 @@ public: virtual void emitVTableDefinitions(CIRGenVTables &cgvt, const CXXRecordDecl *rd) = 0; + using DeleteOrMemberCallExpr = + llvm::PointerUnion<const CXXDeleteExpr *, const CXXMemberCallExpr *>; + + virtual mlir::Value emitVirtualDestructorCall(CIRGenFunction &cgf, + const CXXDestructorDecl *dtor, + CXXDtorType dtorType, + Address thisAddr, + DeleteOrMemberCallExpr e) = 0; + /// Emit any tables needed to implement virtual inheritance. For Itanium, /// this emits virtual table tables. virtual void emitVirtualInheritanceTables(const CXXRecordDecl *rd) = 0; diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp index 485b2c8..dd357ce 100644 --- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp @@ -895,6 +895,26 @@ void CIRGenFunction::destroyCXXObject(CIRGenFunction &cgf, Address addr, } namespace { +mlir::Value loadThisForDtorDelete(CIRGenFunction &cgf, + const CXXDestructorDecl *dd) { + if (Expr *thisArg = dd->getOperatorDeleteThisArg()) + return cgf.emitScalarExpr(thisArg); + return cgf.loadCXXThis(); +} + +/// Call the operator delete associated with the current destructor. +struct CallDtorDelete final : EHScopeStack::Cleanup { + CallDtorDelete() {} + + void emit(CIRGenFunction &cgf) override { + const CXXDestructorDecl *dtor = cast<CXXDestructorDecl>(cgf.curFuncDecl); + const CXXRecordDecl *classDecl = dtor->getParent(); + cgf.emitDeleteCall(dtor->getOperatorDelete(), + loadThisForDtorDelete(cgf, dtor), + cgf.getContext().getCanonicalTagType(classDecl)); + } +}; + class DestroyField final : public EHScopeStack::Cleanup { const FieldDecl *field; CIRGenFunction::Destroyer *destroyer; @@ -932,7 +952,18 @@ void CIRGenFunction::enterDtorCleanups(const CXXDestructorDecl *dd, // The deleting-destructor phase just needs to call the appropriate // operator delete that Sema picked up. if (dtorType == Dtor_Deleting) { - cgm.errorNYI(dd->getSourceRange(), "deleting destructor cleanups"); + assert(dd->getOperatorDelete() && + "operator delete missing - EnterDtorCleanups"); + if (cxxStructorImplicitParamValue) { + cgm.errorNYI(dd->getSourceRange(), "deleting destructor with vtt"); + } else { + if (dd->getOperatorDelete()->isDestroyingOperatorDelete()) { + cgm.errorNYI(dd->getSourceRange(), + "deleting destructor with destroying operator delete"); + } else { + ehStack.pushCleanup<CallDtorDelete>(NormalAndEHCleanup); + } + } return; } diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp index 97c0944..b1e9e76 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp @@ -130,13 +130,11 @@ RValue CIRGenFunction::emitCXXMemberOrOperatorMemberCallExpr( const CXXMethodDecl *calleeDecl = devirtualizedMethod ? devirtualizedMethod : md; const CIRGenFunctionInfo *fInfo = nullptr; - if (isa<CXXDestructorDecl>(calleeDecl)) { - cgm.errorNYI(ce->getSourceRange(), - "emitCXXMemberOrOperatorMemberCallExpr: destructor call"); - return RValue::get(nullptr); - } - - fInfo = &cgm.getTypes().arrangeCXXMethodDeclaration(calleeDecl); + if (const auto *dtor = dyn_cast<CXXDestructorDecl>(calleeDecl)) + fInfo = &cgm.getTypes().arrangeCXXStructorDeclaration( + GlobalDecl(dtor, Dtor_Complete)); + else + fInfo = &cgm.getTypes().arrangeCXXMethodDeclaration(calleeDecl); cir::FuncType ty = cgm.getTypes().getFunctionType(*fInfo); @@ -151,9 +149,34 @@ RValue CIRGenFunction::emitCXXMemberOrOperatorMemberCallExpr( // because then we know what the type is. bool useVirtualCall = canUseVirtualCall && !devirtualizedMethod; - if (isa<CXXDestructorDecl>(calleeDecl)) { - cgm.errorNYI(ce->getSourceRange(), - "emitCXXMemberOrOperatorMemberCallExpr: destructor call"); + if (const auto *dtor = dyn_cast<CXXDestructorDecl>(calleeDecl)) { + assert(ce->arg_begin() == ce->arg_end() && + "Destructor shouldn't have explicit parameters"); + assert(returnValue.isNull() && "Destructor shouldn't have return value"); + if (useVirtualCall) { + cgm.getCXXABI().emitVirtualDestructorCall(*this, dtor, Dtor_Complete, + thisPtr.getAddress(), + cast<CXXMemberCallExpr>(ce)); + } else { + GlobalDecl globalDecl(dtor, Dtor_Complete); + CIRGenCallee callee; + assert(!cir::MissingFeatures::appleKext()); + if (!devirtualizedMethod) { + callee = CIRGenCallee::forDirect( + cgm.getAddrOfCXXStructor(globalDecl, fInfo, ty), globalDecl); + } else { + cgm.errorNYI(ce->getSourceRange(), "devirtualized destructor call"); + return RValue::get(nullptr); + } + + QualType thisTy = + isArrow ? base->getType()->getPointeeType() : base->getType(); + // CIRGen does not pass CallOrInvoke here (different from OG LLVM codegen) + // because in practice it always null even in OG. + emitCXXDestructorCall(globalDecl, callee, thisPtr.getPointer(), thisTy, + /*implicitParam=*/nullptr, + /*implicitParamTy=*/QualType(), ce); + } return RValue::get(nullptr); } diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp index 7a774e0..01a43a99 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp @@ -678,7 +678,13 @@ void CIRGenFunction::emitDestructorBody(FunctionArgList &args) { // possible to delegate the destructor body to the complete // destructor. Do so. if (dtorType == Dtor_Deleting) { - cgm.errorNYI(dtor->getSourceRange(), "deleting destructor"); + RunCleanupsScope dtorEpilogue(*this); + enterDtorCleanups(dtor, Dtor_Deleting); + if (haveInsertPoint()) { + QualType thisTy = dtor->getFunctionObjectParameterType(); + emitCXXDestructorCall(dtor, Dtor_Complete, /*forVirtualBase=*/false, + /*delegating=*/false, loadCXXThisAddress(), thisTy); + } return; } diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp index 9e490c6d..d30c975 100644 --- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp @@ -95,7 +95,10 @@ public: clang::GlobalDecl gd, Address thisAddr, mlir::Type ty, SourceLocation loc) override; - + mlir::Value emitVirtualDestructorCall(CIRGenFunction &cgf, + const CXXDestructorDecl *dtor, + CXXDtorType dtorType, Address thisAddr, + DeleteOrMemberCallExpr e) override; mlir::Value getVTableAddressPoint(BaseSubobject base, const CXXRecordDecl *vtableClass) override; mlir::Value getVTableAddressPointInStructorWithVTT( @@ -465,6 +468,29 @@ void CIRGenItaniumCXXABI::emitVTableDefinitions(CIRGenVTables &cgvt, } } +mlir::Value CIRGenItaniumCXXABI::emitVirtualDestructorCall( + CIRGenFunction &cgf, const CXXDestructorDecl *dtor, CXXDtorType dtorType, + Address thisAddr, DeleteOrMemberCallExpr expr) { + auto *callExpr = dyn_cast<const CXXMemberCallExpr *>(expr); + auto *delExpr = dyn_cast<const CXXDeleteExpr *>(expr); + assert((callExpr != nullptr) ^ (delExpr != nullptr)); + assert(callExpr == nullptr || callExpr->arg_begin() == callExpr->arg_end()); + assert(dtorType == Dtor_Deleting || dtorType == Dtor_Complete); + + GlobalDecl globalDecl(dtor, dtorType); + const CIRGenFunctionInfo *fnInfo = + &cgm.getTypes().arrangeCXXStructorDeclaration(globalDecl); + const cir::FuncType &fnTy = cgm.getTypes().getFunctionType(*fnInfo); + auto callee = CIRGenCallee::forVirtual(callExpr, globalDecl, thisAddr, fnTy); + + QualType thisTy = + callExpr ? callExpr->getObjectType() : delExpr->getDestroyedType(); + + cgf.emitCXXDestructorCall(globalDecl, callee, thisAddr.emitRawPointer(), + thisTy, nullptr, QualType(), nullptr); + return nullptr; +} + void CIRGenItaniumCXXABI::emitVirtualInheritanceTables( const CXXRecordDecl *rd) { CIRGenVTables &vtables = cgm.getVTables(); diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index e65896a..2ab1ea0c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -619,10 +619,8 @@ const CIRGenFunctionInfo &CIRGenTypes::arrangeGlobalDeclaration(GlobalDecl gd) { const auto *fd = cast<FunctionDecl>(gd.getDecl()); if (isa<CXXConstructorDecl>(gd.getDecl()) || - isa<CXXDestructorDecl>(gd.getDecl())) { - cgm.errorNYI(SourceLocation(), - "arrangeGlobalDeclaration for C++ constructor or destructor"); - } + isa<CXXDestructorDecl>(gd.getDecl())) + return arrangeCXXStructorDeclaration(gd); return arrangeFunctionDeclaration(fd); } diff --git a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp index 84f5977..36bab62 100644 --- a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp @@ -120,12 +120,6 @@ mlir::Attribute CIRGenVTables::getVTableComponent( assert(!cir::MissingFeatures::vtableRelativeLayout()); switch (component.getKind()) { - case VTableComponent::CK_CompleteDtorPointer: - cgm.errorNYI("getVTableComponent: CompleteDtorPointer"); - return mlir::Attribute(); - case VTableComponent::CK_DeletingDtorPointer: - cgm.errorNYI("getVTableComponent: DeletingDtorPointer"); - return mlir::Attribute(); case VTableComponent::CK_UnusedFunctionPointer: cgm.errorNYI("getVTableComponent: UnusedFunctionPointer"); return mlir::Attribute(); @@ -148,7 +142,9 @@ mlir::Attribute CIRGenVTables::getVTableComponent( "expected GlobalViewAttr or ConstPtrAttr"); return rtti; - case VTableComponent::CK_FunctionPointer: { + case VTableComponent::CK_FunctionPointer: + case VTableComponent::CK_CompleteDtorPointer: + case VTableComponent::CK_DeletingDtorPointer: { GlobalDecl gd = component.getGlobalDecl(); assert(!cir::MissingFeatures::cudaSupport()); diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index fa94692..1ff2be7 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -1762,8 +1762,11 @@ void CGOpenMPRuntime::emitDeclareTargetFunction(const FunctionDecl *FD, // access its value. llvm::GlobalValue *Addr = GV; if (CGM.getLangOpts().OpenMPIsTargetDevice) { + llvm::PointerType *FnPtrTy = llvm::PointerType::get( + CGM.getLLVMContext(), + CGM.getModule().getDataLayout().getProgramAddressSpace()); Addr = new llvm::GlobalVariable( - CGM.getModule(), CGM.VoidPtrTy, + CGM.getModule(), FnPtrTy, /*isConstant=*/true, llvm::GlobalValue::ExternalLinkage, GV, Name, nullptr, llvm::GlobalValue::NotThreadLocal, CGM.getModule().getDataLayout().getDefaultGlobalsAddressSpace()); diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp index 3613b6a..fddeba9 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// // // This provides a generalized class for OpenMP runtime code generation -// specialized by GPU targets NVPTX and AMDGCN. +// specialized by GPU targets NVPTX, AMDGCN and SPIR-V. // //===----------------------------------------------------------------------===// @@ -1242,12 +1242,13 @@ void CGOpenMPRuntimeGPU::emitParallelCall( CGBuilderTy &Bld = CGF.Builder; llvm::Value *NumThreadsVal = NumThreads; llvm::Function *WFn = WrapperFunctionsMap[OutlinedFn]; - llvm::Value *ID = llvm::ConstantPointerNull::get(CGM.Int8PtrTy); - if (WFn) - ID = Bld.CreateBitOrPointerCast(WFn, CGM.Int8PtrTy); - llvm::Type *FnPtrTy = llvm::PointerType::get( + llvm::PointerType *FnPtrTy = llvm::PointerType::get( CGF.getLLVMContext(), CGM.getDataLayout().getProgramAddressSpace()); + llvm::Value *ID = llvm::ConstantPointerNull::get(FnPtrTy); + if (WFn) + ID = Bld.CreateBitOrPointerCast(WFn, FnPtrTy); + llvm::Value *FnPtr = Bld.CreateBitOrPointerCast(OutlinedFn, FnPtrTy); // Create a private scope that will globalize the arguments diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 0e83c20..8ac09c4 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -20797,7 +20797,7 @@ Sema::FunctionEmissionStatus Sema::getEmissionStatus(const FunctionDecl *FD, // SYCL functions can be template, so we check if they have appropriate // attribute prior to checking if it is a template. - if (LangOpts.SYCLIsDevice && FD->hasAttr<DeviceKernelAttr>()) + if (LangOpts.SYCLIsDevice && FD->hasAttr<SYCLKernelAttr>()) return FunctionEmissionStatus::Emitted; // Templates are emitted when they're instantiated. diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 328ccf6..3107876 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5204,16 +5204,7 @@ static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) { static void handleDeviceKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) { const auto *FD = dyn_cast_or_null<FunctionDecl>(D); bool IsFunctionTemplate = FD && FD->getDescribedFunctionTemplate(); - if (S.getLangOpts().SYCLIsDevice) { - if (!IsFunctionTemplate) { - S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type_str) - << AL << AL.isRegularKeywordAttribute() << "function templates"; - } else { - S.SYCL().handleKernelAttr(D, AL); - } - } else if (DeviceKernelAttr::isSYCLSpelling(AL)) { - S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL; - } else if (S.getASTContext().getTargetInfo().getTriple().isNVPTX()) { + if (S.getASTContext().getTargetInfo().getTriple().isNVPTX()) { handleGlobalAttr(S, D, AL); } else { // OpenCL C++ will throw a more specific error. @@ -7100,6 +7091,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_EnumExtensibility: handleEnumExtensibilityAttr(S, D, AL); break; + case ParsedAttr::AT_SYCLKernel: + S.SYCL().handleKernelAttr(D, AL); + break; case ParsedAttr::AT_SYCLExternal: handleSimpleAttribute<SYCLExternalAttr>(S, D, AL); break; diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 17cb1e4..72b2ac9 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -3544,40 +3544,6 @@ bool SemaHLSL::CanPerformScalarCast(QualType SrcTy, QualType DestTy) { llvm_unreachable("Unhandled scalar cast"); } -// Detect if a type contains a bitfield. Will be removed when -// bitfield support is added to HLSLElementwiseCast and HLSLAggregateSplatCast -bool SemaHLSL::ContainsBitField(QualType BaseTy) { - llvm::SmallVector<QualType, 16> WorkList; - WorkList.push_back(BaseTy); - while (!WorkList.empty()) { - QualType T = WorkList.pop_back_val(); - T = T.getCanonicalType().getUnqualifiedType(); - // only check aggregate types - if (const auto *AT = dyn_cast<ConstantArrayType>(T)) { - WorkList.push_back(AT->getElementType()); - continue; - } - if (const auto *RT = dyn_cast<RecordType>(T)) { - const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); - if (RD->isUnion()) - continue; - - const CXXRecordDecl *CXXD = dyn_cast<CXXRecordDecl>(RD); - - if (CXXD && CXXD->isStandardLayout()) - RD = CXXD->getStandardLayoutBaseWithFields(); - - for (const auto *FD : RD->fields()) { - if (FD->isBitField()) - return true; - WorkList.push_back(FD->getType()); - } - continue; - } - } - return false; -} - // Can perform an HLSL Aggregate splat cast if the Dest is an aggregate and the // Src is a scalar or a vector of length 1 // Or if Dest is a vector and Src is a vector of length 1 diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index 2f97f62..b981c35 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -199,7 +199,7 @@ void SemaSYCL::handleKernelAttr(Decl *D, const ParsedAttr &AL) { return; } - handleSimpleAttribute<DeviceKernelAttr>(*this, D, AL); + handleSimpleAttribute<SYCLKernelAttr>(*this, D, AL); } void SemaSYCL::handleKernelEntryPointAttr(Decl *D, const ParsedAttr &AL) { diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 3819f77..85e3d20 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -710,9 +710,9 @@ static void instantiateDependentAMDGPUMaxNumWorkGroupsAttr( // This doesn't take any template parameters, but we have a custom action that // needs to happen when the kernel itself is instantiated. We need to run the // ItaniumMangler to mark the names required to name this kernel. -static void instantiateDependentDeviceKernelAttr( +static void instantiateDependentSYCLKernelAttr( Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, - const DeviceKernelAttr &Attr, Decl *New) { + const SYCLKernelAttr &Attr, Decl *New) { New->addAttr(Attr.clone(S.getASTContext())); } @@ -966,8 +966,8 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, continue; } - if (auto *A = dyn_cast<DeviceKernelAttr>(TmplAttr)) { - instantiateDependentDeviceKernelAttr(*this, TemplateArgs, *A, New); + if (auto *A = dyn_cast<SYCLKernelAttr>(TmplAttr)) { + instantiateDependentSYCLKernelAttr(*this, TemplateArgs, *A, New); continue; } diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index bee613a..a9e7c34 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -3780,12 +3780,10 @@ static CallingConv getCCForDeclaratorChunk( } } } - if (!S.getLangOpts().isSYCL()) { - for (const ParsedAttr &AL : D.getDeclSpec().getAttributes()) { - if (AL.getKind() == ParsedAttr::AT_DeviceKernel) { - CC = CC_DeviceKernel; - break; - } + for (const ParsedAttr &AL : D.getDeclSpec().getAttributes()) { + if (AL.getKind() == ParsedAttr::AT_DeviceKernel) { + CC = CC_DeviceKernel; + break; } } return CC; diff --git a/clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp b/clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp index abfb176..c207a7b 100644 --- a/clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp +++ b/clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp @@ -24,15 +24,21 @@ using namespace ento; namespace { struct Registry { + std::vector<UnsignedEPStat *> ExplicitlySetStats; + std::vector<UnsignedMaxEPStat *> MaxStats; std::vector<CounterEPStat *> CounterStats; - std::vector<UnsignedMaxEPStat *> UnsignedMaxStats; - std::vector<UnsignedEPStat *> UnsignedStats; bool IsLocked = false; struct Snapshot { const Decl *EntryPoint; - std::vector<unsigned> UnsignedStatValues; + // Explicitly set statistics may not have a value set, so they are separate + // from other unsigned statistics + std::vector<std::optional<unsigned>> ExplicitlySetStatValues; + // These are counting and maximizing statistics that initialize to 0, which + // is meaningful even if they are never updated, so their value is always + // present. + std::vector<unsigned> MaxOrCountStatValues; void dumpAsCSV(llvm::raw_ostream &OS) const; }; @@ -46,10 +52,16 @@ static llvm::ManagedStatic<Registry> StatsRegistry; namespace { template <typename Callback> void enumerateStatVectors(const Callback &Fn) { + // This order is important, it matches the order of the Snapshot fields: + // - ExplicitlySetStatValues + Fn(StatsRegistry->ExplicitlySetStats); + // - MaxOrCountStatValues + Fn(StatsRegistry->MaxStats); Fn(StatsRegistry->CounterStats); - Fn(StatsRegistry->UnsignedMaxStats); - Fn(StatsRegistry->UnsignedStats); } + +void clearSnapshots(void *) { StatsRegistry->Snapshots.clear(); } + } // namespace static void checkStatName(const EntryPointStat *M) { @@ -69,7 +81,8 @@ static void checkStatName(const EntryPointStat *M) { } } -void EntryPointStat::lockRegistry(llvm::StringRef CPPFileName) { +void EntryPointStat::lockRegistry(llvm::StringRef CPPFileName, + ASTContext &Ctx) { auto CmpByNames = [](const EntryPointStat *L, const EntryPointStat *R) { return L->name() < R->name(); }; @@ -80,6 +93,10 @@ void EntryPointStat::lockRegistry(llvm::StringRef CPPFileName) { StatsRegistry->IsLocked = true; llvm::raw_string_ostream OS(StatsRegistry->EscapedCPPFileName); llvm::printEscapedString(CPPFileName, OS); + // Make sure snapshots (that reference function Decl's) do not persist after + // the AST is destroyed. This is especially relevant in the context of unit + // tests that construct and destruct multiple ASTs in the same process. + Ctx.AddDeallocation(clearSnapshots, nullptr); } [[maybe_unused]] static bool isRegistered(llvm::StringLiteral Name) { @@ -101,30 +118,36 @@ UnsignedMaxEPStat::UnsignedMaxEPStat(llvm::StringLiteral Name) : EntryPointStat(Name) { assert(!StatsRegistry->IsLocked); assert(!isRegistered(Name)); - StatsRegistry->UnsignedMaxStats.push_back(this); + StatsRegistry->MaxStats.push_back(this); } UnsignedEPStat::UnsignedEPStat(llvm::StringLiteral Name) : EntryPointStat(Name) { assert(!StatsRegistry->IsLocked); assert(!isRegistered(Name)); - StatsRegistry->UnsignedStats.push_back(this); + StatsRegistry->ExplicitlySetStats.push_back(this); } -static std::vector<unsigned> consumeUnsignedStats() { - std::vector<unsigned> Result; - Result.reserve(StatsRegistry->CounterStats.size() + - StatsRegistry->UnsignedMaxStats.size() + - StatsRegistry->UnsignedStats.size()); - for (auto *M : StatsRegistry->CounterStats) { +static std::vector<std::optional<unsigned>> consumeExplicitlySetStats() { + std::vector<std::optional<unsigned>> Result; + Result.reserve(StatsRegistry->ExplicitlySetStats.size()); + for (auto *M : StatsRegistry->ExplicitlySetStats) { Result.push_back(M->value()); M->reset(); } - for (auto *M : StatsRegistry->UnsignedMaxStats) { + return Result; +} + +static std::vector<unsigned> consumeMaxAndCounterStats() { + std::vector<unsigned> Result; + Result.reserve(StatsRegistry->CounterStats.size() + + StatsRegistry->MaxStats.size()); + // Order is important, it must match the order in enumerateStatVectors + for (auto *M : StatsRegistry->MaxStats) { Result.push_back(M->value()); M->reset(); } - for (auto *M : StatsRegistry->UnsignedStats) { + for (auto *M : StatsRegistry->CounterStats) { Result.push_back(M->value()); M->reset(); } @@ -150,20 +173,33 @@ static std::string getUSR(const Decl *D) { } void Registry::Snapshot::dumpAsCSV(llvm::raw_ostream &OS) const { + auto PrintAsUnsignOpt = [&OS](std::optional<unsigned> U) { + OS << (U.has_value() ? std::to_string(*U) : ""); + }; + auto CommaIfNeeded = [&OS](const auto &Vec1, const auto &Vec2) { + if (!Vec1.empty() && !Vec2.empty()) + OS << ","; + }; + auto PrintAsUnsigned = [&OS](unsigned U) { OS << U; }; + OS << '"'; llvm::printEscapedString(getUSR(EntryPoint), OS); OS << "\",\""; OS << StatsRegistry->EscapedCPPFileName << "\",\""; llvm::printEscapedString( clang::AnalysisDeclContext::getFunctionName(EntryPoint), OS); - OS << "\""; - OS << (UnsignedStatValues.empty() ? "" : ","); - llvm::interleave(UnsignedStatValues, OS, [&OS](unsigned U) { OS << U; }, ","); + OS << "\","; + llvm::interleave(ExplicitlySetStatValues, OS, PrintAsUnsignOpt, ","); + CommaIfNeeded(ExplicitlySetStatValues, MaxOrCountStatValues); + llvm::interleave(MaxOrCountStatValues, OS, PrintAsUnsigned, ","); } void EntryPointStat::takeSnapshot(const Decl *EntryPoint) { - auto UnsignedValues = consumeUnsignedStats(); - StatsRegistry->Snapshots.push_back({EntryPoint, std::move(UnsignedValues)}); + auto ExplicitlySetValues = consumeExplicitlySetStats(); + auto MaxOrCounterValues = consumeMaxAndCounterStats(); + StatsRegistry->Snapshots.push_back({EntryPoint, + std::move(ExplicitlySetValues), + std::move(MaxOrCounterValues)}); } void EntryPointStat::dumpStatsAsCSV(llvm::StringRef FileName) { diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index cf01e2f..4efde59 100644 --- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -39,6 +39,7 @@ #include "llvm/Support/TimeProfiler.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" +#include <cmath> #include <memory> #include <utility> @@ -125,6 +126,7 @@ public: std::unique_ptr<llvm::Timer> SyntaxCheckTimer; std::unique_ptr<llvm::Timer> ExprEngineTimer; std::unique_ptr<llvm::Timer> BugReporterTimer; + bool ShouldClearTimersToPreventDisplayingThem; /// The information about analyzed functions shared throughout the /// translation unit. @@ -138,11 +140,12 @@ public: Injector(std::move(injector)), CTU(CI), MacroExpansions(CI.getLangOpts()) { - EntryPointStat::lockRegistry(getMainFileName(CI.getInvocation())); + EntryPointStat::lockRegistry(getMainFileName(CI.getInvocation()), + CI.getASTContext()); DigestAnalyzerOptions(); if (Opts.AnalyzerDisplayProgress || Opts.PrintStats || - Opts.ShouldSerializeStats) { + Opts.ShouldSerializeStats || !Opts.DumpEntryPointStatsToCSV.empty()) { AnalyzerTimers = std::make_unique<llvm::TimerGroup>( "analyzer", "Analyzer timers"); SyntaxCheckTimer = std::make_unique<llvm::Timer>( @@ -154,6 +157,12 @@ public: *AnalyzerTimers); } + // Avoid displaying the timers created above in case we only want to record + // per-entry-point stats. + ShouldClearTimersToPreventDisplayingThem = !Opts.AnalyzerDisplayProgress && + !Opts.PrintStats && + !Opts.ShouldSerializeStats; + if (Opts.PrintStats || Opts.ShouldSerializeStats) { llvm::EnableStatistics(/* DoPrintOnExit= */ false); } @@ -276,6 +285,9 @@ public: checkerMgr->runCheckersOnASTDecl(D, *Mgr, *RecVisitorBR); if (SyntaxCheckTimer) SyntaxCheckTimer->stopTimer(); + if (AnalyzerTimers && ShouldClearTimersToPreventDisplayingThem) { + AnalyzerTimers->clear(); + } } return true; } @@ -569,6 +581,9 @@ void AnalysisConsumer::runAnalysisOnTranslationUnit(ASTContext &C) { checkerMgr->runCheckersOnASTDecl(TU, *Mgr, BR); if (SyntaxCheckTimer) SyntaxCheckTimer->stopTimer(); + if (AnalyzerTimers && ShouldClearTimersToPreventDisplayingThem) { + AnalyzerTimers->clear(); + } // Run the AST-only checks using the order in which functions are defined. // If inlining is not turned on, use the simplest function order for path @@ -745,6 +760,9 @@ void AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode, llvm::TimeRecord CheckerEndTime = SyntaxCheckTimer->getTotalTime(); CheckerEndTime -= CheckerStartTime; DisplayTime(CheckerEndTime); + if (AnalyzerTimers && ShouldClearTimersToPreventDisplayingThem) { + AnalyzerTimers->clear(); + } } } @@ -788,7 +806,12 @@ void AnalysisConsumer::RunPathSensitiveChecks(Decl *D, ExprEngineTimer->stopTimer(); llvm::TimeRecord ExprEngineEndTime = ExprEngineTimer->getTotalTime(); ExprEngineEndTime -= ExprEngineStartTime; + PathRunningTime.set(static_cast<unsigned>( + std::lround(ExprEngineEndTime.getWallTime() * 1000))); DisplayTime(ExprEngineEndTime); + if (AnalyzerTimers && ShouldClearTimersToPreventDisplayingThem) { + AnalyzerTimers->clear(); + } } if (!Mgr->options.DumpExplodedGraphTo.empty()) @@ -799,6 +822,9 @@ void AnalysisConsumer::RunPathSensitiveChecks(Decl *D, Eng.ViewGraph(Mgr->options.TrimGraph); flushReports(BugReporterTimer.get(), Eng.getBugReporter()); + if (AnalyzerTimers && ShouldClearTimersToPreventDisplayingThem) { + AnalyzerTimers->clear(); + } } //===----------------------------------------------------------------------===// diff --git a/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp b/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp index 9cbe045..2a0caad 100644 --- a/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp +++ b/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp @@ -8,6 +8,13 @@ // CHECK-NEXT: "c:@F@fib#i#": { // CHECK-NEXT: "File": "{{.*}}entry-point-stats.cpp", // CHECK-NEXT: "DebugName": "fib(unsigned int)", +// CHECK-NEXT: "PathRunningTime": "{{[0-9]+}}", +// CHECK-NEXT: "MaxBugClassSize": "{{[0-9]+}}", +// CHECK-NEXT: "MaxCFGSize": "{{[0-9]+}}", +// CHECK-NEXT: "MaxQueueSize": "{{[0-9]+}}", +// CHECK-NEXT: "MaxReachableSize": "{{[0-9]+}}", +// CHECK-NEXT: "MaxTimeSpentSolvingZ3Queries": "{{[0-9]+}}", +// CHECK-NEXT: "MaxValidBugClassSize": "{{[0-9]+}}", // CHECK-NEXT: "NumBlocks": "{{[0-9]+}}", // CHECK-NEXT: "NumBlocksUnreachable": "{{[0-9]+}}", // CHECK-NEXT: "NumCTUSteps": "{{[0-9]+}}", @@ -33,18 +40,18 @@ // CHECK-NEXT: "NumTimesZ3SpendsTooMuchTimeOnASingleEQClass": "{{[0-9]+}}", // CHECK-NEXT: "NumTimesZ3TimedOut": "{{[0-9]+}}", // CHECK-NEXT: "NumZ3QueriesDone": "{{[0-9]+}}", -// CHECK-NEXT: "TimeSpentSolvingZ3Queries": "{{[0-9]+}}", +// CHECK-NEXT: "TimeSpentSolvingZ3Queries": "{{[0-9]+}}" +// CHECK-NEXT: }, +// CHECK-NEXT: "c:@F@main#I#**C#": { +// CHECK-NEXT: "File": "{{.*}}entry-point-stats.cpp", +// CHECK-NEXT: "DebugName": "main(int, char **)", +// CHECK-NEXT: "PathRunningTime": "{{[0-9]+}}", // CHECK-NEXT: "MaxBugClassSize": "{{[0-9]+}}", // CHECK-NEXT: "MaxCFGSize": "{{[0-9]+}}", // CHECK-NEXT: "MaxQueueSize": "{{[0-9]+}}", // CHECK-NEXT: "MaxReachableSize": "{{[0-9]+}}", // CHECK-NEXT: "MaxTimeSpentSolvingZ3Queries": "{{[0-9]+}}", // CHECK-NEXT: "MaxValidBugClassSize": "{{[0-9]+}}", -// CHECK-NEXT: "PathRunningTime": "{{[0-9]+}}" -// CHECK-NEXT: }, -// CHECK-NEXT: "c:@F@main#I#**C#": { -// CHECK-NEXT: "File": "{{.*}}entry-point-stats.cpp", -// CHECK-NEXT: "DebugName": "main(int, char **)", // CHECK-NEXT: "NumBlocks": "{{[0-9]+}}", // CHECK-NEXT: "NumBlocksUnreachable": "{{[0-9]+}}", // CHECK-NEXT: "NumCTUSteps": "{{[0-9]+}}", @@ -70,14 +77,7 @@ // CHECK-NEXT: "NumTimesZ3SpendsTooMuchTimeOnASingleEQClass": "{{[0-9]+}}", // CHECK-NEXT: "NumTimesZ3TimedOut": "{{[0-9]+}}", // CHECK-NEXT: "NumZ3QueriesDone": "{{[0-9]+}}", -// CHECK-NEXT: "TimeSpentSolvingZ3Queries": "{{[0-9]+}}", -// CHECK-NEXT: "MaxBugClassSize": "{{[0-9]+}}", -// CHECK-NEXT: "MaxCFGSize": "{{[0-9]+}}", -// CHECK-NEXT: "MaxQueueSize": "{{[0-9]+}}", -// CHECK-NEXT: "MaxReachableSize": "{{[0-9]+}}", -// CHECK-NEXT: "MaxTimeSpentSolvingZ3Queries": "{{[0-9]+}}", -// CHECK-NEXT: "MaxValidBugClassSize": "{{[0-9]+}}", -// CHECK-NEXT: "PathRunningTime": "{{[0-9]+}}" +// CHECK-NEXT: "TimeSpentSolvingZ3Queries": "{{[0-9]+}}" // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NOT: non_entry_point diff --git a/clang/test/CIR/CodeGen/virtual-destructor-calls.cpp b/clang/test/CIR/CodeGen/virtual-destructor-calls.cpp new file mode 100644 index 0000000..08a6b21 --- /dev/null +++ b/clang/test/CIR/CodeGen/virtual-destructor-calls.cpp @@ -0,0 +1,129 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -std=c++20 -mconstructor-aliases -O0 -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s +// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -std=c++20 -mconstructor-aliases -O0 -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s +// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -std=c++20 -mconstructor-aliases -O0 -emit-llvm %s -o %t.ll +// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s + +// TODO(cir): Try to emit base destructor as an alias at O1 or higher. + +// FIXME: LLVM IR dialect does not yet support function ptr globals, which precludes +// a lot of the proper semantics for properly representing alias functions in LLVM +// (see the note on LLVM_O1 below). + +struct Member { + ~Member(); +}; + +struct A { + virtual ~A(); +}; + +struct B : A { + Member m; + virtual ~B(); +}; + +B::~B() { } + +// Aliases are inserted before the function definitions in LLVM IR +// FIXME: These should have unnamed_addr set. +// LLVM: @_ZN1BD1Ev = alias void (ptr), ptr @_ZN1BD2Ev +// LLVM: @_ZN1CD1Ev = alias void (ptr), ptr @_ZN1CD2Ev + +// OGCG: @_ZN1BD1Ev = unnamed_addr alias void (ptr), ptr @_ZN1BD2Ev +// OGCG: @_ZN1CD1Ev = unnamed_addr alias void (ptr), ptr @_ZN1CD2Ev + + +// Base (D2) dtor for B: calls A's base dtor. + +// CIR: cir.func{{.*}} @_ZN1BD2Ev +// CIR: cir.call @_ZN6MemberD1Ev +// CIR: cir.call @_ZN1AD2Ev + +// LLVM: define{{.*}} void @_ZN1BD2Ev +// LLVM: call void @_ZN6MemberD1Ev +// LLVM: call void @_ZN1AD2Ev + +// OGCG: define{{.*}} @_ZN1BD2Ev +// OGCG: call void @_ZN6MemberD1Ev +// OGCG: call void @_ZN1AD2Ev + +// Complete (D1) dtor for B: just an alias because there are no virtual bases. + +// CIR: cir.func{{.*}} @_ZN1BD1Ev(!cir.ptr<!rec_B>) alias(@_ZN1BD2Ev) +// This is defined above for LLVM and OGCG. + +// Deleting (D0) dtor for B: defers to the complete dtor but also calls operator delete. + +// CIR: cir.func{{.*}} @_ZN1BD0Ev +// CIR: cir.call @_ZN1BD1Ev(%[[THIS:.*]]) nothrow : (!cir.ptr<!rec_B>) -> () +// CIR: %[[THIS_VOID:.*]] = cir.cast bitcast %[[THIS]] : !cir.ptr<!rec_B> -> !cir.ptr<!void> +// CIR: %[[SIZE:.*]] = cir.const #cir.int<16> +// CIR: cir.call @_ZdlPvm(%[[THIS_VOID]], %[[SIZE]]) + +// LLVM: define{{.*}} void @_ZN1BD0Ev +// LLVM: call void @_ZN1BD1Ev(ptr %[[THIS:.*]]) +// LLVM: call void @_ZdlPvm(ptr %[[THIS]], i64 16) + +// OGCG: define{{.*}} @_ZN1BD0Ev +// OGCG: call void @_ZN1BD1Ev(ptr{{.*}} %[[THIS:.*]]) +// OGCG: call void @_ZdlPvm(ptr{{.*}} %[[THIS]], i64{{.*}} 16) + +struct C : B { + ~C(); +}; + +C::~C() { } + +// Base (D2) dtor for C: calls B's base dtor. + +// CIR: cir.func{{.*}} @_ZN1CD2Ev +// CIR: %[[B:.*]] = cir.base_class_addr %[[THIS:.*]] : !cir.ptr<!rec_C> nonnull [0] -> !cir.ptr<!rec_B> +// CIR: cir.call @_ZN1BD2Ev(%[[B]]) + +// LLVM: define{{.*}} void @_ZN1CD2Ev +// LLVM: call void @_ZN1BD2Ev + +// OGCG: define{{.*}} @_ZN1CD2Ev +// OGCG: call void @_ZN1BD2Ev + +// Complete (D1) dtor for C: just an alias because there are no virtual bases. + +// CIR: cir.func{{.*}} @_ZN1CD1Ev(!cir.ptr<!rec_C>) alias(@_ZN1CD2Ev) +// This is defined above for LLVM and OGCG. + + +// Deleting (D0) dtor for C: defers to the complete dtor but also calls operator delete. + +// CIR: cir.func{{.*}} @_ZN1CD0Ev +// CIR: cir.call @_ZN1CD1Ev(%[[THIS:.*]]) nothrow : (!cir.ptr<!rec_C>) -> () +// CIR: %[[THIS_VOID:.*]] = cir.cast bitcast %[[THIS]] : !cir.ptr<!rec_C> -> !cir.ptr<!void> +// CIR: %[[SIZE:.*]] = cir.const #cir.int<16> +// CIR: cir.call @_ZdlPvm(%[[THIS_VOID]], %[[SIZE]]) + +// LLVM: define{{.*}} void @_ZN1CD0Ev +// LLVM: call void @_ZN1CD1Ev(ptr %[[THIS:.*]]) +// LLVM: call void @_ZdlPvm(ptr %[[THIS]], i64 16) + +// OGCG: define{{.*}} @_ZN1CD0Ev +// OGCG: call void @_ZN1CD1Ev(ptr{{.*}} %[[THIS:.*]]) +// OGCG: call void @_ZdlPvm(ptr{{.*}} %[[THIS]], i64{{.*}} 16) + +namespace PR12798 { + // A qualified call to a base class destructor should not undergo virtual + // dispatch. Template instantiation used to lose the qualifier. + struct A { virtual ~A(); }; + template<typename T> void f(T *p) { p->A::~A(); } + + // CIR: cir.func{{.*}} @_ZN7PR127981fINS_1AEEEvPT_ + // CIR: cir.call @_ZN7PR127981AD1Ev + + // LLVM: define{{.*}} @_ZN7PR127981fINS_1AEEEvPT_ + // LLVM: call void @_ZN7PR127981AD1Ev + + // OGCG: define{{.*}} @_ZN7PR127981fINS_1AEEEvPT_ + // OGCG: call void @_ZN7PR127981AD1Ev + + template void f(A*); +} diff --git a/clang/test/OpenMP/target_indirect_codegen.cpp b/clang/test/OpenMP/target_indirect_codegen.cpp index 20a36c2..ec249dd 100644 --- a/clang/test/OpenMP/target_indirect_codegen.cpp +++ b/clang/test/OpenMP/target_indirect_codegen.cpp @@ -4,6 +4,12 @@ // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -x c++ -triple amdgcn-amd-amdhsa %s -fopenmp-is-target-device -fvisibility=protected -fopenmp-host-ir-file-path %t-host.bc -emit-pch -o %t // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -x c++ -triple amdgcn-amd-amdhsa -emit-llvm %s -fopenmp-is-target-device -fvisibility=protected -fopenmp-host-ir-file-path %t-host.bc -include-pch %t -o - | FileCheck %s --check-prefix=DEVICE +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=spirv64-intel -emit-llvm %s -o - | FileCheck %s --check-prefix=HOST +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=spirv64-intel -emit-llvm-bc %s -o %t-spirv-host.bc +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -x c++ -triple spirv64-intel -emit-llvm %s -fopenmp-is-target-device -fvisibility=protected -fopenmp-host-ir-file-path %t-spirv-host.bc -o - | FileCheck %s --check-prefix=DEVICE +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -x c++ -triple spirv64-intel %s -fopenmp-is-target-device -fvisibility=protected -fopenmp-host-ir-file-path %t-spirv-host.bc -emit-pch -o %t +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -x c++ -triple spirv64-intel -emit-llvm %s -fopenmp-is-target-device -fvisibility=protected -fopenmp-host-ir-file-path %t-spirv-host.bc -include-pch %t -o - | FileCheck %s --check-prefix=DEVICE + // expected-no-diagnostics #ifndef HEADER #define HEADER @@ -19,10 +25,10 @@ // HOST: @[[BAR_ENTRY_NAME:.+]] = internal unnamed_addr constant [{{[0-9]+}} x i8] c"[[BAR_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_bar_l[0-9]+]]\00" // HOST: @.offloading.entry.[[BAR_NAME]] = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 8, ptr @_ZL3barv, ptr @[[BAR_ENTRY_NAME]], i64 8, i64 0, ptr null } //. -// DEVICE: @[[FOO_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_foo_l[0-9]+]] = protected addrspace(1) constant ptr @_Z3foov -// DEVICE: @[[BAZ_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_baz_l[0-9]+]] = protected addrspace(1) constant ptr @_Z3bazv +// DEVICE: @[[FOO_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_foo_l[0-9]+]] = protected addrspace(1) constant {{ptr|ptr addrspace\(9\)}} @_Z3foov +// DEVICE: @[[BAZ_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_baz_l[0-9]+]] = protected addrspace(1) constant {{ptr|ptr addrspace\(9\)}} @_Z3bazv // DEVICE: @var = protected addrspace(1) global i8 0, align 1 -// DEVICE: @[[BAR_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_bar_l[0-9]+]] = protected addrspace(1) constant ptr @_ZL3barv +// DEVICE: @[[BAR_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_bar_l[0-9]+]] = protected addrspace(1) constant {{ptr|ptr addrspace\(9\)}} @_ZL3barv //. void foo() { } #pragma omp declare target to(foo) indirect diff --git a/clang/test/OpenMP/amdgcn_parallel_num_threads_strict_messages.cpp b/clang/test/OpenMP/target_parallel_num_threads_strict_messages.cpp index 513754b..8ceff02 100644 --- a/clang/test/OpenMP/amdgcn_parallel_num_threads_strict_messages.cpp +++ b/clang/test/OpenMP/target_parallel_num_threads_strict_messages.cpp @@ -5,6 +5,13 @@ // RUN: %clang_cc1 -DF3 -verify -fopenmp -fopenmp-version=60 -triple x86_64-unknown-unknown -fopenmp-targets=amdgcn-amd-amdhsa -emit-llvm-bc %s -o %t-ppc-host-ppc.bc // RUN: %clang_cc1 -DF3 -DTARGET -verify -fopenmp -fopenmp-version=60 -triple amdgcn-amd-amdhsa -fopenmp-targets=amdgcn-amd-amdhsa -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-ppc-host-ppc.bc -o /dev/null +// RUN: %clang_cc1 -DF1 -verify -fopenmp -fopenmp-version=60 -triple x86_64-unknown-unknown -fopenmp-targets=spirv64-intel -emit-llvm-bc %s -o %t-spirv-ppc-host-ppc.bc +// RUN: %clang_cc1 -DF1 -DTARGET -verify -fopenmp -fopenmp-version=60 -triple spirv64-intel -fopenmp-targets=spirv64-intel -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-spirv-ppc-host-ppc.bc -o /dev/null +// RUN: %clang_cc1 -DF2 -verify -fopenmp -fopenmp-version=60 -triple x86_64-unknown-unknown -fopenmp-targets=spirv64-intel -emit-llvm-bc %s -o %t-spirv-ppc-host-ppc.bc +// RUN: %clang_cc1 -DF2 -DTARGET -verify -fopenmp -fopenmp-version=60 -triple spirv64-intel -fopenmp-targets=spirv64-intel -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-spirv-ppc-host-ppc.bc -o /dev/null +// RUN: %clang_cc1 -DF3 -verify -fopenmp -fopenmp-version=60 -triple x86_64-unknown-unknown -fopenmp-targets=spirv64-intel -emit-llvm-bc %s -o %t-spirv-ppc-host-ppc.bc +// RUN: %clang_cc1 -DF3 -DTARGET -verify -fopenmp -fopenmp-version=60 -triple spirv64-intel -fopenmp-targets=spirv64-intel -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-spirv-ppc-host-ppc.bc -o /dev/null + #ifndef TARGET // expected-no-diagnostics #endif diff --git a/clang/unittests/StaticAnalyzer/CMakeLists.txt b/clang/unittests/StaticAnalyzer/CMakeLists.txt index 9e10c4a..caf686e 100644 --- a/clang/unittests/StaticAnalyzer/CMakeLists.txt +++ b/clang/unittests/StaticAnalyzer/CMakeLists.txt @@ -20,6 +20,7 @@ add_clang_unittest(StaticAnalysisTests SValSimplifyerTest.cpp SValTest.cpp TestReturnValueUnderConstruction.cpp + UnsignedStatDemo.cpp Z3CrosscheckOracleTest.cpp CLANG_LIBS clangBasic diff --git a/clang/unittests/StaticAnalyzer/UnsignedStatDemo.cpp b/clang/unittests/StaticAnalyzer/UnsignedStatDemo.cpp new file mode 100644 index 0000000..2d1323b --- /dev/null +++ b/clang/unittests/StaticAnalyzer/UnsignedStatDemo.cpp @@ -0,0 +1,150 @@ +//=== UnsignedStatDemo.cpp --------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This checker demonstrates the use of UnsignedEPStat for per-entry-point +// statistics. It conditionally sets a statistic based on the entry point name. +// +//===----------------------------------------------------------------------===// + +#include "CheckerRegistration.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/ScopeExit.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/MemoryBuffer.h" +#include "gtest/gtest.h" +#include <optional> + +using namespace clang; +using namespace ento; + +static UnsignedEPStat DemoStat("DemoStat"); + +namespace { +class UnsignedStatTesterChecker : public Checker<check::BeginFunction> { +public: + void checkBeginFunction(CheckerContext &C) const { + StringRef Name; + if (const Decl *D = C.getLocationContext()->getDecl()) + if (const FunctionDecl *F = D->getAsFunction()) + Name = F->getName(); + + // Conditionally set the statistic based on the function name (leaving it + // undefined for all other functions) + if (Name == "func_one") + DemoStat.set(1); + else if (Name == "func_two") + DemoStat.set(2); + else + ; // For any other function (e.g., "func_none") don't set the statistic + } +}; + +void addUnsignedStatTesterChecker(AnalysisASTConsumer &AnalysisConsumer, + AnalyzerOptions &AnOpts) { + AnOpts.CheckersAndPackages = {{"test.DemoStatChecker", true}}; + AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) { + Registry.addChecker<UnsignedStatTesterChecker>( + "test.DemoStatChecker", "DescriptionOfDemoStatChecker"); + }); +} + +// Find the index of a column in the CSV header. +// Returns std::nullopt if the column is not found. +static std::optional<unsigned> +findColumnIndex(llvm::ArrayRef<llvm::StringRef> Header, + llvm::StringRef ColumnName) { + auto Iter = llvm::find(Header, ColumnName); + if (Iter != Header.end()) + return std::distance(Header.begin(), Iter); + return std::nullopt; +} + +// Parse CSV content and extract a mapping from one column to another. +// KeyColumn is used as the map key (e.g., "DebugName"). +// ValueColumn is used as the map value (e.g., "DemoStat"). +// Returns a map from key column values to value column values. +static llvm::StringMap<std::string> +parseCSVColumnMapping(llvm::StringRef CSVContent, llvm::StringRef KeyColumn, + llvm::StringRef ValueColumn) { + llvm::StringMap<std::string> Result; + + // Parse CSV: first line is header, subsequent lines are data + llvm::SmallVector<llvm::StringRef, 8> Lines; + CSVContent.split(Lines, '\n', -1, false); + if (Lines.size() < 2) // Need at least header + one data row + return Result; + + // Parse header to find column indices + llvm::SmallVector<llvm::StringRef, 32> Header; + Lines[0].split(Header, ','); + std::optional<unsigned> KeyIdx = findColumnIndex(Header, KeyColumn); + std::optional<unsigned> ValueIdx = findColumnIndex(Header, ValueColumn); + + if (!KeyIdx || !ValueIdx) + return Result; + + // Parse data rows and extract mappings + for (auto Line : llvm::drop_begin(Lines)) { + llvm::SmallVector<llvm::StringRef, 32> Row; + Line.split(Row, ','); + if (Row.size() <= std::max(*KeyIdx, *ValueIdx)) + continue; + + llvm::StringRef KeyVal = Row[*KeyIdx].trim().trim('"'); + llvm::StringRef ValueVal = Row[*ValueIdx].trim().trim('"'); + + if (!KeyVal.empty()) + Result[KeyVal] = ValueVal.str(); + } + + return Result; +} + +TEST(UnsignedStat, ExplicitlySetUnsignedStatistic) { + llvm::SmallString<128> TempMetricsCsvPath; + std::error_code EC = + llvm::sys::fs::createTemporaryFile("ep_stats", "csv", TempMetricsCsvPath); + ASSERT_FALSE(EC); + std::vector<std::string> Args = { + "-Xclang", "-analyzer-config", "-Xclang", + std::string("dump-entry-point-stats-to-csv=") + + TempMetricsCsvPath.str().str()}; + // Clean up on exit + auto Cleanup = llvm::make_scope_exit( + [&]() { llvm::sys::fs::remove(TempMetricsCsvPath); }); + EXPECT_TRUE(runCheckerOnCodeWithArgs<addUnsignedStatTesterChecker>( + R"cpp( + void func_one() {} + void func_two() {} + void func_none() {} + )cpp", + Args)); + + auto BufferOrError = llvm::MemoryBuffer::getFile(TempMetricsCsvPath); + ASSERT_TRUE(BufferOrError); + llvm::StringRef CSVContent = BufferOrError.get()->getBuffer(); + + // Parse the CSV and extract function statistics + llvm::StringMap<std::string> FunctionStats = + parseCSVColumnMapping(CSVContent, "DebugName", "DemoStat"); + + // Verify the expected values + ASSERT_TRUE(FunctionStats.count("func_one()")); + EXPECT_EQ(FunctionStats["func_one()"], "1"); + + ASSERT_TRUE(FunctionStats.count("func_two()")); + EXPECT_EQ(FunctionStats["func_two()"], "2"); + + ASSERT_TRUE(FunctionStats.count("func_none()")); + EXPECT_EQ(FunctionStats["func_none()"], ""); // Not set, should be empty +} +} // namespace diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp index 0040f79..b0a29db 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp @@ -105,9 +105,11 @@ extern "C" { mach_msg_type_number_t *infoCnt); } +# if !SANITIZER_GO // Weak symbol no-op when TSan is not linked SANITIZER_WEAK_ATTRIBUTE extern void __tsan_set_in_internal_write_call( bool value) {} +# endif namespace __sanitizer { @@ -179,11 +181,15 @@ uptr internal_read(fd_t fd, void *buf, uptr count) { } uptr internal_write(fd_t fd, const void *buf, uptr count) { +# if SANITIZER_GO + return write(fd, buf, count); +# else // We need to disable interceptors when writing in TSan __tsan_set_in_internal_write_call(true); uptr res = write(fd, buf, count); __tsan_set_in_internal_write_call(false); return res; +# endif } uptr internal_stat(const char *path, void *buf) { diff --git a/compiler-rt/lib/tsan/rtl/tsan_flags.cpp b/compiler-rt/lib/tsan/rtl/tsan_flags.cpp index 50632d2..efaaef8 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_flags.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_flags.cpp @@ -20,7 +20,7 @@ #include "tsan_rtl.h" #include "ubsan/ubsan_flags.h" -#if SANITIZER_APPLE +#if SANITIZER_APPLE && !SANITIZER_GO namespace __sanitizer { template <> @@ -55,7 +55,7 @@ inline bool FlagHandler<LockDuringWriteSetting>::Format(char *buffer, } } // namespace __sanitizer -#endif +#endif // SANITIZER_APPLE && !SANITIZER_GO namespace __tsan { diff --git a/compiler-rt/lib/tsan/rtl/tsan_flags.h b/compiler-rt/lib/tsan/rtl/tsan_flags.h index 477d08d..e63d7c4 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_flags.h +++ b/compiler-rt/lib/tsan/rtl/tsan_flags.h @@ -16,7 +16,7 @@ #include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_deadlock_detector_interface.h" -#if SANITIZER_APPLE +#if SANITIZER_APPLE && !SANITIZER_GO enum LockDuringWriteSetting { kLockDuringAllWrites, kNoLockDuringWritesCurrentProcess, diff --git a/compiler-rt/lib/tsan/rtl/tsan_flags.inc b/compiler-rt/lib/tsan/rtl/tsan_flags.inc index 64cc091..77ab910 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_flags.inc +++ b/compiler-rt/lib/tsan/rtl/tsan_flags.inc @@ -81,7 +81,7 @@ TSAN_FLAG(bool, print_full_thread_history, false, "If set, prints thread creation stacks for the threads involved in " "the report and their ancestors up to the main thread.") -#if SANITIZER_APPLE +#if SANITIZER_APPLE && !SANITIZER_GO TSAN_FLAG(LockDuringWriteSetting, lock_during_write, kLockDuringAllWrites, "Determines whether to obtain a lock while writing logs or error " "reports. " diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.h b/compiler-rt/lib/tsan/rtl/tsan_interceptors.h index d4b65ab..f8cc8ff 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.h +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.h @@ -1,7 +1,7 @@ #ifndef TSAN_INTERCEPTORS_H #define TSAN_INTERCEPTORS_H -#if SANITIZER_APPLE +#if SANITIZER_APPLE && !SANITIZER_GO # include "sanitizer_common/sanitizer_mac.h" #endif #include "sanitizer_common/sanitizer_stacktrace.h" @@ -47,7 +47,7 @@ inline bool in_symbolizer() { inline bool MustIgnoreInterceptor(ThreadState *thr) { return !thr->is_inited || thr->ignore_interceptors || thr->in_ignored_lib -#if SANITIZER_APPLE +#if SANITIZER_APPLE && !SANITIZER_GO || (flags()->lock_during_write != kLockDuringAllWrites && thr->in_internal_write_call) #endif diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index 0c35804..714220a 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -31,7 +31,7 @@ #include "sanitizer_common/sanitizer_tls_get_addr.h" #include "sanitizer_common/sanitizer_vector.h" #include "tsan_fd.h" -#if SANITIZER_APPLE +#if SANITIZER_APPLE && !SANITIZER_GO # include "tsan_flags.h" #endif #include "tsan_interceptors.h" @@ -1668,7 +1668,7 @@ TSAN_INTERCEPTOR(int, pthread_barrier_wait, void *b) { TSAN_INTERCEPTOR(int, pthread_once, void *o, void (*f)()) { SCOPED_INTERCEPTOR_RAW(pthread_once, o, f); -#if SANITIZER_APPLE +#if SANITIZER_APPLE && !SANITIZER_GO if (flags()->lock_during_write != kLockDuringAllWrites && cur_thread_init()->in_internal_write_call) { // This is needed to make it through process launch without hanging diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp index b8041d7..feee566 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp @@ -40,7 +40,7 @@ SANITIZER_WEAK_DEFAULT_IMPL void __tsan_test_only_on_fork() {} #endif -#if SANITIZER_APPLE +#if SANITIZER_APPLE && !SANITIZER_GO // Override weak symbol from sanitizer_common extern void __tsan_set_in_internal_write_call(bool value) { __tsan::cur_thread_init()->in_internal_write_call = value; @@ -901,7 +901,7 @@ void ForkChildAfter(ThreadState* thr, uptr pc, bool start_thread) { ThreadIgnoreSyncBegin(thr, pc); } -# if SANITIZER_APPLE +# if SANITIZER_APPLE && !SANITIZER_GO // This flag can have inheritance disabled - we are the child so act // accordingly if (flags()->lock_during_write == kNoLockDuringWritesCurrentProcess) diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h index 77390f0..6356546 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -236,7 +236,7 @@ struct alignas(SANITIZER_CACHE_LINE_SIZE) ThreadState { const ReportDesc *current_report; -#if SANITIZER_APPLE +#if SANITIZER_APPLE && !SANITIZER_GO bool in_internal_write_call; #endif diff --git a/cross-project-tests/intrinsic-header-tests/wasm_simd128.c b/cross-project-tests/intrinsic-header-tests/wasm_simd128.c index b601d90..0f9ef39 100644 --- a/cross-project-tests/intrinsic-header-tests/wasm_simd128.c +++ b/cross-project-tests/intrinsic-header-tests/wasm_simd128.c @@ -1511,13 +1511,13 @@ v128_t test_f16x8_convert_u16x8(v128_t a) { } // CHECK-LABEL: test_f16x8_relaxed_madd: -// CHECK: f16x8.relaxed_madd{{$}} +// CHECK: f16x8.madd{{$}} v128_t test_f16x8_relaxed_madd(v128_t a, v128_t b, v128_t c) { return wasm_f16x8_relaxed_madd(a, b, c); } // CHECK-LABEL: test_f16x8_relaxed_nmadd: -// CHECK: f16x8.relaxed_nmadd{{$}} +// CHECK: f16x8.nmadd{{$}} v128_t test_f16x8_relaxed_nmadd(v128_t a, v128_t b, v128_t c) { return wasm_f16x8_relaxed_nmadd(a, b, c); } diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h index 2adfd6f2..c3cd119b 100644 --- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h +++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h @@ -459,6 +459,7 @@ struct IntrinsicLibrary { mlir::Value genTime(mlir::Type, llvm::ArrayRef<mlir::Value>); void genTMABulkCommitGroup(llvm::ArrayRef<fir::ExtendedValue>); void genTMABulkG2S(llvm::ArrayRef<fir::ExtendedValue>); + void genTMABulkS2G(llvm::ArrayRef<fir::ExtendedValue>); void genTMABulkWaitGroup(llvm::ArrayRef<fir::ExtendedValue>); mlir::Value genTrailz(mlir::Type, llvm::ArrayRef<mlir::Value>); fir::ExtendedValue genTransfer(mlir::Type, diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp index 98dc78f..604b137 100644 --- a/flang/lib/Lower/IO.cpp +++ b/flang/lib/Lower/IO.cpp @@ -524,12 +524,18 @@ getNamelistGroup(Fortran::lower::AbstractConverter &converter, descAddr = builder.createConvert(loc, builder.getRefType(symType), varAddr); } else { + fir::BaseBoxType boxType; const auto expr = Fortran::evaluate::AsGenericExpr(s); fir::ExtendedValue exv = converter.genExprAddr(*expr, stmtCtx); mlir::Type type = fir::getBase(exv).getType(); + bool isClassType = mlir::isa<fir::ClassType>(type); if (mlir::Type baseTy = fir::dyn_cast_ptrOrBoxEleTy(type)) type = baseTy; - fir::BoxType boxType = fir::BoxType::get(fir::PointerType::get(type)); + + if (isClassType) + boxType = fir::ClassType::get(fir::PointerType::get(type)); + else + boxType = fir::BoxType::get(fir::PointerType::get(type)); descAddr = builder.createTemporary(loc, boxType); fir::MutableBoxValue box = fir::MutableBoxValue(descAddr, {}, {}); fir::factory::associateMutableBox(builder, loc, box, exv, diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index 5fe2a76..e07baaf 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -1027,6 +1027,10 @@ static constexpr IntrinsicHandler handlers[]{ {"dst", asAddr}, {"nbytes", asValue}}}, /*isElemental=*/false}, + {"tma_bulk_s2g", + &I::genTMABulkS2G, + {{{"src", asAddr}, {"dst", asAddr}, {"nbytes", asValue}}}, + /*isElemental=*/false}, {"tma_bulk_wait_group", &I::genTMABulkWaitGroup, {{}}, @@ -9227,6 +9231,17 @@ void IntrinsicLibrary::genTMABulkG2S(llvm::ArrayRef<fir::ExtendedValue> args) { builder, loc, dst, src, barrier, fir::getBase(args[3]), {}, {}); } +// TMA_BULK_S2G (CUDA) +void IntrinsicLibrary::genTMABulkS2G(llvm::ArrayRef<fir::ExtendedValue> args) { + assert(args.size() == 3); + mlir::Value src = convertPtrToNVVMSpace(builder, loc, fir::getBase(args[0]), + mlir::NVVM::NVVMMemorySpace::Shared); + mlir::Value dst = convertPtrToNVVMSpace(builder, loc, fir::getBase(args[1]), + mlir::NVVM::NVVMMemorySpace::Global); + mlir::NVVM::CpAsyncBulkSharedCTAToGlobalOp::create( + builder, loc, dst, src, fir::getBase(args[2]), {}, {}); +} + // TMA_BULK_WAIT_GROUP (CUDA) void IntrinsicLibrary::genTMABulkWaitGroup( llvm::ArrayRef<fir::ExtendedValue> args) { diff --git a/flang/lib/Optimizer/Transforms/CUFOpConversion.cpp b/flang/lib/Optimizer/Transforms/CUFOpConversion.cpp index 609a1fc..e5c5ba9 100644 --- a/flang/lib/Optimizer/Transforms/CUFOpConversion.cpp +++ b/flang/lib/Optimizer/Transforms/CUFOpConversion.cpp @@ -558,6 +558,7 @@ static mlir::Value emboxSrc(mlir::PatternRewriter &rewriter, if (srcTy.isInteger(1)) { // i1 is not a supported type in the descriptor and it is actually coming // from a LOGICAL constant. Use the destination type to avoid mismatch. + assert(dstEleTy && "expect dst element type to be set"); srcTy = dstEleTy; src = createConvertOp(rewriter, loc, srcTy, src); addr = builder.createTemporary(loc, srcTy); @@ -652,7 +653,8 @@ struct CUFDataTransferOpConversion // Initialization of an array from a scalar value should be implemented // via a kernel launch. Use the flang runtime via the Assign function // until we have more infrastructure. - mlir::Value src = emboxSrc(rewriter, op, symtab); + mlir::Type dstEleTy = fir::unwrapInnerType(fir::unwrapRefType(dstTy)); + mlir::Value src = emboxSrc(rewriter, op, symtab, dstEleTy); mlir::Value dst = emboxDst(rewriter, op, symtab); mlir::func::FuncOp func = fir::runtime::getRuntimeFunc<mkRTKey(CUFDataTransferCstDesc)>( diff --git a/flang/module/cudadevice.f90 b/flang/module/cudadevice.f90 index a8b9aa8..22df9cd 100644 --- a/flang/module/cudadevice.f90 +++ b/flang/module/cudadevice.f90 @@ -2034,6 +2034,15 @@ implicit none end subroutine end interface + interface + attributes(device) subroutine tma_bulk_s2g(src, dst, nbytes) + !dir$ ignore_tkr src, dst + integer(4), shared :: src(*) + integer(4), device :: dst(*) + integer(4), value :: nbytes + end subroutine + end interface + contains attributes(device) subroutine syncthreads() diff --git a/flang/test/Fir/CUDA/cuda-data-transfer.fir b/flang/test/Fir/CUDA/cuda-data-transfer.fir index 669300c..5d3215d 100644 --- a/flang/test/Fir/CUDA/cuda-data-transfer.fir +++ b/flang/test/Fir/CUDA/cuda-data-transfer.fir @@ -651,5 +651,45 @@ func.func @_QPsub28() { // CHECK: %[[BOX_NONE:.*]] = fir.convert %[[DESC]] : (!fir.ref<!fir.box<!fir.logical<8>>>) -> !fir.ref<!fir.box<none>> // CHECK: fir.call @_FortranACUFDataTransferCstDesc(%{{.*}}, %[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, i32, !fir.ref<i8>, i32) -> () +func.func @_QPtesti4(%arg0: !fir.ref<i32> {fir.bindc_name = "n1"}, %arg1: !fir.ref<i32> {fir.bindc_name = "n2"}, %arg2: !fir.ref<i32> {fir.bindc_name = "n3"}, %arg3: !fir.ref<i32> {fir.bindc_name = "n4"}) { + %true = arith.constant true + %c0 = arith.constant 0 : index + %c2_i32 = arith.constant 2 : i32 + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtesti4En1"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) + %2:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtesti4En2"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) + %3:2 = hlfir.declare %arg2 dummy_scope %0 {uniq_name = "_QFtesti4En3"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) + %4:2 = hlfir.declare %arg3 dummy_scope %0 {uniq_name = "_QFtesti4En4"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) + %5 = fir.load %1#0 : !fir.ref<i32> + %6 = arith.divsi %5, %c2_i32 : i32 + %7 = fir.convert %6 : (i32) -> index + %8 = arith.cmpi sgt, %7, %c0 : index + %9 = arith.select %8, %7, %c0 : index + %10 = fir.load %2#0 : !fir.ref<i32> + %11 = arith.divsi %10, %c2_i32 : i32 + %12 = fir.convert %11 : (i32) -> index + %13 = arith.cmpi sgt, %12, %c0 : index + %14 = arith.select %13, %12, %c0 : index + %15 = fir.load %3#0 : !fir.ref<i32> + %16 = arith.divsi %15, %c2_i32 : i32 + %17 = fir.convert %16 : (i32) -> index + %18 = arith.cmpi sgt, %17, %c0 : index + %19 = arith.select %18, %17, %c0 : index + %20 = fir.load %4#0 : !fir.ref<i32> + %21 = arith.divsi %20, %c2_i32 : i32 + %22 = fir.convert %21 : (i32) -> index + %23 = arith.cmpi sgt, %22, %c0 : index + %24 = arith.select %23, %22, %c0 : index + %25 = cuf.alloc !fir.array<?x?x?x?x!fir.logical<4>>, %9, %14, %19, %24 : index, index, index, index {bindc_name = "lma", data_attr = #cuf.cuda<managed>, uniq_name = "_QFtesti4Elma"} -> !fir.ref<!fir.array<?x?x?x?x!fir.logical<4>>> + %26 = fir.shape %9, %14, %19, %24 : (index, index, index, index) -> !fir.shape<4> + %27:2 = hlfir.declare %25(%26) {data_attr = #cuf.cuda<managed>, uniq_name = "_QFtesti4Elma"} : (!fir.ref<!fir.array<?x?x?x?x!fir.logical<4>>>, !fir.shape<4>) -> (!fir.box<!fir.array<?x?x?x?x!fir.logical<4>>>, !fir.ref<!fir.array<?x?x?x?x!fir.logical<4>>>) + cuf.data_transfer %true to %27#1, %26 : !fir.shape<4> {transfer_kind = #cuf.cuda_transfer<host_device>} : i1, !fir.ref<!fir.array<?x?x?x?x!fir.logical<4>>> + cuf.free %27#1 : !fir.ref<!fir.array<?x?x?x?x!fir.logical<4>>> {data_attr = #cuf.cuda<managed>} + return +} + +// CHECK-LABEL: func.func @_QPtesti4 +// CHECK: fir.call @_FortranACUFDataTransferCstDesc + } // end of module diff --git a/flang/test/Lower/CUDA/cuda-device-proc.cuf b/flang/test/Lower/CUDA/cuda-device-proc.cuf index 83ee011..29c348c 100644 --- a/flang/test/Lower/CUDA/cuda-device-proc.cuf +++ b/flang/test/Lower/CUDA/cuda-device-proc.cuf @@ -438,7 +438,7 @@ end subroutine ! CHECK: nvvm.cp.async.bulk.commit.group ! CHECK: nvvm.cp.async.bulk.wait_group 0 -attributes(global) subroutine test_bulk_g2s(c, a, b, n) +attributes(global) subroutine test_bulk_g2s(a) real(8), device :: a(*) real(8), shared :: tmpa(1024) integer(8), shared :: barrier1 @@ -448,3 +448,13 @@ end subroutine ! CHECK-LABEL: func.func @_QPtest_bulk_g2s ! CHECK: nvvm.cp.async.bulk.shared.cluster.global %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : <7>, <1> + +attributes(global) subroutine test_bulk_s2g(a) + real(8), device :: a(*) + real(8), shared :: tmpa(1024) + integer(4) :: tx_count + call tma_bulk_s2g(tmpa, a(j), tx_count) +end subroutine + +! CHECK-LABEL: func.func @_QPtest_bulk_s2g +! CHECL: nvvm.cp.async.bulk.global.shared.cta %{{.*}}, %{{.*}}, %{{.*}} : <1>, <3> diff --git a/flang/test/Lower/namelist.f90 b/flang/test/Lower/namelist.f90 index 770af46..a258da1 100644 --- a/flang/test/Lower/namelist.f90 +++ b/flang/test/Lower/namelist.f90 @@ -123,6 +123,45 @@ subroutine global_pointer write(10, nml=mygroup) end +module m + type base + real :: r1 + end type + interface write(formatted) + subroutine writeformatted(dtv, unit, iotype, v_list, iostat, iomsg ) + import base + class(base), intent(in) :: dtv + integer, intent(in) :: unit + character(*), intent(in) :: iotype + integer, intent(in) :: v_list(:) + integer, intent(out) :: iostat + character(*), intent(inout) :: iomsg + end subroutine + end interface +end module + +! CHECK-LABEL: c.func @_QPlocal_poly_namelist +subroutine local_poly_namelist + use m + class(base), allocatable :: b1 +! CHECK: %[[V_0:[0-9]+]] = fir.alloca !fir.class<!fir.ptr<!fir.type<_QMmTbase{r1:f32}>>> +! CHECK: %[[V_2:[0-9]+]] = fir.alloca !fir.class<!fir.heap<!fir.type<_QMmTbase{r1:f32}>>> {bindc_name = "b1", uniq_name = "_QFlocal_poly_namelistEb1"} +! CHECK: %[[V_5:[0-9]+]] = fir.declare %[[V_2]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFlocal_poly_namelistEb1"} : (!fir.ref<!fir.class<!fir.heap<!fir.type<_QMmTbase{r1:f32}>>>>) -> !fir.ref<!fir.class<!fir.heap<!fir.type<_QMmTbase{r1:f32}>>>> +! CHECK: %[[V_9:[0-9]+]] = fir.alloca !fir.array<1xtuple<!fir.ref<i8>, !fir.ref<!fir.box<none>>>> +! CHECK: %[[V_10:[0-9]+]] = fir.undefined !fir.array<1xtuple<!fir.ref<i8>, !fir.ref<!fir.box<none>>>> +! CHECK: %[[V_11:[0-9]+]] = fir.address_of(@_QQclX623100) : !fir.ref<!fir.char<1,3>> +! CHECK: %[[V_12:[0-9]+]] = fir.convert %[[V_11]] : (!fir.ref<!fir.char<1,3>>) -> !fir.ref<i8> +! CHECK: %[[V_13:[0-9]+]] = fir.insert_value %[[V_10]], %[[V_12]], [0 : index, 0 : index] : (!fir.array<1xtuple<!fir.ref<i8>, !fir.ref<!fir.box<none>>>>, !fir.ref<i8>) -> !fir.array<1xtuple<!fir.ref<i8>, !fir.ref<!fir.box<none>>>> +! CHECK: %[[V_14:[0-9]+]] = fir.load %[[V_5]] : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMmTbase{r1:f32}>>>> +! CHECK: %[[V_15:[0-9]+]] = fir.rebox %[[V_14]] : (!fir.class<!fir.heap<!fir.type<_QMmTbase{r1:f32}>>>) -> !fir.class<!fir.ptr<!fir.type<_QMmTbase{r1:f32}>>> +! CHECK: fir.store %[[V_15]] to %[[V_0]] : !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMmTbase{r1:f32}>>>> +! CHECK: %[[V_16:[0-9]+]] = fir.convert %[[V_0]] : (!fir.ref<!fir.class<!fir.ptr<!fir.type<_QMmTbase{r1:f32}>>>>) -> !fir.ref<!fir.box<none>> +! CHECK: %[[V_17:[0-9]+]] = fir.insert_value %[[V_13]], %[[V_16]], [0 : index, 1 : index] : (!fir.array<1xtuple<!fir.ref<i8>, !fir.ref<!fir.box<none>>>>, !fir.ref<!fir.box<none>>) -> !fir.array<1xtuple<!fir.ref<i8>, !fir.ref<!fir.box<none>>>> +! CHECK: fir.store %[[V_17]] to %[[V_9]] : !fir.ref<!fir.array<1xtuple<!fir.ref<i8>, !fir.ref<!fir.box<none>>>>> + namelist/mygroup/b1 + write(10, nml=mygroup) +end subroutine + module mmm real rrr namelist /aaa/ rrr @@ -142,3 +181,4 @@ end ! CHECK-NOT: ggg ! CHECK: fir.string_lit "aaa\00"(4) : !fir.char<1,4> + diff --git a/libc/src/string/memory_utils/op_aarch64.h b/libc/src/string/memory_utils/op_aarch64.h index e552601..b5c3bb7 100644 --- a/libc/src/string/memory_utils/op_aarch64.h +++ b/libc/src/string/memory_utils/op_aarch64.h @@ -84,8 +84,7 @@ template <size_t Size> struct Bcmp { uint8x16_t a = vld1q_u8(_p1); uint8x16_t n = vld1q_u8(_p2); uint8x16_t an = veorq_u8(a, n); - uint32x2_t an_reduced = vqmovn_u64(vreinterpretq_u64_u8(an)); - return vmaxv_u32(an_reduced); + return vmaxvq_u32(vreinterpretq_u32_u8(an)); } else if constexpr (Size == 32) { auto _p1 = as_u8(p1); auto _p2 = as_u8(p2); @@ -97,12 +96,9 @@ template <size_t Size> struct Bcmp { uint8x16_t bo = veorq_u8(b, o); // anbo = (a ^ n) | (b ^ o). At least one byte is nonzero if there is // a difference between the two buffers. We reduce this value down to 4 - // bytes in two steps. First, calculate the saturated move value when - // going from 2x64b to 2x32b. Second, compute the max of the 2x32b to get - // a single 32 bit nonzero value if a mismatch occurred. + // bytes using the UMAXV instruction to compute the max across the vector. uint8x16_t anbo = vorrq_u8(an, bo); - uint32x2_t anbo_reduced = vqmovn_u64(vreinterpretq_u64_u8(anbo)); - return vmaxv_u32(anbo_reduced); + return vmaxvq_u32(vreinterpretq_u32_u8(anbo)); } else if constexpr ((Size % BlockSize) == 0) { for (size_t offset = 0; offset < Size; offset += BlockSize) if (auto value = Bcmp<BlockSize>::block(p1 + offset, p2 + offset)) @@ -129,8 +125,7 @@ template <size_t Size> struct Bcmp { uint8x16_t bo = veorq_u8(b, o); // anbo = (a ^ n) | (b ^ o) uint8x16_t anbo = vorrq_u8(an, bo); - uint32x2_t anbo_reduced = vqmovn_u64(vreinterpretq_u64_u8(anbo)); - return vmaxv_u32(anbo_reduced); + return vmaxvq_u32(vreinterpretq_u32_u8(anbo)); } else if constexpr (Size == 32) { auto _p1 = as_u8(p1); auto _p2 = as_u8(p2); @@ -150,9 +145,8 @@ template <size_t Size> struct Bcmp { uint8x16_t cpdq = vorrq_u8(cp, dq); // abnocpdq = ((a ^ n) | (b ^ o)) | ((c ^ p) | (d ^ q)). Reduce this to // a nonzero 32 bit value if a mismatch occurred. - uint64x2_t abnocpdq = vreinterpretq_u64_u8(anbo | cpdq); - uint32x2_t abnocpdq_reduced = vqmovn_u64(abnocpdq); - return vmaxv_u32(abnocpdq_reduced); + uint8x16_t abnocpdq = anbo | cpdq; + return vmaxvq_u32(vreinterpretq_u32_u8(abnocpdq)); } else { static_assert(cpp::always_false<decltype(Size)>, "SIZE not implemented"); } diff --git a/lldb/bindings/python/python-typemaps.swig b/lldb/bindings/python/python-typemaps.swig index 88b6cd9..715914f 100644 --- a/lldb/bindings/python/python-typemaps.swig +++ b/lldb/bindings/python/python-typemaps.swig @@ -233,6 +233,11 @@ AND call SWIG_fail at the same time, because it will result in a double free. } +// For lldb::SBFileSpec::GetPath +%typemap(in) (char *dst_path, size_t dst_len) = (char *dst_or_null, size_t dst_len); +%typemap(argout) (char *dst_path, size_t dst_len) = (char *dst_or_null, size_t dst_len); + + // typemap for an outgoing buffer // See also SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len). // Ditto for SBProcess::PutSTDIN(const char *src, size_t src_len). diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp index 606f951..e20dd31 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp @@ -142,7 +142,13 @@ lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd:: SyntheticChildrenFrontEnd * lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator( CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { - if (valobj_sp) + if (valobj_sp && IsLibCxxAtomic(*valobj_sp)) return new LibcxxStdAtomicSyntheticFrontEnd(valobj_sp); return nullptr; } + +bool lldb_private::formatters::IsLibCxxAtomic(ValueObject &valobj) { + if (auto valobj_sp = valobj.GetNonSyntheticValue()) + return valobj_sp->GetChildMemberWithName("__a_") != nullptr; + return false; +} diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h index 9327446..7005950 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h @@ -18,6 +18,8 @@ namespace lldb_private { namespace formatters { +bool IsLibCxxAtomic(ValueObject &valobj); + lldb::ValueObjectSP GetLibCxxAtomicValue(ValueObject &valobj); bool LibCxxAtomicSummaryProvider(ValueObject &valobj, Stream &stream, diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h index 8a49181..e818b88 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h +++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h @@ -89,6 +89,7 @@ MsvcStlVariantSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp); // MSVC STL std::atomic<> +bool IsMsvcStlAtomic(ValueObject &valobj); bool MsvcStlAtomicSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); SyntheticChildrenFrontEnd * diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStlAtomic.cpp b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlAtomic.cpp index 3ec3245..c871861 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStlAtomic.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlAtomic.cpp @@ -83,7 +83,9 @@ llvm::Expected<size_t> lldb_private::formatters:: lldb_private::SyntheticChildrenFrontEnd * lldb_private::formatters::MsvcStlAtomicSyntheticFrontEndCreator( CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { - return new MsvcStlAtomicSyntheticFrontEnd(valobj_sp); + if (valobj_sp && IsMsvcStlAtomic(*valobj_sp)) + return new MsvcStlAtomicSyntheticFrontEnd(valobj_sp); + return nullptr; } bool lldb_private::formatters::MsvcStlAtomicSummaryProvider( @@ -100,3 +102,9 @@ bool lldb_private::formatters::MsvcStlAtomicSummaryProvider( } return false; } + +bool lldb_private::formatters::IsMsvcStlAtomic(ValueObject &valobj) { + if (auto valobj_sp = valobj.GetNonSyntheticValue()) + return valobj_sp->GetChildMemberWithName("_Storage") != nullptr; + return false; +} diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp b/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp index f538fc6..57d88f6 100644 --- a/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp +++ b/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp @@ -9,6 +9,7 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/UriParser.h" diff --git a/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp index b468171..2e02076 100644 --- a/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp +++ b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp @@ -22,7 +22,7 @@ using namespace lldb_private::process_gdb_remote; using namespace lldb_private::wasm; RegisterContextWasm::RegisterContextWasm( - wasm::ThreadWasm &thread, uint32_t concrete_frame_idx, + ThreadGDBRemote &thread, uint32_t concrete_frame_idx, GDBRemoteDynamicRegisterInfoSP reg_info_sp) : GDBRemoteRegisterContext(thread, concrete_frame_idx, reg_info_sp, false, false) {} diff --git a/lldb/source/Plugins/Process/wasm/RegisterContextWasm.h b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.h index 7e63eb8..6ca31e5 100644 --- a/lldb/source/Plugins/Process/wasm/RegisterContextWasm.h +++ b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.h @@ -10,6 +10,7 @@ #define LLDB_SOURCE_PLUGINS_PROCESS_WASM_REGISTERCONTEXTWASM_H #include "Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h" +#include "Plugins/Process/gdb-remote/ThreadGDBRemote.h" #include "ThreadWasm.h" #include "Utility/WasmVirtualRegisters.h" #include "lldb/lldb-private-types.h" @@ -34,7 +35,7 @@ class RegisterContextWasm : public process_gdb_remote::GDBRemoteRegisterContext { public: RegisterContextWasm( - wasm::ThreadWasm &thread, uint32_t concrete_frame_idx, + process_gdb_remote::ThreadGDBRemote &thread, uint32_t concrete_frame_idx, process_gdb_remote::GDBRemoteDynamicRegisterInfoSP reg_info_sp); ~RegisterContextWasm() override; diff --git a/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp b/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp index 99845dd..319c5e2 100644 --- a/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp +++ b/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp @@ -9,6 +9,7 @@ #include "UnwindWasm.h" #include "Plugins/Process/gdb-remote/ThreadGDBRemote.h" #include "ProcessWasm.h" +#include "RegisterContextWasm.h" #include "ThreadWasm.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" @@ -18,21 +19,6 @@ using namespace lldb_private; using namespace process_gdb_remote; using namespace wasm; -class WasmGDBRemoteRegisterContext : public GDBRemoteRegisterContext { -public: - WasmGDBRemoteRegisterContext(ThreadGDBRemote &thread, - uint32_t concrete_frame_idx, - GDBRemoteDynamicRegisterInfoSP ®_info_sp, - uint64_t pc) - : GDBRemoteRegisterContext(thread, concrete_frame_idx, reg_info_sp, false, - false) { - // Wasm does not have a fixed set of registers but relies on a mechanism - // named local and global variables to store information such as the stack - // pointer. The only actual register is the PC. - PrivateSetRegisterValue(0, pc); - } -}; - lldb::RegisterContextSP UnwindWasm::DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) { if (m_frames.size() <= frame->GetFrameIndex()) @@ -43,9 +29,9 @@ UnwindWasm::DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) { ProcessWasm *wasm_process = static_cast<ProcessWasm *>(thread->GetProcess().get()); - return std::make_shared<WasmGDBRemoteRegisterContext>( - *gdb_thread, frame->GetConcreteFrameIndex(), - wasm_process->GetRegisterInfo(), m_frames[frame->GetFrameIndex()]); + return std::make_shared<RegisterContextWasm>(*gdb_thread, + frame->GetConcreteFrameIndex(), + wasm_process->GetRegisterInfo()); } uint32_t UnwindWasm::DoGetFrameCount() { diff --git a/lldb/source/Target/RegisterContextUnwind.cpp b/lldb/source/Target/RegisterContextUnwind.cpp index c6d15fc..252bee2 100644 --- a/lldb/source/Target/RegisterContextUnwind.cpp +++ b/lldb/source/Target/RegisterContextUnwind.cpp @@ -52,6 +52,14 @@ static ConstString GetSymbolOrFunctionName(const SymbolContext &sym_ctx) { return ConstString(); } +static bool CallFrameAddressIsValid(ABISP abi_sp, lldb::addr_t cfa) { + if (cfa == LLDB_INVALID_ADDRESS) + return false; + if (abi_sp) + return abi_sp->CallFrameAddressIsValid(cfa); + return cfa != 0 && cfa != 1; +} + RegisterContextUnwind::RegisterContextUnwind(Thread &thread, const SharedPtr &next_frame, SymbolContext &sym_ctx, @@ -448,7 +456,7 @@ void RegisterContextUnwind::InitializeNonZerothFrame() { ReadFrameAddress(row_register_kind, row->GetAFAValue(), m_afa); // A couple of sanity checks.. - if (m_cfa == LLDB_INVALID_ADDRESS || m_cfa == 0 || m_cfa == 1) { + if (!CallFrameAddressIsValid(abi_sp, m_cfa)) { UnwindLogMsg("could not find a valid cfa address"); m_frame_type = eNotAValidFrame; return; @@ -1847,9 +1855,11 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() { active_row->GetCFAValue().GetValueType() != UnwindPlan::Row::FAValue::unspecified) { addr_t new_cfa; + ProcessSP process_sp = m_thread.GetProcess(); + ABISP abi_sp = process_sp ? process_sp->GetABI() : nullptr; if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), - active_row->GetCFAValue(), new_cfa) || - new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) { + active_row->GetCFAValue(), new_cfa) || + !CallFrameAddressIsValid(abi_sp, new_cfa)) { UnwindLogMsg("failed to get cfa with fallback unwindplan"); m_fallback_unwind_plan_sp.reset(); m_full_unwind_plan_sp = original_full_unwind_plan_sp; @@ -1870,10 +1880,9 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() { if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) { new_caller_pc_value = reg_value.GetAsUInt64(); - if (ProcessSP process_sp = m_thread.GetProcess()) { - if (ABISP abi_sp = process_sp->GetABI()) - new_caller_pc_value = abi_sp->FixCodeAddress(new_caller_pc_value); - } + if (process_sp) + new_caller_pc_value = + process_sp->FixCodeAddress(new_caller_pc_value); } } } @@ -1932,9 +1941,11 @@ bool RegisterContextUnwind::ForceSwitchToFallbackUnwindPlan() { active_row->GetCFAValue().GetValueType() != UnwindPlan::Row::FAValue::unspecified) { addr_t new_cfa; + ProcessSP process_sp = m_thread.GetProcess(); + ABISP abi_sp = process_sp ? process_sp->GetABI() : nullptr; if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), - active_row->GetCFAValue(), new_cfa) || - new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) { + active_row->GetCFAValue(), new_cfa) || + !CallFrameAddressIsValid(abi_sp, new_cfa)) { UnwindLogMsg("failed to get cfa with fallback unwindplan"); m_fallback_unwind_plan_sp.reset(); return false; @@ -2055,8 +2066,7 @@ bool RegisterContextUnwind::ReadFrameAddress( RegisterNumber cfa_reg(m_thread, row_register_kind, fa.GetRegisterNumber()); if (ReadGPRValue(cfa_reg, cfa_reg_contents)) { - if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 || - cfa_reg_contents == 1) { + if (!CallFrameAddressIsValid(abi_sp, cfa_reg_contents)) { UnwindLogMsg( "Got an invalid CFA register value - reg %s (%d), value 0x%" PRIx64, cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/Makefile new file mode 100644 index 0000000..99998b2 --- /dev/null +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/TestDataFormatterInvalidAtomic.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/TestDataFormatterInvalidAtomic.py new file mode 100644 index 0000000..76b8e7b --- /dev/null +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/TestDataFormatterInvalidAtomic.py @@ -0,0 +1,45 @@ +""" +Test formatting of `std::atomic`s not from any STL +""" + +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class InvalidAtomicDataFormatterTestCase(TestBase): + def test(self): + self.build() + lldbutil.run_to_source_breakpoint( + self, "Set break point at this line.", lldb.SBFileSpec("main.cpp") + ) + + self.expect_expr( + "a", + result_children=[ + ValueCheck(name="foo", value="1"), + ValueCheck(name="bar", value="2"), + ], + ) + self.expect_expr( + "b", + result_children=[ + ValueCheck(name="foo", value="3"), + ValueCheck(name="bar", value="4"), + ], + ) + + self.expect_expr( + "c", + result_children=[ + ValueCheck(name="foo", value="5"), + ValueCheck(name="bar", value="6"), + ], + ) + self.expect_expr( + "d", + result_children=[ + ValueCheck(name="foo", value="7"), + ValueCheck(name="bar", value="8"), + ], + ) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/main.cpp new file mode 100644 index 0000000..7b4c51c --- /dev/null +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic-simulators/invalid-atomic/main.cpp @@ -0,0 +1,23 @@ +namespace std { +template <typename T> struct atomic { + int foo; + int bar; +}; + +namespace __1 { +template <typename T> struct atomic { + int foo; + int bar; +}; +} // namespace __1 +} // namespace std + +int main() { + std::atomic<int> a{1, 2}; + std::atomic<void> b{3, 4}; + + std::__1::atomic<int> c{5, 6}; + std::__1::atomic<void> d{7, 8}; + + return 0; // Set break point at this line. +} diff --git a/lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py b/lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py index 10cbd26..fc7bfe4 100644 --- a/lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py +++ b/lldb/test/API/functionalities/unwind/cortex-m-exception/TestCortexMExceptionUnwind.py @@ -12,7 +12,7 @@ from lldbsuite.test import lldbutil class TestCortexMExceptionUnwind(TestBase): NO_DEBUG_INFO_TESTCASE = True - @skipIfRemote + @skipIfLLVMTargetMissing("ARM") def test_no_fpu(self): """Test that we can backtrace correctly through an ARM Cortex-M Exception return stack""" diff --git a/lldb/test/API/macosx/mte/TestDarwinMTE.py b/lldb/test/API/macosx/mte/TestDarwinMTE.py index ef858b1..489e24a 100644 --- a/lldb/test/API/macosx/mte/TestDarwinMTE.py +++ b/lldb/test/API/macosx/mte/TestDarwinMTE.py @@ -47,7 +47,7 @@ class TestDarwinMTE(TestBase): self.expect("memory region ptr", substrs=["memory tagging: enabled"]) @skipUnlessFeature(cpu_feature.AArch64.MTE) - def test_memory_read_with_tags(self): + def test_memory_read_show_tags(self): self.build() lldbutil.run_to_source_breakpoint( self, "// before free", lldb.SBFileSpec("main.c"), exe_name=exe_name diff --git a/lldb/test/API/python_api/default-constructor/sb_filespec.py b/lldb/test/API/python_api/default-constructor/sb_filespec.py index 4ab5c49..5dd78b1 100644 --- a/lldb/test/API/python_api/default-constructor/sb_filespec.py +++ b/lldb/test/API/python_api/default-constructor/sb_filespec.py @@ -10,5 +10,5 @@ def fuzz_obj(obj): obj.ResolveExecutableLocation() obj.GetFilename() obj.GetDirectory() - obj.GetPath(None, 0) + obj.GetPath(1) obj.GetDescription(lldb.SBStream()) diff --git a/lldb/test/Shell/Expr/TestExprLanguageNote.test b/lldb/test/Shell/Expr/TestExprLanguageNote.test index 7d8c702..e8e4e13 100644 --- a/lldb/test/Shell/Expr/TestExprLanguageNote.test +++ b/lldb/test/Shell/Expr/TestExprLanguageNote.test @@ -1,5 +1,3 @@ -# REQUIRES: (system-windows && lld) || !system-windows - # RUN: split-file %s %t # RUN: %clang_host -g %t/main.cpp -o %t.out # @@ -29,7 +27,7 @@ run expr blah # CHECK-TARGET: (lldb) expr -# CHECK-TARGET: note: Ran expression as 'C++{{.*}}' +# CHECK-TARGET: note: Ran expression as '{{(ISO )?}}C++{{.*}}' expr -l objc -- blah diff --git a/lldb/utils/lui/lui.py b/lldb/utils/lui/lui.py index 42ea3c6..27ed8f3 100755 --- a/lldb/utils/lui/lui.py +++ b/lldb/utils/lui/lui.py @@ -17,11 +17,7 @@ from optparse import OptionParser import os import signal import sys - -try: - import queue -except ImportError: - import Queue as queue +import queue import debuggerdriver import cui diff --git a/lldb/utils/lui/sandbox.py b/lldb/utils/lui/sandbox.py index 3bcf3d5..d05c268 100755 --- a/lldb/utils/lui/sandbox.py +++ b/lldb/utils/lui/sandbox.py @@ -14,10 +14,7 @@ import os import signal import sys -try: - import queue -except ImportError: - import Queue as queue +import queue import cui diff --git a/llvm/include/llvm/ADT/Bitfields.h b/llvm/include/llvm/ADT/Bitfields.h index 4064d71..1af2761 100644 --- a/llvm/include/llvm/ADT/Bitfields.h +++ b/llvm/include/llvm/ADT/Bitfields.h @@ -86,89 +86,43 @@ #include <limits> // numeric_limits #include <type_traits> +#include "llvm/Support/MathExtras.h" + namespace llvm { namespace bitfields_details { -/// A struct defining useful bit patterns for n-bits integer types. -template <typename T, unsigned Bits> struct BitPatterns { - /// Bit patterns are forged using the equivalent `Unsigned` type because of - /// undefined operations over signed types (e.g. Bitwise shift operators). - /// Moreover same size casting from unsigned to signed is well defined but not - /// the other way around. - using Unsigned = std::make_unsigned_t<T>; - static_assert(sizeof(Unsigned) == sizeof(T), "Types must have same size"); - - static constexpr unsigned TypeBits = sizeof(Unsigned) * CHAR_BIT; - static_assert(TypeBits >= Bits, "n-bit must fit in T"); - - /// e.g. with TypeBits == 8 and Bits == 6. - static constexpr Unsigned AllZeros = Unsigned(0); // 00000000 - static constexpr Unsigned AllOnes = ~Unsigned(0); // 11111111 - static constexpr Unsigned Umin = AllZeros; // 00000000 - static constexpr Unsigned Umax = AllOnes >> (TypeBits - Bits); // 00111111 - static constexpr Unsigned SignBitMask = Unsigned(1) << (Bits - 1); // 00100000 - static constexpr Unsigned Smax = Umax >> 1U; // 00011111 - static constexpr Unsigned Smin = ~Smax; // 11100000 - static constexpr Unsigned SignExtend = Unsigned(Smin << 1U); // 11000000 -}; - -/// `Compressor` is used to manipulate the bits of a (possibly signed) integer -/// type so it can be packed and unpacked into a `bits` sized integer, -/// `Compressor` is specialized on signed-ness so no runtime cost is incurred. -/// The `pack` method also checks that the passed in `UserValue` is valid. -template <typename T, unsigned Bits, bool = std::is_unsigned<T>::value> -struct Compressor { - static_assert(std::is_unsigned<T>::value, "T must be unsigned"); - using BP = BitPatterns<T, Bits>; - - static T pack(T UserValue, T UserMaxValue) { - assert(UserValue <= UserMaxValue && "value is too big"); - assert(UserValue <= BP::Umax && "value is too big"); - return UserValue; - } - - static T unpack(T StorageValue) { return StorageValue; } -}; - -template <typename T, unsigned Bits> struct Compressor<T, Bits, false> { - static_assert(std::is_signed<T>::value, "T must be signed"); - using BP = BitPatterns<T, Bits>; - - static T pack(T UserValue, T UserMaxValue) { - assert(UserValue <= UserMaxValue && "value is too big"); - assert(UserValue <= T(BP::Smax) && "value is too big"); - assert(UserValue >= T(BP::Smin) && "value is too small"); - if (UserValue < 0) - UserValue &= ~BP::SignExtend; - return UserValue; - } - - static T unpack(T StorageValue) { - if (StorageValue >= T(BP::SignBitMask)) - StorageValue |= BP::SignExtend; - return StorageValue; - } -}; - /// Impl is where Bifield description and Storage are put together to interact /// with values. template <typename Bitfield, typename StorageType> struct Impl { static_assert(std::is_unsigned<StorageType>::value, "Storage must be unsigned"); using IntegerType = typename Bitfield::IntegerType; - using C = Compressor<IntegerType, Bitfield::Bits>; - using BP = BitPatterns<StorageType, Bitfield::Bits>; static constexpr size_t StorageBits = sizeof(StorageType) * CHAR_BIT; static_assert(Bitfield::FirstBit <= StorageBits, "Data must fit in mask"); static_assert(Bitfield::LastBit <= StorageBits, "Data must fit in mask"); - static constexpr StorageType Mask = BP::Umax << Bitfield::Shift; + static constexpr StorageType LowMask = + maskTrailingOnes<StorageType>(Bitfield::Bits); + static constexpr StorageType Mask = LowMask << Bitfield::Shift; + + /// Validates that `UserValue` fits within the bitfield's range. + static void checkValue(IntegerType UserValue, IntegerType UserMaxValue) { + assert(UserValue <= UserMaxValue && "value is too big"); + if constexpr (std::is_unsigned_v<IntegerType>) { + assert(isUInt<Bitfield::Bits>(UserValue) && "value is too big"); + } else { + static_assert(std::is_signed_v<IntegerType>, + "IntegerType must be signed"); + assert(isInt<Bitfield::Bits>(UserValue) && "value is out of range"); + } + } /// Checks `UserValue` is within bounds and packs it between `FirstBit` and /// `LastBit` of `Packed` leaving the rest unchanged. static void update(StorageType &Packed, IntegerType UserValue) { - const StorageType StorageValue = C::pack(UserValue, Bitfield::UserMaxValue); + checkValue(UserValue, Bitfield::UserMaxValue); + const StorageType StorageValue = UserValue & LowMask; Packed &= ~Mask; Packed |= StorageValue << Bitfield::Shift; } @@ -177,7 +131,9 @@ template <typename Bitfield, typename StorageType> struct Impl { /// an`IntegerType`. static IntegerType extract(StorageType Packed) { const StorageType StorageValue = (Packed & Mask) >> Bitfield::Shift; - return C::unpack(StorageValue); + if constexpr (std::is_signed_v<IntegerType>) + return SignExtend64<Bitfield::Bits>(StorageValue); + return StorageValue; } /// Interprets bits between `FirstBit` and `LastBit` of `Packed` as diff --git a/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h b/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h index 164b46b..07a482d 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h +++ b/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h @@ -182,6 +182,12 @@ m_scev_PtrToInt(const Op0_t &Op0) { return SCEVUnaryExpr_match<SCEVPtrToIntExpr, Op0_t>(Op0); } +template <typename Op0_t> +inline SCEVUnaryExpr_match<SCEVTruncateExpr, Op0_t> +m_scev_Trunc(const Op0_t &Op0) { + return m_scev_Unary<SCEVTruncateExpr>(Op0); +} + /// Match a binary SCEV. template <typename SCEVTy, typename Op0_t, typename Op1_t, SCEV::NoWrapFlags WrapFlags = SCEV::FlagAnyWrap, diff --git a/llvm/include/llvm/Analysis/StaticDataProfileInfo.h b/llvm/include/llvm/Analysis/StaticDataProfileInfo.h index fa21eba..f06e7ce 100644 --- a/llvm/include/llvm/Analysis/StaticDataProfileInfo.h +++ b/llvm/include/llvm/Analysis/StaticDataProfileInfo.h @@ -10,6 +10,24 @@ namespace llvm { +namespace memprof { +// Represents the eligibility status of a global variable for section prefix +// annotation. Other than AnnotationOk, each enum value indicates a specific +// reason for ineligibility. +enum class AnnotationKind : uint8_t { + AnnotationOK, + DeclForLinker, + ExplicitSection, + ReservedName, +}; +/// Returns the annotation kind of the global variable \p GV. +AnnotationKind getAnnotationKind(const GlobalVariable &GV); + +/// Returns true if the annotation kind of the global variable \p GV is +/// AnnotationOK. +bool IsAnnotationOK(const GlobalVariable &GV); +} // namespace memprof + /// A class that holds the constants that represent static data and their /// profile information and provides methods to operate on them. class StaticDataProfileInfo { diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h index c76c83d..ff3dd0d 100644 --- a/llvm/include/llvm/CodeGen/ISDOpcodes.h +++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h @@ -514,6 +514,12 @@ enum NodeType { /// separately rounded operations. FMAD, + /// FMULADD - Performs a * b + c, with, or without, intermediate rounding. + /// It is expected that this will be illegal for most targets, as it usually + /// makes sense to split this or use an FMA. But some targets, such as + /// WebAssembly, can directly support these semantics. + FMULADD, + /// FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This /// DAG node does not require that X and Y have the same type, just that /// they are both floating point. X and the result must have the same type. diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def index 1694a33..46b3d53 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def +++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def @@ -472,7 +472,7 @@ __OMP_RTL(__kmpc_target_init, false, Int32, KernelEnvironmentPtr, KernelLaunchEn __OMP_RTL(__kmpc_target_deinit, false, Void,) __OMP_RTL(__kmpc_kernel_prepare_parallel, false, Void, VoidPtr) __OMP_RTL(__kmpc_parallel_51, false, Void, IdentPtr, Int32, Int32, Int32, Int32, - FuncPtrTy, VoidPtr, VoidPtrPtr, SizeTy) + FuncPtrTy, FuncPtrTy, VoidPtrPtr, SizeTy) __OMP_RTL(__kmpc_for_static_loop_4, false, Void, IdentPtr, VoidPtr, VoidPtr, Int32, Int32, Int32, Int8) __OMP_RTL(__kmpc_for_static_loop_4u, false, Void, IdentPtr, VoidPtr, VoidPtr, Int32, Int32, Int32, Int8) __OMP_RTL(__kmpc_for_static_loop_8, false, Void, IdentPtr, VoidPtr, VoidPtr, Int64, Int64, Int64, Int8) diff --git a/llvm/include/llvm/IR/ConstantFPRange.h b/llvm/include/llvm/IR/ConstantFPRange.h index 10467cc..e772095 100644 --- a/llvm/include/llvm/IR/ConstantFPRange.h +++ b/llvm/include/llvm/IR/ConstantFPRange.h @@ -231,6 +231,15 @@ public: /// from a subtraction of a value in this range and a value in \p Other. LLVM_ABI ConstantFPRange sub(const ConstantFPRange &Other) const; + /// Return a new range representing the possible values resulting + /// from a multiplication of a value in this range and a value in \p Other. + LLVM_ABI ConstantFPRange mul(const ConstantFPRange &Other) const; + + /// Return a new range representing the possible values resulting + /// from a division of a value in this range and a value in + /// \p Other. + LLVM_ABI ConstantFPRange div(const ConstantFPRange &Other) const; + /// Flush denormal values to zero according to the specified mode. /// For dynamic mode, we return the union of all possible results. LLVM_ABI void flushDenormals(DenormalMode::DenormalModeKind Mode); diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index 041a4ce..dacda0a 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -2548,6 +2548,11 @@ public: std::optional<RoundingMode> Rounding = std::nullopt, std::optional<fp::ExceptionBehavior> Except = std::nullopt); + LLVM_ABI Value *CreateSelectWithUnknownProfile(Value *C, Value *True, + Value *False, + StringRef PassName, + const Twine &Name = ""); + LLVM_ABI Value *CreateSelect(Value *C, Value *True, Value *False, const Twine &Name = "", Instruction *MDFrom = nullptr); diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td index 632be7a..07a858f 100644 --- a/llvm/include/llvm/Target/TargetSelectionDAG.td +++ b/llvm/include/llvm/Target/TargetSelectionDAG.td @@ -535,6 +535,7 @@ def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>; def frem : SDNode<"ISD::FREM" , SDTFPBinOp>; def fma : SDNode<"ISD::FMA" , SDTFPTernaryOp, [SDNPCommutative]>; def fmad : SDNode<"ISD::FMAD" , SDTFPTernaryOp, [SDNPCommutative]>; +def fmuladd : SDNode<"ISD::FMULADD" , SDTFPTernaryOp, [SDNPCommutative]>; def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>; def fminnum : SDNode<"ISD::FMINNUM" , SDTFPBinOp, [SDNPCommutative, SDNPAssociative]>; diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.h b/llvm/include/llvm/TargetParser/RISCVTargetParser.h index b1fca55..2ac58a5 100644 --- a/llvm/include/llvm/TargetParser/RISCVTargetParser.h +++ b/llvm/include/llvm/TargetParser/RISCVTargetParser.h @@ -161,6 +161,8 @@ inline static bool isAltFmt(unsigned VType) { return VType & 0x100; } LLVM_ABI void printVType(unsigned VType, raw_ostream &OS); +LLVM_ABI void printXSfmmVType(unsigned VType, raw_ostream &OS); + LLVM_ABI unsigned getSEWLMULRatio(unsigned SEW, VLMUL VLMul); LLVM_ABI std::optional<VLMUL> getSameRatioLMUL(unsigned SEW, VLMUL VLMUL, diff --git a/llvm/include/llvm/Transforms/Coroutines/MaterializationUtils.h b/llvm/include/llvm/Transforms/Coroutines/MaterializationUtils.h index 558984f..eb2b34d 100644 --- a/llvm/include/llvm/Transforms/Coroutines/MaterializationUtils.h +++ b/llvm/include/llvm/Transforms/Coroutines/MaterializationUtils.h @@ -12,9 +12,7 @@ #ifndef LLVM_TRANSFORMS_COROUTINES_MATERIALIZATIONUTILS_H #define LLVM_TRANSFORMS_COROUTINES_MATERIALIZATIONUTILS_H -namespace llvm { - -namespace coro { +namespace llvm::coro { // True if I is trivially rematerialzable, e.g. InsertElementInst LLVM_ABI bool isTriviallyMaterializable(Instruction &I); @@ -24,8 +22,6 @@ LLVM_ABI void doRematerializations(Function &F, SuspendCrossingInfo &Checker, std::function<bool(Instruction &)> IsMaterializable); -} // namespace coro - -} // namespace llvm +} // namespace llvm::coro #endif // LLVM_TRANSFORMS_COROUTINES_MATERIALIZATIONUTILS_H diff --git a/llvm/include/llvm/Transforms/Coroutines/SpillUtils.h b/llvm/include/llvm/Transforms/Coroutines/SpillUtils.h index 6cdf83c0..356f9ca 100644 --- a/llvm/include/llvm/Transforms/Coroutines/SpillUtils.h +++ b/llvm/include/llvm/Transforms/Coroutines/SpillUtils.h @@ -13,9 +13,7 @@ #ifndef LLVM_TRANSFORMS_COROUTINES_SPILLINGINFO_H #define LLVM_TRANSFORMS_COROUTINES_SPILLINGINFO_H -namespace llvm { - -namespace coro { +namespace llvm::coro { using SpillInfo = SmallMapVector<Value *, SmallVector<Instruction *, 2>, 8>; @@ -38,6 +36,7 @@ void collectSpillsAndAllocasFromInsts( SmallVector<CoroAllocaAllocInst *, 4> &LocalAllocas, Function &F, const SuspendCrossingInfo &Checker, const DominatorTree &DT, const coro::Shape &Shape); + void collectSpillsFromDbgInfo(SpillInfo &Spills, Function &F, const SuspendCrossingInfo &Checker); @@ -52,8 +51,6 @@ void sinkSpillUsesAfterCoroBegin(const DominatorTree &DT, BasicBlock::iterator getSpillInsertionPt(const coro::Shape &, Value *Def, const DominatorTree &DT); -} // namespace coro - -} // namespace llvm +} // namespace llvm::coro #endif // LLVM_TRANSFORMS_COROUTINES_SPILLINGINFO_H diff --git a/llvm/include/llvm/XRay/BlockIndexer.h b/llvm/include/llvm/XRay/BlockIndexer.h index e9782da..155e6bd 100644 --- a/llvm/include/llvm/XRay/BlockIndexer.h +++ b/llvm/include/llvm/XRay/BlockIndexer.h @@ -19,8 +19,7 @@ #include <cstdint> #include <vector> -namespace llvm { -namespace xray { +namespace llvm::xray { // The BlockIndexer will gather all related records associated with a // process+thread and group them by 'Block'. @@ -63,7 +62,6 @@ public: Error flush(); }; -} // namespace xray -} // namespace llvm +} // namespace llvm::xray #endif // LLVM_XRAY_BLOCKINDEXER_H diff --git a/llvm/include/llvm/XRay/BlockPrinter.h b/llvm/include/llvm/XRay/BlockPrinter.h index caf78c5..81944a5 100644 --- a/llvm/include/llvm/XRay/BlockPrinter.h +++ b/llvm/include/llvm/XRay/BlockPrinter.h @@ -18,8 +18,7 @@ #include "llvm/XRay/FDRRecords.h" #include "llvm/XRay/RecordPrinter.h" -namespace llvm { -namespace xray { +namespace llvm::xray { class LLVM_ABI BlockPrinter : public RecordVisitor { enum class State { @@ -55,7 +54,6 @@ public: void reset() { CurrentState = State::Start; } }; -} // namespace xray -} // namespace llvm +} // namespace llvm::xray #endif // LLVM_XRAY_BLOCKPRINTER_H diff --git a/llvm/include/llvm/XRay/BlockVerifier.h b/llvm/include/llvm/XRay/BlockVerifier.h index b88785c..5e7b25c 100644 --- a/llvm/include/llvm/XRay/BlockVerifier.h +++ b/llvm/include/llvm/XRay/BlockVerifier.h @@ -16,8 +16,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/XRay/FDRRecords.h" -namespace llvm { -namespace xray { +namespace llvm::xray { class LLVM_ABI BlockVerifier : public RecordVisitor { public: @@ -64,7 +63,6 @@ public: void reset(); }; -} // namespace xray -} // namespace llvm +} // namespace llvm::xray #endif // LLVM_XRAY_BLOCKVERIFIER_H diff --git a/llvm/include/llvm/XRay/FDRLogBuilder.h b/llvm/include/llvm/XRay/FDRLogBuilder.h index f07c446..5f7b815 100644 --- a/llvm/include/llvm/XRay/FDRLogBuilder.h +++ b/llvm/include/llvm/XRay/FDRLogBuilder.h @@ -10,8 +10,7 @@ #include "llvm/XRay/FDRRecords.h" -namespace llvm { -namespace xray { +namespace llvm::xray { /// The LogBuilder class allows for creating ad-hoc collections of records /// through the `add<...>(...)` function. An example use of this API is in @@ -34,7 +33,6 @@ public: std::vector<std::unique_ptr<Record>> consume() { return std::move(Records); } }; -} // namespace xray -} // namespace llvm +} // namespace llvm::xray #endif // LLVM_XRAY_FDRLOGBUILDER_H diff --git a/llvm/include/llvm/XRay/FDRRecordConsumer.h b/llvm/include/llvm/XRay/FDRRecordConsumer.h index 473777f..13bb711 100644 --- a/llvm/include/llvm/XRay/FDRRecordConsumer.h +++ b/llvm/include/llvm/XRay/FDRRecordConsumer.h @@ -15,8 +15,7 @@ #include <memory> #include <vector> -namespace llvm { -namespace xray { +namespace llvm::xray { class RecordConsumer { public: @@ -48,7 +47,6 @@ public: Error consume(std::unique_ptr<Record> R) override; }; -} // namespace xray -} // namespace llvm +} // namespace llvm::xray #endif // LLVM_XRAY_FDRRECORDCONSUMER_H diff --git a/llvm/include/llvm/XRay/FDRRecordProducer.h b/llvm/include/llvm/XRay/FDRRecordProducer.h index 083b571..b953f62 100644 --- a/llvm/include/llvm/XRay/FDRRecordProducer.h +++ b/llvm/include/llvm/XRay/FDRRecordProducer.h @@ -14,8 +14,7 @@ #include "llvm/XRay/XRayRecord.h" #include <memory> -namespace llvm { -namespace xray { +namespace llvm::xray { class RecordProducer { public: @@ -45,7 +44,6 @@ public: Expected<std::unique_ptr<Record>> produce() override; }; -} // namespace xray -} // namespace llvm +} // namespace llvm::xray #endif // LLVM_XRAY_FDRRECORDPRODUCER_H diff --git a/llvm/include/llvm/XRay/FDRRecords.h b/llvm/include/llvm/XRay/FDRRecords.h index 7ee8db6..91689cae 100644 --- a/llvm/include/llvm/XRay/FDRRecords.h +++ b/llvm/include/llvm/XRay/FDRRecords.h @@ -23,8 +23,7 @@ #include "llvm/Support/Error.h" #include "llvm/XRay/XRayRecord.h" -namespace llvm { -namespace xray { +namespace llvm::xray { class RecordVisitor; class RecordInitializer; @@ -444,7 +443,6 @@ public: Error visit(TypedEventRecord &) override; }; -} // namespace xray -} // namespace llvm +} // namespace llvm::xray #endif // LLVM_XRAY_FDRRECORDS_H diff --git a/llvm/include/llvm/XRay/FDRTraceExpander.h b/llvm/include/llvm/XRay/FDRTraceExpander.h index 197c123..ca400c9 100644 --- a/llvm/include/llvm/XRay/FDRTraceExpander.h +++ b/llvm/include/llvm/XRay/FDRTraceExpander.h @@ -17,8 +17,7 @@ #include "llvm/XRay/FDRRecords.h" #include "llvm/XRay/XRayRecord.h" -namespace llvm { -namespace xray { +namespace llvm::xray { class TraceExpander : public RecordVisitor { // Type-erased callback for handling individual XRayRecord instances. @@ -56,7 +55,6 @@ public: Error flush(); }; -} // namespace xray -} // namespace llvm +} // namespace llvm::xray #endif // LLVM_XRAY_FDRTRACEEXPANDER_H diff --git a/llvm/include/llvm/XRay/FDRTraceWriter.h b/llvm/include/llvm/XRay/FDRTraceWriter.h index a3dc58e..957039d 100644 --- a/llvm/include/llvm/XRay/FDRTraceWriter.h +++ b/llvm/include/llvm/XRay/FDRTraceWriter.h @@ -18,8 +18,7 @@ #include "llvm/XRay/FDRRecords.h" #include "llvm/XRay/XRayRecord.h" -namespace llvm { -namespace xray { +namespace llvm::xray { /// The FDRTraceWriter allows us to hand-craft an XRay Flight Data Recorder /// (FDR) mode log file. This is used primarily for testing, generating @@ -50,7 +49,6 @@ private: support::endian::Writer OS; }; -} // namespace xray -} // namespace llvm +} // namespace llvm::xray #endif // LLVM_XRAY_FDRTRACEWRITER_H diff --git a/llvm/include/llvm/XRay/FileHeaderReader.h b/llvm/include/llvm/XRay/FileHeaderReader.h index ecdb975..758ca29 100644 --- a/llvm/include/llvm/XRay/FileHeaderReader.h +++ b/llvm/include/llvm/XRay/FileHeaderReader.h @@ -19,15 +19,13 @@ #include "llvm/XRay/XRayRecord.h" #include <cstdint> -namespace llvm { -namespace xray { +namespace llvm::xray { /// Convenience function for loading the file header given a data extractor at a /// specified offset. LLVM_ABI Expected<XRayFileHeader> readBinaryFormatHeader(DataExtractor &HeaderExtractor, uint64_t &OffsetPtr); -} // namespace xray -} // namespace llvm +} // namespace llvm::xray #endif // LLVM_XRAY_FILEHEADERREADER_H diff --git a/llvm/include/llvm/XRay/Graph.h b/llvm/include/llvm/XRay/Graph.h index 07b418b..8521e09 100644 --- a/llvm/include/llvm/XRay/Graph.h +++ b/llvm/include/llvm/XRay/Graph.h @@ -23,8 +23,7 @@ #include "llvm/ADT/iterator.h" #include "llvm/Support/Error.h" -namespace llvm { -namespace xray { +namespace llvm::xray { /// A Graph object represents a Directed Graph and is used in XRay to compute /// and store function call graphs and associated statistical information. @@ -485,6 +484,6 @@ public: return p; } }; -} -} +} // namespace llvm::xray + #endif diff --git a/llvm/include/llvm/XRay/InstrumentationMap.h b/llvm/include/llvm/XRay/InstrumentationMap.h index b5371478..c5e7ebf 100644 --- a/llvm/include/llvm/XRay/InstrumentationMap.h +++ b/llvm/include/llvm/XRay/InstrumentationMap.h @@ -23,9 +23,7 @@ #include <unordered_map> #include <vector> -namespace llvm { - -namespace xray { +namespace llvm::xray { // Forward declare to make a friend. class InstrumentationMap; @@ -102,11 +100,11 @@ public: const SledContainer &sleds() const { return Sleds; }; }; -} // end namespace xray - -namespace yaml { +} // end namespace llvm::xray -template <> struct ScalarEnumerationTraits<xray::SledEntry::FunctionKinds> { +namespace llvm { +template <> +struct yaml::ScalarEnumerationTraits<xray::SledEntry::FunctionKinds> { static void enumeration(IO &IO, xray::SledEntry::FunctionKinds &Kind) { IO.enumCase(Kind, "function-enter", xray::SledEntry::FunctionKinds::ENTRY); IO.enumCase(Kind, "function-exit", xray::SledEntry::FunctionKinds::EXIT); @@ -118,7 +116,7 @@ template <> struct ScalarEnumerationTraits<xray::SledEntry::FunctionKinds> { } }; -template <> struct MappingTraits<xray::YAMLXRaySledEntry> { +template <> struct yaml::MappingTraits<xray::YAMLXRaySledEntry> { static void mapping(IO &IO, xray::YAMLXRaySledEntry &Entry) { IO.mapRequired("id", Entry.FuncId); IO.mapRequired("address", Entry.Address); @@ -131,10 +129,7 @@ template <> struct MappingTraits<xray::YAMLXRaySledEntry> { static constexpr bool flow = true; }; - -} // end namespace yaml - -} // end namespace llvm +} // namespace llvm LLVM_YAML_IS_SEQUENCE_VECTOR(xray::YAMLXRaySledEntry) diff --git a/llvm/include/llvm/XRay/Profile.h b/llvm/include/llvm/XRay/Profile.h index e30c01e..b5b8dd2 100644 --- a/llvm/include/llvm/XRay/Profile.h +++ b/llvm/include/llvm/XRay/Profile.h @@ -22,8 +22,7 @@ #include <utility> #include <vector> -namespace llvm { -namespace xray { +namespace llvm::xray { class Profile; @@ -144,7 +143,6 @@ public: bool empty() const { return Blocks.empty(); } }; -} // namespace xray -} // namespace llvm +} // namespace llvm::xray #endif diff --git a/llvm/include/llvm/XRay/RecordPrinter.h b/llvm/include/llvm/XRay/RecordPrinter.h index 5d2c277..3281221 100644 --- a/llvm/include/llvm/XRay/RecordPrinter.h +++ b/llvm/include/llvm/XRay/RecordPrinter.h @@ -17,8 +17,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/XRay/FDRRecords.h" -namespace llvm { -namespace xray { +namespace llvm::xray { class LLVM_ABI RecordPrinter : public RecordVisitor { raw_ostream &OS; @@ -44,7 +43,6 @@ public: Error visit(TypedEventRecord &) override; }; -} // namespace xray -} // namespace llvm +} // namespace llvm::xray #endif // LLVM_XRAY_RECORDPRINTER_H diff --git a/llvm/include/llvm/XRay/Trace.h b/llvm/include/llvm/XRay/Trace.h index 5e4e40a..13ada22 100644 --- a/llvm/include/llvm/XRay/Trace.h +++ b/llvm/include/llvm/XRay/Trace.h @@ -21,8 +21,7 @@ #include "llvm/Support/Error.h" #include "llvm/XRay/XRayRecord.h" -namespace llvm { -namespace xray { +namespace llvm::xray { /// A Trace object represents the records that have been loaded from XRay /// log files generated by instrumented binaries. We encapsulate the logic of @@ -76,7 +75,6 @@ LLVM_ABI Expected<Trace> loadTraceFile(StringRef Filename, bool Sort = false); LLVM_ABI Expected<Trace> loadTrace(const DataExtractor &Extractor, bool Sort = false); -} // namespace xray -} // namespace llvm +} // namespace llvm::xray #endif // LLVM_XRAY_TRACE_H diff --git a/llvm/include/llvm/XRay/XRayRecord.h b/llvm/include/llvm/XRay/XRayRecord.h index 238bf3d..8f3440c 100644 --- a/llvm/include/llvm/XRay/XRayRecord.h +++ b/llvm/include/llvm/XRay/XRayRecord.h @@ -18,8 +18,7 @@ #include <vector> #include <string> -namespace llvm { -namespace xray { +namespace llvm::xray { /// XRay traces all have a header providing some top-matter information useful /// to help tools determine how to interpret the information available in the @@ -98,7 +97,6 @@ struct XRayRecord { std::string Data; }; -} // namespace xray -} // namespace llvm +} // namespace llvm::xray #endif // LLVM_XRAY_XRAYRECORD_H diff --git a/llvm/include/llvm/XRay/YAMLXRayRecord.h b/llvm/include/llvm/XRay/YAMLXRayRecord.h index 6062606..6bf4f1d 100644 --- a/llvm/include/llvm/XRay/YAMLXRayRecord.h +++ b/llvm/include/llvm/XRay/YAMLXRayRecord.h @@ -17,8 +17,7 @@ #include "llvm/Support/YAMLTraits.h" #include "llvm/XRay/XRayRecord.h" -namespace llvm { -namespace xray { +namespace llvm::xray { struct YAMLXRayFileHeader { uint16_t Version; @@ -46,13 +45,12 @@ struct YAMLXRayTrace { std::vector<YAMLXRayRecord> Records; }; -} // namespace xray - -namespace yaml { +} // namespace llvm::xray +namespace llvm { // YAML Traits // ----------- -template <> struct ScalarEnumerationTraits<xray::RecordTypes> { +template <> struct yaml::ScalarEnumerationTraits<xray::RecordTypes> { static void enumeration(IO &IO, xray::RecordTypes &Type) { IO.enumCase(Type, "function-enter", xray::RecordTypes::ENTER); IO.enumCase(Type, "function-exit", xray::RecordTypes::EXIT); @@ -63,7 +61,7 @@ template <> struct ScalarEnumerationTraits<xray::RecordTypes> { } }; -template <> struct MappingTraits<xray::YAMLXRayFileHeader> { +template <> struct yaml::MappingTraits<xray::YAMLXRayFileHeader> { static void mapping(IO &IO, xray::YAMLXRayFileHeader &Header) { IO.mapRequired("version", Header.Version); IO.mapRequired("type", Header.Type); @@ -73,7 +71,7 @@ template <> struct MappingTraits<xray::YAMLXRayFileHeader> { } }; -template <> struct MappingTraits<xray::YAMLXRayRecord> { +template <> struct yaml::MappingTraits<xray::YAMLXRayRecord> { static void mapping(IO &IO, xray::YAMLXRayRecord &Record) { IO.mapRequired("type", Record.RecordType); IO.mapOptional("func-id", Record.FuncId); @@ -90,7 +88,7 @@ template <> struct MappingTraits<xray::YAMLXRayRecord> { static constexpr bool flow = true; }; -template <> struct MappingTraits<xray::YAMLXRayTrace> { +template <> struct yaml::MappingTraits<llvm::xray::YAMLXRayTrace> { static void mapping(IO &IO, xray::YAMLXRayTrace &Trace) { // A trace file contains two parts, the header and the list of all the // trace records. @@ -98,8 +96,6 @@ template <> struct MappingTraits<xray::YAMLXRayTrace> { IO.mapRequired("records", Trace.Records); } }; - -} // namespace yaml } // namespace llvm LLVM_YAML_IS_SEQUENCE_VECTOR(xray::YAMLXRayRecord) diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index b5b4cd9..00c3dbb 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -5419,20 +5419,15 @@ static Type *isSimpleCastedPHI(const SCEV *Op, const SCEVUnknown *SymbolicPHI, if (SourceBits != NewBits) return nullptr; - const SCEVSignExtendExpr *SExt = dyn_cast<SCEVSignExtendExpr>(Op); - const SCEVZeroExtendExpr *ZExt = dyn_cast<SCEVZeroExtendExpr>(Op); - if (!SExt && !ZExt) - return nullptr; - const SCEVTruncateExpr *Trunc = - SExt ? dyn_cast<SCEVTruncateExpr>(SExt->getOperand()) - : dyn_cast<SCEVTruncateExpr>(ZExt->getOperand()); - if (!Trunc) - return nullptr; - const SCEV *X = Trunc->getOperand(); - if (X != SymbolicPHI) - return nullptr; - Signed = SExt != nullptr; - return Trunc->getType(); + if (match(Op, m_scev_SExt(m_scev_Trunc(m_scev_Specific(SymbolicPHI))))) { + Signed = true; + return cast<SCEVCastExpr>(Op)->getOperand()->getType(); + } + if (match(Op, m_scev_ZExt(m_scev_Trunc(m_scev_Specific(SymbolicPHI))))) { + Signed = false; + return cast<SCEVCastExpr>(Op)->getOperand()->getType(); + } + return nullptr; } static const Loop *isIntegerLoopHeaderPHI(const PHINode *PN, LoopInfo &LI) { @@ -15428,20 +15423,18 @@ bool ScalarEvolution::matchURem(const SCEV *Expr, const SCEV *&LHS, // Try to match 'zext (trunc A to iB) to iY', which is used // for URem with constant power-of-2 second operands. Make sure the size of // the operand A matches the size of the whole expressions. - if (const auto *ZExt = dyn_cast<SCEVZeroExtendExpr>(Expr)) - if (const auto *Trunc = dyn_cast<SCEVTruncateExpr>(ZExt->getOperand(0))) { - LHS = Trunc->getOperand(); - // Bail out if the type of the LHS is larger than the type of the - // expression for now. - if (getTypeSizeInBits(LHS->getType()) > - getTypeSizeInBits(Expr->getType())) - return false; - if (LHS->getType() != Expr->getType()) - LHS = getZeroExtendExpr(LHS, Expr->getType()); - RHS = getConstant(APInt(getTypeSizeInBits(Expr->getType()), 1) - << getTypeSizeInBits(Trunc->getType())); - return true; - } + if (match(Expr, m_scev_ZExt(m_scev_Trunc(m_SCEV(LHS))))) { + Type *TruncTy = cast<SCEVZeroExtendExpr>(Expr)->getOperand()->getType(); + // Bail out if the type of the LHS is larger than the type of the + // expression for now. + if (getTypeSizeInBits(LHS->getType()) > getTypeSizeInBits(Expr->getType())) + return false; + if (LHS->getType() != Expr->getType()) + LHS = getZeroExtendExpr(LHS, Expr->getType()); + RHS = getConstant(APInt(getTypeSizeInBits(Expr->getType()), 1) + << getTypeSizeInBits(TruncTy)); + return true; + } const auto *Add = dyn_cast<SCEVAddExpr>(Expr); if (Add == nullptr || Add->getNumOperands() != 2) return false; diff --git a/llvm/lib/Analysis/StaticDataProfileInfo.cpp b/llvm/lib/Analysis/StaticDataProfileInfo.cpp index b036b2d..1f751ee 100644 --- a/llvm/lib/Analysis/StaticDataProfileInfo.cpp +++ b/llvm/lib/Analysis/StaticDataProfileInfo.cpp @@ -6,6 +6,46 @@ #include "llvm/ProfileData/InstrProf.h" using namespace llvm; + +namespace llvm { +namespace memprof { +// Returns true iff the global variable has custom section either by +// __attribute__((section("name"))) +// (https://clang.llvm.org/docs/AttributeReference.html#section-declspec-allocate) +// or #pragma clang section directives +// (https://clang.llvm.org/docs/LanguageExtensions.html#specifying-section-names-for-global-objects-pragma-clang-section). +static bool hasExplicitSectionName(const GlobalVariable &GVar) { + if (GVar.hasSection()) + return true; + + auto Attrs = GVar.getAttributes(); + if (Attrs.hasAttribute("bss-section") || Attrs.hasAttribute("data-section") || + Attrs.hasAttribute("relro-section") || + Attrs.hasAttribute("rodata-section")) + return true; + return false; +} + +AnnotationKind getAnnotationKind(const GlobalVariable &GV) { + if (GV.isDeclarationForLinker()) + return AnnotationKind::DeclForLinker; + // Skip 'llvm.'-prefixed global variables conservatively because they are + // often handled specially, + StringRef Name = GV.getName(); + if (Name.starts_with("llvm.")) + return AnnotationKind::ReservedName; + // Respect user-specified custom data sections. + if (hasExplicitSectionName(GV)) + return AnnotationKind::ExplicitSection; + return AnnotationKind::AnnotationOK; +} + +bool IsAnnotationOK(const GlobalVariable &GV) { + return getAnnotationKind(GV) == AnnotationKind::AnnotationOK; +} +} // namespace memprof +} // namespace llvm + void StaticDataProfileInfo::addConstantProfileCount( const Constant *C, std::optional<uint64_t> Count) { if (!Count) { diff --git a/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp b/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp index 6356d71..873ac8f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp @@ -20,7 +20,7 @@ #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" -namespace llvm { +using namespace llvm; AIXException::AIXException(AsmPrinter *A) : EHStreamer(A) {} @@ -90,5 +90,3 @@ void AIXException::endFunction(const MachineFunction *MF) { emitExceptionInfoTable(LSDALabel, PerSym); } - -} // End of namespace llvm diff --git a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp index 260ce8f..93ae548 100644 --- a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp +++ b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp @@ -85,8 +85,7 @@ template <> struct llvm::DenseMapInfo<VariableID> { using VarLocInsertPt = PointerUnion<const Instruction *, const DbgRecord *>; -namespace std { -template <> struct hash<VarLocInsertPt> { +template <> struct std::hash<VarLocInsertPt> { using argument_type = VarLocInsertPt; using result_type = std::size_t; @@ -94,7 +93,6 @@ template <> struct hash<VarLocInsertPt> { return std::hash<void *>()(Arg.getOpaqueValue()); } }; -} // namespace std /// Helper class to build FunctionVarLocs, since that class isn't easy to /// modify. TODO: There's not a great deal of value in the split, it could be diff --git a/llvm/lib/CodeGen/BasicBlockPathCloning.cpp b/llvm/lib/CodeGen/BasicBlockPathCloning.cpp index fd7df6b..47b7a88 100644 --- a/llvm/lib/CodeGen/BasicBlockPathCloning.cpp +++ b/llvm/lib/CodeGen/BasicBlockPathCloning.cpp @@ -207,9 +207,7 @@ bool ApplyCloning(MachineFunction &MF, } return AnyPathsCloned; } -} // end anonymous namespace -namespace llvm { class BasicBlockPathCloning : public MachineFunctionPass { public: static char ID; @@ -229,7 +227,7 @@ public: bool runOnMachineFunction(MachineFunction &MF) override; }; -} // namespace llvm +} // namespace char BasicBlockPathCloning::ID = 0; INITIALIZE_PASS_BEGIN( diff --git a/llvm/lib/CodeGen/BreakFalseDeps.cpp b/llvm/lib/CodeGen/BreakFalseDeps.cpp index 28e6728..1846880 100644 --- a/llvm/lib/CodeGen/BreakFalseDeps.cpp +++ b/llvm/lib/CodeGen/BreakFalseDeps.cpp @@ -31,7 +31,7 @@ using namespace llvm; -namespace llvm { +namespace { class BreakFalseDeps : public MachineFunctionPass { private: @@ -95,7 +95,7 @@ private: void processUndefReads(MachineBasicBlock *); }; -} // namespace llvm +} // namespace #define DEBUG_TYPE "break-false-deps" diff --git a/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp b/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp index 6c2a5a7..87ada87 100644 --- a/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp +++ b/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp @@ -126,8 +126,7 @@ hash_code hash_value(const ComplexValue &Arg) { } // end namespace typedef SmallVector<struct ComplexValue, 2> ComplexValues; -namespace llvm { -template <> struct DenseMapInfo<ComplexValue> { +template <> struct llvm::DenseMapInfo<ComplexValue> { static inline ComplexValue getEmptyKey() { return {DenseMapInfo<Value *>::getEmptyKey(), DenseMapInfo<Value *>::getEmptyKey()}; @@ -144,7 +143,6 @@ template <> struct DenseMapInfo<ComplexValue> { return LHS.Real == RHS.Real && LHS.Imag == RHS.Imag; } }; -} // end namespace llvm namespace { template <typename T, typename IterT> diff --git a/llvm/lib/CodeGen/EdgeBundles.cpp b/llvm/lib/CodeGen/EdgeBundles.cpp index f4335396..50dd66f 100644 --- a/llvm/lib/CodeGen/EdgeBundles.cpp +++ b/llvm/lib/CodeGen/EdgeBundles.cpp @@ -81,13 +81,10 @@ void EdgeBundles::init() { } } -namespace llvm { - /// Specialize WriteGraph, the standard implementation won't work. -template<> -raw_ostream &WriteGraph<>(raw_ostream &O, const EdgeBundles &G, - bool ShortNames, - const Twine &Title) { +template <> +raw_ostream &llvm::WriteGraph<>(raw_ostream &O, const EdgeBundles &G, + bool ShortNames, const Twine &Title) { const MachineFunction *MF = G.getMachineFunction(); O << "digraph {\n"; @@ -107,8 +104,6 @@ raw_ostream &WriteGraph<>(raw_ostream &O, const EdgeBundles &G, return O; } -} // end namespace llvm - /// view - Visualize the annotated bipartite CFG with Graphviz. void EdgeBundles::view() const { ViewGraph(*this, "EdgeBundles"); diff --git a/llvm/lib/CodeGen/ExpandFp.cpp b/llvm/lib/CodeGen/ExpandFp.cpp index c500357..04c7008 100644 --- a/llvm/lib/CodeGen/ExpandFp.cpp +++ b/llvm/lib/CodeGen/ExpandFp.cpp @@ -1036,6 +1036,7 @@ static bool runImpl(Function &F, const TargetLowering &TLI, continue; addToWorklist(I, Worklist); + Modified = true; break; } default: diff --git a/llvm/lib/CodeGen/GlobalMergeFunctions.cpp b/llvm/lib/CodeGen/GlobalMergeFunctions.cpp index 47640c4a..81ab317 100644 --- a/llvm/lib/CodeGen/GlobalMergeFunctions.cpp +++ b/llvm/lib/CodeGen/GlobalMergeFunctions.cpp @@ -587,16 +587,12 @@ public: } // namespace char GlobalMergeFuncPassWrapper::ID = 0; -INITIALIZE_PASS_BEGIN(GlobalMergeFuncPassWrapper, "global-merge-func", - "Global merge function pass", false, false) -INITIALIZE_PASS_END(GlobalMergeFuncPassWrapper, "global-merge-func", - "Global merge function pass", false, false) +INITIALIZE_PASS(GlobalMergeFuncPassWrapper, "global-merge-func", + "Global merge function pass", false, false) -namespace llvm { -ModulePass *createGlobalMergeFuncPass() { +ModulePass *llvm::createGlobalMergeFuncPass() { return new GlobalMergeFuncPassWrapper(); } -} // namespace llvm GlobalMergeFuncPassWrapper::GlobalMergeFuncPassWrapper() : ModulePass(ID) { initializeGlobalMergeFuncPassWrapperPass( diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp index 3485a27..0e38017 100644 --- a/llvm/lib/CodeGen/LiveIntervals.cpp +++ b/llvm/lib/CodeGen/LiveIntervals.cpp @@ -101,15 +101,11 @@ static cl::opt<bool> EnablePrecomputePhysRegs( static bool EnablePrecomputePhysRegs = false; #endif // NDEBUG -namespace llvm { - -cl::opt<bool> UseSegmentSetForPhysRegs( +cl::opt<bool> llvm::UseSegmentSetForPhysRegs( "use-segment-set-for-physregs", cl::Hidden, cl::init(true), cl::desc( "Use segment set for the computation of the live ranges of physregs.")); -} // end namespace llvm - void LiveIntervalsWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addPreserved<LiveVariablesWrapperPass>(); diff --git a/llvm/lib/CodeGen/MIR2Vec.cpp b/llvm/lib/CodeGen/MIR2Vec.cpp index e859765..5c78d98 100644 --- a/llvm/lib/CodeGen/MIR2Vec.cpp +++ b/llvm/lib/CodeGen/MIR2Vec.cpp @@ -29,20 +29,17 @@ using namespace mir2vec; STATISTIC(MIRVocabMissCounter, "Number of lookups to MIR entities not present in the vocabulary"); -namespace llvm { -namespace mir2vec { -cl::OptionCategory MIR2VecCategory("MIR2Vec Options"); +cl::OptionCategory llvm::mir2vec::MIR2VecCategory("MIR2Vec Options"); // FIXME: Use a default vocab when not specified static cl::opt<std::string> VocabFile("mir2vec-vocab-path", cl::Optional, cl::desc("Path to the vocabulary file for MIR2Vec"), cl::init(""), cl::cat(MIR2VecCategory)); -cl::opt<float> OpcWeight("mir2vec-opc-weight", cl::Optional, cl::init(1.0), - cl::desc("Weight for machine opcode embeddings"), - cl::cat(MIR2VecCategory)); -} // namespace mir2vec -} // namespace llvm +cl::opt<float> + llvm::mir2vec::OpcWeight("mir2vec-opc-weight", cl::Optional, cl::init(1.0), + cl::desc("Weight for machine opcode embeddings"), + cl::cat(MIR2VecCategory)); //===----------------------------------------------------------------------===// // Vocabulary Implementation diff --git a/llvm/lib/CodeGen/MIRFSDiscriminator.cpp b/llvm/lib/CodeGen/MIRFSDiscriminator.cpp index f5146f5..d988a2a 100644 --- a/llvm/lib/CodeGen/MIRFSDiscriminator.cpp +++ b/llvm/lib/CodeGen/MIRFSDiscriminator.cpp @@ -40,7 +40,7 @@ cl::opt<bool> ImprovedFSDiscriminator( "improved-fs-discriminator", cl::Hidden, cl::init(false), cl::desc("New FS discriminators encoding (incompatible with the original " "encoding)")); -} +} // namespace llvm char MIRAddFSDiscriminators::ID = 0; diff --git a/llvm/lib/CodeGen/MIRNamerPass.cpp b/llvm/lib/CodeGen/MIRNamerPass.cpp index bc65700..cbf8867 100644 --- a/llvm/lib/CodeGen/MIRNamerPass.cpp +++ b/llvm/lib/CodeGen/MIRNamerPass.cpp @@ -23,10 +23,6 @@ using namespace llvm; -namespace llvm { -extern char &MIRNamerID; -} // namespace llvm - #define DEBUG_TYPE "mir-namer" namespace { @@ -53,10 +49,9 @@ public: VRegRenamer Renamer(MF.getRegInfo()); - unsigned BBIndex = 0; ReversePostOrderTraversal<MachineBasicBlock *> RPOT(&*MF.begin()); - for (auto &MBB : RPOT) - Changed |= Renamer.renameVRegs(MBB, BBIndex++); + for (const auto &[BBIndex, MBB] : enumerate(RPOT)) + Changed |= Renamer.renameVRegs(MBB, BBIndex); return Changed; } @@ -66,10 +61,4 @@ public: char MIRNamer::ID; -char &llvm::MIRNamerID = MIRNamer::ID; - -INITIALIZE_PASS_BEGIN(MIRNamer, "mir-namer", "Rename Register Operands", false, - false) - -INITIALIZE_PASS_END(MIRNamer, "mir-namer", "Rename Register Operands", false, - false) +INITIALIZE_PASS(MIRNamer, "mir-namer", "Rename Register Operands", false, false) diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp index bf8a6cd..96428cd 100644 --- a/llvm/lib/CodeGen/MIRPrinter.cpp +++ b/llvm/lib/CodeGen/MIRPrinter.cpp @@ -107,10 +107,8 @@ struct MFPrintState { } // end anonymous namespace -namespace llvm::yaml { - /// This struct serializes the LLVM IR module. -template <> struct BlockScalarTraits<Module> { +template <> struct yaml::BlockScalarTraits<Module> { static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) { Mod.print(OS, nullptr); } @@ -121,8 +119,6 @@ template <> struct BlockScalarTraits<Module> { } }; -} // end namespace llvm::yaml - static void printRegMIR(Register Reg, yaml::StringValue &Dest, const TargetRegisterInfo *TRI) { raw_string_ostream OS(Dest.Value); diff --git a/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp b/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp index b2731b69..a72c2c4 100644 --- a/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp +++ b/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.cpp @@ -97,7 +97,9 @@ static const bool EnableDevelopmentFeatures = false; /// this happens only in development mode. It's a no-op otherwise. namespace llvm { extern cl::opt<unsigned> EvictInterferenceCutoff; +} // namespace llvm +namespace { class RegAllocScoring : public MachineFunctionPass { public: static char ID; @@ -124,11 +126,12 @@ public: /// Performs this pass bool runOnMachineFunction(MachineFunction &) override; }; +} // namespace char RegAllocScoring::ID = 0; -FunctionPass *createRegAllocScoringPass() { return new RegAllocScoring(); } - -} // namespace llvm +FunctionPass *llvm::createRegAllocScoringPass() { + return new RegAllocScoring(); +} INITIALIZE_PASS(RegAllocScoring, "regallocscoringpass", "Register Allocation Scoring Pass", false, false) diff --git a/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp b/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp index e7fa082..26eb10f 100644 --- a/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp +++ b/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp @@ -29,7 +29,6 @@ using namespace llvm; #define DEBUG_TYPE "machine-block-freq" -namespace llvm { static cl::opt<GVDAGType> ViewMachineBlockFreqPropagationDAG( "view-machine-block-freq-propagation-dags", cl::Hidden, cl::desc("Pop up a window to show a dag displaying how machine block " @@ -44,6 +43,7 @@ static cl::opt<GVDAGType> ViewMachineBlockFreqPropagationDAG( clEnumValN(GVDT_Count, "count", "display a graph using the real " "profile count if available."))); +namespace llvm { // Similar option above, but used to control BFI display only after MBP pass cl::opt<GVDAGType> ViewBlockLayoutWithBFI( "view-block-layout-with-bfi", cl::Hidden, @@ -69,15 +69,15 @@ extern cl::opt<std::string> ViewBlockFreqFuncName; // Defined in Analysis/BlockFrequencyInfo.cpp: -view-hot-freq-perc= extern cl::opt<unsigned> ViewHotFreqPercent; -static cl::opt<bool> PrintMachineBlockFreq( - "print-machine-bfi", cl::init(false), cl::Hidden, - cl::desc("Print the machine block frequency info.")); - // Command line option to specify the name of the function for block frequency // dump. Defined in Analysis/BlockFrequencyInfo.cpp. extern cl::opt<std::string> PrintBFIFuncName; } // namespace llvm +static cl::opt<bool> + PrintMachineBlockFreq("print-machine-bfi", cl::init(false), cl::Hidden, + cl::desc("Print the machine block frequency info.")); + static GVDAGType getGVDT() { if (ViewBlockLayoutWithBFI != GVDT_None) return ViewBlockLayoutWithBFI; @@ -85,9 +85,7 @@ static GVDAGType getGVDT() { return ViewMachineBlockFreqPropagationDAG; } -namespace llvm { - -template <> struct GraphTraits<MachineBlockFrequencyInfo *> { +template <> struct llvm::GraphTraits<MachineBlockFrequencyInfo *> { using NodeRef = const MachineBasicBlock *; using ChildIteratorType = MachineBasicBlock::const_succ_iterator; using nodes_iterator = pointer_iterator<MachineFunction::const_iterator>; @@ -116,7 +114,7 @@ using MBFIDOTGraphTraitsBase = MachineBranchProbabilityInfo>; template <> -struct DOTGraphTraits<MachineBlockFrequencyInfo *> +struct llvm::DOTGraphTraits<MachineBlockFrequencyInfo *> : public MBFIDOTGraphTraitsBase { const MachineFunction *CurFunc = nullptr; DenseMap<const MachineBasicBlock *, int> LayoutOrderMap; @@ -159,8 +157,6 @@ struct DOTGraphTraits<MachineBlockFrequencyInfo *> } }; -} // end namespace llvm - AnalysisKey MachineBlockFrequencyAnalysis::Key; MachineBlockFrequencyAnalysis::Result diff --git a/llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp b/llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp index 2e92dd8..7ca4582 100644 --- a/llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp +++ b/llvm/lib/CodeGen/MachineBranchProbabilityInfo.cpp @@ -18,13 +18,8 @@ using namespace llvm; -INITIALIZE_PASS_BEGIN(MachineBranchProbabilityInfoWrapperPass, - "machine-branch-prob", - "Machine Branch Probability Analysis", false, true) -INITIALIZE_PASS_END(MachineBranchProbabilityInfoWrapperPass, - "machine-branch-prob", - "Machine Branch Probability Analysis", false, true) - +INITIALIZE_PASS(MachineBranchProbabilityInfoWrapperPass, "machine-branch-prob", + "Machine Branch Probability Analysis", false, true) namespace llvm { cl::opt<unsigned> StaticLikelyProb("static-likely-prob", diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp index 224231c..bfa5ab2 100644 --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -719,43 +719,41 @@ MachineFunction::CallSiteInfo::CallSiteInfo(const CallBase &CB) { } } -namespace llvm { +template <> +struct llvm::DOTGraphTraits<const MachineFunction *> + : public DefaultDOTGraphTraits { + DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} - template<> - struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits { - DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} + static std::string getGraphName(const MachineFunction *F) { + return ("CFG for '" + F->getName() + "' function").str(); + } - static std::string getGraphName(const MachineFunction *F) { - return ("CFG for '" + F->getName() + "' function").str(); + std::string getNodeLabel(const MachineBasicBlock *Node, + const MachineFunction *Graph) { + std::string OutStr; + { + raw_string_ostream OSS(OutStr); + + if (isSimple()) { + OSS << printMBBReference(*Node); + if (const BasicBlock *BB = Node->getBasicBlock()) + OSS << ": " << BB->getName(); + } else + Node->print(OSS); } - std::string getNodeLabel(const MachineBasicBlock *Node, - const MachineFunction *Graph) { - std::string OutStr; - { - raw_string_ostream OSS(OutStr); - - if (isSimple()) { - OSS << printMBBReference(*Node); - if (const BasicBlock *BB = Node->getBasicBlock()) - OSS << ": " << BB->getName(); - } else - Node->print(OSS); - } - - if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); - - // Process string output to make it nicer... - for (unsigned i = 0; i != OutStr.length(); ++i) - if (OutStr[i] == '\n') { // Left justify - OutStr[i] = '\\'; - OutStr.insert(OutStr.begin()+i+1, 'l'); - } - return OutStr; - } - }; + if (OutStr[0] == '\n') + OutStr.erase(OutStr.begin()); -} // end namespace llvm + // Process string output to make it nicer... + for (unsigned i = 0; i != OutStr.length(); ++i) + if (OutStr[i] == '\n') { // Left justify + OutStr[i] = '\\'; + OutStr.insert(OutStr.begin() + i + 1, 'l'); + } + return OutStr; + } +}; void MachineFunction::viewCFG() const { diff --git a/llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp b/llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp index 0f88a7b..5111322 100644 --- a/llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp +++ b/llvm/lib/CodeGen/MachineFunctionPrinterPass.cpp @@ -60,13 +60,11 @@ char &llvm::MachineFunctionPrinterPassID = MachineFunctionPrinterPass::ID; INITIALIZE_PASS(MachineFunctionPrinterPass, "machineinstr-printer", "Machine Function Printer", false, false) -namespace llvm { /// Returns a newly-created MachineFunction Printer pass. The /// default banner is empty. /// -MachineFunctionPass *createMachineFunctionPrinterPass(raw_ostream &OS, - const std::string &Banner){ +MachineFunctionPass * +llvm::createMachineFunctionPrinterPass(raw_ostream &OS, + const std::string &Banner) { return new MachineFunctionPrinterPass(OS, Banner); } - -} diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp index fdae3b4..9feb974 100644 --- a/llvm/lib/CodeGen/MachineOutliner.cpp +++ b/llvm/lib/CodeGen/MachineOutliner.cpp @@ -593,15 +593,12 @@ struct MachineOutliner : public ModulePass { char MachineOutliner::ID = 0; -namespace llvm { -ModulePass *createMachineOutlinerPass(RunOutliner RunOutlinerMode) { +ModulePass *llvm::createMachineOutlinerPass(RunOutliner RunOutlinerMode) { MachineOutliner *OL = new MachineOutliner(); OL->RunOutlinerMode = RunOutlinerMode; return OL; } -} // namespace llvm - INITIALIZE_PASS(MachineOutliner, DEBUG_TYPE, "Machine Function Outliner", false, false) diff --git a/llvm/lib/CodeGen/MachinePipeliner.cpp b/llvm/lib/CodeGen/MachinePipeliner.cpp index 89ed4da..a717d9e 100644 --- a/llvm/lib/CodeGen/MachinePipeliner.cpp +++ b/llvm/lib/CodeGen/MachinePipeliner.cpp @@ -201,16 +201,15 @@ static cl::opt<unsigned> SwpMaxNumStores( cl::desc("Maximum number of stores allwed in the target loop."), cl::Hidden, cl::init(200)); -namespace llvm { - // A command line option to enable the CopyToPhi DAG mutation. -cl::opt<bool> SwpEnableCopyToPhi("pipeliner-enable-copytophi", cl::ReallyHidden, - cl::init(true), - cl::desc("Enable CopyToPhi DAG Mutation")); +cl::opt<bool> + llvm::SwpEnableCopyToPhi("pipeliner-enable-copytophi", cl::ReallyHidden, + cl::init(true), + cl::desc("Enable CopyToPhi DAG Mutation")); /// A command line argument to force pipeliner to use specified issue /// width. -cl::opt<int> SwpForceIssueWidth( +cl::opt<int> llvm::SwpForceIssueWidth( "pipeliner-force-issue-width", cl::desc("Force pipeliner to use specified issue width."), cl::Hidden, cl::init(-1)); @@ -226,8 +225,6 @@ static cl::opt<WindowSchedulingFlag> WindowSchedulingOption( clEnumValN(WindowSchedulingFlag::WS_Force, "force", "Use window algorithm instead of SMS algorithm."))); -} // end namespace llvm - unsigned SwingSchedulerDAG::Circuits::MaxPaths = 5; char MachinePipeliner::ID = 0; #ifndef NDEBUG diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp index 299bcc4..3ed1045 100644 --- a/llvm/lib/CodeGen/MachineScheduler.cpp +++ b/llvm/lib/CodeGen/MachineScheduler.cpp @@ -176,9 +176,7 @@ STATISTIC(NumNodeOrderPostRA, STATISTIC(NumFirstValidPostRA, "Number of scheduling units chosen for FirstValid heuristic post-RA"); -namespace llvm { - -cl::opt<MISched::Direction> PreRADirection( +cl::opt<MISched::Direction> llvm::PreRADirection( "misched-prera-direction", cl::Hidden, cl::desc("Pre reg-alloc list scheduling direction"), cl::init(MISched::Unspecified), @@ -206,33 +204,31 @@ static cl::opt<bool> DumpCriticalPathLength("misched-dcpl", cl::Hidden, cl::desc("Print critical path length to stdout")); -cl::opt<bool> VerifyScheduling( +cl::opt<bool> llvm::VerifyScheduling( "verify-misched", cl::Hidden, cl::desc("Verify machine instrs before and after machine scheduling")); #ifndef NDEBUG -cl::opt<bool> ViewMISchedDAGs( +cl::opt<bool> llvm::ViewMISchedDAGs( "view-misched-dags", cl::Hidden, cl::desc("Pop up a window to show MISched dags after they are processed")); -cl::opt<bool> PrintDAGs("misched-print-dags", cl::Hidden, - cl::desc("Print schedule DAGs")); -cl::opt<bool> MISchedDumpReservedCycles( +cl::opt<bool> llvm::PrintDAGs("misched-print-dags", cl::Hidden, + cl::desc("Print schedule DAGs")); +static cl::opt<bool> MISchedDumpReservedCycles( "misched-dump-reserved-cycles", cl::Hidden, cl::init(false), cl::desc("Dump resource usage at schedule boundary.")); -cl::opt<bool> MischedDetailResourceBooking( +static cl::opt<bool> MischedDetailResourceBooking( "misched-detail-resource-booking", cl::Hidden, cl::init(false), cl::desc("Show details of invoking getNextResoufceCycle.")); #else -const bool ViewMISchedDAGs = false; -const bool PrintDAGs = false; -const bool MischedDetailResourceBooking = false; +const bool llvm::ViewMISchedDAGs = false; +const bool llvm::PrintDAGs = false; +static const bool MischedDetailResourceBooking = false; #ifdef LLVM_ENABLE_DUMP -const bool MISchedDumpReservedCycles = false; +static const bool MISchedDumpReservedCycles = false; #endif // LLVM_ENABLE_DUMP #endif // NDEBUG -} // end namespace llvm - #ifndef NDEBUG /// In some situations a few uninteresting nodes depend on nearly all other /// nodes in the graph, provide a cutoff to hide them. @@ -2053,28 +2049,24 @@ public: } // end anonymous namespace -namespace llvm { - std::unique_ptr<ScheduleDAGMutation> -createLoadClusterDAGMutation(const TargetInstrInfo *TII, - const TargetRegisterInfo *TRI, - bool ReorderWhileClustering) { +llvm::createLoadClusterDAGMutation(const TargetInstrInfo *TII, + const TargetRegisterInfo *TRI, + bool ReorderWhileClustering) { return EnableMemOpCluster ? std::make_unique<LoadClusterMutation>( TII, TRI, ReorderWhileClustering) : nullptr; } std::unique_ptr<ScheduleDAGMutation> -createStoreClusterDAGMutation(const TargetInstrInfo *TII, - const TargetRegisterInfo *TRI, - bool ReorderWhileClustering) { +llvm::createStoreClusterDAGMutation(const TargetInstrInfo *TII, + const TargetRegisterInfo *TRI, + bool ReorderWhileClustering) { return EnableMemOpCluster ? std::make_unique<StoreClusterMutation>( TII, TRI, ReorderWhileClustering) : nullptr; } -} // end namespace llvm - // Sorting all the loads/stores first, then for each load/store, checking the // following load/store one by one, until reach the first non-dependent one and // call target hook to see if they can cluster. @@ -2304,16 +2296,12 @@ protected: } // end anonymous namespace -namespace llvm { - std::unique_ptr<ScheduleDAGMutation> -createCopyConstrainDAGMutation(const TargetInstrInfo *TII, - const TargetRegisterInfo *TRI) { +llvm::createCopyConstrainDAGMutation(const TargetInstrInfo *TII, + const TargetRegisterInfo *TRI) { return std::make_unique<CopyConstrain>(TII, TRI); } -} // end namespace llvm - /// constrainLocalCopy handles two possibilities: /// 1) Local src: /// I0: = dst @@ -3445,14 +3433,13 @@ void GenericSchedulerBase::traceCandidate(const SchedCandidate &Cand) { } #endif -namespace llvm { /// Return true if this heuristic determines order. /// TODO: Consider refactor return type of these functions as integer or enum, /// as we may need to differentiate whether TryCand is better than Cand. -bool tryLess(int TryVal, int CandVal, - GenericSchedulerBase::SchedCandidate &TryCand, - GenericSchedulerBase::SchedCandidate &Cand, - GenericSchedulerBase::CandReason Reason) { +bool llvm::tryLess(int TryVal, int CandVal, + GenericSchedulerBase::SchedCandidate &TryCand, + GenericSchedulerBase::SchedCandidate &Cand, + GenericSchedulerBase::CandReason Reason) { if (TryVal < CandVal) { TryCand.Reason = Reason; return true; @@ -3465,10 +3452,10 @@ bool tryLess(int TryVal, int CandVal, return false; } -bool tryGreater(int TryVal, int CandVal, - GenericSchedulerBase::SchedCandidate &TryCand, - GenericSchedulerBase::SchedCandidate &Cand, - GenericSchedulerBase::CandReason Reason) { +bool llvm::tryGreater(int TryVal, int CandVal, + GenericSchedulerBase::SchedCandidate &TryCand, + GenericSchedulerBase::SchedCandidate &Cand, + GenericSchedulerBase::CandReason Reason) { if (TryVal > CandVal) { TryCand.Reason = Reason; return true; @@ -3481,9 +3468,9 @@ bool tryGreater(int TryVal, int CandVal, return false; } -bool tryLatency(GenericSchedulerBase::SchedCandidate &TryCand, - GenericSchedulerBase::SchedCandidate &Cand, - SchedBoundary &Zone) { +bool llvm::tryLatency(GenericSchedulerBase::SchedCandidate &TryCand, + GenericSchedulerBase::SchedCandidate &Cand, + SchedBoundary &Zone) { if (Zone.isTop()) { // Prefer the candidate with the lesser depth, but only if one of them has // depth greater than the total latency scheduled so far, otherwise either @@ -3513,7 +3500,6 @@ bool tryLatency(GenericSchedulerBase::SchedCandidate &TryCand, } return false; } -} // end namespace llvm static void tracePick(GenericSchedulerBase::CandReason Reason, bool IsTop, bool IsPostRA = false) { @@ -3798,14 +3784,12 @@ void GenericScheduler::registerRoots() { } } -namespace llvm { -bool tryPressure(const PressureChange &TryP, - const PressureChange &CandP, - GenericSchedulerBase::SchedCandidate &TryCand, - GenericSchedulerBase::SchedCandidate &Cand, - GenericSchedulerBase::CandReason Reason, - const TargetRegisterInfo *TRI, - const MachineFunction &MF) { +bool llvm::tryPressure(const PressureChange &TryP, const PressureChange &CandP, + GenericSchedulerBase::SchedCandidate &TryCand, + GenericSchedulerBase::SchedCandidate &Cand, + GenericSchedulerBase::CandReason Reason, + const TargetRegisterInfo *TRI, + const MachineFunction &MF) { // If one candidate decreases and the other increases, go with it. // Invalid candidates have UnitInc==0. if (tryGreater(TryP.getUnitInc() < 0, CandP.getUnitInc() < 0, TryCand, Cand, @@ -3838,7 +3822,7 @@ bool tryPressure(const PressureChange &TryP, return tryGreater(TryRank, CandRank, TryCand, Cand, Reason); } -unsigned getWeakLeft(const SUnit *SU, bool isTop) { +unsigned llvm::getWeakLeft(const SUnit *SU, bool isTop) { return (isTop) ? SU->WeakPredsLeft : SU->WeakSuccsLeft; } @@ -3849,7 +3833,7 @@ unsigned getWeakLeft(const SUnit *SU, bool isTop) { /// copies which can be prescheduled. The rest (e.g. x86 MUL) could be bundled /// with the operation that produces or consumes the physreg. We'll do this when /// regalloc has support for parallel copies. -int biasPhysReg(const SUnit *SU, bool isTop) { +int llvm::biasPhysReg(const SUnit *SU, bool isTop) { const MachineInstr *MI = SU->getInstr(); if (MI->isCopy()) { @@ -3884,7 +3868,6 @@ int biasPhysReg(const SUnit *SU, bool isTop) { return 0; } -} // end namespace llvm void GenericScheduler::initCandidate(SchedCandidate &Cand, SUnit *SU, bool AtTop, @@ -4812,13 +4795,13 @@ static MachineSchedRegistry ShufflerRegistry( //===----------------------------------------------------------------------===// #ifndef NDEBUG -namespace llvm { -template<> struct GraphTraits< - ScheduleDAGMI*> : public GraphTraits<ScheduleDAG*> {}; +template <> +struct llvm::GraphTraits<ScheduleDAGMI *> : public GraphTraits<ScheduleDAG *> { +}; -template<> -struct DOTGraphTraits<ScheduleDAGMI*> : public DefaultDOTGraphTraits { +template <> +struct llvm::DOTGraphTraits<ScheduleDAGMI *> : public DefaultDOTGraphTraits { DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} static std::string getGraphName(const ScheduleDAG *G) { @@ -4878,7 +4861,6 @@ struct DOTGraphTraits<ScheduleDAGMI*> : public DefaultDOTGraphTraits { } }; -} // end namespace llvm #endif // NDEBUG /// viewGraph - Pop up a ghostview window with the reachable parts of the DAG diff --git a/llvm/lib/CodeGen/MachineTraceMetrics.cpp b/llvm/lib/CodeGen/MachineTraceMetrics.cpp index c2d4aa0..9ac3f741 100644 --- a/llvm/lib/CodeGen/MachineTraceMetrics.cpp +++ b/llvm/lib/CodeGen/MachineTraceMetrics.cpp @@ -485,10 +485,7 @@ struct LoopBounds { // Specialize po_iterator_storage in order to prune the post-order traversal so // it is limited to the current loop and doesn't traverse the loop back edges. -namespace llvm { - -template<> -class po_iterator_storage<LoopBounds, true> { +template <> class llvm::po_iterator_storage<LoopBounds, true> { LoopBounds &LB; public: @@ -519,8 +516,6 @@ public: } }; -} // end namespace llvm - /// Compute the trace through MBB. void MachineTraceMetrics::Ensemble::computeTrace(const MachineBasicBlock *MBB) { LLVM_DEBUG(dbgs() << "Computing " << getName() << " trace through " diff --git a/llvm/lib/CodeGen/NonRelocatableStringpool.cpp b/llvm/lib/CodeGen/NonRelocatableStringpool.cpp index 087ac62..59c587c 100644 --- a/llvm/lib/CodeGen/NonRelocatableStringpool.cpp +++ b/llvm/lib/CodeGen/NonRelocatableStringpool.cpp @@ -9,7 +9,7 @@ #include "llvm/CodeGen/NonRelocatableStringpool.h" #include "llvm/ADT/STLExtras.h" -namespace llvm { +using namespace llvm; DwarfStringPoolEntryRef NonRelocatableStringpool::getEntry(StringRef S) { auto I = Strings.try_emplace(S); @@ -43,5 +43,3 @@ NonRelocatableStringpool::getEntriesForEmission() const { }); return Result; } - -} // namespace llvm diff --git a/llvm/lib/CodeGen/SafeStack.cpp b/llvm/lib/CodeGen/SafeStack.cpp index 6f373a5..e9ffa85 100644 --- a/llvm/lib/CodeGen/SafeStack.cpp +++ b/llvm/lib/CodeGen/SafeStack.cpp @@ -76,8 +76,6 @@ using namespace llvm::safestack; #define DEBUG_TYPE "safe-stack" -namespace llvm { - STATISTIC(NumFunctions, "Total number of functions"); STATISTIC(NumUnsafeStackFunctions, "Number of functions with unsafe stack"); STATISTIC(NumUnsafeStackRestorePointsFunctions, @@ -89,8 +87,6 @@ STATISTIC(NumUnsafeDynamicAllocas, "Number of unsafe dynamic allocas"); STATISTIC(NumUnsafeByValArguments, "Number of unsafe byval arguments"); STATISTIC(NumUnsafeStackRestorePoints, "Number of setjmps and landingpads"); -} // namespace llvm - /// Use __safestack_pointer_address even if the platform has a faster way of /// access safe stack pointer. static cl::opt<bool> diff --git a/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp b/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp index eae2e8c..3268c26 100644 --- a/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp +++ b/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -1551,14 +1551,10 @@ LLVM_DUMP_METHOD void ILPValue::dump() const { dbgs() << *this << '\n'; } -namespace llvm { - LLVM_ATTRIBUTE_UNUSED -raw_ostream &operator<<(raw_ostream &OS, const ILPValue &Val) { +raw_ostream &llvm::operator<<(raw_ostream &OS, const ILPValue &Val) { Val.print(OS); return OS; } -} // end namespace llvm - #endif diff --git a/llvm/lib/CodeGen/ScheduleDAGPrinter.cpp b/llvm/lib/CodeGen/ScheduleDAGPrinter.cpp index e7b1494..c80eade 100644 --- a/llvm/lib/CodeGen/ScheduleDAGPrinter.cpp +++ b/llvm/lib/CodeGen/ScheduleDAGPrinter.cpp @@ -16,57 +16,51 @@ #include "llvm/Support/raw_ostream.h" using namespace llvm; -namespace llvm { - template<> - struct DOTGraphTraits<ScheduleDAG*> : public DefaultDOTGraphTraits { +template <> +struct llvm::DOTGraphTraits<ScheduleDAG *> : public DefaultDOTGraphTraits { - DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} + DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} - static std::string getGraphName(const ScheduleDAG *G) { - return std::string(G->MF.getName()); - } + static std::string getGraphName(const ScheduleDAG *G) { + return std::string(G->MF.getName()); + } - static bool renderGraphFromBottomUp() { - return true; - } + static bool renderGraphFromBottomUp() { return true; } - static bool isNodeHidden(const SUnit *Node, const ScheduleDAG *G) { - return (Node->NumPreds > 10 || Node->NumSuccs > 10); - } + static bool isNodeHidden(const SUnit *Node, const ScheduleDAG *G) { + return (Node->NumPreds > 10 || Node->NumSuccs > 10); + } - static std::string getNodeIdentifierLabel(const SUnit *Node, - const ScheduleDAG *Graph) { - std::string R; - raw_string_ostream OS(R); - OS << static_cast<const void *>(Node); - return R; - } + static std::string getNodeIdentifierLabel(const SUnit *Node, + const ScheduleDAG *Graph) { + std::string R; + raw_string_ostream OS(R); + OS << static_cast<const void *>(Node); + return R; + } - /// If you want to override the dot attributes printed for a particular - /// edge, override this method. - static std::string getEdgeAttributes(const SUnit *Node, - SUnitIterator EI, - const ScheduleDAG *Graph) { - if (EI.isArtificialDep()) - return "color=cyan,style=dashed"; - if (EI.isCtrlDep()) - return "color=blue,style=dashed"; - return ""; - } + /// If you want to override the dot attributes printed for a particular + /// edge, override this method. + static std::string getEdgeAttributes(const SUnit *Node, SUnitIterator EI, + const ScheduleDAG *Graph) { + if (EI.isArtificialDep()) + return "color=cyan,style=dashed"; + if (EI.isCtrlDep()) + return "color=blue,style=dashed"; + return ""; + } + std::string getNodeLabel(const SUnit *SU, const ScheduleDAG *Graph); + static std::string getNodeAttributes(const SUnit *N, + const ScheduleDAG *Graph) { + return "shape=Mrecord"; + } - std::string getNodeLabel(const SUnit *SU, const ScheduleDAG *Graph); - static std::string getNodeAttributes(const SUnit *N, - const ScheduleDAG *Graph) { - return "shape=Mrecord"; - } - - static void addCustomGraphFeatures(ScheduleDAG *G, - GraphWriter<ScheduleDAG*> &GW) { - return G->addCustomGraphFeatures(GW); - } - }; -} + static void addCustomGraphFeatures(ScheduleDAG *G, + GraphWriter<ScheduleDAG *> &GW) { + return G->addCustomGraphFeatures(GW); + } +}; std::string DOTGraphTraits<ScheduleDAG*>::getNodeLabel(const SUnit *SU, const ScheduleDAG *G) { diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index b1accdd..e153842 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -509,6 +509,7 @@ namespace { SDValue visitFMUL(SDNode *N); template <class MatchContextClass> SDValue visitFMA(SDNode *N); SDValue visitFMAD(SDNode *N); + SDValue visitFMULADD(SDNode *N); SDValue visitFDIV(SDNode *N); SDValue visitFREM(SDNode *N); SDValue visitFSQRT(SDNode *N); @@ -1991,6 +1992,7 @@ SDValue DAGCombiner::visit(SDNode *N) { case ISD::FMUL: return visitFMUL(N); case ISD::FMA: return visitFMA<EmptyMatchContext>(N); case ISD::FMAD: return visitFMAD(N); + case ISD::FMULADD: return visitFMULADD(N); case ISD::FDIV: return visitFDIV(N); case ISD::FREM: return visitFREM(N); case ISD::FSQRT: return visitFSQRT(N); @@ -18444,6 +18446,21 @@ SDValue DAGCombiner::visitFMAD(SDNode *N) { return SDValue(); } +SDValue DAGCombiner::visitFMULADD(SDNode *N) { + SDValue N0 = N->getOperand(0); + SDValue N1 = N->getOperand(1); + SDValue N2 = N->getOperand(2); + EVT VT = N->getValueType(0); + SDLoc DL(N); + + // Constant fold FMULADD. + if (SDValue C = + DAG.FoldConstantArithmetic(ISD::FMULADD, DL, VT, {N0, N1, N2})) + return C; + + return SDValue(); +} + // Combine multiple FDIVs with the same divisor into multiple FMULs by the // reciprocal. // E.g., (a / D; b / D;) -> (recip = 1.0 / D; a * recip; b * recip) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 2b8dd60..4512c5c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -5786,6 +5786,7 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts, case ISD::FCOPYSIGN: case ISD::FMA: case ISD::FMAD: + case ISD::FMULADD: case ISD::FP_EXTEND: case ISD::FP_TO_SINT_SAT: case ISD::FP_TO_UINT_SAT: @@ -5904,6 +5905,7 @@ bool SelectionDAG::isKnownNeverNaN(SDValue Op, const APInt &DemandedElts, case ISD::FCOSH: case ISD::FTANH: case ISD::FMA: + case ISD::FMULADD: case ISD::FMAD: { if (SNaN) return true; @@ -7231,7 +7233,7 @@ SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, } // Handle fma/fmad special cases. - if (Opcode == ISD::FMA || Opcode == ISD::FMAD) { + if (Opcode == ISD::FMA || Opcode == ISD::FMAD || Opcode == ISD::FMULADD) { assert(VT.isFloatingPoint() && "This operator only applies to FP types!"); assert(Ops[0].getValueType() == VT && Ops[1].getValueType() == VT && Ops[2].getValueType() == VT && "FMA types must match!"); @@ -7242,7 +7244,7 @@ SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, APFloat V1 = C1->getValueAPF(); const APFloat &V2 = C2->getValueAPF(); const APFloat &V3 = C3->getValueAPF(); - if (Opcode == ISD::FMAD) { + if (Opcode == ISD::FMAD || Opcode == ISD::FMULADD) { V1.multiply(V2, APFloat::rmNearestTiesToEven); V1.add(V3, APFloat::rmNearestTiesToEven); } else diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index c21890a..0f2b518 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6996,6 +6996,13 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, getValue(I.getArgOperand(0)), getValue(I.getArgOperand(1)), getValue(I.getArgOperand(2)), Flags)); + } else if (TLI.isOperationLegalOrCustom(ISD::FMULADD, VT)) { + // TODO: Support splitting the vector. + setValue(&I, DAG.getNode(ISD::FMULADD, sdl, + getValue(I.getArgOperand(0)).getValueType(), + getValue(I.getArgOperand(0)), + getValue(I.getArgOperand(1)), + getValue(I.getArgOperand(2)), Flags)); } else { // TODO: Intrinsic calls should have fast-math-flags. SDValue Mul = DAG.getNode( diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp index fcfbfe6..39cbfad 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp @@ -310,6 +310,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const { case ISD::FMA: return "fma"; case ISD::STRICT_FMA: return "strict_fma"; case ISD::FMAD: return "fmad"; + case ISD::FMULADD: return "fmuladd"; case ISD::FREM: return "frem"; case ISD::STRICT_FREM: return "strict_frem"; case ISD::FCOPYSIGN: return "fcopysign"; diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index cc503d3..920dff9 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -7676,6 +7676,7 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG, break; } case ISD::FMA: + case ISD::FMULADD: case ISD::FMAD: { if (!Flags.hasNoSignedZeros()) break; diff --git a/llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp b/llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp index 64e5cd5..95a9c3f 100644 --- a/llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp +++ b/llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp @@ -306,10 +306,7 @@ char &llvm::StackFrameLayoutAnalysisPassID = StackFrameLayoutAnalysisLegacy::ID; INITIALIZE_PASS(StackFrameLayoutAnalysisLegacy, "stack-frame-layout", "Stack Frame Layout", false, false) -namespace llvm { /// Returns a newly-created StackFrameLayout pass. -MachineFunctionPass *createStackFrameLayoutAnalysisPass() { +MachineFunctionPass *llvm::createStackFrameLayoutAnalysisPass() { return new StackFrameLayoutAnalysisLegacy(); } - -} // namespace llvm diff --git a/llvm/lib/CodeGen/StaticDataAnnotator.cpp b/llvm/lib/CodeGen/StaticDataAnnotator.cpp index 53a9ab4..eac20120 100644 --- a/llvm/lib/CodeGen/StaticDataAnnotator.cpp +++ b/llvm/lib/CodeGen/StaticDataAnnotator.cpp @@ -75,22 +75,11 @@ bool StaticDataAnnotator::runOnModule(Module &M) { bool Changed = false; for (auto &GV : M.globals()) { - if (GV.isDeclarationForLinker()) + if (!llvm::memprof::IsAnnotationOK(GV)) continue; - // The implementation below assumes prior passes don't set section prefixes, - // and specifically do 'assign' rather than 'update'. So report error if a - // section prefix is already set. - if (auto maybeSectionPrefix = GV.getSectionPrefix(); - maybeSectionPrefix && !maybeSectionPrefix->empty()) - llvm::report_fatal_error("Global variable " + GV.getName() + - " already has a section prefix " + - *maybeSectionPrefix); - StringRef SectionPrefix = SDPI->getConstantSectionPrefix(&GV, PSI); - if (SectionPrefix.empty()) - continue; - + // setSectionPrefix returns true if the section prefix is updated. Changed |= GV.setSectionPrefix(SectionPrefix); } diff --git a/llvm/lib/CodeGen/StaticDataSplitter.cpp b/llvm/lib/CodeGen/StaticDataSplitter.cpp index e22dc25..1593a40 100644 --- a/llvm/lib/CodeGen/StaticDataSplitter.cpp +++ b/llvm/lib/CodeGen/StaticDataSplitter.cpp @@ -130,10 +130,8 @@ StaticDataSplitter::getConstant(const MachineOperand &Op, if (Op.isGlobal()) { // Find global variables with local linkage. const GlobalVariable *GV = getLocalLinkageGlobalVariable(Op.getGlobal()); - // Skip 'llvm.'-prefixed global variables conservatively because they are - // often handled specially, and skip those not in static data - // sections. - if (!GV || GV->getName().starts_with("llvm.") || + // Skip those not eligible for annotation or not in static data sections. + if (!GV || !llvm::memprof::IsAnnotationOK(*GV) || !inStaticDataSection(*GV, TM)) return nullptr; return GV; diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index c23281a..060b1dd 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -815,7 +815,8 @@ void TargetLoweringBase::initActions() { ISD::FTAN, ISD::FACOS, ISD::FASIN, ISD::FATAN, ISD::FCOSH, ISD::FSINH, - ISD::FTANH, ISD::FATAN2}, + ISD::FTANH, ISD::FATAN2, + ISD::FMULADD}, VT, Expand); // Overflow operations default to expand diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp index c9e4618..971f822 100644 --- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp +++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp @@ -102,10 +102,8 @@ bool TargetRegisterInfo::checkAllSuperRegsMarked(const BitVector &RegisterSet, return true; } -namespace llvm { - -Printable printReg(Register Reg, const TargetRegisterInfo *TRI, - unsigned SubIdx, const MachineRegisterInfo *MRI) { +Printable llvm::printReg(Register Reg, const TargetRegisterInfo *TRI, + unsigned SubIdx, const MachineRegisterInfo *MRI) { return Printable([Reg, TRI, SubIdx, MRI](raw_ostream &OS) { if (!Reg) OS << "$noreg"; @@ -135,7 +133,7 @@ Printable printReg(Register Reg, const TargetRegisterInfo *TRI, }); } -Printable printRegUnit(unsigned Unit, const TargetRegisterInfo *TRI) { +Printable llvm::printRegUnit(unsigned Unit, const TargetRegisterInfo *TRI) { return Printable([Unit, TRI](raw_ostream &OS) { // Generic printout when TRI is missing. if (!TRI) { @@ -158,7 +156,7 @@ Printable printRegUnit(unsigned Unit, const TargetRegisterInfo *TRI) { }); } -Printable printVRegOrUnit(unsigned Unit, const TargetRegisterInfo *TRI) { +Printable llvm::printVRegOrUnit(unsigned Unit, const TargetRegisterInfo *TRI) { return Printable([Unit, TRI](raw_ostream &OS) { if (Register::isVirtualRegister(Unit)) { OS << '%' << Register(Unit).virtRegIndex(); @@ -168,8 +166,9 @@ Printable printVRegOrUnit(unsigned Unit, const TargetRegisterInfo *TRI) { }); } -Printable printRegClassOrBank(Register Reg, const MachineRegisterInfo &RegInfo, - const TargetRegisterInfo *TRI) { +Printable llvm::printRegClassOrBank(Register Reg, + const MachineRegisterInfo &RegInfo, + const TargetRegisterInfo *TRI) { return Printable([Reg, &RegInfo, TRI](raw_ostream &OS) { if (RegInfo.getRegClassOrNull(Reg)) OS << StringRef(TRI->getRegClassName(RegInfo.getRegClass(Reg))).lower(); @@ -183,8 +182,6 @@ Printable printRegClassOrBank(Register Reg, const MachineRegisterInfo &RegInfo, }); } -} // end namespace llvm - /// getAllocatableClass - Return the maximal subclass of the given register /// class that is alloctable, or NULL. const TargetRegisterClass * diff --git a/llvm/lib/IR/ConstantFPRange.cpp b/llvm/lib/IR/ConstantFPRange.cpp index e9c058e..5b87686 100644 --- a/llvm/lib/IR/ConstantFPRange.cpp +++ b/llvm/lib/IR/ConstantFPRange.cpp @@ -528,3 +528,147 @@ void ConstantFPRange::flushDenormals(DenormalMode::DenormalModeKind Mode) { Lower = minnum(Lower, APFloat::getZero(Sem, ZeroLowerNegative)); Upper = maxnum(Upper, APFloat::getZero(Sem, ZeroUpperNegative)); } + +/// Represent a contiguous range of values sharing the same sign. +struct SameSignRange { + bool HasZero; + bool HasNonZero; + bool HasInf; + // The lower and upper bounds of the range (inclusive). + // The sign is dropped and infinities are excluded. + std::optional<std::pair<APFloat, APFloat>> FinitePart; + + explicit SameSignRange(const APFloat &Lower, const APFloat &Upper) + : HasZero(Lower.isZero()), HasNonZero(!Upper.isZero()), + HasInf(Upper.isInfinity()) { + assert(!Lower.isNegative() && !Upper.isNegative() && + "The sign should be dropped."); + assert(strictCompare(Lower, Upper) != APFloat::cmpGreaterThan && + "Empty set."); + if (!Lower.isInfinity()) + FinitePart = {Lower, + HasInf ? APFloat::getLargest(Lower.getSemantics()) : Upper}; + } +}; + +/// Split the range into positive and negative components. +static void splitPosNeg(const APFloat &Lower, const APFloat &Upper, + std::optional<SameSignRange> &NegPart, + std::optional<SameSignRange> &PosPart) { + assert(strictCompare(Lower, Upper) != APFloat::cmpGreaterThan && + "Non-NaN part is empty."); + if (Lower.isNegative() == Upper.isNegative()) { + if (Lower.isNegative()) + NegPart = SameSignRange{abs(Upper), abs(Lower)}; + else + PosPart = SameSignRange{Lower, Upper}; + return; + } + auto &Sem = Lower.getSemantics(); + NegPart = SameSignRange{APFloat::getZero(Sem), abs(Lower)}; + PosPart = SameSignRange{APFloat::getZero(Sem), Upper}; +} + +ConstantFPRange ConstantFPRange::mul(const ConstantFPRange &Other) const { + auto &Sem = getSemantics(); + bool ResMayBeQNaN = ((MayBeQNaN || MayBeSNaN) && !Other.isEmptySet()) || + ((Other.MayBeQNaN || Other.MayBeSNaN) && !isEmptySet()); + if (isNaNOnly() || Other.isNaNOnly()) + return getNaNOnly(Sem, /*MayBeQNaN=*/ResMayBeQNaN, + /*MayBeSNaN=*/false); + std::optional<SameSignRange> LHSNeg, LHSPos, RHSNeg, RHSPos; + splitPosNeg(Lower, Upper, LHSNeg, LHSPos); + splitPosNeg(Other.Lower, Other.Upper, RHSNeg, RHSPos); + APFloat ResLower = APFloat::getInf(Sem, /*Negative=*/false); + APFloat ResUpper = APFloat::getInf(Sem, /*Negative=*/true); + auto Update = [&](std::optional<SameSignRange> &LHS, + std::optional<SameSignRange> &RHS, bool Negative) { + if (!LHS || !RHS) + return; + // 0 * inf = QNaN + ResMayBeQNaN |= LHS->HasZero && RHS->HasInf; + ResMayBeQNaN |= RHS->HasZero && LHS->HasInf; + // NonZero * inf = inf + if ((LHS->HasInf && RHS->HasNonZero) || (RHS->HasInf && LHS->HasNonZero)) + (Negative ? ResLower : ResUpper) = APFloat::getInf(Sem, Negative); + // Finite * Finite + if (LHS->FinitePart && RHS->FinitePart) { + APFloat NewLower = LHS->FinitePart->first * RHS->FinitePart->first; + APFloat NewUpper = LHS->FinitePart->second * RHS->FinitePart->second; + if (Negative) { + ResLower = minnum(ResLower, -NewUpper); + ResUpper = maxnum(ResUpper, -NewLower); + } else { + ResLower = minnum(ResLower, NewLower); + ResUpper = maxnum(ResUpper, NewUpper); + } + } + }; + Update(LHSNeg, RHSNeg, /*Negative=*/false); + Update(LHSNeg, RHSPos, /*Negative=*/true); + Update(LHSPos, RHSNeg, /*Negative=*/true); + Update(LHSPos, RHSPos, /*Negative=*/false); + return ConstantFPRange(ResLower, ResUpper, ResMayBeQNaN, /*MayBeSNaN=*/false); +} + +ConstantFPRange ConstantFPRange::div(const ConstantFPRange &Other) const { + auto &Sem = getSemantics(); + bool ResMayBeQNaN = ((MayBeQNaN || MayBeSNaN) && !Other.isEmptySet()) || + ((Other.MayBeQNaN || Other.MayBeSNaN) && !isEmptySet()); + if (isNaNOnly() || Other.isNaNOnly()) + return getNaNOnly(Sem, /*MayBeQNaN=*/ResMayBeQNaN, + /*MayBeSNaN=*/false); + std::optional<SameSignRange> LHSNeg, LHSPos, RHSNeg, RHSPos; + splitPosNeg(Lower, Upper, LHSNeg, LHSPos); + splitPosNeg(Other.Lower, Other.Upper, RHSNeg, RHSPos); + APFloat ResLower = APFloat::getInf(Sem, /*Negative=*/false); + APFloat ResUpper = APFloat::getInf(Sem, /*Negative=*/true); + auto Update = [&](std::optional<SameSignRange> &LHS, + std::optional<SameSignRange> &RHS, bool Negative) { + if (!LHS || !RHS) + return; + // inf / inf = QNaN 0 / 0 = QNaN + ResMayBeQNaN |= LHS->HasInf && RHS->HasInf; + ResMayBeQNaN |= LHS->HasZero && RHS->HasZero; + // It is not straightforward to infer HasNonZeroFinite = HasFinite && + // HasNonZero. By definitions we have: + // HasFinite = HasNonZeroFinite || HasZero + // HasNonZero = HasNonZeroFinite || HasInf + // Since the range is contiguous, if both HasFinite and HasNonZero are true, + // HasNonZeroFinite must be true. + bool LHSHasNonZeroFinite = LHS->FinitePart && LHS->HasNonZero; + bool RHSHasNonZeroFinite = RHS->FinitePart && RHS->HasNonZero; + // inf / Finite = inf FiniteNonZero / 0 = inf + if ((LHS->HasInf && RHS->FinitePart) || + (LHSHasNonZeroFinite && RHS->HasZero)) + (Negative ? ResLower : ResUpper) = APFloat::getInf(Sem, Negative); + // Finite / inf = 0 + if (LHS->FinitePart && RHS->HasInf) { + APFloat Zero = APFloat::getZero(Sem, /*Negative=*/Negative); + ResLower = minnum(ResLower, Zero); + ResUpper = maxnum(ResUpper, Zero); + } + // Finite / FiniteNonZero + if (LHS->FinitePart && RHSHasNonZeroFinite) { + assert(!RHS->FinitePart->second.isZero() && + "Divisor should be non-zero."); + APFloat NewLower = LHS->FinitePart->first / RHS->FinitePart->second; + APFloat NewUpper = LHS->FinitePart->second / + (RHS->FinitePart->first.isZero() + ? APFloat::getSmallest(Sem, /*Negative=*/false) + : RHS->FinitePart->first); + if (Negative) { + ResLower = minnum(ResLower, -NewUpper); + ResUpper = maxnum(ResUpper, -NewLower); + } else { + ResLower = minnum(ResLower, NewLower); + ResUpper = maxnum(ResUpper, NewUpper); + } + } + }; + Update(LHSNeg, RHSNeg, /*Negative=*/false); + Update(LHSNeg, RHSPos, /*Negative=*/true); + Update(LHSPos, RHSNeg, /*Negative=*/true); + Update(LHSPos, RHSPos, /*Negative=*/false); + return ConstantFPRange(ResLower, ResUpper, ResMayBeQNaN, /*MayBeSNaN=*/false); +} diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp index 614c3a9..15c0198 100644 --- a/llvm/lib/IR/IRBuilder.cpp +++ b/llvm/lib/IR/IRBuilder.cpp @@ -25,6 +25,7 @@ #include "llvm/IR/Module.h" #include "llvm/IR/NoFolder.h" #include "llvm/IR/Operator.h" +#include "llvm/IR/ProfDataUtils.h" #include "llvm/IR/Statepoint.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" @@ -1002,6 +1003,18 @@ CallInst *IRBuilderBase::CreateConstrainedFPCall( return C; } +Value *IRBuilderBase::CreateSelectWithUnknownProfile(Value *C, Value *True, + Value *False, + StringRef PassName, + const Twine &Name) { + Value *Ret = CreateSelectFMF(C, True, False, {}, Name); + if (auto *SI = dyn_cast<SelectInst>(Ret)) { + setExplicitlyUnknownBranchWeightsIfProfiled( + *SI, *SI->getParent()->getParent(), PassName); + } + return Ret; +} + Value *IRBuilderBase::CreateSelect(Value *C, Value *True, Value *False, const Twine &Name, Instruction *MDFrom) { return CreateSelectFMF(C, True, False, {}, Name, MDFrom); diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp index 2ea3a24..afce803 100644 --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -1363,9 +1363,12 @@ const Init *BinOpInit::Fold(const Record *CurRec) const { } case LISTSPLAT: { const auto *Value = dyn_cast<TypedInit>(LHS); - const auto *Size = dyn_cast<IntInit>(RHS); - if (Value && Size) { - SmallVector<const Init *, 8> Args(Size->getValue(), Value); + const auto *Count = dyn_cast<IntInit>(RHS); + if (Value && Count) { + if (Count->getValue() < 0) + PrintFatalError(Twine("!listsplat count ") + Count->getAsString() + + " is negative"); + SmallVector<const Init *, 8> Args(Count->getValue(), Value); return ListInit::get(Args, Value->getType()); } break; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp b/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp index dbe74b1..5700468 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp @@ -2394,15 +2394,19 @@ bool SchedGroup::canAddMI(const MachineInstr &MI) const { else if (((SGMask & SchedGroupMask::ALU) != SchedGroupMask::NONE) && (TII->isVALU(MI) || TII->isMFMAorWMMA(MI) || TII->isSALU(MI) || TII->isTRANS(MI))) - Result = true; + Result = !MI.mayLoadOrStore(); else if (((SGMask & SchedGroupMask::VALU) != SchedGroupMask::NONE) && - TII->isVALU(MI) && !TII->isMFMAorWMMA(MI) && !TII->isTRANS(MI)) - Result = true; + TII->isVALU(MI) && !TII->isMFMAorWMMA(MI) && !TII->isTRANS(MI)) { + // Some memory instructions may be marked as VALU (e.g. BUFFER_LOAD_*_LDS). + // For our purposes, these shall not be classified as VALU as this results + // in unexpected behavior. + Result = !MI.mayLoadOrStore(); + } else if (((SGMask & SchedGroupMask::SALU) != SchedGroupMask::NONE) && TII->isSALU(MI)) - Result = true; + Result = !MI.mayLoadOrStore(); else if (((SGMask & SchedGroupMask::MFMA) != SchedGroupMask::NONE) && TII->isMFMAorWMMA(MI)) diff --git a/llvm/lib/Target/AMDGPU/MIMGInstructions.td b/llvm/lib/Target/AMDGPU/MIMGInstructions.td index 64e34db..5f6d742 100644 --- a/llvm/lib/Target/AMDGPU/MIMGInstructions.td +++ b/llvm/lib/Target/AMDGPU/MIMGInstructions.td @@ -260,8 +260,12 @@ class NSAHelper { } class MIMGNSAHelper<int num_addrs, - list<RegisterClass> addr_types=!listsplat(VGPR_32, num_addrs)> - : NSAHelper<> { + list<RegisterOperand> addr_types_in=[]> + : NSAHelper<> { + list<RegisterOperand> addr_types = + !if(!empty(addr_types_in), !listsplat(VGPROp_32, num_addrs), + addr_types_in); + list<string> AddrAsmNames = !foreach(i, !range(num_addrs), "vaddr" # i); let AddrIns = !dag(ins, addr_types, AddrAsmNames); let AddrAsm = "[$" # !interleave(AddrAsmNames, ", $") # "]"; @@ -358,7 +362,7 @@ class MIMG_gfx11<int op, dag outs, string dns = ""> // Base class for all NSA MIMG instructions. // Note that 1-dword addresses always use non-NSA variants. class MIMG_nsa_gfx11<int op, dag outs, int num_addrs, string dns="", - list<RegisterClass> addr_types=[], + list<RegisterOperand> addr_types=[], RegisterOperand LastAddrRC = VGPROp_32> : MIMG<outs, dns>, MIMGe_gfx11<op> { let SubtargetPredicate = isGFX11Only; @@ -378,7 +382,7 @@ class MIMG_nsa_gfx11<int op, dag outs, int num_addrs, string dns="", } class VIMAGE_gfx12<int op, dag outs, int num_addrs, string dns="", - list<RegisterClass> addr_types=[]> + list<RegisterOperand> addr_types=[]> : VIMAGE<outs, dns>, VIMAGEe<op> { let SubtargetPredicate = isGFX12Plus; let AssemblerPredicate = isGFX12Plus; @@ -1521,12 +1525,12 @@ class MIMG_IntersectRay_Helper<bit Is64, bit IsA16, bit isDual, bit isBVH8> { int VAddrDwords = !srl(Size, 5); int GFX11PlusNSAAddrs = !if(IsA16, 4, 5); - RegisterClass node_ptr_type = !if(Is64, VReg_64, VGPR_32); - list<RegisterClass> GFX11PlusAddrTypes = - !cond(isBVH8 : [node_ptr_type, VReg_64, VReg_96, VReg_96, VGPR_32], - isDual : [node_ptr_type, VReg_64, VReg_96, VReg_96, VReg_64], - IsA16 : [node_ptr_type, VGPR_32, VReg_96, VReg_96], - true : [node_ptr_type, VGPR_32, VReg_96, VReg_96, VReg_96]); + RegisterOperand node_ptr_type = !if(Is64, VGPROp_64, VGPROp_32); + list<RegisterOperand> GFX11PlusAddrTypes = + !cond(isBVH8 : [node_ptr_type, VGPROp_64, VGPROp_96, VGPROp_96, VGPROp_32], + isDual : [node_ptr_type, VGPROp_64, VGPROp_96, VGPROp_96, VGPROp_64], + IsA16 : [node_ptr_type, VGPROp_32, VGPROp_96, VGPROp_96], + true : [node_ptr_type, VGPROp_32, VGPROp_96, VGPROp_96, VGPROp_96]); } class MIMG_IntersectRay_gfx10<mimgopc op, string opcode, RegisterOperand AddrRC> @@ -1552,7 +1556,7 @@ class MIMG_IntersectRay_gfx11<mimgopc op, string opcode, RegisterOperand AddrRC> } class MIMG_IntersectRay_nsa_gfx11<mimgopc op, string opcode, int num_addrs, - list<RegisterClass> addr_types> + list<RegisterOperand> addr_types> : MIMG_nsa_gfx11<op.GFX11, (outs VReg_128:$vdata), num_addrs, "GFX11", addr_types> { let InOperandList = !con(nsah.AddrIns, (ins SReg_128_XNULL:$srsrc, A16:$a16)); @@ -1561,7 +1565,7 @@ class MIMG_IntersectRay_nsa_gfx11<mimgopc op, string opcode, int num_addrs, class VIMAGE_IntersectRay_gfx12<mimgopc op, string opcode, int num_addrs, bit isDual, bit isBVH8, - list<RegisterClass> addr_types> + list<RegisterOperand> addr_types> : VIMAGE_gfx12<op.GFX12, !if(!or(isDual, isBVH8), (outs VReg_320:$vdata, VReg_96:$ray_origin_out, VReg_96:$ray_dir_out), diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 4b54231..8851a0f 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -1659,6 +1659,10 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return generateImmOutOfRangeError( Operands, ErrorInfo, -1, (1 << 5) - 1, "immediate must be non-zero in the range"); + case Match_InvalidXSfmmVType: { + SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); + return generateXSfmmVTypeError(ErrorLoc); + } case Match_InvalidVTypeI: { SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); return generateVTypeError(ErrorLoc); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index 70b7c43..e75dfe3 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -142,6 +142,22 @@ enum { ReadsPastVLShift = DestEEWShift + 2, ReadsPastVLMask = 1ULL << ReadsPastVLShift, + + // 0 -> Don't care about altfmt bit in VTYPE. + // 1 -> Is not altfmt. + // 2 -> Is altfmt(BF16). + AltFmtTypeShift = ReadsPastVLShift + 1, + AltFmtTypeMask = 3ULL << AltFmtTypeShift, + + // XSfmmbase + HasTWidenOpShift = AltFmtTypeShift + 2, + HasTWidenOpMask = 1ULL << HasTWidenOpShift, + + HasTMOpShift = HasTWidenOpShift + 1, + HasTMOpMask = 1ULL << HasTMOpShift, + + HasTKOpShift = HasTMOpShift + 1, + HasTKOpMask = 1ULL << HasTKOpShift, }; // Helper functions to read TSFlags. @@ -183,6 +199,11 @@ static inline bool hasRoundModeOp(uint64_t TSFlags) { return TSFlags & HasRoundModeOpMask; } +enum class AltFmtType { DontCare, NotAltFmt, AltFmt }; +static inline AltFmtType getAltFmtType(uint64_t TSFlags) { + return static_cast<AltFmtType>((TSFlags & AltFmtTypeMask) >> AltFmtTypeShift); +} + /// \returns true if this instruction uses vxrm static inline bool usesVXRM(uint64_t TSFlags) { return TSFlags & UsesVXRMMask; } @@ -204,11 +225,47 @@ static inline bool readsPastVL(uint64_t TSFlags) { return TSFlags & ReadsPastVLMask; } +// XSfmmbase +static inline bool hasTWidenOp(uint64_t TSFlags) { + return TSFlags & HasTWidenOpMask; +} + +static inline bool hasTMOp(uint64_t TSFlags) { return TSFlags & HasTMOpMask; } + +static inline bool hasTKOp(uint64_t TSFlags) { return TSFlags & HasTKOpMask; } + +static inline unsigned getTNOpNum(const MCInstrDesc &Desc) { + const uint64_t TSFlags = Desc.TSFlags; + assert(hasTWidenOp(TSFlags) && hasVLOp(TSFlags)); + unsigned Offset = 3; + if (hasTKOp(TSFlags)) + Offset = 4; + return Desc.getNumOperands() - Offset; +} + +static inline unsigned getTMOpNum(const MCInstrDesc &Desc) { + const uint64_t TSFlags = Desc.TSFlags; + assert(hasTWidenOp(TSFlags) && hasTMOp(TSFlags)); + if (hasTKOp(TSFlags)) + return Desc.getNumOperands() - 5; + // vtzero.t + return Desc.getNumOperands() - 4; +} + +static inline unsigned getTKOpNum(const MCInstrDesc &Desc) { + [[maybe_unused]] const uint64_t TSFlags = Desc.TSFlags; + assert(hasTWidenOp(TSFlags) && hasTKOp(TSFlags)); + return Desc.getNumOperands() - 3; +} + static inline unsigned getVLOpNum(const MCInstrDesc &Desc) { const uint64_t TSFlags = Desc.TSFlags; // This method is only called if we expect to have a VL operand, and all // instructions with VL also have SEW. assert(hasSEWOp(TSFlags) && hasVLOp(TSFlags)); + // In Xsfmmbase, TN is an alias for VL, so here we use the same TSFlags bit. + if (hasTWidenOp(TSFlags)) + return getTNOpNum(Desc); unsigned Offset = 2; if (hasVecPolicyOp(TSFlags)) Offset = 3; @@ -226,7 +283,7 @@ static inline unsigned getSEWOpNum(const MCInstrDesc &Desc) { const uint64_t TSFlags = Desc.TSFlags; assert(hasSEWOp(TSFlags)); unsigned Offset = 1; - if (hasVecPolicyOp(TSFlags)) + if (hasVecPolicyOp(TSFlags) || hasTWidenOp(TSFlags)) Offset = 2; return Desc.getNumOperands() - Offset; } @@ -243,6 +300,9 @@ static inline int getFRMOpNum(const MCInstrDesc &Desc) { if (!hasRoundModeOp(TSFlags) || usesVXRM(TSFlags)) return -1; + if (hasTWidenOp(TSFlags) && hasTMOp(TSFlags)) + return getTMOpNum(Desc) - 1; + // The operand order // -------------------------------------- // | n-1 (if any) | n-2 | n-3 | n-4 | @@ -385,7 +445,9 @@ enum OperandType : unsigned { OPERAND_SEW_MASK, // Vector rounding mode for VXRM or FRM. OPERAND_VEC_RM, - OPERAND_LAST_RISCV_IMM = OPERAND_VEC_RM, + // Vtype operand for XSfmm extension. + OPERAND_XSFMM_VTYPE, + OPERAND_LAST_RISCV_IMM = OPERAND_XSFMM_VTYPE, // Operand is either a register or uimm5, this is used by V extension pseudo // instructions to represent a value that be passed as AVL to either vsetvli // or vsetivli. diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp index cf8d120..9ed3b97 100644 --- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp +++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp @@ -168,10 +168,13 @@ struct DemandedFields { // If this is true, we demand that VTYPE is set to some legal state, i.e. that // vill is unset. bool VILL = false; + bool UseTWiden = false; + bool UseAltFmt = false; // Return true if any part of VTYPE was used bool usedVTYPE() const { - return SEW || LMUL || SEWLMULRatio || TailPolicy || MaskPolicy || VILL; + return SEW || LMUL || SEWLMULRatio || TailPolicy || MaskPolicy || VILL || + UseTWiden || UseAltFmt; } // Return true if any property of VL was used @@ -187,6 +190,8 @@ struct DemandedFields { TailPolicy = true; MaskPolicy = true; VILL = true; + UseTWiden = true; + UseAltFmt = true; } // Mark all VL properties as demanded @@ -212,6 +217,8 @@ struct DemandedFields { TailPolicy |= B.TailPolicy; MaskPolicy |= B.MaskPolicy; VILL |= B.VILL; + UseAltFmt |= B.UseAltFmt; + UseTWiden |= B.UseTWiden; } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) @@ -258,7 +265,9 @@ struct DemandedFields { OS << "SEWLMULRatio=" << SEWLMULRatio << ", "; OS << "TailPolicy=" << TailPolicy << ", "; OS << "MaskPolicy=" << MaskPolicy << ", "; - OS << "VILL=" << VILL; + OS << "VILL=" << VILL << ", "; + OS << "UseAltFmt=" << UseAltFmt << ", "; + OS << "UseTWiden=" << UseTWiden; OS << "}"; } #endif @@ -328,6 +337,15 @@ static bool areCompatibleVTYPEs(uint64_t CurVType, uint64_t NewVType, if (Used.MaskPolicy && RISCVVType::isMaskAgnostic(CurVType) != RISCVVType::isMaskAgnostic(NewVType)) return false; + if (Used.UseTWiden && (RISCVVType::hasXSfmmWiden(CurVType) != + RISCVVType::hasXSfmmWiden(NewVType) || + (RISCVVType::hasXSfmmWiden(CurVType) && + RISCVVType::getXSfmmWiden(CurVType) != + RISCVVType::getXSfmmWiden(NewVType)))) + return false; + if (Used.UseAltFmt && + RISCVVType::isAltFmt(CurVType) != RISCVVType::isAltFmt(NewVType)) + return false; return true; } @@ -479,6 +497,11 @@ DemandedFields getDemanded(const MachineInstr &MI, const RISCVSubtarget *ST) { Res.TailPolicy = false; } + Res.UseAltFmt = RISCVII::getAltFmtType(MI.getDesc().TSFlags) != + RISCVII::AltFmtType::DontCare; + Res.UseTWiden = RISCVII::hasTWidenOp(MI.getDesc().TSFlags) || + RISCVInstrInfo::isXSfmmVectorConfigInstr(MI); + return Res; } @@ -510,6 +533,8 @@ class VSETVLIInfo { uint8_t TailAgnostic : 1; uint8_t MaskAgnostic : 1; uint8_t SEWLMULRatioOnly : 1; + uint8_t AltFmt : 1; + uint8_t TWiden : 3; public: VSETVLIInfo() @@ -586,6 +611,8 @@ public: RISCVVType::VLMUL getVLMUL() const { return VLMul; } bool getTailAgnostic() const { return TailAgnostic; } bool getMaskAgnostic() const { return MaskAgnostic; } + bool getAltFmt() const { return AltFmt; } + unsigned getTWiden() const { return TWiden; } bool hasNonZeroAVL(const LiveIntervals *LIS) const { if (hasAVLImm()) @@ -647,21 +674,31 @@ public: SEW = RISCVVType::getSEW(VType); TailAgnostic = RISCVVType::isTailAgnostic(VType); MaskAgnostic = RISCVVType::isMaskAgnostic(VType); + AltFmt = RISCVVType::isAltFmt(VType); + TWiden = + RISCVVType::hasXSfmmWiden(VType) ? RISCVVType::getXSfmmWiden(VType) : 0; } - void setVTYPE(RISCVVType::VLMUL L, unsigned S, bool TA, bool MA) { + void setVTYPE(RISCVVType::VLMUL L, unsigned S, bool TA, bool MA, bool Altfmt, + unsigned W) { assert(isValid() && !isUnknown() && "Can't set VTYPE for uninitialized or unknown"); VLMul = L; SEW = S; TailAgnostic = TA; MaskAgnostic = MA; + AltFmt = Altfmt; + TWiden = W; } + void setAltFmt(bool AF) { AltFmt = AF; } + void setVLMul(RISCVVType::VLMUL VLMul) { this->VLMul = VLMul; } unsigned encodeVTYPE() const { assert(isValid() && !isUnknown() && !SEWLMULRatioOnly && "Can't encode VTYPE for uninitialized or unknown"); + if (TWiden != 0) + return RISCVVType::encodeXSfmmVType(SEW, TWiden, AltFmt); return RISCVVType::encodeVTYPE(VLMul, SEW, TailAgnostic, MaskAgnostic); } @@ -674,9 +711,9 @@ public: "Can't compare VTYPE in unknown state"); assert(!SEWLMULRatioOnly && !Other.SEWLMULRatioOnly && "Can't compare when only LMUL/SEW ratio is valid."); - return std::tie(VLMul, SEW, TailAgnostic, MaskAgnostic) == + return std::tie(VLMul, SEW, TailAgnostic, MaskAgnostic, AltFmt, TWiden) == std::tie(Other.VLMul, Other.SEW, Other.TailAgnostic, - Other.MaskAgnostic); + Other.MaskAgnostic, Other.AltFmt, Other.TWiden); } unsigned getSEWLMULRatio() const { @@ -825,7 +862,9 @@ public: << "SEW=e" << (unsigned)SEW << ", " << "TailAgnostic=" << (bool)TailAgnostic << ", " << "MaskAgnostic=" << (bool)MaskAgnostic << ", " - << "SEWLMULRatioOnly=" << (bool)SEWLMULRatioOnly << "}"; + << "SEWLMULRatioOnly=" << (bool)SEWLMULRatioOnly << ", " + << "TWiden=" << (unsigned)TWiden << ", " + << "AltFmt=" << (bool)AltFmt << "}"; } #endif }; @@ -853,6 +892,11 @@ struct BlockData { BlockData() = default; }; +enum TKTMMode { + VSETTK = 0, + VSETTM = 1, +}; + class RISCVInsertVSETVLI : public MachineFunctionPass { const RISCVSubtarget *ST; const TargetInstrInfo *TII; @@ -908,6 +952,7 @@ private: VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI) const; VSETVLIInfo computeInfoForInstr(const MachineInstr &MI) const; void forwardVSETVLIAVL(VSETVLIInfo &Info) const; + bool insertVSETMTK(MachineBasicBlock &MBB, TKTMMode Mode) const; }; } // end anonymous namespace @@ -945,6 +990,18 @@ RISCVInsertVSETVLI::getInfoForVSETVLI(const MachineInstr &MI) const { VSETVLIInfo NewInfo; if (MI.getOpcode() == RISCV::PseudoVSETIVLI) { NewInfo.setAVLImm(MI.getOperand(1).getImm()); + } else if (RISCVInstrInfo::isXSfmmVectorConfigTNInstr(MI)) { + assert(MI.getOpcode() == RISCV::PseudoSF_VSETTNT || + MI.getOpcode() == RISCV::PseudoSF_VSETTNTX0); + switch (MI.getOpcode()) { + case RISCV::PseudoSF_VSETTNTX0: + NewInfo.setAVLVLMAX(); + break; + case RISCV::PseudoSF_VSETTNT: + Register ATNReg = MI.getOperand(1).getReg(); + NewInfo.setAVLRegDef(getVNInfoFromReg(ATNReg, MI, LIS), ATNReg); + break; + } } else { assert(MI.getOpcode() == RISCV::PseudoVSETVLI || MI.getOpcode() == RISCV::PseudoVSETVLIX0); @@ -1005,11 +1062,34 @@ RISCVInsertVSETVLI::computeInfoForInstr(const MachineInstr &MI) const { RISCVVType::VLMUL VLMul = RISCVII::getLMul(TSFlags); + bool AltFmt = RISCVII::getAltFmtType(TSFlags) == RISCVII::AltFmtType::AltFmt; + InstrInfo.setAltFmt(AltFmt); + unsigned Log2SEW = MI.getOperand(getSEWOpNum(MI)).getImm(); // A Log2SEW of 0 is an operation on mask registers only. unsigned SEW = Log2SEW ? 1 << Log2SEW : 8; assert(RISCVVType::isValidSEW(SEW) && "Unexpected SEW"); + if (RISCVII::hasTWidenOp(TSFlags)) { + const MachineOperand &TWidenOp = + MI.getOperand(MI.getNumExplicitOperands() - 1); + unsigned TWiden = TWidenOp.getImm(); + + InstrInfo.setAVLVLMAX(); + if (RISCVII::hasVLOp(TSFlags)) { + const MachineOperand &TNOp = + MI.getOperand(RISCVII::getTNOpNum(MI.getDesc())); + + if (TNOp.getReg().isVirtual()) + InstrInfo.setAVLRegDef(getVNInfoFromReg(TNOp.getReg(), MI, LIS), + TNOp.getReg()); + } + + InstrInfo.setVTYPE(VLMul, SEW, TailAgnostic, MaskAgnostic, AltFmt, TWiden); + + return InstrInfo; + } + if (RISCVII::hasVLOp(TSFlags)) { const MachineOperand &VLOp = MI.getOperand(getVLOpNum(MI)); if (VLOp.isImm()) { @@ -1045,7 +1125,9 @@ RISCVInsertVSETVLI::computeInfoForInstr(const MachineInstr &MI) const { assert(SEW == EEW && "Initial SEW doesn't match expected EEW"); } #endif - InstrInfo.setVTYPE(VLMul, SEW, TailAgnostic, MaskAgnostic); + // TODO: Propagate the twiden from previous vtype for potential reuse. + InstrInfo.setVTYPE(VLMul, SEW, TailAgnostic, MaskAgnostic, AltFmt, + /*TWiden*/ 0); forwardVSETVLIAVL(InstrInfo); @@ -1053,10 +1135,33 @@ RISCVInsertVSETVLI::computeInfoForInstr(const MachineInstr &MI) const { } void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB, - MachineBasicBlock::iterator InsertPt, DebugLoc DL, - const VSETVLIInfo &Info, const VSETVLIInfo &PrevInfo) { - + MachineBasicBlock::iterator InsertPt, + DebugLoc DL, const VSETVLIInfo &Info, + const VSETVLIInfo &PrevInfo) { ++NumInsertedVSETVL; + + if (Info.getTWiden()) { + if (Info.hasAVLVLMAX()) { + Register DestReg = MRI->createVirtualRegister(&RISCV::GPRNoX0RegClass); + auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoSF_VSETTNTX0)) + .addReg(DestReg, RegState::Define | RegState::Dead) + .addReg(RISCV::X0, RegState::Kill) + .addImm(Info.encodeVTYPE()); + if (LIS) { + LIS->InsertMachineInstrInMaps(*MI); + LIS->createAndComputeVirtRegInterval(DestReg); + } + } else { + auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoSF_VSETTNT)) + .addReg(RISCV::X0, RegState::Define | RegState::Dead) + .addReg(Info.getAVLReg()) + .addImm(Info.encodeVTYPE()); + if (LIS) + LIS->InsertMachineInstrInMaps(*MI); + } + return; + } + if (PrevInfo.isValid() && !PrevInfo.isUnknown()) { // Use X0, X0 form if the AVL is the same and the SEW+LMUL gives the same // VLMAX. @@ -1198,7 +1303,8 @@ void RISCVInsertVSETVLI::transferBefore(VSETVLIInfo &Info, // be coalesced into another vsetvli since we won't demand any fields. VSETVLIInfo NewInfo; // Need a new VSETVLIInfo to clear SEWLMULRatioOnly NewInfo.setAVLImm(1); - NewInfo.setVTYPE(RISCVVType::LMUL_1, /*sew*/ 8, /*ta*/ true, /*ma*/ true); + NewInfo.setVTYPE(RISCVVType::LMUL_1, /*sew*/ 8, /*ta*/ true, /*ma*/ true, + /*AltFmt*/ false, /*W*/ 0); Info = NewInfo; return; } @@ -1240,7 +1346,9 @@ void RISCVInsertVSETVLI::transferBefore(VSETVLIInfo &Info, (Demanded.TailPolicy ? IncomingInfo : Info).getTailAgnostic() || IncomingInfo.getTailAgnostic(), (Demanded.MaskPolicy ? IncomingInfo : Info).getMaskAgnostic() || - IncomingInfo.getMaskAgnostic()); + IncomingInfo.getMaskAgnostic(), + (Demanded.UseAltFmt ? IncomingInfo : Info).getAltFmt(), + Demanded.UseTWiden ? IncomingInfo.getTWiden() : 0); // If we only knew the sew/lmul ratio previously, replace the VTYPE but keep // the AVL. @@ -1293,7 +1401,8 @@ bool RISCVInsertVSETVLI::computeVLVTYPEChanges(const MachineBasicBlock &MBB, if (RISCVInstrInfo::isVectorConfigInstr(MI) || RISCVII::hasSEWOp(MI.getDesc().TSFlags) || - isVectorCopy(ST->getRegisterInfo(), MI)) + isVectorCopy(ST->getRegisterInfo(), MI) || + RISCVInstrInfo::isXSfmmVectorConfigInstr(MI)) HadVectorOp = true; transferAfter(Info, MI); @@ -1675,6 +1784,12 @@ void RISCVInsertVSETVLI::coalesceVSETVLIs(MachineBasicBlock &MBB) const { }; for (MachineInstr &MI : make_early_inc_range(reverse(MBB))) { + // TODO: Support XSfmm. + if (RISCVII::hasTWidenOp(MI.getDesc().TSFlags) || + RISCVInstrInfo::isXSfmmVectorConfigInstr(MI)) { + NextMI = nullptr; + continue; + } if (!RISCVInstrInfo::isVectorConfigInstr(MI)) { Used.doUnion(getDemanded(MI, ST)); @@ -1788,6 +1903,65 @@ void RISCVInsertVSETVLI::insertReadVL(MachineBasicBlock &MBB) { } } +bool RISCVInsertVSETVLI::insertVSETMTK(MachineBasicBlock &MBB, + TKTMMode Mode) const { + + bool Changed = false; + for (auto &MI : MBB) { + uint64_t TSFlags = MI.getDesc().TSFlags; + if (RISCVInstrInfo::isXSfmmVectorConfigTMTKInstr(MI) || + !RISCVII::hasSEWOp(TSFlags) || !RISCVII::hasTWidenOp(TSFlags)) + continue; + + VSETVLIInfo CurrInfo = computeInfoForInstr(MI); + + if (Mode == VSETTK && !RISCVII::hasTKOp(TSFlags)) + continue; + + if (Mode == VSETTM && !RISCVII::hasTMOp(TSFlags)) + continue; + + unsigned OpNum = 0; + unsigned Opcode = 0; + switch (Mode) { + case VSETTK: + OpNum = RISCVII::getTKOpNum(MI.getDesc()); + Opcode = RISCV::PseudoSF_VSETTK; + break; + case VSETTM: + OpNum = RISCVII::getTMOpNum(MI.getDesc()); + Opcode = RISCV::PseudoSF_VSETTM; + break; + } + + assert(OpNum && Opcode && "Invalid OpNum or Opcode"); + + MachineOperand &Op = MI.getOperand(OpNum); + + auto TmpMI = BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(Opcode)) + .addReg(RISCV::X0, RegState::Define | RegState::Dead) + .addReg(Op.getReg()) + .addImm(Log2_32(CurrInfo.getSEW())) + .addImm(Log2_32(CurrInfo.getTWiden()) + 1); + + Changed = true; + Register Reg = Op.getReg(); + Op.setReg(Register()); + Op.setIsKill(false); + if (LIS) { + LIS->InsertMachineInstrInMaps(*TmpMI); + LiveInterval &LI = LIS->getInterval(Reg); + + // Erase the AVL operand from the instruction. + LIS->shrinkToUses(&LI); + // TODO: Enable this once needVSETVLIPHI is supported. + // SmallVector<LiveInterval *> SplitLIs; + // LIS->splitSeparateComponents(LI, SplitLIs); + } + } + return Changed; +} + bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) { // Skip if the vector extension is not enabled. ST = &MF.getSubtarget<RISCVSubtarget>(); @@ -1865,6 +2039,11 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) { for (MachineBasicBlock &MBB : MF) insertReadVL(MBB); + for (MachineBasicBlock &MBB : MF) { + insertVSETMTK(MBB, VSETTM); + insertVSETMTK(MBB, VSETTK); + } + BlockInfo.clear(); return HaveVectorOp; } diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td index 2afd77a..5b06303 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td +++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td @@ -267,6 +267,22 @@ class RVInstCommon<dag outs, dag ins, string opcodestr, string argstr, // operands' VLs. bit ReadsPastVL = 0; let TSFlags{26} = ReadsPastVL; + + // 0 -> Don't care about altfmt bit in VTYPE. + // 1 -> Is not altfmt. + // 2 -> Is altfmt(BF16). + bits<2> AltFmtType = 0; + let TSFlags{28-27} = AltFmtType; + + // XSfmmbase + bit HasTWidenOp = 0; + let TSFlags{29} = HasTWidenOp; + + bit HasTmOp = 0; + let TSFlags{30} = HasTmOp; + + bit HasTkOp = 0; + let TSFlags{31} = HasTkOp; } class RVInst<dag outs, dag ins, string opcodestr, string argstr, diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index 96e1078..ddb53a2 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -3005,6 +3005,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, else Ok = RISCVFPRndMode::isValidRoundingMode(Imm); break; + case RISCVOp::OPERAND_XSFMM_VTYPE: + Ok = RISCVVType::isValidXSfmmVType(Imm); + break; } if (!Ok) { ErrInfo = "Invalid immediate"; @@ -3670,6 +3673,11 @@ std::string RISCVInstrInfo::createMIROperandComment( RISCVVType::printVType(Imm, OS); break; } + case RISCVOp::OPERAND_XSFMM_VTYPE: { + unsigned Imm = Op.getImm(); + RISCVVType::printXSfmmVType(Imm, OS); + break; + } case RISCVOp::OPERAND_SEW: case RISCVOp::OPERAND_SEW_MASK: { unsigned Log2SEW = Op.getImm(); diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td index 298d35a..c1b23af 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td @@ -128,6 +128,9 @@ defvar TAIL_AGNOSTIC = 1; defvar TU_MU = 0; defvar TA_MU = 1; defvar TA_MA = 3; +defvar DONT_CARE_ALTFMT = 0; +defvar IS_NOT_ALTFMT = 1; +defvar IS_ALTFMT = 2; //===----------------------------------------------------------------------===// // Utilities. @@ -159,7 +162,8 @@ class PseudoToVInst<string PseudoInst> { ["_M4", ""], ["_M8", ""], ["_SE", ""], - ["_RM", ""] + ["_RM", ""], + ["_ALT", ""] ]; string VInst = !foldl(PseudoInst, AffixSubsts, Acc, AffixSubst, !subst(AffixSubst[0], AffixSubst[1], Acc)); @@ -6396,7 +6400,7 @@ let Defs = [VXSAT] in { // 13. Vector Floating-Point Instructions //===----------------------------------------------------------------------===// -let Predicates = [HasVInstructionsAnyF] in { +let Predicates = [HasVInstructionsAnyF], AltFmtType = IS_NOT_ALTFMT in { //===----------------------------------------------------------------------===// // 13.2. Vector Single-Width Floating-Point Add/Subtract Instructions //===----------------------------------------------------------------------===// @@ -6565,7 +6569,7 @@ defm PseudoVFNCVT_F_F : VPseudoVNCVTD_W_RM; defm PseudoVFNCVT_ROD_F_F : VPseudoVNCVTD_W; } // mayRaiseFPException = true -} // Predicates = [HasVInstructionsAnyF] +} // Predicates = [HasVInstructionsAnyF], AltFmtType = IS_NOT_ALTFMT //===----------------------------------------------------------------------===// // 14. Vector Reduction Operations @@ -6593,7 +6597,7 @@ defm PseudoVWREDSUM : VPseudoVWRED_VS; } } // Predicates = [HasVInstructions] -let Predicates = [HasVInstructionsAnyF] in { +let Predicates = [HasVInstructionsAnyF], AltFmtType = IS_NOT_ALTFMT in { //===----------------------------------------------------------------------===// // 14.3. Vector Single-Width Floating-Point Reduction Instructions //===----------------------------------------------------------------------===// @@ -6612,7 +6616,7 @@ defm PseudoVFWREDUSUM : VPseudoVFWRED_VS_RM; defm PseudoVFWREDOSUM : VPseudoVFWREDO_VS_RM; } -} // Predicates = [HasVInstructionsAnyF] +} // Predicates = [HasVInstructionsAnyF], AltFmtType = IS_NOT_ALTFMT //===----------------------------------------------------------------------===// // 15. Vector Mask Instructions @@ -6703,7 +6707,7 @@ let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { // 16.2. Floating-Point Scalar Move Instructions //===----------------------------------------------------------------------===// -let Predicates = [HasVInstructionsAnyF] in { +let Predicates = [HasVInstructionsAnyF], AltFmtType = IS_NOT_ALTFMT in { let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { foreach f = FPList in { let HasSEWOp = 1, BaseInstr = VFMV_F_S in @@ -6718,7 +6722,7 @@ let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { Sched<[WriteVMovSF, ReadVMovSF_V, ReadVMovSF_F]>; } } -} // Predicates = [HasVInstructionsAnyF] +} // Predicates = [HasVInstructionsAnyF], AltFmtType = IS_NOT_ALTFMT //===----------------------------------------------------------------------===// // 16.3. Vector Slide Instructions @@ -6730,10 +6734,10 @@ let Predicates = [HasVInstructions] in { defm PseudoVSLIDE1DOWN : VPseudoVSLD1_VX; } // Predicates = [HasVInstructions] -let Predicates = [HasVInstructionsAnyF] in { +let Predicates = [HasVInstructionsAnyF], AltFmtType = IS_NOT_ALTFMT in { defm PseudoVFSLIDE1UP : VPseudoVSLD1_VF<"@earlyclobber $rd">; defm PseudoVFSLIDE1DOWN : VPseudoVSLD1_VF; -} // Predicates = [HasVInstructionsAnyF] +} // Predicates = [HasVInstructionsAnyF], AltFmtType = IS_NOT_ALTFMT //===----------------------------------------------------------------------===// // 16.4. Vector Register Gather Instructions diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td index 557d873..6a4119a 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td @@ -438,8 +438,10 @@ let Predicates = [HasVendorXSfvcp] in { } foreach f = FPList in { foreach m = f.MxList in { - defm f.FX # "V" : VPseudoVC_XV<m, f.fprclass, payload1>; - defm f.FX # "VV" : VPseudoVC_XVV<m, f.fprclass, payload1>; + let AltFmtType = IS_NOT_ALTFMT in { + defm f.FX # "V" : VPseudoVC_XV<m, f.fprclass, payload1>; + defm f.FX # "VV" : VPseudoVC_XVV<m, f.fprclass, payload1>; + } } } foreach m = MxListW in { @@ -449,7 +451,8 @@ let Predicates = [HasVendorXSfvcp] in { } foreach f = FPListW in { foreach m = f.MxList in - defm f.FX # "VW" : VPseudoVC_XVW<m, f.fprclass, payload1>; + let AltFmtType = IS_NOT_ALTFMT in + defm f.FX # "VW" : VPseudoVC_XVW<m, f.fprclass, payload1>; } } diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSfmm.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSfmm.td index a5ee701..5ad22e6b 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSfmm.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSfmm.td @@ -225,7 +225,7 @@ let Predicates = [HasVendorXSfmmbase] in { def SF_VSETTM : SFInstSetSingle<(outs GPR:$rd), (ins GPR:$rs1), 0b00001, "sf.vsettm", "$rd, $rs1">; def SF_VSETTK : SFInstSetSingle<(outs GPR:$rd), (ins GPR:$rs1), 0b00010, - "sf.vsettk", "$rd, $rs1">; + "sf.vsettk", "$rd, $rs1">; def SF_VTDISCARD : SFInstVtDiscard<"sf.vtdiscard">; def SF_VTMV_V_T : SFInstTileMoveOp<0b010000, (outs VR:$vd), (ins GPR:$rs1), @@ -277,3 +277,144 @@ let Uses = [FRM], mayRaiseFPException = true in { } // Predicates = [HasVendorXSfmm32a8f] } // DecoderNamespace = "XSfvector" + +class VPseudoSF_VTileLoad + : RISCVVPseudo<(outs), (ins GPR:$rs2, GPR:$rs1, AVL:$atn, ixlenimm:$sew, + ixlenimm:$twiden)> { + let mayLoad = 1; + let mayStore = 0; + let HasVLOp = 1; // Tn + let HasSEWOp = 1; + let HasTWidenOp = 1; + let hasSideEffects = 1; +} + +class VPseudoSF_VTileStore + : RISCVVPseudo<(outs), (ins GPR:$rs2, GPR:$rs1, AVL:$atn, ixlenimm:$sew, + ixlenimm:$twiden)> { + let mayLoad = 0; + let mayStore = 1; + let HasVLOp = 1; // Tn + let HasSEWOp = 1; + let HasTWidenOp = 1; + let hasSideEffects = 1; +} + +class VPseudoSF_VTileMove_V_T + : RISCVVPseudo<(outs VRM8:$vd), (ins GPR:$rs1, AVL:$atn, ixlenimm:$sew, + ixlenimm:$twiden)> { + let mayLoad = 0; + let mayStore = 0; + let HasVLOp = 1; // Tn + let HasSEWOp = 1; + let HasTWidenOp = 1; + let hasSideEffects = 1; +} + +class VPseudoSF_VTileMove_T_V + : RISCVVPseudo<(outs), (ins GPR:$rs1, VRM8:$vs2, AVL:$atn, ixlenimm:$sew, + ixlenimm:$twiden)> { + let mayLoad = 0; + let mayStore = 0; + let HasVLOp = 1; // Tn + let HasSEWOp = 1; + let HasTWidenOp = 1; + let hasSideEffects = 1; +} + +class VPseudoSF_MatMul<RegisterClass mtd_class> + : RISCVVPseudo<(outs), + (ins mtd_class:$rd, VRM8:$vs2, VRM8:$vs1, AVL:$atm, AVL:$atn, + AVL:$atk, ixlenimm:$sew, ixlenimm:$twiden)> { + let mayLoad = 0; + let mayStore = 0; + let HasTmOp = 1; + let HasVLOp = 1; // Tn + let HasTkOp = 1; + let HasSEWOp = 1; + let HasTWidenOp = 1; + let hasSideEffects = 1; +} + +class VPseudoSF_MatMul_FRM<RegisterClass mtd_class> + : RISCVVPseudo<(outs), + (ins mtd_class:$rd, VRM8:$vs2, VRM8:$vs1, ixlenimm:$frm, + AVL:$atm, AVL:$atn, AVL:$atk, ixlenimm:$sew, + ixlenimm:$twiden), []> { + let mayLoad = 0; + let mayStore = 0; + let HasTmOp = 1; + let HasVLOp = 1; // Tn + let HasTkOp = 1; + let HasSEWOp = 1; + let HasRoundModeOp = 1; + let hasPostISelHook = 1; + let HasTWidenOp = 1; + let hasSideEffects = 1; + let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); +} + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { +let Defs = [VL, VTYPE] in { + def PseudoSF_VSETTNT + : Pseudo<(outs GPR:$rd), + (ins GPRNoX0:$rs1, XSfmmVTypeOp:$vtypei), []>, + PseudoInstExpansion<(VSETVLI GPR:$rd, GPR:$rs1, VTypeIOp11:$vtypei)>, + Sched<[WriteVSETVLI, ReadVSETVLI]>; + def PseudoSF_VSETTNTX0 + : Pseudo<(outs GPRNoX0:$rd), + (ins GPRX0:$rs1, XSfmmVTypeOp:$vtypei), []>, + PseudoInstExpansion<(VSETVLI GPR:$rd, GPR:$rs1, VTypeIOp11:$vtypei)>, + Sched<[WriteVSETVLI, ReadVSETVLI]>; + def PseudoSF_VSETTNTX0X0 + : Pseudo<(outs GPRX0:$rd), + (ins GPRX0:$rs1, XSfmmVTypeOp:$vtypei), []>, + PseudoInstExpansion<(VSETVLI GPR:$rd, GPR:$rs1, VTypeIOp11:$vtypei)>, + Sched<[WriteVSETVLI, ReadVSETVLI]>; +} + +let Defs = [VTYPE], Uses = [VTYPE], HasTWidenOp = 1, HasSEWOp = 1 in { + def PseudoSF_VSETTM + : Pseudo<(outs GPR:$rd), + (ins GPR:$rs1, ixlenimm:$log2sew, ixlenimm:$twiden), []>, + PseudoInstExpansion<(SF_VSETTM GPR:$rd, GPR:$rs1)>, + Sched<[WriteVSETVLI, ReadVSETVLI]>; + def PseudoSF_VSETTK + : Pseudo<(outs GPR:$rd), + (ins GPR:$rs1, ixlenimm:$logwsew, ixlenimm:$twiden), []>, + PseudoInstExpansion<(SF_VSETTK GPR:$rd, GPR:$rs1)>, + Sched<[WriteVSETVLI, ReadVSETVLI]>; +} +} + +foreach eew = [8, 16, 32, 64] in { + def PseudoSF_VLTE # eew : VPseudoSF_VTileLoad; + def PseudoSF_VSTE # eew : VPseudoSF_VTileStore; +} + +def PseudoSF_VTMV_T_V : VPseudoSF_VTileMove_T_V; +def PseudoSF_VTMV_V_T : VPseudoSF_VTileMove_V_T; + +foreach a = I8Encodes in + foreach b = I8Encodes in + def PseudoSF_MM_ # !toupper(a.Name) # _ # !toupper(b.Name) + : VPseudoSF_MatMul<TRM4>; + +let AltFmtType = IS_NOT_ALTFMT in + def PseudoSF_MM_F_F : VPseudoSF_MatMul_FRM<TRM2>; +let AltFmtType = IS_ALTFMT in + def PseudoSF_MM_F_F_ALT : VPseudoSF_MatMul_FRM<TRM2>; + +foreach e1 = [5, 4] in + foreach e2 = [5, 4] in + def PseudoSF_MM_E # e1 # M # !sub(7, e1) # _E # e2 # M # !sub(7, e2) + : VPseudoSF_MatMul_FRM<TRM4>; + +let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { + let HasVLOp = 1, HasTmOp = 1, HasTWidenOp = 1, HasSEWOp = 1 in + def PseudoSF_VTZERO_T + : RISCVVPseudo<(outs), + (ins TR:$rd, AVL:$atm, AVL:$atn, ixlenimm:$sew, + ixlenimm:$twiden)>; + def PseudoSF_VTDISCARD : RISCVVPseudo<(outs), (ins), []>; +} diff --git a/llvm/lib/Target/RISCV/RISCVInstrPredicates.td b/llvm/lib/Target/RISCV/RISCVInstrPredicates.td index 3658817..dcae977 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrPredicates.td +++ b/llvm/lib/Target/RISCV/RISCVInstrPredicates.td @@ -78,7 +78,41 @@ def isVectorConfigInstr PseudoVSETVLI, PseudoVSETVLIX0, PseudoVSETVLIX0X0, - PseudoVSETIVLI + PseudoVSETIVLI, + PseudoSF_VSETTNT, + PseudoSF_VSETTNTX0, + PseudoSF_VSETTNTX0X0 + ]>>>; + +// Returns true if this is a PseudoSF_VSETTNT* instructions. +def isXSfmmVectorConfigTNInstr + : TIIPredicate<"isXSfmmVectorConfigTNInstr", + MCReturnStatement< + CheckOpcode<[ + PseudoSF_VSETTNT, + PseudoSF_VSETTNTX0, + PseudoSF_VSETTNTX0X0 + ]>>>; + +// Returns true if this is PseudoSF_VSETTM or PseudoSF_VSETTK. +def isXSfmmVectorConfigTMTKInstr + : TIIPredicate<"isXSfmmVectorConfigTMTKInstr", + MCReturnStatement< + CheckOpcode<[ + PseudoSF_VSETTM, + PseudoSF_VSETTK + ]>>>; + +// Returns true if this is a XSfmm vector configuration instruction. +def isXSfmmVectorConfigInstr + : TIIPredicate<"isXSfmmVectorConfigInstr", + MCReturnStatement< + CheckOpcode<[ + PseudoSF_VSETTNT, + PseudoSF_VSETTNTX0, + PseudoSF_VSETTNTX0X0, + PseudoSF_VSETTM, + PseudoSF_VSETTK ]>>>; // Return true if this is 'vsetvli x0, x0, vtype' which preserves diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp index 40b6416..e9f43b9 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -178,6 +178,10 @@ BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const { // Shadow stack pointer. markSuperRegs(Reserved, RISCV::SSP); + // XSfmmbase + for (MCPhysReg Reg = RISCV::T0; Reg <= RISCV::T15; Reg++) + markSuperRegs(Reserved, Reg); + assert(checkAllSuperRegsMarked(Reserved)); return Reserved; } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index 6472334..47c24fc 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -317,6 +317,15 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering( setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, T, Custom); } + if (Subtarget->hasFP16()) { + setOperationAction(ISD::FMA, MVT::v8f16, Legal); + } + + if (Subtarget->hasRelaxedSIMD()) { + setOperationAction(ISD::FMULADD, MVT::v4f32, Legal); + setOperationAction(ISD::FMULADD, MVT::v2f64, Legal); + } + // Partial MLA reductions. for (auto Op : {ISD::PARTIAL_REDUCE_SMLA, ISD::PARTIAL_REDUCE_UMLA}) { setPartialReduceMLAAction(Op, MVT::v4i32, MVT::v16i8, Legal); @@ -1120,6 +1129,18 @@ WebAssemblyTargetLowering::getPreferredVectorAction(MVT VT) const { return TargetLoweringBase::getPreferredVectorAction(VT); } +bool WebAssemblyTargetLowering::isFMAFasterThanFMulAndFAdd( + const MachineFunction &MF, EVT VT) const { + if (!Subtarget->hasFP16() || !VT.isVector()) + return false; + + EVT ScalarVT = VT.getScalarType(); + if (!ScalarVT.isSimple()) + return false; + + return ScalarVT.getSimpleVT().SimpleTy == MVT::f16; +} + bool WebAssemblyTargetLowering::shouldSimplifyDemandedVectorElts( SDValue Op, const TargetLoweringOpt &TLO) const { // ISel process runs DAGCombiner after legalization; this step is called diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h index b33a853..472ec67 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h @@ -81,6 +81,8 @@ private: TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT) const override; + bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, + EVT VT) const override; SDValue LowerCall(CallLoweringInfo &CLI, SmallVectorImpl<SDValue> &InVals) const override; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td index 49af78b..0f6e1ca 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -1213,6 +1213,27 @@ defm EXTMUL_LOW_U : defm EXTMUL_HIGH_U : SIMDExtBinary<I64x2, extmul_high_u, "extmul_high_i32x4_u", 0xdf>; +// Pattern for i32x4.dot_i16x8_s +def : Pat< + (v4i32 (add + (wasm_shuffle + (v4i32 (extmul_low_s v8i16:$lhs, v8i16:$rhs)), + (v4i32 (extmul_high_s v8i16:$lhs, v8i16:$rhs)), + (i32 0), (i32 1), (i32 2), (i32 3), + (i32 8), (i32 9), (i32 10), (i32 11), + (i32 16), (i32 17), (i32 18), (i32 19), + (i32 24), (i32 25), (i32 26), (i32 27)), + (wasm_shuffle + (v4i32 (extmul_low_s v8i16:$lhs, v8i16:$rhs)), + (v4i32 (extmul_high_s v8i16:$lhs, v8i16:$rhs)), + (i32 4), (i32 5), (i32 6), (i32 7), + (i32 12), (i32 13), (i32 14), (i32 15), + (i32 20), (i32 21), (i32 22), (i32 23), + (i32 28), (i32 29), (i32 30), (i32 31))) + ), + (v4i32 (DOT v8i16:$lhs, v8i16:$rhs)) +>; + //===----------------------------------------------------------------------===// // Floating-point unary arithmetic //===----------------------------------------------------------------------===// @@ -1626,7 +1647,8 @@ defm "" : RelaxedConvert<I32x4, F64x2, int_wasm_relaxed_trunc_unsigned_zero, // Relaxed (Negative) Multiply-Add (madd/nmadd) //===----------------------------------------------------------------------===// -multiclass SIMDMADD<Vec vec, bits<32> simdopA, bits<32> simdopS, list<Predicate> reqs> { +multiclass RELAXED_SIMDMADD<Vec vec, bits<32> simdopA, bits<32> simdopS, + list<Predicate> reqs> { defm MADD_#vec : SIMD_I<(outs V128:$dst), (ins V128:$a, V128:$b, V128:$c), (outs), (ins), [(set (vec.vt V128:$dst), (int_wasm_relaxed_madd @@ -1640,16 +1662,46 @@ multiclass SIMDMADD<Vec vec, bits<32> simdopA, bits<32> simdopS, list<Predicate> vec.prefix#".relaxed_nmadd\t$dst, $a, $b, $c", vec.prefix#".relaxed_nmadd", simdopS, reqs>; - def : Pat<(fadd_contract (vec.vt V128:$a), (fmul_contract (vec.vt V128:$b), (vec.vt V128:$c))), - (!cast<Instruction>("MADD_"#vec) V128:$a, V128:$b, V128:$c)>, Requires<[HasRelaxedSIMD]>; + def : Pat<(fadd_contract (fmul_contract (vec.vt V128:$a), (vec.vt V128:$b)), (vec.vt V128:$c)), + (!cast<Instruction>("MADD_"#vec) V128:$a, V128:$b, V128:$c)>, Requires<reqs>; + def : Pat<(fmuladd (vec.vt V128:$a), (vec.vt V128:$b), (vec.vt V128:$c)), + (!cast<Instruction>("MADD_"#vec) V128:$a, V128:$b, V128:$c)>, Requires<reqs>; - def : Pat<(fsub_contract (vec.vt V128:$a), (fmul_contract (vec.vt V128:$b), (vec.vt V128:$c))), - (!cast<Instruction>("NMADD_"#vec) V128:$a, V128:$b, V128:$c)>, Requires<[HasRelaxedSIMD]>; + def : Pat<(fsub_contract (vec.vt V128:$c), (fmul_contract (vec.vt V128:$a), (vec.vt V128:$b))), + (!cast<Instruction>("NMADD_"#vec) V128:$a, V128:$b, V128:$c)>, Requires<reqs>; + def : Pat<(fmuladd (fneg (vec.vt V128:$a)), (vec.vt V128:$b), (vec.vt V128:$c)), + (!cast<Instruction>("NMADD_"#vec) V128:$a, V128:$b, V128:$c)>, Requires<reqs>; } -defm "" : SIMDMADD<F32x4, 0x105, 0x106, [HasRelaxedSIMD]>; -defm "" : SIMDMADD<F64x2, 0x107, 0x108, [HasRelaxedSIMD]>; -defm "" : SIMDMADD<F16x8, 0x14e, 0x14f, [HasFP16]>; +defm "" : RELAXED_SIMDMADD<F32x4, 0x105, 0x106, [HasRelaxedSIMD]>; +defm "" : RELAXED_SIMDMADD<F64x2, 0x107, 0x108, [HasRelaxedSIMD]>; + +//===----------------------------------------------------------------------===// +// FP16 (Negative) Multiply-Add (madd/nmadd) +//===----------------------------------------------------------------------===// + +multiclass HALF_PRECISION_SIMDMADD<Vec vec, bits<32> simdopA, bits<32> simdopS, + list<Predicate> reqs> { + defm MADD_#vec : + SIMD_I<(outs V128:$dst), (ins V128:$a, V128:$b, V128:$c), (outs), (ins), + [(set (vec.vt V128:$dst), (fma + (vec.vt V128:$a), (vec.vt V128:$b), (vec.vt V128:$c)))], + vec.prefix#".madd\t$dst, $a, $b, $c", + vec.prefix#".madd", simdopA, reqs>; + defm NMADD_#vec : + SIMD_I<(outs V128:$dst), (ins V128:$a, V128:$b, V128:$c), (outs), (ins), + [(set (vec.vt V128:$dst), (fma + (fneg (vec.vt V128:$a)), (vec.vt V128:$b), (vec.vt V128:$c)))], + vec.prefix#".nmadd\t$dst, $a, $b, $c", + vec.prefix#".nmadd", simdopS, reqs>; +} +defm "" : HALF_PRECISION_SIMDMADD<F16x8, 0x14e, 0x14f, [HasFP16]>; + +// TODO: I think separate intrinsics should be introduced for these FP16 operations. +def : Pat<(v8f16 (int_wasm_relaxed_madd (v8f16 V128:$a), (v8f16 V128:$b), (v8f16 V128:$c))), + (MADD_F16x8 V128:$a, V128:$b, V128:$c)>; +def : Pat<(v8f16 (int_wasm_relaxed_nmadd (v8f16 V128:$a), (v8f16 V128:$b), (v8f16 V128:$c))), + (NMADD_F16x8 V128:$a, V128:$b, V128:$c)>; //===----------------------------------------------------------------------===// // Laneselect diff --git a/llvm/lib/TargetParser/RISCVTargetParser.cpp b/llvm/lib/TargetParser/RISCVTargetParser.cpp index acf8e4c..5ea63a9 100644 --- a/llvm/lib/TargetParser/RISCVTargetParser.cpp +++ b/llvm/lib/TargetParser/RISCVTargetParser.cpp @@ -228,6 +228,10 @@ void printVType(unsigned VType, raw_ostream &OS) { OS << ", mu"; } +void printXSfmmVType(unsigned VType, raw_ostream &OS) { + OS << "e" << getSEW(VType) << ", w" << getXSfmmWiden(VType); +} + unsigned getSEWLMULRatio(unsigned SEW, VLMUL VLMul) { unsigned LMul; bool Fractional; diff --git a/llvm/lib/Transforms/Coroutines/CoroCloner.h b/llvm/lib/Transforms/Coroutines/CoroCloner.h index 26ec4f3..e05fe28 100644 --- a/llvm/lib/Transforms/Coroutines/CoroCloner.h +++ b/llvm/lib/Transforms/Coroutines/CoroCloner.h @@ -1,3 +1,4 @@ +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -19,9 +20,7 @@ #include "llvm/Transforms/Coroutines/CoroInstr.h" #include "llvm/Transforms/Utils/ValueMapper.h" -namespace llvm { - -namespace coro { +namespace llvm::coro { enum class CloneKind { /// The shared resume function for a switch lowering. @@ -149,8 +148,6 @@ public: } }; -} // end namespace coro - -} // end namespace llvm +} // end namespace llvm::coro #endif // LLVM_LIB_TRANSFORMS_COROUTINES_COROCLONER_H diff --git a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp index 471b9eb..cdb5852 100644 --- a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp @@ -38,7 +38,7 @@ public: AnyResumeFnPtrTy(PointerType::getUnqual(Context)) {} void lowerEarlyIntrinsics(Function &F); }; -} +} // namespace // Replace a direct call to coro.resume or coro.destroy with an indirect call to // an address returned by coro.subfn.addr intrinsic. This is done so that diff --git a/llvm/lib/Transforms/Coroutines/CoroInternal.h b/llvm/lib/Transforms/Coroutines/CoroInternal.h index 52f4ffe..cc47a55 100644 --- a/llvm/lib/Transforms/Coroutines/CoroInternal.h +++ b/llvm/lib/Transforms/Coroutines/CoroInternal.h @@ -16,11 +16,7 @@ #include "llvm/Transforms/Coroutines/CoroInstr.h" #include "llvm/Transforms/Coroutines/CoroShape.h" -namespace llvm { - -class CallGraph; - -namespace coro { +namespace llvm::coro { bool isSuspendBlock(BasicBlock *BB); bool declaresAnyIntrinsic(const Module &M); @@ -61,7 +57,6 @@ void normalizeCoroutine(Function &F, coro::Shape &Shape, CallInst *createMustTailCall(DebugLoc Loc, Function *MustTailCallFn, TargetTransformInfo &TTI, ArrayRef<Value *> Arguments, IRBuilder<> &); -} // End namespace coro. -} // End namespace llvm +} // End namespace llvm::coro #endif diff --git a/llvm/lib/Transforms/Coroutines/MaterializationUtils.cpp b/llvm/lib/Transforms/Coroutines/MaterializationUtils.cpp index 6aaabca..f2444da 100644 --- a/llvm/lib/Transforms/Coroutines/MaterializationUtils.cpp +++ b/llvm/lib/Transforms/Coroutines/MaterializationUtils.cpp @@ -137,8 +137,7 @@ struct RematGraph { } // namespace -namespace llvm { -template <> struct GraphTraits<RematGraph *> { +template <> struct llvm::GraphTraits<RematGraph *> { using NodeRef = RematGraph::RematNode *; using ChildIteratorType = RematGraph::RematNode **; @@ -149,8 +148,6 @@ template <> struct GraphTraits<RematGraph *> { static ChildIteratorType child_end(NodeRef N) { return N->Operands.end(); } }; -} // end namespace llvm - // For each instruction identified as materializable across the suspend point, // and its associated DAG of other rematerializable instructions, // recreate the DAG of instructions after the suspend point. diff --git a/llvm/lib/Transforms/Coroutines/SpillUtils.cpp b/llvm/lib/Transforms/Coroutines/SpillUtils.cpp index e474c07..81fe0c9 100644 --- a/llvm/lib/Transforms/Coroutines/SpillUtils.cpp +++ b/llvm/lib/Transforms/Coroutines/SpillUtils.cpp @@ -16,11 +16,8 @@ #include "llvm/IR/InstIterator.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" -namespace llvm { - -namespace coro { - -namespace { +using namespace llvm; +using namespace llvm::coro; typedef SmallPtrSet<BasicBlock *, 8> VisitedBlocksSet; @@ -71,7 +68,7 @@ static bool isLocalAlloca(CoroAllocaAllocInst *AI) { /// This happens during the all-instructions iteration, so it must not /// delete the call. static Instruction * -lowerNonLocalAlloca(CoroAllocaAllocInst *AI, const coro::Shape &Shape, +lowerNonLocalAlloca(CoroAllocaAllocInst *AI, const Shape &Shape, SmallVectorImpl<Instruction *> &DeadInsts) { IRBuilder<> Builder(AI); auto Alloc = Shape.emitAlloc(Builder, AI->getSize(), nullptr); @@ -450,10 +447,8 @@ static void collectFrameAlloca(AllocaInst *AI, const coro::Shape &Shape, Visitor.getMayWriteBeforeCoroBegin()); } -} // namespace - -void collectSpillsFromArgs(SpillInfo &Spills, Function &F, - const SuspendCrossingInfo &Checker) { +void coro::collectSpillsFromArgs(SpillInfo &Spills, Function &F, + const SuspendCrossingInfo &Checker) { // Collect the spills for arguments and other not-materializable values. for (Argument &A : F.args()) for (User *U : A.users()) @@ -461,7 +456,7 @@ void collectSpillsFromArgs(SpillInfo &Spills, Function &F, Spills[&A].push_back(cast<Instruction>(U)); } -void collectSpillsAndAllocasFromInsts( +void coro::collectSpillsAndAllocasFromInsts( SpillInfo &Spills, SmallVector<AllocaInfo, 8> &Allocas, SmallVector<Instruction *, 4> &DeadInstructions, SmallVector<CoroAllocaAllocInst *, 4> &LocalAllocas, Function &F, @@ -516,8 +511,8 @@ void collectSpillsAndAllocasFromInsts( } } -void collectSpillsFromDbgInfo(SpillInfo &Spills, Function &F, - const SuspendCrossingInfo &Checker) { +void coro::collectSpillsFromDbgInfo(SpillInfo &Spills, Function &F, + const SuspendCrossingInfo &Checker) { // We don't want the layout of coroutine frame to be affected // by debug information. So we only choose to salvage dbg.values for // whose value is already in the frame. @@ -535,10 +530,9 @@ void collectSpillsFromDbgInfo(SpillInfo &Spills, Function &F, /// Async and Retcon{Once} conventions assume that all spill uses can be sunk /// after the coro.begin intrinsic. -void sinkSpillUsesAfterCoroBegin(const DominatorTree &Dom, - CoroBeginInst *CoroBegin, - coro::SpillInfo &Spills, - SmallVectorImpl<coro::AllocaInfo> &Allocas) { +void coro::sinkSpillUsesAfterCoroBegin( + const DominatorTree &Dom, CoroBeginInst *CoroBegin, coro::SpillInfo &Spills, + SmallVectorImpl<coro::AllocaInfo> &Allocas) { SmallSetVector<Instruction *, 32> ToMove; SmallVector<Instruction *, 32> Worklist; @@ -582,8 +576,9 @@ void sinkSpillUsesAfterCoroBegin(const DominatorTree &Dom, Inst->moveBefore(InsertPt->getIterator()); } -BasicBlock::iterator getSpillInsertionPt(const coro::Shape &Shape, Value *Def, - const DominatorTree &DT) { +BasicBlock::iterator coro::getSpillInsertionPt(const coro::Shape &Shape, + Value *Def, + const DominatorTree &DT) { BasicBlock::iterator InsertPt; if (auto *Arg = dyn_cast<Argument>(Def)) { // For arguments, we will place the store instruction right after @@ -625,7 +620,3 @@ BasicBlock::iterator getSpillInsertionPt(const coro::Shape &Shape, Value *Def, return InsertPt; } - -} // End namespace coro. - -} // End namespace llvm. diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h index 7071876..943c223 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h @@ -471,7 +471,6 @@ private: Value *simplifyNonNullOperand(Value *V, bool HasDereferenceable, unsigned Depth = 0); -public: /// Create `select C, S1, S2`. Use only when the profile cannot be calculated /// from existing profile metadata: if the Function has profiles, this will /// set the profile of this select to "unknown". @@ -484,6 +483,7 @@ public: return Sel; } +public: /// Create and insert the idiom we use to indicate a block is unreachable /// without having to rewrite the CFG from within InstCombine. void CreateNonTerminatorUnreachable(Instruction *InsertAt) { diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 63e24a0..a330bb7 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -110,8 +110,8 @@ static Value *simplifyShiftSelectingPackedElement(Instruction *I, ShrAmt->getName() + ".z"); // There is no existing !prof metadata we can derive the !prof metadata for // this select. - Value *Select = IC.createSelectInstWithUnknownProfile(ShrAmtZ, Lower, Upper); - IC.Builder.Insert(Select); + Value *Select = IC.Builder.CreateSelectWithUnknownProfile(ShrAmtZ, Lower, + Upper, DEBUG_TYPE); Select->takeName(I); return Select; } diff --git a/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp b/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp index c86092b..a6ec6c1 100644 --- a/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp @@ -17,6 +17,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Analysis/MemoryProfileInfo.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" +#include "llvm/Analysis/StaticDataProfileInfo.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Function.h" @@ -194,6 +195,30 @@ static bool isAllocationWithHotColdVariant(const Function *Callee, } } +static void HandleUnsupportedAnnotationKinds(GlobalVariable &GVar, + AnnotationKind Kind) { + assert(Kind != llvm::memprof::AnnotationKind::AnnotationOK && + "Should not handle AnnotationOK here"); + SmallString<32> Reason; + switch (Kind) { + case llvm::memprof::AnnotationKind::ExplicitSection: + ++NumOfMemProfExplicitSectionGlobalVars; + Reason.append("explicit section name"); + break; + case llvm::memprof::AnnotationKind::DeclForLinker: + Reason.append("linker declaration"); + break; + case llvm::memprof::AnnotationKind::ReservedName: + Reason.append("name starts with `llvm.`"); + break; + default: + llvm_unreachable("Unexpected annotation kind"); + } + LLVM_DEBUG(dbgs() << "Skip annotation for " << GVar.getName() << " due to " + << Reason << ".\n"); + return; +} + struct AllocMatchInfo { uint64_t TotalSize = 0; AllocationType AllocType = AllocationType::None; @@ -775,29 +800,13 @@ PreservedAnalyses MemProfUsePass::run(Module &M, ModuleAnalysisManager &AM) { return PreservedAnalyses::none(); } -// Returns true iff the global variable has custom section either by -// __attribute__((section("name"))) -// (https://clang.llvm.org/docs/AttributeReference.html#section-declspec-allocate) -// or #pragma clang section directives -// (https://clang.llvm.org/docs/LanguageExtensions.html#specifying-section-names-for-global-objects-pragma-clang-section). -static bool hasExplicitSectionName(const GlobalVariable &GVar) { - if (GVar.hasSection()) - return true; - - auto Attrs = GVar.getAttributes(); - if (Attrs.hasAttribute("bss-section") || Attrs.hasAttribute("data-section") || - Attrs.hasAttribute("relro-section") || - Attrs.hasAttribute("rodata-section")) - return true; - return false; -} - bool MemProfUsePass::annotateGlobalVariables( Module &M, const memprof::DataAccessProfData *DataAccessProf) { if (!AnnotateStaticDataSectionPrefix || M.globals().empty()) return false; if (!DataAccessProf) { + M.addModuleFlag(Module::Warning, "EnableDataAccessProf", 0U); M.getContext().diagnose(DiagnosticInfoPGOProfile( MemoryProfileFileName.data(), StringRef("Data access profiles not found in memprof. Ignore " @@ -805,6 +814,7 @@ bool MemProfUsePass::annotateGlobalVariables( DS_Warning)); return false; } + M.addModuleFlag(Module::Warning, "EnableDataAccessProf", 1U); bool Changed = false; // Iterate all global variables in the module and annotate them based on @@ -815,13 +825,9 @@ bool MemProfUsePass::annotateGlobalVariables( for (GlobalVariable &GVar : M.globals()) { assert(!GVar.getSectionPrefix().has_value() && "GVar shouldn't have section prefix yet"); - if (GVar.isDeclarationForLinker()) - continue; - - if (hasExplicitSectionName(GVar)) { - ++NumOfMemProfExplicitSectionGlobalVars; - LLVM_DEBUG(dbgs() << "Global variable " << GVar.getName() - << " has explicit section name. Skip annotating.\n"); + auto Kind = llvm::memprof::getAnnotationKind(GVar); + if (Kind != llvm::memprof::AnnotationKind::AnnotationOK) { + HandleUnsupportedAnnotationKinds(GVar, Kind); continue; } @@ -831,7 +837,6 @@ bool MemProfUsePass::annotateGlobalVariables( // TODO: Track string content hash in the profiles and compute it inside the // compiler to categeorize the hotness string literals. if (Name.starts_with(".str")) { - LLVM_DEBUG(dbgs() << "Skip annotating string literal " << Name << "\n"); continue; } diff --git a/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp b/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp index ccb86eb..fb39fdd 100644 --- a/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp +++ b/llvm/lib/Transforms/Utils/SSAUpdaterBulk.cpp @@ -269,8 +269,7 @@ static bool replaceIfIdentical(PHINode &PHI, PHINode &ReplPHI) { bool EliminateNewDuplicatePHINodes(BasicBlock *BB, BasicBlock::phi_iterator FirstExistingPN) { - auto NewPHIs = make_range(BB->phis().begin(), FirstExistingPN); - assert(!PHIAreRefEachOther(NewPHIs)); + assert(!PHIAreRefEachOther(make_range(BB->phis().begin(), FirstExistingPN))); // Deduplicate new PHIs first to reduce the number of comparisons on the // following new -> existing pass. diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index f95d288..88af2cf 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -19460,7 +19460,8 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) { } assert(getNumElements(Cond->getType()) == TrueNumElements && "Cannot vectorize Instruction::Select"); - Value *V = Builder.CreateSelect(Cond, True, False); + Value *V = + Builder.CreateSelectWithUnknownProfile(Cond, True, False, DEBUG_TYPE); V = FinalShuffle(V, E); E->VectorizedValue = V; @@ -23580,18 +23581,19 @@ class HorizontalReduction { switch (Kind) { case RecurKind::Or: { if (UseSelect && OpTy == CmpInst::makeCmpResultType(OpTy)) - return Builder.CreateSelect( + return Builder.CreateSelectWithUnknownProfile( LHS, ConstantInt::getAllOnesValue(CmpInst::makeCmpResultType(OpTy)), - RHS, Name); + RHS, DEBUG_TYPE, Name); unsigned RdxOpcode = RecurrenceDescriptor::getOpcode(Kind); return Builder.CreateBinOp((Instruction::BinaryOps)RdxOpcode, LHS, RHS, Name); } case RecurKind::And: { if (UseSelect && OpTy == CmpInst::makeCmpResultType(OpTy)) - return Builder.CreateSelect( + return Builder.CreateSelectWithUnknownProfile( LHS, RHS, - ConstantInt::getNullValue(CmpInst::makeCmpResultType(OpTy)), Name); + ConstantInt::getNullValue(CmpInst::makeCmpResultType(OpTy)), + DEBUG_TYPE, Name); unsigned RdxOpcode = RecurrenceDescriptor::getOpcode(Kind); return Builder.CreateBinOp((Instruction::BinaryOps)RdxOpcode, LHS, RHS, Name); @@ -23612,7 +23614,8 @@ class HorizontalReduction { if (UseSelect) { CmpInst::Predicate Pred = llvm::getMinMaxReductionPredicate(Kind); Value *Cmp = Builder.CreateICmp(Pred, LHS, RHS, Name); - return Builder.CreateSelect(Cmp, LHS, RHS, Name); + return Builder.CreateSelectWithUnknownProfile(Cmp, LHS, RHS, DEBUG_TYPE, + Name); } [[fallthrough]]; case RecurKind::FMax: diff --git a/llvm/lib/XRay/BlockIndexer.cpp b/llvm/lib/XRay/BlockIndexer.cpp index f4ba0eb..d0c6853 100644 --- a/llvm/lib/XRay/BlockIndexer.cpp +++ b/llvm/lib/XRay/BlockIndexer.cpp @@ -12,8 +12,8 @@ //===----------------------------------------------------------------------===// #include "llvm/XRay/BlockIndexer.h" -namespace llvm { -namespace xray { +using namespace llvm; +using namespace llvm::xray; Error BlockIndexer::visit(BufferExtents &) { return Error::success(); } @@ -89,6 +89,3 @@ Error BlockIndexer::flush() { CurrentBlock.WallclockTime = nullptr; return Error::success(); } - -} // namespace xray -} // namespace llvm diff --git a/llvm/lib/XRay/BlockPrinter.cpp b/llvm/lib/XRay/BlockPrinter.cpp index 63a60c3..d85be5b 100644 --- a/llvm/lib/XRay/BlockPrinter.cpp +++ b/llvm/lib/XRay/BlockPrinter.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #include "llvm/XRay/BlockPrinter.h" -namespace llvm { -namespace xray { +using namespace llvm; +using namespace llvm::xray; Error BlockPrinter::visit(BufferExtents &R) { OS << "\n[New Block]\n"; @@ -108,6 +108,3 @@ Error BlockPrinter::visit(EndBufferRecord &R) { auto E = RP.visit(R); return E; } - -} // namespace xray -} // namespace llvm diff --git a/llvm/lib/XRay/BlockVerifier.cpp b/llvm/lib/XRay/BlockVerifier.cpp index 99f255e..e39f6b6 100644 --- a/llvm/lib/XRay/BlockVerifier.cpp +++ b/llvm/lib/XRay/BlockVerifier.cpp @@ -10,19 +10,18 @@ #include <bitset> -namespace llvm { -namespace xray { -namespace { +using namespace llvm; +using namespace llvm::xray; -constexpr unsigned long long mask(BlockVerifier::State S) { +static constexpr unsigned long long mask(BlockVerifier::State S) { return 1uLL << static_cast<std::size_t>(S); } -constexpr std::size_t number(BlockVerifier::State S) { +static constexpr std::size_t number(BlockVerifier::State S) { return static_cast<std::size_t>(S); } -StringRef recordToString(BlockVerifier::State R) { +static StringRef recordToString(BlockVerifier::State R) { switch (R) { case BlockVerifier::State::BufferExtents: return "BufferExtents"; @@ -53,6 +52,8 @@ StringRef recordToString(BlockVerifier::State R) { llvm_unreachable("Unkown state!"); } +namespace { + struct Transition { BlockVerifier::State From; std::bitset<number(BlockVerifier::State::StateMax)> ToStates; @@ -133,7 +134,7 @@ Error BlockVerifier::transition(State To) { CurrentRecord = To; return Error::success(); -} // namespace xray +} Error BlockVerifier::visit(BufferExtents &) { return transition(State::BufferExtents); @@ -201,6 +202,3 @@ Error BlockVerifier::verify() { } void BlockVerifier::reset() { CurrentRecord = State::Unknown; } - -} // namespace xray -} // namespace llvm diff --git a/llvm/lib/XRay/FDRRecordProducer.cpp b/llvm/lib/XRay/FDRRecordProducer.cpp index 479b710..0f4eed1 100644 --- a/llvm/lib/XRay/FDRRecordProducer.cpp +++ b/llvm/lib/XRay/FDRRecordProducer.cpp @@ -10,8 +10,8 @@ #include <cstdint> -namespace llvm { -namespace xray { +using namespace llvm; +using namespace llvm::xray; namespace { @@ -31,8 +31,9 @@ enum MetadataRecordKinds : uint8_t { // This is an end marker, used to identify the upper bound for this enum. EnumEndMarker, }; +} // namespace -Expected<std::unique_ptr<Record>> +static Expected<std::unique_ptr<Record>> metadataRecordType(const XRayFileHeader &Header, uint8_t T) { if (T >= static_cast<uint8_t>(MetadataRecordKinds::EnumEndMarker)) @@ -72,12 +73,10 @@ metadataRecordType(const XRayFileHeader &Header, uint8_t T) { llvm_unreachable("Unhandled MetadataRecordKinds enum value"); } -constexpr bool isMetadataIntroducer(uint8_t FirstByte) { +static constexpr bool isMetadataIntroducer(uint8_t FirstByte) { return FirstByte & 0x01u; } -} // namespace - Expected<std::unique_ptr<Record>> FileBasedRecordProducer::findNextBufferExtent() { // We seek one byte at a time until we find a suitable buffer extents metadata @@ -193,6 +192,3 @@ Expected<std::unique_ptr<Record>> FileBasedRecordProducer::produce() { assert(R != nullptr); return std::move(R); } - -} // namespace xray -} // namespace llvm diff --git a/llvm/lib/XRay/FDRRecords.cpp b/llvm/lib/XRay/FDRRecords.cpp index ff315d3..a18f733 100644 --- a/llvm/lib/XRay/FDRRecords.cpp +++ b/llvm/lib/XRay/FDRRecords.cpp @@ -12,8 +12,8 @@ //===----------------------------------------------------------------------===// #include "llvm/XRay/FDRRecords.h" -namespace llvm { -namespace xray { +using namespace llvm; +using namespace llvm::xray; Error BufferExtents::apply(RecordVisitor &V) { return V.visit(*this); } Error WallclockRecord::apply(RecordVisitor &V) { return V.visit(*this); } @@ -61,6 +61,3 @@ StringRef Record::kindToString(RecordKind K) { } return "Unknown"; } - -} // namespace xray -} // namespace llvm diff --git a/llvm/lib/XRay/FDRTraceExpander.cpp b/llvm/lib/XRay/FDRTraceExpander.cpp index b68e997..991e6e5 100644 --- a/llvm/lib/XRay/FDRTraceExpander.cpp +++ b/llvm/lib/XRay/FDRTraceExpander.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #include "llvm/XRay/FDRTraceExpander.h" -namespace llvm { -namespace xray { +using namespace llvm; +using namespace llvm::xray; void TraceExpander::resetCurrentRecord() { if (BuildingRecord) @@ -126,6 +126,3 @@ Error TraceExpander::flush() { resetCurrentRecord(); return Error::success(); } - -} // namespace xray -} // namespace llvm diff --git a/llvm/lib/XRay/FDRTraceWriter.cpp b/llvm/lib/XRay/FDRTraceWriter.cpp index fb59125..3e320a6 100644 --- a/llvm/lib/XRay/FDRTraceWriter.cpp +++ b/llvm/lib/XRay/FDRTraceWriter.cpp @@ -12,8 +12,8 @@ #include "llvm/XRay/FDRTraceWriter.h" #include <tuple> -namespace llvm { -namespace xray { +using namespace llvm; +using namespace llvm::xray; namespace { @@ -37,9 +37,10 @@ template <size_t Index> struct IndexedWriter { return 0; } }; +} // namespace template <uint8_t Kind, class... Values> -Error writeMetadata(support::endian::Writer &OS, Values &&... Ds) { +static Error writeMetadata(support::endian::Writer &OS, Values &&...Ds) { // The first bit in the first byte of metadata records is always set to 1, so // we ensure this is the case when we write out the first byte of the record. uint8_t FirstByte = (static_cast<uint8_t>(Kind) << 1) | uint8_t{0x01u}; @@ -54,8 +55,6 @@ Error writeMetadata(support::endian::Writer &OS, Values &&... Ds) { return Error::success(); } -} // namespace - FDRTraceWriter::FDRTraceWriter(raw_ostream &O, const XRayFileHeader &H) : OS(O, llvm::endianness::native) { // We need to re-construct a header, by writing the fields we care about for @@ -146,6 +145,3 @@ Error FDRTraceWriter::visit(FunctionRecord &R) { OS.write(R.delta()); return Error::success(); } - -} // namespace xray -} // namespace llvm diff --git a/llvm/lib/XRay/FileHeaderReader.cpp b/llvm/lib/XRay/FileHeaderReader.cpp index 6b6daf9..681cef7 100644 --- a/llvm/lib/XRay/FileHeaderReader.cpp +++ b/llvm/lib/XRay/FileHeaderReader.cpp @@ -7,12 +7,13 @@ //===----------------------------------------------------------------------===// #include "llvm/XRay/FileHeaderReader.h" -namespace llvm { -namespace xray { +using namespace llvm; +using namespace llvm::xray; // Populates the FileHeader reference by reading the first 32 bytes of the file. -Expected<XRayFileHeader> readBinaryFormatHeader(DataExtractor &HeaderExtractor, - uint64_t &OffsetPtr) { +Expected<XRayFileHeader> +xray::readBinaryFormatHeader(DataExtractor &HeaderExtractor, + uint64_t &OffsetPtr) { // FIXME: Maybe deduce whether the data is little or big-endian using some // magic bytes in the beginning of the file? @@ -68,6 +69,3 @@ Expected<XRayFileHeader> readBinaryFormatHeader(DataExtractor &HeaderExtractor, OffsetPtr += 16; return std::move(FileHeader); } - -} // namespace xray -} // namespace llvm diff --git a/llvm/lib/XRay/LogBuilderConsumer.cpp b/llvm/lib/XRay/LogBuilderConsumer.cpp index ffb49f9..f0fc336 100644 --- a/llvm/lib/XRay/LogBuilderConsumer.cpp +++ b/llvm/lib/XRay/LogBuilderConsumer.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #include "llvm/XRay/FDRRecordConsumer.h" -namespace llvm { -namespace xray { +using namespace llvm; +using namespace llvm::xray; Error LogBuilderConsumer::consume(std::unique_ptr<Record> R) { if (!R) @@ -32,6 +32,3 @@ Error PipelineConsumer::consume(std::unique_ptr<Record> R) { Result = joinErrors(std::move(Result), R->apply(*V)); return Result; } - -} // namespace xray -} // namespace llvm diff --git a/llvm/lib/XRay/Profile.cpp b/llvm/lib/XRay/Profile.cpp index 1b340e5..ecb767b 100644 --- a/llvm/lib/XRay/Profile.cpp +++ b/llvm/lib/XRay/Profile.cpp @@ -18,8 +18,8 @@ #include "llvm/XRay/Trace.h" #include <memory> -namespace llvm { -namespace xray { +using namespace llvm; +using namespace llvm::xray; Profile::Profile(const Profile &O) { // We need to re-create all the tries from the original (O), into the current @@ -46,6 +46,7 @@ struct BlockHeader { uint32_t Number; uint64_t Thread; }; +} // namespace static Expected<BlockHeader> readBlockHeader(DataExtractor &Extractor, uint64_t &Offset) { @@ -115,8 +116,6 @@ static Expected<Profile::Data> readData(DataExtractor &Extractor, return D; } -} // namespace - Error Profile::addBlock(Block &&B) { if (B.PathData.empty()) return make_error<StringError>( @@ -189,7 +188,7 @@ Profile::PathID Profile::internPath(ArrayRef<FuncID> P) { return Node->ID; } -Profile mergeProfilesByThread(const Profile &L, const Profile &R) { +Profile xray::mergeProfilesByThread(const Profile &L, const Profile &R) { Profile Merged; using PathDataMap = DenseMap<Profile::PathID, Profile::Data>; using PathDataMapPtr = std::unique_ptr<PathDataMap>; @@ -228,7 +227,7 @@ Profile mergeProfilesByThread(const Profile &L, const Profile &R) { return Merged; } -Profile mergeProfilesByStack(const Profile &L, const Profile &R) { +Profile xray::mergeProfilesByStack(const Profile &L, const Profile &R) { Profile Merged; using PathDataMap = DenseMap<Profile::PathID, Profile::Data>; PathDataMap PathData; @@ -258,7 +257,7 @@ Profile mergeProfilesByStack(const Profile &L, const Profile &R) { return Merged; } -Expected<Profile> loadProfile(StringRef Filename) { +Expected<Profile> xray::loadProfile(StringRef Filename) { Expected<sys::fs::file_t> FdOrErr = sys::fs::openNativeFileForRead(Filename); if (!FdOrErr) return FdOrErr.takeError(); @@ -322,7 +321,7 @@ struct StackEntry { } // namespace -Expected<Profile> profileFromTrace(const Trace &T) { +Expected<Profile> xray::profileFromTrace(const Trace &T) { Profile P; // The implementation of the algorithm re-creates the execution of @@ -397,6 +396,3 @@ Expected<Profile> profileFromTrace(const Trace &T) { return P; } - -} // namespace xray -} // namespace llvm diff --git a/llvm/lib/XRay/RecordInitializer.cpp b/llvm/lib/XRay/RecordInitializer.cpp index 68ab3db..83d5f14 100644 --- a/llvm/lib/XRay/RecordInitializer.cpp +++ b/llvm/lib/XRay/RecordInitializer.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #include "llvm/XRay/FDRRecords.h" -namespace llvm { -namespace xray { +using namespace llvm; +using namespace llvm::xray; Error RecordInitializer::visit(BufferExtents &R) { if (!E.isValidOffsetForDataOfSize(OffsetPtr, sizeof(uint64_t))) @@ -426,6 +426,3 @@ Error RecordInitializer::visit(FunctionRecord &R) { assert(FunctionRecord::kFunctionRecordSize == (OffsetPtr - BeginOffset)); return Error::success(); } - -} // namespace xray -} // namespace llvm diff --git a/llvm/lib/XRay/RecordPrinter.cpp b/llvm/lib/XRay/RecordPrinter.cpp index 32d4210..b9b7a16 100644 --- a/llvm/lib/XRay/RecordPrinter.cpp +++ b/llvm/lib/XRay/RecordPrinter.cpp @@ -9,8 +9,8 @@ #include "llvm/Support/FormatVariadic.h" -namespace llvm { -namespace xray { +using namespace llvm; +using namespace llvm::xray; Error RecordPrinter::visit(BufferExtents &R) { OS << formatv("<Buffer: size = {0} bytes>", R.size()) << Delim; @@ -103,6 +103,3 @@ Error RecordPrinter::visit(FunctionRecord &R) { OS << Delim; return Error::success(); } - -} // namespace xray -} // namespace llvm diff --git a/llvm/lib/XRay/Trace.cpp b/llvm/lib/XRay/Trace.cpp index 74515b1..14a3f01 100644 --- a/llvm/lib/XRay/Trace.cpp +++ b/llvm/lib/XRay/Trace.cpp @@ -29,11 +29,9 @@ using namespace llvm; using namespace llvm::xray; using llvm::yaml::Input; -namespace { - -Error loadNaiveFormatLog(StringRef Data, bool IsLittleEndian, - XRayFileHeader &FileHeader, - std::vector<XRayRecord> &Records) { +static Error loadNaiveFormatLog(StringRef Data, bool IsLittleEndian, + XRayFileHeader &FileHeader, + std::vector<XRayRecord> &Records) { if (Data.size() < 32) return make_error<StringError>( "Not enough bytes for an XRay log.", @@ -265,8 +263,9 @@ Error loadNaiveFormatLog(StringRef Data, bool IsLittleEndian, /// what FunctionRecord instances use, and we no longer need to include the CPU /// id in the CustomEventRecord. /// -Error loadFDRLog(StringRef Data, bool IsLittleEndian, - XRayFileHeader &FileHeader, std::vector<XRayRecord> &Records) { +static Error loadFDRLog(StringRef Data, bool IsLittleEndian, + XRayFileHeader &FileHeader, + std::vector<XRayRecord> &Records) { if (Data.size() < 32) return createStringError(std::make_error_code(std::errc::invalid_argument), @@ -348,8 +347,8 @@ Error loadFDRLog(StringRef Data, bool IsLittleEndian, return Error::success(); } -Error loadYAMLLog(StringRef Data, XRayFileHeader &FileHeader, - std::vector<XRayRecord> &Records) { +static Error loadYAMLLog(StringRef Data, XRayFileHeader &FileHeader, + std::vector<XRayRecord> &Records) { YAMLXRayTrace Trace; Input In(Data); In >> Trace; @@ -376,7 +375,6 @@ Error loadYAMLLog(StringRef Data, XRayFileHeader &FileHeader, }); return Error::success(); } -} // namespace Expected<Trace> llvm::xray::loadTraceFile(StringRef Filename, bool Sort) { Expected<sys::fs::file_t> FdOrErr = sys::fs::openNativeFileForRead(Filename); diff --git a/llvm/test/CodeGen/AMDGPU/sched.group.classification.mir b/llvm/test/CodeGen/AMDGPU/sched.group.classification.mir new file mode 100644 index 0000000..a4aad57 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/sched.group.classification.mir @@ -0,0 +1,59 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx950 -run-pass=machine-scheduler -o - %s | FileCheck %s + +--- +name: buffer_load_lds_not_valu +tracksRegLiveness: true +body: | + bb.0: + liveins: $vgpr0_vgpr1 + ; CHECK-LABEL: name: buffer_load_lds_not_valu + ; CHECK: liveins: $vgpr0_vgpr1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: $exec = IMPLICIT_DEF + ; CHECK-NEXT: [[DEF:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF + ; CHECK-NEXT: [[DEF1:%[0-9]+]]:sgpr_128 = IMPLICIT_DEF + ; CHECK-NEXT: [[DEF2:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF + ; CHECK-NEXT: [[DEF3:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF + ; CHECK-NEXT: [[V_ADD_U32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 [[DEF2]], [[DEF3]], implicit $exec + ; CHECK-NEXT: [[V_ADD_U32_e32_1:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 [[DEF3]], [[V_ADD_U32_e32_]], implicit $exec + ; CHECK-NEXT: $m0 = S_MOV_B32 0 + ; CHECK-NEXT: BUFFER_LOAD_DWORDX4_LDS_OFFEN [[DEF]], [[DEF1]], 0, 0, 0, 0, implicit $exec, implicit $m0 + ; CHECK-NEXT: [[V_ADD_U32_e32_2:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 [[V_ADD_U32_e32_]], [[V_ADD_U32_e32_1]], implicit $exec + ; CHECK-NEXT: [[V_ADD_U32_e32_3:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 [[V_ADD_U32_e32_1]], [[V_ADD_U32_e32_2]], implicit $exec + ; CHECK-NEXT: $m0 = S_MOV_B32 1 + ; CHECK-NEXT: BUFFER_LOAD_DWORDX4_LDS_OFFEN [[DEF]], [[DEF1]], 0, 0, 0, 0, implicit $exec, implicit $m0 + ; CHECK-NEXT: [[V_ADD_U32_e32_4:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 [[V_ADD_U32_e32_2]], [[V_ADD_U32_e32_3]], implicit $exec + ; CHECK-NEXT: [[V_ADD_U32_e32_5:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 [[V_ADD_U32_e32_3]], [[V_ADD_U32_e32_4]], implicit $exec + ; CHECK-NEXT: [[V_ADD_U32_e32_6:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 [[V_ADD_U32_e32_4]], [[V_ADD_U32_e32_5]], implicit $exec + ; CHECK-NEXT: dead [[V_ADD_U32_e32_7:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 [[V_ADD_U32_e32_5]], [[V_ADD_U32_e32_6]], implicit $exec + ; CHECK-NEXT: SCHED_GROUP_BARRIER 2, 2, 0 + ; CHECK-NEXT: SCHED_GROUP_BARRIER 4, 1, 0 + ; CHECK-NEXT: SCHED_GROUP_BARRIER 2, 2, 0 + ; CHECK-NEXT: SCHED_GROUP_BARRIER 4, 1, 0 + ; CHECK-NEXT: SCHED_GROUP_BARRIER 2, 4, 0 + ; CHECK-NEXT: S_ENDPGM 0 + $exec = IMPLICIT_DEF + %0:vgpr_32 = IMPLICIT_DEF + %1:sgpr_128 = IMPLICIT_DEF + %2:vgpr_32 = IMPLICIT_DEF + %3:vgpr_32 = IMPLICIT_DEF + %4:vgpr_32 = V_ADD_U32_e32 %2, %3, implicit $exec + %5:vgpr_32 = V_ADD_U32_e32 %3, %4, implicit $exec + $m0 = S_MOV_B32 0 + BUFFER_LOAD_DWORDX4_LDS_OFFEN %0, %1, 0, 0, 0, 0, implicit $exec, implicit $m0 + $m0 = S_MOV_B32 1 + BUFFER_LOAD_DWORDX4_LDS_OFFEN %0, %1, 0, 0, 0, 0, implicit $exec, implicit $m0 + %6:vgpr_32 = V_ADD_U32_e32 %4, %5, implicit $exec + %7:vgpr_32 = V_ADD_U32_e32 %5, %6, implicit $exec + %8:vgpr_32 = V_ADD_U32_e32 %6, %7, implicit $exec + %9:vgpr_32 = V_ADD_U32_e32 %7, %8, implicit $exec + %10:vgpr_32 = V_ADD_U32_e32 %8, %9, implicit $exec + %11:vgpr_32 = V_ADD_U32_e32 %9, %10, implicit $exec + SCHED_GROUP_BARRIER 2, 2, 0 + SCHED_GROUP_BARRIER 4, 1 ,0 + SCHED_GROUP_BARRIER 2, 2, 0 + SCHED_GROUP_BARRIER 4, 1 ,0 + SCHED_GROUP_BARRIER 2, 4, 0 + S_ENDPGM 0 +... diff --git a/llvm/test/CodeGen/RISCV/rvv/sifive-xsfmm-vset-insert.mir b/llvm/test/CodeGen/RISCV/rvv/sifive-xsfmm-vset-insert.mir new file mode 100644 index 0000000..389283a --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/sifive-xsfmm-vset-insert.mir @@ -0,0 +1,523 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc %s -o - -mtriple=riscv64 -mattr=+v \ +# RUN: -run-pass=phi-node-elimination,register-coalescer,riscv-insert-vsetvli | FileCheck %s + +--- | + define void @xsfmm_same_state(<vscale x 32 x half> %tile1, <vscale x 32 x half> %tile2, i64 noundef %tm, i64 noundef %tn, i64 noundef %tk) { + entry: + tail call void @llvm.riscv.sf.mm.f.f.i64.nxv32f16(i64 2, <vscale x 32 x half> %tile1, <vscale x 32 x half> %tile2, i64 %tm, i64 %tn, i64 %tk, i64 2) + tail call void @llvm.riscv.sf.mm.f.f.i64.nxv32f16(i64 2, <vscale x 32 x half> %tile1, <vscale x 32 x half> %tile2, i64 %tm, i64 %tn, i64 %tk, i64 2) + ret void + } + + define void @xsfmm_different_state(<vscale x 32 x half> %tile1, <vscale x 32 x half> %tile2, i64 %tm, i64 %tn, i64 %tk) { + entry: + tail call void @llvm.riscv.sf.mm.f.f.i64.nxv32f16(i64 2, <vscale x 32 x half> %tile1, <vscale x 32 x half> %tile2, i64 %tm, i64 %tn, i64 %tk, i64 2) + tail call void @llvm.riscv.sf.mm.f.f.i64.nxv32f16(i64 2, <vscale x 32 x half> %tile1, <vscale x 32 x half> %tile2, i64 %tm, i64 %tn, i64 %tk, i64 4) + ret void + } + + define void @xsfmm_different_state_bf(<vscale x 32 x half> %tile1, <vscale x 32 x bfloat> %tile2, i64 %tm, i64 %tn, i64 %tk) { + entry: + tail call void @llvm.riscv.sf.mm.f.f.i64.nxv32f16(i64 2, <vscale x 32 x half> %tile1, <vscale x 32 x half> %tile1, i64 %tm, i64 %tn, i64 %tk, i64 2) + tail call void @llvm.riscv.sf.mm.f.f.i64.nxv32bf16(i64 2, <vscale x 32 x bfloat> %tile2, <vscale x 32 x bfloat> %tile2, i64 %tm, i64 %tn, i64 %tk, i64 2) + tail call void @llvm.riscv.sf.mm.f.f.i64.nxv32f16(i64 2, <vscale x 32 x half> %tile1, <vscale x 32 x half> %tile1, i64 %tm, i64 %tn, i64 %tk, i64 2) + ret void + } + + define <vscale x 64 x i8> @interleave_rvv_and_xsfmm(<vscale x 64 x i8> %tile, i64 %vl, ptr %base) { + entry: + %0 = call <vscale x 64 x i8> @llvm.riscv.sf.vtmv.v.t.nxv64i8.i64(i64 1, i64 %vl) + %1 = call <vscale x 64 x i8> @llvm.riscv.vadd.nxv64i8.nxv64i8.i64(<vscale x 64 x i8> poison, <vscale x 64 x i8> %tile, <vscale x 64 x i8> %0, i64 %vl) + call void @llvm.riscv.sf.vste16.i64(i64 1, ptr %base, i64 %vl) + ret <vscale x 64 x i8> %1 + } + + define <vscale x 64 x i8> @interleave_rvv_and_xsfmm2(<vscale x 64 x i8> %tile, i64 %vl, ptr %base) { + entry: + %0 = call <vscale x 64 x i8> @llvm.riscv.vadd.nxv64i8.nxv64i8.i64(<vscale x 64 x i8> poison, <vscale x 64 x i8> %tile, <vscale x 64 x i8> %tile, i64 %vl) + %1 = call <vscale x 64 x i8> @llvm.riscv.sf.vtmv.v.t.nxv64i8.i64(i64 1, i64 %vl) + %2 = call <vscale x 64 x i8> @llvm.riscv.vadd.nxv64i8.nxv64i8.i64(<vscale x 64 x i8> poison, <vscale x 64 x i8> %tile, <vscale x 64 x i8> %0, i64 %vl) + call void @llvm.riscv.sf.vste16.i64(i64 1, ptr %base, i64 %vl) + ret <vscale x 64 x i8> %2 + } + + define void @consecutive_xsfmm(<vscale x 32 x half> %tile, i64 %tm, i64 %tn, i64 %tk, ptr %base) { + entry: + tail call void @llvm.riscv.sf.mm.f.f.i64.nxv32f16(i64 0, <vscale x 32 x half> %tile, <vscale x 32 x half> %tile, i64 %tm, i64 %tn, i64 %tk, i64 2) + call void @llvm.riscv.sf.vste16.i64(i64 0, ptr %base, i64 %tn) + ret void + } + + define i64 @vsettnt_max(i64 %vl) { + entry: + %0 = call i64 @llvm.riscv.sf.vsettm.i64(i64 %vl, i64 1, i64 2) + %1 = call i64 @llvm.riscv.sf.vsettnt_max.i64(i64 1, i64 2) + ret i64 %0 + } + + define i64 @single_vsettm(i64 %vl) { + entry: + %0 = call i64 @llvm.riscv.sf.vsettm.i64(i64 %vl, i64 1, i64 2) + ret i64 %0 + } + + define i64 @single_vsettn(i64 %vl) { + entry: + %0 = call i64 @llvm.riscv.sf.vsettn.i64(i64 %vl, i64 1, i64 2) + ret i64 %0 + } + + define i64 @single_vsettk(i64 %vl) { + entry: + %0 = call i64 @llvm.riscv.sf.vsettk.i64(i64 %vl, i64 1, i64 2) + ret i64 %0 + } + + define void @sf_vtzero(i64 %tm, i64 %tn) { + entry: + call void @llvm.riscv.sf.vtzero.i64(i64 1, i64 %tm, i64 %tn, i64 3, i64 4) + ret void + } + + declare void @llvm.riscv.sf.mm.f.f.i64.nxv32f16(i64, <vscale x 32 x half>, <vscale x 32 x half>, i64, i64, i64, i64) + declare void @llvm.riscv.sf.mm.f.f.i64.nxv32bf16(i64, <vscale x 32 x bfloat>, <vscale x 32 x bfloat>, i64, i64, i64, i64) + declare <vscale x 64 x i8> @llvm.riscv.sf.vtmv.v.t.nxv64i8.i64(i64, i64) + declare <vscale x 64 x i8> @llvm.riscv.vadd.nxv64i8.nxv64i8.i64(<vscale x 64 x i8>, <vscale x 64 x i8>, <vscale x 64 x i8>, i64) + declare void @llvm.riscv.sf.vste16.i64(i64, ptr, i64) + declare i64 @llvm.riscv.sf.vsettnt_max.i64(i64, i64) + declare i64 @llvm.riscv.sf.vsettm.i64(i64, i64, i64) + declare i64 @llvm.riscv.sf.vsettn.i64(i64, i64, i64) + declare i64 @llvm.riscv.sf.vsettk.i64(i64, i64, i64) + declare void @llvm.riscv.sf.vtzero.i64(i64, i64, i64, i64, i64) +... +--- +name: xsfmm_same_state +alignment: 4 +tracksRegLiveness: true +registers: + - { id: 0, class: vrm8 } + - { id: 1, class: vrm8 } + - { id: 2, class: gprnox0 } + - { id: 3, class: gprnox0 } + - { id: 4, class: gprnox0 } +liveins: + - { reg: '$v8m8', virtual-reg: '%0' } + - { reg: '$v8m8', virtual-reg: '%1' } + - { reg: '$x10', virtual-reg: '%2' } + - { reg: '$x11', virtual-reg: '%3' } + - { reg: '$x12', virtual-reg: '%4' } +frameInfo: + maxAlignment: 1 +machineFunctionInfo: {} +body: | + bb.0.entry: + liveins: $v8m8, $v16m8, $x10, $x11, $x12 + ; CHECK-LABEL: name: xsfmm_same_state + ; CHECK: liveins: $v8m8, $v16m8, $x10, $x11, $x12 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x12 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gprnox0 = COPY $x11 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gprnox0 = COPY $x10 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:vrm8 = COPY $v16m8 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:vrm8 = COPY $v8m8 + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 1032 /* e16, w2 */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY2]], 4, 2, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTK [[COPY]], 4, 2, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: PseudoSF_MM_F_F $t2, [[COPY4]], [[COPY3]], 7, $noreg, $noreg, $noreg, 4, 2, implicit $frm, implicit $vl, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY2]], 4, 2, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTK [[COPY]], 4, 2, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: PseudoSF_MM_F_F $t2, [[COPY4]], [[COPY3]], 7, $noreg, $noreg, $noreg, 4, 2, implicit $frm, implicit $vl, implicit $vtype + ; CHECK-NEXT: PseudoRET + %4:gprnox0 = COPY $x12 + %3:gprnox0 = COPY $x11 + %2:gprnox0 = COPY $x10 + %1:vrm8 = COPY $v16m8 + %0:vrm8 = COPY $v8m8 + PseudoSF_MM_F_F $t2, %0:vrm8, %1:vrm8, 7, %2:gprnox0, %3:gprnox0, %4:gprnox0, 4, 2, implicit $frm + PseudoSF_MM_F_F $t2, %0:vrm8, %1:vrm8, 7, %2:gprnox0, %3:gprnox0, %4:gprnox0, 4, 2, implicit $frm + PseudoRET +... +--- +name: xsfmm_different_state +alignment: 4 +tracksRegLiveness: true +registers: + - { id: 0, class: vrm8 } + - { id: 1, class: vrm8 } + - { id: 2, class: gprnox0 } + - { id: 3, class: gprnox0 } + - { id: 4, class: gprnox0 } +liveins: + - { reg: '$v8m8', virtual-reg: '%0' } + - { reg: '$v8m8', virtual-reg: '%1' } + - { reg: '$x10', virtual-reg: '%2' } + - { reg: '$x11', virtual-reg: '%3' } + - { reg: '$x12', virtual-reg: '%4' } +frameInfo: + maxAlignment: 1 +machineFunctionInfo: {} +body: | + bb.0.entry: + liveins: $v8m8, $v16m8, $x10, $x11, $x12 + ; CHECK-LABEL: name: xsfmm_different_state + ; CHECK: liveins: $v8m8, $v16m8, $x10, $x11, $x12 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x12 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gprnox0 = COPY $x11 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gprnox0 = COPY $x10 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:vrm8 = COPY $v16m8 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:vrm8 = COPY $v8m8 + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 1032 /* e16, w2 */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY2]], 4, 2, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTK [[COPY]], 4, 2, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: PseudoSF_MM_F_F $t2, [[COPY4]], [[COPY3]], 7, $noreg, $noreg, $noreg, 4, 2, implicit $frm, implicit $vl, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 1544 /* e16, w4 */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY2]], 4, 3, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTK [[COPY]], 4, 3, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: PseudoSF_MM_F_F $t2, [[COPY4]], [[COPY3]], 7, $noreg, $noreg, $noreg, 4, 4, implicit $frm, implicit $vl, implicit $vtype + ; CHECK-NEXT: PseudoRET + %4:gprnox0 = COPY $x12 + %3:gprnox0 = COPY $x11 + %2:gprnox0 = COPY $x10 + %1:vrm8 = COPY $v16m8 + %0:vrm8 = COPY $v8m8 + PseudoSF_MM_F_F $t2, %0:vrm8, %1:vrm8, 7, %2:gprnox0, %3:gprnox0, %4:gprnox0, 4, 2, implicit $frm + PseudoSF_MM_F_F $t2, %0:vrm8, %1:vrm8, 7, %2:gprnox0, %3:gprnox0, %4:gprnox0, 4, 4, implicit $frm + PseudoRET +... +--- +name: xsfmm_different_state_bf +alignment: 4 +tracksRegLiveness: true +registers: + - { id: 0, class: vrm8 } + - { id: 1, class: vrm8 } + - { id: 2, class: gprnox0 } + - { id: 3, class: gprnox0 } + - { id: 4, class: gprnox0 } +liveins: + - { reg: '$v8m8', virtual-reg: '%0' } + - { reg: '$v8m8', virtual-reg: '%1' } + - { reg: '$x10', virtual-reg: '%2' } + - { reg: '$x11', virtual-reg: '%3' } + - { reg: '$x12', virtual-reg: '%4' } +frameInfo: + maxAlignment: 1 +machineFunctionInfo: {} +body: | + bb.0.entry: + liveins: $v8m8, $v16m8, $x10, $x11, $x12 + ; CHECK-LABEL: name: xsfmm_different_state_bf + ; CHECK: liveins: $v8m8, $v16m8, $x10, $x11, $x12 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x12 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gprnox0 = COPY $x11 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gprnox0 = COPY $x10 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:vrm8 = COPY $v16m8 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:vrm8 = COPY $v8m8 + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 1032 /* e16, w2 */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY2]], 4, 2, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTK [[COPY]], 4, 2, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: PseudoSF_MM_F_F $t2, [[COPY4]], [[COPY4]], 7, $noreg, $noreg, $noreg, 4, 2, implicit $frm, implicit $vl, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 1288 /* e16, w2 */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY2]], 4, 2, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTK [[COPY]], 4, 2, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: PseudoSF_MM_F_F_ALT $t2, [[COPY3]], [[COPY3]], 7, $noreg, $noreg, $noreg, 4, 2, implicit $frm, implicit $vl, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 1032 /* e16, w2 */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY2]], 4, 2, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTK [[COPY]], 4, 2, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: PseudoSF_MM_F_F $t2, [[COPY4]], [[COPY4]], 7, $noreg, $noreg, $noreg, 4, 2, implicit $frm, implicit $vl, implicit $vtype + ; CHECK-NEXT: PseudoRET + %4:gprnox0 = COPY $x12 + %3:gprnox0 = COPY $x11 + %2:gprnox0 = COPY $x10 + %1:vrm8 = COPY $v16m8 + %0:vrm8 = COPY $v8m8 + PseudoSF_MM_F_F $t2, %0:vrm8, %0:vrm8, 7, %2:gprnox0, %3:gprnox0, %4:gprnox0, 4, 2, implicit $frm + PseudoSF_MM_F_F_ALT $t2, %1:vrm8, %1:vrm8, 7, %2:gprnox0, %3:gprnox0, %4:gprnox0, 4, 2, implicit $frm + PseudoSF_MM_F_F $t2, %0:vrm8, %0:vrm8, 7, %2:gprnox0, %3:gprnox0, %4:gprnox0, 4, 2, implicit $frm + PseudoRET +... +--- +name: interleave_rvv_and_xsfmm +alignment: 4 +tracksRegLiveness: true +registers: + - { id: 0, class: vrm8 } + - { id: 1, class: gprnox0 } + - { id: 2, class: gpr } + - { id: 3, class: gpr } + - { id: 4, class: vrm8 } + - { id: 5, class: vrm8 } +liveins: + - { reg: '$v8m8', virtual-reg: '%0' } + - { reg: '$x10', virtual-reg: '%1' } + - { reg: '$x11', virtual-reg: '%2' } +frameInfo: + maxAlignment: 1 +machineFunctionInfo: {} +body: | + bb.0.entry: + liveins: $v8m8, $x10, $x11 + ; CHECK-LABEL: name: interleave_rvv_and_xsfmm + ; CHECK: liveins: $v8m8, $x10, $x11 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x11 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gprnox0 = COPY $x10 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vrm8 = COPY $v8m8 + ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 1 + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 512 /* e8, w1 */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: [[PseudoSF_VTMV_V_T:%[0-9]+]]:vrm8 = PseudoSF_VTMV_V_T [[ADDI]], $noreg, 3, 1, implicit $vl, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoVSETVLI [[COPY1]], 195 /* e8, m8, ta, ma */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: [[PseudoVADD_VV_M8_:%[0-9]+]]:vrm8 = PseudoVADD_VV_M8 $noreg, [[COPY2]], [[PseudoSF_VTMV_V_T]], $noreg, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 520 /* e16, w1 */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: PseudoSF_VSTE16 [[ADDI]], [[COPY]], $noreg, 4, 1, implicit $vl, implicit $vtype + ; CHECK-NEXT: $v8m8 = COPY [[PseudoVADD_VV_M8_]], implicit $vtype + ; CHECK-NEXT: PseudoRET implicit $v8m8 + %2:gpr = COPY $x11 + %1:gprnox0 = COPY $x10 + %0:vrm8 = COPY $v8m8 + %3:gpr = ADDI $x0, 1 + %4:vrm8 = PseudoSF_VTMV_V_T %3:gpr, %1:gprnox0, 3, 1 + %5:vrm8 = PseudoVADD_VV_M8 $noreg, %0:vrm8, killed %4:vrm8, %1:gprnox0, 3, 0 + PseudoSF_VSTE16 %3:gpr, %2:gpr, %1:gprnox0, 4, 1 + $v8m8 = COPY %5:vrm8 + PseudoRET implicit $v8m8 +... +--- +name: interleave_rvv_and_xsfmm2 +alignment: 4 +tracksRegLiveness: true +registers: + - { id: 0, class: vrm8 } + - { id: 1, class: gprnox0 } + - { id: 2, class: gpr } + - { id: 3, class: gpr } + - { id: 4, class: vrm8 } + - { id: 5, class: vrm8 } +liveins: + - { reg: '$v8m8', virtual-reg: '%0' } + - { reg: '$x10', virtual-reg: '%1' } + - { reg: '$x11', virtual-reg: '%2' } +frameInfo: + maxAlignment: 1 +machineFunctionInfo: {} +body: | + bb.0.entry: + liveins: $v8m8, $x10, $x11 + ; CHECK-LABEL: name: interleave_rvv_and_xsfmm2 + ; CHECK: liveins: $v8m8, $x10, $x11 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x11 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gprnox0 = COPY $x10 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vrm8 = COPY $v8m8 + ; CHECK-NEXT: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 1 + ; CHECK-NEXT: dead $x0 = PseudoVSETVLI [[COPY1]], 195 /* e8, m8, ta, ma */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: [[PseudoVADD_VV_M8_:%[0-9]+]]:vrm8 = PseudoVADD_VV_M8 $noreg, [[COPY2]], [[COPY2]], $noreg, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 512 /* e8, w1 */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead [[PseudoSF_VTMV_V_T:%[0-9]+]]:vrm8 = PseudoSF_VTMV_V_T [[ADDI]], $noreg, 3, 1, implicit $vl, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoVSETVLI [[COPY1]], 195 /* e8, m8, ta, ma */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: [[PseudoVADD_VV_M8_1:%[0-9]+]]:vrm8 = PseudoVADD_VV_M8 $noreg, [[PseudoVADD_VV_M8_]], [[PseudoVADD_VV_M8_]], $noreg, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 520 /* e16, w1 */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: PseudoSF_VSTE16 [[ADDI]], [[COPY]], $noreg, 4, 1, implicit $vl, implicit $vtype + ; CHECK-NEXT: $v8m8 = COPY [[PseudoVADD_VV_M8_1]], implicit $vtype + ; CHECK-NEXT: PseudoRET implicit $v8m8 + %2:gpr = COPY $x11 + %1:gprnox0 = COPY $x10 + %0:vrm8 = COPY $v8m8 + %3:gpr = ADDI $x0, 1 + %4:vrm8 = PseudoVADD_VV_M8 $noreg, %0:vrm8, killed %0:vrm8, %1:gprnox0, 3, 0 + %5:vrm8 = PseudoSF_VTMV_V_T %3:gpr, %1:gprnox0, 3, 1 + %6:vrm8 = PseudoVADD_VV_M8 $noreg, %4:vrm8, killed %4:vrm8, %1:gprnox0, 3, 0 + PseudoSF_VSTE16 %3:gpr, %2:gpr, %1:gprnox0, 4, 1 + $v8m8 = COPY %6:vrm8 + PseudoRET implicit $v8m8 +... +--- +name: consecutive_xsfmm +alignment: 4 +tracksRegLiveness: true +registers: + - { id: 0, class: vrm8 } + - { id: 1, class: gprnox0 } + - { id: 2, class: gprnox0 } + - { id: 3, class: gprnox0 } + - { id: 4, class: gprnox0 } +liveins: + - { reg: '$v8m8', virtual-reg: '%0' } + - { reg: '$x10', virtual-reg: '%1' } + - { reg: '$x11', virtual-reg: '%2' } + - { reg: '$x12', virtual-reg: '%3' } + - { reg: '$x13', virtual-reg: '%4' } +frameInfo: + maxAlignment: 1 +machineFunctionInfo: {} +body: | + bb.0.entry: + liveins: $v8m8, $x10, $x11, $x12, $x13 + ; CHECK-LABEL: name: consecutive_xsfmm + ; CHECK: liveins: $v8m8, $x10, $x11, $x12, $x13 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:vrm8 = COPY $v8m8 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gprnox0 = COPY $x10 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gprnox0 = COPY $x11 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gprnox0 = COPY $x12 + ; CHECK-NEXT: dead [[COPY4:%[0-9]+]]:gprnox0 = COPY $x13 + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY2]], 1032 /* e16, w2 */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY1]], 4, 2, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTK [[COPY3]], 4, 2, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: PseudoSF_MM_F_F $t2, [[COPY]], [[COPY]], 7, $noreg, $noreg, $noreg, 4, 2, implicit $frm, implicit $vl, implicit $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY3]], 520 /* e16, w1 */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: PseudoSF_VSTE16 [[COPY1]], [[COPY2]], $noreg, 4, 1, implicit $vl, implicit $vtype + ; CHECK-NEXT: PseudoRET + %0:vrm8 = COPY $v8m8 + %1:gprnox0 = COPY $x10 + %2:gprnox0 = COPY $x11 + %3:gprnox0 = COPY $x12 + %4:gprnox0 = COPY $x13 + PseudoSF_MM_F_F $t2, %0:vrm8, %0:vrm8, 7, %1:gprnox0, %2:gprnox0, %3:gprnox0, 4, 2, implicit $frm + PseudoSF_VSTE16 %1:gprnox0, %2:gprnox0, %3:gprnox0, 4, 1 + PseudoRET +... +--- +name: vsettnt_max +alignment: 4 +tracksRegLiveness: true +registers: + - { id: 0, class: gprnox0 } +liveins: + - { reg: '$x10', virtual-reg: '%0' } +frameInfo: + maxAlignment: 1 +machineFunctionInfo: {} +body: | + bb.0.entry: + liveins: $x10 + ; CHECK-LABEL: name: vsettnt_max + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; CHECK-NEXT: dead [[PseudoSF_VSETTNTX0_:%[0-9]+]]:gprnox0 = PseudoSF_VSETTNTX0 killed $x0, 520 /* e16, w1 */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead [[PseudoSF_VSETTK:%[0-9]+]]:gprnox0 = PseudoSF_VSETTK [[COPY]], 4, 1, implicit-def $vtype, implicit $vtype, implicit $vtype + ; CHECK-NEXT: dead [[PseudoSF_VSETTNTX0_1:%[0-9]+]]:gprnox0 = PseudoSF_VSETTNTX0 $x0, 520 /* e16, w1 */, implicit-def $vl, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: [[PseudoSF_VSETTM:%[0-9]+]]:gprnox0 = PseudoSF_VSETTM [[COPY]], 4, 1, implicit-def $vtype, implicit $vtype, implicit $vtype + ; CHECK-NEXT: $x10 = COPY [[PseudoSF_VSETTM]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprnox0 = COPY $x10 + %1:gprnox0 = PseudoSF_VSETTK %0:gprnox0, 4, 1, implicit-def $vtype, implicit $vtype + %2:gprnox0 = PseudoSF_VSETTNTX0 $x0, 520, implicit-def $vl, implicit-def $vtype, implicit $vtype + %3:gprnox0 = PseudoSF_VSETTM %0:gprnox0, 4, 1, implicit-def $vtype, implicit $vtype + $x10 = COPY %3:gprnox0 + PseudoRET implicit $x10 +... +--- +name: single_vsettm +alignment: 4 +tracksRegLiveness: true +registers: + - { id: 0, class: gprnox0 } +liveins: + - { reg: '$x10', virtual-reg: '%0' } +frameInfo: + maxAlignment: 1 +machineFunctionInfo: {} +body: | + bb.0.entry: + liveins: $x10 + ; CHECK-LABEL: name: single_vsettm + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; CHECK-NEXT: dead [[PseudoSF_VSETTNTX0_:%[0-9]+]]:gprnox0 = PseudoSF_VSETTNTX0 killed $x0, 520 /* e16, w1 */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: [[PseudoSF_VSETTM:%[0-9]+]]:gprnox0 = PseudoSF_VSETTM [[COPY]], 4, 1, implicit-def $vtype, implicit $vtype, implicit $vtype + ; CHECK-NEXT: $x10 = COPY [[PseudoSF_VSETTM]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprnox0 = COPY $x10 + %1:gprnox0 = PseudoSF_VSETTM %0:gprnox0, 4, 1, implicit-def $vtype, implicit $vtype + $x10 = COPY %1:gprnox0 + PseudoRET implicit $x10 +... +--- +name: single_vsettn +alignment: 4 +tracksRegLiveness: true +registers: + - { id: 0, class: gprnox0 } +liveins: + - { reg: '$x10', virtual-reg: '%0' } +frameInfo: + maxAlignment: 1 +machineFunctionInfo: {} +body: | + bb.0.entry: + liveins: $x10 + ; CHECK-LABEL: name: single_vsettn + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; CHECK-NEXT: [[PseudoSF_VSETTNT:%[0-9]+]]:gprnox0 = PseudoSF_VSETTNT [[COPY]], 520 /* e16, w1 */, implicit-def $vl, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: $x10 = COPY [[PseudoSF_VSETTNT]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprnox0 = COPY $x10 + %1:gprnox0 = PseudoSF_VSETTNT %0:gprnox0, 520, implicit-def $vl, implicit-def $vtype, implicit $vtype + $x10 = COPY %1:gprnox0 + PseudoRET implicit $x10 +... +--- +name: single_vsettk +alignment: 4 +tracksRegLiveness: true +registers: + - { id: 0, class: gprnox0 } +liveins: + - { reg: '$x10', virtual-reg: '%0' } +frameInfo: + maxAlignment: 1 +machineFunctionInfo: {} +body: | + bb.0.entry: + liveins: $x10 + ; CHECK-LABEL: name: single_vsettk + ; CHECK: liveins: $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; CHECK-NEXT: dead [[PseudoSF_VSETTNTX0_:%[0-9]+]]:gprnox0 = PseudoSF_VSETTNTX0 killed $x0, 520 /* e16, w1 */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: [[PseudoSF_VSETTK:%[0-9]+]]:gprnox0 = PseudoSF_VSETTK [[COPY]], 4, 1, implicit-def $vtype, implicit $vtype, implicit $vtype + ; CHECK-NEXT: $x10 = COPY [[PseudoSF_VSETTK]] + ; CHECK-NEXT: PseudoRET implicit $x10 + %0:gprnox0 = COPY $x10 + %1:gprnox0 = PseudoSF_VSETTK %0:gprnox0, 4, 1, implicit-def $vtype, implicit $vtype + $x10 = COPY %1:gprnox0 + PseudoRET implicit $x10 +... +--- +name: sf_vtzero +alignment: 4 +tracksRegLiveness: true +registers: + - { id: 0, class: gprnox0 } + - { id: 1, class: gprnox0 } +liveins: + - { reg: '$x10', virtual-reg: '%0' } + - { reg: '$x11', virtual-reg: '%1' } +frameInfo: + maxAlignment: 1 +machineFunctionInfo: {} +body: | + bb.0.entry: + liveins: $x10, $x11 + ; CHECK-LABEL: name: sf_vtzero + ; CHECK: liveins: $x10, $x11 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gprnox0 = COPY $x11 + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTNT [[COPY1]], 1536 /* e8, w4 */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead $x0 = PseudoSF_VSETTM [[COPY]], 3, 3, implicit-def $vtype, implicit $vtype + ; CHECK-NEXT: PseudoSF_VTZERO_T $t1, $noreg, $noreg, 3, 4, implicit $vl, implicit $vtype + ; CHECK-NEXT: PseudoRET + %0:gprnox0 = COPY $x10 + %1:gprnox0 = COPY $x11 + PseudoSF_VTZERO_T $t1, %0:gprnox0, %1:gprnox0, 3, 4 + PseudoRET +... diff --git a/llvm/test/CodeGen/WebAssembly/simd-dot-reductions.ll b/llvm/test/CodeGen/WebAssembly/simd-dot-reductions.ll new file mode 100644 index 0000000..3654aae --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/simd-dot-reductions.ll @@ -0,0 +1,106 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc < %s -mattr=+simd128 | FileCheck %s + +target triple = "wasm32-unknown-unknown" + +define <4 x i32> @dot_sext_1(<8 x i16> %a, <8 x i16> %b) { +; CHECK-LABEL: dot_sext_1: +; CHECK: .functype dot_sext_1 (v128, v128) -> (v128) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: i32x4.dot_i16x8_s +; CHECK-NEXT: # fallthrough-return + %sext1 = sext <8 x i16> %a to <8 x i32> + %sext2 = sext <8 x i16> %b to <8 x i32> + %mul = mul <8 x i32> %sext1, %sext2 + %shuffle1 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6> + %shuffle2 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7> + %res = add <4 x i32> %shuffle1, %shuffle2 + ret <4 x i32> %res +} + + +define <4 x i32> @dot_sext_2(<8 x i16> %a, <8 x i16> %b) { +; CHECK-LABEL: dot_sext_2: +; CHECK: .functype dot_sext_2 (v128, v128) -> (v128) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: i32x4.dot_i16x8_s +; CHECK-NEXT: # fallthrough-return + %sext1 = sext <8 x i16> %a to <8 x i32> + %sext2 = sext <8 x i16> %b to <8 x i32> + %mul = mul <8 x i32> %sext1, %sext2 + %shuffle1 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6> + %shuffle2 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7> + %res = add <4 x i32> %shuffle2, %shuffle1 + ret <4 x i32> %res +} + +define <4 x i32> @dot_sext_self(<8 x i16> %v) { +; CHECK-LABEL: dot_sext_self: +; CHECK: .functype dot_sext_self (v128) -> (v128) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: i32x4.dot_i16x8_s +; CHECK-NEXT: # fallthrough-return + %sext = sext <8 x i16> %v to <8 x i32> + %mul = mul <8 x i32> %sext, %sext + %shuffle1 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6> + %shuffle2 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7> + %res = add <4 x i32> %shuffle1, %shuffle2 + ret <4 x i32> %res +} + +; INFO: Negative test +define <4 x i32> @dot_zext(<8 x i16> %a, <8 x i16> %b) { +; CHECK-LABEL: dot_zext: +; CHECK: .functype dot_zext (v128, v128) -> (v128) +; CHECK-NEXT: .local v128 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: i32x4.extmul_low_i16x8_u +; CHECK-NEXT: local.tee 2 +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: i32x4.extmul_high_i16x8_u +; CHECK-NEXT: local.tee 1 +; CHECK-NEXT: i8x16.shuffle 0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27 +; CHECK-NEXT: local.get 2 +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: i8x16.shuffle 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 +; CHECK-NEXT: i32x4.add +; CHECK-NEXT: # fallthrough-return + %zext1 = zext <8 x i16> %a to <8 x i32> + %zext2 = zext <8 x i16> %b to <8 x i32> + %mul = mul <8 x i32> %zext1, %zext2 + %shuffle1 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6> + %shuffle2 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7> + %res = add <4 x i32> %shuffle1, %shuffle2 + ret <4 x i32> %res +} + +; INFO: Negative test +define <4 x i32> @dot_wrong_shuffle(<8 x i16> %a, <8 x i16> %b) { +; CHECK-LABEL: dot_wrong_shuffle: +; CHECK: .functype dot_wrong_shuffle (v128, v128) -> (v128) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: i32x4.extmul_low_i16x8_s +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: i32x4.extmul_high_i16x8_s +; CHECK-NEXT: i32x4.add +; CHECK-NEXT: # fallthrough-return + %sext1 = sext <8 x i16> %a to <8 x i32> + %sext2 = sext <8 x i16> %b to <8 x i32> + %mul = mul <8 x i32> %sext1, %sext2 + %shuffle1 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3> + %shuffle2 = shufflevector <8 x i32> %mul, <8 x i32> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7> + %res = add <4 x i32> %shuffle1, %shuffle2 + ret <4 x i32> %res +} diff --git a/llvm/test/CodeGen/WebAssembly/simd-relaxed-fma.ll b/llvm/test/CodeGen/WebAssembly/simd-relaxed-fma.ll index e065de3..600241a 100644 --- a/llvm/test/CodeGen/WebAssembly/simd-relaxed-fma.ll +++ b/llvm/test/CodeGen/WebAssembly/simd-relaxed-fma.ll @@ -2,9 +2,278 @@ ; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+fp16,+simd128,+relaxed-simd | FileCheck %s --check-prefix=RELAXED ; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+fp16,+simd128, | FileCheck %s --check-prefix=STRICT +; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 | FileCheck %s --check-prefix=NOFP16 +; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefix=NOSIMD target triple = "wasm32" +define half @fadd_fmul_contract_f16(half %a, half %b, half %c) { +; RELAXED-LABEL: fadd_fmul_contract_f16: +; RELAXED: .functype fadd_fmul_contract_f16 (f32, f32, f32) -> (f32) +; RELAXED-NEXT: # %bb.0: +; RELAXED-NEXT: call $push0=, __truncsfhf2, $0 +; RELAXED-NEXT: call $push1=, __extendhfsf2, $pop0 +; RELAXED-NEXT: call $push2=, __truncsfhf2, $1 +; RELAXED-NEXT: call $push3=, __extendhfsf2, $pop2 +; RELAXED-NEXT: f32.mul $push4=, $pop1, $pop3 +; RELAXED-NEXT: call $push5=, __truncsfhf2, $2 +; RELAXED-NEXT: call $push6=, __extendhfsf2, $pop5 +; RELAXED-NEXT: f32.add $push7=, $pop4, $pop6 +; RELAXED-NEXT: return $pop7 +; +; STRICT-LABEL: fadd_fmul_contract_f16: +; STRICT: .functype fadd_fmul_contract_f16 (f32, f32, f32) -> (f32) +; STRICT-NEXT: # %bb.0: +; STRICT-NEXT: call $push0=, __truncsfhf2, $0 +; STRICT-NEXT: call $push1=, __extendhfsf2, $pop0 +; STRICT-NEXT: call $push2=, __truncsfhf2, $1 +; STRICT-NEXT: call $push3=, __extendhfsf2, $pop2 +; STRICT-NEXT: f32.mul $push4=, $pop1, $pop3 +; STRICT-NEXT: call $push5=, __truncsfhf2, $2 +; STRICT-NEXT: call $push6=, __extendhfsf2, $pop5 +; STRICT-NEXT: f32.add $push7=, $pop4, $pop6 +; STRICT-NEXT: return $pop7 +; +; NOFP16-LABEL: fadd_fmul_contract_f16: +; NOFP16: .functype fadd_fmul_contract_f16 (f32, f32, f32) -> (f32) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: call $push0=, __truncsfhf2, $0 +; NOFP16-NEXT: call $push1=, __extendhfsf2, $pop0 +; NOFP16-NEXT: call $push2=, __truncsfhf2, $1 +; NOFP16-NEXT: call $push3=, __extendhfsf2, $pop2 +; NOFP16-NEXT: f32.mul $push4=, $pop1, $pop3 +; NOFP16-NEXT: call $push5=, __truncsfhf2, $2 +; NOFP16-NEXT: call $push6=, __extendhfsf2, $pop5 +; NOFP16-NEXT: f32.add $push7=, $pop4, $pop6 +; NOFP16-NEXT: return $pop7 +; +; NOSIMD-LABEL: fadd_fmul_contract_f16: +; NOSIMD: .functype fadd_fmul_contract_f16 (f32, f32, f32) -> (f32) +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: call $push0=, __truncsfhf2, $0 +; NOSIMD-NEXT: call $push1=, __extendhfsf2, $pop0 +; NOSIMD-NEXT: call $push2=, __truncsfhf2, $1 +; NOSIMD-NEXT: call $push3=, __extendhfsf2, $pop2 +; NOSIMD-NEXT: f32.mul $push4=, $pop1, $pop3 +; NOSIMD-NEXT: call $push5=, __truncsfhf2, $2 +; NOSIMD-NEXT: call $push6=, __extendhfsf2, $pop5 +; NOSIMD-NEXT: f32.add $push7=, $pop4, $pop6 +; NOSIMD-NEXT: return $pop7 + %mul = fmul contract half %b, %a + %add = fadd contract half %mul, %c + ret half %add +} + +define half @fmuladd_contract_f16(half %a, half %b, half %c) { +; RELAXED-LABEL: fmuladd_contract_f16: +; RELAXED: .functype fmuladd_contract_f16 (f32, f32, f32) -> (f32) +; RELAXED-NEXT: # %bb.0: +; RELAXED-NEXT: call $push0=, __truncsfhf2, $1 +; RELAXED-NEXT: call $push1=, __extendhfsf2, $pop0 +; RELAXED-NEXT: call $push2=, __truncsfhf2, $0 +; RELAXED-NEXT: call $push3=, __extendhfsf2, $pop2 +; RELAXED-NEXT: f32.mul $push4=, $pop1, $pop3 +; RELAXED-NEXT: call $push5=, __truncsfhf2, $2 +; RELAXED-NEXT: call $push6=, __extendhfsf2, $pop5 +; RELAXED-NEXT: f32.add $push7=, $pop4, $pop6 +; RELAXED-NEXT: return $pop7 +; +; STRICT-LABEL: fmuladd_contract_f16: +; STRICT: .functype fmuladd_contract_f16 (f32, f32, f32) -> (f32) +; STRICT-NEXT: # %bb.0: +; STRICT-NEXT: call $push0=, __truncsfhf2, $1 +; STRICT-NEXT: call $push1=, __extendhfsf2, $pop0 +; STRICT-NEXT: call $push2=, __truncsfhf2, $0 +; STRICT-NEXT: call $push3=, __extendhfsf2, $pop2 +; STRICT-NEXT: f32.mul $push4=, $pop1, $pop3 +; STRICT-NEXT: call $push5=, __truncsfhf2, $2 +; STRICT-NEXT: call $push6=, __extendhfsf2, $pop5 +; STRICT-NEXT: f32.add $push7=, $pop4, $pop6 +; STRICT-NEXT: return $pop7 +; +; NOFP16-LABEL: fmuladd_contract_f16: +; NOFP16: .functype fmuladd_contract_f16 (f32, f32, f32) -> (f32) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: call $push0=, __truncsfhf2, $1 +; NOFP16-NEXT: call $push1=, __extendhfsf2, $pop0 +; NOFP16-NEXT: call $push2=, __truncsfhf2, $0 +; NOFP16-NEXT: call $push3=, __extendhfsf2, $pop2 +; NOFP16-NEXT: f32.mul $push4=, $pop1, $pop3 +; NOFP16-NEXT: call $push5=, __truncsfhf2, $2 +; NOFP16-NEXT: call $push6=, __extendhfsf2, $pop5 +; NOFP16-NEXT: f32.add $push7=, $pop4, $pop6 +; NOFP16-NEXT: return $pop7 +; +; NOSIMD-LABEL: fmuladd_contract_f16: +; NOSIMD: .functype fmuladd_contract_f16 (f32, f32, f32) -> (f32) +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: call $push0=, __truncsfhf2, $1 +; NOSIMD-NEXT: call $push1=, __extendhfsf2, $pop0 +; NOSIMD-NEXT: call $push2=, __truncsfhf2, $0 +; NOSIMD-NEXT: call $push3=, __extendhfsf2, $pop2 +; NOSIMD-NEXT: f32.mul $push4=, $pop1, $pop3 +; NOSIMD-NEXT: call $push5=, __truncsfhf2, $2 +; NOSIMD-NEXT: call $push6=, __extendhfsf2, $pop5 +; NOSIMD-NEXT: f32.add $push7=, $pop4, $pop6 +; NOSIMD-NEXT: return $pop7 + %fma = call contract half @llvm.fmuladd(half %a, half %b, half %c) + ret half %fma +} + +define half @fmuladd_f16(half %a, half %b, half %c) { +; RELAXED-LABEL: fmuladd_f16: +; RELAXED: .functype fmuladd_f16 (f32, f32, f32) -> (f32) +; RELAXED-NEXT: # %bb.0: +; RELAXED-NEXT: call $push0=, __truncsfhf2, $1 +; RELAXED-NEXT: call $push1=, __extendhfsf2, $pop0 +; RELAXED-NEXT: call $push2=, __truncsfhf2, $0 +; RELAXED-NEXT: call $push3=, __extendhfsf2, $pop2 +; RELAXED-NEXT: f32.mul $push4=, $pop1, $pop3 +; RELAXED-NEXT: call $push5=, __truncsfhf2, $2 +; RELAXED-NEXT: call $push6=, __extendhfsf2, $pop5 +; RELAXED-NEXT: f32.add $push7=, $pop4, $pop6 +; RELAXED-NEXT: return $pop7 +; +; STRICT-LABEL: fmuladd_f16: +; STRICT: .functype fmuladd_f16 (f32, f32, f32) -> (f32) +; STRICT-NEXT: # %bb.0: +; STRICT-NEXT: call $push0=, __truncsfhf2, $1 +; STRICT-NEXT: call $push1=, __extendhfsf2, $pop0 +; STRICT-NEXT: call $push2=, __truncsfhf2, $0 +; STRICT-NEXT: call $push3=, __extendhfsf2, $pop2 +; STRICT-NEXT: f32.mul $push4=, $pop1, $pop3 +; STRICT-NEXT: call $push5=, __truncsfhf2, $2 +; STRICT-NEXT: call $push6=, __extendhfsf2, $pop5 +; STRICT-NEXT: f32.add $push7=, $pop4, $pop6 +; STRICT-NEXT: return $pop7 +; +; NOFP16-LABEL: fmuladd_f16: +; NOFP16: .functype fmuladd_f16 (f32, f32, f32) -> (f32) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: call $push0=, __truncsfhf2, $1 +; NOFP16-NEXT: call $push1=, __extendhfsf2, $pop0 +; NOFP16-NEXT: call $push2=, __truncsfhf2, $0 +; NOFP16-NEXT: call $push3=, __extendhfsf2, $pop2 +; NOFP16-NEXT: f32.mul $push4=, $pop1, $pop3 +; NOFP16-NEXT: call $push5=, __truncsfhf2, $2 +; NOFP16-NEXT: call $push6=, __extendhfsf2, $pop5 +; NOFP16-NEXT: f32.add $push7=, $pop4, $pop6 +; NOFP16-NEXT: return $pop7 +; +; NOSIMD-LABEL: fmuladd_f16: +; NOSIMD: .functype fmuladd_f16 (f32, f32, f32) -> (f32) +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: call $push0=, __truncsfhf2, $1 +; NOSIMD-NEXT: call $push1=, __extendhfsf2, $pop0 +; NOSIMD-NEXT: call $push2=, __truncsfhf2, $0 +; NOSIMD-NEXT: call $push3=, __extendhfsf2, $pop2 +; NOSIMD-NEXT: f32.mul $push4=, $pop1, $pop3 +; NOSIMD-NEXT: call $push5=, __truncsfhf2, $2 +; NOSIMD-NEXT: call $push6=, __extendhfsf2, $pop5 +; NOSIMD-NEXT: f32.add $push7=, $pop4, $pop6 +; NOSIMD-NEXT: return $pop7 + %fma = call half @llvm.fmuladd(half %a, half %b, half %c) + ret half %fma +} + + +define float @fadd_fmul_contract_f32(float %a, float %b, float %c) { +; RELAXED-LABEL: fadd_fmul_contract_f32: +; RELAXED: .functype fadd_fmul_contract_f32 (f32, f32, f32) -> (f32) +; RELAXED-NEXT: # %bb.0: +; RELAXED-NEXT: f32.mul $push0=, $1, $0 +; RELAXED-NEXT: f32.add $push1=, $pop0, $2 +; RELAXED-NEXT: return $pop1 +; +; STRICT-LABEL: fadd_fmul_contract_f32: +; STRICT: .functype fadd_fmul_contract_f32 (f32, f32, f32) -> (f32) +; STRICT-NEXT: # %bb.0: +; STRICT-NEXT: f32.mul $push0=, $1, $0 +; STRICT-NEXT: f32.add $push1=, $pop0, $2 +; STRICT-NEXT: return $pop1 +; +; NOFP16-LABEL: fadd_fmul_contract_f32: +; NOFP16: .functype fadd_fmul_contract_f32 (f32, f32, f32) -> (f32) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: f32.mul $push0=, $1, $0 +; NOFP16-NEXT: f32.add $push1=, $pop0, $2 +; NOFP16-NEXT: return $pop1 +; +; NOSIMD-LABEL: fadd_fmul_contract_f32: +; NOSIMD: .functype fadd_fmul_contract_f32 (f32, f32, f32) -> (f32) +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: f32.mul $push0=, $1, $0 +; NOSIMD-NEXT: f32.add $push1=, $pop0, $2 +; NOSIMD-NEXT: return $pop1 + %mul = fmul contract float %b, %a + %add = fadd contract float %mul, %c + ret float %add +} + +define float @fmuladd_contract_f32(float %a, float %b, float %c) { +; RELAXED-LABEL: fmuladd_contract_f32: +; RELAXED: .functype fmuladd_contract_f32 (f32, f32, f32) -> (f32) +; RELAXED-NEXT: # %bb.0: +; RELAXED-NEXT: f32.mul $push0=, $0, $1 +; RELAXED-NEXT: f32.add $push1=, $pop0, $2 +; RELAXED-NEXT: return $pop1 +; +; STRICT-LABEL: fmuladd_contract_f32: +; STRICT: .functype fmuladd_contract_f32 (f32, f32, f32) -> (f32) +; STRICT-NEXT: # %bb.0: +; STRICT-NEXT: f32.mul $push0=, $0, $1 +; STRICT-NEXT: f32.add $push1=, $pop0, $2 +; STRICT-NEXT: return $pop1 +; +; NOFP16-LABEL: fmuladd_contract_f32: +; NOFP16: .functype fmuladd_contract_f32 (f32, f32, f32) -> (f32) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: f32.mul $push0=, $0, $1 +; NOFP16-NEXT: f32.add $push1=, $pop0, $2 +; NOFP16-NEXT: return $pop1 +; +; NOSIMD-LABEL: fmuladd_contract_f32: +; NOSIMD: .functype fmuladd_contract_f32 (f32, f32, f32) -> (f32) +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: f32.mul $push0=, $0, $1 +; NOSIMD-NEXT: f32.add $push1=, $pop0, $2 +; NOSIMD-NEXT: return $pop1 + %fma = call contract float @llvm.fmuladd(float %a, float %b, float %c) + ret float %fma +} + +define float @fmuladd_f32(float %a, float %b, float %c) { +; RELAXED-LABEL: fmuladd_f32: +; RELAXED: .functype fmuladd_f32 (f32, f32, f32) -> (f32) +; RELAXED-NEXT: # %bb.0: +; RELAXED-NEXT: f32.mul $push0=, $0, $1 +; RELAXED-NEXT: f32.add $push1=, $pop0, $2 +; RELAXED-NEXT: return $pop1 +; +; STRICT-LABEL: fmuladd_f32: +; STRICT: .functype fmuladd_f32 (f32, f32, f32) -> (f32) +; STRICT-NEXT: # %bb.0: +; STRICT-NEXT: f32.mul $push0=, $0, $1 +; STRICT-NEXT: f32.add $push1=, $pop0, $2 +; STRICT-NEXT: return $pop1 +; +; NOFP16-LABEL: fmuladd_f32: +; NOFP16: .functype fmuladd_f32 (f32, f32, f32) -> (f32) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: f32.mul $push0=, $0, $1 +; NOFP16-NEXT: f32.add $push1=, $pop0, $2 +; NOFP16-NEXT: return $pop1 +; +; NOSIMD-LABEL: fmuladd_f32: +; NOSIMD: .functype fmuladd_f32 (f32, f32, f32) -> (f32) +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: f32.mul $push0=, $0, $1 +; NOSIMD-NEXT: f32.add $push1=, $pop0, $2 +; NOSIMD-NEXT: return $pop1 + %fma = call float @llvm.fmuladd(float %a, float %b, float %c) + ret float %fma +} + define double @fadd_fmul_contract_f64(double %a, double %b, double %c) { ; RELAXED-LABEL: fadd_fmul_contract_f64: ; RELAXED: .functype fadd_fmul_contract_f64 (f64, f64, f64) -> (f64) @@ -19,16 +288,94 @@ define double @fadd_fmul_contract_f64(double %a, double %b, double %c) { ; STRICT-NEXT: f64.mul $push0=, $1, $0 ; STRICT-NEXT: f64.add $push1=, $pop0, $2 ; STRICT-NEXT: return $pop1 +; +; NOFP16-LABEL: fadd_fmul_contract_f64: +; NOFP16: .functype fadd_fmul_contract_f64 (f64, f64, f64) -> (f64) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: f64.mul $push0=, $1, $0 +; NOFP16-NEXT: f64.add $push1=, $pop0, $2 +; NOFP16-NEXT: return $pop1 +; +; NOSIMD-LABEL: fadd_fmul_contract_f64: +; NOSIMD: .functype fadd_fmul_contract_f64 (f64, f64, f64) -> (f64) +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: f64.mul $push0=, $1, $0 +; NOSIMD-NEXT: f64.add $push1=, $pop0, $2 +; NOSIMD-NEXT: return $pop1 %mul = fmul contract double %b, %a %add = fadd contract double %mul, %c ret double %add } +define double @fmuladd_f64(double %a, double %b, double %c) { +; RELAXED-LABEL: fmuladd_f64: +; RELAXED: .functype fmuladd_f64 (f64, f64, f64) -> (f64) +; RELAXED-NEXT: # %bb.0: +; RELAXED-NEXT: f64.mul $push0=, $0, $1 +; RELAXED-NEXT: f64.add $push1=, $pop0, $2 +; RELAXED-NEXT: return $pop1 +; +; STRICT-LABEL: fmuladd_f64: +; STRICT: .functype fmuladd_f64 (f64, f64, f64) -> (f64) +; STRICT-NEXT: # %bb.0: +; STRICT-NEXT: f64.mul $push0=, $0, $1 +; STRICT-NEXT: f64.add $push1=, $pop0, $2 +; STRICT-NEXT: return $pop1 +; +; NOFP16-LABEL: fmuladd_f64: +; NOFP16: .functype fmuladd_f64 (f64, f64, f64) -> (f64) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: f64.mul $push0=, $0, $1 +; NOFP16-NEXT: f64.add $push1=, $pop0, $2 +; NOFP16-NEXT: return $pop1 +; +; NOSIMD-LABEL: fmuladd_f64: +; NOSIMD: .functype fmuladd_f64 (f64, f64, f64) -> (f64) +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: f64.mul $push0=, $0, $1 +; NOSIMD-NEXT: f64.add $push1=, $pop0, $2 +; NOSIMD-NEXT: return $pop1 + %fma = call double @llvm.fmuladd(double %a, double %b, double %c) + ret double %fma +} + +define double @fmuladd_contract_f64(double %a, double %b, double %c) { +; RELAXED-LABEL: fmuladd_contract_f64: +; RELAXED: .functype fmuladd_contract_f64 (f64, f64, f64) -> (f64) +; RELAXED-NEXT: # %bb.0: +; RELAXED-NEXT: f64.mul $push0=, $0, $1 +; RELAXED-NEXT: f64.add $push1=, $pop0, $2 +; RELAXED-NEXT: return $pop1 +; +; STRICT-LABEL: fmuladd_contract_f64: +; STRICT: .functype fmuladd_contract_f64 (f64, f64, f64) -> (f64) +; STRICT-NEXT: # %bb.0: +; STRICT-NEXT: f64.mul $push0=, $0, $1 +; STRICT-NEXT: f64.add $push1=, $pop0, $2 +; STRICT-NEXT: return $pop1 +; +; NOFP16-LABEL: fmuladd_contract_f64: +; NOFP16: .functype fmuladd_contract_f64 (f64, f64, f64) -> (f64) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: f64.mul $push0=, $0, $1 +; NOFP16-NEXT: f64.add $push1=, $pop0, $2 +; NOFP16-NEXT: return $pop1 +; +; NOSIMD-LABEL: fmuladd_contract_f64: +; NOSIMD: .functype fmuladd_contract_f64 (f64, f64, f64) -> (f64) +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: f64.mul $push0=, $0, $1 +; NOSIMD-NEXT: f64.add $push1=, $pop0, $2 +; NOSIMD-NEXT: return $pop1 + %fma = call contract double @llvm.fmuladd(double %a, double %b, double %c) + ret double %fma +} + define <4 x float> @fadd_fmul_contract_4xf32(<4 x float> %a, <4 x float> %b, <4 x float> %c) { ; RELAXED-LABEL: fadd_fmul_contract_4xf32: ; RELAXED: .functype fadd_fmul_contract_4xf32 (v128, v128, v128) -> (v128) ; RELAXED-NEXT: # %bb.0: -; RELAXED-NEXT: f32x4.relaxed_madd $push0=, $2, $1, $0 +; RELAXED-NEXT: f32x4.relaxed_madd $push0=, $1, $0, $2 ; RELAXED-NEXT: return $pop0 ; ; STRICT-LABEL: fadd_fmul_contract_4xf32: @@ -37,31 +384,222 @@ define <4 x float> @fadd_fmul_contract_4xf32(<4 x float> %a, <4 x float> %b, <4 ; STRICT-NEXT: f32x4.mul $push0=, $1, $0 ; STRICT-NEXT: f32x4.add $push1=, $pop0, $2 ; STRICT-NEXT: return $pop1 +; +; NOFP16-LABEL: fadd_fmul_contract_4xf32: +; NOFP16: .functype fadd_fmul_contract_4xf32 (v128, v128, v128) -> (v128) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: f32x4.mul $push0=, $1, $0 +; NOFP16-NEXT: f32x4.add $push1=, $pop0, $2 +; NOFP16-NEXT: return $pop1 +; +; NOSIMD-LABEL: fadd_fmul_contract_4xf32: +; NOSIMD: .functype fadd_fmul_contract_4xf32 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> () +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: f32.mul $push0=, $8, $4 +; NOSIMD-NEXT: f32.add $push1=, $pop0, $12 +; NOSIMD-NEXT: f32.store 12($0), $pop1 +; NOSIMD-NEXT: f32.mul $push2=, $7, $3 +; NOSIMD-NEXT: f32.add $push3=, $pop2, $11 +; NOSIMD-NEXT: f32.store 8($0), $pop3 +; NOSIMD-NEXT: f32.mul $push4=, $6, $2 +; NOSIMD-NEXT: f32.add $push5=, $pop4, $10 +; NOSIMD-NEXT: f32.store 4($0), $pop5 +; NOSIMD-NEXT: f32.mul $push6=, $5, $1 +; NOSIMD-NEXT: f32.add $push7=, $pop6, $9 +; NOSIMD-NEXT: f32.store 0($0), $pop7 +; NOSIMD-NEXT: return %mul = fmul contract <4 x float> %b, %a %add = fadd contract <4 x float> %mul, %c ret <4 x float> %add } - define <8 x half> @fadd_fmul_contract_8xf16(<8 x half> %a, <8 x half> %b, <8 x half> %c) { ; RELAXED-LABEL: fadd_fmul_contract_8xf16: ; RELAXED: .functype fadd_fmul_contract_8xf16 (v128, v128, v128) -> (v128) ; RELAXED-NEXT: # %bb.0: -; RELAXED-NEXT: f16x8.relaxed_madd $push0=, $2, $1, $0 +; RELAXED-NEXT: f16x8.madd $push0=, $1, $0, $2 ; RELAXED-NEXT: return $pop0 ; ; STRICT-LABEL: fadd_fmul_contract_8xf16: ; STRICT: .functype fadd_fmul_contract_8xf16 (v128, v128, v128) -> (v128) ; STRICT-NEXT: # %bb.0: -; STRICT-NEXT: f16x8.mul $push0=, $1, $0 -; STRICT-NEXT: f16x8.add $push1=, $pop0, $2 -; STRICT-NEXT: return $pop1 +; STRICT-NEXT: f16x8.madd $push0=, $1, $0, $2 +; STRICT-NEXT: return $pop0 +; +; NOFP16-LABEL: fadd_fmul_contract_8xf16: +; NOFP16: .functype fadd_fmul_contract_8xf16 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> () +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: call $push0=, __truncsfhf2, $8 +; NOFP16-NEXT: call $push1=, __extendhfsf2, $pop0 +; NOFP16-NEXT: call $push2=, __truncsfhf2, $16 +; NOFP16-NEXT: call $push3=, __extendhfsf2, $pop2 +; NOFP16-NEXT: f32.mul $push4=, $pop1, $pop3 +; NOFP16-NEXT: call $push5=, __truncsfhf2, $24 +; NOFP16-NEXT: call $push6=, __extendhfsf2, $pop5 +; NOFP16-NEXT: f32.add $push7=, $pop4, $pop6 +; NOFP16-NEXT: call $push8=, __truncsfhf2, $pop7 +; NOFP16-NEXT: i32.store16 14($0), $pop8 +; NOFP16-NEXT: call $push9=, __truncsfhf2, $7 +; NOFP16-NEXT: call $push10=, __extendhfsf2, $pop9 +; NOFP16-NEXT: call $push11=, __truncsfhf2, $15 +; NOFP16-NEXT: call $push12=, __extendhfsf2, $pop11 +; NOFP16-NEXT: f32.mul $push13=, $pop10, $pop12 +; NOFP16-NEXT: call $push14=, __truncsfhf2, $23 +; NOFP16-NEXT: call $push15=, __extendhfsf2, $pop14 +; NOFP16-NEXT: f32.add $push16=, $pop13, $pop15 +; NOFP16-NEXT: call $push17=, __truncsfhf2, $pop16 +; NOFP16-NEXT: i32.store16 12($0), $pop17 +; NOFP16-NEXT: call $push18=, __truncsfhf2, $6 +; NOFP16-NEXT: call $push19=, __extendhfsf2, $pop18 +; NOFP16-NEXT: call $push20=, __truncsfhf2, $14 +; NOFP16-NEXT: call $push21=, __extendhfsf2, $pop20 +; NOFP16-NEXT: f32.mul $push22=, $pop19, $pop21 +; NOFP16-NEXT: call $push23=, __truncsfhf2, $22 +; NOFP16-NEXT: call $push24=, __extendhfsf2, $pop23 +; NOFP16-NEXT: f32.add $push25=, $pop22, $pop24 +; NOFP16-NEXT: call $push26=, __truncsfhf2, $pop25 +; NOFP16-NEXT: i32.store16 10($0), $pop26 +; NOFP16-NEXT: call $push27=, __truncsfhf2, $5 +; NOFP16-NEXT: call $push28=, __extendhfsf2, $pop27 +; NOFP16-NEXT: call $push29=, __truncsfhf2, $13 +; NOFP16-NEXT: call $push30=, __extendhfsf2, $pop29 +; NOFP16-NEXT: f32.mul $push31=, $pop28, $pop30 +; NOFP16-NEXT: call $push32=, __truncsfhf2, $21 +; NOFP16-NEXT: call $push33=, __extendhfsf2, $pop32 +; NOFP16-NEXT: f32.add $push34=, $pop31, $pop33 +; NOFP16-NEXT: call $push35=, __truncsfhf2, $pop34 +; NOFP16-NEXT: i32.store16 8($0), $pop35 +; NOFP16-NEXT: call $push36=, __truncsfhf2, $4 +; NOFP16-NEXT: call $push37=, __extendhfsf2, $pop36 +; NOFP16-NEXT: call $push38=, __truncsfhf2, $12 +; NOFP16-NEXT: call $push39=, __extendhfsf2, $pop38 +; NOFP16-NEXT: f32.mul $push40=, $pop37, $pop39 +; NOFP16-NEXT: call $push41=, __truncsfhf2, $20 +; NOFP16-NEXT: call $push42=, __extendhfsf2, $pop41 +; NOFP16-NEXT: f32.add $push43=, $pop40, $pop42 +; NOFP16-NEXT: call $push44=, __truncsfhf2, $pop43 +; NOFP16-NEXT: i32.store16 6($0), $pop44 +; NOFP16-NEXT: call $push45=, __truncsfhf2, $3 +; NOFP16-NEXT: call $push46=, __extendhfsf2, $pop45 +; NOFP16-NEXT: call $push47=, __truncsfhf2, $11 +; NOFP16-NEXT: call $push48=, __extendhfsf2, $pop47 +; NOFP16-NEXT: f32.mul $push49=, $pop46, $pop48 +; NOFP16-NEXT: call $push50=, __truncsfhf2, $19 +; NOFP16-NEXT: call $push51=, __extendhfsf2, $pop50 +; NOFP16-NEXT: f32.add $push52=, $pop49, $pop51 +; NOFP16-NEXT: call $push53=, __truncsfhf2, $pop52 +; NOFP16-NEXT: i32.store16 4($0), $pop53 +; NOFP16-NEXT: call $push54=, __truncsfhf2, $2 +; NOFP16-NEXT: call $push55=, __extendhfsf2, $pop54 +; NOFP16-NEXT: call $push56=, __truncsfhf2, $10 +; NOFP16-NEXT: call $push57=, __extendhfsf2, $pop56 +; NOFP16-NEXT: f32.mul $push58=, $pop55, $pop57 +; NOFP16-NEXT: call $push59=, __truncsfhf2, $18 +; NOFP16-NEXT: call $push60=, __extendhfsf2, $pop59 +; NOFP16-NEXT: f32.add $push61=, $pop58, $pop60 +; NOFP16-NEXT: call $push62=, __truncsfhf2, $pop61 +; NOFP16-NEXT: i32.store16 2($0), $pop62 +; NOFP16-NEXT: call $push63=, __truncsfhf2, $1 +; NOFP16-NEXT: call $push64=, __extendhfsf2, $pop63 +; NOFP16-NEXT: call $push65=, __truncsfhf2, $9 +; NOFP16-NEXT: call $push66=, __extendhfsf2, $pop65 +; NOFP16-NEXT: f32.mul $push67=, $pop64, $pop66 +; NOFP16-NEXT: call $push68=, __truncsfhf2, $17 +; NOFP16-NEXT: call $push69=, __extendhfsf2, $pop68 +; NOFP16-NEXT: f32.add $push70=, $pop67, $pop69 +; NOFP16-NEXT: call $push71=, __truncsfhf2, $pop70 +; NOFP16-NEXT: i32.store16 0($0), $pop71 +; NOFP16-NEXT: return +; +; NOSIMD-LABEL: fadd_fmul_contract_8xf16: +; NOSIMD: .functype fadd_fmul_contract_8xf16 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> () +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: call $push0=, __truncsfhf2, $8 +; NOSIMD-NEXT: call $push1=, __extendhfsf2, $pop0 +; NOSIMD-NEXT: call $push2=, __truncsfhf2, $16 +; NOSIMD-NEXT: call $push3=, __extendhfsf2, $pop2 +; NOSIMD-NEXT: f32.mul $push4=, $pop1, $pop3 +; NOSIMD-NEXT: call $push5=, __truncsfhf2, $24 +; NOSIMD-NEXT: call $push6=, __extendhfsf2, $pop5 +; NOSIMD-NEXT: f32.add $push7=, $pop4, $pop6 +; NOSIMD-NEXT: call $push8=, __truncsfhf2, $pop7 +; NOSIMD-NEXT: i32.store16 14($0), $pop8 +; NOSIMD-NEXT: call $push9=, __truncsfhf2, $7 +; NOSIMD-NEXT: call $push10=, __extendhfsf2, $pop9 +; NOSIMD-NEXT: call $push11=, __truncsfhf2, $15 +; NOSIMD-NEXT: call $push12=, __extendhfsf2, $pop11 +; NOSIMD-NEXT: f32.mul $push13=, $pop10, $pop12 +; NOSIMD-NEXT: call $push14=, __truncsfhf2, $23 +; NOSIMD-NEXT: call $push15=, __extendhfsf2, $pop14 +; NOSIMD-NEXT: f32.add $push16=, $pop13, $pop15 +; NOSIMD-NEXT: call $push17=, __truncsfhf2, $pop16 +; NOSIMD-NEXT: i32.store16 12($0), $pop17 +; NOSIMD-NEXT: call $push18=, __truncsfhf2, $6 +; NOSIMD-NEXT: call $push19=, __extendhfsf2, $pop18 +; NOSIMD-NEXT: call $push20=, __truncsfhf2, $14 +; NOSIMD-NEXT: call $push21=, __extendhfsf2, $pop20 +; NOSIMD-NEXT: f32.mul $push22=, $pop19, $pop21 +; NOSIMD-NEXT: call $push23=, __truncsfhf2, $22 +; NOSIMD-NEXT: call $push24=, __extendhfsf2, $pop23 +; NOSIMD-NEXT: f32.add $push25=, $pop22, $pop24 +; NOSIMD-NEXT: call $push26=, __truncsfhf2, $pop25 +; NOSIMD-NEXT: i32.store16 10($0), $pop26 +; NOSIMD-NEXT: call $push27=, __truncsfhf2, $5 +; NOSIMD-NEXT: call $push28=, __extendhfsf2, $pop27 +; NOSIMD-NEXT: call $push29=, __truncsfhf2, $13 +; NOSIMD-NEXT: call $push30=, __extendhfsf2, $pop29 +; NOSIMD-NEXT: f32.mul $push31=, $pop28, $pop30 +; NOSIMD-NEXT: call $push32=, __truncsfhf2, $21 +; NOSIMD-NEXT: call $push33=, __extendhfsf2, $pop32 +; NOSIMD-NEXT: f32.add $push34=, $pop31, $pop33 +; NOSIMD-NEXT: call $push35=, __truncsfhf2, $pop34 +; NOSIMD-NEXT: i32.store16 8($0), $pop35 +; NOSIMD-NEXT: call $push36=, __truncsfhf2, $4 +; NOSIMD-NEXT: call $push37=, __extendhfsf2, $pop36 +; NOSIMD-NEXT: call $push38=, __truncsfhf2, $12 +; NOSIMD-NEXT: call $push39=, __extendhfsf2, $pop38 +; NOSIMD-NEXT: f32.mul $push40=, $pop37, $pop39 +; NOSIMD-NEXT: call $push41=, __truncsfhf2, $20 +; NOSIMD-NEXT: call $push42=, __extendhfsf2, $pop41 +; NOSIMD-NEXT: f32.add $push43=, $pop40, $pop42 +; NOSIMD-NEXT: call $push44=, __truncsfhf2, $pop43 +; NOSIMD-NEXT: i32.store16 6($0), $pop44 +; NOSIMD-NEXT: call $push45=, __truncsfhf2, $3 +; NOSIMD-NEXT: call $push46=, __extendhfsf2, $pop45 +; NOSIMD-NEXT: call $push47=, __truncsfhf2, $11 +; NOSIMD-NEXT: call $push48=, __extendhfsf2, $pop47 +; NOSIMD-NEXT: f32.mul $push49=, $pop46, $pop48 +; NOSIMD-NEXT: call $push50=, __truncsfhf2, $19 +; NOSIMD-NEXT: call $push51=, __extendhfsf2, $pop50 +; NOSIMD-NEXT: f32.add $push52=, $pop49, $pop51 +; NOSIMD-NEXT: call $push53=, __truncsfhf2, $pop52 +; NOSIMD-NEXT: i32.store16 4($0), $pop53 +; NOSIMD-NEXT: call $push54=, __truncsfhf2, $2 +; NOSIMD-NEXT: call $push55=, __extendhfsf2, $pop54 +; NOSIMD-NEXT: call $push56=, __truncsfhf2, $10 +; NOSIMD-NEXT: call $push57=, __extendhfsf2, $pop56 +; NOSIMD-NEXT: f32.mul $push58=, $pop55, $pop57 +; NOSIMD-NEXT: call $push59=, __truncsfhf2, $18 +; NOSIMD-NEXT: call $push60=, __extendhfsf2, $pop59 +; NOSIMD-NEXT: f32.add $push61=, $pop58, $pop60 +; NOSIMD-NEXT: call $push62=, __truncsfhf2, $pop61 +; NOSIMD-NEXT: i32.store16 2($0), $pop62 +; NOSIMD-NEXT: call $push63=, __truncsfhf2, $1 +; NOSIMD-NEXT: call $push64=, __extendhfsf2, $pop63 +; NOSIMD-NEXT: call $push65=, __truncsfhf2, $9 +; NOSIMD-NEXT: call $push66=, __extendhfsf2, $pop65 +; NOSIMD-NEXT: f32.mul $push67=, $pop64, $pop66 +; NOSIMD-NEXT: call $push68=, __truncsfhf2, $17 +; NOSIMD-NEXT: call $push69=, __extendhfsf2, $pop68 +; NOSIMD-NEXT: f32.add $push70=, $pop67, $pop69 +; NOSIMD-NEXT: call $push71=, __truncsfhf2, $pop70 +; NOSIMD-NEXT: i32.store16 0($0), $pop71 +; NOSIMD-NEXT: return %mul = fmul contract <8 x half> %b, %a %add = fadd contract <8 x half> %mul, %c ret <8 x half> %add } - define <4 x float> @fadd_fmul_4xf32(<4 x float> %a, <4 x float> %b, <4 x float> %c) { ; RELAXED-LABEL: fadd_fmul_4xf32: ; RELAXED: .functype fadd_fmul_4xf32 (v128, v128, v128) -> (v128) @@ -76,16 +614,412 @@ define <4 x float> @fadd_fmul_4xf32(<4 x float> %a, <4 x float> %b, <4 x float> ; STRICT-NEXT: f32x4.mul $push0=, $1, $0 ; STRICT-NEXT: f32x4.add $push1=, $pop0, $2 ; STRICT-NEXT: return $pop1 +; +; NOFP16-LABEL: fadd_fmul_4xf32: +; NOFP16: .functype fadd_fmul_4xf32 (v128, v128, v128) -> (v128) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: f32x4.mul $push0=, $1, $0 +; NOFP16-NEXT: f32x4.add $push1=, $pop0, $2 +; NOFP16-NEXT: return $pop1 +; +; NOSIMD-LABEL: fadd_fmul_4xf32: +; NOSIMD: .functype fadd_fmul_4xf32 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> () +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: f32.mul $push0=, $8, $4 +; NOSIMD-NEXT: f32.add $push1=, $pop0, $12 +; NOSIMD-NEXT: f32.store 12($0), $pop1 +; NOSIMD-NEXT: f32.mul $push2=, $7, $3 +; NOSIMD-NEXT: f32.add $push3=, $pop2, $11 +; NOSIMD-NEXT: f32.store 8($0), $pop3 +; NOSIMD-NEXT: f32.mul $push4=, $6, $2 +; NOSIMD-NEXT: f32.add $push5=, $pop4, $10 +; NOSIMD-NEXT: f32.store 4($0), $pop5 +; NOSIMD-NEXT: f32.mul $push6=, $5, $1 +; NOSIMD-NEXT: f32.add $push7=, $pop6, $9 +; NOSIMD-NEXT: f32.store 0($0), $pop7 +; NOSIMD-NEXT: return %mul = fmul <4 x float> %b, %a %add = fadd contract <4 x float> %mul, %c ret <4 x float> %add } +define <8 x half> @fmuladd_contract_8xf16(<8 x half> %a, <8 x half> %b, <8 x half> %c) { +; RELAXED-LABEL: fmuladd_contract_8xf16: +; RELAXED: .functype fmuladd_contract_8xf16 (v128, v128, v128) -> (v128) +; RELAXED-NEXT: # %bb.0: +; RELAXED-NEXT: f16x8.madd $push0=, $0, $1, $2 +; RELAXED-NEXT: return $pop0 +; +; STRICT-LABEL: fmuladd_contract_8xf16: +; STRICT: .functype fmuladd_contract_8xf16 (v128, v128, v128) -> (v128) +; STRICT-NEXT: # %bb.0: +; STRICT-NEXT: f16x8.madd $push0=, $0, $1, $2 +; STRICT-NEXT: return $pop0 +; +; NOFP16-LABEL: fmuladd_contract_8xf16: +; NOFP16: .functype fmuladd_contract_8xf16 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> () +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: call $push0=, __truncsfhf2, $16 +; NOFP16-NEXT: call $push1=, __extendhfsf2, $pop0 +; NOFP16-NEXT: call $push2=, __truncsfhf2, $8 +; NOFP16-NEXT: call $push3=, __extendhfsf2, $pop2 +; NOFP16-NEXT: f32.mul $push4=, $pop1, $pop3 +; NOFP16-NEXT: call $push5=, __truncsfhf2, $24 +; NOFP16-NEXT: call $push6=, __extendhfsf2, $pop5 +; NOFP16-NEXT: f32.add $push7=, $pop4, $pop6 +; NOFP16-NEXT: call $push8=, __truncsfhf2, $pop7 +; NOFP16-NEXT: i32.store16 14($0), $pop8 +; NOFP16-NEXT: call $push9=, __truncsfhf2, $15 +; NOFP16-NEXT: call $push10=, __extendhfsf2, $pop9 +; NOFP16-NEXT: call $push11=, __truncsfhf2, $7 +; NOFP16-NEXT: call $push12=, __extendhfsf2, $pop11 +; NOFP16-NEXT: f32.mul $push13=, $pop10, $pop12 +; NOFP16-NEXT: call $push14=, __truncsfhf2, $23 +; NOFP16-NEXT: call $push15=, __extendhfsf2, $pop14 +; NOFP16-NEXT: f32.add $push16=, $pop13, $pop15 +; NOFP16-NEXT: call $push17=, __truncsfhf2, $pop16 +; NOFP16-NEXT: i32.store16 12($0), $pop17 +; NOFP16-NEXT: call $push18=, __truncsfhf2, $14 +; NOFP16-NEXT: call $push19=, __extendhfsf2, $pop18 +; NOFP16-NEXT: call $push20=, __truncsfhf2, $6 +; NOFP16-NEXT: call $push21=, __extendhfsf2, $pop20 +; NOFP16-NEXT: f32.mul $push22=, $pop19, $pop21 +; NOFP16-NEXT: call $push23=, __truncsfhf2, $22 +; NOFP16-NEXT: call $push24=, __extendhfsf2, $pop23 +; NOFP16-NEXT: f32.add $push25=, $pop22, $pop24 +; NOFP16-NEXT: call $push26=, __truncsfhf2, $pop25 +; NOFP16-NEXT: i32.store16 10($0), $pop26 +; NOFP16-NEXT: call $push27=, __truncsfhf2, $13 +; NOFP16-NEXT: call $push28=, __extendhfsf2, $pop27 +; NOFP16-NEXT: call $push29=, __truncsfhf2, $5 +; NOFP16-NEXT: call $push30=, __extendhfsf2, $pop29 +; NOFP16-NEXT: f32.mul $push31=, $pop28, $pop30 +; NOFP16-NEXT: call $push32=, __truncsfhf2, $21 +; NOFP16-NEXT: call $push33=, __extendhfsf2, $pop32 +; NOFP16-NEXT: f32.add $push34=, $pop31, $pop33 +; NOFP16-NEXT: call $push35=, __truncsfhf2, $pop34 +; NOFP16-NEXT: i32.store16 8($0), $pop35 +; NOFP16-NEXT: call $push36=, __truncsfhf2, $12 +; NOFP16-NEXT: call $push37=, __extendhfsf2, $pop36 +; NOFP16-NEXT: call $push38=, __truncsfhf2, $4 +; NOFP16-NEXT: call $push39=, __extendhfsf2, $pop38 +; NOFP16-NEXT: f32.mul $push40=, $pop37, $pop39 +; NOFP16-NEXT: call $push41=, __truncsfhf2, $20 +; NOFP16-NEXT: call $push42=, __extendhfsf2, $pop41 +; NOFP16-NEXT: f32.add $push43=, $pop40, $pop42 +; NOFP16-NEXT: call $push44=, __truncsfhf2, $pop43 +; NOFP16-NEXT: i32.store16 6($0), $pop44 +; NOFP16-NEXT: call $push45=, __truncsfhf2, $11 +; NOFP16-NEXT: call $push46=, __extendhfsf2, $pop45 +; NOFP16-NEXT: call $push47=, __truncsfhf2, $3 +; NOFP16-NEXT: call $push48=, __extendhfsf2, $pop47 +; NOFP16-NEXT: f32.mul $push49=, $pop46, $pop48 +; NOFP16-NEXT: call $push50=, __truncsfhf2, $19 +; NOFP16-NEXT: call $push51=, __extendhfsf2, $pop50 +; NOFP16-NEXT: f32.add $push52=, $pop49, $pop51 +; NOFP16-NEXT: call $push53=, __truncsfhf2, $pop52 +; NOFP16-NEXT: i32.store16 4($0), $pop53 +; NOFP16-NEXT: call $push54=, __truncsfhf2, $10 +; NOFP16-NEXT: call $push55=, __extendhfsf2, $pop54 +; NOFP16-NEXT: call $push56=, __truncsfhf2, $2 +; NOFP16-NEXT: call $push57=, __extendhfsf2, $pop56 +; NOFP16-NEXT: f32.mul $push58=, $pop55, $pop57 +; NOFP16-NEXT: call $push59=, __truncsfhf2, $18 +; NOFP16-NEXT: call $push60=, __extendhfsf2, $pop59 +; NOFP16-NEXT: f32.add $push61=, $pop58, $pop60 +; NOFP16-NEXT: call $push62=, __truncsfhf2, $pop61 +; NOFP16-NEXT: i32.store16 2($0), $pop62 +; NOFP16-NEXT: call $push63=, __truncsfhf2, $9 +; NOFP16-NEXT: call $push64=, __extendhfsf2, $pop63 +; NOFP16-NEXT: call $push65=, __truncsfhf2, $1 +; NOFP16-NEXT: call $push66=, __extendhfsf2, $pop65 +; NOFP16-NEXT: f32.mul $push67=, $pop64, $pop66 +; NOFP16-NEXT: call $push68=, __truncsfhf2, $17 +; NOFP16-NEXT: call $push69=, __extendhfsf2, $pop68 +; NOFP16-NEXT: f32.add $push70=, $pop67, $pop69 +; NOFP16-NEXT: call $push71=, __truncsfhf2, $pop70 +; NOFP16-NEXT: i32.store16 0($0), $pop71 +; NOFP16-NEXT: return +; +; NOSIMD-LABEL: fmuladd_contract_8xf16: +; NOSIMD: .functype fmuladd_contract_8xf16 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> () +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: call $push0=, __truncsfhf2, $16 +; NOSIMD-NEXT: call $push1=, __extendhfsf2, $pop0 +; NOSIMD-NEXT: call $push2=, __truncsfhf2, $8 +; NOSIMD-NEXT: call $push3=, __extendhfsf2, $pop2 +; NOSIMD-NEXT: f32.mul $push4=, $pop1, $pop3 +; NOSIMD-NEXT: call $push5=, __truncsfhf2, $24 +; NOSIMD-NEXT: call $push6=, __extendhfsf2, $pop5 +; NOSIMD-NEXT: f32.add $push7=, $pop4, $pop6 +; NOSIMD-NEXT: call $push8=, __truncsfhf2, $pop7 +; NOSIMD-NEXT: i32.store16 14($0), $pop8 +; NOSIMD-NEXT: call $push9=, __truncsfhf2, $15 +; NOSIMD-NEXT: call $push10=, __extendhfsf2, $pop9 +; NOSIMD-NEXT: call $push11=, __truncsfhf2, $7 +; NOSIMD-NEXT: call $push12=, __extendhfsf2, $pop11 +; NOSIMD-NEXT: f32.mul $push13=, $pop10, $pop12 +; NOSIMD-NEXT: call $push14=, __truncsfhf2, $23 +; NOSIMD-NEXT: call $push15=, __extendhfsf2, $pop14 +; NOSIMD-NEXT: f32.add $push16=, $pop13, $pop15 +; NOSIMD-NEXT: call $push17=, __truncsfhf2, $pop16 +; NOSIMD-NEXT: i32.store16 12($0), $pop17 +; NOSIMD-NEXT: call $push18=, __truncsfhf2, $14 +; NOSIMD-NEXT: call $push19=, __extendhfsf2, $pop18 +; NOSIMD-NEXT: call $push20=, __truncsfhf2, $6 +; NOSIMD-NEXT: call $push21=, __extendhfsf2, $pop20 +; NOSIMD-NEXT: f32.mul $push22=, $pop19, $pop21 +; NOSIMD-NEXT: call $push23=, __truncsfhf2, $22 +; NOSIMD-NEXT: call $push24=, __extendhfsf2, $pop23 +; NOSIMD-NEXT: f32.add $push25=, $pop22, $pop24 +; NOSIMD-NEXT: call $push26=, __truncsfhf2, $pop25 +; NOSIMD-NEXT: i32.store16 10($0), $pop26 +; NOSIMD-NEXT: call $push27=, __truncsfhf2, $13 +; NOSIMD-NEXT: call $push28=, __extendhfsf2, $pop27 +; NOSIMD-NEXT: call $push29=, __truncsfhf2, $5 +; NOSIMD-NEXT: call $push30=, __extendhfsf2, $pop29 +; NOSIMD-NEXT: f32.mul $push31=, $pop28, $pop30 +; NOSIMD-NEXT: call $push32=, __truncsfhf2, $21 +; NOSIMD-NEXT: call $push33=, __extendhfsf2, $pop32 +; NOSIMD-NEXT: f32.add $push34=, $pop31, $pop33 +; NOSIMD-NEXT: call $push35=, __truncsfhf2, $pop34 +; NOSIMD-NEXT: i32.store16 8($0), $pop35 +; NOSIMD-NEXT: call $push36=, __truncsfhf2, $12 +; NOSIMD-NEXT: call $push37=, __extendhfsf2, $pop36 +; NOSIMD-NEXT: call $push38=, __truncsfhf2, $4 +; NOSIMD-NEXT: call $push39=, __extendhfsf2, $pop38 +; NOSIMD-NEXT: f32.mul $push40=, $pop37, $pop39 +; NOSIMD-NEXT: call $push41=, __truncsfhf2, $20 +; NOSIMD-NEXT: call $push42=, __extendhfsf2, $pop41 +; NOSIMD-NEXT: f32.add $push43=, $pop40, $pop42 +; NOSIMD-NEXT: call $push44=, __truncsfhf2, $pop43 +; NOSIMD-NEXT: i32.store16 6($0), $pop44 +; NOSIMD-NEXT: call $push45=, __truncsfhf2, $11 +; NOSIMD-NEXT: call $push46=, __extendhfsf2, $pop45 +; NOSIMD-NEXT: call $push47=, __truncsfhf2, $3 +; NOSIMD-NEXT: call $push48=, __extendhfsf2, $pop47 +; NOSIMD-NEXT: f32.mul $push49=, $pop46, $pop48 +; NOSIMD-NEXT: call $push50=, __truncsfhf2, $19 +; NOSIMD-NEXT: call $push51=, __extendhfsf2, $pop50 +; NOSIMD-NEXT: f32.add $push52=, $pop49, $pop51 +; NOSIMD-NEXT: call $push53=, __truncsfhf2, $pop52 +; NOSIMD-NEXT: i32.store16 4($0), $pop53 +; NOSIMD-NEXT: call $push54=, __truncsfhf2, $10 +; NOSIMD-NEXT: call $push55=, __extendhfsf2, $pop54 +; NOSIMD-NEXT: call $push56=, __truncsfhf2, $2 +; NOSIMD-NEXT: call $push57=, __extendhfsf2, $pop56 +; NOSIMD-NEXT: f32.mul $push58=, $pop55, $pop57 +; NOSIMD-NEXT: call $push59=, __truncsfhf2, $18 +; NOSIMD-NEXT: call $push60=, __extendhfsf2, $pop59 +; NOSIMD-NEXT: f32.add $push61=, $pop58, $pop60 +; NOSIMD-NEXT: call $push62=, __truncsfhf2, $pop61 +; NOSIMD-NEXT: i32.store16 2($0), $pop62 +; NOSIMD-NEXT: call $push63=, __truncsfhf2, $9 +; NOSIMD-NEXT: call $push64=, __extendhfsf2, $pop63 +; NOSIMD-NEXT: call $push65=, __truncsfhf2, $1 +; NOSIMD-NEXT: call $push66=, __extendhfsf2, $pop65 +; NOSIMD-NEXT: f32.mul $push67=, $pop64, $pop66 +; NOSIMD-NEXT: call $push68=, __truncsfhf2, $17 +; NOSIMD-NEXT: call $push69=, __extendhfsf2, $pop68 +; NOSIMD-NEXT: f32.add $push70=, $pop67, $pop69 +; NOSIMD-NEXT: call $push71=, __truncsfhf2, $pop70 +; NOSIMD-NEXT: i32.store16 0($0), $pop71 +; NOSIMD-NEXT: return + %fma = call contract <8 x half> @llvm.fmuladd(<8 x half> %a, <8 x half> %b, <8 x half> %c) + ret <8 x half> %fma +} + +define <8 x half> @fmuladd_8xf16(<8 x half> %a, <8 x half> %b, <8 x half> %c) { +; RELAXED-LABEL: fmuladd_8xf16: +; RELAXED: .functype fmuladd_8xf16 (v128, v128, v128) -> (v128) +; RELAXED-NEXT: # %bb.0: +; RELAXED-NEXT: f16x8.madd $push0=, $0, $1, $2 +; RELAXED-NEXT: return $pop0 +; +; STRICT-LABEL: fmuladd_8xf16: +; STRICT: .functype fmuladd_8xf16 (v128, v128, v128) -> (v128) +; STRICT-NEXT: # %bb.0: +; STRICT-NEXT: f16x8.madd $push0=, $0, $1, $2 +; STRICT-NEXT: return $pop0 +; +; NOFP16-LABEL: fmuladd_8xf16: +; NOFP16: .functype fmuladd_8xf16 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> () +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: call $push0=, __truncsfhf2, $16 +; NOFP16-NEXT: call $push1=, __extendhfsf2, $pop0 +; NOFP16-NEXT: call $push2=, __truncsfhf2, $8 +; NOFP16-NEXT: call $push3=, __extendhfsf2, $pop2 +; NOFP16-NEXT: f32.mul $push4=, $pop1, $pop3 +; NOFP16-NEXT: call $push5=, __truncsfhf2, $24 +; NOFP16-NEXT: call $push6=, __extendhfsf2, $pop5 +; NOFP16-NEXT: f32.add $push7=, $pop4, $pop6 +; NOFP16-NEXT: call $push8=, __truncsfhf2, $pop7 +; NOFP16-NEXT: i32.store16 14($0), $pop8 +; NOFP16-NEXT: call $push9=, __truncsfhf2, $15 +; NOFP16-NEXT: call $push10=, __extendhfsf2, $pop9 +; NOFP16-NEXT: call $push11=, __truncsfhf2, $7 +; NOFP16-NEXT: call $push12=, __extendhfsf2, $pop11 +; NOFP16-NEXT: f32.mul $push13=, $pop10, $pop12 +; NOFP16-NEXT: call $push14=, __truncsfhf2, $23 +; NOFP16-NEXT: call $push15=, __extendhfsf2, $pop14 +; NOFP16-NEXT: f32.add $push16=, $pop13, $pop15 +; NOFP16-NEXT: call $push17=, __truncsfhf2, $pop16 +; NOFP16-NEXT: i32.store16 12($0), $pop17 +; NOFP16-NEXT: call $push18=, __truncsfhf2, $14 +; NOFP16-NEXT: call $push19=, __extendhfsf2, $pop18 +; NOFP16-NEXT: call $push20=, __truncsfhf2, $6 +; NOFP16-NEXT: call $push21=, __extendhfsf2, $pop20 +; NOFP16-NEXT: f32.mul $push22=, $pop19, $pop21 +; NOFP16-NEXT: call $push23=, __truncsfhf2, $22 +; NOFP16-NEXT: call $push24=, __extendhfsf2, $pop23 +; NOFP16-NEXT: f32.add $push25=, $pop22, $pop24 +; NOFP16-NEXT: call $push26=, __truncsfhf2, $pop25 +; NOFP16-NEXT: i32.store16 10($0), $pop26 +; NOFP16-NEXT: call $push27=, __truncsfhf2, $13 +; NOFP16-NEXT: call $push28=, __extendhfsf2, $pop27 +; NOFP16-NEXT: call $push29=, __truncsfhf2, $5 +; NOFP16-NEXT: call $push30=, __extendhfsf2, $pop29 +; NOFP16-NEXT: f32.mul $push31=, $pop28, $pop30 +; NOFP16-NEXT: call $push32=, __truncsfhf2, $21 +; NOFP16-NEXT: call $push33=, __extendhfsf2, $pop32 +; NOFP16-NEXT: f32.add $push34=, $pop31, $pop33 +; NOFP16-NEXT: call $push35=, __truncsfhf2, $pop34 +; NOFP16-NEXT: i32.store16 8($0), $pop35 +; NOFP16-NEXT: call $push36=, __truncsfhf2, $12 +; NOFP16-NEXT: call $push37=, __extendhfsf2, $pop36 +; NOFP16-NEXT: call $push38=, __truncsfhf2, $4 +; NOFP16-NEXT: call $push39=, __extendhfsf2, $pop38 +; NOFP16-NEXT: f32.mul $push40=, $pop37, $pop39 +; NOFP16-NEXT: call $push41=, __truncsfhf2, $20 +; NOFP16-NEXT: call $push42=, __extendhfsf2, $pop41 +; NOFP16-NEXT: f32.add $push43=, $pop40, $pop42 +; NOFP16-NEXT: call $push44=, __truncsfhf2, $pop43 +; NOFP16-NEXT: i32.store16 6($0), $pop44 +; NOFP16-NEXT: call $push45=, __truncsfhf2, $11 +; NOFP16-NEXT: call $push46=, __extendhfsf2, $pop45 +; NOFP16-NEXT: call $push47=, __truncsfhf2, $3 +; NOFP16-NEXT: call $push48=, __extendhfsf2, $pop47 +; NOFP16-NEXT: f32.mul $push49=, $pop46, $pop48 +; NOFP16-NEXT: call $push50=, __truncsfhf2, $19 +; NOFP16-NEXT: call $push51=, __extendhfsf2, $pop50 +; NOFP16-NEXT: f32.add $push52=, $pop49, $pop51 +; NOFP16-NEXT: call $push53=, __truncsfhf2, $pop52 +; NOFP16-NEXT: i32.store16 4($0), $pop53 +; NOFP16-NEXT: call $push54=, __truncsfhf2, $10 +; NOFP16-NEXT: call $push55=, __extendhfsf2, $pop54 +; NOFP16-NEXT: call $push56=, __truncsfhf2, $2 +; NOFP16-NEXT: call $push57=, __extendhfsf2, $pop56 +; NOFP16-NEXT: f32.mul $push58=, $pop55, $pop57 +; NOFP16-NEXT: call $push59=, __truncsfhf2, $18 +; NOFP16-NEXT: call $push60=, __extendhfsf2, $pop59 +; NOFP16-NEXT: f32.add $push61=, $pop58, $pop60 +; NOFP16-NEXT: call $push62=, __truncsfhf2, $pop61 +; NOFP16-NEXT: i32.store16 2($0), $pop62 +; NOFP16-NEXT: call $push63=, __truncsfhf2, $9 +; NOFP16-NEXT: call $push64=, __extendhfsf2, $pop63 +; NOFP16-NEXT: call $push65=, __truncsfhf2, $1 +; NOFP16-NEXT: call $push66=, __extendhfsf2, $pop65 +; NOFP16-NEXT: f32.mul $push67=, $pop64, $pop66 +; NOFP16-NEXT: call $push68=, __truncsfhf2, $17 +; NOFP16-NEXT: call $push69=, __extendhfsf2, $pop68 +; NOFP16-NEXT: f32.add $push70=, $pop67, $pop69 +; NOFP16-NEXT: call $push71=, __truncsfhf2, $pop70 +; NOFP16-NEXT: i32.store16 0($0), $pop71 +; NOFP16-NEXT: return +; +; NOSIMD-LABEL: fmuladd_8xf16: +; NOSIMD: .functype fmuladd_8xf16 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> () +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: call $push0=, __truncsfhf2, $16 +; NOSIMD-NEXT: call $push1=, __extendhfsf2, $pop0 +; NOSIMD-NEXT: call $push2=, __truncsfhf2, $8 +; NOSIMD-NEXT: call $push3=, __extendhfsf2, $pop2 +; NOSIMD-NEXT: f32.mul $push4=, $pop1, $pop3 +; NOSIMD-NEXT: call $push5=, __truncsfhf2, $24 +; NOSIMD-NEXT: call $push6=, __extendhfsf2, $pop5 +; NOSIMD-NEXT: f32.add $push7=, $pop4, $pop6 +; NOSIMD-NEXT: call $push8=, __truncsfhf2, $pop7 +; NOSIMD-NEXT: i32.store16 14($0), $pop8 +; NOSIMD-NEXT: call $push9=, __truncsfhf2, $15 +; NOSIMD-NEXT: call $push10=, __extendhfsf2, $pop9 +; NOSIMD-NEXT: call $push11=, __truncsfhf2, $7 +; NOSIMD-NEXT: call $push12=, __extendhfsf2, $pop11 +; NOSIMD-NEXT: f32.mul $push13=, $pop10, $pop12 +; NOSIMD-NEXT: call $push14=, __truncsfhf2, $23 +; NOSIMD-NEXT: call $push15=, __extendhfsf2, $pop14 +; NOSIMD-NEXT: f32.add $push16=, $pop13, $pop15 +; NOSIMD-NEXT: call $push17=, __truncsfhf2, $pop16 +; NOSIMD-NEXT: i32.store16 12($0), $pop17 +; NOSIMD-NEXT: call $push18=, __truncsfhf2, $14 +; NOSIMD-NEXT: call $push19=, __extendhfsf2, $pop18 +; NOSIMD-NEXT: call $push20=, __truncsfhf2, $6 +; NOSIMD-NEXT: call $push21=, __extendhfsf2, $pop20 +; NOSIMD-NEXT: f32.mul $push22=, $pop19, $pop21 +; NOSIMD-NEXT: call $push23=, __truncsfhf2, $22 +; NOSIMD-NEXT: call $push24=, __extendhfsf2, $pop23 +; NOSIMD-NEXT: f32.add $push25=, $pop22, $pop24 +; NOSIMD-NEXT: call $push26=, __truncsfhf2, $pop25 +; NOSIMD-NEXT: i32.store16 10($0), $pop26 +; NOSIMD-NEXT: call $push27=, __truncsfhf2, $13 +; NOSIMD-NEXT: call $push28=, __extendhfsf2, $pop27 +; NOSIMD-NEXT: call $push29=, __truncsfhf2, $5 +; NOSIMD-NEXT: call $push30=, __extendhfsf2, $pop29 +; NOSIMD-NEXT: f32.mul $push31=, $pop28, $pop30 +; NOSIMD-NEXT: call $push32=, __truncsfhf2, $21 +; NOSIMD-NEXT: call $push33=, __extendhfsf2, $pop32 +; NOSIMD-NEXT: f32.add $push34=, $pop31, $pop33 +; NOSIMD-NEXT: call $push35=, __truncsfhf2, $pop34 +; NOSIMD-NEXT: i32.store16 8($0), $pop35 +; NOSIMD-NEXT: call $push36=, __truncsfhf2, $12 +; NOSIMD-NEXT: call $push37=, __extendhfsf2, $pop36 +; NOSIMD-NEXT: call $push38=, __truncsfhf2, $4 +; NOSIMD-NEXT: call $push39=, __extendhfsf2, $pop38 +; NOSIMD-NEXT: f32.mul $push40=, $pop37, $pop39 +; NOSIMD-NEXT: call $push41=, __truncsfhf2, $20 +; NOSIMD-NEXT: call $push42=, __extendhfsf2, $pop41 +; NOSIMD-NEXT: f32.add $push43=, $pop40, $pop42 +; NOSIMD-NEXT: call $push44=, __truncsfhf2, $pop43 +; NOSIMD-NEXT: i32.store16 6($0), $pop44 +; NOSIMD-NEXT: call $push45=, __truncsfhf2, $11 +; NOSIMD-NEXT: call $push46=, __extendhfsf2, $pop45 +; NOSIMD-NEXT: call $push47=, __truncsfhf2, $3 +; NOSIMD-NEXT: call $push48=, __extendhfsf2, $pop47 +; NOSIMD-NEXT: f32.mul $push49=, $pop46, $pop48 +; NOSIMD-NEXT: call $push50=, __truncsfhf2, $19 +; NOSIMD-NEXT: call $push51=, __extendhfsf2, $pop50 +; NOSIMD-NEXT: f32.add $push52=, $pop49, $pop51 +; NOSIMD-NEXT: call $push53=, __truncsfhf2, $pop52 +; NOSIMD-NEXT: i32.store16 4($0), $pop53 +; NOSIMD-NEXT: call $push54=, __truncsfhf2, $10 +; NOSIMD-NEXT: call $push55=, __extendhfsf2, $pop54 +; NOSIMD-NEXT: call $push56=, __truncsfhf2, $2 +; NOSIMD-NEXT: call $push57=, __extendhfsf2, $pop56 +; NOSIMD-NEXT: f32.mul $push58=, $pop55, $pop57 +; NOSIMD-NEXT: call $push59=, __truncsfhf2, $18 +; NOSIMD-NEXT: call $push60=, __extendhfsf2, $pop59 +; NOSIMD-NEXT: f32.add $push61=, $pop58, $pop60 +; NOSIMD-NEXT: call $push62=, __truncsfhf2, $pop61 +; NOSIMD-NEXT: i32.store16 2($0), $pop62 +; NOSIMD-NEXT: call $push63=, __truncsfhf2, $9 +; NOSIMD-NEXT: call $push64=, __extendhfsf2, $pop63 +; NOSIMD-NEXT: call $push65=, __truncsfhf2, $1 +; NOSIMD-NEXT: call $push66=, __extendhfsf2, $pop65 +; NOSIMD-NEXT: f32.mul $push67=, $pop64, $pop66 +; NOSIMD-NEXT: call $push68=, __truncsfhf2, $17 +; NOSIMD-NEXT: call $push69=, __extendhfsf2, $pop68 +; NOSIMD-NEXT: f32.add $push70=, $pop67, $pop69 +; NOSIMD-NEXT: call $push71=, __truncsfhf2, $pop70 +; NOSIMD-NEXT: i32.store16 0($0), $pop71 +; NOSIMD-NEXT: return + %fma = call <8 x half> @llvm.fmuladd(<8 x half> %a, <8 x half> %b, <8 x half> %c) + ret <8 x half> %fma +} + define <4 x float> @fmuladd_contract_4xf32(<4 x float> %a, <4 x float> %b, <4 x float> %c) { ; RELAXED-LABEL: fmuladd_contract_4xf32: ; RELAXED: .functype fmuladd_contract_4xf32 (v128, v128, v128) -> (v128) ; RELAXED-NEXT: # %bb.0: -; RELAXED-NEXT: f32x4.relaxed_madd $push0=, $2, $0, $1 +; RELAXED-NEXT: f32x4.relaxed_madd $push0=, $0, $1, $2 ; RELAXED-NEXT: return $pop0 ; ; STRICT-LABEL: fmuladd_contract_4xf32: @@ -94,18 +1028,40 @@ define <4 x float> @fmuladd_contract_4xf32(<4 x float> %a, <4 x float> %b, <4 x ; STRICT-NEXT: f32x4.mul $push0=, $0, $1 ; STRICT-NEXT: f32x4.add $push1=, $pop0, $2 ; STRICT-NEXT: return $pop1 +; +; NOFP16-LABEL: fmuladd_contract_4xf32: +; NOFP16: .functype fmuladd_contract_4xf32 (v128, v128, v128) -> (v128) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: f32x4.mul $push0=, $0, $1 +; NOFP16-NEXT: f32x4.add $push1=, $pop0, $2 +; NOFP16-NEXT: return $pop1 +; +; NOSIMD-LABEL: fmuladd_contract_4xf32: +; NOSIMD: .functype fmuladd_contract_4xf32 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> () +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: f32.mul $push0=, $4, $8 +; NOSIMD-NEXT: f32.add $push1=, $pop0, $12 +; NOSIMD-NEXT: f32.store 12($0), $pop1 +; NOSIMD-NEXT: f32.mul $push2=, $3, $7 +; NOSIMD-NEXT: f32.add $push3=, $pop2, $11 +; NOSIMD-NEXT: f32.store 8($0), $pop3 +; NOSIMD-NEXT: f32.mul $push4=, $2, $6 +; NOSIMD-NEXT: f32.add $push5=, $pop4, $10 +; NOSIMD-NEXT: f32.store 4($0), $pop5 +; NOSIMD-NEXT: f32.mul $push6=, $1, $5 +; NOSIMD-NEXT: f32.add $push7=, $pop6, $9 +; NOSIMD-NEXT: f32.store 0($0), $pop7 +; NOSIMD-NEXT: return %fma = call contract <4 x float> @llvm.fmuladd(<4 x float> %a, <4 x float> %b, <4 x float> %c) ret <4 x float> %fma } -; TODO: This should also have relaxed_madd in RELAXED case define <4 x float> @fmuladd_4xf32(<4 x float> %a, <4 x float> %b, <4 x float> %c) { ; RELAXED-LABEL: fmuladd_4xf32: ; RELAXED: .functype fmuladd_4xf32 (v128, v128, v128) -> (v128) ; RELAXED-NEXT: # %bb.0: -; RELAXED-NEXT: f32x4.mul $push0=, $0, $1 -; RELAXED-NEXT: f32x4.add $push1=, $pop0, $2 -; RELAXED-NEXT: return $pop1 +; RELAXED-NEXT: f32x4.relaxed_madd $push0=, $0, $1, $2 +; RELAXED-NEXT: return $pop0 ; ; STRICT-LABEL: fmuladd_4xf32: ; STRICT: .functype fmuladd_4xf32 (v128, v128, v128) -> (v128) @@ -113,10 +1069,170 @@ define <4 x float> @fmuladd_4xf32(<4 x float> %a, <4 x float> %b, <4 x float> %c ; STRICT-NEXT: f32x4.mul $push0=, $0, $1 ; STRICT-NEXT: f32x4.add $push1=, $pop0, $2 ; STRICT-NEXT: return $pop1 +; +; NOFP16-LABEL: fmuladd_4xf32: +; NOFP16: .functype fmuladd_4xf32 (v128, v128, v128) -> (v128) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: f32x4.mul $push0=, $0, $1 +; NOFP16-NEXT: f32x4.add $push1=, $pop0, $2 +; NOFP16-NEXT: return $pop1 +; +; NOSIMD-LABEL: fmuladd_4xf32: +; NOSIMD: .functype fmuladd_4xf32 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> () +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: f32.mul $push0=, $4, $8 +; NOSIMD-NEXT: f32.add $push1=, $pop0, $12 +; NOSIMD-NEXT: f32.store 12($0), $pop1 +; NOSIMD-NEXT: f32.mul $push2=, $3, $7 +; NOSIMD-NEXT: f32.add $push3=, $pop2, $11 +; NOSIMD-NEXT: f32.store 8($0), $pop3 +; NOSIMD-NEXT: f32.mul $push4=, $2, $6 +; NOSIMD-NEXT: f32.add $push5=, $pop4, $10 +; NOSIMD-NEXT: f32.store 4($0), $pop5 +; NOSIMD-NEXT: f32.mul $push6=, $1, $5 +; NOSIMD-NEXT: f32.add $push7=, $pop6, $9 +; NOSIMD-NEXT: f32.store 0($0), $pop7 +; NOSIMD-NEXT: return %fma = call <4 x float> @llvm.fmuladd(<4 x float> %a, <4 x float> %b, <4 x float> %c) ret <4 x float> %fma } +define <8 x float> @fmuladd_8xf32(<8 x float> %a, <8 x float> %b, <8 x float> %c) { +; RELAXED-LABEL: fmuladd_8xf32: +; RELAXED: .functype fmuladd_8xf32 (i32, v128, v128, v128, v128, v128, v128) -> () +; RELAXED-NEXT: # %bb.0: +; RELAXED-NEXT: f32x4.mul $push0=, $2, $4 +; RELAXED-NEXT: f32x4.add $push1=, $pop0, $6 +; RELAXED-NEXT: v128.store 16($0), $pop1 +; RELAXED-NEXT: f32x4.mul $push2=, $1, $3 +; RELAXED-NEXT: f32x4.add $push3=, $pop2, $5 +; RELAXED-NEXT: v128.store 0($0), $pop3 +; RELAXED-NEXT: return +; +; STRICT-LABEL: fmuladd_8xf32: +; STRICT: .functype fmuladd_8xf32 (i32, v128, v128, v128, v128, v128, v128) -> () +; STRICT-NEXT: # %bb.0: +; STRICT-NEXT: f32x4.mul $push0=, $2, $4 +; STRICT-NEXT: f32x4.add $push1=, $pop0, $6 +; STRICT-NEXT: v128.store 16($0), $pop1 +; STRICT-NEXT: f32x4.mul $push2=, $1, $3 +; STRICT-NEXT: f32x4.add $push3=, $pop2, $5 +; STRICT-NEXT: v128.store 0($0), $pop3 +; STRICT-NEXT: return +; +; NOFP16-LABEL: fmuladd_8xf32: +; NOFP16: .functype fmuladd_8xf32 (i32, v128, v128, v128, v128, v128, v128) -> () +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: f32x4.mul $push0=, $2, $4 +; NOFP16-NEXT: f32x4.add $push1=, $pop0, $6 +; NOFP16-NEXT: v128.store 16($0), $pop1 +; NOFP16-NEXT: f32x4.mul $push2=, $1, $3 +; NOFP16-NEXT: f32x4.add $push3=, $pop2, $5 +; NOFP16-NEXT: v128.store 0($0), $pop3 +; NOFP16-NEXT: return +; +; NOSIMD-LABEL: fmuladd_8xf32: +; NOSIMD: .functype fmuladd_8xf32 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> () +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: f32.mul $push0=, $8, $16 +; NOSIMD-NEXT: f32.add $push1=, $pop0, $24 +; NOSIMD-NEXT: f32.store 28($0), $pop1 +; NOSIMD-NEXT: f32.mul $push2=, $7, $15 +; NOSIMD-NEXT: f32.add $push3=, $pop2, $23 +; NOSIMD-NEXT: f32.store 24($0), $pop3 +; NOSIMD-NEXT: f32.mul $push4=, $6, $14 +; NOSIMD-NEXT: f32.add $push5=, $pop4, $22 +; NOSIMD-NEXT: f32.store 20($0), $pop5 +; NOSIMD-NEXT: f32.mul $push6=, $5, $13 +; NOSIMD-NEXT: f32.add $push7=, $pop6, $21 +; NOSIMD-NEXT: f32.store 16($0), $pop7 +; NOSIMD-NEXT: f32.mul $push8=, $4, $12 +; NOSIMD-NEXT: f32.add $push9=, $pop8, $20 +; NOSIMD-NEXT: f32.store 12($0), $pop9 +; NOSIMD-NEXT: f32.mul $push10=, $3, $11 +; NOSIMD-NEXT: f32.add $push11=, $pop10, $19 +; NOSIMD-NEXT: f32.store 8($0), $pop11 +; NOSIMD-NEXT: f32.mul $push12=, $2, $10 +; NOSIMD-NEXT: f32.add $push13=, $pop12, $18 +; NOSIMD-NEXT: f32.store 4($0), $pop13 +; NOSIMD-NEXT: f32.mul $push14=, $1, $9 +; NOSIMD-NEXT: f32.add $push15=, $pop14, $17 +; NOSIMD-NEXT: f32.store 0($0), $pop15 +; NOSIMD-NEXT: return + %fma = call <8 x float> @llvm.fmuladd(<8 x float> %a, <8 x float> %b, <8 x float> %c) + ret <8 x float> %fma +} + +define <2 x double> @fmuladd_contract_2xf64(<2 x double> %a, <2 x double> %b, <2 x double> %c) { +; RELAXED-LABEL: fmuladd_contract_2xf64: +; RELAXED: .functype fmuladd_contract_2xf64 (v128, v128, v128) -> (v128) +; RELAXED-NEXT: # %bb.0: +; RELAXED-NEXT: f64x2.relaxed_madd $push0=, $0, $1, $2 +; RELAXED-NEXT: return $pop0 +; +; STRICT-LABEL: fmuladd_contract_2xf64: +; STRICT: .functype fmuladd_contract_2xf64 (v128, v128, v128) -> (v128) +; STRICT-NEXT: # %bb.0: +; STRICT-NEXT: f64x2.mul $push0=, $0, $1 +; STRICT-NEXT: f64x2.add $push1=, $pop0, $2 +; STRICT-NEXT: return $pop1 +; +; NOFP16-LABEL: fmuladd_contract_2xf64: +; NOFP16: .functype fmuladd_contract_2xf64 (v128, v128, v128) -> (v128) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: f64x2.mul $push0=, $0, $1 +; NOFP16-NEXT: f64x2.add $push1=, $pop0, $2 +; NOFP16-NEXT: return $pop1 +; +; NOSIMD-LABEL: fmuladd_contract_2xf64: +; NOSIMD: .functype fmuladd_contract_2xf64 (i32, f64, f64, f64, f64, f64, f64) -> () +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: f64.mul $push0=, $2, $4 +; NOSIMD-NEXT: f64.add $push1=, $pop0, $6 +; NOSIMD-NEXT: f64.store 8($0), $pop1 +; NOSIMD-NEXT: f64.mul $push2=, $1, $3 +; NOSIMD-NEXT: f64.add $push3=, $pop2, $5 +; NOSIMD-NEXT: f64.store 0($0), $pop3 +; NOSIMD-NEXT: return + %fma = call contract <2 x double> @llvm.fmuladd(<2 x double> %a, <2 x double> %b, <2 x double> %c) + ret <2 x double> %fma +} + +define <2 x double> @fmuladd_2xf64(<2 x double> %a, <2 x double> %b, <2 x double> %c) { +; RELAXED-LABEL: fmuladd_2xf64: +; RELAXED: .functype fmuladd_2xf64 (v128, v128, v128) -> (v128) +; RELAXED-NEXT: # %bb.0: +; RELAXED-NEXT: f64x2.relaxed_madd $push0=, $0, $1, $2 +; RELAXED-NEXT: return $pop0 +; +; STRICT-LABEL: fmuladd_2xf64: +; STRICT: .functype fmuladd_2xf64 (v128, v128, v128) -> (v128) +; STRICT-NEXT: # %bb.0: +; STRICT-NEXT: f64x2.mul $push0=, $0, $1 +; STRICT-NEXT: f64x2.add $push1=, $pop0, $2 +; STRICT-NEXT: return $pop1 +; +; NOFP16-LABEL: fmuladd_2xf64: +; NOFP16: .functype fmuladd_2xf64 (v128, v128, v128) -> (v128) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: f64x2.mul $push0=, $0, $1 +; NOFP16-NEXT: f64x2.add $push1=, $pop0, $2 +; NOFP16-NEXT: return $pop1 +; +; NOSIMD-LABEL: fmuladd_2xf64: +; NOSIMD: .functype fmuladd_2xf64 (i32, f64, f64, f64, f64, f64, f64) -> () +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: f64.mul $push0=, $2, $4 +; NOSIMD-NEXT: f64.add $push1=, $pop0, $6 +; NOSIMD-NEXT: f64.store 8($0), $pop1 +; NOSIMD-NEXT: f64.mul $push2=, $1, $3 +; NOSIMD-NEXT: f64.add $push3=, $pop2, $5 +; NOSIMD-NEXT: f64.store 0($0), $pop3 +; NOSIMD-NEXT: return + %fma = call <2 x double> @llvm.fmuladd(<2 x double> %a, <2 x double> %b, <2 x double> %c) + ret <2 x double> %fma +} + define <4 x float> @fma_4xf32(<4 x float> %a, <4 x float> %b, <4 x float> %c) { ; RELAXED-LABEL: fma_4xf32: ; RELAXED: .functype fma_4xf32 (v128, v128, v128) -> (v128) @@ -167,6 +1283,44 @@ define <4 x float> @fma_4xf32(<4 x float> %a, <4 x float> %b, <4 x float> %c) { ; STRICT-NEXT: call $push18=, fmaf, $pop17, $pop16, $pop15 ; STRICT-NEXT: f32x4.replace_lane $push19=, $pop14, 3, $pop18 ; STRICT-NEXT: return $pop19 +; +; NOFP16-LABEL: fma_4xf32: +; NOFP16: .functype fma_4xf32 (v128, v128, v128) -> (v128) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: f32x4.extract_lane $push2=, $0, 0 +; NOFP16-NEXT: f32x4.extract_lane $push1=, $1, 0 +; NOFP16-NEXT: f32x4.extract_lane $push0=, $2, 0 +; NOFP16-NEXT: call $push3=, fmaf, $pop2, $pop1, $pop0 +; NOFP16-NEXT: f32x4.splat $push4=, $pop3 +; NOFP16-NEXT: f32x4.extract_lane $push7=, $0, 1 +; NOFP16-NEXT: f32x4.extract_lane $push6=, $1, 1 +; NOFP16-NEXT: f32x4.extract_lane $push5=, $2, 1 +; NOFP16-NEXT: call $push8=, fmaf, $pop7, $pop6, $pop5 +; NOFP16-NEXT: f32x4.replace_lane $push9=, $pop4, 1, $pop8 +; NOFP16-NEXT: f32x4.extract_lane $push12=, $0, 2 +; NOFP16-NEXT: f32x4.extract_lane $push11=, $1, 2 +; NOFP16-NEXT: f32x4.extract_lane $push10=, $2, 2 +; NOFP16-NEXT: call $push13=, fmaf, $pop12, $pop11, $pop10 +; NOFP16-NEXT: f32x4.replace_lane $push14=, $pop9, 2, $pop13 +; NOFP16-NEXT: f32x4.extract_lane $push17=, $0, 3 +; NOFP16-NEXT: f32x4.extract_lane $push16=, $1, 3 +; NOFP16-NEXT: f32x4.extract_lane $push15=, $2, 3 +; NOFP16-NEXT: call $push18=, fmaf, $pop17, $pop16, $pop15 +; NOFP16-NEXT: f32x4.replace_lane $push19=, $pop14, 3, $pop18 +; NOFP16-NEXT: return $pop19 +; +; NOSIMD-LABEL: fma_4xf32: +; NOSIMD: .functype fma_4xf32 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> () +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: call $push0=, fmaf, $4, $8, $12 +; NOSIMD-NEXT: f32.store 12($0), $pop0 +; NOSIMD-NEXT: call $push1=, fmaf, $3, $7, $11 +; NOSIMD-NEXT: f32.store 8($0), $pop1 +; NOSIMD-NEXT: call $push2=, fmaf, $2, $6, $10 +; NOSIMD-NEXT: f32.store 4($0), $pop2 +; NOSIMD-NEXT: call $push3=, fmaf, $1, $5, $9 +; NOSIMD-NEXT: f32.store 0($0), $pop3 +; NOSIMD-NEXT: return %fma = call <4 x float> @llvm.fma(<4 x float> %a, <4 x float> %b, <4 x float> %c) ret <4 x float> %fma } @@ -176,9 +1330,9 @@ define <8 x float> @fadd_fmul_contract_8xf32(<8 x float> %a, <8 x float> %b, <8 ; RELAXED-LABEL: fadd_fmul_contract_8xf32: ; RELAXED: .functype fadd_fmul_contract_8xf32 (i32, v128, v128, v128, v128, v128, v128) -> () ; RELAXED-NEXT: # %bb.0: -; RELAXED-NEXT: f32x4.relaxed_madd $push0=, $6, $4, $2 +; RELAXED-NEXT: f32x4.relaxed_madd $push0=, $4, $2, $6 ; RELAXED-NEXT: v128.store 16($0), $pop0 -; RELAXED-NEXT: f32x4.relaxed_madd $push1=, $5, $3, $1 +; RELAXED-NEXT: f32x4.relaxed_madd $push1=, $3, $1, $5 ; RELAXED-NEXT: v128.store 0($0), $pop1 ; RELAXED-NEXT: return ; @@ -192,17 +1346,56 @@ define <8 x float> @fadd_fmul_contract_8xf32(<8 x float> %a, <8 x float> %b, <8 ; STRICT-NEXT: f32x4.add $push3=, $pop2, $5 ; STRICT-NEXT: v128.store 0($0), $pop3 ; STRICT-NEXT: return +; +; NOFP16-LABEL: fadd_fmul_contract_8xf32: +; NOFP16: .functype fadd_fmul_contract_8xf32 (i32, v128, v128, v128, v128, v128, v128) -> () +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: f32x4.mul $push0=, $4, $2 +; NOFP16-NEXT: f32x4.add $push1=, $pop0, $6 +; NOFP16-NEXT: v128.store 16($0), $pop1 +; NOFP16-NEXT: f32x4.mul $push2=, $3, $1 +; NOFP16-NEXT: f32x4.add $push3=, $pop2, $5 +; NOFP16-NEXT: v128.store 0($0), $pop3 +; NOFP16-NEXT: return +; +; NOSIMD-LABEL: fadd_fmul_contract_8xf32: +; NOSIMD: .functype fadd_fmul_contract_8xf32 (i32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32) -> () +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: f32.mul $push0=, $16, $8 +; NOSIMD-NEXT: f32.add $push1=, $pop0, $24 +; NOSIMD-NEXT: f32.store 28($0), $pop1 +; NOSIMD-NEXT: f32.mul $push2=, $15, $7 +; NOSIMD-NEXT: f32.add $push3=, $pop2, $23 +; NOSIMD-NEXT: f32.store 24($0), $pop3 +; NOSIMD-NEXT: f32.mul $push4=, $14, $6 +; NOSIMD-NEXT: f32.add $push5=, $pop4, $22 +; NOSIMD-NEXT: f32.store 20($0), $pop5 +; NOSIMD-NEXT: f32.mul $push6=, $13, $5 +; NOSIMD-NEXT: f32.add $push7=, $pop6, $21 +; NOSIMD-NEXT: f32.store 16($0), $pop7 +; NOSIMD-NEXT: f32.mul $push8=, $12, $4 +; NOSIMD-NEXT: f32.add $push9=, $pop8, $20 +; NOSIMD-NEXT: f32.store 12($0), $pop9 +; NOSIMD-NEXT: f32.mul $push10=, $11, $3 +; NOSIMD-NEXT: f32.add $push11=, $pop10, $19 +; NOSIMD-NEXT: f32.store 8($0), $pop11 +; NOSIMD-NEXT: f32.mul $push12=, $10, $2 +; NOSIMD-NEXT: f32.add $push13=, $pop12, $18 +; NOSIMD-NEXT: f32.store 4($0), $pop13 +; NOSIMD-NEXT: f32.mul $push14=, $9, $1 +; NOSIMD-NEXT: f32.add $push15=, $pop14, $17 +; NOSIMD-NEXT: f32.store 0($0), $pop15 +; NOSIMD-NEXT: return %mul = fmul contract <8 x float> %b, %a %add = fadd contract <8 x float> %mul, %c ret <8 x float> %add } - define <2 x double> @fadd_fmul_contract_2xf64(<2 x double> %a, <2 x double> %b, <2 x double> %c) { ; RELAXED-LABEL: fadd_fmul_contract_2xf64: ; RELAXED: .functype fadd_fmul_contract_2xf64 (v128, v128, v128) -> (v128) ; RELAXED-NEXT: # %bb.0: -; RELAXED-NEXT: f64x2.relaxed_madd $push0=, $2, $1, $0 +; RELAXED-NEXT: f64x2.relaxed_madd $push0=, $1, $0, $2 ; RELAXED-NEXT: return $pop0 ; ; STRICT-LABEL: fadd_fmul_contract_2xf64: @@ -211,28 +1404,64 @@ define <2 x double> @fadd_fmul_contract_2xf64(<2 x double> %a, <2 x double> %b, ; STRICT-NEXT: f64x2.mul $push0=, $1, $0 ; STRICT-NEXT: f64x2.add $push1=, $pop0, $2 ; STRICT-NEXT: return $pop1 +; +; NOFP16-LABEL: fadd_fmul_contract_2xf64: +; NOFP16: .functype fadd_fmul_contract_2xf64 (v128, v128, v128) -> (v128) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: f64x2.mul $push0=, $1, $0 +; NOFP16-NEXT: f64x2.add $push1=, $pop0, $2 +; NOFP16-NEXT: return $pop1 +; +; NOSIMD-LABEL: fadd_fmul_contract_2xf64: +; NOSIMD: .functype fadd_fmul_contract_2xf64 (i32, f64, f64, f64, f64, f64, f64) -> () +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: f64.mul $push0=, $4, $2 +; NOSIMD-NEXT: f64.add $push1=, $pop0, $6 +; NOSIMD-NEXT: f64.store 8($0), $pop1 +; NOSIMD-NEXT: f64.mul $push2=, $3, $1 +; NOSIMD-NEXT: f64.add $push3=, $pop2, $5 +; NOSIMD-NEXT: f64.store 0($0), $pop3 +; NOSIMD-NEXT: return %mul = fmul contract <2 x double> %b, %a %add = fadd contract <2 x double> %mul, %c ret <2 x double> %add } -define float @fadd_fmul_contract_f32(float %a, float %b, float %c) { -; RELAXED-LABEL: fadd_fmul_contract_f32: -; RELAXED: .functype fadd_fmul_contract_f32 (f32, f32, f32) -> (f32) +define <2 x double> @fadd_fmul_2xf64(<2 x double> %a, <2 x double> %b, <2 x double> %c) { +; RELAXED-LABEL: fadd_fmul_2xf64: +; RELAXED: .functype fadd_fmul_2xf64 (v128, v128, v128) -> (v128) ; RELAXED-NEXT: # %bb.0: -; RELAXED-NEXT: f32.mul $push0=, $1, $0 -; RELAXED-NEXT: f32.add $push1=, $pop0, $2 +; RELAXED-NEXT: f64x2.mul $push0=, $1, $0 +; RELAXED-NEXT: f64x2.add $push1=, $pop0, $2 ; RELAXED-NEXT: return $pop1 ; -; STRICT-LABEL: fadd_fmul_contract_f32: -; STRICT: .functype fadd_fmul_contract_f32 (f32, f32, f32) -> (f32) +; STRICT-LABEL: fadd_fmul_2xf64: +; STRICT: .functype fadd_fmul_2xf64 (v128, v128, v128) -> (v128) ; STRICT-NEXT: # %bb.0: -; STRICT-NEXT: f32.mul $push0=, $1, $0 -; STRICT-NEXT: f32.add $push1=, $pop0, $2 +; STRICT-NEXT: f64x2.mul $push0=, $1, $0 +; STRICT-NEXT: f64x2.add $push1=, $pop0, $2 ; STRICT-NEXT: return $pop1 - %mul = fmul contract float %b, %a - %add = fadd contract float %mul, %c - ret float %add +; +; NOFP16-LABEL: fadd_fmul_2xf64: +; NOFP16: .functype fadd_fmul_2xf64 (v128, v128, v128) -> (v128) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: f64x2.mul $push0=, $1, $0 +; NOFP16-NEXT: f64x2.add $push1=, $pop0, $2 +; NOFP16-NEXT: return $pop1 +; +; NOSIMD-LABEL: fadd_fmul_2xf64: +; NOSIMD: .functype fadd_fmul_2xf64 (i32, f64, f64, f64, f64, f64, f64) -> () +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: f64.mul $push0=, $4, $2 +; NOSIMD-NEXT: f64.add $push1=, $pop0, $6 +; NOSIMD-NEXT: f64.store 8($0), $pop1 +; NOSIMD-NEXT: f64.mul $push2=, $3, $1 +; NOSIMD-NEXT: f64.add $push3=, $pop2, $5 +; NOSIMD-NEXT: f64.store 0($0), $pop3 +; NOSIMD-NEXT: return + %mul = fmul <2 x double> %b, %a + %add = fadd <2 x double> %mul, %c + ret <2 x double> %add } define float @fma_f32(float %a, float %b, float %c) { @@ -247,6 +1476,18 @@ define float @fma_f32(float %a, float %b, float %c) { ; STRICT-NEXT: # %bb.0: ; STRICT-NEXT: call $push0=, fmaf, $0, $1, $2 ; STRICT-NEXT: return $pop0 +; +; NOFP16-LABEL: fma_f32: +; NOFP16: .functype fma_f32 (f32, f32, f32) -> (f32) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: call $push0=, fmaf, $0, $1, $2 +; NOFP16-NEXT: return $pop0 +; +; NOSIMD-LABEL: fma_f32: +; NOSIMD: .functype fma_f32 (f32, f32, f32) -> (f32) +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: call $push0=, fmaf, $0, $1, $2 +; NOSIMD-NEXT: return $pop0 %fma = call float @llvm.fma(float %a, float %b, float %c) ret float %fma } @@ -263,6 +1504,18 @@ define double @fma_f64(double %a, double %b, double %c) { ; STRICT-NEXT: # %bb.0: ; STRICT-NEXT: call $push0=, fma, $0, $1, $2 ; STRICT-NEXT: return $pop0 +; +; NOFP16-LABEL: fma_f64: +; NOFP16: .functype fma_f64 (f64, f64, f64) -> (f64) +; NOFP16-NEXT: # %bb.0: +; NOFP16-NEXT: call $push0=, fma, $0, $1, $2 +; NOFP16-NEXT: return $pop0 +; +; NOSIMD-LABEL: fma_f64: +; NOSIMD: .functype fma_f64 (f64, f64, f64) -> (f64) +; NOSIMD-NEXT: # %bb.0: +; NOSIMD-NEXT: call $push0=, fma, $0, $1, $2 +; NOSIMD-NEXT: return $pop0 %fma = call double @llvm.fma(double %a, double %b, double %c) ret double %fma } diff --git a/llvm/test/CodeGen/WebAssembly/simd-relaxed-fnma.ll b/llvm/test/CodeGen/WebAssembly/simd-relaxed-fnma.ll index 6e2d860..b90c1da 100644 --- a/llvm/test/CodeGen/WebAssembly/simd-relaxed-fnma.ll +++ b/llvm/test/CodeGen/WebAssembly/simd-relaxed-fnma.ll @@ -27,7 +27,7 @@ define <4 x float> @fsub_fmul_contract_4xf32(<4 x float> %a, <4 x float> %b, <4 ; RELAXED-LABEL: fsub_fmul_contract_4xf32: ; RELAXED: .functype fsub_fmul_contract_4xf32 (v128, v128, v128) -> (v128) ; RELAXED-NEXT: # %bb.0: -; RELAXED-NEXT: f32x4.relaxed_nmadd $push0=, $2, $1, $0 +; RELAXED-NEXT: f32x4.relaxed_nmadd $push0=, $1, $0, $2 ; RELAXED-NEXT: return $pop0 ; ; STRICT-LABEL: fsub_fmul_contract_4xf32: @@ -46,15 +46,14 @@ define <8 x half> @fsub_fmul_contract_8xf16(<8 x half> %a, <8 x half> %b, <8 x h ; RELAXED-LABEL: fsub_fmul_contract_8xf16: ; RELAXED: .functype fsub_fmul_contract_8xf16 (v128, v128, v128) -> (v128) ; RELAXED-NEXT: # %bb.0: -; RELAXED-NEXT: f16x8.relaxed_nmadd $push0=, $2, $1, $0 +; RELAXED-NEXT: f16x8.nmadd $push0=, $1, $0, $2 ; RELAXED-NEXT: return $pop0 ; ; STRICT-LABEL: fsub_fmul_contract_8xf16: ; STRICT: .functype fsub_fmul_contract_8xf16 (v128, v128, v128) -> (v128) ; STRICT-NEXT: # %bb.0: -; STRICT-NEXT: f16x8.mul $push0=, $1, $0 -; STRICT-NEXT: f16x8.sub $push1=, $2, $pop0 -; STRICT-NEXT: return $pop1 +; STRICT-NEXT: f16x8.nmadd $push0=, $1, $0, $2 +; STRICT-NEXT: return $pop0 %mul = fmul contract <8 x half> %b, %a %sub = fsub contract <8 x half> %c, %mul ret <8 x half> %sub @@ -84,9 +83,9 @@ define <8 x float> @fsub_fmul_contract_8xf32(<8 x float> %a, <8 x float> %b, <8 ; RELAXED-LABEL: fsub_fmul_contract_8xf32: ; RELAXED: .functype fsub_fmul_contract_8xf32 (i32, v128, v128, v128, v128, v128, v128) -> () ; RELAXED-NEXT: # %bb.0: -; RELAXED-NEXT: f32x4.relaxed_nmadd $push0=, $6, $4, $2 +; RELAXED-NEXT: f32x4.relaxed_nmadd $push0=, $4, $2, $6 ; RELAXED-NEXT: v128.store 16($0), $pop0 -; RELAXED-NEXT: f32x4.relaxed_nmadd $push1=, $5, $3, $1 +; RELAXED-NEXT: f32x4.relaxed_nmadd $push1=, $3, $1, $5 ; RELAXED-NEXT: v128.store 0($0), $pop1 ; RELAXED-NEXT: return ; @@ -110,7 +109,7 @@ define <2 x double> @fsub_fmul_contract_2xf64(<2 x double> %a, <2 x double> %b, ; RELAXED-LABEL: fsub_fmul_contract_2xf64: ; RELAXED: .functype fsub_fmul_contract_2xf64 (v128, v128, v128) -> (v128) ; RELAXED-NEXT: # %bb.0: -; RELAXED-NEXT: f64x2.relaxed_nmadd $push0=, $2, $1, $0 +; RELAXED-NEXT: f64x2.relaxed_nmadd $push0=, $1, $0, $2 ; RELAXED-NEXT: return $pop0 ; ; STRICT-LABEL: fsub_fmul_contract_2xf64: @@ -143,3 +142,55 @@ define float @fsub_fmul_contract_f32(float %a, float %b, float %c) { ret float %sub } +define <8 x half> @fmuladd_8xf16(<8 x half> %a, <8 x half> %b, <8 x half> %c) { +; RELAXED-LABEL: fmuladd_8xf16: +; RELAXED: .functype fmuladd_8xf16 (v128, v128, v128) -> (v128) +; RELAXED-NEXT: # %bb.0: +; RELAXED-NEXT: f16x8.nmadd $push0=, $0, $1, $2 +; RELAXED-NEXT: return $pop0 +; +; STRICT-LABEL: fmuladd_8xf16: +; STRICT: .functype fmuladd_8xf16 (v128, v128, v128) -> (v128) +; STRICT-NEXT: # %bb.0: +; STRICT-NEXT: f16x8.nmadd $push0=, $0, $1, $2 +; STRICT-NEXT: return $pop0 + %fneg = fneg <8 x half> %a + %fma = call <8 x half> @llvm.fmuladd(<8 x half> %fneg, <8 x half> %b, <8 x half> %c) + ret <8 x half> %fma +} + +define <4 x float> @fmuladd_4xf32(<4 x float> %a, <4 x float> %b, <4 x float> %c) { +; RELAXED-LABEL: fmuladd_4xf32: +; RELAXED: .functype fmuladd_4xf32 (v128, v128, v128) -> (v128) +; RELAXED-NEXT: # %bb.0: +; RELAXED-NEXT: f32x4.relaxed_nmadd $push0=, $0, $1, $2 +; RELAXED-NEXT: return $pop0 +; +; STRICT-LABEL: fmuladd_4xf32: +; STRICT: .functype fmuladd_4xf32 (v128, v128, v128) -> (v128) +; STRICT-NEXT: # %bb.0: +; STRICT-NEXT: f32x4.mul $push0=, $0, $1 +; STRICT-NEXT: f32x4.sub $push1=, $2, $pop0 +; STRICT-NEXT: return $pop1 + %fneg = fneg <4 x float> %a + %fma = call <4 x float> @llvm.fmuladd(<4 x float> %fneg, <4 x float> %b, <4 x float> %c) + ret <4 x float> %fma +} + +define <2 x double> @fmuladd_2xf64(<2 x double> %a, <2 x double> %b, <2 x double> %c) { +; RELAXED-LABEL: fmuladd_2xf64: +; RELAXED: .functype fmuladd_2xf64 (v128, v128, v128) -> (v128) +; RELAXED-NEXT: # %bb.0: +; RELAXED-NEXT: f64x2.relaxed_nmadd $push0=, $0, $1, $2 +; RELAXED-NEXT: return $pop0 +; +; STRICT-LABEL: fmuladd_2xf64: +; STRICT: .functype fmuladd_2xf64 (v128, v128, v128) -> (v128) +; STRICT-NEXT: # %bb.0: +; STRICT-NEXT: f64x2.mul $push0=, $0, $1 +; STRICT-NEXT: f64x2.sub $push1=, $2, $pop0 +; STRICT-NEXT: return $pop1 + %fneg = fneg <2 x double> %a + %fma = call <2 x double> @llvm.fmuladd(<2 x double> %fneg, <2 x double> %b, <2 x double> %c) + ret <2 x double> %fma +} diff --git a/llvm/test/CodeGen/X86/global-variable-partition-with-dap.ll b/llvm/test/CodeGen/X86/global-variable-partition-with-dap.ll index a0c243b..f3950b7 100644 --- a/llvm/test/CodeGen/X86/global-variable-partition-with-dap.ll +++ b/llvm/test/CodeGen/X86/global-variable-partition-with-dap.ll @@ -1,16 +1,15 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" -;; A minimal test case. llc will crash if global variables already has a section -;; prefix. Subsequent PRs will expand on this test case to test the hotness -;; reconciliation implementation. - -; RUN: not llc -mtriple=x86_64-unknown-linux-gnu -relocation-model=pic \ +;; A minimal test case. Subsequent PRs will expand on this test case +;; (e.g., with more functions, variables and profiles) and test the hotness +;; reconcillation implementation. +; RUN: llc -mtriple=x86_64-unknown-linux-gnu -relocation-model=pic \ ; RUN: -partition-static-data-sections=true \ ; RUN: -data-sections=true -unique-section-names=false \ -; RUN: %s -o - 2>&1 | FileCheck %s --check-prefix=ERR +; RUN: %s -o - 2>&1 | FileCheck %s --check-prefix=IR -; ERR: Global variable hot_bss already has a section prefix hot +; IR: .section .bss.hot.,"aw" @hot_bss = internal global i32 0, !section_prefix !17 diff --git a/llvm/test/CodeGen/X86/global-variable-partition.ll b/llvm/test/CodeGen/X86/global-variable-partition.ll index ce06d17..604b4fd 100644 --- a/llvm/test/CodeGen/X86/global-variable-partition.ll +++ b/llvm/test/CodeGen/X86/global-variable-partition.ll @@ -106,23 +106,31 @@ target triple = "x86_64-unknown-linux-gnu" ; UNIQ-NEXT: .section .data.unlikely.,"aw",@progbits,unique,8 ; AGG-NEXT: .section .data.unlikely.,"aw",@progbits +;; The `.section` directive is omitted for .data with -unique-section-names=false. +; See MCSectionELF::shouldOmitSectionDirective for the implementation details. + ; For @data_with_unknown_hotness ; SYM: .type .Ldata_with_unknown_hotness,@object # @data_with_unknown_hotness ; SYM: .section .data..Ldata_with_unknown_hotness,"aw",@progbits ; UNIQ: .section .data,"aw",@progbits,unique,9 -; The `.section` directive is omitted for .data with -unique-section-names=false. -; See MCSectionELF::shouldOmitSectionDirective for the implementation details. + ; AGG: .data ; COMMON: .Ldata_with_unknown_hotness: -; For @hot_data_custom_bar_section -; It has an explicit section attribute 'var' and shouldn't have hot or unlikely suffix. +; For variables that are not eligible for section prefix annotation ; COMMON: .type hot_data_custom_bar_section,@object ; SYM-NEXT: .section bar,"aw",@progbits ; SYM: hot_data_custom_bar_section ; UNIQ: .section bar,"aw",@progbits ; AGG: .section bar,"aw",@progbits +; SYM: .section .data.llvm.fake_var,"aw" +; UNIQ: .section .data,"aw" +; AGG: .data + +;; No section for linker declaration +; COMMON-NOT: qux + @.str = private unnamed_addr constant [5 x i8] c"hot\09\00", align 1 @.str.1 = private unnamed_addr constant [10 x i8] c"%d\09%d\09%d\0A\00", align 1 @hot_relro_array = internal constant [2 x ptr] [ptr @bss2, ptr @data3] @@ -137,6 +145,8 @@ target triple = "x86_64-unknown-linux-gnu" @data3 = internal global i32 3 @data_with_unknown_hotness = private global i32 5 @hot_data_custom_bar_section = internal global i32 101 #0 +@llvm.fake_var = internal global i32 123 +@qux = external global i64 define void @cold_func(i32 %0) !prof !15 { %2 = load i32, ptr @cold_bss diff --git a/llvm/test/CodeGen/X86/setcc-wide-types.ll b/llvm/test/CodeGen/X86/setcc-wide-types.ll index 5aa266d..69abf6e 100644 --- a/llvm/test/CodeGen/X86/setcc-wide-types.ll +++ b/llvm/test/CodeGen/X86/setcc-wide-types.ll @@ -1447,3 +1447,158 @@ define i1 @eq_i512_load_arg(ptr%p, i512 %b) { %r = icmp eq i512 %a, %b ret i1 %r } + +; Tests for any/allbits from memory. + +define i1 @anybits_i128_load_arg(ptr %w) { +; ANY-LABEL: anybits_i128_load_arg: +; ANY: # %bb.0: +; ANY-NEXT: movq (%rdi), %rax +; ANY-NEXT: orq 8(%rdi), %rax +; ANY-NEXT: setne %al +; ANY-NEXT: retq + %ld = load i128, ptr %w + %cmp = icmp ne i128 %ld, 0 + ret i1 %cmp +} + +define i1 @allbits_i128_load_arg(ptr %w) { +; SSE2-LABEL: allbits_i128_load_arg: +; SSE2: # %bb.0: +; SSE2-NEXT: pcmpeqd %xmm0, %xmm0 +; SSE2-NEXT: pcmpeqb (%rdi), %xmm0 +; SSE2-NEXT: pmovmskb %xmm0, %eax +; SSE2-NEXT: cmpl $65535, %eax # imm = 0xFFFF +; SSE2-NEXT: sete %al +; SSE2-NEXT: retq +; +; SSE41-LABEL: allbits_i128_load_arg: +; SSE41: # %bb.0: +; SSE41-NEXT: movdqa (%rdi), %xmm0 +; SSE41-NEXT: pcmpeqd %xmm1, %xmm1 +; SSE41-NEXT: ptest %xmm1, %xmm0 +; SSE41-NEXT: setb %al +; SSE41-NEXT: retq +; +; AVXANY-LABEL: allbits_i128_load_arg: +; AVXANY: # %bb.0: +; AVXANY-NEXT: vmovdqa (%rdi), %xmm0 +; AVXANY-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 +; AVXANY-NEXT: vptest %xmm1, %xmm0 +; AVXANY-NEXT: setb %al +; AVXANY-NEXT: retq + %ld = load i128, ptr %w + %cmp = icmp eq i128 %ld, -1 + ret i1 %cmp +} + +define i1 @anybits_i256_load_arg(ptr %w) { +; ANY-LABEL: anybits_i256_load_arg: +; ANY: # %bb.0: +; ANY-NEXT: movq (%rdi), %rax +; ANY-NEXT: movq 8(%rdi), %rcx +; ANY-NEXT: orq 24(%rdi), %rcx +; ANY-NEXT: orq 16(%rdi), %rax +; ANY-NEXT: orq %rcx, %rax +; ANY-NEXT: setne %al +; ANY-NEXT: retq + %ld = load i256, ptr %w + %cmp = icmp ne i256 %ld, 0 + ret i1 %cmp +} + +define i1 @allbits_i256_load_arg(ptr %w) { +; SSE-LABEL: allbits_i256_load_arg: +; SSE: # %bb.0: +; SSE-NEXT: movq (%rdi), %rax +; SSE-NEXT: movq 8(%rdi), %rcx +; SSE-NEXT: andq 24(%rdi), %rcx +; SSE-NEXT: andq 16(%rdi), %rax +; SSE-NEXT: andq %rcx, %rax +; SSE-NEXT: cmpq $-1, %rax +; SSE-NEXT: sete %al +; SSE-NEXT: retq +; +; AVX1-LABEL: allbits_i256_load_arg: +; AVX1: # %bb.0: +; AVX1-NEXT: vmovdqu (%rdi), %ymm0 +; AVX1-NEXT: vxorps %xmm1, %xmm1, %xmm1 +; AVX1-NEXT: vcmptrueps %ymm1, %ymm1, %ymm1 +; AVX1-NEXT: vptest %ymm1, %ymm0 +; AVX1-NEXT: setb %al +; AVX1-NEXT: vzeroupper +; AVX1-NEXT: retq +; +; AVX2-LABEL: allbits_i256_load_arg: +; AVX2: # %bb.0: +; AVX2-NEXT: vmovdqu (%rdi), %ymm0 +; AVX2-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 +; AVX2-NEXT: vptest %ymm1, %ymm0 +; AVX2-NEXT: setb %al +; AVX2-NEXT: vzeroupper +; AVX2-NEXT: retq +; +; AVX512-LABEL: allbits_i256_load_arg: +; AVX512: # %bb.0: +; AVX512-NEXT: vmovdqu (%rdi), %ymm0 +; AVX512-NEXT: vpcmpeqd %ymm1, %ymm1, %ymm1 +; AVX512-NEXT: vptest %ymm1, %ymm0 +; AVX512-NEXT: setb %al +; AVX512-NEXT: vzeroupper +; AVX512-NEXT: retq + %ld = load i256, ptr %w + %cmp = icmp eq i256 %ld, -1 + ret i1 %cmp +} + +define i1 @anybits_i512_load_arg(ptr %w) { +; ANY-LABEL: anybits_i512_load_arg: +; ANY: # %bb.0: +; ANY-NEXT: movq 16(%rdi), %rax +; ANY-NEXT: movq (%rdi), %rcx +; ANY-NEXT: movq 8(%rdi), %rdx +; ANY-NEXT: movq 24(%rdi), %rsi +; ANY-NEXT: orq 56(%rdi), %rsi +; ANY-NEXT: orq 40(%rdi), %rdx +; ANY-NEXT: orq %rsi, %rdx +; ANY-NEXT: orq 48(%rdi), %rax +; ANY-NEXT: orq 32(%rdi), %rcx +; ANY-NEXT: orq %rax, %rcx +; ANY-NEXT: orq %rdx, %rcx +; ANY-NEXT: setne %al +; ANY-NEXT: retq + %ld = load i512, ptr %w + %cmp = icmp ne i512 %ld, 0 + ret i1 %cmp +} + +define i1 @allbits_i512_load_arg(ptr %w) { +; NO512-LABEL: allbits_i512_load_arg: +; NO512: # %bb.0: +; NO512-NEXT: movq 16(%rdi), %rax +; NO512-NEXT: movq (%rdi), %rcx +; NO512-NEXT: movq 8(%rdi), %rdx +; NO512-NEXT: movq 24(%rdi), %rsi +; NO512-NEXT: andq 56(%rdi), %rsi +; NO512-NEXT: andq 40(%rdi), %rdx +; NO512-NEXT: andq %rsi, %rdx +; NO512-NEXT: andq 48(%rdi), %rax +; NO512-NEXT: andq 32(%rdi), %rcx +; NO512-NEXT: andq %rax, %rcx +; NO512-NEXT: andq %rdx, %rcx +; NO512-NEXT: cmpq $-1, %rcx +; NO512-NEXT: sete %al +; NO512-NEXT: retq +; +; AVX512-LABEL: allbits_i512_load_arg: +; AVX512: # %bb.0: +; AVX512-NEXT: vpternlogd {{.*#+}} zmm0 = -1 +; AVX512-NEXT: vpcmpneqd (%rdi), %zmm0, %k0 +; AVX512-NEXT: kortestw %k0, %k0 +; AVX512-NEXT: sete %al +; AVX512-NEXT: vzeroupper +; AVX512-NEXT: retq + %ld = load i512, ptr %w + %cmp = icmp eq i512 %ld, -1 + ret i1 %cmp +} diff --git a/llvm/test/MC/WebAssembly/simd-encodings.s b/llvm/test/MC/WebAssembly/simd-encodings.s index 48aec4b..57da338 100644 --- a/llvm/test/MC/WebAssembly/simd-encodings.s +++ b/llvm/test/MC/WebAssembly/simd-encodings.s @@ -917,11 +917,11 @@ main: # CHECK: f16x8.nearest # encoding: [0xfd,0xb6,0x02] f16x8.nearest - # CHECK: f16x8.relaxed_madd # encoding: [0xfd,0xce,0x02] - f16x8.relaxed_madd + # CHECK: f16x8.madd # encoding: [0xfd,0xce,0x02] + f16x8.madd - # CHECK: f16x8.relaxed_nmadd # encoding: [0xfd,0xcf,0x02] - f16x8.relaxed_nmadd + # CHECK: f16x8.nmadd # encoding: [0xfd,0xcf,0x02] + f16x8.nmadd # CHECK: i16x8.trunc_sat_f16x8_s # encoding: [0xfd,0xc5,0x02] i16x8.trunc_sat_f16x8_s diff --git a/llvm/test/TableGen/listsplat.td b/llvm/test/TableGen/listsplat.td index 5a93a4c..43803d6 100644 --- a/llvm/test/TableGen/listsplat.td +++ b/llvm/test/TableGen/listsplat.td @@ -1,4 +1,5 @@ // RUN: llvm-tblgen %s | FileCheck %s +// RUN: not llvm-tblgen -DERROR1 %s 2>&1 | FileCheck --check-prefix=ERROR1 %s // CHECK: ------------- Classes ----------------- // CHECK-NEXT: class X<int X:a = ?, int X:b = ?> { @@ -73,3 +74,8 @@ def DYa1 : Y<"a", 1>; def DYa2 : Y<"a", 2>; def DZ : X<42, !size([1, 2, 3])>; + +#ifdef ERROR1 +// ERROR1: !listsplat count -1 is negative +defvar E = !listsplat("", -1); +#endif diff --git a/llvm/test/Transforms/PGOProfile/data-access-profile.ll b/llvm/test/Transforms/PGOProfile/data-access-profile.ll index 29198f34..205184b 100644 --- a/llvm/test/Transforms/PGOProfile/data-access-profile.ll +++ b/llvm/test/Transforms/PGOProfile/data-access-profile.ll @@ -3,55 +3,72 @@ ; RUN: rm -rf %t && split-file %s %t && cd %t -;; Read a text profile and merge it into indexed profile. +;; Read text profiles and merge them into indexed profiles. ; RUN: llvm-profdata merge --memprof-version=4 memprof.yaml -o memprof.profdata +; RUN: llvm-profdata merge --memprof-version=4 memprof-no-dap.yaml -o memprof-no-dap.profdata ;; Run optimizer pass on an IR module without IR functions, and test that global ;; variables in the module could be annotated (i.e., no early return), ; RUN: opt -passes='memprof-use<profile-filename=memprof.profdata>' -memprof-annotate-static-data-prefix \ -; RUN: -debug-only=memprof -stats -S funcless-module.ll -o - 2>&1 | FileCheck %s --check-prefixes=LOG,PREFIX,STAT +; RUN: -debug-only=memprof -stats -S funcless-module.ll -o - 2>&1 | FileCheck %s --check-prefixes=LOG,IR,STAT ;; Run optimizer pass on the IR, and check the section prefix. ; RUN: opt -passes='memprof-use<profile-filename=memprof.profdata>' -memprof-annotate-static-data-prefix \ -; RUN: -debug-only=memprof -stats -S input.ll -o - 2>&1 | FileCheck %s --check-prefixes=LOG,PREFIX,STAT +; RUN: -debug-only=memprof -stats -S input.ll -o - 2>&1 | FileCheck %s --check-prefixes=LOG,IR,STAT -;; Run optimizer pass without explicitly setting -memprof-annotate-static-data-prefix. -;; The output text IR shouldn't have `section_prefix` +;; Run memprof without providing memprof data. Test that IR has module flag +;; `EnableDataAccessProf` as 0. +; RUN: opt -passes='memprof-use<profile-filename=memprof-no-dap.profdata>' -memprof-annotate-static-data-prefix \ +; RUN: -debug-only=memprof -stats -S input.ll -o - 2>&1 | FileCheck %s --check-prefix=FLAG + +;; Run memprof without explicitly setting -memprof-annotate-static-data-prefix. +;; The output text IR shouldn't have `section_prefix` or EnableDataAccessProf module flag. ; RUN: opt -passes='memprof-use<profile-filename=memprof.profdata>' \ -; RUN: -debug-only=memprof -stats -S input.ll -o - | FileCheck %s --implicit-check-not="section_prefix" +; RUN: -debug-only=memprof -stats -S input.ll -o - | FileCheck %s --check-prefix=FLAGLESS --implicit-check-not="section_prefix" ; LOG: Skip annotating string literal .str ; LOG: Global variable var1 is annotated as hot ; LOG: Global variable var2.llvm.125 is annotated as hot ; LOG: Global variable bar is not annotated ; LOG: Global variable foo is annotated as unlikely -; LOG: Global variable var3 has explicit section name. Skip annotating. -; LOG: Global variable var4 has explicit section name. Skip annotating. +; LOG: Skip annotation for var3 due to explicit section name. +; LOG: Skip annotation for var4 due to explicit section name. +; LOG: Skip annotation for llvm.fake_var due to name starts with `llvm.`. +; LOG: Skip annotation for qux due to linker declaration. ;; String literals are not annotated. -; PREFIX: @.str = unnamed_addr constant [5 x i8] c"abcde" -; PREFIX-NOT: section_prefix -; PREFIX: @var1 = global i32 123, !section_prefix !0 +; IR: @.str = unnamed_addr constant [5 x i8] c"abcde" +; IR-NOT: section_prefix +; IR: @var1 = global i32 123, !section_prefix !0 ;; @var.llvm.125 will be canonicalized to @var2 for profile look-up. -; PREFIX-NEXT: @var2.llvm.125 = global i64 0, !section_prefix !0 +; IR-NEXT: @var2.llvm.125 = global i64 0, !section_prefix !0 ;; @bar is not seen in hot symbol or known symbol set, so it won't get a section ;; prefix. Test this by testing that there is no section_prefix between @bar and ;; @foo. -; PREFIX-NEXT: @bar = global i16 3 -; PREFIX-NOT: !section_prefix +; IR-NEXT: @bar = global i16 3 +; IR-NOT: !section_prefix ;; @foo is unlikely. -; PREFIX-NEXT: @foo = global i8 2, !section_prefix !1 +; IR-NEXT: @foo = global i8 2, !section_prefix !1 + +; IR-NEXT: @var3 = constant [2 x i32] [i32 12345, i32 6789], section "sec1" +; IR-NEXT: @var4 = constant [1 x i64] [i64 98765] #0 + +; IR: @llvm.fake_var = global i32 123 +; IR-NOT: !section_prefix +; IR: @qux = external global i64 +; IR-NOT: !section_prefix -; PREFIX-NEXT: @var3 = constant [2 x i32] [i32 12345, i32 6789], section "sec1" -; PREFIX-NEXT: @var4 = constant [1 x i64] [i64 98765] #0 +; IR: attributes #0 = { "rodata-section"="sec2" } -; PREFIX: attributes #0 = { "rodata-section"="sec2" } +; IR: !0 = !{!"section_prefix", !"hot"} +; IR-NEXT: !1 = !{!"section_prefix", !"unlikely"} +; IR-NEXT: !2 = !{i32 2, !"EnableDataAccessProf", i32 1} -; PREFIX: !0 = !{!"section_prefix", !"hot"} -; PREFIX-NEXT: !1 = !{!"section_prefix", !"unlikely"} +; FLAG: !{i32 2, !"EnableDataAccessProf", i32 0} +; FLAGLESS-NOT: EnableDataAccessProf ; STAT: 1 memprof - Number of global vars annotated with 'unlikely' section prefix. ; STAT: 2 memprof - Number of global vars with user-specified section (not annotated). @@ -72,6 +89,24 @@ DataAccessProfiles: - foo KnownColdStrHashes: [ 999, 1001 ] ... +;--- memprof-no-dap.yaml +--- +# A memprof file with without data access profiles. The heap records are simplified +# to pass profile parsing and don't need to match the IR. +HeapProfileRecords: + - GUID: 0xdeadbeef12345678 + AllocSites: + - Callstack: + - { Function: 0x1111111111111111, LineOffset: 11, Column: 10, IsInlineFrame: true } + MemInfoBlock: + AllocCount: 111 + TotalSize: 222 + TotalLifetime: 333 + TotalLifetimeAccessDensity: 444 + CallSites: + - Frames: + - { Function: 0x5555555555555555, LineOffset: 55, Column: 50, IsInlineFrame: true } +... ;--- input.ll target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" @@ -84,11 +119,14 @@ target triple = "x86_64-unknown-linux-gnu" @foo = global i8 2 @var3 = constant [2 x i32][i32 12345, i32 6789], section "sec1" @var4 = constant [1 x i64][i64 98765] #0 +@llvm.fake_var = global i32 123 +@qux = external global i64 define i32 @func() { %a = load i32, ptr @var1 %b = load i32, ptr @var2.llvm.125 - %ret = call i32 (...) @func_taking_arbitrary_param(i32 %a, i32 %b) + %c = load i32, ptr @llvm.fake_var + %ret = call i32 (...) @func_taking_arbitrary_param(i32 %a, i32 %b, i32 %c) ret i32 %ret } @@ -108,5 +146,8 @@ target triple = "x86_64-unknown-linux-gnu" @foo = global i8 2 @var3 = constant [2 x i32][i32 12345, i32 6789], section "sec1" @var4 = constant [1 x i64][i64 98765] #0 +@llvm.fake_var = global i32 123 +@qux = external global i64 + attributes #0 = { "rodata-section"="sec2" } diff --git a/llvm/unittests/ADT/BitFieldsTest.cpp b/llvm/unittests/ADT/BitFieldsTest.cpp index 3062d5d..ae541fe 100644 --- a/llvm/unittests/ADT/BitFieldsTest.cpp +++ b/llvm/unittests/ADT/BitFieldsTest.cpp @@ -247,8 +247,8 @@ TEST(BitfieldsTest, ValueTooBigBounded) { Bitfield::set<A>(Storage, 0); Bitfield::set<A>(Storage, -1); Bitfield::set<A>(Storage, -2); - EXPECT_DEBUG_DEATH(Bitfield::set<A>(Storage, 2), "value is too big"); - EXPECT_DEBUG_DEATH(Bitfield::set<A>(Storage, -3), "value is too small"); + EXPECT_DEBUG_DEATH(Bitfield::set<A>(Storage, 2), "value is out of range"); + EXPECT_DEBUG_DEATH(Bitfield::set<A>(Storage, -3), "value is out of range"); } #endif diff --git a/llvm/unittests/IR/ConstantFPRangeTest.cpp b/llvm/unittests/IR/ConstantFPRangeTest.cpp index 2431db9..67fee96 100644 --- a/llvm/unittests/IR/ConstantFPRangeTest.cpp +++ b/llvm/unittests/IR/ConstantFPRangeTest.cpp @@ -1066,6 +1066,115 @@ TEST_F(ConstantFPRangeTest, sub) { #endif } +TEST_F(ConstantFPRangeTest, mul) { + EXPECT_EQ(Full.mul(Full), NonNaN.unionWith(QNaN)); + EXPECT_EQ(Full.mul(Empty), Empty); + EXPECT_EQ(Empty.mul(Full), Empty); + EXPECT_EQ(Empty.mul(Empty), Empty); + EXPECT_EQ(One.mul(One), ConstantFPRange(APFloat(1.0))); + EXPECT_EQ(Some.mul(Some), + ConstantFPRange::getNonNaN(APFloat(-9.0), APFloat(9.0))); + EXPECT_EQ(SomePos.mul(SomeNeg), + ConstantFPRange::getNonNaN(APFloat(-9.0), APFloat(-0.0))); + EXPECT_EQ(PosInf.mul(PosInf), PosInf); + EXPECT_EQ(NegInf.mul(NegInf), PosInf); + EXPECT_EQ(PosInf.mul(Finite), NonNaN.unionWith(QNaN)); + EXPECT_EQ(NegInf.mul(Finite), NonNaN.unionWith(QNaN)); + EXPECT_EQ(PosInf.mul(NegInf), NegInf); + EXPECT_EQ(NegInf.mul(PosInf), NegInf); + EXPECT_EQ(PosZero.mul(NegZero), NegZero); + EXPECT_EQ(PosZero.mul(Zero), Zero); + EXPECT_EQ(NegZero.mul(NegZero), PosZero); + EXPECT_EQ(NegZero.mul(Zero), Zero); + EXPECT_EQ(NaN.mul(NaN), QNaN); + EXPECT_EQ(NaN.mul(Finite), QNaN); + +#if defined(EXPENSIVE_CHECKS) + EnumerateTwoInterestingConstantFPRanges( + [](const ConstantFPRange &LHS, const ConstantFPRange &RHS) { + ConstantFPRange Res = LHS.mul(RHS); + ConstantFPRange Expected = + ConstantFPRange::getEmpty(LHS.getSemantics()); + EnumerateValuesInConstantFPRange( + LHS, + [&](const APFloat &LHSC) { + EnumerateValuesInConstantFPRange( + RHS, + [&](const APFloat &RHSC) { + APFloat Prod = LHSC * RHSC; + EXPECT_TRUE(Res.contains(Prod)) + << "Wrong result for " << LHS << " * " << RHS + << ". The result " << Res << " should contain " << Prod; + if (!Expected.contains(Prod)) + Expected = Expected.unionWith(ConstantFPRange(Prod)); + }, + /*IgnoreNaNPayload=*/true); + }, + /*IgnoreNaNPayload=*/true); + EXPECT_EQ(Res, Expected) + << "Suboptimal result for " << LHS << " * " << RHS << ". Expected " + << Expected << ", but got " << Res; + }, + SparseLevel::SpecialValuesOnly); +#endif +} + +TEST_F(ConstantFPRangeTest, div) { + EXPECT_EQ(Full.div(Full), NonNaN.unionWith(QNaN)); + EXPECT_EQ(Full.div(Empty), Empty); + EXPECT_EQ(Empty.div(Full), Empty); + EXPECT_EQ(Empty.div(Empty), Empty); + EXPECT_EQ(One.div(One), ConstantFPRange(APFloat(1.0))); + EXPECT_EQ(Some.div(Some), NonNaN.unionWith(QNaN)); + EXPECT_EQ(SomePos.div(SomeNeg), + ConstantFPRange(APFloat::getInf(Sem, /*Negative=*/true), + APFloat::getZero(Sem, /*Negative=*/true), + /*MayBeQNaN=*/true, /*MayBeSNaN=*/false)); + EXPECT_EQ(PosInf.div(PosInf), QNaN); + EXPECT_EQ(NegInf.div(NegInf), QNaN); + EXPECT_EQ(PosInf.div(Finite), NonNaN); + EXPECT_EQ(NegInf.div(Finite), NonNaN); + EXPECT_EQ(PosInf.div(NegInf), QNaN); + EXPECT_EQ(NegInf.div(PosInf), QNaN); + EXPECT_EQ(Zero.div(Zero), QNaN); + EXPECT_EQ(SomePos.div(PosInf), PosZero); + EXPECT_EQ(SomeNeg.div(PosInf), NegZero); + EXPECT_EQ(PosInf.div(SomePos), PosInf); + EXPECT_EQ(NegInf.div(SomeNeg), PosInf); + EXPECT_EQ(NegInf.div(Some), NonNaN); + EXPECT_EQ(NaN.div(NaN), QNaN); + EXPECT_EQ(NaN.div(Finite), QNaN); + +#if defined(EXPENSIVE_CHECKS) + EnumerateTwoInterestingConstantFPRanges( + [](const ConstantFPRange &LHS, const ConstantFPRange &RHS) { + ConstantFPRange Res = LHS.div(RHS); + ConstantFPRange Expected = + ConstantFPRange::getEmpty(LHS.getSemantics()); + EnumerateValuesInConstantFPRange( + LHS, + [&](const APFloat &LHSC) { + EnumerateValuesInConstantFPRange( + RHS, + [&](const APFloat &RHSC) { + APFloat Val = LHSC / RHSC; + EXPECT_TRUE(Res.contains(Val)) + << "Wrong result for " << LHS << " / " << RHS + << ". The result " << Res << " should contain " << Val; + if (!Expected.contains(Val)) + Expected = Expected.unionWith(ConstantFPRange(Val)); + }, + /*IgnoreNaNPayload=*/true); + }, + /*IgnoreNaNPayload=*/true); + EXPECT_EQ(Res, Expected) + << "Suboptimal result for " << LHS << " / " << RHS << ". Expected " + << Expected << ", but got " << Res; + }, + SparseLevel::SpecialValuesOnly); +#endif +} + TEST_F(ConstantFPRangeTest, flushDenormals) { const fltSemantics &FP8Sem = APFloat::Float8E4M3(); APFloat NormalVal = APFloat::getSmallestNormalized(FP8Sem); diff --git a/llvm/utils/profcheck-xfail.txt b/llvm/utils/profcheck-xfail.txt index bdcb8a3..343c2bb71 100644 --- a/llvm/utils/profcheck-xfail.txt +++ b/llvm/utils/profcheck-xfail.txt @@ -1129,6 +1129,7 @@ Transforms/LowerIFunc/ifunc-alias.ll Transforms/LowerIFunc/ifunc-nonsense-resolvers.ll Transforms/LowerIFunc/ifunc-program-addrspace.ll Transforms/LowerIFunc/lower-ifunc.ll +Transforms/LowerMatrixIntrinsics/data-layout-multiply-fused.ll Transforms/LowerMatrixIntrinsics/multiply-fused-dominance.ll Transforms/LowerMatrixIntrinsics/multiply-fused.ll Transforms/LowerMatrixIntrinsics/multiply-fused-loops.ll @@ -1311,82 +1312,6 @@ Transforms/SimpleLoopUnswitch/pr60736.ll Transforms/SimpleLoopUnswitch/trivial-unswitch-freeze-individual-conditions.ll Transforms/SimpleLoopUnswitch/trivial-unswitch.ll Transforms/SimpleLoopUnswitch/trivial-unswitch-logical-and-or.ll -Transforms/SLPVectorizer/AArch64/gather-root.ll -Transforms/SLPVectorizer/AArch64/horizontal.ll -Transforms/SLPVectorizer/AArch64/loadi8.ll -Transforms/SLPVectorizer/AArch64/phi-node-bitwidt-op-not.ll -Transforms/SLPVectorizer/AArch64/uselistorder.ll -Transforms/SLPVectorizer/AArch64/vec3-reorder-reshuffle.ll -Transforms/SLPVectorizer/AArch64/vectorizable-selects-min-max.ll -Transforms/SLPVectorizer/AArch64/vectorizable-selects-uniform-cmps.ll -Transforms/SLPVectorizer/AMDGPU/horizontal-store.ll -Transforms/SLPVectorizer/bool-logical-op-reduction-with-poison.ll -Transforms/SLPVectorizer/call-arg-reduced-by-minbitwidth.ll -Transforms/SLPVectorizer/const-bool-logical-or-reduction.ll -Transforms/SLPVectorizer/extracts-with-undefs.ll -Transforms/SLPVectorizer/freeze-signedness-missed.ll -Transforms/SLPVectorizer/gathered-consecutive-loads-different-types.ll -Transforms/SLPVectorizer/gather_extract_from_vectorbuild.ll -Transforms/SLPVectorizer/insert-element-build-vector-const.ll -Transforms/SLPVectorizer/insert-element-build-vector-inseltpoison.ll -Transforms/SLPVectorizer/insert-element-build-vector.ll -Transforms/SLPVectorizer/logical-ops-poisonous-repeated.ll -Transforms/SLPVectorizer/minbitwidth-node-with-multi-users.ll -Transforms/SLPVectorizer/minbitwidth-user-not-min.ll -Transforms/SLPVectorizer/partial-register-extract.ll -Transforms/SLPVectorizer/reduction-gather-non-scheduled-extracts.ll -Transforms/SLPVectorizer/reorder-node.ll -Transforms/SLPVectorizer/reused-buildvector-matching-vectorized-node.ll -Transforms/SLPVectorizer/revec.ll -Transforms/SLPVectorizer/RISCV/remarks_cmp_sel_min_max.ll -Transforms/SLPVectorizer/RISCV/remarks-insert-into-small-vector.ll -Transforms/SLPVectorizer/RISCV/reordered-interleaved-loads.ll -Transforms/SLPVectorizer/RISCV/revec.ll -Transforms/SLPVectorizer/RISCV/select-profitability.ll -Transforms/SLPVectorizer/RISCV/shuffled-gather-casted.ll -Transforms/SLPVectorizer/RISCV/unsigned-node-trunc-with-signed-users.ll -Transforms/SLPVectorizer/slp-deleted-inst.ll -Transforms/SLPVectorizer/SystemZ/cmp-ptr-minmax.ll -Transforms/SLPVectorizer/SystemZ/ext-not-resized-op-resized.ll -Transforms/SLPVectorizer/SystemZ/minbitwidth-trunc.ll -Transforms/SLPVectorizer/X86/bool-mask.ll -Transforms/SLPVectorizer/X86/bv-root-part-of-graph.ll -Transforms/SLPVectorizer/X86/cmp-after-intrinsic-call-minbitwidth.ll -Transforms/SLPVectorizer/X86/cmp-as-alternate-ops.ll -Transforms/SLPVectorizer/X86/cmp_sel.ll -Transforms/SLPVectorizer/X86/crash_7zip.ll -Transforms/SLPVectorizer/X86/crash_clear_undefs.ll -Transforms/SLPVectorizer/X86/crash_cmpop.ll -Transforms/SLPVectorizer/X86/debug-counter.ll -Transforms/SLPVectorizer/X86/debug-info-salvage.ll -Transforms/SLPVectorizer/X86/extractelement-single-use-many-nodes.ll -Transforms/SLPVectorizer/X86/extracts-non-extendable.ll -Transforms/SLPVectorizer/X86/ext-used-scalar-different-bitwidth.ll -Transforms/SLPVectorizer/X86/gather-node-same-as-vect-but-order.ll -Transforms/SLPVectorizer/X86/horizontal-minmax.ll -Transforms/SLPVectorizer/X86/insert-after-bundle.ll -Transforms/SLPVectorizer/X86/jumbled-load-multiuse.ll -Transforms/SLPVectorizer/X86/minbitwidth-icmp-to-trunc.ll -Transforms/SLPVectorizer/X86/minbw-user-non-sizable.ll -Transforms/SLPVectorizer/X86/non-load-reduced-as-part-of-bv.ll -Transforms/SLPVectorizer/X86/ordering-bug.ll -Transforms/SLPVectorizer/X86/phi-node-bitwidt-op-not.ll -Transforms/SLPVectorizer/X86/phi-node-reshuffled-part.ll -Transforms/SLPVectorizer/X86/pr46983.ll -Transforms/SLPVectorizer/X86/pr49933.ll -Transforms/SLPVectorizer/X86/propagate_ir_flags.ll -Transforms/SLPVectorizer/X86/reduction-bool-logic-op-inside.ll -Transforms/SLPVectorizer/X86/reduction-logical.ll -Transforms/SLPVectorizer/X86/resized-bv-values-non-power-of2-node.ll -Transforms/SLPVectorizer/X86/reused-reductions-with-minbitwidth.ll -Transforms/SLPVectorizer/X86/select-reduction-op.ll -Transforms/SLPVectorizer/X86/shrink_after_reorder.ll -Transforms/SLPVectorizer/X86/subvector-minbitwidth-unsigned-value.ll -Transforms/SLPVectorizer/X86/undef_vect.ll -Transforms/SLPVectorizer/X86/used-reduced-op.ll -Transforms/SLPVectorizer/X86/vec3-reorder-reshuffle.ll -Transforms/SLPVectorizer/X86/vectorize-widest-phis.ll -Transforms/SLPVectorizer/X86/whole-registers-compare.ll Transforms/SROA/addrspacecast.ll Transforms/SROA/phi-and-select.ll Transforms/SROA/phi-gep.ll diff --git a/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt b/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt index 8d9474b..c301e0b 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt +++ b/mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt @@ -48,6 +48,10 @@ mlir_tablegen(LLVMIntrinsicFromLLVMIRConversions.inc -gen-intr-from-llvmir-conve mlir_tablegen(LLVMConvertibleLLVMIRIntrinsics.inc -gen-convertible-llvmir-intrinsics) add_mlir_dialect_tablegen_target(MLIRLLVMIntrinsicConversionsIncGen) +set(LLVM_TARGET_DEFINITIONS LLVMDialectBytecode.td) +mlir_tablegen(LLVMDialectBytecode.cpp.inc -gen-bytecode -bytecode-dialect="LLVM") +add_public_tablegen_target(MLIRLLVMDialectBytecodeIncGen) + set(LLVM_TARGET_DEFINITIONS BasicPtxBuilderInterface.td) mlir_tablegen(BasicPtxBuilderInterface.h.inc -gen-op-interface-decls) mlir_tablegen(BasicPtxBuilderInterface.cpp.inc -gen-op-interface-defs) diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td new file mode 100644 index 0000000..e7b202c --- /dev/null +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td @@ -0,0 +1,353 @@ +//===-- LLVMDialectBytecode.td - LLVM bytecode defs --------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This is the LLVM bytecode reader/writer definition file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DIALECT_BYTECODE +#define LLVM_DIALECT_BYTECODE + +include "mlir/IR/BytecodeBase.td" + +//===----------------------------------------------------------------------===// +// Bytecode classes for attributes and types. +//===----------------------------------------------------------------------===// + +def String : + WithParser <"succeeded($_reader.readString($_var))", + WithBuilder<"$_args", + WithPrinter<"$_writer.writeOwnedString($_getter)", + WithType <"StringRef">>>>; + +class Attr<string type> : WithType<type, Attribute>; + +class OptionalAttribute<string type> : + WithParser <"succeeded($_reader.readOptionalAttribute($_var))", + WithPrinter<"$_writer.writeOptionalAttribute($_getter)", + WithType<type, Attribute>>>; + +class OptionalInt<string type> : + WithParser <"succeeded(readOptionalInt($_reader, $_var))", + WithPrinter<"writeOptionalInt($_writer, $_getter)", + WithType<"std::optional<" # type # ">", VarInt>>>; + +class OptionalArrayRef<string eltType> : + WithParser <"succeeded(readOptionalArrayRef<" + # eltType # ">($_reader, $_var))", + WithPrinter<"writeOptionalArrayRef<" + # eltType # ">($_writer, $_getter)", + WithType<"SmallVector<" + # eltType # ">", Attribute>>>; + +class EnumClassFlag<string flag, string getter> : + WithParser<"succeeded($_reader.readVarInt($_var))", + WithBuilder<"(" # flag # ")$_args", + WithPrinter<"$_writer.writeVarInt((uint64_t)$_name." # getter # ")", + WithType<"uint64_t", VarInt>>>>; + +//===----------------------------------------------------------------------===// +// General notes +// - For each attribute or type entry, the argument names should match +// LLVMAttrDefs.td +// - The mnemonics are either LLVM or builtin MLIR attributes and types, but +// regular C++ types are also allowed to match builders and parsers. +// - DIScopeAttr and DINodeAttr are empty base classes, custom encoding not +// needed. +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// DIBasicTypeAttr +//===----------------------------------------------------------------------===// + +def DIBasicTypeAttr : DialectAttribute<(attr + VarInt:$tag, + String:$name, + VarInt:$sizeInBits, + VarInt:$encoding +)>; + +//===----------------------------------------------------------------------===// +// DIExpressionAttr, DIExpressionElemAttr +//===----------------------------------------------------------------------===// + +def DIExpressionElemAttr : DialectAttribute<(attr + VarInt:$opcode, + OptionalArrayRef<"uint64_t">:$arguments +)>; + +def DIExpressionAttr : DialectAttribute<(attr + OptionalArrayRef<"DIExpressionElemAttr">:$operations +)>; + +//===----------------------------------------------------------------------===// +// DIFileAttr +//===----------------------------------------------------------------------===// + +def DIFileAttr : DialectAttribute<(attr + String:$name, + String:$directory +)>; + +//===----------------------------------------------------------------------===// +// DILocalVariableAttr +//===----------------------------------------------------------------------===// + +def DILocalVariableAttr : DialectAttribute<(attr + Attr<"DIScopeAttr">:$scope, + OptionalAttribute<"StringAttr">:$name, + OptionalAttribute<"DIFileAttr">:$file, + VarInt:$line, + VarInt:$arg, + VarInt:$alignInBits, + OptionalAttribute<"DITypeAttr">:$type, + EnumClassFlag<"DIFlags", "getFlags()">:$_rawflags, + LocalVar<"DIFlags", "(DIFlags)_rawflags">:$flags +)> { + // DILocalVariableAttr direct getter uses a `StringRef` for `name`. Since the + // more direct getter is prefered during bytecode reading, force the base one + // and prevent crashes for empty `StringAttr`. + let cBuilder = "$_resultType::get(context, $_args)"; +} + +//===----------------------------------------------------------------------===// +// DISubroutineTypeAttr +//===----------------------------------------------------------------------===// + +def DISubroutineTypeAttr : DialectAttribute<(attr + VarInt:$callingConvention, + OptionalArrayRef<"DITypeAttr">:$types +)>; + +//===----------------------------------------------------------------------===// +// DICompileUnitAttr +//===----------------------------------------------------------------------===// + +def DICompileUnitAttr : DialectAttribute<(attr + Attr<"DistinctAttr">:$id, + VarInt:$sourceLanguage, + Attr<"DIFileAttr">:$file, + OptionalAttribute<"StringAttr">:$producer, + Bool:$isOptimized, + EnumClassFlag<"DIEmissionKind", "getEmissionKind()">:$_rawEmissionKind, + LocalVar<"DIEmissionKind", "(DIEmissionKind)_rawEmissionKind">:$emissionKind, + EnumClassFlag<"DINameTableKind", "getNameTableKind()">:$_rawNameTableKind, + LocalVar<"DINameTableKind", + "(DINameTableKind)_rawNameTableKind">:$nameTableKind +)>; + +//===----------------------------------------------------------------------===// +// DISubprogramAttr +//===----------------------------------------------------------------------===// + +def DISubprogramAttr : DialectAttribute<(attr + OptionalAttribute<"DistinctAttr">:$recId, + Bool:$isRecSelf, + OptionalAttribute<"DistinctAttr">:$id, + OptionalAttribute<"DICompileUnitAttr">:$compileUnit, + OptionalAttribute<"DIScopeAttr">:$scope, + OptionalAttribute<"StringAttr">:$name, + OptionalAttribute<"StringAttr">:$linkageName, + OptionalAttribute<"DIFileAttr">:$file, + VarInt:$line, + VarInt:$scopeLine, + EnumClassFlag<"DISubprogramFlags", "getSubprogramFlags()">:$_rawflags, + LocalVar<"DISubprogramFlags", "(DISubprogramFlags)_rawflags">:$subprogramFlags, + OptionalAttribute<"DISubroutineTypeAttr">:$type, + OptionalArrayRef<"DINodeAttr">:$retainedNodes, + OptionalArrayRef<"DINodeAttr">:$annotations +)>; + +//===----------------------------------------------------------------------===// +// DICompositeTypeAttr +//===----------------------------------------------------------------------===// + +def DICompositeTypeAttr : DialectAttribute<(attr + OptionalAttribute<"DistinctAttr">:$recId, + Bool:$isRecSelf, + VarInt:$tag, + OptionalAttribute<"StringAttr">:$name, + OptionalAttribute<"DIFileAttr">:$file, + VarInt:$line, + OptionalAttribute<"DIScopeAttr">:$scope, + OptionalAttribute<"DITypeAttr">:$baseType, + EnumClassFlag<"DIFlags", "getFlags()">:$_rawflags, + LocalVar<"DIFlags", "(DIFlags)_rawflags">:$flags, + VarInt:$sizeInBits, + VarInt:$alignInBits, + OptionalAttribute<"DIExpressionAttr">:$dataLocation, + OptionalAttribute<"DIExpressionAttr">:$rank, + OptionalAttribute<"DIExpressionAttr">:$allocated, + OptionalAttribute<"DIExpressionAttr">:$associated, + OptionalArrayRef<"DINodeAttr">:$elements +)>; + +//===----------------------------------------------------------------------===// +// DIDerivedTypeAttr +//===----------------------------------------------------------------------===// + +def DIDerivedTypeAttr : DialectAttribute<(attr + VarInt:$tag, + OptionalAttribute<"StringAttr">:$name, + OptionalAttribute<"DITypeAttr">:$baseType, + VarInt:$sizeInBits, + VarInt:$alignInBits, + VarInt:$offsetInBits, + OptionalInt<"unsigned">:$dwarfAddressSpace, + OptionalAttribute<"DINodeAttr">:$extraData +)>; + +//===----------------------------------------------------------------------===// +// DIImportedEntityAttr +//===----------------------------------------------------------------------===// + +def DIImportedEntityAttr : DialectAttribute<(attr + VarInt:$tag, + Attr<"DIScopeAttr">:$scope, + Attr<"DINodeAttr">:$entity, + OptionalAttribute<"DIFileAttr">:$file, + VarInt:$line, + OptionalAttribute<"StringAttr">:$name, + OptionalArrayRef<"DINodeAttr">:$elements +)>; + +//===----------------------------------------------------------------------===// +// DIGlobalVariableAttr, DIGlobalVariableExpressionAttr +//===----------------------------------------------------------------------===// + +def DIGlobalVariableAttr : DialectAttribute<(attr + OptionalAttribute<"DIScopeAttr">:$scope, + OptionalAttribute<"StringAttr">:$name, + OptionalAttribute<"StringAttr">:$linkageName, + Attr<"DIFileAttr">:$file, + VarInt:$line, + Attr<"DITypeAttr">:$type, + Bool:$isLocalToUnit, + Bool:$isDefined, + VarInt:$alignInBits +)>; + +def DIGlobalVariableExpressionAttr : DialectAttribute<(attr + Attr<"DIGlobalVariableAttr">:$var, + OptionalAttribute<"DIExpressionAttr">:$expr +)>; + +//===----------------------------------------------------------------------===// +// DILabelAttr +//===----------------------------------------------------------------------===// + +def DILabelAttr : DialectAttribute<(attr + Attr<"DIScopeAttr">:$scope, + OptionalAttribute<"StringAttr">:$name, + OptionalAttribute<"DIFileAttr">:$file, + VarInt:$line +)> { + // DILabelAttr direct getter uses a `StringRef` for `name`. Since the + // more direct getter is prefered during bytecode reading, force the base one + // and prevent crashes for empty `StringAttr`. + let cBuilder = "$_resultType::get(context, $_args)"; +} + +//===----------------------------------------------------------------------===// +// DILexicalBlockAttr, DILexicalBlockFileAttr +//===----------------------------------------------------------------------===// + +def DILexicalBlockAttr : DialectAttribute<(attr + Attr<"DIScopeAttr">:$scope, + OptionalAttribute<"DIFileAttr">:$file, + VarInt:$line, + VarInt:$column +)>; + +def DILexicalBlockFileAttr : DialectAttribute<(attr + Attr<"DIScopeAttr">:$scope, + OptionalAttribute<"DIFileAttr">:$file, + VarInt:$discriminator +)>; + +//===----------------------------------------------------------------------===// +// DINamespaceAttr +//===----------------------------------------------------------------------===// + +def DINamespaceAttr : DialectAttribute<(attr + OptionalAttribute<"StringAttr">:$name, + OptionalAttribute<"DIScopeAttr">:$scope, + Bool:$exportSymbols +)>; + +//===----------------------------------------------------------------------===// +// DISubrangeAttr +//===----------------------------------------------------------------------===// + +def DISubrangeAttr : DialectAttribute<(attr + OptionalAttribute<"Attribute">:$count, + OptionalAttribute<"Attribute">:$lowerBound, + OptionalAttribute<"Attribute">:$upperBound, + OptionalAttribute<"Attribute">:$stride +)>; + +//===----------------------------------------------------------------------===// +// LoopAnnotationAttr +//===----------------------------------------------------------------------===// + +def LoopAnnotationAttr : DialectAttribute<(attr + OptionalAttribute<"BoolAttr">:$disableNonforced, + OptionalAttribute<"LoopVectorizeAttr">:$vectorize, + OptionalAttribute<"LoopInterleaveAttr">:$interleave, + OptionalAttribute<"LoopUnrollAttr">:$unroll, + OptionalAttribute<"LoopUnrollAndJamAttr">:$unrollAndJam, + OptionalAttribute<"LoopLICMAttr">:$licm, + OptionalAttribute<"LoopDistributeAttr">:$distribute, + OptionalAttribute<"LoopPipelineAttr">:$pipeline, + OptionalAttribute<"LoopPeeledAttr">:$peeled, + OptionalAttribute<"LoopUnswitchAttr">:$unswitch, + OptionalAttribute<"BoolAttr">:$mustProgress, + OptionalAttribute<"BoolAttr">:$isVectorized, + OptionalAttribute<"FusedLoc">:$startLoc, + OptionalAttribute<"FusedLoc">:$endLoc, + OptionalArrayRef<"AccessGroupAttr">:$parallelAccesses +)>; + +//===----------------------------------------------------------------------===// +// Attributes & Types with custom bytecode handling. +//===----------------------------------------------------------------------===// + +// All the attributes with custom bytecode handling. +def LLVMDialectAttributes : DialectAttributes<"LLVM"> { + let elems = [ + DIBasicTypeAttr, + DICompileUnitAttr, + DICompositeTypeAttr, + DIDerivedTypeAttr, + DIExpressionElemAttr, + DIExpressionAttr, + DIFileAttr, + DIGlobalVariableAttr, + DIGlobalVariableExpressionAttr, + DIImportedEntityAttr, + DILabelAttr, + DILexicalBlockAttr, + DILexicalBlockFileAttr, + DILocalVariableAttr, + DINamespaceAttr, + DISubprogramAttr, + DISubrangeAttr, + DISubroutineTypeAttr, + LoopAnnotationAttr + // Referenced attributes currently missing support: + // AccessGroupAttr, LoopVectorizeAttr, LoopInterleaveAttr, LoopUnrollAttr, + // LoopUnrollAndJamAttr, LoopLICMAttr, LoopDistributeAttr, LoopPipelineAttr, + // LoopPeeledAttr, LoopUnswitchAttr + ]; +} + +def LLVMDialectTypes : DialectTypes<"LLVM"> { + let elems = []; +} + +#endif // LLVM_DIALECT_BYTECODE diff --git a/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td b/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td index 40b7d7e..89bd0f1 100644 --- a/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td +++ b/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td @@ -184,6 +184,7 @@ def AssumeAlignmentOp : MemRef_Op<"assume_alignment", [ def DistinctObjectsOp : MemRef_Op<"distinct_objects", [ Pure, + DistinctObjectsTrait, DeclareOpInterfaceMethods<InferTypeOpInterface> // ViewLikeOpInterface TODO: ViewLikeOpInterface only supports a single argument ]> { diff --git a/mlir/include/mlir/Interfaces/ViewLikeInterface.h b/mlir/include/mlir/Interfaces/ViewLikeInterface.h index db9c37f..c1c2269 100644 --- a/mlir/include/mlir/Interfaces/ViewLikeInterface.h +++ b/mlir/include/mlir/Interfaces/ViewLikeInterface.h @@ -230,6 +230,22 @@ LogicalResult verifyListOfOperandsOrIntegers(Operation *op, StringRef name, ArrayRef<int64_t> attr, ValueRange values); +namespace OpTrait { +/// This trai indicates that pointer-like objects (such as memrefs) returned +/// from this operation will never alias with each other. This provides a +/// guarantee to optimization passes that accesses through different results +/// of this operation can be safely reordered, as they will never reference +/// overlapping memory locations. +/// +/// Operations with this trait take multiple pointer-like operands +/// and return the same operands with additional non-aliasing guarantees. +/// If the access to the results of this operation aliases at runtime, the +/// behavior of such access is undefined. +template <typename ConcreteType> +class DistinctObjectsTrait + : public TraitBase<ConcreteType, DistinctObjectsTrait> {}; +} // namespace OpTrait + } // namespace mlir #endif // MLIR_INTERFACES_VIEWLIKEINTERFACE_H_ diff --git a/mlir/include/mlir/Interfaces/ViewLikeInterface.td b/mlir/include/mlir/Interfaces/ViewLikeInterface.td index ed213bf..131c1a0 100644 --- a/mlir/include/mlir/Interfaces/ViewLikeInterface.td +++ b/mlir/include/mlir/Interfaces/ViewLikeInterface.td @@ -414,4 +414,16 @@ def OffsetSizeAndStrideOpInterface : OpInterface<"OffsetSizeAndStrideOpInterface }]; } +// This trai indicates that pointer-like objects (such as memrefs) returned +// from this operation will never alias with each other. This provides a +// guarantee to optimization passes that accesses through different results +// of this operation can be safely reordered, as they will never reference +// overlapping memory locations. +// +// Operations with this trait take multiple pointer-like operands +// and return the same operands with additional non-aliasing guarantees. +// If the access to the results of this operation aliases at runtime, the +// behavior of such access is undefined. +def DistinctObjectsTrait : NativeOpTrait<"DistinctObjectsTrait">; + #endif // MLIR_INTERFACES_VIEWLIKEINTERFACE diff --git a/mlir/lib/Analysis/AliasAnalysis/LocalAliasAnalysis.cpp b/mlir/lib/Analysis/AliasAnalysis/LocalAliasAnalysis.cpp index 8062b474..a84d10d 100644 --- a/mlir/lib/Analysis/AliasAnalysis/LocalAliasAnalysis.cpp +++ b/mlir/lib/Analysis/AliasAnalysis/LocalAliasAnalysis.cpp @@ -258,6 +258,39 @@ getAllocEffectFor(Value value, return success(); } +static Operation *isDistinctObjectsOp(Operation *op) { + if (op && op->hasTrait<OpTrait::DistinctObjectsTrait>()) + return op; + + return nullptr; +} + +static Value getDistinctObjectsOperand(Operation *op, Value value) { + unsigned argNumber = cast<OpResult>(value).getResultNumber(); + return op->getOperand(argNumber); +} + +static std::optional<AliasResult> checkDistinctObjects(Value lhs, Value rhs) { + // We should already checked that lhs and rhs are different. + assert(lhs != rhs && "lhs and rhs must be different"); + + // Result and corresponding operand must alias. + auto lhsOp = isDistinctObjectsOp(lhs.getDefiningOp()); + if (lhsOp && getDistinctObjectsOperand(lhsOp, lhs) == rhs) + return AliasResult::MustAlias; + + auto rhsOp = isDistinctObjectsOp(rhs.getDefiningOp()); + if (rhsOp && getDistinctObjectsOperand(rhsOp, rhs) == lhs) + return AliasResult::MustAlias; + + // If two different values come from the same `DistinctObjects` operation, + // they don't alias. + if (lhsOp && lhsOp == rhsOp) + return AliasResult::NoAlias; + + return std::nullopt; +} + /// Given the two values, return their aliasing behavior. AliasResult LocalAliasAnalysis::aliasImpl(Value lhs, Value rhs) { if (lhs == rhs) @@ -289,6 +322,9 @@ AliasResult LocalAliasAnalysis::aliasImpl(Value lhs, Value rhs) { : AliasResult::MayAlias; } + if (std::optional<AliasResult> result = checkDistinctObjects(lhs, rhs)) + return *result; + // Otherwise, neither of the values are constant so check to see if either has // an allocation effect. bool lhsHasAlloc = succeeded(getAllocEffectFor(lhs, lhsAlloc, lhsAllocScope)); diff --git a/mlir/lib/Dialect/LLVMIR/CMakeLists.txt b/mlir/lib/Dialect/LLVMIR/CMakeLists.txt index ec581ac..cc66fac 100644 --- a/mlir/lib/Dialect/LLVMIR/CMakeLists.txt +++ b/mlir/lib/Dialect/LLVMIR/CMakeLists.txt @@ -8,11 +8,13 @@ add_mlir_dialect_library(MLIRLLVMDialect IR/LLVMMemorySlot.cpp IR/LLVMTypes.cpp IR/LLVMTypeSyntax.cpp + IR/LLVMDialectBytecode.cpp ADDITIONAL_HEADER_DIRS ${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/LLVMIR DEPENDS + MLIRLLVMDialectBytecodeIncGen MLIRLLVMOpsIncGen MLIRLLVMTypesIncGen MLIRLLVMIntrinsicOpsIncGen diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp index 5d08ccc..7ca09d9 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -29,6 +29,8 @@ #include "llvm/IR/DataLayout.h" #include "llvm/Support/Error.h" +#include "LLVMDialectBytecode.h" + #include <numeric> #include <optional> @@ -4237,6 +4239,7 @@ void LLVMDialect::initialize() { // Support unknown operations because not all LLVM operations are registered. allowUnknownOperations(); declarePromisedInterface<DialectInlinerInterface, LLVMDialect>(); + detail::addBytecodeInterface(this); } #define GET_OP_CLASSES diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialectBytecode.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialectBytecode.cpp new file mode 100644 index 0000000..41d1f80 --- /dev/null +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialectBytecode.cpp @@ -0,0 +1,154 @@ +//===- LLVMDialectBytecode.cpp - LLVM Bytecode Implementation -------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "LLVMDialectBytecode.h" +#include "mlir/Bytecode/BytecodeImplementation.h" +#include "mlir/Dialect/LLVMIR/LLVMAttrs.h" +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" +#include "mlir/Dialect/LLVMIR/LLVMTypes.h" +#include "mlir/IR/Diagnostics.h" +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/TypeSwitch.h" +#include <type_traits> + +using namespace mlir; +using namespace mlir::LLVM; + +namespace { + +// Provide some forward declarations of the functions that will be generated by +// the include below. +static void write(DIExpressionElemAttr attribute, + DialectBytecodeWriter &writer); +static LogicalResult writeAttribute(Attribute attribute, + DialectBytecodeWriter &writer); + +//===--------------------------------------------------------------------===// +// Optional ArrayRefs +// +// Note that both the writer and reader functions consider attributes to be +// optional. This is because the attribute may be present or empty. +//===--------------------------------------------------------------------===// + +template <class EntryTy> +static void writeOptionalArrayRef(DialectBytecodeWriter &writer, + ArrayRef<EntryTy> storage) { + if (storage.empty()) { + writer.writeOwnedBool(false); + return; + } + + writer.writeOwnedBool(true); + writer.writeList(storage, [&](EntryTy val) { + if constexpr (std::is_base_of_v<Attribute, EntryTy>) { + (void)writer.writeOptionalAttribute(val); + } else if constexpr (std::is_integral_v<EntryTy>) { + (void)writer.writeVarInt(val); + } else { + static_assert(true, "EntryTy not supported"); + } + }); +} + +template <class EntryTy> +static LogicalResult readOptionalArrayRef(DialectBytecodeReader &reader, + SmallVectorImpl<EntryTy> &storage) { + bool isPresent = false; + if (failed(reader.readBool(isPresent))) + return failure(); + // Nothing to do here, the array is empty. + if (!isPresent) + return success(); + + auto readEntry = [&]() -> FailureOr<EntryTy> { + EntryTy temp; + if constexpr (std::is_base_of_v<Attribute, EntryTy>) { + if (succeeded(reader.readOptionalAttribute(temp))) + return temp; + } else if constexpr (std::is_integral_v<EntryTy>) { + if (succeeded(reader.readVarInt(temp))) + return temp; + } else { + static_assert(true, "EntryTy not supported"); + } + return failure(); + }; + + return reader.readList(storage, readEntry); +} + +//===--------------------------------------------------------------------===// +// Optional integral types +//===--------------------------------------------------------------------===// + +template <class EntryTy> +static void writeOptionalInt(DialectBytecodeWriter &writer, + std::optional<EntryTy> storage) { + static_assert(std::is_integral_v<EntryTy>, + "EntryTy must be an integral type"); + EntryTy val = storage.value_or(0); + writer.writeVarIntWithFlag(val, storage.has_value()); +} + +template <class EntryTy> +static LogicalResult readOptionalInt(DialectBytecodeReader &reader, + std::optional<EntryTy> &storage) { + static_assert(std::is_integral_v<EntryTy>, + "EntryTy must be an integral type"); + uint64_t result = 0; + bool flag = false; + if (failed(reader.readVarIntWithFlag(result, flag))) + return failure(); + if (flag) + storage = static_cast<EntryTy>(result); + else + storage = std::nullopt; + return success(); +} + +//===--------------------------------------------------------------------===// +// Tablegen generated bytecode functions +//===--------------------------------------------------------------------===// + +#include "mlir/Dialect/LLVMIR/LLVMDialectBytecode.cpp.inc" + +//===--------------------------------------------------------------------===// +// LLVMDialectBytecodeInterface +//===--------------------------------------------------------------------===// + +/// This class implements the bytecode interface for the LLVM dialect. +struct LLVMDialectBytecodeInterface : public BytecodeDialectInterface { + LLVMDialectBytecodeInterface(Dialect *dialect) + : BytecodeDialectInterface(dialect) {} + + // Attributes + Attribute readAttribute(DialectBytecodeReader &reader) const override { + return ::readAttribute(getContext(), reader); + } + + LogicalResult writeAttribute(Attribute attr, + DialectBytecodeWriter &writer) const override { + return ::writeAttribute(attr, writer); + } + + // Types + Type readType(DialectBytecodeReader &reader) const override { + return ::readType(getContext(), reader); + } + + LogicalResult writeType(Type type, + DialectBytecodeWriter &writer) const override { + return ::writeType(type, writer); + } +}; +} // namespace + +void LLVM::detail::addBytecodeInterface(LLVMDialect *dialect) { + dialect->addInterfaces<LLVMDialectBytecodeInterface>(); +} diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialectBytecode.h b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialectBytecode.h new file mode 100644 index 0000000..1a17cb4 --- /dev/null +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialectBytecode.h @@ -0,0 +1,27 @@ +//===- LLVMDialectBytecode.h - LLVM Bytecode Implementation -----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This header defines hooks into the LLVM dialect bytecode +// implementation. +// +//===----------------------------------------------------------------------===// + +#ifndef LIB_MLIR_DIALECT_LLVM_IR_LLVMDIALECTBYTECODE_H +#define LIB_MLIR_DIALECT_LLVM_IR_LLVMDIALECTBYTECODE_H + +namespace mlir::LLVM { +class LLVMDialect; + +namespace detail { +/// Add the interfaces necessary for encoding the LLVM dialect components in +/// bytecode. +void addBytecodeInterface(LLVMDialect *dialect); +} // namespace detail +} // namespace mlir::LLVM + +#endif // LIB_MLIR_DIALECT_LLVM_IR_LLVMDIALECTBYTECODE_H diff --git a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUBlocking.cpp b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUBlocking.cpp index 36c498e..f77784a 100644 --- a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUBlocking.cpp +++ b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUBlocking.cpp @@ -161,11 +161,24 @@ XeGPUBlockingPass::getTileShape(Operation *op) const { xegpu::UpdateOffsetOp, xegpu::LoadMatrixOp>(op)) return getTileShape(op->getOpResult(0)); if (isa<xegpu::PrefetchNdOp, xegpu::LoadNdOp, xegpu::PrefetchOp, - xegpu::LoadGatherOp, xegpu::StoreMatrixOp>(op)) + xegpu::StoreMatrixOp>(op)) return getTileShape(op->getOpOperand(0)); - if (isa<xegpu::StoreNdOp, xegpu::StoreScatterOp>(op)) + if (isa<xegpu::StoreNdOp>(op)) return getTileShape(op->getOpOperand(1)); + // Handle LoadGatherOp and StoreScatterOp (with and without offset) + if (auto loadGatherOp = dyn_cast<xegpu::LoadGatherOp>(op)) { + if (loadGatherOp.getOffsets()) + return getTileShape(loadGatherOp->getOpResult(0)); + else + return getTileShape(loadGatherOp->getOpOperand(0)); + } + + if (auto storeScatterOp = dyn_cast<xegpu::StoreScatterOp>(op)) + return getTileShape(storeScatterOp.getOffsets() + ? storeScatterOp->getOpOperand(0) + : storeScatterOp->getOpOperand(1)); + if (isa<xegpu::DpasOp>(op)) { std::optional<SmallVector<int64_t>> aTile = getTileShape(op->getOpOperand(0)); diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp index 3d19c5a..9b23dd6 100644 --- a/mlir/lib/IR/AsmPrinter.cpp +++ b/mlir/lib/IR/AsmPrinter.cpp @@ -2200,10 +2200,9 @@ void AsmPrinter::Impl::printLocationInternal(LocationAttr loc, bool pretty, os << '>'; } os << '['; - interleave( - loc.getLocations(), - [&](Location loc) { printLocationInternal(loc, pretty); }, - [&]() { os << ", "; }); + interleaveComma(loc.getLocations(), [&](Location loc) { + printLocationInternal(loc, pretty); + }); os << ']'; }) .Default([&](LocationAttr loc) { diff --git a/mlir/test/Analysis/test-alias-analysis.mlir b/mlir/test/Analysis/test-alias-analysis.mlir index 8cbee61..d71adee 100644 --- a/mlir/test/Analysis/test-alias-analysis.mlir +++ b/mlir/test/Analysis/test-alias-analysis.mlir @@ -256,3 +256,19 @@ func.func @constants(%arg: memref<2xf32>) attributes {test.ptr = "func"} { return } + +// ----- + +// CHECK-LABEL: Testing : "distinct_objects" +// CHECK-DAG: func.region0#0 <-> func.region0#1: MayAlias + +// CHECK-DAG: distinct#0 <-> distinct#1: NoAlias +// CHECK-DAG: distinct#0 <-> func.region0#0: MustAlias +// CHECK-DAG: distinct#1 <-> func.region0#0: MayAlias +// CHECK-DAG: distinct#0 <-> func.region0#1: MayAlias +// CHECK-DAG: distinct#1 <-> func.region0#1: MustAlias + +func.func @distinct_objects(%arg: memref<?xf32>, %arg1: memref<?xf32>) attributes {test.ptr = "func"} { + %0, %1 = memref.distinct_objects %arg, %arg1 {test.ptr = "distinct"} : memref<?xf32>, memref<?xf32> + return +} diff --git a/mlir/test/Dialect/LLVMIR/bytecode.mlir b/mlir/test/Dialect/LLVMIR/bytecode.mlir new file mode 100644 index 0000000..821b0ac --- /dev/null +++ b/mlir/test/Dialect/LLVMIR/bytecode.mlir @@ -0,0 +1,35 @@ +// RUN: mlir-opt -verify-roundtrip %s + +#access_group = #llvm.access_group<id = distinct[0]<>> +#access_group1 = #llvm.access_group<id = distinct[1]<>> +#di_subprogram = #llvm.di_subprogram<recId = distinct[2]<>> +#loc1 = loc("test.f90":12:14) +#loc2 = loc("test":4:3) +#loc6 = loc(fused<#di_subprogram>[#loc1]) +#loc7 = loc(fused<#di_subprogram>[#loc2]) +#loop_annotation = #llvm.loop_annotation<disableNonforced = false, mustProgress = true, startLoc = #loc6, endLoc = #loc7, parallelAccesses = #access_group, #access_group1> +module { + llvm.func @imp_fn() { + llvm.return loc(#loc2) + } loc(#loc8) + llvm.func @loop_annotation_with_locs() { + llvm.br ^bb1 {loop_annotation = #loop_annotation} loc(#loc4) + ^bb1: // pred: ^bb0 + llvm.return loc(#loc5) + } loc(#loc3) +} loc(#loc) +#di_file = #llvm.di_file<"test.f90" in ""> +#di_subroutine_type = #llvm.di_subroutine_type<callingConvention = DW_CC_program> +#loc = loc("test":0:0) +#loc3 = loc("test-path":36:3) +#loc4 = loc("test-path":37:5) +#loc5 = loc("test-path":39:5) +#di_compile_unit = #llvm.di_compile_unit<id = distinct[3]<>, sourceLanguage = DW_LANG_Fortran95, file = #di_file, isOptimized = false, emissionKind = Full> +#di_compile_unit1 = #llvm.di_compile_unit<id = distinct[4]<>, sourceLanguage = DW_LANG_Fortran95, file = #di_file, isOptimized = false, emissionKind = Full> +#di_compile_unit2 = #llvm.di_compile_unit<id = distinct[5]<>, sourceLanguage = DW_LANG_Fortran95, file = #di_file, isOptimized = false, emissionKind = Full> +#di_module = #llvm.di_module<file = #di_file, scope = #di_compile_unit1, name = "mod1"> +#di_module1 = #llvm.di_module<file = #di_file, scope = #di_compile_unit2, name = "mod2"> +#di_imported_entity = #llvm.di_imported_entity<tag = DW_TAG_imported_module, scope = #di_subprogram, entity = #di_module, file = #di_file, line = 1> +#di_imported_entity1 = #llvm.di_imported_entity<tag = DW_TAG_imported_module, scope = #di_subprogram, entity = #di_module1, file = #di_file, line = 1> +#di_subprogram1 = #llvm.di_subprogram<recId = distinct[2]<>, id = distinct[6]<>, compileUnit = #di_compile_unit, scope = #di_file, name = "imp_fn", file = #di_file, subprogramFlags = Definition, type = #di_subroutine_type, retainedNodes = #di_imported_entity, #di_imported_entity1> +#loc8 = loc(fused<#di_subprogram1>[#loc1]) diff --git a/mlir/test/Dialect/LLVMIR/debuginfo.mlir b/mlir/test/Dialect/LLVMIR/debuginfo.mlir index 1834b0a..d7bf99b 100644 --- a/mlir/test/Dialect/LLVMIR/debuginfo.mlir +++ b/mlir/test/Dialect/LLVMIR/debuginfo.mlir @@ -1,4 +1,5 @@ // RUN: mlir-opt %s | mlir-opt | FileCheck %s +// RUN: mlir-opt -emit-bytecode %s | mlir-opt | FileCheck %s // CHECK-DAG: #[[FILE:.*]] = #llvm.di_file<"debuginfo.mlir" in "/test/"> #file = #llvm.di_file<"debuginfo.mlir" in "/test/"> diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir index 7344797..00e763a 100644 --- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir +++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir @@ -1,4 +1,4 @@ -// RUN: mlir-opt %s | mlir-opt | FileCheck %s +// RUN: mlir-opt -verify-roundtrip %s // CHECK-LABEL: func @baz @@ -757,7 +757,7 @@ llvm.func @stackrestore(%arg0: !llvm.ptr) { // CHECK-LABEL: @experimental_noalias_scope_decl llvm.func @experimental_noalias_scope_decl() { - // CHECK: llvm.intr.experimental.noalias.scope.decl #{{.*}} + // CHECK: llvm.intr.experimental.noalias.scope.decl #alias_scope{{.*}} llvm.intr.experimental.noalias.scope.decl #alias_scope llvm.return } @@ -767,7 +767,7 @@ llvm.func @experimental_noalias_scope_decl() { // CHECK-LABEL: @experimental_noalias_scope_with_string_id llvm.func @experimental_noalias_scope_with_string_id() { - // CHECK: llvm.intr.experimental.noalias.scope.decl #{{.*}} + // CHECK: llvm.intr.experimental.noalias.scope.decl #alias_scope{{.*}} llvm.intr.experimental.noalias.scope.decl #alias_scope2 llvm.return } diff --git a/mlir/test/Dialect/XeGPU/xegpu-blocking.mlir b/mlir/test/Dialect/XeGPU/xegpu-blocking.mlir index 9d63c2d..fe4f44c 100644 --- a/mlir/test/Dialect/XeGPU/xegpu-blocking.mlir +++ b/mlir/test/Dialect/XeGPU/xegpu-blocking.mlir @@ -584,3 +584,101 @@ gpu.module @test_kernel { gpu.return } } + +// ----- +gpu.module @test_kernel { + // CHECK-LABEL: load_with_offsets + // CHECK-COUNT-2: xegpu.load {{.*}}[{{.*}}], {{.*}} <{chunk_size = 1 : i64, l1_hint = #xegpu.cache_hint<cached>}> : ui64, vector<16xindex>, vector<16xi1> -> vector<16xf32> + gpu.func @load_with_offsets(%src: ui64) -> vector<32xf32> { + %cst = arith.constant dense<[ + 0, 8, 16, 24, 32, 40, 48, 56, + 64, 72, 80, 88, 96, 104, 112, 120, + 128, 136, 144, 152, 160, 168, 176, 184, + 192, 200, 208, 216, 224, 232, 240, 248 + ]> : vector<32xindex> + + %c17 = arith.constant 17: index + %mask = vector.create_mask %c17: vector<32xi1> + %ld = xegpu.load %src[%cst], %mask {chunk_size = 1, layout_result_0 = #xegpu.layout<inst_data = [16]>, l1_hint = #xegpu.cache_hint<cached>} : ui64, vector<32xindex>, vector<32xi1> -> vector<32xf32> + + gpu.return %ld : vector<32xf32> + } +} + +// ----- +gpu.module @test_kernel { + // CHECK-LABEL: store_with_offsets + // CHECK-COUNT-2: xegpu.store {{.*}}[{{.*}}], {{.*}} <{chunk_size = 1 : i64, l1_hint = #xegpu.cache_hint<cached>}> : vector<16xf32>, ui64, vector<16xindex>, vector<16xi1> + gpu.func @store_with_offsets(%src: ui64) { + %cst = arith.constant dense<[ + 0, 8, 16, 24, 32, 40, 48, 56, + 64, 72, 80, 88, 96, 104, 112, 120, + 128, 136, 144, 152, 160, 168, 176, 184, + 192, 200, 208, 216, 224, 232, 240, 248 + ]> : vector<32xindex> + + %c17 = arith.constant 17: index + %mask = vector.create_mask %c17: vector<32xi1> + + %st_vec = arith.constant dense<1023.0>: vector<32xf32> + xegpu.store %st_vec, %src[%cst], %mask {chunk_size = 1, layout_operand_0 = #xegpu.layout<inst_data = [16]>, + layout_operand_2 = #xegpu.layout<inst_data = [16]>, + layout_operand_3 = #xegpu.layout<inst_data = [16]>, + l1_hint = #xegpu.cache_hint<cached>} : vector<32xf32>, ui64, vector<32xindex>, vector<32xi1> + + gpu.return + } +} + +// ----- +gpu.module @test_kernel { + // CHECK-LABEL: load_with_offsets_chunk + // CHECK: [[cst:%.+]] = arith.constant dense<0.000000e+00> : vector<32x4xf32> + // CHECK: [[cst0:%.+]] = arith.constant dense<[130, 138, 146, 154, 162, 170, 178, 186, 194, 202, 210, 218, 226, 234, 242, 250]> : vector<16xindex> + // CHECK: [[cst1:%.+]] = arith.constant dense<[2, 10, 18, 26, 34, 42, 50, 58, 66, 74, 82, 90, 98, 106, 114, 122]> : vector<16xindex> + // CHECK: [[cst2:%.+]] = arith.constant dense<[128, 136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232, 240, 248]> : vector<16xindex> + // CHECK: [[cst3:%.+]] = arith.constant dense<[0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120]> : vector<16xindex> + // CHECK-COUNT-4: xegpu.load {{.*}}[{{.*}}], {{.*}} <{chunk_size = 2 : i64, l1_hint = #xegpu.cache_hint<cached>}> : ui64, vector<16xindex>, vector<16xi1> -> vector<16x2xf32> + gpu.func @load_with_offsets_chunk(%src: ui64) -> vector<32x4xf32> { + %cst = arith.constant dense<[ + 0, 8, 16, 24, 32, 40, 48, 56, + 64, 72, 80, 88, 96, 104, 112, 120, + 128, 136, 144, 152, 160, 168, 176, 184, + 192, 200, 208, 216, 224, 232, 240, 248 + ]> : vector<32xindex> + + %c17 = arith.constant 17: index + %mask = vector.create_mask %c17: vector<32xi1> + %ld = xegpu.load %src[%cst], %mask {chunk_size = 4, layout_result_0 = #xegpu.layout<inst_data = [16, 2]>, l1_hint = #xegpu.cache_hint<cached>} : ui64, vector<32xindex>, vector<32xi1> -> vector<32x4xf32> + gpu.return %ld : vector<32x4xf32> + } +} + +// ----- +gpu.module @test_kernel { + // CHECK-LABEL: store_with_offsets_chunk + // CHECK: [[cst:%.+]] = arith.constant dense<1.023000e+03> : vector<16x2xf32 + // CHECK: [[cst0:%.+]] = arith.constant dense<[130, 138, 146, 154, 162, 170, 178, 186, 194, 202, 210, 218, 226, 234, 242, 250]> : vector<16xindex> + // CHECK: [[cst1:%.+]] = arith.constant dense<[2, 10, 18, 26, 34, 42, 50, 58, 66, 74, 82, 90, 98, 106, 114, 122]> : vector<16xindex> + // CHECK: [[cst2:%.+]] = arith.constant dense<[128, 136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232, 240, 248]> : vector<16xindex> + // CHECK: [[cst3:%.+]] = arith.constant dense<[0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120]> : vector<16xindex> + // CHECK-COUNT-4: xegpu.store {{.*}}[{{.*}}], {{.*}} <{chunk_size = 2 : i64, l1_hint = #xegpu.cache_hint<cached>}> : vector<16x2xf32>, ui64, vector<16xindex>, vector<16xi1> + gpu.func @store_with_offsets_chunk(%src: ui64) { + %cst = arith.constant dense<[ + 0, 8, 16, 24, 32, 40, 48, 56, + 64, 72, 80, 88, 96, 104, 112, 120, + 128, 136, 144, 152, 160, 168, 176, 184, + 192, 200, 208, 216, 224, 232, 240, 248 + ]> : vector<32xindex> + + %c17 = arith.constant 17: index + %mask = vector.create_mask %c17: vector<32xi1> + + %st_vec = arith.constant dense<1023.>: vector<32x4xf32> + xegpu.store %st_vec, %src[%cst], %mask {chunk_size = 4, layout_operand_0 = #xegpu.layout<inst_data = [16, 2]>, + layout_operand_2 = #xegpu.layout<inst_data = [16, 2]>, + layout_operand_3 = #xegpu.layout<inst_data = [16, 2]>, + l1_hint = #xegpu.cache_hint<cached>} : vector<32x4xf32>, ui64, vector<32xindex>, vector<32xi1> + gpu.return + } +} |