Skip to content
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

[RISCV] Teach RISCVMergeBaseOffset to handle inline asm #78945

Merged
merged 1 commit into from
Jan 22, 2024

Conversation

wangpc-pp
Copy link
Contributor

For inline asm with memory operands, we can merge the offset into
the second operand of memory constraint operands.

Differential Revision: https://reviews.llvm.org/D158062

For inline asm with memory operands, we can merge the offset into
the second operand of memory constraint operands.

Reviewed By:
craig.topper

Differential Revision: https://reviews.llvm.org/D158062
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 22, 2024

@llvm/pr-subscribers-backend-risc-v

Author: Wang Pengcheng (wangpc-pp)

Changes

For inline asm with memory operands, we can merge the offset into
the second operand of memory constraint operands.

Differential Revision: https://reviews.llvm.org/D158062


Patch is 38.93 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/78945.diff

5 Files Affected:

  • (modified) llvm/include/llvm/CodeGen/MachineOperand.h (+4)
  • (modified) llvm/lib/CodeGen/MachineOperand.cpp (+13)
  • (modified) llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp (+3-2)
  • (modified) llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp (+73-5)
  • (modified) llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll (+100-164)
diff --git a/llvm/include/llvm/CodeGen/MachineOperand.h b/llvm/include/llvm/CodeGen/MachineOperand.h
index 1f3b7feedd1897f..63a172134538c42 100644
--- a/llvm/include/llvm/CodeGen/MachineOperand.h
+++ b/llvm/include/llvm/CodeGen/MachineOperand.h
@@ -782,6 +782,10 @@ class MachineOperand {
   void ChangeToGA(const GlobalValue *GV, int64_t Offset,
                   unsigned TargetFlags = 0);
 
+  /// ChangeToBA - Replace this operand with a new block address operand.
+  void ChangeToBA(const BlockAddress *BA, int64_t Offset,
+                  unsigned TargetFlags = 0);
+
   /// ChangeToMCSymbol - Replace this operand with a new MC symbol operand.
   void ChangeToMCSymbol(MCSymbol *Sym, unsigned TargetFlags = 0);
 
diff --git a/llvm/lib/CodeGen/MachineOperand.cpp b/llvm/lib/CodeGen/MachineOperand.cpp
index 12d6b79f735d7ea..c7c0a1c20d57f4f 100644
--- a/llvm/lib/CodeGen/MachineOperand.cpp
+++ b/llvm/lib/CodeGen/MachineOperand.cpp
@@ -206,6 +206,19 @@ void MachineOperand::ChangeToGA(const GlobalValue *GV, int64_t Offset,
   setTargetFlags(TargetFlags);
 }
 
+void MachineOperand::ChangeToBA(const BlockAddress *BA, int64_t Offset,
+                                unsigned TargetFlags) {
+  assert((!isReg() || !isTied()) &&
+         "Cannot change a tied operand into a block address");
+
+  removeRegFromUses();
+
+  OpKind = MO_BlockAddress;
+  Contents.OffsetedInfo.Val.BA = BA;
+  setOffset(Offset);
+  setTargetFlags(TargetFlags);
+}
+
 void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym, unsigned TargetFlags) {
   assert((!isReg() || !isTied()) &&
          "Cannot change a tied operand into an MCSymbol");
diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
index f2bd5118fc0717b..aee6ec05f1f9c5e 100644
--- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
+++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
@@ -323,7 +323,8 @@ bool RISCVAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
   // RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand).
   if (!AddrReg.isReg())
     return true;
-  if (!Offset.isImm() && !Offset.isGlobal() && !Offset.isBlockAddress())
+  if (!Offset.isImm() && !Offset.isGlobal() && !Offset.isBlockAddress() &&
+      !Offset.isMCSymbol())
     return true;
 
   MCOperand MCO;
@@ -332,7 +333,7 @@ bool RISCVAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
 
   if (Offset.isImm())
     OS << MCO.getImm();
-  else if (Offset.isGlobal() || Offset.isBlockAddress())
+  else if (Offset.isGlobal() || Offset.isBlockAddress() || 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 866b2453579cc37..313f7f396d4d469 100644
--- a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
+++ b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
@@ -362,6 +362,8 @@ bool RISCVMergeBaseOffsetOpt::foldIntoMemoryOps(MachineInstr &Hi,
   // Tail: lw vreg3, 8(vreg2)
 
   std::optional<int64_t> CommonOffset;
+  DenseMap<const MachineInstr *, SmallVector<unsigned>>
+      InlineAsmMemoryOpIndexesMap;
   for (const MachineInstr &UseMI : MRI->use_instructions(DestReg)) {
     switch (UseMI.getOpcode()) {
     default:
@@ -396,6 +398,49 @@ bool RISCVMergeBaseOffsetOpt::foldIntoMemoryOps(MachineInstr &Hi,
       if (CommonOffset && Offset != CommonOffset)
         return false;
       CommonOffset = Offset;
+      break;
+    }
+    case RISCV::INLINEASM:
+    case RISCV::INLINEASM_BR: {
+      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())
+          continue;
+
+        // We can't do this for constraint A because AMO instructions don't have
+        // an immediate offset field.
+        if (Flags.getMemoryConstraintID() == InlineAsm::ConstraintCode::A)
+          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;
     }
     }
   }
@@ -420,13 +465,36 @@ 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 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.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 eb0e0287d48d7be..52d0dabf18839db 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 elementtype(i32) getelementptr ([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 elementtype(i32) getelementptr ([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
 ;
@@ -385,9 +371,8 @@ define void @constraint_m_with_local_1() nounwind {
 ; RV32I-MEDIUM-NEXT:  # %bb.1: # %label
 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi6:
 ; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp0)
-; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi6)
 ; RV32I-MEDIUM-NEXT:    #APP
-; RV32I-MEDIUM-NEXT:    lw zero, 0(a0)
+; RV32I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi6)(a0)
 ; RV32I-MEDIUM-NEXT:    #NO_APP
 ; RV32I-MEDIUM-NEXT:    ret
 ;
@@ -397,9 +382,8 @@ define void @constraint_m_with_local_1() nounwind {
 ; RV64I-MEDIUM-NEXT:  # %bb.1: # %label
 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi6:
 ; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp0)
-; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi6)
 ; RV64I-MEDIUM-NEXT:    #APP
-; RV64I-MEDIUM-NEXT:    lw zero, 0(a0)
+; RV64I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi6)(a0)
 ; RV64I-MEDIUM-NEXT:    #NO_APP
 ; RV64I-MEDIUM-NEXT:    ret
 entry:
@@ -415,10 +399,9 @@ define void @constraint_m_with_local_2() nounwind {
 ; RV32I:       # %bb.0: # %entry
 ; RV32I-NEXT:  .Ltmp1: # Block address taken
 ; RV32I-NEXT:  # %bb.1: # %label
-; RV32I-NEXT:    lui a0, %hi(.Ltmp1)
-; RV32I-NEXT:    addi a0, a0, %lo(.Ltmp1)
+; RV32I-NEXT:    lui a0, %hi(.Ltmp1+4)
 ; RV32I-NEXT:    #APP
-; RV32I-NEXT:    lw zero, 4(a0)
+; RV32I-NEXT:    lw zero, %lo(.Ltmp1+4)(a0)
 ; RV32I-NEXT:    #NO_APP
 ; RV32I-NEXT:    ret
 ;
@@ -426,10 +409,9 @@ define void @constraint_m_with_local_2() nounwind {
 ; RV64I:       # %bb.0: # %entry
 ; RV64I-NEXT:  .Ltmp1: # Block address taken
 ; RV64I-NEXT:  # %bb.1: # %label
-; RV64I-NEXT:    lui a0, %hi(.Ltmp1)
-; RV64I-NEXT:    addi a0, a0, %lo(.Ltmp1)
+; RV64I-NEXT:    lui a0, %hi(.Ltmp1+4)
 ; RV64I-NEXT:    #APP
-; RV64I-NEXT:    lw zero, 4(a0)
+; RV64I-NEXT:    lw zero, %lo(.Ltmp1+4)(a0)
 ; RV64I-NEXT:    #NO_APP
 ; RV64I-NEXT:    ret
 ;
@@ -438,10 +420,9 @@ define void @constraint_m_with_local_2() nounwind {
 ; RV32I-MEDIUM-NEXT:  .Ltmp1: # Block address taken
 ; RV32I-MEDIUM-NEXT:  # %bb.1: # %label
 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi7:
-; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp1)
-; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi7)
+; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp1+4)
 ; RV32I-MEDIUM-NEXT:    #APP
-; RV32I-MEDIUM-NEXT:    lw zero, 4(a0)
+; RV32I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi7)(a0)
 ; RV32I-MEDIUM-NEXT:    #NO_APP
 ; RV32I-MEDIUM-NEXT:    ret
 ;
@@ -450,10 +431,9 @@ define void @constraint_m_with_local_2() nounwind {
 ; RV64I-MEDIUM-NEXT:  .Ltmp1: # Block address taken
 ; RV64I-MEDIUM-NEXT:  # %bb.1: # %label
 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi7:
-; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp1)
-; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi7)
+; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp1+4)
 ; RV64I-MEDIUM-NEXT:    #APP
