[llvm] [RISCV][GISel] Fix 2 indirect call bugs. (PR #73170)

via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 22 13:08:43 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-globalisel

Author: Craig Topper (topperc)

<details>
<summary>Changes</summary>

We can't set MO_PLT on an indirect call.
We need to constrain the register class for the operand to the call instruction.

---
Full diff: https://github.com/llvm/llvm-project/pull/73170.diff


2 Files Affected:

- (modified) llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp (+12-2) 
- (modified) llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calls.ll (+24) 


``````````diff
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp b/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
index 1aba8a8f52e96fc..3108ce9837891b5 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
@@ -505,14 +505,15 @@ bool RISCVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
   Info.IsTailCall = false;
 
   // Select the recommended relocation type R_RISCV_CALL_PLT.
-  Info.Callee.setTargetFlags(RISCVII::MO_PLT);
+  if (!Info.Callee.isReg())
+    Info.Callee.setTargetFlags(RISCVII::MO_PLT);
 
   MachineInstrBuilder Call =
       MIRBuilder
           .buildInstrNoInsert(Info.Callee.isReg() ? RISCV::PseudoCALLIndirect
                                                   : RISCV::PseudoCALL)
           .add(Info.Callee);
-  const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
+  const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
   Call.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv));
 
   RISCVOutgoingValueAssigner ArgAssigner(
@@ -530,6 +531,15 @@ bool RISCVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
       .addImm(ArgAssigner.StackSize)
       .addImm(0);
 
+  // If Callee is a reg, since it is used by a target specific
+  // instruction, it must have a register class matching the
+  // constraint of that instruction.
+  if (Call->getOperand(0).isReg())
+    constrainOperandRegClass(MF, *TRI, MF.getRegInfo(),
+                             *Subtarget.getInstrInfo(),
+                             *Subtarget.getRegBankInfo(), *Call,
+                             Call->getDesc(), Call->getOperand(0), 0);
+
   if (Info.OrigRet.Ty->isVoidTy())
     return true;
 
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calls.ll b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calls.ll
index 14c86a3e99e4493..e7e093f7110b863 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calls.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calls.ll
@@ -441,3 +441,27 @@ entry:
   call void @dso_local_function()
   ret void
 }
+
+define void @test_indirect_call(ptr %func) {
+  ; RV32I-LABEL: name: test_indirect_call
+  ; RV32I: bb.1 (%ir-block.0):
+  ; RV32I-NEXT:   liveins: $x10
+  ; RV32I-NEXT: {{  $}}
+  ; RV32I-NEXT:   [[COPY:%[0-9]+]]:gprjalr(p0) = COPY $x10
+  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+  ; RV32I-NEXT:   PseudoCALLIndirect [[COPY]](p0), csr_ilp32_lp64, implicit-def $x1
+  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+  ; RV32I-NEXT:   PseudoRET
+  ;
+  ; RV64I-LABEL: name: test_indirect_call
+  ; RV64I: bb.1 (%ir-block.0):
+  ; RV64I-NEXT:   liveins: $x10
+  ; RV64I-NEXT: {{  $}}
+  ; RV64I-NEXT:   [[COPY:%[0-9]+]]:gprjalr(p0) = COPY $x10
+  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
+  ; RV64I-NEXT:   PseudoCALLIndirect [[COPY]](p0), csr_ilp32_lp64, implicit-def $x1
+  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
+  ; RV64I-NEXT:   PseudoRET
+  call void %func()
+  ret void
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/73170


More information about the llvm-commits mailing list