From 6b11f688f951fe9a052d64f88f329210b0301c03 Mon Sep 17 00:00:00 2001 From: Alex Bradbury Date: Tue, 17 Apr 2018 21:56:40 +0000 Subject: [PATCH] [RISCV] implement li pseudo instruction 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@330224 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 69 ++++++-- lib/Target/RISCV/MCTargetDesc/CMakeLists.txt | 1 + .../MCTargetDesc/RISCVMCPseudoExpansion.cpp | 101 +++++++++++ .../MCTargetDesc/RISCVMCPseudoExpansion.h | 29 ++++ lib/Target/RISCV/RISCVAsmPrinter.cpp | 9 + lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 63 ++++--- lib/Target/RISCV/RISCVInstrFormats.td | 4 +- lib/Target/RISCV/RISCVInstrInfo.cpp | 13 +- lib/Target/RISCV/RISCVInstrInfo.td | 24 ++- test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll | 159 +++++++++--------- test/CodeGen/RISCV/calling-conv.ll | 36 ++-- test/CodeGen/RISCV/float-arith.ll | 2 - test/CodeGen/RISCV/vararg.ll | 32 ++-- test/MC/RISCV/rv32i-aliases-invalid.s | 7 + test/MC/RISCV/rv32i-aliases-valid.s | 66 +++++++- test/MC/RISCV/rv64i-aliases-invalid.s | 6 + test/MC/RISCV/rv64i-aliases-valid.s | 91 +++++++++- test/MC/RISCV/rvi-aliases-valid.s | 5 +- 18 files changed, 535 insertions(+), 182 deletions(-) create mode 100644 lib/Target/RISCV/MCTargetDesc/RISCVMCPseudoExpansion.cpp create mode 100644 lib/Target/RISCV/MCTargetDesc/RISCVMCPseudoExpansion.h diff --git a/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 521d72b546d..7f0433410d0 100644 --- a/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -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" @@ -22,8 +23,11 @@ #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 + 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::min(), + std::numeric_limits::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() { diff --git a/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt b/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt index d9f4188aa75..2ea149a388d 100644 --- a/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt +++ b/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt @@ -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/lib/Target/RISCV/MCTargetDesc/RISCVMCPseudoExpansion.cpp b/lib/Target/RISCV/MCTargetDesc/RISCVMCPseudoExpansion.cpp new file mode 100644 index 00000000000..406c4c20fe9 --- /dev/null +++ b/lib/Target/RISCV/MCTargetDesc/RISCVMCPseudoExpansion.cpp @@ -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 + +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/lib/Target/RISCV/MCTargetDesc/RISCVMCPseudoExpansion.h b/lib/Target/RISCV/MCTargetDesc/RISCVMCPseudoExpansion.h new file mode 100644 index 00000000000..0a577a9bc33 --- /dev/null +++ b/lib/Target/RISCV/MCTargetDesc/RISCVMCPseudoExpansion.h @@ -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 + +namespace llvm { + +class MCStreamer; +class MCSubtargetInfo; + +void emitRISCVLoadImm(unsigned DestReg, int64_t Value, MCStreamer &Out, + const MCSubtargetInfo *STI); + +} // namespace llvm + +#endif diff --git a/lib/Target/RISCV/RISCVAsmPrinter.cpp b/lib/Target/RISCV/RISCVAsmPrinter.cpp index bdf8e5d840b..820cbe1ed5d 100644 --- a/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -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); diff --git a/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 630439bb53c..8fdf18efb58 100644 --- a/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -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); + SDValue ImmOperand; + SDValue Parent; + if (Base.getMachineOpcode() == RISCV::PseudoLI) { + ImmOperand = Base.getOperand(0); + auto Const = dyn_cast(ImmOperand); + if (!Const || (Const->getSExtValue() & 0xFFF) == 0) + continue; - if (auto Const = dyn_cast(ImmOperand)) { - ImmOperand = CurDAG->getTargetConstant( - Const->getSExtValue(), SDLoc(ImmOperand), ImmOperand.getValueType()); - } else if (auto GA = dyn_cast(ImmOperand)) { - ImmOperand = CurDAG->getTargetGlobalAddress( - GA->getGlobal(), SDLoc(ImmOperand), ImmOperand.getValueType(), - GA->getOffset(), GA->getTargetFlags()); + 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(ImmOperand)) { + ImmOperand = + CurDAG->getTargetConstant(Const->getSExtValue(), SDLoc(ImmOperand), + ImmOperand.getValueType()); + } else if (auto GA = dyn_cast(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 diff --git a/lib/Target/RISCV/RISCVInstrFormats.td b/lib/Target/RISCV/RISCVInstrFormats.td index 7479ffbc953..529e048045c 100644 --- a/lib/Target/RISCV/RISCVInstrFormats.td +++ b/lib/Target/RISCV/RISCVInstrFormats.td @@ -102,8 +102,8 @@ class RVInst pattern> - : RVInst { +class Pseudo pattern, string opcodestr = "", string argstr = ""> + : RVInst { let isPseudo = 1; let isCodeGenOnly = 1; } diff --git a/lib/Target/RISCV/RISCVInstrInfo.cpp b/lib/Target/RISCV/RISCVInstrInfo.cpp index 91a0dfb233f..cbbe07a27bf 100644 --- a/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -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); } diff --git a/lib/Target/RISCV/RISCVInstrInfo.td b/lib/Target/RISCV/RISCVInstrInfo.td index 1c429da7419..56fb9f60927 100644 --- a/lib/Target/RISCV/RISCVInstrInfo.td +++ b/lib/Target/RISCV/RISCVInstrInfo.td @@ -43,6 +43,12 @@ def SelectCC : SDNode<"RISCVISD::SELECT_CC", SDT_RISCVSelectCC, // Operand and SDNode transformation definitions. //===----------------------------------------------------------------------===// +class ImmXLenAsmOperand : AsmOperandClass { + let Name = prefix # "ImmXLen" # suffix; + let RenderMethod = "addImmOperands"; + let DiagnosticType = !strconcat("Invalid", Name); +} + class ImmAsmOperand : AsmOperandClass { let Name = prefix # "Imm" # width # suffix; let RenderMethod = "addImmOperands"; @@ -154,7 +160,9 @@ def simm21_lsb0 : Operand { } // A parameterized register class alternative to i32imm/i64imm from Target.td. -def ixlenimm : Operand; +def ixlenimm : Operand { + let ParserMatchClass = ImmXLenAsmOperand<"">; +} // Standalone (codegen-only) immleaf patterns. def simm32 : ImmLeaf(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 diff --git a/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll b/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll index 1fbc429cae4..07d60128414 100644 --- a/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll +++ b/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll @@ -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) diff --git a/test/CodeGen/RISCV/calling-conv.ll b/test/CodeGen/RISCV/calling-conv.ll index 8d752cbb6e7..12270ff51b4 100644 --- a/test/CodeGen/RISCV/calling-conv.ll +++ b/test/CodeGen/RISCV/calling-conv.ll @@ -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) diff --git a/test/CodeGen/RISCV/float-arith.ll b/test/CodeGen/RISCV/float-arith.ll index c7c5f91301e..f3ec61b4357 100644 --- a/test/CodeGen/RISCV/float-arith.ll +++ b/test/CodeGen/RISCV/float-arith.ll @@ -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 diff --git a/test/CodeGen/RISCV/vararg.ll b/test/CodeGen/RISCV/vararg.ll index 61a6178e095..9e7131bbd28 100644 --- a/test/CodeGen/RISCV/vararg.ll +++ b/test/CodeGen/RISCV/vararg.ll @@ -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) diff --git a/test/MC/RISCV/rv32i-aliases-invalid.s b/test/MC/RISCV/rv32i-aliases-invalid.s index e0473ca371d..37cd36c3b40 100644 --- a/test/MC/RISCV/rv32i-aliases-invalid.s +++ b/test/MC/RISCV/rv32i-aliases-invalid.s @@ -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 diff --git a/test/MC/RISCV/rv32i-aliases-valid.s b/test/MC/RISCV/rv32i-aliases-valid.s index f4f35c543ac..84ed1ec3c30 100644 --- a/test/MC/RISCV/rv32i-aliases-valid.s +++ b/test/MC/RISCV/rv32i-aliases-valid.s @@ -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 diff --git a/test/MC/RISCV/rv64i-aliases-invalid.s b/test/MC/RISCV/rv64i-aliases-invalid.s index f8e3991f1c9..e21601b51a4 100644 --- a/test/MC/RISCV/rv64i-aliases-invalid.s +++ b/test/MC/RISCV/rv64i-aliases-invalid.s @@ -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 diff --git a/test/MC/RISCV/rv64i-aliases-valid.s b/test/MC/RISCV/rv64i-aliases-valid.s index 953493e147b..edfa66e0463 100644 --- a/test/MC/RISCV/rv64i-aliases-valid.s +++ b/test/MC/RISCV/rv64i-aliases-valid.s @@ -1,17 +1,100 @@ # 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 diff --git a/test/MC/RISCV/rvi-aliases-valid.s b/test/MC/RISCV/rvi-aliases-valid.s index 72ed72eab27..2ad1b3c65d2 100644 --- a/test/MC/RISCV/rvi-aliases-valid.s +++ b/test/MC/RISCV/rvi-aliases-valid.s @@ -19,6 +19,10 @@ # 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