-; RV64I-MEDIUM-NEXT:    lw zero, 4(a0)
+; RV64I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi7)(a0)
 ; RV64I-MEDIUM-NEXT:    #NO_APP
 ; RV64I-MEDIUM-NEXT:    ret
 entry:
@@ -469,10 +449,9 @@ define void @constraint_m_with_local_3() nounwind {
 ; RV32I:       # %bb.0: # %entry
 ; RV32I-NEXT:  .Ltmp2: # Block address taken
 ; RV32I-NEXT:  # %bb.1: # %label
-; RV32I-NEXT:    lui a0, %hi(.Ltmp2)
-; RV32I-NEXT:    addi a0, a0, %lo(.Ltmp2)
+; RV32I-NEXT:    lui a0, %hi(.Ltmp2+2000)
 ; RV32I-NEXT:    #APP
-; RV32I-NEXT:    lw zero, 2000(a0)
+; RV32I-NEXT:    lw zero, %lo(.Ltmp2+2000)(a0)
 ; RV32I-NEXT:    #NO_APP
 ; RV32I-NEXT:    ret
 ;
@@ -480,10 +459,9 @@ define void @constraint_m_with_local_3() nounwind {
 ; RV64I:       # %bb.0: # %entry
 ; RV64I-NEXT:  .Ltmp2: # Block address taken
 ; RV64I-NEXT:  # %bb.1: # %label
-; RV64I-NEXT:    lui a0, %hi(.Ltmp2)
-; RV64I-NEXT:    addi a0, a0, %lo(.Ltmp2)
+; RV64I-NEXT:    lui a0, %hi(.Ltmp2+2000)
 ; RV64I-NEXT:    #APP
-; RV64I-NEXT:    lw zero, 2000(a0)
+; RV64I-NEXT:    lw zero, %lo(.Ltmp2+2000)(a0)
 ; RV64I-NEXT:    #NO_APP
 ; RV64I-NEXT:    ret
 ;
@@ -492,10 +470,9 @@ define void @constraint_m_with_local_3() nounwind {
 ; RV32I-MEDIUM-NEXT:  .Ltmp2: # Block address taken
 ; RV32I-MEDIUM-NEXT:  # %bb.1: # %label
 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi8:
-; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp2)
-; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi8)
+; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp2+2000)
 ; RV32I-MEDIUM-NEXT:    #APP
