diff --git a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp --- a/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp +++ b/llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "MCTargetDesc/LoongArchInstPrinter.h" +#include "MCTargetDesc/LoongArchMCExpr.h" #include "MCTargetDesc/LoongArchMCTargetDesc.h" #include "TargetInfo/LoongArchTargetInfo.h" #include "llvm/MC/MCContext.h" @@ -17,6 +18,7 @@ #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCValue.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/Casting.h" @@ -62,6 +64,8 @@ OperandMatchResultTy parseRegister(OperandVector &Operands); OperandMatchResultTy parseImmediate(OperandVector &Operands); + OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands); + OperandMatchResultTy parseSImm26Operand(OperandVector &Operands); bool parseOperand(OperandVector &Operands, StringRef Mnemonic); @@ -75,6 +79,9 @@ #undef GET_OPERAND_DIAGNOSTIC_TYPES }; + static bool classifySymbolRef(const MCExpr *Expr, + LoongArchMCExpr::VariantKind &Kind); + LoongArchAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII, const MCTargetOptions &Options) : MCTargetAsmParser(Options, STI, MII) { @@ -120,7 +127,13 @@ bool isMem() const override { return false; } void setReg(MCRegister PhysReg) { Reg.RegNum = PhysReg; } - static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) { + static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm, + LoongArchMCExpr::VariantKind &VK) { + if (auto *LE = dyn_cast(Expr)) { + VK = LE->getKind(); + return false; + } + if (auto CE = dyn_cast(Expr)) { Imm = CE->getValue(); return true; @@ -134,8 +147,10 @@ return false; int64_t Imm; - bool IsConstantImm = evaluateConstantImm(getImm(), Imm); - return IsConstantImm && isUInt(Imm - P); + LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; + bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); + return IsConstantImm && isUInt(Imm - P) && + VK == LoongArchMCExpr::VK_LoongArch_None; } template bool isSImm() const { @@ -143,8 +158,10 @@ return false; int64_t Imm; - bool IsConstantImm = evaluateConstantImm(getImm(), Imm); - return IsConstantImm && isShiftedInt(Imm); + LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; + bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); + return IsConstantImm && isShiftedInt(Imm) && + VK == LoongArchMCExpr::VK_LoongArch_None; } bool isUImm2() const { return isUImm<2>(); } @@ -156,13 +173,59 @@ bool isUImm12() const { return isUImm<12>(); } bool isUImm14() const { return isUImm<14>(); } bool isUImm15() const { return isUImm<15>(); } - bool isSImm12() const { return isSImm<12>(); } + + bool isSImm12() const { + if (!isImm()) + return false; + + int64_t Imm; + LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; + bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); + bool IsValidKind = VK == LoongArchMCExpr::VK_LoongArch_PCREL_LO; + + return IsConstantImm + ? (isInt<12>(Imm) && + (VK == LoongArchMCExpr::VK_LoongArch_None || IsValidKind)) + : (LoongArchAsmParser::classifySymbolRef(getImm(), VK) && + IsValidKind); + } + bool isSImm14lsl2() const { return isSImm<14, 2>(); } bool isSImm16() const { return isSImm<16>(); } bool isSImm16lsl2() const { return isSImm<16, 2>(); } bool isSImm20() const { return isSImm<20>(); } + + bool isSImm20pcalau12i() const { + if (!isImm()) + return false; + + int64_t Imm; + LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; + bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); + bool IsValidKind = VK == LoongArchMCExpr::VK_LoongArch_PCREL_HI; + + return IsConstantImm + ? (isInt<20>(Imm) && + (VK == LoongArchMCExpr::VK_LoongArch_None || IsValidKind)) + : (LoongArchAsmParser::classifySymbolRef(getImm(), VK) && + IsValidKind); + } + bool isSImm21lsl2() const { return isSImm<21, 2>(); } - bool isSImm26lsl2() const { return isSImm<26, 2>(); } + + bool isSImm26Operand() const { + int64_t Imm; + LoongArchMCExpr::VariantKind VK = LoongArchMCExpr::VK_LoongArch_None; + bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); + bool IsValidKind = (VK == LoongArchMCExpr::VK_LoongArch_CALL || + VK == LoongArchMCExpr::VK_LoongArch_CALL_PLT); + + return IsConstantImm + ? (isShiftedInt<26, 2>(Imm) && + (VK == LoongArchMCExpr::VK_LoongArch_None || IsValidKind)) + : (LoongArchAsmParser::classifySymbolRef(getImm(), VK) && + IsValidKind); + } /// Gets location of the first token of this operand. SMLoc getStartLoc() const override { return StartLoc; } @@ -289,6 +352,21 @@ llvm_unreachable("Unimplemented function."); } +bool LoongArchAsmParser::classifySymbolRef(const MCExpr *Expr, + LoongArchMCExpr::VariantKind &Kind) { + Kind = LoongArchMCExpr::VK_LoongArch_None; + + if (const LoongArchMCExpr *RE = dyn_cast(Expr)) { + Kind = RE->getKind(); + Expr = RE->getSubExpr(); + } + + MCValue Res; + if (Expr->evaluateAsRelocatable(Res, nullptr, nullptr)) + return Res.getRefKind() == LoongArchMCExpr::VK_LoongArch_None; + return false; +} + OperandMatchResultTy LoongArchAsmParser::parseRegister(OperandVector &Operands) { if (getLexer().getTok().isNot(AsmToken::Dollar)) @@ -319,9 +397,91 @@ SMLoc E; const MCExpr *Res; - if (getParser().parseExpression(Res, E)) + switch (getLexer().getKind()) { + default: + return MatchOperand_NoMatch; + case AsmToken::LParen: + case AsmToken::Dot: + case AsmToken::Minus: + case AsmToken::Plus: + case AsmToken::Exclaim: + case AsmToken::Tilde: + case AsmToken::Integer: + case AsmToken::String: + case AsmToken::Identifier: + if (getParser().parseExpression(Res, E)) + return MatchOperand_ParseFail; + break; + case AsmToken::Percent: + return parseOperandWithModifier(Operands); + } + + Operands.push_back(LoongArchOperand::createImm(Res, S, E)); + return MatchOperand_Success; +} + +OperandMatchResultTy +LoongArchAsmParser::parseOperandWithModifier(OperandVector &Operands) { + SMLoc S = getLoc(); + SMLoc E; + + if (getLexer().getKind() != AsmToken::Percent) { + Error(getLoc(), "expected '%' for operand modifier"); + return MatchOperand_ParseFail; + } + + getParser().Lex(); // Eat '%' + + if (getLexer().getKind() != AsmToken::Identifier) { + Error(getLoc(), "expected valid identifier for operand modifier"); + return MatchOperand_ParseFail; + } + StringRef Identifier = getParser().getTok().getIdentifier(); + LoongArchMCExpr::VariantKind VK = + LoongArchMCExpr::getVariantKindForName(Identifier); + if (VK == LoongArchMCExpr::VK_LoongArch_Invalid) { + Error(getLoc(), "unrecognized operand modifier"); + return MatchOperand_ParseFail; + } + + getParser().Lex(); // Eat the identifier + if (getLexer().getKind() != AsmToken::LParen) { + Error(getLoc(), "expected '('"); + return MatchOperand_ParseFail; + } + getParser().Lex(); // Eat '(' + + const MCExpr *SubExpr; + if (getParser().parseParenExpression(SubExpr, E)) { + return MatchOperand_ParseFail; + } + + const MCExpr *ModExpr = LoongArchMCExpr::create(SubExpr, VK, getContext()); + Operands.push_back(LoongArchOperand::createImm(ModExpr, S, E)); + return MatchOperand_Success; +} + +OperandMatchResultTy +LoongArchAsmParser::parseSImm26Operand(OperandVector &Operands) { + SMLoc S = getLoc(); + const MCExpr *Res; + + if (getLexer().getKind() == AsmToken::Percent) + return parseOperandWithModifier(Operands); + + if (getLexer().getKind() != AsmToken::Identifier) + return MatchOperand_NoMatch; + + StringRef Identifier; + if (getParser().parseIdentifier(Identifier)) return MatchOperand_ParseFail; + SMLoc E = SMLoc::getFromPointer(S.getPointer() + Identifier.size()); + + MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); + Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); + Res = LoongArchMCExpr::create(Res, LoongArchMCExpr::VK_LoongArch_CALL, + getContext()); Operands.push_back(LoongArchOperand::createImm(Res, S, E)); return MatchOperand_Success; } @@ -330,6 +490,15 @@ /// information, adding to Operands. Return true upon an error. bool LoongArchAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { + // Check if the current operand has a custom associated parser, if so, try to + // custom parse the operand, or fallback to the general approach. + OperandMatchResultTy Result = + MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); + if (Result == MatchOperand_Success) + return false; + if (Result == MatchOperand_ParseFail) + return true; + if (parseRegister(Operands) == MatchOperand_Success || parseImmediate(Operands) == MatchOperand_Success) return false; @@ -522,8 +691,11 @@ return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/0, /*Upper=*/(1 << 15) - 1); case Match_InvalidSImm12: - return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/-(1 << 11), - /*Upper=*/(1 << 11) - 1); + return generateImmOutOfRangeError( + Operands, ErrorInfo, /*Lower=*/-(1 << 11), + /*Upper=*/(1 << 11) - 1, + "operand must be a symbol with modifier (e.g. %pc_lo12) or an integer " + "in the range"); case Match_InvalidSImm14lsl2: return generateImmOutOfRangeError( Operands, ErrorInfo, /*Lower=*/-(1 << 15), /*Upper=*/(1 << 15) - 4, @@ -538,14 +710,21 @@ case Match_InvalidSImm20: return generateImmOutOfRangeError(Operands, ErrorInfo, /*Lower=*/-(1 << 19), /*Upper=*/(1 << 19) - 1); + case Match_InvalidSImm20pcalau12i: + return generateImmOutOfRangeError( + Operands, ErrorInfo, /*Lower=*/-(1 << 19), + /*Upper=*/(1 << 19) - 1, + "operand must be a symbol with modifier (e.g. %pc_hi20) or an integer " + "in the range"); case Match_InvalidSImm21lsl2: return generateImmOutOfRangeError( Operands, ErrorInfo, /*Lower=*/-(1 << 22), /*Upper=*/(1 << 22) - 4, "immediate must be a multiple of 4 in the range"); - case Match_InvalidSImm26lsl2: + case Match_InvalidSImm26Operand: return generateImmOutOfRangeError( Operands, ErrorInfo, /*Lower=*/-(1 << 27), /*Upper=*/(1 << 27) - 4, - "immediate must be a multiple of 4 in the range"); + "operand must be a bare symbol name or an immediate must be a multiple " + "of 4 in the range"); } llvm_unreachable("Unknown match type detected!"); } diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -17,6 +17,7 @@ #include "LoongArchRegisterInfo.h" #include "LoongArchSubtarget.h" #include "LoongArchTargetMachine.h" +#include "MCTargetDesc/LoongArchBaseInfo.h" #include "MCTargetDesc/LoongArchMCTargetDesc.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/ISDOpcodes.h" @@ -278,10 +279,13 @@ // TODO: Support dso_preemptable and target flags. if (GV->isDSOLocal()) { - SDValue GA = DAG.getTargetGlobalAddress(GV, DL, Ty); - SDValue AddrHi(DAG.getMachineNode(LoongArch::PCALAU12I, DL, Ty, GA), 0); - SDValue Addr(DAG.getMachineNode(ADDIOp, DL, Ty, AddrHi, GA), 0); - return Addr; + SDValue GAHi = + DAG.getTargetGlobalAddress(GV, DL, Ty, 0, LoongArchII::MO_PCREL_HI); + SDValue GALo = + DAG.getTargetGlobalAddress(GV, DL, Ty, 0, LoongArchII::MO_PCREL_LO); + SDValue AddrHi(DAG.getMachineNode(LoongArch::PCALAU12I, DL, Ty, GAHi), 0); + + return SDValue(DAG.getMachineNode(ADDIOp, DL, Ty, AddrHi, GALo), 0); } report_fatal_error("Unable to lowerGlobalAddress"); } @@ -1601,11 +1605,20 @@ // If the callee is a GlobalAddress/ExternalSymbol node, turn it into a // TargetGlobalAddress/TargetExternalSymbol node so that legalize won't // split it and then direct call can be matched by PseudoCALL. - // FIXME: Add target flags for relocation. - if (GlobalAddressSDNode *S = dyn_cast(Callee)) - Callee = DAG.getTargetGlobalAddress(S->getGlobal(), DL, PtrVT); - else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) - Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT); + if (GlobalAddressSDNode *S = dyn_cast(Callee)) { + const GlobalValue *GV = S->getGlobal(); + unsigned OpFlags = + getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV) + ? LoongArchII::MO_CALL + : LoongArchII::MO_CALL_PLT; + Callee = DAG.getTargetGlobalAddress(S->getGlobal(), DL, PtrVT, 0, OpFlags); + } else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) { + unsigned OpFlags = getTargetMachine().shouldAssumeDSOLocal( + *MF.getFunction().getParent(), nullptr) + ? LoongArchII::MO_CALL + : LoongArchII::MO_CALL_PLT; + Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, OpFlags); + } // The first call operand is the chain and the second is the target address. SmallVector Ops; diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -150,19 +150,42 @@ let DecoderMethod = "decodeSImmOperand<16, 2>"; } -def simm20 : Operand { - let ParserMatchClass = SImmAsmOperand<20>; +class SImm20Operand : Operand { let DecoderMethod = "decodeSImmOperand<20>"; } +def simm20 : SImm20Operand { + let ParserMatchClass = SImmAsmOperand<20>; +} + +def simm20_pcalau12i : SImm20Operand { + let ParserMatchClass = SImmAsmOperand<20, "pcalau12i">; +} + def simm21_lsl2 : Operand { let ParserMatchClass = SImmAsmOperand<21, "lsl2">; let EncoderMethod = "getImmOpValueAsr2"; let DecoderMethod = "decodeSImmOperand<21, 2>"; } -def simm26_lsl2 : Operand { - let ParserMatchClass = SImmAsmOperand<26, "lsl2">; +// TODO: Need split the ParserMethod/PredicateMethod for call/jump/tailcall. +def SImm26Operand: AsmOperandClass { + let Name = "SImm26Operand"; + let RenderMethod = "addImmOperands"; + let DiagnosticType = "InvalidSImm26Operand"; + let ParserMethod = "parseSImm26Operand"; +} + +// A symbol or an imm used in B/PseudoBR. +def simm26_b : Operand { + let ParserMatchClass = SImm26Operand; + let EncoderMethod = "getImmOpValueAsr2"; + let DecoderMethod = "decodeSImmOperand<26, 2>"; +} + +// A symbol or an imm used in BL/PseudoCALL. +def simm26_bl : Operand { + let ParserMatchClass = SImm26Operand; let EncoderMethod = "getImmOpValueAsr2"; let DecoderMethod = "decodeSImmOperand<26, 2>"; } @@ -190,17 +213,6 @@ N->getValueType(0)); }]>; -def CallSymbol: AsmOperandClass { - let Name = "CallSymbol"; - let RenderMethod = "addImmOperands"; - let PredicateMethod = "isImm"; -} - -// A bare symbol used in call only. -def call_symbol : Operand { - let ParserMatchClass = CallSymbol; -} - def BaseAddr : ComplexPattern; //===----------------------------------------------------------------------===// @@ -259,7 +271,7 @@ let isTerminator = 1; } class Br_I26 op, string opstr> - : FmtI26 { + : FmtI26 { let isBranch = 1; let isTerminator = 1; } @@ -323,7 +335,7 @@ def SLTUI : ALU_2RI12<0b0000001001, "sltui", simm12>; def PCADDI : ALU_1RI20<0b0001100, "pcaddi", simm20>; def PCADDU12I : ALU_1RI20<0b0001110, "pcaddu12i", simm20>; -def PCALAU12I : ALU_1RI20<0b0001101, "pcalau12i", simm20>; +def PCALAU12I : ALU_1RI20<0b0001101, "pcalau12i", simm20_pcalau12i>; def AND : ALU_3R<0b00000000000101001, "and">; def OR : ALU_3R<0b00000000000101010, "or">; def NOR : ALU_3R<0b00000000000101000, "nor">; @@ -387,8 +399,8 @@ def BNEZ : BrCCZ_1RI21<0b010001, "bnez">; def B : Br_I26<0b010100, "b">; -let isCall = 1 in -def BL : FmtI26<0b010101, (outs), (ins simm26_lsl2:$imm26), "bl", "$imm26">; +let isCall = 1, Defs=[R1] in +def BL : FmtI26<0b010101, (outs), (ins simm26_bl:$imm26), "bl", "$imm26">; def JIRL : Fmt2RI16<0b010011, (outs GPR:$rd), (ins GPR:$rj, simm16_lsl2:$imm16), "jirl", "$rd, $rj, $imm16">; @@ -827,8 +839,8 @@ (BNEZ GPR:$rj, bb:$imm21)>; let isBarrier = 1, isBranch = 1, isTerminator = 1 in -def PseudoBR : Pseudo<(outs), (ins simm26_lsl2:$imm26), [(br bb:$imm26)]>, - PseudoInstExpansion<(B simm26_lsl2:$imm26)>; +def PseudoBR : Pseudo<(outs), (ins simm26_b:$imm26), [(br bb:$imm26)]>, + PseudoInstExpansion<(B simm26_b:$imm26)>; let isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in def PseudoBRIND : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16), []>, @@ -839,7 +851,7 @@ (PseudoBRIND GPR:$rj, simm16_lsl2:$imm16)>; let isCall = 1, Defs = [R1] in -def PseudoCALL : Pseudo<(outs), (ins call_symbol:$func), []> { +def PseudoCALL : Pseudo<(outs), (ins simm26_bl:$func), []> { let AsmString = "bl\t$func"; } diff --git a/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp --- a/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp @@ -13,6 +13,8 @@ #include "LoongArch.h" #include "LoongArchSubtarget.h" +#include "MCTargetDesc/LoongArchBaseInfo.h" +#include "MCTargetDesc/LoongArchMCExpr.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineInstr.h" @@ -25,8 +27,28 @@ static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym, const AsmPrinter &AP) { MCContext &Ctx = AP.OutContext; + LoongArchMCExpr::VariantKind Kind; - // TODO: Processing target flags. + switch (MO.getTargetFlags()) { + default: + llvm_unreachable("Unknown target flag on GV operand"); + case LoongArchII::MO_None: + Kind = LoongArchMCExpr::VK_LoongArch_None; + break; + case LoongArchII::MO_CALL: + Kind = LoongArchMCExpr::VK_LoongArch_CALL; + break; + case LoongArchII::MO_CALL_PLT: + Kind = LoongArchMCExpr::VK_LoongArch_CALL_PLT; + break; + case LoongArchII::MO_PCREL_HI: + Kind = LoongArchMCExpr::VK_LoongArch_PCREL_HI; + break; + case LoongArchII::MO_PCREL_LO: + Kind = LoongArchMCExpr::VK_LoongArch_PCREL_LO; + break; + // TODO: Handle more target-flags. + } const MCExpr *ME = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); @@ -35,6 +57,8 @@ ME = MCBinaryExpr::createAdd( ME, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); + if (Kind != LoongArchMCExpr::VK_LoongArch_None) + ME = LoongArchMCExpr::create(ME, Kind, Ctx); return MCOperand::createExpr(ME); } diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt --- a/llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt +++ b/llvm/lib/Target/LoongArch/MCTargetDesc/CMakeLists.txt @@ -5,8 +5,9 @@ LoongArchELFStreamer.cpp LoongArchInstPrinter.cpp LoongArchMCAsmInfo.cpp - LoongArchMCTargetDesc.cpp LoongArchMCCodeEmitter.cpp + LoongArchMCExpr.cpp + LoongArchMCTargetDesc.cpp LoongArchMatInt.cpp LoongArchTargetStreamer.cpp diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h --- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h +++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h @@ -14,6 +14,7 @@ #define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHASMBACKEND_H #include "MCTargetDesc/LoongArchBaseInfo.h" +#include "MCTargetDesc/LoongArchFixupKinds.h" #include "MCTargetDesc/LoongArchMCTargetDesc.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCFixupKindInfo.h" @@ -45,10 +46,11 @@ } unsigned getNumFixupKinds() const override { - // FIXME: Implement this when we define fixup kind - return 0; + return LoongArch::NumTargetFixupKinds; } + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; + void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const override {} diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp --- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp +++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp @@ -22,6 +22,30 @@ using namespace llvm; +const MCFixupKindInfo & +LoongArchAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { + const static MCFixupKindInfo Infos[] = { + // This table *must* be in the order that the fixup_* kinds are defined in + // LoongArchFixupKinds.h. + // + // {name, offset, bits, flags} + {"fixup_loongarch_b26", 0, 26, 0}, + {"fixup_loongarch_pcala_hi20", 5, 20, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_loongarch_pcala_lo12", 10, 12, MCFixupKindInfo::FKF_IsPCRel}, + // TODO: Add more fixup kinds. + }; + + static_assert((array_lengthof(Infos)) == LoongArch::NumTargetFixupKinds, + "Not all fixup kinds added to Infos array"); + + if (Kind < FirstTargetFixupKind) + return MCAsmBackend::getFixupKindInfo(Kind); + + assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && + "Invalid kind!"); + return Infos[Kind - FirstTargetFixupKind]; +} + void LoongArchAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h --- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h +++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h @@ -22,6 +22,19 @@ namespace llvm { +// This namespace holds all of the target specific flags that instruction info +// tracks. +namespace LoongArchII { +enum { + MO_None, + MO_CALL, + MO_CALL_PLT, + MO_PCREL_HI, + MO_PCREL_LO, + // TODO: Add more flags. +}; +} // end namespace LoongArchII + namespace LoongArchABI { enum ABI { ABI_ILP32S, diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp --- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp +++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFObjectWriter.cpp @@ -6,7 +6,9 @@ // //===----------------------------------------------------------------------===// +#include "MCTargetDesc/LoongArchFixupKinds.h" #include "MCTargetDesc/LoongArchMCTargetDesc.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCFixup.h" @@ -52,9 +54,26 @@ return Kind - FirstLiteralRelocationKind; switch (Kind) { - // TODO: Implement this when we defined fixup kind. default: + Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type"); return ELF::R_LARCH_NONE; + case FK_Data_1: + Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); + return ELF::R_LARCH_NONE; + case FK_Data_2: + Ctx.reportError(Fixup.getLoc(), "2-byte data relocations not supported"); + return ELF::R_LARCH_NONE; + case FK_Data_4: + return ELF::R_LARCH_32; + case FK_Data_8: + return ELF::R_LARCH_64; + case LoongArch::fixup_loongarch_pcala_hi20: + return ELF::R_LARCH_PCALA_HI20; + case LoongArch::fixup_loongarch_pcala_lo12: + return ELF::R_LARCH_PCALA_LO12; + case LoongArch::fixup_loongarch_b26: + return ELF::R_LARCH_B26; + // TODO: Handle more fixup-kinds. } } diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchFixupKinds.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchFixupKinds.h new file mode 100644 --- /dev/null +++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchFixupKinds.h @@ -0,0 +1,39 @@ +//===- LoongArchFixupKinds.h - LoongArch Specific Fixup Entries -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHFIXUPKINDS_H +#define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHFIXUPKINDS_H + +#include "llvm/MC/MCFixup.h" + +#undef LoongArch + +namespace llvm { +namespace LoongArch { +// +// This table *must* be in the same order of +// MCFixupKindInfo Infos[LoongArch::NumTargetFixupKinds] in +// LoongArchAsmBackend.cpp. +// +enum Fixups { + // 26-bit fixup for symbol references in the b/bl instructions. + fixup_loongarch_b26 = FirstTargetFixupKind, + // 20-bit fixup corresponding to %pc_hi20(foo) for instruction pcalau12i. + fixup_loongarch_pcala_hi20, + // 12-bit fixup corresponding to %pc_lo12(foo) for instructions addi.w/d. + fixup_loongarch_pcala_lo12, + // TODO: Add more fixup kind. + + // Used as a sentinel, must be the last. + fixup_loongarch_invalid, + NumTargetFixupKinds = fixup_loongarch_invalid - FirstTargetFixupKind +}; +} // end namespace LoongArch +} // end namespace llvm + +#endif diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp --- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp +++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp @@ -10,13 +10,16 @@ // //===----------------------------------------------------------------------===// +#include "LoongArchFixupKinds.h" #include "MCTargetDesc/LoongArchBaseInfo.h" +#include "MCTargetDesc/LoongArchMCExpr.h" #include "MCTargetDesc/LoongArchMCTargetDesc.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCInstBuilder.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/EndianStream.h" using namespace llvm; @@ -40,6 +43,10 @@ SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const override; + void expandFunctionCall(const MCInst &MI, raw_ostream &OS, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + /// TableGen'erated function for getting the binary encoding for an /// instruction. uint64_t getBinaryCodeForInstr(const MCInst &MI, @@ -68,6 +75,10 @@ unsigned getImmOpValueAsr2(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + + unsigned getExprOpValue(const MCInst &MI, const MCOperand &MO, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; }; } // end namespace @@ -82,7 +93,9 @@ if (MO.isImm()) return static_cast(MO.getImm()); - llvm_unreachable("Unhandled expression!"); + // MO must be an Expr. + assert(MO.isExpr()); + return getExprOpValue(MI, MO, Fixups, STI); } unsigned @@ -96,9 +109,62 @@ LoongArchMCCodeEmitter::getImmOpValueAsr2(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { - unsigned Res = MI.getOperand(OpNo).getImm(); - assert((Res & 3) == 0 && "lowest 2 bits are non-zero"); - return Res >> 2; + const MCOperand &MO = MI.getOperand(OpNo); + + if (MO.isImm()) { + unsigned Res = MI.getOperand(OpNo).getImm(); + assert((Res & 3) == 0 && "lowest 2 bits are non-zero"); + return Res >> 2; + } + + return getExprOpValue(MI, MO, Fixups, STI); +} + +unsigned +LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + assert(MO.isExpr() && "getExprOpValue expects only expressions"); + const MCExpr *Expr = MO.getExpr(); + MCExpr::ExprKind Kind = Expr->getKind(); + LoongArch::Fixups FixupKind = LoongArch::fixup_loongarch_invalid; + if (Kind == MCExpr::Target) { + const LoongArchMCExpr *LAExpr = cast(Expr); + + switch (LAExpr->getKind()) { + case LoongArchMCExpr::VK_LoongArch_None: + case LoongArchMCExpr::VK_LoongArch_Invalid: + llvm_unreachable("Unhandled fixup kind!"); + case LoongArchMCExpr::VK_LoongArch_PCREL_HI: + FixupKind = LoongArch::fixup_loongarch_pcala_hi20; + break; + case LoongArchMCExpr::VK_LoongArch_PCREL_LO: + FixupKind = LoongArch::fixup_loongarch_pcala_lo12; + break; + case LoongArchMCExpr::VK_LoongArch_CALL: + case LoongArchMCExpr::VK_LoongArch_CALL_PLT: + FixupKind = LoongArch::fixup_loongarch_b26; + break; + } + } + + assert(FixupKind != LoongArch::fixup_loongarch_invalid && + "Unhandled expression!"); + + Fixups.push_back( + MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc())); + return 0; +} + +void LoongArchMCCodeEmitter::expandFunctionCall( + const MCInst &MI, raw_ostream &OS, SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + MCOperand Func = MI.getOperand(0); + MCInst TmpInst = Func.isExpr() + ? MCInstBuilder(LoongArch::BL).addExpr(Func.getExpr()) + : MCInstBuilder(LoongArch::BL).addImm(Func.getImm()); + uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); + support::endian::write(OS, Binary, support::little); } void LoongArchMCCodeEmitter::encodeInstruction( @@ -108,6 +174,9 @@ // Get byte count of instruction. unsigned Size = Desc.getSize(); + if (MI.getOpcode() == LoongArch::PseudoCALL) + return expandFunctionCall(MI, OS, Fixups, STI); + switch (Size) { default: llvm_unreachable("Unhandled encodeInstruction length!"); diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h new file mode 100644 --- /dev/null +++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h @@ -0,0 +1,69 @@ +//= LoongArchMCExpr.h - LoongArch specific MC expression classes -*- C++ -*-==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file describes LoongArch-specific MCExprs, used for modifiers like +// "%pc_hi20" or "%pc_lo12" etc. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCEXPR_H +#define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCEXPR_H + +#include "llvm/MC/MCExpr.h" + +namespace llvm { + +class StringRef; + +class LoongArchMCExpr : public MCTargetExpr { +public: + enum VariantKind { + // TODO: Add more target kinds. + VK_LoongArch_None, + VK_LoongArch_CALL, + VK_LoongArch_CALL_PLT, + VK_LoongArch_PCREL_HI, + VK_LoongArch_PCREL_LO, + VK_LoongArch_Invalid // Must be the last item. + }; + +private: + const MCExpr *Expr; + const VariantKind Kind; + + explicit LoongArchMCExpr(const MCExpr *Expr, VariantKind Kind) + : Expr(Expr), Kind(Kind) {} + +public: + static const LoongArchMCExpr *create(const MCExpr *Expr, VariantKind Kind, + MCContext &Ctx); + + VariantKind getKind() const { return Kind; } + const MCExpr *getSubExpr() const { return Expr; } + + void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override; + bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, + const MCFixup *Fixup) const override; + void visitUsedExpr(MCStreamer &Streamer) const override; + MCFragment *findAssociatedFragment() const override { + return getSubExpr()->findAssociatedFragment(); + } + + void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override {} + + static bool classof(const MCExpr *E) { + return E->getKind() == MCExpr::Target; + } + + static StringRef getVariantKindName(VariantKind Kind); + static VariantKind getVariantKindForName(StringRef name); +}; + +} // end namespace llvm + +#endif diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp @@ -0,0 +1,82 @@ +//===-- LoongArchMCExpr.cpp - LoongArch specific MC expression classes ----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the implementation of the assembly expression modifiers +// accepted by the LoongArch architecture. +// +//===----------------------------------------------------------------------===// + +#include "LoongArchMCExpr.h" +#include "LoongArchAsmBackend.h" +#include "LoongArchFixupKinds.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCValue.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace llvm; + +#define DEBUG_TYPE "loongarch-mcexpr" + +const LoongArchMCExpr * +LoongArchMCExpr::create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx) { + return new (Ctx) LoongArchMCExpr(Expr, Kind); +} + +void LoongArchMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { + VariantKind Kind = getKind(); + bool HasVariant = + ((Kind != VK_LoongArch_None) && (Kind != VK_LoongArch_CALL)); + + if (HasVariant) + OS << '%' << getVariantKindName(getKind()) << '('; + Expr->print(OS, MAI); + if (HasVariant) + OS << ')'; +} + +bool LoongArchMCExpr::evaluateAsRelocatableImpl(MCValue &Res, + const MCAsmLayout *Layout, + const MCFixup *Fixup) const { + // Explicitly drop the layout and assembler to prevent any symbolic folding in + // the expression handling. This is required to preserve symbolic difference + // expressions to emit the paired relocations. + if (!getSubExpr()->evaluateAsRelocatable(Res, nullptr, nullptr)) + return false; + + Res = + MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind()); + // Custom fixup types are not valid with symbol difference expressions. + return Res.getSymB() ? getKind() == VK_LoongArch_None : true; +} + +void LoongArchMCExpr::visitUsedExpr(MCStreamer &Streamer) const { + Streamer.visitUsedExpr(*getSubExpr()); +} + +StringRef LoongArchMCExpr::getVariantKindName(VariantKind Kind) { + switch (Kind) { + default: + llvm_unreachable("Invalid ELF symbol kind"); + case VK_LoongArch_CALL_PLT: + return "plt"; + case VK_LoongArch_PCREL_HI: + return "pc_hi20"; + case VK_LoongArch_PCREL_LO: + return "pc_lo12"; + } +} + +LoongArchMCExpr::VariantKind +LoongArchMCExpr::getVariantKindForName(StringRef name) { + return StringSwitch(name) + .Case("pc_hi20", VK_LoongArch_PCREL_HI) + .Case("pc_lo12", VK_LoongArch_PCREL_LO) + .Case("plt", VK_LoongArch_CALL_PLT) + .Default(VK_LoongArch_Invalid); +} diff --git a/llvm/test/CodeGen/LoongArch/analyze-branch.ll b/llvm/test/CodeGen/LoongArch/analyze-branch.ll --- a/llvm/test/CodeGen/LoongArch/analyze-branch.ll +++ b/llvm/test/CodeGen/LoongArch/analyze-branch.ll @@ -19,13 +19,13 @@ ; CHECK-NEXT: ori $a1, $zero, 42 ; CHECK-NEXT: bne $a0, $a1, .LBB0_3 ; CHECK-NEXT: # %bb.1: # %true -; CHECK-NEXT: bl test_true +; CHECK-NEXT: bl %plt(test_true) ; CHECK-NEXT: .LBB0_2: # %true ; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; CHECK-NEXT: addi.d $sp, $sp, 16 ; CHECK-NEXT: ret ; CHECK-NEXT: .LBB0_3: # %false -; CHECK-NEXT: bl test_false +; CHECK-NEXT: bl %plt(test_false) ; CHECK-NEXT: b .LBB0_2 %tst = icmp eq i64 %in, 42 br i1 %tst, label %true, label %false, !prof !0 @@ -51,13 +51,13 @@ ; CHECK-NEXT: ori $a1, $zero, 42 ; CHECK-NEXT: beq $a0, $a1, .LBB1_1 ; CHECK-NEXT: # %bb.3: # %false -; CHECK-NEXT: bl test_false +; CHECK-NEXT: bl %plt(test_false) ; CHECK-NEXT: .LBB1_2: # %true ; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; CHECK-NEXT: addi.d $sp, $sp, 16 ; CHECK-NEXT: ret ; CHECK-NEXT: .LBB1_1: # %true -; CHECK-NEXT: bl test_true +; CHECK-NEXT: bl %plt(test_true) ; CHECK-NEXT: b .LBB1_2 %tst = icmp eq i64 %in, 42 br i1 %tst, label %true, label %false, !prof !1 diff --git a/llvm/test/CodeGen/LoongArch/bnez-beqz.ll b/llvm/test/CodeGen/LoongArch/bnez-beqz.ll --- a/llvm/test/CodeGen/LoongArch/bnez-beqz.ll +++ b/llvm/test/CodeGen/LoongArch/bnez-beqz.ll @@ -11,7 +11,7 @@ ; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill ; LA32-NEXT: bnez $a0, .LBB0_2 ; LA32-NEXT: # %bb.1: # %t -; LA32-NEXT: bl bar +; LA32-NEXT: bl %plt(bar) ; LA32-NEXT: .LBB0_2: # %f ; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-NEXT: addi.w $sp, $sp, 16 @@ -23,7 +23,7 @@ ; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill ; LA64-NEXT: bnez $a0, .LBB0_2 ; LA64-NEXT: # %bb.1: # %t -; LA64-NEXT: bl bar +; LA64-NEXT: bl %plt(bar) ; LA64-NEXT: .LBB0_2: # %f ; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; LA64-NEXT: addi.d $sp, $sp, 16 @@ -47,7 +47,7 @@ ; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill ; LA32-NEXT: beqz $a0, .LBB1_2 ; LA32-NEXT: # %bb.1: # %t -; LA32-NEXT: bl bar +; LA32-NEXT: bl %plt(bar) ; LA32-NEXT: .LBB1_2: # %f ; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-NEXT: addi.w $sp, $sp, 16 @@ -59,7 +59,7 @@ ; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill ; LA64-NEXT: beqz $a0, .LBB1_2 ; LA64-NEXT: # %bb.1: # %t -; LA64-NEXT: bl bar +; LA64-NEXT: bl %plt(bar) ; LA64-NEXT: .LBB1_2: # %f ; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; LA64-NEXT: addi.d $sp, $sp, 16 @@ -84,7 +84,7 @@ ; LA32-NEXT: or $a0, $a0, $a1 ; LA32-NEXT: bnez $a0, .LBB2_2 ; LA32-NEXT: # %bb.1: # %t -; LA32-NEXT: bl bar +; LA32-NEXT: bl %plt(bar) ; LA32-NEXT: .LBB2_2: # %f ; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-NEXT: addi.w $sp, $sp, 16 @@ -96,7 +96,7 @@ ; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill ; LA64-NEXT: bnez $a0, .LBB2_2 ; LA64-NEXT: # %bb.1: # %t -; LA64-NEXT: bl bar +; LA64-NEXT: bl %plt(bar) ; LA64-NEXT: .LBB2_2: # %f ; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; LA64-NEXT: addi.d $sp, $sp, 16 @@ -121,7 +121,7 @@ ; LA32-NEXT: or $a0, $a0, $a1 ; LA32-NEXT: beqz $a0, .LBB3_2 ; LA32-NEXT: # %bb.1: # %t -; LA32-NEXT: bl bar +; LA32-NEXT: bl %plt(bar) ; LA32-NEXT: .LBB3_2: # %f ; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-NEXT: addi.w $sp, $sp, 16 @@ -133,7 +133,7 @@ ; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill ; LA64-NEXT: beqz $a0, .LBB3_2 ; LA64-NEXT: # %bb.1: # %t -; LA64-NEXT: bl bar +; LA64-NEXT: bl %plt(bar) ; LA64-NEXT: .LBB3_2: # %f ; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; LA64-NEXT: addi.d $sp, $sp, 16 diff --git a/llvm/test/CodeGen/LoongArch/calling-conv-lp64d.ll b/llvm/test/CodeGen/LoongArch/calling-conv-lp64d.ll --- a/llvm/test/CodeGen/LoongArch/calling-conv-lp64d.ll +++ b/llvm/test/CodeGen/LoongArch/calling-conv-lp64d.ll @@ -21,7 +21,7 @@ ; CHECK-NEXT: ori $a0, $zero, 1 ; CHECK-NEXT: ori $a1, $zero, 2 ; CHECK-NEXT: move $a2, $zero -; CHECK-NEXT: bl callee_i128_in_regs +; CHECK-NEXT: bl %plt(callee_i128_in_regs) ; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; CHECK-NEXT: addi.d $sp, $sp, 16 ; CHECK-NEXT: ret @@ -79,7 +79,7 @@ ; CHECK-NEXT: ori $a6, $zero, 6 ; CHECK-NEXT: ori $a7, $zero, 7 ; CHECK-NEXT: move $a5, $zero -; CHECK-NEXT: bl callee_many_scalars +; CHECK-NEXT: bl %plt(callee_many_scalars) ; CHECK-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload ; CHECK-NEXT: addi.d $sp, $sp, 32 ; CHECK-NEXT: ret @@ -131,7 +131,7 @@ ; CHECK-NEXT: st.d $a0, $sp, 32 ; CHECK-NEXT: addi.d $a0, $sp, 32 ; CHECK-NEXT: addi.d $a1, $sp, 0 -; CHECK-NEXT: bl callee_large_scalars +; CHECK-NEXT: bl %plt(callee_large_scalars) ; CHECK-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload ; CHECK-NEXT: addi.d $sp, $sp, 80 ; CHECK-NEXT: ret @@ -196,7 +196,7 @@ ; CHECK-NEXT: ori $a5, $zero, 6 ; CHECK-NEXT: ori $a6, $zero, 7 ; CHECK-NEXT: addi.d $a7, $sp, 48 -; CHECK-NEXT: bl callee_large_scalars_exhausted_regs +; CHECK-NEXT: bl %plt(callee_large_scalars_exhausted_regs) ; CHECK-NEXT: ld.d $ra, $sp, 88 # 8-byte Folded Reload ; CHECK-NEXT: addi.d $sp, $sp, 96 ; CHECK-NEXT: ret @@ -243,7 +243,7 @@ ; CHECK-NEXT: st.d $a0, $sp, 64 ; CHECK-NEXT: st.d $a0, $sp, 32 ; CHECK-NEXT: addi.d $a0, $sp, 8 -; CHECK-NEXT: bl callee_large_struct +; CHECK-NEXT: bl %plt(callee_large_struct) ; CHECK-NEXT: ld.d $ra, $sp, 72 # 8-byte Folded Reload ; CHECK-NEXT: addi.d $sp, $sp, 80 ; CHECK-NEXT: ret @@ -276,7 +276,7 @@ ; CHECK: # %bb.0: ; CHECK-NEXT: addi.d $sp, $sp, -16 ; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill -; CHECK-NEXT: bl callee_small_scalar_ret +; CHECK-NEXT: bl %plt(callee_small_scalar_ret) ; CHECK-NEXT: addi.w $a2, $zero, -2 ; CHECK-NEXT: xor $a0, $a0, $a2 ; CHECK-NEXT: orn $a0, $a0, $a1 @@ -308,7 +308,7 @@ ; CHECK: # %bb.0: ; CHECK-NEXT: addi.d $sp, $sp, -16 ; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill -; CHECK-NEXT: bl callee_small_struct_ret +; CHECK-NEXT: bl %plt(callee_small_struct_ret) ; CHECK-NEXT: add.d $a0, $a0, $a1 ; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; CHECK-NEXT: addi.d $sp, $sp, 16 @@ -343,7 +343,7 @@ ; CHECK-NEXT: addi.d $sp, $sp, -48 ; CHECK-NEXT: st.d $ra, $sp, 40 # 8-byte Folded Spill ; CHECK-NEXT: addi.d $a0, $sp, 0 -; CHECK-NEXT: bl callee_large_scalar_ret +; CHECK-NEXT: bl %plt(callee_large_scalar_ret) ; CHECK-NEXT: ld.d $ra, $sp, 40 # 8-byte Folded Reload ; CHECK-NEXT: addi.d $sp, $sp, 48 ; CHECK-NEXT: ret @@ -386,7 +386,7 @@ ; CHECK-NEXT: addi.d $sp, $sp, -48 ; CHECK-NEXT: st.d $ra, $sp, 40 # 8-byte Folded Spill ; CHECK-NEXT: addi.d $a0, $sp, 8 -; CHECK-NEXT: bl callee_large_struct_ret +; CHECK-NEXT: bl %plt(callee_large_struct_ret) ; CHECK-NEXT: ld.d $a0, $sp, 32 ; CHECK-NEXT: ld.d $a1, $sp, 8 ; CHECK-NEXT: add.d $a0, $a1, $a0 @@ -430,7 +430,7 @@ ; CHECK-NEXT: ori $a0, $zero, 1 ; CHECK-NEXT: movgr2fr.w $fa0, $zero ; CHECK-NEXT: movgr2fr.d $fa1, $zero -; CHECK-NEXT: bl callee_float_in_fpr +; CHECK-NEXT: bl %plt(callee_float_in_fpr) ; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; CHECK-NEXT: addi.d $sp, $sp, 16 ; CHECK-NEXT: ret @@ -489,7 +489,7 @@ ; CHECK-NEXT: ori $a0, $zero, 0 ; CHECK-NEXT: lu32i.d $a0, 131072 ; CHECK-NEXT: lu52i.d $a0, $a0, 1026 -; CHECK-NEXT: bl callee_double_in_gpr_exhausted_fprs +; CHECK-NEXT: bl %plt(callee_double_in_gpr_exhausted_fprs) ; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; CHECK-NEXT: addi.d $sp, $sp, 16 ; CHECK-NEXT: ret @@ -516,7 +516,7 @@ ; CHECK: # %bb.0: ; CHECK-NEXT: addi.d $sp, $sp, -16 ; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill -; CHECK-NEXT: bl callee_double_ret +; CHECK-NEXT: bl %plt(callee_double_ret) ; CHECK-NEXT: movfr2gr.d $a0, $fa0 ; CHECK-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; CHECK-NEXT: addi.d $sp, $sp, 16 diff --git a/llvm/test/CodeGen/LoongArch/eh-dwarf-cfa.ll b/llvm/test/CodeGen/LoongArch/eh-dwarf-cfa.ll --- a/llvm/test/CodeGen/LoongArch/eh-dwarf-cfa.ll +++ b/llvm/test/CodeGen/LoongArch/eh-dwarf-cfa.ll @@ -10,7 +10,7 @@ ; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill ; LA32-NEXT: .cfi_offset 1, -4 ; LA32-NEXT: addi.w $a0, $sp, 16 -; LA32-NEXT: bl foo +; LA32-NEXT: bl %plt(foo) ; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-NEXT: addi.w $sp, $sp, 16 ; LA32-NEXT: ret @@ -22,7 +22,7 @@ ; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill ; LA64-NEXT: .cfi_offset 1, -8 ; LA64-NEXT: addi.d $a0, $sp, 16 -; LA64-NEXT: bl foo +; LA64-NEXT: bl %plt(foo) ; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; LA64-NEXT: addi.d $sp, $sp, 16 ; LA64-NEXT: ret diff --git a/llvm/test/CodeGen/LoongArch/frame.ll b/llvm/test/CodeGen/LoongArch/frame.ll --- a/llvm/test/CodeGen/LoongArch/frame.ll +++ b/llvm/test/CodeGen/LoongArch/frame.ll @@ -12,7 +12,7 @@ ; CHECK-NEXT: st.d $zero, $sp, 8 ; CHECK-NEXT: st.d $zero, $sp, 0 ; CHECK-NEXT: addi.d $a0, $sp, 4 -; CHECK-NEXT: bl test1 +; CHECK-NEXT: bl %plt(test1) ; CHECK-NEXT: move $a0, $zero ; CHECK-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload ; CHECK-NEXT: addi.d $sp, $sp, 32 diff --git a/llvm/test/CodeGen/LoongArch/fsqrt.ll b/llvm/test/CodeGen/LoongArch/fsqrt.ll --- a/llvm/test/CodeGen/LoongArch/fsqrt.ll +++ b/llvm/test/CodeGen/LoongArch/fsqrt.ll @@ -36,7 +36,7 @@ ; LA32F: # %bb.0: ; LA32F-NEXT: addi.w $sp, $sp, -16 ; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill -; LA32F-NEXT: bl sqrt +; LA32F-NEXT: bl %plt(sqrt) ; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32F-NEXT: addi.w $sp, $sp, 16 ; LA32F-NEXT: ret @@ -50,7 +50,7 @@ ; LA64F: # %bb.0: ; LA64F-NEXT: addi.d $sp, $sp, -16 ; LA64F-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill -; LA64F-NEXT: bl sqrt +; LA64F-NEXT: bl %plt(sqrt) ; LA64F-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; LA64F-NEXT: addi.d $sp, $sp, 16 ; LA64F-NEXT: ret @@ -93,12 +93,12 @@ ; LA32F: # %bb.0: ; LA32F-NEXT: addi.w $sp, $sp, -16 ; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill -; LA32F-NEXT: bl sqrt +; LA32F-NEXT: bl %plt(sqrt) ; LA32F-NEXT: move $a2, $a0 ; LA32F-NEXT: move $a3, $a1 ; LA32F-NEXT: lu12i.w $a1, 261888 ; LA32F-NEXT: move $a0, $zero -; LA32F-NEXT: bl __divdf3 +; LA32F-NEXT: bl %plt(__divdf3) ; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32F-NEXT: addi.w $sp, $sp, 16 ; LA32F-NEXT: ret @@ -112,10 +112,10 @@ ; LA64F: # %bb.0: ; LA64F-NEXT: addi.d $sp, $sp, -16 ; LA64F-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill -; LA64F-NEXT: bl sqrt +; LA64F-NEXT: bl %plt(sqrt) ; LA64F-NEXT: move $a1, $a0 ; LA64F-NEXT: lu52i.d $a0, $zero, 1023 -; LA64F-NEXT: bl __divdf3 +; LA64F-NEXT: bl %plt(__divdf3) ; LA64F-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; LA64F-NEXT: addi.d $sp, $sp, 16 ; LA64F-NEXT: ret diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/call.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/call.ll --- a/llvm/test/CodeGen/LoongArch/ir-instruction/call.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/call.ll @@ -9,7 +9,7 @@ ; LA32: # %bb.0: ; LA32-NEXT: addi.w $sp, $sp, -16 ; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill -; LA32-NEXT: bl external_function +; LA32-NEXT: bl %plt(external_function) ; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-NEXT: addi.w $sp, $sp, 16 ; LA32-NEXT: ret @@ -18,7 +18,7 @@ ; LA64: # %bb.0: ; LA64-NEXT: addi.d $sp, $sp, -16 ; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill -; LA64-NEXT: bl external_function +; LA64-NEXT: bl %plt(external_function) ; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; LA64-NEXT: addi.d $sp, $sp, 16 ; LA64-NEXT: ret @@ -45,7 +45,7 @@ ; LA32: # %bb.0: ; LA32-NEXT: addi.w $sp, $sp, -16 ; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill -; LA32-NEXT: bl defined_function +; LA32-NEXT: bl %plt(defined_function) ; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-NEXT: addi.w $sp, $sp, 16 ; LA32-NEXT: ret @@ -54,7 +54,7 @@ ; LA64: # %bb.0: ; LA64-NEXT: addi.d $sp, $sp, -16 ; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill -; LA64-NEXT: bl defined_function +; LA64-NEXT: bl %plt(defined_function) ; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; LA64-NEXT: addi.d $sp, $sp, 16 ; LA64-NEXT: ret diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll --- a/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll @@ -83,7 +83,7 @@ ; LA32: # %bb.0: ; LA32-NEXT: addi.w $sp, $sp, -16 ; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill -; LA32-NEXT: bl __floatdidf +; LA32-NEXT: bl %plt(__floatdidf) ; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-NEXT: addi.w $sp, $sp, 16 ; LA32-NEXT: ret @@ -147,7 +147,7 @@ ; LA32: # %bb.0: ; LA32-NEXT: addi.w $sp, $sp, -16 ; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill -; LA32-NEXT: bl __fixdfdi +; LA32-NEXT: bl %plt(__fixdfdi) ; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-NEXT: addi.w $sp, $sp, 16 ; LA32-NEXT: ret @@ -166,7 +166,7 @@ ; LA32: # %bb.0: ; LA32-NEXT: addi.w $sp, $sp, -16 ; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill -; LA32-NEXT: bl __fixunsdfdi +; LA32-NEXT: bl %plt(__fixunsdfdi) ; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-NEXT: addi.w $sp, $sp, 16 ; LA32-NEXT: ret @@ -262,7 +262,7 @@ ; LA32: # %bb.0: ; LA32-NEXT: addi.w $sp, $sp, -16 ; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill -; LA32-NEXT: bl __floatundidf +; LA32-NEXT: bl %plt(__floatundidf) ; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-NEXT: addi.w $sp, $sp, 16 ; LA32-NEXT: ret diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll --- a/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll @@ -93,7 +93,7 @@ ; LA32F: # %bb.0: ; LA32F-NEXT: addi.w $sp, $sp, -16 ; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill -; LA32F-NEXT: bl __fixsfdi +; LA32F-NEXT: bl %plt(__fixsfdi) ; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32F-NEXT: addi.w $sp, $sp, 16 ; LA32F-NEXT: ret @@ -102,7 +102,7 @@ ; LA32D: # %bb.0: ; LA32D-NEXT: addi.w $sp, $sp, -16 ; LA32D-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill -; LA32D-NEXT: bl __fixsfdi +; LA32D-NEXT: bl %plt(__fixsfdi) ; LA32D-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32D-NEXT: addi.w $sp, $sp, 16 ; LA32D-NEXT: ret @@ -250,7 +250,7 @@ ; LA32F: # %bb.0: ; LA32F-NEXT: addi.w $sp, $sp, -16 ; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill -; LA32F-NEXT: bl __fixunssfdi +; LA32F-NEXT: bl %plt(__fixunssfdi) ; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32F-NEXT: addi.w $sp, $sp, 16 ; LA32F-NEXT: ret @@ -259,7 +259,7 @@ ; LA32D: # %bb.0: ; LA32D-NEXT: addi.w $sp, $sp, -16 ; LA32D-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill -; LA32D-NEXT: bl __fixunssfdi +; LA32D-NEXT: bl %plt(__fixunssfdi) ; LA32D-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32D-NEXT: addi.w $sp, $sp, 16 ; LA32D-NEXT: ret @@ -396,7 +396,7 @@ ; LA32F: # %bb.0: ; LA32F-NEXT: addi.w $sp, $sp, -16 ; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill -; LA32F-NEXT: bl __floatdisf +; LA32F-NEXT: bl %plt(__floatdisf) ; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32F-NEXT: addi.w $sp, $sp, 16 ; LA32F-NEXT: ret @@ -405,7 +405,7 @@ ; LA32D: # %bb.0: ; LA32D-NEXT: addi.w $sp, $sp, -16 ; LA32D-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill -; LA32D-NEXT: bl __floatdisf +; LA32D-NEXT: bl %plt(__floatdisf) ; LA32D-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32D-NEXT: addi.w $sp, $sp, 16 ; LA32D-NEXT: ret @@ -552,7 +552,7 @@ ; LA32F: # %bb.0: ; LA32F-NEXT: addi.w $sp, $sp, -16 ; LA32F-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill -; LA32F-NEXT: bl __floatundisf +; LA32F-NEXT: bl %plt(__floatundisf) ; LA32F-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32F-NEXT: addi.w $sp, $sp, 16 ; LA32F-NEXT: ret @@ -561,7 +561,7 @@ ; LA32D: # %bb.0: ; LA32D-NEXT: addi.w $sp, $sp, -16 ; LA32D-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill -; LA32D-NEXT: bl __floatundisf +; LA32D-NEXT: bl %plt(__floatundisf) ; LA32D-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32D-NEXT: addi.w $sp, $sp, 16 ; LA32D-NEXT: ret diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store-atomic.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/load-store-atomic.ll --- a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store-atomic.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/load-store-atomic.ll @@ -58,7 +58,7 @@ ; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill ; LA32-NEXT: .cfi_offset 1, -4 ; LA32-NEXT: ori $a1, $zero, 2 -; LA32-NEXT: bl __atomic_load_8 +; LA32-NEXT: bl %plt(__atomic_load_8) ; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-NEXT: addi.w $sp, $sp, 16 ; LA32-NEXT: ret @@ -128,7 +128,7 @@ ; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill ; LA32-NEXT: .cfi_offset 1, -4 ; LA32-NEXT: ori $a3, $zero, 3 -; LA32-NEXT: bl __atomic_store_8 +; LA32-NEXT: bl %plt(__atomic_store_8) ; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-NEXT: addi.w $sp, $sp, 16 ; LA32-NEXT: ret diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll --- a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll @@ -11,18 +11,18 @@ ; ALL-LABEL: load_store_global: ; ALL: # %bb.0: -; LA32NOPIC-NEXT: pcalau12i $a0, G -; LA32NOPIC-NEXT: addi.w $a1, $a0, G -; LA32PIC-NEXT: pcalau12i $a0, .LG$local -; LA32PIC-NEXT: addi.w $a1, $a0, .LG$local +; LA32NOPIC-NEXT: pcalau12i $a0, %pc_hi20(G) +; LA32NOPIC-NEXT: addi.w $a1, $a0, %pc_lo12(G) +; LA32PIC-NEXT: pcalau12i $a0, %pc_hi20(.LG$local) +; LA32PIC-NEXT: addi.w $a1, $a0, %pc_lo12(.LG$local) ; LA32-NEXT: ld.w $a0, $a1, 0 ; LA32-NEXT: addi.w $a0, $a0, 1 ; LA32-NEXT: st.w $a0, $a1, 0 -; LA64NOPIC-NEXT: pcalau12i $a0, G -; LA64NOPIC-NEXT: addi.d $a1, $a0, G -; LA64PIC-NEXT: pcalau12i $a0, .LG$local -; LA64PIC-NEXT: addi.d $a1, $a0, .LG$local +; LA64NOPIC-NEXT: pcalau12i $a0, %pc_hi20(G) +; LA64NOPIC-NEXT: addi.d $a1, $a0, %pc_lo12(G) +; LA64PIC-NEXT: pcalau12i $a0, %pc_hi20(.LG$local) +; LA64PIC-NEXT: addi.d $a1, $a0, %pc_lo12(.LG$local) ; LA64-NEXT: ld.w $a0, $a1, 0 ; LA64-NEXT: addi.d $a0, $a0, 1 ; LA64-NEXT: st.w $a0, $a1, 0 @@ -39,10 +39,10 @@ ; ALL-LABEL: load_store_global_array: ; ALL: # %bb.0: -; LA32NOPIC-NEXT: pcalau12i $a1, arr -; LA32NOPIC-NEXT: addi.w $a2, $a1, arr -; LA32PIC-NEXT: pcalau12i $a1, .Larr$local -; LA32PIC-NEXT: addi.w $a2, $a1, .Larr$local +; LA32NOPIC-NEXT: pcalau12i $a1, %pc_hi20(arr) +; LA32NOPIC-NEXT: addi.w $a2, $a1, %pc_lo12(arr) +; LA32PIC-NEXT: pcalau12i $a1, %pc_hi20(.Larr$local) +; LA32PIC-NEXT: addi.w $a2, $a1, %pc_lo12(.Larr$local) ; LA32-NEXT: ld.w $a1, $a2, 0 ; LA32-NEXT: st.w $a0, $a2, 0 ; LA32NOPIC-NEXT: ld.w $a3, $a2, 36 @@ -50,10 +50,10 @@ ; LA32PIC-NEXT: ld.w $a3, $a2, 36 ; LA32PIC-NEXT: st.w $a0, $a2, 36 -; LA64NOPIC-NEXT: pcalau12i $a1, arr -; LA64NOPIC-NEXT: addi.d $a2, $a1, arr -; LA64PIC-NEXT: pcalau12i $a1, .Larr$local -; LA64PIC-NEXT: addi.d $a2, $a1, .Larr$local +; LA64NOPIC-NEXT: pcalau12i $a1, %pc_hi20(arr) +; LA64NOPIC-NEXT: addi.d $a2, $a1, %pc_lo12(arr) +; LA64PIC-NEXT: pcalau12i $a1, %pc_hi20(.Larr$local) +; LA64PIC-NEXT: addi.d $a2, $a1, %pc_lo12(.Larr$local) ; LA64-NEXT: ld.w $a1, $a2, 0 ; LA64-NEXT: st.w $a0, $a2, 0 ; LA64NOPIC-NEXT: ld.w $a3, $a2, 36 diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem.ll --- a/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem.ll @@ -155,7 +155,7 @@ ; LA32-NEXT: .cfi_def_cfa_offset 16 ; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill ; LA32-NEXT: .cfi_offset 1, -4 -; LA32-NEXT: bl __divdi3 +; LA32-NEXT: bl %plt(__divdi3) ; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-NEXT: addi.w $sp, $sp, 16 ; LA32-NEXT: ret @@ -171,7 +171,7 @@ ; LA32-TRAP-NEXT: .cfi_def_cfa_offset 16 ; LA32-TRAP-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill ; LA32-TRAP-NEXT: .cfi_offset 1, -4 -; LA32-TRAP-NEXT: bl __divdi3 +; LA32-TRAP-NEXT: bl %plt(__divdi3) ; LA32-TRAP-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-TRAP-NEXT: addi.w $sp, $sp, 16 ; LA32-TRAP-NEXT: ret @@ -336,7 +336,7 @@ ; LA32-NEXT: .cfi_def_cfa_offset 16 ; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill ; LA32-NEXT: .cfi_offset 1, -4 -; LA32-NEXT: bl __udivdi3 +; LA32-NEXT: bl %plt(__udivdi3) ; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-NEXT: addi.w $sp, $sp, 16 ; LA32-NEXT: ret @@ -352,7 +352,7 @@ ; LA32-TRAP-NEXT: .cfi_def_cfa_offset 16 ; LA32-TRAP-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill ; LA32-TRAP-NEXT: .cfi_offset 1, -4 -; LA32-TRAP-NEXT: bl __udivdi3 +; LA32-TRAP-NEXT: bl %plt(__udivdi3) ; LA32-TRAP-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-TRAP-NEXT: addi.w $sp, $sp, 16 ; LA32-TRAP-NEXT: ret @@ -521,7 +521,7 @@ ; LA32-NEXT: .cfi_def_cfa_offset 16 ; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill ; LA32-NEXT: .cfi_offset 1, -4 -; LA32-NEXT: bl __moddi3 +; LA32-NEXT: bl %plt(__moddi3) ; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-NEXT: addi.w $sp, $sp, 16 ; LA32-NEXT: ret @@ -537,7 +537,7 @@ ; LA32-TRAP-NEXT: .cfi_def_cfa_offset 16 ; LA32-TRAP-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill ; LA32-TRAP-NEXT: .cfi_offset 1, -4 -; LA32-TRAP-NEXT: bl __moddi3 +; LA32-TRAP-NEXT: bl %plt(__moddi3) ; LA32-TRAP-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-TRAP-NEXT: addi.w $sp, $sp, 16 ; LA32-TRAP-NEXT: ret @@ -706,7 +706,7 @@ ; LA32-NEXT: .cfi_def_cfa_offset 16 ; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill ; LA32-NEXT: .cfi_offset 1, -4 -; LA32-NEXT: bl __umoddi3 +; LA32-NEXT: bl %plt(__umoddi3) ; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-NEXT: addi.w $sp, $sp, 16 ; LA32-NEXT: ret @@ -722,7 +722,7 @@ ; LA32-TRAP-NEXT: .cfi_def_cfa_offset 16 ; LA32-TRAP-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill ; LA32-TRAP-NEXT: .cfi_offset 1, -4 -; LA32-TRAP-NEXT: bl __umoddi3 +; LA32-TRAP-NEXT: bl %plt(__umoddi3) ; LA32-TRAP-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload ; LA32-TRAP-NEXT: addi.w $sp, $sp, 16 ; LA32-TRAP-NEXT: ret diff --git a/llvm/test/CodeGen/LoongArch/vararg.ll b/llvm/test/CodeGen/LoongArch/vararg.ll --- a/llvm/test/CodeGen/LoongArch/vararg.ll +++ b/llvm/test/CodeGen/LoongArch/vararg.ll @@ -132,7 +132,7 @@ ; LA64-FPELIM-NEXT: st.d $s0, $fp, 8 ; LA64-FPELIM-NEXT: sub.d $a0, $sp, $a0 ; LA64-FPELIM-NEXT: move $sp, $a0 -; LA64-FPELIM-NEXT: bl notdead +; LA64-FPELIM-NEXT: bl %plt(notdead) ; LA64-FPELIM-NEXT: move $a0, $s0 ; LA64-FPELIM-NEXT: addi.d $sp, $fp, -32 ; LA64-FPELIM-NEXT: ld.d $s0, $sp, 8 # 8-byte Folded Reload @@ -163,7 +163,7 @@ ; LA64-WITHFP-NEXT: st.d $s0, $fp, 8 ; LA64-WITHFP-NEXT: sub.d $a0, $sp, $a0 ; LA64-WITHFP-NEXT: move $sp, $a0 -; LA64-WITHFP-NEXT: bl notdead +; LA64-WITHFP-NEXT: bl %plt(notdead) ; LA64-WITHFP-NEXT: move $a0, $s0 ; LA64-WITHFP-NEXT: addi.d $sp, $fp, -32 ; LA64-WITHFP-NEXT: ld.d $s0, $sp, 8 # 8-byte Folded Reload @@ -187,7 +187,7 @@ ; LA64-FPELIM-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill ; LA64-FPELIM-NEXT: lu52i.d $a1, $zero, 1023 ; LA64-FPELIM-NEXT: ori $a2, $zero, 2 -; LA64-FPELIM-NEXT: bl va1 +; LA64-FPELIM-NEXT: bl %plt(va1) ; LA64-FPELIM-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; LA64-FPELIM-NEXT: addi.d $sp, $sp, 16 ; LA64-FPELIM-NEXT: ret @@ -200,7 +200,7 @@ ; LA64-WITHFP-NEXT: addi.d $fp, $sp, 16 ; LA64-WITHFP-NEXT: lu52i.d $a1, $zero, 1023 ; LA64-WITHFP-NEXT: ori $a2, $zero, 2 -; LA64-WITHFP-NEXT: bl va1 +; LA64-WITHFP-NEXT: bl %plt(va1) ; LA64-WITHFP-NEXT: ld.d $fp, $sp, 0 # 8-byte Folded Reload ; LA64-WITHFP-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; LA64-WITHFP-NEXT: addi.d $sp, $sp, 16 @@ -230,7 +230,7 @@ ; LA64-FPELIM-NEXT: ori $a0, $zero, 2 ; LA64-FPELIM-NEXT: ori $a1, $zero, 1111 ; LA64-FPELIM-NEXT: move $a2, $zero -; LA64-FPELIM-NEXT: bl va_aligned_register +; LA64-FPELIM-NEXT: bl %plt(va_aligned_register) ; LA64-FPELIM-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; LA64-FPELIM-NEXT: addi.d $sp, $sp, 16 ; LA64-FPELIM-NEXT: ret @@ -252,7 +252,7 @@ ; LA64-WITHFP-NEXT: ori $a0, $zero, 2 ; LA64-WITHFP-NEXT: ori $a1, $zero, 1111 ; LA64-WITHFP-NEXT: move $a2, $zero -; LA64-WITHFP-NEXT: bl va_aligned_register +; LA64-WITHFP-NEXT: bl %plt(va_aligned_register) ; LA64-WITHFP-NEXT: ld.d $fp, $sp, 0 # 8-byte Folded Reload ; LA64-WITHFP-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload ; LA64-WITHFP-NEXT: addi.d $sp, $sp, 16 @@ -302,7 +302,7 @@ ; LA64-FPELIM-NEXT: ori $a0, $zero, 1 ; LA64-FPELIM-NEXT: move $a6, $zero ; LA64-FPELIM-NEXT: move $a7, $a0 -; LA64-FPELIM-NEXT: bl va_aligned_stack_callee +; LA64-FPELIM-NEXT: bl %plt(va_aligned_stack_callee) ; LA64-FPELIM-NEXT: ld.d $ra, $sp, 104 # 8-byte Folded Reload ; LA64-FPELIM-NEXT: addi.d $sp, $sp, 112 ; LA64-FPELIM-NEXT: ret @@ -343,7 +343,7 @@ ; LA64-WITHFP-NEXT: ori $a0, $zero, 1 ; LA64-WITHFP-NEXT: move $a6, $zero ; LA64-WITHFP-NEXT: move $a7, $a0 -; LA64-WITHFP-NEXT: bl va_aligned_stack_callee +; LA64-WITHFP-NEXT: bl %plt(va_aligned_stack_callee) ; LA64-WITHFP-NEXT: ld.d $fp, $sp, 96 # 8-byte Folded Reload ; LA64-WITHFP-NEXT: ld.d $ra, $sp, 104 # 8-byte Folded Reload ; LA64-WITHFP-NEXT: addi.d $sp, $sp, 112 diff --git a/llvm/test/MC/LoongArch/Basic/Integer/invalid.s b/llvm/test/MC/LoongArch/Basic/Integer/invalid.s --- a/llvm/test/MC/LoongArch/Basic/Integer/invalid.s +++ b/llvm/test/MC/LoongArch/Basic/Integer/invalid.s @@ -44,29 +44,29 @@ ## simm12 addi.w $a0, $a0, -2049 -# CHECK: :[[#@LINE-1]]:18: error: immediate must be an integer in the range [-2048, 2047] +# CHECK: :[[#@LINE-1]]:18: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] slti $a0, $a0, -2049 -# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-2048, 2047] +# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] sltui $a0, $a0, 2048 -# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [-2048, 2047] +# CHECK: :[[#@LINE-1]]:17: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] preld 0, $a0, 2048 -# CHECK: :[[#@LINE-1]]:15: error: immediate must be an integer in the range [-2048, 2047] +# CHECK: :[[#@LINE-1]]:15: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] ld.b $a0, $a0, 2048 -# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-2048, 2047] +# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] ld.h $a0, $a0, 2048 -# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-2048, 2047] +# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] ld.w $a0, $a0, 2048 -# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-2048, 2047] +# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] ld.bu $a0, $a0, -2049 -# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [-2048, 2047] +# CHECK: :[[#@LINE-1]]:17: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] ld.hu $a0, $a0, -2049 -# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [-2048, 2047] +# CHECK: :[[#@LINE-1]]:17: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] st.b $a0, $a0, 2048 -# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-2048, 2047] +# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] st.h $a0, $a0, 2048 -# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-2048, 2047] +# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] st.w $a0, $a0, -2049 -# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-2048, 2047] +# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] ## simm14_lsl2 ll.w $a0, $a0, -32772 @@ -101,8 +101,10 @@ # CHECK: :[[#@LINE-1]]:13: error: immediate must be an integer in the range [-524288, 524287] pcaddu12i $a0, 0x80000 # CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-524288, 524287] + +## simm20_pcalau12i pcalau12i $a0, 0x80000 -# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-524288, 524287] +# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_hi20) or an integer in the range [-524288, 524287] ## simm21_lsl2 beqz $a0, -0x400001 @@ -116,13 +118,13 @@ ## simm26_lsl2 b -0x8000001 -# CHECK: :[[#@LINE-1]]:3: error: immediate must be a multiple of 4 in the range [-134217728, 134217724] +# CHECK: :[[#@LINE-1]]:3: error: operand must be a bare symbol name or an immediate must be a multiple of 4 in the range [-134217728, 134217724] b 0x1 -# CHECK: :[[#@LINE-1]]:3: error: immediate must be a multiple of 4 in the range [-134217728, 134217724] +# CHECK: :[[#@LINE-1]]:3: error: operand must be a bare symbol name or an immediate must be a multiple of 4 in the range [-134217728, 134217724] bl 0x7FFFFFF -# CHECK: :[[#@LINE-1]]:4: error: immediate must be a multiple of 4 in the range [-134217728, 134217724] +# CHECK: :[[#@LINE-1]]:4: error: operand must be a bare symbol name or an immediate must be a multiple of 4 in the range [-134217728, 134217724] bl 0x8000000 -# CHECK: :[[#@LINE-1]]:4: error: immediate must be a multiple of 4 in the range [-134217728, 134217724] +# CHECK: :[[#@LINE-1]]:4: error: operand must be a bare symbol name or an immediate must be a multiple of 4 in the range [-134217728, 134217724] ## Invalid mnemonics nori $a0, $a0, 0 diff --git a/llvm/test/MC/LoongArch/Basic/Integer/invalid64.s b/llvm/test/MC/LoongArch/Basic/Integer/invalid64.s --- a/llvm/test/MC/LoongArch/Basic/Integer/invalid64.s +++ b/llvm/test/MC/LoongArch/Basic/Integer/invalid64.s @@ -31,15 +31,15 @@ ## simm12 addi.d $a0, $a0, -2049 -# CHECK: :[[#@LINE-1]]:18: error: immediate must be an integer in the range [-2048, 2047] +# CHECK: :[[#@LINE-1]]:18: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] lu52i.d $a0, $a0, -2049 -# CHECK: :[[#@LINE-1]]:19: error: immediate must be an integer in the range [-2048, 2047] +# CHECK: :[[#@LINE-1]]:19: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] ld.wu $a0, $a0, 2048 -# CHECK: :[[#@LINE-1]]:17: error: immediate must be an integer in the range [-2048, 2047] +# CHECK: :[[#@LINE-1]]:17: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] ld.d $a0, $a0, 2048 -# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-2048, 2047] +# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] st.d $a0, $a0, 2048 -# CHECK: :[[#@LINE-1]]:16: error: immediate must be an integer in the range [-2048, 2047] +# CHECK: :[[#@LINE-1]]:16: error: operand must be a symbol with modifier (e.g. %pc_lo12) or an integer in the range [-2048, 2047] ## simm14_lsl2 ldptr.w $a0, $a0, -32772 diff --git a/llvm/test/MC/LoongArch/Relocations/relocations.s b/llvm/test/MC/LoongArch/Relocations/relocations.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/LoongArch/Relocations/relocations.s @@ -0,0 +1,55 @@ +# RUN: llvm-mc --triple=loongarch64 < %s --show-encoding \ +# RUN: | FileCheck --check-prefixes=INSTR,FIXUP %s +# RUN: llvm-mc --filetype=obj --triple=loongarch64 < %s \ +# RUN: | llvm-readobj -r - | FileCheck --check-prefix=RELOC %s + +## Check prefixes: +## RELOC - Check the relocation in the object. +## FIXUP - Check the fixup on the instruction. +## INSTR - Check the instruction is handled properly by the ASMPrinter. + +.long foo +# RELOC: R_LARCH_32 foo + +.quad foo +# RELOC: R_LARCH_64 foo + +pcalau12i $t1, %pc_hi20(foo) +# RELOC: R_LARCH_PCALA_HI20 foo 0x0 +# INSTR: pcalau12i $t1, %pc_hi20(foo) +# FIXUP: fixup A - offset: 0, value: %pc_hi20(foo), kind: fixup_loongarch_pcala_hi20 + +pcalau12i $t1, %pc_hi20(foo+4) +# RELOC: R_LARCH_PCALA_HI20 foo 0x4 +# INSTR: pcalau12i $t1, %pc_hi20(foo+4) +# FIXUP: fixup A - offset: 0, value: %pc_hi20(foo+4), kind: fixup_loongarch_pcala_hi20 + +addi.d $t1, $t1, %pc_lo12(foo) +# RELOC: R_LARCH_PCALA_LO12 foo 0x0 +# INSTR: addi.d $t1, $t1, %pc_lo12(foo) +# FIXUP: fixup A - offset: 0, value: %pc_lo12(foo), kind: fixup_loongarch_pcala_lo12 + +addi.d $t1, $t1, %pc_lo12(foo+4) +# RELOC: R_LARCH_PCALA_LO12 foo 0x4 +# INSTR: addi.d $t1, $t1, %pc_lo12(foo+4) +# FIXUP: fixup A - offset: 0, value: %pc_lo12(foo+4), kind: fixup_loongarch_pcala_lo12 + +st.b $t1, $a2, %pc_lo12(foo) +# RELOC: R_LARCH_PCALA_LO12 foo 0x0 +# INSTR: st.b $t1, $a2, %pc_lo12(foo) +# FIXUP: fixup A - offset: 0, value: %pc_lo12(foo), kind: fixup_loongarch_pcala_lo12 + +st.b $t1, $a2, %pc_lo12(foo+4) +# RELOC: R_LARCH_PCALA_LO12 foo 0x4 +# INSTR: st.b $t1, $a2, %pc_lo12(foo+4) +# FIXUP: fixup A - offset: 0, value: %pc_lo12(foo+4), kind: fixup_loongarch_pcala_lo12 + +bl %plt(foo) +# RELOC: R_LARCH_B26 +# INSTR: bl %plt(foo) +# FIXUP: fixup A - offset: 0, value: %plt(foo), kind: fixup_loongarch_b26 + +bl foo +# RELOC: R_LARCH_B26 +# INSTR: bl foo +# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_loongarch_b26 diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected --- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected +++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.generated.expected @@ -121,8 +121,8 @@ ; CHECK-NEXT: .cfi_offset 22, -8 ; CHECK-NEXT: addi.w $fp, $sp, 32 ; CHECK-NEXT: .cfi_def_cfa 22, 0 -; CHECK-NEXT: pcalau12i $a0, x -; CHECK-NEXT: addi.w $a0, $a0, x +; CHECK-NEXT: pcalau12i $a0, %pc_hi20(x) +; CHECK-NEXT: addi.w $a0, $a0, %pc_lo12(x) ; CHECK-NEXT: ori $a1, $zero, 1 ; CHECK-NEXT: st.w $a1, $a0, 0 ; CHECK-NEXT: st.w $zero, $fp, -12 diff --git a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected --- a/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected +++ b/llvm/test/tools/UpdateTestChecks/update_llc_test_checks/Inputs/loongarch_generated_funcs.ll.nogenerated.expected @@ -98,8 +98,8 @@ ; CHECK-NEXT: .cfi_offset 22, -8 ; CHECK-NEXT: addi.w $fp, $sp, 32 ; CHECK-NEXT: .cfi_def_cfa 22, 0 -; CHECK-NEXT: pcalau12i $a0, x -; CHECK-NEXT: addi.w $a0, $a0, x +; CHECK-NEXT: pcalau12i $a0, %pc_hi20(x) +; CHECK-NEXT: addi.w $a0, $a0, %pc_lo12(x) ; CHECK-NEXT: ori $a1, $zero, 1 ; CHECK-NEXT: st.w $a1, $a0, 0 ; CHECK-NEXT: st.w $zero, $fp, -12