Skip to content

Commit 3a38baa

Browse files
[GISEL][RISCV] Legalize llvm.vacopy intrinsic (#73066)
In the future, we can consider adding a G_VACOPY opcode instead of going through the GIntrinsic for all targets. We do the approach in this patch because that is what other targets do today.
1 parent 9c6693f commit 3a38baa

File tree

6 files changed

+1499
-13
lines changed

6 files changed

+1499
-13
lines changed

llvm/include/llvm/Support/TargetOpcodes.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ HANDLE_TARGET_OPCODE(G_FCONSTANT)
454454
/// Generic va_start instruction. Stores to its one pointer operand.
455455
HANDLE_TARGET_OPCODE(G_VASTART)
456456

457-
/// Generic va_start instruction. Stores to its one pointer operand.
457+
/// Generic va_arg instruction. Stores to its one pointer operand.
458458
HANDLE_TARGET_OPCODE(G_VAARG)
459459

460460
// Generic sign extend

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

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "RISCVLegalizerInfo.h"
1414
#include "RISCVMachineFunctionInfo.h"
1515
#include "RISCVSubtarget.h"
16+
#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
1617
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
1718
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
1819
#include "llvm/CodeGen/MachineRegisterInfo.h"
@@ -328,6 +329,49 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
328329
getLegacyLegalizerInfo().computeTables();
329330
}
330331

332+
static Type *getTypeForLLT(LLT Ty, LLVMContext &C) {
333+
if (Ty.isVector())
334+
return FixedVectorType::get(IntegerType::get(C, Ty.getScalarSizeInBits()),
335+
Ty.getNumElements());
336+
return IntegerType::get(C, Ty.getSizeInBits());
337+
}
338+
339+
bool RISCVLegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper,
340+
MachineInstr &MI) const {
341+
Intrinsic::ID IntrinsicID = cast<GIntrinsic>(MI).getIntrinsicID();
342+
switch (IntrinsicID) {
343+
default:
344+
return false;
345+
case Intrinsic::vacopy: {
346+
// vacopy arguments must be legal because of the intrinsic signature.
347+
// No need to check here.
348+
349+
MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
350+
MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
351+
MachineFunction &MF = *MI.getMF();
352+
const DataLayout &DL = MIRBuilder.getDataLayout();
353+
LLVMContext &Ctx = MF.getFunction().getContext();
354+
355+
Register DstLst = MI.getOperand(1).getReg();
356+
LLT PtrTy = MRI.getType(DstLst);
357+
358+
// Load the source va_list
359+
Align Alignment = DL.getABITypeAlign(getTypeForLLT(PtrTy, Ctx));
360+
MachineMemOperand *LoadMMO = MF.getMachineMemOperand(
361+
MachinePointerInfo(), MachineMemOperand::MOLoad, PtrTy, Alignment);
362+
auto Tmp = MIRBuilder.buildLoad(PtrTy, MI.getOperand(2), *LoadMMO);
363+
364+
// Store the result in the destination va_list
365+
MachineMemOperand *StoreMMO = MF.getMachineMemOperand(
366+
MachinePointerInfo(), MachineMemOperand::MOStore, PtrTy, Alignment);
367+
MIRBuilder.buildStore(DstLst, Tmp, *StoreMMO);
368+
369+
MI.eraseFromParent();
370+
return true;
371+
}
372+
}
373+
}
374+
331375
bool RISCVLegalizerInfo::legalizeShlAshrLshr(
332376
MachineInstr &MI, MachineIRBuilder &MIRBuilder,
333377
GISelChangeObserver &Observer) const {

llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ class RISCVLegalizerInfo : public LegalizerInfo {
3232

3333
bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI) const override;
3434

35+
bool legalizeIntrinsic(LegalizerHelper &Helper,
36+
MachineInstr &MI) const override;
37+
3538
private:
3639
bool legalizeShlAshrLshr(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
3740
GISelChangeObserver &Observer) const;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
2+
; RUN: llc -mtriple=riscv32 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
3+
; RUN: | FileCheck -check-prefix=RV32I %s
4+
; RUN: llc -mtriple=riscv64 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
5+
; RUN: | FileCheck -check-prefix=RV64I %s
6+
7+
declare void @llvm.va_copy(ptr, ptr)
8+
define void @test_va_copy(ptr %dest_list, ptr %src_list) {
9+
; RV32I-LABEL: name: test_va_copy
10+
; RV32I: bb.1 (%ir-block.0):
11+
; RV32I-NEXT: liveins: $x10, $x11
12+
; RV32I-NEXT: {{ $}}
13+
; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
14+
; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
15+
; RV32I-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.va_copy), [[COPY]](p0), [[COPY1]](p0)
16+
; RV32I-NEXT: PseudoRET
17+
;
18+
; RV64I-LABEL: name: test_va_copy
19+
; RV64I: bb.1 (%ir-block.0):
20+
; RV64I-NEXT: liveins: $x10, $x11
21+
; RV64I-NEXT: {{ $}}
22+
; RV64I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
23+
; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
24+
; RV64I-NEXT: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.va_copy), [[COPY]](p0), [[COPY1]](p0)
25+
; RV64I-NEXT: PseudoRET
26+
call void @llvm.va_copy(ptr %dest_list, ptr %src_list)
27+
ret void
28+
}

0 commit comments

Comments
 (0)