diff options
author | Craig Topper <craig.topper@sifive.com> | 2023-11-27 12:59:01 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-27 12:59:01 -0800 |
commit | 9e8691962626e62382eb31da6fea49ddbb559750 (patch) | |
tree | d1cba18f46cb60a8028dea1aed5b23df55609839 | |
parent | 03d4a9d94da30590ebfc444cf13a8763f47b7bb9 (diff) | |
download | llvm-9e8691962626e62382eb31da6fea49ddbb559750.zip llvm-9e8691962626e62382eb31da6fea49ddbb559750.tar.gz llvm-9e8691962626e62382eb31da6fea49ddbb559750.tar.bz2 |
[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.
-rw-r--r-- | llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp | 14 | ||||
-rw-r--r-- | llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calls.ll | 24 |
2 files changed, 36 insertions, 2 deletions
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp b/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp index 1aba8a8..3108ce9 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 14c86a3..e7e093f 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 +} |