Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c2478fe

Browse files
committed
[AArch64][Win] Work around an MSVC arm64 compiler bug
The MSVC compiler 19.37 for ARM64 from Visual Studio 17.7.4 has an optimization bug that causes an incorrect behavior with isAdvSIMDModImmType10() and causes the test test/CodeGen/AArch64/arm64-build-vector.ll to fail. Work around by using a slightly different variation. Bug: https://developercommunity.visualstudio.com/t/C-ARM64-compiler-optimization-bug/10481261 Cherrypick commit llvm@f776e0b
1 parent ab81227 commit c2478fe

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

llvm/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h

+22
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,27 @@ static inline uint64_t decodeAdvSIMDModImmType9(uint8_t Imm) {
592592
// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
593593
// cmode: 1110, op: 1
594594
static inline bool isAdvSIMDModImmType10(uint64_t Imm) {
595+
#if defined(_MSC_VER) && _MSC_VER == 1937 && !defined(__clang__) && \
596+
defined(_M_ARM64)
597+
// The MSVC compiler 19.37 for ARM64 has an optimization bug that
598+
// causes an incorrect behavior with the orignal version. Work around
599+
// by using a slightly different variation.
600+
// https://developercommunity.visualstudio.com/t/C-ARM64-compiler-optimization-bug/10481261
601+
constexpr uint64_t Mask = 0xFFULL;
602+
uint64_t ByteA = (Imm >> 56) & Mask;
603+
uint64_t ByteB = (Imm >> 48) & Mask;
604+
uint64_t ByteC = (Imm >> 40) & Mask;
605+
uint64_t ByteD = (Imm >> 32) & Mask;
606+
uint64_t ByteE = (Imm >> 24) & Mask;
607+
uint64_t ByteF = (Imm >> 16) & Mask;
608+
uint64_t ByteG = (Imm >> 8) & Mask;
609+
uint64_t ByteH = Imm & Mask;
610+
611+
return (ByteA == 0ULL || ByteA == Mask) && (ByteB == 0ULL || ByteB == Mask) &&
612+
(ByteC == 0ULL || ByteC == Mask) && (ByteD == 0ULL || ByteD == Mask) &&
613+
(ByteE == 0ULL || ByteE == Mask) && (ByteF == 0ULL || ByteF == Mask) &&
614+
(ByteG == 0ULL || ByteG == Mask) && (ByteH == 0ULL || ByteH == Mask);
615+
#else
595616
uint64_t ByteA = Imm & 0xff00000000000000ULL;
596617
uint64_t ByteB = Imm & 0x00ff000000000000ULL;
597618
uint64_t ByteC = Imm & 0x0000ff0000000000ULL;
@@ -609,6 +630,7 @@ static inline bool isAdvSIMDModImmType10(uint64_t Imm) {
609630
(ByteF == 0ULL || ByteF == 0x0000000000ff0000ULL) &&
610631
(ByteG == 0ULL || ByteG == 0x000000000000ff00ULL) &&
611632
(ByteH == 0ULL || ByteH == 0x00000000000000ffULL);
633+
#endif
612634
}
613635

614636
static inline uint8_t encodeAdvSIMDModImmType10(uint64_t Imm) {

0 commit comments

Comments
 (0)