diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp index 1832ef50b9ad1c..f0f5d2a9b2a31f 100644 --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -237,7 +237,7 @@ bool RISCVAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, // RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand). if (!AddrReg.isReg()) return true; - if (!Offset.isImm() && !Offset.isGlobal()) + if (!Offset.isImm() && !Offset.isGlobal() && !Offset.isMCSymbol()) return true; MCOperand MCO; @@ -246,7 +246,7 @@ bool RISCVAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, if (Offset.isImm()) OS << MCO.getImm(); - else if (Offset.isGlobal()) + else if (Offset.isGlobal() || Offset.isMCSymbol()) OS << *MCO.getExpr(); OS << "(" << RISCVInstPrinter::getRegisterName(AddrReg.getReg()) << ")"; return false; diff --git a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp index 855322b981fb63..4d79b67b9e5f2c 100644 --- a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp +++ b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp @@ -357,6 +357,8 @@ bool RISCVMergeBaseOffsetOpt::foldIntoMemoryOps(MachineInstr &Hi, // Tail: lw vreg3, 8(vreg2) std::optional CommonOffset; + DenseMap> + InlineAsmMemoryOpIndexesMap; for (const MachineInstr &UseMI : MRI->use_instructions(DestReg)) { switch (UseMI.getOpcode()) { default: @@ -391,6 +393,44 @@ bool RISCVMergeBaseOffsetOpt::foldIntoMemoryOps(MachineInstr &Hi, if (CommonOffset && Offset != CommonOffset) return false; CommonOffset = Offset; + break; + } + case RISCV::INLINEASM: + case RISCV::INLINEASM_BR: { + SmallVector 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; + + unsigned Flags = FlagsMO.getImm(); + NumOps = InlineAsm::getNumOperandRegisters(Flags); + + // Memory constraints have two operands. + if (NumOps != 2 || !InlineAsm::isMemKind(Flags)) + continue; + + 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; } } } @@ -415,13 +455,32 @@ bool RISCVMergeBaseOffsetOpt::foldIntoMemoryOps(MachineInstr &Hi, // Update the immediate in the load/store instructions to add the offset. for (MachineInstr &UseMI : llvm::make_early_inc_range(MRI->use_instructions(DestReg))) { - UseMI.removeOperand(2); - UseMI.addOperand(ImmOp); - // Update the base reg in the Tail instruction to feed from LUI. - // Output of Hi is only used in Lo, no need to use MRI->replaceRegWith(). - UseMI.getOperand(1).setReg(Hi.getOperand(0).getReg()); + if (UseMI.getOpcode() == RISCV::INLINEASM || + UseMI.getOpcode() == RISCV::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 llvm::MachineOperand::MachineOperandType::MO_MCSymbol: + MO.ChangeToMCSymbol(ImmOp.getMCSymbol(), ImmOp.getTargetFlags()); + MO.setOffset(ImmOp.getOffset()); + break; + default: + report_fatal_error("unsupported machine operand type"); + break; + } + } + } else { + UseMI.removeOperand(2); + UseMI.addOperand(ImmOp); + } } + MRI->replaceRegWith(Lo.getOperand(0).getReg(), Hi.getOperand(0).getReg()); Lo.eraseFromParent(); return true; } diff --git a/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll b/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll index a74572518cd033..94087ec1149fd8 100644 --- a/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll +++ b/llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll @@ -125,9 +125,8 @@ define void @constraint_m_with_global_1() nounwind { ; RV32I-MEDIUM: # %bb.0: ; RV32I-MEDIUM-NEXT: .Lpcrel_hi0: ; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg) -; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi0) ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 0(a0) +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi0)(a0) ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: ret ; @@ -135,9 +134,8 @@ define void @constraint_m_with_global_1() nounwind { ; RV64I-MEDIUM: # %bb.0: ; RV64I-MEDIUM-NEXT: .Lpcrel_hi0: ; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg) -; RV64I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi0) ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 0(a0) +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi0)(a0) ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: ret call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) @eg) @@ -147,39 +145,35 @@ define void @constraint_m_with_global_1() nounwind { define void @constraint_m_with_global_2() nounwind { ; RV32I-LABEL: constraint_m_with_global_2: ; RV32I: # %bb.0: -; RV32I-NEXT: lui a0, %hi(eg) -; RV32I-NEXT: addi a0, a0, %lo(eg) +; RV32I-NEXT: lui a0, %hi(eg+4) ; RV32I-NEXT: #APP -; RV32I-NEXT: sw zero, 4(a0) +; RV32I-NEXT: sw zero, %lo(eg+4)(a0) ; RV32I-NEXT: #NO_APP ; RV32I-NEXT: ret ; ; RV64I-LABEL: constraint_m_with_global_2: ; RV64I: # %bb.0: -; RV64I-NEXT: lui a0, %hi(eg) -; RV64I-NEXT: addi a0, a0, %lo(eg) +; RV64I-NEXT: lui a0, %hi(eg+4) ; RV64I-NEXT: #APP -; RV64I-NEXT: sw zero, 4(a0) +; RV64I-NEXT: sw zero, %lo(eg+4)(a0) ; RV64I-NEXT: #NO_APP ; RV64I-NEXT: ret ; ; RV32I-MEDIUM-LABEL: constraint_m_with_global_2: ; RV32I-MEDIUM: # %bb.0: ; RV32I-MEDIUM-NEXT: .Lpcrel_hi1: -; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg) -; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi1) +; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg+4) ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 4(a0) +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi1)(a0) ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: ret ; ; RV64I-MEDIUM-LABEL: constraint_m_with_global_2: ; RV64I-MEDIUM: # %bb.0: ; RV64I-MEDIUM-NEXT: .Lpcrel_hi1: -; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg) -; RV64I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi1) +; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg+4) ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 4(a0) +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi1)(a0) ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: ret call void asm "sw zero, $0", "=*m"(ptr nonnull elementtype(i32) getelementptr inbounds ([400000 x i32], ptr @eg, i32 0, i32 1)) @@ -190,18 +184,16 @@ define void @constraint_m_with_global_3() nounwind { ; RV32I-LABEL: constraint_m_with_global_3: ; RV32I: # %bb.0: ; RV32I-NEXT: lui a0, %hi(eg+8000) -; RV32I-NEXT: addi a0, a0, %lo(eg+8000) ; RV32I-NEXT: #APP -; RV32I-NEXT: sw zero, 0(a0) +; RV32I-NEXT: sw zero, %lo(eg+8000)(a0) ; RV32I-NEXT: #NO_APP ; RV32I-NEXT: ret ; ; RV64I-LABEL: constraint_m_with_global_3: ; RV64I: # %bb.0: ; RV64I-NEXT: lui a0, %hi(eg+8000) -; RV64I-NEXT: addi a0, a0, %lo(eg+8000) ; RV64I-NEXT: #APP -; RV64I-NEXT: sw zero, 0(a0) +; RV64I-NEXT: sw zero, %lo(eg+8000)(a0) ; RV64I-NEXT: #NO_APP ; RV64I-NEXT: ret ; @@ -209,9 +201,8 @@ define void @constraint_m_with_global_3() nounwind { ; RV32I-MEDIUM: # %bb.0: ; RV32I-MEDIUM-NEXT: .Lpcrel_hi2: ; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg+8000) -; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi2) ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 0(a0) +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi2)(a0) ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: ret ; @@ -219,9 +210,8 @@ define void @constraint_m_with_global_3() nounwind { ; RV64I-MEDIUM: # %bb.0: ; RV64I-MEDIUM-NEXT: .Lpcrel_hi2: ; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg+8000) -; RV64I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi2) ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 0(a0) +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi2)(a0) ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: ret call void asm "sw zero, $0", "=*m"(ptr nonnull elementtype(i32) getelementptr inbounds ([400000 x i32], ptr @eg, i32 0, i32 2000)) @@ -271,19 +261,17 @@ define void @constraint_m_with_extern_weak_global_1() nounwind { define void @constraint_m_with_extern_weak_global_2() nounwind { ; RV32I-LABEL: constraint_m_with_extern_weak_global_2: ; RV32I: # %bb.0: -; RV32I-NEXT: lui a0, %hi(ewg) -; RV32I-NEXT: addi a0, a0, %lo(ewg) +; RV32I-NEXT: lui a0, %hi(ewg+4) ; RV32I-NEXT: #APP -; RV32I-NEXT: sw zero, 4(a0) +; RV32I-NEXT: sw zero, %lo(ewg+4)(a0) ; RV32I-NEXT: #NO_APP ; RV32I-NEXT: ret ; ; RV64I-LABEL: constraint_m_with_extern_weak_global_2: ; RV64I: # %bb.0: -; RV64I-NEXT: lui a0, %hi(ewg) -; RV64I-NEXT: addi a0, a0, %lo(ewg) +; RV64I-NEXT: lui a0, %hi(ewg+4) ; RV64I-NEXT: #APP -; RV64I-NEXT: sw zero, 4(a0) +; RV64I-NEXT: sw zero, %lo(ewg+4)(a0) ; RV64I-NEXT: #NO_APP ; RV64I-NEXT: ret ; @@ -314,18 +302,16 @@ define void @constraint_m_with_extern_weak_global_3() nounwind { ; RV32I-LABEL: constraint_m_with_extern_weak_global_3: ; RV32I: # %bb.0: ; RV32I-NEXT: lui a0, %hi(ewg+8000) -; RV32I-NEXT: addi a0, a0, %lo(ewg+8000) ; RV32I-NEXT: #APP -; RV32I-NEXT: sw zero, 0(a0) +; RV32I-NEXT: sw zero, %lo(ewg+8000)(a0) ; RV32I-NEXT: #NO_APP ; RV32I-NEXT: ret ; ; RV64I-LABEL: constraint_m_with_extern_weak_global_3: ; RV64I: # %bb.0: ; RV64I-NEXT: lui a0, %hi(ewg+8000) -; RV64I-NEXT: addi a0, a0, %lo(ewg+8000) ; RV64I-NEXT: #APP -; RV64I-NEXT: sw zero, 0(a0) +; RV64I-NEXT: sw zero, %lo(ewg+8000)(a0) ; RV64I-NEXT: #NO_APP ; RV64I-NEXT: ret ; @@ -379,9 +365,8 @@ define void @constraint_m_with_multi_operands() nounwind { ; RV32I-MEDIUM: # %bb.0: ; RV32I-MEDIUM-NEXT: .Lpcrel_hi6: ; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg) -; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi6) ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 0(a0); sw zero, 0(a0) +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi6)(a0); sw zero, %pcrel_lo(.Lpcrel_hi6)(a0) ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: ret ; @@ -389,9 +374,8 @@ define void @constraint_m_with_multi_operands() nounwind { ; RV64I-MEDIUM: # %bb.0: ; RV64I-MEDIUM-NEXT: .Lpcrel_hi6: ; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg) -; RV64I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi6) ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 0(a0); sw zero, 0(a0) +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi6)(a0); sw zero, %pcrel_lo(.Lpcrel_hi6)(a0) ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: ret call void asm "sw zero, $0; sw zero, $1", "=*m,=*m"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg) @@ -425,12 +409,11 @@ define void @constraint_m_with_multi_asm() nounwind { ; RV32I-MEDIUM: # %bb.0: ; RV32I-MEDIUM-NEXT: .Lpcrel_hi7: ; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg) -; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi7) ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 0(a0) +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi7)(a0) ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 0(a0) +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi7)(a0) ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: ret ; @@ -438,12 +421,11 @@ define void @constraint_m_with_multi_asm() nounwind { ; RV64I-MEDIUM: # %bb.0: ; RV64I-MEDIUM-NEXT: .Lpcrel_hi7: ; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg) -; RV64I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi7) ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 0(a0) +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi7)(a0) ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 0(a0) +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi7)(a0) ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: ret call void asm "sw zero, $0", "=*m"(ptr elementtype(i32) @eg) @@ -486,9 +468,8 @@ define i32 @constraint_m_with_callbr_multi_operands(i32 %a) { ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Lpcrel_hi8: ; RV32I-MEDIUM-NEXT: auipc a1, %pcrel_hi(eg) -; RV32I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi8) ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB11_2 +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi8)(a1); sw zero, %pcrel_lo(.Lpcrel_hi8)(a1); beqz a0, .LBB11_2 ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: # %bb.1: # %normal ; RV32I-MEDIUM-NEXT: li a0, 0 @@ -503,9 +484,8 @@ define i32 @constraint_m_with_callbr_multi_operands(i32 %a) { ; RV64I-MEDIUM: # %bb.0: # %entry ; RV64I-MEDIUM-NEXT: .Lpcrel_hi8: ; RV64I-MEDIUM-NEXT: auipc a1, %pcrel_hi(eg) -; RV64I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi8) ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB11_2 +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi8)(a1); sw zero, %pcrel_lo(.Lpcrel_hi8)(a1); beqz a0, .LBB11_2 ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: # %bb.1: # %normal ; RV64I-MEDIUM-NEXT: li a0, 0 @@ -568,13 +548,12 @@ define i32 @constraint_m_with_multi_callbr_asm(i32 %a) { ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Lpcrel_hi9: ; RV32I-MEDIUM-NEXT: auipc a1, %pcrel_hi(eg) -; RV32I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi9) ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 0(a1); beqz a0, .LBB12_3 +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi9)(a1); beqz a0, .LBB12_3 ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: # %bb.1: # %normal0 ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 0(a1); beqz a0, .LBB12_3 +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi9)(a1); beqz a0, .LBB12_3 ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: # %bb.2: # %normal1 ; RV32I-MEDIUM-NEXT: li a0, 0 @@ -589,13 +568,12 @@ define i32 @constraint_m_with_multi_callbr_asm(i32 %a) { ; RV64I-MEDIUM: # %bb.0: # %entry ; RV64I-MEDIUM-NEXT: .Lpcrel_hi9: ; RV64I-MEDIUM-NEXT: auipc a1, %pcrel_hi(eg) -; RV64I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi9) ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 0(a1); beqz a0, .LBB12_3 +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi9)(a1); beqz a0, .LBB12_3 ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: # %bb.1: # %normal0 ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 0(a1); beqz a0, .LBB12_3 +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi9)(a1); beqz a0, .LBB12_3 ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: # %bb.2: # %normal1 ; RV64I-MEDIUM-NEXT: li a0, 0 @@ -732,9 +710,8 @@ define void @constraint_o_with_global_1() nounwind { ; RV32I-MEDIUM: # %bb.0: ; RV32I-MEDIUM-NEXT: .Lpcrel_hi10: ; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg) -; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi10) ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 0(a0) +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi10)(a0) ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: ret ; @@ -742,9 +719,8 @@ define void @constraint_o_with_global_1() nounwind { ; RV64I-MEDIUM: # %bb.0: ; RV64I-MEDIUM-NEXT: .Lpcrel_hi10: ; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg) -; RV64I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi10) ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 0(a0) +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi10)(a0) ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: ret call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) @eg) @@ -754,39 +730,35 @@ define void @constraint_o_with_global_1() nounwind { define void @constraint_o_with_global_2() nounwind { ; RV32I-LABEL: constraint_o_with_global_2: ; RV32I: # %bb.0: -; RV32I-NEXT: lui a0, %hi(eg) -; RV32I-NEXT: addi a0, a0, %lo(eg) +; RV32I-NEXT: lui a0, %hi(eg+4) ; RV32I-NEXT: #APP -; RV32I-NEXT: sw zero, 4(a0) +; RV32I-NEXT: sw zero, %lo(eg+4)(a0) ; RV32I-NEXT: #NO_APP ; RV32I-NEXT: ret ; ; RV64I-LABEL: constraint_o_with_global_2: ; RV64I: # %bb.0: -; RV64I-NEXT: lui a0, %hi(eg) -; RV64I-NEXT: addi a0, a0, %lo(eg) +; RV64I-NEXT: lui a0, %hi(eg+4) ; RV64I-NEXT: #APP -; RV64I-NEXT: sw zero, 4(a0) +; RV64I-NEXT: sw zero, %lo(eg+4)(a0) ; RV64I-NEXT: #NO_APP ; RV64I-NEXT: ret ; ; RV32I-MEDIUM-LABEL: constraint_o_with_global_2: ; RV32I-MEDIUM: # %bb.0: ; RV32I-MEDIUM-NEXT: .Lpcrel_hi11: -; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg) -; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi11) +; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg+4) ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 4(a0) +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi11)(a0) ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: ret ; ; RV64I-MEDIUM-LABEL: constraint_o_with_global_2: ; RV64I-MEDIUM: # %bb.0: ; RV64I-MEDIUM-NEXT: .Lpcrel_hi11: -; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg) -; RV64I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi11) +; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg+4) ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 4(a0) +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi11)(a0) ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: ret call void asm "sw zero, $0", "=*o"(ptr nonnull elementtype(i32) getelementptr inbounds ([400000 x i32], ptr @eg, i32 0, i32 1)) @@ -797,18 +769,16 @@ define void @constraint_o_with_global_3() nounwind { ; RV32I-LABEL: constraint_o_with_global_3: ; RV32I: # %bb.0: ; RV32I-NEXT: lui a0, %hi(eg+8000) -; RV32I-NEXT: addi a0, a0, %lo(eg+8000) ; RV32I-NEXT: #APP -; RV32I-NEXT: sw zero, 0(a0) +; RV32I-NEXT: sw zero, %lo(eg+8000)(a0) ; RV32I-NEXT: #NO_APP ; RV32I-NEXT: ret ; ; RV64I-LABEL: constraint_o_with_global_3: ; RV64I: # %bb.0: ; RV64I-NEXT: lui a0, %hi(eg+8000) -; RV64I-NEXT: addi a0, a0, %lo(eg+8000) ; RV64I-NEXT: #APP -; RV64I-NEXT: sw zero, 0(a0) +; RV64I-NEXT: sw zero, %lo(eg+8000)(a0) ; RV64I-NEXT: #NO_APP ; RV64I-NEXT: ret ; @@ -816,9 +786,8 @@ define void @constraint_o_with_global_3() nounwind { ; RV32I-MEDIUM: # %bb.0: ; RV32I-MEDIUM-NEXT: .Lpcrel_hi12: ; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg+8000) -; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi12) ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 0(a0) +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi12)(a0) ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: ret ; @@ -826,9 +795,8 @@ define void @constraint_o_with_global_3() nounwind { ; RV64I-MEDIUM: # %bb.0: ; RV64I-MEDIUM-NEXT: .Lpcrel_hi12: ; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg+8000) -; RV64I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi12) ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 0(a0) +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi12)(a0) ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: ret call void asm "sw zero, $0", "=*o"(ptr nonnull elementtype(i32) getelementptr inbounds ([400000 x i32], ptr @eg, i32 0, i32 2000)) @@ -878,19 +846,17 @@ define void @constraint_o_with_extern_weak_global_1() nounwind { define void @constraint_o_with_extern_weak_global_2() nounwind { ; RV32I-LABEL: constraint_o_with_extern_weak_global_2: ; RV32I: # %bb.0: -; RV32I-NEXT: lui a0, %hi(ewg) -; RV32I-NEXT: addi a0, a0, %lo(ewg) +; RV32I-NEXT: lui a0, %hi(ewg+4) ; RV32I-NEXT: #APP -; RV32I-NEXT: sw zero, 4(a0) +; RV32I-NEXT: sw zero, %lo(ewg+4)(a0) ; RV32I-NEXT: #NO_APP ; RV32I-NEXT: ret ; ; RV64I-LABEL: constraint_o_with_extern_weak_global_2: ; RV64I: # %bb.0: -; RV64I-NEXT: lui a0, %hi(ewg) -; RV64I-NEXT: addi a0, a0, %lo(ewg) +; RV64I-NEXT: lui a0, %hi(ewg+4) ; RV64I-NEXT: #APP -; RV64I-NEXT: sw zero, 4(a0) +; RV64I-NEXT: sw zero, %lo(ewg+4)(a0) ; RV64I-NEXT: #NO_APP ; RV64I-NEXT: ret ; @@ -921,18 +887,16 @@ define void @constraint_o_with_extern_weak_global_3() nounwind { ; RV32I-LABEL: constraint_o_with_extern_weak_global_3: ; RV32I: # %bb.0: ; RV32I-NEXT: lui a0, %hi(ewg+8000) -; RV32I-NEXT: addi a0, a0, %lo(ewg+8000) ; RV32I-NEXT: #APP -; RV32I-NEXT: sw zero, 0(a0) +; RV32I-NEXT: sw zero, %lo(ewg+8000)(a0) ; RV32I-NEXT: #NO_APP ; RV32I-NEXT: ret ; ; RV64I-LABEL: constraint_o_with_extern_weak_global_3: ; RV64I: # %bb.0: ; RV64I-NEXT: lui a0, %hi(ewg+8000) -; RV64I-NEXT: addi a0, a0, %lo(ewg+8000) ; RV64I-NEXT: #APP -; RV64I-NEXT: sw zero, 0(a0) +; RV64I-NEXT: sw zero, %lo(ewg+8000)(a0) ; RV64I-NEXT: #NO_APP ; RV64I-NEXT: ret ; @@ -986,9 +950,8 @@ define void @constraint_o_with_multi_operands() nounwind { ; RV32I-MEDIUM: # %bb.0: ; RV32I-MEDIUM-NEXT: .Lpcrel_hi16: ; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg) -; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi16) ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 0(a0) \n sw zero, 0(a0) +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi16)(a0) \n sw zero, %pcrel_lo(.Lpcrel_hi16)(a0) ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: ret ; @@ -996,9 +959,8 @@ define void @constraint_o_with_multi_operands() nounwind { ; RV64I-MEDIUM: # %bb.0: ; RV64I-MEDIUM-NEXT: .Lpcrel_hi16: ; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg) -; RV64I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi16) ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 0(a0) \n sw zero, 0(a0) +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi16)(a0) \n sw zero, %pcrel_lo(.Lpcrel_hi16)(a0) ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: ret call void asm "sw zero, $0 \n sw zero, $1", "=*o,=*o"(ptr elementtype(i32) @eg, ptr elementtype(i32) @eg) @@ -1032,12 +994,11 @@ define void @constraint_o_with_multi_asm() nounwind { ; RV32I-MEDIUM: # %bb.0: ; RV32I-MEDIUM-NEXT: .Lpcrel_hi17: ; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg) -; RV32I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi17) ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 0(a0) +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi17)(a0) ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 0(a0) +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi17)(a0) ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: ret ; @@ -1045,12 +1006,11 @@ define void @constraint_o_with_multi_asm() nounwind { ; RV64I-MEDIUM: # %bb.0: ; RV64I-MEDIUM-NEXT: .Lpcrel_hi17: ; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(eg) -; RV64I-MEDIUM-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi17) ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 0(a0) +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi17)(a0) ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 0(a0) +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi17)(a0) ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: ret call void asm "sw zero, $0", "=*o"(ptr elementtype(i32) @eg) @@ -1093,9 +1053,8 @@ define i32 @constraint_o_with_callbr_multi_operands(i32 %a) { ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Lpcrel_hi18: ; RV32I-MEDIUM-NEXT: auipc a1, %pcrel_hi(eg) -; RV32I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi18) ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB24_2 +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi18)(a1); sw zero, %pcrel_lo(.Lpcrel_hi18)(a1); beqz a0, .LBB24_2 ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: # %bb.1: # %normal ; RV32I-MEDIUM-NEXT: li a0, 0 @@ -1110,9 +1069,8 @@ define i32 @constraint_o_with_callbr_multi_operands(i32 %a) { ; RV64I-MEDIUM: # %bb.0: # %entry ; RV64I-MEDIUM-NEXT: .Lpcrel_hi18: ; RV64I-MEDIUM-NEXT: auipc a1, %pcrel_hi(eg) -; RV64I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi18) ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 0(a1); sw zero, 0(a1); beqz a0, .LBB24_2 +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi18)(a1); sw zero, %pcrel_lo(.Lpcrel_hi18)(a1); beqz a0, .LBB24_2 ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: # %bb.1: # %normal ; RV64I-MEDIUM-NEXT: li a0, 0 @@ -1175,13 +1133,12 @@ define i32 @constraint_o_with_multi_callbr_asm(i32 %a) { ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Lpcrel_hi19: ; RV32I-MEDIUM-NEXT: auipc a1, %pcrel_hi(eg) -; RV32I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi19) ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 0(a1); beqz a0, .LBB25_3 +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi19)(a1); beqz a0, .LBB25_3 ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: # %bb.1: # %normal0 ; RV32I-MEDIUM-NEXT: #APP -; RV32I-MEDIUM-NEXT: sw zero, 0(a1); beqz a0, .LBB25_3 +; RV32I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi19)(a1); beqz a0, .LBB25_3 ; RV32I-MEDIUM-NEXT: #NO_APP ; RV32I-MEDIUM-NEXT: # %bb.2: # %normal1 ; RV32I-MEDIUM-NEXT: li a0, 0 @@ -1196,13 +1153,12 @@ define i32 @constraint_o_with_multi_callbr_asm(i32 %a) { ; RV64I-MEDIUM: # %bb.0: # %entry ; RV64I-MEDIUM-NEXT: .Lpcrel_hi19: ; RV64I-MEDIUM-NEXT: auipc a1, %pcrel_hi(eg) -; RV64I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi19) ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 0(a1); beqz a0, .LBB25_3 +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi19)(a1); beqz a0, .LBB25_3 ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: # %bb.1: # %normal0 ; RV64I-MEDIUM-NEXT: #APP -; RV64I-MEDIUM-NEXT: sw zero, 0(a1); beqz a0, .LBB25_3 +; RV64I-MEDIUM-NEXT: sw zero, %pcrel_lo(.Lpcrel_hi19)(a1); beqz a0, .LBB25_3 ; RV64I-MEDIUM-NEXT: #NO_APP ; RV64I-MEDIUM-NEXT: # %bb.2: # %normal1 ; RV64I-MEDIUM-NEXT: li a0, 0