-; RV32I-MEDIUM-NEXT:    lw zero, 2000(a0)
+; RV32I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi8)(a0)
 ; RV32I-MEDIUM-NEXT:    #NO_APP
 ; RV32I-MEDIUM-NEXT:    ret
 ;
@@ -504,10 +481,9 @@ define void @constraint_m_with_local_3() nounwind {
 ; RV64I-MEDIUM-NEXT:  .Ltmp2: # Block address taken
 ; RV64I-MEDIUM-NEXT:  # %bb.1: # %label
 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi8:
-; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp2)
-; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi8)
+; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(.Ltmp2+2000)
 ; RV64I-MEDIUM-NEXT:    #APP
-; RV64I-MEDIUM-NEXT:    lw zero, 2000(a0)
+; RV64I-MEDIUM-NEXT:    lw zero, %pcrel_lo(.Lpcrel_hi8)(a0)
 ; RV64I-MEDIUM-NEXT:    #NO_APP
 ; RV64I-MEDIUM-NEXT:    ret
 entry:
@@ -539,9 +515,8 @@ define void @constraint_m_with_multi_operands() nounwind {
 ; RV32I-MEDIUM:       # %bb.0:
 ; RV32I-MEDIUM-NEXT:  .Lpcrel_hi9:
 ; RV32I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
-; RV32I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi9)
 ; RV32I-MEDIUM-NEXT:    #APP
-; RV32I-MEDIUM-NEXT:    sw zero, 0(a0); sw zero, 0(a0)
+; RV32I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi9)(a0); sw zero, %pcrel_lo(.Lpcrel_hi9)(a0)
 ; RV32I-MEDIUM-NEXT:    #NO_APP
 ; RV32I-MEDIUM-NEXT:    ret
 ;
@@ -549,9 +524,8 @@ define void @constraint_m_with_multi_operands() nounwind {
 ; RV64I-MEDIUM:       # %bb.0:
 ; RV64I-MEDIUM-NEXT:  .Lpcrel_hi9:
 ; RV64I-MEDIUM-NEXT:    auipc a0, %pcrel_hi(eg)
-; RV64I-MEDIUM-NEXT:    addi a0, a0, %pcrel_lo(.Lpcrel_hi9)
 ; RV64I-MEDIUM-NEXT:    #APP
-; RV64I-MEDIUM-NEXT:    sw zero, 0(a0); sw zero, 0(a0)
+; RV64I-MEDIUM-NEXT:    sw zero, %pcrel_lo(.Lpcrel_hi9)(a0); sw zero, %pcrel_lo(.Lpcrel_hi9)(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)
@@ -585,12 +559,11 @@ define void @constraint_m_with_multi_asm() 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:    #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
 ;
@@ -598,12 +571,11 @@ define void @constraint_m_with_multi_asm() 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:    #APP
-; RV64I-MEDIUM-NEXT:    sw zero, 0(a0)
+; RV64I-MEDIUM-NEXT:    sw zero, %...
[truncated]

@wangpc-pp wangpc-pp requested a review from asb January 22, 2024 06:43
Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@wangpc-pp wangpc-pp merged commit 5cd8d53 into llvm:main Jan 22, 2024
4 of 5 checks passed
@wangpc-pp wangpc-pp deleted the main-merge-base-offset-inline-asm branch January 22, 2024 09:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants