-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[LoongArch] Add machine function pass to merge base + offset #101139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This commit references RISC-V to add a machine function pass to merge the base address and offset.
@llvm/pr-subscribers-backend-loongarch Author: hev (heiher) ChangesThis commit references RISC-V to add a machine function pass to merge the base address and offset. Patch is 116.78 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/101139.diff 26 Files Affected:
diff --git a/llvm/lib/Target/LoongArch/CMakeLists.txt b/llvm/lib/Target/LoongArch/CMakeLists.txt
index cadc335a621f2..0f674b1b0fa9e 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 adfb844ee31b6..db60523738880 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 f478870217ec6..8bb9497a847fa 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 0000000000000..ae50b7a6f923e
--- /dev/null
+++ b/llvm/lib/Target/LoongArch/LoongArchMergeBaseOffset.cpp
@@ -0,0 +1,636 @@
+//===---- 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;
+
+ 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();
+ 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;
+
+ 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 (!isGlobalOrCPIOrBlockAddress(Hi12Op2) || 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 (!isGlobalOrCPIOrBlockAddress(Lo20Op2) || 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 ||
+ !(isGlobalOrCPIOrBlockAddress(Lo12Op2) || 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::opti...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, Thanks!
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/10/builds/25 Here is the relevant piece of the build log for the reference
|
This commit references RISC-V to add a machine function pass to merge the base address and offset.