mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
[AArch64][GlobalISel] Add support for FCONSTANT of FP128 type
Add support for G_FCONSTANT of FP128 (Quadruple precision) type. It replaces the constant by emitting a load with a constant pool entry. Reviewed By: aemerson Differential Revision: https://reviews.llvm.org/D94437
This commit is contained in:
parent
f44895099b
commit
680b733958
@ -2289,6 +2289,7 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
|
||||
const LLT s16 = LLT::scalar(16);
|
||||
const LLT s32 = LLT::scalar(32);
|
||||
const LLT s64 = LLT::scalar(64);
|
||||
const LLT s128 = LLT::scalar(128);
|
||||
const LLT p0 = LLT::pointer(0, 64);
|
||||
|
||||
const Register DefReg = I.getOperand(0).getReg();
|
||||
@ -2298,10 +2299,10 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
|
||||
|
||||
// FIXME: Redundant check, but even less readable when factored out.
|
||||
if (isFP) {
|
||||
if (Ty != s32 && Ty != s64) {
|
||||
if (Ty != s32 && Ty != s64 && Ty != s128) {
|
||||
LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
|
||||
<< " constant, expected: " << s32 << " or " << s64
|
||||
<< '\n');
|
||||
<< " or " << s128 << '\n');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2314,7 +2315,9 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
|
||||
|
||||
// The case when we have 0.0 is covered by tablegen. Reject it here so we
|
||||
// can be sure tablegen works correctly and isn't rescued by this code.
|
||||
if (I.getOperand(1).getFPImm()->getValueAPF().isExactlyValue(0.0))
|
||||
// 0.0 is not covered by tablegen for FP128. So we will handle this
|
||||
// scenario in the code here.
|
||||
if (DefSize != 128 && I.getOperand(1).getFPImm()->isExactlyValue(0.0))
|
||||
return false;
|
||||
} else {
|
||||
// s32 and s64 are covered by tablegen.
|
||||
@ -2341,15 +2344,17 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
|
||||
// Either emit a FMOV, or emit a copy to emit a normal mov.
|
||||
const TargetRegisterClass &GPRRC =
|
||||
DefSize == 32 ? AArch64::GPR32RegClass : AArch64::GPR64RegClass;
|
||||
const TargetRegisterClass &FPRRC =
|
||||
DefSize == 32 ? AArch64::FPR32RegClass : AArch64::FPR64RegClass;
|
||||
const TargetRegisterClass &FPRRC =
|
||||
DefSize == 32 ? AArch64::FPR32RegClass
|
||||
: (DefSize == 64 ? AArch64::FPR64RegClass
|
||||
: AArch64::FPR128RegClass);
|
||||
|
||||
// Can we use a FMOV instruction to represent the immediate?
|
||||
if (emitFMovForFConstant(I, MRI))
|
||||
return true;
|
||||
|
||||
// For 64b values, emit a constant pool load instead.
|
||||
if (DefSize == 64) {
|
||||
if (DefSize == 64 || DefSize == 128) {
|
||||
auto *FPImm = I.getOperand(1).getFPImm();
|
||||
MachineIRBuilder MIB(I);
|
||||
auto *LoadMI = emitLoadFromConstantPool(FPImm, MIB);
|
||||
|
@ -332,9 +332,9 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
|
||||
const auto &Ty = Query.Types[0];
|
||||
if (HasFP16 && Ty == s16)
|
||||
return true;
|
||||
return Ty == s32 || Ty == s64;
|
||||
return Ty == s32 || Ty == s64 || Ty == s128;
|
||||
})
|
||||
.clampScalar(0, MinFPScalar, s64);
|
||||
.clampScalar(0, MinFPScalar, s128);
|
||||
|
||||
getActionDefinitionsBuilder({G_ICMP, G_FCMP})
|
||||
.legalFor({{s32, s32},
|
||||
|
@ -64,13 +64,6 @@ define void @test_write_register_intrin() {
|
||||
@_ZTIi = external global i8*
|
||||
declare i32 @__gxx_personality_v0(...)
|
||||
|
||||
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %0:_(s128) = G_FCONSTANT fp128 0xL00000000000000004000000000000000
|
||||
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for test_quad_dump
|
||||
; FALLBACK-WITH-REPORT-OUT-LABEL: test_quad_dump:
|
||||
define fp128 @test_quad_dump() {
|
||||
ret fp128 0xL00000000000000004000000000000000
|
||||
}
|
||||
|
||||
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %2:_(<2 x p0>) = G_INSERT_VECTOR_ELT %0:_, %{{[0-9]+}}:_(p0), %{{[0-9]+}}:_(s32) (in function: vector_of_pointers_insertelement)
|
||||
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for vector_of_pointers_insertelement
|
||||
; FALLBACK-WITH-REPORT-OUT-LABEL: vector_of_pointers_insertelement:
|
||||
|
22
test/CodeGen/AArch64/GlobalISel/legalize-fp128-fconstant.mir
Normal file
22
test/CodeGen/AArch64/GlobalISel/legalize-fp128-fconstant.mir
Normal file
@ -0,0 +1,22 @@
|
||||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
||||
# RUN: llc -O0 -mtriple=aarch64 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
|
||||
|
||||
...
|
||||
---
|
||||
name: fp128-fconstant
|
||||
alignment: 16
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0:
|
||||
; CHECK-LABEL: name: fp128-fconstant
|
||||
; CHECK: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
|
||||
; CHECK: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0
|
||||
; CHECK: $q0 = COPY [[LDRQui]]
|
||||
; CHECK: RET_ReallyLR implicit $q0
|
||||
%0:fpr(s128) = G_FCONSTANT fp128 0xL00000000000000004000000000000000
|
||||
$q0 = COPY %0:fpr(s128)
|
||||
RET_ReallyLR implicit $q0
|
||||
...
|
||||
|
Loading…
Reference in New Issue
Block a user