[llvm] [AArch64][GlobalISel] Add `G_FMODF` instruction (PR #160061)
Ryan Cowan via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 23 06:45:33 PDT 2025
https://github.com/HolyMolyCowMan updated https://github.com/llvm/llvm-project/pull/160061
>From ead0af9972c0cd71baecd5efb2f51267fb95aafa Mon Sep 17 00:00:00 2001
From: Ryan Cowan <ryan.cowan at arm.com>
Date: Mon, 22 Sep 2025 09:06:48 +0000
Subject: [PATCH] [AArch64][GlobalISel] Add `G_MODF` instruction
---
.../llvm/CodeGen/GlobalISel/LegalizerHelper.h | 4 +
.../CodeGen/GlobalISel/MachineIRBuilder.h | 7 +
llvm/include/llvm/Support/TargetOpcodes.def | 3 +
llvm/include/llvm/Target/GenericOpcodes.td | 7 +
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 7 +
.../CodeGen/GlobalISel/LegalizerHelper.cpp | 71 ++++++
.../AArch64/GISel/AArch64LegalizerInfo.cpp | 3 +-
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 12 +-
llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp | 1 +
.../AArch64/GlobalISel/irtranslator-modf.ll | 140 ++++++++++++
.../AArch64/GlobalISel/legalize-modf.mir | 206 ++++++++++++++++++
.../GlobalISel/legalizer-info-validation.mir | 4 +
.../AArch64/GlobalISel/select-modf.mir | 136 ++++++++++++
.../GlobalISel/legalizer-info-validation.mir | 7 +-
.../match-table-cxx.td | 132 +++++------
.../GlobalISelEmitter/GlobalISelEmitter.td | 2 +-
llvm/test/TableGen/RegClassByHwMode.td | 2 +-
17 files changed, 667 insertions(+), 77 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-modf.ll
create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/legalize-modf.mir
create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/select-modf.mir
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index 22569aab236af..c0e426c4a8db3 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -300,6 +300,10 @@ class LegalizerHelper {
Type *OpType,
LostDebugLocObserver &LocObserver);
+ LegalizeResult emitModfLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
+ unsigned Size, Type *OpType,
+ LostDebugLocObserver &LocObserver);
+
public:
/// Return the alignment to use for a stack temporary object with the given
/// type.
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index 99d3cd0aac85c..f1855efe17891 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -2184,6 +2184,13 @@ class LLVM_ABI MachineIRBuilder {
return buildInstr(TargetOpcode::G_FSINCOS, {Sin, Cos}, {Src}, Flags);
}
+ /// Build and insert \p Fract, \p Int = G_FMODF \p Src
+ MachineInstrBuilder buildModf(const DstOp &Fract, const DstOp &Int,
+ const SrcOp &Src,
+ std::optional<unsigned> Flags = std::nullopt) {
+ return buildInstr(TargetOpcode::G_FMODF, {Fract, Int}, {Src}, Flags);
+ }
+
/// Build and insert \p Res = G_FCOPYSIGN \p Op0, \p Op1
MachineInstrBuilder buildFCopysign(const DstOp &Dst, const SrcOp &Src0,
const SrcOp &Src1) {
diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def
index b905576b61791..4fb224acf439a 100644
--- a/llvm/include/llvm/Support/TargetOpcodes.def
+++ b/llvm/include/llvm/Support/TargetOpcodes.def
@@ -650,6 +650,9 @@ HANDLE_TARGET_OPCODE(G_FDIV)
/// Generic FP remainder.
HANDLE_TARGET_OPCODE(G_FREM)
+/// Generic FP modf
+HANDLE_TARGET_OPCODE(G_FMODF)
+
/// Generic FP exponentiation.
HANDLE_TARGET_OPCODE(G_FPOW)
diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td
index ce4750db88c9a..3555c487417ba 100644
--- a/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/llvm/include/llvm/Target/GenericOpcodes.td
@@ -981,6 +981,13 @@ def G_FREM : GenericInstruction {
let hasSideEffects = false;
}
+/// Generic FP modf
+def G_FMODF : GenericInstruction {
+ let OutOperandList = (outs type0:$dst1, type0:$dst2);
+ let InOperandList = (ins type0:$src1);
+ let hasSideEffects = false;
+}
+
// Floating point exponentiation.
def G_FPOW : GenericInstruction {
let OutOperandList = (outs type0:$dst);
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 12b735e053bde..b3d1c00de05a8 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -2362,6 +2362,13 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
MachineInstr::copyFlagsFromInstruction(CI));
return true;
}
+ case Intrinsic::modf: {
+ ArrayRef<Register> VRegs = getOrCreateVRegs(CI);
+ MIRBuilder.buildModf(VRegs[0], VRegs[1],
+ getOrCreateVReg(*CI.getArgOperand(0)),
+ MachineInstr::copyFlagsFromInstruction(CI));
+ return true;
+ }
case Intrinsic::sincos: {
ArrayRef<Register> VRegs = getOrCreateVRegs(CI);
MIRBuilder.buildFSincos(VRegs[0], VRegs[1],
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index f3e036ed1b947..8ffb10cf12a92 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -471,6 +471,8 @@ static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size) {
RTLIBCASE(TANH_F);
case TargetOpcode::G_FSINCOS:
RTLIBCASE(SINCOS_F);
+ case TargetOpcode::G_FMODF:
+ RTLIBCASE(MODF_F);
case TargetOpcode::G_FLOG10:
RTLIBCASE(LOG10_F);
case TargetOpcode::G_FLOG:
@@ -702,6 +704,46 @@ LegalizerHelper::LegalizeResult LegalizerHelper::emitSincosLibcall(
return LegalizerHelper::Legalized;
}
+LegalizerHelper::LegalizeResult
+LegalizerHelper::emitModfLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
+ unsigned Size, Type *OpType,
+ LostDebugLocObserver &LocObserver) {
+ MachineFunction &MF = *MI.getMF();
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+
+ Register DstFrac = MI.getOperand(0).getReg();
+ Register DstInt = MI.getOperand(1).getReg();
+ Register Src = MI.getOperand(2).getReg();
+ LLT DstTy = MRI.getType(DstFrac);
+
+ int MemSize = DstTy.getSizeInBytes();
+ Align Alignment = getStackTemporaryAlignment(DstTy);
+ const DataLayout &DL = MIRBuilder.getDataLayout();
+ unsigned AddrSpace = DL.getAllocaAddrSpace();
+ MachinePointerInfo PtrInfo;
+
+ Register StackPtrInt =
+ createStackTemporary(TypeSize::getFixed(MemSize), Alignment, PtrInfo)
+ .getReg(0);
+
+ auto &Ctx = MF.getFunction().getContext();
+ auto LibcallResult = createLibcall(
+ MIRBuilder, getRTLibDesc(MI.getOpcode(), Size), {DstFrac, OpType, 0},
+ {{Src, OpType, 0}, {StackPtrInt, PointerType::get(Ctx, AddrSpace), 1}},
+ LocObserver, &MI);
+
+ if (LibcallResult != LegalizeResult::Legalized)
+ return LegalizerHelper::UnableToLegalize;
+
+ MachineMemOperand *LoadMMOInt = MF.getMachineMemOperand(
+ PtrInfo, MachineMemOperand::MOLoad, MemSize, Alignment);
+
+ MIRBuilder.buildLoad(DstInt, StackPtrInt, *LoadMMOInt);
+ MI.eraseFromParent();
+
+ return LegalizerHelper::Legalized;
+}
+
LegalizerHelper::LegalizeResult
llvm::createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
MachineInstr &MI, LostDebugLocObserver &LocObserver) {
@@ -1341,6 +1383,16 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
}
return emitSincosLibcall(MI, MIRBuilder, Size, HLTy, LocObserver);
}
+ case TargetOpcode::G_FMODF: {
+ LLT LLTy = MRI.getType(MI.getOperand(0).getReg());
+ unsigned Size = LLTy.getSizeInBits();
+ Type *HLTy = getFloatTypeForLLT(Ctx, LLTy);
+ if (!HLTy || (Size != 32 && Size != 64 && Size != 80 && Size != 128)) {
+ LLVM_DEBUG(dbgs() << "No libcall available for type " << LLTy << ".\n");
+ return UnableToLegalize;
+ }
+ return emitModfLibcall(MI, MIRBuilder, Size, HLTy, LocObserver);
+ }
case TargetOpcode::G_LROUND:
case TargetOpcode::G_LLROUND:
case TargetOpcode::G_INTRINSIC_LRINT:
@@ -3331,6 +3383,24 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
Observer.changedInstr(MI);
return Legalized;
+ case TargetOpcode::G_FMODF: {
+ widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_FPEXT);
+
+ Register DstFrac = MI.getOperand(0).getReg();
+ Register DstInt = MI.getOperand(1).getReg();
+
+ Register DstFracWide = MRI.createGenericVirtualRegister(WideTy);
+ Register DstIntWide = MRI.createGenericVirtualRegister(WideTy);
+ Register SrcWide = MI.getOperand(2).getReg();
+
+ MIRBuilder.buildInstr(TargetOpcode::G_FMODF, {DstFracWide, DstIntWide},
+ {SrcWide});
+
+ MIRBuilder.buildFPTrunc(DstFrac, DstFracWide);
+ MIRBuilder.buildFPTrunc(DstInt, DstIntWide);
+ MI.eraseFromParent();
+ return Legalized;
+ }
case TargetOpcode::G_FPOWI:
case TargetOpcode::G_FLDEXP:
case TargetOpcode::G_STRICT_FLDEXP: {
@@ -5470,6 +5540,7 @@ LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
case G_LROUND:
case G_LLROUND:
case G_INTRINSIC_TRUNC:
+ case G_FMODF:
case G_FCOS:
case G_FSIN:
case G_FTAN:
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index ea2196a584127..7c0b8302da1c2 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -438,12 +438,13 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
getActionDefinitionsBuilder({G_FCOS, G_FSIN, G_FPOW, G_FLOG, G_FLOG2,
G_FLOG10, G_FTAN, G_FEXP, G_FEXP2, G_FEXP10,
G_FACOS, G_FASIN, G_FATAN, G_FATAN2, G_FCOSH,
- G_FSINH, G_FTANH})
+ G_FSINH, G_FTANH, G_FMODF})
// We need a call for these, so we always need to scalarize.
.scalarize(0)
// Regardless of FP16 support, widen 16-bit elements to 32-bits.
.minScalar(0, s32)
.libcallFor({s32, s64, s128});
+
getActionDefinitionsBuilder(G_FPOWI)
.scalarize(0)
.minScalar(0, s32)
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 3ad5528fab061..0948b32392f0e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -725,6 +725,8 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg,
return selectExtInst(ResVReg, ResType, I, CL::exp, GL::Exp);
case TargetOpcode::G_FEXP2:
return selectExtInst(ResVReg, ResType, I, CL::exp2, GL::Exp2);
+ case TargetOpcode::G_FMODF:
+ return selectModf(ResVReg, ResType, I);
case TargetOpcode::G_FLOG:
return selectExtInst(ResVReg, ResType, I, CL::log, GL::Log);
@@ -4131,6 +4133,7 @@ bool SPIRVInstructionSelector::selectModf(Register ResVReg,
PtrTyReg,
LLT::pointer(storageClassToAddressSpace(SPIRV::StorageClass::Function),
GR.getPointerSize()));
+
// Assign SPIR-V type of the pointer type of the alloca variable to the
// new register.
GR.assignSPIRVTypeToVReg(PtrType, PtrTyReg, MIRBuilder.getMF());
@@ -4143,10 +4146,7 @@ bool SPIRVInstructionSelector::selectModf(Register ResVReg,
.addUse(GR.getSPIRVTypeID(PtrType))
.addImm(static_cast<uint32_t>(SPIRV::StorageClass::Function));
Register Variable = AllocaMIB->getOperand(0).getReg();
- // Modf must have 4 operands, the first two are the 2 parts of the result,
- // the third is the operand, and the last one is the floating point value.
- assert(I.getNumOperands() == 4 &&
- "Expected 4 operands for modf instruction");
+
MachineBasicBlock &BB = *I.getParent();
// Create the OpenCLLIB::modf instruction.
auto MIB =
@@ -4156,8 +4156,8 @@ bool SPIRVInstructionSelector::selectModf(Register ResVReg,
.addImm(static_cast<uint32_t>(SPIRV::InstructionSet::OpenCL_std))
.addImm(CL::modf)
.setMIFlags(I.getFlags())
- .add(I.getOperand(3)) // Floating point value.
- .addUse(Variable); // Pointer to integral part.
+ .add(I.getOperand(I.getNumExplicitDefs())) // Floating point value.
+ .addUse(Variable); // Pointer to integral part.
// Assign the integral part stored in the ptr to the second element of the
// result.
Register IntegralPartReg = I.getOperand(1).getReg();
diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
index 170bddd507e3b..0e40c40c781f2 100644
--- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
@@ -293,6 +293,7 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
getActionDefinitionsBuilder({G_STRICT_FSQRT,
G_FPOW,
G_FEXP,
+ G_FMODF,
G_FEXP2,
G_FLOG,
G_FLOG2,
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-modf.ll b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-modf.ll
new file mode 100644
index 0000000000000..b4ab099e6ac4f
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-modf.ll
@@ -0,0 +1,140 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+; RUN: llc -O0 -mtriple=aarch64-linux-gnu -global-isel -stop-after=irtranslator %s -o - | FileCheck %s
+
+define { half, half } @test_modf_f16(half %a) {
+ ; CHECK-LABEL: name: test_modf_f16
+ ; CHECK: bb.1 (%ir-block.0):
+ ; CHECK-NEXT: liveins: $h0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY $h0
+ ; CHECK-NEXT: [[FMODF:%[0-9]+]]:_(s16), [[FMODF1:%[0-9]+]]:_ = G_FMODF [[COPY]]
+ ; CHECK-NEXT: $h0 = COPY [[FMODF]](s16)
+ ; CHECK-NEXT: $h1 = COPY [[FMODF1]](s16)
+ ; CHECK-NEXT: RET_ReallyLR implicit $h0, implicit $h1
+ %result = call { half, half } @llvm.modf.f16(half %a)
+ ret { half, half } %result
+}
+
+define { <2 x half>, <2 x half> } @test_modf_v2f16(<2 x half> %a) {
+ ; CHECK-LABEL: name: test_modf_v2f16
+ ; CHECK: bb.1 (%ir-block.0):
+ ; CHECK-NEXT: liveins: $d0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s16>) = COPY $d0
+ ; CHECK-NEXT: [[UV:%[0-9]+]]:_(<2 x s16>), [[UV1:%[0-9]+]]:_(<2 x s16>) = G_UNMERGE_VALUES [[COPY]](<4 x s16>)
+ ; CHECK-NEXT: [[FMODF:%[0-9]+]]:_(<2 x s16>), [[FMODF1:%[0-9]+]]:_ = G_FMODF [[UV]]
+ ; CHECK-NEXT: [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[FMODF]](<2 x s16>)
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s16>) = G_BUILD_VECTOR [[UV2]](s16), [[UV3]](s16), [[DEF]](s16), [[DEF]](s16)
+ ; CHECK-NEXT: [[UV4:%[0-9]+]]:_(s16), [[UV5:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[FMODF1]](<2 x s16>)
+ ; CHECK-NEXT: [[BUILD_VECTOR1:%[0-9]+]]:_(<4 x s16>) = G_BUILD_VECTOR [[UV4]](s16), [[UV5]](s16), [[DEF]](s16), [[DEF]](s16)
+ ; CHECK-NEXT: $d0 = COPY [[BUILD_VECTOR]](<4 x s16>)
+ ; CHECK-NEXT: $d1 = COPY [[BUILD_VECTOR1]](<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1
+ %result = call { <2 x half>, <2 x half> } @llvm.modf.v2f16(<2 x half> %a)
+ ret { <2 x half>, <2 x half> } %result
+}
+
+define { float, float } @test_modf_f32(float %a) {
+ ; CHECK-LABEL: name: test_modf_f32
+ ; CHECK: bb.1 (%ir-block.0):
+ ; CHECK-NEXT: liveins: $s0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0
+ ; CHECK-NEXT: [[FMODF:%[0-9]+]]:_(s32), [[FMODF1:%[0-9]+]]:_ = G_FMODF [[COPY]]
+ ; CHECK-NEXT: $s0 = COPY [[FMODF]](s32)
+ ; CHECK-NEXT: $s1 = COPY [[FMODF1]](s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $s0, implicit $s1
+ %result = call { float, float } @llvm.modf.f32(float %a)
+ ret { float, float } %result
+}
+
+define { <2 x float>, <2 x float> } @test_modf_v2f32(<2 x float> %a) {
+ ; CHECK-LABEL: name: test_modf_v2f32
+ ; CHECK: bb.1 (%ir-block.0):
+ ; CHECK-NEXT: liveins: $d0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0
+ ; CHECK-NEXT: [[FMODF:%[0-9]+]]:_(<2 x s32>), [[FMODF1:%[0-9]+]]:_ = G_FMODF [[COPY]]
+ ; CHECK-NEXT: $d0 = COPY [[FMODF]](<2 x s32>)
+ ; CHECK-NEXT: $d1 = COPY [[FMODF1]](<2 x s32>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1
+ %result = call { <2 x float>, <2 x float> } @llvm.modf.v2f32(<2 x float> %a)
+ ret { <2 x float>, <2 x float> } %result
+}
+
+define { double, double } @test_modf_f64(double %a) {
+ ; CHECK-LABEL: name: test_modf_f64
+ ; CHECK: bb.1 (%ir-block.0):
+ ; CHECK-NEXT: liveins: $d0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $d0
+ ; CHECK-NEXT: [[FMODF:%[0-9]+]]:_(s64), [[FMODF1:%[0-9]+]]:_ = G_FMODF [[COPY]]
+ ; CHECK-NEXT: $d0 = COPY [[FMODF]](s64)
+ ; CHECK-NEXT: $d1 = COPY [[FMODF1]](s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1
+ %result = call { double, double } @llvm.modf.f64(double %a)
+ ret { double, double } %result
+}
+
+define { <2 x double>, <2 x double> } @test_modf_v2f64(<2 x double> %a) {
+ ; CHECK-LABEL: name: test_modf_v2f64
+ ; CHECK: bb.1 (%ir-block.0):
+ ; CHECK-NEXT: liveins: $q0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
+ ; CHECK-NEXT: [[FMODF:%[0-9]+]]:_(<2 x s64>), [[FMODF1:%[0-9]+]]:_ = G_FMODF [[COPY]]
+ ; CHECK-NEXT: $q0 = COPY [[FMODF]](<2 x s64>)
+ ; CHECK-NEXT: $q1 = COPY [[FMODF1]](<2 x s64>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1
+ %result = call { <2 x double>, <2 x double> } @llvm.modf.v2f64(<2 x double> %a)
+ ret { <2 x double>, <2 x double> } %result
+}
+
+define { fp128, fp128 } @test_modf_fp128(fp128 %a) {
+ ; CHECK-LABEL: name: test_modf_fp128
+ ; CHECK: bb.1 (%ir-block.0):
+ ; CHECK-NEXT: liveins: $q0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s128) = COPY $q0
+ ; CHECK-NEXT: [[FMODF:%[0-9]+]]:_(s128), [[FMODF1:%[0-9]+]]:_ = G_FMODF [[COPY]]
+ ; CHECK-NEXT: $q0 = COPY [[FMODF]](s128)
+ ; CHECK-NEXT: $q1 = COPY [[FMODF1]](s128)
+ ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1
+ %result = call { fp128, fp128 } @llvm.modf.fp128(fp128 %a)
+ ret { fp128, fp128 } %result
+}
+
+define { <2 x fp128>, <2 x fp128> } @test_modf_v2fp128(<2 x fp128> %a) {
+ ; CHECK-LABEL: name: test_modf_v2fp128
+ ; CHECK: bb.1 (%ir-block.0):
+ ; CHECK-NEXT: liveins: $q0, $q1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s128) = COPY $q0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s128) = COPY $q1
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s128>) = G_BUILD_VECTOR [[COPY]](s128), [[COPY1]](s128)
+ ; CHECK-NEXT: [[FMODF:%[0-9]+]]:_(<2 x s128>), [[FMODF1:%[0-9]+]]:_ = G_FMODF [[BUILD_VECTOR]]
+ ; CHECK-NEXT: [[UV:%[0-9]+]]:_(s128), [[UV1:%[0-9]+]]:_(s128) = G_UNMERGE_VALUES [[FMODF]](<2 x s128>)
+ ; CHECK-NEXT: [[UV2:%[0-9]+]]:_(s128), [[UV3:%[0-9]+]]:_(s128) = G_UNMERGE_VALUES [[FMODF1]](<2 x s128>)
+ ; CHECK-NEXT: $q0 = COPY [[UV]](s128)
+ ; CHECK-NEXT: $q1 = COPY [[UV1]](s128)
+ ; CHECK-NEXT: $q2 = COPY [[UV2]](s128)
+ ; CHECK-NEXT: $q3 = COPY [[UV3]](s128)
+ ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1, implicit $q2, implicit $q3
+ %result = call { <2 x fp128>, <2 x fp128> } @llvm.modf.v2fp128(<2 x fp128> %a)
+ ret { <2 x fp128>, <2 x fp128> } %result
+}
+
+define { float, float } @test_modf_f32_afn(float %a) {
+ ; CHECK-LABEL: name: test_modf_f32_afn
+ ; CHECK: bb.1 (%ir-block.0):
+ ; CHECK-NEXT: liveins: $s0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0
+ ; CHECK-NEXT: [[FMODF:%[0-9]+]]:_(s32), [[FMODF1:%[0-9]+]]:_ = afn G_FMODF [[COPY]]
+ ; CHECK-NEXT: $s0 = COPY [[FMODF]](s32)
+ ; CHECK-NEXT: $s1 = COPY [[FMODF1]](s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $s0, implicit $s1
+ %result = call afn { float, float } @llvm.modf.f32(float %a)
+ ret { float, float } %result
+}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-modf.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-modf.mir
new file mode 100644
index 0000000000000..5d0d94ed2a274
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-modf.mir
@@ -0,0 +1,206 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple=aarch64 -run-pass=legalizer %s -o - | FileCheck %s
+---
+name: test_modf_f16
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: test_modf_f16
+ ; CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY $h0
+ ; CHECK-NEXT: [[FPEXT:%[0-9]+]]:_(s32) = G_FPEXT [[COPY]](s16)
+ ; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: $s0 = COPY [[FPEXT]](s32)
+ ; CHECK-NEXT: $x0 = COPY [[FRAME_INDEX]](p0)
+ ; CHECK-NEXT: BL &modff, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $s0, implicit $x0, implicit-def $s0
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $s0
+ ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %stack.0)
+ ; CHECK-NEXT: [[FPTRUNC:%[0-9]+]]:_(s16) = G_FPTRUNC [[COPY1]](s32)
+ ; CHECK-NEXT: [[FPTRUNC1:%[0-9]+]]:_(s16) = G_FPTRUNC [[LOAD]](s32)
+ ; CHECK-NEXT: $h0 = COPY [[FPTRUNC]](s16)
+ ; CHECK-NEXT: $h1 = COPY [[FPTRUNC1]](s16)
+ ; CHECK-NEXT: RET_ReallyLR implicit $h0, implicit $h1
+ %0:_(s16) = COPY $h0
+ %1:_(s16), %2:_(s16) = G_FMODF %0
+ $h0 = COPY %1(s16)
+ $h1 = COPY %2(s16)
+ RET_ReallyLR implicit $h0, implicit $h1
+...
+---
+name: test_modf_f16_only_use_fractional_part
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: test_modf_f16_only_use_fractional_part
+ ; CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY $h0
+ ; CHECK-NEXT: [[FPEXT:%[0-9]+]]:_(s32) = G_FPEXT [[COPY]](s16)
+ ; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: $s0 = COPY [[FPEXT]](s32)
+ ; CHECK-NEXT: $x0 = COPY [[FRAME_INDEX]](p0)
+ ; CHECK-NEXT: BL &modff, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $s0, implicit $x0, implicit-def $s0
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $s0
+ ; CHECK-NEXT: [[FPTRUNC:%[0-9]+]]:_(s16) = G_FPTRUNC [[COPY1]](s32)
+ ; CHECK-NEXT: $h0 = COPY [[FPTRUNC]](s16)
+ ; CHECK-NEXT: RET_ReallyLR implicit $h0
+ %0:_(s16) = COPY $h0
+ %1:_(s16), %2:_(s16) = G_FMODF %0
+ $h0 = COPY %1(s16)
+ RET_ReallyLR implicit $h0
+...
+---
+name: test_modf_v2f16
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: test_modf_v2f16
+ ; CHECK: [[COPY:%[0-9]+]]:_(<4 x s16>) = COPY $d0
+ ; CHECK-NEXT: [[UV:%[0-9]+]]:_(s16), [[UV1:%[0-9]+]]:_(s16), [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[COPY]](<4 x s16>)
+ ; CHECK-NEXT: [[FPEXT:%[0-9]+]]:_(s32) = G_FPEXT [[UV]](s16)
+ ; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: $s0 = COPY [[FPEXT]](s32)
+ ; CHECK-NEXT: $x0 = COPY [[FRAME_INDEX]](p0)
+ ; CHECK-NEXT: BL &modff, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $s0, implicit $x0, implicit-def $s0
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $s0
+ ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %stack.1)
+ ; CHECK-NEXT: [[FPTRUNC:%[0-9]+]]:_(s16) = G_FPTRUNC [[COPY1]](s32)
+ ; CHECK-NEXT: [[FPTRUNC1:%[0-9]+]]:_(s16) = G_FPTRUNC [[LOAD]](s32)
+ ; CHECK-NEXT: [[FPEXT1:%[0-9]+]]:_(s32) = G_FPEXT [[UV1]](s16)
+ ; CHECK-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: $s0 = COPY [[FPEXT1]](s32)
+ ; CHECK-NEXT: $x0 = COPY [[FRAME_INDEX1]](p0)
+ ; CHECK-NEXT: BL &modff, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $s0, implicit $x0, implicit-def $s0
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $s0
+ ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s32) from %stack.0)
+ ; CHECK-NEXT: [[FPTRUNC2:%[0-9]+]]:_(s16) = G_FPTRUNC [[COPY2]](s32)
+ ; CHECK-NEXT: [[FPTRUNC3:%[0-9]+]]:_(s16) = G_FPTRUNC [[LOAD1]](s32)
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s16>) = G_BUILD_VECTOR [[FPTRUNC]](s16), [[FPTRUNC2]](s16), [[DEF]](s16), [[DEF]](s16)
+ ; CHECK-NEXT: [[BUILD_VECTOR1:%[0-9]+]]:_(<4 x s16>) = G_BUILD_VECTOR [[FPTRUNC1]](s16), [[FPTRUNC3]](s16), [[DEF]](s16), [[DEF]](s16)
+ ; CHECK-NEXT: $d0 = COPY [[BUILD_VECTOR]](<4 x s16>)
+ ; CHECK-NEXT: $d1 = COPY [[BUILD_VECTOR1]](<4 x s16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1
+ %1:_(<4 x s16>) = COPY $d0
+ %0:_(<2 x s16>), %2:_(<2 x s16>) = G_UNMERGE_VALUES %1(<4 x s16>)
+ %3:_(<2 x s16>), %4:_(<2 x s16>) = G_FMODF %0
+ %5:_(s16), %6:_(s16) = G_UNMERGE_VALUES %3(<2 x s16>)
+ %7:_(s16) = G_IMPLICIT_DEF
+ %8:_(<4 x s16>) = G_BUILD_VECTOR %5(s16), %6(s16), %7(s16), %7(s16)
+ %9:_(s16), %10:_(s16) = G_UNMERGE_VALUES %4(<2 x s16>)
+ %11:_(<4 x s16>) = G_BUILD_VECTOR %9(s16), %10(s16), %7(s16), %7(s16)
+ $d0 = COPY %8(<4 x s16>)
+ $d1 = COPY %11(<4 x s16>)
+ RET_ReallyLR implicit $d0, implicit $d1
+...
+---
+name: test_modf_v3f32
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: test_modf_v3f32
+ ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
+ ; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(<4 x s32>) = G_BITCAST [[COPY]](<2 x s64>)
+ ; CHECK-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32), [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]](<4 x s32>)
+ ; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.2
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: $s0 = COPY [[UV]](s32)
+ ; CHECK-NEXT: $x0 = COPY [[FRAME_INDEX]](p0)
+ ; CHECK-NEXT: BL &modff, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $s0, implicit $x0, implicit-def $s0
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $s0
+ ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %stack.2)
+ ; CHECK-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: $s0 = COPY [[UV1]](s32)
+ ; CHECK-NEXT: $x0 = COPY [[FRAME_INDEX1]](p0)
+ ; CHECK-NEXT: BL &modff, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $s0, implicit $x0, implicit-def $s0
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $s0
+ ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s32) from %stack.1)
+ ; CHECK-NEXT: [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: $s0 = COPY [[UV2]](s32)
+ ; CHECK-NEXT: $x0 = COPY [[FRAME_INDEX2]](p0)
+ ; CHECK-NEXT: BL &modff, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $s0, implicit $x0, implicit-def $s0
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $s0
+ ; CHECK-NEXT: [[LOAD2:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (s32) from %stack.0)
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[COPY1]](s32), [[COPY2]](s32), [[COPY3]](s32), [[DEF]](s32)
+ ; CHECK-NEXT: [[BUILD_VECTOR1:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[LOAD]](s32), [[LOAD1]](s32), [[LOAD2]](s32), [[DEF]](s32)
+ ; CHECK-NEXT: $q0 = COPY [[BUILD_VECTOR]](<4 x s32>)
+ ; CHECK-NEXT: $q1 = COPY [[BUILD_VECTOR1]](<4 x s32>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1
+ %1:_(<2 x s64>) = COPY $q0
+ %2:_(<4 x s32>) = G_BITCAST %1(<2 x s64>)
+ %3:_(s32), %4:_(s32), %5:_(s32), %6:_(s32) = G_UNMERGE_VALUES %2(<4 x s32>)
+ %0:_(<3 x s32>) = G_BUILD_VECTOR %3(s32), %4(s32), %5(s32)
+ %7:_(<3 x s32>), %8:_(<3 x s32>) = G_FMODF %0
+ %9:_(s32), %10:_(s32), %11:_(s32) = G_UNMERGE_VALUES %7(<3 x s32>)
+ %12:_(s32) = G_IMPLICIT_DEF
+ %13:_(<4 x s32>) = G_BUILD_VECTOR %9(s32), %10(s32), %11(s32), %12(s32)
+ %14:_(s32), %15:_(s32), %16:_(s32) = G_UNMERGE_VALUES %8(<3 x s32>)
+ %17:_(<4 x s32>) = G_BUILD_VECTOR %14(s32), %15(s32), %16(s32), %12(s32)
+ $q0 = COPY %13(<4 x s32>)
+ $q1 = COPY %17(<4 x s32>)
+ RET_ReallyLR implicit $q0, implicit $q1
+...
+---
+name: test_modf_v2f64
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: test_modf_v2f64
+ ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
+ ; CHECK-NEXT: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[COPY]](<2 x s64>)
+ ; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: $d0 = COPY [[UV]](s64)
+ ; CHECK-NEXT: $x0 = COPY [[FRAME_INDEX]](p0)
+ ; CHECK-NEXT: BL &modf, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $d0, implicit $x0, implicit-def $d0
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $d0
+ ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s64) from %stack.1)
+ ; CHECK-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: $d0 = COPY [[UV1]](s64)
+ ; CHECK-NEXT: $x0 = COPY [[FRAME_INDEX1]](p0)
+ ; CHECK-NEXT: BL &modf, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $d0, implicit $x0, implicit-def $d0
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $d0
+ ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s64) from %stack.0)
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[COPY1]](s64), [[COPY2]](s64)
+ ; CHECK-NEXT: [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[LOAD]](s64), [[LOAD1]](s64)
+ ; CHECK-NEXT: $q0 = COPY [[BUILD_VECTOR]](<2 x s64>)
+ ; CHECK-NEXT: $q1 = COPY [[BUILD_VECTOR1]](<2 x s64>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1
+ %0:_(<2 x s64>) = COPY $q0
+ %1:_(<2 x s64>), %2:_(<2 x s64>) = G_FMODF %0
+ $q0 = COPY %1(<2 x s64>)
+ $q1 = COPY %2(<2 x s64>)
+ RET_ReallyLR implicit $q0, implicit $q1
+...
+---
+name: test_modf_fp128
+body: |
+ bb.0.entry:
+ ; CHECK-LABEL: name: test_modf_fp128
+ ; CHECK: [[COPY:%[0-9]+]]:_(s128) = COPY $q0
+ ; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: $q0 = COPY [[COPY]](s128)
+ ; CHECK-NEXT: $x0 = COPY [[FRAME_INDEX]](p0)
+ ; CHECK-NEXT: BL &modfl, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $q0, implicit $x0, implicit-def $q0
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s128) = COPY $q0
+ ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s128) from %stack.0)
+ ; CHECK-NEXT: $q0 = COPY [[COPY1]](s128)
+ ; CHECK-NEXT: $q1 = COPY [[LOAD]](s128)
+ ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1
+ %0:_(s128) = COPY $q0
+ %1:_(s128), %2:_(s128) = G_FMODF %0
+ $q0 = COPY %1(s128)
+ $q1 = COPY %2(s128)
+ RET_ReallyLR implicit $q0, implicit $q1
+...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
index 040f97f96ee21..9fff73e3e235e 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
@@ -508,6 +508,10 @@
# DEBUG-NEXT: G_FREM (opcode {{[0-9]+}}): 1 type index, 0 imm indices
# DEBUG-NEXT: .. the first uncovered type index: 1, OK
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
+# DEBUG-NEXT: G_FMODF (opcode {{[0-9]+}}): 1 type index, 0 imm indices
+# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
+# DEBUG-NEXT: .. the first uncovered type index: 1, OK
+# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
# DEBUG-NEXT: G_FPOW (opcode {{[0-9]+}}): 1 type index, 0 imm indices
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
# DEBUG-NEXT: .. the first uncovered type index: 1, OK
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-modf.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-modf.mir
new file mode 100644
index 0000000000000..604cb96e38dc3
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-modf.mir
@@ -0,0 +1,136 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -verify-machineinstrs -mtriple aarch64-unknown-unknown -run-pass=instruction-select %s -o - | FileCheck %s
+---
+name: test_modf_fp128
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+liveins:
+ - { reg: '$q0' }
+frameInfo:
+ maxAlignment: 16
+stack:
+ - { id: 0, size: 16, alignment: 16 }
+body: |
+ bb.1:
+ liveins: $q0
+
+ ; CHECK-LABEL: name: test_modf_fp128
+ ; CHECK: liveins: $q0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0
+ ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri %stack.0, 0, 0
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: $q0 = COPY [[COPY]]
+ ; CHECK-NEXT: $x0 = COPY [[ADDXri]]
+ ; CHECK-NEXT: BL &modfl, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $q0, implicit $x0, implicit-def $q0
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr128 = COPY $q0
+ ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui %stack.0, 0 :: (load (s128) from %stack.0)
+ ; CHECK-NEXT: $q0 = COPY [[COPY1]]
+ ; CHECK-NEXT: $q1 = COPY [[LDRQui]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1
+ %0:fpr(s128) = COPY $q0
+ %3:gpr(p0) = G_FRAME_INDEX %stack.0
+ ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ $q0 = COPY %0(s128)
+ $x0 = COPY %3(p0)
+ BL &modfl, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $q0, implicit $x0, implicit-def $q0
+ ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ %1:fpr(s128) = COPY $q0
+ %2:fpr(s128) = G_LOAD %3(p0) :: (load (s128) from %stack.0)
+ $q0 = COPY %1(s128)
+ $q1 = COPY %2(s128)
+ RET_ReallyLR implicit $q0, implicit $q1
+...
+---
+name: test_modf_double
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+liveins:
+ - { reg: '$d0' }
+frameInfo:
+ maxAlignment: 8
+stack:
+ - { id: 0, size: 8, alignment: 8 }
+machineFunctionInfo: {}
+body: |
+ bb.1:
+ liveins: $d0
+
+ ; CHECK-LABEL: name: test_modf_double
+ ; CHECK: liveins: $d0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0
+ ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri %stack.0, 0, 0
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: $d0 = COPY [[COPY]]
+ ; CHECK-NEXT: $x0 = COPY [[ADDXri]]
+ ; CHECK-NEXT: BL &modf, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $d0, implicit $x0, implicit-def $d0
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $d0
+ ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui %stack.0, 0 :: (load (s64) from %stack.0)
+ ; CHECK-NEXT: $d0 = COPY [[COPY1]]
+ ; CHECK-NEXT: $d1 = COPY [[LDRDui]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1
+ %0:fpr(s64) = COPY $d0
+ %3:gpr(p0) = G_FRAME_INDEX %stack.0
+ ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ $d0 = COPY %0(s64)
+ $x0 = COPY %3(p0)
+ BL &modf, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $d0, implicit $x0, implicit-def $d0
+ ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ %1:fpr(s64) = COPY $d0
+ %2:fpr(s64) = G_LOAD %3(p0) :: (load (s64) from %stack.0)
+ $d0 = COPY %1(s64)
+ $d1 = COPY %2(s64)
+ RET_ReallyLR implicit $d0, implicit $d1
+...
+---
+name: test_modf_double_vec
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+liveins:
+ - { reg: '$d0' }
+frameInfo:
+ maxAlignment: 8
+stack:
+ - { id: 0, size: 8, alignment: 8 }
+machineFunctionInfo: {}
+body: |
+ bb.1:
+ liveins: $d0
+
+ ; CHECK-LABEL: name: test_modf_double_vec
+ ; CHECK: liveins: $d0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0
+ ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri %stack.0, 0, 0
+ ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: $d0 = COPY [[COPY]]
+ ; CHECK-NEXT: $x0 = COPY [[ADDXri]]
+ ; CHECK-NEXT: BL &modf, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $d0, implicit $x0, implicit-def $d0
+ ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $d0
+ ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui %stack.0, 0 :: (load (s64) from %stack.0)
+ ; CHECK-NEXT: $d0 = COPY [[COPY1]]
+ ; CHECK-NEXT: $d1 = COPY [[LDRDui]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1
+ %0:fpr(s64) = COPY $d0
+ %3:gpr(p0) = G_FRAME_INDEX %stack.0
+ ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+ $d0 = COPY %0(s64)
+ $x0 = COPY %3(p0)
+ BL &modf, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $d0, implicit $x0, implicit-def $d0
+ ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+ %1:fpr(s64) = COPY $d0
+ %2:fpr(s64) = G_LOAD %3(p0) :: (load (s64) from %stack.0)
+ $d0 = COPY %1(s64)
+ $d1 = COPY %2(s64)
+ RET_ReallyLR implicit $d0, implicit $d1
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
index 86084ae531cdb..a9e086c6b6aaf 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir
@@ -505,6 +505,9 @@
# DEBUG-NEXT: G_FREM (opcode {{[0-9]+}}): 1 type index, 0 imm indices
# DEBUG-NEXT: .. the first uncovered type index: 1, OK
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
+# DEBUG-NEXT: G_FMODF (opcode {{[0-9]+}}): 1 type index, 0 imm indices
+# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: G_FPOW (opcode {{[0-9]+}}): 1 type index, 0 imm indices
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
# DEBUG-NEXT: .. the first uncovered type index: 1, OK
@@ -607,11 +610,11 @@
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: G_FMINIMUMNUM (opcode {{[0-9]+}}): 1 type index, 0 imm indices
-# DEBUG-NEXT: .. opcode 219 is aliased to 183
+# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
# DEBUG-NEXT: .. the first uncovered type index: 1, OK
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
# DEBUG-NEXT: G_FMAXIMUMNUM (opcode {{[0-9]+}}): 1 type index, 0 imm indices
-# DEBUG-NEXT: .. opcode 220 is aliased to 183
+# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
# DEBUG-NEXT: .. the first uncovered type index: 1, OK
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
# DEBUG-NEXT: G_GET_FPENV (opcode {{[0-9]+}}): 1 type index, 0 imm indices
diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-cxx.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-cxx.td
index ce4f0108b4843..18960b43ab97d 100644
--- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-cxx.td
+++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-cxx.td
@@ -96,71 +96,71 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
// CHECK: const uint8_t *GenMyCombiner::getMatchTable() const {
// CHECK-NEXT: constexpr static uint8_t MatchTable0[] = {
-// CHECK-NEXT: /* 0 */ GIM_SwitchOpcode, /*MI*/0, /*[*/GIMT_Encode2(99), GIMT_Encode2(210), /*)*//*default:*//*Label 5*/ GIMT_Encode4(520),
-// CHECK-NEXT: /* 10 */ /*TargetOpcode::G_STORE*//*Label 0*/ GIMT_Encode4(454), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0),
-// CHECK-NEXT: /* 182 */ /*TargetOpcode::G_SEXT*//*Label 1*/ GIMT_Encode4(472), GIMT_Encode4(0),
-// CHECK-NEXT: /* 190 */ /*TargetOpcode::G_ZEXT*//*Label 2*/ GIMT_Encode4(484), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0),
-// CHECK-NEXT: /* 414 */ /*TargetOpcode::G_FNEG*//*Label 3*/ GIMT_Encode4(496), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0),
-// CHECK-NEXT: /* 450 */ /*TargetOpcode::G_FABS*//*Label 4*/ GIMT_Encode4(508),
-// CHECK-NEXT: /* 454 */ // Label 0: @454
-// CHECK-NEXT: /* 454 */ GIM_Try, /*On fail goto*//*Label 6*/ GIMT_Encode4(471), // Rule ID 2 //
-// CHECK-NEXT: /* 459 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule2Enabled),
-// CHECK-NEXT: /* 462 */ // MIs[0] x
-// CHECK-NEXT: /* 462 */ // No operand predicates
-// CHECK-NEXT: /* 462 */ // MIs[0] y
-// CHECK-NEXT: /* 462 */ // No operand predicates
-// CHECK-NEXT: /* 462 */ GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner0),
-// CHECK-NEXT: /* 466 */ GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner1),
-// CHECK-NEXT: /* 470 */ // Combiner Rule #2: TwoMatchNoApply
-// CHECK-NEXT: /* 470 */ GIR_EraseRootFromParent_Done,
-// CHECK-NEXT: /* 471 */ // Label 6: @471
-// CHECK-NEXT: /* 471 */ GIM_Reject,
-// CHECK-NEXT: /* 472 */ // Label 1: @472
-// CHECK-NEXT: /* 472 */ GIM_Try, /*On fail goto*//*Label 7*/ GIMT_Encode4(483), // Rule ID 3 //
-// CHECK-NEXT: /* 477 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule3Enabled),
-// CHECK-NEXT: /* 480 */ // MIs[0] a
-// CHECK-NEXT: /* 480 */ // No operand predicates
-// CHECK-NEXT: /* 480 */ // MIs[0] y
-// CHECK-NEXT: /* 480 */ // No operand predicates
-// CHECK-NEXT: /* 480 */ // Combiner Rule #3: NoMatchTwoApply
-// CHECK-NEXT: /* 480 */ GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner2),
-// CHECK-NEXT: /* 483 */ // Label 7: @483
-// CHECK-NEXT: /* 483 */ GIM_Reject,
-// CHECK-NEXT: /* 484 */ // Label 2: @484
-// CHECK-NEXT: /* 484 */ GIM_Try, /*On fail goto*//*Label 8*/ GIMT_Encode4(495), // Rule ID 4 //
-// CHECK-NEXT: /* 489 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule4Enabled),
-// CHECK-NEXT: /* 492 */ // MIs[0] a
-// CHECK-NEXT: /* 492 */ // No operand predicates
-// CHECK-NEXT: /* 492 */ // MIs[0] y
-// CHECK-NEXT: /* 492 */ // No operand predicates
-// CHECK-NEXT: /* 492 */ // Combiner Rule #4: CombineCXXOrder
-// CHECK-NEXT: /* 492 */ GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner3),
-// CHECK-NEXT: /* 495 */ // Label 8: @495
-// CHECK-NEXT: /* 495 */ GIM_Reject,
-// CHECK-NEXT: /* 496 */ // Label 3: @496
-// CHECK-NEXT: /* 496 */ GIM_Try, /*On fail goto*//*Label 9*/ GIMT_Encode4(507), // Rule ID 1 //
-// CHECK-NEXT: /* 501 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule1Enabled),
-// CHECK-NEXT: /* 504 */ // MIs[0] a
-// CHECK-NEXT: /* 504 */ // No operand predicates
-// CHECK-NEXT: /* 504 */ // MIs[0] b
-// CHECK-NEXT: /* 504 */ // No operand predicates
-// CHECK-NEXT: /* 504 */ // Combiner Rule #1: TwoMatchTwoApply
-// CHECK-NEXT: /* 504 */ GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner1),
-// CHECK-NEXT: /* 507 */ // Label 9: @507
-// CHECK-NEXT: /* 507 */ GIM_Reject,
-// CHECK-NEXT: /* 508 */ // Label 4: @508
-// CHECK-NEXT: /* 508 */ GIM_Try, /*On fail goto*//*Label 10*/ GIMT_Encode4(519), // Rule ID 0 //
-// CHECK-NEXT: /* 513 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
-// CHECK-NEXT: /* 516 */ // MIs[0] a
-// CHECK-NEXT: /* 516 */ // No operand predicates
-// CHECK-NEXT: /* 516 */ // MIs[0] b
-// CHECK-NEXT: /* 516 */ // No operand predicates
-// CHECK-NEXT: /* 516 */ // Combiner Rule #0: OneMatchOneApply
-// CHECK-NEXT: /* 516 */ GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
-// CHECK-NEXT: /* 519 */ // Label 10: @519
-// CHECK-NEXT: /* 519 */ GIM_Reject,
-// CHECK-NEXT: /* 520 */ // Label 5: @520
-// CHECK-NEXT: /* 520 */ GIM_Reject,
-// CHECK-NEXT: /* 521 */ }; // Size: 521 bytes
+// CHECK-NEXT: /* 0 */ GIM_SwitchOpcode, /*MI*/0, /*[*/GIMT_Encode2(99), GIMT_Encode2(211), /*)*//*default:*//*Label 5*/ GIMT_Encode4(524),
+// CHECK-NEXT: /* 10 */ /*TargetOpcode::G_STORE*//*Label 0*/ GIMT_Encode4(458), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0),
+// CHECK-NEXT: /* 182 */ /*TargetOpcode::G_SEXT*//*Label 1*/ GIMT_Encode4(476), GIMT_Encode4(0),
+// CHECK-NEXT: /* 190 */ /*TargetOpcode::G_ZEXT*//*Label 2*/ GIMT_Encode4(488), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0),
+// CHECK-NEXT: /* 418 */ /*TargetOpcode::G_FNEG*//*Label 3*/ GIMT_Encode4(500), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0),
+// CHECK-NEXT: /* 454 */ /*TargetOpcode::G_FABS*//*Label 4*/ GIMT_Encode4(512),
+// CHECK-NEXT: /* 458 */ // Label 0: @458
+// CHECK-NEXT: /* 458 */ GIM_Try, /*On fail goto*//*Label 6*/ GIMT_Encode4(475), // Rule ID 2 //
+// CHECK-NEXT: /* 463 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule2Enabled),
+// CHECK-NEXT: /* 466 */ // MIs[0] x
+// CHECK-NEXT: /* 466 */ // No operand predicates
+// CHECK-NEXT: /* 466 */ // MIs[0] y
+// CHECK-NEXT: /* 466 */ // No operand predicates
+// CHECK-NEXT: /* 466 */ GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner0),
+// CHECK-NEXT: /* 470 */ GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_GICombiner1),
+// CHECK-NEXT: /* 474 */ // Combiner Rule #2: TwoMatchNoApply
+// CHECK-NEXT: /* 474 */ GIR_EraseRootFromParent_Done,
+// CHECK-NEXT: /* 475 */ // Label 6: @475
+// CHECK-NEXT: /* 475 */ GIM_Reject,
+// CHECK-NEXT: /* 476 */ // Label 1: @476
+// CHECK-NEXT: /* 476 */ GIM_Try, /*On fail goto*//*Label 7*/ GIMT_Encode4(487), // Rule ID 3 //
+// CHECK-NEXT: /* 481 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule3Enabled),
+// CHECK-NEXT: /* 484 */ // MIs[0] a
+// CHECK-NEXT: /* 484 */ // No operand predicates
+// CHECK-NEXT: /* 484 */ // MIs[0] y
+// CHECK-NEXT: /* 484 */ // No operand predicates
+// CHECK-NEXT: /* 484 */ // Combiner Rule #3: NoMatchTwoApply
+// CHECK-NEXT: /* 484 */ GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner2),
+// CHECK-NEXT: /* 487 */ // Label 7: @487
+// CHECK-NEXT: /* 487 */ GIM_Reject,
+// CHECK-NEXT: /* 488 */ // Label 2: @488
+// CHECK-NEXT: /* 488 */ GIM_Try, /*On fail goto*//*Label 8*/ GIMT_Encode4(499), // Rule ID 4 //
+// CHECK-NEXT: /* 493 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule4Enabled),
+// CHECK-NEXT: /* 496 */ // MIs[0] a
+// CHECK-NEXT: /* 496 */ // No operand predicates
+// CHECK-NEXT: /* 496 */ // MIs[0] y
+// CHECK-NEXT: /* 496 */ // No operand predicates
+// CHECK-NEXT: /* 496 */ // Combiner Rule #4: CombineCXXOrder
+// CHECK-NEXT: /* 496 */ GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner3),
+// CHECK-NEXT: /* 499 */ // Label 8: @499
+// CHECK-NEXT: /* 499 */ GIM_Reject,
+// CHECK-NEXT: /* 500 */ // Label 3: @500
+// CHECK-NEXT: /* 500 */ GIM_Try, /*On fail goto*//*Label 9*/ GIMT_Encode4(511), // Rule ID 1 //
+// CHECK-NEXT: /* 505 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule1Enabled),
+// CHECK-NEXT: /* 508 */ // MIs[0] a
+// CHECK-NEXT: /* 508 */ // No operand predicates
+// CHECK-NEXT: /* 508 */ // MIs[0] b
+// CHECK-NEXT: /* 508 */ // No operand predicates
+// CHECK-NEXT: /* 508 */ // Combiner Rule #1: TwoMatchTwoApply
+// CHECK-NEXT: /* 508 */ GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner1),
+// CHECK-NEXT: /* 511 */ // Label 9: @511
+// CHECK-NEXT: /* 511 */ GIM_Reject,
+// CHECK-NEXT: /* 512 */ // Label 4: @512
+// CHECK-NEXT: /* 512 */ GIM_Try, /*On fail goto*//*Label 10*/ GIMT_Encode4(523), // Rule ID 0 //
+// CHECK-NEXT: /* 517 */ GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
+// CHECK-NEXT: /* 520 */ // MIs[0] a
+// CHECK-NEXT: /* 520 */ // No operand predicates
+// CHECK-NEXT: /* 520 */ // MIs[0] b
+// CHECK-NEXT: /* 520 */ // No operand predicates
+// CHECK-NEXT: /* 520 */ // Combiner Rule #0: OneMatchOneApply
+// CHECK-NEXT: /* 520 */ GIR_DoneWithCustomAction, /*Fn*/GIMT_Encode2(GICXXCustomAction_GICombiner0),
+// CHECK-NEXT: /* 523 */ // Label 10: @523
+// CHECK-NEXT: /* 523 */ GIM_Reject,
+// CHECK-NEXT: /* 524 */ // Label 5: @524
+// CHECK-NEXT: /* 524 */ GIM_Reject,
+// CHECK-NEXT: /* 525 */ }; // Size: 525 bytes
// CHECK-NEXT: return MatchTable0;
// CHECK-NEXT: }
diff --git a/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td b/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td
index 7a86b5b726a82..6be1720a6da23 100644
--- a/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td
+++ b/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td
@@ -535,7 +535,7 @@ def : Pat<(frag GPR32:$src1, complex:$src2, complex:$src3),
// R00O-NEXT: GIM_Reject,
// R00O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]]
// R00O-NEXT: GIM_Reject,
-// R00O-NEXT: }; // Size: 1894 bytes
+// R00O-NEXT: }; // Size: 1898 bytes
def INSNBOB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3, GPR32:$src4),
[(set GPR32:$dst,
diff --git a/llvm/test/TableGen/RegClassByHwMode.td b/llvm/test/TableGen/RegClassByHwMode.td
index 5d813d2bfc83a..99fe1c0b00408 100644
--- a/llvm/test/TableGen/RegClassByHwMode.td
+++ b/llvm/test/TableGen/RegClassByHwMode.td
@@ -50,7 +50,7 @@ include "llvm/Target/Target.td"
// INSTRINFO-NEXT: };
// INSTRINFO: static inline void InitMyTargetMCInstrInfo(
-// INSTRINFO-NEXT: II->InitMCInstrInfo(MyTargetDescs.Insts, MyTargetInstrNameIndices, MyTargetInstrNameData, nullptr, nullptr, 321, &MyTargetRegClassByHwModeTables[0][0], 3);
+// INSTRINFO-NEXT: II->InitMCInstrInfo(MyTargetDescs.Insts, MyTargetInstrNameIndices, MyTargetInstrNameData, nullptr, nullptr, 322, &MyTargetRegClassByHwModeTables[0][0], 3);
More information about the llvm-commits
mailing list