[llvm] [Mips] Allow expressions in some immediate operands (PR #127581)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 1 10:19:35 PST 2025


https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/127581

>From cc48332e51b6670ebcb36f7b4676d47d04e7ee90 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Mon, 17 Feb 2025 23:02:35 -0800
Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
 =?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.5-bogner
---
 .../Target/Mips/AsmParser/MipsAsmParser.cpp   | 14 +++++-
 .../Mips/MCTargetDesc/MipsAsmBackend.cpp      | 29 +++++++-----
 .../Target/Mips/MCTargetDesc/MipsBaseInfo.h   | 22 ++++++----
 .../Mips/MCTargetDesc/MipsELFObjectWriter.cpp |  3 +-
 .../Target/Mips/MCTargetDesc/MipsFixupKinds.h | 21 +++++----
 .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp   | 44 ++++++++++---------
 .../Mips/MCTargetDesc/MipsMCCodeEmitter.h     |  3 ++
 llvm/test/MC/Mips/fixup-expr.s                | 37 ++++++++++++++++
 llvm/test/MC/Mips/fixup-out-of-range.s        | 13 ++++++
 llvm/test/MC/Mips/imm-operand-err.s           | 10 ++---
 10 files changed, 141 insertions(+), 55 deletions(-)
 create mode 100644 llvm/test/MC/Mips/fixup-expr.s
 create mode 100644 llvm/test/MC/Mips/fixup-out-of-range.s

diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 8c328d5ed7234..82fff1dad697f 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -1311,11 +1311,21 @@ class MipsOperand : public MCParsedAsmOperand {
   }
 
   template <unsigned Bits> bool isSImm() const {
-    return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
+    if (!isImm())
+      return false;
+    int64_t Res;
+    if (getImm()->evaluateAsAbsolute(Res))
+      return isInt<Bits>(Res);
+    return true;
   }
 
   template <unsigned Bits> bool isUImm() const {
-    return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
+    if (!isImm())
+      return false;
+    int64_t Res;
+    if (getImm()->evaluateAsAbsolute(Res))
+      return isUInt<Bits>(Res);
+    return true;
   }
 
   template <unsigned Bits> bool isAnyImm() const {
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
index 4af6768b13cc9..49df6a5e7fca6 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
@@ -60,6 +60,11 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
   case Mips::fixup_MIPS_PCLO16:
     Value &= 0xffff;
     break;
+  case Mips::fixup_Mips_AnyImm16:
+    if (!isInt<16>(Value) && !isUInt<16>(Value))
+      Ctx.reportError(Fixup.getLoc(),
+                      "fixup value out of range [-32768, 65535]");
+    break;
   case FK_DTPRel_4:
   case FK_DTPRel_8:
   case FK_TPRel_4:
@@ -351,16 +356,18 @@ std::optional<MCFixupKind> MipsAsmBackend::getFixupKind(StringRef Name) const {
 const MCFixupKindInfo &MipsAsmBackend::
 getFixupKindInfo(MCFixupKind Kind) const {
   const static MCFixupKindInfo LittleEndianInfos[] = {
-    // This table *must* be in same the order of fixup_* kinds in
-    // MipsFixupKinds.h.
-    //
-    // name                    offset  bits  flags
+      // This table *must* be in same the order of fixup_* kinds in
+      // MipsFixupKinds.h.
+      //
+      // name                    offset  bits  flags
+      // clang-format off
     { "fixup_Mips_16",           0,     16,   0 },
     { "fixup_Mips_32",           0,     32,   0 },
     { "fixup_Mips_REL32",        0,     32,   0 },
     { "fixup_Mips_26",           0,     26,   0 },
     { "fixup_Mips_HI16",         0,     16,   0 },
     { "fixup_Mips_LO16",         0,     16,   0 },
+    { "fixup_Mips_AnyImm16",     0,     16,   0 },
     { "fixup_Mips_GPREL16",      0,     16,   0 },
     { "fixup_Mips_LITERAL",      0,     16,   0 },
     { "fixup_Mips_GOT",          0,     16,   0 },
@@ -424,22 +431,24 @@ getFixupKindInfo(MCFixupKind Kind) const {
     { "fixup_Mips_SUB",                  0,     64,   0 },
     { "fixup_MICROMIPS_SUB",             0,     64,   0 },
     { "fixup_Mips_JALR",                 0,     32,   0 },
-    { "fixup_MICROMIPS_JALR",            0,     32,   0 }
+    { "fixup_MICROMIPS_JALR",            0,     32,   0 } // clang-format on
   };
   static_assert(std::size(LittleEndianInfos) == Mips::NumTargetFixupKinds,
                 "Not all MIPS little endian fixup kinds added!");
 
   const static MCFixupKindInfo BigEndianInfos[] = {
-    // This table *must* be in same the order of fixup_* kinds in
-    // MipsFixupKinds.h.
-    //
-    // name                    offset  bits  flags
+      // This table *must* be in same the order of fixup_* kinds in
+      // MipsFixupKinds.h.
+      //
+      // name                    offset  bits  flags
+      // clang-format off
     { "fixup_Mips_16",          16,     16,   0 },
     { "fixup_Mips_32",           0,     32,   0 },
     { "fixup_Mips_REL32",        0,     32,   0 },
     { "fixup_Mips_26",           6,     26,   0 },
     { "fixup_Mips_HI16",        16,     16,   0 },
     { "fixup_Mips_LO16",        16,     16,   0 },
+    { "fixup_Mips_AnyImm16",    16,     16,   0 },
     { "fixup_Mips_GPREL16",     16,     16,   0 },
     { "fixup_Mips_LITERAL",     16,     16,   0 },
     { "fixup_Mips_GOT",         16,     16,   0 },
@@ -503,7 +512,7 @@ getFixupKindInfo(MCFixupKind Kind) const {
     { "fixup_Mips_SUB",                   0,     64,   0 },
     { "fixup_MICROMIPS_SUB",              0,     64,   0 },
     { "fixup_Mips_JALR",                  0,     32,   0 },
-    { "fixup_MICROMIPS_JALR",             0,     32,   0 }
+    { "fixup_MICROMIPS_JALR",             0,     32,   0 } // clang-format on
   };
   static_assert(std::size(BigEndianInfos) == Mips::NumTargetFixupKinds,
                 "Not all MIPS big endian fixup kinds added!");
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h
index bd4c5d35ddfbe..b0c5aea9bddab 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h
@@ -26,7 +26,8 @@ namespace llvm {
 /// instruction info tracks.
 ///
 namespace MipsII {
-  /// Target Operand Flag enum.
+/// Target Operand Flag enum.
+// clang-format off
   enum TOF {
     //===------------------------------------------------------------------===//
     // Mips Specific MachineOperand flags.
@@ -100,7 +101,7 @@ namespace MipsII {
     MO_DLLIMPORT = 0x20,
   };
 
-  enum {
+enum {
     //===------------------------------------------------------------------===//
     // Instruction encodings.  These are the standard/most common forms for
     // Mips instructions.
@@ -132,13 +133,18 @@ namespace MipsII {
     /// HasFCCRegOperand - Instruction uses an $fcc<x> register.
     HasFCCRegOperand = 1 << 6
 
-  };
+};
+// clang-format on
 
-  enum OperandType : unsigned {
-    OPERAND_FIRST_MIPS_MEM_IMM = MCOI::OPERAND_FIRST_TARGET,
-    OPERAND_MEM_SIMM9 = OPERAND_FIRST_MIPS_MEM_IMM,
-    OPERAND_LAST_MIPS_MEM_IMM = OPERAND_MEM_SIMM9
-  };
+enum OperandType : unsigned {
+  OPERAND_FIRST_MIPS_MEM_IMM = MCOI::OPERAND_FIRST_TARGET,
+  OPERAND_MEM_SIMM9 = OPERAND_FIRST_MIPS_MEM_IMM,
+  OPERAND_LAST_MIPS_MEM_IMM = OPERAND_MEM_SIMM9
+};
+
+static inline unsigned getFormat(uint64_t TSFlags) {
+  return TSFlags & FormMask;
+}
 }
 
 inline static MCRegister getMSARegFromFReg(MCRegister Reg) {
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
index f2d4a6a5bf263..b60b336422ed5 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
@@ -328,7 +328,8 @@ unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx,
     return ELF::R_MICROMIPS_JALR;
   }
 
-  llvm_unreachable("invalid fixup kind!");
+  Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
+  return ELF::R_MIPS_NONE;
 }
 
 /// Sort relocation table entries by offset except where another order is
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h
index b83d822bd8d03..1c8b59396ad8f 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h
@@ -13,14 +13,15 @@
 
 namespace llvm {
 namespace Mips {
-  // Although most of the current fixup types reflect a unique relocation
-  // one can have multiple fixup types for a given relocation and thus need
-  // to be uniquely named.
-  //
-  // This table *must* be in the same order of
-  // MCFixupKindInfo Infos[Mips::NumTargetFixupKinds]
-  // in MipsAsmBackend.cpp.
-  //
+// Although most of the current fixup types reflect a unique relocation
+// one can have multiple fixup types for a given relocation and thus need
+// to be uniquely named.
+//
+// This table *must* be in the same order of
+// MCFixupKindInfo Infos[Mips::NumTargetFixupKinds]
+// in MipsAsmBackend.cpp.
+//
+// clang-format off
   enum Fixups {
     // Branch fixups resulting in R_MIPS_16.
     fixup_Mips_16 = FirstTargetFixupKind,
@@ -40,6 +41,9 @@ namespace Mips {
     // Pure lower 16 bit fixup resulting in - R_MIPS_LO16.
     fixup_Mips_LO16,
 
+    // 16-bit fixup that must be resolved.
+    fixup_Mips_AnyImm16,
+
     // 16 bit fixup for GP offest resulting in - R_MIPS_GPREL16.
     fixup_Mips_GPREL16,
 
@@ -226,6 +230,7 @@ namespace Mips {
     LastTargetFixupKind,
     NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
   };
+// clang-format on
 } // namespace Mips
 } // namespace llvm
 
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index 097b3cf8aa723..23e8ea53f5142 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "MipsMCCodeEmitter.h"
+#include "MCTargetDesc/MipsBaseInfo.h"
 #include "MCTargetDesc/MipsFixupKinds.h"
 #include "MCTargetDesc/MipsMCExpr.h"
 #include "MCTargetDesc/MipsMCTargetDesc.h"
@@ -578,23 +579,7 @@ getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo,
 unsigned MipsMCCodeEmitter::
 getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
                const MCSubtargetInfo &STI) const {
-  int64_t Res;
-
-  if (Expr->evaluateAsAbsolute(Res))
-    return Res;
-
   MCExpr::ExprKind Kind = Expr->getKind();
-  if (Kind == MCExpr::Constant) {
-    return cast<MCConstantExpr>(Expr)->getValue();
-  }
-
-  if (Kind == MCExpr::Binary) {
-    unsigned Res =
-        getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI);
-    Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI);
-    return Res;
-  }
-
   if (Kind == MCExpr::Target) {
     const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);
 
@@ -712,8 +697,7 @@ getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
     return 0;
   }
 
-  if (Kind == MCExpr::SymbolRef)
-    Ctx.reportError(Expr->getLoc(), "expected an immediate");
+  Ctx.reportError(Expr->getLoc(), "expected an immediate");
   return 0;
 }
 
@@ -732,9 +716,29 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
   } else if (MO.isDFPImm()) {
     return static_cast<unsigned>(bit_cast<double>(MO.getDFPImm()));
   }
-  // MO must be an Expr.
+  // TODO: Set EncoderMethod to "getImmOpValue" for imm Operand so that
+  // getMachineOpValue will not be called for isExpr code paths.
   assert(MO.isExpr());
-  return getExprOpValue(MO.getExpr(),Fixups, STI);
+  return getImmOpValue(MI, MO, Fixups, STI);
+}
+
+unsigned MipsMCCodeEmitter::getImmOpValue(const MCInst &MI, const MCOperand &MO,
+                                          SmallVectorImpl<MCFixup> &Fixups,
+                                          const MCSubtargetInfo &STI) const {
+  if (MO.isImm())
+    return MO.getImm();
+  assert(MO.isExpr() && "getImmOpValue expects only expressions or immediates");
+  const MCExpr *Expr = MO.getExpr();
+  int64_t Res;
+  if (Expr->evaluateAsAbsolute(Res))
+    return Res;
+  unsigned MIFrm = MipsII::getFormat(MCII.get(MI.getOpcode()).TSFlags);
+  if (!isa<MCTargetExpr>(Expr) && MIFrm == MipsII::FrmI) {
+    Fixups.push_back(MCFixup::create(
+        0, Expr, MCFixupKind(Mips::fixup_Mips_AnyImm16), MI.getLoc()));
+    return 0;
+  }
+  return getExprOpValue(Expr, Fixups, STI);
 }
 
 /// Return binary encoding of memory related operand.
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
index 871afd9eb9584..497b3e64df533 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
@@ -177,6 +177,9 @@ class MipsMCCodeEmitter : public MCCodeEmitter {
   unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
                              SmallVectorImpl<MCFixup> &Fixups,
                              const MCSubtargetInfo &STI) const;
+  unsigned getImmOpValue(const MCInst &MI, const MCOperand &MO,
+                         SmallVectorImpl<MCFixup> &Fixups,
+                         const MCSubtargetInfo &STI) const;
 
   unsigned getMSAMemEncoding(const MCInst &MI, unsigned OpNo,
                              SmallVectorImpl<MCFixup> &Fixups,
diff --git a/llvm/test/MC/Mips/fixup-expr.s b/llvm/test/MC/Mips/fixup-expr.s
new file mode 100644
index 0000000000000..85a855e1a83c0
--- /dev/null
+++ b/llvm/test/MC/Mips/fixup-expr.s
@@ -0,0 +1,37 @@
+# RUN: llvm-mc -filetype=obj -triple=mips64 %s -o %t.be
+# RUN: llvm-objdump -d %t.be | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple=mips64el %s -o %t.le
+# RUN: llvm-objdump -d %t.le | FileCheck %s
+
+# RUN: not llvm-mc -filetype=obj -triple=mips64el --defsym ERR=1 %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR
+
+# CHECK:      addiu $4, $5, -0x8000
+# CHECK-NEXT: addiu $4, $5, -0x1
+# CHECK-NEXT: addiu $4, $5, -0x8000
+# CHECK-NEXT: addiu $4, $5, 0x7fff
+# CHECK-NEXT: addiu $4, $5, -0x1
+addiu $4, $5, v_32769+1
+addiu $4, $5, v65535
+addiu $4, $5, .L0-.L1
+addiu $4, $5, .L2-.L1
+addiu $4, $5, .L2-.L0+0
+
+.ifdef ERR
+# ERR: :[[#@LINE+1]]:1: error: fixup value out of range [-32768, 65535]
+addiu $4, $5, v_32769
+# ERR: :[[#@LINE+1]]:1: error: fixup value out of range [-32768, 65535]
+addiu $4, $5, v65535+1
+
+# ERR: [[#@LINE+1]]:1: error: fixup value out of range [-32768, 65535]
+addiu $4, $5, .L2-.L0+1
+.endif
+
+v_32769 = -32769
+v65535 = 65535
+
+.section .rodata,"a"
+.L0:
+.space 32768
+.L1:
+.space 32767
+.L2:
diff --git a/llvm/test/MC/Mips/fixup-out-of-range.s b/llvm/test/MC/Mips/fixup-out-of-range.s
new file mode 100644
index 0000000000000..08744c8b2320d
--- /dev/null
+++ b/llvm/test/MC/Mips/fixup-out-of-range.s
@@ -0,0 +1,13 @@
+# RUN: not llvm-mc -triple mips64 -filetype obj %s -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error:
+
+# CHECK: :[[#@LINE+1]]:1: error: fixup value out of range [-32768, 65535]
+addiu $t2, $t3, v_32769
+addiu $t2, $t3, v_32768
+addiu $t2, $t3, v65535
+# CHECK: :[[#@LINE+1]]:1: error: fixup value out of range [-32768, 65535]
+addiu $t2, $t3, v65536
+
+v_32769 = -32769
+v_32768 = -32768
+v65535 = 65535
+v65536 = 65536
diff --git a/llvm/test/MC/Mips/imm-operand-err.s b/llvm/test/MC/Mips/imm-operand-err.s
index 8ded4a21b4807..278ba0cacda96 100644
--- a/llvm/test/MC/Mips/imm-operand-err.s
+++ b/llvm/test/MC/Mips/imm-operand-err.s
@@ -1,15 +1,13 @@
 ## Print an error if a non-immediate operand is used while an immediate is expected
-# RUN: not llvm-mc -filetype=obj -triple=mips -o /dev/null %s 2>&1 | FileCheck %s
-# RUN: not llvm-mc -filetype=obj -triple=mips64 -o /dev/null %s 2>&1 | FileCheck %s
+# RUN: not llvm-mc -filetype=obj -triple=mips -o /dev/null %s 2>&1 | FileCheck %s --implicit-check-not=error:
+# RUN: not llvm-mc -filetype=obj -triple=mips64 -o /dev/null %s 2>&1 | FileCheck %s --implicit-check-not=error:
 
-# CHECK: [[#@LINE+1]]:16: error: expected an immediate
+# CHECK: [[#@LINE+1]]:3: error: unsupported relocation type
   ori  $4, $4, start
-# CHECK: [[#@LINE+1]]:17: error: expected an immediate
   ori  $4, $4, (start - .)
 
-# CHECK: [[#@LINE+1]]:18: error: expected an immediate
+# CHECK: [[#@LINE+1]]:3: error: unsupported relocation type
   addiu  $4, $4, start
-# CHECK: [[#@LINE+1]]:19: error: expected an immediate
   addiu  $4, $4, (start - .)
 
 start:

>From c0476c3f22b6eea389b719d38a2c1e3447a954cc Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Mon, 17 Feb 2025 23:42:55 -0800
Subject: [PATCH 2/2] comment better test

Created using spr 1.3.5-bogner
---
 llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp    |  2 ++
 .../Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp  |  2 +-
 llvm/test/MC/Mips/fixup-expr.s                      | 11 ++++++++---
 llvm/test/MC/Mips/fixup-out-of-range.s              | 13 -------------
 llvm/test/MC/Mips/imm-operand-err.s                 |  4 ++--
 5 files changed, 13 insertions(+), 19 deletions(-)
 delete mode 100644 llvm/test/MC/Mips/fixup-out-of-range.s

diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 82fff1dad697f..7fdf02d29e173 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -1316,6 +1316,7 @@ class MipsOperand : public MCParsedAsmOperand {
     int64_t Res;
     if (getImm()->evaluateAsAbsolute(Res))
       return isInt<Bits>(Res);
+    // Allow conservatively if not a parse-time constant.
     return true;
   }
 
@@ -1325,6 +1326,7 @@ class MipsOperand : public MCParsedAsmOperand {
     int64_t Res;
     if (getImm()->evaluateAsAbsolute(Res))
       return isUInt<Bits>(Res);
+    // Allow conservatively if not a parse-time constant.
     return true;
   }
 
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index 23e8ea53f5142..d53ee15168825 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -735,7 +735,7 @@ unsigned MipsMCCodeEmitter::getImmOpValue(const MCInst &MI, const MCOperand &MO,
   unsigned MIFrm = MipsII::getFormat(MCII.get(MI.getOpcode()).TSFlags);
   if (!isa<MCTargetExpr>(Expr) && MIFrm == MipsII::FrmI) {
     Fixups.push_back(MCFixup::create(
-        0, Expr, MCFixupKind(Mips::fixup_Mips_AnyImm16), MI.getLoc()));
+        0, Expr, MCFixupKind(Mips::fixup_Mips_AnyImm16), Expr->getLoc()));
     return 0;
   }
   return getExprOpValue(Expr, Fixups, STI);
diff --git a/llvm/test/MC/Mips/fixup-expr.s b/llvm/test/MC/Mips/fixup-expr.s
index 85a855e1a83c0..b296a31d6e1cc 100644
--- a/llvm/test/MC/Mips/fixup-expr.s
+++ b/llvm/test/MC/Mips/fixup-expr.s
@@ -16,13 +16,18 @@ addiu $4, $5, .L0-.L1
 addiu $4, $5, .L2-.L1
 addiu $4, $5, .L2-.L0+0
 
+# CHECK:      andi $4, $5, 0xffff
+# CHECK:      slti $4, $5, -0x1
+andi $4, $5, v65535 # uimm16
+slti $4, $5, v65535 # simm16
+
 .ifdef ERR
-# ERR: :[[#@LINE+1]]:1: error: fixup value out of range [-32768, 65535]
+# ERR: :[[#@LINE+1]]:15: error: fixup value out of range [-32768, 65535]
 addiu $4, $5, v_32769
-# ERR: :[[#@LINE+1]]:1: error: fixup value out of range [-32768, 65535]
+# ERR: :[[#@LINE+1]]:21: error: fixup value out of range [-32768, 65535]
 addiu $4, $5, v65535+1
 
-# ERR: [[#@LINE+1]]:1: error: fixup value out of range [-32768, 65535]
+# ERR: [[#@LINE+1]]:18: error: fixup value out of range [-32768, 65535]
 addiu $4, $5, .L2-.L0+1
 .endif
 
diff --git a/llvm/test/MC/Mips/fixup-out-of-range.s b/llvm/test/MC/Mips/fixup-out-of-range.s
deleted file mode 100644
index 08744c8b2320d..0000000000000
--- a/llvm/test/MC/Mips/fixup-out-of-range.s
+++ /dev/null
@@ -1,13 +0,0 @@
-# RUN: not llvm-mc -triple mips64 -filetype obj %s -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error:
-
-# CHECK: :[[#@LINE+1]]:1: error: fixup value out of range [-32768, 65535]
-addiu $t2, $t3, v_32769
-addiu $t2, $t3, v_32768
-addiu $t2, $t3, v65535
-# CHECK: :[[#@LINE+1]]:1: error: fixup value out of range [-32768, 65535]
-addiu $t2, $t3, v65536
-
-v_32769 = -32769
-v_32768 = -32768
-v65535 = 65535
-v65536 = 65536
diff --git a/llvm/test/MC/Mips/imm-operand-err.s b/llvm/test/MC/Mips/imm-operand-err.s
index 278ba0cacda96..b4a2b58912325 100644
--- a/llvm/test/MC/Mips/imm-operand-err.s
+++ b/llvm/test/MC/Mips/imm-operand-err.s
@@ -2,11 +2,11 @@
 # RUN: not llvm-mc -filetype=obj -triple=mips -o /dev/null %s 2>&1 | FileCheck %s --implicit-check-not=error:
 # RUN: not llvm-mc -filetype=obj -triple=mips64 -o /dev/null %s 2>&1 | FileCheck %s --implicit-check-not=error:
 
-# CHECK: [[#@LINE+1]]:3: error: unsupported relocation type
+# CHECK: [[#@LINE+1]]:16: error: unsupported relocation type
   ori  $4, $4, start
   ori  $4, $4, (start - .)
 
-# CHECK: [[#@LINE+1]]:3: error: unsupported relocation type
+# CHECK: [[#@LINE+1]]:18: error: unsupported relocation type
   addiu  $4, $4, start
   addiu  $4, $4, (start - .)
 



More information about the llvm-commits mailing list