diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -926,6 +926,8 @@ /// For example, if the instruction has a unique labels attached /// to it, duplicating it would cause multiple definition errors. bool isNotDuplicable(QueryType Type = AnyInBundle) const { + if (getPreInstrSymbol() || getPostInstrSymbol()) + return true; return hasProperty(MCID::NotDuplicable, Type); } diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -630,6 +630,11 @@ if (getDebugLoc() && Other.getDebugLoc() && getDebugLoc() != Other.getDebugLoc()) return false; + // If pre- or post-instruction symbols do not match then the two instructions + // are not identical. + if (getPreInstrSymbol() != Other.getPreInstrSymbol() || + getPostInstrSymbol() != Other.getPostInstrSymbol()) + return false; return true; } diff --git a/llvm/lib/Target/RISCV/RISCV.h b/llvm/lib/Target/RISCV/RISCV.h --- a/llvm/lib/Target/RISCV/RISCV.h +++ b/llvm/lib/Target/RISCV/RISCV.h @@ -53,6 +53,9 @@ FunctionPass *createRISCVExpandPseudoPass(); void initializeRISCVExpandPseudoPass(PassRegistry &); +FunctionPass *createRISCVPreRAExpandPseudoPass(); +void initializeRISCVPreRAExpandPseudoPass(PassRegistry &); + FunctionPass *createRISCVExpandAtomicPseudoPass(); void initializeRISCVExpandAtomicPseudoPass(PassRegistry &); diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp --- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp +++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp @@ -19,10 +19,12 @@ #include "llvm/CodeGen/LivePhysRegs.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/MC/MCContext.h" using namespace llvm; #define RISCV_EXPAND_PSEUDO_NAME "RISCV pseudo instruction expansion pass" +#define RISCV_PRERA_EXPAND_PSEUDO_NAME "RISCV Pre-RA pseudo instruction expansion pass" namespace { @@ -47,9 +49,6 @@ MachineBasicBlock::iterator MBBI, MachineBasicBlock::iterator &NextMBBI, unsigned FlagsHi, unsigned SecondOpcode); - bool expandLoadLocalAddress(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MBBI, - MachineBasicBlock::iterator &NextMBBI); bool expandLoadAddress(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MachineBasicBlock::iterator &NextMBBI); @@ -96,8 +95,6 @@ // expanded instructions for each pseudo is correct in the Size field of the // tablegen definition for the pseudo. switch (MBBI->getOpcode()) { - case RISCV::PseudoLLA: - return expandLoadLocalAddress(MBB, MBBI, NextMBBI); case RISCV::PseudoLA: return expandLoadAddress(MBB, MBBI, NextMBBI); case RISCV::PseudoLA_TLS_IE: @@ -196,13 +193,6 @@ return true; } -bool RISCVExpandPseudo::expandLoadLocalAddress( - MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - MachineBasicBlock::iterator &NextMBBI) { - return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_PCREL_HI, - RISCV::ADDI); -} - bool RISCVExpandPseudo::expandLoadAddress( MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MachineBasicBlock::iterator &NextMBBI) { @@ -377,12 +367,118 @@ return true; } +class RISCVPreRAExpandPseudo : public MachineFunctionPass { +public: + const RISCVInstrInfo *TII; + static char ID; + + RISCVPreRAExpandPseudo() : MachineFunctionPass(ID) { + initializeRISCVPreRAExpandPseudoPass(*PassRegistry::getPassRegistry()); + } + + bool runOnMachineFunction(MachineFunction &MF) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesCFG(); + MachineFunctionPass::getAnalysisUsage(AU); + } + StringRef getPassName() const override { + return RISCV_PRERA_EXPAND_PSEUDO_NAME; + } + +private: + bool expandMBB(MachineBasicBlock &MBB); + bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + MachineBasicBlock::iterator &NextMBBI); + bool expandAuipcInstPair(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + MachineBasicBlock::iterator &NextMBBI, + unsigned FlagsHi, unsigned SecondOpcode); + bool expandLoadLocalAddress(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + MachineBasicBlock::iterator &NextMBBI); +}; + +char RISCVPreRAExpandPseudo::ID = 0; + +bool RISCVPreRAExpandPseudo::runOnMachineFunction(MachineFunction &MF) { + TII = static_cast(MF.getSubtarget().getInstrInfo()); + bool Modified = false; + for (auto &MBB : MF) + Modified |= expandMBB(MBB); + return Modified; +} + +bool RISCVPreRAExpandPseudo::expandMBB(MachineBasicBlock &MBB) { + bool Modified = false; + + MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); + while (MBBI != E) { + MachineBasicBlock::iterator NMBBI = std::next(MBBI); + Modified |= expandMI(MBB, MBBI, NMBBI); + MBBI = NMBBI; + } + + return Modified; +} + +bool RISCVPreRAExpandPseudo::expandMI(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + MachineBasicBlock::iterator &NextMBBI) { + + switch (MBBI->getOpcode()) { + case RISCV::PseudoLLA: + return expandLoadLocalAddress(MBB, MBBI, NextMBBI); + } + return false; +} + +bool RISCVPreRAExpandPseudo::expandAuipcInstPair( + MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + MachineBasicBlock::iterator &NextMBBI, unsigned FlagsHi, + unsigned SecondOpcode) { + MachineFunction *MF = MBB.getParent(); + MachineInstr &MI = *MBBI; + DebugLoc DL = MI.getDebugLoc(); + + Register DestReg = MI.getOperand(0).getReg(); + Register ScratchReg = + MF->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass); + + MachineOperand &Symbol = MI.getOperand(1); + Symbol.setTargetFlags(FlagsHi); + MCSymbol *AUIPCSymbol = MF->getContext().createNamedTempSymbol("pcrel_hi"); + + MachineInstr *MIAUIPC = + BuildMI(MBB, MBBI, DL, TII->get(RISCV::AUIPC), ScratchReg).add(Symbol); + MIAUIPC->setPreInstrSymbol(*MF, AUIPCSymbol); + + BuildMI(MBB, MBBI, DL, TII->get(SecondOpcode), DestReg) + .addReg(ScratchReg) + .addSym(AUIPCSymbol, RISCVII::MO_PCREL_LO); + + MI.eraseFromParent(); + return true; +} + +bool RISCVPreRAExpandPseudo::expandLoadLocalAddress( + MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + MachineBasicBlock::iterator &NextMBBI) { + return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_PCREL_HI, + RISCV::ADDI); +} + } // end of anonymous namespace INITIALIZE_PASS(RISCVExpandPseudo, "riscv-expand-pseudo", RISCV_EXPAND_PSEUDO_NAME, false, false) + +INITIALIZE_PASS(RISCVPreRAExpandPseudo, "riscv-prera-expand-pseudo", + RISCV_PRERA_EXPAND_PSEUDO_NAME, false, false) + namespace llvm { FunctionPass *createRISCVExpandPseudoPass() { return new RISCVExpandPseudo(); } +FunctionPass *createRISCVPreRAExpandPseudoPass() { return new RISCVPreRAExpandPseudo(); } } // end of namespace llvm diff --git a/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp b/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp --- a/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp +++ b/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp @@ -125,6 +125,9 @@ case MachineOperand::MO_JumpTableIndex: MCOp = lowerSymbolOperand(MO, AP.GetJTISymbol(MO.getIndex()), AP); break; + case MachineOperand::MO_MCSymbol: + MCOp = lowerSymbolOperand(MO, MO.getMCSymbol(), AP); + break; } return true; } diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp --- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp @@ -248,6 +248,7 @@ if (TM->getTargetTriple().getArch() == Triple::riscv64) addPass(createRISCVSExtWRemovalPass()); + addPass(createRISCVPreRAExpandPseudoPass()); } void RISCVPassConfig::addPreRegAlloc() { diff --git a/llvm/test/CodeGen/RISCV/O3-pipeline.ll b/llvm/test/CodeGen/RISCV/O3-pipeline.ll --- a/llvm/test/CodeGen/RISCV/O3-pipeline.ll +++ b/llvm/test/CodeGen/RISCV/O3-pipeline.ll @@ -95,6 +95,7 @@ ; CHECK-NEXT: Peephole Optimizations ; CHECK-NEXT: Remove dead machine instructions ; RV64-NEXT: RISCV sext.w Removal +; CHECK-NEXT: RISCV Pre-RA pseudo instruction expansion pass ; CHECK-NEXT: RISCV Merge Base Offset ; CHECK-NEXT: RISCV Insert VSETVLI pass ; CHECK-NEXT: Detect Dead Lanes diff --git a/llvm/test/CodeGen/RISCV/codemodel-lowering.ll b/llvm/test/CodeGen/RISCV/codemodel-lowering.ll --- a/llvm/test/CodeGen/RISCV/codemodel-lowering.ll +++ b/llvm/test/CodeGen/RISCV/codemodel-lowering.ll @@ -16,9 +16,9 @@ ; ; RV32I-MEDIUM-LABEL: lower_global: ; RV32I-MEDIUM: # %bb.0: -; RV32I-MEDIUM-NEXT: .LBB0_1: # Label of block must be emitted +; RV32I-MEDIUM-NEXT: .Lpcrel_hi0: ; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(G) -; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.LBB0_1) +; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi0) ; RV32I-MEDIUM-NEXT: lw a0, 0(a0) ; RV32I-MEDIUM-NEXT: ret %1 = load volatile i32, i32* @G @@ -39,9 +39,9 @@ ; ; RV32I-MEDIUM-LABEL: lower_blockaddress: ; RV32I-MEDIUM: # %bb.0: -; RV32I-MEDIUM-NEXT: .LBB1_1: # Label of block must be emitted +; RV32I-MEDIUM-NEXT: .Lpcrel_hi1: ; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(addr) -; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.LBB1_1) +; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi1) ; RV32I-MEDIUM-NEXT: li a1, 1 ; RV32I-MEDIUM-NEXT: sw a1, 0(a0) ; RV32I-MEDIUM-NEXT: ret @@ -79,10 +79,9 @@ ; RV32I-MEDIUM-LABEL: lower_blockaddress_displ: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: addi sp, sp, -16 -; RV32I-MEDIUM-NEXT: .LBB2_4: # %entry -; RV32I-MEDIUM-NEXT: # Label of block must be emitted +; RV32I-MEDIUM-NEXT: .Lpcrel_hi2: ; RV32I-MEDIUM-NEXT: auipc a1, %pcrel_hi(.Ltmp0) -; RV32I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.LBB2_4) +; RV32I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi2) ; RV32I-MEDIUM-NEXT: li a2, 101 ; RV32I-MEDIUM-NEXT: sw a1, 8(sp) ; RV32I-MEDIUM-NEXT: blt a0, a2, .LBB2_3 @@ -134,9 +133,9 @@ ; ; RV32I-MEDIUM-LABEL: lower_constantpool: ; RV32I-MEDIUM: # %bb.0: -; RV32I-MEDIUM-NEXT: .LBB3_1: # Label of block must be emitted +; RV32I-MEDIUM-NEXT: .Lpcrel_hi3: ; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(.LCPI3_0) -; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.LBB3_1) +; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi3) ; RV32I-MEDIUM-NEXT: flw ft0, 0(a0) ; RV32I-MEDIUM-NEXT: fadd.s fa0, fa0, ft0 ; RV32I-MEDIUM-NEXT: ret diff --git a/llvm/test/CodeGen/RISCV/elf-preemption.ll b/llvm/test/CodeGen/RISCV/elf-preemption.ll --- a/llvm/test/CodeGen/RISCV/elf-preemption.ll +++ b/llvm/test/CodeGen/RISCV/elf-preemption.ll @@ -48,9 +48,9 @@ ; ; RV32-PIC-LABEL: get_dsolocal_var: ; RV32-PIC: # %bb.0: -; RV32-PIC-NEXT: .LBB1_1: # Label of block must be emitted +; RV32-PIC-NEXT: .Lpcrel_hi0: ; RV32-PIC-NEXT: auipc a0, %pcrel_hi(.Ldsolocal_var$local) -; RV32-PIC-NEXT: addi a0, a0, %pcrel_lo(.LBB1_1) +; RV32-PIC-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi0) ; RV32-PIC-NEXT: ret ; ; RV64-STATIC-LABEL: get_dsolocal_var: @@ -61,9 +61,9 @@ ; ; RV64-PIC-LABEL: get_dsolocal_var: ; RV64-PIC: # %bb.0: -; RV64-PIC-NEXT: .LBB1_1: # Label of block must be emitted +; RV64-PIC-NEXT: .Lpcrel_hi0: ; RV64-PIC-NEXT: auipc a0, %pcrel_hi(.Ldsolocal_var$local) -; RV64-PIC-NEXT: addi a0, a0, %pcrel_lo(.LBB1_1) +; RV64-PIC-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi0) ; RV64-PIC-NEXT: ret ret i32* @dsolocal_var } @@ -78,9 +78,9 @@ ; ; RV32-PIC-LABEL: get_weak_dsolocal_var: ; RV32-PIC: # %bb.0: -; RV32-PIC-NEXT: .LBB2_1: # Label of block must be emitted +; RV32-PIC-NEXT: .Lpcrel_hi1: ; RV32-PIC-NEXT: auipc a0, %pcrel_hi(weak_dsolocal_var) -; RV32-PIC-NEXT: addi a0, a0, %pcrel_lo(.LBB2_1) +; RV32-PIC-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi1) ; RV32-PIC-NEXT: ret ; ; RV64-STATIC-LABEL: get_weak_dsolocal_var: @@ -91,9 +91,9 @@ ; ; RV64-PIC-LABEL: get_weak_dsolocal_var: ; RV64-PIC: # %bb.0: -; RV64-PIC-NEXT: .LBB2_1: # Label of block must be emitted +; RV64-PIC-NEXT: .Lpcrel_hi1: ; RV64-PIC-NEXT: auipc a0, %pcrel_hi(weak_dsolocal_var) -; RV64-PIC-NEXT: addi a0, a0, %pcrel_lo(.LBB2_1) +; RV64-PIC-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi1) ; RV64-PIC-NEXT: ret ret i32* @weak_dsolocal_var } @@ -108,9 +108,9 @@ ; ; RV32-PIC-LABEL: get_hidden_var: ; RV32-PIC: # %bb.0: -; RV32-PIC-NEXT: .LBB3_1: # Label of block must be emitted +; RV32-PIC-NEXT: .Lpcrel_hi2: ; RV32-PIC-NEXT: auipc a0, %pcrel_hi(hidden_var) -; RV32-PIC-NEXT: addi a0, a0, %pcrel_lo(.LBB3_1) +; RV32-PIC-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi2) ; RV32-PIC-NEXT: ret ; ; RV64-STATIC-LABEL: get_hidden_var: @@ -121,9 +121,9 @@ ; ; RV64-PIC-LABEL: get_hidden_var: ; RV64-PIC: # %bb.0: -; RV64-PIC-NEXT: .LBB3_1: # Label of block must be emitted +; RV64-PIC-NEXT: .Lpcrel_hi2: ; RV64-PIC-NEXT: auipc a0, %pcrel_hi(hidden_var) -; RV64-PIC-NEXT: addi a0, a0, %pcrel_lo(.LBB3_1) +; RV64-PIC-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi2) ; RV64-PIC-NEXT: ret ret i32* @hidden_var } @@ -138,9 +138,9 @@ ; ; RV32-PIC-LABEL: get_protected_var: ; RV32-PIC: # %bb.0: -; RV32-PIC-NEXT: .LBB4_1: # Label of block must be emitted +; RV32-PIC-NEXT: .Lpcrel_hi3: ; RV32-PIC-NEXT: auipc a0, %pcrel_hi(protected_var) -; RV32-PIC-NEXT: addi a0, a0, %pcrel_lo(.LBB4_1) +; RV32-PIC-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi3) ; RV32-PIC-NEXT: ret ; ; RV64-STATIC-LABEL: get_protected_var: @@ -151,9 +151,9 @@ ; ; RV64-PIC-LABEL: get_protected_var: ; RV64-PIC: # %bb.0: -; RV64-PIC-NEXT: .LBB4_1: # Label of block must be emitted +; RV64-PIC-NEXT: .Lpcrel_hi3: ; RV64-PIC-NEXT: auipc a0, %pcrel_hi(protected_var) -; RV64-PIC-NEXT: addi a0, a0, %pcrel_lo(.LBB4_1) +; RV64-PIC-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi3) ; RV64-PIC-NEXT: ret ret i32* @protected_var } @@ -196,9 +196,9 @@ ; ; RV32-PIC-LABEL: dsolocal_func: ; RV32-PIC: # %bb.0: -; RV32-PIC-NEXT: .LBB6_1: # Label of block must be emitted +; RV32-PIC-NEXT: .Lpcrel_hi4: ; RV32-PIC-NEXT: auipc a0, %pcrel_hi(.Ldsolocal_func$local) -; RV32-PIC-NEXT: addi a0, a0, %pcrel_lo(.LBB6_1) +; RV32-PIC-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi4) ; RV32-PIC-NEXT: ret ; ; RV64-STATIC-LABEL: dsolocal_func: @@ -209,9 +209,9 @@ ; ; RV64-PIC-LABEL: dsolocal_func: ; RV64-PIC: # %bb.0: -; RV64-PIC-NEXT: .LBB6_1: # Label of block must be emitted +; RV64-PIC-NEXT: .Lpcrel_hi4: ; RV64-PIC-NEXT: auipc a0, %pcrel_hi(.Ldsolocal_func$local) -; RV64-PIC-NEXT: addi a0, a0, %pcrel_lo(.LBB6_1) +; RV64-PIC-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi4) ; RV64-PIC-NEXT: ret ret void()* bitcast(void()*()* @dsolocal_func to void()*) } @@ -225,9 +225,9 @@ ; ; RV32-PIC-LABEL: weak_dsolocal_func: ; RV32-PIC: # %bb.0: -; RV32-PIC-NEXT: .LBB7_1: # Label of block must be emitted +; RV32-PIC-NEXT: .Lpcrel_hi5: ; RV32-PIC-NEXT: auipc a0, %pcrel_hi(weak_dsolocal_func) -; RV32-PIC-NEXT: addi a0, a0, %pcrel_lo(.LBB7_1) +; RV32-PIC-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi5) ; RV32-PIC-NEXT: ret ; ; RV64-STATIC-LABEL: weak_dsolocal_func: @@ -238,9 +238,9 @@ ; ; RV64-PIC-LABEL: weak_dsolocal_func: ; RV64-PIC: # %bb.0: -; RV64-PIC-NEXT: .LBB7_1: # Label of block must be emitted +; RV64-PIC-NEXT: .Lpcrel_hi5: ; RV64-PIC-NEXT: auipc a0, %pcrel_hi(weak_dsolocal_func) -; RV64-PIC-NEXT: addi a0, a0, %pcrel_lo(.LBB7_1) +; RV64-PIC-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi5) ; RV64-PIC-NEXT: ret ret void()* bitcast(void()*()* @weak_dsolocal_func to void()*) } diff --git a/llvm/test/CodeGen/RISCV/jumptable.ll b/llvm/test/CodeGen/RISCV/jumptable.ll --- a/llvm/test/CodeGen/RISCV/jumptable.ll +++ b/llvm/test/CodeGen/RISCV/jumptable.ll @@ -203,10 +203,9 @@ ; RV32I-MEDIUM-NEXT: bltu a2, a0, .LBB1_9 ; RV32I-MEDIUM-NEXT: # %bb.1: # %entry ; RV32I-MEDIUM-NEXT: slli a0, a0, 2 -; RV32I-MEDIUM-NEXT: .LBB1_10: # %entry -; RV32I-MEDIUM-NEXT: # Label of block must be emitted +; RV32I-MEDIUM-NEXT: .Lpcrel_hi0: ; RV32I-MEDIUM-NEXT: auipc a2, %pcrel_hi(.LJTI1_0) -; RV32I-MEDIUM-NEXT: addi a2, a2, %pcrel_lo(.LBB1_10) +; RV32I-MEDIUM-NEXT: addi a2, a2, %pcrel_lo(.Lpcrel_hi0) ; RV32I-MEDIUM-NEXT: add a0, a0, a2 ; RV32I-MEDIUM-NEXT: lw a0, 0(a0) ; RV32I-MEDIUM-NEXT: jr a0 @@ -275,10 +274,9 @@ ; RV64I-MEDIUM-NEXT: bltu a2, a0, .LBB1_9 ; RV64I-MEDIUM-NEXT: # %bb.1: # %entry ; RV64I-MEDIUM-NEXT: slli a0, a0, 3 -; RV64I-MEDIUM-NEXT: .LBB1_10: # %entry -; RV64I-MEDIUM-NEXT: # Label of block must be emitted +; RV64I-MEDIUM-NEXT: .Lpcrel_hi0: ; RV64I-MEDIUM-NEXT: auipc a2, %pcrel_hi(.LJTI1_0) -; RV64I-MEDIUM-NEXT: addi a2, a2, %pcrel_lo(.LBB1_10) +; RV64I-MEDIUM-NEXT: addi a2, a2, %pcrel_lo(.Lpcrel_hi0) ; RV64I-MEDIUM-NEXT: add a0, a0, a2 ; RV64I-MEDIUM-NEXT: ld a0, 0(a0) ; RV64I-MEDIUM-NEXT: jr a0 diff --git a/llvm/test/CodeGen/RISCV/machinelicm-address-pseudos.ll b/llvm/test/CodeGen/RISCV/machinelicm-address-pseudos.ll --- a/llvm/test/CodeGen/RISCV/machinelicm-address-pseudos.ll +++ b/llvm/test/CodeGen/RISCV/machinelicm-address-pseudos.ll @@ -12,10 +12,9 @@ ; RV32I-LABEL: test_lla: ; RV32I: # %bb.0: # %entry ; RV32I-NEXT: li a1, 0 -; RV32I-NEXT: .LBB0_3: # %entry -; RV32I-NEXT: # Label of block must be emitted +; RV32I-NEXT: .Lpcrel_hi0: ; RV32I-NEXT: auipc a2, %pcrel_hi(l) -; RV32I-NEXT: addi a2, a2, %pcrel_lo(.LBB0_3) +; RV32I-NEXT: addi a2, a2, %pcrel_lo(.Lpcrel_hi0) ; RV32I-NEXT: .LBB0_1: # %loop ; RV32I-NEXT: # =>This Inner Loop Header: Depth=1 ; RV32I-NEXT: lw a3, 0(a2) @@ -27,10 +26,9 @@ ; RV64I-LABEL: test_lla: ; RV64I: # %bb.0: # %entry ; RV64I-NEXT: li a1, 0 -; RV64I-NEXT: .LBB0_3: # %entry -; RV64I-NEXT: # Label of block must be emitted +; RV64I-NEXT: .Lpcrel_hi0: ; RV64I-NEXT: auipc a2, %pcrel_hi(l) -; RV64I-NEXT: addi a2, a2, %pcrel_lo(.LBB0_3) +; RV64I-NEXT: addi a2, a2, %pcrel_lo(.Lpcrel_hi0) ; RV64I-NEXT: .LBB0_1: # %loop ; RV64I-NEXT: # =>This Inner Loop Header: Depth=1 ; RV64I-NEXT: lw a3, 0(a2) diff --git a/llvm/test/CodeGen/RISCV/mir-target-flags-medium.ll b/llvm/test/CodeGen/RISCV/mir-target-flags-medium.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/mir-target-flags-medium.ll @@ -0,0 +1,51 @@ +; RUN: llc -mtriple=riscv32 --code-model=medium --relocation-model=pic \ +; RUN: -stop-after riscv-expand-pseudo %s -o %t.mir +; RUN: llc -mtriple=riscv32 -run-pass none %t.mir -o - | \ +; RUN: FileCheck %s -check-prefix=RV32-MED + +; This tests the RISC-V-specific serialization and deserialization of +; `target-flags(...)` with the medium code model. We currently can't test +; `internal global` variables with this model because MIR printing doesn't +; yet support temporary MCSymbols, which we now emit during the PseudoLLA +; expansion into AUIPC+ADDI instructions. + +@g_e = external global i32 +@t_un = external thread_local global i32 +@t_ld = external thread_local(localdynamic) global i32 +@t_ie = external thread_local(initialexec) global i32 +@t_le = external thread_local(localexec) global i32 + +declare i32 @callee(i32) nounwind + +define i32 @caller(i32 %a) nounwind { +; RV32-MED-LABEL: name: caller +; RV32-MED: target-flags(riscv-got-hi) @g_e +; RV32-MED-NEXT: target-flags(riscv-pcrel-lo) %bb.1 +; RV32-MED: target-flags(riscv-tls-gd-hi) @t_un +; RV32-MED-NEXT: target-flags(riscv-pcrel-lo) %bb.2 +; RV32-MED-NEXT: target-flags(riscv-plt) &__tls_get_addr +; RV32-MED: target-flags(riscv-tls-gd-hi) @t_ld +; RV32-MED-NEXT: target-flags(riscv-pcrel-lo) %bb.3 +; RV32-MED-NEXT: target-flags(riscv-plt) &__tls_get_addr +; RV32-MED: target-flags(riscv-tls-got-hi) @t_ie +; RV32-MED-NEXT: target-flags(riscv-pcrel-lo) %bb.4 +; RV32-MED: target-flags(riscv-tprel-hi) @t_le +; RV32-MED-NEXT: target-flags(riscv-tprel-add) @t_le +; RV32-MED-NEXT: target-flags(riscv-tprel-lo) @t_le +; RV32-MED: target-flags(riscv-plt) @callee +; + %b = load i32, i32* @g_e + %c = load i32, i32* @t_un + %d = load i32, i32* @t_ld + %e = load i32, i32* @t_ie + %f = load i32, i32* @t_le + %sum = bitcast i32 0 to i32 + %sum.a = add i32 %sum, %a + %sum.b = add i32 %sum.a, %b + %sum.c = add i32 %sum.b, %c + %sum.d = add i32 %sum.c, %d + %sum.e = add i32 %sum.d, %e + %sum.f = add i32 %sum.e, %f + %retval = call i32 @callee(i32 %sum.f) + ret i32 %retval +} diff --git a/llvm/test/CodeGen/RISCV/mir-target-flags.ll b/llvm/test/CodeGen/RISCV/mir-target-flags-small.ll rename from llvm/test/CodeGen/RISCV/mir-target-flags.ll rename to llvm/test/CodeGen/RISCV/mir-target-flags-small.ll --- a/llvm/test/CodeGen/RISCV/mir-target-flags.ll +++ b/llvm/test/CodeGen/RISCV/mir-target-flags-small.ll @@ -3,13 +3,8 @@ ; RUN: llc -mtriple=riscv32 -run-pass none %t.mir -o - | \ ; RUN: FileCheck %s -check-prefix=RV32-SMALL ; -; RUN: llc -mtriple=riscv32 --code-model=medium --relocation-model=pic \ -; RUN: -stop-after riscv-expand-pseudo %s -o %t.mir -; RUN: llc -mtriple=riscv32 -run-pass none %t.mir -o - | \ -; RUN: FileCheck %s -check-prefix=RV32-MED - ; This tests the RISC-V-specific serialization and deserialization of -; `target-flags(...)` +; `target-flags(...)` with the small code model. @g_e = external global i32 @g_i = internal global i32 0 @@ -36,24 +31,6 @@ ; RV32-SMALL-NEXT: target-flags(riscv-tprel-add) @t_le ; RV32-SMALL-NEXT: target-flags(riscv-tprel-lo) @t_le ; RV32-SMALL: target-flags(riscv-plt) @callee -; -; RV32-MED-LABEL: name: caller -; RV32-MED: target-flags(riscv-got-hi) @g_e -; RV32-MED-NEXT: target-flags(riscv-pcrel-lo) %bb.1 -; RV32-MED: target-flags(riscv-pcrel-hi) @g_i -; RV32-MED-NEXT: target-flags(riscv-pcrel-lo) %bb.2 -; RV32-MED: target-flags(riscv-tls-gd-hi) @t_un -; RV32-MED-NEXT: target-flags(riscv-pcrel-lo) %bb.3 -; RV32-MED-NEXT: target-flags(riscv-plt) &__tls_get_addr -; RV32-MED: target-flags(riscv-tls-gd-hi) @t_ld -; RV32-MED-NEXT: target-flags(riscv-pcrel-lo) %bb.4 -; RV32-MED-NEXT: target-flags(riscv-plt) &__tls_get_addr -; RV32-MED: target-flags(riscv-tls-got-hi) @t_ie -; RV32-MED-NEXT: target-flags(riscv-pcrel-lo) %bb.5 -; RV32-MED: target-flags(riscv-tprel-hi) @t_le -; RV32-MED-NEXT: target-flags(riscv-tprel-add) @t_le -; RV32-MED-NEXT: target-flags(riscv-tprel-lo) @t_le -; RV32-MED: target-flags(riscv-plt) @callee ; %b = load i32, i32* @g_e %c = load i32, i32* @g_i diff --git a/llvm/test/CodeGen/RISCV/pic-models.ll b/llvm/test/CodeGen/RISCV/pic-models.ll --- a/llvm/test/CodeGen/RISCV/pic-models.ll +++ b/llvm/test/CodeGen/RISCV/pic-models.ll @@ -61,10 +61,9 @@ ; ; RV32-PIC-LABEL: f2: ; RV32-PIC: # %bb.0: # %entry -; RV32-PIC-NEXT: .LBB1_1: # %entry -; RV32-PIC-NEXT: # Label of block must be emitted +; RV32-PIC-NEXT: .Lpcrel_hi0: ; RV32-PIC-NEXT: auipc a0, %pcrel_hi(internal_var) -; RV32-PIC-NEXT: addi a0, a0, %pcrel_lo(.LBB1_1) +; RV32-PIC-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi0) ; RV32-PIC-NEXT: ret ; ; RV64-STATIC-LABEL: f2: @@ -75,10 +74,9 @@ ; ; RV64-PIC-LABEL: f2: ; RV64-PIC: # %bb.0: # %entry -; RV64-PIC-NEXT: .LBB1_1: # %entry -; RV64-PIC-NEXT: # Label of block must be emitted +; RV64-PIC-NEXT: .Lpcrel_hi0: ; RV64-PIC-NEXT: auipc a0, %pcrel_hi(internal_var) -; RV64-PIC-NEXT: addi a0, a0, %pcrel_lo(.LBB1_1) +; RV64-PIC-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi0) ; RV64-PIC-NEXT: ret entry: ret i32* @internal_var