[llvm] [LoongArch] Add machine function pass to merge base + offset (PR #101139)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 7 23:07:43 PDT 2024
https://github.com/heiher updated https://github.com/llvm/llvm-project/pull/101139
>From da73216f364b591d6f82d7b24878a4e67aa0f600 Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Sat, 27 Jul 2024 11:41:52 +0800
Subject: [PATCH 1/2] [LoongArch] Add machine function pass to merge base +
offset
This commit references RISC-V to add a machine function pass to merge the base
address and offset.
---
llvm/lib/Target/LoongArch/CMakeLists.txt | 1 +
llvm/lib/Target/LoongArch/LoongArch.h | 2 +
.../Target/LoongArch/LoongArchAsmPrinter.cpp | 6 +
.../LoongArch/LoongArchMergeBaseOffset.cpp | 633 ++++++++++++++++++
.../LoongArch/LoongArchTargetMachine.cpp | 3 +
llvm/test/CodeGen/LoongArch/block-address.ll | 10 +-
.../CodeGen/LoongArch/calling-conv-lp64d.ll | 21 +-
llvm/test/CodeGen/LoongArch/double-imm.ll | 6 +-
llvm/test/CodeGen/LoongArch/float-imm.ll | 6 +-
llvm/test/CodeGen/LoongArch/ghc-cc.ll | 51 +-
llvm/test/CodeGen/LoongArch/global-address.ll | 18 +-
.../LoongArch/global-variable-code-model.ll | 6 +-
.../LoongArch/inline-asm-constraint-f.ll | 6 +-
.../LoongArch/inline-asm-constraint-m.ll | 10 +-
.../LoongArch/ir-instruction/atomicrmw-fp.ll | 45 +-
.../ir-instruction/double-convert.ll | 12 +-
.../LoongArch/ir-instruction/float-convert.ll | 18 +-
.../LoongArch/ir-instruction/load-store.ll | 28 +-
.../LoongArch/machinelicm-address-pseudos.ll | 23 +-
.../CodeGen/LoongArch/merge-base-offset.ll | 435 +++++-------
llvm/test/CodeGen/LoongArch/opt-pipeline.ll | 1 +
.../LoongArch/psabi-restricted-scheduling.ll | 12 +-
llvm/test/CodeGen/LoongArch/vector-fp-imm.ll | 126 ++--
...arch_generated_funcs.ll.generated.expected | 3 +-
...ch_generated_funcs.ll.nogenerated.expected | 3 +-
.../llvm/lib/Target/LoongArch/BUILD.gn | 1 +
26 files changed, 951 insertions(+), 535 deletions(-)
create mode 100644 llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp
diff --git a/llvm/lib/Target/LoongArch/CMakeLists.txt b/llvm/lib/Target/LoongArch/CMakeLists.txt
index cadc335a621f2e..0f674b1b0fa9e2 100644
--- a/llvm/lib/Target/LoongArch/CMakeLists.txt
+++ b/llvm/lib/Target/LoongArch/CMakeLists.txt
@@ -24,6 +24,7 @@ add_llvm_target(LoongArchCodeGen
LoongArchISelDAGToDAG.cpp
LoongArchISelLowering.cpp
LoongArchMCInstLower.cpp
+ LoongArchMergeBaseOffset.cpp
LoongArchOptWInstrs.cpp
LoongArchRegisterInfo.cpp
LoongArchSubtarget.cpp
diff --git a/llvm/lib/Target/LoongArch/LoongArch.h b/llvm/lib/Target/LoongArch/LoongArch.h
index adfb844ee31b64..db605237388809 100644
--- a/llvm/lib/Target/LoongArch/LoongArch.h
+++ b/llvm/lib/Target/LoongArch/LoongArch.h
@@ -36,12 +36,14 @@ bool lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO,
FunctionPass *createLoongArchDeadRegisterDefinitionsPass();
FunctionPass *createLoongArchExpandAtomicPseudoPass();
FunctionPass *createLoongArchISelDag(LoongArchTargetMachine &TM);
+FunctionPass *createLoongArchMergeBaseOffsetOptPass();
FunctionPass *createLoongArchOptWInstrsPass();
FunctionPass *createLoongArchPreRAExpandPseudoPass();
FunctionPass *createLoongArchExpandPseudoPass();
void initializeLoongArchDAGToDAGISelLegacyPass(PassRegistry &);
void initializeLoongArchDeadRegisterDefinitionsPass(PassRegistry &);
void initializeLoongArchExpandAtomicPseudoPass(PassRegistry &);
+void initializeLoongArchMergeBaseOffsetOptPass(PassRegistry &);
void initializeLoongArchOptWInstrsPass(PassRegistry &);
void initializeLoongArchPreRAExpandPseudoPass(PassRegistry &);
void initializeLoongArchExpandPseudoPass(PassRegistry &);
diff --git a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
index f478870217ec60..8bb9497a847fa7 100644
--- a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
@@ -130,10 +130,16 @@ bool LoongArchAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
OS << "$" << LoongArchInstPrinter::getRegisterName(BaseMO.getReg());
// Print the offset operand.
const MachineOperand &OffsetMO = MI->getOperand(OpNo + 1);
+ MCOperand MCO;
+ if (!lowerOperand(OffsetMO, MCO))
+ return true;
if (OffsetMO.isReg())
OS << ", $" << LoongArchInstPrinter::getRegisterName(OffsetMO.getReg());
else if (OffsetMO.isImm())
OS << ", " << OffsetMO.getImm();
+ else if (OffsetMO.isGlobal() || OffsetMO.isBlockAddress() ||
+ OffsetMO.isMCSymbol())
+ OS << ", " << *MCO.getExpr();
else
return true;
diff --git a/llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp b/llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp
new file mode 100644
index 00000000000000..4fbe31616a7efc
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp
@@ -0,0 +1,633 @@
+//===---- LoongArchMergeBaseOffset.cpp - Optimise address calculations ----===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Merge the offset of address calculation into the offset field
+// of instructions in a global address lowering sequence.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArch.h"
+#include "LoongArchTargetMachine.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Target/TargetOptions.h"
+#include <optional>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "loongarch-merge-base-offset"
+#define LoongArch_MERGE_BASE_OFFSET_NAME "LoongArch Merge Base Offset"
+
+namespace {
+
+class LoongArchMergeBaseOffsetOpt : public MachineFunctionPass {
+ const LoongArchSubtarget *ST = nullptr;
+ MachineRegisterInfo *MRI;
+
+public:
+ static char ID;
+ bool runOnMachineFunction(MachineFunction &Fn) override;
+ bool detectFoldable(MachineInstr &Hi20, MachineInstr *&Lo12,
+ MachineInstr *&Lo20, MachineInstr *&Hi12,
+ MachineInstr *&Last);
+
+ bool detectAndFoldOffset(MachineInstr &Hi20, MachineInstr &Lo12,
+ MachineInstr *&Lo20, MachineInstr *&Hi12,
+ MachineInstr *&Last);
+ void foldOffset(MachineInstr &Hi20, MachineInstr &Lo12, MachineInstr *&Lo20,
+ MachineInstr *&Hi12, MachineInstr *&Last, MachineInstr &Tail,
+ int64_t Offset);
+ bool foldLargeOffset(MachineInstr &Hi20, MachineInstr &Lo12,
+ MachineInstr *&Lo20, MachineInstr *&Hi12,
+ MachineInstr *&Last, MachineInstr &TailAdd,
+ Register GAReg);
+
+ bool foldIntoMemoryOps(MachineInstr &Hi20, MachineInstr &Lo12,
+ MachineInstr *&Lo20, MachineInstr *&Hi12,
+ MachineInstr *&Last);
+
+ LoongArchMergeBaseOffsetOpt() : MachineFunctionPass(ID) {}
+
+ MachineFunctionProperties getRequiredProperties() const override {
+ return MachineFunctionProperties().set(
+ MachineFunctionProperties::Property::IsSSA);
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesCFG();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+ StringRef getPassName() const override {
+ return LoongArch_MERGE_BASE_OFFSET_NAME;
+ }
+};
+} // end anonymous namespace
+
+char LoongArchMergeBaseOffsetOpt::ID = 0;
+INITIALIZE_PASS(LoongArchMergeBaseOffsetOpt, DEBUG_TYPE,
+ LoongArch_MERGE_BASE_OFFSET_NAME, false, false)
+
+// Detect either of the patterns:
+//
+// 1. (small/medium):
+// pcalau12i vreg1, %pc_hi20(s)
+// addi.d vreg2, vreg1, %pc_lo12(s)
+//
+// 2. (large):
+// pcalau12i vreg1, %pc_hi20(s)
+// addi.d vreg2, $zero, %pc_lo12(s)
+// lu32i.d vreg3, vreg2, %pc64_lo20(s)
+// lu52i.d vreg4, vreg3, %pc64_hi12(s)
+// add.d vreg5, vreg4, vreg1
+
+// The pattern is only accepted if:
+// 1) For small and medium pattern, the first instruction has only one use,
+// which is the ADDI.
+// 2) For large pattern, the first four instructions each have only one use,
+// and the user of the fourth instruction is ADD.
+// 3) The address operands have the appropriate type, reflecting the
+// lowering of a global address or constant pool using the pattern.
+// 4) The offset value in the Global Address or Constant Pool is 0.
+bool LoongArchMergeBaseOffsetOpt::detectFoldable(MachineInstr &Hi20,
+ MachineInstr *&Lo12,
+ MachineInstr *&Lo20,
+ MachineInstr *&Hi12,
+ MachineInstr *&Last) {
+ if (Hi20.getOpcode() != LoongArch::PCALAU12I)
+ return false;
+
+ const MachineOperand &Hi20Op1 = Hi20.getOperand(1);
+ if (Hi20Op1.getTargetFlags() != LoongArchII::MO_PCREL_HI)
+ return false;
+
+ if (!(Hi20Op1.isGlobal() || Hi20Op1.isCPI() || Hi20Op1.isBlockAddress()) ||
+ Hi20Op1.getOffset() != 0)
+ return false;
+
+ Register HiDestReg = Hi20.getOperand(0).getReg();
+ if (!MRI->hasOneUse(HiDestReg))
+ return false;
+
+ MachineInstr *UseInst = &*MRI->use_instr_begin(HiDestReg);
+ if (UseInst->getOpcode() != LoongArch::ADD_D) {
+ Lo12 = UseInst;
+ if ((ST->is64Bit() && Lo12->getOpcode() != LoongArch::ADDI_D) ||
+ (!ST->is64Bit() && Lo12->getOpcode() != LoongArch::ADDI_W))
+ return false;
+ } else {
+ assert(ST->is64Bit());
+ Last = UseInst;
+
+ Hi12 = MRI->getVRegDef(Last->getOperand(1).getReg());
+ const MachineOperand &Hi12Op2 = Hi12->getOperand(2);
+ if (Hi12Op2.getTargetFlags() != LoongArchII::MO_PCREL64_HI)
+ return false;
+ if (!(Hi12Op2.isGlobal() || Hi12Op2.isCPI() || Hi12Op2.isBlockAddress()) ||
+ Hi12Op2.getOffset() != 0)
+ return false;
+ if (!MRI->hasOneUse(Hi12->getOperand(0).getReg()))
+ return false;
+
+ Lo20 = MRI->getVRegDef(Hi12->getOperand(1).getReg());
+ const MachineOperand &Lo20Op2 = Lo20->getOperand(2);
+ if (Lo20Op2.getTargetFlags() != LoongArchII::MO_PCREL64_LO)
+ return false;
+ if (!(Lo20Op2.isGlobal() || Lo20Op2.isCPI() || Lo20Op2.isBlockAddress()) ||
+ Lo20Op2.getOffset() != 0)
+ return false;
+ if (!MRI->hasOneUse(Lo20->getOperand(0).getReg()))
+ return false;
+
+ Lo12 = MRI->getVRegDef(Lo20->getOperand(1).getReg());
+ if (!MRI->hasOneUse(Lo12->getOperand(0).getReg()))
+ return false;
+ }
+
+ const MachineOperand &Lo12Op2 = Lo12->getOperand(2);
+ assert(Hi20.getOpcode() == LoongArch::PCALAU12I);
+ if (Lo12Op2.getTargetFlags() != LoongArchII::MO_PCREL_LO ||
+ !(Lo12Op2.isGlobal() || Lo12Op2.isCPI() || Lo12Op2.isBlockAddress() ||
+ Lo12Op2.isMCSymbol()) ||
+ Lo12Op2.getOffset() != 0)
+ return false;
+
+ if (Hi20Op1.isGlobal()) {
+ LLVM_DEBUG(dbgs() << " Found lowered global address: "
+ << *Hi20Op1.getGlobal() << "\n");
+ } else if (Hi20Op1.isBlockAddress()) {
+ LLVM_DEBUG(dbgs() << " Found lowered basic address: "
+ << *Hi20Op1.getBlockAddress() << "\n");
+ } else if (Hi20Op1.isCPI()) {
+ LLVM_DEBUG(dbgs() << " Found lowered constant pool: " << Hi20Op1.getIndex()
+ << "\n");
+ }
+
+ return true;
+}
+
+// Update the offset in Hi20, Lo12, Lo20 and Hi12 instructions.
+// Delete the tail instruction and update all the uses to use the
+// output from Last.
+void LoongArchMergeBaseOffsetOpt::foldOffset(
+ MachineInstr &Hi20, MachineInstr &Lo12, MachineInstr *&Lo20,
+ MachineInstr *&Hi12, MachineInstr *&Last, MachineInstr &Tail,
+ int64_t Offset) {
+ assert(isInt<32>(Offset) && "Unexpected offset");
+ // Put the offset back in Hi and the Lo
+ Hi20.getOperand(1).setOffset(Offset);
+ Lo12.getOperand(2).setOffset(Offset);
+ if (Lo20 && Hi12) {
+ Lo20->getOperand(2).setOffset(Offset);
+ Hi12->getOperand(2).setOffset(Offset);
+ }
+ // Delete the tail instruction.
+ MachineInstr *Def = Last ? Last : &Lo12;
+ MRI->constrainRegClass(Def->getOperand(0).getReg(),
+ MRI->getRegClass(Tail.getOperand(0).getReg()));
+ MRI->replaceRegWith(Tail.getOperand(0).getReg(), Def->getOperand(0).getReg());
+ Tail.eraseFromParent();
+ LLVM_DEBUG(dbgs() << " Merged offset " << Offset << " into base.\n"
+ << " " << Hi20 << " " << Lo12;);
+ if (Lo20 && Hi12) {
+ LLVM_DEBUG(dbgs() << " " << *Lo20 << " " << *Hi12;);
+ }
+}
+
+// Detect patterns for large offsets that are passed into an ADD instruction.
+// If the pattern is found, updates the offset in Hi20, Lo12, Lo20 and Hi12
+// instructions and deletes TailAdd and the instructions that produced the
+// offset.
+//
+// Base address lowering is of the form:
+// Hi20: pcalau12i vreg1, %pc_hi20(s)
+// Lo12: addi.d vreg2, vreg1, %pc_lo12(s)
+// / \
+// / \
+// / \
+// / The large offset can be of two forms: \
+// 1) Offset that has non zero bits in lower 2) Offset that has non zero
+// 12 bits and upper 20 bits bits in upper 20 bits only
+// OffsetHi: lu12i.w vreg3, 4
+// OffsetLo: ori voff, vreg3, 188 OffsetHi: lu12i.w voff, 128
+// \ /
+// \ /
+// \ /
+// \ /
+// TailAdd: add.d vreg4, vreg2, voff
+bool LoongArchMergeBaseOffsetOpt::foldLargeOffset(
+ MachineInstr &Hi20, MachineInstr &Lo12, MachineInstr *&Lo20,
+ MachineInstr *&Hi12, MachineInstr *&Last, MachineInstr &TailAdd,
+ Register GAReg) {
+ assert((TailAdd.getOpcode() == LoongArch::ADD_W ||
+ TailAdd.getOpcode() == LoongArch::ADD_D) &&
+ "Expected ADD instruction!");
+ Register Rs = TailAdd.getOperand(1).getReg();
+ Register Rt = TailAdd.getOperand(2).getReg();
+ Register Reg = Rs == GAReg ? Rt : Rs;
+
+ // Can't fold if the register has more than one use.
+ if (!Reg.isVirtual() || !MRI->hasOneUse(Reg))
+ return false;
+ // This can point to an ORI or a LU12I.W:
+ MachineInstr &OffsetTail = *MRI->getVRegDef(Reg);
+ if (OffsetTail.getOpcode() == LoongArch::ORI) {
+ // The offset value has non zero bits in both %hi and %lo parts.
+ // Detect an ORI that feeds from a LU12I.W instruction.
+ MachineOperand &OriImmOp = OffsetTail.getOperand(2);
+ if (OriImmOp.getTargetFlags() != LoongArchII::MO_None)
+ return false;
+ Register OriReg = OffsetTail.getOperand(1).getReg();
+ int64_t OffLo = OriImmOp.getImm();
+
+ // Handle rs1 of ORI is R0.
+ if (OriReg == LoongArch::R0) {
+ LLVM_DEBUG(dbgs() << " Offset Instrs: " << OffsetTail);
+ foldOffset(Hi20, Lo12, Lo20, Hi12, Last, TailAdd, OffLo);
+ OffsetTail.eraseFromParent();
+ return true;
+ }
+
+ MachineInstr &OffsetLu12i = *MRI->getVRegDef(OriReg);
+ MachineOperand &Lu12iImmOp = OffsetLu12i.getOperand(1);
+ if (OffsetLu12i.getOpcode() != LoongArch::LU12I_W ||
+ Lu12iImmOp.getTargetFlags() != LoongArchII::MO_None ||
+ !MRI->hasOneUse(OffsetLu12i.getOperand(0).getReg()))
+ return false;
+ int64_t Offset = SignExtend64<32>(Lu12iImmOp.getImm() << 12);
+ Offset += OffLo;
+ // LU12I.W+ORI sign extends the result.
+ Offset = SignExtend64<32>(Offset);
+ LLVM_DEBUG(dbgs() << " Offset Instrs: " << OffsetTail
+ << " " << OffsetLu12i);
+ foldOffset(Hi20, Lo12, Lo20, Hi12, Last, TailAdd, Offset);
+ OffsetTail.eraseFromParent();
+ OffsetLu12i.eraseFromParent();
+ return true;
+ } else if (OffsetTail.getOpcode() == LoongArch::LU12I_W) {
+ // The offset value has all zero bits in the lower 12 bits. Only LU12I.W
+ // exists.
+ LLVM_DEBUG(dbgs() << " Offset Instr: " << OffsetTail);
+ int64_t Offset = SignExtend64<32>(OffsetTail.getOperand(1).getImm() << 12);
+ foldOffset(Hi20, Lo12, Lo20, Hi12, Last, TailAdd, Offset);
+ OffsetTail.eraseFromParent();
+ return true;
+ }
+ return false;
+}
+
+bool LoongArchMergeBaseOffsetOpt::detectAndFoldOffset(MachineInstr &Hi20,
+ MachineInstr &Lo12,
+ MachineInstr *&Lo20,
+ MachineInstr *&Hi12,
+ MachineInstr *&Last) {
+ Register DestReg =
+ Last ? Last->getOperand(0).getReg() : Lo12.getOperand(0).getReg();
+
+ // Look for arithmetic instructions we can get an offset from.
+ // We might be able to remove the arithmetic instructions by folding the
+ // offset into the PCALAU12I+(ADDI/ADDI+LU32I+LU52I).
+ if (!MRI->hasOneUse(DestReg))
+ return false;
+
+ // DestReg has only one use.
+ MachineInstr &Tail = *MRI->use_instr_begin(DestReg);
+ switch (Tail.getOpcode()) {
+ default:
+ LLVM_DEBUG(dbgs() << "Don't know how to get offset from this instr:"
+ << Tail);
+ break;
+ case LoongArch::ADDI_W:
+ if (ST->is64Bit())
+ return false;
+ [[fallthrough]];
+ case LoongArch::ADDI_D:
+ case LoongArch::ADDU16I_D: {
+ // Offset is simply an immediate operand.
+ int64_t Offset = Tail.getOperand(2).getImm();
+ if (Tail.getOpcode() == LoongArch::ADDU16I_D)
+ Offset = SignExtend64<32>(Offset << 16);
+
+ // We might have two ADDIs in a row.
+ Register TailDestReg = Tail.getOperand(0).getReg();
+ if (MRI->hasOneUse(TailDestReg)) {
+ MachineInstr &TailTail = *MRI->use_instr_begin(TailDestReg);
+ if (ST->is64Bit() && TailTail.getOpcode() == LoongArch::ADDI_W)
+ return false;
+ if (TailTail.getOpcode() == LoongArch::ADDI_W ||
+ TailTail.getOpcode() == LoongArch::ADDI_D) {
+ Offset += TailTail.getOperand(2).getImm();
+ LLVM_DEBUG(dbgs() << " Offset Instrs: " << Tail << TailTail);
+ foldOffset(Hi20, Lo12, Lo20, Hi12, Last, TailTail, Offset);
+ Tail.eraseFromParent();
+ return true;
+ }
+ }
+
+ LLVM_DEBUG(dbgs() << " Offset Instr: " << Tail);
+ foldOffset(Hi20, Lo12, Lo20, Hi12, Last, Tail, Offset);
+ return true;
+ }
+ case LoongArch::ADD_W:
+ if (ST->is64Bit())
+ return false;
+ [[fallthrough]];
+ case LoongArch::ADD_D:
+ // The offset is too large to fit in the immediate field of ADDI.
+ // This can be in two forms:
+ // 1) LU12I.W hi_offset followed by:
+ // ORI lo_offset
+ // This happens in case the offset has non zero bits in
+ // both hi 20 and lo 12 bits.
+ // 2) LU12I.W (offset20)
+ // This happens in case the lower 12 bits of the offset are zeros.
+ return foldLargeOffset(Hi20, Lo12, Lo20, Hi12, Last, Tail, DestReg);
+ break;
+ }
+
+ return false;
+}
+
+// Memory access opcode mapping for transforms.
+static unsigned getNewOpc(unsigned Op, bool isLarge) {
+ switch (Op) {
+ case LoongArch::LD_B:
+ return isLarge ? LoongArch::LDX_B : LoongArch::LD_B;
+ case LoongArch::LD_H:
+ return isLarge ? LoongArch::LDX_H : LoongArch::LD_H;
+ case LoongArch::LD_W:
+ case LoongArch::LDPTR_W:
+ return isLarge ? LoongArch::LDX_W : LoongArch::LD_W;
+ case LoongArch::LD_D:
+ case LoongArch::LDPTR_D:
+ return isLarge ? LoongArch::LDX_D : LoongArch::LD_D;
+ case LoongArch::LD_BU:
+ return isLarge ? LoongArch::LDX_BU : LoongArch::LD_BU;
+ case LoongArch::LD_HU:
+ return isLarge ? LoongArch::LDX_HU : LoongArch::LD_HU;
+ case LoongArch::LD_WU:
+ return isLarge ? LoongArch::LDX_WU : LoongArch::LD_WU;
+ case LoongArch::FLD_S:
+ return isLarge ? LoongArch::FLDX_S : LoongArch::FLD_S;
+ case LoongArch::FLD_D:
+ return isLarge ? LoongArch::FLDX_D : LoongArch::FLD_D;
+ case LoongArch::ST_B:
+ return isLarge ? LoongArch::STX_B : LoongArch::ST_B;
+ case LoongArch::ST_H:
+ return isLarge ? LoongArch::STX_H : LoongArch::ST_H;
+ case LoongArch::ST_W:
+ case LoongArch::STPTR_W:
+ return isLarge ? LoongArch::STX_W : LoongArch::ST_W;
+ case LoongArch::ST_D:
+ case LoongArch::STPTR_D:
+ return isLarge ? LoongArch::STX_D : LoongArch::ST_D;
+ case LoongArch::FST_S:
+ return isLarge ? LoongArch::FSTX_S : LoongArch::FST_S;
+ case LoongArch::FST_D:
+ return isLarge ? LoongArch::FSTX_D : LoongArch::FST_D;
+ default:
+ llvm_unreachable("Unexpected opcode for replacement");
+ }
+}
+
+bool LoongArchMergeBaseOffsetOpt::foldIntoMemoryOps(MachineInstr &Hi20,
+ MachineInstr &Lo12,
+ MachineInstr *&Lo20,
+ MachineInstr *&Hi12,
+ MachineInstr *&Last) {
+ Register DestReg =
+ Last ? Last->getOperand(0).getReg() : Lo12.getOperand(0).getReg();
+
+ // If all the uses are memory ops with the same offset, we can transform:
+ //
+ // 1. (small/medium):
+ // pcalau12i vreg1, %pc_hi20(s)
+ // addi.d vreg2, vreg1, %pc_lo12(s)
+ // ld.w vreg3, 8(vreg2)
+ //
+ // =>
+ //
+ // pcalau12i vreg1, %pc_hi20(s+8)
+ // ld.w vreg3, vreg1, %pc_lo12(s+8)(vreg1)
+ //
+ // 2. (large):
+ // pcalau12i vreg1, %pc_hi20(s)
+ // addi.d vreg2, $zero, %pc_lo12(s)
+ // lu32i.d vreg3, vreg2, %pc64_lo20(s)
+ // lu52i.d vreg4, vreg3, %pc64_hi12(s)
+ // add.d vreg5, vreg4, vreg1
+ // ld.w vreg6, 8(vreg5)
+ //
+ // =>
+ //
+ // pcalau12i vreg1, %pc_hi20(s+8)
+ // addi.d vreg2, $zero, %pc_lo12(s+8)
+ // lu32i.d vreg3, vreg2, %pc64_lo20(s+8)
+ // lu52i.d vreg4, vreg3, %pc64_hi12(s+8)
+ // ldx.w vreg6, vreg4, vreg1
+
+ std::optional<int64_t> CommonOffset;
+ DenseMap<const MachineInstr *, SmallVector<unsigned>>
+ InlineAsmMemoryOpIndexesMap;
+ for (const MachineInstr &UseMI : MRI->use_instructions(DestReg)) {
+ switch (UseMI.getOpcode()) {
+ default:
+ LLVM_DEBUG(dbgs() << "Not a load or store instruction: " << UseMI);
+ return false;
+ case LoongArch::LD_B:
+ case LoongArch::LD_H:
+ case LoongArch::LD_W:
+ case LoongArch::LD_D:
+ case LoongArch::LD_BU:
+ case LoongArch::LD_HU:
+ case LoongArch::LD_WU:
+ case LoongArch::LDPTR_W:
+ case LoongArch::LDPTR_D:
+ case LoongArch::FLD_S:
+ case LoongArch::FLD_D:
+ case LoongArch::ST_B:
+ case LoongArch::ST_H:
+ case LoongArch::ST_W:
+ case LoongArch::ST_D:
+ case LoongArch::STPTR_W:
+ case LoongArch::STPTR_D:
+ case LoongArch::FST_S:
+ case LoongArch::FST_D: {
+ if (UseMI.getOperand(1).isFI())
+ return false;
+ // Register defined by Lo should not be the value register.
+ if (DestReg == UseMI.getOperand(0).getReg())
+ return false;
+ assert(DestReg == UseMI.getOperand(1).getReg() &&
+ "Expected base address use");
+ // All load/store instructions must use the same offset.
+ int64_t Offset = UseMI.getOperand(2).getImm();
+ if (CommonOffset && Offset != CommonOffset)
+ return false;
+ CommonOffset = Offset;
+ break;
+ }
+ case LoongArch::INLINEASM:
+ case LoongArch::INLINEASM_BR: {
+ // We can't do this for large pattern.
+ if (Last)
+ return false;
+ SmallVector<unsigned> InlineAsmMemoryOpIndexes;
+ unsigned NumOps = 0;
+ for (unsigned I = InlineAsm::MIOp_FirstOperand;
+ I < UseMI.getNumOperands(); I += 1 + NumOps) {
+ const MachineOperand &FlagsMO = UseMI.getOperand(I);
+ // Should be an imm.
+ if (!FlagsMO.isImm())
+ continue;
+
+ const InlineAsm::Flag Flags(FlagsMO.getImm());
+ NumOps = Flags.getNumOperandRegisters();
+
+ // Memory constraints have two operands.
+ if (NumOps != 2 || !Flags.isMemKind()) {
+ // If the register is used by something other than a memory contraint,
+ // we should not fold.
+ for (unsigned J = 0; J < NumOps; ++J) {
+ const MachineOperand &MO = UseMI.getOperand(I + 1 + J);
+ if (MO.isReg() && MO.getReg() == DestReg)
+ return false;
+ }
+ continue;
+ }
+
+ // We can only do this for constraint m.
+ if (Flags.getMemoryConstraintID() != InlineAsm::ConstraintCode::m)
+ return false;
+
+ const MachineOperand &AddrMO = UseMI.getOperand(I + 1);
+ if (!AddrMO.isReg() || AddrMO.getReg() != DestReg)
+ continue;
+
+ const MachineOperand &OffsetMO = UseMI.getOperand(I + 2);
+ if (!OffsetMO.isImm())
+ continue;
+
+ // All inline asm memory operands must use the same offset.
+ int64_t Offset = OffsetMO.getImm();
+ if (CommonOffset && Offset != CommonOffset)
+ return false;
+ CommonOffset = Offset;
+ InlineAsmMemoryOpIndexes.push_back(I + 1);
+ }
+ InlineAsmMemoryOpIndexesMap.insert(
+ std::make_pair(&UseMI, InlineAsmMemoryOpIndexes));
+ break;
+ }
+ }
+ }
+
+ // We found a common offset.
+ // Update the offsets in global address lowering.
+ // We may have already folded some arithmetic so we need to add to any
+ // existing offset.
+ int64_t NewOffset = Hi20.getOperand(1).getOffset() + *CommonOffset;
+ // LA32 ignores the upper 32 bits.
+ if (!ST->is64Bit())
+ NewOffset = SignExtend64<32>(NewOffset);
+ // We can only fold simm32 offsets.
+ if (!isInt<32>(NewOffset))
+ return false;
+
+ Hi20.getOperand(1).setOffset(NewOffset);
+ MachineOperand &ImmOp = Lo12.getOperand(2);
+ ImmOp.setOffset(NewOffset);
+ if (Lo20 && Hi12) {
+ Lo20->getOperand(2).setOffset(NewOffset);
+ Hi12->getOperand(2).setOffset(NewOffset);
+ }
+
+ // Update the immediate in the load/store instructions to add the offset.
+ const LoongArchInstrInfo &TII = *ST->getInstrInfo();
+ for (MachineInstr &UseMI :
+ llvm::make_early_inc_range(MRI->use_instructions(DestReg))) {
+ if (UseMI.getOpcode() == LoongArch::INLINEASM ||
+ UseMI.getOpcode() == LoongArch::INLINEASM_BR) {
+ auto &InlineAsmMemoryOpIndexes = InlineAsmMemoryOpIndexesMap[&UseMI];
+ for (unsigned I : InlineAsmMemoryOpIndexes) {
+ MachineOperand &MO = UseMI.getOperand(I + 1);
+ switch (ImmOp.getType()) {
+ case MachineOperand::MO_GlobalAddress:
+ MO.ChangeToGA(ImmOp.getGlobal(), ImmOp.getOffset(),
+ ImmOp.getTargetFlags());
+ break;
+ case MachineOperand::MO_MCSymbol:
+ MO.ChangeToMCSymbol(ImmOp.getMCSymbol(), ImmOp.getTargetFlags());
+ MO.setOffset(ImmOp.getOffset());
+ break;
+ case MachineOperand::MO_BlockAddress:
+ MO.ChangeToBA(ImmOp.getBlockAddress(), ImmOp.getOffset(),
+ ImmOp.getTargetFlags());
+ break;
+ default:
+ report_fatal_error("unsupported machine operand type");
+ break;
+ }
+ }
+ } else {
+ UseMI.setDesc(TII.get(getNewOpc(UseMI.getOpcode(), Last)));
+ if (Last) {
+ UseMI.removeOperand(2);
+ UseMI.removeOperand(1);
+ UseMI.addOperand(Last->getOperand(1));
+ UseMI.addOperand(Last->getOperand(2));
+ UseMI.getOperand(1).setIsKill(false);
+ UseMI.getOperand(2).setIsKill(false);
+ } else {
+ UseMI.removeOperand(2);
+ UseMI.addOperand(ImmOp);
+ }
+ }
+ }
+
+ if (Last) {
+ Last->eraseFromParent();
+ return true;
+ }
+
+ MRI->replaceRegWith(Lo12.getOperand(0).getReg(), Hi20.getOperand(0).getReg());
+ Lo12.eraseFromParent();
+ return true;
+}
+
+bool LoongArchMergeBaseOffsetOpt::runOnMachineFunction(MachineFunction &Fn) {
+ if (skipFunction(Fn.getFunction()))
+ return false;
+
+ ST = &Fn.getSubtarget<LoongArchSubtarget>();
+
+ bool MadeChange = false;
+ MRI = &Fn.getRegInfo();
+ for (MachineBasicBlock &MBB : Fn) {
+ LLVM_DEBUG(dbgs() << "MBB: " << MBB.getName() << "\n");
+ for (MachineInstr &Hi20 : MBB) {
+ MachineInstr *Lo12 = nullptr;
+ MachineInstr *Lo20 = nullptr;
+ MachineInstr *Hi12 = nullptr;
+ MachineInstr *Last = nullptr;
+ if (!detectFoldable(Hi20, Lo12, Lo20, Hi12, Last))
+ continue;
+ MadeChange |= detectAndFoldOffset(Hi20, *Lo12, Lo20, Hi12, Last);
+ MadeChange |= foldIntoMemoryOps(Hi20, *Lo12, Lo20, Hi12, Last);
+ }
+ }
+
+ return MadeChange;
+}
+
+/// Returns an instance of the Merge Base Offset Optimization pass.
+FunctionPass *llvm::createLoongArchMergeBaseOffsetOptPass() {
+ return new LoongArchMergeBaseOffsetOpt();
+}
diff --git a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
index e83fc08696aea5..4401aadfe78485 100644
--- a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
@@ -35,6 +35,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTarget() {
RegisterTargetMachine<LoongArchTargetMachine> Y(getTheLoongArch64Target());
auto *PR = PassRegistry::getPassRegistry();
initializeLoongArchDeadRegisterDefinitionsPass(*PR);
+ initializeLoongArchMergeBaseOffsetOptPass(*PR);
initializeLoongArchOptWInstrsPass(*PR);
initializeLoongArchPreRAExpandPseudoPass(*PR);
initializeLoongArchDAGToDAGISelLegacyPass(*PR);
@@ -216,6 +217,8 @@ void LoongArchPassConfig::addMachineSSAOptimization() {
void LoongArchPassConfig::addPreRegAlloc() {
addPass(createLoongArchPreRAExpandPseudoPass());
+ if (TM->getOptLevel() != CodeGenOptLevel::None)
+ addPass(createLoongArchMergeBaseOffsetOptPass());
}
bool LoongArchPassConfig::addRegAssignAndRewriteFast() {
diff --git a/llvm/test/CodeGen/LoongArch/block-address.ll b/llvm/test/CodeGen/LoongArch/block-address.ll
index eaba81f3563d7f..114cbb73a51259 100644
--- a/llvm/test/CodeGen/LoongArch/block-address.ll
+++ b/llvm/test/CodeGen/LoongArch/block-address.ll
@@ -8,11 +8,10 @@ define void @test_blockaddress() nounwind {
; LA32-LABEL: test_blockaddress:
; LA32: # %bb.0:
; LA32-NEXT: pcalau12i $a0, %pc_hi20(addr)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(addr)
; LA32-NEXT: pcalau12i $a1, %pc_hi20(.Ltmp0)
; LA32-NEXT: addi.w $a1, $a1, %pc_lo12(.Ltmp0)
-; LA32-NEXT: st.w $a1, $a0, 0
-; LA32-NEXT: ld.w $a0, $a0, 0
+; LA32-NEXT: st.w $a1, $a0, %pc_lo12(addr)
+; LA32-NEXT: ld.w $a0, $a0, %pc_lo12(addr)
; LA32-NEXT: jr $a0
; LA32-NEXT: .Ltmp0: # Block address taken
; LA32-NEXT: .LBB0_1: # %block
@@ -21,11 +20,10 @@ define void @test_blockaddress() nounwind {
; LA64-LABEL: test_blockaddress:
; LA64: # %bb.0:
; LA64-NEXT: pcalau12i $a0, %pc_hi20(addr)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(addr)
; LA64-NEXT: pcalau12i $a1, %pc_hi20(.Ltmp0)
; LA64-NEXT: addi.d $a1, $a1, %pc_lo12(.Ltmp0)
-; LA64-NEXT: st.d $a1, $a0, 0
-; LA64-NEXT: ld.d $a0, $a0, 0
+; LA64-NEXT: st.d $a1, $a0, %pc_lo12(addr)
+; LA64-NEXT: ld.d $a0, $a0, %pc_lo12(addr)
; LA64-NEXT: jr $a0
; LA64-NEXT: .Ltmp0: # Block address taken
; LA64-NEXT: .LBB0_1: # %block
diff --git a/llvm/test/CodeGen/LoongArch/calling-conv-lp64d.ll b/llvm/test/CodeGen/LoongArch/calling-conv-lp64d.ll
index cc6ba057019c65..34fbec03c535b0 100644
--- a/llvm/test/CodeGen/LoongArch/calling-conv-lp64d.ll
+++ b/llvm/test/CodeGen/LoongArch/calling-conv-lp64d.ll
@@ -64,26 +64,19 @@ define i64 @caller_double_in_gpr_exhausted_fprs() nounwind {
; CHECK-NEXT: addi.d $sp, $sp, -16
; CHECK-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI3_0)
-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI3_0)
-; CHECK-NEXT: fld.d $fa1, $a0, 0
+; CHECK-NEXT: fld.d $fa1, $a0, %pc_lo12(.LCPI3_0)
; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI3_1)
-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI3_1)
-; CHECK-NEXT: fld.d $fa2, $a0, 0
+; CHECK-NEXT: fld.d $fa2, $a0, %pc_lo12(.LCPI3_1)
; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI3_2)
-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI3_2)
-; CHECK-NEXT: fld.d $fa3, $a0, 0
+; CHECK-NEXT: fld.d $fa3, $a0, %pc_lo12(.LCPI3_2)
; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI3_3)
-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI3_3)
-; CHECK-NEXT: fld.d $fa4, $a0, 0
+; CHECK-NEXT: fld.d $fa4, $a0, %pc_lo12(.LCPI3_3)
; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI3_4)
-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI3_4)
-; CHECK-NEXT: fld.d $fa5, $a0, 0
+; CHECK-NEXT: fld.d $fa5, $a0, %pc_lo12(.LCPI3_4)
; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI3_5)
-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI3_5)
-; CHECK-NEXT: fld.d $fa6, $a0, 0
+; CHECK-NEXT: fld.d $fa6, $a0, %pc_lo12(.LCPI3_5)
; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI3_6)
-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI3_6)
-; CHECK-NEXT: fld.d $fa7, $a0, 0
+; CHECK-NEXT: fld.d $fa7, $a0, %pc_lo12(.LCPI3_6)
; CHECK-NEXT: addi.d $a0, $zero, 1
; CHECK-NEXT: movgr2fr.d $fa0, $a0
; CHECK-NEXT: ffint.d.l $fa0, $fa0
diff --git a/llvm/test/CodeGen/LoongArch/double-imm.ll b/llvm/test/CodeGen/LoongArch/double-imm.ll
index 3e89db3ec5c8cc..8d50b27907d72b 100644
--- a/llvm/test/CodeGen/LoongArch/double-imm.ll
+++ b/llvm/test/CodeGen/LoongArch/double-imm.ll
@@ -36,15 +36,13 @@ define double @f64_constant_pi() nounwind {
; LA32-LABEL: f64_constant_pi:
; LA32: # %bb.0:
; LA32-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_0)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI2_0)
-; LA32-NEXT: fld.d $fa0, $a0, 0
+; LA32-NEXT: fld.d $fa0, $a0, %pc_lo12(.LCPI2_0)
; LA32-NEXT: ret
;
; LA64-LABEL: f64_constant_pi:
; LA64: # %bb.0:
; LA64-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_0)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI2_0)
-; LA64-NEXT: fld.d $fa0, $a0, 0
+; LA64-NEXT: fld.d $fa0, $a0, %pc_lo12(.LCPI2_0)
; LA64-NEXT: ret
ret double 3.1415926535897931159979634685441851615905761718750
}
diff --git a/llvm/test/CodeGen/LoongArch/float-imm.ll b/llvm/test/CodeGen/LoongArch/float-imm.ll
index e2cbf4bf9b3e87..006a9e64b190de 100644
--- a/llvm/test/CodeGen/LoongArch/float-imm.ll
+++ b/llvm/test/CodeGen/LoongArch/float-imm.ll
@@ -34,15 +34,13 @@ define float @f32_constant_pi() nounwind {
; LA32-LABEL: f32_constant_pi:
; LA32: # %bb.0:
; LA32-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_0)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI2_0)
-; LA32-NEXT: fld.s $fa0, $a0, 0
+; LA32-NEXT: fld.s $fa0, $a0, %pc_lo12(.LCPI2_0)
; LA32-NEXT: ret
;
; LA64-LABEL: f32_constant_pi:
; LA64: # %bb.0:
; LA64-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_0)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI2_0)
-; LA64-NEXT: fld.s $fa0, $a0, 0
+; LA64-NEXT: fld.s $fa0, $a0, %pc_lo12(.LCPI2_0)
; LA64-NEXT: ret
ret float 3.14159274101257324218750
}
diff --git a/llvm/test/CodeGen/LoongArch/ghc-cc.ll b/llvm/test/CodeGen/LoongArch/ghc-cc.ll
index 735315d323a362..f99759b4b5ed56 100644
--- a/llvm/test/CodeGen/LoongArch/ghc-cc.ll
+++ b/llvm/test/CodeGen/LoongArch/ghc-cc.ll
@@ -27,56 +27,39 @@ define ghccc void @foo() nounwind {
; LA64-LABEL: foo:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(d4)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(d4)
-; LA64-NEXT: fld.d $fs7, $a0, 0
+; LA64-NEXT: fld.d $fs7, $a0, %pc_lo12(d4)
; LA64-NEXT: pcalau12i $a0, %pc_hi20(d3)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(d3)
-; LA64-NEXT: fld.d $fs6, $a0, 0
+; LA64-NEXT: fld.d $fs6, $a0, %pc_lo12(d3)
; LA64-NEXT: pcalau12i $a0, %pc_hi20(d2)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(d2)
-; LA64-NEXT: fld.d $fs5, $a0, 0
+; LA64-NEXT: fld.d $fs5, $a0, %pc_lo12(d2)
; LA64-NEXT: pcalau12i $a0, %pc_hi20(d1)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(d1)
-; LA64-NEXT: fld.d $fs4, $a0, 0
+; LA64-NEXT: fld.d $fs4, $a0, %pc_lo12(d1)
; LA64-NEXT: pcalau12i $a0, %pc_hi20(f4)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(f4)
-; LA64-NEXT: fld.s $fs3, $a0, 0
+; LA64-NEXT: fld.s $fs3, $a0, %pc_lo12(f4)
; LA64-NEXT: pcalau12i $a0, %pc_hi20(f3)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(f3)
-; LA64-NEXT: fld.s $fs2, $a0, 0
+; LA64-NEXT: fld.s $fs2, $a0, %pc_lo12(f3)
; LA64-NEXT: pcalau12i $a0, %pc_hi20(f2)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(f2)
-; LA64-NEXT: fld.s $fs1, $a0, 0
+; LA64-NEXT: fld.s $fs1, $a0, %pc_lo12(f2)
; LA64-NEXT: pcalau12i $a0, %pc_hi20(f1)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(f1)
-; LA64-NEXT: fld.s $fs0, $a0, 0
+; LA64-NEXT: fld.s $fs0, $a0, %pc_lo12(f1)
; LA64-NEXT: pcalau12i $a0, %pc_hi20(splim)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(splim)
-; LA64-NEXT: ld.d $s8, $a0, 0
+; LA64-NEXT: ld.d $s8, $a0, %pc_lo12(splim)
; LA64-NEXT: pcalau12i $a0, %pc_hi20(r5)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(r5)
-; LA64-NEXT: ld.d $s7, $a0, 0
+; LA64-NEXT: ld.d $s7, $a0, %pc_lo12(r5)
; LA64-NEXT: pcalau12i $a0, %pc_hi20(r4)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(r4)
-; LA64-NEXT: ld.d $s6, $a0, 0
+; LA64-NEXT: ld.d $s6, $a0, %pc_lo12(r4)
; LA64-NEXT: pcalau12i $a0, %pc_hi20(r3)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(r3)
-; LA64-NEXT: ld.d $s5, $a0, 0
+; LA64-NEXT: ld.d $s5, $a0, %pc_lo12(r3)
; LA64-NEXT: pcalau12i $a0, %pc_hi20(r2)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(r2)
-; LA64-NEXT: ld.d $s4, $a0, 0
+; LA64-NEXT: ld.d $s4, $a0, %pc_lo12(r2)
; LA64-NEXT: pcalau12i $a0, %pc_hi20(r1)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(r1)
-; LA64-NEXT: ld.d $s3, $a0, 0
+; LA64-NEXT: ld.d $s3, $a0, %pc_lo12(r1)
; LA64-NEXT: pcalau12i $a0, %pc_hi20(hp)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(hp)
-; LA64-NEXT: ld.d $s2, $a0, 0
+; LA64-NEXT: ld.d $s2, $a0, %pc_lo12(hp)
; LA64-NEXT: pcalau12i $a0, %pc_hi20(sp)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(sp)
-; LA64-NEXT: ld.d $s1, $a0, 0
+; LA64-NEXT: ld.d $s1, $a0, %pc_lo12(sp)
; LA64-NEXT: pcalau12i $a0, %pc_hi20(base)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(base)
-; LA64-NEXT: ld.d $s0, $a0, 0
+; LA64-NEXT: ld.d $s0, $a0, %pc_lo12(base)
; LA64-NEXT: b %plt(bar)
entry:
diff --git a/llvm/test/CodeGen/LoongArch/global-address.ll b/llvm/test/CodeGen/LoongArch/global-address.ll
index 2423dd81a4d3a8..89ea48c3b1cbf6 100644
--- a/llvm/test/CodeGen/LoongArch/global-address.ll
+++ b/llvm/test/CodeGen/LoongArch/global-address.ll
@@ -16,8 +16,7 @@ define void @foo() nounwind {
; LA32NOPIC-NEXT: ld.w $a0, $a0, %got_pc_lo12(G)
; LA32NOPIC-NEXT: ld.w $zero, $a0, 0
; LA32NOPIC-NEXT: pcalau12i $a0, %pc_hi20(g)
-; LA32NOPIC-NEXT: addi.w $a0, $a0, %pc_lo12(g)
-; LA32NOPIC-NEXT: ld.w $zero, $a0, 0
+; LA32NOPIC-NEXT: ld.w $zero, $a0, %pc_lo12(g)
; LA32NOPIC-NEXT: ret
;
; LA32PIC-LABEL: foo:
@@ -26,8 +25,7 @@ define void @foo() nounwind {
; LA32PIC-NEXT: ld.w $a0, $a0, %got_pc_lo12(G)
; LA32PIC-NEXT: ld.w $zero, $a0, 0
; LA32PIC-NEXT: pcalau12i $a0, %pc_hi20(.Lg$local)
-; LA32PIC-NEXT: addi.w $a0, $a0, %pc_lo12(.Lg$local)
-; LA32PIC-NEXT: ld.w $zero, $a0, 0
+; LA32PIC-NEXT: ld.w $zero, $a0, %pc_lo12(.Lg$local)
; LA32PIC-NEXT: ret
;
; LA64NOPIC-LABEL: foo:
@@ -36,8 +34,7 @@ define void @foo() nounwind {
; LA64NOPIC-NEXT: ld.d $a0, $a0, %got_pc_lo12(G)
; LA64NOPIC-NEXT: ld.w $zero, $a0, 0
; LA64NOPIC-NEXT: pcalau12i $a0, %pc_hi20(g)
-; LA64NOPIC-NEXT: addi.d $a0, $a0, %pc_lo12(g)
-; LA64NOPIC-NEXT: ld.w $zero, $a0, 0
+; LA64NOPIC-NEXT: ld.w $zero, $a0, %pc_lo12(g)
; LA64NOPIC-NEXT: ret
;
; LA64PIC-LABEL: foo:
@@ -46,8 +43,7 @@ define void @foo() nounwind {
; LA64PIC-NEXT: ld.d $a0, $a0, %got_pc_lo12(G)
; LA64PIC-NEXT: ld.w $zero, $a0, 0
; LA64PIC-NEXT: pcalau12i $a0, %pc_hi20(.Lg$local)
-; LA64PIC-NEXT: addi.d $a0, $a0, %pc_lo12(.Lg$local)
-; LA64PIC-NEXT: ld.w $zero, $a0, 0
+; LA64PIC-NEXT: ld.w $zero, $a0, %pc_lo12(.Lg$local)
; LA64PIC-NEXT: ret
;
; LA64LARGENOPIC-LABEL: foo:
@@ -62,8 +58,7 @@ define void @foo() nounwind {
; LA64LARGENOPIC-NEXT: addi.d $a1, $zero, %pc_lo12(g)
; LA64LARGENOPIC-NEXT: lu32i.d $a1, %pc64_lo20(g)
; LA64LARGENOPIC-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g)
-; LA64LARGENOPIC-NEXT: add.d $a0, $a1, $a0
-; LA64LARGENOPIC-NEXT: ld.w $zero, $a0, 0
+; LA64LARGENOPIC-NEXT: ldx.w $zero, $a1, $a0
; LA64LARGENOPIC-NEXT: ret
;
; LA64LARGEPIC-LABEL: foo:
@@ -78,8 +73,7 @@ define void @foo() nounwind {
; LA64LARGEPIC-NEXT: addi.d $a1, $zero, %pc_lo12(.Lg$local)
; LA64LARGEPIC-NEXT: lu32i.d $a1, %pc64_lo20(.Lg$local)
; LA64LARGEPIC-NEXT: lu52i.d $a1, $a1, %pc64_hi12(.Lg$local)
-; LA64LARGEPIC-NEXT: add.d $a0, $a1, $a0
-; LA64LARGEPIC-NEXT: ld.w $zero, $a0, 0
+; LA64LARGEPIC-NEXT: ldx.w $zero, $a1, $a0
; LA64LARGEPIC-NEXT: ret
%V = load volatile i32, ptr @G
%v = load volatile i32, ptr @g
diff --git a/llvm/test/CodeGen/LoongArch/global-variable-code-model.ll b/llvm/test/CodeGen/LoongArch/global-variable-code-model.ll
index 2b7a862ecde11e..04f6a635778eba 100644
--- a/llvm/test/CodeGen/LoongArch/global-variable-code-model.ll
+++ b/llvm/test/CodeGen/LoongArch/global-variable-code-model.ll
@@ -7,8 +7,7 @@ define dso_local signext i32 @local_small() #0 {
; CHECK-LABEL: local_small:
; CHECK: # %bb.0:
; CHECK-NEXT: pcalau12i $a0, %pc_hi20(a)
-; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(a)
-; CHECK-NEXT: ld.w $a0, $a0, 0
+; CHECK-NEXT: ld.w $a0, $a0, %pc_lo12(a)
; CHECK-NEXT: ret
%1 = load i32, ptr @a, align 4
ret i32 %1
@@ -23,8 +22,7 @@ define dso_local signext i32 @local_large() #0 {
; CHECK-NEXT: addi.d $a1, $zero, %pc_lo12(b)
; CHECK-NEXT: lu32i.d $a1, %pc64_lo20(b)
; CHECK-NEXT: lu52i.d $a1, $a1, %pc64_hi12(b)
-; CHECK-NEXT: add.d $a0, $a1, $a0
-; CHECK-NEXT: ld.w $a0, $a0, 0
+; CHECK-NEXT: ldx.w $a0, $a1, $a0
; CHECK-NEXT: ret
%1 = load i32, ptr @b, align 4
ret i32 %1
diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-f.ll b/llvm/test/CodeGen/LoongArch/inline-asm-constraint-f.ll
index fa675e4bbb3243..be9ea29b54c332 100644
--- a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-f.ll
+++ b/llvm/test/CodeGen/LoongArch/inline-asm-constraint-f.ll
@@ -10,8 +10,7 @@ define double @constraint_f_double(double %a) nounwind {
; LA32-LABEL: constraint_f_double:
; LA32: # %bb.0:
; LA32-NEXT: pcalau12i $a0, %pc_hi20(gd)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(gd)
-; LA32-NEXT: fld.d $fa1, $a0, 0
+; LA32-NEXT: fld.d $fa1, $a0, %pc_lo12(gd)
; LA32-NEXT: #APP
; LA32-NEXT: fadd.d $fa0, $fa0, $fa1
; LA32-NEXT: #NO_APP
@@ -20,8 +19,7 @@ define double @constraint_f_double(double %a) nounwind {
; LA64-LABEL: constraint_f_double:
; LA64: # %bb.0:
; LA64-NEXT: pcalau12i $a0, %pc_hi20(gd)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(gd)
-; LA64-NEXT: fld.d $fa1, $a0, 0
+; LA64-NEXT: fld.d $fa1, $a0, %pc_lo12(gd)
; LA64-NEXT: #APP
; LA64-NEXT: fadd.d $fa0, $fa0, $fa1
; LA64-NEXT: #NO_APP
diff --git a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-m.ll b/llvm/test/CodeGen/LoongArch/inline-asm-constraint-m.ll
index becb3cae46b8c0..565ccdbe6880fb 100644
--- a/llvm/test/CodeGen/LoongArch/inline-asm-constraint-m.ll
+++ b/llvm/test/CodeGen/LoongArch/inline-asm-constraint-m.ll
@@ -147,19 +147,17 @@ define i32 @m_offset_2048(ptr %p) nounwind {
define i32 @m_addr_pcrel() nounwind {
; LA32-LABEL: m_addr_pcrel:
; LA32: # %bb.0:
-; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_i32)
-; LA32-NEXT: addi.w $a1, $a0, %pc_lo12(g_i32)
+; LA32-NEXT: pcalau12i $a1, %pc_hi20(g_i32)
; LA32-NEXT: #APP
-; LA32-NEXT: ld.w $a0, $a1, 0
+; LA32-NEXT: ld.w $a0, $a1, %pc_lo12(g_i32)
; LA32-NEXT: #NO_APP
; LA32-NEXT: ret
;
; LA64-LABEL: m_addr_pcrel:
; LA64: # %bb.0:
-; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_i32)
-; LA64-NEXT: addi.d $a1, $a0, %pc_lo12(g_i32)
+; LA64-NEXT: pcalau12i $a1, %pc_hi20(g_i32)
; LA64-NEXT: #APP
-; LA64-NEXT: ld.w $a0, $a1, 0
+; LA64-NEXT: ld.w $a0, $a1, %pc_lo12(g_i32)
; LA64-NEXT: #NO_APP
; LA64-NEXT: ret
%1 = tail call i32 asm sideeffect "ld.w $0, $1", "=&r,*m"(ptr nonnull elementtype(i32) @g_i32)
diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw-fp.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw-fp.ll
index 193fa6c08600ae..7e320d9245f1c2 100644
--- a/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw-fp.ll
+++ b/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw-fp.ll
@@ -79,8 +79,7 @@ define float @float_fsub_acquire(ptr %p) nounwind {
; LA64F: # %bb.0:
; LA64F-NEXT: fld.s $fa0, $a0, 0
; LA64F-NEXT: pcalau12i $a1, %pc_hi20(.LCPI1_0)
-; LA64F-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI1_0)
-; LA64F-NEXT: fld.s $fa1, $a1, 0
+; LA64F-NEXT: fld.s $fa1, $a1, %pc_lo12(.LCPI1_0)
; LA64F-NEXT: .p2align 4, , 16
; LA64F-NEXT: .LBB1_1: # %atomicrmw.start
; LA64F-NEXT: # =>This Loop Header: Depth=1
@@ -113,8 +112,7 @@ define float @float_fsub_acquire(ptr %p) nounwind {
; LA64D: # %bb.0:
; LA64D-NEXT: fld.s $fa0, $a0, 0
; LA64D-NEXT: pcalau12i $a1, %pc_hi20(.LCPI1_0)
-; LA64D-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI1_0)
-; LA64D-NEXT: fld.s $fa1, $a1, 0
+; LA64D-NEXT: fld.s $fa1, $a1, %pc_lo12(.LCPI1_0)
; LA64D-NEXT: .p2align 4, , 16
; LA64D-NEXT: .LBB1_1: # %atomicrmw.start
; LA64D-NEXT: # =>This Loop Header: Depth=1
@@ -413,8 +411,7 @@ define double @double_fsub_acquire(ptr %p) nounwind {
; LA64D-NEXT: move $fp, $a0
; LA64D-NEXT: fld.d $fa0, $a0, 0
; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI5_0)
-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI5_0)
-; LA64D-NEXT: fld.d $fs0, $a0, 0
+; LA64D-NEXT: fld.d $fs0, $a0, %pc_lo12(.LCPI5_0)
; LA64D-NEXT: .p2align 4, , 16
; LA64D-NEXT: .LBB5_1: # %atomicrmw.start
; LA64D-NEXT: # =>This Inner Loop Header: Depth=1
@@ -665,8 +662,7 @@ define float @float_fsub_release(ptr %p) nounwind {
; LA64F: # %bb.0:
; LA64F-NEXT: fld.s $fa0, $a0, 0
; LA64F-NEXT: pcalau12i $a1, %pc_hi20(.LCPI9_0)
-; LA64F-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI9_0)
-; LA64F-NEXT: fld.s $fa1, $a1, 0
+; LA64F-NEXT: fld.s $fa1, $a1, %pc_lo12(.LCPI9_0)
; LA64F-NEXT: .p2align 4, , 16
; LA64F-NEXT: .LBB9_1: # %atomicrmw.start
; LA64F-NEXT: # =>This Loop Header: Depth=1
@@ -699,8 +695,7 @@ define float @float_fsub_release(ptr %p) nounwind {
; LA64D: # %bb.0:
; LA64D-NEXT: fld.s $fa0, $a0, 0
; LA64D-NEXT: pcalau12i $a1, %pc_hi20(.LCPI9_0)
-; LA64D-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI9_0)
-; LA64D-NEXT: fld.s $fa1, $a1, 0
+; LA64D-NEXT: fld.s $fa1, $a1, %pc_lo12(.LCPI9_0)
; LA64D-NEXT: .p2align 4, , 16
; LA64D-NEXT: .LBB9_1: # %atomicrmw.start
; LA64D-NEXT: # =>This Loop Header: Depth=1
@@ -999,8 +994,7 @@ define double @double_fsub_release(ptr %p) nounwind {
; LA64D-NEXT: move $fp, $a0
; LA64D-NEXT: fld.d $fa0, $a0, 0
; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI13_0)
-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI13_0)
-; LA64D-NEXT: fld.d $fs0, $a0, 0
+; LA64D-NEXT: fld.d $fs0, $a0, %pc_lo12(.LCPI13_0)
; LA64D-NEXT: .p2align 4, , 16
; LA64D-NEXT: .LBB13_1: # %atomicrmw.start
; LA64D-NEXT: # =>This Inner Loop Header: Depth=1
@@ -1251,8 +1245,7 @@ define float @float_fsub_acq_rel(ptr %p) nounwind {
; LA64F: # %bb.0:
; LA64F-NEXT: fld.s $fa0, $a0, 0
; LA64F-NEXT: pcalau12i $a1, %pc_hi20(.LCPI17_0)
-; LA64F-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI17_0)
-; LA64F-NEXT: fld.s $fa1, $a1, 0
+; LA64F-NEXT: fld.s $fa1, $a1, %pc_lo12(.LCPI17_0)
; LA64F-NEXT: .p2align 4, , 16
; LA64F-NEXT: .LBB17_1: # %atomicrmw.start
; LA64F-NEXT: # =>This Loop Header: Depth=1
@@ -1285,8 +1278,7 @@ define float @float_fsub_acq_rel(ptr %p) nounwind {
; LA64D: # %bb.0:
; LA64D-NEXT: fld.s $fa0, $a0, 0
; LA64D-NEXT: pcalau12i $a1, %pc_hi20(.LCPI17_0)
-; LA64D-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI17_0)
-; LA64D-NEXT: fld.s $fa1, $a1, 0
+; LA64D-NEXT: fld.s $fa1, $a1, %pc_lo12(.LCPI17_0)
; LA64D-NEXT: .p2align 4, , 16
; LA64D-NEXT: .LBB17_1: # %atomicrmw.start
; LA64D-NEXT: # =>This Loop Header: Depth=1
@@ -1585,8 +1577,7 @@ define double @double_fsub_acq_rel(ptr %p) nounwind {
; LA64D-NEXT: move $fp, $a0
; LA64D-NEXT: fld.d $fa0, $a0, 0
; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI21_0)
-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI21_0)
-; LA64D-NEXT: fld.d $fs0, $a0, 0
+; LA64D-NEXT: fld.d $fs0, $a0, %pc_lo12(.LCPI21_0)
; LA64D-NEXT: .p2align 4, , 16
; LA64D-NEXT: .LBB21_1: # %atomicrmw.start
; LA64D-NEXT: # =>This Inner Loop Header: Depth=1
@@ -1837,8 +1828,7 @@ define float @float_fsub_seq_cst(ptr %p) nounwind {
; LA64F: # %bb.0:
; LA64F-NEXT: fld.s $fa0, $a0, 0
; LA64F-NEXT: pcalau12i $a1, %pc_hi20(.LCPI25_0)
-; LA64F-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI25_0)
-; LA64F-NEXT: fld.s $fa1, $a1, 0
+; LA64F-NEXT: fld.s $fa1, $a1, %pc_lo12(.LCPI25_0)
; LA64F-NEXT: .p2align 4, , 16
; LA64F-NEXT: .LBB25_1: # %atomicrmw.start
; LA64F-NEXT: # =>This Loop Header: Depth=1
@@ -1871,8 +1861,7 @@ define float @float_fsub_seq_cst(ptr %p) nounwind {
; LA64D: # %bb.0:
; LA64D-NEXT: fld.s $fa0, $a0, 0
; LA64D-NEXT: pcalau12i $a1, %pc_hi20(.LCPI25_0)
-; LA64D-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI25_0)
-; LA64D-NEXT: fld.s $fa1, $a1, 0
+; LA64D-NEXT: fld.s $fa1, $a1, %pc_lo12(.LCPI25_0)
; LA64D-NEXT: .p2align 4, , 16
; LA64D-NEXT: .LBB25_1: # %atomicrmw.start
; LA64D-NEXT: # =>This Loop Header: Depth=1
@@ -2171,8 +2160,7 @@ define double @double_fsub_seq_cst(ptr %p) nounwind {
; LA64D-NEXT: move $fp, $a0
; LA64D-NEXT: fld.d $fa0, $a0, 0
; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI29_0)
-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI29_0)
-; LA64D-NEXT: fld.d $fs0, $a0, 0
+; LA64D-NEXT: fld.d $fs0, $a0, %pc_lo12(.LCPI29_0)
; LA64D-NEXT: .p2align 4, , 16
; LA64D-NEXT: .LBB29_1: # %atomicrmw.start
; LA64D-NEXT: # =>This Inner Loop Header: Depth=1
@@ -2423,8 +2411,7 @@ define float @float_fsub_monotonic(ptr %p) nounwind {
; LA64F: # %bb.0:
; LA64F-NEXT: fld.s $fa0, $a0, 0
; LA64F-NEXT: pcalau12i $a1, %pc_hi20(.LCPI33_0)
-; LA64F-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI33_0)
-; LA64F-NEXT: fld.s $fa1, $a1, 0
+; LA64F-NEXT: fld.s $fa1, $a1, %pc_lo12(.LCPI33_0)
; LA64F-NEXT: .p2align 4, , 16
; LA64F-NEXT: .LBB33_1: # %atomicrmw.start
; LA64F-NEXT: # =>This Loop Header: Depth=1
@@ -2457,8 +2444,7 @@ define float @float_fsub_monotonic(ptr %p) nounwind {
; LA64D: # %bb.0:
; LA64D-NEXT: fld.s $fa0, $a0, 0
; LA64D-NEXT: pcalau12i $a1, %pc_hi20(.LCPI33_0)
-; LA64D-NEXT: addi.d $a1, $a1, %pc_lo12(.LCPI33_0)
-; LA64D-NEXT: fld.s $fa1, $a1, 0
+; LA64D-NEXT: fld.s $fa1, $a1, %pc_lo12(.LCPI33_0)
; LA64D-NEXT: .p2align 4, , 16
; LA64D-NEXT: .LBB33_1: # %atomicrmw.start
; LA64D-NEXT: # =>This Loop Header: Depth=1
@@ -2757,8 +2743,7 @@ define double @double_fsub_monotonic(ptr %p) nounwind {
; LA64D-NEXT: move $fp, $a0
; LA64D-NEXT: fld.d $fa0, $a0, 0
; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI37_0)
-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI37_0)
-; LA64D-NEXT: fld.d $fs0, $a0, 0
+; LA64D-NEXT: fld.d $fs0, $a0, %pc_lo12(.LCPI37_0)
; LA64D-NEXT: .p2align 4, , 16
; LA64D-NEXT: .LBB37_1: # %atomicrmw.start
; LA64D-NEXT: # =>This Inner Loop Header: Depth=1
diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll
index ef117f97488715..8d08942c314aa4 100644
--- a/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll
+++ b/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll
@@ -117,8 +117,7 @@ define i32 @convert_double_to_u32(double %a) nounwind {
; LA32-LABEL: convert_double_to_u32:
; LA32: # %bb.0:
; LA32-NEXT: pcalau12i $a0, %pc_hi20(.LCPI7_0)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI7_0)
-; LA32-NEXT: fld.d $fa1, $a0, 0
+; LA32-NEXT: fld.d $fa1, $a0, %pc_lo12(.LCPI7_0)
; LA32-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1
; LA32-NEXT: fsub.d $fa1, $fa0, $fa1
; LA32-NEXT: ftintrz.w.d $fa1, $fa1
@@ -174,8 +173,7 @@ define i64 @convert_double_to_u64(double %a) nounwind {
; LA64-LABEL: convert_double_to_u64:
; LA64: # %bb.0:
; LA64-NEXT: pcalau12i $a0, %pc_hi20(.LCPI9_0)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI9_0)
-; LA64-NEXT: fld.d $fa1, $a0, 0
+; LA64-NEXT: fld.d $fa1, $a0, %pc_lo12(.LCPI9_0)
; LA64-NEXT: fcmp.clt.d $fcc0, $fa0, $fa1
; LA64-NEXT: fsub.d $fa1, $fa0, $fa1
; LA64-NEXT: ftintrz.l.d $fa1, $fa1
@@ -234,8 +232,7 @@ define double @convert_u32_to_double(i32 %a) nounwind {
; LA32-NEXT: st.w $a0, $sp, 8
; LA32-NEXT: fld.d $fa0, $sp, 8
; LA32-NEXT: pcalau12i $a0, %pc_hi20(.LCPI12_0)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI12_0)
-; LA32-NEXT: fld.d $fa1, $a0, 0
+; LA32-NEXT: fld.d $fa1, $a0, %pc_lo12(.LCPI12_0)
; LA32-NEXT: fsub.d $fa0, $fa0, $fa1
; LA32-NEXT: addi.w $sp, $sp, 16
; LA32-NEXT: ret
@@ -264,8 +261,7 @@ define double @convert_u64_to_double(i64 %a) nounwind {
; LA64: # %bb.0:
; LA64-NEXT: srli.d $a1, $a0, 32
; LA64-NEXT: pcalau12i $a2, %pc_hi20(.LCPI13_0)
-; LA64-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI13_0)
-; LA64-NEXT: fld.d $fa0, $a2, 0
+; LA64-NEXT: fld.d $fa0, $a2, %pc_lo12(.LCPI13_0)
; LA64-NEXT: lu52i.d $a2, $zero, 1107
; LA64-NEXT: or $a1, $a1, $a2
; LA64-NEXT: movgr2fr.d $fa1, $a1
diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll
index b01b84ba385ec8..b7de5a592c3598 100644
--- a/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll
+++ b/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll
@@ -182,8 +182,7 @@ define i32 @convert_float_to_u32(float %a) nounwind {
; LA32F-LABEL: convert_float_to_u32:
; LA32F: # %bb.0:
; LA32F-NEXT: pcalau12i $a0, %pc_hi20(.LCPI6_0)
-; LA32F-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI6_0)
-; LA32F-NEXT: fld.s $fa1, $a0, 0
+; LA32F-NEXT: fld.s $fa1, $a0, %pc_lo12(.LCPI6_0)
; LA32F-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1
; LA32F-NEXT: fsub.s $fa1, $fa0, $fa1
; LA32F-NEXT: ftintrz.w.s $fa1, $fa1
@@ -201,8 +200,7 @@ define i32 @convert_float_to_u32(float %a) nounwind {
; LA32D-LABEL: convert_float_to_u32:
; LA32D: # %bb.0:
; LA32D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI6_0)
-; LA32D-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI6_0)
-; LA32D-NEXT: fld.s $fa1, $a0, 0
+; LA32D-NEXT: fld.s $fa1, $a0, %pc_lo12(.LCPI6_0)
; LA32D-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1
; LA32D-NEXT: fsub.s $fa1, $fa0, $fa1
; LA32D-NEXT: ftintrz.w.s $fa1, $fa1
@@ -220,8 +218,7 @@ define i32 @convert_float_to_u32(float %a) nounwind {
; LA64F-LABEL: convert_float_to_u32:
; LA64F: # %bb.0:
; LA64F-NEXT: pcalau12i $a0, %pc_hi20(.LCPI6_0)
-; LA64F-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI6_0)
-; LA64F-NEXT: fld.s $fa1, $a0, 0
+; LA64F-NEXT: fld.s $fa1, $a0, %pc_lo12(.LCPI6_0)
; LA64F-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1
; LA64F-NEXT: fsub.s $fa1, $fa0, $fa1
; LA64F-NEXT: ftintrz.w.s $fa1, $fa1
@@ -267,8 +264,7 @@ define i64 @convert_float_to_u64(float %a) nounwind {
; LA64F-LABEL: convert_float_to_u64:
; LA64F: # %bb.0:
; LA64F-NEXT: pcalau12i $a0, %pc_hi20(.LCPI7_0)
-; LA64F-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI7_0)
-; LA64F-NEXT: fld.s $fa1, $a0, 0
+; LA64F-NEXT: fld.s $fa1, $a0, %pc_lo12(.LCPI7_0)
; LA64F-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1
; LA64F-NEXT: fsub.s $fa1, $fa0, $fa1
; LA64F-NEXT: ftintrz.w.s $fa1, $fa1
@@ -286,8 +282,7 @@ define i64 @convert_float_to_u64(float %a) nounwind {
; LA64D-LABEL: convert_float_to_u64:
; LA64D: # %bb.0:
; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI7_0)
-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI7_0)
-; LA64D-NEXT: fld.s $fa1, $a0, 0
+; LA64D-NEXT: fld.s $fa1, $a0, %pc_lo12(.LCPI7_0)
; LA64D-NEXT: fcmp.clt.s $fcc0, $fa0, $fa1
; LA64D-NEXT: fsub.s $fa1, $fa0, $fa1
; LA64D-NEXT: ftintrz.l.s $fa1, $fa1
@@ -506,8 +501,7 @@ define float @convert_u32_to_float(i32 %a) nounwind {
; LA32D-NEXT: st.w $a0, $sp, 8
; LA32D-NEXT: fld.d $fa0, $sp, 8
; LA32D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI14_0)
-; LA32D-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI14_0)
-; LA32D-NEXT: fld.d $fa1, $a0, 0
+; LA32D-NEXT: fld.d $fa1, $a0, %pc_lo12(.LCPI14_0)
; LA32D-NEXT: fsub.d $fa0, $fa0, $fa1
; LA32D-NEXT: fcvt.s.d $fa0, $fa0
; LA32D-NEXT: addi.w $sp, $sp, 16
diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll
index 26f44adc613586..772ae8d81a88bf 100644
--- a/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll
+++ b/llvm/test/CodeGen/LoongArch/ir-instruction/load-store.ll
@@ -11,38 +11,34 @@
define i32 @load_store_global() nounwind {
; LA32NOPIC-LABEL: load_store_global:
; LA32NOPIC: # %bb.0:
-; LA32NOPIC-NEXT: pcalau12i $a0, %pc_hi20(G)
-; LA32NOPIC-NEXT: addi.w $a1, $a0, %pc_lo12(G)
-; LA32NOPIC-NEXT: ld.w $a0, $a1, 0
+; LA32NOPIC-NEXT: pcalau12i $a1, %pc_hi20(G)
+; LA32NOPIC-NEXT: ld.w $a0, $a1, %pc_lo12(G)
; LA32NOPIC-NEXT: addi.w $a0, $a0, 1
-; LA32NOPIC-NEXT: st.w $a0, $a1, 0
+; LA32NOPIC-NEXT: st.w $a0, $a1, %pc_lo12(G)
; LA32NOPIC-NEXT: ret
;
; LA32PIC-LABEL: load_store_global:
; LA32PIC: # %bb.0:
-; LA32PIC-NEXT: pcalau12i $a0, %pc_hi20(.LG$local)
-; LA32PIC-NEXT: addi.w $a1, $a0, %pc_lo12(.LG$local)
-; LA32PIC-NEXT: ld.w $a0, $a1, 0
+; LA32PIC-NEXT: pcalau12i $a1, %pc_hi20(.LG$local)
+; LA32PIC-NEXT: ld.w $a0, $a1, %pc_lo12(.LG$local)
; LA32PIC-NEXT: addi.w $a0, $a0, 1
-; LA32PIC-NEXT: st.w $a0, $a1, 0
+; LA32PIC-NEXT: st.w $a0, $a1, %pc_lo12(.LG$local)
; LA32PIC-NEXT: ret
;
; LA64NOPIC-LABEL: load_store_global:
; LA64NOPIC: # %bb.0:
-; LA64NOPIC-NEXT: pcalau12i $a0, %pc_hi20(G)
-; LA64NOPIC-NEXT: addi.d $a1, $a0, %pc_lo12(G)
-; LA64NOPIC-NEXT: ld.w $a0, $a1, 0
+; LA64NOPIC-NEXT: pcalau12i $a1, %pc_hi20(G)
+; LA64NOPIC-NEXT: ld.w $a0, $a1, %pc_lo12(G)
; LA64NOPIC-NEXT: addi.w $a0, $a0, 1
-; LA64NOPIC-NEXT: st.w $a0, $a1, 0
+; LA64NOPIC-NEXT: st.w $a0, $a1, %pc_lo12(G)
; LA64NOPIC-NEXT: ret
;
; LA64PIC-LABEL: load_store_global:
; LA64PIC: # %bb.0:
-; LA64PIC-NEXT: pcalau12i $a0, %pc_hi20(.LG$local)
-; LA64PIC-NEXT: addi.d $a1, $a0, %pc_lo12(.LG$local)
-; LA64PIC-NEXT: ld.w $a0, $a1, 0
+; LA64PIC-NEXT: pcalau12i $a1, %pc_hi20(.LG$local)
+; LA64PIC-NEXT: ld.w $a0, $a1, %pc_lo12(.LG$local)
; LA64PIC-NEXT: addi.w $a0, $a0, 1
-; LA64PIC-NEXT: st.w $a0, $a1, 0
+; LA64PIC-NEXT: st.w $a0, $a1, %pc_lo12(.LG$local)
; LA64PIC-NEXT: ret
%v = load i32, ptr @G
%sum = add i32 %v, 1
diff --git a/llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll b/llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll
index 5248468b6027d5..ba72ef5bd7ba4b 100644
--- a/llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll
+++ b/llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll
@@ -15,11 +15,10 @@ define void @test_la_pcrel(i32 signext %n) {
; LA32: # %bb.0: # %entry
; LA32-NEXT: move $a1, $zero
; LA32-NEXT: pcalau12i $a2, %pc_hi20(l)
-; LA32-NEXT: addi.w $a2, $a2, %pc_lo12(l)
; LA32-NEXT: .p2align 4, , 16
; LA32-NEXT: .LBB0_1: # %loop
; LA32-NEXT: # =>This Inner Loop Header: Depth=1
-; LA32-NEXT: ld.w $zero, $a2, 0
+; LA32-NEXT: ld.w $zero, $a2, %pc_lo12(l)
; LA32-NEXT: addi.w $a1, $a1, 1
; LA32-NEXT: blt $a1, $a0, .LBB0_1
; LA32-NEXT: # %bb.2: # %ret
@@ -29,11 +28,10 @@ define void @test_la_pcrel(i32 signext %n) {
; LA64: # %bb.0: # %entry
; LA64-NEXT: move $a1, $zero
; LA64-NEXT: pcalau12i $a2, %pc_hi20(l)
-; LA64-NEXT: addi.d $a2, $a2, %pc_lo12(l)
; LA64-NEXT: .p2align 4, , 16
; LA64-NEXT: .LBB0_1: # %loop
; LA64-NEXT: # =>This Inner Loop Header: Depth=1
-; LA64-NEXT: ld.w $zero, $a2, 0
+; LA64-NEXT: ld.w $zero, $a2, %pc_lo12(l)
; LA64-NEXT: addi.w $a1, $a1, 1
; LA64-NEXT: blt $a1, $a0, .LBB0_1
; LA64-NEXT: # %bb.2: # %ret
@@ -41,18 +39,17 @@ define void @test_la_pcrel(i32 signext %n) {
;
; LA64LARGE-LABEL: test_la_pcrel:
; LA64LARGE: # %bb.0: # %entry
-; LA64LARGE-NEXT: pcalau12i $a2, %pc_hi20(l)
-; LA64LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(l)
-; LA64LARGE-NEXT: lu32i.d $a1, %pc64_lo20(l)
-; LA64LARGE-NEXT: lu52i.d $a3, $a1, %pc64_hi12(l)
-; LA64LARGE-NEXT: move $a1, $zero
-; LA64LARGE-NEXT: add.d $a2, $a3, $a2
+; LA64LARGE-NEXT: pcalau12i $a1, %pc_hi20(l)
+; LA64LARGE-NEXT: addi.d $a2, $zero, %pc_lo12(l)
+; LA64LARGE-NEXT: lu32i.d $a2, %pc64_lo20(l)
+; LA64LARGE-NEXT: lu52i.d $a2, $a2, %pc64_hi12(l)
+; LA64LARGE-NEXT: move $a3, $zero
; LA64LARGE-NEXT: .p2align 4, , 16
; LA64LARGE-NEXT: .LBB0_1: # %loop
; LA64LARGE-NEXT: # =>This Inner Loop Header: Depth=1
-; LA64LARGE-NEXT: ld.w $zero, $a2, 0
-; LA64LARGE-NEXT: addi.w $a1, $a1, 1
-; LA64LARGE-NEXT: blt $a1, $a0, .LBB0_1
+; LA64LARGE-NEXT: ldx.w $zero, $a2, $a1
+; LA64LARGE-NEXT: addi.w $a3, $a3, 1
+; LA64LARGE-NEXT: blt $a3, $a0, .LBB0_1
; LA64LARGE-NEXT: # %bb.2: # %ret
; LA64LARGE-NEXT: ret
entry:
diff --git a/llvm/test/CodeGen/LoongArch/merge-base-offset.ll b/llvm/test/CodeGen/LoongArch/merge-base-offset.ll
index 48d18dbedcaf26..32a4c4bdd1508a 100644
--- a/llvm/test/CodeGen/LoongArch/merge-base-offset.ll
+++ b/llvm/test/CodeGen/LoongArch/merge-base-offset.ll
@@ -12,15 +12,13 @@ define dso_local signext i8 @load_s8() nounwind {
; LA32-LABEL: load_s8:
; LA32: # %bb.0: # %entry
; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_i8)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_i8)
-; LA32-NEXT: ld.b $a0, $a0, 0
+; LA32-NEXT: ld.b $a0, $a0, %pc_lo12(g_i8)
; LA32-NEXT: ret
;
; LA64-LABEL: load_s8:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_i8)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_i8)
-; LA64-NEXT: ld.b $a0, $a0, 0
+; LA64-NEXT: ld.b $a0, $a0, %pc_lo12(g_i8)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: load_s8:
@@ -29,8 +27,7 @@ define dso_local signext i8 @load_s8() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_i8)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_i8)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_i8)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ld.b $a0, $a0, 0
+; LA64-LARGE-NEXT: ldx.b $a0, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
%0 = load i8, ptr @g_i8
@@ -41,15 +38,13 @@ define dso_local zeroext i8 @load_u8() nounwind {
; LA32-LABEL: load_u8:
; LA32: # %bb.0: # %entry
; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_i8)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_i8)
-; LA32-NEXT: ld.bu $a0, $a0, 0
+; LA32-NEXT: ld.bu $a0, $a0, %pc_lo12(g_i8)
; LA32-NEXT: ret
;
; LA64-LABEL: load_u8:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_i8)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_i8)
-; LA64-NEXT: ld.bu $a0, $a0, 0
+; LA64-NEXT: ld.bu $a0, $a0, %pc_lo12(g_i8)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: load_u8:
@@ -58,8 +53,7 @@ define dso_local zeroext i8 @load_u8() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_i8)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_i8)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_i8)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ld.bu $a0, $a0, 0
+; LA64-LARGE-NEXT: ldx.bu $a0, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
%0 = load i8, ptr @g_i8
@@ -70,17 +64,15 @@ define dso_local void @store_i8() nounwind {
; LA32-LABEL: store_i8:
; LA32: # %bb.0: # %entry
; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_i8)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_i8)
; LA32-NEXT: ori $a1, $zero, 1
-; LA32-NEXT: st.b $a1, $a0, 0
+; LA32-NEXT: st.b $a1, $a0, %pc_lo12(g_i8)
; LA32-NEXT: ret
;
; LA64-LABEL: store_i8:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_i8)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_i8)
; LA64-NEXT: ori $a1, $zero, 1
-; LA64-NEXT: st.b $a1, $a0, 0
+; LA64-NEXT: st.b $a1, $a0, %pc_lo12(g_i8)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: store_i8:
@@ -89,9 +81,8 @@ define dso_local void @store_i8() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_i8)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_i8)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_i8)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ori $a1, $zero, 1
-; LA64-LARGE-NEXT: st.b $a1, $a0, 0
+; LA64-LARGE-NEXT: ori $a2, $zero, 1
+; LA64-LARGE-NEXT: stx.b $a2, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
store i8 1, ptr @g_i8
@@ -104,15 +95,13 @@ define dso_local signext i16 @load_s16() nounwind {
; LA32-LABEL: load_s16:
; LA32: # %bb.0: # %entry
; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_i16)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_i16)
-; LA32-NEXT: ld.h $a0, $a0, 0
+; LA32-NEXT: ld.h $a0, $a0, %pc_lo12(g_i16)
; LA32-NEXT: ret
;
; LA64-LABEL: load_s16:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_i16)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_i16)
-; LA64-NEXT: ld.h $a0, $a0, 0
+; LA64-NEXT: ld.h $a0, $a0, %pc_lo12(g_i16)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: load_s16:
@@ -121,8 +110,7 @@ define dso_local signext i16 @load_s16() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_i16)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_i16)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_i16)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ld.h $a0, $a0, 0
+; LA64-LARGE-NEXT: ldx.h $a0, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
%0 = load i16, ptr @g_i16
@@ -133,15 +121,13 @@ define dso_local zeroext i16 @load_u16() nounwind {
; LA32-LABEL: load_u16:
; LA32: # %bb.0: # %entry
; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_i16)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_i16)
-; LA32-NEXT: ld.hu $a0, $a0, 0
+; LA32-NEXT: ld.hu $a0, $a0, %pc_lo12(g_i16)
; LA32-NEXT: ret
;
; LA64-LABEL: load_u16:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_i16)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_i16)
-; LA64-NEXT: ld.hu $a0, $a0, 0
+; LA64-NEXT: ld.hu $a0, $a0, %pc_lo12(g_i16)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: load_u16:
@@ -150,8 +136,7 @@ define dso_local zeroext i16 @load_u16() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_i16)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_i16)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_i16)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ld.hu $a0, $a0, 0
+; LA64-LARGE-NEXT: ldx.hu $a0, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
%0 = load i16, ptr @g_i16
@@ -162,17 +147,15 @@ define dso_local void @store_i16() nounwind {
; LA32-LABEL: store_i16:
; LA32: # %bb.0: # %entry
; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_i16)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_i16)
; LA32-NEXT: ori $a1, $zero, 1
-; LA32-NEXT: st.h $a1, $a0, 0
+; LA32-NEXT: st.h $a1, $a0, %pc_lo12(g_i16)
; LA32-NEXT: ret
;
; LA64-LABEL: store_i16:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_i16)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_i16)
; LA64-NEXT: ori $a1, $zero, 1
-; LA64-NEXT: st.h $a1, $a0, 0
+; LA64-NEXT: st.h $a1, $a0, %pc_lo12(g_i16)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: store_i16:
@@ -181,9 +164,8 @@ define dso_local void @store_i16() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_i16)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_i16)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_i16)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ori $a1, $zero, 1
-; LA64-LARGE-NEXT: st.h $a1, $a0, 0
+; LA64-LARGE-NEXT: ori $a2, $zero, 1
+; LA64-LARGE-NEXT: stx.h $a2, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
store i16 1, ptr @g_i16
@@ -196,15 +178,13 @@ define dso_local signext i32 @load_s32() nounwind {
; LA32-LABEL: load_s32:
; LA32: # %bb.0: # %entry
; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_i32)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_i32)
-; LA32-NEXT: ld.w $a0, $a0, 0
+; LA32-NEXT: ld.w $a0, $a0, %pc_lo12(g_i32)
; LA32-NEXT: ret
;
; LA64-LABEL: load_s32:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_i32)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_i32)
-; LA64-NEXT: ld.w $a0, $a0, 0
+; LA64-NEXT: ld.w $a0, $a0, %pc_lo12(g_i32)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: load_s32:
@@ -213,8 +193,7 @@ define dso_local signext i32 @load_s32() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_i32)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_i32)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_i32)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ld.w $a0, $a0, 0
+; LA64-LARGE-NEXT: ldx.w $a0, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
%0 = load i32, ptr @g_i32
@@ -225,15 +204,13 @@ define dso_local zeroext i32 @load_u32() nounwind {
; LA32-LABEL: load_u32:
; LA32: # %bb.0: # %entry
; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_i32)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_i32)
-; LA32-NEXT: ld.w $a0, $a0, 0
+; LA32-NEXT: ld.w $a0, $a0, %pc_lo12(g_i32)
; LA32-NEXT: ret
;
; LA64-LABEL: load_u32:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_i32)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_i32)
-; LA64-NEXT: ld.wu $a0, $a0, 0
+; LA64-NEXT: ld.wu $a0, $a0, %pc_lo12(g_i32)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: load_u32:
@@ -242,8 +219,7 @@ define dso_local zeroext i32 @load_u32() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_i32)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_i32)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_i32)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ld.wu $a0, $a0, 0
+; LA64-LARGE-NEXT: ldx.wu $a0, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
%0 = load i32, ptr @g_i32
@@ -254,17 +230,15 @@ define dso_local void @store_i32() nounwind {
; LA32-LABEL: store_i32:
; LA32: # %bb.0: # %entry
; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_i32)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_i32)
; LA32-NEXT: ori $a1, $zero, 1
-; LA32-NEXT: st.w $a1, $a0, 0
+; LA32-NEXT: st.w $a1, $a0, %pc_lo12(g_i32)
; LA32-NEXT: ret
;
; LA64-LABEL: store_i32:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_i32)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_i32)
; LA64-NEXT: ori $a1, $zero, 1
-; LA64-NEXT: st.w $a1, $a0, 0
+; LA64-NEXT: st.w $a1, $a0, %pc_lo12(g_i32)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: store_i32:
@@ -273,9 +247,8 @@ define dso_local void @store_i32() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_i32)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_i32)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_i32)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ori $a1, $zero, 1
-; LA64-LARGE-NEXT: st.w $a1, $a0, 0
+; LA64-LARGE-NEXT: ori $a2, $zero, 1
+; LA64-LARGE-NEXT: stx.w $a2, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
store i32 1, ptr @g_i32
@@ -296,8 +269,7 @@ define dso_local i64 @load_64() nounwind {
; LA64-LABEL: load_64:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_i64)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_i64)
-; LA64-NEXT: ld.d $a0, $a0, 0
+; LA64-NEXT: ld.d $a0, $a0, %pc_lo12(g_i64)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: load_64:
@@ -306,8 +278,7 @@ define dso_local i64 @load_64() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_i64)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_i64)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_i64)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ld.d $a0, $a0, 0
+; LA64-LARGE-NEXT: ldx.d $a0, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
%0 = load i64, ptr @g_i64
@@ -327,9 +298,8 @@ define dso_local void @store_i64() nounwind {
; LA64-LABEL: store_i64:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_i64)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_i64)
; LA64-NEXT: ori $a1, $zero, 1
-; LA64-NEXT: st.d $a1, $a0, 0
+; LA64-NEXT: st.d $a1, $a0, %pc_lo12(g_i64)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: store_i64:
@@ -338,9 +308,8 @@ define dso_local void @store_i64() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_i64)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_i64)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_i64)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ori $a1, $zero, 1
-; LA64-LARGE-NEXT: st.d $a1, $a0, 0
+; LA64-LARGE-NEXT: ori $a2, $zero, 1
+; LA64-LARGE-NEXT: stx.d $a2, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
store i64 1, ptr @g_i64
@@ -353,15 +322,13 @@ define dso_local float @load_f32() nounwind {
; LA32-LABEL: load_f32:
; LA32: # %bb.0: # %entry
; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_f32)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_f32)
-; LA32-NEXT: fld.s $fa0, $a0, 0
+; LA32-NEXT: fld.s $fa0, $a0, %pc_lo12(g_f32)
; LA32-NEXT: ret
;
; LA64-LABEL: load_f32:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_f32)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_f32)
-; LA64-NEXT: fld.s $fa0, $a0, 0
+; LA64-NEXT: fld.s $fa0, $a0, %pc_lo12(g_f32)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: load_f32:
@@ -370,8 +337,7 @@ define dso_local float @load_f32() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_f32)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_f32)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_f32)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: fld.s $fa0, $a0, 0
+; LA64-LARGE-NEXT: fldx.s $fa0, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
%0 = load float, ptr @g_f32
@@ -382,17 +348,15 @@ define dso_local void @store_f32() nounwind {
; LA32-LABEL: store_f32:
; LA32: # %bb.0: # %entry
; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_f32)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_f32)
; LA32-NEXT: lu12i.w $a1, 260096
-; LA32-NEXT: st.w $a1, $a0, 0
+; LA32-NEXT: st.w $a1, $a0, %pc_lo12(g_f32)
; LA32-NEXT: ret
;
; LA64-LABEL: store_f32:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_f32)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_f32)
; LA64-NEXT: lu12i.w $a1, 260096
-; LA64-NEXT: st.w $a1, $a0, 0
+; LA64-NEXT: st.w $a1, $a0, %pc_lo12(g_f32)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: store_f32:
@@ -401,9 +365,8 @@ define dso_local void @store_f32() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_f32)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_f32)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_f32)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: lu12i.w $a1, 260096
-; LA64-LARGE-NEXT: st.w $a1, $a0, 0
+; LA64-LARGE-NEXT: lu12i.w $a2, 260096
+; LA64-LARGE-NEXT: stx.w $a2, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
store float 1.0, ptr @g_f32
@@ -416,15 +379,13 @@ define dso_local double @load_f64() nounwind {
; LA32-LABEL: load_f64:
; LA32: # %bb.0: # %entry
; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_f64)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_f64)
-; LA32-NEXT: fld.d $fa0, $a0, 0
+; LA32-NEXT: fld.d $fa0, $a0, %pc_lo12(g_f64)
; LA32-NEXT: ret
;
; LA64-LABEL: load_f64:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_f64)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_f64)
-; LA64-NEXT: fld.d $fa0, $a0, 0
+; LA64-NEXT: fld.d $fa0, $a0, %pc_lo12(g_f64)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: load_f64:
@@ -433,8 +394,7 @@ define dso_local double @load_f64() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_f64)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_f64)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_f64)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: fld.d $fa0, $a0, 0
+; LA64-LARGE-NEXT: fldx.d $fa0, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
%0 = load double, ptr @g_f64
@@ -445,20 +405,18 @@ define dso_local void @store_f64() nounwind {
; LA32-LABEL: store_f64:
; LA32: # %bb.0: # %entry
; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_f64)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_f64)
; LA32-NEXT: addi.w $a1, $zero, 1
; LA32-NEXT: movgr2fr.w $fa0, $a1
; LA32-NEXT: ffint.s.w $fa0, $fa0
; LA32-NEXT: fcvt.d.s $fa0, $fa0
-; LA32-NEXT: fst.d $fa0, $a0, 0
+; LA32-NEXT: fst.d $fa0, $a0, %pc_lo12(g_f64)
; LA32-NEXT: ret
;
; LA64-LABEL: store_f64:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_f64)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_f64)
; LA64-NEXT: lu52i.d $a1, $zero, 1023
-; LA64-NEXT: st.d $a1, $a0, 0
+; LA64-NEXT: st.d $a1, $a0, %pc_lo12(g_f64)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: store_f64:
@@ -467,9 +425,8 @@ define dso_local void @store_f64() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_f64)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_f64)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_f64)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: lu52i.d $a1, $zero, 1023
-; LA64-LARGE-NEXT: st.d $a1, $a0, 0
+; LA64-LARGE-NEXT: lu52i.d $a2, $zero, 1023
+; LA64-LARGE-NEXT: stx.d $a2, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
store double 1.0, ptr @g_f64
@@ -494,11 +451,10 @@ define dso_local void @store_multi() nounwind {
; LA64-LABEL: store_multi:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_m64)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_m64)
; LA64-NEXT: ori $a1, $zero, 1
-; LA64-NEXT: st.d $a1, $a0, 0
+; LA64-NEXT: st.d $a1, $a0, %pc_lo12(g_m64)
; LA64-NEXT: ori $a1, $zero, 2
-; LA64-NEXT: st.d $a1, $a0, 0
+; LA64-NEXT: st.d $a1, $a0, %pc_lo12(g_m64)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: store_multi:
@@ -507,11 +463,10 @@ define dso_local void @store_multi() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_m64)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_m64)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_m64)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ori $a1, $zero, 1
-; LA64-LARGE-NEXT: st.d $a1, $a0, 0
-; LA64-LARGE-NEXT: ori $a1, $zero, 2
-; LA64-LARGE-NEXT: st.d $a1, $a0, 0
+; LA64-LARGE-NEXT: ori $a2, $zero, 1
+; LA64-LARGE-NEXT: stx.d $a2, $a1, $a0
+; LA64-LARGE-NEXT: ori $a2, $zero, 2
+; LA64-LARGE-NEXT: stx.d $a2, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
store volatile i64 1, ptr @g_m64
@@ -525,17 +480,15 @@ define dso_local void @store_sf32() nounwind {
; LA32-LABEL: store_sf32:
; LA32: # %bb.0: # %entry
; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_sf32)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_sf32)
-; LA32-NEXT: fld.s $fa0, $a0, 0
-; LA32-NEXT: fst.s $fa0, $a0, 0
+; LA32-NEXT: fld.s $fa0, $a0, %pc_lo12(g_sf32)
+; LA32-NEXT: fst.s $fa0, $a0, %pc_lo12(g_sf32)
; LA32-NEXT: ret
;
; LA64-LABEL: store_sf32:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_sf32)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_sf32)
-; LA64-NEXT: fld.s $fa0, $a0, 0
-; LA64-NEXT: fst.s $fa0, $a0, 0
+; LA64-NEXT: fld.s $fa0, $a0, %pc_lo12(g_sf32)
+; LA64-NEXT: fst.s $fa0, $a0, %pc_lo12(g_sf32)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: store_sf32:
@@ -544,9 +497,8 @@ define dso_local void @store_sf32() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_sf32)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_sf32)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_sf32)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: fld.s $fa0, $a0, 0
-; LA64-LARGE-NEXT: fst.s $fa0, $a0, 0
+; LA64-LARGE-NEXT: fldx.s $fa0, $a1, $a0
+; LA64-LARGE-NEXT: fstx.s $fa0, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
%0 = load float, ptr @g_sf32
@@ -560,17 +512,15 @@ define dso_local void @store_sf64() nounwind {
; LA32-LABEL: store_sf64:
; LA32: # %bb.0: # %entry
; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_sf64)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_sf64)
-; LA32-NEXT: fld.d $fa0, $a0, 0
-; LA32-NEXT: fst.d $fa0, $a0, 0
+; LA32-NEXT: fld.d $fa0, $a0, %pc_lo12(g_sf64)
+; LA32-NEXT: fst.d $fa0, $a0, %pc_lo12(g_sf64)
; LA32-NEXT: ret
;
; LA64-LABEL: store_sf64:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_sf64)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_sf64)
-; LA64-NEXT: fld.d $fa0, $a0, 0
-; LA64-NEXT: fst.d $fa0, $a0, 0
+; LA64-NEXT: fld.d $fa0, $a0, %pc_lo12(g_sf64)
+; LA64-NEXT: fst.d $fa0, $a0, %pc_lo12(g_sf64)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: store_sf64:
@@ -579,9 +529,8 @@ define dso_local void @store_sf64() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_sf64)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_sf64)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_sf64)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: fld.d $fa0, $a0, 0
-; LA64-LARGE-NEXT: fst.d $fa0, $a0, 0
+; LA64-LARGE-NEXT: fldx.d $fa0, $a1, $a0
+; LA64-LARGE-NEXT: fstx.d $fa0, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
%0 = load double, ptr @g_sf64
@@ -608,10 +557,9 @@ define dso_local void @rmw() nounwind {
; LA64-LABEL: rmw:
; LA64: # %bb.0: # %entry
; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_rmw)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_rmw)
-; LA64-NEXT: ld.d $a1, $a0, 0
+; LA64-NEXT: ld.d $a1, $a0, %pc_lo12(g_rmw)
; LA64-NEXT: addi.d $a1, $a1, 1
-; LA64-NEXT: st.d $a1, $a0, 0
+; LA64-NEXT: st.d $a1, $a0, %pc_lo12(g_rmw)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: rmw:
@@ -620,10 +568,9 @@ define dso_local void @rmw() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_rmw)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_rmw)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_rmw)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ld.d $a1, $a0, 0
-; LA64-LARGE-NEXT: addi.d $a1, $a1, 1
-; LA64-LARGE-NEXT: st.d $a1, $a0, 0
+; LA64-LARGE-NEXT: ldx.d $a2, $a1, $a0
+; LA64-LARGE-NEXT: addi.d $a2, $a2, 1
+; LA64-LARGE-NEXT: stx.d $a2, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
%0 = load i64, ptr @g_rmw
@@ -637,31 +584,26 @@ entry:
define dso_local void @store_a32() nounwind {
; LA32-LABEL: store_a32:
; LA32: # %bb.0: # %entry
-; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a32)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a32)
-; LA32-NEXT: lu12i.w $a1, 1
-; LA32-NEXT: add.w $a0, $a0, $a1
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a32+4096)
; LA32-NEXT: ori $a1, $zero, 1
-; LA32-NEXT: st.w $a1, $a0, 0
+; LA32-NEXT: st.w $a1, $a0, %pc_lo12(g_a32+4096)
; LA32-NEXT: ret
;
; LA64-LABEL: store_a32:
; LA64: # %bb.0: # %entry
-; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_a32)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_a32)
+; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_a32+4096)
; LA64-NEXT: ori $a1, $zero, 1
-; LA64-NEXT: stptr.w $a1, $a0, 4096
+; LA64-NEXT: st.w $a1, $a0, %pc_lo12(g_a32+4096)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: store_a32:
; LA64-LARGE: # %bb.0: # %entry
-; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a32)
-; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a32)
-; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a32)
-; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a32)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ori $a1, $zero, 1
-; LA64-LARGE-NEXT: stptr.w $a1, $a0, 4096
+; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a32+4096)
+; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a32+4096)
+; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a32+4096)
+; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a32+4096)
+; LA64-LARGE-NEXT: ori $a2, $zero, 1
+; LA64-LARGE-NEXT: stx.w $a2, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
store i32 1, ptr getelementptr inbounds ([1 x i32], ptr @g_a32, i32 1024), align 4
@@ -714,48 +656,44 @@ entry:
define dso_local void @control_flow_with_mem_access() nounwind {
; LA32-LABEL: control_flow_with_mem_access:
; LA32: # %bb.0: # %entry
-; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a32)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a32)
-; LA32-NEXT: ld.w $a1, $a0, 4
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a32+4)
+; LA32-NEXT: ld.w $a1, $a0, %pc_lo12(g_a32+4)
; LA32-NEXT: ori $a2, $zero, 1
; LA32-NEXT: blt $a1, $a2, .LBB21_2
; LA32-NEXT: # %bb.1: # %if.then
; LA32-NEXT: ori $a1, $zero, 10
-; LA32-NEXT: st.w $a1, $a0, 4
+; LA32-NEXT: st.w $a1, $a0, %pc_lo12(g_a32+4)
; LA32-NEXT: .LBB21_2: # %if.end
; LA32-NEXT: ret
;
; LA64-LABEL: control_flow_with_mem_access:
; LA64: # %bb.0: # %entry
-; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_a32)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_a32)
-; LA64-NEXT: ld.w $a1, $a0, 4
+; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_a32+4)
+; LA64-NEXT: ld.w $a1, $a0, %pc_lo12(g_a32+4)
; LA64-NEXT: ori $a2, $zero, 1
; LA64-NEXT: blt $a1, $a2, .LBB21_2
; LA64-NEXT: # %bb.1: # %if.then
; LA64-NEXT: ori $a1, $zero, 10
-; LA64-NEXT: st.w $a1, $a0, 4
+; LA64-NEXT: st.w $a1, $a0, %pc_lo12(g_a32+4)
; LA64-NEXT: .LBB21_2: # %if.end
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: control_flow_with_mem_access:
; LA64-LARGE: # %bb.0: # %entry
-; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a32)
-; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a32)
-; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a32)
-; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a32)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ld.w $a0, $a0, 4
+; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a32+4)
+; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a32+4)
+; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a32+4)
+; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a32+4)
+; LA64-LARGE-NEXT: ldx.w $a0, $a1, $a0
; LA64-LARGE-NEXT: ori $a1, $zero, 1
; LA64-LARGE-NEXT: blt $a0, $a1, .LBB21_2
; LA64-LARGE-NEXT: # %bb.1: # %if.then
-; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a32)
-; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a32)
-; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a32)
-; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a32)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ori $a1, $zero, 10
-; LA64-LARGE-NEXT: st.w $a1, $a0, 4
+; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a32+4)
+; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a32+4)
+; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a32+4)
+; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a32+4)
+; LA64-LARGE-NEXT: ori $a2, $zero, 10
+; LA64-LARGE-NEXT: stx.w $a2, $a1, $a0
; LA64-LARGE-NEXT: .LBB21_2: # %if.end
; LA64-LARGE-NEXT: ret
entry:
@@ -777,8 +715,7 @@ define dso_local ptr @load_ba_1() nounwind {
; LA32-NEXT: .Ltmp0: # Block address taken
; LA32-NEXT: # %bb.1: # %label
; LA32-NEXT: pcalau12i $a0, %pc_hi20(.Ltmp0)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(.Ltmp0)
-; LA32-NEXT: ld.w $a0, $a0, 0
+; LA32-NEXT: ld.w $a0, $a0, %pc_lo12(.Ltmp0)
; LA32-NEXT: ret
;
; LA64-LABEL: load_ba_1:
@@ -786,8 +723,7 @@ define dso_local ptr @load_ba_1() nounwind {
; LA64-NEXT: .Ltmp0: # Block address taken
; LA64-NEXT: # %bb.1: # %label
; LA64-NEXT: pcalau12i $a0, %pc_hi20(.Ltmp0)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(.Ltmp0)
-; LA64-NEXT: ld.d $a0, $a0, 0
+; LA64-NEXT: ld.d $a0, $a0, %pc_lo12(.Ltmp0)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: load_ba_1:
@@ -798,8 +734,7 @@ define dso_local ptr @load_ba_1() nounwind {
; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(.Ltmp0)
; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(.Ltmp0)
; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(.Ltmp0)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ld.d $a0, $a0, 0
+; LA64-LARGE-NEXT: ldx.d $a0, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
br label %label
@@ -813,30 +748,27 @@ define dso_local ptr @load_ba_2() nounwind {
; LA32: # %bb.0: # %entry
; LA32-NEXT: .Ltmp1: # Block address taken
; LA32-NEXT: # %bb.1: # %label
-; LA32-NEXT: pcalau12i $a0, %pc_hi20(.Ltmp1)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(.Ltmp1)
-; LA32-NEXT: ld.w $a0, $a0, 8
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(.Ltmp1+8)
+; LA32-NEXT: ld.w $a0, $a0, %pc_lo12(.Ltmp1+8)
; LA32-NEXT: ret
;
; LA64-LABEL: load_ba_2:
; LA64: # %bb.0: # %entry
; LA64-NEXT: .Ltmp1: # Block address taken
; LA64-NEXT: # %bb.1: # %label
-; LA64-NEXT: pcalau12i $a0, %pc_hi20(.Ltmp1)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(.Ltmp1)
-; LA64-NEXT: ld.d $a0, $a0, 8
+; LA64-NEXT: pcalau12i $a0, %pc_hi20(.Ltmp1+8)
+; LA64-NEXT: ld.d $a0, $a0, %pc_lo12(.Ltmp1+8)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: load_ba_2:
; LA64-LARGE: # %bb.0: # %entry
; LA64-LARGE-NEXT: .Ltmp1: # Block address taken
; LA64-LARGE-NEXT: # %bb.1: # %label
-; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(.Ltmp1)
-; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(.Ltmp1)
-; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(.Ltmp1)
-; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(.Ltmp1)
-; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: ld.d $a0, $a0, 8
+; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(.Ltmp1+8)
+; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(.Ltmp1+8)
+; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(.Ltmp1+8)
+; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(.Ltmp1+8)
+; LA64-LARGE-NEXT: ldx.d $a0, $a1, $a0
; LA64-LARGE-NEXT: ret
entry:
br label %label
@@ -850,26 +782,23 @@ label:
define dso_local ptr @load_addr_offset_1() nounwind {
; LA32-LABEL: load_addr_offset_1:
; LA32: # %bb.0: # %entry
-; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a64)
-; LA32-NEXT: addi.w $a0, $a0, 8
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a64+8)
+; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a64+8)
; LA32-NEXT: ret
;
; LA64-LABEL: load_addr_offset_1:
; LA64: # %bb.0: # %entry
-; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_a64)
-; LA64-NEXT: addi.d $a0, $a0, 8
+; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_a64+8)
+; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_a64+8)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: load_addr_offset_1:
; LA64-LARGE: # %bb.0: # %entry
-; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a64)
-; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a64)
-; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a64)
+; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a64+8)
+; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a64+8)
+; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a64+8)
+; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a64+8)
; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: addi.d $a0, $a0, 8
; LA64-LARGE-NEXT: ret
entry:
ret ptr getelementptr inbounds ([1 x i64], ptr @g_a64, i64 1)
@@ -878,29 +807,23 @@ entry:
define dso_local ptr @load_addr_offset_257() nounwind {
; LA32-LABEL: load_addr_offset_257:
; LA32: # %bb.0: # %entry
-; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a64)
-; LA32-NEXT: addi.w $a0, $a0, 2047
-; LA32-NEXT: addi.w $a0, $a0, 9
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a64+2056)
+; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a64+2056)
; LA32-NEXT: ret
;
; LA64-LABEL: load_addr_offset_257:
; LA64: # %bb.0: # %entry
-; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_a64)
-; LA64-NEXT: addi.d $a0, $a0, 2047
-; LA64-NEXT: addi.d $a0, $a0, 9
+; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_a64+2056)
+; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_a64+2056)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: load_addr_offset_257:
; LA64-LARGE: # %bb.0: # %entry
-; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a64)
-; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a64)
-; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a64)
+; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a64+2056)
+; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a64+2056)
+; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a64+2056)
+; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a64+2056)
; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: addi.d $a0, $a0, 2047
-; LA64-LARGE-NEXT: addi.d $a0, $a0, 9
; LA64-LARGE-NEXT: ret
entry:
ret ptr getelementptr inbounds ([1 x i64], ptr @g_a64, i64 257)
@@ -909,27 +832,23 @@ entry:
define dso_local ptr @load_addr_offset_1048576() nounwind {
; LA32-LABEL: load_addr_offset_1048576:
; LA32: # %bb.0: # %entry
-; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a64)
-; LA32-NEXT: lu12i.w $a1, 2048
-; LA32-NEXT: add.w $a0, $a0, $a1
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a64+8388608)
+; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a64+8388608)
; LA32-NEXT: ret
;
; LA64-LABEL: load_addr_offset_1048576:
; LA64: # %bb.0: # %entry
-; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_a64)
-; LA64-NEXT: addu16i.d $a0, $a0, 128
+; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_a64+8388608)
+; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_a64+8388608)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: load_addr_offset_1048576:
; LA64-LARGE: # %bb.0: # %entry
-; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a64)
-; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a64)
-; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a64)
+; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a64+8388608)
+; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a64+8388608)
+; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a64+8388608)
+; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a64+8388608)
; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: addu16i.d $a0, $a0, 128
; LA64-LARGE-NEXT: ret
entry:
ret ptr getelementptr inbounds ([1 x i64], ptr @g_a64, i64 1048576)
@@ -938,30 +857,23 @@ entry:
define dso_local ptr @load_addr_offset_1048577() nounwind {
; LA32-LABEL: load_addr_offset_1048577:
; LA32: # %bb.0: # %entry
-; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a64)
-; LA32-NEXT: lu12i.w $a1, 2048
-; LA32-NEXT: ori $a1, $a1, 8
-; LA32-NEXT: add.w $a0, $a0, $a1
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a64+8388616)
+; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a64+8388616)
; LA32-NEXT: ret
;
; LA64-LABEL: load_addr_offset_1048577:
; LA64: # %bb.0: # %entry
-; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_a64)
-; LA64-NEXT: addu16i.d $a0, $a0, 128
-; LA64-NEXT: addi.d $a0, $a0, 8
+; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_a64+8388616)
+; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_a64+8388616)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: load_addr_offset_1048577:
; LA64-LARGE: # %bb.0: # %entry
-; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a64)
-; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a64)
-; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a64)
+; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a64+8388616)
+; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a64+8388616)
+; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a64+8388616)
+; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a64+8388616)
; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: addu16i.d $a0, $a0, 128
-; LA64-LARGE-NEXT: addi.d $a0, $a0, 8
; LA64-LARGE-NEXT: ret
entry:
ret ptr getelementptr inbounds ([1 x i64], ptr @g_a64, i64 1048577)
@@ -970,29 +882,23 @@ entry:
define dso_local ptr @load_addr_offset_268432896() nounwind {
; LA32-LABEL: load_addr_offset_268432896:
; LA32: # %bb.0: # %entry
-; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a64)
-; LA32-NEXT: lu12i.w $a1, 524283
-; LA32-NEXT: add.w $a0, $a0, $a1
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a64+2147463168)
+; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a64+2147463168)
; LA32-NEXT: ret
;
; LA64-LABEL: load_addr_offset_268432896:
; LA64: # %bb.0: # %entry
-; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_a64)
-; LA64-NEXT: lu12i.w $a1, 524283
-; LA64-NEXT: add.d $a0, $a0, $a1
+; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_a64+2147463168)
+; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_a64+2147463168)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: load_addr_offset_268432896:
; LA64-LARGE: # %bb.0: # %entry
-; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a64)
-; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a64)
-; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a64)
+; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a64+2147463168)
+; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a64+2147463168)
+; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a64+2147463168)
+; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a64+2147463168)
; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: lu12i.w $a1, 524283
-; LA64-LARGE-NEXT: add.d $a0, $a0, $a1
; LA64-LARGE-NEXT: ret
entry:
ret ptr getelementptr inbounds ([1 x i64], ptr @g_a64, i64 268432896)
@@ -1001,32 +907,23 @@ entry:
define dso_local ptr @load_addr_offset_268432897() nounwind {
; LA32-LABEL: load_addr_offset_268432897:
; LA32: # %bb.0: # %entry
-; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a64)
-; LA32-NEXT: lu12i.w $a1, 524283
-; LA32-NEXT: ori $a1, $a1, 8
-; LA32-NEXT: add.w $a0, $a0, $a1
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a64+2147463176)
+; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a64+2147463176)
; LA32-NEXT: ret
;
; LA64-LABEL: load_addr_offset_268432897:
; LA64: # %bb.0: # %entry
-; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_a64)
-; LA64-NEXT: lu12i.w $a1, 524283
-; LA64-NEXT: ori $a1, $a1, 8
-; LA64-NEXT: add.d $a0, $a0, $a1
+; LA64-NEXT: pcalau12i $a0, %pc_hi20(g_a64+2147463176)
+; LA64-NEXT: addi.d $a0, $a0, %pc_lo12(g_a64+2147463176)
; LA64-NEXT: ret
;
; LA64-LARGE-LABEL: load_addr_offset_268432897:
; LA64-LARGE: # %bb.0: # %entry
-; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a64)
-; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a64)
-; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a64)
+; LA64-LARGE-NEXT: pcalau12i $a0, %pc_hi20(g_a64+2147463176)
+; LA64-LARGE-NEXT: addi.d $a1, $zero, %pc_lo12(g_a64+2147463176)
+; LA64-LARGE-NEXT: lu32i.d $a1, %pc64_lo20(g_a64+2147463176)
+; LA64-LARGE-NEXT: lu52i.d $a1, $a1, %pc64_hi12(g_a64+2147463176)
; LA64-LARGE-NEXT: add.d $a0, $a1, $a0
-; LA64-LARGE-NEXT: lu12i.w $a1, 524283
-; LA64-LARGE-NEXT: ori $a1, $a1, 8
-; LA64-LARGE-NEXT: add.d $a0, $a0, $a1
; LA64-LARGE-NEXT: ret
entry:
ret ptr getelementptr inbounds ([1 x i64], ptr @g_a64, i64 268432897)
@@ -1035,11 +932,8 @@ entry:
define dso_local ptr @load_addr_offset_9380351707272() nounwind {
; LA32-LABEL: load_addr_offset_9380351707272:
; LA32: # %bb.0: # %entry
-; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a64)
-; LA32-NEXT: lu12i.w $a1, 279556
-; LA32-NEXT: ori $a1, $a1, 1088
-; LA32-NEXT: add.w $a0, $a0, $a1
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a64+1145062464)
+; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a64+1145062464)
; LA32-NEXT: ret
;
; LA64-LABEL: load_addr_offset_9380351707272:
@@ -1071,11 +965,8 @@ entry:
define dso_local ptr @load_addr_offset_614750729487779976() nounwind {
; LA32-LABEL: load_addr_offset_614750729487779976:
; LA32: # %bb.0: # %entry
-; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a64)
-; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a64)
-; LA32-NEXT: lu12i.w $a1, 279556
-; LA32-NEXT: ori $a1, $a1, 1088
-; LA32-NEXT: add.w $a0, $a0, $a1
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(g_a64+1145062464)
+; LA32-NEXT: addi.w $a0, $a0, %pc_lo12(g_a64+1145062464)
; LA32-NEXT: ret
;
; LA64-LABEL: load_addr_offset_614750729487779976:
diff --git a/llvm/test/CodeGen/LoongArch/opt-pipeline.ll b/llvm/test/CodeGen/LoongArch/opt-pipeline.ll
index 4e5a5433596dbc..4767adec44eff4 100644
--- a/llvm/test/CodeGen/LoongArch/opt-pipeline.ll
+++ b/llvm/test/CodeGen/LoongArch/opt-pipeline.ll
@@ -107,6 +107,7 @@
; LAXX-NEXT: Remove dead machine instructions
; LA64-NEXT: LoongArch Optimize W Instructions
; LAXX-NEXT: LoongArch Pre-RA pseudo instruction expansion pass
+; LAXX-NEXT: LoongArch Merge Base Offset
; LAXX-NEXT: Detect Dead Lanes
; LAXX-NEXT: Init Undef Pass
; LAXX-NEXT: Process Implicit Definitions
diff --git a/llvm/test/CodeGen/LoongArch/psabi-restricted-scheduling.ll b/llvm/test/CodeGen/LoongArch/psabi-restricted-scheduling.ll
index b03a523fb79a9b..a7873f466bee3f 100644
--- a/llvm/test/CodeGen/LoongArch/psabi-restricted-scheduling.ll
+++ b/llvm/test/CodeGen/LoongArch/psabi-restricted-scheduling.ll
@@ -25,8 +25,7 @@ define void @foo() nounwind {
; MEDIUM_NO_SCH-NEXT: ld.d $a0, $a0, %got_pc_lo12(G)
; MEDIUM_NO_SCH-NEXT: ld.d $zero, $a0, 0
; MEDIUM_NO_SCH-NEXT: pcalau12i $a0, %pc_hi20(.Lg$local)
-; MEDIUM_NO_SCH-NEXT: addi.d $a0, $a0, %pc_lo12(.Lg$local)
-; MEDIUM_NO_SCH-NEXT: ld.d $zero, $a0, 0
+; MEDIUM_NO_SCH-NEXT: ld.d $zero, $a0, %pc_lo12(.Lg$local)
; MEDIUM_NO_SCH-NEXT: ori $a0, $zero, 1
; MEDIUM_NO_SCH-NEXT: pcaddu18i $ra, %call36(bar)
; MEDIUM_NO_SCH-NEXT: jirl $ra, $ra, 0
@@ -55,8 +54,7 @@ define void @foo() nounwind {
; MEDIUM_SCH-NEXT: ld.d $a0, $a0, %got_pc_lo12(G)
; MEDIUM_SCH-NEXT: ld.d $zero, $a0, 0
; MEDIUM_SCH-NEXT: pcalau12i $a0, %pc_hi20(.Lg$local)
-; MEDIUM_SCH-NEXT: addi.d $a0, $a0, %pc_lo12(.Lg$local)
-; MEDIUM_SCH-NEXT: ld.d $zero, $a0, 0
+; MEDIUM_SCH-NEXT: ld.d $zero, $a0, %pc_lo12(.Lg$local)
; MEDIUM_SCH-NEXT: ori $a0, $zero, 1
; MEDIUM_SCH-NEXT: pcaddu18i $ra, %call36(bar)
; MEDIUM_SCH-NEXT: jirl $ra, $ra, 0
@@ -91,8 +89,7 @@ define void @foo() nounwind {
; LARGE_NO_SCH-NEXT: addi.d $a1, $zero, %pc_lo12(.Lg$local)
; LARGE_NO_SCH-NEXT: lu32i.d $a1, %pc64_lo20(.Lg$local)
; LARGE_NO_SCH-NEXT: lu52i.d $a1, $a1, %pc64_hi12(.Lg$local)
-; LARGE_NO_SCH-NEXT: add.d $a0, $a1, $a0
-; LARGE_NO_SCH-NEXT: ld.d $zero, $a0, 0
+; LARGE_NO_SCH-NEXT: ldx.d $zero, $a1, $a0
; LARGE_NO_SCH-NEXT: ori $a0, $zero, 1
; LARGE_NO_SCH-NEXT: pcalau12i $a1, %got_pc_hi20(bar)
; LARGE_NO_SCH-NEXT: addi.d $ra, $zero, %got_pc_lo12(bar)
@@ -148,8 +145,7 @@ define void @foo() nounwind {
; LARGE_SCH-NEXT: addi.d $a1, $zero, %pc_lo12(.Lg$local)
; LARGE_SCH-NEXT: lu32i.d $a1, %pc64_lo20(.Lg$local)
; LARGE_SCH-NEXT: lu52i.d $a1, $a1, %pc64_hi12(.Lg$local)
-; LARGE_SCH-NEXT: add.d $a0, $a1, $a0
-; LARGE_SCH-NEXT: ld.d $zero, $a0, 0
+; LARGE_SCH-NEXT: ldx.d $zero, $a1, $a0
; LARGE_SCH-NEXT: ori $a0, $zero, 1
; LARGE_SCH-NEXT: pcalau12i $a1, %got_pc_hi20(bar)
; LARGE_SCH-NEXT: addi.d $ra, $zero, %got_pc_lo12(bar)
diff --git a/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll b/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll
index 0a401ebe5f6b2a..8dd1ec465c13ad 100644
--- a/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll
+++ b/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll
@@ -94,8 +94,7 @@ define void @test_f2(ptr %P, ptr %S) nounwind {
; LA32F-NEXT: fld.s $fa1, $a0, 0
; LA32F-NEXT: addi.w $a0, $zero, 1
; LA32F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI1_0)
-; LA32F-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI1_0)
-; LA32F-NEXT: fld.s $fa2, $a2, 0
+; LA32F-NEXT: fld.s $fa2, $a2, %pc_lo12(.LCPI1_0)
; LA32F-NEXT: movgr2fr.w $fa3, $a0
; LA32F-NEXT: ffint.s.w $fa3, $fa3
; LA32F-NEXT: fadd.s $fa1, $fa1, $fa3
@@ -110,8 +109,7 @@ define void @test_f2(ptr %P, ptr %S) nounwind {
; LA32D-NEXT: fld.s $fa1, $a0, 0
; LA32D-NEXT: addi.w $a0, $zero, 1
; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI1_0)
-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI1_0)
-; LA32D-NEXT: fld.s $fa2, $a2, 0
+; LA32D-NEXT: fld.s $fa2, $a2, %pc_lo12(.LCPI1_0)
; LA32D-NEXT: movgr2fr.w $fa3, $a0
; LA32D-NEXT: ffint.s.w $fa3, $fa3
; LA32D-NEXT: fadd.s $fa1, $fa1, $fa3
@@ -126,8 +124,7 @@ define void @test_f2(ptr %P, ptr %S) nounwind {
; LA64F-NEXT: fld.s $fa1, $a0, 0
; LA64F-NEXT: addi.w $a0, $zero, 1
; LA64F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI1_0)
-; LA64F-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI1_0)
-; LA64F-NEXT: fld.s $fa2, $a2, 0
+; LA64F-NEXT: fld.s $fa2, $a2, %pc_lo12(.LCPI1_0)
; LA64F-NEXT: movgr2fr.w $fa3, $a0
; LA64F-NEXT: ffint.s.w $fa3, $fa3
; LA64F-NEXT: fadd.s $fa1, $fa1, $fa3
@@ -142,8 +139,7 @@ define void @test_f2(ptr %P, ptr %S) nounwind {
; LA64D-NEXT: fld.s $fa1, $a0, 0
; LA64D-NEXT: addi.w $a0, $zero, 1
; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI1_0)
-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI1_0)
-; LA64D-NEXT: fld.s $fa2, $a2, 0
+; LA64D-NEXT: fld.s $fa2, $a2, %pc_lo12(.LCPI1_0)
; LA64D-NEXT: movgr2fr.w $fa3, $a0
; LA64D-NEXT: ffint.s.w $fa3, $fa3
; LA64D-NEXT: fadd.s $fa1, $fa1, $fa3
@@ -168,14 +164,11 @@ define void @test_f4(ptr %P, ptr %S) nounwind {
; LA32F-NEXT: movgr2fr.w $fa4, $a0
; LA32F-NEXT: ffint.s.w $fa4, $fa4
; LA32F-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_0)
-; LA32F-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI2_0)
-; LA32F-NEXT: fld.s $fa5, $a0, 0
+; LA32F-NEXT: fld.s $fa5, $a0, %pc_lo12(.LCPI2_0)
; LA32F-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_1)
-; LA32F-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI2_1)
-; LA32F-NEXT: fld.s $fa6, $a0, 0
+; LA32F-NEXT: fld.s $fa6, $a0, %pc_lo12(.LCPI2_1)
; LA32F-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_2)
-; LA32F-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI2_2)
-; LA32F-NEXT: fld.s $fa7, $a0, 0
+; LA32F-NEXT: fld.s $fa7, $a0, %pc_lo12(.LCPI2_2)
; LA32F-NEXT: fadd.s $fa3, $fa3, $fa4
; LA32F-NEXT: fadd.s $fa2, $fa2, $fa5
; LA32F-NEXT: fadd.s $fa1, $fa1, $fa6
@@ -196,14 +189,11 @@ define void @test_f4(ptr %P, ptr %S) nounwind {
; LA32D-NEXT: movgr2fr.w $fa4, $a0
; LA32D-NEXT: ffint.s.w $fa4, $fa4
; LA32D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_0)
-; LA32D-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI2_0)
-; LA32D-NEXT: fld.s $fa5, $a0, 0
+; LA32D-NEXT: fld.s $fa5, $a0, %pc_lo12(.LCPI2_0)
; LA32D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_1)
-; LA32D-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI2_1)
-; LA32D-NEXT: fld.s $fa6, $a0, 0
+; LA32D-NEXT: fld.s $fa6, $a0, %pc_lo12(.LCPI2_1)
; LA32D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_2)
-; LA32D-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI2_2)
-; LA32D-NEXT: fld.s $fa7, $a0, 0
+; LA32D-NEXT: fld.s $fa7, $a0, %pc_lo12(.LCPI2_2)
; LA32D-NEXT: fadd.s $fa3, $fa3, $fa4
; LA32D-NEXT: fadd.s $fa2, $fa2, $fa5
; LA32D-NEXT: fadd.s $fa1, $fa1, $fa6
@@ -224,14 +214,11 @@ define void @test_f4(ptr %P, ptr %S) nounwind {
; LA64F-NEXT: movgr2fr.w $fa4, $a0
; LA64F-NEXT: ffint.s.w $fa4, $fa4
; LA64F-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_0)
-; LA64F-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI2_0)
-; LA64F-NEXT: fld.s $fa5, $a0, 0
+; LA64F-NEXT: fld.s $fa5, $a0, %pc_lo12(.LCPI2_0)
; LA64F-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_1)
-; LA64F-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI2_1)
-; LA64F-NEXT: fld.s $fa6, $a0, 0
+; LA64F-NEXT: fld.s $fa6, $a0, %pc_lo12(.LCPI2_1)
; LA64F-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_2)
-; LA64F-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI2_2)
-; LA64F-NEXT: fld.s $fa7, $a0, 0
+; LA64F-NEXT: fld.s $fa7, $a0, %pc_lo12(.LCPI2_2)
; LA64F-NEXT: fadd.s $fa3, $fa3, $fa4
; LA64F-NEXT: fadd.s $fa2, $fa2, $fa5
; LA64F-NEXT: fadd.s $fa1, $fa1, $fa6
@@ -252,14 +239,11 @@ define void @test_f4(ptr %P, ptr %S) nounwind {
; LA64D-NEXT: movgr2fr.w $fa4, $a0
; LA64D-NEXT: ffint.s.w $fa4, $fa4
; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_0)
-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI2_0)
-; LA64D-NEXT: fld.s $fa5, $a0, 0
+; LA64D-NEXT: fld.s $fa5, $a0, %pc_lo12(.LCPI2_0)
; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_1)
-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI2_1)
-; LA64D-NEXT: fld.s $fa6, $a0, 0
+; LA64D-NEXT: fld.s $fa6, $a0, %pc_lo12(.LCPI2_1)
; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI2_2)
-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI2_2)
-; LA64D-NEXT: fld.s $fa7, $a0, 0
+; LA64D-NEXT: fld.s $fa7, $a0, %pc_lo12(.LCPI2_2)
; LA64D-NEXT: fadd.s $fa3, $fa3, $fa4
; LA64D-NEXT: fadd.s $fa2, $fa2, $fa5
; LA64D-NEXT: fadd.s $fa1, $fa1, $fa6
@@ -281,14 +265,11 @@ define void @test_f8(ptr %P, ptr %S) nounwind {
; LA32F-NEXT: addi.w $a2, $zero, 1
; LA32F-NEXT: movgr2fr.w $fa0, $a2
; LA32F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_0)
-; LA32F-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI3_0)
-; LA32F-NEXT: fld.s $fa1, $a2, 0
+; LA32F-NEXT: fld.s $fa1, $a2, %pc_lo12(.LCPI3_0)
; LA32F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_1)
-; LA32F-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI3_1)
-; LA32F-NEXT: fld.s $fa2, $a2, 0
+; LA32F-NEXT: fld.s $fa2, $a2, %pc_lo12(.LCPI3_1)
; LA32F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_2)
-; LA32F-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI3_2)
-; LA32F-NEXT: fld.s $fa3, $a2, 0
+; LA32F-NEXT: fld.s $fa3, $a2, %pc_lo12(.LCPI3_2)
; LA32F-NEXT: fld.s $fa4, $a0, 28
; LA32F-NEXT: fld.s $fa5, $a0, 24
; LA32F-NEXT: fld.s $fa6, $a0, 12
@@ -321,14 +302,11 @@ define void @test_f8(ptr %P, ptr %S) nounwind {
; LA32D-NEXT: addi.w $a2, $zero, 1
; LA32D-NEXT: movgr2fr.w $fa0, $a2
; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_0)
-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI3_0)
-; LA32D-NEXT: fld.s $fa1, $a2, 0
+; LA32D-NEXT: fld.s $fa1, $a2, %pc_lo12(.LCPI3_0)
; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_1)
-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI3_1)
-; LA32D-NEXT: fld.s $fa2, $a2, 0
+; LA32D-NEXT: fld.s $fa2, $a2, %pc_lo12(.LCPI3_1)
; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_2)
-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI3_2)
-; LA32D-NEXT: fld.s $fa3, $a2, 0
+; LA32D-NEXT: fld.s $fa3, $a2, %pc_lo12(.LCPI3_2)
; LA32D-NEXT: fld.s $fa4, $a0, 28
; LA32D-NEXT: fld.s $fa5, $a0, 24
; LA32D-NEXT: fld.s $fa6, $a0, 12
@@ -361,14 +339,11 @@ define void @test_f8(ptr %P, ptr %S) nounwind {
; LA64F-NEXT: addi.w $a2, $zero, 1
; LA64F-NEXT: movgr2fr.w $fa0, $a2
; LA64F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_0)
-; LA64F-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI3_0)
-; LA64F-NEXT: fld.s $fa1, $a2, 0
+; LA64F-NEXT: fld.s $fa1, $a2, %pc_lo12(.LCPI3_0)
; LA64F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_1)
-; LA64F-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI3_1)
-; LA64F-NEXT: fld.s $fa2, $a2, 0
+; LA64F-NEXT: fld.s $fa2, $a2, %pc_lo12(.LCPI3_1)
; LA64F-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_2)
-; LA64F-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI3_2)
-; LA64F-NEXT: fld.s $fa3, $a2, 0
+; LA64F-NEXT: fld.s $fa3, $a2, %pc_lo12(.LCPI3_2)
; LA64F-NEXT: fld.s $fa4, $a0, 28
; LA64F-NEXT: fld.s $fa5, $a0, 24
; LA64F-NEXT: fld.s $fa6, $a0, 12
@@ -401,14 +376,11 @@ define void @test_f8(ptr %P, ptr %S) nounwind {
; LA64D-NEXT: addi.w $a2, $zero, 1
; LA64D-NEXT: movgr2fr.w $fa0, $a2
; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_0)
-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI3_0)
-; LA64D-NEXT: fld.s $fa1, $a2, 0
+; LA64D-NEXT: fld.s $fa1, $a2, %pc_lo12(.LCPI3_0)
; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_1)
-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI3_1)
-; LA64D-NEXT: fld.s $fa2, $a2, 0
+; LA64D-NEXT: fld.s $fa2, $a2, %pc_lo12(.LCPI3_1)
; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI3_2)
-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI3_2)
-; LA64D-NEXT: fld.s $fa3, $a2, 0
+; LA64D-NEXT: fld.s $fa3, $a2, %pc_lo12(.LCPI3_2)
; LA64D-NEXT: fld.s $fa4, $a0, 28
; LA64D-NEXT: fld.s $fa5, $a0, 24
; LA64D-NEXT: fld.s $fa6, $a0, 12
@@ -488,8 +460,7 @@ define void @test_d2(ptr %P, ptr %S) nounwind {
; LA32D-NEXT: addi.w $a0, $zero, 1
; LA32D-NEXT: movgr2fr.w $fa2, $a0
; LA32D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI4_0)
-; LA32D-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI4_0)
-; LA32D-NEXT: fld.d $fa3, $a0, 0
+; LA32D-NEXT: fld.d $fa3, $a0, %pc_lo12(.LCPI4_0)
; LA32D-NEXT: ffint.s.w $fa2, $fa2
; LA32D-NEXT: fcvt.d.s $fa2, $fa2
; LA32D-NEXT: fadd.d $fa1, $fa1, $fa2
@@ -529,8 +500,7 @@ define void @test_d2(ptr %P, ptr %S) nounwind {
; LA64D-NEXT: fld.d $fa1, $a0, 0
; LA64D-NEXT: addi.d $a0, $zero, 1
; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI4_0)
-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI4_0)
-; LA64D-NEXT: fld.d $fa2, $a2, 0
+; LA64D-NEXT: fld.d $fa2, $a2, %pc_lo12(.LCPI4_0)
; LA64D-NEXT: movgr2fr.d $fa3, $a0
; LA64D-NEXT: ffint.d.l $fa3, $fa3
; LA64D-NEXT: fadd.d $fa1, $fa1, $fa3
@@ -625,14 +595,11 @@ define void @test_d4(ptr %P, ptr %S) nounwind {
; LA32D-NEXT: ffint.s.w $fa4, $fa4
; LA32D-NEXT: fcvt.d.s $fa4, $fa4
; LA32D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI5_0)
-; LA32D-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI5_0)
-; LA32D-NEXT: fld.d $fa5, $a0, 0
+; LA32D-NEXT: fld.d $fa5, $a0, %pc_lo12(.LCPI5_0)
; LA32D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI5_1)
-; LA32D-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI5_1)
-; LA32D-NEXT: fld.d $fa6, $a0, 0
+; LA32D-NEXT: fld.d $fa6, $a0, %pc_lo12(.LCPI5_1)
; LA32D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI5_2)
-; LA32D-NEXT: addi.w $a0, $a0, %pc_lo12(.LCPI5_2)
-; LA32D-NEXT: fld.d $fa7, $a0, 0
+; LA32D-NEXT: fld.d $fa7, $a0, %pc_lo12(.LCPI5_2)
; LA32D-NEXT: fadd.d $fa3, $fa3, $fa4
; LA32D-NEXT: fadd.d $fa2, $fa2, $fa5
; LA32D-NEXT: fadd.d $fa1, $fa1, $fa6
@@ -696,14 +663,11 @@ define void @test_d4(ptr %P, ptr %S) nounwind {
; LA64D-NEXT: movgr2fr.d $fa4, $a0
; LA64D-NEXT: ffint.d.l $fa4, $fa4
; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI5_0)
-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI5_0)
-; LA64D-NEXT: fld.d $fa5, $a0, 0
+; LA64D-NEXT: fld.d $fa5, $a0, %pc_lo12(.LCPI5_0)
; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI5_1)
-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI5_1)
-; LA64D-NEXT: fld.d $fa6, $a0, 0
+; LA64D-NEXT: fld.d $fa6, $a0, %pc_lo12(.LCPI5_1)
; LA64D-NEXT: pcalau12i $a0, %pc_hi20(.LCPI5_2)
-; LA64D-NEXT: addi.d $a0, $a0, %pc_lo12(.LCPI5_2)
-; LA64D-NEXT: fld.d $fa7, $a0, 0
+; LA64D-NEXT: fld.d $fa7, $a0, %pc_lo12(.LCPI5_2)
; LA64D-NEXT: fadd.d $fa3, $fa3, $fa4
; LA64D-NEXT: fadd.d $fa2, $fa2, $fa5
; LA64D-NEXT: fadd.d $fa1, $fa1, $fa6
@@ -852,14 +816,11 @@ define void @test_d8(ptr %P, ptr %S) nounwind {
; LA32D-NEXT: addi.w $a2, $zero, 1
; LA32D-NEXT: movgr2fr.w $fa0, $a2
; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI6_0)
-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI6_0)
-; LA32D-NEXT: fld.d $fa1, $a2, 0
+; LA32D-NEXT: fld.d $fa1, $a2, %pc_lo12(.LCPI6_0)
; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI6_1)
-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI6_1)
-; LA32D-NEXT: fld.d $fa2, $a2, 0
+; LA32D-NEXT: fld.d $fa2, $a2, %pc_lo12(.LCPI6_1)
; LA32D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI6_2)
-; LA32D-NEXT: addi.w $a2, $a2, %pc_lo12(.LCPI6_2)
-; LA32D-NEXT: fld.d $fa3, $a2, 0
+; LA32D-NEXT: fld.d $fa3, $a2, %pc_lo12(.LCPI6_2)
; LA32D-NEXT: fld.d $fa4, $a0, 56
; LA32D-NEXT: fld.d $fa5, $a0, 48
; LA32D-NEXT: fld.d $fa6, $a0, 24
@@ -976,14 +937,11 @@ define void @test_d8(ptr %P, ptr %S) nounwind {
; LA64D-NEXT: addi.d $a2, $zero, 1
; LA64D-NEXT: movgr2fr.d $fa0, $a2
; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI6_0)
-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI6_0)
-; LA64D-NEXT: fld.d $fa1, $a2, 0
+; LA64D-NEXT: fld.d $fa1, $a2, %pc_lo12(.LCPI6_0)
; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI6_1)
-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI6_1)
-; LA64D-NEXT: fld.d $fa2, $a2, 0
+; LA64D-NEXT: fld.d $fa2, $a2, %pc_lo12(.LCPI6_1)
; LA64D-NEXT: pcalau12i $a2, %pc_hi20(.LCPI6_2)
-; LA64D-NEXT: addi.d $a2, $a2, %pc_lo12(.LCPI6_2)
-; LA64D-NEXT: fld.d $fa3, $a2, 0
+; LA64D-NEXT: fld.d $fa3, $a2, %pc_lo12(.LCPI6_2)
; LA64D-NEXT: fld.d $fa4, $a0, 56
; LA64D-NEXT: fld.d $fa5, $a0, 48
; LA64D-NEXT: fld.d $fa6, $a0, 24
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
index 56b6c90a2f6f33..7a7115b393b1db 100644
--- 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
@@ -122,7 +122,6 @@ attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
; CHECK-NEXT: .cfi_def_cfa 22, 0
; CHECK-NEXT: st.w $zero, $fp, -12
; 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, $fp, -16
; CHECK-NEXT: ori $a2, $zero, 2
@@ -131,7 +130,7 @@ attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
; CHECK-NEXT: st.w $a3, $fp, -24
; CHECK-NEXT: ori $a4, $zero, 4
; CHECK-NEXT: st.w $a4, $fp, -28
-; CHECK-NEXT: st.w $a1, $a0, 0
+; CHECK-NEXT: st.w $a1, $a0, %pc_lo12(x)
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: st.w $a1, $fp, -16
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
index 2e063202fcf79e..d99eb3749826f0 100644
--- 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
@@ -99,7 +99,6 @@ define dso_local i32 @main() #0 {
; CHECK-NEXT: .cfi_def_cfa 22, 0
; CHECK-NEXT: st.w $zero, $fp, -12
; 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, $fp, -16
; CHECK-NEXT: ori $a2, $zero, 2
@@ -108,7 +107,7 @@ define dso_local i32 @main() #0 {
; CHECK-NEXT: st.w $a3, $fp, -24
; CHECK-NEXT: ori $a4, $zero, 4
; CHECK-NEXT: st.w $a4, $fp, -28
-; CHECK-NEXT: st.w $a1, $a0, 0
+; CHECK-NEXT: st.w $a1, $a0, %pc_lo12(x)
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: st.w $a1, $fp, -16
diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/BUILD.gn
index 248e47a9584cdf..09a5311c122fc5 100644
--- a/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/BUILD.gn
@@ -42,6 +42,7 @@ static_library("LLVMLoongArchCodeGen") {
"LoongArchISelLowering.cpp",
"LoongArchInstrInfo.cpp",
"LoongArchMCInstLower.cpp",
+ "LoongArchMergeBaseOffset.cpp",
"LoongArchOptWInstrs.cpp",
"LoongArchRegisterInfo.cpp",
"LoongArchSubtarget.cpp",
>From 44bc783e25d4d45389c60c1c070dc96a7b4f4667 Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Thu, 8 Aug 2024 12:00:47 +0800
Subject: [PATCH 2/2] Address wanglei's comments
---
.../LoongArch/LoongArchMergeBaseOffset.cpp | 21 +++++++++++--------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp b/llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp
index 4fbe31616a7efc..ae50b7a6f923e3 100644
--- a/llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp
@@ -108,8 +108,11 @@ bool LoongArchMergeBaseOffsetOpt::detectFoldable(MachineInstr &Hi20,
if (Hi20Op1.getTargetFlags() != LoongArchII::MO_PCREL_HI)
return false;
- if (!(Hi20Op1.isGlobal() || Hi20Op1.isCPI() || Hi20Op1.isBlockAddress()) ||
- Hi20Op1.getOffset() != 0)
+ auto isGlobalOrCPIOrBlockAddress = [](const MachineOperand &Op) {
+ return Op.isGlobal() || Op.isCPI() || Op.isBlockAddress();
+ };
+
+ if (!isGlobalOrCPIOrBlockAddress(Hi20Op1) || Hi20Op1.getOffset() != 0)
return false;
Register HiDestReg = Hi20.getOperand(0).getReg();
@@ -126,12 +129,14 @@ bool LoongArchMergeBaseOffsetOpt::detectFoldable(MachineInstr &Hi20,
assert(ST->is64Bit());
Last = UseInst;
- Hi12 = MRI->getVRegDef(Last->getOperand(1).getReg());
+ Register LastOp1Reg = Last->getOperand(1).getReg();
+ if (!LastOp1Reg.isVirtual())
+ return false;
+ Hi12 = MRI->getVRegDef(LastOp1Reg);
const MachineOperand &Hi12Op2 = Hi12->getOperand(2);
if (Hi12Op2.getTargetFlags() != LoongArchII::MO_PCREL64_HI)
return false;
- if (!(Hi12Op2.isGlobal() || Hi12Op2.isCPI() || Hi12Op2.isBlockAddress()) ||
- Hi12Op2.getOffset() != 0)
+ if (!isGlobalOrCPIOrBlockAddress(Hi12Op2) || Hi12Op2.getOffset() != 0)
return false;
if (!MRI->hasOneUse(Hi12->getOperand(0).getReg()))
return false;
@@ -140,8 +145,7 @@ bool LoongArchMergeBaseOffsetOpt::detectFoldable(MachineInstr &Hi20,
const MachineOperand &Lo20Op2 = Lo20->getOperand(2);
if (Lo20Op2.getTargetFlags() != LoongArchII::MO_PCREL64_LO)
return false;
- if (!(Lo20Op2.isGlobal() || Lo20Op2.isCPI() || Lo20Op2.isBlockAddress()) ||
- Lo20Op2.getOffset() != 0)
+ if (!isGlobalOrCPIOrBlockAddress(Lo20Op2) || Lo20Op2.getOffset() != 0)
return false;
if (!MRI->hasOneUse(Lo20->getOperand(0).getReg()))
return false;
@@ -154,8 +158,7 @@ bool LoongArchMergeBaseOffsetOpt::detectFoldable(MachineInstr &Hi20,
const MachineOperand &Lo12Op2 = Lo12->getOperand(2);
assert(Hi20.getOpcode() == LoongArch::PCALAU12I);
if (Lo12Op2.getTargetFlags() != LoongArchII::MO_PCREL_LO ||
- !(Lo12Op2.isGlobal() || Lo12Op2.isCPI() || Lo12Op2.isBlockAddress() ||
- Lo12Op2.isMCSymbol()) ||
+ !(isGlobalOrCPIOrBlockAddress(Lo12Op2) || Lo12Op2.isMCSymbol()) ||
Lo12Op2.getOffset() != 0)
return false;
More information about the llvm-commits
mailing list