[RISCV] implement li pseudo instruction
authorAlex Bradbury <asb@lowrisc.org>
Tue, 17 Apr 2018 21:56:40 +0000 (21:56 +0000)
committerAlex Bradbury <asb@lowrisc.org>
Tue, 17 Apr 2018 21:56:40 +0000 (21:56 +0000)
The implementation follows the MIPS backend and expands the
pseudo instruction directly during asm parsing. As the result, only
real MC instructions are emitted to the MCStreamer. Additionally,
PseudoLI instructions are emitted during codegen. The actual
expansion to real instructions is performed during MI to MC lowering
and is similar to the expansion performed by the GNU Assembler.

Differential Revision: https://reviews.llvm.org/D41949
Patch by Mario Werner.

llvm-svn: 330224

18 files changed:
llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt
llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCPseudoExpansion.cpp [new file with mode: 0644]
llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCPseudoExpansion.h [new file with mode: 0644]
llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
llvm/lib/Target/RISCV/RISCVInstrFormats.td
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
llvm/lib/Target/RISCV/RISCVInstrInfo.td
llvm/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll
llvm/test/CodeGen/RISCV/calling-conv.ll
llvm/test/CodeGen/RISCV/float-arith.ll
llvm/test/CodeGen/RISCV/vararg.ll
llvm/test/MC/RISCV/rv32i-aliases-invalid.s
llvm/test/MC/RISCV/rv32i-aliases-valid.s
llvm/test/MC/RISCV/rv64i-aliases-invalid.s
llvm/test/MC/RISCV/rv64i-aliases-valid.s
llvm/test/MC/RISCV/rvi-aliases-valid.s

index 521d72b546dcf75ae9e547b45ccd58a1f5775624..7f0433410d042b20b0812009b79ec4106de98ecd 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "MCTargetDesc/RISCVBaseInfo.h"
 #include "MCTargetDesc/RISCVMCExpr.h"
+#include "MCTargetDesc/RISCVMCPseudoExpansion.h"
 #include "MCTargetDesc/RISCVMCTargetDesc.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/TargetRegistry.h"
 
+#include <limits>
+
 using namespace llvm;
 
 // Include the auto-generated portion of the compress emitter.
@@ -41,7 +45,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
                                       unsigned Kind) override;
 
   bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
-                                  int Lower, int Upper, Twine Msg);
+                                  int64_t Lower, int64_t Upper, Twine Msg);
 
   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
                                OperandVector &Operands, MCStreamer &Out,
@@ -55,6 +59,12 @@ class RISCVAsmParser : public MCTargetAsmParser {
 
   bool ParseDirective(AsmToken DirectiveID) override;
 
+  /// Helper for emitting MC instructions that have been successfully matched
+  /// by MatchAndEmitInstruction. Modifications to the emitted instructions,
+  /// like the expansion of pseudo instructions (e.g., "li"), can be performed
+  /// in this method.
+  bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
+
 // Auto-generated instruction matching functions
 #define GET_ASSEMBLER_HEADER
 #include "RISCVGenAsmMatcher.inc"
@@ -210,6 +220,18 @@ public:
     return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid;
   }
 
+  bool isImmXLen() const {
+    int64_t Imm;
+    RISCVMCExpr::VariantKind VK;
+    if (!isImm())
+      return false;
+    bool IsConstantImm = evaluateConstantImm(Imm, VK);
+    // Given only Imm, ensuring that the actually specified constant is either
+    // a signed or unsigned 64-bit number is unfortunately impossible.
+    bool IsInRange = isRV64() ? true : isInt<32>(Imm) || isUInt<32>(Imm);
+    return IsConstantImm && IsInRange && VK == RISCVMCExpr::VK_RISCV_None;
+  }
+
   bool isUImmLog2XLen() const {
     int64_t Imm;
     RISCVMCExpr::VariantKind VK;
@@ -583,7 +605,7 @@ unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
 }
 
 bool RISCVAsmParser::generateImmOutOfRangeError(
-    OperandVector &Operands, uint64_t ErrorInfo, int Lower, int Upper,
+    OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
     Twine Msg = "immediate must be an integer in the range") {
   SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
   return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
@@ -599,14 +621,8 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
   default:
     break;
-  case Match_Success: {
-    MCInst CInst;
-    bool Res = compressInst(CInst, Inst, getSTI(), Out.getContext());
-    CInst.setLoc(IDLoc);
-    Inst.setLoc(IDLoc);
-    Out.EmitInstruction((Res ? CInst : Inst), getSTI());
-    return false;
-  }
+  case Match_Success:
+    return processInstruction(Inst, IDLoc, Out);
   case Match_MissingFeature:
     return Error(IDLoc, "instruction use requires an option to be enabled");
   case Match_MnemonicFail:
@@ -623,6 +639,14 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
     }
     return Error(ErrorLoc, "invalid operand for instruction");
   }
+  case Match_InvalidImmXLen:
+    if (isRV64()) {
+      SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
+      return Error(ErrorLoc, "operand must be a constant 64-bit integer");
+    }
+    return generateImmOutOfRangeError(Operands, ErrorInfo,
+                                      std::numeric_limits<int32_t>::min(),
+                                      std::numeric_limits<uint32_t>::max());
   case Match_InvalidUImmLog2XLen:
     if (isRV64())
       return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
@@ -967,6 +991,31 @@ bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr,
   return Kind != RISCVMCExpr::VK_RISCV_Invalid;
 }
 
+bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
+                                        MCStreamer &Out) {
+  Inst.setLoc(IDLoc);
+
+  switch (Inst.getOpcode()) {
+  case RISCV::PseudoLI: {
+    auto Reg = Inst.getOperand(0).getReg();
+    int64_t Imm = Inst.getOperand(1).getImm();
+    // On RV32 the immediate here can either be a signed or an unsigned
+    // 32-bit number. Sign extension has to be performed to ensure that Imm
+    // represents the expected signed 64-bit number.
+    if (!isRV64())
+      Imm = SignExtend64<32>(Imm);
+    emitRISCVLoadImm(Reg, Imm, Out, STI);
+    return false;
+  }
+  }
+
+  MCInst CInst;
+  bool Res = compressInst(CInst, Inst, getSTI(), Out.getContext());
+  CInst.setLoc(IDLoc);
+  Out.EmitInstruction((Res ? CInst : Inst), getSTI());
+  return false;
+}
+
 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { return true; }
 
 extern "C" void LLVMInitializeRISCVAsmParser() {
index d9f4188aa75ce55fff139a91fb9f6d1b671c8771..2ea149a388dd69528b1c1d47f5ede51f94ce57dc 100644 (file)
@@ -4,6 +4,7 @@ add_llvm_library(LLVMRISCVDesc
   RISCVMCAsmInfo.cpp
   RISCVMCCodeEmitter.cpp
   RISCVMCExpr.cpp
+  RISCVMCPseudoExpansion.cpp
   RISCVMCTargetDesc.cpp
   RISCVTargetStreamer.cpp
   RISCVELFStreamer.cpp
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCPseudoExpansion.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCPseudoExpansion.cpp
new file mode 100644 (file)
index 0000000..406c4c2
--- /dev/null
@@ -0,0 +1,101 @@
+//===-- RISCVMCPseudoExpansion.cpp - RISCV MC Pseudo Expansion ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// This file provides helpers to expand pseudo MC instructions that are usable
+/// in the AsmParser and the AsmPrinter.
+///
+//===----------------------------------------------------------------------===//
+
+#include "RISCVMCPseudoExpansion.h"
+#include "RISCVMCTargetDesc.h"
+#include "llvm/MC/MCInstBuilder.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/MathExtras.h"
+
+#include <cassert>
+
+using namespace llvm;
+
+void llvm::emitRISCVLoadImm(unsigned DestReg, int64_t Value, MCStreamer &Out,
+                            const MCSubtargetInfo *STI) {
+  if (isInt<32>(Value)) {
+    // Emits the MC instructions for loading a 32-bit constant into a register.
+    //
+    // Depending on the active bits in the immediate Value v, the following
+    // instruction sequences are emitted:
+    //
+    // v == 0                        : ADDI(W)
+    // v[0,12) != 0 && v[12,32) == 0 : ADDI(W)
+    // v[0,12) == 0 && v[12,32) != 0 : LUI
+    // v[0,32) != 0                  : LUI+ADDI(W)
+    //
+    int64_t Hi20 = ((Value + 0x800) >> 12) & 0xFFFFF;
+    int64_t Lo12 = SignExtend64<12>(Value);
+    unsigned SrcReg = RISCV::X0;
+
+    if (Hi20) {
+      Out.EmitInstruction(
+          MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Hi20), *STI);
+      SrcReg = DestReg;
+    }
+
+    if (Lo12 || Hi20 == 0) {
+      unsigned AddiOpcode =
+          STI->hasFeature(RISCV::Feature64Bit) ? RISCV::ADDIW : RISCV::ADDI;
+      Out.EmitInstruction(
+          MCInstBuilder(AddiOpcode).addReg(DestReg).addReg(SrcReg).addImm(Lo12),
+          *STI);
+    }
+    return;
+  }
+  assert(STI->hasFeature(RISCV::Feature64Bit) &&
+         "Target must be 64-bit to support a >32-bit constant");
+
+  // In the worst case, for a full 64-bit constant, a sequence of 8 instructions
+  // (i.e., LUI+ADDIW+SLLI+ADDI+SLLI+ADDI+SLLI+ADDI) has to be emmitted. Note
+  // that the first two instructions (LUI+ADDIW) can contribute up to 32 bits
+  // while the following ADDI instructions contribute up to 12 bits each.
+  //
+  // On the first glance, implementing this seems to be possible by simply
+  // emitting the most significant 32 bits (LUI+ADDIW) followed by as many left
+  // shift (SLLI) and immediate additions (ADDI) as needed. However, due to the
+  // fact that ADDI performs a sign extended addition, doing it like that would
+  // only be possible when at most 11 bits of the ADDI instructions are used.
+  // Using all 12 bits of the ADDI instructions, like done by GAS, actually
+  // requires that the constant is processed starting with the least significant
+  // bit.
+  //
+  // In the following, constants are processed from LSB to MSB but instruction
+  // emission is performed from MSB to LSB by recursively calling
+  // emitRISCVLoadImm. In each recursion, first the lowest 12 bits are removed
+  // from the constant and the optimal shift amount, which can be greater than
+  // 12 bits if the constant is sparse, is determined. Then, the shifted
+  // remaining constant is processed recursively and gets emitted as soon as it
+  // fits into 32 bits. The emission of the shifts and additions is subsequently
+  // performed when the recursion returns.
+  //
+  int64_t Lo12 = SignExtend64<12>(Value);
+  int64_t Hi52 = (Value + 0x800) >> 12;
+  int ShiftAmount = 12 + findFirstSet((uint64_t)Hi52);
+  Hi52 = SignExtend64(Hi52 >> (ShiftAmount - 12), 64 - ShiftAmount);
+
+  emitRISCVLoadImm(DestReg, Hi52, Out, STI);
+
+  Out.EmitInstruction(MCInstBuilder(RISCV::SLLI)
+                          .addReg(DestReg)
+                          .addReg(DestReg)
+                          .addImm(ShiftAmount),
+                      *STI);
+
+  if (Lo12)
+    Out.EmitInstruction(
+        MCInstBuilder(RISCV::ADDI).addReg(DestReg).addReg(DestReg).addImm(Lo12),
+        *STI);
+}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCPseudoExpansion.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCPseudoExpansion.h
new file mode 100644 (file)
index 0000000..0a577a9
--- /dev/null
@@ -0,0 +1,29 @@
+//===-- RISCVMCPseudoExpansion.h - RISCV MC Pseudo Expansion ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// This file describes helpers to expand pseudo MC instructions that are usable
+/// in the AsmParser and the AsmPrinter.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCPSEUDOEXPANSION_H
+#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCPSEUDOEXPANSION_H
+
+#include <cstdint>
+
+namespace llvm {
+
+class MCStreamer;
+class MCSubtargetInfo;
+
+void emitRISCVLoadImm(unsigned DestReg, int64_t Value, MCStreamer &Out,
+                      const MCSubtargetInfo *STI);
+
+} // namespace llvm
+
+#endif
index bdf8e5d840b308d26c5b95aaa93233a0fb50f433..820cbe1ed5daec20b0ea30b748fae8cb3b7eef19 100644 (file)
@@ -15,6 +15,7 @@
 #include "RISCV.h"
 #include "InstPrinter/RISCVInstPrinter.h"
 #include "MCTargetDesc/RISCVMCExpr.h"
+#include "MCTargetDesc/RISCVMCPseudoExpansion.h"
 #include "RISCVTargetMachine.h"
 #include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
@@ -78,6 +79,14 @@ void RISCVAsmPrinter::EmitInstruction(const MachineInstr *MI) {
   if (emitPseudoExpansionLowering(*OutStreamer, MI))
     return;
 
+  if (MI->getOpcode() == RISCV::PseudoLI) {
+    const MachineOperand &DstRegOp = MI->getOperand(0);
+    const MachineOperand &ImmOp = MI->getOperand(1);
+    emitRISCVLoadImm(DstRegOp.getReg(), ImmOp.getImm(), *OutStreamer,
+                     &getSubtargetInfo());
+    return;
+  }
+
   MCInst TmpInst;
   LowerRISCVMachineInstrToMCInst(MI, TmpInst, *this);
   EmitToStreamer(*OutStreamer, TmpInst);
index 630439bb53c240bd0c707367ffa390343395ecf6..8fdf18efb58acceb094a71816658f05156df1433 100644 (file)
@@ -179,41 +179,62 @@ void RISCVDAGToDAGISel::doPeepholeLoadStoreADDI() {
 
     SDValue Base = N->getOperand(BaseOpIdx);
 
-    // If the base is an ADDI, we can merge it in to the load/store.
-    if (!Base.isMachineOpcode() || Base.getMachineOpcode() != RISCV::ADDI)
+    // If the base is an ADDI or PseudoLI, we can either merge it or at least
+    // sink the lowest 12 bits into the load/store.
+    if (!Base.isMachineOpcode() || (Base.getMachineOpcode() != RISCV::ADDI &&
+                                    Base.getMachineOpcode() != RISCV::PseudoLI))
       continue;
 
-    SDValue ImmOperand = Base.getOperand(1);
-
-    if (auto Const = dyn_cast<ConstantSDNode>(ImmOperand)) {
-      ImmOperand = CurDAG->getTargetConstant(
-          Const->getSExtValue(), SDLoc(ImmOperand), ImmOperand.getValueType());
-    } else if (auto GA = dyn_cast<GlobalAddressSDNode>(ImmOperand)) {
-      ImmOperand = CurDAG->getTargetGlobalAddress(
-          GA->getGlobal(), SDLoc(ImmOperand), ImmOperand.getValueType(),
-          GA->getOffset(), GA->getTargetFlags());
+    SDValue ImmOperand;
+    SDValue Parent;
+    if (Base.getMachineOpcode() == RISCV::PseudoLI) {
+      ImmOperand = Base.getOperand(0);
+      auto Const = dyn_cast<ConstantSDNode>(ImmOperand);
+      if (!Const || (Const->getSExtValue() & 0xFFF) == 0)
+        continue;
+
+      int64_t Hi52 = (Const->getSExtValue() + 0x800) & ~0xFFF;
+      SDValue HiVal = CurDAG->getTargetConstant(Hi52, SDLoc(ImmOperand),
+                                                ImmOperand.getValueType());
+      Parent =
+          SDValue(CurDAG->getMachineNode(RISCV::PseudoLI, SDLoc(ImmOperand),
+                                         ImmOperand.getValueType(), HiVal),
+                  0);
+
+      int64_t Lo12 = SignExtend64<12>(Const->getSExtValue());
+      ImmOperand = CurDAG->getTargetConstant(Lo12, SDLoc(ImmOperand),
+                                             ImmOperand.getValueType());
     } else {
-      continue;
+      Parent = Base.getOperand(0);
+      ImmOperand = Base.getOperand(1);
+
+      if (auto Const = dyn_cast<ConstantSDNode>(ImmOperand)) {
+        ImmOperand =
+            CurDAG->getTargetConstant(Const->getSExtValue(), SDLoc(ImmOperand),
+                                      ImmOperand.getValueType());
+      } else if (auto GA = dyn_cast<GlobalAddressSDNode>(ImmOperand)) {
+        ImmOperand = CurDAG->getTargetGlobalAddress(
+            GA->getGlobal(), SDLoc(ImmOperand), ImmOperand.getValueType(),
+            GA->getOffset(), GA->getTargetFlags());
+      } else {
+        continue;
+      }
     }
 
-    DEBUG(dbgs() << "Folding add-immediate into mem-op:\nBase:    ");
-    DEBUG(Base->dump(CurDAG));
+    DEBUG(dbgs() << "Folding add-immediate or PseudoLI into mem-op:\nBase: ");
+    DEBUG(Base.dump(CurDAG));
     DEBUG(dbgs() << "\nN: ");
     DEBUG(N->dump(CurDAG));
     DEBUG(dbgs() << "\n");
 
     // Modify the offset operand of the load/store.
     if (BaseOpIdx == 0) // Load
-      CurDAG->UpdateNodeOperands(N, Base.getOperand(0), ImmOperand,
-                                 N->getOperand(2));
+      CurDAG->UpdateNodeOperands(N, Parent, ImmOperand, N->getOperand(2));
     else // Store
-      CurDAG->UpdateNodeOperands(N, N->getOperand(0), Base.getOperand(0),
-                                 ImmOperand, N->getOperand(3));
-
-    // The add-immediate may now be dead, in which case remove it.
-    if (Base.getNode()->use_empty())
-      CurDAG->RemoveDeadNode(Base.getNode());
+      CurDAG->UpdateNodeOperands(N, N->getOperand(0), Parent, ImmOperand,
+                                 N->getOperand(3));
   }
+  CurDAG->RemoveDeadNodes();
 }
 
 // Remove redundant BuildPairF64+SplitF64 pairs. i.e. cases where an f64 is
index 7479ffbc9532602c5ec1fc26dfc616263e8df634..529e048045c6f10c1ebc1ce4e2acddd62496100a 100644 (file)
@@ -102,8 +102,8 @@ class RVInst<dag outs, dag ins, string opcodestr, string argstr,
 }
 
 // Pseudo instructions
-class Pseudo<dag outs, dag ins, list<dag> pattern>
-    : RVInst<outs, ins, "", "", pattern, InstFormatPseudo> {
+class Pseudo<dag outs, dag ins, list<dag> pattern, string opcodestr = "", string argstr = "">
+    : RVInst<outs, ins, opcodestr, argstr, pattern, InstFormatPseudo> {
   let isPseudo = 1;
   let isCodeGenOnly = 1;
 }
index 91a0dfb233fb03ff25e666975ecae173e0474ddd..cbbe07a27bf47ca3c6bd834929ec09eff37b411d 100644 (file)
@@ -112,17 +112,8 @@ void RISCVInstrInfo::movImm32(MachineBasicBlock &MBB,
                               MachineInstr::MIFlag Flag) const {
   assert(isInt<32>(Val) && "Can only materialize 32-bit constants");
 
-  // TODO: If the value can be materialized using only one instruction, only
-  // insert a single instruction.
-
-  uint64_t Hi20 = ((Val + 0x800) >> 12) & 0xfffff;
-  uint64_t Lo12 = SignExtend64<12>(Val);
-  BuildMI(MBB, MBBI, DL, get(RISCV::LUI), DstReg)
-      .addImm(Hi20)
-      .setMIFlag(Flag);
-  BuildMI(MBB, MBBI, DL, get(RISCV::ADDI), DstReg)
-      .addReg(DstReg, RegState::Kill)
-      .addImm(Lo12)
+  BuildMI(MBB, MBBI, DL, get(RISCV::PseudoLI), DstReg)
+      .addImm(Val)
       .setMIFlag(Flag);
 }
 
index 1c429da7419907355e0c1c614c1028e66c84a6be..56fb9f60927e6670a2519277d29423a923cf77ff 100644 (file)
@@ -43,6 +43,12 @@ def SelectCC     : SDNode<"RISCVISD::SELECT_CC", SDT_RISCVSelectCC,
 // Operand and SDNode transformation definitions.
 //===----------------------------------------------------------------------===//
 
+class ImmXLenAsmOperand<string prefix, string suffix = ""> : AsmOperandClass {
+  let Name = prefix # "ImmXLen" # suffix;
+  let RenderMethod = "addImmOperands";
+  let DiagnosticType = !strconcat("Invalid", Name);
+}
+
 class ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass {
   let Name = prefix # "Imm" # width # suffix;
   let RenderMethod = "addImmOperands";
@@ -154,7 +160,9 @@ def simm21_lsb0 : Operand<OtherVT> {
 }
 
 // A parameterized register class alternative to i32imm/i64imm from Target.td.
-def ixlenimm : Operand<XLenVT>;
+def ixlenimm : Operand<XLenVT> {
+  let ParserMatchClass = ImmXLenAsmOperand<"">;
+}
 
 // Standalone (codegen-only) immleaf patterns.
 def simm32 : ImmLeaf<XLenVT, [{return isInt<32>(Imm);}]>;
@@ -418,7 +426,16 @@ def SFENCE_VMA : RVInstR<0b0001001, 0b000, OPC_SYSTEM, (outs),
 // TODO RV64I: sd
 
 def : InstAlias<"nop",           (ADDI      X0,      X0,       0)>;
-// TODO li
+
+// Note that a size of 8 is currently correct because only 32-bit immediates
+// are emitted as PseudoLI during codegen. Emitting larger constants as
+// PseudoLI is probably not the best idea anyway given that up to
+// 8 32-bit instructions are needed to generate an arbitrary 64-bit immediate.
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8,
+    isCodeGenOnly = 0, isAsmParserOnly = 1 in
+def PseudoLI : Pseudo<(outs GPR:$rd), (ins ixlenimm:$imm), [],
+                      "li", "$rd, $imm">;
+
 def : InstAlias<"mv $rd, $rs",   (ADDI GPR:$rd, GPR:$rs,       0)>;
 def : InstAlias<"not $rd, $rs",  (XORI GPR:$rd, GPR:$rs,      -1)>;
 def : InstAlias<"neg $rd, $rs",  (SUB  GPR:$rd,      X0, GPR:$rs)>;
@@ -521,8 +538,7 @@ def IsOrAdd: PatFrag<(ops node:$A, node:$B), (or node:$A, node:$B), [{
 /// Immediates
 
 def : Pat<(simm12:$imm), (ADDI X0, simm12:$imm)>;
-// TODO: Add a pattern for immediates with all zeroes in the lower 12 bits.
-def : Pat<(simm32:$imm), (ADDI (LUI (HI20 imm:$imm)), (LO12Sext imm:$imm))>;
+def : Pat<(simm32:$imm), (PseudoLI imm:$imm)>;
 
 /// Simple arithmetic operations
 
index 1fbc429cae4f9c7dd0d86324846b8192b7712184..07d601284144d125e55aac6d0b3ca0067df6c166 100644 (file)
@@ -15,10 +15,9 @@ declare i32 @llvm.ctpop.i32(i32)
 define i16 @test_bswap_i16(i16 %a) nounwind {
 ; RV32I-LABEL: test_bswap_i16:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    lui a1, 4080
-; RV32I-NEXT:    mv a1, a1
-; RV32I-NEXT:    slli a2, a0, 8
-; RV32I-NEXT:    and a1, a2, a1
+; RV32I-NEXT:    slli a1, a0, 8
+; RV32I-NEXT:    lui a2, 4080
+; RV32I-NEXT:    and a1, a1, a2
 ; RV32I-NEXT:    slli a0, a0, 24
 ; RV32I-NEXT:    or a0, a0, a1
 ; RV32I-NEXT:    srli a0, a0, 16
@@ -30,16 +29,15 @@ define i16 @test_bswap_i16(i16 %a) nounwind {
 define i32 @test_bswap_i32(i32 %a) nounwind {
 ; RV32I-LABEL: test_bswap_i32:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    lui a1, 16
-; RV32I-NEXT:    addi a1, a1, -256
-; RV32I-NEXT:    srli a2, a0, 8
-; RV32I-NEXT:    and a1, a2, a1
+; RV32I-NEXT:    srli a1, a0, 8
+; RV32I-NEXT:    lui a2, 16
+; RV32I-NEXT:    addi a2, a2, -256
+; RV32I-NEXT:    and a1, a1, a2
 ; RV32I-NEXT:    srli a2, a0, 24
 ; RV32I-NEXT:    or a1, a1, a2
-; RV32I-NEXT:    lui a2, 4080
-; RV32I-NEXT:    mv a2, a2
-; RV32I-NEXT:    slli a3, a0, 8
-; RV32I-NEXT:    and a2, a3, a2
+; RV32I-NEXT:    slli a2, a0, 8
+; RV32I-NEXT:    lui a3, 4080
+; RV32I-NEXT:    and a2, a2, a3
 ; RV32I-NEXT:    slli a0, a0, 24
 ; RV32I-NEXT:    or a0, a0, a2
 ; RV32I-NEXT:    or a0, a0, a1
@@ -51,25 +49,24 @@ define i32 @test_bswap_i32(i32 %a) nounwind {
 define i64 @test_bswap_i64(i64 %a) nounwind {
 ; RV32I-LABEL: test_bswap_i64:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    lui a2, 16
-; RV32I-NEXT:    addi a3, a2, -256
 ; RV32I-NEXT:    srli a2, a1, 8
+; RV32I-NEXT:    lui a3, 16
+; RV32I-NEXT:    addi a3, a3, -256
 ; RV32I-NEXT:    and a2, a2, a3
 ; RV32I-NEXT:    srli a4, a1, 24
 ; RV32I-NEXT:    or a2, a2, a4
-; RV32I-NEXT:    lui a4, 4080
-; RV32I-NEXT:    mv a4, a4
-; RV32I-NEXT:    slli a5, a1, 8
-; RV32I-NEXT:    and a5, a5, a4
+; RV32I-NEXT:    slli a4, a1, 8
+; RV32I-NEXT:    lui a5, 4080
+; RV32I-NEXT:    and a4, a4, a5
 ; RV32I-NEXT:    slli a1, a1, 24
-; RV32I-NEXT:    or a1, a1, a5
+; RV32I-NEXT:    or a1, a1, a4
 ; RV32I-NEXT:    or a2, a1, a2
 ; RV32I-NEXT:    srli a1, a0, 8
 ; RV32I-NEXT:    and a1, a1, a3
 ; RV32I-NEXT:    srli a3, a0, 24
 ; RV32I-NEXT:    or a1, a1, a3
 ; RV32I-NEXT:    slli a3, a0, 8
-; RV32I-NEXT:    and a3, a3, a4
+; RV32I-NEXT:    and a3, a3, a5
 ; RV32I-NEXT:    slli a0, a0, 24
 ; RV32I-NEXT:    or a0, a0, a3
 ; RV32I-NEXT:    or a1, a0, a1
@@ -90,10 +87,10 @@ define i8 @test_cttz_i8(i8 %a) nounwind {
 ; RV32I-NEXT:    addi a1, a0, -1
 ; RV32I-NEXT:    not a0, a0
 ; RV32I-NEXT:    and a0, a0, a1
-; RV32I-NEXT:    lui a1, 349525
-; RV32I-NEXT:    addi a1, a1, 1365
-; RV32I-NEXT:    srli a2, a0, 1
-; RV32I-NEXT:    and a1, a2, a1
+; RV32I-NEXT:    srli a1, a0, 1
+; RV32I-NEXT:    lui a2, 349525
+; RV32I-NEXT:    addi a2, a2, 1365
+; RV32I-NEXT:    and a1, a1, a2
 ; RV32I-NEXT:    sub a0, a0, a1
 ; RV32I-NEXT:    lui a1, 209715
 ; RV32I-NEXT:    addi a1, a1, 819
@@ -106,10 +103,10 @@ define i8 @test_cttz_i8(i8 %a) nounwind {
 ; RV32I-NEXT:    lui a1, 61681
 ; RV32I-NEXT:    addi a1, a1, -241
 ; RV32I-NEXT:    and a0, a0, a1
+; RV32I-NEXT:    lui a1, %hi(__mulsi3)
+; RV32I-NEXT:    addi a2, a1, %lo(__mulsi3)
 ; RV32I-NEXT:    lui a1, 4112
 ; RV32I-NEXT:    addi a1, a1, 257
-; RV32I-NEXT:    lui a2, %hi(__mulsi3)
-; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr a2
 ; RV32I-NEXT:    srli a0, a0, 24
 ; RV32I-NEXT:    j .LBB3_3
@@ -136,10 +133,10 @@ define i16 @test_cttz_i16(i16 %a) nounwind {
 ; RV32I-NEXT:    addi a1, a0, -1
 ; RV32I-NEXT:    not a0, a0
 ; RV32I-NEXT:    and a0, a0, a1
-; RV32I-NEXT:    lui a1, 349525
-; RV32I-NEXT:    addi a1, a1, 1365
-; RV32I-NEXT:    srli a2, a0, 1
-; RV32I-NEXT:    and a1, a2, a1
+; RV32I-NEXT:    srli a1, a0, 1
+; RV32I-NEXT:    lui a2, 349525
+; RV32I-NEXT:    addi a2, a2, 1365
+; RV32I-NEXT:    and a1, a1, a2
 ; RV32I-NEXT:    sub a0, a0, a1
 ; RV32I-NEXT:    lui a1, 209715
 ; RV32I-NEXT:    addi a1, a1, 819
@@ -152,10 +149,10 @@ define i16 @test_cttz_i16(i16 %a) nounwind {
 ; RV32I-NEXT:    lui a1, 61681
 ; RV32I-NEXT:    addi a1, a1, -241
 ; RV32I-NEXT:    and a0, a0, a1
+; RV32I-NEXT:    lui a1, %hi(__mulsi3)
+; RV32I-NEXT:    addi a2, a1, %lo(__mulsi3)
 ; RV32I-NEXT:    lui a1, 4112
 ; RV32I-NEXT:    addi a1, a1, 257
-; RV32I-NEXT:    lui a2, %hi(__mulsi3)
-; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr a2
 ; RV32I-NEXT:    srli a0, a0, 24
 ; RV32I-NEXT:    j .LBB4_3
@@ -179,10 +176,10 @@ define i32 @test_cttz_i32(i32 %a) nounwind {
 ; RV32I-NEXT:    addi a1, a0, -1
 ; RV32I-NEXT:    not a0, a0
 ; RV32I-NEXT:    and a0, a0, a1
-; RV32I-NEXT:    lui a1, 349525
-; RV32I-NEXT:    addi a1, a1, 1365
-; RV32I-NEXT:    srli a2, a0, 1
-; RV32I-NEXT:    and a1, a2, a1
+; RV32I-NEXT:    srli a1, a0, 1
+; RV32I-NEXT:    lui a2, 349525
+; RV32I-NEXT:    addi a2, a2, 1365
+; RV32I-NEXT:    and a1, a1, a2
 ; RV32I-NEXT:    sub a0, a0, a1
 ; RV32I-NEXT:    lui a1, 209715
 ; RV32I-NEXT:    addi a1, a1, 819
@@ -195,10 +192,10 @@ define i32 @test_cttz_i32(i32 %a) nounwind {
 ; RV32I-NEXT:    lui a1, 61681
 ; RV32I-NEXT:    addi a1, a1, -241
 ; RV32I-NEXT:    and a0, a0, a1
+; RV32I-NEXT:    lui a1, %hi(__mulsi3)
+; RV32I-NEXT:    addi a2, a1, %lo(__mulsi3)
 ; RV32I-NEXT:    lui a1, 4112
 ; RV32I-NEXT:    addi a1, a1, 257
-; RV32I-NEXT:    lui a2, %hi(__mulsi3)
-; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr a2
 ; RV32I-NEXT:    srli a0, a0, 24
 ; RV32I-NEXT:    j .LBB5_3
@@ -229,9 +226,9 @@ define i32 @test_ctlz_i32(i32 %a) nounwind {
 ; RV32I-NEXT:    or a0, a0, a1
 ; RV32I-NEXT:    srli a1, a0, 16
 ; RV32I-NEXT:    or a0, a0, a1
+; RV32I-NEXT:    not a0, a0
 ; RV32I-NEXT:    lui a1, 349525
 ; RV32I-NEXT:    addi a1, a1, 1365
-; RV32I-NEXT:    not a0, a0
 ; RV32I-NEXT:    srli a2, a0, 1
 ; RV32I-NEXT:    and a1, a2, a1
 ; RV32I-NEXT:    sub a0, a0, a1
@@ -246,10 +243,10 @@ define i32 @test_ctlz_i32(i32 %a) nounwind {
 ; RV32I-NEXT:    lui a1, 61681
 ; RV32I-NEXT:    addi a1, a1, -241
 ; RV32I-NEXT:    and a0, a0, a1
+; RV32I-NEXT:    lui a1, %hi(__mulsi3)
+; RV32I-NEXT:    addi a2, a1, %lo(__mulsi3)
 ; RV32I-NEXT:    lui a1, 4112
 ; RV32I-NEXT:    addi a1, a1, 257
-; RV32I-NEXT:    lui a2, %hi(__mulsi3)
-; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr a2
 ; RV32I-NEXT:    srli a0, a0, 24
 ; RV32I-NEXT:    j .LBB6_3
@@ -281,26 +278,26 @@ define i64 @test_cttz_i64(i64 %a) nounwind {
 ; RV32I-NEXT:    addi a0, a0, -1
 ; RV32I-NEXT:    not a1, s3
 ; RV32I-NEXT:    and a0, a1, a0
-; RV32I-NEXT:    lui a1, 349525
-; RV32I-NEXT:    addi s5, a1, 1365
 ; RV32I-NEXT:    srli a1, a0, 1
+; RV32I-NEXT:    lui s5, 349525
+; RV32I-NEXT:    addi s5, s5, 1365
 ; RV32I-NEXT:    and a1, a1, s5
 ; RV32I-NEXT:    sub a0, a0, a1
-; RV32I-NEXT:    lui a1, 209715
-; RV32I-NEXT:    addi s6, a1, 819
+; RV32I-NEXT:    lui s6, 209715
+; RV32I-NEXT:    addi s6, s6, 819
 ; RV32I-NEXT:    and a1, a0, s6
 ; RV32I-NEXT:    srli a0, a0, 2
 ; RV32I-NEXT:    and a0, a0, s6
 ; RV32I-NEXT:    add a0, a1, a0
 ; RV32I-NEXT:    srli a1, a0, 4
 ; RV32I-NEXT:    add a0, a0, a1
-; RV32I-NEXT:    lui a1, 4112
-; RV32I-NEXT:    addi s4, a1, 257
 ; RV32I-NEXT:    lui a1, %hi(__mulsi3)
 ; RV32I-NEXT:    addi s7, a1, %lo(__mulsi3)
-; RV32I-NEXT:    lui a1, 61681
-; RV32I-NEXT:    addi s8, a1, -241
+; RV32I-NEXT:    lui s8, 61681
+; RV32I-NEXT:    addi s8, s8, -241
 ; RV32I-NEXT:    and a0, a0, s8
+; RV32I-NEXT:    lui s4, 4112
+; RV32I-NEXT:    addi s4, s4, 257
 ; RV32I-NEXT:    mv a1, s4
 ; RV32I-NEXT:    jalr s7
 ; RV32I-NEXT:    mv s1, a0
@@ -351,10 +348,10 @@ define i8 @test_cttz_i8_zero_undef(i8 %a) nounwind {
 ; RV32I-NEXT:    addi a1, a0, -1
 ; RV32I-NEXT:    not a0, a0
 ; RV32I-NEXT:    and a0, a0, a1
-; RV32I-NEXT:    lui a1, 349525
-; RV32I-NEXT:    addi a1, a1, 1365
-; RV32I-NEXT:    srli a2, a0, 1
-; RV32I-NEXT:    and a1, a2, a1
+; RV32I-NEXT:    srli a1, a0, 1
+; RV32I-NEXT:    lui a2, 349525
+; RV32I-NEXT:    addi a2, a2, 1365
+; RV32I-NEXT:    and a1, a1, a2
 ; RV32I-NEXT:    sub a0, a0, a1
 ; RV32I-NEXT:    lui a1, 209715
 ; RV32I-NEXT:    addi a1, a1, 819
@@ -367,10 +364,10 @@ define i8 @test_cttz_i8_zero_undef(i8 %a) nounwind {
 ; RV32I-NEXT:    lui a1, 61681
 ; RV32I-NEXT:    addi a1, a1, -241
 ; RV32I-NEXT:    and a0, a0, a1
+; RV32I-NEXT:    lui a1, %hi(__mulsi3)
+; RV32I-NEXT:    addi a2, a1, %lo(__mulsi3)
 ; RV32I-NEXT:    lui a1, 4112
 ; RV32I-NEXT:    addi a1, a1, 257
-; RV32I-NEXT:    lui a2, %hi(__mulsi3)
-; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr a2
 ; RV32I-NEXT:    srli a0, a0, 24
 ; RV32I-NEXT:    lw ra, 12(sp)
@@ -388,10 +385,10 @@ define i16 @test_cttz_i16_zero_undef(i16 %a) nounwind {
 ; RV32I-NEXT:    addi a1, a0, -1
 ; RV32I-NEXT:    not a0, a0
 ; RV32I-NEXT:    and a0, a0, a1
-; RV32I-NEXT:    lui a1, 349525
-; RV32I-NEXT:    addi a1, a1, 1365
-; RV32I-NEXT:    srli a2, a0, 1
-; RV32I-NEXT:    and a1, a2, a1
+; RV32I-NEXT:    srli a1, a0, 1
+; RV32I-NEXT:    lui a2, 349525
+; RV32I-NEXT:    addi a2, a2, 1365
+; RV32I-NEXT:    and a1, a1, a2
 ; RV32I-NEXT:    sub a0, a0, a1
 ; RV32I-NEXT:    lui a1, 209715
 ; RV32I-NEXT:    addi a1, a1, 819
@@ -404,10 +401,10 @@ define i16 @test_cttz_i16_zero_undef(i16 %a) nounwind {
 ; RV32I-NEXT:    lui a1, 61681
 ; RV32I-NEXT:    addi a1, a1, -241
 ; RV32I-NEXT:    and a0, a0, a1
+; RV32I-NEXT:    lui a1, %hi(__mulsi3)
+; RV32I-NEXT:    addi a2, a1, %lo(__mulsi3)
 ; RV32I-NEXT:    lui a1, 4112
 ; RV32I-NEXT:    addi a1, a1, 257
-; RV32I-NEXT:    lui a2, %hi(__mulsi3)
-; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr a2
 ; RV32I-NEXT:    srli a0, a0, 24
 ; RV32I-NEXT:    lw ra, 12(sp)
@@ -425,10 +422,10 @@ define i32 @test_cttz_i32_zero_undef(i32 %a) nounwind {
 ; RV32I-NEXT:    addi a1, a0, -1
 ; RV32I-NEXT:    not a0, a0
 ; RV32I-NEXT:    and a0, a0, a1
-; RV32I-NEXT:    lui a1, 349525
-; RV32I-NEXT:    addi a1, a1, 1365
-; RV32I-NEXT:    srli a2, a0, 1
-; RV32I-NEXT:    and a1, a2, a1
+; RV32I-NEXT:    srli a1, a0, 1
+; RV32I-NEXT:    lui a2, 349525
+; RV32I-NEXT:    addi a2, a2, 1365
+; RV32I-NEXT:    and a1, a1, a2
 ; RV32I-NEXT:    sub a0, a0, a1
 ; RV32I-NEXT:    lui a1, 209715
 ; RV32I-NEXT:    addi a1, a1, 819
@@ -441,10 +438,10 @@ define i32 @test_cttz_i32_zero_undef(i32 %a) nounwind {
 ; RV32I-NEXT:    lui a1, 61681
 ; RV32I-NEXT:    addi a1, a1, -241
 ; RV32I-NEXT:    and a0, a0, a1
+; RV32I-NEXT:    lui a1, %hi(__mulsi3)
+; RV32I-NEXT:    addi a2, a1, %lo(__mulsi3)
 ; RV32I-NEXT:    lui a1, 4112
 ; RV32I-NEXT:    addi a1, a1, 257
-; RV32I-NEXT:    lui a2, %hi(__mulsi3)
-; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr a2
 ; RV32I-NEXT:    srli a0, a0, 24
 ; RV32I-NEXT:    lw ra, 12(sp)
@@ -472,26 +469,26 @@ define i64 @test_cttz_i64_zero_undef(i64 %a) nounwind {
 ; RV32I-NEXT:    addi a0, a0, -1
 ; RV32I-NEXT:    not a1, s3
 ; RV32I-NEXT:    and a0, a1, a0
-; RV32I-NEXT:    lui a1, 349525
-; RV32I-NEXT:    addi s5, a1, 1365
 ; RV32I-NEXT:    srli a1, a0, 1
+; RV32I-NEXT:    lui s5, 349525
+; RV32I-NEXT:    addi s5, s5, 1365
 ; RV32I-NEXT:    and a1, a1, s5
 ; RV32I-NEXT:    sub a0, a0, a1
-; RV32I-NEXT:    lui a1, 209715
-; RV32I-NEXT:    addi s6, a1, 819
+; RV32I-NEXT:    lui s6, 209715
+; RV32I-NEXT:    addi s6, s6, 819
 ; RV32I-NEXT:    and a1, a0, s6
 ; RV32I-NEXT:    srli a0, a0, 2
 ; RV32I-NEXT:    and a0, a0, s6
 ; RV32I-NEXT:    add a0, a1, a0
 ; RV32I-NEXT:    srli a1, a0, 4
 ; RV32I-NEXT:    add a0, a0, a1
-; RV32I-NEXT:    lui a1, 4112
-; RV32I-NEXT:    addi s4, a1, 257
 ; RV32I-NEXT:    lui a1, %hi(__mulsi3)
 ; RV32I-NEXT:    addi s7, a1, %lo(__mulsi3)
-; RV32I-NEXT:    lui a1, 61681
-; RV32I-NEXT:    addi s8, a1, -241
+; RV32I-NEXT:    lui s8, 61681
+; RV32I-NEXT:    addi s8, s8, -241
 ; RV32I-NEXT:    and a0, a0, s8
+; RV32I-NEXT:    lui s4, 4112
+; RV32I-NEXT:    addi s4, s4, 257
 ; RV32I-NEXT:    mv a1, s4
 ; RV32I-NEXT:    jalr s7
 ; RV32I-NEXT:    mv s1, a0
@@ -539,10 +536,10 @@ define i32 @test_ctpop_i32(i32 %a) nounwind {
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp)
-; RV32I-NEXT:    lui a1, 349525
-; RV32I-NEXT:    addi a1, a1, 1365
-; RV32I-NEXT:    srli a2, a0, 1
-; RV32I-NEXT:    and a1, a2, a1
+; RV32I-NEXT:    srli a1, a0, 1
+; RV32I-NEXT:    lui a2, 349525
+; RV32I-NEXT:    addi a2, a2, 1365
+; RV32I-NEXT:    and a1, a1, a2
 ; RV32I-NEXT:    sub a0, a0, a1
 ; RV32I-NEXT:    lui a1, 209715
 ; RV32I-NEXT:    addi a1, a1, 819
@@ -555,10 +552,10 @@ define i32 @test_ctpop_i32(i32 %a) nounwind {
 ; RV32I-NEXT:    lui a1, 61681
 ; RV32I-NEXT:    addi a1, a1, -241
 ; RV32I-NEXT:    and a0, a0, a1
+; RV32I-NEXT:    lui a1, %hi(__mulsi3)
+; RV32I-NEXT:    addi a2, a1, %lo(__mulsi3)
 ; RV32I-NEXT:    lui a1, 4112
 ; RV32I-NEXT:    addi a1, a1, 257
-; RV32I-NEXT:    lui a2, %hi(__mulsi3)
-; RV32I-NEXT:    addi a2, a2, %lo(__mulsi3)
 ; RV32I-NEXT:    jalr a2
 ; RV32I-NEXT:    srli a0, a0, 24
 ; RV32I-NEXT:    lw ra, 12(sp)
index 8d752cbb6e72b50b98a76557728d9dc49f4d4962..12270ff51b42f63a904b8ecae4df931565f3cce3 100644 (file)
@@ -85,14 +85,13 @@ define i32 @caller_scalars() nounwind {
 ; RV32I-FPELIM:       # %bb.0:
 ; RV32I-FPELIM-NEXT:    addi sp, sp, -16
 ; RV32I-FPELIM-NEXT:    sw ra, 12(sp)
-; RV32I-FPELIM-NEXT:    lui a0, 262464
-; RV32I-FPELIM-NEXT:    mv a6, a0
 ; RV32I-FPELIM-NEXT:    lui a0, %hi(callee_scalars)
 ; RV32I-FPELIM-NEXT:    addi a7, a0, %lo(callee_scalars)
 ; RV32I-FPELIM-NEXT:    addi a0, zero, 1
 ; RV32I-FPELIM-NEXT:    addi a1, zero, 2
 ; RV32I-FPELIM-NEXT:    addi a3, zero, 3
 ; RV32I-FPELIM-NEXT:    addi a4, zero, 4
+; RV32I-FPELIM-NEXT:    lui a6, 262464
 ; RV32I-FPELIM-NEXT:    mv a2, zero
 ; RV32I-FPELIM-NEXT:    mv a5, zero
 ; RV32I-FPELIM-NEXT:    jalr a7
@@ -106,14 +105,13 @@ define i32 @caller_scalars() nounwind {
 ; RV32I-WITHFP-NEXT:    sw ra, 12(sp)
 ; RV32I-WITHFP-NEXT:    sw s0, 8(sp)
 ; RV32I-WITHFP-NEXT:    addi s0, sp, 16
-; RV32I-WITHFP-NEXT:    lui a0, 262464
-; RV32I-WITHFP-NEXT:    mv a6, a0
 ; RV32I-WITHFP-NEXT:    lui a0, %hi(callee_scalars)
 ; RV32I-WITHFP-NEXT:    addi a7, a0, %lo(callee_scalars)
 ; RV32I-WITHFP-NEXT:    addi a0, zero, 1
 ; RV32I-WITHFP-NEXT:    addi a1, zero, 2
 ; RV32I-WITHFP-NEXT:    addi a3, zero, 3
 ; RV32I-WITHFP-NEXT:    addi a4, zero, 4
+; RV32I-WITHFP-NEXT:    lui a6, 262464
 ; RV32I-WITHFP-NEXT:    mv a2, zero
 ; RV32I-WITHFP-NEXT:    mv a5, zero
 ; RV32I-WITHFP-NEXT:    jalr a7
@@ -187,6 +185,8 @@ define i32 @caller_large_scalars() nounwind {
 ; RV32I-FPELIM:       # %bb.0:
 ; RV32I-FPELIM-NEXT:    addi sp, sp, -48
 ; RV32I-FPELIM-NEXT:    sw ra, 44(sp)
+; RV32I-FPELIM-NEXT:    lui a0, 524272
+; RV32I-FPELIM-NEXT:    sw a0, 12(sp)
 ; RV32I-FPELIM-NEXT:    sw zero, 8(sp)
 ; RV32I-FPELIM-NEXT:    sw zero, 4(sp)
 ; RV32I-FPELIM-NEXT:    sw zero, 0(sp)
@@ -195,9 +195,6 @@ define i32 @caller_large_scalars() nounwind {
 ; RV32I-FPELIM-NEXT:    sw zero, 28(sp)
 ; RV32I-FPELIM-NEXT:    addi a0, zero, 1
 ; RV32I-FPELIM-NEXT:    sw a0, 24(sp)
-; RV32I-FPELIM-NEXT:    lui a0, 524272
-; RV32I-FPELIM-NEXT:    mv a0, a0
-; RV32I-FPELIM-NEXT:    sw a0, 12(sp)
 ; RV32I-FPELIM-NEXT:    lui a0, %hi(callee_large_scalars)
 ; RV32I-FPELIM-NEXT:    addi a2, a0, %lo(callee_large_scalars)
 ; RV32I-FPELIM-NEXT:    addi a0, sp, 24
@@ -213,6 +210,8 @@ define i32 @caller_large_scalars() nounwind {
 ; RV32I-WITHFP-NEXT:    sw ra, 44(sp)
 ; RV32I-WITHFP-NEXT:    sw s0, 40(sp)
 ; RV32I-WITHFP-NEXT:    addi s0, sp, 48
+; RV32I-WITHFP-NEXT:    lui a0, 524272
+; RV32I-WITHFP-NEXT:    sw a0, -36(s0)
 ; RV32I-WITHFP-NEXT:    sw zero, -40(s0)
 ; RV32I-WITHFP-NEXT:    sw zero, -44(s0)
 ; RV32I-WITHFP-NEXT:    sw zero, -48(s0)
@@ -221,9 +220,6 @@ define i32 @caller_large_scalars() nounwind {
 ; RV32I-WITHFP-NEXT:    sw zero, -20(s0)
 ; RV32I-WITHFP-NEXT:    addi a0, zero, 1
 ; RV32I-WITHFP-NEXT:    sw a0, -24(s0)
-; RV32I-WITHFP-NEXT:    lui a0, 524272
-; RV32I-WITHFP-NEXT:    mv a0, a0
-; RV32I-WITHFP-NEXT:    sw a0, -36(s0)
 ; RV32I-WITHFP-NEXT:    lui a0, %hi(callee_large_scalars)
 ; RV32I-WITHFP-NEXT:    addi a2, a0, %lo(callee_large_scalars)
 ; RV32I-WITHFP-NEXT:    addi a0, s0, -24
@@ -306,6 +302,8 @@ define i32 @caller_large_scalars_exhausted_regs() nounwind {
 ; RV32I-FPELIM-NEXT:    sw a0, 4(sp)
 ; RV32I-FPELIM-NEXT:    addi a0, zero, 9
 ; RV32I-FPELIM-NEXT:    sw a0, 0(sp)
+; RV32I-FPELIM-NEXT:    lui a0, 524272
+; RV32I-FPELIM-NEXT:    sw a0, 28(sp)
 ; RV32I-FPELIM-NEXT:    sw zero, 24(sp)
 ; RV32I-FPELIM-NEXT:    sw zero, 20(sp)
 ; RV32I-FPELIM-NEXT:    sw zero, 16(sp)
@@ -314,9 +312,6 @@ define i32 @caller_large_scalars_exhausted_regs() nounwind {
 ; RV32I-FPELIM-NEXT:    sw zero, 44(sp)
 ; RV32I-FPELIM-NEXT:    addi a0, zero, 8
 ; RV32I-FPELIM-NEXT:    sw a0, 40(sp)
-; RV32I-FPELIM-NEXT:    lui a0, 524272
-; RV32I-FPELIM-NEXT:    mv a0, a0
-; RV32I-FPELIM-NEXT:    sw a0, 28(sp)
 ; RV32I-FPELIM-NEXT:    lui a0, %hi(callee_large_scalars_exhausted_regs)
 ; RV32I-FPELIM-NEXT:    addi t0, a0, %lo(callee_large_scalars_exhausted_regs)
 ; RV32I-FPELIM-NEXT:    addi a0, zero, 1
@@ -342,6 +337,8 @@ define i32 @caller_large_scalars_exhausted_regs() nounwind {
 ; RV32I-WITHFP-NEXT:    sw a0, 4(sp)
 ; RV32I-WITHFP-NEXT:    addi a0, zero, 9
 ; RV32I-WITHFP-NEXT:    sw a0, 0(sp)
+; RV32I-WITHFP-NEXT:    lui a0, 524272
+; RV32I-WITHFP-NEXT:    sw a0, -36(s0)
 ; RV32I-WITHFP-NEXT:    sw zero, -40(s0)
 ; RV32I-WITHFP-NEXT:    sw zero, -44(s0)
 ; RV32I-WITHFP-NEXT:    sw zero, -48(s0)
@@ -350,9 +347,6 @@ define i32 @caller_large_scalars_exhausted_regs() nounwind {
 ; RV32I-WITHFP-NEXT:    sw zero, -20(s0)
 ; RV32I-WITHFP-NEXT:    addi a0, zero, 8
 ; RV32I-WITHFP-NEXT:    sw a0, -24(s0)
-; RV32I-WITHFP-NEXT:    lui a0, 524272
-; RV32I-WITHFP-NEXT:    mv a0, a0
-; RV32I-WITHFP-NEXT:    sw a0, -36(s0)
 ; RV32I-WITHFP-NEXT:    lui a0, %hi(callee_large_scalars_exhausted_regs)
 ; RV32I-WITHFP-NEXT:    addi t0, a0, %lo(callee_large_scalars_exhausted_regs)
 ; RV32I-WITHFP-NEXT:    addi a0, zero, 1
@@ -776,8 +770,6 @@ define void @caller_aligned_stack() nounwind {
 ; RV32I-FPELIM-NEXT:    lui a0, 335544
 ; RV32I-FPELIM-NEXT:    addi a0, a0, 1311
 ; RV32I-FPELIM-NEXT:    sw a0, 32(sp)
-; RV32I-FPELIM-NEXT:    lui a0, 688509
-; RV32I-FPELIM-NEXT:    addi a5, a0, -2048
 ; RV32I-FPELIM-NEXT:    lui a0, %hi(callee_aligned_stack)
 ; RV32I-FPELIM-NEXT:    addi t0, a0, %lo(callee_aligned_stack)
 ; RV32I-FPELIM-NEXT:    addi a0, zero, 1
@@ -785,6 +777,8 @@ define void @caller_aligned_stack() nounwind {
 ; RV32I-FPELIM-NEXT:    addi a2, sp, 32
 ; RV32I-FPELIM-NEXT:    addi a3, zero, 12
 ; RV32I-FPELIM-NEXT:    addi a4, zero, 13
+; RV32I-FPELIM-NEXT:    lui a5, 688509
+; RV32I-FPELIM-NEXT:    addi a5, a5, -2048
 ; RV32I-FPELIM-NEXT:    addi a6, zero, 4
 ; RV32I-FPELIM-NEXT:    addi a7, zero, 14
 ; RV32I-FPELIM-NEXT:    jalr t0
@@ -824,8 +818,6 @@ define void @caller_aligned_stack() nounwind {
 ; RV32I-WITHFP-NEXT:    lui a0, 335544
 ; RV32I-WITHFP-NEXT:    addi a0, a0, 1311
 ; RV32I-WITHFP-NEXT:    sw a0, -32(s0)
-; RV32I-WITHFP-NEXT:    lui a0, 688509
-; RV32I-WITHFP-NEXT:    addi a5, a0, -2048
 ; RV32I-WITHFP-NEXT:    lui a0, %hi(callee_aligned_stack)
 ; RV32I-WITHFP-NEXT:    addi t0, a0, %lo(callee_aligned_stack)
 ; RV32I-WITHFP-NEXT:    addi a0, zero, 1
@@ -833,6 +825,8 @@ define void @caller_aligned_stack() nounwind {
 ; RV32I-WITHFP-NEXT:    addi a2, s0, -32
 ; RV32I-WITHFP-NEXT:    addi a3, zero, 12
 ; RV32I-WITHFP-NEXT:    addi a4, zero, 13
+; RV32I-WITHFP-NEXT:    lui a5, 688509
+; RV32I-WITHFP-NEXT:    addi a5, a5, -2048
 ; RV32I-WITHFP-NEXT:    addi a6, zero, 4
 ; RV32I-WITHFP-NEXT:    addi a7, zero, 14
 ; RV32I-WITHFP-NEXT:    jalr t0
@@ -987,7 +981,6 @@ define fp128 @callee_large_scalar_ret() nounwind {
 ; RV32I-FPELIM-LABEL: callee_large_scalar_ret:
 ; RV32I-FPELIM:       # %bb.0:
 ; RV32I-FPELIM-NEXT:    lui a1, 524272
-; RV32I-FPELIM-NEXT:    mv a1, a1
 ; RV32I-FPELIM-NEXT:    sw a1, 12(a0)
 ; RV32I-FPELIM-NEXT:    sw zero, 8(a0)
 ; RV32I-FPELIM-NEXT:    sw zero, 4(a0)
@@ -1001,7 +994,6 @@ define fp128 @callee_large_scalar_ret() nounwind {
 ; RV32I-WITHFP-NEXT:    sw s0, 8(sp)
 ; RV32I-WITHFP-NEXT:    addi s0, sp, 16
 ; RV32I-WITHFP-NEXT:    lui a1, 524272
-; RV32I-WITHFP-NEXT:    mv a1, a1
 ; RV32I-WITHFP-NEXT:    sw a1, 12(a0)
 ; RV32I-WITHFP-NEXT:    sw zero, 8(a0)
 ; RV32I-WITHFP-NEXT:    sw zero, 4(a0)
index c7c5f91301eeb7009bbcd6418f032976fad10966..f3ec61b435748d75fce1186bb6dfa63dae42faef 100644 (file)
@@ -84,7 +84,6 @@ define float @fneg_s(float %a) nounwind {
 ; RV32IF-LABEL: fneg_s:
 ; RV32IF:       # %bb.0:
 ; RV32IF-NEXT:    lui a1, 524288
-; RV32IF-NEXT:    mv a1, a1
 ; RV32IF-NEXT:    xor a0, a0, a1
 ; RV32IF-NEXT:    ret
   %1 = fsub float -0.0, %a
@@ -97,7 +96,6 @@ define float @fsgnjn_s(float %a, float %b) nounwind {
 ; RV32IF-LABEL: fsgnjn_s:
 ; RV32IF:       # %bb.0:
 ; RV32IF-NEXT:    lui a2, 524288
-; RV32IF-NEXT:    mv a2, a2
 ; RV32IF-NEXT:    xor a1, a1, a2
 ; RV32IF-NEXT:    fmv.w.x ft0, a1
 ; RV32IF-NEXT:    fmv.w.x ft1, a0
index 61a6178e09587e66ac163f6537e97408eb38fbc1..9e7131bbd28c8f4acfdb96e7612aad09e47f3f96 100644 (file)
@@ -264,10 +264,9 @@ define void @va1_caller() nounwind {
 ; RV32I-FPELIM:       # %bb.0:
 ; RV32I-FPELIM-NEXT:    addi sp, sp, -16
 ; RV32I-FPELIM-NEXT:    sw ra, 12(sp)
-; RV32I-FPELIM-NEXT:    lui a0, 261888
-; RV32I-FPELIM-NEXT:    mv a3, a0
 ; RV32I-FPELIM-NEXT:    lui a0, %hi(va1)
 ; RV32I-FPELIM-NEXT:    addi a0, a0, %lo(va1)
+; RV32I-FPELIM-NEXT:    lui a3, 261888
 ; RV32I-FPELIM-NEXT:    addi a4, zero, 2
 ; RV32I-FPELIM-NEXT:    mv a2, zero
 ; RV32I-FPELIM-NEXT:    jalr a0
@@ -281,10 +280,9 @@ define void @va1_caller() nounwind {
 ; RV32I-WITHFP-NEXT:    sw ra, 12(sp)
 ; RV32I-WITHFP-NEXT:    sw s0, 8(sp)
 ; RV32I-WITHFP-NEXT:    addi s0, sp, 16
-; RV32I-WITHFP-NEXT:    lui a0, 261888
-; RV32I-WITHFP-NEXT:    mv a3, a0
 ; RV32I-WITHFP-NEXT:    lui a0, %hi(va1)
 ; RV32I-WITHFP-NEXT:    addi a0, a0, %lo(va1)
+; RV32I-WITHFP-NEXT:    lui a3, 261888
 ; RV32I-WITHFP-NEXT:    addi a4, zero, 2
 ; RV32I-WITHFP-NEXT:    mv a2, zero
 ; RV32I-WITHFP-NEXT:    jalr a0
@@ -472,10 +470,9 @@ define void @va2_caller() nounwind {
 ; RV32I-FPELIM:       # %bb.0:
 ; RV32I-FPELIM-NEXT:    addi sp, sp, -16
 ; RV32I-FPELIM-NEXT:    sw ra, 12(sp)
-; RV32I-FPELIM-NEXT:    lui a0, 261888
-; RV32I-FPELIM-NEXT:    mv a3, a0
 ; RV32I-FPELIM-NEXT:    lui a0, %hi(va2)
 ; RV32I-FPELIM-NEXT:    addi a0, a0, %lo(va2)
+; RV32I-FPELIM-NEXT:    lui a3, 261888
 ; RV32I-FPELIM-NEXT:    mv a2, zero
 ; RV32I-FPELIM-NEXT:    jalr a0
 ; RV32I-FPELIM-NEXT:    lw ra, 12(sp)
@@ -488,10 +485,9 @@ define void @va2_caller() nounwind {
 ; RV32I-WITHFP-NEXT:    sw ra, 12(sp)
 ; RV32I-WITHFP-NEXT:    sw s0, 8(sp)
 ; RV32I-WITHFP-NEXT:    addi s0, sp, 16
-; RV32I-WITHFP-NEXT:    lui a0, 261888
-; RV32I-WITHFP-NEXT:    mv a3, a0
 ; RV32I-WITHFP-NEXT:    lui a0, %hi(va2)
 ; RV32I-WITHFP-NEXT:    addi a0, a0, %lo(va2)
+; RV32I-WITHFP-NEXT:    lui a3, 261888
 ; RV32I-WITHFP-NEXT:    mv a2, zero
 ; RV32I-WITHFP-NEXT:    jalr a0
 ; RV32I-WITHFP-NEXT:    lw s0, 8(sp)
@@ -716,13 +712,11 @@ define void @va3_caller() nounwind {
 ; RV32I-FPELIM:       # %bb.0:
 ; RV32I-FPELIM-NEXT:    addi sp, sp, -16
 ; RV32I-FPELIM-NEXT:    sw ra, 12(sp)
-; RV32I-FPELIM-NEXT:    lui a0, 261888
-; RV32I-FPELIM-NEXT:    mv a2, a0
-; RV32I-FPELIM-NEXT:    lui a0, 262144
-; RV32I-FPELIM-NEXT:    mv a5, a0
 ; RV32I-FPELIM-NEXT:    lui a0, %hi(va3)
 ; RV32I-FPELIM-NEXT:    addi a3, a0, %lo(va3)
 ; RV32I-FPELIM-NEXT:    addi a0, zero, 2
+; RV32I-FPELIM-NEXT:    lui a2, 261888
+; RV32I-FPELIM-NEXT:    lui a5, 262144
 ; RV32I-FPELIM-NEXT:    mv a1, zero
 ; RV32I-FPELIM-NEXT:    mv a4, zero
 ; RV32I-FPELIM-NEXT:    jalr a3
@@ -736,13 +730,11 @@ define void @va3_caller() nounwind {
 ; RV32I-WITHFP-NEXT:    sw ra, 12(sp)
 ; RV32I-WITHFP-NEXT:    sw s0, 8(sp)
 ; RV32I-WITHFP-NEXT:    addi s0, sp, 16
-; RV32I-WITHFP-NEXT:    lui a0, 261888
-; RV32I-WITHFP-NEXT:    mv a2, a0
-; RV32I-WITHFP-NEXT:    lui a0, 262144
-; RV32I-WITHFP-NEXT:    mv a5, a0
 ; RV32I-WITHFP-NEXT:    lui a0, %hi(va3)
 ; RV32I-WITHFP-NEXT:    addi a3, a0, %lo(va3)
 ; RV32I-WITHFP-NEXT:    addi a0, zero, 2
+; RV32I-WITHFP-NEXT:    lui a2, 261888
+; RV32I-WITHFP-NEXT:    lui a5, 262144
 ; RV32I-WITHFP-NEXT:    mv a1, zero
 ; RV32I-WITHFP-NEXT:    mv a4, zero
 ; RV32I-WITHFP-NEXT:    jalr a3
@@ -1035,8 +1027,6 @@ define void @va5_aligned_stack_caller() nounwind {
 ; RV32I-FPELIM-NEXT:    lui a0, 335544
 ; RV32I-FPELIM-NEXT:    addi a0, a0, 1311
 ; RV32I-FPELIM-NEXT:    sw a0, 32(sp)
-; RV32I-FPELIM-NEXT:    lui a0, 688509
-; RV32I-FPELIM-NEXT:    addi a6, a0, -2048
 ; RV32I-FPELIM-NEXT:    lui a0, %hi(va5_aligned_stack_callee)
 ; RV32I-FPELIM-NEXT:    addi a5, a0, %lo(va5_aligned_stack_callee)
 ; RV32I-FPELIM-NEXT:    addi a0, zero, 1
@@ -1044,6 +1034,8 @@ define void @va5_aligned_stack_caller() nounwind {
 ; RV32I-FPELIM-NEXT:    addi a2, sp, 32
 ; RV32I-FPELIM-NEXT:    addi a3, zero, 12
 ; RV32I-FPELIM-NEXT:    addi a4, zero, 13
+; RV32I-FPELIM-NEXT:    lui a6, 688509
+; RV32I-FPELIM-NEXT:    addi a6, a6, -2048
 ; RV32I-FPELIM-NEXT:    addi a7, zero, 4
 ; RV32I-FPELIM-NEXT:    jalr a5
 ; RV32I-FPELIM-NEXT:    lw ra, 60(sp)
@@ -1082,8 +1074,6 @@ define void @va5_aligned_stack_caller() nounwind {
 ; RV32I-WITHFP-NEXT:    lui a0, 335544
 ; RV32I-WITHFP-NEXT:    addi a0, a0, 1311
 ; RV32I-WITHFP-NEXT:    sw a0, -32(s0)
-; RV32I-WITHFP-NEXT:    lui a0, 688509
-; RV32I-WITHFP-NEXT:    addi a6, a0, -2048
 ; RV32I-WITHFP-NEXT:    lui a0, %hi(va5_aligned_stack_callee)
 ; RV32I-WITHFP-NEXT:    addi a5, a0, %lo(va5_aligned_stack_callee)
 ; RV32I-WITHFP-NEXT:    addi a0, zero, 1
@@ -1091,6 +1081,8 @@ define void @va5_aligned_stack_caller() nounwind {
 ; RV32I-WITHFP-NEXT:    addi a2, s0, -32
 ; RV32I-WITHFP-NEXT:    addi a3, zero, 12
 ; RV32I-WITHFP-NEXT:    addi a4, zero, 13
+; RV32I-WITHFP-NEXT:    lui a6, 688509
+; RV32I-WITHFP-NEXT:    addi a6, a6, -2048
 ; RV32I-WITHFP-NEXT:    addi a7, zero, 4
 ; RV32I-WITHFP-NEXT:    jalr a5
 ; RV32I-WITHFP-NEXT:    lw s0, 56(sp)
index e0473ca371d17974fe0f0d274cb3260a098941d9..37cd36c3b400fa47ccf1d30553cc36d8f32c07b0 100644 (file)
@@ -4,5 +4,12 @@
 # TODO ld
 # TODO sd
 
+li x0, 4294967296   # CHECK: :[[@LINE]]:8: error: immediate must be an integer in the range [-2147483648, 4294967295]
+li x0, -2147483649  # CHECK: :[[@LINE]]:8: error: immediate must be an integer in the range [-2147483648, 4294967295]
+li t4, foo          # CHECK: :[[@LINE]]:8: error: immediate must be an integer in the range [-2147483648, 4294967295]
+
 negw x1, x2   # CHECK: :[[@LINE]]:1: error: instruction use requires an option to be enabled
 sext.w x3, x4 # CHECK: :[[@LINE]]:1: error: instruction use requires an option to be enabled
+
+foo:
+  .space 4
index f4f35c543ac3fbbb245789e3e3941c5565ea2bb0..84ed1ec3c30ccda7c5a9207ef51fdc520518e46a 100644 (file)
@@ -1,13 +1,71 @@
 # RUN: llvm-mc %s -triple=riscv32 -riscv-no-aliases \
-# RUN:     | FileCheck -check-prefixes=CHECK-INST %s
+# RUN:     | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s
 # RUN: llvm-mc %s -triple=riscv32 \
-# RUN:     | FileCheck -check-prefixes=CHECK-ALIAS %s
+# RUN:     | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s
 # RUN: llvm-mc -filetype=obj -triple riscv32 < %s \
 # RUN:     | llvm-objdump -riscv-no-aliases -d - \
-# RUN:     | FileCheck -check-prefixes=CHECK-INST %s
+# RUN:     | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s
 # RUN: llvm-mc -filetype=obj -triple riscv32 < %s \
 # RUN:     | llvm-objdump -d - \
-# RUN:     | FileCheck -check-prefixes=CHECK-ALIAS %s
+# RUN:     | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s
+
+# The following check prefixes are used in this test:
+# CHECK-INST.....Match the canonical instr (tests alias to instr. mapping)
+# CHECK-ALIAS....Match the alias (tests instr. to alias mapping)
+# CHECK-EXPAND...Match canonical instr. unconditionally (tests alias expansion)
+
+# CHECK-INST: addi a0, zero, 0
+# CHECK-ALIAS: mv a0, zero
+li x10, 0
+# CHECK-EXPAND: addi a0, zero, 1
+li x10, 1
+# CHECK-EXPAND: addi a0, zero, -1
+li x10, -1
+# CHECK-EXPAND: addi a0, zero, 2047
+li x10, 2047
+# CHECK-EXPAND: addi a0, zero, -2047
+li x10, -2047
+# CHECK-EXPAND: lui a1, 1
+# CHECK-EXPAND: addi a1, a1, -2048
+li x11, 2048
+# CHECK-EXPAND: addi a1, zero, -2048
+li x11, -2048
+# CHECK-EXPAND: lui a1, 1
+# CHECK-EXPAND: addi a1, a1, -2047
+li x11, 2049
+# CHECK-EXPAND: lui a1, 1048575
+# CHECK-EXPAND: addi a1, a1, 2047
+li x11, -2049
+# CHECK-EXPAND: lui a1, 1
+# CHECK-EXPAND: addi a1, a1, -1
+li x11, 4095
+# CHECK-EXPAND: lui a1, 1048575
+# CHECK-EXPAND: addi a1, a1, 1
+li x11, -4095
+# CHECK-EXPAND: lui a2, 1
+li x12, 4096
+# CHECK-EXPAND: lui a2, 1048575
+li x12, -4096
+# CHECK-EXPAND: lui a2, 1
+# CHECK-EXPAND: addi a2, a2, 1
+li x12, 4097
+# CHECK-EXPAND: lui a2, 1048575
+# CHECK-EXPAND: addi a2, a2, -1
+li x12, -4097
+# CHECK-EXPAND: lui a2, 524288
+# CHECK-EXPAND: addi a2, a2, -1
+li x12, 2147483647
+# CHECK-EXPAND: lui a2, 524288
+# CHECK-EXPAND: addi a2, a2, 1
+li x12, -2147483647
+# CHECK-EXPAND: lui a2, 524288
+li x12, -2147483648
+# CHECK-EXPAND: lui a2, 524288
+li x12, 0x80000000
+# CHECK-EXPAND: lui a2, 524288
+li x12, -0x80000000
+# CHECK-EXPAND: addi a2, zero, -1
+li x12, 0xFFFFFFFF
 
 # CHECK-INST: csrrs t4, 3202, zero
 # CHECK-ALIAS: rdinstreth t4
index f8e3991f1c9336900211167e81072da12326ff2a..e21601b51a4b246b2dc5ec73aac627a3da32981c 100644 (file)
@@ -1,6 +1,12 @@
 # RUN: not llvm-mc %s -triple=riscv64 -riscv-no-aliases 2>&1 | FileCheck %s
 # RUN: not llvm-mc %s -triple=riscv64 2>&1 | FileCheck %s
 
+li t5, 0x10000000000000000 # CHECK: :[[@LINE]]:8: error: unknown operand
+li t4, foo                 # CHECK: :[[@LINE]]:8: error: operand must be a constant 64-bit integer
+
 rdinstreth x29 # CHECK: :[[@LINE]]:1: error: instruction use requires an option to be enabled
 rdcycleh x27   # CHECK: :[[@LINE]]:1: error: instruction use requires an option to be enabled
 rdtimeh x28    # CHECK: :[[@LINE]]:1: error: instruction use requires an option to be enabled
+
+foo:
+  .space 8
index 953493e147b4d81707870a94f85737038fb3effd..edfa66e0463c2d0ad6fe5d73705dabb60d0d06e5 100644 (file)
 # RUN: llvm-mc %s -triple=riscv64 -riscv-no-aliases \
-# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN:     | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s
 # RUN: llvm-mc %s -triple=riscv64 \
-# RUN:     | FileCheck -check-prefix=CHECK-ALIAS %s
+# RUN:     | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s
 # RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
 # RUN:     | llvm-objdump -riscv-no-aliases -d - \
-# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN:     | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-INST %s
 # RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
 # RUN:     | llvm-objdump -d - \
-# RUN:     | FileCheck -check-prefix=CHECK-ALIAS %s
+# RUN:     | FileCheck -check-prefixes=CHECK-EXPAND,CHECK-ALIAS %s
+
+# The following check prefixes are used in this test:
+# CHECK-INST.....Match the canonical instr (tests alias to instr. mapping)
+# CHECK-ALIAS....Match the alias (tests instr. to alias mapping)
+# CHECK-EXPAND...Match canonical instr. unconditionally (tests alias expansion)
 
 # TODO ld
 # TODO sd
 
+# CHECK-INST: addiw a0, zero, 0
+# CHECK-ALIAS: sext.w a0, zero
+li x10, 0
+# CHECK-EXPAND: addiw a0, zero, 1
+li x10, 1
+# CHECK-EXPAND: addiw a0, zero, -1
+li x10, -1
+# CHECK-EXPAND: addiw a0, zero, 2047
+li x10, 2047
+# CHECK-EXPAND: addiw a0, zero, -2047
+li x10, -2047
+# CHECK-EXPAND: lui a1, 1
+# CHECK-EXPAND: addiw a1, a1, -2048
+li x11, 2048
+# CHECK-EXPAND: addiw a1, zero, -2048
+li x11, -2048
+# CHECK-EXPAND: lui a1, 1
+# CHECK-EXPAND: addiw a1, a1, -2047
+li x11, 2049
+# CHECK-EXPAND: lui a1, 1048575
+# CHECK-EXPAND: addiw a1, a1, 2047
+li x11, -2049
+# CHECK-EXPAND: lui a1, 1
+# CHECK-EXPAND: addiw a1, a1, -1
+li x11, 4095
+# CHECK-EXPAND: lui a1, 1048575
+# CHECK-EXPAND: addiw a1, a1, 1
+li x11, -4095
+# CHECK-EXPAND: lui a2, 1
+li x12, 4096
+# CHECK-EXPAND: lui a2, 1048575
+li x12, -4096
+# CHECK-EXPAND: lui a2, 1
+# CHECK-EXPAND: addiw a2, a2, 1
+li x12, 4097
+# CHECK-EXPAND: lui a2, 1048575
+# CHECK-EXPAND: addiw a2, a2, -1
+li x12, -4097
+# CHECK-EXPAND: lui a2, 524288
+# CHECK-EXPAND: addiw a2, a2, -1
+li x12, 2147483647
+# CHECK-EXPAND: lui a2, 524288
+# CHECK-EXPAND: addiw a2, a2, 1
+li x12, -2147483647
+# CHECK-EXPAND: lui a2, 524288
+li x12, -2147483648
+
+# CHECK-EXPAND: addiw t0, zero, 1
+# CHECK-EXPAND: slli t0, t0, 32
+li t0, 0x100000000
+# CHECK-EXPAND: addiw t1, zero, -1
+# CHECK-EXPAND: slli t1, t1, 63
+li t1, 0x8000000000000000
+# CHECK-EXPAND: addiw t1, zero, -1
+# CHECK-EXPAND: slli t1, t1, 63
+li t1, -0x8000000000000000
+# CHECK-EXPAND: lui t2, 9321
+# CHECK-EXPAND: addiw t2, t2, -1329
+# CHECK-EXPAND: slli t2, t2, 35
+li t2, 0x1234567800000000
+# CHECK-EXPAND: addiw t3, zero, 7
+# CHECK-EXPAND: slli t3, t3, 36
+# CHECK-EXPAND: addi t3, t3, 11
+# CHECK-EXPAND: slli t3, t3, 24
+# CHECK-EXPAND: addi t3, t3, 15
+li t3, 0x700000000B00000F
+# CHECK-EXPAND: lui t4, 583
+# CHECK-EXPAND: addiw t4, t4, -1875
+# CHECK-EXPAND: slli t4, t4, 14
+# CHECK-EXPAND: addi t4, t4, -947
+# CHECK-EXPAND: slli t4, t4, 12
+# CHECK-EXPAND: addi t4, t4, 1511
+# CHECK-EXPAND: slli t4, t4, 13
+# CHECK-EXPAND: addi t4, t4, -272
+li t4, 0x123456789abcdef0
+# CHECK-EXPAND: addiw t5, zero, -1
+li t5, 0xFFFFFFFFFFFFFFFF
+
 # CHECK-INST: subw t6, zero, ra
 # CHECK-ALIAS: negw t6, ra
 negw x31, x1
index 72ed72eab2788386b1df5708c62c844892095110..2ad1b3c65d295712de498c1834d257ad2237a500 100644 (file)
 # RUN:     | llvm-objdump -d - \
 # RUN:     | FileCheck -check-prefix=CHECK-ALIAS %s
 
+# The following check prefixes are used in this test:
+# CHECK-INST.....Match the canonical instr (tests alias to instr. mapping)
+# CHECK-ALIAS....Match the alias (tests instr. to alias mapping)
+
 # TODO la
 # TODO lb lh lw
 # TODO sb sh sw
@@ -26,7 +30,6 @@
 # CHECK-INST: addi zero, zero, 0
 # CHECK-ALIAS: nop
 nop
-# TODO li
 # CHECK-INST: addi t6, zero, 0
 # CHECK-ALIAS: mv t6, zero
 mv x31, zero