diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -757,12 +757,13 @@ return false; int64_t Val = MCE->getValue(); - int64_t SVal = std::make_signed_t(Val); - int64_t UVal = std::make_unsigned_t(Val); - if (Val != SVal && Val != UVal) + // Avoid left shift by 64 directly. + uint64_t Upper = UINT64_C(-1) << (sizeof(T) * 4) << (sizeof(T) * 4); + // Allow all-0 or all-1 in top bits to permit bitwise NOT. + if ((Val & Upper) && (Val & Upper) != Upper) return false; - return AArch64_AM::isLogicalImmediate(UVal, sizeof(T) * 8); + return AArch64_AM::isLogicalImmediate(Val & ~Upper, sizeof(T) * 8); } bool isShiftedImm() const { return Kind == k_ShiftedImm; } diff --git a/llvm/test/MC/AArch64/SVE/mov-diagnostics.s b/llvm/test/MC/AArch64/SVE/mov-diagnostics.s --- a/llvm/test/MC/AArch64/SVE/mov-diagnostics.s +++ b/llvm/test/MC/AArch64/SVE/mov-diagnostics.s @@ -153,16 +153,6 @@ // CHECK-NEXT: mov z0.b, #1, lsl #8 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: -mov z0.h, #-33024 -// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 65280] -// CHECK-NEXT: mov z0.h, #-33024 -// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: - -mov z0.h, #-32769 -// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 65280] -// CHECK-NEXT: mov z0.h, #-32769 -// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: - mov z0.h, #-129, lsl #8 // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [-128, 127] or a multiple of 256 in range [-32768, 65280] // CHECK-NEXT: mov z0.h, #-129, lsl #8 diff --git a/llvm/test/MC/AArch64/SVE/mov.s b/llvm/test/MC/AArch64/SVE/mov.s --- a/llvm/test/MC/AArch64/SVE/mov.s +++ b/llvm/test/MC/AArch64/SVE/mov.s @@ -205,6 +205,18 @@ // CHECK-ERROR: instruction requires: sve // CHECK-UNKNOWN: e0 ff 78 25 +mov z0.h, #-33024 +// CHECK-INST: dupm z0.h, #0x7f00 +// CHECK-ENCODING: [0xc0,0x44,0xc0,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: c0 44 c0 05 + +mov z0.h, #-32769 +// CHECK-INST: mov z0.h, #32767 +// CHECK-ENCODING: [0xc0,0x05,0xc0,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: c0 05 c0 05 + mov z0.s, #-32769 // CHECK-INST: mov z0.s, #0xffff7fff // CHECK-ENCODING: [0xc0,0x83,0xc0,0x05] diff --git a/llvm/test/MC/AArch64/arm64-logical-encoding.s b/llvm/test/MC/AArch64/arm64-logical-encoding.s --- a/llvm/test/MC/AArch64/arm64-logical-encoding.s +++ b/llvm/test/MC/AArch64/arm64-logical-encoding.s @@ -222,3 +222,10 @@ ; CHECK: orn x1, x2, x3, asr #7 ; encoding: [0x41,0x1c,0xa3,0xaa] ; CHECK: orn w1, w2, w3, ror #7 ; encoding: [0x41,0x1c,0xe3,0x2a] ; CHECK: orn x1, x2, x3, ror #7 ; encoding: [0x41,0x1c,0xe3,0xaa] + +;; Allow all-1 in top bits. + and w0, w0, #~(0xfe<<24) + and w1, w1, #~(0xff<<24) + +; CHECK: and w0, w0, #0x1ffffff +; CHECK: and w1, w1, #0xffffff