-
Notifications
You must be signed in to change notification settings - Fork 110
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CIR] Lower certain cir.cmp3way operations to corresponding LLVM intr…
…insics LLVM recently added two families of intrinsics named `llvm.scmp.*` and `llvm.ucmp.*` that generate potentially better code for three-way comparison operations. This patch lowers certain `cir.cmp3way` operations to these intrinsics. Not all `cir.cmp3way` operations can be lowered to these intrinsics. The qualifying conditions are: 1) the comparison is between two integers, and 2) the comparison produces a strong order. `cir.cmp3way` operations that are not qualified are not affected by this patch. Qualifying `cir.cmp3way` operations may still need some canonicalization work before lowering. The "canonicalized" form of a qualifying three-way comparison operation yields -1 for lt, 0 for eq, and 1 for gt. This patch converts those non-canonicalized but qualifying `cir.cmp3way` operations to their canonical forms in the LLVM lowering prepare pass.
- Loading branch information
Showing
9 changed files
with
361 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
110 changes: 110 additions & 0 deletions
110
clang/test/CIR/CodeGen/Inputs/std-compare-noncanonical.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
#ifndef STD_COMPARE_H | ||
#define STD_COMPARE_H | ||
|
||
namespace std { | ||
inline namespace __1 { | ||
|
||
// exposition only | ||
enum class _EqResult : unsigned char { | ||
__equal = 2, | ||
__equiv = __equal, | ||
}; | ||
|
||
enum class _OrdResult : signed char { | ||
__less = 1, | ||
__greater = 3 | ||
}; | ||
|
||
struct _CmpUnspecifiedType; | ||
using _CmpUnspecifiedParam = void (_CmpUnspecifiedType::*)(); | ||
|
||
class strong_ordering { | ||
using _ValueT = signed char; | ||
explicit constexpr strong_ordering(_EqResult __v) noexcept : __value_(static_cast<signed char>(__v)) {} | ||
explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(static_cast<signed char>(__v)) {} | ||
|
||
public: | ||
static const strong_ordering less; | ||
static const strong_ordering equal; | ||
static const strong_ordering equivalent; | ||
static const strong_ordering greater; | ||
|
||
// comparisons | ||
friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept; | ||
friend constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; | ||
friend constexpr bool operator<(strong_ordering __v, _CmpUnspecifiedParam) noexcept; | ||
friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; | ||
friend constexpr bool operator>(strong_ordering __v, _CmpUnspecifiedParam) noexcept; | ||
friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept; | ||
friend constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept; | ||
friend constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; | ||
friend constexpr bool operator<(_CmpUnspecifiedParam, strong_ordering __v) noexcept; | ||
friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; | ||
friend constexpr bool operator>(_CmpUnspecifiedParam, strong_ordering __v) noexcept; | ||
friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; | ||
|
||
friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept; | ||
friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept; | ||
|
||
// test helper | ||
constexpr bool test_eq(strong_ordering const &other) const noexcept { | ||
return __value_ == other.__value_; | ||
} | ||
|
||
private: | ||
_ValueT __value_; | ||
}; | ||
|
||
inline constexpr strong_ordering strong_ordering::less(_OrdResult::__less); | ||
inline constexpr strong_ordering strong_ordering::equal(_EqResult::__equal); | ||
inline constexpr strong_ordering strong_ordering::equivalent(_EqResult::__equiv); | ||
inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater); | ||
|
||
constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { | ||
return __v.__value_ == 0; | ||
} | ||
constexpr bool operator!=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { | ||
return __v.__value_ != 0; | ||
} | ||
constexpr bool operator<(strong_ordering __v, _CmpUnspecifiedParam) noexcept { | ||
return __v.__value_ < 0; | ||
} | ||
constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { | ||
return __v.__value_ <= 0; | ||
} | ||
constexpr bool operator>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { | ||
return __v.__value_ > 0; | ||
} | ||
constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { | ||
return __v.__value_ >= 0; | ||
} | ||
constexpr bool operator==(_CmpUnspecifiedParam, strong_ordering __v) noexcept { | ||
return 0 == __v.__value_; | ||
} | ||
constexpr bool operator!=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { | ||
return 0 != __v.__value_; | ||
} | ||
constexpr bool operator<(_CmpUnspecifiedParam, strong_ordering __v) noexcept { | ||
return 0 < __v.__value_; | ||
} | ||
constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { | ||
return 0 <= __v.__value_; | ||
} | ||
constexpr bool operator>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { | ||
return 0 > __v.__value_; | ||
} | ||
constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { | ||
return 0 >= __v.__value_; | ||
} | ||
|
||
constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { | ||
return __v; | ||
} | ||
constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { | ||
return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v); | ||
} | ||
|
||
} // namespace __1 | ||
} // end namespace std | ||
|
||
#endif // STD_COMPARE_H |
Oops, something went wrong.