summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2023-12-17 19:04:51 -0800
committerFangrui Song <i@maskray.me>2023-12-17 19:04:51 -0800
commit5bad8efe3529fac050e1cd601519ea7254a9e4a9 (patch)
treecb3af6b48b0b15b19c1f27c7036720d4c0857b9f
parent6655581038f8479f0f6942b7d34cbd6556d00a0e (diff)
parentd5e16e36d5695812bee8bd3e0d4c2904787bf0c0 (diff)
[𝘀𝗽𝗿] initial versionupstream/users/MaskRay/spr/improve-warning
Created using spr 1.3.4
-rw-r--r--llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp29
-rw-r--r--llvm/test/MC/X86/displacement-overflow.s38
-rw-r--r--llvm/test/MC/X86/x86-64.s52
-rw-r--r--llvm/test/MC/X86/x86_64-asm-match.s6
-rw-r--r--llvm/test/MC/X86/x86_64-encoding.s6
5 files changed, 99 insertions, 32 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index e78d16056460..1d40ce35c1b4 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -3062,6 +3062,35 @@ bool X86AsmParser::ParseMemOperand(unsigned SegReg, const MCExpr *Disp,
ErrMsg))
return Error(BaseLoc, ErrMsg);
+ // If the displacement is a constant, check overflows. For 64-bit addressing,
+ // gas requires isInt<32> and otherwise reports an error. For others, gas
+ // reports a warning and allows a wider range. E.g. gas allows
+ // [-0xffffffff,0xffffffff] for 32-bit addressing (e.g. Linux kernel uses
+ // `leal -__PAGE_OFFSET(%ecx),%esp` where __PAGE_OFFSET is 0xc0000000).
+ if (BaseReg || IndexReg) {
+ if (auto CE = dyn_cast<MCConstantExpr>(Disp)) {
+ auto Imm = CE->getValue();
+ bool Is64 = X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) ||
+ X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg);
+ bool Is16 = X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg);
+ if (Is64) {
+ if (!isInt<32>(Imm))
+ return Error(BaseLoc, "displacement " + Twine(Imm) +
+ " is not within [-2147483648, 2147483647]");
+ } else if (!Is16) {
+ if (!isUInt<32>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
+ Warning(BaseLoc, "displacement " + Twine(Imm) +
+ " shortened to 32-bit signed " +
+ Twine(static_cast<int32_t>(Imm)));
+ }
+ } else if (!isUInt<16>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
+ Warning(BaseLoc, "displacement " + Twine(Imm) +
+ " shortened to 16-bit signed " +
+ Twine(static_cast<int16_t>(Imm)));
+ }
+ }
+ }
+
if (SegReg || BaseReg || IndexReg)
Operands.push_back(X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
BaseReg, IndexReg, Scale, StartLoc,
diff --git a/llvm/test/MC/X86/displacement-overflow.s b/llvm/test/MC/X86/displacement-overflow.s
new file mode 100644
index 000000000000..2882147af482
--- /dev/null
+++ b/llvm/test/MC/X86/displacement-overflow.s
@@ -0,0 +1,38 @@
+# RUN: not llvm-mc -triple=x86_64 %s 2>&1 | FileCheck %s --check-prefixes=CHECK,64 --implicit-check-not=error: --implicit-check-not=warning:
+# RUN: llvm-mc -triple=i686 --defsym A16=1 %s 2>&1 | FileCheck %s --check-prefixes=CHECK,32 --implicit-check-not=error: --implicit-check-not=warning:
+
+.ifndef A16
+movq 0x80000000-1(%rip), %rax
+leaq -0x80000000(%rip), %rax
+
+# 64: [[#@LINE+1]]:17: error: displacement 2147483648 is not within [-2147483648, 2147483647]
+movq 0x80000000(%rip), %rax
+
+# 64: [[#@LINE+1]]:18: error: displacement -2147483649 is not within [-2147483648, 2147483647]
+leaq -0x80000001(%rip), %rax
+.endif
+
+movl 0xffffffff(%eax), %eax
+leal -0xffffffff(%eax), %eax
+
+# CHECK: [[#@LINE+1]]:19: warning: displacement 4294967296 shortened to 32-bit signed 0
+movl 0xffffffff+1(%eax), %eax
+
+# CHECK: [[#@LINE+1]]:20: warning: displacement -4294967296 shortened to 32-bit signed 0
+leal -0xffffffff-1(%eax), %eax
+# CHECK: [[#@LINE+1]]:20: warning: displacement -4294967297 shortened to 32-bit signed -1
+leal -0xffffffff-2(%eax), %eax
+
+{disp8} leal 0x100(%ebx), %eax
+{disp8} leal -0x100(%ebx), %eax
+
+.ifdef A16
+.code16
+movw $0, 0xffff(%bp)
+movw $0, -0xffff(%si)
+
+# 32: [[#@LINE+1]]:19: warning: displacement 65536 shortened to 16-bit signed 0
+movw $0, 0xffff+1(%bp)
+# 32: [[#@LINE+1]]:20: warning: displacement -65536 shortened to 16-bit signed 0
+movw $0, -0xffff-1(%si)
+.endif
diff --git a/llvm/test/MC/X86/x86-64.s b/llvm/test/MC/X86/x86-64.s
index 67b962c563eb..108d1220107e 100644
--- a/llvm/test/MC/X86/x86-64.s
+++ b/llvm/test/MC/X86/x86-64.s
@@ -346,11 +346,11 @@ fnstsw %ax
// rdar://8431880
// CHECK: rclb %bl
-// CHECK: rcll 3735928559(%ebx,%ecx,8)
+// CHECK: rcll 2125315823(%ebx,%ecx,8)
// CHECK: rcrl %ecx
// CHECK: rcrl 305419896
rcl %bl
-rcll 0xdeadbeef(%ebx,%ecx,8)
+rcll 0x7eadbeef(%ebx,%ecx,8)
rcr %ecx
rcrl 0x12345678
@@ -573,9 +573,9 @@ leaq 8(%rax), %rsi
// CHECK: encoding: [0x48,0x8d,0x70,0x08]
-cvttpd2dq 0xdeadbeef(%ebx,%ecx,8),%xmm5
-// CHECK: cvttpd2dq 3735928559(%ebx,%ecx,8), %xmm5
-// CHECK: encoding: [0x67,0x66,0x0f,0xe6,0xac,0xcb,0xef,0xbe,0xad,0xde]
+cvttpd2dq 0x7eadbeef(%ebx,%ecx,8),%xmm5
+// CHECK: cvttpd2dq 2125315823(%ebx,%ecx,8), %xmm5
+// CHECK: encoding: [0x67,0x66,0x0f,0xe6,0xac,0xcb,0xef,0xbe,0xad,0x7e]
// rdar://8490728 - llvm-mc rejects 'movmskpd'
movmskpd %xmm6, %rax
@@ -906,8 +906,8 @@ xchgl %ecx, 368(%rax)
// CHECK: xchgl %ecx, 368(%rax)
// rdar://8407548
-xchg 0xdeadbeef(%rbx,%rcx,8),%bl
-// CHECK: xchgb %bl, 3735928559(%rbx,%rcx,8)
+xchg 0x7fffffff(%rbx,%rcx,8),%bl
+// CHECK: xchgb %bl, 2147483647(%rbx,%rcx,8)
@@ -1112,7 +1112,7 @@ mov %gs, (%rsi) // CHECK: movw %gs, (%rsi) # encoding: [0x8c,0x2e]
//CHECK: divb %bl
//CHECK: divw %bx
//CHECK: divl %ecx
-//CHECK: divl 3735928559(%ebx,%ecx,8)
+//CHECK: divl 2125315823(%ebx,%ecx,8)
//CHECK: divl 69
//CHECK: divl 32493
//CHECK: divl 3133065982
@@ -1120,7 +1120,7 @@ mov %gs, (%rsi) // CHECK: movw %gs, (%rsi) # encoding: [0x8c,0x2e]
//CHECK: idivb %bl
//CHECK: idivw %bx
//CHECK: idivl %ecx
-//CHECK: idivl 3735928559(%ebx,%ecx,8)
+//CHECK: idivl 2125315823(%ebx,%ecx,8)
//CHECK: idivl 69
//CHECK: idivl 32493
//CHECK: idivl 3133065982
@@ -1128,7 +1128,7 @@ mov %gs, (%rsi) // CHECK: movw %gs, (%rsi) # encoding: [0x8c,0x2e]
div %bl,%al
div %bx,%ax
div %ecx,%eax
- div 0xdeadbeef(%ebx,%ecx,8),%eax
+ div 0x7eadbeef(%ebx,%ecx,8),%eax
div 0x45,%eax
div 0x7eed,%eax
div 0xbabecafe,%eax
@@ -1136,7 +1136,7 @@ mov %gs, (%rsi) // CHECK: movw %gs, (%rsi) # encoding: [0x8c,0x2e]
idiv %bl,%al
idiv %bx,%ax
idiv %ecx,%eax
- idiv 0xdeadbeef(%ebx,%ecx,8),%eax
+ idiv 0x7eadbeef(%ebx,%ecx,8),%eax
idiv 0x45,%eax
idiv 0x7eed,%eax
idiv 0xbabecafe,%eax
@@ -1510,9 +1510,9 @@ vmovd %xmm0, %eax
vmovd %xmm0, %rax
vmovq %xmm0, %rax
-// CHECK: seto 3735928559(%r10,%r9,8)
-// CHECK: encoding: [0x43,0x0f,0x90,0x84,0xca,0xef,0xbe,0xad,0xde]
- seto 0xdeadbeef(%r10,%r9,8)
+// CHECK: seto 2125315823(%r10,%r9,8)
+// CHECK: encoding: [0x43,0x0f,0x90,0x84,0xca,0xef,0xbe,0xad,0x7e]
+ seto 0x7eadbeef(%r10,%r9,8)
// CHECK: monitorx
// CHECK: encoding: [0x0f,0x01,0xfa]
@@ -1550,9 +1550,9 @@ vmovq %xmm0, %rax
// CHECK: encoding: [0x47,0x89,0x3c,0x3f]
movl %r15d, (%r15,%r15)
-// CHECK: nopq 3735928559(%rbx,%rcx,8)
-// CHECK: encoding: [0x48,0x0f,0x1f,0x84,0xcb,0xef,0xbe,0xad,0xde]
-nopq 0xdeadbeef(%rbx,%rcx,8)
+// CHECK: nopq 2125315823(%rbx,%rcx,8)
+// CHECK: encoding: [0x48,0x0f,0x1f,0x84,0xcb,0xef,0xbe,0xad,0x7e]
+nopq 0x7eadbeef(%rbx,%rcx,8)
// CHECK: nopq %rax
// CHECK: encoding: [0x48,0x0f,0x1f,0xc0]
@@ -1562,17 +1562,17 @@ nopq %rax
// CHECK: encoding: [0xf3,0x0f,0xc7,0xf8]
rdpid %rax
-// CHECK: ptwritel 3735928559(%rbx,%rcx,8)
-// CHECK: encoding: [0xf3,0x0f,0xae,0xa4,0xcb,0xef,0xbe,0xad,0xde]
-ptwritel 0xdeadbeef(%rbx,%rcx,8)
+// CHECK: ptwritel 2125315823(%rbx,%rcx,8)
+// CHECK: encoding: [0xf3,0x0f,0xae,0xa4,0xcb,0xef,0xbe,0xad,0x7e]
+ptwritel 0x7eadbeef(%rbx,%rcx,8)
// CHECK: ptwritel %eax
// CHECK: encoding: [0xf3,0x0f,0xae,0xe0]
ptwritel %eax
-// CHECK: ptwriteq 3735928559(%rbx,%rcx,8)
-// CHECK: encoding: [0xf3,0x48,0x0f,0xae,0xa4,0xcb,0xef,0xbe,0xad,0xde]
-ptwriteq 0xdeadbeef(%rbx,%rcx,8)
+// CHECK: ptwriteq 2125315823(%rbx,%rcx,8)
+// CHECK: encoding: [0xf3,0x48,0x0f,0xae,0xa4,0xcb,0xef,0xbe,0xad,0x7e]
+ptwriteq 0x7eadbeef(%rbx,%rcx,8)
// CHECK: ptwriteq %rax
// CHECK: encoding: [0xf3,0x48,0x0f,0xae,0xe0]
@@ -1586,9 +1586,9 @@ wbnoinvd
// CHECK: encoding: [0x0f,0x1c,0x40,0x04]
cldemote 4(%rax)
-// CHECK: cldemote 3735928559(%rbx,%rcx,8)
-// CHECK: encoding: [0x0f,0x1c,0x84,0xcb,0xef,0xbe,0xad,0xde]
-cldemote 0xdeadbeef(%rbx,%rcx,8)
+// CHECK: cldemote 2125315823(%rbx,%rcx,8)
+// CHECK: encoding: [0x0f,0x1c,0x84,0xcb,0xef,0xbe,0xad,0x7e]
+cldemote 0x7eadbeef(%rbx,%rcx,8)
// CHECK: umonitor %r13
// CHECK: encoding: [0xf3,0x41,0x0f,0xae,0xf5]
diff --git a/llvm/test/MC/X86/x86_64-asm-match.s b/llvm/test/MC/X86/x86_64-asm-match.s
index 50f25e59f49f..7d35ebdbb2c2 100644
--- a/llvm/test/MC/X86/x86_64-asm-match.s
+++ b/llvm/test/MC/X86/x86_64-asm-match.s
@@ -31,9 +31,9 @@
// CHECK: Opcode result: complete match, selecting this opcode
// CHECK: AsmMatcher: found 2 encodings with mnemonic 'crc32l'
// CHECK: Trying to match opcode CRC32r32r32
-// CHECK: Matching formal operand class MCK_GR32 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=rbx,IndexReg=rcx,Scale=8,Disp=3735928559,SegReg=gs): Opcode result: multiple operand mismatches, ignoring this opcode
+// CHECK: Matching formal operand class MCK_GR32 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=rbx,IndexReg=rcx,Scale=8,Disp=2125315823,SegReg=gs): Opcode result: multiple operand mismatches, ignoring this opcode
// CHECK: Trying to match opcode CRC32r32m32
-// CHECK: Matching formal operand class MCK_Mem32 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=rbx,IndexReg=rcx,Scale=8,Disp=3735928559,SegReg=gs): match success using generic matcher
+// CHECK: Matching formal operand class MCK_Mem32 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=rbx,IndexReg=rcx,Scale=8,Disp=2125315823,SegReg=gs): match success using generic matcher
// CHECK: Matching formal operand class MCK_GR32 against actual operand at index 2 (Reg:ecx): match success using generic matcher
// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range
// CHECK: Opcode result: complete match, selecting this opcode
@@ -62,7 +62,7 @@
pshufb CPI1_0(%rip), %xmm1
sha1rnds4 $1, %xmm1, %xmm2
pinsrw $3, %ecx, %xmm5
-crc32l %gs:0xdeadbeef(%rbx,%rcx,8),%ecx
+crc32l %gs:0x7eadbeef(%rbx,%rcx,8),%ecx
maskmovdqu %xmm0, %xmm1
vmaskmovdqu %xmm0, %xmm1
diff --git a/llvm/test/MC/X86/x86_64-encoding.s b/llvm/test/MC/X86/x86_64-encoding.s
index ff541c2d6568..247b1dc656bc 100644
--- a/llvm/test/MC/X86/x86_64-encoding.s
+++ b/llvm/test/MC/X86/x86_64-encoding.s
@@ -29,9 +29,9 @@ movq %gs:(%rdi), %rax
// CHECK: encoding: [0xf2,0x0f,0x38,0xf1,0x43,0x04]
crc32l 4(%rbx), %eax
-// CHECK: crc32l 3735928559(%rbx,%rcx,8), %ecx
-// CHECK: encoding: [0xf2,0x0f,0x38,0xf1,0x8c,0xcb,0xef,0xbe,0xad,0xde]
- crc32l 0xdeadbeef(%rbx,%rcx,8),%ecx
+// CHECK: crc32l 2125315823(%rbx,%rcx,8), %ecx
+// CHECK: encoding: [0xf2,0x0f,0x38,0xf1,0x8c,0xcb,0xef,0xbe,0xad,0x7e]
+ crc32l 0x7eadbeef(%rbx,%rcx,8),%ecx
// CHECK: crc32l 69, %ecx
// CHECK: encoding: [0xf2,0x0f,0x38,0xf1,0x0c,0x25,0x45,0x00,0x00,0x00]