mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 02:52:53 +02:00
GlobalISel: support floating-point constants on AArch64.
Patch from Ahmed Bougacha. llvm-svn: 284523
This commit is contained in:
parent
7adf6be710
commit
189324351a
@ -513,14 +513,81 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const {
|
||||
return constrainSelectedInstRegOperands(*MIB.getInstr(), TII, TRI, RBI);
|
||||
}
|
||||
|
||||
case TargetOpcode::G_FCONSTANT:
|
||||
case TargetOpcode::G_CONSTANT: {
|
||||
if (Ty.getSizeInBits() <= 32)
|
||||
I.setDesc(TII.get(AArch64::MOVi32imm));
|
||||
else if (Ty.getSizeInBits() <= 64)
|
||||
I.setDesc(TII.get(AArch64::MOVi64imm));
|
||||
else
|
||||
return false;
|
||||
return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
|
||||
const bool isFP = Opcode == TargetOpcode::G_FCONSTANT;
|
||||
|
||||
const LLT s32 = LLT::scalar(32);
|
||||
const LLT s64 = LLT::scalar(64);
|
||||
const LLT p0 = LLT::pointer(0, 64);
|
||||
|
||||
const unsigned DefReg = I.getOperand(0).getReg();
|
||||
const LLT DefTy = MRI.getType(DefReg);
|
||||
const unsigned DefSize = DefTy.getSizeInBits();
|
||||
const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
|
||||
|
||||
// FIXME: Redundant check, but even less readable when factored out.
|
||||
if (isFP) {
|
||||
if (Ty != s32 && Ty != s64) {
|
||||
DEBUG(dbgs() << "Unable to materialize FP " << Ty
|
||||
<< " constant, expected: " << s32 << " or " << s64
|
||||
<< '\n');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (RB.getID() != AArch64::FPRRegBankID) {
|
||||
DEBUG(dbgs() << "Unable to materialize FP " << Ty
|
||||
<< " constant on bank: " << RB << ", expected: FPR\n");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (Ty != s32 && Ty != s64 && Ty != p0) {
|
||||
DEBUG(dbgs() << "Unable to materialize integer " << Ty
|
||||
<< " constant, expected: " << s32 << ", " << s64 << ", or "
|
||||
<< p0 << '\n');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (RB.getID() != AArch64::GPRRegBankID) {
|
||||
DEBUG(dbgs() << "Unable to materialize integer " << Ty
|
||||
<< " constant on bank: " << RB << ", expected: GPR\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const unsigned MovOpc =
|
||||
DefSize == 32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
|
||||
|
||||
I.setDesc(TII.get(MovOpc));
|
||||
|
||||
if (isFP) {
|
||||
const TargetRegisterClass &GPRRC =
|
||||
DefSize == 32 ? AArch64::GPR32RegClass : AArch64::GPR64RegClass;
|
||||
const TargetRegisterClass &FPRRC =
|
||||
DefSize == 32 ? AArch64::FPR32RegClass : AArch64::FPR64RegClass;
|
||||
|
||||
const unsigned DefGPRReg = MRI.createVirtualRegister(&GPRRC);
|
||||
MachineOperand &RegOp = I.getOperand(0);
|
||||
RegOp.setReg(DefGPRReg);
|
||||
|
||||
BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(),
|
||||
TII.get(AArch64::COPY))
|
||||
.addDef(DefReg)
|
||||
.addUse(DefGPRReg);
|
||||
|
||||
if (!RBI.constrainGenericRegister(DefReg, FPRRC, MRI)) {
|
||||
DEBUG(dbgs() << "Failed to constrain G_FCONSTANT def operand\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
MachineOperand &ImmOp = I.getOperand(1);
|
||||
// FIXME: Is going through int64_t always correct?
|
||||
ImmOp.ChangeToImmediate(
|
||||
ImmOp.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue());
|
||||
}
|
||||
|
||||
constrainSelectedInstRegOperands(I, TII, TRI, RBI);
|
||||
return true;
|
||||
}
|
||||
|
||||
case TargetOpcode::G_FRAME_INDEX: {
|
||||
|
@ -103,6 +103,9 @@
|
||||
define i32 @const_s32() { ret i32 42 }
|
||||
define i64 @const_s64() { ret i64 1234567890123 }
|
||||
|
||||
define i32 @fconst_s32() { ret i32 42 }
|
||||
define i64 @fconst_s64() { ret i64 1234567890123 }
|
||||
|
||||
define i8* @gep(i8* %in) { ret i8* undef }
|
||||
|
||||
@var_local = global i8 0
|
||||
@ -1878,6 +1881,38 @@ body: |
|
||||
%0(s64) = G_CONSTANT 1234567890123
|
||||
...
|
||||
|
||||
---
|
||||
# CHECK-LABEL: name: fconst_s32
|
||||
name: fconst_s32
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
registers:
|
||||
- { id: 0, class: fpr }
|
||||
|
||||
# CHECK: body:
|
||||
# CHECK: [[TMP:%[0-9]+]] = MOVi32imm 1080033280
|
||||
# CHECK: %0 = COPY [[TMP]]
|
||||
body: |
|
||||
bb.0:
|
||||
%0(s32) = G_FCONSTANT float 3.5
|
||||
...
|
||||
|
||||
---
|
||||
# CHECK-LABEL: name: fconst_s64
|
||||
name: fconst_s64
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
registers:
|
||||
- { id: 0, class: fpr }
|
||||
|
||||
# CHECK: body:
|
||||
# CHECK: [[TMP:%[0-9]+]] = MOVi64imm 4607182418800017408
|
||||
# CHECK: %0 = COPY [[TMP]]
|
||||
body: |
|
||||
bb.0:
|
||||
%0(s64) = G_FCONSTANT double 1.0
|
||||
...
|
||||
|
||||
---
|
||||
# CHECK-LABEL: name: gep
|
||||
name: gep
|
||||
|
Loading…
Reference in New Issue
Block a user