Skip to content

Commit 9e86919

Browse files
authored
[RISCV][GISel] Fix 2 indirect call bugs. (#73170)
We can't set MO_PLT on an indirect call. We need to constrain the register class for the operand to the call instruction.
1 parent 03d4a9d commit 9e86919

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -505,14 +505,15 @@ bool RISCVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
505505
Info.IsTailCall = false;
506506

507507
// Select the recommended relocation type R_RISCV_CALL_PLT.
508-
Info.Callee.setTargetFlags(RISCVII::MO_PLT);
508+
if (!Info.Callee.isReg())
509+
Info.Callee.setTargetFlags(RISCVII::MO_PLT);
509510

510511
MachineInstrBuilder Call =
511512
MIRBuilder
512513
.buildInstrNoInsert(Info.Callee.isReg() ? RISCV::PseudoCALLIndirect
513514
: RISCV::PseudoCALL)
514515
.add(Info.Callee);
515-
const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
516+
const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
516517
Call.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv));
517518

518519
RISCVOutgoingValueAssigner ArgAssigner(
@@ -530,6 +531,15 @@ bool RISCVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
530531
.addImm(ArgAssigner.StackSize)
531532
.addImm(0);
532533

534+
// If Callee is a reg, since it is used by a target specific
535+
// instruction, it must have a register class matching the
536+
// constraint of that instruction.
537+
if (Call->getOperand(0).isReg())
538+
constrainOperandRegClass(MF, *TRI, MF.getRegInfo(),
539+
*Subtarget.getInstrInfo(),
540+
*Subtarget.getRegBankInfo(), *Call,
541+
Call->getDesc(), Call->getOperand(0), 0);
542+
533543
if (Info.OrigRet.Ty->isVoidTy())
534544
return true;
535545

llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calls.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,3 +441,27 @@ entry:
441441
call void @dso_local_function()
442442
ret void
443443
}
444+
445+
define void @test_indirect_call(ptr %func) {
446+
; RV32I-LABEL: name: test_indirect_call
447+
; RV32I: bb.1 (%ir-block.0):
448+
; RV32I-NEXT: liveins: $x10
449+
; RV32I-NEXT: {{ $}}
450+
; RV32I-NEXT: [[COPY:%[0-9]+]]:gprjalr(p0) = COPY $x10
451+
; RV32I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
452+
; RV32I-NEXT: PseudoCALLIndirect [[COPY]](p0), csr_ilp32_lp64, implicit-def $x1
453+
; RV32I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
454+
; RV32I-NEXT: PseudoRET
455+
;
456+
; RV64I-LABEL: name: test_indirect_call
457+
; RV64I: bb.1 (%ir-block.0):
458+
; RV64I-NEXT: liveins: $x10
459+
; RV64I-NEXT: {{ $}}
460+
; RV64I-NEXT: [[COPY:%[0-9]+]]:gprjalr(p0) = COPY $x10
461+
; RV64I-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
462+
; RV64I-NEXT: PseudoCALLIndirect [[COPY]](p0), csr_ilp32_lp64, implicit-def $x1
463+
; RV64I-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
464+
; RV64I-NEXT: PseudoRET
465+
call void %func()
466+
ret void
467+
}

0 commit comments

Comments
 (0)